patch-2.1.31 linux/drivers/scsi/ibmmca.c
Next file: linux/drivers/scsi/ibmmca.h
Previous file: linux/drivers/scsi/g_NCR5380.c
Back to the patch index
Back to the overall index
- Lines: 658
- Date:
Mon Mar 31 13:25:25 1997
- Orig file:
v2.1.30/linux/drivers/scsi/ibmmca.c
- Orig date:
Wed Dec 18 01:48:52 1996
diff -u --recursive --new-file v2.1.30/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c
@@ -38,8 +38,14 @@
Aug 21 1996: Modified the code which maps ldns to (pun,0). It was
insufficient for those of us with CD-ROM changers.
- Chris Beauregard
+
+ Mar 16 1997: Modified driver to run as a module and to support
+ multiple adapters.
+ - Klaus Kudielka
*/
+#include <linux/module.h>
+
#include <linux/kernel.h>
#include <linux/head.h>
#include <linux/types.h>
@@ -64,16 +70,10 @@
Driver Description
(A) Subsystem Detection
- This is done in find_adapter() function and is easy, since
+ This is done in the ibmmca_detect() function and is easy, since
the information about MCA integrated subsystems and plug-in
adapters is readily available in structure *mca_info.
- In case you have more than one SCSI subsystem, only one can be used,
- and its I/O port addresses should be standard 0x3540-7. To use more
- than one adapter, the sharing of interrupt 14 would have to be
- supported in Linux (it is not at present, but could be, since MCA
- interrupts are level-triggered).
-
(B) Physical Units, Logical Units, and Logical Devices
There can be up to 56 devices on SCSI bus (besides the adapter):
there are up to 7 "physical units" (each identified by physical unit
@@ -136,7 +136,7 @@
100% sure that it is correct for larger disks.
(F) Kernel Boot Option
- The function ibmmca_scsi_setup() is called if option ibmmcascsi=n
+ The function ibmmca_scsi_setup() is called if option ibmmcascsi=...
is passed to the kernel. See file linux/init/main.c for details.
*/
@@ -153,12 +153,25 @@
* keyboard controller, serial port controller, VGA, and XGA.
*/
-/*addresses of hardware registers on the subsystem */
-#define IM_CMD_REG 0x3540 /*Command Interface, (4 bytes long) */
-#define IM_ATTN_REG 0x3544 /*Attention (1 byte) */
-#define IM_CTR_REG 0x3545 /*Basic Control (1 byte) */
-#define IM_INTR_REG 0x3546 /*Interrupt Status (1 byte, read only) */
-#define IM_STAT_REG 0x3547 /*Basic Status (1 byte, read only) */
+/* driver configuration */
+#define IM_MAX_HOSTS 8 /* maximum number of host adapters */
+#define IM_RESET_DELAY 10 /* seconds allowed for a reset */
+
+/* driver debugging - #undef all for normal operation */
+#undef IM_DEBUG_TIMEOUT 50 /* if defined: count interrupts
+ and ignore this special one */
+#undef IM_DEBUG_INT /* verbose interrupt */
+#undef IM_DEBUG_CMD /* verbose queuecommand */
+
+/* addresses of hardware registers on the subsystem */
+#define IM_CMD_REG (shpnt->io_port) /*Command Interface, (4 bytes long) */
+#define IM_ATTN_REG (shpnt->io_port+4) /*Attention (1 byte) */
+#define IM_CTR_REG (shpnt->io_port+5) /*Basic Control (1 byte) */
+#define IM_INTR_REG (shpnt->io_port+6) /*Interrupt Status (1 byte, r/o) */
+#define IM_STAT_REG (shpnt->io_port+7) /*Basic Status (1 byte, read only) */
+
+#define IM_IO_PORT 0x3540
+#define IM_N_IO_PORT 8
/*requests going into the upper nibble of the Attention register */
/*note: the lower nibble specifies the device(0-14), or subsystem(15) */
@@ -314,40 +327,67 @@
int is_disk;
int block_length;
};
-static struct logical_device ld[MAX_LOG_DEV];
-/*if this is nonzero, ibmmcascsi option has been passed to the kernel */
-static int setup_called = 0;
+/* data structure for each host adapter */
+struct ibmmca_hostdata
+ {
+ /* array of logical devices */
+ struct logical_device _ld[MAX_LOG_DEV];
+ /* array to convert (pun, lun) into logical device number */
+ unsigned char _get_ldn[8][8];
+ /* used only when checking logical devices */
+ int _local_checking_phase_flag;
+ int _got_interrupt;
+ int _stat_result;
+ /* reset status (used only when doing reset) */
+ int _reset_status;
+ };
-/*scsi id (physical unit number) of subsystem (set during detect) */
-static int subsystem_pun;
+/* reset status values */
+#define IM_RESET_NOT_IN_PROGRESS 0
+#define IM_RESET_IN_PROGRESS 1
+#define IM_RESET_FINISHED_OK 2
+#define IM_RESET_FINISHED_FAIL 3
-/*array to convert (pun, lun) into logical device number */
-static unsigned char get_ldn[8][8];
+/* macros to access host data structure */
+#define HOSTDATA(shpnt) ((struct ibmmca_hostdata *) shpnt->hostdata)
+#define subsystem_pun (shpnt->this_id)
+#define ld (HOSTDATA(shpnt)->_ld)
+#define get_ldn (HOSTDATA(shpnt)->_get_ldn)
+#define local_checking_phase_flag (HOSTDATA(shpnt)->_local_checking_phase_flag)
+#define got_interrupt (HOSTDATA(shpnt)->_got_interrupt)
+#define stat_result (HOSTDATA(shpnt)->_stat_result)
+#define reset_status (HOSTDATA(shpnt)->_reset_status)
+
+/*--------------------------------------------------------------------*/
+
+/* if this is nonzero, ibmmcascsi option has been passed to the kernel */
+static int io_port[IM_MAX_HOSTS] = { 0 };
+static int scsi_id[IM_MAX_HOSTS] = { 7 };
+
+MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
+MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
/*counter of concurrent disk read/writes, to turn on/off disk led */
-static int disk_rw_in_progress;
+static int disk_rw_in_progress = 0;
-/*used only when checking logical devices */
-static int local_checking_phase_flag;
-static int got_interrupt;
-static int stat_result;
+/* host information */
+static int found = 0;
+static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL };
-/*reset status and its values (used only when doing reset) */
-static int reset_status;
-#define IM_RESET_NOT_IN_PROGRESS 0
-#define IM_RESET_IN_PROGRESS 1
-#define IM_RESET_FINISHED_OK 2
-#define IM_RESET_FINISHED_FAIL 3
+/*--------------------------------------------------------------------*/
/*local functions */
static void interrupt_handler (int irq, void *dev_id,
struct pt_regs *regs);
-static void issue_cmd (unsigned long cmd_reg, unsigned char attn_reg);
+static void issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg,
+ unsigned char attn_reg);
static void internal_done (Scsi_Cmnd * cmd);
-static int find_subsystem (void);
-static void check_devices (void);
-static int device_exists (int ldn, int *is_disk, int *block_length);
+static void check_devices (struct Scsi_Host *shpnt);
+static int device_exists (struct Scsi_Host *shpnt, int ldn, int *is_disk,
+ int *block_length);
+static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * template,
+ int port, int id);
/*--------------------------------------------------------------------*/
@@ -355,16 +395,20 @@
interrupt_handler (int irq, void *dev_id,
struct pt_regs *regs)
{
- /*get command result and logical device */
- unsigned int intr_reg = inb (IM_INTR_REG);
- unsigned int cmd_result = intr_reg & 0xf0;
- unsigned int ldn = intr_reg & 0x0f;
+ int i = 0;
+ struct Scsi_Host *shpnt;
+ unsigned int intr_reg;
+ unsigned int cmd_result;
+ unsigned int ldn;
- if (!inb (IM_STAT_REG) & IM_INTR_REQUEST)
- {
- printk ("ibmmca SCSI: spurious/shared interrupt?\n");
- return;
- }
+ do shpnt = hosts[i++];
+ while (shpnt && !(inb(IM_STAT_REG) & IM_INTR_REQUEST));
+ if (!shpnt) return;
+
+ /*get command result and logical device */
+ intr_reg = inb(IM_INTR_REG);
+ cmd_result = intr_reg & 0xf0;
+ ldn = intr_reg & 0x0f;
/*must wait for attention reg not busy, then send EOI to subsystem */
while (1)
@@ -409,9 +453,6 @@
}
else
{
- /*reset disk led counter, turn of disk led */
- disk_rw_in_progress = 0;
- PS2_DISK_LED_OFF ();
reset_status = IM_RESET_FINISHED_OK;
}
return;
@@ -420,16 +461,29 @@
panic ("IBM MCA SCSI: invalid logical device number.\n");
}
+#ifdef IM_DEBUG_TIMEOUT
+ {
+ static int count = 0;
+
+ if (++count == IM_DEBUG_TIMEOUT) {
+ printk("IBM MCA SCSI: Ignoring interrupt.\n");
+ return;
+ }
+ }
+#endif
+
/*if no command structure, just return, else clear cmd */
cmd = ld[ldn].cmd;
if (!cmd)
return;
ld[ldn].cmd = 0;
- /* printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n",
- cmd->cmnd[0], intr_reg,
- ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status,
- ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error); */
+#ifdef IM_DEBUG_INT
+ printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n",
+ cmd->cmnd[0], intr_reg,
+ ld[ldn].tsb.dev_status, ld[ldn].tsb.cmd_status,
+ ld[ldn].tsb.dev_error, ld[ldn].tsb.cmd_error);
+#endif
/*if this is end of disk read/write, may turn off PS/2 disk led */
if (ld[ldn].is_disk)
@@ -457,7 +511,8 @@
/*--------------------------------------------------------------------*/
static void
-issue_cmd (unsigned long cmd_reg, unsigned char attn_reg)
+issue_cmd (struct Scsi_Host *shpnt, unsigned long cmd_reg,
+ unsigned char attn_reg)
{
/*must wait for attention reg not busy */
while (1)
@@ -487,83 +542,29 @@
static int
ibmmca_getinfo (char *buf, int slot, void *dev)
{
+ struct Scsi_Host *shpnt = dev;
int len = 0;
len += sprintf (buf + len, "Subsystem PUN: %d\n", subsystem_pun);
- len += sprintf (buf + len, "Detected at boot: %s\n",
- setup_called ? "No" : "Yes");
+ len += sprintf (buf + len, "I/O base address: 0x%x\n", shpnt->io_port);
return len;
}
-static int
-find_subsystem (void)
-{
- int j, list_size, slot;
- unsigned char pos2, pos3;
-
- /*if this is not MCA machine, return "nothing found" */
- if (!MCA_bus)
- return 0;
-
- /*if ibmmcascsi setup option was passed to kernel, return "found" */
- if (setup_called)
- {
- printk ("IBM MCA SCSI: forced detection, scsi id=%d.\n",
- subsystem_pun);
- return 1;
- }
-
- /*first look for the SCSI integrated on the motherboard */
- pos2 = mca_read_stored_pos (MCA_INTEGSCSI, 2);
- if ((pos2 & 1) == 0)
- {
- pos3 = mca_read_stored_pos (MCA_INTEGSCSI, 3);
- subsystem_pun = (pos3 & 0xe0) >> 5;
- printk ("IBM MCA SCSI: integrated SCSI found, scsi id=%d.\n",
- subsystem_pun);
- mca_set_adapter_name (MCA_INTEGSCSI, "PS/2 Integrated SCSI");
- mca_set_adapter_procfn (MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
- NULL);
- return 1;
- }
-
- list_size = sizeof (subsys_list) / sizeof (struct subsys_list_struct);
- for (j = 0; j < list_size; j += 1)
- {
- if ((slot = mca_find_adapter (subsys_list[j].mca_id, 0)) != MCA_NOTFOUND)
- {
- pos3 = mca_read_stored_pos (slot, 3);
- subsystem_pun = (pos3 & 0xe0) >> 5;
- printk ("IBM MCA SCSI: %s found in slot %d, scsi id=%d.\n",
- subsys_list[j].description, slot + 1, subsystem_pun);
-
- mca_set_adapter_name (slot, subsys_list[j].description);
- mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
- NULL);
-
- return 1;
- }
- }
-
- /*return "nothing found" */
- return 0;
-}
-
/*--------------------------------------------------------------------*/
static void
-check_devices (void)
+check_devices(struct Scsi_Host *shpnt)
{
int is_disk, block_length;
int ldn;
int num_ldn = 0;
- /*check ldn's from 0 to MAX_LOG_DEV to find which devices exist */
+ /* check ldn's from 0 to MAX_LOG_DEV to find which devices exist */
for (ldn = 0; ldn < MAX_LOG_DEV; ldn++)
{
- if (device_exists (ldn, &is_disk, &block_length))
+ if (device_exists(shpnt, ldn, &is_disk, &block_length))
{
- printk ("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn);
+ printk("IBM MCA SCSI: logical device found at ldn=%d.\n", ldn);
ld[ldn].is_disk = is_disk;
ld[ldn].block_length = block_length;
get_ldn[num_ldn / 8][num_ldn % 8] = ldn;
@@ -577,7 +578,8 @@
/*--------------------------------------------------------------------*/
static int
-device_exists (int ldn, int *is_disk, int *block_length)
+device_exists(struct Scsi_Host *shpnt, int ldn, int *is_disk,
+ int *block_length)
{
struct im_scb scb;
struct im_tsb tsb;
@@ -596,7 +598,7 @@
/*issue scb to passed ldn, and busy wait for interrupt */
got_interrupt = 0;
- issue_cmd (virt_to_bus(&scb), IM_SCB | ldn);
+ issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn);
while (!got_interrupt)
barrier ();
@@ -633,7 +635,7 @@
/*issue scb to passed ldn, and busy wait for interrupt */
got_interrupt = 0;
- issue_cmd (virt_to_bus(&scb), IM_SCB | ldn);
+ issue_cmd (shpnt, virt_to_bus(&scb), IM_SCB | ldn);
while (!got_interrupt)
barrier ();
@@ -656,47 +658,154 @@
/*--------------------------------------------------------------------*/
+#ifdef CONFIG_SCSI_IBMMCA
+
void
ibmmca_scsi_setup (char *str, int *ints)
{
- /*verify that one value (between 0 and 7) was specified */
- if (setup_called++ || ints[0] != 1 || ints[1] < 0 || ints[1] >= 8)
+ int i;
+
+ for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++)
{
- printk ("IBM MCA SCSI: usage: ibmmcascsi=<ADAPTER_SCSI_ID>\n");
- return;
+ io_port[i] = ints[i+1];
}
- subsystem_pun = ints[1];
}
+#endif
+
/*--------------------------------------------------------------------*/
int
ibmmca_detect (Scsi_Host_Template * template)
{
- /*initialize local data */
- memset (ld, 0, sizeof ld);
- memset (get_ldn, 0xff, sizeof get_ldn);
- disk_rw_in_progress = 0;
- reset_status = IM_RESET_NOT_IN_PROGRESS;
+ struct Scsi_Host *shpnt;
+ int port, id, i, list_size, slot;
+ unsigned pos2, pos3;
- /*search for the subsystem, return 0 if not found */
- if (!find_subsystem ())
+ /* if this is not MCA machine, return "nothing found" */
+ if (!MCA_bus)
return 0;
- /*get interrupt request level */
- if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", 0))
+ /* get interrupt request level */
+ if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmca", hosts))
{
- printk ("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ);
+ printk("IBM MCA SCSI: Unable to get IRQ %d.\n", IM_IRQ);
return 0;
}
- /*check which logical devices exist */
+ /* if ibmmcascsi setup option was passed to kernel, return "found" */
+ for (i = 0; i < IM_MAX_HOSTS; i++)
+ if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8)
+ {
+ printk("IBM MCA SCSI: forced detection, io=0x%x, scsi id=%d.\n",
+ io_port[i], scsi_id[i]);
+ ibmmca_register(template, io_port[i], scsi_id[i]);
+ }
+ if (found) return found;
+
+ /* first look for the SCSI integrated on the motherboard */
+ pos2 = mca_read_stored_pos(MCA_INTEGSCSI, 2);
+ if ((pos2 & 1) == 0)
+ {
+ pos3 = mca_read_stored_pos(MCA_INTEGSCSI, 3);
+ port = IM_IO_PORT + ((pos2 & 0x0e) << 2);
+ id = (pos3 & 0xe0) >> 5;
+ printk("IBM MCA SCSI: integrated SCSI found, io=0x%x, scsi id=%d.\n",
+ port, id);
+ if ((shpnt = ibmmca_register(template, port, id)))
+ {
+ mca_set_adapter_name(MCA_INTEGSCSI, "PS/2 Integrated SCSI");
+ mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
+ shpnt);
+ }
+ }
+
+ /* now look for other adapters */
+ list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
+ for (i = 0; i < list_size; i++)
+ {
+ slot = 0;
+ while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
+ != MCA_NOTFOUND)
+ {
+ pos2 = mca_read_stored_pos(slot, 2);
+ pos3 = mca_read_stored_pos(slot, 3);
+ port = IM_IO_PORT + ((pos2 & 0x0e) << 2);
+ id = (pos3 & 0xe0) >> 5;
+ printk ("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d.\n",
+ subsys_list[i].description, slot + 1, port, id);
+ if ((shpnt = ibmmca_register(template, port, id)))
+ {
+ mca_set_adapter_name (slot, subsys_list[i].description);
+ mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
+ shpnt);
+ }
+ slot++;
+ }
+ }
+
+ if (!found) {
+ free_irq (IM_IRQ, hosts);
+ printk("IBM MCA SCSI: No adapter attached.\n");
+ }
+
+ return found;
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct Scsi_Host *
+ibmmca_register(Scsi_Host_Template * template, int port, int id)
+{
+ struct Scsi_Host *shpnt;
+ int i, j;
+
+ /* check I/O region */
+ if (check_region(port, IM_N_IO_PORT))
+ {
+ printk("IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x.\n",
+ port, port + IM_N_IO_PORT);
+ return NULL;
+ }
+
+ /* register host */
+ shpnt = scsi_register(template, sizeof(struct ibmmca_hostdata));
+ if (!shpnt)
+ {
+ printk("IBM MCA SCSI: Unable to register host.\n");
+ return NULL;
+ }
+
+ /* request I/O region */
+ request_region(port, IM_N_IO_PORT, "ibmmca");
+
+ hosts[found++] = shpnt;
+ shpnt->irq = IM_IRQ;
+ shpnt->io_port = port;
+ shpnt->n_io_port = IM_N_IO_PORT;
+ shpnt->this_id = id;
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ get_ldn[i][j] = MAX_LOG_DEV;
+
+ /* check which logical devices exist */
local_checking_phase_flag = 1;
- check_devices ();
+ check_devices(shpnt);
local_checking_phase_flag = 0;
- /*if got here, one ibm mca subsystem has been detected */
- return 1;
+ /* an ibm mca subsystem has been detected */
+ return shpnt;
+}
+
+/*--------------------------------------------------------------------*/
+
+int
+ibmmca_release(struct Scsi_Host *shpnt)
+{
+ release_region(shpnt->io_port, shpnt->n_io_port);
+ if (!(--found))
+ free_irq(shpnt->irq, hosts);
+ return 0;
}
/*--------------------------------------------------------------------*/
@@ -719,6 +828,7 @@
unsigned int ldn;
unsigned int scsi_cmd;
struct im_scb *scb;
+ struct Scsi_Host *shpnt = cmd->host;
/*if (target,lun) unassigned, return error */
ldn = get_ldn[cmd->target][cmd->lun];
@@ -764,7 +874,9 @@
/*fill scb information dependent on scsi command */
scsi_cmd = cmd->cmnd[0];
- /* printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn); */
+#ifdef IM_DEBUG_CMD
+ printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
+#endif
switch (scsi_cmd)
{
case READ_6:
@@ -833,7 +945,7 @@
}
/*issue scb command, and return */
- issue_cmd (virt_to_bus(scb), IM_SCB | ldn);
+ issue_cmd (shpnt, virt_to_bus(scb), IM_SCB | ldn);
return 0;
}
@@ -842,10 +954,13 @@
int
ibmmca_abort (Scsi_Cmnd * cmd)
{
-/*do a reset instead, since abort does not work well for me at present */
- return ibmmca_reset (cmd);
+ /* The code below doesn't work right now, so we tell the upper layer
+ that we can't abort. This eventually causes a reset.
+ */
+ return SCSI_ABORT_SNOOZE;
#if 0
+ struct Scsi_Host *shpnt = cmd->host;
unsigned int ldn;
void (*saved_done) (Scsi_Cmnd *);
@@ -870,7 +985,7 @@
saved_done = cmd->scsi_done;
cmd->scsi_done = internal_done;
cmd->SCp.Status = 0;
- issue_cmd (IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn);
+ issue_cmd (shpnt, IM_ABORT_IMM_CMD, IM_IMM_CMD | ldn);
while (!cmd->SCp.Status)
barrier ();
@@ -889,22 +1004,42 @@
/*--------------------------------------------------------------------*/
int
-ibmmca_reset (Scsi_Cmnd * cmd)
+ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
{
- /*issue reset immediate command to subsystem, and wait for interrupt */
- printk ("IBM MCA SCSI: resetting all devices.\n");
+ struct Scsi_Host *shpnt = cmd->host;
+ int ticks = IM_RESET_DELAY*HZ;
+
+ if (local_checking_phase_flag) {
+ printk("IBM MCA SCSI: unable to reset while checking devices.\n");
+ return SCSI_RESET_SNOOZE;
+ }
+
+ /* issue reset immediate command to subsystem, and wait for interrupt */
+ printk("IBM MCA SCSI: resetting all devices.\n");
cli ();
reset_status = IM_RESET_IN_PROGRESS;
- issue_cmd (IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf);
- while (reset_status == IM_RESET_IN_PROGRESS)
- barrier ();
+ issue_cmd (shpnt, IM_RESET_IMM_CMD, IM_IMM_CMD | 0xf);
+ while (reset_status == IM_RESET_IN_PROGRESS && --ticks) {
+ udelay(1000000/HZ);
+ barrier();
+ }
- /*if reset failed, just return error */
- if (reset_status == IM_RESET_FINISHED_FAIL)
+ /* if reset did not complete, just return an error*/
+ if (!ticks) {
+ printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
+ IM_RESET_DELAY);
+ reset_status = IM_RESET_FINISHED_FAIL;
return SCSI_RESET_ERROR;
+ }
+
+ /* if reset failed, just return an error */
+ if (reset_status == IM_RESET_FINISHED_FAIL) {
+ printk("IBM MCA SCSI: reset failed.\n");
+ return SCSI_RESET_ERROR;
+ }
- /*so reset finished ok - call outstanding done's, and return success */
- printk ("IBM MCA SCSI: reset finished well.\n");
+ /* so reset finished ok - call outstanding done's, and return success */
+ printk ("IBM MCA SCSI: reset completed without error.\n");
{
int i;
for (i = 0; i < MAX_LOG_DEV; i++)
@@ -947,3 +1082,11 @@
}
/*--------------------------------------------------------------------*/
+
+#ifdef MODULE
+/* Eventually this will go into an include file, but this will be later */
+Scsi_Host_Template driver_template = IBMMCA;
+
+#include "scsi_module.c"
+#endif
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov