|
|
1.1 ! root 1: /************************************************************ ! 2: * * ! 3: * Linux EATA SCSI 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 ISA based EATA-DMA boards * ! 11: * like PM2011, PM2021, PM2041, PM3021 * ! 12: * -supports all EISA based EATA-DMA boards * ! 13: * like PM2012B, PM2022, PM2122, PM2322, PM2042, * ! 14: * PM3122, PM3222, PM3332 * ! 15: * -supports all PCI based EATA-DMA boards * ! 16: * like PM2024, PM2124, PM2044, PM2144, PM3224, * ! 17: * PM3334 * ! 18: * -supports the Wide, Ultra Wide and Differential * ! 19: * versions of the boards * ! 20: * -supports multiple HBAs with & without IRQ sharing * ! 21: * -supports all SCSI channels on multi channel boards * ! 22: * -supports ix86 and MIPS, untested on ALPHA * ! 23: * -needs identical IDs on all channels of a HBA * ! 24: * -can be loaded as module * ! 25: * -displays statistical and hardware information * ! 26: * in /proc/scsi/eata_dma * ! 27: * -provides rudimentary latency measurement * ! 28: * possibilities via /proc/scsi/eata_dma/<hostnum> * ! 29: * * ! 30: * (c)1993-96 Michael Neuffer * ! 31: * [email protected] * ! 32: * [email protected] * ! 33: * * ! 34: * This program is free software; you can redistribute it * ! 35: * and/or modify it under the terms of the GNU General * ! 36: * Public License as published by the Free Software * ! 37: * Foundation; either version 2 of the License, or * ! 38: * (at your option) any later version. * ! 39: * * ! 40: * This program is distributed in the hope that it will be * ! 41: * useful, but WITHOUT ANY WARRANTY; without even the * ! 42: * implied warranty of MERCHANTABILITY or FITNESS FOR A * ! 43: * PARTICULAR PURPOSE. See the GNU General Public License * ! 44: * for more details. * ! 45: * * ! 46: * You should have received a copy of the GNU General * ! 47: * Public License along with this kernel; if not, write to * ! 48: * the Free Software Foundation, Inc., 675 Mass Ave, * ! 49: * Cambridge, MA 02139, USA. * ! 50: * * ! 51: * I have to thank DPT for their excellent support. I took * ! 52: * me almost a year and a stopover at their HQ, on my first * ! 53: * trip to the USA, to get it, but since then they've been * ! 54: * very helpful and tried to give me all the infos and * ! 55: * support I need. * ! 56: * * ! 57: * Thanks also to Simon Shapiro, Greg Hosler and Mike * ! 58: * Jagdis who did a lot of testing and found quite a number * ! 59: * of bugs during the development. * ! 60: ************************************************************ ! 61: * last change: 96/10/21 OS: Linux 2.0.23 * ! 62: ************************************************************/ ! 63: ! 64: /* Look in eata_dma.h for configuration and revision information */ ! 65: ! 66: #include <linux/module.h> ! 67: #include <linux/kernel.h> ! 68: #include <linux/sched.h> ! 69: #include <linux/string.h> ! 70: #include <linux/ioport.h> ! 71: #include <linux/malloc.h> ! 72: #include <linux/in.h> ! 73: #include <linux/bios32.h> ! 74: #include <linux/pci.h> ! 75: #include <linux/proc_fs.h> ! 76: #include <linux/delay.h> ! 77: #include <asm/byteorder.h> ! 78: #include <asm/types.h> ! 79: #include <asm/io.h> ! 80: #include <asm/dma.h> ! 81: #include <asm/pgtable.h> ! 82: #ifdef __mips__ ! 83: #include <asm/cachectl.h> ! 84: #endif ! 85: #include <linux/blk.h> ! 86: #include "scsi.h" ! 87: #include "sd.h" ! 88: #include "hosts.h" ! 89: #include "eata_dma.h" ! 90: #include "eata_dma_proc.h" ! 91: ! 92: #include <linux/stat.h> ! 93: #include <linux/config.h> /* for CONFIG_PCI */ ! 94: ! 95: struct proc_dir_entry proc_scsi_eata_dma = { ! 96: PROC_SCSI_EATA, 8, "eata_dma", ! 97: S_IFDIR | S_IRUGO | S_IXUGO, 2 ! 98: }; ! 99: ! 100: static u32 ISAbases[] = ! 101: {0x1F0, 0x170, 0x330, 0x230}; ! 102: static unchar EISAbases[] = ! 103: {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; ! 104: static uint registered_HBAs = 0; ! 105: static struct Scsi_Host *last_HBA = NULL; ! 106: static struct Scsi_Host *first_HBA = NULL; ! 107: static unchar reg_IRQ[] = ! 108: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! 109: static unchar reg_IRQL[] = ! 110: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! 111: static struct eata_sp *status = 0; /* Statuspacket array */ ! 112: static void *dma_scratch = 0; ! 113: ! 114: static struct eata_register *fake_int_base; ! 115: static int fake_int_result; ! 116: static int fake_int_happened; ! 117: ! 118: static ulong int_counter = 0; ! 119: static ulong queue_counter = 0; ! 120: ! 121: void eata_scsi_done (Scsi_Cmnd * scmd) ! 122: { ! 123: scmd->request.rq_status = RQ_SCSI_DONE; ! 124: ! 125: if (scmd->request.sem != NULL) ! 126: up(scmd->request.sem); ! 127: ! 128: return; ! 129: } ! 130: ! 131: void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs) ! 132: { ! 133: fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS); ! 134: fake_int_happened = TRUE; ! 135: DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %p" ! 136: " res %#x\n", irq, fake_int_base, fake_int_result)); ! 137: return; ! 138: } ! 139: ! 140: #include "eata_dma_proc.c" ! 141: ! 142: #ifdef MODULE ! 143: int eata_release(struct Scsi_Host *sh) ! 144: { ! 145: uint i; ! 146: if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); ! 147: else reg_IRQ[sh->irq]--; ! 148: ! 149: scsi_init_free((void *)status, 512); ! 150: scsi_init_free((void *)dma_scratch - 4, 1024); ! 151: for (i = 0; i < sh->can_queue; i++){ /* Free all SG arrays */ ! 152: if(SD(sh)->ccb[i].sg_list != NULL) ! 153: scsi_init_free((void *) SD(sh)->ccb[i].sg_list, ! 154: sh->sg_tablesize * sizeof(struct eata_sg_list)); ! 155: } ! 156: ! 157: if (SD(sh)->channel == 0) { ! 158: if (sh->dma_channel != BUSMASTER) free_dma(sh->dma_channel); ! 159: if (sh->io_port && sh->n_io_port) ! 160: release_region(sh->io_port, sh->n_io_port); ! 161: } ! 162: return(TRUE); ! 163: } ! 164: #endif ! 165: ! 166: ! 167: inline void eata_latency_in(struct eata_ccb *cp, hostdata *hd) ! 168: { ! 169: uint time; ! 170: time = jiffies - cp->timestamp; ! 171: if(hd->all_lat[1] > time) ! 172: hd->all_lat[1] = time; ! 173: if(hd->all_lat[2] < time) ! 174: hd->all_lat[2] = time; ! 175: hd->all_lat[3] += time; ! 176: hd->all_lat[0]++; ! 177: if((cp->rw_latency) == WRITE) { /* was WRITE */ ! 178: if(hd->writes_lat[cp->sizeindex][1] > time) ! 179: hd->writes_lat[cp->sizeindex][1] = time; ! 180: if(hd->writes_lat[cp->sizeindex][2] < time) ! 181: hd->writes_lat[cp->sizeindex][2] = time; ! 182: hd->writes_lat[cp->sizeindex][3] += time; ! 183: hd->writes_lat[cp->sizeindex][0]++; ! 184: } else if((cp->rw_latency) == READ) { ! 185: if(hd->reads_lat[cp->sizeindex][1] > time) ! 186: hd->reads_lat[cp->sizeindex][1] = time; ! 187: if(hd->reads_lat[cp->sizeindex][2] < time) ! 188: hd->reads_lat[cp->sizeindex][2] = time; ! 189: hd->reads_lat[cp->sizeindex][3] += time; ! 190: hd->reads_lat[cp->sizeindex][0]++; ! 191: } ! 192: } ! 193: ! 194: inline void eata_latency_out(struct eata_ccb *cp, Scsi_Cmnd *cmd) ! 195: { ! 196: int x, z; ! 197: short *sho; ! 198: long *lon; ! 199: x = 0; /* just to keep GCC quiet */ ! 200: cp->timestamp = jiffies; /* For latency measurements */ ! 201: switch(cmd->cmnd[0]) { ! 202: case WRITE_6: ! 203: x = cmd->cmnd[4]/2; ! 204: cp->rw_latency = WRITE; ! 205: break; ! 206: case READ_6: ! 207: x = cmd->cmnd[4]/2; ! 208: cp->rw_latency = READ; ! 209: break; ! 210: case WRITE_10: ! 211: sho = (short *) &cmd->cmnd[7]; ! 212: x = ntohs(*sho)/2; ! 213: cp->rw_latency = WRITE; ! 214: break; ! 215: case READ_10: ! 216: sho = (short *) &cmd->cmnd[7]; ! 217: x = ntohs(*sho)/2; ! 218: cp->rw_latency = READ; ! 219: break; ! 220: case WRITE_12: ! 221: lon = (long *) &cmd->cmnd[6]; ! 222: x = ntohl(*lon)/2; ! 223: cp->rw_latency = WRITE; ! 224: break; ! 225: case READ_12: ! 226: lon = (long *) &cmd->cmnd[6]; ! 227: x = ntohl(*lon)/2; ! 228: cp->rw_latency = READ; ! 229: break; ! 230: default: ! 231: cp->rw_latency = OTHER; ! 232: break; ! 233: } ! 234: if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 || ! 235: cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 || ! 236: cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) { ! 237: for(z = 0; (x > (1 << z)) && (z <= 11); z++) ! 238: /* nothing */; ! 239: cp->sizeindex = z; ! 240: } ! 241: } ! 242: ! 243: ! 244: void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs) ! 245: { ! 246: uint i, result = 0; ! 247: uint hba_stat, scsi_stat, eata_stat; ! 248: Scsi_Cmnd *cmd; ! 249: struct eata_ccb *ccb; ! 250: struct eata_sp *sp; ! 251: uint base; ! 252: uint x; ! 253: struct Scsi_Host *sh; ! 254: ! 255: for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { ! 256: if (sh->irq != irq) ! 257: continue; ! 258: ! 259: while(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { ! 260: ! 261: int_counter++; ! 262: ! 263: sp = &SD(sh)->sp; ! 264: #ifdef __mips__ ! 265: sys_cacheflush(sp, sizeof(struct eata_sp), 2); ! 266: #endif ! 267: ccb = sp->ccb; ! 268: ! 269: if(ccb == NULL) { ! 270: eata_stat = inb((uint)sh->base + HA_RSTATUS); ! 271: printk("eata_dma: int_handler, Spurious IRQ %d " ! 272: "received. CCB pointer not set.\n", irq); ! 273: break; ! 274: } ! 275: ! 276: cmd = ccb->cmd; ! 277: base = (uint) cmd->host->base; ! 278: hba_stat = sp->hba_stat; ! 279: ! 280: scsi_stat = (sp->scsi_stat >> 1) & 0x1f; ! 281: ! 282: if (sp->EOC == FALSE) { ! 283: eata_stat = inb(base + HA_RSTATUS); ! 284: printk(KERN_WARNING "eata_dma: int_handler, board: %x cmd %lx " ! 285: "returned unfinished.\n" ! 286: "EATA: %x HBA: %x SCSI: %x spadr %lx spadrirq %lx, " ! 287: "irq%d\n", base, (long)ccb, eata_stat, hba_stat, ! 288: scsi_stat,(long)&status, (long)&status[irq], irq); ! 289: cmd->result = DID_ERROR << 16; ! 290: ccb->status = FREE; ! 291: cmd->scsi_done(cmd); ! 292: break; ! 293: } ! 294: ! 295: sp->EOC = FALSE; /* Clean out this flag */ ! 296: ! 297: if (ccb->status == LOCKED || ccb->status == RESET) { ! 298: printk("eata_dma: int_handler, reseted command pid %ld returned" ! 299: "\n", cmd->pid); ! 300: DBG(DBG_INTR && DBG_DELAY, DELAY(1)); ! 301: } ! 302: ! 303: eata_stat = inb(base + HA_RSTATUS); ! 304: DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, " ! 305: "target: %x, lun: %x, ea_s: %#.2x, hba_s: " ! 306: "%#.2x \n", irq, base, cmd->pid, cmd->target, ! 307: cmd->lun, eata_stat, hba_stat)); ! 308: ! 309: switch (hba_stat) { ! 310: case HA_NO_ERROR: /* NO Error */ ! 311: if(HD(cmd)->do_latency == TRUE && ccb->timestamp) ! 312: eata_latency_in(ccb, HD(cmd)); ! 313: result = DID_OK << 16; ! 314: break; ! 315: case HA_ERR_SEL_TO: /* Selection Timeout */ ! 316: case HA_ERR_CMD_TO: /* Command Timeout */ ! 317: result = DID_TIME_OUT << 16; ! 318: break; ! 319: case HA_BUS_RESET: /* SCSI Bus Reset Received */ ! 320: result = DID_RESET << 16; ! 321: DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: BUS RESET " ! 322: "received on cmd %ld\n", ! 323: HD(cmd)->HBA_number, cmd->pid)); ! 324: break; ! 325: case HA_INIT_POWERUP: /* Initial Controller Power-up */ ! 326: if (cmd->device->type != TYPE_TAPE) ! 327: result = DID_BUS_BUSY << 16; ! 328: else ! 329: result = DID_ERROR << 16; ! 330: ! 331: for (i = 0; i < MAXTARGET; i++) ! 332: DBG(DBG_STATUS, printk(KERN_DEBUG "scsi%d: cmd pid %ld " ! 333: "returned with INIT_POWERUP\n", ! 334: HD(cmd)->HBA_number, cmd->pid)); ! 335: break; ! 336: case HA_CP_ABORT_NA: ! 337: case HA_CP_ABORTED: ! 338: result = DID_ABORT << 16; ! 339: DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: aborted cmd " ! 340: "returned\n", HD(cmd)->HBA_number)); ! 341: break; ! 342: case HA_CP_RESET_NA: ! 343: case HA_CP_RESET: ! 344: HD(cmd)->resetlevel[cmd->channel] = 0; ! 345: result = DID_RESET << 16; ! 346: DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: reseted cmd " ! 347: "pid %ldreturned\n", ! 348: HD(cmd)->HBA_number, cmd->pid)); ! 349: case HA_SCSI_HUNG: /* SCSI Hung */ ! 350: printk(KERN_ERR "scsi%d: SCSI hung\n", HD(cmd)->HBA_number); ! 351: result = DID_ERROR << 16; ! 352: break; ! 353: case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */ ! 354: DBG(DBG_STATUS, printk(KERN_ERR "scsi%d: Auto Request Sense " ! 355: "Failed\n", HD(cmd)->HBA_number)); ! 356: result = DID_ERROR << 16; ! 357: break; ! 358: case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */ ! 359: case HA_UNX_BUS_FREE: /* Unexpected Bus Free */ ! 360: case HA_BUS_PARITY: /* Bus Parity Error */ ! 361: case HA_UNX_MSGRJCT: /* Unexpected Message Reject */ ! 362: case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */ ! 363: case HA_PARITY_ERR: /* Controller Ram Parity */ ! 364: default: ! 365: result = DID_ERROR << 16; ! 366: break; ! 367: } ! 368: cmd->result = result | (scsi_stat << 1); ! 369: ! 370: #if DBG_INTR2 ! 371: if (scsi_stat || result || hba_stat || eata_stat != 0x50 ! 372: || cmd->scsi_done == NULL || cmd->device->id == 7) ! 373: printk("HBA: %d, channel %d, id: %d, lun %d, pid %ld:\n" ! 374: "eata_stat %#x, hba_stat %#.2x, scsi_stat %#.2x, " ! 375: "sense_key: %#x, result: %#.8x\n", x, ! 376: cmd->device->channel, cmd->device->id, cmd->device->lun, ! 377: cmd->pid, eata_stat, hba_stat, scsi_stat, ! 378: cmd->sense_buffer[2] & 0xf, cmd->result); ! 379: DBG(DBG_INTR&&DBG_DELAY,DELAY(1)); ! 380: #endif ! 381: ! 382: ccb->status = FREE; /* now we can release the slot */ ! 383: cmd->scsi_done(cmd); ! 384: } ! 385: } ! 386: ! 387: return; ! 388: } ! 389: ! 390: inline int eata_send_command(u32 addr, u32 base, u8 command) ! 391: { ! 392: long loop = R_LIMIT; ! 393: ! 394: while (inb(base + HA_RAUXSTAT) & HA_ABUSY) ! 395: if (--loop == 0) ! 396: return(FALSE); ! 397: ! 398: if(addr != (u32) NULL) ! 399: addr = virt_to_bus((void *)addr); ! 400: ! 401: /* ! 402: * This is overkill.....but the MIPSen seem to need this ! 403: * and it will be optimized away for i86 and ALPHA machines. ! 404: */ ! 405: flush_cache_all(); ! 406: ! 407: /* And now the address in nice little byte chunks */ ! 408: #ifdef __LITTLE_ENDIAN ! 409: outb(addr, base + HA_WDMAADDR); ! 410: outb(addr >> 8, base + HA_WDMAADDR + 1); ! 411: outb(addr >> 16, base + HA_WDMAADDR + 2); ! 412: outb(addr >> 24, base + HA_WDMAADDR + 3); ! 413: #else ! 414: outb(addr >> 24, base + HA_WDMAADDR); ! 415: outb(addr >> 16, base + HA_WDMAADDR + 1); ! 416: outb(addr >> 8, base + HA_WDMAADDR + 2); ! 417: outb(addr, base + HA_WDMAADDR + 3); ! 418: #endif ! 419: outb(command, base + HA_WCOMMAND); ! 420: return(TRUE); ! 421: } ! 422: ! 423: inline int eata_send_immediate(u32 base, u32 addr, u8 ifc, u8 code, u8 code2) ! 424: { ! 425: if(addr != (u32) NULL) ! 426: addr = virt_to_bus((void *)addr); ! 427: ! 428: /* ! 429: * This is overkill.....but the MIPSen seem to need this ! 430: * and it will be optimized away for i86 and ALPHA machines. ! 431: */ ! 432: flush_cache_all(); ! 433: ! 434: outb(0x0, base + HA_WDMAADDR - 1); ! 435: if(addr){ ! 436: #ifdef __LITTLE_ENDIAN ! 437: outb(addr, base + HA_WDMAADDR); ! 438: outb(addr >> 8, base + HA_WDMAADDR + 1); ! 439: outb(addr >> 16, base + HA_WDMAADDR + 2); ! 440: outb(addr >> 24, base + HA_WDMAADDR + 3); ! 441: #else ! 442: outb(addr >> 24, base + HA_WDMAADDR); ! 443: outb(addr >> 16, base + HA_WDMAADDR + 1); ! 444: outb(addr >> 8, base + HA_WDMAADDR + 2); ! 445: outb(addr, base + HA_WDMAADDR + 3); ! 446: #endif ! 447: } else { ! 448: outb(0x0, base + HA_WDMAADDR); ! 449: outb(0x0, base + HA_WDMAADDR + 1); ! 450: outb(code2, base + HA_WCODE2); ! 451: outb(code, base + HA_WCODE); ! 452: } ! 453: ! 454: outb(ifc, base + HA_WIFC); ! 455: outb(EATA_CMD_IMMEDIATE, base + HA_WCOMMAND); ! 456: return(TRUE); ! 457: } ! 458: ! 459: int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) ! 460: { ! 461: unsigned int i, x, y; ! 462: ulong flags; ! 463: hostdata *hd; ! 464: struct Scsi_Host *sh; ! 465: struct eata_ccb *ccb; ! 466: struct scatterlist *sl; ! 467: ! 468: ! 469: save_flags(flags); ! 470: cli(); ! 471: ! 472: #if 0 ! 473: for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { ! 474: if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { ! 475: printk("eata_dma: scsi%d interrupt pending in eata_queue.\n" ! 476: " Calling interrupt handler.\n", sh->host_no); ! 477: eata_int_handler(sh->irq, 0, 0); ! 478: } ! 479: } ! 480: #endif ! 481: ! 482: queue_counter++; ! 483: ! 484: hd = HD(cmd); ! 485: sh = cmd->host; ! 486: ! 487: if (cmd->cmnd[0] == REQUEST_SENSE && cmd->sense_buffer[0] != 0) { ! 488: DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n")); ! 489: cmd->result = DID_OK << 16; ! 490: done(cmd); ! 491: ! 492: return(0); ! 493: } ! 494: ! 495: /* check for free slot */ ! 496: for (y = hd->last_ccb + 1, x = 0; x < sh->can_queue; x++, y++) { ! 497: if (y >= sh->can_queue) ! 498: y = 0; ! 499: if (hd->ccb[y].status == FREE) ! 500: break; ! 501: } ! 502: ! 503: hd->last_ccb = y; ! 504: ! 505: if (x >= sh->can_queue) { ! 506: cmd->result = DID_BUS_BUSY << 16; ! 507: DBG(DBG_QUEUE && DBG_ABNORM, ! 508: printk(KERN_CRIT "eata_queue pid %ld, HBA QUEUE FULL..., " ! 509: "returning DID_BUS_BUSY\n", cmd->pid)); ! 510: done(cmd); ! 511: restore_flags(flags); ! 512: return(0); ! 513: } ! 514: ccb = &hd->ccb[y]; ! 515: ! 516: memset(ccb, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *)); ! 517: ! 518: ccb->status = USED; /* claim free slot */ ! 519: ! 520: restore_flags(flags); ! 521: ! 522: DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n", ! 523: cmd->pid, cmd->target, cmd->lun, y)); ! 524: DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); ! 525: ! 526: if(hd->do_latency == TRUE) ! 527: eata_latency_out(ccb, cmd); ! 528: ! 529: cmd->scsi_done = (void *)done; ! 530: ! 531: switch (cmd->cmnd[0]) { ! 532: case CHANGE_DEFINITION: case COMPARE: case COPY: ! 533: case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: ! 534: case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER: ! 535: case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: ! 536: case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: ! 537: case WRITE_6: case WRITE_10: case WRITE_VERIFY: ! 538: case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: ! 539: case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: ! 540: case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: ! 541: case MEDIUM_SCAN: case SEND_VOLUME_TAG: ! 542: case 0xea: /* alternate number for WRITE LONG */ ! 543: ccb->DataOut = TRUE; /* Output mode */ ! 544: break; ! 545: case TEST_UNIT_READY: ! 546: default: ! 547: ccb->DataIn = TRUE; /* Input mode */ ! 548: } ! 549: ! 550: /* FIXME: This will have to be changed once the midlevel driver ! 551: * allows different HBA IDs on every channel. ! 552: */ ! 553: if (cmd->target == sh->this_id) ! 554: ccb->Interpret = TRUE; /* Interpret command */ ! 555: ! 556: if (cmd->use_sg) { ! 557: ccb->scatter = TRUE; /* SG mode */ ! 558: if (ccb->sg_list == NULL) { ! 559: ccb->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list), ! 560: GFP_ATOMIC | GFP_DMA); ! 561: } ! 562: if (ccb->sg_list == NULL) ! 563: panic("eata_dma: Run out of DMA memory for SG lists !\n"); ! 564: ccb->cp_dataDMA = htonl(virt_to_bus(ccb->sg_list)); ! 565: ! 566: ccb->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list)); ! 567: sl=(struct scatterlist *)cmd->request_buffer; ! 568: for(i = 0; i < cmd->use_sg; i++, sl++){ ! 569: ccb->sg_list[i].data = htonl(virt_to_bus(sl->address)); ! 570: ccb->sg_list[i].len = htonl((u32) sl->length); ! 571: } ! 572: } else { ! 573: ccb->scatter = FALSE; ! 574: ccb->cp_datalen = htonl(cmd->request_bufflen); ! 575: ccb->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer)); ! 576: } ! 577: ! 578: ccb->Auto_Req_Sen = TRUE; ! 579: ccb->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer)); ! 580: ccb->reqlen = sizeof(cmd->sense_buffer); ! 581: ! 582: ccb->cp_id = cmd->target; ! 583: ccb->cp_channel = cmd->channel; ! 584: ccb->cp_lun = cmd->lun; ! 585: ccb->cp_dispri = TRUE; ! 586: ccb->cp_identify = TRUE; ! 587: memcpy(ccb->cp_cdb, cmd->cmnd, cmd->cmd_len); ! 588: ! 589: ccb->cp_statDMA = htonl(virt_to_bus(&(hd->sp))); ! 590: ! 591: ccb->cp_viraddr = ccb; /* This will be passed thru, so we don't need to ! 592: * convert it */ ! 593: ccb->cmd = cmd; ! 594: cmd->host_scribble = (char *)&hd->ccb[y]; ! 595: ! 596: if(eata_send_command((u32) ccb, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) { ! 597: cmd->result = DID_BUS_BUSY << 16; ! 598: DBG(DBG_QUEUE && DBG_ABNORM, ! 599: printk("eata_queue target %d, pid %ld, HBA busy, " ! 600: "returning DID_BUS_BUSY\n",cmd->target, cmd->pid)); ! 601: ccb->status = FREE; ! 602: done(cmd); ! 603: return(0); ! 604: } ! 605: DBG(DBG_QUEUE, printk("Queued base %#.4x pid: %ld target: %x lun: %x " ! 606: "slot %d irq %d\n", (s32)sh->base, cmd->pid, ! 607: cmd->target, cmd->lun, y, sh->irq)); ! 608: DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); ! 609: ! 610: return(0); ! 611: } ! 612: ! 613: ! 614: int eata_abort(Scsi_Cmnd * cmd) ! 615: { ! 616: ulong loop = HZ / 2; ! 617: ulong flags; ! 618: int x; ! 619: struct Scsi_Host *sh; ! 620: ! 621: save_flags(flags); ! 622: cli(); ! 623: ! 624: DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x" ! 625: " reason %x\n", cmd->pid, cmd->target, cmd->lun, ! 626: cmd->abort_reason)); ! 627: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 628: ! 629: /* Some interrupt controllers seem to loose interrupts */ ! 630: for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { ! 631: if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { ! 632: printk("eata_dma: scsi%d interrupt pending in eata_abort.\n" ! 633: " Calling interrupt handler.\n", sh->host_no); ! 634: eata_int_handler(sh->irq, 0, 0); ! 635: } ! 636: } ! 637: ! 638: while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) { ! 639: if (--loop == 0) { ! 640: printk("eata_dma: abort, timeout error.\n"); ! 641: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 642: restore_flags(flags); ! 643: return (SCSI_ABORT_ERROR); ! 644: } ! 645: } ! 646: if (CD(cmd)->status == RESET) { ! 647: printk("eata_dma: abort, command reset error.\n"); ! 648: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 649: restore_flags(flags); ! 650: return (SCSI_ABORT_ERROR); ! 651: } ! 652: if (CD(cmd)->status == LOCKED) { ! 653: DBG(DBG_ABNORM, printk("eata_dma: abort, queue slot locked.\n")); ! 654: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 655: restore_flags(flags); ! 656: return (SCSI_ABORT_NOT_RUNNING); ! 657: } ! 658: if (CD(cmd)->status == USED) { ! 659: DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_BUSY\n")); ! 660: restore_flags(flags); ! 661: return (SCSI_ABORT_BUSY); /* SNOOZE */ ! 662: } ! 663: if (CD(cmd)->status == FREE) { ! 664: DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_NOT_RUNNING\n")); ! 665: restore_flags(flags); ! 666: return (SCSI_ABORT_NOT_RUNNING); ! 667: } ! 668: restore_flags(flags); ! 669: panic("eata_dma: abort: invalid slot status\n"); ! 670: } ! 671: ! 672: int eata_reset(Scsi_Cmnd * cmd, unsigned int resetflags) ! 673: { ! 674: uint x; ! 675: ulong loop = loops_per_sec / 3; ! 676: ulong flags; ! 677: unchar success = FALSE; ! 678: Scsi_Cmnd *sp; ! 679: struct Scsi_Host *sh; ! 680: ! 681: save_flags(flags); ! 682: cli(); ! 683: ! 684: DBG(DBG_ABNORM, printk("eata_reset called pid:%ld target: %x lun: %x" ! 685: " reason %x\n", cmd->pid, cmd->target, cmd->lun, ! 686: cmd->abort_reason)); ! 687: ! 688: for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { ! 689: if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { ! 690: printk("eata_dma: scsi%d interrupt pending in eata_reset.\n" ! 691: " Calling interrupt handler.\n", sh->host_no); ! 692: eata_int_handler(sh->irq, 0, 0); ! 693: } ! 694: } ! 695: ! 696: if (HD(cmd)->state == RESET) { ! 697: printk("eata_reset: exit, already in reset.\n"); ! 698: restore_flags(flags); ! 699: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 700: return (SCSI_RESET_ERROR); ! 701: } ! 702: ! 703: while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) ! 704: if (--loop == 0) { ! 705: printk("eata_reset: exit, timeout error.\n"); ! 706: restore_flags(flags); ! 707: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 708: return (SCSI_RESET_ERROR); ! 709: } ! 710: ! 711: for (x = 0; x < cmd->host->can_queue; x++) { ! 712: if (HD(cmd)->ccb[x].status == FREE) ! 713: continue; ! 714: ! 715: if (HD(cmd)->ccb[x].status == LOCKED) { ! 716: HD(cmd)->ccb[x].status = FREE; ! 717: printk("eata_reset: locked slot %d forced free.\n", x); ! 718: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 719: continue; ! 720: } ! 721: ! 722: ! 723: sp = HD(cmd)->ccb[x].cmd; ! 724: HD(cmd)->ccb[x].status = RESET; ! 725: ! 726: if (sp == NULL) ! 727: panic("eata_reset: slot %d, sp==NULL.\n", x); ! 728: ! 729: printk("eata_reset: slot %d in reset, pid %ld.\n", x, sp->pid); ! 730: ! 731: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 732: ! 733: if (sp == cmd) ! 734: success = TRUE; ! 735: } ! 736: ! 737: /* hard reset the HBA */ ! 738: inb((u32) (cmd->host->base) + HA_RSTATUS); /* This might cause trouble */ ! 739: eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET); ! 740: ! 741: HD(cmd)->state = RESET; ! 742: ! 743: DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling " ! 744: "interrupts.\n")); ! 745: ! 746: DELAY(2); /* In theorie we should get interrupts and set free all ! 747: * used queueslots */ ! 748: ! 749: DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled again.\n")); ! 750: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 751: ! 752: for (x = 0; x < cmd->host->can_queue; x++) { ! 753: ! 754: /* Skip slots already set free by interrupt and those that ! 755: * are still LOCKED from the last reset */ ! 756: if (HD(cmd)->ccb[x].status != RESET) ! 757: continue; ! 758: ! 759: sp = HD(cmd)->ccb[x].cmd; ! 760: sp->result = DID_RESET << 16; ! 761: ! 762: /* This mailbox is still waiting for its interrupt */ ! 763: HD(cmd)->ccb[x].status = LOCKED; ! 764: ! 765: printk("eata_reset: slot %d locked, DID_RESET, pid %ld done.\n", ! 766: x, sp->pid); ! 767: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 768: ! 769: sp->scsi_done(sp); ! 770: } ! 771: ! 772: HD(cmd)->state = FALSE; ! 773: restore_flags(flags); ! 774: ! 775: if (success) { ! 776: DBG(DBG_ABNORM, printk("eata_reset: exit, pending.\n")); ! 777: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 778: return (SCSI_RESET_PENDING); ! 779: } else { ! 780: DBG(DBG_ABNORM, printk("eata_reset: exit, wakeup.\n")); ! 781: DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); ! 782: return (SCSI_RESET_PUNT); ! 783: } ! 784: } ! 785: ! 786: /* Here we try to determine the optimum queue depth for ! 787: * each attached device. ! 788: * ! 789: * At the moment the algorithm is rather simple ! 790: */ ! 791: static void eata_select_queue_depths(struct Scsi_Host *host, ! 792: Scsi_Device *devicelist) ! 793: { ! 794: Scsi_Device *device; ! 795: int devcount = 0; ! 796: int factor = 0; ! 797: ! 798: #if CRIPPLE_QUEUE ! 799: for(device = devicelist; device != NULL; device = device->next) { ! 800: if(device->host == host) ! 801: device->queue_depth = 2; ! 802: } ! 803: #else ! 804: /* First we do a sample run go find out what we have */ ! 805: for(device = devicelist; device != NULL; device = device->next) { ! 806: if (device->host == host) { ! 807: devcount++; ! 808: switch(device->type) { ! 809: case TYPE_DISK: ! 810: case TYPE_MOD: ! 811: factor += TYPE_DISK_QUEUE; ! 812: break; ! 813: case TYPE_TAPE: ! 814: factor += TYPE_TAPE_QUEUE; ! 815: break; ! 816: case TYPE_WORM: ! 817: case TYPE_ROM: ! 818: factor += TYPE_ROM_QUEUE; ! 819: break; ! 820: case TYPE_PROCESSOR: ! 821: case TYPE_SCANNER: ! 822: default: ! 823: factor += TYPE_OTHER_QUEUE; ! 824: break; ! 825: } ! 826: } ! 827: } ! 828: ! 829: DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: needed queueslots %d\n", ! 830: host->host_no, factor)); ! 831: ! 832: if(factor == 0) /* We don't want to get a DIV BY ZERO error */ ! 833: factor = 1; ! 834: ! 835: factor = (SD(host)->queuesize * 10) / factor; ! 836: ! 837: DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: using factor %dE-1\n", ! 838: host->host_no, factor)); ! 839: ! 840: /* Now that have the factor we can set the individual queuesizes */ ! 841: for(device = devicelist; device != NULL; device = device->next) { ! 842: if(device->host == host) { ! 843: if(SD(device->host)->bustype != IS_ISA){ ! 844: switch(device->type) { ! 845: case TYPE_DISK: ! 846: case TYPE_MOD: ! 847: device->queue_depth = (TYPE_DISK_QUEUE * factor) / 10; ! 848: break; ! 849: case TYPE_TAPE: ! 850: device->queue_depth = (TYPE_TAPE_QUEUE * factor) / 10; ! 851: break; ! 852: case TYPE_WORM: ! 853: case TYPE_ROM: ! 854: device->queue_depth = (TYPE_ROM_QUEUE * factor) / 10; ! 855: break; ! 856: case TYPE_PROCESSOR: ! 857: case TYPE_SCANNER: ! 858: default: ! 859: device->queue_depth = (TYPE_OTHER_QUEUE * factor) / 10; ! 860: break; ! 861: } ! 862: } else /* ISA forces us to limit the queue depth because of the ! 863: * bounce buffer memory overhead. I know this is cruel */ ! 864: device->queue_depth = 2; ! 865: ! 866: /* ! 867: * It showed that we need to set an upper limit of commands ! 868: * we can allow to queue for a single device on the bus. ! 869: * If we get above that limit, the broken midlevel SCSI code ! 870: * will produce bogus timeouts and aborts en masse. :-( ! 871: */ ! 872: if(device->queue_depth > UPPER_DEVICE_QUEUE_LIMIT) ! 873: device->queue_depth = UPPER_DEVICE_QUEUE_LIMIT; ! 874: if(device->queue_depth == 0) ! 875: device->queue_depth = 1; ! 876: ! 877: printk(KERN_INFO "scsi%d: queue depth for target %d on channel %d " ! 878: "set to %d\n", host->host_no, device->id, device->channel, ! 879: device->queue_depth); ! 880: } ! 881: } ! 882: #endif ! 883: } ! 884: ! 885: #if CHECK_BLINK ! 886: int check_blink_state(long base) ! 887: { ! 888: ushort loops = 10; ! 889: u32 blinkindicator; ! 890: u32 state = 0x12345678; ! 891: u32 oldstate = 0; ! 892: ! 893: blinkindicator = htonl(0x54504442); ! 894: while ((loops--) && (state != oldstate)) { ! 895: oldstate = state; ! 896: state = inl((uint) base + 1); ! 897: } ! 898: ! 899: DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n", ! 900: (state == oldstate) && (state == blinkindicator))); ! 901: ! 902: if ((state == oldstate) && (state == blinkindicator)) ! 903: return(TRUE); ! 904: else ! 905: return (FALSE); ! 906: } ! 907: #endif ! 908: ! 909: char * get_board_data(u32 base, u32 irq, u32 id) ! 910: { ! 911: struct eata_ccb *cp; ! 912: struct eata_sp *sp; ! 913: static char *buff; ! 914: ulong i; ! 915: ! 916: cp = (struct eata_ccb *) scsi_init_malloc(sizeof(struct eata_ccb), ! 917: GFP_ATOMIC | GFP_DMA); ! 918: sp = (struct eata_sp *) scsi_init_malloc(sizeof(struct eata_sp), ! 919: GFP_ATOMIC | GFP_DMA); ! 920: ! 921: buff = dma_scratch; ! 922: ! 923: memset(cp, 0, sizeof(struct eata_ccb)); ! 924: memset(sp, 0, sizeof(struct eata_sp)); ! 925: memset(buff, 0, 256); ! 926: ! 927: cp->DataIn = TRUE; ! 928: cp->Interpret = TRUE; /* Interpret command */ ! 929: cp->cp_dispri = TRUE; ! 930: cp->cp_identify = TRUE; ! 931: ! 932: cp->cp_datalen = htonl(56); ! 933: cp->cp_dataDMA = htonl(virt_to_bus(buff)); ! 934: cp->cp_statDMA = htonl(virt_to_bus(sp)); ! 935: cp->cp_viraddr = cp; ! 936: ! 937: cp->cp_id = id; ! 938: cp->cp_lun = 0; ! 939: ! 940: cp->cp_cdb[0] = INQUIRY; ! 941: cp->cp_cdb[1] = 0; ! 942: cp->cp_cdb[2] = 0; ! 943: cp->cp_cdb[3] = 0; ! 944: cp->cp_cdb[4] = 56; ! 945: cp->cp_cdb[5] = 0; ! 946: ! 947: fake_int_base = (struct eata_register *) base; ! 948: fake_int_result = FALSE; ! 949: fake_int_happened = FALSE; ! 950: ! 951: eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP); ! 952: ! 953: i = jiffies + (3 * HZ); ! 954: while (fake_int_happened == FALSE && jiffies <= i) ! 955: barrier(); ! 956: ! 957: DBG(DBG_INTR3, printk(KERN_DEBUG "fake_int_result: %#x hbastat %#x " ! 958: "scsistat %#x, buff %p sp %p\n", ! 959: fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/), ! 960: (u32) sp->scsi_stat, buff, sp)); ! 961: ! 962: scsi_init_free((void *)cp, sizeof(struct eata_ccb)); ! 963: scsi_init_free((void *)sp, sizeof(struct eata_sp)); ! 964: ! 965: if ((fake_int_result & HA_SERROR) || jiffies > i){ ! 966: printk(KERN_WARNING "eata_dma: trying to reset HBA at %x to clear " ! 967: "possible blink state\n", base); ! 968: /* hard reset the HBA */ ! 969: inb((u32) (base) + HA_RSTATUS); ! 970: eata_send_command(0, base, EATA_CMD_RESET); ! 971: DELAY(1); ! 972: return (NULL); ! 973: } else ! 974: return (buff); ! 975: } ! 976: ! 977: ! 978: int get_conf_PIO(u32 base, struct get_conf *buf) ! 979: { ! 980: ulong loop = R_LIMIT; ! 981: u16 *p; ! 982: ! 983: if(check_region(base, 9)) ! 984: return (FALSE); ! 985: ! 986: memset(buf, 0, sizeof(struct get_conf)); ! 987: ! 988: while (inb(base + HA_RSTATUS) & HA_SBUSY) ! 989: if (--loop == 0) ! 990: return (FALSE); ! 991: ! 992: fake_int_base = (struct eata_register *) base; ! 993: fake_int_result = FALSE; ! 994: fake_int_happened = FALSE; ! 995: ! 996: DBG(DBG_PIO && DBG_PROBE, ! 997: printk("Issuing PIO READ CONFIG to HBA at %#x\n", base)); ! 998: eata_send_command(0, base, EATA_CMD_PIO_READ_CONFIG); ! 999: ! 1000: loop = R_LIMIT; ! 1001: for (p = (u16 *) buf; ! 1002: (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) { ! 1003: while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) ! 1004: if (--loop == 0) ! 1005: return (FALSE); ! 1006: ! 1007: loop = R_LIMIT; ! 1008: *p = inw(base + HA_RDATA); ! 1009: } ! 1010: ! 1011: if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ ! 1012: if (htonl(EATA_SIGNATURE) == buf->signature) { ! 1013: DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x " ! 1014: "EATA Level: %x\n", (uint) base, ! 1015: (uint) (buf->version))); ! 1016: ! 1017: while (inb(base + HA_RSTATUS) & HA_SDRQ) ! 1018: inw(base + HA_RDATA); ! 1019: return (TRUE); ! 1020: } ! 1021: } else { ! 1022: DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " ! 1023: "for HBA at %lx\n", (long)base)); ! 1024: } ! 1025: return (FALSE); ! 1026: } ! 1027: ! 1028: ! 1029: void print_config(struct get_conf *gc) ! 1030: { ! 1031: printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n", ! 1032: (u32) ntohl(gc->len), gc->version, ! 1033: gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support, ! 1034: gc->DMA_support); ! 1035: printk("DMAV:%d HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", ! 1036: gc->DMA_valid, gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], ! 1037: gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND); ! 1038: printk("IRQ:%d IRQT:%d DMAC:%d FORCADR:%d SG_64K:%d SG_UAE:%d MID:%d " ! 1039: "MCH:%d MLUN:%d\n", ! 1040: gc->IRQ, gc->IRQ_TR, (8 - gc->DMA_channel) & 7, gc->FORCADR, ! 1041: gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); ! 1042: printk("RIDQ:%d PCI:%d EISA:%d\n", ! 1043: gc->ID_qest, gc->is_PCI, gc->is_EISA); ! 1044: DBG(DPT_DEBUG, DELAY(14)); ! 1045: } ! 1046: ! 1047: short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, ! 1048: u8 bustype) ! 1049: { ! 1050: ulong size = 0; ! 1051: unchar dma_channel = 0; ! 1052: char *buff = 0; ! 1053: unchar bugs = 0; ! 1054: struct Scsi_Host *sh; ! 1055: hostdata *hd; ! 1056: int x; ! 1057: ! 1058: ! 1059: DBG(DBG_REGISTER, print_config(gc)); ! 1060: ! 1061: if (gc->DMA_support == FALSE) { ! 1062: printk("The EATA HBA at %#.4x does not support DMA.\n" ! 1063: "Please use the EATA-PIO driver.\n", base); ! 1064: return (FALSE); ! 1065: } ! 1066: if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) ! 1067: gc->MAX_CHAN = 0; ! 1068: ! 1069: if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ ! 1070: if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT, ! 1071: "eata_dma", NULL)){ ! 1072: reg_IRQ[gc->IRQ]++; ! 1073: if (!gc->IRQ_TR) ! 1074: reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ ! 1075: } else { ! 1076: printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ); ! 1077: return (FALSE); ! 1078: } ! 1079: } else { /* More than one HBA on this IRQ */ ! 1080: if (reg_IRQL[gc->IRQ] == TRUE) { ! 1081: printk("Can't support more than one HBA on this IRQ,\n" ! 1082: " if the IRQ is edge triggered. Sorry.\n"); ! 1083: return (FALSE); ! 1084: } else ! 1085: reg_IRQ[gc->IRQ]++; ! 1086: } ! 1087: ! 1088: ! 1089: /* If DMA is supported but DMA_valid isn't set to indicate that ! 1090: * the channel number is given we must have pre 2.0 firmware (1.7?) ! 1091: * which leaves us to guess since the "newer ones" also don't set the ! 1092: * DMA_valid bit. ! 1093: */ ! 1094: if (gc->DMA_support && !gc->DMA_valid && gc->DMA_channel) { ! 1095: printk(KERN_WARNING "eata_dma: If you are using a pre 2.0 firmware " ! 1096: "please update it !\n" ! 1097: " You can get new firmware releases from ftp.dpt.com\n"); ! 1098: gc->DMA_channel = (base == 0x1f0 ? 3 /* DMA=5 */ : 2 /* DMA=6 */); ! 1099: gc->DMA_valid = TRUE; ! 1100: } ! 1101: ! 1102: /* if gc->DMA_valid it must be an ISA HBA and we have to register it */ ! 1103: dma_channel = BUSMASTER; ! 1104: if (gc->DMA_valid) { ! 1105: if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) { ! 1106: printk(KERN_WARNING "Unable to allocate DMA channel %d for ISA HBA" ! 1107: " at %#.4x.\n", dma_channel, base); ! 1108: reg_IRQ[gc->IRQ]--; ! 1109: if (reg_IRQ[gc->IRQ] == 0) ! 1110: free_irq(gc->IRQ, NULL); ! 1111: if (gc->IRQ_TR == FALSE) ! 1112: reg_IRQL[gc->IRQ] = FALSE; ! 1113: return (FALSE); ! 1114: } ! 1115: } ! 1116: ! 1117: if (dma_channel != BUSMASTER) { ! 1118: disable_dma(dma_channel); ! 1119: clear_dma_ff(dma_channel); ! 1120: set_dma_mode(dma_channel, DMA_MODE_CASCADE); ! 1121: enable_dma(dma_channel); ! 1122: } ! 1123: ! 1124: if (bustype != IS_EISA && bustype != IS_ISA) ! 1125: buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]); ! 1126: ! 1127: if (buff == NULL) { ! 1128: if (bustype == IS_EISA || bustype == IS_ISA) { ! 1129: bugs = bugs || BROKEN_INQUIRY; ! 1130: } else { ! 1131: if (gc->DMA_support == FALSE) ! 1132: printk(KERN_WARNING "HBA at %#.4x doesn't support DMA. " ! 1133: "Sorry\n", base); ! 1134: else ! 1135: printk(KERN_WARNING "HBA at %#.4x does not react on INQUIRY. " ! 1136: "Sorry.\n", base); ! 1137: if (gc->DMA_valid) ! 1138: free_dma(dma_channel); ! 1139: reg_IRQ[gc->IRQ]--; ! 1140: if (reg_IRQ[gc->IRQ] == 0) ! 1141: free_irq(gc->IRQ, NULL); ! 1142: if (gc->IRQ_TR == FALSE) ! 1143: reg_IRQL[gc->IRQ] = FALSE; ! 1144: return (FALSE); ! 1145: } ! 1146: } ! 1147: ! 1148: if (gc->DMA_support == FALSE && buff != NULL) ! 1149: printk(KERN_WARNING "HBA %.12sat %#.4x doesn't set the DMA_support " ! 1150: "flag correctly.\n", &buff[16], base); ! 1151: ! 1152: request_region(base, 9, "eata_dma"); /* We already checked the ! 1153: * availability, so this ! 1154: * should not fail. ! 1155: */ ! 1156: ! 1157: if(ntohs(gc->queuesiz) == 0) { ! 1158: gc->queuesiz = ntohs(64); ! 1159: printk(KERN_WARNING "Warning: Queue size has to be corrected. Assuming" ! 1160: " 64 queueslots\n" ! 1161: " This might be a PM2012B with a defective Firmware\n" ! 1162: " Contact DPT [email protected] for an upgrade\n"); ! 1163: } ! 1164: ! 1165: size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) ! 1166: * ntohs(gc->queuesiz)); ! 1167: ! 1168: DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size)); ! 1169: ! 1170: sh = scsi_register(tpnt, size); ! 1171: ! 1172: if(sh != NULL) { ! 1173: ! 1174: hd = SD(sh); ! 1175: ! 1176: memset(hd->reads, 0, sizeof(u32) * 26); ! 1177: ! 1178: sh->select_queue_depths = eata_select_queue_depths; ! 1179: ! 1180: hd->bustype = bustype; ! 1181: ! 1182: /* ! 1183: * If we are using a ISA board, we can't use extended SG, ! 1184: * because we would need excessive amounts of memory for ! 1185: * bounce buffers. ! 1186: */ ! 1187: if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){ ! 1188: sh->sg_tablesize = SG_SIZE_BIG; ! 1189: } else { ! 1190: sh->sg_tablesize = ntohs(gc->SGsiz); ! 1191: if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) { ! 1192: if (sh->sg_tablesize == 0) ! 1193: printk(KERN_WARNING "Warning: SG size had to be fixed.\n" ! 1194: "This might be a PM2012 with a defective Firmware" ! 1195: "\nContact DPT [email protected] for an upgrade\n"); ! 1196: sh->sg_tablesize = SG_SIZE; ! 1197: } ! 1198: } ! 1199: hd->sgsize = sh->sg_tablesize; ! 1200: } ! 1201: ! 1202: if(sh != NULL) { ! 1203: sh->can_queue = hd->queuesize = ntohs(gc->queuesiz); ! 1204: sh->cmd_per_lun = 0; ! 1205: } ! 1206: ! 1207: if(sh == NULL) { ! 1208: DBG(DBG_REGISTER, printk(KERN_NOTICE "eata_dma: couldn't register HBA" ! 1209: " at%x \n", base)); ! 1210: scsi_unregister(sh); ! 1211: if (gc->DMA_valid) ! 1212: free_dma(dma_channel); ! 1213: ! 1214: reg_IRQ[gc->IRQ]--; ! 1215: if (reg_IRQ[gc->IRQ] == 0) ! 1216: free_irq(gc->IRQ, NULL); ! 1217: if (gc->IRQ_TR == FALSE) ! 1218: reg_IRQL[gc->IRQ] = FALSE; ! 1219: return (FALSE); ! 1220: } ! 1221: ! 1222: ! 1223: hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY); ! 1224: ! 1225: if(hd->broken_INQUIRY == TRUE) { ! 1226: strcpy(hd->vendor, "DPT"); ! 1227: strcpy(hd->name, "??????????"); ! 1228: strcpy(hd->revision, "???.?"); ! 1229: hd->firmware_revision = 0; ! 1230: } else { ! 1231: strncpy(hd->vendor, &buff[8], 8); ! 1232: hd->vendor[8] = 0; ! 1233: strncpy(hd->name, &buff[16], 17); ! 1234: hd->name[17] = 0; ! 1235: hd->revision[0] = buff[32]; ! 1236: hd->revision[1] = buff[33]; ! 1237: hd->revision[2] = buff[34]; ! 1238: hd->revision[3] = '.'; ! 1239: hd->revision[4] = buff[35]; ! 1240: hd->revision[5] = 0; ! 1241: hd->firmware_revision = (buff[32] << 24) + (buff[33] << 16) ! 1242: + (buff[34] << 8) + buff[35]; ! 1243: } ! 1244: ! 1245: if (hd->firmware_revision >= (('0'<<24) + ('7'<<16) + ('G'<< 8) + '0')) ! 1246: hd->immediate_support = 1; ! 1247: else ! 1248: hd->immediate_support = 0; ! 1249: ! 1250: switch (ntohl(gc->len)) { ! 1251: case 0x1c: ! 1252: hd->EATA_revision = 'a'; ! 1253: break; ! 1254: case 0x1e: ! 1255: hd->EATA_revision = 'b'; ! 1256: break; ! 1257: case 0x22: ! 1258: hd->EATA_revision = 'c'; ! 1259: break; ! 1260: case 0x24: ! 1261: hd->EATA_revision = 'z'; ! 1262: default: ! 1263: hd->EATA_revision = '?'; ! 1264: } ! 1265: ! 1266: ! 1267: if(ntohl(gc->len) >= 0x22) { ! 1268: sh->max_id = gc->MAX_ID + 1; ! 1269: sh->max_lun = gc->MAX_LUN + 1; ! 1270: } else { ! 1271: sh->max_id = 8; ! 1272: sh->max_lun = 8; ! 1273: } ! 1274: ! 1275: hd->HBA_number = sh->host_no; ! 1276: hd->channel = gc->MAX_CHAN; ! 1277: sh->max_channel = gc->MAX_CHAN; ! 1278: sh->unique_id = base; ! 1279: sh->base = (char *) base; ! 1280: sh->io_port = base; ! 1281: sh->n_io_port = 9; ! 1282: sh->irq = gc->IRQ; ! 1283: sh->dma_channel = dma_channel; ! 1284: ! 1285: /* FIXME: ! 1286: * SCSI midlevel code should support different HBA ids on every channel ! 1287: */ ! 1288: sh->this_id = gc->scsi_id[3]; ! 1289: ! 1290: if (gc->SECOND) ! 1291: hd->primary = FALSE; ! 1292: else ! 1293: hd->primary = TRUE; ! 1294: ! 1295: sh->wish_block = FALSE; ! 1296: ! 1297: if (hd->bustype != IS_ISA) { ! 1298: sh->unchecked_isa_dma = FALSE; ! 1299: } else { ! 1300: sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ ! 1301: } ! 1302: ! 1303: for(x = 0; x <= 11; x++){ /* Initialize min. latency */ ! 1304: hd->writes_lat[x][1] = 0xffffffff; ! 1305: hd->reads_lat[x][1] = 0xffffffff; ! 1306: } ! 1307: hd->all_lat[1] = 0xffffffff; ! 1308: ! 1309: hd->next = NULL; /* build a linked list of all HBAs */ ! 1310: hd->prev = last_HBA; ! 1311: if(hd->prev != NULL) ! 1312: SD(hd->prev)->next = sh; ! 1313: last_HBA = sh; ! 1314: if (first_HBA == NULL) ! 1315: first_HBA = sh; ! 1316: registered_HBAs++; ! 1317: ! 1318: return (TRUE); ! 1319: } ! 1320: ! 1321: ! 1322: ! 1323: void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 1324: { ! 1325: u32 base; ! 1326: int i; ! 1327: ! 1328: #if CHECKPAL ! 1329: u8 pal1, pal2, pal3; ! 1330: #endif ! 1331: ! 1332: for (i = 0; i < MAXEISA; i++) { ! 1333: if (EISAbases[i] == TRUE) { /* Still a possibility ? */ ! 1334: ! 1335: base = 0x1c88 + (i * 0x1000); ! 1336: #if CHECKPAL ! 1337: pal1 = inb((u16)base - 8); ! 1338: pal2 = inb((u16)base - 7); ! 1339: pal3 = inb((u16)base - 6); ! 1340: ! 1341: if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || ! 1342: ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3))|| ! 1343: ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && (pal3 == ATT_ID3))){ ! 1344: DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n", ! 1345: (int)pal1, (int)pal2, (int)pal3)); ! 1346: #endif ! 1347: if (get_conf_PIO(base, buf) == TRUE) { ! 1348: if (buf->IRQ) { ! 1349: DBG(DBG_EISA, printk("Registering EISA HBA\n")); ! 1350: register_HBA(base, buf, tpnt, IS_EISA); ! 1351: } else ! 1352: printk("eata_dma: No valid IRQ. HBA removed from list\n"); ! 1353: } ! 1354: #if CHECK_BLINK ! 1355: else { ! 1356: if (check_blink_state(base)) ! 1357: printk("HBA is in BLINK state. Consult your HBAs " ! 1358: "Manual to correct this.\n"); ! 1359: } ! 1360: #endif ! 1361: /* Nothing found here so we take it from the list */ ! 1362: EISAbases[i] = 0; ! 1363: #if CHECKPAL ! 1364: } ! 1365: #endif ! 1366: } ! 1367: } ! 1368: return; ! 1369: } ! 1370: ! 1371: void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 1372: { ! 1373: int i; ! 1374: ! 1375: for (i = 0; i < MAXISA; i++) { ! 1376: if (ISAbases[i]) { ! 1377: if (get_conf_PIO(ISAbases[i],buf) == TRUE){ ! 1378: DBG(DBG_ISA, printk("Registering ISA HBA\n")); ! 1379: register_HBA(ISAbases[i], buf, tpnt, IS_ISA); ! 1380: } ! 1381: #if CHECK_BLINK ! 1382: else { ! 1383: if (check_blink_state(ISAbases[i])) ! 1384: printk("HBA is in BLINK state. Consult your HBAs " ! 1385: "Manual to correct this.\n"); ! 1386: } ! 1387: #endif ! 1388: ISAbases[i] = 0; ! 1389: } ! 1390: } ! 1391: return; ! 1392: } ! 1393: ! 1394: void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) ! 1395: { ! 1396: ! 1397: #ifndef CONFIG_PCI ! 1398: printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); ! 1399: #else ! 1400: ! 1401: u8 pci_bus, pci_device_fn; ! 1402: static s16 pci_index = 0; /* Device index to PCI BIOS calls */ ! 1403: u32 base = 0; ! 1404: u16 com_adr; ! 1405: u16 rev_device; ! 1406: u32 error, i, x; ! 1407: u8 pal1, pal2, pal3; ! 1408: ! 1409: if (pcibios_present()) { ! 1410: for (i = 0; i <= MAXPCI; ++i, ++pci_index) { ! 1411: if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, ! 1412: pci_index, &pci_bus, &pci_device_fn)) ! 1413: break; ! 1414: DBG(DBG_PROBE && DBG_PCI, ! 1415: printk("eata_dma: find_PCI, HBA at bus %d, device %d," ! 1416: " function %d, index %d\n", (s32)pci_bus, ! 1417: (s32)((pci_device_fn & 0xf8) >> 3), ! 1418: (s32)(pci_device_fn & 7), pci_index)); ! 1419: ! 1420: if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, ! 1421: PCI_CLASS_DEVICE, &rev_device))) { ! 1422: if (rev_device == PCI_CLASS_STORAGE_SCSI) { ! 1423: if (!(error = pcibios_read_config_word(pci_bus, ! 1424: pci_device_fn, PCI_COMMAND, ! 1425: (u16 *) & com_adr))) { ! 1426: if (!((com_adr & PCI_COMMAND_IO) && ! 1427: (com_adr & PCI_COMMAND_MASTER))) { ! 1428: printk("eata_dma: find_PCI, HBA has IO or" ! 1429: " BUSMASTER mode disabled\n"); ! 1430: continue; ! 1431: } ! 1432: } else ! 1433: printk("eata_dma: find_PCI, error %x while reading " ! 1434: "PCI_COMMAND\n", error); ! 1435: } else ! 1436: printk("eata_dma: find_PCI, DEVICECLASSID %x didn't match\n", ! 1437: rev_device); ! 1438: } else { ! 1439: printk("eata_dma: find_PCI, error %x while reading " ! 1440: "PCI_CLASS_BASE\n", ! 1441: error); ! 1442: continue; ! 1443: } ! 1444: ! 1445: if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, ! 1446: PCI_BASE_ADDRESS_0, (int *) &base))){ ! 1447: ! 1448: /* Check if the address is valid */ ! 1449: if (base & 0x01) { ! 1450: base &= 0xfffffffe; ! 1451: /* EISA tag there ? */ ! 1452: pal1 = inb(base); ! 1453: pal2 = inb(base + 1); ! 1454: pal3 = inb(base + 2); ! 1455: if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || ! 1456: ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && ! 1457: (pal3 == NEC_ID3)) || ! 1458: ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && ! 1459: (pal3 == ATT_ID3))) ! 1460: base += 0x08; ! 1461: else ! 1462: base += 0x10; /* Now, THIS is the real address */ ! 1463: ! 1464: if (base != 0x1f8) { ! 1465: /* We didn't find it in the primary search */ ! 1466: if (get_conf_PIO(base, buf) == TRUE) { ! 1467: ! 1468: /* OK. We made it till here, so we can go now ! 1469: * and register it. We only have to check and ! 1470: * eventually remove it from the EISA and ISA list ! 1471: */ ! 1472: DBG(DBG_PCI, printk("Registering PCI HBA\n")); ! 1473: register_HBA(base, buf, tpnt, IS_PCI); ! 1474: ! 1475: if (base < 0x1000) { ! 1476: for (x = 0; x < MAXISA; ++x) { ! 1477: if (ISAbases[x] == base) { ! 1478: ISAbases[x] = 0; ! 1479: break; ! 1480: } ! 1481: } ! 1482: } else if ((base & 0x0fff) == 0x0c88) ! 1483: EISAbases[(base >> 12) & 0x0f] = 0; ! 1484: continue; /* break; */ ! 1485: } ! 1486: #if CHECK_BLINK ! 1487: else if (check_blink_state(base) == TRUE) { ! 1488: printk("eata_dma: HBA is in BLINK state.\n" ! 1489: "Consult your HBAs manual to correct this.\n"); ! 1490: } ! 1491: #endif ! 1492: } ! 1493: } ! 1494: } else { ! 1495: printk("eata_dma: error %x while reading " ! 1496: "PCI_BASE_ADDRESS_0\n", error); ! 1497: } ! 1498: } ! 1499: } else { ! 1500: printk("eata_dma: No BIOS32 extensions present. This driver release " ! 1501: "still depends on it.\n" ! 1502: " Skipping scan for PCI HBAs. \n"); ! 1503: } ! 1504: #endif /* #ifndef CONFIG_PCI */ ! 1505: return; ! 1506: } ! 1507: ! 1508: int eata_detect(Scsi_Host_Template * tpnt) ! 1509: { ! 1510: struct Scsi_Host *HBA_ptr; ! 1511: struct get_conf gc; ! 1512: int i; ! 1513: ! 1514: DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, ! 1515: printk("Using lots of delays to let you read the debugging output\n")); ! 1516: ! 1517: tpnt->proc_dir = &proc_scsi_eata_dma; ! 1518: ! 1519: status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA); ! 1520: dma_scratch = scsi_init_malloc(1024, GFP_ATOMIC | GFP_DMA); ! 1521: ! 1522: if(status == NULL || dma_scratch == NULL) { ! 1523: printk("eata_dma: can't allocate enough memory to probe for hosts !\n"); ! 1524: return(0); ! 1525: } ! 1526: ! 1527: dma_scratch += 4; ! 1528: ! 1529: find_PCI(&gc, tpnt); ! 1530: ! 1531: find_EISA(&gc, tpnt); ! 1532: ! 1533: find_ISA(&gc, tpnt); ! 1534: ! 1535: for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */ ! 1536: if (reg_IRQ[i] >= 1){ /* exchange the interrupt handler which */ ! 1537: free_irq(i, NULL); /* we used for probing with the real one */ ! 1538: request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT|SA_SHIRQ, ! 1539: "eata_dma", NULL); ! 1540: } ! 1541: } ! 1542: ! 1543: HBA_ptr = first_HBA; ! 1544: ! 1545: if (registered_HBAs != 0) { ! 1546: printk("EATA (Extended Attachment) driver version: %d.%d%s" ! 1547: "\ndeveloped in co-operation with DPT\n" ! 1548: "(c) 1993-96 Michael Neuffer, [email protected]\n", ! 1549: VER_MAJOR, VER_MINOR, VER_SUB); ! 1550: printk("Registered HBAs:"); ! 1551: printk("\nHBA no. Boardtype Revis EATA Bus BaseIO IRQ" ! 1552: " DMA Ch ID Pr QS S/G IS\n"); ! 1553: for (i = 1; i <= registered_HBAs; i++) { ! 1554: printk("scsi%-2d: %.12s v%s 2.0%c %s %#.4x %2d", ! 1555: HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, ! 1556: SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? ! 1557: "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ", ! 1558: (u32) HBA_ptr->base, HBA_ptr->irq); ! 1559: if(HBA_ptr->dma_channel != BUSMASTER) ! 1560: printk(" %2x ", HBA_ptr->dma_channel); ! 1561: else ! 1562: printk(" %s", "BMST"); ! 1563: printk(" %d %d %c %3d %3d %c\n", ! 1564: SD(HBA_ptr)->channel+1, HBA_ptr->this_id, ! 1565: (SD(HBA_ptr)->primary == TRUE)?'Y':'N', ! 1566: HBA_ptr->can_queue, HBA_ptr->sg_tablesize, ! 1567: (SD(HBA_ptr)->immediate_support == TRUE)?'Y':'N'); ! 1568: HBA_ptr = SD(HBA_ptr)->next; ! 1569: } ! 1570: } else { ! 1571: scsi_init_free((void *)status, 512); ! 1572: } ! 1573: ! 1574: scsi_init_free((void *)dma_scratch - 4, 1024); ! 1575: ! 1576: DBG(DPT_DEBUG, DELAY(12)); ! 1577: ! 1578: return(registered_HBAs); ! 1579: } ! 1580: ! 1581: #ifdef MODULE ! 1582: /* Eventually this will go into an include file, but this will be later */ ! 1583: Scsi_Host_Template driver_template = EATA_DMA; ! 1584: #include "scsi_module.c" ! 1585: #endif ! 1586: ! 1587: /* ! 1588: * Overrides for Emacs so that we almost follow Linus's tabbing style. ! 1589: * Emacs will notice this stuff at the end of the file and automatically ! 1590: * adjust the settings for this buffer only. This must remain at the end ! 1591: * of the file. ! 1592: * --------------------------------------------------------------------------- ! 1593: * Local variables: ! 1594: * c-indent-level: 4 ! 1595: * c-brace-imaginary-offset: 0 ! 1596: * c-brace-offset: -4 ! 1597: * c-argdecl-indent: 4 ! 1598: * c-label-offset: -4 ! 1599: * c-continued-statement-offset: 4 ! 1600: * c-continued-brace-offset: 0 ! 1601: * tab-width: 8 ! 1602: * End: ! 1603: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.