diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-16 05:34:03 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-16 05:34:03 +0000 |
commit | 967c65a99059fd459b956c1588ce0ba227912c4e (patch) | |
tree | 8224d013ff5d255420713d05610c7efebd204d2a /drivers/scsi | |
parent | e20c1cc1656a66a2773bca4591a895cbc12696ff (diff) |
Merge with Linux 2.1.72, part 1.
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/BusLogic.h | 8 | ||||
-rw-r--r-- | drivers/scsi/Config.in | 2 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx.c | 115 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx.reg | 30 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx_proc.c | 254 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx_reg.h | 64 | ||||
-rw-r--r-- | drivers/scsi/ibmmca.c | 11 | ||||
-rw-r--r-- | drivers/scsi/scsi_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 11 | ||||
-rw-r--r-- | drivers/scsi/sr_ioctl.c | 5 | ||||
-rw-r--r-- | drivers/scsi/sr_vendor.c | 3 |
11 files changed, 295 insertions, 210 deletions
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 87e44e758..6f62e04b0 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -1526,15 +1526,11 @@ void BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T *HostAdapter) static inline void BusLogic_Delay(int Seconds) { + int Milliseconds = 1000 * Seconds; unsigned long ProcessorFlags; save_flags(ProcessorFlags); sti(); - while (--Seconds >= 0) { - int i = 1000; - do { - udelay(1000); - } while (--i); - } + while (--Milliseconds >= 0) udelay(1000); restore_flags(ProcessorFlags); } diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index ac6d3bb6e..969ef7831 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -85,7 +85,7 @@ fi if [ "$CONFIG_MCA" = "y" ]; then dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then - bool ' reset SCSI-devices while booting' SCSI_IBMMCA_DEV_RESET + bool ' reset SCSI-devices while booting' CONFIG_SCSI_IBMMCA_DEV_RESET fi fi if [ "$CONFIG_PARPORT" != "n" ]; then diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 5551cbad8..051dedaac 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -147,6 +147,8 @@ struct proc_dir_entry proc_scsi_aic7xxx = { #define ALL_TARGETS -1 #define ALL_CHANNELS '\0' #define ALL_LUNS -1 +#define MAX_TARGETS 16 +#define MAX_LUNS 8 #ifndef TRUE # define TRUE 1 #endif @@ -301,7 +303,7 @@ struct proc_dir_entry proc_scsi_aic7xxx = { #ifdef AIC7XXX_TAGGED_QUEUEING_BY_DEVICE typedef struct { - char tag_commands[16]; /* Allow for wide/twin channel adapters. */ + unsigned char tag_commands[16]; /* Allow for wide/twin channel adapters. */ } adapter_tag_info_t; /* @@ -871,7 +873,7 @@ struct aic7xxx_host { 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[MAX_TARGETS][MAX_LUNS]; /* [(channel << 3)|target][lun] */ #endif /* AIC7XXX_PROC_STATS */ }; @@ -969,6 +971,7 @@ static int aic7xxx_verbose = 0; /* verbose messages */ * IO, we'll use them then. * ***************************************************************************/ + static inline unsigned char aic_inb(struct aic7xxx_host *p, long port) { @@ -992,15 +995,24 @@ aic_outsb(struct aic7xxx_host *p, long port, unsigned char *valp, size_t size) { if (p->maddr != NULL) { +#ifdef __alpha__ + int i; + + for (i=0; i < size; i++) + { + p->maddr[port] = valp[i]; + } +#else __asm __volatile(" cld; 1: lodsb; movb %%al,(%0); loop 1b" : : - "r" ((p)->maddr + (port)), - "S" ((valp)), "c" ((size)) : + "r" (p->maddr + port), + "S" (valp), "c" (size) : "%esi", "%ecx", "%eax"); +#endif } else { @@ -1439,7 +1451,7 @@ aic7xxx_scsirate(struct aic7xxx_host *p, unsigned char *scsirate, * If the offset is 0, then the device is requesting asynchronous * transfers. */ - if ((*period >= aic7xxx_syncrates[i].period) && *offset != 0) + if ((*period <= aic7xxx_syncrates[i - 1].period) && *offset != 0) { for (i = 0; i < num_aic7xxx_syncrates; i++) { @@ -1970,21 +1982,46 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0) { unsigned short mask; + int message_error = FALSE; mask = 0x01 << TARGET_INDEX(scb->cmd); + + /* + * Check to see if we get an invalid message or a message error + * after failing to negotiate a wide or sync transfer message. + */ + if ((scb->flags & SCB_SENSE) && + ((scb->cmd->sense_buffer[12] == 0x43) || /* INVALID_MESSAGE */ + (scb->cmd->sense_buffer[12] == 0x49))) /* MESSAGE_ERROR */ + { + message_error = TRUE; + } + if (scb->flags & SCB_MSGOUT_WDTR) { p->wdtr_pending &= ~mask; + if (message_error) + { + p->needwdtr &= ~mask; + p->needwdtr_copy &= ~mask; + } } if (scb->flags & SCB_MSGOUT_SDTR) { p->sdtr_pending &= ~mask; + if (message_error) + { + p->needsdtr &= ~mask; + p->needsdtr_copy &= ~mask; + } } } 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; @@ -2000,7 +2037,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) long *ptr; int x; - sp = &p->stats[cmd->channel & 0x01][cmd->target & 0x0F][cmd->lun & 0x07]; + sp = &p->stats[TARGET_INDEX(cmd)][cmd->lun & 0x7]; sp->xfers++; if (cmd->request.cmd == WRITE) @@ -3088,6 +3125,8 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) } else { + int send_reject = FALSE; + /* * Send our own WDTR in reply. */ @@ -3110,14 +3149,25 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) { bus_width = BUS_8_BIT; scratch &= 0x7F; /* XXX - FreeBSD doesn't do this. */ + send_reject = TRUE; } break; default: break; } - aic7xxx_construct_wdtr(p, /* start byte */ 0, bus_width); - outb(SEND_MSG, p->base + RETURN_1); + if (send_reject) + { + outb(SEND_REJ, p->base + RETURN_1); + printk(KERN_WARNING "scsi%d: Target %d, channel %c, initiating " + "wide negotiation on a narrow bus - rejecting!", + p->host_no, target, channel); + } + else + { + aic7xxx_construct_wdtr(p, /* start byte */ 0, bus_width); + outb(SEND_MSG, p->base + RETURN_1); + } } p->needwdtr &= ~target_mask; outb(scratch, p->base + TARG_SCRATCH + scratch_offset); @@ -4062,7 +4112,7 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) #ifndef AIC7XXX_TAGGED_QUEUEING_BY_DEVICE device->queue_depth = default_depth; #else - if (p->instance > NUMBER(aic7xxx_tag_info)) + if (p->instance >= NUMBER(aic7xxx_tag_info)) { device->queue_depth = default_depth; } @@ -5022,7 +5072,7 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p) 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; @@ -5305,8 +5355,17 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p) */ outb(p->qcntmask, p->base + QCNTMASK); - outb(p->qfullcount, p->base + FIFODEPTH); - outb(0, p->base + CMDOUTCNT); + /* + * Set FIFO depth and command out count. These are only used when + * paging is enabled and should not be touched for AIC-7770 based + * adapters; FIFODEPTH and CMDOUTCNT overlay SCSICONF and SCSICONF+1 + * which are used to control termination. + */ + if (p->flags & PAGE_ENABLED) + { + outb(p->qfullcount, p->base + FIFODEPTH); + outb(0, p->base + CMDOUTCNT); + } /* * We don't have any waiting selections or disconnected SCBs. @@ -5537,7 +5596,6 @@ load_seeprom (struct aic7xxx_host *p, unsigned char *sxfrctl1) { case AIC_7770: /* None of these adapters have seeproms. */ case AIC_7771: - case AIC_7850: case AIC_7855: break; @@ -5545,6 +5603,7 @@ load_seeprom (struct aic7xxx_host *p, unsigned char *sxfrctl1) have_seeprom = read_284x_seeprom(p, (struct seeprom_config *) scarray); break; + case AIC_7850: /* The 2910B is a 7850 with a seeprom. */ case AIC_7861: case AIC_7870: case AIC_7871: @@ -5654,7 +5713,11 @@ load_seeprom (struct aic7xxx_host *p, unsigned char *sxfrctl1) scsi_conf = (p->scsi_id & 0x7); if (sc->adapter_control & CFSPARITY) scsi_conf |= ENSPCHK; - if (sc->adapter_control & CFRESETB) + /* + * The 7850 controllers with a seeprom, do not honor the CFRESETB + * flag in the seeprom. Assume that we want to reset the SCSI bus. + */ + if ((sc->adapter_control & CFRESETB) || (p->chip_class == AIC_7850)) scsi_conf |= RESET_SCSI; if ((p->chip_class == AIC_786x) || (p->chip_class == AIC_788x)) @@ -5721,7 +5784,7 @@ aic7xxx_detect(Scsi_Host_Template *template) * 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; } @@ -5787,6 +5850,14 @@ aic7xxx_detect(Scsi_Host_Template *template) hcntrl = inb(base + HCNTRL) & IRQMS; /* Default */ outb(hcntrl | PAUSE, base + HCNTRL); + p = aic7xxx_alloc(template, base, 0, chip_type, 0, NULL); + if (p == NULL) + { + printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n"); + continue; + } + aic7xxx_chip_reset(p); + irq = inb(INTDEF + base) & 0x0F; switch (irq) { @@ -5800,19 +5871,14 @@ aic7xxx_detect(Scsi_Host_Template *template) default: printk(KERN_WARNING "aic7xxx: Host adapter uses unsupported IRQ " - "level, ignoring.\n"); + "level %d, ignoring.\n", irq); irq = 0; + aic7xxx_free(p); break; } if (irq != 0) { - p = aic7xxx_alloc(template, base, 0, chip_type, 0, NULL); - if (p == NULL) - { - printk(KERN_WARNING "aic7xxx: Unable to allocate device space.\n"); - continue; - } p->irq = irq & 0x0F; p->chip_class = AIC_777x; #ifdef AIC7XXX_PAGE_ENABLE @@ -5823,7 +5889,6 @@ aic7xxx_detect(Scsi_Host_Template *template) { p->flags |= EXTENDED_TRANSLATION; } - aic7xxx_chip_reset(p); switch (p->chip_type) { @@ -5985,7 +6050,6 @@ aic7xxx_detect(Scsi_Host_Template *template) flags = 0; switch (aic7xxx_pci_devices[i].chip_type) { - case AIC_7850: case AIC_7855: flags |= USE_DEFAULTS; break; @@ -6887,7 +6951,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd, unsigned int flags) scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); base = p->base; channel = cmd->channel ? 'B': 'A'; - tindex = (cmd->channel << 4) | cmd->target; + tindex = TARGET_INDEX(cmd); #ifdef 0 /* AIC7XXX_DEBUG_ABORT */ if (scb != NULL) @@ -7128,4 +7192,3 @@ Scsi_Host_Template driver_template = AIC7XXX; * tab-width: 8 * End: */ - diff --git a/drivers/scsi/aic7xxx/aic7xxx.reg b/drivers/scsi/aic7xxx/aic7xxx.reg index d3486e078..ac8549b34 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.reg +++ b/drivers/scsi/aic7xxx/aic7xxx.reg @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx.reg,v 1.2 1997/08/30 02:17:28 ralf Exp $ + * $Id: aic7xxx.reg,v 1.3 1997/12/15 12:47:28 ralf Exp $ */ /* @@ -1079,10 +1079,26 @@ scratch_ram { CUR_SCBID { size 1 } + ARG_1 { + size 1 + mask SEND_MSG 0x80 + mask SEND_SENSE 0x40 + mask SEND_REJ 0x20 + alias RETURN_1 + } /* * Running count of commands placed in * the QOUTFIFO. This is cleared by the * kernel driver every FIFODEPTH commands. + * + * NOTE: These scratch RAM registers are overlaying SCSICONF + * and SCSICONF2 and are only used on cards that are + * capable of SCB paging. Currently, only the PCI + * controllers can do this, which is good because the + * AIC-7770 based controllers use the SCSICONF register + * to control termination. In other words, do not + * destroy the contents of SCSICONF and SCSICONF2 for + * AIC-7770 based controllers. */ CMDOUTCNT { size 1 @@ -1094,13 +1110,6 @@ scratch_ram { FIFODEPTH { size 1 } - ARG_1 { - size 1 - mask SEND_MSG 0x80 - mask SEND_SENSE 0x40 - mask SEND_REJ 0x20 - alias RETURN_1 - } /* * These are reserved registers in the card's scratch ram. Some of * the values are specified in the AHA2742 technical reference manual @@ -1111,6 +1120,11 @@ scratch_ram { size 1 bit RESET_SCSI 0x40 } + SCSICONF2 { + address 0x05b + size 1 + bit RESET_SCSI 0x40 + } HOSTCONF { address 0x05d size 1 diff --git a/drivers/scsi/aic7xxx_proc.c b/drivers/scsi/aic7xxx_proc.c index dee247534..8ad2cfb03 100644 --- a/drivers/scsi/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx_proc.c @@ -21,13 +21,15 @@ * 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" @@ -49,6 +51,13 @@ proc_debug(const char *fmt, ...) # define proc_debug(fmt, args...) #endif /* PROC_DEBUG */ +static int aic7xxx_buffer_size = 0; +static char *aic7xxx_buffer = NULL; +static const char *bus_names[] = { "Single", "Twin", "Wide" }; +static const char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", + "AIC-787x", "AIC-788x" }; + + /*+F************************************************************************* * Function: * aic7xxx_set_info @@ -63,6 +72,7 @@ aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) return (-ENOSYS); /* Currently this is a no-op */ } + /*+F************************************************************************* * Function: * aic7xxx_proc_info @@ -71,20 +81,18 @@ aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) * 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 char *bus_names[] = { "Single", "Twin", "Wide" }; - static char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", - "AIC-787x", "AIC-788x" }; + int found = FALSE; + int size = 0; + unsigned char i; +#ifdef AIC7XXX_PROC_STATS + struct aic7xxx_xferstats *sp; + unsigned char target, lun; +#endif HBAptr = NULL; for (i=0; i < NUMBER(aic7xxx_boards); i++) @@ -118,9 +126,15 @@ aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, 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); + } + else + { + return (length); + } } if (inout == TRUE) /* Has data been written to the file? */ @@ -130,21 +144,49 @@ aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, 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 < MAX_TARGETS; target++) + { + for (lun = 0; lun < MAX_LUNS; 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_size = 0; + } + 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 @@ -168,30 +210,19 @@ aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, #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", + size += sprintf(BLS, " SCSI Adapter: %s\n", board_names[p->chip_type]); - size += sprintf(BLS, " (%s chipset)\n", + size += sprintf(BLS, " (%s chipset)\n", 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", + 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); - size += sprintf(BLS, " Interrupts: %d", p->isr_count); + size += sprintf(BLS, " Interrupts: %d", p->isr_count); if (p->chip_class == AIC_777x) { size += sprintf(BLS, " %s\n", @@ -201,102 +232,81 @@ aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, { size += sprintf(BLS, "\n"); } - size += sprintf(BLS, " Serial EEPROM: %s\n", + size += sprintf(BLS, " Serial EEPROM: %s\n", (p->flags & HAVE_SEEPROM) ? "True" : "False"); - size += sprintf(BLS, " Extended Translation: %sabled\n", + size += sprintf(BLS, " Extended Translation: %sabled\n", (p->flags & EXTENDED_TRANSLATION) ? "En" : "Dis"); - size += sprintf(BLS, " SCSI Bus Reset: %sabled\n", + size += sprintf(BLS, " SCSI Bus Reset: %sabled\n", aic7xxx_no_reset ? "Dis" : "En"); - size += sprintf(BLS, " Ultra SCSI: %sabled\n", + 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; - + size += sprintf(BLS, "Disconnect Enable Flags: 0x%x\n", p->discenable); + #ifdef AIC7XXX_PROC_STATS + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Statistics:\n"); + for (target = 0; target < MAX_TARGETS; 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 < MAX_LUNS; 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 < NUMBER(sp->r_bins); i++) + { + size += sprintf(BLS, "%6ld ", sp->r_bins[i]); + } + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Writes:"); + for (i = 0; i < NUMBER(sp->w_bins); 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) + if (size >= aic7xxx_buffer_size) { - len = 0; /* off end of file */ + printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); } - else if (len > length) + + if (offset > size - 1) { - len = length; /* Ending slop */ + kfree(aic7xxx_buffer); + aic7xxx_buffer = NULL; + aic7xxx_buffer_size = length = 0; + *start = NULL; } - proc_debug("3pos: %ld offset: %ld len: %d\n", pos, offset, len); - - return (len); + else + { + *start = &aic7xxx_buffer[offset]; /* Start of wanted data */ + if (size - offset < length) + { + length = size - offset; + } + } + + return (length); } /* diff --git a/drivers/scsi/aic7xxx_reg.h b/drivers/scsi/aic7xxx_reg.h index 8fbf84fa6..855a20441 100644 --- a/drivers/scsi/aic7xxx_reg.h +++ b/drivers/scsi/aic7xxx_reg.h @@ -30,6 +30,13 @@ #define ACTNEGEN 0x02 #define STPWEN 0x01 +#define SCSISIGI 0x03 +#define ATNI 0x10 +#define SELI 0x08 +#define BSYI 0x04 +#define REQI 0x02 +#define ACKI 0x01 + #define SCSISIGO 0x03 #define CDO 0x80 #define IOO 0x40 @@ -40,13 +47,6 @@ #define REQO 0x02 #define ACKO 0x01 -#define SCSISIGI 0x03 -#define ATNI 0x10 -#define SELI 0x08 -#define BSYI 0x04 -#define REQI 0x02 -#define ACKI 0x01 - #define SCSIRATE 0x04 #define WIDEXFER 0x80 #define SXFR 0x70 @@ -252,24 +252,26 @@ #define CUR_SCBID 0x58 -#define CMDOUTCNT 0x59 +#define ARG_1 0x59 +#define RETURN_1 0x59 +#define SEND_MSG 0x80 +#define SEND_SENSE 0x40 +#define SEND_REJ 0x20 #define SCSICONF 0x5a -#define RESET_SCSI 0x40 -#define FIFODEPTH 0x5a +#define CMDOUTCNT 0x5a -#define ARG_1 0x5b -#define RETURN_1 0x5b -#define SEND_MSG 0x80 -#define SEND_SENSE 0x40 -#define SEND_REJ 0x20 +#define SCSICONF2 0x5b +#define RESET_SCSI 0x40 + +#define FIFODEPTH 0x5b #define HOSTCONF 0x5d #define HA_274_BIOSCTRL 0x5f -#define BIOSMODE 0x30 #define BIOSDISABLED 0x30 +#define BIOSMODE 0x30 #define CHANNEL_B_PRIMARY 0x08 #define SEQCTL 0x60 @@ -313,16 +315,16 @@ #define STACK 0x6f -#define BCTL 0x84 -#define ACE 0x08 -#define ENABLE 0x01 - #define DSCOMMAND 0x84 #define CACHETHEN 0x80 #define DPARCKEN 0x40 #define MPARCKEN 0x20 #define EXTREQLCK 0x10 +#define BCTL 0x84 +#define ACE 0x08 +#define ENABLE 0x01 + #define BUSTIME 0x85 #define BOFF 0xf0 #define BON 0x0f @@ -372,18 +374,18 @@ #define BAD_PHASE 0x01 #define SEQINT 0x01 -#define CLRINT 0x92 -#define CLRBRKADRINT 0x08 -#define CLRSCSIINT 0x04 -#define CLRCMDINT 0x02 -#define CLRSEQINT 0x01 - #define ERROR 0x92 #define PARERR 0x08 #define ILLOPCODE 0x04 #define ILLSADDR 0x02 #define ILLHADDR 0x01 +#define CLRINT 0x92 +#define CLRBRKADRINT 0x08 +#define CLRSCSIINT 0x04 +#define CLRCMDINT 0x02 +#define CLRSEQINT 0x01 + #define DFCNTRL 0x93 #define DFSTATUS 0x94 @@ -408,6 +410,8 @@ #define QOUTCNT 0x9e +#define SCB_BASE 0xa0 + #define SCB_CONTROL 0xa0 #define MK_MESSAGE 0x80 #define DISCENB 0x40 @@ -417,8 +421,6 @@ #define DISCONNECTED 0x04 #define SCB_TAG_TYPE 0x03 -#define SCB_BASE 0xa0 - #define SCB_TCL 0xa1 #define TID 0xf0 #define SELBUSB 0x08 @@ -464,10 +466,10 @@ #define DI_2840 0x01 -#define BUS_8_BIT 0x00 -#define MAX_OFFSET_8BIT 0x0f -#define BUS_16_BIT 0x01 #define MAX_OFFSET_16BIT 0x08 +#define BUS_8_BIT 0x00 #define SCB_LIST_NULL 0xff #define SG_SIZEOF 0x08 +#define MAX_OFFSET_8BIT 0x0f #define BUS_32_BIT 0x02 +#define BUS_16_BIT 0x01 diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 1bd283a45..2600f7397 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -199,11 +199,10 @@ 5) Magneto-Optical drives and medium-changers are also recognized, now. Therefore, we have a completely gapfree recognition of all SCSI- device-types, that are known by Linux up to kernel 2.1.31. - 6) The flag SCSI_IBMMCA_DEV_RESET has been inserted. If it is set within - the configuration, each connected SCSI-device will get a reset command - during boottime. This can be necessary for some special SCSI-devices. - This flag should be included in Config.in. - (See also the new Config.in file.) + 6) The flag CONFIG_SCSI_IBMMCA_DEV_RESET has been inserted. If it is set + within the configuration, each connected SCSI-device will get a reset + command during boottime. This can be necessary for some special + SCSI-devices. (See also the new Config.in file.) Probable next improvement: bad disk handler. - Michael Lang @@ -1164,7 +1163,7 @@ static void check_devices (struct Scsi_Host *shpnt) if (device_exists (shpnt, ldn, &ld[ldn].block_length, &ld[ldn].device_type)) { -#ifdef SCSI_IBMMCA_DEV_RESET +#ifdef CONFIG_SCSI_IBMMCA_DEV_RESET int ticks; printk("(resetting)"); ticks = IM_RESET_DELAY*HZ; diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 0971ce954..93711a0d2 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -397,7 +397,7 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) */ int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) { - unsigned long oldfs; + mm_segment_t oldfs; int tmp; oldfs = get_fs(); set_fs(get_ds()); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 12a8f3723..2504b30a5 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -31,7 +31,6 @@ #include <linux/string.h> #include <linux/errno.h> #include <linux/cdrom.h> -#include <linux/ucdrom.h> #include <linux/interrupt.h> #include <linux/config.h> #include <asm/system.h> @@ -90,7 +89,6 @@ static struct cdrom_device_ops sr_dops = { sr_open, /* open */ sr_release, /* release */ sr_drive_status, /* drive status */ - sr_disk_status, /* disc status */ sr_media_change, /* media changed */ sr_tray_move, /* tray move */ sr_lock_door, /* lock door */ @@ -102,7 +100,8 @@ static struct cdrom_device_ops sr_dops = { sr_audio_ioctl, /* audio ioctl */ sr_dev_ioctl, /* device-specific ioctl */ CDC_CLOSE_TRAY | CDC_OPEN_TRAY| CDC_LOCK | CDC_SELECT_SPEED | - CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO, + CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | + CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS, 0 }; @@ -1022,6 +1021,7 @@ static int sr_init() void sr_finish() { int i; + char name[6]; blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; blk_size[MAJOR_NR] = sr_sizes; @@ -1052,7 +1052,10 @@ void sr_finish() scsi_CDs[i].cdi.dev = MKDEV(MAJOR_NR,i); scsi_CDs[i].cdi.mask = 0; get_capabilities(i); - register_cdrom(&scsi_CDs[i].cdi, "sr"); + + sprintf(name, "sr%d", i); + strcpy(scsi_CDs[i].cdi.name, name); + register_cdrom(&scsi_CDs[i].cdi); } diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 628d39c3e..265c7d04f 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -12,7 +12,6 @@ #include <scsi/scsi_ioctl.h> #include <linux/cdrom.h> -#include <linux/ucdrom.h> #include "sr.h" #if 0 @@ -729,7 +728,7 @@ int sr_dev_ioctl(struct cdrom_device_info *cdi, return -ENOMEM; lba = (((msf.cdmsf_min0 * CD_SECS) + msf.cdmsf_sec0) - * CD_FRAMES + msf.cdmsf_frame0) - CD_BLOCK_OFFSET; + * CD_FRAMES + msf.cdmsf_frame0) - CD_MSF_OFFSET; if (lba < 0 || lba >= scsi_CDs[target].capacity) return -EINVAL; @@ -757,7 +756,7 @@ int sr_dev_ioctl(struct cdrom_device_info *cdi, lba = ra.addr.lba; else lba = (((ra.addr.msf.minute * CD_SECS) + ra.addr.msf.second) - * CD_FRAMES + ra.addr.msf.frame) - CD_BLOCK_OFFSET; + * CD_FRAMES + ra.addr.msf.frame) - CD_MSF_OFFSET; if (lba < 0 || lba >= scsi_CDs[target].capacity) return -EINVAL; diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c index 82d5ba7d8..7fec8fea1 100644 --- a/drivers/scsi/sr_vendor.c +++ b/drivers/scsi/sr_vendor.c @@ -44,7 +44,6 @@ #include <scsi/scsi_ioctl.h> #include <linux/cdrom.h> -#include <linux/ucdrom.h> #include "sr.h" #if 0 @@ -231,7 +230,7 @@ int sr_cd_check(struct cdrom_device_info *cdi) frame = BCD_TO_BIN(buffer[3]); sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame; if (sector) - sector -= CD_BLOCK_OFFSET; + sector -= CD_MSF_OFFSET; break; case VENDOR_HP_4020: |