1 /* $Id: $
2 * linux/drivers/scsi/wd7000.c
3 *
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 :-) )
7 *
8 * Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
9 * accommodate Eric Youngdale's modifications to scsi.c. Nov 1992.
10 *
11 * Additional changes to support scatter/gather. Dec. 1992. tw/jb
12 *
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
18 *
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:
25 *
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
36 *
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.
42 *
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.
54 *
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...
58 *
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):
64 *
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.
70 *
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.
80 *
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.
88 *
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.
93 *
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.
101 */
102
103 #include <stdarg.h>
104 #include <linux/kernel.h>
105 #include <linux/head.h>
106 #include <linux/types.h>
107 #include <linux/string.h>
108 #include <linux/sched.h>
109 #include <linux/malloc.h>
110 #include <asm/system.h>
111 #include <asm/dma.h>
112 #include <asm/io.h>
113 #include <linux/ioport.h>
114
115 #include "../block/blk.h"
116 #include "scsi.h"
117 #include "hosts.h"
118 #include "sd.h"
119
120 #define ANY2SCSI_INLINE /* undef this to use old macros */
121 #undef DEBUG
122
123 #include "wd7000.h"
124
125
126 /*
127 * Mailbox structure sizes.
128 * I prefer to keep the number of ICMBs much larger than the number of
129 * OGMBs. OGMBs are used very quickly by the driver to start one or
130 * more commands, while ICMBs are used by the host adapter per command.
131 */
132 #define OGMB_CNT 16
133 #define ICMB_CNT 32
134
135 /*
136 * Scb's are shared by all active adapters. So, if they all become busy,
137 * callers may be made to wait in alloc_scbs for them to free. That can
138 * be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q. If you'd
139 * rather conserve memory, use a smaller number (> 0, of course) - things
140 * will should still work OK.
141 */
142 #define MAX_SCBS 32
143
144 /*
145 * WD7000-specific mailbox structure
146 *
147 */
148 typedef volatile struct mailbox{
149 unchar status;
150 unchar scbptr[3]; /* SCSI-style - MSB first (big endian) */
151 } Mailbox;
152
153 /*
154 * This structure should contain all per-adapter global data. I.e., any
155 * new global per-adapter data should put in here.
156 *
157 */
158 typedef struct adapter {
159 struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */
160 int iobase; /* This adapter's I/O base address */
161 int irq; /* This adapter's IRQ level */
162 int dma; /* This adapter's DMA channel */
163 struct { /* This adapter's mailboxes */
164 Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes */
165 Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes */
166 } mb;
167 int next_ogmb; /* to reduce contention at mailboxes */
168 unchar control; /* shadows CONTROL port value */
169 unchar rev1, rev2; /* filled in by wd7000_revision */
170 } Adapter;
171
172 /*
173 * The following is set up by wd7000_detect, and used thereafter by
174 * wd7000_intr_handle to map the irq level to the corresponding Adapter.
175 * Note that if SA_INTERRUPT is not used, wd7000_intr_handle must be
176 * changed to pick up the IRQ level correctly.
177 */
178 Adapter *irq2host[16] = {NULL}; /* Possible IRQs are 0-15 */
179
180 /*
181 * Standard Adapter Configurations - used by wd7000_detect
182 */
183 typedef struct {
184 const void *bios; /* (linear) base address for ROM BIOS */
185 int iobase; /* I/O ports base address */
186 int irq; /* IRQ level */
187 int dma; /* DMA channel */
188 } Config;
189
190 static const Config configs[] = {
191 {(void *) 0xce000, 0x350, 15, 6}, /* defaults for single adapter */
192 {(void *) 0xc8000, 0x330, 11, 5}, /* defaults for second adapter */
193 {(void *) 0xd8000, 0x350, 15, 6}, /* Arghhh.... who added this ? */
194 };
195 #define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
196
197 /*
198 * The following list defines strings to look for in the BIOS that identify
199 * it as the WD7000-FASST2 SST BIOS. I suspect that something should be
200 * added for the Future Domain version.
201 */
202 typedef struct signature {
203 void *sig; /* String to look for */
204 unsigned ofs; /* offset from BIOS base address */
205 unsigned len; /* length of string */
206 } Signature;
207
208 static const Signature signatures[] = {
209 {"SSTBIOS",0x0000d,7} /* "SSTBIOS" @ offset 0x0000d */
210 };
211 #define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
212
213
214 /*
215 * I/O Port Offsets and Bit Definitions
216 * 4 addresses are used. Those not defined here are reserved.
217 */
218 #define ASC_STAT 0 /* Status, Read */
219 #define ASC_COMMAND 0 /* Command, Write */
220 #define ASC_INTR_STAT 1 /* Interrupt Status, Read */
221 #define ASC_INTR_ACK 1 /* Acknowledge, Write */
222 #define ASC_CONTROL 2 /* Control, Write */
223
224 /* ASC Status Port
225 */
226 #define INT_IM 0x80 /* Interrupt Image Flag */
227 #define CMD_RDY 0x40 /* Command Port Ready */
228 #define CMD_REJ 0x20 /* Command Port Byte Rejected */
229 #define ASC_INIT 0x10 /* ASC Initialized Flag */
230 #define ASC_STATMASK 0xf0 /* The lower 4 Bytes are reserved */
231
232 /* COMMAND opcodes
233 *
234 * Unfortunately, I have no idea how to properly use some of these commands,
235 * as the OEM manual does not make it clear. I have not been able to use
236 * enable/disable unsolicited interrupts or the reset commands with any
237 * discernible effect whatsoever. I think they may be related to certain
238 * ICB commands, but again, the OEM manual doesn't make that clear.
239 */
240 #define NO_OP 0 /* NO-OP toggles CMD_RDY bit in ASC_STAT */
241 #define INITIALIZATION 1 /* initialization (10 bytes) */
242 #define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */
243 #define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */
244 #define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */
245 #define SOFT_RESET 5 /* SCSI bus soft reset */
246 #define HARD_RESET_ACK 6 /* SCSI bus hard reset acknowledge */
247 #define START_OGMB 0x80 /* start command in OGMB (n) */
248 #define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */
249 /* where (n) = lower 6 bits */
250 /* For INITIALIZATION:
251 */
252 typedef struct initCmd {
253 unchar op; /* command opcode (= 1) */
254 unchar ID; /* Adapter's SCSI ID */
255 unchar bus_on; /* Bus on time, x 125ns (see below) */
256 unchar bus_off; /* Bus off time, "" "" */
257 unchar rsvd; /* Reserved */
258 unchar mailboxes[3]; /* Address of Mailboxes, MSB first */
259 unchar ogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */
260 unchar icmbs; /* Number of incoming MBs, "" "" */
261 } InitCmd;
262
263 #define BUS_ON 64 /* x 125ns = 8000ns (BIOS default) */
264 #define BUS_OFF 15 /* x 125ns = 1875ns (BIOS default) */
265
266 /* Interrupt Status Port - also returns diagnostic codes at ASC reset
267 *
268 * if msb is zero, the lower bits are diagnostic status
269 * Diagnostics:
270 * 01 No diagnostic error occurred
271 * 02 RAM failure
272 * 03 FIFO R/W failed
273 * 04 SBIC register read/write failed
274 * 05 Initialization D-FF failed
275 * 06 Host IRQ D-FF failed
276 * 07 ROM checksum error
277 * Interrupt status (bitwise):
278 * 10NNNNNN outgoing mailbox NNNNNN is free
279 * 11NNNNNN incoming mailbox NNNNNN needs service
280 */
281 #define MB_INTR 0xC0 /* Mailbox Service possible/required */
282 #define IMB_INTR 0x40 /* 1 Incoming / 0 Outgoing */
283 #define MB_MASK 0x3f /* mask for mailbox number */
284
285 /* CONTROL port bits
286 */
287 #define INT_EN 0x08 /* Interrupt Enable */
288 #define DMA_EN 0x04 /* DMA Enable */
289 #define SCSI_RES 0x02 /* SCSI Reset */
290 #define ASC_RES 0x01 /* ASC Reset */
291
292 /*
293 Driver data structures:
294 - mb and scbs are required for interfacing with the host adapter.
295 An SCB has extra fields not visible to the adapter; mb's
296 _cannot_ do this, since the adapter assumes they are contiguous in
297 memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
298 to access them.
299 - An icb is for host-only (non-SCSI) commands. ICBs are 16 bytes each;
300 the additional bytes are used only by the driver.
301 - For now, a pool of SCBs are kept in global storage by this driver,
302 and are allocated and freed as needed.
303
304 The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
305 not when it has finished. Since the SCB must be around for completion,
306 problems arise when SCBs correspond to OGMBs, which may be reallocated
307 earlier (or delayed unnecessarily until a command completes).
308 Mailboxes are used as transient data structures, simply for
309 carrying SCB addresses to/from the 7000-FASST2.
310
311 Note also since SCBs are not "permanently" associated with mailboxes,
312 there is no need to keep a global list of Scsi_Cmnd pointers indexed
313 by OGMB. Again, SCBs reference their Scsi_Cmnds directly, so mailbox
314 indices need not be involved.
315 */
316
317 /*
318 * WD7000-specific scatter/gather element structure
319 */
320 typedef struct sgb {
321 unchar len[3];
322 unchar ptr[3]; /* Also SCSI-style - MSB first */
323 } Sgb;
324
325 typedef struct scb { /* Command Control Block 5.4.1 */
326 unchar op; /* Command Control Block Operation Code */
327 unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */
328 /* Outbound data transfer, length is checked*/
329 /* Inbound data transfer, length is checked */
330 /* Logical Unit Number */
331 unchar cdb[12]; /* SCSI Command Block */
332 volatile unchar status; /* SCSI Return Status */
333 volatile unchar vue; /* Vendor Unique Error Code */
334 unchar maxlen[3]; /* Maximum Data Transfer Length */
335 unchar dataptr[3]; /* SCSI Data Block Pointer */
336 unchar linkptr[3]; /* Next Command Link Pointer */
337 unchar direc; /* Transfer Direction */
338 unchar reserved2[6]; /* SCSI Command Descriptor Block */
339 /* end of hardware SCB */
340 Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */
341 Sgb sgb[WD7000_SG]; /* Scatter/gather list for this SCB */
342 Adapter *host; /* host adapter */
343 struct scb *next; /* for lists of scbs */
344 } Scb;
345
346 /*
347 * This driver is written to allow host-only commands to be executed.
348 * These use a 16-byte block called an ICB. The format is extended by the
349 * driver to 18 bytes, to support the status returned in the ICMB and
350 * an execution phase code.
351 *
352 * There are other formats besides these; these are the ones I've tried
353 * to use. Formats for some of the defined ICB opcodes are not defined
354 * (notably, get/set unsolicited interrupt status) in my copy of the OEM
355 * manual, and others are ambiguous/hard to follow.
356 */
357 #define ICB_OP_MASK 0x80 /* distinguishes scbs from icbs */
358 #define ICB_OP_OPEN_RBUF 0x80 /* open receive buffer */
359 #define ICB_OP_RECV_CMD 0x81 /* receive command from initiator */
360 #define ICB_OP_RECV_DATA 0x82 /* receive data from initiator */
361 #define ICB_OP_RECV_SDATA 0x83 /* receive data with status from init. */
362 #define ICB_OP_SEND_DATA 0x84 /* send data with status to initiator */
363 #define ICB_OP_SEND_STAT 0x86 /* send command status to initiator */
364 /* 0x87 is reserved */
365 #define ICB_OP_READ_INIT 0x88 /* read initialization bytes */
366 #define ICB_OP_READ_ID 0x89 /* read adapter's SCSI ID */
367 #define ICB_OP_SET_UMASK 0x8A /* set unsolicited interrupt mask */
368 #define ICB_OP_GET_UMASK 0x8B /* read unsolicited interrupt mask */
369 #define ICB_OP_GET_REVISION 0x8C /* read firmware revision level */
370 #define ICB_OP_DIAGNOSTICS 0x8D /* execute diagnostics */
371 #define ICB_OP_SET_EPARMS 0x8E /* set execution parameters */
372 #define ICB_OP_GET_EPARMS 0x8F /* read execution parameters */
373
374 typedef struct icbRecvCmd {
375 unchar op;
376 unchar IDlun; /* Initiator SCSI ID/lun */
377 unchar len[3]; /* command buffer length */
378 unchar ptr[3]; /* command buffer address */
379 unchar rsvd[7]; /* reserved */
380 volatile unchar vue; /* vendor-unique error code */
381 volatile unchar status; /* returned (icmb) status */
382 volatile unchar phase; /* used by interrupt handler */
383 } IcbRecvCmd;
384
385 typedef struct icbSendStat {
386 unchar op;
387 unchar IDlun; /* Target SCSI ID/lun */
388 unchar stat; /* (outgoing) completion status byte 1 */
389 unchar rsvd[12]; /* reserved */
390 volatile unchar vue; /* vendor-unique error code */
391 volatile unchar status; /* returned (icmb) status */
392 volatile unchar phase; /* used by interrupt handler */
393 } IcbSendStat;
394
395 typedef struct icbRevLvl {
396 unchar op;
397 volatile unchar primary; /* primary revision level (returned) */
398 volatile unchar secondary; /* secondary revision level (returned) */
399 unchar rsvd[12]; /* reserved */
400 volatile unchar vue; /* vendor-unique error code */
401 volatile unchar status; /* returned (icmb) status */
402 volatile unchar phase; /* used by interrupt handler */
403 } IcbRevLvl;
404
405 typedef struct icbUnsMask { /* I'm totally guessing here */
406 unchar op;
407 volatile unchar mask[14]; /* mask bits */
408 #ifdef 0
409 unchar rsvd[12]; /* reserved */
410 #endif
411 volatile unchar vue; /* vendor-unique error code */
412 volatile unchar status; /* returned (icmb) status */
413 volatile unchar phase; /* used by interrupt handler */
414 } IcbUnsMask;
415
416 typedef struct icbDiag {
417 unchar op;
418 unchar type; /* diagnostics type code (0-3) */
419 unchar len[3]; /* buffer length */
420 unchar ptr[3]; /* buffer address */
421 unchar rsvd[7]; /* reserved */
422 volatile unchar vue; /* vendor-unique error code */
423 volatile unchar status; /* returned (icmb) status */
424 volatile unchar phase; /* used by interrupt handler */
425 } IcbDiag;
426
427 #define ICB_DIAG_POWERUP 0 /* Power-up diags only */
428 #define ICB_DIAG_WALKING 1 /* walking 1's pattern */
429 #define ICB_DIAG_DMA 2 /* DMA - system memory diags */
430 #define ICB_DIAG_FULL 3 /* do both 1 & 2 */
431
432 typedef struct icbParms {
433 unchar op;
434 unchar rsvd1; /* reserved */
435 unchar len[3]; /* parms buffer length */
436 unchar ptr[3]; /* parms buffer address */
437 unchar idx[2]; /* index (MSB-LSB) */
438 unchar rsvd2[5]; /* reserved */
439 volatile unchar vue; /* vendor-unique error code */
440 volatile unchar status; /* returned (icmb) status */
441 volatile unchar phase; /* used by interrupt handler */
442 } IcbParms;
443
444 typedef struct icbAny {
445 unchar op;
446 unchar data[14]; /* format-specific data */
447 volatile unchar vue; /* vendor-unique error code */
448 volatile unchar status; /* returned (icmb) status */
449 volatile unchar phase; /* used by interrupt handler */
450 } IcbAny;
451
452 typedef union icb {
453 unchar op; /* ICB opcode */
454 IcbRecvCmd recv_cmd; /* format for receive command */
455 IcbSendStat send_stat; /* format for send status */
456 IcbRevLvl rev_lvl; /* format for get revision level */
457 IcbDiag diag; /* format for execute diagnostics */
458 IcbParms eparms; /* format for get/set exec parms */
459 IcbAny icb; /* generic format */
460 unchar data[18];
461 } Icb;
462
463
464 /*
465 * Driver SCB structure pool.
466 *
467 * The SCBs declared here are shared by all host adapters; hence, this
468 * structure is not part of the Adapter structure.
469 */
470 static Scb scbs[MAX_SCBS];
471 static Scb *scbfree = NULL; /* free list */
472 static int freescbs = MAX_SCBS; /* free list counter */
473
474 /*
475 * END of data/declarations - code follows.
476 */
477
478
479 #ifdef ANY2SCSI_INLINE
480 /*
481 Since they're used a lot, I've redone the following from the macros
482 formerly in wd7000.h, hopefully to speed them up by getting rid of
483 all the shifting (it may not matter; GCC might have done as well anyway).
484
485 xany2scsi and xscsi2int were not being used, and are no longer defined.
486 (They were simply 4-byte versions of these routines).
487 */
488
489 typedef union { /* let's cheat... */
490 int i;
491 unchar u[sizeof(int)]; /* the sizeof(int) makes it more portable */
492 } i_u;
493
494
495 static inline void any2scsi( unchar *scsi, int any )
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
496 {
497 *scsi++ = ((i_u) any).u[2];
498 *scsi++ = ((i_u) any).u[1];
499 *scsi++ = ((i_u) any).u[0];
500 }
501
502
503 static inline int scsi2int( unchar *scsi )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
504 {
505 i_u result;
506
507 result.i = 0; /* clears unused bytes */
508 *(result.u+2) = *scsi++;
509 *(result.u+1) = *scsi++;
510 *(result.u) = *scsi++;
511 return result.i;
512 }
513 #else
514 /*
515 These are the old ones - I've just moved them here...
516 */
517 #undef any2scsi
518 #define any2scsi(up, p) \
519 (up)[0] = (((unsigned long)(p)) >> 16); \
520 (up)[1] = ((unsigned long)(p)) >> 8; \
521 (up)[2] = ((unsigned long)(p));
522
523 #undef scsi2int
524 #define scsi2int(up) ( (((unsigned long)*(up)) << 16) + \
525 (((unsigned long)(up)[1]) << 8) + ((unsigned long)(up)[2]) )
526 #endif
527
528
529 static inline void wd7000_enable_intr(Adapter *host)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
530 {
531 host->control |= INT_EN;
532 outb(host->control, host->iobase+ASC_CONTROL);
533 }
534
535
536 static inline void wd7000_enable_dma(Adapter *host)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
537 {
538 host->control |= DMA_EN;
539 outb(host->control,host->iobase+ASC_CONTROL);
540 set_dma_mode(host->dma, DMA_MODE_CASCADE);
541 enable_dma(host->dma);
542 }
543
544
545 #define WAITnexttimeout 200 /* 2 seconds */
546
547 #define WAIT(port, mask, allof, noneof) \
548 { register volatile unsigned WAITbits; \
549 register unsigned long WAITtimeout = jiffies + WAITnexttimeout; \
550 while (1) { \
551 WAITbits = inb(port) & (mask); \
552 if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
553 break; \
554 if (jiffies > WAITtimeout) goto fail; \
555 } \
556 }
557
558
559 static inline void delay( unsigned how_long )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
560 {
561 register unsigned long time = jiffies + how_long;
562
563 while (jiffies < time);
564 }
565
566
567 static inline int command_out(Adapter *host, unchar *cmd, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
568 {
569 WAIT(host->iobase+ASC_STAT,ASC_STATMASK,CMD_RDY,0);
570 while (len--) {
571 do {
572 outb(*cmd, host->iobase+ASC_COMMAND);
573 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
574 } while (inb(host->iobase+ASC_STAT) & CMD_REJ);
575 cmd++;
576 }
577 return 1;
578
579 fail:
580 printk("wd7000 command_out: WAIT failed(%d)\n", len+1);
581 return 0;
582 }
583
584
585 /*
586 * This version of alloc_scbs is in preparation for supporting multiple
587 * commands per lun and command chaining, by queueing pending commands.
588 * We will need to allocate Scbs in blocks since they will wait to be
589 * executed so there is the possibility of deadlock otherwise.
590 * Also, to keep larger requests from being starved by smaller requests,
591 * we limit access to this routine with an internal busy flag, so that
592 * the satisfiability of a request is not dependent on the size of the
593 * request.
594 */
595 static inline Scb *alloc_scbs(int needed)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
596 {
597 register Scb *scb, *p;
598 register unsigned long flags;
599 register unsigned long timeout = jiffies + WAITnexttimeout;
600 register unsigned long now;
601 static int busy = 0;
602 int i;
603
604 if (needed <= 0) return NULL; /* sanity check */
605
606 save_flags(flags);
607 cli();
608 while (busy) { /* someone else is allocating */
609 sti(); /* Yes this is really needed here */
610 now = jiffies; while (jiffies == now) /* wait a jiffy */;
611 cli();
612 }
613 busy = 1; /* not busy now; it's our turn */
614
615 while (freescbs < needed) {
616 timeout = jiffies + WAITnexttimeout;
617 do {
618 sti(); /* Yes this is really needed here */
619 now = jiffies; while (jiffies == now) /* wait a jiffy */;
620 cli();
621 } while (freescbs < needed && jiffies <= timeout);
622 /*
623 * If we get here with enough free Scbs, we can take them.
624 * Otherwise, we timed out and didn't get enough.
625 */
626 if (freescbs < needed) {
627 busy = 0;
628 panic("wd7000: can't get enough free SCBs.\n");
629 restore_flags(flags);
630 return NULL;
631 }
632 }
633 scb = scbfree; freescbs -= needed;
634 for (i = 0; i < needed; i++) { p = scbfree; scbfree = p->next; }
635 p->next = NULL;
636
637 busy = 0; /* we're done */
638
639 restore_flags(flags);
640
641 return scb;
642 }
643
644
645 static inline void free_scb( Scb *scb )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
646 {
647 register unsigned long flags;
648
649 save_flags(flags);
650 cli();
651
652 memset(scb, 0, sizeof(Scb));
653 scb->next = scbfree; scbfree = scb;
654 freescbs++;
655
656 restore_flags(flags);
657 }
658
659
660 static inline void init_scbs(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
661 {
662 int i;
663 unsigned long flags;
664
665 save_flags(flags);
666 cli();
667
668 scbfree = &(scbs[0]);
669 memset(scbs, 0, sizeof(scbs));
670 for (i = 0; i < MAX_SCBS-1; i++) {
671 scbs[i].next = &(scbs[i+1]); scbs[i].SCpnt = NULL;
672 }
673 scbs[MAX_SCBS-1].next = NULL;
674 scbs[MAX_SCBS-1].SCpnt = NULL;
675
676 restore_flags(flags);
677 }
678
679
680 static int mail_out( Adapter *host, Scb *scbptr )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
681 /*
682 * Note: this can also be used for ICBs; just cast to the parm type.
683 */
684 {
685 register int i, ogmb;
686 register unsigned long flags;
687 unchar start_ogmb;
688 Mailbox *ogmbs = host->mb.ogmb;
689 int *next_ogmb = &(host->next_ogmb);
690 #ifdef DEBUG
691 printk("wd7000 mail_out: %06x",(unsigned int) scbptr);
692 #endif
693 /* We first look for a free outgoing mailbox */
694 save_flags(flags);
695 cli();
696 ogmb = *next_ogmb;
697 for (i = 0; i < OGMB_CNT; i++) {
698 if (ogmbs[ogmb].status == 0) {
699 #ifdef DEBUG
700 printk(" using OGMB %x",ogmb);
701 #endif
702 ogmbs[ogmb].status = 1;
703 any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
704
705 *next_ogmb = (ogmb+1) % OGMB_CNT;
706 break;
707 } else
708 ogmb = (++ogmb) % OGMB_CNT;
709 }
710 restore_flags(flags);
711 #ifdef DEBUG
712 printk(", scb is %x",(unsigned int) scbptr);
713 #endif
714 if (i >= OGMB_CNT) {
715 /*
716 * Alternatively, we might issue the "interrupt on free OGMB",
717 * and sleep, but it must be ensured that it isn't the init
718 * task running. Instead, this version assumes that the caller
719 * will be persistent, and try again. Since it's the adapter
720 * that marks OGMB's free, waiting even with interrupts off
721 * should work, since they are freed very quickly in most cases.
722 */
723 #ifdef DEBUG
724 printk(", no free OGMBs.\n");
725 #endif
726 return 0;
727 }
728
729 wd7000_enable_intr(host);
730
731 start_ogmb = START_OGMB | ogmb;
732 command_out( host, &start_ogmb, 1 );
733 #ifdef DEBUG
734 printk(", awaiting interrupt.\n");
735 #endif
736 return 1;
737 }
738
739
740 int make_code(unsigned hosterr, unsigned scsierr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
741 {
742 #ifdef DEBUG
743 int in_error = hosterr;
744 #endif
745
746 switch ((hosterr>>8)&0xff){
747 case 0: /* Reserved */
748 hosterr = DID_ERROR;
749 break;
750 case 1: /* Command Complete, no errors */
751 hosterr = DID_OK;
752 break;
753 case 2: /* Command complete, error logged in scb status (scsierr) */
754 hosterr = DID_OK;
755 break;
756 case 4: /* Command failed to complete - timeout */
757 hosterr = DID_TIME_OUT;
758 break;
759 case 5: /* Command terminated; Bus reset by external device */
760 hosterr = DID_RESET;
761 break;
762 case 6: /* Unexpected Command Received w/ host as target */
763 hosterr = DID_BAD_TARGET;
764 break;
765 case 80: /* Unexpected Reselection */
766 case 81: /* Unexpected Selection */
767 hosterr = DID_BAD_INTR;
768 break;
769 case 82: /* Abort Command Message */
770 hosterr = DID_ABORT;
771 break;
772 case 83: /* SCSI Bus Software Reset */
773 case 84: /* SCSI Bus Hardware Reset */
774 hosterr = DID_RESET;
775 break;
776 default: /* Reserved */
777 hosterr = DID_ERROR;
778 break;
779 }
780 #ifdef DEBUG
781 if (scsierr||hosterr)
782 printk("\nSCSI command error: SCSI %02x host %04x return %d",
783 scsierr,in_error,hosterr);
784 #endif
785 return scsierr | (hosterr << 16);
786 }
787
788
789 static void wd7000_scsi_done(Scsi_Cmnd * SCpnt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
790 {
791 #ifdef DEBUG
792 printk("wd7000_scsi_done: %06x\n",(unsigned int) SCpnt);
793 #endif
794 SCpnt->SCp.phase = 0;
795 }
796
797
798 #define wd7000_intr_ack(host) outb(0,host->iobase+ASC_INTR_ACK)
799
800 void wd7000_intr_handle(int irq, struct pt_regs * regs)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
801 {
802 register int flag, icmb, errstatus, icmb_status;
803 register int host_error, scsi_error;
804 register Scb *scb; /* for SCSI commands */
805 register IcbAny *icb; /* for host commands */
806 register Scsi_Cmnd *SCpnt;
807 Adapter *host = irq2host[irq]; /* This MUST be set!!! */
808 Mailbox *icmbs = host->mb.icmb;
809
810 #ifdef DEBUG
811 printk("wd7000_intr_handle: irq = %d, host = %06x\n", irq, host);
812 #endif
813
814 flag = inb(host->iobase+ASC_INTR_STAT);
815 #ifdef DEBUG
816 printk("wd7000_intr_handle: intr stat = %02x\n",flag);
817 #endif
818
819 if (!(inb(host->iobase+ASC_STAT) & INT_IM)) {
820 /* NB: these are _very_ possible if IRQ 15 is being used, since
821 it's the "garbage collector" on the 2nd 8259 PIC. Specifically,
822 any interrupt signal into the 8259 which can't be identified
823 comes out as 7 from the 8259, which is 15 to the host. Thus, it
824 is a good thing the WD7000 has an interrupt status port, so we
825 can sort these out. Otherwise, electrical noise and other such
826 problems would be indistinguishable from valid interrupts...
827 */
828 #ifdef DEBUG
829 printk("wd7000_intr_handle: phantom interrupt...\n");
830 #endif
831 wd7000_intr_ack(host);
832 return;
833 }
834
835 if (flag & MB_INTR) {
836 /* The interrupt is for a mailbox */
837 if (!(flag & IMB_INTR)) {
838 #ifdef DEBUG
839 printk("wd7000_intr_handle: free outgoing mailbox");
840 #endif
841 /*
842 * If sleep_on() and the "interrupt on free OGMB" command are
843 * used in mail_out(), wake_up() should correspondingly be called
844 * here. For now, we don't need to do anything special.
845 */
846 wd7000_intr_ack(host);
847 return;
848 } else {
849 /* The interrupt is for an incoming mailbox */
850 icmb = flag & MB_MASK;
851 icmb_status = icmbs[icmb].status;
852 if (icmb_status & 0x80) { /* unsolicited - result in ICMB */
853 #ifdef DEBUG
854 printk("wd7000_intr_handle: unsolicited interrupt %02xh\n",
855 icmb_status);
856 #endif
857 wd7000_intr_ack(host);
858 return;
859 }
860 scb = (struct scb *) scsi2int((unchar *)icmbs[icmb].scbptr);
861 icmbs[icmb].status = 0;
862 if (!(scb->op & ICB_OP_MASK)) { /* an SCB is done */
863 SCpnt = scb->SCpnt;
864 if (--(SCpnt->SCp.phase) <= 0) { /* all scbs are done */
865 host_error = scb->vue | (icmb_status << 8);
866 scsi_error = scb->status;
867 errstatus = make_code(host_error,scsi_error);
868 SCpnt->result = errstatus;
869
870 free_scb(scb);
871
872 SCpnt->scsi_done(SCpnt);
873 }
874 } else { /* an ICB is done */
875 icb = (IcbAny *) scb;
876 icb->status = icmb_status;
877 icb->phase = 0;
878 }
879 } /* incoming mailbox */
880 }
881
882 wd7000_intr_ack(host);
883 return;
884 }
885
886
887 int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
888 {
889 register Scb *scb;
890 register Sgb *sgb;
891 register unchar *cdb = (unchar *) SCpnt->cmnd;
892 register unchar idlun;
893 register short cdblen;
894 Adapter *host = (Adapter *) SCpnt->host->hostdata;
895
896 cdblen = SCpnt->cmd_len;
897 idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
898 SCpnt->scsi_done = done;
899 SCpnt->SCp.phase = 1;
900 scb = alloc_scbs(1);
901 scb->idlun = idlun;
902 memcpy(scb->cdb, cdb, cdblen);
903 scb->direc = 0x40; /* Disable direction check */
904
905 scb->SCpnt = SCpnt; /* so we can find stuff later */
906 SCpnt->host_scribble = (unchar *) scb;
907 scb->host = host;
908
909 if (SCpnt->use_sg) {
910 struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
911 unsigned i;
912
913 if (SCpnt->host->sg_tablesize == SG_NONE) {
914 panic("wd7000_queuecommand: scatter/gather not supported.\n");
915 }
916 #ifdef DEBUG
917 printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
918 #endif
919
920 sgb = scb->sgb;
921 scb->op = 1;
922 any2scsi(scb->dataptr, (int) sgb);
923 any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
924
925 for (i = 0; i < SCpnt->use_sg; i++) {
926 any2scsi(sgb[i].ptr, (int) sg[i].address);
927 any2scsi(sgb[i].len, sg[i].length);
928 }
929 } else {
930 scb->op = 0;
931 any2scsi(scb->dataptr, (int) SCpnt->request_buffer);
932 any2scsi(scb->maxlen, SCpnt->request_bufflen);
933 }
934 while (!mail_out(host, scb)) /* keep trying */;
935
936 return 1;
937 }
938
939
940 int wd7000_command(Scsi_Cmnd *SCpnt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
941 {
942 wd7000_queuecommand(SCpnt, wd7000_scsi_done);
943
944 while (SCpnt->SCp.phase > 0); /* phase counts scbs down to 0 */
945
946 return SCpnt->result;
947 }
948
949
950 int wd7000_diagnostics( Adapter *host, int code )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
951 {
952 static IcbDiag icb = {ICB_OP_DIAGNOSTICS};
953 static unchar buf[256];
954 unsigned long timeout;
955
956 icb.type = code;
957 any2scsi(icb.len, sizeof(buf));
958 any2scsi(icb.ptr, (int) &buf);
959 icb.phase = 1;
960 /*
961 * This routine is only called at init, so there should be OGMBs
962 * available. I'm assuming so here. If this is going to
963 * fail, I can just let the timeout catch the failure.
964 */
965 mail_out(host, (struct scb *) &icb);
966 timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */
967 while (icb.phase && jiffies < timeout) /* wait for completion */;
968
969 if (icb.phase) {
970 printk("wd7000_diagnostics: timed out.\n");
971 return 0;
972 }
973 if (make_code(icb.vue|(icb.status << 8),0)) {
974 printk("wd7000_diagnostics: failed (%02x,%02x)\n",
975 icb.vue, icb.status);
976 return 0;
977 }
978
979 return 1;
980 }
981
982
983 int wd7000_init( Adapter *host )
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
984 {
985 InitCmd init_cmd = {
986 INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, 0,0,0, OGMB_CNT, ICMB_CNT
987 };
988 int diag;
989
990 /*
991 Reset the adapter - only. The SCSI bus was initialized at power-up,
992 and we need to do this just so we control the mailboxes, etc.
993 */
994 outb(ASC_RES, host->iobase+ASC_CONTROL);
995 delay(1); /* reset pulse: this is 10ms, only need 25us */
996 outb(0,host->iobase+ASC_CONTROL);
997 host->control = 0; /* this must always shadow ASC_CONTROL */
998 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
999
1000 if ((diag = inb(host->iobase+ASC_INTR_STAT)) != 1) {
1001 printk("wd7000_init: ");
1002 switch (diag) {
1003 case 2:
1004 printk("RAM failure.\n");
1005 break;
1006 case 3:
1007 printk("FIFO R/W failed\n");
1008 break;
1009 case 4:
1010 printk("SBIC register R/W failed\n");
1011 break;
1012 case 5:
1013 printk("Initialization D-FF failed.\n");
1014 break;
1015 case 6:
1016 printk("Host IRQ D-FF failed.\n");
1017 break;
1018 case 7:
1019 printk("ROM checksum error.\n");
1020 break;
1021 default:
1022 printk("diagnostic code %02Xh received.\n", diag);
1023 break;
1024 }
1025 return 0;
1026 }
1027
1028 /* Clear mailboxes */
1029 memset(&(host->mb), 0, sizeof(host->mb));
1030
1031 /* Execute init command */
1032 any2scsi((unchar *) &(init_cmd.mailboxes), (int) &(host->mb));
1033 if (!command_out(host, (unchar *) &init_cmd, sizeof(init_cmd))) {
1034 printk("wd7000_init: adapter initialization failed.\n");
1035 return 0;
1036 }
1037 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
1038
1039 if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {
1040 printk("wd7000_init: can't get IRQ %d.\n", host->irq);
1041 return 0;
1042 }
1043 if (request_dma(host->dma,"wd7000")) {
1044 printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
1045 free_irq(host->irq);
1046 return 0;
1047 }
1048 wd7000_enable_dma(host);
1049 wd7000_enable_intr(host);
1050
1051 if (!wd7000_diagnostics(host,ICB_DIAG_FULL)) {
1052 free_dma(host->dma);
1053 free_irq(host->irq);
1054 return 0;
1055 }
1056
1057 return 1;
1058
1059 fail:
1060 printk("wd7000_init: WAIT timed out.\n");
1061 return 0; /* 0 = not ok */
1062 }
1063
1064
1065 void wd7000_revision(Adapter *host)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1066 {
1067 static IcbRevLvl icb = {ICB_OP_GET_REVISION};
1068
1069 icb.phase = 1;
1070 /*
1071 * Like diagnostics, this is only done at init time, in fact, from
1072 * wd7000_detect, so there should be OGMBs available. If it fails,
1073 * the only damage will be that the revision will show up as 0.0,
1074 * which in turn means that scatter/gather will be disabled.
1075 */
1076 mail_out(host, (struct scb *) &icb);
1077 while (icb.phase) /* wait for completion */;
1078 host->rev1 = icb.primary;
1079 host->rev2 = icb.secondary;
1080 }
1081
1082
1083 int wd7000_detect(Scsi_Host_Template * tpnt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1084 /*
1085 * Returns the number of adapters this driver is supporting.
1086 *
1087 * The source for hosts.c says to wait to call scsi_register until 100%
1088 * sure about an adapter. We need to do it a little sooner here; we
1089 * need the storage set up by scsi_register before wd7000_init, and
1090 * changing the location of an Adapter structure is more trouble than
1091 * calling scsi_unregister.
1092 *
1093 */
1094 {
1095 int i,j, present = 0;
1096 const Config *cfg;
1097 const Signature *sig;
1098 Adapter *host = NULL;
1099 struct Scsi_Host *sh;
1100
1101 /* Set up SCB free list, which is shared by all adapters */
1102 init_scbs();
1103
1104 cfg = configs;
1105 for (i = 0; i < NUM_CONFIGS; i++) {
1106 sig = signatures;
1107 for (j = 0; j < NUM_SIGNATURES; j++) {
1108 if (!memcmp(cfg->bios+sig->ofs, sig->sig, sig->len)) {
1109 /* matched this one */
1110 #ifdef DEBUG
1111 printk("WD-7000 SST BIOS detected at %04X: checking...\n",
1112 (int) cfg->bios);
1113 #endif
1114 /*
1115 * We won't explicitly test the configuration (in this
1116 * version); instead, we'll just see if it works to
1117 * setup the adapter; if it does, we'll use it.
1118 */
1119 if (check_region(cfg->iobase, 4)) { /* ports in use */
1120 printk("IO %xh already in use.\n", host->iobase);
1121 continue;
1122 }
1123 /*
1124 * We register here, to get a pointer to the extra space,
1125 * which we'll use as the Adapter structure (host) for
1126 * this adapter. It is located just after the registered
1127 * Scsi_Host structure (sh), and is located by the empty
1128 * array hostdata.
1129 */
1130 sh = scsi_register(tpnt, sizeof(Adapter) );
1131 host = (Adapter *) sh->hostdata;
1132 #ifdef DEBUG
1133 printk("wd7000_detect: adapter allocated at %06x\n",
1134 (int)host);
1135 #endif
1136 memset( host, 0, sizeof(Adapter) );
1137 host->sh = sh;
1138 host->irq = cfg->irq;
1139 host->iobase = cfg->iobase;
1140 host->dma = cfg->dma;
1141 irq2host[host->irq] = host;
1142
1143 if (!wd7000_init(host)) { /* Initialization failed */
1144 scsi_unregister (sh);
1145 continue;
1146 }
1147
1148 /*
1149 * OK from here - we'll use this adapter/configuration.
1150 */
1151 wd7000_revision(host); /* important for scatter/gather */
1152
1153 printk("Western Digital WD-7000 (%d.%d) ",
1154 host->rev1, host->rev2);
1155 printk("using IO %xh IRQ %d DMA %d.\n",
1156 host->iobase, host->irq, host->dma);
1157
1158 request_region(host->iobase, 4,"wd7000"); /* Register our ports */
1159 /*
1160 * For boards before rev 6.0, scatter/gather isn't supported.
1161 */
1162 if (host->rev1 < 6) sh->sg_tablesize = SG_NONE;
1163
1164 present++; /* count it */
1165 break; /* don't try any more sigs */
1166 }
1167 sig++; /* try next signature with this configuration */
1168 }
1169 cfg++; /* try next configuration */
1170 }
1171
1172 return present;
1173 }
1174
1175
1176 /*
1177 * I have absolutely NO idea how to do an abort with the WD7000...
1178 */
1179 int wd7000_abort(Scsi_Cmnd * SCpnt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1180 {
1181 Adapter *host = (Adapter *) SCpnt->host->hostdata;
1182
1183 if (inb(host->iobase+ASC_STAT) & INT_IM) {
1184 printk("wd7000_abort: lost interrupt\n");
1185 wd7000_intr_handle(host->irq, NULL);
1186 return SCSI_ABORT_SUCCESS;
1187 }
1188
1189 return SCSI_ABORT_SNOOZE;
1190 }
1191
1192
1193 /*
1194 * I also have no idea how to do a reset...
1195 */
1196 int wd7000_reset(Scsi_Cmnd * SCpnt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1197 {
1198 return SCSI_RESET_PUNT;
1199 }
1200
1201
1202 /*
1203 * This was borrowed directly from aha1542.c, but my disks are organized
1204 * this way, so I think it will work OK. Someone who is ambitious can
1205 * borrow a newer or more complete version from another driver.
1206 */
1207 int wd7000_biosparam(Disk * disk, int dev, int* ip)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1208 {
1209 int size = disk->capacity;
1210 ip[0] = 64;
1211 ip[1] = 32;
1212 ip[2] = size >> 11;
1213 /* if (ip[2] >= 1024) ip[2] = 1024; */
1214 return 0;
1215 }