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 #defineANY2SCSI_INLINE/* undef this to use old macros */ 121 #undefDEBUG 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 #defineOGMB_CNT 16
133 #defineICMB_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 #defineMAX_SCBS 32
143
144 /* 145 * WD7000-specific mailbox structure 146 * 147 */ 148 typedefvolatilestructmailbox{ 149 uncharstatus;
150 uncharscbptr[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 typedefstructadapter{ 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 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 typedefstruct{ 184 constvoid *bios; /* (linear) base address for ROM BIOS */ 185 intiobase; /* I/O ports base address */ 186 intirq; /* IRQ level */ 187 intdma; /* DMA channel */ 188 }Config;
189
190 staticconstConfigconfigs[] = { 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 #defineNUM_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 typedefstructsignature{ 203 void *sig; /* String to look for */ 204 unsignedofs; /* offset from BIOS base address */ 205 unsignedlen; /* length of string */ 206 }Signature;
207
208 staticconstSignaturesignatures[] = { 209 {"SSTBIOS",0x0000d,7}/* "SSTBIOS" @ offset 0x0000d */ 210 };
211 #defineNUM_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 #defineASC_STAT 0 /* Status, Read */ 219 #defineASC_COMMAND 0 /* Command, Write */ 220 #defineASC_INTR_STAT 1 /* Interrupt Status, Read */ 221 #defineASC_INTR_ACK 1 /* Acknowledge, Write */ 222 #defineASC_CONTROL 2 /* Control, Write */ 223
224 /* ASC Status Port 225 */ 226 #defineINT_IM 0x80 /* Interrupt Image Flag */ 227 #defineCMD_RDY 0x40 /* Command Port Ready */ 228 #defineCMD_REJ 0x20 /* Command Port Byte Rejected */ 229 #defineASC_INIT 0x10 /* ASC Initialized Flag */ 230 #defineASC_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 #defineINITIALIZATION 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 #defineSTART_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 typedefstruct initCmd { 253 uncharop; /* 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 uncharrsvd; /* Reserved */ 258 uncharmailboxes[3]; /* Address of Mailboxes, MSB first */ 259 uncharogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */ 260 uncharicmbs; /* Number of incoming MBs, "" "" */ 261 }InitCmd;
262
263 #defineBUS_ON 64 /* x 125ns = 8000ns (BIOS default) */ 264 #defineBUS_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 #defineMB_INTR 0xC0 /* Mailbox Service possible/required */ 282 #defineIMB_INTR 0x40 /* 1 Incoming / 0 Outgoing */ 283 #defineMB_MASK 0x3f /* mask for mailbox number */ 284
285 /* CONTROL port bits 286 */ 287 #defineINT_EN 0x08 /* Interrupt Enable */ 288 #defineDMA_EN 0x04 /* DMA Enable */ 289 #define SCSI_RES 0x02 /* SCSI Reset */ 290 #defineASC_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 typedefstructsgb{ 321 uncharlen[3];
322 uncharptr[3]; /* Also SCSI-style - MSB first */ 323 }Sgb;
324
325 typedefstructscb{/* Command Control Block 5.4.1 */ 326 uncharop; /* Command Control Block Operation Code */ 327 uncharidlun; /* 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 uncharcdb[12]; /* SCSI Command Block */ 332 volatileuncharstatus; /* SCSI Return Status */ 333 volatileuncharvue; /* Vendor Unique Error Code */ 334 uncharmaxlen[3]; /* Maximum Data Transfer Length */ 335 unchardataptr[3]; /* SCSI Data Block Pointer */ 336 uncharlinkptr[3]; /* Next Command Link Pointer */ 337 unchardirec; /* 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 Sgbsgb[WD7000_SG]; /* Scatter/gather list for this SCB */ 342 Adapter *host; /* host adapter */ 343 structscb *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 #defineICB_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 #defineICB_OP_GET_REVISION 0x8C /* read firmware revision level */ 370 #defineICB_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 typedefstruct icbRecvCmd { 375 uncharop;
376 uncharIDlun; /* Initiator SCSI ID/lun */ 377 uncharlen[3]; /* command buffer length */ 378 uncharptr[3]; /* command buffer address */ 379 uncharrsvd[7]; /* reserved */ 380 volatileuncharvue; /* vendor-unique error code */ 381 volatileuncharstatus; /* returned (icmb) status */ 382 volatileuncharphase; /* used by interrupt handler */ 383 }IcbRecvCmd;
384
385 typedefstruct icbSendStat { 386 uncharop;
387 uncharIDlun; /* Target SCSI ID/lun */ 388 uncharstat; /* (outgoing) completion status byte 1 */ 389 uncharrsvd[12]; /* reserved */ 390 volatileuncharvue; /* vendor-unique error code */ 391 volatileuncharstatus; /* returned (icmb) status */ 392 volatileuncharphase; /* used by interrupt handler */ 393 }IcbSendStat;
394
395 typedefstruct icbRevLvl { 396 uncharop;
397 volatileuncharprimary; /* primary revision level (returned) */ 398 volatileuncharsecondary; /* secondary revision level (returned) */ 399 uncharrsvd[12]; /* reserved */ 400 volatileuncharvue; /* vendor-unique error code */ 401 volatileuncharstatus; /* returned (icmb) status */ 402 volatileuncharphase; /* used by interrupt handler */ 403 }IcbRevLvl;
404
405 typedefstruct icbUnsMask {/* I'm totally guessing here */ 406 uncharop;
407 volatileuncharmask[14]; /* mask bits */ 408 #ifdef 0
409 uncharrsvd[12]; /* reserved */ 410 #endif 411 volatileuncharvue; /* vendor-unique error code */ 412 volatileuncharstatus; /* returned (icmb) status */ 413 volatileuncharphase; /* used by interrupt handler */ 414 } IcbUnsMask;
415
416 typedefstruct icbDiag { 417 uncharop;
418 unchartype; /* diagnostics type code (0-3) */ 419 uncharlen[3]; /* buffer length */ 420 uncharptr[3]; /* buffer address */ 421 uncharrsvd[7]; /* reserved */ 422 volatileuncharvue; /* vendor-unique error code */ 423 volatileuncharstatus; /* returned (icmb) status */ 424 volatileuncharphase; /* 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 #defineICB_DIAG_FULL 3 /* do both 1 & 2 */ 431
432 typedefstruct icbParms { 433 uncharop;
434 unchar rsvd1; /* reserved */ 435 uncharlen[3]; /* parms buffer length */ 436 uncharptr[3]; /* parms buffer address */ 437 uncharidx[2]; /* index (MSB-LSB) */ 438 unchar rsvd2[5]; /* reserved */ 439 volatileuncharvue; /* vendor-unique error code */ 440 volatileuncharstatus; /* returned (icmb) status */ 441 volatileuncharphase; /* used by interrupt handler */ 442 }IcbParms;
443
444 typedefstruct icbAny { 445 uncharop;
446 unchardata[14]; /* format-specific data */ 447 volatileuncharvue; /* vendor-unique error code */ 448 volatileuncharstatus; /* returned (icmb) status */ 449 volatileuncharphase; /* used by interrupt handler */ 450 }IcbAny;
451
452 typedefunionicb{ 453 uncharop; /* 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 IcbDiagdiag; /* format for execute diagnostics */ 458 IcbParms eparms; /* format for get/set exec parms */ 459 IcbAnyicb; /* generic format */ 460 unchardata[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 staticScbscbs[MAX_SCBS];
471 staticScb *scbfree = NULL; /* free list */ 472 staticintfreescbs = MAX_SCBS; /* free list counter */ 473
474 /* 475 * END of data/declarations - code follows. 476 */ 477
478
479 #ifdefANY2SCSI_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 typedefunion{/* let's cheat... */ 490 inti;
491 uncharu[sizeof(int)]; /* the sizeof(int) makes it more portable */ 492 }i_u;
493
494
495 staticinlinevoidany2scsi( unchar *scsi, intany )
/* */ 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 staticinlineintscsi2int( unchar *scsi )
/* */ 504 { 505 i_uresult;
506
507 result.i = 0; /* clears unused bytes */ 508 *(result.u+2) = *scsi++;
509 *(result.u+1) = *scsi++;
510 *(result.u) = *scsi++;
511 returnresult.i;
512 } 513 #else 514 /* 515 These are the old ones - I've just moved them here... 516 */ 517 #undefany2scsi 518 #defineany2scsi(up, p) \
519 (up)[0] = (((unsignedlong)(p)) >> 16); \
520 (up)[1] = ((unsignedlong)(p)) >> 8; \
521 (up)[2] = ((unsignedlong)(p));
522
523 #undefscsi2int 524 #definescsi2int(up) ( (((unsignedlong)*(up)) << 16) + \
525 (((unsignedlong)(up)[1]) << 8) + ((unsignedlong)(up)[2]) )
526 #endif 527
528
529 staticinlinevoidwd7000_enable_intr(Adapter *host)
/* */ 530 { 531 host->control |= INT_EN;
532 outb(host->control, host->iobase+ASC_CONTROL);
533 } 534
535
536 staticinlinevoidwd7000_enable_dma(Adapter *host)
/* */ 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 #defineWAITnexttimeout 200 /* 2 seconds */ 546
547 #defineWAIT(port, mask, allof, noneof) \
548 {registervolatileunsignedWAITbits; \
549 registerunsignedlongWAITtimeout = jiffies + WAITnexttimeout; \
550 while (1) { \
551 WAITbits = inb(port) & (mask); \
552 if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
553 break; \
554 if (jiffies > WAITtimeout) gotofail; \
555 } \
556 } 557
558
559 staticinlinevoiddelay( unsignedhow_long )
/* */ 560 { 561 registerunsignedlongtime = jiffies + how_long;
562
563 while (jiffies < time);
564 } 565
566
567 staticinlineintcommand_out(Adapter *host, unchar *cmd, intlen)
/* */ 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 staticinlineScb *alloc_scbs(intneeded)
/* */ 596 { 597 registerScb *scb, *p;
598 registerunsignedlongflags;
599 registerunsignedlongtimeout = jiffies + WAITnexttimeout;
600 registerunsignedlongnow;
601 staticintbusy = 0;
602 inti;
603
604 if (needed <= 0) returnNULL; /* sanity check */ 605
606 save_flags(flags);
607 cli();
608 while (busy) {/* someone else is allocating */ 609 sti();
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();
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 returnNULL;
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 returnscb;
642 } 643
644
645 staticinlinevoidfree_scb( Scb *scb )
/* */ 646 { 647 registerunsignedlongflags;
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 staticinlinevoidinit_scbs(void)
/* */ 661 { 662 inti;
663 unsignedlongflags;
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 staticintmail_out( Adapter *host, Scb *scbptr )
/* */ 681 /* 682 * Note: this can also be used for ICBs; just cast to the parm type. 683 */ 684 { 685 registerinti, ogmb;
686 registerunsignedlongflags;
687 uncharstart_ogmb;
688 Mailbox *ogmbs = host->mb.ogmb;
689 int *next_ogmb = &(host->next_ogmb);
690 #ifdefDEBUG 691 printk("wd7000 mail_out: %06x",(unsignedint) 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 #ifdefDEBUG 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 #ifdefDEBUG 712 printk(", scb is %x",(unsignedint) 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 #ifdefDEBUG 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 #ifdefDEBUG 734 printk(", awaiting interrupt.\n");
735 #endif 736 return 1;
737 } 738
739
740 intmake_code(unsignedhosterr, unsignedscsierr)
/* */ 741 { 742 #ifdefDEBUG 743 intin_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 #ifdefDEBUG 781 if (scsierr||hosterr)
782 printk("\nSCSI command error: SCSI %02x host %04x return %d",
783 scsierr,in_error,hosterr);
784 #endif 785 returnscsierr | (hosterr << 16);
786 } 787
788
789 staticvoidwd7000_scsi_done(Scsi_Cmnd * SCpnt)
/* */ 790 { 791 #ifdefDEBUG 792 printk("wd7000_scsi_done: %06x\n",(unsignedint) SCpnt);
793 #endif 794 SCpnt->SCp.phase = 0;
795 } 796
797
798 #definewd7000_intr_ack(host) outb(0,host->iobase+ASC_INTR_ACK)
799
800 voidwd7000_intr_handle(intirq)
/* */ 801 { 802 #ifdef 0
803 /* 804 * Use irqp as the parm, and the following declaration, if 805 * SA_INTERRUPT is not used. 806 */ 807 registerintirq = *(((int *)irqp)-2);
808 #endif 809 registerintflag, icmb, errstatus, icmb_status;
810 registerinthost_error, scsi_error;
811 registerScb *scb; /* for SCSI commands */ 812 registerIcbAny *icb; /* for host commands */ 813 registerScsi_Cmnd *SCpnt;
814 Adapter *host = irq2host[irq]; /* This MUST be set!!! */ 815 Mailbox *icmbs = host->mb.icmb;
816
817 #ifdefDEBUG 818 printk("wd7000_intr_handle: irq = %d, host = %06x\n", irq, host);
819 #endif 820
821 flag = inb(host->iobase+ASC_INTR_STAT);
822 #ifdefDEBUG 823 printk("wd7000_intr_handle: intr stat = %02x\n",flag);
824 #endif 825
826 if (!(inb(host->iobase+ASC_STAT) & INT_IM)) { 827 /* NB: these are _very_ possible if IRQ 15 is being used, since 828 it's the "garbage collector" on the 2nd 8259 PIC. Specifically, 829 any interrupt signal into the 8259 which can't be identified 830 comes out as 7 from the 8259, which is 15 to the host. Thus, it 831 is a good thing the WD7000 has an interrupt status port, so we 832 can sort these out. Otherwise, electrical noise and other such 833 problems would be indistinguishable from valid interrupts... 834 */ 835 #ifdefDEBUG 836 printk("wd7000_intr_handle: phantom interrupt...\n");
837 #endif 838 wd7000_intr_ack(host);
839 return;
840 } 841
842 if (flag & MB_INTR) { 843 /* The interrupt is for a mailbox */ 844 if (!(flag & IMB_INTR)) { 845 #ifdefDEBUG 846 printk("wd7000_intr_handle: free outgoing mailbox");
847 #endif 848 /* 849 * If sleep_on() and the "interrupt on free OGMB" command are 850 * used in mail_out(), wake_up() should correspondingly be called 851 * here. For now, we don't need to do anything special. 852 */ 853 wd7000_intr_ack(host);
854 return;
855 }else{ 856 /* The interrupt is for an incoming mailbox */ 857 icmb = flag & MB_MASK;
858 icmb_status = icmbs[icmb].status;
859 if (icmb_status & 0x80) {/* unsolicited - result in ICMB */ 860 #ifdefDEBUG 861 printk("wd7000_intr_handle: unsolicited interrupt %02xh\n",
862 icmb_status);
863 #endif 864 wd7000_intr_ack(host);
865 return;
866 } 867 scb = (structscb *) scsi2int((unchar *)icmbs[icmb].scbptr);
868 icmbs[icmb].status = 0;
869 if (!(scb->op & ICB_OP_MASK)) {/* an SCB is done */ 870 SCpnt = scb->SCpnt;
871 if (--(SCpnt->SCp.phase) <= 0) {/* all scbs are done */ 872 host_error = scb->vue | (icmb_status << 8);
873 scsi_error = scb->status;
874 errstatus = make_code(host_error,scsi_error);
875 SCpnt->result = errstatus;
876
877 free_scb(scb);
878
879 SCpnt->scsi_done(SCpnt);
880 } 881 }else{/* an ICB is done */ 882 icb = (IcbAny *) scb;
883 icb->status = icmb_status;
884 icb->phase = 0;
885 } 886 }/* incoming mailbox */ 887 } 888
889 wd7000_intr_ack(host);
890 return;
891 } 892
893
894 intwd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */ 895 { 896 registerScb *scb;
897 registerSgb *sgb;
898 registerunchar *cdb = (unchar *) SCpnt->cmnd;
899 registeruncharidlun;
900 registershortcdblen;
901 Adapter *host = (Adapter *) SCpnt->host->hostdata;
902
903 cdblen = COMMAND_SIZE(cdb[0]);
904 idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
905 SCpnt->scsi_done = done;
906 SCpnt->SCp.phase = 1;
907 scb = alloc_scbs(1);
908 scb->idlun = idlun;
909 memcpy(scb->cdb, cdb, cdblen);
910 scb->direc = 0x40; /* Disable direction check */ 911
912 scb->SCpnt = SCpnt; /* so we can find stuff later */ 913 SCpnt->host_scribble = (unchar *) scb;
914 scb->host = host;
915
916 if (SCpnt->use_sg) { 917 structscatterlist *sg = (structscatterlist *) SCpnt->request_buffer;
918 unsignedi;
919
920 if (SCpnt->host->sg_tablesize == SG_NONE) { 921 panic("wd7000_queuecommand: scatter/gather not supported.\n");
922 } 923 #ifdefDEBUG 924 printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
925 #endif 926
927 sgb = scb->sgb;
928 scb->op = 1;
929 any2scsi(scb->dataptr, (int) sgb);
930 any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
931
932 for (i = 0; i < SCpnt->use_sg; i++) { 933 any2scsi(sgb[i].ptr, (int) sg[i].address);
934 any2scsi(sgb[i].len, sg[i].length);
935 } 936 }else{ 937 scb->op = 0;
938 any2scsi(scb->dataptr, (int) SCpnt->request_buffer);
939 any2scsi(scb->maxlen, SCpnt->request_bufflen);
940 } 941 while (!mail_out(host, scb)) /* keep trying */;
942
943 return 1;
944 } 945
946
947 intwd7000_command(Scsi_Cmnd *SCpnt)
/* */ 948 { 949 wd7000_queuecommand(SCpnt, wd7000_scsi_done);
950
951 while (SCpnt->SCp.phase > 0); /* phase counts scbs down to 0 */ 952
953 returnSCpnt->result;
954 } 955
956
957 intwd7000_diagnostics( Adapter *host, intcode )
/* */ 958 { 959 staticIcbDiagicb = {ICB_OP_DIAGNOSTICS};
960 staticuncharbuf[256];
961 unsignedlongtimeout;
962
963 icb.type = code;
964 any2scsi(icb.len, sizeof(buf));
965 any2scsi(icb.ptr, (int) &buf);
966 icb.phase = 1;
967 /* 968 * This routine is only called at init, so there should be OGMBs 969 * available. I'm assuming so here. If this is going to 970 * fail, I can just let the timeout catch the failure. 971 */ 972 mail_out(host, (structscb *) &icb);
973 timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */ 974 while (icb.phase && jiffies < timeout) /* wait for completion */;
975
976 if (icb.phase) { 977 printk("wd7000_diagnostics: timed out.\n");
978 return 0;
979 } 980 if (make_code(icb.vue|(icb.status << 8),0)) { 981 printk("wd7000_diagnostics: failed (%02x,%02x)\n",
982 icb.vue, icb.status);
983 return 0;
984 } 985
986 return 1;
987 } 988
989
990 intwd7000_init( Adapter *host )
/* */ 991 { 992 InitCmdinit_cmd = { 993 INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, 0,0,0, OGMB_CNT, ICMB_CNT 994 };
995 intdiag;
996
997 /* 998 Reset the adapter - only. The SCSI bus was initialized at power-up, 999 and we need to do this just so we control the mailboxes, etc.1000 */1001 outb(ASC_RES, host->iobase+ASC_CONTROL);
1002 delay(1); /* reset pulse: this is 10ms, only need 25us */1003 outb(0,host->iobase+ASC_CONTROL);
1004 host->control = 0; /* this must always shadow ASC_CONTROL */1005 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
1006
1007 if ((diag = inb(host->iobase+ASC_INTR_STAT)) != 1) {1008 printk("wd7000_init: ");
1009 switch (diag) {1010 case 2:
1011 printk("RAM failure.\n");
1012 break;
1013 case 3:
1014 printk("FIFO R/W failed\n");
1015 break;
1016 case 4:
1017 printk("SBIC register R/W failed\n");
1018 break;
1019 case 5:
1020 printk("Initialization D-FF failed.\n");
1021 break;
1022 case 6:
1023 printk("Host IRQ D-FF failed.\n");
1024 break;
1025 case 7:
1026 printk("ROM checksum error.\n");
1027 break;
1028 default:
1029 printk("diagnostic code %02Xh received.\n", diag);
1030 break;
1031 }1032 return 0;
1033 }1034
1035 /* Clear mailboxes */1036 memset(&(host->mb), 0, sizeof(host->mb));
1037
1038 /* Execute init command */1039 any2scsi((unchar *) &(init_cmd.mailboxes), (int) &(host->mb));
1040 if (!command_out(host, (unchar *) &init_cmd, sizeof(init_cmd))) {1041 printk("wd7000_init: adapter initialization failed.\n");
1042 return 0;
1043 }1044 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
1045
1046 if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {1047 printk("wd7000_init: can't get IRQ %d.\n", host->irq);
1048 return 0;
1049 }1050 if (request_dma(host->dma,"wd7000")) {1051 printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
1052 free_irq(host->irq);
1053 return 0;
1054 }1055 wd7000_enable_dma(host);
1056 wd7000_enable_intr(host);
1057
1058 if (!wd7000_diagnostics(host,ICB_DIAG_FULL)) {1059 free_dma(host->dma);
1060 free_irq(host->irq);
1061 return 0;
1062 }1063
1064 return 1;
1065
1066 fail:
1067 printk("wd7000_init: WAIT timed out.\n");
1068 return 0; /* 0 = not ok */1069 }1070
1071
1072 voidwd7000_revision(Adapter *host)
/* */1073 {1074 staticIcbRevLvlicb = {ICB_OP_GET_REVISION};
1075
1076 icb.phase = 1;
1077 /*1078 * Like diagnostics, this is only done at init time, in fact, from1079 * wd7000_detect, so there should be OGMBs available. If it fails,1080 * the only damage will be that the revision will show up as 0.0,1081 * which in turn means that scatter/gather will be disabled.1082 */1083 mail_out(host, (structscb *) &icb);
1084 while (icb.phase) /* wait for completion */;
1085 host->rev1 = icb.primary;
1086 host->rev2 = icb.secondary;
1087 }1088
1089
1090 intwd7000_detect(Scsi_Host_Template * tpnt)
/* */1091 /* 1092 * Returns the number of adapters this driver is supporting.1093 *1094 * The source for hosts.c says to wait to call scsi_register until 100%1095 * sure about an adapter. We need to do it a little sooner here; we1096 * need the storage set up by scsi_register before wd7000_init, and1097 * changing the location of an Adapter structure is more trouble than1098 * calling scsi_unregister.1099 *1100 */1101 {1102 inti,j, present = 0;
1103 constConfig *cfg;
1104 constSignature *sig;
1105 Adapter *host = NULL;
1106 structScsi_Host *sh;
1107
1108 /* Set up SCB free list, which is shared by all adapters */1109 init_scbs();
1110
1111 cfg = configs;
1112 for (i = 0; i < NUM_CONFIGS; i++) {1113 sig = signatures;
1114 for (j = 0; j < NUM_SIGNATURES; j++) {1115 if (!memcmp(cfg->bios+sig->ofs, sig->sig, sig->len)) {1116 /* matched this one */1117 #ifdefDEBUG1118 printk("WD-7000 SST BIOS detected at %04X: checking...\n",
1119 (int) cfg->bios);
1120 #endif1121 /*1122 * We won't explicitly test the configuration (in this1123 * version); instead, we'll just see if it works to1124 * setup the adapter; if it does, we'll use it.1125 */1126 if (check_region(cfg->iobase, 4)) {/* ports in use */1127 printk("IO %xh already in use.\n", host->iobase);
1128 continue;
1129 }1130 /*1131 * We register here, to get a pointer to the extra space,1132 * which we'll use as the Adapter structure (host) for1133 * this adapter. It is located just after the registered1134 * Scsi_Host structure (sh), and is located by the empty1135 * array hostdata.1136 */1137 sh = scsi_register(tpnt, sizeof(Adapter) );
1138 host = (Adapter *) sh->hostdata;
1139 #ifdefDEBUG1140 printk("wd7000_detect: adapter allocated at %06x\n",
1141 (int)host);
1142 #endif1143 memset( host, 0, sizeof(Adapter) );
1144 host->sh = sh;
1145 host->irq = cfg->irq;
1146 host->iobase = cfg->iobase;
1147 host->dma = cfg->dma;
1148 irq2host[host->irq] = host;
1149
1150 if (!wd7000_init(host)) {/* Initialization failed */1151 scsi_unregister (sh);
1152 continue;
1153 }1154
1155 /*1156 * OK from here - we'll use this adapter/configuration.1157 */1158 wd7000_revision(host); /* important for scatter/gather */1159
1160 printk("Western Digital WD-7000 (%d.%d) ",
1161 host->rev1, host->rev2);
1162 printk("using IO %xh IRQ %d DMA %d.\n",
1163 host->iobase, host->irq, host->dma);
1164
1165 snarf_region(host->iobase, 4); /* Register our ports */1166 /*1167 * For boards before rev 6.0, scatter/gather isn't supported.1168 */1169 if (host->rev1 < 6) sh->sg_tablesize = SG_NONE;
1170
1171 present++; /* count it */1172 break; /* don't try any more sigs */1173 }1174 sig++; /* try next signature with this configuration */1175 }1176 cfg++; /* try next configuration */1177 }1178
1179 returnpresent;
1180 }1181
1182
1183 /*1184 * I have absolutely NO idea how to do an abort with the WD7000...1185 */1186 intwd7000_abort(Scsi_Cmnd * SCpnt)
/* */1187 {1188 Adapter *host = (Adapter *) SCpnt->host->hostdata;
1189
1190 if (inb(host->iobase+ASC_STAT) & INT_IM) {1191 printk("wd7000_abort: lost interrupt\n");
1192 wd7000_intr_handle(host->irq);
1193 returnSCSI_ABORT_SUCCESS;
1194 }1195
1196 returnSCSI_ABORT_SNOOZE;
1197 }1198
1199
1200 /*1201 * I also have no idea how to do a reset...1202 */1203 intwd7000_reset(Scsi_Cmnd * SCpnt)
/* */1204 {1205 returnSCSI_RESET_PUNT;
1206 }1207
1208
1209 /*1210 * The info routine in the WD7000 structure isn't per-adapter, so it can't1211 * really return any useful information about an adapter. Because of this,1212 * I'm no longer using it to return rev. level.1213 */1214 constchar *wd7000_info(void)
/* */1215 {1216 staticcharinfo[] = "Western Digital WD-7000";
1217 returninfo;
1218 }1219
1220
1221 /*1222 * This was borrowed directly from aha1542.c, but my disks are organized1223 * this way, so I think it will work OK. Someone who is ambitious can1224 * borrow a newer or more complete version from another driver.1225 */1226 intwd7000_biosparam(Disk * disk, intdev, int* ip)
/* */1227 {1228 intsize = disk->capacity;
1229 ip[0] = 64;
1230 ip[1] = 32;
1231 ip[2] = size >> 11;
1232 /* if (ip[2] >= 1024) ip[2] = 1024; */1233 return 0;
1234 }