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