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 uncharID; /* 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 uncharreserved2[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(); /* Yes this is really needed here */ 610 now = jiffies; while (jiffies == now) /* wait a jiffy */;
611 cli();
612 } 613 busy = 1; /* not busy now; it's our turn */ 614
615 while (freescbs < needed) { 616 timeout = jiffies + WAITnexttimeout;
617 do{ 618 sti(); /* Yes this is really needed here */ 619 now = jiffies; while (jiffies == now) /* wait a jiffy */;
620 cli();
621 }while (freescbs < needed && jiffies <= timeout);
622 /* 623 * If we get here with enough free Scbs, we can take them. 624 * Otherwise, we timed out and didn't get enough. 625 */ 626 if (freescbs < needed) { 627 busy = 0;
628 panic("wd7000: can't get enough free SCBs.\n");
629 restore_flags(flags);
630 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, structpt_regs * regs)
/* */ 801 { 802 registerintflag, icmb, errstatus, icmb_status;
803 registerinthost_error, scsi_error;
804 registerScb *scb; /* for SCSI commands */ 805 registerIcbAny *icb; /* for host commands */ 806 registerScsi_Cmnd *SCpnt;
807 Adapter *host = irq2host[irq]; /* This MUST be set!!! */ 808 Mailbox *icmbs = host->mb.icmb;
809
810 #ifdefDEBUG 811 printk("wd7000_intr_handle: irq = %d, host = %06x\n", irq, host);
812 #endif 813
814 flag = inb(host->iobase+ASC_INTR_STAT);
815 #ifdefDEBUG 816 printk("wd7000_intr_handle: intr stat = %02x\n",flag);
817 #endif 818
819 if (!(inb(host->iobase+ASC_STAT) & INT_IM)) { 820 /* NB: these are _very_ possible if IRQ 15 is being used, since 821 it's the "garbage collector" on the 2nd 8259 PIC. Specifically, 822 any interrupt signal into the 8259 which can't be identified 823 comes out as 7 from the 8259, which is 15 to the host. Thus, it 824 is a good thing the WD7000 has an interrupt status port, so we 825 can sort these out. Otherwise, electrical noise and other such 826 problems would be indistinguishable from valid interrupts... 827 */ 828 #ifdefDEBUG 829 printk("wd7000_intr_handle: phantom interrupt...\n");
830 #endif 831 wd7000_intr_ack(host);
832 return;
833 } 834
835 if (flag & MB_INTR) { 836 /* The interrupt is for a mailbox */ 837 if (!(flag & IMB_INTR)) { 838 #ifdefDEBUG 839 printk("wd7000_intr_handle: free outgoing mailbox");
840 #endif 841 /* 842 * If sleep_on() and the "interrupt on free OGMB" command are 843 * used in mail_out(), wake_up() should correspondingly be called 844 * here. For now, we don't need to do anything special. 845 */ 846 wd7000_intr_ack(host);
847 return;
848 }else{ 849 /* The interrupt is for an incoming mailbox */ 850 icmb = flag & MB_MASK;
851 icmb_status = icmbs[icmb].status;
852 if (icmb_status & 0x80) {/* unsolicited - result in ICMB */ 853 #ifdefDEBUG 854 printk("wd7000_intr_handle: unsolicited interrupt %02xh\n",
855 icmb_status);
856 #endif 857 wd7000_intr_ack(host);
858 return;
859 } 860 scb = (structscb *) scsi2int((unchar *)icmbs[icmb].scbptr);
861 icmbs[icmb].status = 0;
862 if (!(scb->op & ICB_OP_MASK)) {/* an SCB is done */ 863 SCpnt = scb->SCpnt;
864 if (--(SCpnt->SCp.phase) <= 0) {/* all scbs are done */ 865 host_error = scb->vue | (icmb_status << 8);
866 scsi_error = scb->status;
867 errstatus = make_code(host_error,scsi_error);
868 SCpnt->result = errstatus;
869
870 free_scb(scb);
871
872 SCpnt->scsi_done(SCpnt);
873 } 874 }else{/* an ICB is done */ 875 icb = (IcbAny *) scb;
876 icb->status = icmb_status;
877 icb->phase = 0;
878 } 879 }/* incoming mailbox */ 880 } 881
882 wd7000_intr_ack(host);
883 return;
884 } 885
886
887 intwd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */ 888 { 889 registerScb *scb;
890 registerSgb *sgb;
891 registerunchar *cdb = (unchar *) SCpnt->cmnd;
892 registeruncharidlun;
893 registershortcdblen;
894 Adapter *host = (Adapter *) SCpnt->host->hostdata;
895
896 cdblen = SCpnt->cmd_len;
897 idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
898 SCpnt->scsi_done = done;
899 SCpnt->SCp.phase = 1;
900 scb = alloc_scbs(1);
901 scb->idlun = idlun;
902 memcpy(scb->cdb, cdb, cdblen);
903 scb->direc = 0x40; /* Disable direction check */ 904
905 scb->SCpnt = SCpnt; /* so we can find stuff later */ 906 SCpnt->host_scribble = (unchar *) scb;
907 scb->host = host;
908
909 if (SCpnt->use_sg) { 910 structscatterlist *sg = (structscatterlist *) SCpnt->request_buffer;
911 unsignedi;
912
913 if (SCpnt->host->sg_tablesize == SG_NONE) { 914 panic("wd7000_queuecommand: scatter/gather not supported.\n");
915 } 916 #ifdefDEBUG 917 printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
918 #endif 919
920 sgb = scb->sgb;
921 scb->op = 1;
922 any2scsi(scb->dataptr, (int) sgb);
923 any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
924
925 for (i = 0; i < SCpnt->use_sg; i++) { 926 any2scsi(sgb[i].ptr, (int) sg[i].address);
927 any2scsi(sgb[i].len, sg[i].length);
928 } 929 }else{ 930 scb->op = 0;
931 any2scsi(scb->dataptr, (int) SCpnt->request_buffer);
932 any2scsi(scb->maxlen, SCpnt->request_bufflen);
933 } 934 while (!mail_out(host, scb)) /* keep trying */;
935
936 return 1;
937 } 938
939
940 intwd7000_command(Scsi_Cmnd *SCpnt)
/* */ 941 { 942 wd7000_queuecommand(SCpnt, wd7000_scsi_done);
943
944 while (SCpnt->SCp.phase > 0); /* phase counts scbs down to 0 */ 945
946 returnSCpnt->result;
947 } 948
949
950 intwd7000_diagnostics( Adapter *host, intcode )
/* */ 951 { 952 staticIcbDiagicb = {ICB_OP_DIAGNOSTICS};
953 staticuncharbuf[256];
954 unsignedlongtimeout;
955
956 icb.type = code;
957 any2scsi(icb.len, sizeof(buf));
958 any2scsi(icb.ptr, (int) &buf);
959 icb.phase = 1;
960 /* 961 * This routine is only called at init, so there should be OGMBs 962 * available. I'm assuming so here. If this is going to 963 * fail, I can just let the timeout catch the failure. 964 */ 965 mail_out(host, (structscb *) &icb);
966 timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */ 967 while (icb.phase && jiffies < timeout) /* wait for completion */;
968
969 if (icb.phase) { 970 printk("wd7000_diagnostics: timed out.\n");
971 return 0;
972 } 973 if (make_code(icb.vue|(icb.status << 8),0)) { 974 printk("wd7000_diagnostics: failed (%02x,%02x)\n",
975 icb.vue, icb.status);
976 return 0;
977 } 978
979 return 1;
980 } 981
982
983 intwd7000_init( Adapter *host )
/* */ 984 { 985 InitCmdinit_cmd = { 986 INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, 0,0,0, OGMB_CNT, ICMB_CNT 987 };
988 intdiag;
989
990 /* 991 Reset the adapter - only. The SCSI bus was initialized at power-up, 992 and we need to do this just so we control the mailboxes, etc. 993 */ 994 outb(ASC_RES, host->iobase+ASC_CONTROL);
995 delay(1); /* reset pulse: this is 10ms, only need 25us */ 996 outb(0,host->iobase+ASC_CONTROL);
997 host->control = 0; /* this must always shadow ASC_CONTROL */ 998 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
999
1000 if ((diag = inb(host->iobase+ASC_INTR_STAT)) != 1) {1001 printk("wd7000_init: ");
1002 switch (diag) {1003 case 2:
1004 printk("RAM failure.\n");
1005 break;
1006 case 3:
1007 printk("FIFO R/W failed\n");
1008 break;
1009 case 4:
1010 printk("SBIC register R/W failed\n");
1011 break;
1012 case 5:
1013 printk("Initialization D-FF failed.\n");
1014 break;
1015 case 6:
1016 printk("Host IRQ D-FF failed.\n");
1017 break;
1018 case 7:
1019 printk("ROM checksum error.\n");
1020 break;
1021 default:
1022 printk("diagnostic code %02Xh received.\n", diag);
1023 break;
1024 }1025 return 0;
1026 }1027
1028 /* Clear mailboxes */1029 memset(&(host->mb), 0, sizeof(host->mb));
1030
1031 /* Execute init command */1032 any2scsi((unchar *) &(init_cmd.mailboxes), (int) &(host->mb));
1033 if (!command_out(host, (unchar *) &init_cmd, sizeof(init_cmd))) {1034 printk("wd7000_init: adapter initialization failed.\n");
1035 return 0;
1036 }1037 WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
1038
1039 if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {1040 printk("wd7000_init: can't get IRQ %d.\n", host->irq);
1041 return 0;
1042 }1043 if (request_dma(host->dma,"wd7000")) {1044 printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
1045 free_irq(host->irq);
1046 return 0;
1047 }1048 wd7000_enable_dma(host);
1049 wd7000_enable_intr(host);
1050
1051 if (!wd7000_diagnostics(host,ICB_DIAG_FULL)) {1052 free_dma(host->dma);
1053 free_irq(host->irq);
1054 return 0;
1055 }1056
1057 return 1;
1058
1059 fail:
1060 printk("wd7000_init: WAIT timed out.\n");
1061 return 0; /* 0 = not ok */1062 }1063
1064
1065 voidwd7000_revision(Adapter *host)
/* */1066 {1067 staticIcbRevLvlicb = {ICB_OP_GET_REVISION};
1068
1069 icb.phase = 1;
1070 /*1071 * Like diagnostics, this is only done at init time, in fact, from1072 * wd7000_detect, so there should be OGMBs available. If it fails,1073 * the only damage will be that the revision will show up as 0.0,1074 * which in turn means that scatter/gather will be disabled.1075 */1076 mail_out(host, (structscb *) &icb);
1077 while (icb.phase) /* wait for completion */;
1078 host->rev1 = icb.primary;
1079 host->rev2 = icb.secondary;
1080 }1081
1082
1083 intwd7000_detect(Scsi_Host_Template * tpnt)
/* */1084 /* 1085 * Returns the number of adapters this driver is supporting.1086 *1087 * The source for hosts.c says to wait to call scsi_register until 100%1088 * sure about an adapter. We need to do it a little sooner here; we1089 * need the storage set up by scsi_register before wd7000_init, and1090 * changing the location of an Adapter structure is more trouble than1091 * calling scsi_unregister.1092 *1093 */1094 {1095 inti,j, present = 0;
1096 constConfig *cfg;
1097 constSignature *sig;
1098 Adapter *host = NULL;
1099 structScsi_Host *sh;
1100
1101 /* Set up SCB free list, which is shared by all adapters */1102 init_scbs();
1103
1104 cfg = configs;
1105 for (i = 0; i < NUM_CONFIGS; i++) {1106 sig = signatures;
1107 for (j = 0; j < NUM_SIGNATURES; j++) {1108 if (!memcmp(cfg->bios+sig->ofs, sig->sig, sig->len)) {1109 /* matched this one */1110 #ifdefDEBUG1111 printk("WD-7000 SST BIOS detected at %04X: checking...\n",
1112 (int) cfg->bios);
1113 #endif1114 /*1115 * We won't explicitly test the configuration (in this1116 * version); instead, we'll just see if it works to1117 * setup the adapter; if it does, we'll use it.1118 */1119 if (check_region(cfg->iobase, 4)) {/* ports in use */1120 printk("IO %xh already in use.\n", host->iobase);
1121 continue;
1122 }1123 /*1124 * We register here, to get a pointer to the extra space,1125 * which we'll use as the Adapter structure (host) for1126 * this adapter. It is located just after the registered1127 * Scsi_Host structure (sh), and is located by the empty1128 * array hostdata.1129 */1130 sh = scsi_register(tpnt, sizeof(Adapter) );
1131 host = (Adapter *) sh->hostdata;
1132 #ifdefDEBUG1133 printk("wd7000_detect: adapter allocated at %06x\n",
1134 (int)host);
1135 #endif1136 memset( host, 0, sizeof(Adapter) );
1137 host->sh = sh;
1138 host->irq = cfg->irq;
1139 host->iobase = cfg->iobase;
1140 host->dma = cfg->dma;
1141 irq2host[host->irq] = host;
1142
1143 if (!wd7000_init(host)) {/* Initialization failed */1144 scsi_unregister (sh);
1145 continue;
1146 }1147
1148 /*1149 * OK from here - we'll use this adapter/configuration.1150 */1151 wd7000_revision(host); /* important for scatter/gather */1152
1153 printk("Western Digital WD-7000 (%d.%d) ",
1154 host->rev1, host->rev2);
1155 printk("using IO %xh IRQ %d DMA %d.\n",
1156 host->iobase, host->irq, host->dma);
1157
1158 request_region(host->iobase, 4,"wd7000"); /* Register our ports */1159 /*1160 * For boards before rev 6.0, scatter/gather isn't supported.1161 */1162 if (host->rev1 < 6) sh->sg_tablesize = SG_NONE;
1163
1164 present++; /* count it */1165 break; /* don't try any more sigs */1166 }1167 sig++; /* try next signature with this configuration */1168 }1169 cfg++; /* try next configuration */1170 }1171
1172 returnpresent;
1173 }1174
1175
1176 /*1177 * I have absolutely NO idea how to do an abort with the WD7000...1178 */1179 intwd7000_abort(Scsi_Cmnd * SCpnt)
/* */1180 {1181 Adapter *host = (Adapter *) SCpnt->host->hostdata;
1182
1183 if (inb(host->iobase+ASC_STAT) & INT_IM) {1184 printk("wd7000_abort: lost interrupt\n");
1185 wd7000_intr_handle(host->irq, NULL);
1186 returnSCSI_ABORT_SUCCESS;
1187 }1188
1189 returnSCSI_ABORT_SNOOZE;
1190 }1191
1192
1193 /*1194 * I also have no idea how to do a reset...1195 */1196 intwd7000_reset(Scsi_Cmnd * SCpnt)
/* */1197 {1198 returnSCSI_RESET_PUNT;
1199 }1200
1201
1202 /*1203 * This was borrowed directly from aha1542.c, but my disks are organized1204 * this way, so I think it will work OK. Someone who is ambitious can1205 * borrow a newer or more complete version from another driver.1206 */1207 intwd7000_biosparam(Disk * disk, intdev, int* ip)
/* */1208 {1209 intsize = disk->capacity;
1210 ip[0] = 64;
1211 ip[1] = 32;
1212 ip[2] = size >> 11;
1213 /* if (ip[2] >= 1024) ip[2] = 1024; */1214 return 0;
1215 }