summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-16 05:34:03 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-16 05:34:03 +0000
commit967c65a99059fd459b956c1588ce0ba227912c4e (patch)
tree8224d013ff5d255420713d05610c7efebd204d2a /drivers/scsi
parente20c1cc1656a66a2773bca4591a895cbc12696ff (diff)
Merge with Linux 2.1.72, part 1.
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/BusLogic.h8
-rw-r--r--drivers/scsi/Config.in2
-rw-r--r--drivers/scsi/aic7xxx.c115
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx.reg30
-rw-r--r--drivers/scsi/aic7xxx_proc.c254
-rw-r--r--drivers/scsi/aic7xxx_reg.h64
-rw-r--r--drivers/scsi/ibmmca.c11
-rw-r--r--drivers/scsi/scsi_ioctl.c2
-rw-r--r--drivers/scsi/sr.c11
-rw-r--r--drivers/scsi/sr_ioctl.c5
-rw-r--r--drivers/scsi/sr_vendor.c3
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: