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