|
|
1.1 ! root 1: /* $Id: aha1542.c,v 1.1 1999/04/26 05:54:11 tb Exp $ ! 2: * linux/kernel/aha1542.c ! 3: * ! 4: * Copyright (C) 1992 Tommy Thorn ! 5: * Copyright (C) 1993, 1994, 1995 Eric Youngdale ! 6: * ! 7: * Modified by Eric Youngdale ! 8: * Use request_irq and request_dma to help prevent unexpected conflicts ! 9: * Set up on-board DMA controller, such that we do not have to ! 10: * have the bios enabled to use the aha1542. ! 11: * Modified by David Gentzel ! 12: * Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus ! 13: * controller). ! 14: * Modified by Matti Aarnio ! 15: * Accept parameters from LILO cmd-line. -- 1-Oct-94 ! 16: * Modified by Mike McLagan <[email protected]> ! 17: * Recognise extended mode on AHA1542CP, different bit than 1542CF ! 18: * 1-Jan-97 ! 19: * Modified by Bjorn L. Thordarson and Einar Thor Einarsson ! 20: * Recognize that DMA0 is valid DMA channel -- 13-Jul-98 ! 21: */ ! 22: ! 23: #include <linux/module.h> ! 24: ! 25: #include <linux/kernel.h> ! 26: #include <linux/head.h> ! 27: #include <linux/types.h> ! 28: #include <linux/string.h> ! 29: #include <linux/ioport.h> ! 30: #include <linux/delay.h> ! 31: #include <linux/sched.h> ! 32: #include <linux/proc_fs.h> ! 33: #include <asm/dma.h> ! 34: #include <asm/system.h> ! 35: #include <asm/io.h> ! 36: #include <linux/blk.h> ! 37: #include "scsi.h" ! 38: #include "hosts.h" ! 39: ! 40: ! 41: #include "aha1542.h" ! 42: ! 43: #include<linux/stat.h> ! 44: ! 45: struct proc_dir_entry proc_scsi_aha1542 = { ! 46: PROC_SCSI_AHA1542, 7, "aha1542", ! 47: S_IFDIR | S_IRUGO | S_IXUGO, 2 ! 48: }; ! 49: ! 50: #ifdef DEBUG ! 51: #define DEB(x) x ! 52: #else ! 53: #define DEB(x) ! 54: #endif ! 55: /* ! 56: static const char RCSid[] = "$Header: /afs/sipb.mit.edu/project/hurddev/cvsroot/gnumach/linux/src/drivers/scsi/aha1542.c,v 1.1 1999/04/26 05:54:11 tb Exp $"; ! 57: */ ! 58: ! 59: /* The adaptec can be configured for quite a number of addresses, but ! 60: I generally do not want the card poking around at random. We allow ! 61: two addresses - this allows people to use the Adaptec with a Midi ! 62: card, which also used 0x330 -- can be overridden with LILO! */ ! 63: ! 64: #define MAXBOARDS 2 /* Increase this and the sizes of the ! 65: arrays below, if you need more.. */ ! 66: ! 67: static unsigned int bases[MAXBOARDS]={0x330, 0x334}; ! 68: ! 69: /* set by aha1542_setup according to the command line */ ! 70: static int setup_called[MAXBOARDS] = {0,0}; ! 71: static int setup_buson[MAXBOARDS] = {0,0}; ! 72: static int setup_busoff[MAXBOARDS] = {0,0}; ! 73: static int setup_dmaspeed[MAXBOARDS] = {-1,-1}; ! 74: ! 75: static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL}; ! 76: ! 77: /* ! 78: * LILO params: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]] ! 79: * ! 80: * Where: <PORTBASE> is any of the valid AHA addresses: ! 81: * 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 ! 82: * <BUSON> is the time (in microsecs) that AHA spends on the AT-bus ! 83: * when transferring data. 1542A power-on default is 11us, ! 84: * valid values are in range: 2..15 (decimal) ! 85: * <BUSOFF> is the time that AHA spends OFF THE BUS after while ! 86: * it is transferring data (not to monopolize the bus). ! 87: * Power-on default is 4us, valid range: 1..64 microseconds. ! 88: * <DMASPEED> Default is jumper selected (1542A: on the J1), ! 89: * but experimenter can alter it with this. ! 90: * Valid values: 5, 6, 7, 8, 10 (MB/s) ! 91: * Factory default is 5 MB/s. ! 92: */ ! 93: ! 94: #define BIOS_TRANSLATION_1632 0 /* Used by some old 1542A boards */ ! 95: #define BIOS_TRANSLATION_6432 1 /* Default case these days */ ! 96: #define BIOS_TRANSLATION_25563 2 /* Big disk case */ ! 97: ! 98: struct aha1542_hostdata{ ! 99: /* This will effectively start both of them at the first mailbox */ ! 100: int bios_translation; /* Mapping bios uses - for compatibility */ ! 101: int aha1542_last_mbi_used; ! 102: int aha1542_last_mbo_used; ! 103: Scsi_Cmnd * SCint[AHA1542_MAILBOXES]; ! 104: struct mailbox mb[2*AHA1542_MAILBOXES]; ! 105: struct ccb ccb[AHA1542_MAILBOXES]; ! 106: }; ! 107: ! 108: #define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata) ! 109: ! 110: static struct Scsi_Host * aha_host[7] = {NULL,}; /* One for each IRQ level (9-15) */ ! 111: ! 112: ! 113: ! 114: ! 115: #define WAITnexttimeout 3000000 ! 116: ! 117: static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt); ! 118: static int aha1542_restart(struct Scsi_Host * shost); ! 119: ! 120: #define aha1542_intr_reset(base) outb(IRST, CONTROL(base)) ! 121: ! 122: #define WAIT(port, mask, allof, noneof) \ ! 123: { register WAITbits; \ ! 124: register WAITtimeout = WAITnexttimeout; \ ! 125: while (1) { \ ! 126: WAITbits = inb(port) & (mask); \ ! 127: if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \ ! 128: break; \ ! 129: if (--WAITtimeout == 0) goto fail; \ ! 130: } \ ! 131: } ! 132: ! 133: /* Similar to WAIT, except we use the udelay call to regulate the ! 134: amount of time we wait. */ ! 135: #define WAITd(port, mask, allof, noneof, timeout) \ ! 136: { register WAITbits; \ ! 137: register WAITtimeout = timeout; \ ! 138: while (1) { \ ! 139: WAITbits = inb(port) & (mask); \ ! 140: if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \ ! 141: break; \ ! 142: udelay(1000); \ ! 143: if (--WAITtimeout == 0) goto fail; \ ! 144: } \ ! 145: } ! 146: ! 147: static void aha1542_stat(void) ! 148: { ! 149: /* int s = inb(STATUS), i = inb(INTRFLAGS); ! 150: printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */ ! 151: } ! 152: ! 153: /* This is a bit complicated, but we need to make sure that an interrupt ! 154: routine does not send something out while we are in the middle of this. ! 155: Fortunately, it is only at boot time that multi-byte messages ! 156: are ever sent. */ ! 157: static int aha1542_out(unsigned int base, unchar *cmdp, int len) ! 158: { ! 159: unsigned long flags = 0; ! 160: ! 161: save_flags(flags); ! 162: if(len == 1) { ! 163: while(1==1){ ! 164: WAIT(STATUS(base), CDF, 0, CDF); ! 165: cli(); ! 166: if(inb(STATUS(base)) & CDF) {restore_flags(flags); continue;} ! 167: outb(*cmdp, DATA(base)); ! 168: restore_flags(flags); ! 169: return 0; ! 170: } ! 171: } else { ! 172: cli(); ! 173: while (len--) ! 174: { ! 175: WAIT(STATUS(base), CDF, 0, CDF); ! 176: outb(*cmdp++, DATA(base)); ! 177: } ! 178: restore_flags(flags); ! 179: } ! 180: return 0; ! 181: fail: ! 182: restore_flags(flags); ! 183: printk("aha1542_out failed(%d): ", len+1); aha1542_stat(); ! 184: return 1; ! 185: } ! 186: ! 187: /* Only used at boot time, so we do not need to worry about latency as much ! 188: here */ ! 189: static int aha1542_in(unsigned int base, unchar *cmdp, int len) ! 190: { ! 191: unsigned long flags; ! 192: ! 193: save_flags(flags); ! 194: cli(); ! 195: while (len--) ! 196: { ! 197: WAIT(STATUS(base), DF, DF, 0); ! 198: *cmdp++ = inb(DATA(base)); ! 199: } ! 200: restore_flags(flags); ! 201: return 0; ! 202: fail: ! 203: restore_flags(flags); ! 204: printk("aha1542_in failed(%d): ", len+1); aha1542_stat(); ! 205: return 1; ! 206: } ! 207: ! 208: /* Similar to aha1542_in, except that we wait a very short period of time. ! 209: We use this if we know the board is alive and awake, but we are not sure ! 210: if the board will respond to the command we are about to send or not */ ! 211: static int aha1542_in1(unsigned int base, unchar *cmdp, int len) ! 212: { ! 213: unsigned long flags; ! 214: ! 215: save_flags(flags); ! 216: cli(); ! 217: while (len--) ! 218: { ! 219: WAITd(STATUS(base), DF, DF, 0, 100); ! 220: *cmdp++ = inb(DATA(base)); ! 221: } ! 222: restore_flags(flags); ! 223: return 0; ! 224: fail: ! 225: restore_flags(flags); ! 226: return 1; ! 227: } ! 228: ! 229: static int makecode(unsigned hosterr, unsigned scsierr) ! 230: { ! 231: switch (hosterr) { ! 232: case 0x0: ! 233: case 0xa: /* Linked command complete without error and linked normally */ ! 234: case 0xb: /* Linked command complete without error, interrupt generated */ ! 235: hosterr = 0; ! 236: break; ! 237: ! 238: case 0x11: /* Selection time out-The initiator selection or target ! 239: reselection was not complete within the SCSI Time out period */ ! 240: hosterr = DID_TIME_OUT; ! 241: break; ! 242: ! 243: case 0x12: /* Data overrun/underrun-The target attempted to transfer more data ! 244: than was allocated by the Data Length field or the sum of the ! 245: Scatter / Gather Data Length fields. */ ! 246: ! 247: case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ ! 248: ! 249: case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was ! 250: invalid. This usually indicates a software failure. */ ! 251: ! 252: case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. ! 253: This usually indicates a software failure. */ ! 254: ! 255: case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set ! 256: of linked CCB's does not specify the same logical unit number as ! 257: the first. */ ! 258: case 0x18: /* Invalid Target Direction received from Host-The direction of a ! 259: Target Mode CCB was invalid. */ ! 260: ! 261: case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was ! 262: received to service data transfer between the same target LUN ! 263: and initiator SCSI ID in the same direction. */ ! 264: ! 265: case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero ! 266: length segment or invalid segment list boundaries was received. ! 267: A CCB parameter was invalid. */ ! 268: DEB(printk("Aha1542: %x %x\n", hosterr, scsierr)); ! 269: hosterr = DID_ERROR; /* Couldn't find any better */ ! 270: break; ! 271: ! 272: case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus ! 273: phase sequence was requested by the target. The host adapter ! 274: will generate a SCSI Reset Condition, notifying the host with ! 275: a SCRD interrupt */ ! 276: hosterr = DID_RESET; ! 277: break; ! 278: default: ! 279: printk("makecode: unknown hoststatus %x\n", hosterr); ! 280: break; ! 281: } ! 282: return scsierr|(hosterr << 16); ! 283: } ! 284: ! 285: static int aha1542_test_port(int bse, struct Scsi_Host * shpnt) ! 286: { ! 287: int i; ! 288: unchar inquiry_cmd[] = {CMD_INQUIRY }; ! 289: unchar inquiry_result[4]; ! 290: unchar *cmdp; ! 291: int len; ! 292: volatile int debug = 0; ! 293: ! 294: /* Quick and dirty test for presence of the card. */ ! 295: if(inb(STATUS(bse)) == 0xff) return 0; ! 296: ! 297: /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */ ! 298: ! 299: /* DEB(printk("aha1542_test_port called \n")); */ ! 300: ! 301: /* In case some other card was probing here, reset interrupts */ ! 302: aha1542_intr_reset(bse); /* reset interrupts, so they don't block */ ! 303: ! 304: outb(SRST|IRST/*|SCRST*/, CONTROL(bse)); ! 305: ! 306: i = jiffies + 2; ! 307: while (i>jiffies); /* Wait a little bit for things to settle down. */ ! 308: ! 309: debug = 1; ! 310: /* Expect INIT and IDLE, any of the others are bad */ ! 311: WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF); ! 312: ! 313: debug = 2; ! 314: /* Shouldn't have generated any interrupts during reset */ ! 315: if (inb(INTRFLAGS(bse))&INTRMASK) goto fail; ! 316: ! 317: ! 318: /* Perform a host adapter inquiry instead so we do not need to set ! 319: up the mailboxes ahead of time */ ! 320: ! 321: aha1542_out(bse, inquiry_cmd, 1); ! 322: ! 323: debug = 3; ! 324: len = 4; ! 325: cmdp = &inquiry_result[0]; ! 326: ! 327: while (len--) ! 328: { ! 329: WAIT(STATUS(bse), DF, DF, 0); ! 330: *cmdp++ = inb(DATA(bse)); ! 331: } ! 332: ! 333: debug = 8; ! 334: /* Reading port should reset DF */ ! 335: if (inb(STATUS(bse)) & DF) goto fail; ! 336: ! 337: debug = 9; ! 338: /* When HACC, command is completed, and we're though testing */ ! 339: WAIT(INTRFLAGS(bse), HACC, HACC, 0); ! 340: /* now initialize adapter */ ! 341: ! 342: debug = 10; ! 343: /* Clear interrupts */ ! 344: outb(IRST, CONTROL(bse)); ! 345: ! 346: debug = 11; ! 347: ! 348: return debug; /* 1 = ok */ ! 349: fail: ! 350: return 0; /* 0 = not ok */ ! 351: } ! 352: ! 353: /* A "high" level interrupt handler */ ! 354: static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs) ! 355: { ! 356: void (*my_done)(Scsi_Cmnd *) = NULL; ! 357: int errstatus, mbi, mbo, mbistatus; ! 358: int number_serviced; ! 359: unsigned int flags; ! 360: struct Scsi_Host * shost; ! 361: Scsi_Cmnd * SCtmp; ! 362: int flag; ! 363: int needs_restart; ! 364: struct mailbox * mb; ! 365: struct ccb *ccb; ! 366: ! 367: shost = aha_host[irq - 9]; ! 368: if(!shost) panic("Splunge!"); ! 369: ! 370: mb = HOSTDATA(shost)->mb; ! 371: ccb = HOSTDATA(shost)->ccb; ! 372: ! 373: #ifdef DEBUG ! 374: { ! 375: flag = inb(INTRFLAGS(shost->io_port)); ! 376: printk("aha1542_intr_handle: "); ! 377: if (!(flag&ANYINTR)) printk("no interrupt?"); ! 378: if (flag&MBIF) printk("MBIF "); ! 379: if (flag&MBOA) printk("MBOF "); ! 380: if (flag&HACC) printk("HACC "); ! 381: if (flag&SCRD) printk("SCRD "); ! 382: printk("status %02x\n", inb(STATUS(shost->io_port))); ! 383: }; ! 384: #endif ! 385: number_serviced = 0; ! 386: needs_restart = 0; ! 387: ! 388: while(1==1){ ! 389: flag = inb(INTRFLAGS(shost->io_port)); ! 390: ! 391: /* Check for unusual interrupts. If any of these happen, we should ! 392: probably do something special, but for now just printing a message ! 393: is sufficient. A SCSI reset detected is something that we really ! 394: need to deal with in some way. */ ! 395: if (flag & ~MBIF) { ! 396: if (flag&MBOA) printk("MBOF "); ! 397: if (flag&HACC) printk("HACC "); ! 398: if (flag&SCRD) { ! 399: needs_restart = 1; ! 400: printk("SCRD "); ! 401: } ! 402: } ! 403: ! 404: aha1542_intr_reset(shost->io_port); ! 405: ! 406: save_flags(flags); ! 407: cli(); ! 408: mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1; ! 409: if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES; ! 410: ! 411: do{ ! 412: if(mb[mbi].status != 0) break; ! 413: mbi++; ! 414: if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES; ! 415: } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used); ! 416: ! 417: if(mb[mbi].status == 0){ ! 418: restore_flags(flags); ! 419: /* Hmm, no mail. Must have read it the last time around */ ! 420: if (!number_serviced && !needs_restart) ! 421: printk("aha1542.c: interrupt received, but no mail.\n"); ! 422: /* We detected a reset. Restart all pending commands for ! 423: devices that use the hard reset option */ ! 424: if(needs_restart) aha1542_restart(shost); ! 425: return; ! 426: }; ! 427: ! 428: mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb); ! 429: mbistatus = mb[mbi].status; ! 430: mb[mbi].status = 0; ! 431: HOSTDATA(shost)->aha1542_last_mbi_used = mbi; ! 432: restore_flags(flags); ! 433: ! 434: #ifdef DEBUG ! 435: { ! 436: if (ccb[mbo].tarstat|ccb[mbo].hastat) ! 437: printk("aha1542_command: returning %x (status %d)\n", ! 438: ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status); ! 439: }; ! 440: #endif ! 441: ! 442: if(mbistatus == 3) continue; /* Aborted command not found */ ! 443: ! 444: #ifdef DEBUG ! 445: printk("...done %d %d\n",mbo, mbi); ! 446: #endif ! 447: ! 448: SCtmp = HOSTDATA(shost)->SCint[mbo]; ! 449: ! 450: if (!SCtmp || !SCtmp->scsi_done) { ! 451: printk("aha1542_intr_handle: Unexpected interrupt\n"); ! 452: printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat, ! 453: ccb[mbo].hastat, ccb[mbo].idlun, mbo); ! 454: return; ! 455: } ! 456: ! 457: my_done = SCtmp->scsi_done; ! 458: if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512); ! 459: ! 460: /* Fetch the sense data, and tuck it away, in the required slot. The ! 461: Adaptec automatically fetches it, and there is no guarantee that ! 462: we will still have it in the cdb when we come back */ ! 463: if (ccb[mbo].tarstat == 2) ! 464: memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen], ! 465: sizeof(SCtmp->sense_buffer)); ! 466: ! 467: ! 468: /* is there mail :-) */ ! 469: ! 470: /* more error checking left out here */ ! 471: if (mbistatus != 1) ! 472: /* This is surely wrong, but I don't know what's right */ ! 473: errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat); ! 474: else ! 475: errstatus = 0; ! 476: ! 477: #ifdef DEBUG ! 478: if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus, ! 479: ccb[mbo].hastat, ccb[mbo].tarstat); ! 480: #endif ! 481: ! 482: if (ccb[mbo].tarstat == 2) { ! 483: #ifdef DEBUG ! 484: int i; ! 485: #endif ! 486: DEB(printk("aha1542_intr_handle: sense:")); ! 487: #ifdef DEBUG ! 488: for (i = 0; i < 12; i++) ! 489: printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]); ! 490: printk("\n"); ! 491: #endif ! 492: /* ! 493: DEB(printk("aha1542_intr_handle: buf:")); ! 494: for (i = 0; i < bufflen; i++) ! 495: printk("%02x ", ((unchar *)buff)[i]); ! 496: printk("\n"); ! 497: */ ! 498: } ! 499: DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus)); ! 500: SCtmp->result = errstatus; ! 501: HOSTDATA(shost)->SCint[mbo] = NULL; /* This effectively frees up the mailbox slot, as ! 502: far as queuecommand is concerned */ ! 503: my_done(SCtmp); ! 504: number_serviced++; ! 505: }; ! 506: } ! 507: ! 508: int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ! 509: { ! 510: unchar ahacmd = CMD_START_SCSI; ! 511: unchar direction; ! 512: unchar *cmd = (unchar *) SCpnt->cmnd; ! 513: unchar target = SCpnt->target; ! 514: unchar lun = SCpnt->lun; ! 515: unsigned long flags; ! 516: void *buff = SCpnt->request_buffer; ! 517: int bufflen = SCpnt->request_bufflen; ! 518: int mbo; ! 519: struct mailbox * mb; ! 520: struct ccb *ccb; ! 521: ! 522: DEB(int i); ! 523: ! 524: mb = HOSTDATA(SCpnt->host)->mb; ! 525: ccb = HOSTDATA(SCpnt->host)->ccb; ! 526: ! 527: DEB(if (target > 1) { ! 528: SCpnt->result = DID_TIME_OUT << 16; ! 529: done(SCpnt); return 0;}); ! 530: ! 531: if(*cmd == REQUEST_SENSE){ ! 532: #ifndef DEBUG ! 533: if (bufflen != sizeof(SCpnt->sense_buffer)) { ! 534: printk("Wrong buffer length supplied for request sense (%d)\n",bufflen); ! 535: }; ! 536: #endif ! 537: SCpnt->result = 0; ! 538: done(SCpnt); ! 539: return 0; ! 540: }; ! 541: ! 542: #ifdef DEBUG ! 543: if (*cmd == READ_10 || *cmd == WRITE_10) ! 544: i = xscsi2int(cmd+2); ! 545: else if (*cmd == READ_6 || *cmd == WRITE_6) ! 546: i = scsi2int(cmd+2); ! 547: else ! 548: i = -1; ! 549: if (done) ! 550: printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen); ! 551: else ! 552: printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen); ! 553: aha1542_stat(); ! 554: printk("aha1542_queuecommand: dumping scsi cmd:"); ! 555: for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]); ! 556: printk("\n"); ! 557: if (*cmd == WRITE_10 || *cmd == WRITE_6) ! 558: return 0; /* we are still testing, so *don't* write */ ! 559: #endif ! 560: /* Use the outgoing mailboxes in a round-robin fashion, because this ! 561: is how the host adapter will scan for them */ ! 562: ! 563: save_flags(flags); ! 564: cli(); ! 565: mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1; ! 566: if (mbo >= AHA1542_MAILBOXES) mbo = 0; ! 567: ! 568: do{ ! 569: if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL) ! 570: break; ! 571: mbo++; ! 572: if (mbo >= AHA1542_MAILBOXES) mbo = 0; ! 573: } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used); ! 574: ! 575: if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo]) ! 576: panic("Unable to find empty mailbox for aha1542.\n"); ! 577: ! 578: HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt; /* This will effectively prevent someone else from ! 579: screwing with this cdb. */ ! 580: ! 581: HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo; ! 582: restore_flags(flags); ! 583: ! 584: #ifdef DEBUG ! 585: printk("Sending command (%d %x)...",mbo, done); ! 586: #endif ! 587: ! 588: any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/ ! 589: ! 590: memset(&ccb[mbo], 0, sizeof(struct ccb)); ! 591: ! 592: ccb[mbo].cdblen = SCpnt->cmd_len; ! 593: ! 594: direction = 0; ! 595: if (*cmd == READ_10 || *cmd == READ_6) ! 596: direction = 8; ! 597: else if (*cmd == WRITE_10 || *cmd == WRITE_6) ! 598: direction = 16; ! 599: ! 600: memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen); ! 601: ! 602: if (SCpnt->use_sg) { ! 603: struct scatterlist * sgpnt; ! 604: struct chain * cptr; ! 605: #ifdef DEBUG ! 606: unsigned char * ptr; ! 607: #endif ! 608: int i; ! 609: ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather*/ ! 610: SCpnt->host_scribble = (unsigned char *) scsi_malloc(512); ! 611: sgpnt = (struct scatterlist *) SCpnt->request_buffer; ! 612: cptr = (struct chain *) SCpnt->host_scribble; ! 613: if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n"); ! 614: for(i=0; i<SCpnt->use_sg; i++) { ! 615: if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 || ! 616: (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){ ! 617: unsigned char * ptr; ! 618: printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i); ! 619: for(i=0;i<SCpnt->use_sg;i++){ ! 620: printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address, ! 621: sgpnt[i].length); ! 622: }; ! 623: printk("cptr %x: ",(unsigned int) cptr); ! 624: ptr = (unsigned char *) &cptr[i]; ! 625: for(i=0;i<18;i++) printk("%02x ", ptr[i]); ! 626: panic("Foooooooood fight!"); ! 627: }; ! 628: any2scsi(cptr[i].dataptr, sgpnt[i].address); ! 629: if(((unsigned int) sgpnt[i].address) & 0xff000000) goto baddma; ! 630: any2scsi(cptr[i].datalen, sgpnt[i].length); ! 631: }; ! 632: any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain)); ! 633: any2scsi(ccb[mbo].dataptr, cptr); ! 634: #ifdef DEBUG ! 635: printk("cptr %x: ",cptr); ! 636: ptr = (unsigned char *) cptr; ! 637: for(i=0;i<18;i++) printk("%02x ", ptr[i]); ! 638: #endif ! 639: } else { ! 640: ccb[mbo].op = 0; /* SCSI Initiator Command */ ! 641: SCpnt->host_scribble = NULL; ! 642: any2scsi(ccb[mbo].datalen, bufflen); ! 643: if(((unsigned int) buff & 0xff000000)) goto baddma; ! 644: any2scsi(ccb[mbo].dataptr, buff); ! 645: }; ! 646: ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/ ! 647: ccb[mbo].rsalen = 16; ! 648: ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0; ! 649: ccb[mbo].commlinkid = 0; ! 650: ! 651: #ifdef DEBUG ! 652: { int i; ! 653: printk("aha1542_command: sending.. "); ! 654: for (i = 0; i < sizeof(ccb[mbo])-10; i++) ! 655: printk("%02x ", ((unchar *)&ccb[mbo])[i]); ! 656: }; ! 657: #endif ! 658: ! 659: if (done) { ! 660: DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat()); ! 661: SCpnt->scsi_done = done; ! 662: mb[mbo].status = 1; ! 663: aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */ ! 664: DEB(aha1542_stat()); ! 665: } ! 666: else ! 667: printk("aha1542_queuecommand: done can't be NULL\n"); ! 668: ! 669: return 0; ! 670: baddma: ! 671: panic("Buffer at address > 16Mb used for 1542B"); ! 672: } ! 673: ! 674: static void internal_done(Scsi_Cmnd * SCpnt) ! 675: { ! 676: SCpnt->SCp.Status++; ! 677: } ! 678: ! 679: int aha1542_command(Scsi_Cmnd * SCpnt) ! 680: { ! 681: DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n")); ! 682: ! 683: aha1542_queuecommand(SCpnt, internal_done); ! 684: ! 685: SCpnt->SCp.Status = 0; ! 686: while (!SCpnt->SCp.Status) ! 687: barrier(); ! 688: return SCpnt->result; ! 689: } ! 690: ! 691: /* Initialize mailboxes */ ! 692: static void setup_mailboxes(int bse, struct Scsi_Host * shpnt) ! 693: { ! 694: int i; ! 695: struct mailbox * mb; ! 696: struct ccb *ccb; ! 697: ! 698: unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0}; ! 699: ! 700: mb = HOSTDATA(shpnt)->mb; ! 701: ccb = HOSTDATA(shpnt)->ccb; ! 702: ! 703: for(i=0; i<AHA1542_MAILBOXES; i++){ ! 704: mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0; ! 705: any2scsi(mb[i].ccbptr, &ccb[i]); ! 706: }; ! 707: aha1542_intr_reset(bse); /* reset interrupts, so they don't block */ ! 708: any2scsi((cmd+2), mb); ! 709: aha1542_out(bse, cmd, 5); ! 710: WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0); ! 711: while (0) { ! 712: fail: ! 713: printk("aha1542_detect: failed setting up mailboxes\n"); ! 714: } ! 715: aha1542_intr_reset(bse); ! 716: } ! 717: ! 718: static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan, unsigned char * scsi_id) ! 719: { ! 720: unchar inquiry_cmd[] = {CMD_RETCONF }; ! 721: unchar inquiry_result[3]; ! 722: int i; ! 723: i = inb(STATUS(base_io)); ! 724: if (i & DF) { ! 725: i = inb(DATA(base_io)); ! 726: }; ! 727: aha1542_out(base_io, inquiry_cmd, 1); ! 728: aha1542_in(base_io, inquiry_result, 3); ! 729: WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0); ! 730: while (0) { ! 731: fail: ! 732: printk("aha1542_detect: query board settings\n"); ! 733: } ! 734: aha1542_intr_reset(base_io); ! 735: switch(inquiry_result[0]){ ! 736: case 0x80: ! 737: *dma_chan = 7; ! 738: break; ! 739: case 0x40: ! 740: *dma_chan = 6; ! 741: break; ! 742: case 0x20: ! 743: *dma_chan = 5; ! 744: break; ! 745: case 0x01: ! 746: *dma_chan = 0; ! 747: break; ! 748: case 0: ! 749: /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel. ! 750: Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */ ! 751: *dma_chan = 0xFF; ! 752: break; ! 753: default: ! 754: printk("Unable to determine Adaptec DMA priority. Disabling board\n"); ! 755: return -1; ! 756: }; ! 757: switch(inquiry_result[1]){ ! 758: case 0x40: ! 759: *irq_level = 15; ! 760: break; ! 761: case 0x20: ! 762: *irq_level = 14; ! 763: break; ! 764: case 0x8: ! 765: *irq_level = 12; ! 766: break; ! 767: case 0x4: ! 768: *irq_level = 11; ! 769: break; ! 770: case 0x2: ! 771: *irq_level = 10; ! 772: break; ! 773: case 0x1: ! 774: *irq_level = 9; ! 775: break; ! 776: default: ! 777: printk("Unable to determine Adaptec IRQ level. Disabling board\n"); ! 778: return -1; ! 779: }; ! 780: *scsi_id=inquiry_result[2] & 7; ! 781: return 0; ! 782: } ! 783: ! 784: /* This function should only be called for 1542C boards - we can detect ! 785: the special firmware settings and unlock the board */ ! 786: ! 787: static int aha1542_mbenable(int base) ! 788: { ! 789: static unchar mbenable_cmd[3]; ! 790: static unchar mbenable_result[2]; ! 791: int retval; ! 792: ! 793: retval = BIOS_TRANSLATION_6432; ! 794: ! 795: mbenable_cmd[0]=CMD_EXTBIOS; ! 796: aha1542_out(base,mbenable_cmd,1); ! 797: if(aha1542_in1(base,mbenable_result,2)) ! 798: return retval; ! 799: WAITd(INTRFLAGS(base),INTRMASK,HACC,0,100); ! 800: aha1542_intr_reset(base); ! 801: ! 802: if ((mbenable_result[0] & 0x08) || mbenable_result[1]) { ! 803: mbenable_cmd[0]=CMD_MBENABLE; ! 804: mbenable_cmd[1]=0; ! 805: mbenable_cmd[2]=mbenable_result[1]; ! 806: ! 807: if((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03)) retval = BIOS_TRANSLATION_25563; ! 808: ! 809: aha1542_out(base,mbenable_cmd,3); ! 810: WAIT(INTRFLAGS(base),INTRMASK,HACC,0); ! 811: }; ! 812: while(0) { ! 813: fail: ! 814: printk("aha1542_mbenable: Mailbox init failed\n"); ! 815: } ! 816: aha1542_intr_reset(base); ! 817: return retval; ! 818: } ! 819: ! 820: /* Query the board to find out if it is a 1542 or a 1740, or whatever. */ ! 821: static int aha1542_query(int base_io, int * transl) ! 822: { ! 823: unchar inquiry_cmd[] = {CMD_INQUIRY }; ! 824: unchar inquiry_result[4]; ! 825: int i; ! 826: i = inb(STATUS(base_io)); ! 827: if (i & DF) { ! 828: i = inb(DATA(base_io)); ! 829: }; ! 830: aha1542_out(base_io, inquiry_cmd, 1); ! 831: aha1542_in(base_io, inquiry_result, 4); ! 832: WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0); ! 833: while (0) { ! 834: fail: ! 835: printk("aha1542_detect: query card type\n"); ! 836: } ! 837: aha1542_intr_reset(base_io); ! 838: ! 839: *transl = BIOS_TRANSLATION_6432; /* Default case */ ! 840: ! 841: /* For an AHA1740 series board, we ignore the board since there is a ! 842: hardware bug which can lead to wrong blocks being returned if the board ! 843: is operating in the 1542 emulation mode. Since there is an extended mode ! 844: driver, we simply ignore the board and let the 1740 driver pick it up. ! 845: */ ! 846: ! 847: if (inquiry_result[0] == 0x43) { ! 848: printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n"); ! 849: return 1; ! 850: }; ! 851: ! 852: /* Always call this - boards that do not support extended bios translation ! 853: will ignore the command, and we will set the proper default */ ! 854: ! 855: *transl = aha1542_mbenable(base_io); ! 856: ! 857: return 0; ! 858: } ! 859: ! 860: /* called from init/main.c */ ! 861: void aha1542_setup( char *str, int *ints) ! 862: { ! 863: const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n"; ! 864: static int setup_idx = 0; ! 865: int setup_portbase; ! 866: ! 867: if(setup_idx >= MAXBOARDS) ! 868: { ! 869: printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n"); ! 870: printk(" Entryline 1: %s\n",setup_str[0]); ! 871: printk(" Entryline 2: %s\n",setup_str[1]); ! 872: printk(" This line: %s\n",str); ! 873: return; ! 874: } ! 875: if (ints[0] < 1 || ints[0] > 4) ! 876: { ! 877: printk("aha1542: %s\n", str ); ! 878: printk(ahausage); ! 879: printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n"); ! 880: } ! 881: ! 882: setup_called[setup_idx]=ints[0]; ! 883: setup_str[setup_idx]=str; ! 884: ! 885: setup_portbase = ints[0] >= 1 ? ints[1] : 0; /* Preserve the default value.. */ ! 886: setup_buson [setup_idx] = ints[0] >= 2 ? ints[2] : 7; ! 887: setup_busoff [setup_idx] = ints[0] >= 3 ? ints[3] : 5; ! 888: if (ints[0] >= 4) { ! 889: int atbt = -1; ! 890: switch (ints[4]) { ! 891: case 5: ! 892: atbt = 0x00; ! 893: break; ! 894: case 6: ! 895: atbt = 0x04; ! 896: break; ! 897: case 7: ! 898: atbt = 0x01; ! 899: break; ! 900: case 8: ! 901: atbt = 0x02; ! 902: break; ! 903: case 10: ! 904: atbt = 0x03; ! 905: break; ! 906: default: ! 907: printk("aha1542: %s\n", str ); ! 908: printk(ahausage); ! 909: printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s. Using jumper defaults.\n"); ! 910: break; ! 911: } ! 912: setup_dmaspeed[setup_idx] = atbt; ! 913: } ! 914: ! 915: if (setup_portbase != 0) ! 916: bases[setup_idx] = setup_portbase; ! 917: ! 918: ++setup_idx; ! 919: } ! 920: ! 921: /* return non-zero on detection */ ! 922: int aha1542_detect(Scsi_Host_Template * tpnt) ! 923: { ! 924: unsigned char dma_chan; ! 925: unsigned char irq_level; ! 926: unsigned char scsi_id; ! 927: unsigned long flags; ! 928: unsigned int base_io; ! 929: int trans; ! 930: struct Scsi_Host * shpnt = NULL; ! 931: int count = 0; ! 932: int indx; ! 933: ! 934: DEB(printk("aha1542_detect: \n")); ! 935: ! 936: tpnt->proc_dir = &proc_scsi_aha1542; ! 937: ! 938: for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++) ! 939: if(bases[indx] != 0 && !check_region(bases[indx], 4)) { ! 940: shpnt = scsi_register(tpnt, ! 941: sizeof(struct aha1542_hostdata)); ! 942: ! 943: /* For now we do this - until kmalloc is more intelligent ! 944: we are resigned to stupid hacks like this */ ! 945: if ((unsigned int) shpnt > 0xffffff) { ! 946: printk("Invalid address for shpnt with 1542.\n"); ! 947: goto unregister; ! 948: } ! 949: ! 950: if(!aha1542_test_port(bases[indx], shpnt)) goto unregister; ! 951: ! 952: ! 953: base_io = bases[indx]; ! 954: ! 955: /* Set the Bus on/off-times as not to ruin floppy performance */ ! 956: { ! 957: unchar oncmd[] = {CMD_BUSON_TIME, 7}; ! 958: unchar offcmd[] = {CMD_BUSOFF_TIME, 5}; ! 959: ! 960: if(setup_called[indx]) ! 961: { ! 962: oncmd[1] = setup_buson[indx]; ! 963: offcmd[1] = setup_busoff[indx]; ! 964: } ! 965: ! 966: aha1542_intr_reset(base_io); ! 967: aha1542_out(base_io, oncmd, 2); ! 968: WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0); ! 969: aha1542_intr_reset(base_io); ! 970: aha1542_out(base_io, offcmd, 2); ! 971: WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0); ! 972: if (setup_dmaspeed[indx] >= 0) ! 973: { ! 974: unchar dmacmd[] = {CMD_DMASPEED, 0}; ! 975: dmacmd[1] = setup_dmaspeed[indx]; ! 976: aha1542_intr_reset(base_io); ! 977: aha1542_out(base_io, dmacmd, 2); ! 978: WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0); ! 979: } ! 980: while (0) { ! 981: fail: ! 982: printk("aha1542_detect: setting bus on/off-time failed\n"); ! 983: } ! 984: aha1542_intr_reset(base_io); ! 985: } ! 986: if(aha1542_query(base_io, &trans)) goto unregister; ! 987: ! 988: if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1) goto unregister; ! 989: ! 990: printk("Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level); ! 991: if (dma_chan != 0xFF) ! 992: printk(", DMA priority %d", dma_chan); ! 993: printk("\n"); ! 994: ! 995: DEB(aha1542_stat()); ! 996: setup_mailboxes(base_io, shpnt); ! 997: ! 998: DEB(aha1542_stat()); ! 999: ! 1000: DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level)); ! 1001: save_flags(flags); ! 1002: cli(); ! 1003: if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542", NULL)) { ! 1004: printk("Unable to allocate IRQ for adaptec controller.\n"); ! 1005: restore_flags(flags); ! 1006: goto unregister; ! 1007: } ! 1008: ! 1009: if (dma_chan != 0xFF) { ! 1010: if (request_dma(dma_chan,"aha1542")) { ! 1011: printk("Unable to allocate DMA channel for Adaptec.\n"); ! 1012: free_irq(irq_level, NULL); ! 1013: restore_flags(flags); ! 1014: goto unregister; ! 1015: } ! 1016: ! 1017: if (dma_chan == 0 || dma_chan >= 5) { ! 1018: set_dma_mode(dma_chan, DMA_MODE_CASCADE); ! 1019: enable_dma(dma_chan); ! 1020: } ! 1021: } ! 1022: aha_host[irq_level - 9] = shpnt; ! 1023: shpnt->this_id = scsi_id; ! 1024: shpnt->unique_id = base_io; ! 1025: shpnt->io_port = base_io; ! 1026: shpnt->n_io_port = 4; /* Number of bytes of I/O space used */ ! 1027: shpnt->dma_channel = dma_chan; ! 1028: shpnt->irq = irq_level; ! 1029: HOSTDATA(shpnt)->bios_translation = trans; ! 1030: if(trans == BIOS_TRANSLATION_25563) ! 1031: printk("aha1542.c: Using extended bios translation\n"); ! 1032: HOSTDATA(shpnt)->aha1542_last_mbi_used = (2*AHA1542_MAILBOXES - 1); ! 1033: HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1); ! 1034: memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint)); ! 1035: restore_flags(flags); ! 1036: #if 0 ! 1037: DEB(printk(" *** READ CAPACITY ***\n")); ! 1038: ! 1039: { ! 1040: unchar buf[8]; ! 1041: static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! 1042: int i; ! 1043: ! 1044: for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87; ! 1045: for (i = 0; i < 2; ++i) ! 1046: if (!aha1542_command(i, cmd, buf, sizeof(buf))) { ! 1047: printk("aha_detect: LU %d sector_size %d device_size %d\n", ! 1048: i, xscsi2int(buf+4), xscsi2int(buf)); ! 1049: } ! 1050: } ! 1051: ! 1052: DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n")); ! 1053: ! 1054: for (i = 0; i < 4; ++i) ! 1055: { ! 1056: unsigned char cmd[10]; ! 1057: static buffer[512]; ! 1058: ! 1059: cmd[0] = READ_10; ! 1060: cmd[1] = 0; ! 1061: xany2scsi(cmd+2, i); ! 1062: cmd[6] = 0; ! 1063: cmd[7] = 0; ! 1064: cmd[8] = 1; ! 1065: cmd[9] = 0; ! 1066: aha1542_command(0, cmd, buffer, 512); ! 1067: } ! 1068: #endif ! 1069: request_region(bases[indx], 4,"aha1542"); /* Register the IO ports that we use */ ! 1070: count++; ! 1071: continue; ! 1072: unregister: ! 1073: scsi_unregister(shpnt); ! 1074: continue; ! 1075: ! 1076: }; ! 1077: ! 1078: return count; ! 1079: } ! 1080: ! 1081: static int aha1542_restart(struct Scsi_Host * shost) ! 1082: { ! 1083: int i; ! 1084: int count = 0; ! 1085: #if 0 ! 1086: unchar ahacmd = CMD_START_SCSI; ! 1087: #endif ! 1088: ! 1089: for(i=0; i< AHA1542_MAILBOXES; i++) ! 1090: if(HOSTDATA(shost)->SCint[i] && ! 1091: !(HOSTDATA(shost)->SCint[i]->device->soft_reset)) ! 1092: { ! 1093: #if 0 ! 1094: HOSTDATA(shost)->mb[i].status = 1; /* Indicate ready to restart... */ ! 1095: #endif ! 1096: count++; ! 1097: } ! 1098: ! 1099: printk("Potential to restart %d stalled commands...\n", count); ! 1100: #if 0 ! 1101: /* start scsi command */ ! 1102: if (count) aha1542_out(shost->io_port, &ahacmd, 1); ! 1103: #endif ! 1104: return 0; ! 1105: } ! 1106: ! 1107: /* The abort command does not leave the device in a clean state where ! 1108: it is available to be used again. Until this gets worked out, we will ! 1109: leave it commented out. */ ! 1110: ! 1111: int aha1542_abort(Scsi_Cmnd * SCpnt) ! 1112: { ! 1113: #if 0 ! 1114: unchar ahacmd = CMD_START_SCSI; ! 1115: unsigned long flags; ! 1116: struct mailbox * mb; ! 1117: int mbi, mbo, i; ! 1118: ! 1119: printk("In aha1542_abort: %x %x\n", ! 1120: inb(STATUS(SCpnt->host->io_port)), ! 1121: inb(INTRFLAGS(SCpnt->host->io_port))); ! 1122: ! 1123: save_flags(flags); ! 1124: cli(); ! 1125: mb = HOSTDATA(SCpnt->host)->mb; ! 1126: mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1; ! 1127: if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES; ! 1128: ! 1129: do{ ! 1130: if(mb[mbi].status != 0) break; ! 1131: mbi++; ! 1132: if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES; ! 1133: } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used); ! 1134: restore_flags(flags); ! 1135: ! 1136: if(mb[mbi].status) { ! 1137: printk("Lost interrupt discovered on irq %d - attempting to recover\n", ! 1138: SCpnt->host->irq); ! 1139: aha1542_intr_handle(SCpnt->host->irq, NULL); ! 1140: return 0; ! 1141: } ! 1142: ! 1143: /* OK, no lost interrupt. Try looking to see how many pending commands ! 1144: we think we have. */ ! 1145: ! 1146: for(i=0; i< AHA1542_MAILBOXES; i++) ! 1147: if(HOSTDATA(SCpnt->host)->SCint[i]) ! 1148: { ! 1149: if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) { ! 1150: printk("Timed out command pending for %s\n", ! 1151: kdevname(SCpnt->request.rq_dev)); ! 1152: if (HOSTDATA(SCpnt->host)->mb[i].status) { ! 1153: printk("OGMB still full - restarting\n"); ! 1154: aha1542_out(SCpnt->host->io_port, &ahacmd, 1); ! 1155: }; ! 1156: } else ! 1157: printk("Other pending command %s\n", ! 1158: kdevname(SCpnt->request.rq_dev)); ! 1159: } ! 1160: ! 1161: #endif ! 1162: ! 1163: DEB(printk("aha1542_abort\n")); ! 1164: #if 0 ! 1165: save_flags(flags); ! 1166: cli(); ! 1167: for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++) ! 1168: if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){ ! 1169: mb[mbo].status = 2; /* Abort command */ ! 1170: aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */ ! 1171: restore_flags(flags); ! 1172: break; ! 1173: }; ! 1174: #endif ! 1175: return SCSI_ABORT_SNOOZE; ! 1176: } ! 1177: ! 1178: /* We do not implement a reset function here, but the upper level code ! 1179: assumes that it will get some kind of response for the command in ! 1180: SCpnt. We must oblige, or the command will hang the scsi system. ! 1181: For a first go, we assume that the 1542 notifies us with all of the ! 1182: pending commands (it does implement soft reset, after all). */ ! 1183: ! 1184: int aha1542_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) ! 1185: { ! 1186: unchar ahacmd = CMD_START_SCSI; ! 1187: int i; ! 1188: ! 1189: /* ! 1190: * See if a bus reset was suggested. ! 1191: */ ! 1192: if( reset_flags & SCSI_RESET_SUGGEST_BUS_RESET ) ! 1193: { ! 1194: /* ! 1195: * This does a scsi reset for all devices on the bus. ! 1196: * In principle, we could also reset the 1542 - should ! 1197: * we do this? Try this first, and we can add that later ! 1198: * if it turns out to be useful. ! 1199: */ ! 1200: outb(HRST | SCRST, CONTROL(SCpnt->host->io_port)); ! 1201: ! 1202: /* ! 1203: * Wait for the thing to settle down a bit. Unfortunately ! 1204: * this is going to basically lock up the machine while we ! 1205: * wait for this to complete. To be 100% correct, we need to ! 1206: * check for timeout, and if we are doing something like this ! 1207: * we are pretty desperate anyways. ! 1208: */ ! 1209: WAIT(STATUS(SCpnt->host->io_port), ! 1210: STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF); ! 1211: ! 1212: /* ! 1213: * We need to do this too before the 1542 can interact with ! 1214: * us again. ! 1215: */ ! 1216: setup_mailboxes(SCpnt->host->io_port, SCpnt->host); ! 1217: ! 1218: /* ! 1219: * Now try to pick up the pieces. Restart all commands ! 1220: * that are currently active on the bus, and reset all of ! 1221: * the datastructures. We have some time to kill while ! 1222: * things settle down, so print a nice message. ! 1223: */ ! 1224: printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no); ! 1225: ! 1226: for(i=0; i< AHA1542_MAILBOXES; i++) ! 1227: if(HOSTDATA(SCpnt->host)->SCint[i] != NULL) ! 1228: { ! 1229: Scsi_Cmnd * SCtmp; ! 1230: SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; ! 1231: SCtmp->result = DID_RESET << 16; ! 1232: if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512); ! 1233: printk("Sending DID_RESET for target %d\n", SCpnt->target); ! 1234: SCtmp->scsi_done(SCpnt); ! 1235: ! 1236: HOSTDATA(SCpnt->host)->SCint[i] = NULL; ! 1237: HOSTDATA(SCpnt->host)->mb[i].status = 0; ! 1238: } ! 1239: /* ! 1240: * Now tell the mid-level code what we did here. Since ! 1241: * we have restarted all of the outstanding commands, ! 1242: * then report SUCCESS. ! 1243: */ ! 1244: return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET); ! 1245: fail: ! 1246: printk("aha1542.c: Unable to perform hard reset.\n"); ! 1247: printk("Power cycle machine to reset\n"); ! 1248: return (SCSI_RESET_ERROR | SCSI_RESET_BUS_RESET); ! 1249: ! 1250: ! 1251: } ! 1252: else ! 1253: { ! 1254: /* This does a selective reset of just the one device */ ! 1255: /* First locate the ccb for this command */ ! 1256: for(i=0; i< AHA1542_MAILBOXES; i++) ! 1257: if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) ! 1258: { ! 1259: HOSTDATA(SCpnt->host)->ccb[i].op = 0x81; /* BUS DEVICE RESET */ ! 1260: /* Now tell the 1542 to flush all pending commands for this target */ ! 1261: aha1542_out(SCpnt->host->io_port, &ahacmd, 1); ! 1262: ! 1263: /* Here is the tricky part. What to do next. Do we get an interrupt ! 1264: for the commands that we aborted with the specified target, or ! 1265: do we generate this on our own? Try it without first and see ! 1266: what happens */ ! 1267: printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target); ! 1268: ! 1269: /* If the first does not work, then try the second. I think the ! 1270: first option is more likely to be correct. Free the command ! 1271: block for all commands running on this target... */ ! 1272: for(i=0; i< AHA1542_MAILBOXES; i++) ! 1273: if(HOSTDATA(SCpnt->host)->SCint[i] && ! 1274: HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) ! 1275: { ! 1276: Scsi_Cmnd * SCtmp; ! 1277: SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; ! 1278: SCtmp->result = DID_RESET << 16; ! 1279: if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512); ! 1280: printk("Sending DID_RESET for target %d\n", SCpnt->target); ! 1281: SCtmp->scsi_done(SCpnt); ! 1282: ! 1283: HOSTDATA(SCpnt->host)->SCint[i] = NULL; ! 1284: HOSTDATA(SCpnt->host)->mb[i].status = 0; ! 1285: } ! 1286: return SCSI_RESET_SUCCESS; ! 1287: } ! 1288: } ! 1289: /* No active command at this time, so this means that each time we got ! 1290: some kind of response the last time through. Tell the mid-level code ! 1291: to request sense information in order to decide what to do next. */ ! 1292: return SCSI_RESET_PUNT; ! 1293: } ! 1294: ! 1295: #include "sd.h" ! 1296: ! 1297: int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip) ! 1298: { ! 1299: int translation_algorithm; ! 1300: int size = disk->capacity; ! 1301: ! 1302: translation_algorithm = HOSTDATA(disk->device->host)->bios_translation; ! 1303: ! 1304: if((size>>11) > 1024 && translation_algorithm == BIOS_TRANSLATION_25563) { ! 1305: /* Please verify that this is the same as what DOS returns */ ! 1306: ip[0] = 255; ! 1307: ip[1] = 63; ! 1308: ip[2] = size /255/63; ! 1309: } else { ! 1310: ip[0] = 64; ! 1311: ip[1] = 32; ! 1312: ip[2] = size >> 11; ! 1313: } ! 1314: ! 1315: return 0; ! 1316: } ! 1317: ! 1318: ! 1319: #ifdef MODULE ! 1320: /* Eventually this will go into an include file, but this will be later */ ! 1321: Scsi_Host_Template driver_template = AHA1542; ! 1322: ! 1323: #include "scsi_module.c" ! 1324: #endif ! 1325:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.