- pre4:
[davej-history.git] / drivers / scsi / wd7000.c
blob6f2681117da8b5587f8281256c0bdb1ba04fad0c
1 /* $Id: $
2 * linux/drivers/scsi/wd7000.c
4 * Copyright (C) 1992 Thomas Wuensche
5 * closely related to the aha1542 driver from Tommy Thorn
6 * ( as close as different hardware allows on a lowlevel-driver :-) )
8 * Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
9 * accommodate Eric Youngdale's modifications to scsi.c. Nov 1992.
11 * Additional changes to support scatter/gather. Dec. 1992. tw/jb
13 * No longer tries to reset SCSI bus at boot (it wasn't working anyway).
14 * Rewritten to support multiple host adapters.
15 * Miscellaneous cleanup.
16 * So far, still doesn't do reset or abort correctly, since I have no idea
17 * how to do them with this board (8^(. Jan 1994 jb
19 * This driver now supports both of the two standard configurations (per
20 * the 3.36 Owner's Manual, my latest reference) by the same method as
21 * before; namely, by looking for a BIOS signature. Thus, the location of
22 * the BIOS signature determines the board configuration. Until I have
23 * time to do something more flexible, users should stick to one of the
24 * following:
26 * Standard configuration for single-adapter systems:
27 * - BIOS at CE00h
28 * - I/O base address 350h
29 * - IRQ level 15
30 * - DMA channel 6
31 * Standard configuration for a second adapter in a system:
32 * - BIOS at C800h
33 * - I/O base address 330h
34 * - IRQ level 11
35 * - DMA channel 5
37 * Anyone who can recompile the kernel is welcome to add others as need
38 * arises, but unpredictable results may occur if there are conflicts.
39 * In any event, if there are multiple adapters in a system, they MUST
40 * use different I/O bases, IRQ levels, and DMA channels, since they will be
41 * indistinguishable (and in direct conflict) otherwise.
43 * As a point of information, the NO_OP command toggles the CMD_RDY bit
44 * of the status port, and this fact could be used as a test for the I/O
45 * base address (or more generally, board detection). There is an interrupt
46 * status port, so IRQ probing could also be done. I suppose the full
47 * DMA diagnostic could be used to detect the DMA channel being used. I
48 * haven't done any of this, though, because I think there's too much of
49 * a chance that such explorations could be destructive, if some other
50 * board's resources are used inadvertently. So, call me a wimp, but I
51 * don't want to try it. The only kind of exploration I trust is memory
52 * exploration, since it's more certain that reading memory won't be
53 * destructive.
55 * More to my liking would be a LILO boot command line specification, such
56 * as is used by the aha152x driver (and possibly others). I'll look into
57 * it, as I have time...
59 * I get mail occasionally from people who either are using or are
60 * considering using a WD7000 with Linux. There is a variety of
61 * nomenclature describing WD7000's. To the best of my knowledge, the
62 * following is a brief summary (from an old WD doc - I don't work for
63 * them or anything like that):
65 * WD7000-FASST2: This is a WD7000 board with the real-mode SST ROM BIOS
66 * installed. Last I heard, the BIOS was actually done by Columbia
67 * Data Products. The BIOS is only used by this driver (and thus
68 * by Linux) to identify the board; none of it can be executed under
69 * Linux.
71 * WD7000-ASC: This is the original adapter board, with or without BIOS.
72 * The board uses a WD33C93 or WD33C93A SBIC, which in turn is
73 * controlled by an onboard Z80 processor. The board interface
74 * visible to the host CPU is defined effectively by the Z80's
75 * firmware, and it is this firmware's revision level that is
76 * determined and reported by this driver. (The version of the
77 * on-board BIOS is of no interest whatsoever.) The host CPU has
78 * no access to the SBIC; hence the fact that it is a WD33C93 is
79 * also of no interest to this driver.
81 * WD7000-AX:
82 * WD7000-MX:
83 * WD7000-EX: These are newer versions of the WD7000-ASC. The -ASC is
84 * largely built from discrete components; these boards use more
85 * integration. The -AX is an ISA bus board (like the -ASC),
86 * the -MX is an MCA (i.e., PS/2) bus board), and the -EX is an
87 * EISA bus board.
89 * At the time of my documentation, the -?X boards were "future" products,
90 * and were not yet available. However, I vaguely recall that Thomas
91 * Wuensche had an -AX, so I believe at least it is supported by this
92 * driver. I have no personal knowledge of either -MX or -EX boards.
94 * P.S. Just recently, I've discovered (directly from WD and Future
95 * Domain) that all but the WD7000-EX have been out of production for
96 * two years now. FD has production rights to the 7000-EX, and are
97 * producing it under a new name, and with a new BIOS. If anyone has
98 * one of the FD boards, it would be nice to come up with a signature
99 * for it.
100 * J.B. Jan 1994.
103 * Revisions by Miroslav Zagorac <zaga@fly.cc.fer.hr>
105 * 08/24/1996.
107 * Enhancement for wd7000_detect function has been made, so you don't have
108 * to enter BIOS ROM address in initialisation data (see struct Config).
109 * We cannot detect IRQ, DMA and I/O base address for now, so we have to
110 * enter them as arguments while wd_7000 is detected. If someone has IRQ,
111 * DMA or I/O base address set to some other value, he can enter them in
112 * configuration without any problem. Also I wrote a function wd7000_setup,
113 * so now you can enter WD-7000 definition as kernel arguments,
114 * as in lilo.conf:
116 * append="wd7000=IRQ,DMA,IO"
118 * PS: If card BIOS ROM is disabled, function wd7000_detect now will recognize
119 * adapter, unlike the old one. Anyway, BIOS ROM from WD7000 adapter is
120 * useless for Linux. B^)
123 * 09/06/1996.
125 * Autodetecting of I/O base address from wd7000_detect function is removed,
126 * some little bugs removed, etc...
128 * Thanks to Roger Scott for driver debugging.
130 * 06/07/1997
132 * Added support for /proc file system (/proc/scsi/wd7000/[0...] files).
133 * Now, driver can handle hard disks with capacity >1GB.
135 * 01/15/1998
137 * Added support for BUS_ON and BUS_OFF parameters in config line.
138 * Miscellaneous cleanup.
140 * 03/01/1998
142 * WD7000 driver now work on kernels >= 2.1.x
145 #ifdef MODULE
146 #include <linux/module.h>
147 #endif
149 #include <stdarg.h>
150 #include <linux/kernel.h>
151 #include <linux/types.h>
152 #include <linux/string.h>
153 #include <linux/sched.h>
154 #include <linux/malloc.h>
155 #include <linux/spinlock.h>
156 #include <asm/system.h>
157 #include <asm/dma.h>
158 #include <asm/io.h>
159 #include <linux/ioport.h>
160 #include <linux/proc_fs.h>
161 #include <linux/blk.h>
162 #include <linux/version.h>
163 #include <linux/init.h>
164 #include "scsi.h"
165 #include "hosts.h"
166 #include "sd.h"
167 #include <scsi/scsicam.h>
169 #define ANY2SCSI_INLINE /* undef this to use old macros */
170 #undef WD7000_DEBUG /* general debug */
172 #include "wd7000.h"
173 #include <linux/stat.h>
176 * Mailbox structure sizes.
177 * I prefer to keep the number of ICMBs much larger than the number of
178 * OGMBs. OGMBs are used very quickly by the driver to start one or
179 * more commands, while ICMBs are used by the host adapter per command.
181 #define OGMB_CNT 16
182 #define ICMB_CNT 32
185 * Scb's are shared by all active adapters. So, if they all become busy,
186 * callers may be made to wait in alloc_scbs for them to free. That can
187 * be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q. If you'd
188 * rather conserve memory, use a smaller number (> 0, of course) - things
189 * will should still work OK.
191 #define MAX_SCBS 32
194 * WD7000-specific mailbox structure
197 typedef volatile struct mailbox {
198 unchar status;
199 unchar scbptr[3]; /* SCSI-style - MSB first (big endian) */
200 } Mailbox;
203 * This structure should contain all per-adapter global data. I.e., any
204 * new global per-adapter data should put in here.
206 typedef struct adapter {
207 struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */
208 int iobase; /* This adapter's I/O base address */
209 int irq; /* This adapter's IRQ level */
210 int dma; /* This adapter's DMA channel */
211 int int_counter; /* This adapter's interrupt counter */
212 int bus_on; /* This adapter's BUS_ON time */
213 int bus_off; /* This adapter's BUS_OFF time */
214 struct { /* This adapter's mailboxes */
215 Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes */
216 Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes */
217 } mb;
218 int next_ogmb; /* to reduce contention at mailboxes */
219 unchar control; /* shadows CONTROL port value */
220 unchar rev1, rev2; /* filled in by wd7000_revision */
221 } Adapter;
224 * (linear) base address for ROM BIOS
226 static const long wd7000_biosaddr[] =
228 0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000,
229 0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000
231 #define NUM_ADDRS (sizeof(wd7000_biosaddr)/sizeof(long))
233 static const unsigned short wd7000_iobase[] =
235 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338,
236 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378,
237 0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8,
238 0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8
240 #define NUM_IOPORTS (sizeof(wd7000_iobase)/sizeof(unsigned short))
242 static const short wd7000_irq[] = { 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 };
243 #define NUM_IRQS (sizeof(wd7000_irq)/sizeof(short))
245 static const short wd7000_dma[] = { 5, 6, 7 };
246 #define NUM_DMAS (sizeof(wd7000_dma)/sizeof(short))
249 * possible irq range
251 #define IRQ_MIN 3
252 #define IRQ_MAX 15
253 #define IRQS (IRQ_MAX - IRQ_MIN + 1)
256 * The following is set up by wd7000_detect, and used thereafter by
257 * wd7000_intr_handle to map the irq level to the corresponding Adapter.
258 * Note that if SA_INTERRUPT is not used, wd7000_intr_handle must be
259 * changed to pick up the IRQ level correctly.
261 static struct Scsi_Host *wd7000_host[IRQS];
263 #define BUS_ON 64 /* x 125ns = 8000ns (BIOS default) */
264 #define BUS_OFF 15 /* x 125ns = 1875ns (BIOS default) */
267 * Standard Adapter Configurations - used by wd7000_detect
269 typedef struct {
270 short irq; /* IRQ level */
271 short dma; /* DMA channel */
272 unsigned iobase; /* I/O base address */
273 short bus_on; /* Time that WD7000 spends on the AT-bus when */
274 /* transferring data. BIOS default is 8000ns. */
275 short bus_off; /* Time that WD7000 spends OFF THE BUS after */
276 /* while it is transferring data. */
277 /* BIOS default is 1875ns */
278 } Config;
281 * Add here your configuration...
283 static Config configs[] =
285 { 15, 6, 0x350, BUS_ON, BUS_OFF }, /* defaults for single adapter */
286 { 11, 5, 0x320, BUS_ON, BUS_OFF }, /* defaults for second adapter */
287 { 7, 6, 0x350, BUS_ON, BUS_OFF }, /* My configuration (Zaga) */
288 { -1, -1, 0x0, BUS_ON, BUS_OFF } /* Empty slot */
290 #define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
293 * The following list defines strings to look for in the BIOS that identify
294 * it as the WD7000-FASST2 SST BIOS. I suspect that something should be
295 * added for the Future Domain version.
297 typedef struct signature {
298 const char *sig; /* String to look for */
299 unsigned long ofs; /* offset from BIOS base address */
300 unsigned len; /* length of string */
301 } Signature;
303 static const Signature signatures[] =
305 {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */
307 #define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
311 * I/O Port Offsets and Bit Definitions
312 * 4 addresses are used. Those not defined here are reserved.
314 #define ASC_STAT 0 /* Status, Read */
315 #define ASC_COMMAND 0 /* Command, Write */
316 #define ASC_INTR_STAT 1 /* Interrupt Status, Read */
317 #define ASC_INTR_ACK 1 /* Acknowledge, Write */
318 #define ASC_CONTROL 2 /* Control, Write */
321 * ASC Status Port
323 #define INT_IM 0x80 /* Interrupt Image Flag */
324 #define CMD_RDY 0x40 /* Command Port Ready */
325 #define CMD_REJ 0x20 /* Command Port Byte Rejected */
326 #define ASC_INIT 0x10 /* ASC Initialized Flag */
327 #define ASC_STATMASK 0xf0 /* The lower 4 Bytes are reserved */
330 * COMMAND opcodes
332 * Unfortunately, I have no idea how to properly use some of these commands,
333 * as the OEM manual does not make it clear. I have not been able to use
334 * enable/disable unsolicited interrupts or the reset commands with any
335 * discernible effect whatsoever. I think they may be related to certain
336 * ICB commands, but again, the OEM manual doesn't make that clear.
338 #define NO_OP 0 /* NO-OP toggles CMD_RDY bit in ASC_STAT */
339 #define INITIALIZATION 1 /* initialization (10 bytes) */
340 #define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */
341 #define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */
342 #define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */
343 #define SOFT_RESET 5 /* SCSI bus soft reset */
344 #define HARD_RESET_ACK 6 /* SCSI bus hard reset acknowledge */
345 #define START_OGMB 0x80 /* start command in OGMB (n) */
346 #define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */
347 /* where (n) = lower 6 bits */
349 * For INITIALIZATION:
351 typedef struct initCmd {
352 unchar op; /* command opcode (= 1) */
353 unchar ID; /* Adapter's SCSI ID */
354 unchar bus_on; /* Bus on time, x 125ns (see below) */
355 unchar bus_off; /* Bus off time, "" "" */
356 unchar rsvd; /* Reserved */
357 unchar mailboxes[3]; /* Address of Mailboxes, MSB first */
358 unchar ogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */
359 unchar icmbs; /* Number of incoming MBs, "" "" */
360 } InitCmd;
363 * Interrupt Status Port - also returns diagnostic codes at ASC reset
365 * if msb is zero, the lower bits are diagnostic status
366 * Diagnostics:
367 * 01 No diagnostic error occurred
368 * 02 RAM failure
369 * 03 FIFO R/W failed
370 * 04 SBIC register read/write failed
371 * 05 Initialization D-FF failed
372 * 06 Host IRQ D-FF failed
373 * 07 ROM checksum error
374 * Interrupt status (bitwise):
375 * 10NNNNNN outgoing mailbox NNNNNN is free
376 * 11NNNNNN incoming mailbox NNNNNN needs service
378 #define MB_INTR 0xC0 /* Mailbox Service possible/required */
379 #define IMB_INTR 0x40 /* 1 Incoming / 0 Outgoing */
380 #define MB_MASK 0x3f /* mask for mailbox number */
383 * CONTROL port bits
385 #define INT_EN 0x08 /* Interrupt Enable */
386 #define DMA_EN 0x04 /* DMA Enable */
387 #define SCSI_RES 0x02 /* SCSI Reset */
388 #define ASC_RES 0x01 /* ASC Reset */
391 * Driver data structures:
392 * - mb and scbs are required for interfacing with the host adapter.
393 * An SCB has extra fields not visible to the adapter; mb's
394 * _cannot_ do this, since the adapter assumes they are contiguous in
395 * memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
396 * to access them.
397 * - An icb is for host-only (non-SCSI) commands. ICBs are 16 bytes each;
398 * the additional bytes are used only by the driver.
399 * - For now, a pool of SCBs are kept in global storage by this driver,
400 * and are allocated and freed as needed.
402 * The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
403 * not when it has finished. Since the SCB must be around for completion,
404 * problems arise when SCBs correspond to OGMBs, which may be reallocated
405 * earlier (or delayed unnecessarily until a command completes).
406 * Mailboxes are used as transient data structures, simply for
407 * carrying SCB addresses to/from the 7000-FASST2.
409 * Note also since SCBs are not "permanently" associated with mailboxes,
410 * there is no need to keep a global list of Scsi_Cmnd pointers indexed
411 * by OGMB. Again, SCBs reference their Scsi_Cmnds directly, so mailbox
412 * indices need not be involved.
416 * WD7000-specific scatter/gather element structure
418 typedef struct sgb {
419 unchar len[3];
420 unchar ptr[3]; /* Also SCSI-style - MSB first */
421 } Sgb;
423 typedef struct scb { /* Command Control Block 5.4.1 */
424 unchar op; /* Command Control Block Operation Code */
425 unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */
426 /* Outbound data transfer, length is checked */
427 /* Inbound data transfer, length is checked */
428 /* Logical Unit Number */
429 unchar cdb[12]; /* SCSI Command Block */
430 volatile unchar status; /* SCSI Return Status */
431 volatile unchar vue; /* Vendor Unique Error Code */
432 unchar maxlen[3]; /* Maximum Data Transfer Length */
433 unchar dataptr[3]; /* SCSI Data Block Pointer */
434 unchar linkptr[3]; /* Next Command Link Pointer */
435 unchar direc; /* Transfer Direction */
436 unchar reserved2[6]; /* SCSI Command Descriptor Block */
437 /* end of hardware SCB */
438 Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */
439 Sgb sgb[WD7000_SG]; /* Scatter/gather list for this SCB */
440 Adapter *host; /* host adapter */
441 struct scb *next; /* for lists of scbs */
442 } Scb;
445 * This driver is written to allow host-only commands to be executed.
446 * These use a 16-byte block called an ICB. The format is extended by the
447 * driver to 18 bytes, to support the status returned in the ICMB and
448 * an execution phase code.
450 * There are other formats besides these; these are the ones I've tried
451 * to use. Formats for some of the defined ICB opcodes are not defined
452 * (notably, get/set unsolicited interrupt status) in my copy of the OEM
453 * manual, and others are ambiguous/hard to follow.
455 #define ICB_OP_MASK 0x80 /* distinguishes scbs from icbs */
456 #define ICB_OP_OPEN_RBUF 0x80 /* open receive buffer */
457 #define ICB_OP_RECV_CMD 0x81 /* receive command from initiator */
458 #define ICB_OP_RECV_DATA 0x82 /* receive data from initiator */
459 #define ICB_OP_RECV_SDATA 0x83 /* receive data with status from init. */
460 #define ICB_OP_SEND_DATA 0x84 /* send data with status to initiator */
461 #define ICB_OP_SEND_STAT 0x86 /* send command status to initiator */
462 /* 0x87 is reserved */
463 #define ICB_OP_READ_INIT 0x88 /* read initialization bytes */
464 #define ICB_OP_READ_ID 0x89 /* read adapter's SCSI ID */
465 #define ICB_OP_SET_UMASK 0x8A /* set unsolicited interrupt mask */
466 #define ICB_OP_GET_UMASK 0x8B /* read unsolicited interrupt mask */
467 #define ICB_OP_GET_REVISION 0x8C /* read firmware revision level */
468 #define ICB_OP_DIAGNOSTICS 0x8D /* execute diagnostics */
469 #define ICB_OP_SET_EPARMS 0x8E /* set execution parameters */
470 #define ICB_OP_GET_EPARMS 0x8F /* read execution parameters */
472 typedef struct icbRecvCmd {
473 unchar op;
474 unchar IDlun; /* Initiator SCSI ID/lun */
475 unchar len[3]; /* command buffer length */
476 unchar ptr[3]; /* command buffer address */
477 unchar rsvd[7]; /* reserved */
478 volatile unchar vue; /* vendor-unique error code */
479 volatile unchar status; /* returned (icmb) status */
480 volatile unchar phase; /* used by interrupt handler */
481 } IcbRecvCmd;
483 typedef struct icbSendStat {
484 unchar op;
485 unchar IDlun; /* Target SCSI ID/lun */
486 unchar stat; /* (outgoing) completion status byte 1 */
487 unchar rsvd[12]; /* reserved */
488 volatile unchar vue; /* vendor-unique error code */
489 volatile unchar status; /* returned (icmb) status */
490 volatile unchar phase; /* used by interrupt handler */
491 } IcbSendStat;
493 typedef struct icbRevLvl {
494 unchar op;
495 volatile unchar primary; /* primary revision level (returned) */
496 volatile unchar secondary; /* secondary revision level (returned) */
497 unchar rsvd[12]; /* reserved */
498 volatile unchar vue; /* vendor-unique error code */
499 volatile unchar status; /* returned (icmb) status */
500 volatile unchar phase; /* used by interrupt handler */
501 } IcbRevLvl;
503 typedef struct icbUnsMask { /* I'm totally guessing here */
504 unchar op;
505 volatile unchar mask[14]; /* mask bits */
506 #if 0
507 unchar rsvd[12]; /* reserved */
508 #endif
509 volatile unchar vue; /* vendor-unique error code */
510 volatile unchar status; /* returned (icmb) status */
511 volatile unchar phase; /* used by interrupt handler */
512 } IcbUnsMask;
514 typedef struct icbDiag {
515 unchar op;
516 unchar type; /* diagnostics type code (0-3) */
517 unchar len[3]; /* buffer length */
518 unchar ptr[3]; /* buffer address */
519 unchar rsvd[7]; /* reserved */
520 volatile unchar vue; /* vendor-unique error code */
521 volatile unchar status; /* returned (icmb) status */
522 volatile unchar phase; /* used by interrupt handler */
523 } IcbDiag;
525 #define ICB_DIAG_POWERUP 0 /* Power-up diags only */
526 #define ICB_DIAG_WALKING 1 /* walking 1's pattern */
527 #define ICB_DIAG_DMA 2 /* DMA - system memory diags */
528 #define ICB_DIAG_FULL 3 /* do both 1 & 2 */
530 typedef struct icbParms {
531 unchar op;
532 unchar rsvd1; /* reserved */
533 unchar len[3]; /* parms buffer length */
534 unchar ptr[3]; /* parms buffer address */
535 unchar idx[2]; /* index (MSB-LSB) */
536 unchar rsvd2[5]; /* reserved */
537 volatile unchar vue; /* vendor-unique error code */
538 volatile unchar status; /* returned (icmb) status */
539 volatile unchar phase; /* used by interrupt handler */
540 } IcbParms;
542 typedef struct icbAny {
543 unchar op;
544 unchar data[14]; /* format-specific data */
545 volatile unchar vue; /* vendor-unique error code */
546 volatile unchar status; /* returned (icmb) status */
547 volatile unchar phase; /* used by interrupt handler */
548 } IcbAny;
550 typedef union icb {
551 unchar op; /* ICB opcode */
552 IcbRecvCmd recv_cmd; /* format for receive command */
553 IcbSendStat send_stat; /* format for send status */
554 IcbRevLvl rev_lvl; /* format for get revision level */
555 IcbDiag diag; /* format for execute diagnostics */
556 IcbParms eparms; /* format for get/set exec parms */
557 IcbAny icb; /* generic format */
558 unchar data[18];
559 } Icb;
561 #ifdef MODULE
562 static char * wd7000 = NULL;
563 MODULE_PARM(wd7000, "s");
564 #endif
567 * Driver SCB structure pool.
569 * The SCBs declared here are shared by all host adapters; hence, this
570 * structure is not part of the Adapter structure.
572 static Scb scbs[MAX_SCBS];
573 static Scb *scbfree = NULL; /* free list */
574 static int freescbs = MAX_SCBS; /* free list counter */
577 * END of data/declarations - code follows.
579 static void setup_error (char *mesg, int *ints)
581 if (ints[0] == 3)
582 printk ("wd7000_setup: \"wd7000=%d,%d,0x%x\" -> %s\n",
583 ints[1], ints[2], ints[3], mesg);
584 else if (ints[0] == 4)
585 printk ("wd7000_setup: \"wd7000=%d,%d,0x%x,%d\" -> %s\n",
586 ints[1], ints[2], ints[3], ints[4], mesg);
587 else
588 printk ("wd7000_setup: \"wd7000=%d,%d,0x%x,%d,%d\" -> %s\n",
589 ints[1], ints[2], ints[3], ints[4], ints[5], mesg);
594 * Note: You can now set these options from the kernel's "command line".
595 * The syntax is:
597 * wd7000=<IRQ>,<DMA>,<IO>[,<BUS_ON>[,<BUS_OFF>]]
599 * , where BUS_ON and BUS_OFF are in nanoseconds. BIOS default values
600 * are 8000ns for BUS_ON and 1875ns for BUS_OFF.
601 * eg:
602 * wd7000=7,6,0x350
604 * will configure the driver for a WD-7000 controller
605 * using IRQ 15 with a DMA channel 6, at IO base address 0x350.
607 static int __init wd7000_setup(char *str)
609 static short wd7000_card_num = 0;
610 short i, j;
611 int ints[6];
613 (void)get_options(str, ARRAY_SIZE(ints), ints);
615 if (wd7000_card_num >= NUM_CONFIGS) {
616 printk("wd7000_setup: Too many \"wd7000=\" configurations in "
617 "command line!\n");
618 return 0;
621 if ((ints[0] < 3) || (ints[0] > 5)) {
622 printk("wd7000_setup: Error in command line! "
623 "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>[,<BUS_OFF>]]\n");
624 } else {
625 for (i = 0; i < NUM_IRQS; i++)
626 if (ints[1] == wd7000_irq[i])
627 break;
629 if (i == NUM_IRQS) {
630 setup_error("invalid IRQ.", ints);
631 return 0;
632 } else
633 configs[wd7000_card_num].irq = ints[1];
635 for (i = 0; i < NUM_DMAS; i++)
636 if (ints[2] == wd7000_dma[i])
637 break;
639 if (i == NUM_DMAS) {
640 setup_error("invalid DMA channel.", ints);
641 return 0;
642 } else
643 configs[wd7000_card_num].dma = ints[2];
645 for (i = 0; i < NUM_IOPORTS; i++)
646 if (ints[3] == wd7000_iobase[i])
647 break;
649 if (i == NUM_IOPORTS) {
650 setup_error("invalid I/O base address.", ints);
651 return 0;
652 } else
653 configs[wd7000_card_num].iobase = ints[3];
655 if (ints[0] > 3) {
656 if ((ints[4] < 500) || (ints[4] > 31875)) {
657 setup_error("BUS_ON value is out of range (500 to 31875 nanoseconds)!", ints);
658 configs[wd7000_card_num].bus_on = BUS_ON;
659 } else
660 configs[wd7000_card_num].bus_on = ints[4] / 125;
661 } else
662 configs[wd7000_card_num].bus_on = BUS_ON;
664 if (ints[0] > 4) {
665 if ((ints[5] < 500) || (ints[5] > 31875)) {
666 setup_error("BUS_OFF value is out of range (500 to 31875 nanoseconds)!", ints);
667 configs[wd7000_card_num].bus_off = BUS_OFF;
668 } else
669 configs[wd7000_card_num].bus_off = ints[5] / 125;
670 } else
671 configs[wd7000_card_num].bus_off = BUS_OFF;
673 if (wd7000_card_num) {
674 for (i = 0; i < (wd7000_card_num - 1); i++)
675 for (j = i + 1; j < wd7000_card_num; j++)
676 if (configs[i].irq == configs[j].irq) {
677 setup_error("duplicated IRQ!", ints);
678 return 0;
679 } else if (configs[i].dma == configs[j].dma) {
680 setup_error("duplicated DMA channel!", ints);
681 return 0;
682 } else if (configs[i].iobase == configs[j].iobase) {
683 setup_error ("duplicated I/O base address!", ints);
684 return 0;
688 #ifdef WD7000_DEBUG
689 printk ("wd7000_setup: IRQ=%d, DMA=%d, I/O=0x%x, BUS_ON=%dns, BUS_OFF=%dns\n",
690 configs[wd7000_card_num].irq,
691 configs[wd7000_card_num].dma,
692 configs[wd7000_card_num].iobase,
693 configs[wd7000_card_num].bus_on * 125,
694 configs[wd7000_card_num].bus_off * 125);
695 #endif
697 wd7000_card_num++;
699 return 1;
702 __setup("wd7000=", wd7000_setup);
704 #ifdef ANY2SCSI_INLINE
706 * Since they're used a lot, I've redone the following from the macros
707 * formerly in wd7000.h, hopefully to speed them up by getting rid of
708 * all the shifting (it may not matter; GCC might have done as well anyway).
710 * xany2scsi and xscsi2int were not being used, and are no longer defined.
711 * (They were simply 4-byte versions of these routines).
713 typedef union { /* let's cheat... */
714 int i;
715 unchar u[sizeof (int)]; /* the sizeof(int) makes it more portable */
716 } i_u;
719 static inline void any2scsi (unchar * scsi, int any)
721 *scsi++ = ((i_u) any).u[2];
722 *scsi++ = ((i_u) any).u[1];
723 *scsi++ = ((i_u) any).u[0];
727 static inline int scsi2int (unchar * scsi)
729 i_u result;
731 result.i = 0; /* clears unused bytes */
732 result.u[2] = *scsi++;
733 result.u[1] = *scsi++;
734 result.u[0] = *scsi++;
736 return (result.i);
738 #else
740 * These are the old ones - I've just moved them here...
742 #undef any2scsi
743 #define any2scsi(up, p) (up)[0] = (((unsigned long) (p)) >> 16); \
744 (up)[1] = ((unsigned long) (p)) >> 8; \
745 (up)[2] = ((unsigned long) (p));
747 #undef scsi2int
748 #define scsi2int(up) ( (((unsigned long) *(up)) << 16) + \
749 (((unsigned long) (up)[1]) << 8) + \
750 ((unsigned long) (up)[2]) )
751 #endif
754 static inline void wd7000_enable_intr (Adapter *host)
756 host->control |= INT_EN;
757 outb (host->control, host->iobase + ASC_CONTROL);
761 static inline void wd7000_enable_dma (Adapter *host)
763 unsigned long flags;
764 host->control |= DMA_EN;
765 outb (host->control, host->iobase + ASC_CONTROL);
767 flags = claim_dma_lock();
768 set_dma_mode (host->dma, DMA_MODE_CASCADE);
769 enable_dma (host->dma);
770 release_dma_lock(flags);
775 #define WAITnexttimeout 200 /* 2 seconds */
777 static inline short WAIT (unsigned port, unsigned mask, unsigned allof, unsigned noneof)
779 register unsigned WAITbits;
780 register unsigned long WAITtimeout = jiffies + WAITnexttimeout;
782 while (time_before_eq(jiffies, WAITtimeout)) {
783 WAITbits = inb (port) & mask;
785 if (((WAITbits & allof) == allof) && ((WAITbits & noneof) == 0))
786 return (0);
789 return (1);
793 static inline void delay (unsigned how_long)
795 register unsigned long time = jiffies + how_long;
797 while (time_before(jiffies, time));
801 static inline int command_out (Adapter * host, unchar * cmd, int len)
803 if (!WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
804 while (len--) {
805 do {
806 outb (*cmd, host->iobase + ASC_COMMAND);
807 WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
808 } while (inb (host->iobase + ASC_STAT) & CMD_REJ);
810 cmd++;
813 return (1);
816 printk ("wd7000 command_out: WAIT failed(%d)\n", len + 1);
818 return (0);
823 * This version of alloc_scbs is in preparation for supporting multiple
824 * commands per lun and command chaining, by queueing pending commands.
825 * We will need to allocate Scbs in blocks since they will wait to be
826 * executed so there is the possibility of deadlock otherwise.
827 * Also, to keep larger requests from being starved by smaller requests,
828 * we limit access to this routine with an internal busy flag, so that
829 * the satisfiability of a request is not dependent on the size of the
830 * request.
832 static inline Scb *alloc_scbs (int needed)
834 register Scb *scb, *p;
835 register unsigned long flags;
836 register unsigned long timeout = jiffies + WAITnexttimeout;
837 register unsigned long now;
838 static int busy = 0;
839 int i;
841 if (needed <= 0)
842 return (NULL); /* sanity check */
844 save_flags (flags);
845 cli ();
846 while (busy) { /* someone else is allocating */
847 spin_unlock_irq(&io_request_lock);
848 for (now = jiffies; now == jiffies; ); /* wait a jiffy */
849 spin_lock_irq(&io_request_lock);
851 busy = 1; /* not busy now; it's our turn */
853 while (freescbs < needed) {
854 timeout = jiffies + WAITnexttimeout;
855 do {
856 spin_unlock_irq(&io_request_lock);
857 for (now = jiffies; now == jiffies; ); /* wait a jiffy */
858 spin_lock_irq(&io_request_lock);
859 } while (freescbs < needed && time_before_eq(jiffies, timeout));
861 * If we get here with enough free Scbs, we can take them.
862 * Otherwise, we timed out and didn't get enough.
864 if (freescbs < needed) {
865 busy = 0;
866 panic ("wd7000: can't get enough free SCBs.\n");
867 restore_flags (flags);
868 return (NULL);
871 scb = scbfree;
872 freescbs -= needed;
873 for (i = 0; i < needed; i++) {
874 p = scbfree;
875 scbfree = p->next;
877 p->next = NULL;
878 busy = 0; /* we're done */
880 restore_flags (flags);
882 return (scb);
886 static inline void free_scb (Scb *scb)
888 register unsigned long flags;
890 save_flags (flags);
891 cli ();
893 memset (scb, 0, sizeof (Scb));
894 scb->next = scbfree;
895 scbfree = scb;
896 freescbs++;
898 restore_flags (flags);
902 static inline void init_scbs (void)
904 int i;
905 unsigned long flags;
907 save_flags (flags);
908 cli ();
910 scbfree = &(scbs[0]);
911 memset (scbs, 0, sizeof (scbs));
912 for (i = 0; i < MAX_SCBS - 1; i++) {
913 scbs[i].next = &(scbs[i + 1]);
914 scbs[i].SCpnt = NULL;
916 scbs[MAX_SCBS - 1].next = NULL;
917 scbs[MAX_SCBS - 1].SCpnt = NULL;
919 restore_flags (flags);
923 static int mail_out (Adapter *host, Scb *scbptr)
925 * Note: this can also be used for ICBs; just cast to the parm type.
928 register int i, ogmb;
929 register unsigned long flags;
930 unchar start_ogmb;
931 Mailbox *ogmbs = host->mb.ogmb;
932 int *next_ogmb = &(host->next_ogmb);
934 #ifdef WD7000_DEBUG
935 printk ("wd7000_mail_out: 0x%06lx", (long) scbptr);
936 #endif
938 /* We first look for a free outgoing mailbox */
939 save_flags (flags);
940 cli ();
941 ogmb = *next_ogmb;
942 for (i = 0; i < OGMB_CNT; i++) {
943 if (ogmbs[ogmb].status == 0) {
944 #ifdef WD7000_DEBUG
945 printk (" using OGMB 0x%x", ogmb);
946 #endif
947 ogmbs[ogmb].status = 1;
948 any2scsi ((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
950 *next_ogmb = (ogmb + 1) % OGMB_CNT;
951 break;
953 else
954 ogmb = (++ogmb) % OGMB_CNT;
956 restore_flags (flags);
958 #ifdef WD7000_DEBUG
959 printk (", scb is 0x%06lx", (long) scbptr);
960 #endif
962 if (i >= OGMB_CNT) {
964 * Alternatively, we might issue the "interrupt on free OGMB",
965 * and sleep, but it must be ensured that it isn't the init
966 * task running. Instead, this version assumes that the caller
967 * will be persistent, and try again. Since it's the adapter
968 * that marks OGMB's free, waiting even with interrupts off
969 * should work, since they are freed very quickly in most cases.
971 #ifdef WD7000_DEBUG
972 printk (", no free OGMBs.\n");
973 #endif
974 return (0);
977 wd7000_enable_intr (host);
979 start_ogmb = START_OGMB | ogmb;
980 command_out (host, &start_ogmb, 1);
982 #ifdef WD7000_DEBUG
983 printk (", awaiting interrupt.\n");
984 #endif
986 return (1);
990 int make_code (unsigned hosterr, unsigned scsierr)
992 #ifdef WD7000_DEBUG
993 int in_error = hosterr;
994 #endif
996 switch ((hosterr >> 8) & 0xff) {
997 case 0: /* Reserved */
998 hosterr = DID_ERROR;
999 break;
1000 case 1: /* Command Complete, no errors */
1001 hosterr = DID_OK;
1002 break;
1003 case 2: /* Command complete, error logged in scb status (scsierr) */
1004 hosterr = DID_OK;
1005 break;
1006 case 4: /* Command failed to complete - timeout */
1007 hosterr = DID_TIME_OUT;
1008 break;
1009 case 5: /* Command terminated; Bus reset by external device */
1010 hosterr = DID_RESET;
1011 break;
1012 case 6: /* Unexpected Command Received w/ host as target */
1013 hosterr = DID_BAD_TARGET;
1014 break;
1015 case 80: /* Unexpected Reselection */
1016 case 81: /* Unexpected Selection */
1017 hosterr = DID_BAD_INTR;
1018 break;
1019 case 82: /* Abort Command Message */
1020 hosterr = DID_ABORT;
1021 break;
1022 case 83: /* SCSI Bus Software Reset */
1023 case 84: /* SCSI Bus Hardware Reset */
1024 hosterr = DID_RESET;
1025 break;
1026 default: /* Reserved */
1027 hosterr = DID_ERROR;
1029 #ifdef WD7000_DEBUG
1030 if (scsierr || hosterr)
1031 printk ("\nSCSI command error: SCSI 0x%02x host 0x%04x return %d\n",
1032 scsierr, in_error, hosterr);
1033 #endif
1034 return (scsierr | (hosterr << 16));
1038 static void wd7000_scsi_done (Scsi_Cmnd *SCpnt)
1040 #ifdef WD7000_DEBUG
1041 printk ("wd7000_scsi_done: 0x%06lx\n", (long) SCpnt);
1042 #endif
1044 SCpnt->SCp.phase = 0;
1048 #define wd7000_intr_ack(host) outb (0, host->iobase + ASC_INTR_ACK)
1050 void wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
1052 register int flag, icmb, errstatus, icmb_status;
1053 register int host_error, scsi_error;
1054 register Scb *scb; /* for SCSI commands */
1055 register IcbAny *icb; /* for host commands */
1056 register Scsi_Cmnd *SCpnt;
1057 Adapter *host = (Adapter *) wd7000_host[irq - IRQ_MIN]->hostdata; /* This MUST be set!!! */
1058 Mailbox *icmbs = host->mb.icmb;
1060 host->int_counter++;
1062 #ifdef WD7000_DEBUG
1063 printk ("wd7000_intr_handle: irq = %d, host = 0x%06lx\n", irq, (long) host);
1064 #endif
1066 flag = inb (host->iobase + ASC_INTR_STAT);
1068 #ifdef WD7000_DEBUG
1069 printk ("wd7000_intr_handle: intr stat = 0x%02x\n", flag);
1070 #endif
1072 if (!(inb (host->iobase + ASC_STAT) & INT_IM)) {
1073 /* NB: these are _very_ possible if IRQ 15 is being used, since
1074 * it's the "garbage collector" on the 2nd 8259 PIC. Specifically,
1075 * any interrupt signal into the 8259 which can't be identified
1076 * comes out as 7 from the 8259, which is 15 to the host. Thus, it
1077 * is a good thing the WD7000 has an interrupt status port, so we
1078 * can sort these out. Otherwise, electrical noise and other such
1079 * problems would be indistinguishable from valid interrupts...
1081 #ifdef WD7000_DEBUG
1082 printk ("wd7000_intr_handle: phantom interrupt...\n");
1083 #endif
1084 wd7000_intr_ack (host);
1085 return;
1088 if (flag & MB_INTR) {
1089 /* The interrupt is for a mailbox */
1090 if (!(flag & IMB_INTR)) {
1091 #ifdef WD7000_DEBUG
1092 printk ("wd7000_intr_handle: free outgoing mailbox\n");
1093 #endif
1095 * If sleep_on() and the "interrupt on free OGMB" command are
1096 * used in mail_out(), wake_up() should correspondingly be called
1097 * here. For now, we don't need to do anything special.
1099 wd7000_intr_ack (host);
1100 return;
1102 else {
1103 /* The interrupt is for an incoming mailbox */
1104 icmb = flag & MB_MASK;
1105 icmb_status = icmbs[icmb].status;
1106 if (icmb_status & 0x80) { /* unsolicited - result in ICMB */
1107 #ifdef WD7000_DEBUG
1108 printk ("wd7000_intr_handle: unsolicited interrupt 0x%02x\n",
1109 icmb_status);
1110 #endif
1111 wd7000_intr_ack (host);
1112 return;
1114 /* Aaaargh! (Zaga) */
1115 scb = bus_to_virt(scsi2int ((unchar *) icmbs[icmb].scbptr));
1116 icmbs[icmb].status = 0;
1117 if (!(scb->op & ICB_OP_MASK)) { /* an SCB is done */
1118 SCpnt = scb->SCpnt;
1119 if (--(SCpnt->SCp.phase) <= 0) { /* all scbs are done */
1120 host_error = scb->vue | (icmb_status << 8);
1121 scsi_error = scb->status;
1122 errstatus = make_code (host_error, scsi_error);
1123 SCpnt->result = errstatus;
1125 free_scb (scb);
1127 SCpnt->scsi_done (SCpnt);
1130 else { /* an ICB is done */
1131 icb = (IcbAny *) scb;
1132 icb->status = icmb_status;
1133 icb->phase = 0;
1135 } /* incoming mailbox */
1138 wd7000_intr_ack (host);
1140 #ifdef WD7000_DEBUG
1141 printk ("wd7000_intr_handle: return from interrupt handler\n");
1142 #endif
1145 void do_wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
1147 unsigned long flags;
1149 spin_lock_irqsave(&io_request_lock, flags);
1150 wd7000_intr_handle(irq, dev_id, regs);
1151 spin_unlock_irqrestore(&io_request_lock, flags);
1155 int wd7000_queuecommand (Scsi_Cmnd *SCpnt, void (*done) (Scsi_Cmnd *))
1157 register Scb *scb;
1158 register Sgb *sgb;
1159 register unchar *cdb = (unchar *) SCpnt->cmnd;
1160 register unchar idlun;
1161 register short cdblen;
1162 Adapter *host = (Adapter *) SCpnt->host->hostdata;
1164 cdblen = SCpnt->cmd_len;
1165 idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
1166 SCpnt->scsi_done = done;
1167 SCpnt->SCp.phase = 1;
1168 scb = alloc_scbs (1);
1169 scb->idlun = idlun;
1170 memcpy (scb->cdb, cdb, cdblen);
1171 scb->direc = 0x40; /* Disable direction check */
1173 scb->SCpnt = SCpnt; /* so we can find stuff later */
1174 SCpnt->host_scribble = (unchar *) scb;
1175 scb->host = host;
1177 if (SCpnt->use_sg) {
1178 struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
1179 unsigned i;
1181 if (SCpnt->host->sg_tablesize == SG_NONE) {
1182 panic ("wd7000_queuecommand: scatter/gather not supported.\n");
1184 #ifdef WD7000_DEBUG
1185 printk ("Using scatter/gather with %d elements.\n", SCpnt->use_sg);
1186 #endif
1188 sgb = scb->sgb;
1189 scb->op = 1;
1190 any2scsi (scb->dataptr, (int) sgb);
1191 any2scsi (scb->maxlen, SCpnt->use_sg * sizeof (Sgb));
1193 for (i = 0; i < SCpnt->use_sg; i++) {
1194 any2scsi (sgb[i].ptr, (int) sg[i].address);
1195 any2scsi (sgb[i].len, sg[i].length);
1198 else {
1199 scb->op = 0;
1200 any2scsi (scb->dataptr, (int) SCpnt->request_buffer);
1201 any2scsi (scb->maxlen, SCpnt->request_bufflen);
1204 while (!mail_out (host, scb)); /* keep trying */
1206 return (1);
1210 int wd7000_command (Scsi_Cmnd *SCpnt)
1212 wd7000_queuecommand (SCpnt, wd7000_scsi_done);
1214 while (SCpnt->SCp.phase > 0)
1215 barrier (); /* phase counts scbs down to 0 */
1217 return (SCpnt->result);
1221 int wd7000_diagnostics (Adapter *host, int code)
1223 static IcbDiag icb = {ICB_OP_DIAGNOSTICS};
1224 static unchar buf[256];
1225 unsigned long timeout;
1227 icb.type = code;
1228 any2scsi (icb.len, sizeof (buf));
1229 any2scsi (icb.ptr, (int) &buf);
1230 icb.phase = 1;
1232 * This routine is only called at init, so there should be OGMBs
1233 * available. I'm assuming so here. If this is going to
1234 * fail, I can just let the timeout catch the failure.
1236 mail_out (host, (struct scb *) &icb);
1237 timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */
1238 while (icb.phase && time_before(jiffies, timeout))
1239 barrier (); /* wait for completion */
1241 if (icb.phase) {
1242 printk ("wd7000_diagnostics: timed out.\n");
1243 return (0);
1245 if (make_code (icb.vue | (icb.status << 8), 0)) {
1246 printk ("wd7000_diagnostics: failed (0x%02x,0x%02x)\n",
1247 icb.vue, icb.status);
1248 return (0);
1251 return (1);
1255 int wd7000_init (Adapter *host)
1257 InitCmd init_cmd =
1259 INITIALIZATION,
1261 host->bus_on,
1262 host->bus_off,
1264 { 0, 0, 0 },
1265 OGMB_CNT,
1266 ICMB_CNT
1268 int diag;
1271 * Reset the adapter - only. The SCSI bus was initialized at power-up,
1272 * and we need to do this just so we control the mailboxes, etc.
1274 outb (ASC_RES, host->iobase + ASC_CONTROL);
1275 delay (1); /* reset pulse: this is 10ms, only need 25us */
1276 outb (0, host->iobase + ASC_CONTROL);
1277 host->control = 0; /* this must always shadow ASC_CONTROL */
1279 if (WAIT (host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
1280 printk ("wd7000_init: WAIT timed out.\n");
1281 return (0); /* 0 = not ok */
1284 if ((diag = inb (host->iobase + ASC_INTR_STAT)) != 1) {
1285 printk ("wd7000_init: ");
1287 switch (diag) {
1288 case 2: printk ("RAM failure.\n");
1289 break;
1290 case 3: printk ("FIFO R/W failed\n");
1291 break;
1292 case 4: printk ("SBIC register R/W failed\n");
1293 break;
1294 case 5: printk ("Initialization D-FF failed.\n");
1295 break;
1296 case 6: printk ("Host IRQ D-FF failed.\n");
1297 break;
1298 case 7: printk ("ROM checksum error.\n");
1299 break;
1300 default: printk ("diagnostic code 0x%02Xh received.\n", diag);
1302 return (0);
1305 /* Clear mailboxes */
1306 memset (&(host->mb), 0, sizeof (host->mb));
1308 /* Execute init command */
1309 any2scsi ((unchar *) & (init_cmd.mailboxes), (int) &(host->mb));
1310 if (!command_out (host, (unchar *) &init_cmd, sizeof (init_cmd))) {
1311 printk ("wd7000_init: adapter initialization failed.\n");
1312 return (0);
1315 if (WAIT (host->iobase + ASC_STAT, ASC_STATMASK, ASC_INIT, 0)) {
1316 printk ("wd7000_init: WAIT timed out.\n");
1317 return (0);
1320 if (request_irq (host->irq, do_wd7000_intr_handle, SA_INTERRUPT, "wd7000", NULL)) {
1321 printk ("wd7000_init: can't get IRQ %d.\n", host->irq);
1322 return (0);
1324 if (request_dma (host->dma, "wd7000")) {
1325 printk ("wd7000_init: can't get DMA channel %d.\n", host->dma);
1326 free_irq (host->irq, NULL);
1327 return (0);
1329 wd7000_enable_dma (host);
1330 wd7000_enable_intr (host);
1332 if (!wd7000_diagnostics (host, ICB_DIAG_FULL)) {
1333 free_dma (host->dma);
1334 free_irq (host->irq, NULL);
1335 return (0);
1338 return (1);
1342 void wd7000_revision (Adapter *host)
1344 static IcbRevLvl icb =
1345 {ICB_OP_GET_REVISION};
1347 icb.phase = 1;
1349 * Like diagnostics, this is only done at init time, in fact, from
1350 * wd7000_detect, so there should be OGMBs available. If it fails,
1351 * the only damage will be that the revision will show up as 0.0,
1352 * which in turn means that scatter/gather will be disabled.
1354 mail_out (host, (struct scb *) &icb);
1355 while (icb.phase)
1356 barrier (); /* wait for completion */
1357 host->rev1 = icb.primary;
1358 host->rev2 = icb.secondary;
1362 #undef SPRINTF
1363 #define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
1365 int wd7000_set_info (char *buffer, int length, struct Scsi_Host *host)
1367 unsigned long flags;
1369 save_flags (flags);
1370 cli ();
1372 #ifdef WD7000_DEBUG
1373 printk ("Buffer = <%.*s>, length = %d\n", length, buffer, length);
1374 #endif
1377 * Currently this is a no-op
1379 printk ("Sorry, this function is currently out of order...\n");
1381 restore_flags (flags);
1383 return (length);
1387 int wd7000_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout)
1389 struct Scsi_Host *host = NULL;
1390 Scsi_Device *scd;
1391 Adapter *adapter;
1392 unsigned long flags;
1393 char *pos = buffer;
1394 short i;
1396 #ifdef WD7000_DEBUG
1397 Mailbox *ogmbs, *icmbs;
1398 short count;
1399 #endif
1402 * Find the specified host board.
1404 for (i = 0; i < IRQS; i++)
1405 if (wd7000_host[i] && (wd7000_host[i]->host_no == hostno)) {
1406 host = wd7000_host[i];
1408 break;
1412 * Host not found!
1414 if (! host)
1415 return (-ESRCH);
1418 * Has data been written to the file ?
1420 if (inout)
1421 return (wd7000_set_info (buffer, length, host));
1423 adapter = (Adapter *) host->hostdata;
1425 save_flags (flags);
1426 cli ();
1428 SPRINTF ("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", hostno, adapter->rev1, adapter->rev2);
1429 SPRINTF (" IO base: 0x%x\n", adapter->iobase);
1430 SPRINTF (" IRQ: %d\n", adapter->irq);
1431 SPRINTF (" DMA channel: %d\n", adapter->dma);
1432 SPRINTF (" Interrupts: %d\n", adapter->int_counter);
1433 SPRINTF (" BUS_ON time: %d nanoseconds\n", adapter->bus_on * 125);
1434 SPRINTF (" BUS_OFF time: %d nanoseconds\n", adapter->bus_off * 125);
1436 #ifdef WD7000_DEBUG
1437 ogmbs = adapter->mb.ogmb;
1438 icmbs = adapter->mb.icmb;
1440 SPRINTF ("\nControl port value: 0x%x\n", adapter->control);
1441 SPRINTF ("Incoming mailbox:\n");
1442 SPRINTF (" size: %d\n", ICMB_CNT);
1443 SPRINTF (" queued messages: ");
1445 for (i = count = 0; i < ICMB_CNT; i++)
1446 if (icmbs[i].status) {
1447 count++;
1448 SPRINTF ("0x%x ", i);
1451 SPRINTF (count ? "\n" : "none\n");
1453 SPRINTF ("Outgoing mailbox:\n");
1454 SPRINTF (" size: %d\n", OGMB_CNT);
1455 SPRINTF (" next message: 0x%x\n", adapter->next_ogmb);
1456 SPRINTF (" queued messages: ");
1458 for (i = count = 0; i < OGMB_CNT; i++)
1459 if (ogmbs[i].status) {
1460 count++;
1461 SPRINTF ("0x%x ", i);
1464 SPRINTF (count ? "\n" : "none\n");
1465 #endif
1468 * Display driver information for each device attached to the board.
1470 scd = host->host_queue;
1472 SPRINTF ("\nAttached devices: %s\n", scd ? "" : "none");
1474 for ( ; scd; scd = scd->next)
1475 if (scd->host->host_no == hostno) {
1476 SPRINTF (" [Channel: %02d, Id: %02d, Lun: %02d] ",
1477 scd->channel, scd->id, scd->lun);
1478 SPRINTF ("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ?
1479 scsi_device_types[(short) scd->type] : "Unknown device");
1481 for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++)
1482 SPRINTF ("%c", scd->vendor[i]);
1483 SPRINTF (" ");
1485 for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++)
1486 SPRINTF ("%c", scd->model[i]);
1487 SPRINTF ("\n");
1490 SPRINTF ("\n");
1492 restore_flags (flags);
1495 * Calculate start of next buffer, and return value.
1497 *start = buffer + offset;
1499 if ((pos - buffer) < offset)
1500 return (0);
1501 else if ((pos - buffer - offset) < length)
1502 return (pos - buffer - offset);
1503 else
1504 return (length);
1509 * Returns the number of adapters this driver is supporting.
1511 * The source for hosts.c says to wait to call scsi_register until 100%
1512 * sure about an adapter. We need to do it a little sooner here; we
1513 * need the storage set up by scsi_register before wd7000_init, and
1514 * changing the location of an Adapter structure is more trouble than
1515 * calling scsi_unregister.
1518 int wd7000_detect (Scsi_Host_Template *tpnt)
1520 short present = 0, biosaddr_ptr, sig_ptr, i, pass;
1521 short biosptr[NUM_CONFIGS];
1522 unsigned iobase;
1523 Adapter *host = NULL;
1524 struct Scsi_Host *sh;
1526 #ifdef WD7000_DEBUG
1527 printk ("wd7000_detect: started\n");
1528 #endif
1530 #ifdef MODULE
1531 if (wd7000)
1532 wd7000_setup(wd7000);
1533 #endif
1535 for (i = 0; i < IRQS; wd7000_host[i++] = NULL) ;
1536 for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1) ;
1538 tpnt->proc_name = "wd7000";
1539 tpnt->proc_info = &wd7000_proc_info;
1542 * Set up SCB free list, which is shared by all adapters
1544 init_scbs ();
1546 for (pass = 0; pass < NUM_CONFIGS; pass++) {
1548 * First, search for BIOS SIGNATURE...
1550 for (biosaddr_ptr = 0; biosaddr_ptr < NUM_ADDRS; biosaddr_ptr++)
1551 for (sig_ptr = 0; sig_ptr < NUM_SIGNATURES; sig_ptr++) {
1552 for (i = 0; i < pass; i++)
1553 if (biosptr[i] == biosaddr_ptr)
1554 break;
1556 if (i == pass) {
1557 void *biosaddr = ioremap (wd7000_biosaddr[biosaddr_ptr] +
1558 signatures[sig_ptr].ofs,
1559 signatures[sig_ptr].len);
1560 short bios_match=0;
1562 if(biosaddr)
1563 bios_match = memcmp ((char *) biosaddr, signatures[sig_ptr].sig,
1564 signatures[sig_ptr].len);
1566 iounmap (biosaddr);
1568 if (! bios_match)
1569 goto bios_matched;
1573 bios_matched:
1575 * BIOS SIGNATURE has been found.
1577 #ifdef WD7000_DEBUG
1578 printk ("wd7000_detect: pass %d\n", pass + 1);
1580 if (biosaddr_ptr == NUM_ADDRS)
1581 printk ("WD-7000 SST BIOS not detected...\n");
1582 else
1583 printk ("WD-7000 SST BIOS detected at 0x%lx: checking...\n",
1584 wd7000_biosaddr[biosaddr_ptr]);
1585 #endif
1587 if (configs[pass].irq < 0)
1588 continue;
1590 iobase = configs[pass].iobase;
1592 #ifdef WD7000_DEBUG
1593 printk ("wd7000_detect: check IO 0x%x region...\n", iobase);
1594 #endif
1596 if (!check_region (iobase, 4)) {
1598 #ifdef WD7000_DEBUG
1599 printk ("wd7000_detect: ASC reset (IO 0x%x) ...", iobase);
1600 #endif
1602 * ASC reset...
1604 outb (ASC_RES, iobase + ASC_CONTROL);
1605 delay (1);
1606 outb (0, iobase + ASC_CONTROL);
1608 if (WAIT (iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0))
1609 #ifdef WD7000_DEBUG
1611 printk ("failed!\n");
1612 continue;
1614 else
1615 printk ("ok!\n");
1616 #else
1617 continue;
1618 #endif
1620 if (inb (iobase + ASC_INTR_STAT) == 1) {
1622 * We register here, to get a pointer to the extra space,
1623 * which we'll use as the Adapter structure (host) for
1624 * this adapter. It is located just after the registered
1625 * Scsi_Host structure (sh), and is located by the empty
1626 * array hostdata.
1628 sh = scsi_register (tpnt, sizeof (Adapter));
1629 host = (Adapter *) sh->hostdata;
1631 #ifdef WD7000_DEBUG
1632 printk ("wd7000_detect: adapter allocated at 0x%x\n", (int) host);
1633 #endif
1635 memset (host, 0, sizeof (Adapter));
1637 host->irq = configs[pass].irq;
1638 host->dma = configs[pass].dma;
1639 host->iobase = iobase;
1640 host->int_counter = 0;
1641 host->bus_on = configs[pass].bus_on;
1642 host->bus_off = configs[pass].bus_off;
1643 host->sh = wd7000_host[host->irq - IRQ_MIN] = sh;
1645 #ifdef WD7000_DEBUG
1646 printk ("wd7000_detect: Trying init WD-7000 card at IO "
1647 "0x%x, IRQ %d, DMA %d...\n",
1648 host->iobase, host->irq, host->dma);
1649 #endif
1651 if (!wd7000_init (host)) { /* Initialization failed */
1652 scsi_unregister (sh);
1654 continue;
1658 * OK from here - we'll use this adapter/configuration.
1660 wd7000_revision (host); /* important for scatter/gather */
1663 * Register our ports.
1665 request_region (host->iobase, 4, "wd7000");
1668 * For boards before rev 6.0, scatter/gather isn't supported.
1670 if (host->rev1 < 6)
1671 sh->sg_tablesize = SG_NONE;
1673 present++; /* count it */
1675 if (biosaddr_ptr != NUM_ADDRS)
1676 biosptr[pass] = biosaddr_ptr;
1678 printk ("Western Digital WD-7000 (rev %d.%d) ",
1679 host->rev1, host->rev2);
1680 printk ("using IO 0x%x, IRQ %d, DMA %d.\n",
1681 host->iobase, host->irq, host->dma);
1682 printk (" BUS_ON time: %dns, BUS_OFF time: %dns\n",
1683 host->bus_on * 125, host->bus_off * 125);
1687 #ifdef WD7000_DEBUG
1688 else
1689 printk ("wd7000_detect: IO 0x%x region already allocated!\n", iobase);
1690 #endif
1694 if (!present)
1695 printk ("Failed initialization of WD-7000 SCSI card!\n");
1697 return (present);
1702 * I have absolutely NO idea how to do an abort with the WD7000...
1704 int wd7000_abort (Scsi_Cmnd *SCpnt)
1706 Adapter *host = (Adapter *) SCpnt->host->hostdata;
1708 if (inb (host->iobase + ASC_STAT) & INT_IM) {
1709 printk ("wd7000_abort: lost interrupt\n");
1710 wd7000_intr_handle (host->irq, NULL, NULL);
1712 return (SCSI_ABORT_SUCCESS);
1715 return (SCSI_ABORT_SNOOZE);
1720 * I also have no idea how to do a reset...
1722 int wd7000_reset (Scsi_Cmnd *SCpnt, unsigned int unused)
1724 return (SCSI_RESET_PUNT);
1729 * This was borrowed directly from aha1542.c. (Zaga)
1731 int wd7000_biosparam (Disk *disk, kdev_t dev, int *ip)
1733 #ifdef WD7000_DEBUG
1734 printk ("wd7000_biosparam: dev=%s, size=%d, ", kdevname (dev), disk->capacity);
1735 #endif
1738 * try default translation
1740 ip[0] = 64;
1741 ip[1] = 32;
1742 ip[2] = disk->capacity / (64 * 32);
1745 * for disks >1GB do some guessing
1747 if (ip[2] >= 1024) {
1748 int info[3];
1751 * try to figure out the geometry from the partition table
1753 if ((scsicam_bios_param (disk, dev, info) < 0) ||
1754 !(((info[0] == 64) && (info[1] == 32)) ||
1755 ((info[0] == 255) && (info[1] == 63)))) {
1756 printk ("wd7000_biosparam: unable to verify geometry for disk with >1GB.\n"
1757 " using extended translation.\n");
1759 ip[0] = 255;
1760 ip[1] = 63;
1761 ip[2] = disk->capacity / (255 * 63);
1763 else {
1764 ip[0] = info[0];
1765 ip[1] = info[1];
1766 ip[2] = info[2];
1768 if (info[0] == 255)
1769 printk ("wd7000_biosparam: current partition table is using extended translation.\n");
1773 #ifdef WD7000_DEBUG
1774 printk ("bios geometry: head=%d, sec=%d, cyl=%d\n", ip[0], ip[1], ip[2]);
1775 printk ("WARNING: check, if the bios geometry is correct.\n");
1776 #endif
1778 return (0);
1781 #ifdef MODULE
1782 /* Eventually this will go into an include file, but this will be later */
1783 Scsi_Host_Template driver_template = WD7000;
1785 #include "scsi_module.c"
1786 #endif