patch-1.3.26 linux/drivers/scsi/aha1542.c
Next file: linux/drivers/scsi/hosts.c
Previous file: linux/drivers/scsi/README.st
Back to the patch index
Back to the overall index
- Lines: 123
- Date:
Sun Sep 10 09:37:22 1995
- Orig file:
v1.3.25/linux/drivers/scsi/aha1542.c
- Orig date:
Sun Sep 3 12:26:59 1995
diff -u --recursive --new-file v1.3.25/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
@@ -1011,6 +1011,8 @@
}
}
aha_host[irq_level - 9] = shpnt;
+ shpnt->this_id = scsi_id;
+ shpnt->unique_id = base_io;
shpnt->io_port = base_io;
shpnt->n_io_port = 4; /* Number of bytes of I/O space used */
shpnt->dma_channel = dma_chan;
@@ -1172,33 +1174,28 @@
unchar ahacmd = CMD_START_SCSI;
int i;
- DEB(printk("aha1542_reset called\n"));
-#if 0
- /* This does a scsi reset for all devices on the bus */
- outb(SCRST, CONTROL(SCpnt->host->io_port));
-#else
- /* This does a selective reset of just the one device */
- /* First locate the ccb for this command */
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
- {
- HOSTDATA(SCpnt->host)->ccb[i].op = 0x81; /* BUS DEVICE RESET */
- /* Now tell the 1542 to flush all pending commands for this target */
- aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
-
- /* Here is the tricky part. What to do next. Do we get an interrupt
- for the commands that we aborted with the specified target, or
- do we generate this on our own? Try it without first and see
- what happens */
- printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
-
- /* If the first does not work, then try the second. I think the
- first option is more likely to be correct. Free the command
- block for all commands running on this target... */
-#if 1
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i] &&
- HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
+ /*
+ * See if a bus reset was suggested.
+ */
+ if( SCpnt->host->suggest_bus_reset )
+ {
+ /*
+ * This does a scsi reset for all devices on the bus.
+ * In principle, we could also reset the 1542 - should
+ * we do this? Try this first, and we can add that later
+ * if it turns out to be useful.
+ */
+ outb(SCRST, CONTROL(SCpnt->host->io_port));
+ /*
+ * Now try and pick up the pieces. Restart all commands
+ * that are currently active on the bus, and reset all of
+ * the datastructures. We have some time to kill while
+ * things settle down, so print a nice message.
+ */
+ printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no);
+
+ for(i=0; i< AHA1542_MAILBOXES; i++)
+ if(HOSTDATA(SCpnt->host)->SCint[i] != NULL)
{
Scsi_Cmnd * SCtmp;
SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
@@ -1210,13 +1207,50 @@
HOSTDATA(SCpnt->host)->SCint[i] = NULL;
HOSTDATA(SCpnt->host)->mb[i].status = 0;
}
- return SCSI_RESET_SUCCESS;
-#else
- return SCSI_RESET_PENDING;
-#endif
- }
-
-#endif
+ /*
+ * Now tell the mid-level code what we did here. Since
+ * we have restarted all of the outstanding commands,
+ * then report SUCCESS.
+ */
+ return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
+ }
+ else
+ {
+ /* This does a selective reset of just the one device */
+ /* First locate the ccb for this command */
+ for(i=0; i< AHA1542_MAILBOXES; i++)
+ if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
+ {
+ HOSTDATA(SCpnt->host)->ccb[i].op = 0x81; /* BUS DEVICE RESET */
+ /* Now tell the 1542 to flush all pending commands for this target */
+ aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
+
+ /* Here is the tricky part. What to do next. Do we get an interrupt
+ for the commands that we aborted with the specified target, or
+ do we generate this on our own? Try it without first and see
+ what happens */
+ printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
+
+ /* If the first does not work, then try the second. I think the
+ first option is more likely to be correct. Free the command
+ block for all commands running on this target... */
+ for(i=0; i< AHA1542_MAILBOXES; i++)
+ if(HOSTDATA(SCpnt->host)->SCint[i] &&
+ HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
+ {
+ Scsi_Cmnd * SCtmp;
+ SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
+ SCtmp->result = DID_RESET << 16;
+ if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
+ printk("Sending DID_RESET for target %d\n", SCpnt->target);
+ SCtmp->scsi_done(SCpnt);
+
+ HOSTDATA(SCpnt->host)->SCint[i] = NULL;
+ HOSTDATA(SCpnt->host)->mb[i].status = 0;
+ }
+ return SCSI_RESET_SUCCESS;
+ }
+ }
/* No active command at this time, so this means that each time we got
some kind of response the last time through. Tell the mid-level code
to request sense information in order to decide what to do next. */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this