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