diff -U 4 linux/drivers/scsi/aic7xxx.c.old linux/drivers/scsi/aic7xxx.c --- linux/drivers/scsi/aic7xxx.c.old Thu Sep 11 15:45:14 1997 +++ linux/drivers/scsi/aic7xxx.c Thu Sep 11 15:54:35 1997 @@ -870,9 +870,9 @@ long w_bins[10]; /* binned write */ long r_total; /* total reads */ long r_total512; /* 512 byte blocks read */ long r_bins[10]; /* binned reads */ - } stats[2][16][8]; /* channel, target, lun */ + } stats[16][8]; /* channel, target, lun */ #endif /* AIC7XXX_PROC_STATS */ }; /* @@ -967,9 +967,15 @@ * * These functions are not used yet, but when we do memory mapped * IO, we'll use them then. * + * For now we leave these commented out as the x86 inline assembly causes + * compiles to barf on DEC Alphas. Besides, they aren't even used yet, so + * they constitute wasted .text space right now. ***************************************************************************/ + +/*************************************************************************** + static inline unsigned char aic_inb(struct aic7xxx_host *p, long port) { if (p->maddr != NULL) @@ -1006,8 +1012,9 @@ { outsb(p->base + port, valp, size); } } + ***************************************************************************/ /*+F************************************************************************* * Function: * aic7xxx_setup @@ -1984,8 +1991,10 @@ aic7xxx_free_scb(p, scb); aic7xxx_queue_cmd_complete(p, cmd); #ifdef AIC7XXX_PROC_STATS + if ( (cmd->cmnd[0] != TEST_UNIT_READY) && + (cmd->cmnd[0] != INQUIRY) ) { int actual; /* @@ -1999,9 +2008,9 @@ struct aic7xxx_xferstats *sp; long *ptr; int x; - sp = &p->stats[cmd->channel & 0x01][cmd->target & 0x0F][cmd->lun & 0x07]; + sp = &p->stats[((cmd->channel << 3) | cmd->target) & 0xf][cmd->lun & 0x7]; sp->xfers++; if (cmd->request.cmd == WRITE) { @@ -5021,9 +5030,9 @@ p->completeq.tail = NULL; scbq_init(&p->scb_data->free_scbs); scbq_init(&p->waiting_scbs); - for (i = 0; i <= NUMBER(p->device_status); i++) + for (i = 0; i < NUMBER(p->device_status); i++) { p->device_status[i].commands_sent = 0; p->device_status[i].flags = 0; p->device_status[i].active_cmds = 0; @@ -5720,9 +5729,9 @@ * not guaranteed to be initialized to 0 (NULL). We use * a NULL entry to indicate that no prior hosts have * been found/registered for that IRQ. */ - for (i = 0; i <= NUMBER(aic7xxx_boards); i++) + for (i = 0; i < NUMBER(aic7xxx_boards); i++) { aic7xxx_boards[i] = NULL; } @@ -6886,9 +6895,9 @@ p = (struct aic7xxx_host *) cmd->host->hostdata; scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); base = p->base; channel = cmd->channel ? 'B': 'A'; - tindex = (cmd->channel << 4) | cmd->target; + tindex = (cmd->channel << 3) | cmd->target; #ifdef 0 /* AIC7XXX_DEBUG_ABORT */ if (scb != NULL) { diff -U 4 linux/drivers/scsi/aic7xxx_proc.c.old linux/drivers/scsi/aic7xxx_proc.c --- linux/drivers/scsi/aic7xxx_proc.c.old Sat Aug 30 11:14:39 1997 +++ linux/drivers/scsi/aic7xxx_proc.c Thu Sep 11 16:04:15 1997 @@ -20,15 +20,17 @@ * ---------------------------------------------------------------- * o Modified from the EATA-DMA /proc support. * o Additional support for device block statistics provided by * Matthew Jacob. + * o Correction of overflow by Heinz Mauelshagen + * o Adittional corrections by Doug Ledford * * Dean W. Gehnert, deang@teleport.com, 05/01/96 * * $Id: aic7xxx_proc.c,v 4.1 1997/06/97 08:23:42 deang Exp $ *-M*************************************************************************/ -#define BLS buffer + len + size +#define BLS (&aic7xxx_buffer[size]) #define HDRB \ " < 512 512-1K 1-2K 2-4K 4-8K 8-16K 16-32K 32-64K 64-128K >128K" #ifdef PROC_DEBUG @@ -61,31 +63,34 @@ { proc_debug("aic7xxx_set_info(): %s\n", buffer); return (-ENOSYS); /* Currently this is a no-op */ } - + /*+F************************************************************************* * Function: * aic7xxx_proc_info * * Description: * Return information to handle /proc support for the driver. *-F*************************************************************************/ int -aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, - int hostno, int inout) +aic7xxx_proc_info ( char *buffer, char **start, off_t offset, int length, + int hostno, int inout) { struct Scsi_Host *HBAptr; struct aic7xxx_host *p; - int i; - int found = FALSE; - int size = 0; - int len = 0; - off_t begin = 0; - off_t pos = 0; + static int aic7xxx_buffer_size = 0; + int found = FALSE; + static int size = 0; + unsigned char i; + static char *aic7xxx_buffer = NULL; static char *bus_names[] = { "Single", "Twin", "Wide" }; static char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", "AIC-787x", "AIC-788x" }; +#ifdef AIC7XXX_PROC_STATS + struct aic7xxx_xferstats *sp; + unsigned char target, lun; +#endif HBAptr = NULL; for (i=0; i < NUMBER(aic7xxx_boards); i++) { @@ -94,18 +99,18 @@ if (HBAptr->host_no == hostno) { break; } - + while ((HBAptr->hostdata != NULL) && !found && ((HBAptr = ((struct aic7xxx_host *) HBAptr->hostdata)->next) != NULL)) { if (HBAptr->host_no == hostno) { found = TRUE; } } - + if (!found) { HBAptr = NULL; } @@ -114,45 +119,68 @@ break; } } } - + if (HBAptr == NULL) { - size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno); - len += size; pos = begin + len; size = 0; - goto stop_output; + size += sprintf( buffer, "Can't find adapter for host number %d\n", hostno); + if ( size > length) return size; + return length; } - + if (inout == TRUE) /* Has data been written to the file? */ { return (aic7xxx_set_info(buffer, length, HBAptr)); } - + p = (struct aic7xxx_host *) HBAptr->hostdata; + /* It takes roughly 1K of space to hold all relevant card info, not */ + /* counting any proc stats, so we start out with a 1.5k buffer size and */ + /* if proc_stats is defined, then we sweep the stats structure to see */ + /* how many drives we will be printing out for and add 384 bytes per */ + /* device with active stats. */ + + size = 1536; +#ifdef AIC7XXX_PROC_STATS + for (target=0; target<16; target++) + { + for (lun=0; lun<8; lun++) + { + if (p->stats[target][lun].xfers != 0) + size += 384; + } + } +#endif + if ( aic7xxx_buffer_size != size) { + if ( aic7xxx_buffer != NULL) + kfree ( aic7xxx_buffer); + aic7xxx_buffer = kmalloc ( size, GFP_KERNEL); + } + if ( aic7xxx_buffer == NULL) { + size = sprintf ( buffer, "AIC7xxx - kmalloc error at line %d\n", + __LINE__); + return size; + } + aic7xxx_buffer_size = size; + + size = 0; size += sprintf(BLS, "Adaptec AIC7xxx driver version: "); size += sprintf(BLS, "%s/", rcs_version(AIC7XXX_C_VERSION)); size += sprintf(BLS, "%s", rcs_version(AIC7XXX_H_VERSION)); #if 0 size += sprintf(BLS, "%s\n", rcs_version(AIC7XXX_SEQ_VER)); #endif - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at first position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - size += sprintf(BLS, "\n"); size += sprintf(BLS, "Compile Options:\n"); #ifdef AIC7XXX_RESET_DELAY - size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY); + size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", + AIC7XXX_RESET_DELAY); #endif #ifdef AIC7XXX_CMDS_PER_LUN - size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", AIC7XXX_CMDS_PER_LUN); + size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", + AIC7XXX_CMDS_PER_LUN); #endif #ifdef AIC7XXX_TAGGED_QUEUEING size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Enabled\n"); #else @@ -167,31 +195,21 @@ size += sprintf(BLS, " AIC7XXX_PROC_STATS : Enabled\n"); #else size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n"); #endif - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at second position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; - size += sprintf(BLS, "\n"); size += sprintf(BLS, "Adapter Configuration:\n"); size += sprintf(BLS, " SCSI Adapter: %s\n", - board_names[p->chip_type]); + board_names[p->chip_type]); size += sprintf(BLS, " (%s chipset)\n", - chip_names[p->chip_class]); - size += sprintf(BLS, " Host Bus: %s\n", bus_names[p->bus_type]); + chip_names[p->chip_class]); + size += sprintf(BLS, " Host Bus: %s\n", + bus_names[p->bus_type]); size += sprintf(BLS, " Base IO: %#.4x\n", p->base); size += sprintf(BLS, " Base IO Memory: 0x%x\n", p->mbase); size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); size += sprintf(BLS, " SCBs: Used %d, HW %d, Page %d\n", - p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); + p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); size += sprintf(BLS, " Interrupts: %d", p->isr_count); if (p->chip_class == AIC_777x) { size += sprintf(BLS, " %s\n", @@ -210,94 +228,58 @@ size += sprintf(BLS, " Ultra SCSI: %sabled\n", (p->flags & ULTRA_ENABLED) ? "En" : "Dis"); size += sprintf(BLS, " Target Disconnect: %sabled\n", p->discenable ? "En" : "Dis"); - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at third position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; - + #ifdef AIC7XXX_PROC_STATS + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Statistics:\n"); + for (target = 0; target < 16; target++) { - struct aic7xxx_xferstats *sp; - int channel, target, lun; - - /* - * XXX: Need to fix this to avoid overflow... - * Fixed - gordo. - */ - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Statistics:\n"); - for (channel = 0; channel < 2; channel++) + for (lun = 0; lun < 8; lun++) { - for (target = 0; target < 16; target++) + sp = &p->stats[target][lun]; + if (sp->xfers == 0) { - for (lun = 0; lun < 8; lun++) - { - sp = &p->stats[channel][target][lun]; - if (sp->xfers == 0) - { - continue; - } - size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", - 'A' + channel, target, lun); - size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n", - sp->xfers, sp->r_total, sp->w_total); - size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n", - sp->r_total512, sp->w_total512); - size += sprintf(BLS, "%s\n", HDRB); - size += sprintf(BLS, " Reads:"); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[0], - sp->r_bins[1], sp->r_bins[2], sp->r_bins[3]); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[4], - sp->r_bins[5], sp->r_bins[6], sp->r_bins[7]); - size += sprintf(BLS, "%6ld %6ld\n", sp->r_bins[8], - sp->r_bins[9]); - size += sprintf(BLS, "Writes:"); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[0], - sp->w_bins[1], sp->w_bins[2], sp->w_bins[3]); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[4], - sp->w_bins[5], sp->w_bins[6], sp->w_bins[7]); - size += sprintf(BLS, "%6ld %6ld\n", sp->w_bins[8], - sp->w_bins[9]); - size += sprintf(BLS, "\n"); - } - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at loop %d:%d\n", target, lun); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; + continue; } + if (p->bus_type == AIC_TWIN) + size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", + 'A' + (target >> 3), (target & 0x7), lun); + else + size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", + 'A', target, lun); + size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n", + sp->xfers, sp->r_total, sp->w_total); + size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n", + sp->r_total512, sp->w_total512); + size += sprintf(BLS, "%s\n", HDRB); + size += sprintf(BLS, " Reads:"); + for (i=0; i<10; i++) + size += sprintf(BLS, "%6ld ", sp->r_bins[i]); + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Writes:"); + for (i=0; i<10; i++) + size += sprintf(BLS, "%6ld ", sp->w_bins[i]); + size += sprintf(BLS, "\n\n"); } } #endif /* AIC7XXX_PROC_STATS */ -stop_output: - proc_debug("2pos: %ld offset: %ld len: %d\n", pos, offset, len); - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len < 0) - { - len = 0; /* off end of file */ - } - else if (len > length) - { - len = length; /* Ending slop */ + if ( size >= aic7xxx_buffer_size ) + printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); + + if ( offset > size - 1) { + kfree ( aic7xxx_buffer); + aic7xxx_buffer = NULL; + aic7xxx_buffer_size = length = 0; + *start = NULL; + } else { + *start = &aic7xxx_buffer[offset]; /* Start of wanted data */ + if ( size - offset < length) length = size - offset; } - proc_debug("3pos: %ld offset: %ld len: %d\n", pos, offset, len); - return (len); + return length; } /* * Overrides for Emacs so that we follow Linus's tabbing style.