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