|
|
1.1 ! root 1: /************************************************************ ! 2: * * ! 3: * Linux EATA SCSI PIO driver * ! 4: * * ! 5: * based on the CAM document CAM/89-004 rev. 2.0c, * ! 6: * DPT's driver kit, some internal documents and source, * ! 7: * and several other Linux scsi drivers and kernel docs. * ! 8: * * ! 9: * The driver currently: * ! 10: * -supports all EATA-PIO boards * ! 11: * -only supports DASD devices * ! 12: * * ! 13: * (c)1993-96 Michael Neuffer, Alfred Arnold * ! 14: * [email protected] * ! 15: * [email protected] * ! 16: * * ! 17: * This program is free software; you can redistribute it * ! 18: * and/or modify it under the terms of the GNU General * ! 19: * Public License as published by the Free Software * ! 20: * Foundation; either version 2 of the License, or * ! 21: * (at your option) any later version. * ! 22: * * ! 23: * This program is distributed in the hope that it will be * ! 24: * useful, but WITHOUT ANY WARRANTY; without even the * ! 25: * implied warranty of MERCHANTABILITY or FITNESS FOR A * ! 26: * PARTICULAR PURPOSE. See the GNU General Public License * ! 27: * for more details. * ! 28: * * ! 29: * You should have received a copy of the GNU General * ! 30: * Public License along with this kernel; if not, write to * ! 31: * the Free Software Foundation, Inc., 675 Mass Ave, * ! 32: * Cambridge, MA 02139, USA. * ! 33: * * ! 34: ************************************************************ ! 35: * last change: 96/07/16 OS: Linux 2.0.8 * ! 36: ************************************************************/ ! 37: ! 38: /* Look in eata_pio.h for configuration information */ ! 39: ! 40: #include <linux/module.h> ! 41: ! 42: #include <linux/kernel.h> ! 43: #include <linux/sched.h> ! 44: #include <linux/string.h> ! 45: #include <linux/ioport.h> ! 46: #include <linux/malloc.h> ! 47: #include <linux/in.h> ! 48: #include <linux/bios32.h> ! 49: #include <linux/pci.h> ! 50: #include <linux/proc_fs.h> ! 51: #include <asm/io.h> ! 52: #include "eata_pio.h" ! 53: #include "eata_dma_proc.h" ! 54: #include "scsi.h" ! 55: #include "sd.h" ! 56: ! 57: #include <linux/stat.h> ! 58: #include <linux/config.h> /* for CONFIG_PCI */ ! 59: ! 60: struct proc_dir_entry proc_scsi_eata_pio = { ! 61: PROC_SCSI_EATA_PIO, 9, "eata_pio", ! 62: S_IFDIR | S_IRUGO | S_IXUGO, 2 ! 63: }; ! 64: ! 65: static uint ISAbases[MAXISA] = ! 66: {0x1F0, 0x170, 0x330, 0x230}; ! 67: static uint ISAirqs[MAXISA] = ! 68: {14,12,15,11}; ! 69: static unchar EISAbases[] = ! 70: {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; ! 71: static uint registered_HBAs = 0; ! 72: static struct Scsi_Host *last_HBA = NULL; ! 73: static struct Scsi_Host *first_HBA = NULL; ! 74: static unchar reg_IRQ[] = ! 75: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! 76: static unchar reg_IRQL[] = ! 77: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! 78: ! 79: static ulong int_counter = 0; ! 80: static ulong queue_counter = 0; ! 81: ! 82: #include "eata_pio_proc.c" ! 83: ! 84: #ifdef MODULE ! 85: int eata_pio_release(struct Scsi_Host *sh) ! 86: { ! 87: if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); ! 88: else reg_IRQ[sh->irq]--; ! 89: if (SD(sh)->channel == 0) { ! 90: if (sh->io_port && sh->n_io_port) ! 91: release_region(sh->io_port, sh->n_io_port); ! 92: } ! 93: return(TRUE); ! 94: } ! 95: #endif ! 96: ! 97: void IncStat(Scsi_Pointer *SCp, uint Increment) ! 98: { ! 99: SCp->ptr+=Increment; ! 100: if ((SCp->this_residual-=Increment)==0) ! 101: { ! 102: if ((--SCp->buffers_residual)==0) SCp->Status=FALSE; ! 103: else ! 104: { ! 105: SCp->buffer++; ! 106: SCp->ptr=SCp->buffer->address; ! 107: SCp->this_residual=SCp->buffer->length; ! 108: } ! 109: } ! 110: } ! 111: ! 112: void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs) ! 113: { ! 114: uint eata_stat = 0xfffff; ! 115: Scsi_Cmnd *cmd; ! 116: hostdata *hd; ! 117: struct eata_ccb *cp; ! 118: uint base; ! 119: ulong flags; ! 120: uint x,z; ! 121: struct Scsi_Host *sh; ! 122: ushort zwickel=0; ! 123: unchar stat,odd; ! 124: ! 125: save_flags(flags); ! 126: cli(); ! 127: ! 128: for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) { ! 129: if (sh->irq != irq) ! 130: continue; ! 131: if (inb((uint)sh->base + HA_RSTATUS) & HA_SBUSY) ! 132: continue; ! 133: ! 134: int_counter++; ! 135: ! 136: hd=SD(sh); ! 137: ! 138: cp = &hd->ccb[0]; ! 139: cmd = cp->cmd; ! 140: base = (uint) cmd->host->base; ! 141: ! 142: do ! 143: { ! 144: stat=inb(base+HA_RSTATUS); ! 145: if (stat&HA_SDRQ) ! 146: if (cp->DataIn) ! 147: { ! 148: z=256; odd=FALSE; ! 149: while ((cmd->SCp.Status)&&((z>0)||(odd))) ! 150: { ! 151: if (odd) ! 152: { ! 153: *(cmd->SCp.ptr)=zwickel>>8; ! 154: IncStat(&cmd->SCp,1); ! 155: odd=FALSE; ! 156: } ! 157: x=min(z,cmd->SCp.this_residual/2); ! 158: insw(base+HA_RDATA,cmd->SCp.ptr,x); ! 159: z-=x; ! 160: IncStat(&cmd->SCp,2*x); ! 161: if ((z>0)&&(cmd->SCp.this_residual==1)) ! 162: { ! 163: zwickel=inw(base+HA_RDATA); ! 164: *(cmd->SCp.ptr)=zwickel&0xff; ! 165: IncStat(&cmd->SCp,1); z--; ! 166: odd=TRUE; ! 167: } ! 168: } ! 169: while (z>0) { ! 170: zwickel=inw(base+HA_RDATA); ! 171: z--; ! 172: } ! 173: } ! 174: else /* cp->DataOut */ ! 175: { ! 176: odd=FALSE; z=256; ! 177: while ((cmd->SCp.Status)&&((z>0)||(odd))) ! 178: { ! 179: if (odd) ! 180: { ! 181: zwickel+=*(cmd->SCp.ptr)<<8; ! 182: IncStat(&cmd->SCp,1); ! 183: outw(zwickel,base+HA_RDATA); ! 184: z--; ! 185: odd=FALSE; ! 186: } ! 187: x=min(z,cmd->SCp.this_residual/2); ! 188: outsw(base+HA_RDATA,cmd->SCp.ptr,x); ! 189: z-=x; ! 190: IncStat(&cmd->SCp,2*x); ! 191: if ((z>0)&&(cmd->SCp.this_residual==1)) ! 192: { ! 193: zwickel=*(cmd->SCp.ptr); ! 194: zwickel&=0xff; ! 195: IncStat(&cmd->SCp,1); ! 196: odd=TRUE; ! 197: } ! 198: } ! 199: while (z>0||odd) { ! 200: outw(zwickel,base+HA_RDATA); ! 201: z--; ! 202: odd=FALSE; ! 203: } ! 204: } ! 205: } ! 206: while ((stat&HA_SDRQ)||((stat&HA_SMORE)&&hd->moresupport)); ! 207: ! 208: /* terminate handler if HBA goes busy again, i.e. transfers ! 209: * more data */ ! 210: ! 211: if (stat&HA_SBUSY) break; ! 212: ! 213: /* OK, this is quite stupid, but I haven't found any correct ! 214: * way to get HBA&SCSI status so far */ ! 215: ! 216: if (!(inb(base+HA_RSTATUS)&HA_SERROR)) ! 217: { ! 218: cmd->result=(DID_OK<<16); ! 219: hd->devflags|=(1<<cp->cp_id); ! 220: } ! 221: else if (hd->devflags&1<<cp->cp_id) ! 222: cmd->result=(DID_OK<<16)+0x02; ! 223: else cmd->result=(DID_NO_CONNECT<<16); ! 224: ! 225: if (cp->status == LOCKED) { ! 226: cp->status = FREE; ! 227: eata_stat = inb(base + HA_RSTATUS); ! 228: printk(KERN_NOTICE "eata_pio: int_handler, freeing locked " ! 229: "queueslot\n"); ! 230: DBG(DBG_INTR&&DBG_DELAY,DELAY(1)); ! 231: restore_flags(flags); ! 232: return; ! 233: } ! 234: ! 235: #if DBG_INTR2 ! 236: if (stat != 0x50) ! 237: printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, ! 238: cmd->result); ! 239: DBG(DBG_INTR&&DBG_DELAY,DELAY(1)); ! 240: #endif ! 241: ! 242: cp->status = FREE; /* now we can release the slot */ ! 243: ! 244: restore_flags(flags); ! 245: cmd->scsi_done(cmd); ! 246: save_flags(flags); ! 247: cli(); ! 248: } ! 249: restore_flags(flags); ! 250: ! 251: return; ! 252: } ! 253: ! 254: inline uint eata_pio_send_command(uint base, unchar command) ! 255: { ! 256: uint loop = HZ/2; ! 257: ! 258: while (inb(base + HA_RSTATUS) & HA_SBUSY) ! 259: if (--loop == 0) ! 260: return(TRUE); ! 261: ! 262: /* Enable interrupts for HBA. It is not the best way to do it at this ! 263: * place, but I hope that it doesn't interfere with the IDE driver ! 264: * initialization this way */ ! 265: ! 266: outb(HA_CTRL_8HEADS,base+HA_CTRLREG); ! 267: ! 268: outb(command, base + HA_WCOMMAND); ! 269: return(FALSE); ! 270: } ! 271: ! 272: int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) ! 273: { ! 274: uint x, y; ! 275: long flags; ! 276: uint base; ! 277: ! 278: hostdata *hd; ! 279: struct Scsi_Host *sh; ! 280: struct eata_ccb *cp; ! 281: ! 282: save_flags(flags); ! 283: cli(); ! 284: ! 285: queue_counter++; ! 286: ! 287: hd = HD(cmd); ! 288: sh = cmd->host; ! 289: base = (uint) sh->base; ! 290: ! 291: /* use only slot 0, as 2001 can handle only one cmd at a time */ ! 292: ! 293: y = x = 0; ! 294: ! 295: if (hd->ccb[y].status!=FREE) { ! 296: ! 297: DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n", ! 298: sh->can_queue,x,y)); ! 299: #if DEBUG_EATA ! 300: panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld " ! 301: "intrno: %ld\n", queue_counter, int_counter); ! 302: #else ! 303: panic(KERN_EMERG "eata_pio: run out of queue slots....\n"); ! 304: #endif ! 305: } ! 306: ! 307: cp = &hd->ccb[y]; ! 308: ! 309: memset(cp, 0, sizeof(struct eata_ccb)); ! 310: memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); ! 311: ! 312: cp->status = USED; /* claim free slot */ ! 313: ! 314: DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" ! 315: " %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y)); ! 316: DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); ! 317: ! 318: cmd->scsi_done = (void *)done; ! 319: ! 320: switch (cmd->cmnd[0]) { ! 321: case CHANGE_DEFINITION: case COMPARE: case COPY: ! 322: case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: ! 323: case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER: ! 324: case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: ! 325: case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: ! 326: case WRITE_6: case WRITE_10: case WRITE_VERIFY: ! 327: case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: ! 328: case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: ! 329: case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: ! 330: case MEDIUM_SCAN: case SEND_VOLUME_TAG: ! 331: case 0xea: /* alternate number for WRITE LONG */ ! 332: cp->DataOut = TRUE; /* Output mode */ ! 333: break; ! 334: case TEST_UNIT_READY: ! 335: default: ! 336: cp->DataIn = TRUE; /* Input mode */ ! 337: } ! 338: ! 339: cp->Interpret = (cmd->target == hd->hostid); ! 340: cp->cp_datalen = htonl((ulong)cmd->request_bufflen); ! 341: cp->Auto_Req_Sen = FALSE; ! 342: cp->cp_reqDMA = htonl(0); ! 343: cp->reqlen = 0; ! 344: ! 345: cp->cp_id = cmd->target; ! 346: cp->cp_lun = cmd->lun; ! 347: cp->cp_dispri = FALSE; ! 348: cp->cp_identify = TRUE; ! 349: memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); ! 350: ! 351: cp->cp_statDMA = htonl(0); ! 352: ! 353: cp->cp_viraddr = cp; ! 354: cp->cmd = cmd; ! 355: cmd->host_scribble = (char *)&hd->ccb[y]; ! 356: ! 357: if (cmd->use_sg == 0) ! 358: { ! 359: cmd->SCp.buffers_residual=1; ! 360: cmd->SCp.ptr = cmd->request_buffer; ! 361: cmd->SCp.this_residual = cmd->request_bufflen; ! 362: cmd->SCp.buffer = NULL; ! 363: } else { ! 364: cmd->SCp.buffer = cmd->request_buffer; ! 365: cmd->SCp.buffers_residual = cmd->use_sg; ! 366: cmd->SCp.ptr = cmd->SCp.buffer->address; ! 367: cmd->SCp.this_residual = cmd->SCp.buffer->length; ! 368: } ! 369: cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes ! 370: * are to transfer */ ! 371: ! 372: if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) ! 373: { ! 374: cmd->result = DID_BUS_BUSY << 16; ! 375: printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " ! 376: "returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid); ! 377: done(cmd); ! 378: cp->status = FREE; ! 379: restore_flags(flags); ! 380: return (0); ! 381: } ! 382: while (!(inb(base + HA_RSTATUS) & HA_SDRQ)); ! 383: outsw(base + HA_RDATA, cp, hd->cplen); ! 384: outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); ! 385: for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA); ! 386: ! 387: DBG(DBG_QUEUE,printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " ! 388: "lun: %x slot %d irq %d\n", (long)sh->base, cmd->pid, ! 389: cmd->target, cmd->lun, y, sh->irq)); ! 390: DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); ! 391: ! 392: restore_flags(flags); ! 393: return (0); ! 394: } ! 395: ! 396: int eata_pio_abort(Scsi_Cmnd * cmd) ! 397: { ! 398: ulong flags; ! 399: uint loop = HZ; ! 400: ! 401: save_flags(flags); ! 402: cli(); ! 403: ! 404: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " ! 405: "target: %x lun: %x reason %x\n", cmd->pid, ! 406: cmd->target, cmd->lun, cmd->abort_reason)); ! 407: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 408: ! 409: ! 410: while (inb((uint)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) ! 411: if (--loop == 0) { ! 412: printk(KERN_WARNING "eata_pio: abort, timeout error.\n"); ! 413: restore_flags(flags); ! 414: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 415: return (SCSI_ABORT_ERROR); ! 416: } ! 417: if (CD(cmd)->status == FREE) { ! 418: DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n")); ! 419: restore_flags(flags); ! 420: return (SCSI_ABORT_NOT_RUNNING); ! 421: } ! 422: if (CD(cmd)->status == USED) { ! 423: DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n")); ! 424: restore_flags(flags); ! 425: return (SCSI_ABORT_BUSY); /* SNOOZE */ ! 426: } ! 427: if (CD(cmd)->status == RESET) { ! 428: restore_flags(flags); ! 429: printk(KERN_WARNING "eata_pio: abort, command reset error.\n"); ! 430: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 431: return (SCSI_ABORT_ERROR); ! 432: } ! 433: if (CD(cmd)->status == LOCKED) { ! 434: restore_flags(flags); ! 435: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot " ! 436: "locked.\n")); ! 437: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 438: return (SCSI_ABORT_NOT_RUNNING); ! 439: } ! 440: restore_flags(flags); ! 441: panic("eata_pio: abort: invalid slot status\n"); ! 442: } ! 443: ! 444: int eata_pio_reset(Scsi_Cmnd * cmd, unsigned int dummy) ! 445: { ! 446: uint x, time, limit = 0; ! 447: ulong flags; ! 448: unchar success = FALSE; ! 449: Scsi_Cmnd *sp; ! 450: ! 451: save_flags(flags); ! 452: cli(); ! 453: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" ! 454: " %x lun: %x reason %x\n", cmd->pid, cmd->target, ! 455: cmd->lun, cmd->abort_reason)); ! 456: ! 457: if (HD(cmd)->state == RESET) { ! 458: printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n"); ! 459: restore_flags(flags); ! 460: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 461: return (SCSI_RESET_ERROR); ! 462: } ! 463: ! 464: /* force all slots to be free */ ! 465: ! 466: for (x = 0; x < cmd->host->can_queue; x++) { ! 467: ! 468: if (HD(cmd)->ccb[x].status == FREE) ! 469: continue; ! 470: ! 471: sp = HD(cmd)->ccb[x].cmd; ! 472: HD(cmd)->ccb[x].status = RESET; ! 473: printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, ! 474: sp->pid); ! 475: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 476: ! 477: if (sp == NULL) ! 478: panic("eata_pio_reset: slot %d, sp==NULL.\n", x); ! 479: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 480: } ! 481: ! 482: /* hard reset the HBA */ ! 483: outb(EATA_CMD_RESET, (uint) cmd->host->base+HA_WCOMMAND); ! 484: ! 485: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n")); ! 486: HD(cmd)->state = RESET; ! 487: ! 488: time = jiffies; ! 489: while (jiffies < (time + (3 * HZ)) && limit++ < 10000000); ! 490: ! 491: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " ! 492: "loops %d.\n", limit)); ! 493: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 494: ! 495: for (x = 0; x < cmd->host->can_queue; x++) { ! 496: ! 497: /* Skip slots already set free by interrupt */ ! 498: if (HD(cmd)->ccb[x].status != RESET) ! 499: continue; ! 500: ! 501: sp = HD(cmd)->ccb[x].cmd; ! 502: sp->result = DID_RESET << 16; ! 503: ! 504: /* This mailbox is terminated */ ! 505: printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n",x); ! 506: HD(cmd)->ccb[x].status = FREE; ! 507: ! 508: restore_flags(flags); ! 509: sp->scsi_done(sp); ! 510: cli(); ! 511: } ! 512: ! 513: HD(cmd)->state = FALSE; ! 514: restore_flags(flags); ! 515: ! 516: if (success) { /* hmmm... */ ! 517: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n")); ! 518: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 519: return (SCSI_RESET_SUCCESS); ! 520: } else { ! 521: DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n")); ! 522: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 523: return (SCSI_RESET_PUNT); ! 524: } ! 525: } ! 526: ! 527: char * get_pio_board_data(ulong base, uint irq, uint id, ulong cplen, ushort cppadlen) ! 528: { ! 529: struct eata_ccb cp; ! 530: static char buff[256]; ! 531: int z; ! 532: ! 533: memset(&cp, 0, sizeof(struct eata_ccb)); ! 534: memset(buff, 0, sizeof(buff)); ! 535: ! 536: cp.DataIn = TRUE; ! 537: cp.Interpret = TRUE; /* Interpret command */ ! 538: ! 539: cp.cp_datalen = htonl(254); ! 540: cp.cp_dataDMA = htonl(0); ! 541: ! 542: cp.cp_id = id; ! 543: cp.cp_lun = 0; ! 544: ! 545: cp.cp_cdb[0] = INQUIRY; ! 546: cp.cp_cdb[1] = 0; ! 547: cp.cp_cdb[2] = 0; ! 548: cp.cp_cdb[3] = 0; ! 549: cp.cp_cdb[4] = 254; ! 550: cp.cp_cdb[5] = 0; ! 551: ! 552: if (eata_pio_send_command((uint) base, EATA_CMD_PIO_SEND_CP)) ! 553: return (NULL); ! 554: while (!(inb(base + HA_RSTATUS) & HA_SDRQ)); ! 555: outsw(base + HA_RDATA, &cp, cplen); ! 556: outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); ! 557: for (z = 0; z < cppadlen; z++) outw(0, base + HA_RDATA); ! 558: ! 559: while (inb(base + HA_RSTATUS) & HA_SBUSY); ! 560: if (inb(base + HA_RSTATUS) & HA_SERROR) ! 561: return (NULL); ! 562: else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) ! 563: return (NULL); ! 564: else ! 565: { ! 566: insw(base+HA_RDATA, &buff, 127); ! 567: while (inb(base + HA_RSTATUS)&HA_SDRQ) inw(base + HA_RDATA); ! 568: return (buff); ! 569: } ! 570: } ! 571: ! 572: int get_pio_conf_PIO(u32 base, struct get_conf *buf) ! 573: { ! 574: ulong loop = HZ/2; ! 575: int z; ! 576: ushort *p; ! 577: ! 578: if(check_region(base, 9)) ! 579: return (FALSE); ! 580: ! 581: memset(buf, 0, sizeof(struct get_conf)); ! 582: ! 583: while (inb(base + HA_RSTATUS) & HA_SBUSY) ! 584: if (--loop == 0) ! 585: return (FALSE); ! 586: ! 587: DBG(DBG_PIO && DBG_PROBE, ! 588: printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base)); ! 589: eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG); ! 590: ! 591: loop = HZ/2; ! 592: for (p = (ushort *) buf; ! 593: (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) { ! 594: while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) ! 595: if (--loop == 0) ! 596: return (FALSE); ! 597: ! 598: loop = HZ/2; ! 599: *p = inw(base + HA_RDATA); ! 600: } ! 601: if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ ! 602: if (htonl(EATA_SIGNATURE) == buf->signature) { ! 603: DBG(DBG_PIO&&DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " ! 604: "at %#4x EATA Level: %x\n", base, ! 605: (uint) (buf->version))); ! 606: ! 607: while (inb(base + HA_RSTATUS) & HA_SDRQ) ! 608: inw(base + HA_RDATA); ! 609: if(ALLOW_DMA_BOARDS == FALSE) { ! 610: for (z = 0; z < MAXISA; z++) ! 611: if (base == ISAbases[z]) { ! 612: buf->IRQ = ISAirqs[z]; ! 613: break; ! 614: } ! 615: } ! 616: return (TRUE); ! 617: } ! 618: } else { ! 619: DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " ! 620: "for HBA at %x\n", base)); ! 621: } ! 622: return (FALSE); ! 623: } ! 624: ! 625: void print_pio_config(struct get_conf *gc) ! 626: { ! 627: printk("Please check values: (read config data)\n"); ! 628: printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n", ! 629: (uint) ntohl(gc->len), gc->version, ! 630: gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support); ! 631: printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", ! 632: gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], ! 633: gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND); ! 634: printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", ! 635: gc->IRQ, gc->IRQ_TR, gc->FORCADR, ! 636: gc->MAX_CHAN, gc->ID_qest); ! 637: DBG(DPT_DEBUG, DELAY(14)); ! 638: } ! 639: ! 640: static uint print_selftest(uint base) ! 641: { ! 642: unchar buffer[512]; ! 643: #ifdef VERBOSE_SETUP ! 644: int z; ! 645: #endif ! 646: ! 647: printk("eata_pio: executing controller self test & setup...\n"); ! 648: while (inb(base + HA_RSTATUS) & HA_SBUSY); ! 649: outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND); ! 650: do { ! 651: while (inb(base + HA_RSTATUS) & HA_SBUSY) ! 652: /* nothing */ ; ! 653: if (inb(base + HA_RSTATUS) & HA_SDRQ) ! 654: { ! 655: insw(base + HA_RDATA, &buffer, 256); ! 656: #ifdef VERBOSE_SETUP ! 657: /* no beeps please... */ ! 658: for (z = 0; z < 511 && buffer[z]; z++) ! 659: if (buffer[z] != 7) printk("%c", buffer[z]); ! 660: #endif ! 661: } ! 662: } while (inb(base+HA_RSTATUS) & (HA_SBUSY|HA_SDRQ)); ! 663: ! 664: return (!(inb(base+HA_RSTATUS) & HA_SERROR)); ! 665: } ! 666: ! 667: int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt) ! 668: { ! 669: ulong size = 0; ! 670: char *buff; ! 671: ulong cplen; ! 672: ushort cppadlen; ! 673: struct Scsi_Host *sh; ! 674: hostdata *hd; ! 675: ! 676: DBG(DBG_REGISTER, print_pio_config(gc)); ! 677: ! 678: if (gc->DMA_support == TRUE) { ! 679: printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n",base); ! 680: if(ALLOW_DMA_BOARDS == FALSE) ! 681: return (FALSE); ! 682: } ! 683: ! 684: if ((buff = get_pio_board_data((uint)base, gc->IRQ, gc->scsi_id[3], ! 685: cplen =(htonl(gc->cplen )+1)/2, ! 686: cppadlen=(htons(gc->cppadlen)+1)/2)) == NULL) ! 687: { ! 688: printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (ulong) base); ! 689: return (FALSE); ! 690: } ! 691: ! 692: if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) ! 693: { ! 694: printk("HBA at %#lx failed while performing self test & setup.\n", ! 695: (ulong) base); ! 696: return (FALSE); ! 697: } ! 698: ! 699: if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */ ! 700: if (!request_irq(gc->IRQ, eata_pio_int_handler, SA_INTERRUPT, ! 701: "EATA-PIO", NULL)){ ! 702: reg_IRQ[gc->IRQ]++; ! 703: if (!gc->IRQ_TR) ! 704: reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ ! 705: } else { ! 706: printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ); ! 707: return (FALSE); ! 708: } ! 709: } else { /* More than one HBA on this IRQ */ ! 710: if (reg_IRQL[gc->IRQ] == TRUE) { ! 711: printk("Can't support more than one HBA on this IRQ,\n" ! 712: " if the IRQ is edge triggered. Sorry.\n"); ! 713: return (FALSE); ! 714: } else ! 715: reg_IRQ[gc->IRQ]++; ! 716: } ! 717: ! 718: request_region(base, 8, "eata_pio"); ! 719: ! 720: size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)); ! 721: ! 722: sh = scsi_register(tpnt, size); ! 723: hd = SD(sh); ! 724: ! 725: memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz))); ! 726: memset(hd->reads, 0, sizeof(ulong) * 26); ! 727: ! 728: strncpy(SD(sh)->vendor, &buff[8], 8); ! 729: SD(sh)->vendor[8] = 0; ! 730: strncpy(SD(sh)->name, &buff[16], 17); ! 731: SD(sh)->name[17] = 0; ! 732: SD(sh)->revision[0] = buff[32]; ! 733: SD(sh)->revision[1] = buff[33]; ! 734: SD(sh)->revision[2] = buff[34]; ! 735: SD(sh)->revision[3] = '.'; ! 736: SD(sh)->revision[4] = buff[35]; ! 737: SD(sh)->revision[5] = 0; ! 738: ! 739: switch (ntohl(gc->len)) { ! 740: case 0x1c: ! 741: SD(sh)->EATA_revision = 'a'; ! 742: break; ! 743: case 0x1e: ! 744: SD(sh)->EATA_revision = 'b'; ! 745: break; ! 746: case 0x22: ! 747: SD(sh)->EATA_revision = 'c'; ! 748: break; ! 749: case 0x24: ! 750: SD(sh)->EATA_revision = 'z'; ! 751: default: ! 752: SD(sh)->EATA_revision = '?'; ! 753: } ! 754: ! 755: if(ntohl(gc->len) >= 0x22) { ! 756: if (gc->is_PCI == TRUE) ! 757: hd->bustype = IS_PCI; ! 758: else if (gc->is_EISA == TRUE) ! 759: hd->bustype = IS_EISA; ! 760: else ! 761: hd->bustype = IS_ISA; ! 762: } else { ! 763: if (buff[21] == '4') ! 764: hd->bustype = IS_PCI; ! 765: else if (buff[21] == '2') ! 766: hd->bustype = IS_EISA; ! 767: else ! 768: hd->bustype = IS_ISA; ! 769: } ! 770: ! 771: SD(sh)->cplen=cplen; ! 772: SD(sh)->cppadlen=cppadlen; ! 773: SD(sh)->hostid=gc->scsi_id[3]; ! 774: SD(sh)->devflags=1<<gc->scsi_id[3]; ! 775: SD(sh)->moresupport=gc->MORE_support; ! 776: sh->unique_id = base; ! 777: sh->base = (char *) base; ! 778: sh->io_port = base; ! 779: sh->n_io_port = 8; ! 780: sh->irq = gc->IRQ; ! 781: sh->dma_channel = PIO; ! 782: sh->this_id = gc->scsi_id[3]; ! 783: sh->can_queue = 1; ! 784: sh->cmd_per_lun = 1; ! 785: sh->sg_tablesize = SG_ALL; ! 786: ! 787: hd->channel = 0; ! 788: ! 789: sh->max_id = 8; ! 790: sh->max_lun = 8; ! 791: ! 792: if (gc->SECOND) ! 793: hd->primary = FALSE; ! 794: else ! 795: hd->primary = TRUE; ! 796: ! 797: sh->unchecked_isa_dma = FALSE; /* We can only do PIO */ ! 798: ! 799: hd->next = NULL; /* build a linked list of all HBAs */ ! 800: hd->prev = last_HBA; ! 801: if(hd->prev != NULL) ! 802: SD(hd->prev)->next = sh; ! 803: last_HBA = sh; ! 804: if (first_HBA == NULL) ! 805: first_HBA = sh; ! 806: registered_HBAs++; ! 807: return (1); ! 808: } ! 809: ! 810: void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 811: { ! 812: int i; ! 813: ! 814: for (i = 0; i < MAXISA; i++) { ! 815: if (ISAbases[i]) { ! 816: if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE){ ! 817: register_pio_HBA(ISAbases[i], buf, tpnt); ! 818: } ! 819: ISAbases[i] = 0; ! 820: } ! 821: } ! 822: return; ! 823: } ! 824: ! 825: void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 826: { ! 827: u32 base; ! 828: int i; ! 829: ! 830: #if CHECKPAL ! 831: u8 pal1, pal2, pal3; ! 832: #endif ! 833: ! 834: for (i = 0; i < MAXEISA; i++) { ! 835: if (EISAbases[i] == TRUE) { /* Still a possibility ? */ ! 836: ! 837: base = 0x1c88 + (i * 0x1000); ! 838: #if CHECKPAL ! 839: pal1 = inb((u16)base - 8); ! 840: pal2 = inb((u16)base - 7); ! 841: pal3 = inb((u16)base - 6); ! 842: ! 843: if (((pal1 == 0x12) && (pal2 == 0x14)) || ! 844: ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ! 845: ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) { ! 846: DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " ! 847: "%x %x %x \n", ! 848: (int)pal1, (int)pal2, (int)pal3)); ! 849: #endif ! 850: if (get_pio_conf_PIO(base, buf) == TRUE) { ! 851: DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf)); ! 852: if (buf->IRQ) { ! 853: register_pio_HBA(base, buf, tpnt); ! 854: } else ! 855: printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " ! 856: "removed from list\n"); ! 857: } ! 858: /* Nothing found here so we take it from the list */ ! 859: EISAbases[i] = 0; ! 860: #if CHECKPAL ! 861: } ! 862: #endif ! 863: } ! 864: } ! 865: return; ! 866: } ! 867: ! 868: void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 869: { ! 870: ! 871: #ifndef CONFIG_PCI ! 872: printk(KERN_ERR "eata_pio: kernel PCI support not enabled. Skipping scan " ! 873: "for PCI HBAs.\n"); ! 874: #else ! 875: ! 876: u8 pci_bus, pci_device_fn; ! 877: static s16 pci_index = 0; /* Device index to PCI BIOS calls */ ! 878: u32 base = 0; ! 879: u16 com_adr; ! 880: u16 rev_device; ! 881: u32 error, i, x; ! 882: ! 883: if (pcibios_present()) { ! 884: for (i = 0; i <= MAXPCI; ++i, ++pci_index) { ! 885: if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, ! 886: pci_index, &pci_bus, &pci_device_fn)) ! 887: break; ! 888: DBG(DBG_PROBE && DBG_PCI, ! 889: printk("eata_pio: HBA at bus %d, device %d," ! 890: " function %d, index %d\n", (s32)pci_bus, ! 891: (s32)((pci_device_fn & 0xf8) >> 3), ! 892: (s32)(pci_device_fn & 7), pci_index)); ! 893: ! 894: if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, ! 895: PCI_CLASS_DEVICE, &rev_device))) { ! 896: if (rev_device == PCI_CLASS_STORAGE_SCSI) { ! 897: if (!(error = pcibios_read_config_word(pci_bus, ! 898: pci_device_fn, PCI_COMMAND, ! 899: (u16 *) & com_adr))) { ! 900: if (!((com_adr & PCI_COMMAND_IO) && ! 901: (com_adr & PCI_COMMAND_MASTER))) { ! 902: printk("HBA has IO or BUSMASTER mode disabled\n"); ! 903: continue; ! 904: } ! 905: } else ! 906: printk("eata_pio: error %x while reading " ! 907: "PCI_COMMAND\n", error); ! 908: } else ! 909: printk("DEVICECLASSID %x didn't match\n", rev_device); ! 910: } else { ! 911: printk("eata_pio: error %x while reading PCI_CLASS_BASE\n", ! 912: error); ! 913: continue; ! 914: } ! 915: ! 916: if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, ! 917: PCI_BASE_ADDRESS_0, (int *) &base))){ ! 918: ! 919: /* Check if the address is valid */ ! 920: if (base & 0x01) { ! 921: base &= 0xfffffffe; ! 922: /* EISA tag there ? */ ! 923: if ((inb(base) == 0x12) && (inb(base + 1) == 0x14)) ! 924: continue; /* Jep, it's forced, so move on */ ! 925: base += 0x10; /* Now, THIS is the real address */ ! 926: if (base != 0x1f8) { ! 927: /* We didn't find it in the primary search */ ! 928: if (get_pio_conf_PIO(base, buf) == TRUE) { ! 929: if (buf->FORCADR) /* If the address is forced */ ! 930: continue; /* we'll find it later */ ! 931: ! 932: /* OK. We made it till here, so we can go now ! 933: * and register it. We only have to check and ! 934: * eventually remove it from the EISA and ISA list ! 935: */ ! 936: ! 937: register_pio_HBA(base, buf, tpnt); ! 938: ! 939: if (base < 0x1000) { ! 940: for (x = 0; x < MAXISA; ++x) { ! 941: if (ISAbases[x] == base) { ! 942: ISAbases[x] = 0; ! 943: break; ! 944: } ! 945: } ! 946: } else if ((base & 0x0fff) == 0x0c88) { ! 947: x = (base >> 12) & 0x0f; ! 948: EISAbases[x] = 0; ! 949: } ! 950: continue; /* break; */ ! 951: } ! 952: } ! 953: } ! 954: } else ! 955: printk("eata_pio: error %x while reading " ! 956: "PCI_BASE_ADDRESS_0\n", error); ! 957: } ! 958: } else ! 959: printk("eata_pio: No BIOS32 extensions present. This driver release " ! 960: "still depends on it.\n" ! 961: " Skipping scan for PCI HBAs.\n"); ! 962: #endif /* #ifndef CONFIG_PCI */ ! 963: return; ! 964: } ! 965: ! 966: ! 967: int eata_pio_detect(Scsi_Host_Template * tpnt) ! 968: { ! 969: struct Scsi_Host *HBA_ptr; ! 970: struct get_conf gc; ! 971: int i; ! 972: ! 973: DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, ! 974: printk("Using lots of delays to let you read the debugging output\n")); ! 975: ! 976: tpnt->proc_dir = &proc_scsi_eata_pio; ! 977: ! 978: find_pio_PCI(&gc, tpnt); ! 979: ! 980: find_pio_EISA(&gc, tpnt); ! 981: ! 982: find_pio_ISA(&gc, tpnt); ! 983: ! 984: for (i = 0; i <= MAXIRQ; i++) ! 985: if (reg_IRQ[i]) ! 986: request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", NULL); ! 987: ! 988: HBA_ptr = first_HBA; ! 989: ! 990: if (registered_HBAs != 0) { ! 991: printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n" ! 992: "(c) 1993-95 Michael Neuffer, [email protected]\n" ! 993: " Alfred Arnold, [email protected]\n" ! 994: "This release only supports DASD devices (harddisks)\n", ! 995: VER_MAJOR, VER_MINOR, VER_SUB); ! 996: ! 997: printk("Registered HBAs:\n"); ! 998: printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:" ! 999: " QS: SG: CPL:\n"); ! 1000: for (i = 1; i <= registered_HBAs; i++) { ! 1001: printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d %d %d %c" ! 1002: " %2d %2d %2d\n", ! 1003: HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, ! 1004: SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? ! 1005: "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ", ! 1006: (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, ! 1007: HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', ! 1008: HBA_ptr->can_queue, HBA_ptr->sg_tablesize, ! 1009: HBA_ptr->cmd_per_lun); ! 1010: HBA_ptr = SD(HBA_ptr)->next; ! 1011: } ! 1012: } ! 1013: DBG(DPT_DEBUG,DELAY(12)); ! 1014: ! 1015: return (registered_HBAs); ! 1016: } ! 1017: ! 1018: #ifdef MODULE ! 1019: /* Eventually this will go into an include file, but this will be later */ ! 1020: Scsi_Host_Template driver_template = EATA_PIO; ! 1021: ! 1022: #include "scsi_module.c" ! 1023: #endif ! 1024: ! 1025: /* ! 1026: * Overrides for Emacs so that we almost follow Linus's tabbing style. ! 1027: * Emacs will notice this stuff at the end of the file and automatically ! 1028: * adjust the settings for this buffer only. This must remain at the end ! 1029: * of the file. ! 1030: * --------------------------------------------------------------------------- ! 1031: * Local variables: ! 1032: * c-indent-level: 4 ! 1033: * c-brace-imaginary-offset: 0 ! 1034: * c-brace-offset: -4 ! 1035: * c-argdecl-indent: 4 ! 1036: * c-label-offset: -4 ! 1037: * c-continued-statement-offset: 4 ! 1038: * c-continued-brace-offset: 0 ! 1039: * indent-tabs-mode: nil ! 1040: * tab-width: 8 ! 1041: * End: ! 1042: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.