diff -uNr linux/CREDITS linux.wrk.2.0.31/CREDITS --- linux/CREDITS Wed Sep 17 21:00:48 1997 +++ linux.wrk.2.0.31/CREDITS Sun Nov 2 19:55:11 1997 @@ -1019,9 +1019,9 @@ S: United Kingdom N: Michael Neuffer -E: mike@i-Connect.Net E: neuffer@goofy.zdv.uni-mainz.de -W: http://www.i-Connect.Net/~mike/ +W: http://www.uni-mainz.de/~neuffer/ D: Developer and maintainer of the EATA-DMA SCSI driver D: Co-developer EATA-PIO SCSI driver D: /proc/scsi and assorted other snippets + diff -uNr linux/drivers/scsi/eata_dma.c linux.wrk.2.0.31/drivers/scsi/eata_dma.c --- linux/drivers/scsi/eata_dma.c Mon Oct 28 23:30:43 1996 +++ linux.wrk.2.0.31/drivers/scsi/eata_dma.c Mon Nov 3 19:25:14 1997 @@ -27,8 +27,7 @@ * -provides rudimentary latency measurement * * possibilities via /proc/scsi/eata_dma/ * * * - * (c)1993-96 Michael Neuffer * - * mike@i-Connect.Net * + * (c)1993-97 Michael Neuffer * * neuffer@mail.uni-mainz.de * * * * This program is free software; you can redistribute it * @@ -58,7 +57,7 @@ * Jagdis who did a lot of testing and found quite a number * * of bugs during the development. * ************************************************************ - * last change: 96/10/21 OS: Linux 2.0.23 * + * last change: 97/10/01 OS: Linux 2.0.31 * ************************************************************/ /* Look in eata_dma.h for configuration and revision information */ @@ -74,6 +73,10 @@ #include #include #include +#include +/* +#include +*/ #include #include #include @@ -101,22 +104,28 @@ {0x1F0, 0x170, 0x330, 0x230}; static unchar EISAbases[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -static uint registered_HBAs = 0; +static int registered_HBAs = 0; static struct Scsi_Host *last_HBA = NULL; static struct Scsi_Host *first_HBA = NULL; + +#if OLD_IRQ static unchar reg_IRQ[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static unchar reg_IRQL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif + static struct eata_sp *status = 0; /* Statuspacket array */ static void *dma_scratch = 0; static struct eata_register *fake_int_base; -static int fake_int_result; -static int fake_int_happened; +volatile static int fake_int_result; +volatile static int fake_int_happened; static ulong int_counter = 0; static ulong queue_counter = 0; +static ulong sg_counter = 0; +static ulong nsg_counter = 0; void eata_scsi_done (Scsi_Cmnd * scmd) { @@ -143,6 +152,8 @@ int eata_release(struct Scsi_Host *sh) { uint i; + + if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); else reg_IRQ[sh->irq]--; @@ -158,36 +169,87 @@ if (sh->dma_channel != BUSMASTER) free_dma(sh->dma_channel); if (sh->io_port && sh->n_io_port) release_region(sh->io_port, sh->n_io_port); - } + } + + printk(KERN_INFO "eata_dma/dpt: Unloaded.\n"); + return(TRUE); } #endif +inline void add_timeval(struct timeval *t2, struct timeval *t1) +{ + t2->tv_sec += t1->tv_sec; + t2->tv_usec += t1->tv_usec; + if(t2->tv_usec > 1000000) { + t2->tv_usec -= 1000000; + t2->tv_sec += 1; + } +} + + + +inline void sub_timeval(struct timeval *t2, struct timeval *t1) +{ + t2->tv_sec -= t1->tv_sec; + + /* FIXME: We've got a problem here: + * Sometimes we have t2 < t1 + * even so the timestamp has been taken later. + * We shouldn't need to have to check if we can + * decrease t2->tv_sec. This will cause incorrect + * statistics. + */ + if(t2->tv_sec) { + if(t2->tv_usec < t1->tv_usec) { + + t2->tv_usec += 1000000; + + t2->tv_sec -= 1; + } + t2->tv_usec -= t1->tv_usec; + + } else if (t2->tv_usec >= t1->tv_usec) { + + t2->tv_usec -= t1->tv_usec; + } + +} inline void eata_latency_in(struct eata_ccb *cp, hostdata *hd) { - uint time; - time = jiffies - cp->timestamp; - if(hd->all_lat[1] > time) - hd->all_lat[1] = time; - if(hd->all_lat[2] < time) - hd->all_lat[2] = time; - hd->all_lat[3] += time; - hd->all_lat[0]++; + struct timeval ttime; + ulong time; + + do_gettimeofday(&ttime); + + sub_timeval(&ttime, &cp->timestamp); + + /* If a operation takes longer then 1000s set it to 1000s + * We might want to increase this value */ + + time = (ttime.tv_sec * 1000000) + ttime.tv_usec; + if (time > 1000000000) { + DBG(DBG_TC, printk("time %ul, sec %ul, usec %ul\n", time, ttime.tv_sec, ttime.tv_usec)); + + time = 1000000000; + } + if((cp->rw_latency) == WRITE) { /* was WRITE */ - if(hd->writes_lat[cp->sizeindex][1] > time) + if(hd->writes_lat[cp->sizeindex][0] > time) + hd->writes_lat[cp->sizeindex][0] = time; + if(hd->writes_lat[cp->sizeindex][1] < time) hd->writes_lat[cp->sizeindex][1] = time; - if(hd->writes_lat[cp->sizeindex][2] < time) - hd->writes_lat[cp->sizeindex][2] = time; - hd->writes_lat[cp->sizeindex][3] += time; - hd->writes_lat[cp->sizeindex][0]++; + add_timeval(&hd->writes_sum[cp->sizeindex], &ttime); + hd->writescount[cp->sizeindex]++; + } else if((cp->rw_latency) == READ) { - if(hd->reads_lat[cp->sizeindex][1] > time) + if(hd->reads_lat[cp->sizeindex][0] > time) + hd->reads_lat[cp->sizeindex][0] = time; + if(hd->reads_lat[cp->sizeindex][1] < time) hd->reads_lat[cp->sizeindex][1] = time; - if(hd->reads_lat[cp->sizeindex][2] < time) - hd->reads_lat[cp->sizeindex][2] = time; - hd->reads_lat[cp->sizeindex][3] += time; - hd->reads_lat[cp->sizeindex][0]++; + add_timeval(&hd->reads_sum[cp->sizeindex], &ttime); + hd->readscount[cp->sizeindex]++; } } @@ -197,7 +259,8 @@ short *sho; long *lon; x = 0; /* just to keep GCC quiet */ - cp->timestamp = jiffies; /* For latency measurements */ + cp->do_latency = TRUE; + do_gettimeofday(&cp->timestamp); /* For latency measurements */ switch(cmd->cmnd[0]) { case WRITE_6: x = cmd->cmnd[4]/2; @@ -241,7 +304,7 @@ } -void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs) +void eata_int_handler(int irq, struct Scsi_Host *sh, struct pt_regs * regs) { uint i, result = 0; uint hba_stat, scsi_stat, eata_stat; @@ -249,12 +312,16 @@ struct eata_ccb *ccb; struct eata_sp *sp; uint base; - uint x; + /* struct Scsi_Host *sh; + */ +#if OLD_IRQ + uint x; for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { - if (sh->irq != irq) + if (sh->irq != irq) continue; +#endif while(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { @@ -308,7 +375,7 @@ switch (hba_stat) { case HA_NO_ERROR: /* NO Error */ - if(HD(cmd)->do_latency == TRUE && ccb->timestamp) + if(HD(cmd)->do_latency == TRUE && ccb->do_latency) eata_latency_in(ccb, HD(cmd)); result = DID_OK << 16; break; @@ -369,21 +436,27 @@ #if DBG_INTR2 if (scsi_stat || result || hba_stat || eata_stat != 0x50 - || cmd->scsi_done == NULL || cmd->device->id == 7) + || cmd->scsi_done == NULL || cmd->device->id == 7) { printk("HBA: %d, channel %d, id: %d, lun %d, pid %ld:\n" "eata_stat %#x, hba_stat %#.2x, scsi_stat %#.2x, " - "sense_key: %#x, result: %#.8x\n", x, + "sense_key: %#x, result: %#.8x\n", + (int)SD(sh)->HBA_number, cmd->device->channel, cmd->device->id, cmd->device->lun, cmd->pid, eata_stat, hba_stat, scsi_stat, - cmd->sense_buffer[2] & 0xf, cmd->result); - DBG(DBG_INTR&&DBG_DELAY,DELAY(1)); + cmd->sense_buffer[2] & 0xf, cmd->result); + + /* Why did this start happening ? */ + if(eata_stat != 0xd0) + DBG(DBG_DELAY,DELAY(2)); + } #endif ccb->status = FREE; /* now we can release the slot */ cmd->scsi_done(cmd); } +#if OLD_IRQ } - +#endif return; } @@ -458,7 +531,7 @@ int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) { - unsigned int i, x, y; + int i, x, y; ulong flags; hostdata *hd; struct Scsi_Host *sh; @@ -523,7 +596,7 @@ cmd->pid, cmd->target, cmd->lun, y)); DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); - if(hd->do_latency == TRUE) + if(hd->do_latency == TRUE) eata_latency_out(ccb, cmd); cmd->scsi_done = (void *)done; @@ -555,12 +628,15 @@ if (cmd->use_sg) { ccb->scatter = TRUE; /* SG mode */ + +#if !(USE_MALLOC_SG) if (ccb->sg_list == NULL) { ccb->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list), GFP_ATOMIC | GFP_DMA); } if (ccb->sg_list == NULL) panic("eata_dma: Run out of DMA memory for SG lists !\n"); +#endif ccb->cp_dataDMA = htonl(virt_to_bus(ccb->sg_list)); ccb->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list)); @@ -569,7 +645,9 @@ ccb->sg_list[i].data = htonl(virt_to_bus(sl->address)); ccb->sg_list[i].len = htonl((u32) sl->length); } + sg_counter++; } else { + nsg_counter++; ccb->scatter = FALSE; ccb->cp_datalen = htonl(cmd->request_bufflen); ccb->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer)); @@ -631,7 +709,7 @@ if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { printk("eata_dma: scsi%d interrupt pending in eata_abort.\n" " Calling interrupt handler.\n", sh->host_no); - eata_int_handler(sh->irq, 0, 0); + eata_int_handler(sh->irq, sh, 0); } } @@ -660,6 +738,7 @@ restore_flags(flags); return (SCSI_ABORT_BUSY); /* SNOOZE */ } + if (CD(cmd)->status == FREE) { DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_NOT_RUNNING\n")); restore_flags(flags); @@ -671,7 +750,8 @@ int eata_reset(Scsi_Cmnd * cmd, unsigned int resetflags) { - uint x; + int indx; + int x; ulong loop = loops_per_sec / 3; ulong flags; unchar success = FALSE; @@ -689,7 +769,7 @@ if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { printk("eata_dma: scsi%d interrupt pending in eata_reset.\n" " Calling interrupt handler.\n", sh->host_no); - eata_int_handler(sh->irq, 0, 0); + eata_int_handler(sh->irq, sh, 0); } } @@ -708,25 +788,25 @@ return (SCSI_RESET_ERROR); } - for (x = 0; x < cmd->host->can_queue; x++) { - if (HD(cmd)->ccb[x].status == FREE) + for (indx = 0; indx < cmd->host->can_queue; indx++) { + if (HD(cmd)->ccb[indx].status == FREE) continue; - if (HD(cmd)->ccb[x].status == LOCKED) { - HD(cmd)->ccb[x].status = FREE; - printk("eata_reset: locked slot %d forced free.\n", x); + if (HD(cmd)->ccb[indx].status == LOCKED) { + HD(cmd)->ccb[indx].status = FREE; + printk("eata_reset: locked slot %d forced free.\n", indx); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); continue; } - sp = HD(cmd)->ccb[x].cmd; - HD(cmd)->ccb[x].status = RESET; + sp = HD(cmd)->ccb[indx].cmd; + HD(cmd)->ccb[indx].status = RESET; if (sp == NULL) - panic("eata_reset: slot %d, sp==NULL.\n", x); + panic("eata_reset: slot %d, sp==NULL.\n", indx); - printk("eata_reset: slot %d in reset, pid %ld.\n", x, sp->pid); + printk("eata_reset: slot %d in reset, pid %ld.\n", indx, sp->pid); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); @@ -749,21 +829,21 @@ DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled again.\n")); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - for (x = 0; x < cmd->host->can_queue; x++) { + for (indx = 0; indx < cmd->host->can_queue; indx++) { /* Skip slots already set free by interrupt and those that * are still LOCKED from the last reset */ - if (HD(cmd)->ccb[x].status != RESET) + if (HD(cmd)->ccb[indx].status != RESET) continue; - sp = HD(cmd)->ccb[x].cmd; + sp = HD(cmd)->ccb[indx].cmd; sp->result = DID_RESET << 16; /* This mailbox is still waiting for its interrupt */ - HD(cmd)->ccb[x].status = LOCKED; + HD(cmd)->ccb[indx].status = LOCKED; printk("eata_reset: slot %d locked, DID_RESET, pid %ld done.\n", - x, sp->pid); + indx, sp->pid); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); sp->scsi_done(sp); @@ -783,6 +863,21 @@ } } +int eata_bios_param(Disk * disk, kdev_t dev, int *geo) +{ + uint size = disk->capacity; + + if(size < 0x800000) { + return(scsicam_bios_param(disk, dev, geo)); + } else { + geo[0] = 255; + geo[1] = 62; + geo[2] = size / (255 * 62); + } + return(0); +} + + /* Here we try to determine the optimum queue depth for * each attached device. * @@ -882,29 +977,30 @@ #endif } -#if CHECK_BLINK int check_blink_state(long base) { - ushort loops = 10; + int i, loops = 10; u32 blinkindicator; - u32 state = 0x12345678; + u32 state; u32 oldstate = 0; + + i = 0; + state = htonl(0x78563412); blinkindicator = htonl(0x54504442); + while ((loops--) && (state != oldstate)) { oldstate = state; - state = inl((uint) base + 1); + state = inl((uint) base + HA_RERROR); } DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n", (state == oldstate) && (state == blinkindicator))); if ((state == oldstate) && (state == blinkindicator)) - return(TRUE); - else - return (FALSE); + i = inb(base + HA_WDMAADDR + 3); + return(i); } -#endif char * get_board_data(u32 base, u32 irq, u32 id) { @@ -913,6 +1009,8 @@ static char *buff; ulong i; + DBG(DBG_GBD || DBG_COM, printk("Entering get_board_data()\n")); + cp = (struct eata_ccb *) scsi_init_malloc(sizeof(struct eata_ccb), GFP_ATOMIC | GFP_DMA); sp = (struct eata_sp *) scsi_init_malloc(sizeof(struct eata_sp), @@ -975,6 +1073,70 @@ } +int get_conf_dma(struct eata_register *base, struct get_conf *buf, int irq) +{ + + unsigned long wait; + + int bad_irq; + + volatile unsigned long *signature; + signature = (unsigned long *)(&(buf->signature)); + + + DBG(DBG_DMA, printk("eata_dma: entering get_conf_dma(%p,%p,%d)\n", + base, buf, irq)); + + if(check_region((uint)base, 9)) { + printk("eata_dma: IO-Region: %p - %p already in use", base, base + 9); + return (FALSE); + } + memset(buf, 0, sizeof(struct get_conf)); + + fake_int_base = base; + fake_int_result = FALSE; + fake_int_happened = FALSE; + + if (!(bad_irq = request_irq(irq, (void *) eata_fake_int_handler, + SA_INTERRUPT|SA_SHIRQ, "eata-dma-probe", base) + )){ + + if(eata_send_command((u32) buf, (u32)base, EATA_CMD_DMA_READ_CONFIG) == FALSE){ + free_irq(irq, base); + printk("eata_dma: Couldn't send command to %p\n", base); + return(FALSE); + } + wait = jiffies + (2 * HZ); + while((jiffies <= wait) + /* && (htonl(EATA_SIGNATURE) != ((volatile ulong) *signature)) */ + && fake_int_happened == FALSE) + barrier(); + + wait = jiffies + (2 * HZ) - wait; + + if(fake_int_happened == FALSE) + printk("NO interrupt happened ! This is bad. Waited %ld jiffies\n", + wait); + + if (htonl(EATA_SIGNATURE) == ((volatile ulong) *signature)) { + DBG(DBG_DMA&&DBG_PROBE, printk("EATA Controller found at %x " + "EATA Level: %x, IRQ: %d\n", + (uint) base, (uint) (buf->version), + (uint) (buf->IRQ))); + + free_irq(irq, base); + return (TRUE); + } + } else { + printk("eata_dma: get_conf_dma(), couldn't register IRQ for probing\n"); + } + free_irq(irq, base); + + DBG(DBG_DMA,print_config((struct get_conf *)buf)); + + return (FALSE); +} + int get_conf_PIO(u32 base, struct get_conf *buf) { ulong loop = R_LIMIT; @@ -1026,6 +1188,36 @@ } +int malloc_sg(hostdata *hd) +{ + int size; + int i; + + size = sizeof(struct eata_sg_list) * hd->sgsize; + + printk("%s, %d: Allocating %d * %d bytes for SG lists\n", + __FILE__, __LINE__, hd->queuesize, size); + + for(i = 0; i < hd->queuesize; i++) { + if(!(hd->ccb[i].sg_list = scsi_init_malloc(size, GFP_DMA))){ + printk("Cannot malloc memory for Scatter/Gather Operation !\n" + "Reverting to non-SG mode to limp along.....\n"); + +panic("%s, %d: Stop operation during tests\n", __FILE__, __LINE__); + + while(i >= 0) { + kfree(hd->ccb[i].sg_list); + hd->ccb[i].sg_list = NULL; + i--; + return(FALSE); + } + } + } + + return(TRUE); +} + + void print_config(struct get_conf *gc) { printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n", @@ -1041,7 +1233,7 @@ gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); printk("RIDQ:%d PCI:%d EISA:%d\n", gc->ID_qest, gc->is_PCI, gc->is_EISA); - DBG(DPT_DEBUG, DELAY(14)); + DBG(DBG_DELAY, DELAY(14)); } short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, @@ -1066,6 +1258,8 @@ if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) gc->MAX_CHAN = 0; + +#if OLD_IRQ if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT, "eata_dma", NULL)){ @@ -1084,7 +1278,14 @@ } else reg_IRQ[gc->IRQ]++; } - +#else + if (request_irq(gc->IRQ, (void *) eata_fake_int_handler, + SA_INTERRUPT|SA_SHIRQ, "eata_dma", base)){ + printk("eata_dma: Couldn't allocate IRQ %d for controller at %lx," + "Interrupt already in exclusive use.", gc->IRQ, (long)base); + return (FALSE); + } +#endif /* If DMA is supported but DMA_valid isn't set to indicate that * the channel number is given we must have pre 2.0 firmware (1.7?) @@ -1105,11 +1306,13 @@ if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) { printk(KERN_WARNING "Unable to allocate DMA channel %d for ISA HBA" " at %#.4x.\n", dma_channel, base); +#if OLD_IRQ reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; +#endif return (FALSE); } } @@ -1121,9 +1324,18 @@ enable_dma(dma_channel); } + /* FIXME: We must find a way to reliably read the board data + * on ISA and EISA controllers + */ if (bustype != IS_EISA && bustype != IS_ISA) buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]); +#if !(OLD_IRQ) + /* Now that we have the board data, we can free the fake handler for + * the last time. + */ + free_irq(gc->IRQ, base); +#endif if (buff == NULL) { if (bustype == IS_EISA || bustype == IS_ISA) { bugs = bugs || BROKEN_INQUIRY; @@ -1136,11 +1348,13 @@ "Sorry.\n", base); if (gc->DMA_valid) free_dma(dma_channel); +#if OLD_IRQ reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; +#endif return (FALSE); } } @@ -1165,44 +1379,10 @@ size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) * ntohs(gc->queuesiz)); - DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size)); + DBG(DBG_REGISTER, printk("%s %d: scsi_register size: %ld\n", + __FILE__, __LINE__, size)); sh = scsi_register(tpnt, size); - - if(sh != NULL) { - - hd = SD(sh); - - memset(hd->reads, 0, sizeof(u32) * 26); - - sh->select_queue_depths = eata_select_queue_depths; - - hd->bustype = bustype; - - /* - * If we are using a ISA board, we can't use extended SG, - * because we would need excessive amounts of memory for - * bounce buffers. - */ - if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){ - sh->sg_tablesize = SG_SIZE_BIG; - } else { - sh->sg_tablesize = ntohs(gc->SGsiz); - if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) { - if (sh->sg_tablesize == 0) - printk(KERN_WARNING "Warning: SG size had to be fixed.\n" - "This might be a PM2012 with a defective Firmware" - "\nContact DPT support@dpt.com for an upgrade\n"); - sh->sg_tablesize = SG_SIZE; - } - } - hd->sgsize = sh->sg_tablesize; - } - - if(sh != NULL) { - sh->can_queue = hd->queuesize = ntohs(gc->queuesiz); - sh->cmd_per_lun = 0; - } if(sh == NULL) { DBG(DBG_REGISTER, printk(KERN_NOTICE "eata_dma: couldn't register HBA" @@ -1210,15 +1390,55 @@ scsi_unregister(sh); if (gc->DMA_valid) free_dma(dma_channel); - - reg_IRQ[gc->IRQ]--; +#if OLD_IRQ + reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; +#endif return (FALSE); } + + hd = SD(sh); + + sh->can_queue = hd->queuesize = ntohs(gc->queuesiz); + sh->cmd_per_lun = 0; + + sh->select_queue_depths = eata_select_queue_depths; + + hd->bustype = bustype; + + /* + * If we are using a ISA board, we can't use extended SG, + * because we would need excessive amounts of memory for + * bounce buffers. + */ + if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){ + sh->sg_tablesize = SG_SIZE_BIG; + } else { + sh->sg_tablesize = ntohs(gc->SGsiz); + if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) { + if (sh->sg_tablesize == 0) + printk(KERN_WARNING "Warning: SG size had to be fixed.\n" + "This might be a PM2012 with a defective Firmware" + "\nContact DPT support@dpt.com for an upgrade\n"); + sh->sg_tablesize = SG_SIZE; + } + } + hd->sgsize = sh->sg_tablesize; + +#if USE_MALLOC_SG + + if(malloc_sg(hd) == FALSE) { + /* Darn, we couldn't get the needed memory. + * Reset the settings + */ + hd->sgsize = sh->sg_tablesize = 1; + } + +#endif hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY); @@ -1301,10 +1521,14 @@ } for(x = 0; x <= 11; x++){ /* Initialize min. latency */ - hd->writes_lat[x][1] = 0xffffffff; - hd->reads_lat[x][1] = 0xffffffff; + hd->writes_lat[x][0] = 0xffffffff; + hd->reads_lat[x][0] = 0xffffffff; } - hd->all_lat[1] = 0xffffffff; + + memset(hd->reads, 0, sizeof(hd->reads)); + memset(hd->writes, 0, sizeof(hd->writes)); + memset(hd->reads_sum, 0, sizeof(hd->reads_sum)); + memset(hd->writes_sum, 0, sizeof(hd->writes_sum)); hd->next = NULL; /* build a linked list of all HBAs */ hd->prev = last_HBA; @@ -1344,7 +1568,8 @@ DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n", (int)pal1, (int)pal2, (int)pal3)); #endif - if (get_conf_PIO(base, buf) == TRUE) { + if (get_conf_PIO(base, buf) == TRUE) + { if (buf->IRQ) { DBG(DBG_EISA, printk("Registering EISA HBA\n")); register_HBA(base, buf, tpnt, IS_EISA); @@ -1398,29 +1623,27 @@ printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); #else - u8 pci_bus, pci_device_fn; + u8 pci_bus, pci_device_fn, irq; static s16 pci_index = 0; /* Device index to PCI BIOS calls */ - u32 base = 0; + u32 base, base1; u16 com_adr; u16 rev_device; - u32 error, i, x; + u32 error, x; u8 pal1, pal2, pal3; if (pcibios_present()) { - for (i = 0; i <= MAXPCI; ++i, ++pci_index) { - if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, - pci_index, &pci_bus, &pci_device_fn)) - break; - DBG(DBG_PROBE && DBG_PCI, - printk("eata_dma: find_PCI, HBA at bus %d, device %d," - " function %d, index %d\n", (s32)pci_bus, - (s32)((pci_device_fn & 0xf8) >> 3), - (s32)(pci_device_fn & 7), pci_index)); + while(pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, + pci_index++, &pci_bus, &pci_device_fn) == 0) { + DBG(DBG_PROBE && DBG_PCI, + printk("eata_dma: find_PCI, HBA at bus %d, device %d," + " function %d, index %d\n", (s32)pci_bus, + (s32)((pci_device_fn & 0xf8) >> 3), + (s32)(pci_device_fn & 7), pci_index)); - if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_CLASS_DEVICE, &rev_device))) { - if (rev_device == PCI_CLASS_STORAGE_SCSI) { - if (!(error = pcibios_read_config_word(pci_bus, + if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_CLASS_DEVICE, &rev_device))) { + if (rev_device == PCI_CLASS_STORAGE_SCSI) { + if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, (u16 *) & com_adr))) { if (!((com_adr & PCI_COMMAND_IO) && @@ -1441,9 +1664,19 @@ error); continue; } + + /* TODO Diese beiden muessen noch ins if() */ + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_1, (int *) &base1); + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &irq); + + if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, (int *) &base))){ - if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, (int *) &base))){ + DBG(DBG_PCI, printk("IOaddress=%lx\nPCIaddress=%lx\n", + (ulong)base & PCI_BASE_ADDRESS_IO_MASK, + (ulong)base1 & PCI_BASE_ADDRESS_MEM_MASK)); /* Check if the address is valid */ if (base & 0x01) { @@ -1456,14 +1689,22 @@ ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3)) || ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && - (pal3 == ATT_ID3))) + (pal3 == ATT_ID3))) { base += 0x08; - else + } else { base += 0x10; /* Now, THIS is the real address */ - + } if (base != 0x1f8) { /* We didn't find it in the primary search */ - if (get_conf_PIO(base, buf) == TRUE) { +#if DMA_PROBE + + + if (get_conf_dma((struct eata_register *)base, buf, irq) + == TRUE) +#else + if (get_conf_PIO(base, buf) == TRUE) +#endif + { /* OK. We made it till here, so we can go now * and register it. We only have to check and @@ -1511,7 +1752,7 @@ struct get_conf gc; int i; - DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, + DBG((DBG_PROBE && DBG_DELAY), printk("Using lots of delays to let you read the debugging output\n")); tpnt->proc_dir = &proc_scsi_eata_dma; @@ -1532,6 +1773,9 @@ find_ISA(&gc, tpnt); + HBA_ptr = first_HBA; + +#if OLD_IRQ for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */ if (reg_IRQ[i] >= 1){ /* exchange the interrupt handler which */ free_irq(i, NULL); /* we used for probing with the real one */ @@ -1539,18 +1783,21 @@ "eata_dma", NULL); } } - - HBA_ptr = first_HBA; +#endif if (registered_HBAs != 0) { printk("EATA (Extended Attachment) driver version: %d.%d%s" "\ndeveloped in co-operation with DPT\n" - "(c) 1993-96 Michael Neuffer, mike@i-Connect.Net\n", + "(c) 1993-97 Michael Neuffer, neuffer@mail.uni-mainz.de\n", VER_MAJOR, VER_MINOR, VER_SUB); printk("Registered HBAs:"); printk("\nHBA no. Boardtype Revis EATA Bus BaseIO IRQ" " DMA Ch ID Pr QS S/G IS\n"); for (i = 1; i <= registered_HBAs; i++) { +#if !(OLD_IRQ) + request_irq(HBA_ptr->irq, (void *)(eata_int_handler), + SA_INTERRUPT|SA_SHIRQ, SD(HBA_ptr)->name, HBA_ptr); +#endif printk("scsi%-2d: %.12s v%s 2.0%c %s %#.4x %2d", HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? @@ -1573,10 +1820,11 @@ scsi_init_free((void *)dma_scratch - 4, 1024); - DBG(DPT_DEBUG, DELAY(12)); + DBG(DBG_DELAY, DELAY(12)); return(registered_HBAs); } + #ifdef MODULE /* Eventually this will go into an include file, but this will be later */ diff -uNr linux/drivers/scsi/eata_dma.h linux.wrk.2.0.31/drivers/scsi/eata_dma.h --- linux/drivers/scsi/eata_dma.h Mon Oct 28 23:30:43 1996 +++ linux.wrk.2.0.31/drivers/scsi/eata_dma.h Mon Nov 3 18:47:43 1997 @@ -1,10 +1,9 @@ /******************************************************** * Header file for eata_dma.c Linux EATA-DMA SCSI driver * -* (c) 1993-96 Michael Neuffer * -* mike@i-Connect.Net * +* (c) 1993-97 Michael Neuffer * * neuffer@mail.uni-mainz.de * ********************************************************* -* last change: 96/10/14 * +* last change: 97/08/05 * ********************************************************/ #ifndef _EATA_DMA_H @@ -16,16 +15,21 @@ #define VER_MAJOR 2 -#define VER_MINOR 5 -#define VER_SUB "9b" +#define VER_MINOR 7 +#define VER_SUB "0a" /************************************************************************ * Here you can switch parts of the code on and of * ************************************************************************/ +#define USE_MALLOC_SG 1 +#define OLD_IRQ 0 /* Use new interrupt routines */ + +#define DMA_PROBE 0 /* Use get_conf_dma() for probing */ + #define CHECKPAL 0 /* EISA pal checking on/off */ -#define CHECK_BLINK 1 /* Switch Blink state check off, might * +#define CHECK_BLINK 0 /* Switch Blink state check off, might * * be nessessary for some MIPS machines*/ #define CRIPPLE_QUEUE 0 /* Only enable this if the interrupt * controller on your motherboard is @@ -37,16 +41,17 @@ * Enable DEBUG and whichever options you require. * ************************************************************************/ #define DEBUG_EATA 1 /* Enable debug code. */ -#define DPT_DEBUG 0 /* Bobs special */ #define DBG_DELAY 0 /* Build in delays so debug messages can be * be read before they vanish of the top of * the screen! */ -#define DBG_PROBE 0 /* Debug probe routines. */ -#define DBG_PCI 0 /* Trace PCI routines */ -#define DBG_EISA 0 /* Trace EISA routines */ -#define DBG_ISA 0 /* Trace ISA routines */ -#define DBG_BLINK 0 /* Trace Blink check */ -#define DBG_PIO 0 /* Trace get_config_PIO */ +#define DBG_PROBE 1 /* Debug probe routines. */ +#define DBG_PCI 1 /* Trace PCI routines */ +#define DBG_EISA 1 /* Trace EISA routines */ +#define DBG_ISA 1 /* Trace ISA routines */ +#define DBG_BLINK 1 /* Trace Blink check */ +#define DBG_PIO 1 /* Trace get_config_PIO */ +#define DBG_DMA 1 /* Trace get_config_dma */ +#define DBG_GBD 1 /* Trace get_board_data */ #define DBG_COM 0 /* Trace command call */ #define DBG_QUEUE 0 /* Trace command queueing. */ #define DBG_QUEUE2 0 /* Trace command queueing SG. */ @@ -58,7 +63,10 @@ #define DBG_STATUS 0 /* Trace status generation */ #define DBG_PROC 0 /* Debug proc-fs related statistics */ #define DBG_PROC_WRITE 0 -#define DBG_REGISTER 0 /* */ +#define DBG_REGISTER 0 /* Debug registration process */ +#define DBG_IOCTL 0 /* Debug IOCTL code */ +#define DBG_TC 1 + #define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort)*/ #if DEBUG_EATA @@ -67,6 +75,29 @@ #define DBG(x, y) #endif +/* Function Prototypes */ + +/* Declaring this one gives gcc the fritz, I don't want to look in to this now, + * but it is probably some easy to fix header file problem + */ +/* +void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs) +*/ +void eata_scsi_done (Scsi_Cmnd *); +void eata_latency_in(struct eata_ccb *, hostdata *); +void eata_latency_out(struct eata_ccb *, Scsi_Cmnd *); +int eata_send_command(u32 addr, u32 base, u8 command); +int eata_send_immediate(u32 base, u32 addr, u8 ifc, u8 code, u8 code2); +int check_blink_state(long base ); +char * get_board_data(u32 base, u32 irq, u32 id); +int get_conf_dma(struct eata_register *, struct get_conf *, int); +void print_config(struct get_conf *); +short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, + u8 bustype); +void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt); +void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt); +void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt); + #endif /* !HOSTS_C */ int eata_detect(Scsi_Host_Template *); @@ -76,6 +107,8 @@ int eata_abort(Scsi_Cmnd *); int eata_reset(Scsi_Cmnd *, unsigned int); int eata_proc_info(char *, char **, off_t, int, int, int); +int eata_bios_param(Disk * disk, kdev_t dev, int *geo); + #ifdef MODULE int eata_release(struct Scsi_Host *); #else @@ -96,7 +129,7 @@ eata_abort, \ eata_reset, \ NULL, /* Slave attach */ \ - scsicam_bios_param, \ + eata_bios_param, \ 0, /* Canqueue */ \ 0, /* this_id */ \ 0, /* sg_tablesize */ \ diff -uNr linux/drivers/scsi/eata_dma_proc.c linux.wrk.2.0.31/drivers/scsi/eata_dma_proc.c --- linux/drivers/scsi/eata_dma_proc.c Mon Aug 5 09:13:52 1996 +++ linux.wrk.2.0.31/drivers/scsi/eata_dma_proc.c Sun Nov 2 19:55:29 1997 @@ -29,30 +29,43 @@ * length : number of bytes written to the hostfile * HBA_ptr: pointer to the Scsi_Host struct */ -int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr) +int eata_set_info(char *buf, int length, struct Scsi_Host *HBA_ptr) { int orig_length = length; + char * buffer; + + buffer = buf; if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) { buffer += 9; length -= 9; - if(length >= 8 && strncmp(buffer, "latency", 7) == 0) { + if(length >= 7 && strncmp(buffer, "latency", 7) == 0) { SD(HBA_ptr)->do_latency = TRUE; return(orig_length); } - if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) { + if(length >=9 && strncmp(buffer, "nolatency", 9) == 0) { SD(HBA_ptr)->do_latency = FALSE; return(orig_length); } printk("Unknown command:%s length: %d\n", buffer, length); } else - printk("Wrong Signature:%10s\n", buffer); + DBG(DBG_PROC,printk("Wrong Signature:%10s\n", buffer)); return(-EINVAL); } +inline uint dpt_ave_latency(ulong count, struct timeval *sum) +{ + if(!count) + count = 1; + + return((sum->tv_sec / count * 1000000) + + ((sum->tv_sec % count) * (1000000 / count)) + + (sum->tv_usec / count)); +} + /* * eata_proc_info * inout : decides on the direction of the dataflow and the meaning of the @@ -70,6 +83,7 @@ Scsi_Device *scd, SDev; struct Scsi_Host *HBA_ptr; + hostdata *hd; Scsi_Cmnd scmd; char cmnd[10]; static u8 buff[512]; @@ -86,7 +100,8 @@ subinf *si; pcinf *pi; arrlim *al; - int i, x; + int i; + int x; int size, len = 0; off_t begin = 0; off_t pos = 0; @@ -97,10 +112,12 @@ if (HBA_ptr->host_no == hostno) break; HBA_ptr = SD(HBA_ptr)->next; - } + } + + hd = SD(HBA_ptr); if(inout == TRUE) /* Has data been written to the file ? */ - return(eata_set_info(buffer, length, HBA_ptr)); + return(eata_set_info(buffer, length, HBA_ptr)); if (offset == 0) memset(buff, 0, sizeof(buff)); @@ -124,19 +141,23 @@ "processed interrupts:%10ld\n", queue_counter, int_counter); len += size; pos = begin + len; + size = sprintf(buffer + len, "commands with SG : %10ld\n" + "commands without SG: %10ld\n", sg_counter, nsg_counter); + len += size; pos = begin + len; + size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", - HBA_ptr->host_no, SD(HBA_ptr)->name); + HBA_ptr->host_no, hd->name); len += size; pos = begin + len; size = sprintf(buffer + len, "Firmware revision: v%s\n", - SD(HBA_ptr)->revision); + hd->revision); len += size; pos = begin + len; size = sprintf(buffer + len, "Hardware Configuration:\n"); len += size; pos = begin + len; - if(SD(HBA_ptr)->broken_INQUIRY == TRUE) { + if(hd->broken_INQUIRY == TRUE) { if (HBA_ptr->dma_channel == BUSMASTER) size = sprintf(buffer + len, "DMA: BUSMASTER\n"); else @@ -202,7 +223,7 @@ else size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel); len += size; - pos = begin + len; + pos = begin + len; size = sprintf(buffer + len, "CPU: MC680%02d %dMHz\n", bt->cpu_type, bt->cpu_speed); len += size; @@ -211,19 +232,21 @@ len += size; pos = begin + len; size = sprintf(buffer + len, "Host Bus: %s\n", - (SD(HBA_ptr)->bustype == IS_PCI)?"PCI ": - (SD(HBA_ptr)->bustype == IS_EISA)?"EISA":"ISA "); + (hd->bustype == IS_PCI)?"PCI ": + (hd->bustype == IS_EISA)?"EISA":"ISA "); len += size; pos = begin + len; - size = sprintf(buffer + len, "SCSI Bus:%s%s Speed: %sMB/sec. %s\n", + size = sprintf(buffer + len, "SCSI Bus:%s%s%s Speed: %sMHz. %s\n", + (sb->ultra == TRUE)?" ULTRA":"", (sb->wide == TRUE)?" WIDE":"", (sb->dif == TRUE)?" DIFFERENTIAL":"", - (sb->speed == 0)?"5":(sb->speed == 1)?"10":"20", + (sb->ultra == TRUE)?"20":"10", (sb->ext == TRUE)?"With external cable detection":""); len += size; pos = begin + len; - size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n", + size = sprintf(buffer + len, "SCSI channel expansion Module: " + "%s present\n", (bt->sx1 == TRUE)?"SX1 (one channel)": ((bt->sx2 == TRUE)?"SX2 (two channels)":"not")); len += size; @@ -296,7 +319,7 @@ if (pos > offset + length) goto stop_output; - if(SD(HBA_ptr)->do_latency == FALSE) { + if(hd->do_latency == FALSE) { cmnd[0] = LOG_SENSE; cmnd[1] = 0; @@ -328,10 +351,10 @@ whcs = (hst_cmd_stat *)(buff2 + 0x8c); for (x = 0; x <= 11; x++) { - SD(HBA_ptr)->reads[x] += rhcs->sizes[x]; - SD(HBA_ptr)->writes[x] += whcs->sizes[x]; - SD(HBA_ptr)->reads[12] += rhcs->sizes[x]; - SD(HBA_ptr)->writes[12] += whcs->sizes[x]; + hd->reads[x] += rhcs->sizes[x]; + hd->writes[x] += whcs->sizes[x]; + hd->reads[12] += rhcs->sizes[x]; + hd->writes[12] += whcs->sizes[x]; } size = sprintf(buffer + len, "Host<->Disk command statistics:\n" " Reads: Writes:\n"); @@ -339,19 +362,19 @@ pos = begin + len; for (x = 0; x <= 10; x++) { size = sprintf(buffer+len,"%5dk:%12u %12u\n", 1 << x, - SD(HBA_ptr)->reads[x], - SD(HBA_ptr)->writes[x]); + hd->reads[x], + hd->writes[x]); len += size; pos = begin + len; } size = sprintf(buffer+len,">1024k:%12u %12u\n", - SD(HBA_ptr)->reads[11], - SD(HBA_ptr)->writes[11]); + hd->reads[11], + hd->writes[11]); len += size; pos = begin + len; size = sprintf(buffer+len,"Sum :%12u %12u\n", - SD(HBA_ptr)->reads[12], - SD(HBA_ptr)->writes[12]); + hd->reads[12], + hd->writes[12]); len += size; pos = begin + len; } @@ -364,35 +387,32 @@ if (pos > offset + length) goto stop_output; - if(SD(HBA_ptr)->do_latency == TRUE) { - int factor = 1024/HZ; + if(hd->do_latency == TRUE) { size = sprintf(buffer + len, "Host Latency Command Statistics:\n" - "Current timer resolution: %2dms\n" - " Reads: Min:(ms) Max:(ms) Ave:(ms)\n", - factor); + "Current timer resolution: 1 usec\n" + " Reads: Min:(us) Max:(us) " + "Ave:(us)\n"); len += size; pos = begin + len; for (x = 0; x <= 10; x++) { size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 1 << x, - SD(HBA_ptr)->reads_lat[x][0], - (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->reads_lat[x][1] * factor), - SD(HBA_ptr)->reads_lat[x][2] * factor, - SD(HBA_ptr)->reads_lat[x][3] * factor / - ((SD(HBA_ptr)->reads_lat[x][0]) - ? SD(HBA_ptr)->reads_lat[x][0]:1)); + hd->readscount[x], + (hd->reads_lat[x][0] == 0xffffffff) + ? 0:(hd->reads_lat[x][0]), + hd->reads_lat[x][1], + dpt_ave_latency(hd->readscount[x], + &hd->reads_sum[x])); len += size; pos = begin + len; } size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n", - SD(HBA_ptr)->reads_lat[11][0], - (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->reads_lat[11][1] * factor), - SD(HBA_ptr)->reads_lat[11][2] * factor, - SD(HBA_ptr)->reads_lat[11][3] * factor / - ((SD(HBA_ptr)->reads_lat[x][0]) - ? SD(HBA_ptr)->reads_lat[x][0]:1)); + hd->readscount[11], + (hd->reads_lat[11][0] == 0xffffffff) + ? 0:(hd->reads_lat[x][0]), + hd->reads_lat[11][1], + dpt_ave_latency(hd->readscount[11], + &hd->reads_sum[11])); len += size; pos = begin + len; @@ -404,31 +424,30 @@ goto stop_output; size = sprintf(buffer + len, - " Writes: Min:(ms) Max:(ms) Ave:(ms)\n"); + " Writes: Min:(us) Max:(us) Ave:(us)\n"); len += size; pos = begin + len; for (x = 0; x <= 10; x++) { size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", 1 << x, - SD(HBA_ptr)->writes_lat[x][0], - (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), - SD(HBA_ptr)->writes_lat[x][2] * factor, - SD(HBA_ptr)->writes_lat[x][3] * factor / - ((SD(HBA_ptr)->writes_lat[x][0]) - ? SD(HBA_ptr)->writes_lat[x][0]:1)); + hd->writescount[x], + (hd->writes_lat[x][0] == 0xffffffff) + ? 0:(hd->writes_lat[x][0]), + hd->writes_lat[x][1], + dpt_ave_latency(hd->writescount[x], + &hd->writes_sum[x])); + len += size; pos = begin + len; } size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n", - SD(HBA_ptr)->writes_lat[11][0], - (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), - SD(HBA_ptr)->writes_lat[11][2] * factor, - SD(HBA_ptr)->writes_lat[11][3] * factor / - ((SD(HBA_ptr)->writes_lat[x][0]) - ? SD(HBA_ptr)->writes_lat[x][0]:1)); - len += size; + hd->writescount[11], + (hd->writes_lat[11][0] == 0xffffffff) + ? 0:(hd->writes_lat[x][0]), + hd->writes_lat[11][1], + dpt_ave_latency(hd->writescount[11], + &hd->writes_sum[11])); + len += size; pos = begin + len; if (pos < offset) { diff -uNr linux/drivers/scsi/eata_dma_proc.h linux.wrk.2.0.31/drivers/scsi/eata_dma_proc.h --- linux/drivers/scsi/eata_dma_proc.h Fri Jun 30 14:30:56 1995 +++ linux.wrk.2.0.31/drivers/scsi/eata_dma_proc.h Sun Nov 2 19:55:29 1997 @@ -1,21 +1,21 @@ struct lun_map { __u8 id:5, - chan:3; + chan:3; __u8 lun; }; typedef struct emul_pp { __u8 p_code:6, - null:1, - p_save:1; + null:1, + p_save:1; __u8 p_length; __u16 cylinder; __u8 heads; __u8 sectors; __u8 null2; __u8 s_lunmap:4, - ems:1; + ems:1; __u16 drive_type; /* In Little Endian ! */ struct lun_map lunmap[4]; }emulpp; @@ -25,7 +25,7 @@ typedef struct log_sheader { __u8 page_code, - reserved; + reserved; __u16 length; }logsh; @@ -37,14 +37,14 @@ __u8 flags; __u8 length; /* 0x24 */ __u32 h_commands, - uncached, - la_cmds, - la_blks, - la_hits, - missed, - hits, - seq_la_blks, - seq_la_hits; + uncached, + la_cmds, + la_blks, + la_hits, + missed, + hits, + seq_la_blks, + seq_la_hits; }r_cmd_stat; typedef struct write_command_statistics { @@ -52,15 +52,15 @@ __u8 flags; __u8 length; /* 0x28 */ __u32 h_commands, - uncached, - thru, - bypass, - soft_err, - hits, - b_idle, - b_activ, - b_blks, - b_blks_clean; + uncached, + thru, + bypass, + soft_err, + hits, + b_idle, + b_activ, + b_blks, + b_blks_clean; }w_cmd_stat; typedef struct host_command_statistics { @@ -82,9 +82,9 @@ __u8 flags; __u8 length; /* 0x10 */ __u32 disconnect, - pass_thru, - sg_commands, - stripe_boundary_crosses; + pass_thru, + sg_commands, + stripe_boundary_crosses; }msc_stats; /* Configuration Pages */ @@ -94,12 +94,13 @@ __u8 flags; __u8 length; /* 0x02 */ __u8 intt:1, - sec:1, - csh:1, - key:1, - tmr:1, - srs:1, - nvr:1; + sec:1, + csh:1, + key:1, + tmr:1, + srs:1, + nvr:1, + atm:1; __u8 interrupt; }coco; @@ -108,7 +109,10 @@ __u8 flags; __u8 length; /* 0x02 */ __u8 unused:1, - per:1; + per:1, + unused2:4, + batna:1, + batlo:1; __u8 interrupt; }coher; @@ -124,7 +128,7 @@ __u8 flags; __u8 length; /* 0x04 */ __u8 offset, - period; + period; __u16 speed; }scsitrans; @@ -132,12 +136,13 @@ __u16 code; /* 0x06 */ __u8 flags; __u8 length; /* 0x02 */ - __u8 que:1, - cdis:1, - wtru:1, - dasd:1, - ncr:1, - awre:1; + __u8 que:1, + cdis:1, + wtru:1, + dasd:1, + ncr:1, + awre:1, + unused:1; __u8 reserved; }scsimod; @@ -146,8 +151,8 @@ __u8 flags; __u8 length; /* 0x02 */ __u8 speed:6, - pci:1, - eisa:1; + pci:1, + eisa:1; __u8 reserved; }hobu; @@ -155,11 +160,11 @@ __u16 code; /* 0x08 */ __u8 flags; __u8 length; /* 0x02 */ - __u8 speed:4, - res:1, - ext:1, - wide:1, - dif:1; + __u8 speed:4, /* Removed, was always set to 10MHz */ + ultra:1, + ext:1, + wide:1, + dif:1; __u8 busnum; }scbu; @@ -168,20 +173,23 @@ __u8 flags; __u8 length; /* 0x04 */ __u8 unused:1, - cmi:1, - dmi:1, - cm4k:1, - cm4:1, - dm4k:1, - dm4:1, - hba:1; + cmi:1, + dmi:1, + cm4k:1, + cm4:1, + dm4k:1, + dm4:1, + hba:1; __u8 cpu_type, - cpu_speed; - __u8 sx1:1, - sx2:1, - unused2:4, - alrm:1, - srom:1; + cpu_speed; + __u8 sx1:1, + sx2:1, + bbu:1, + sc4:1, + rc40:1, + rc41:1, + alrm:1, + srom:1; }boty; typedef struct memory_config { @@ -196,12 +204,17 @@ __u8 flags; __u8 length; /* 0x04 */ __u8 dnld:1, - bs528:1, - fmt:1, - fw528:1; - __u8 unused1, - fw_type, - unused; + bs528:1, + fmt:1, + fw528:1, + diag:1, + targ:1, + mult:1, + smart:1; + __u8 unused0; + __u16 fw_type; + __u8 tmpwth, + tmphth; }firm; typedef struct subsystem_info { @@ -209,8 +222,8 @@ __u8 flags; __u8 length; /* 0x02 */ __u8 shlf:1, - swap:1, - noss:1; + swap:1, + noss:1; __u8 reserved; }subinf; @@ -219,14 +232,18 @@ __u8 flags; __u8 length; /* 0x02 */ __u8 channel; - __u8 shlf:1, - swap:1, - noss:1, - srs:1, - que:1, - ext:1, - wide:1, - diff:1; + __u8 shlf:1, + swap:1, + noss:1, + srs:1, + que:1, + ext:1, + wide:1, + diff:1; + __u8 unused:7, + ultra:1; + __u8 speed; + __u16 scam_id_map; }pcinf; typedef struct array_limits { @@ -234,10 +251,28 @@ __u8 flags; __u8 length; /* 0x04 */ __u8 max_groups, - raid0_drv, - raid35_drv, - unused; + raid0_drv, + raid35_drv, + unused, + r0_min_stripe_size, + r0_max_stripe_size, + r0_def_stripe_size, + r3_min_stripe_size, + r3_max_stripe_size, + r3_def_stripe_size, + r5_min_stripe_size, + r5_max_stripe_size, + r5_def_stripe_size; }arrlim; + +typedef struct scheduled_diagnostics_exclusion { + __u16 code; /* 0x0e */ + __u8 flags; + __u8 length; /* 0x04 */ + __u8 start_h, + end_h; +}experiod; + /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -uNr linux/drivers/scsi/eata_generic.h linux.wrk.2.0.31/drivers/scsi/eata_generic.h --- linux/drivers/scsi/eata_generic.h Mon Oct 28 23:30:43 1996 +++ linux.wrk.2.0.31/drivers/scsi/eata_generic.h Sun Nov 2 19:55:29 1997 @@ -5,7 +5,7 @@ * mike@i-Connect.Net * * neuffer@mail.uni-mainz.de * ********************************************************* -* last change: 96/08/14 * +* last change: 97/08/09 * ********************************************************/ @@ -66,7 +66,7 @@ #define MAX_PCI_BUS 16 /* Maximum # Of Busses Allowed */ #define SG_SIZE 64 -#define SG_SIZE_BIG 252 /* max. 8096 elements, 64k */ +#define SG_SIZE_BIG 512 /* max. 8096 elements, 64k */ #define UPPER_DEVICE_QUEUE_LIMIT 64 /* The limit we have to set for the * device queue to keep the broken @@ -149,6 +149,7 @@ #define HA_WDMAADDR 0x02 /* DMA address LSB offset */ #define HA_RAUXSTAT 0x08 /* aux status register offset*/ #define HA_RSTATUS 0x07 /* status register offset */ +#define HA_RERROR 0x01 /* error register */ #define HA_RDATA 0x00 /* data register (16bit) */ #define HA_WDATA 0x00 /* data register (16bit) */ @@ -285,7 +286,7 @@ HBA_Init:1, /* Cause Controller to reinitialize */ Auto_Req_Sen:1, /* Do Auto Request Sense on errors */ scatter:1, /* Data Ptr points to a SG Packet */ - Resrvd:1, /* RFU */ + quick:1, /* quick protocol, not supportet anymore */ Interpret:1, /* Interpret the SCSI cdb of own use */ DataOut:1, /* Data Out phase with command */ DataIn:1; /* Data In phase with command */ @@ -319,8 +320,9 @@ __u32 cp_reqDMA; /* Request Sense Address, used if * * CP command ends with error */ /* Additional CP info begins here */ - __u32 timestamp; /* Needed to measure command latency */ + struct timeval timestamp; __u32 timeout; + int do_latency; __u8 sizeindex; __u8 rw_latency; __u8 retries; @@ -355,12 +357,15 @@ immediate_support:1, /* HBA supports IMMEDIATE CMDs*/ broken_INQUIRY:1; /* This is an EISA HBA with * * broken INQUIRY */ - __u8 do_latency; /* Latency measurement flag */ - __u32 reads[13]; + uint do_latency; /* Latency measurement flag */ + __u32 reads[13]; /* Controller provided information */ __u32 writes[13]; - __u32 reads_lat[12][4]; - __u32 writes_lat[12][4]; - __u32 all_lat[4]; + __u32 reads_lat[12][2]; /* Min/Max latencies */ + __u32 writes_lat[12][2]; /* indexed by size */ + struct timeval reads_sum[12];/* Latency sum */ + struct timeval writes_sum[12];/* indexed by size */ + __u32 readscount[12]; /* Read/Write counter */ + __u32 writescount[12]; /* indexed by size */ __u8 resetlevel[MAXCHANNEL]; __u32 last_ccb; /* Last used ccb */ __u32 cplen; /* size of CP in words */ diff -uNr linux/drivers/scsi/scsi_proc.c linux.wrk.2.0.31/drivers/scsi/scsi_proc.c --- linux/drivers/scsi/scsi_proc.c Mon Aug 11 22:37:24 1997 +++ linux.wrk.2.0.31/drivers/scsi/scsi_proc.c Sun Nov 2 20:02:22 1997 @@ -77,6 +77,8 @@ extern int dispatch_scsi_info(int ino, char *buffer, char **start, off_t offset, int length, int func) { + + struct Scsi_Host *hpnt = scsi_hostlist; if(ino == PROC_SCSI_SCSI) { @@ -89,12 +91,13 @@ while(hpnt) { if (ino == (hpnt->host_no + PROC_SCSI_FILE)) { - if(hpnt->hostt->proc_info == NULL) + if(hpnt->hostt->proc_info == NULL) { return generic_proc_info(buffer, start, offset, length, hpnt->host_no, func); - else + } else { return(hpnt->hostt->proc_info(buffer, start, offset, length, hpnt->host_no, func)); + } } hpnt = hpnt->next; } diff -uNr linux/include/scsi/scsi_ioctl.h linux.wrk.2.0.31/include/scsi/scsi_ioctl.h --- linux/include/scsi/scsi_ioctl.h Mon Aug 11 22:37:24 1997 +++ linux.wrk.2.0.31/include/scsi/scsi_ioctl.h Sun Nov 2 20:05:10 1997 @@ -4,13 +4,13 @@ #define SCSI_IOCTL_SEND_COMMAND 1 #define SCSI_IOCTL_TEST_UNIT_READY 2 #define SCSI_IOCTL_BENCHMARK_COMMAND 3 -#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */ +#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */ #define SCSI_IOCTL_START_UNIT 5 #define SCSI_IOCTL_STOP_UNIT 6 /* The door lock/unlock constants are compatible with Sun constants for - the cdrom */ -#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */ -#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */ + * the cdrom */ +#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */ +#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */ #define SCSI_REMOVAL_PREVENT 1 #define SCSI_REMOVAL_ALLOW 0 @@ -23,5 +23,8 @@ #endif #endif + + +