patch-2.1.36 linux/drivers/scsi/ncr53c8xx.c
Next file: linux/drivers/scsi/ncr53c8xx.h
Previous file: linux/drivers/scsi/hosts.c
Back to the patch index
Back to the overall index
- Lines: 184
- Date:
Tue Apr 22 08:30:20 1997
- Orig file:
v2.1.35/linux/drivers/scsi/ncr53c8xx.c
- Orig date:
Sun Apr 13 10:18:21 1997
diff -u --recursive --new-file v2.1.35/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
@@ -40,7 +40,7 @@
*/
/*
-** 6 April 1997, version 1.18d
+** 16 April 1997, version 1.18e
**
** Supported SCSI-II features:
** Synchronous negotiation
@@ -1735,7 +1735,7 @@
static char *ncr_name (ncb_p np)
{
- static char name[10];
+ static char name[16];
sprintf(name, "ncr53c%d-%d", np->chip, np->unit);
return (name);
}
@@ -4520,7 +4520,7 @@
**
**==========================================================
*/
-int ncr_reset_bus (Scsi_Cmnd *cmd)
+int ncr_reset_bus (Scsi_Cmnd *cmd, int sync_reset)
{
struct Scsi_Host *host = cmd->host;
/* Scsi_Device *device = cmd->device; */
@@ -4572,11 +4572,12 @@
*/
ncr_wakeup(np, HS_RESET);
/*
- * If the involved command was not in a driver queue, and is
- * not in the waiting list, complete it with DID_RESET status,
+ * If the involved command was not in a driver queue, and the
+ * scsi driver told us reset is synchronous, and the command is not
+ * currently in the waiting list, complete it with DID_RESET status,
* in order to keep it alive.
*/
- if (!found && cmd && !remove_from_waiting_list(np, cmd)) {
+ if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
cmd->result = ScsiResult(DID_RESET, 0);
cmd->scsi_done(cmd);
}
@@ -6363,27 +6364,13 @@
((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) {
/*
** Unexpected data cycle while waiting for disconnect.
- */
- if (INB(nc_sstat2) & LDSC) {
- /*
- ** It's an early reconnect.
- ** Let's continue ...
- */
- OUTONB (nc_dcntl, (STD|NOCOM));
- /*
- ** info message
- */
- printf ("%s: INFO: LDSC while IID.\n",
- ncr_name (np));
- return;
- };
- printf ("%s: target %d doesn't release the bus.\n",
- ncr_name (np), (int)INB (nc_ctest0)&0x0f);
- /*
- ** return without restarting the NCR.
- ** timeout will do the real work.
- */
- return;
+ ** LDSC and CON bits may help in order to understand
+ ** what really happened. Print some info message and let
+ ** the reset function reset the BUS and the NCR.
+ */
+ printf("%s:%d: data cycle while waiting for disconnect, LDSC=%d CON=%d\n",
+ ncr_name (np), (int)(INB(nc_ctest0)&0x0f),
+ (0!=(INB(nc_sstat2)&LDSC)), (0!=(INB(nc_scntl1)&ISCON)));
};
/*----------------------------------------
@@ -7375,7 +7362,7 @@
/*==========================================================
**
**
-** Aquire a control block
+** Acquire a control block
**
**
**==========================================================
@@ -8617,25 +8604,93 @@
** Linux entry point of reset() function
*/
-#if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,98)
+#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
+
int ncr53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
+{
+ int sts;
+ unsigned long flags;
+
+ printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
+ cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
+
+ save_flags(flags); cli();
+
+ /*
+ * We have to just ignore reset requests in some situations.
+ */
+#if defined SCSI_RESET_NOT_RUNNING
+ if (cmd->serial_number != cmd->serial_number_at_timeout) {
+ sts = SCSI_RESET_NOT_RUNNING;
+ goto out;
+ }
+#endif
+ /*
+ * If the mid-level driver told us reset is synchronous, it seems
+ * that we must call the done() callback for the involved command,
+ * even if this command was not queued to the low-level driver,
+ * before returning SCSI_RESET_SUCCESS.
+ */
+
+ sts = ncr_reset_bus(cmd,
+ (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS);
+ /*
+ * Since we always reset the controller, when we return success,
+ * we add this information to the return code.
+ */
+#if defined SCSI_RESET_HOST_RESET
+ if (sts == SCSI_RESET_SUCCESS)
+ sts |= SCSI_RESET_HOST_RESET;
+#endif
+
+out:
+ restore_flags(flags);
+ return sts;
+}
#else
int ncr53c8xx_reset(Scsi_Cmnd *cmd)
-#endif
{
printk("ncr53c8xx_reset: command pid %lu\n", cmd->pid);
- return ncr_reset_bus(cmd);
+ return ncr_reset_bus(cmd, 1);
}
+#endif
/*
** Linux entry point of abort() function
*/
+#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
+
+int ncr53c8xx_abort(Scsi_Cmnd *cmd)
+{
+ int sts;
+ unsigned long flags;
+
+ printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
+ cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
+
+ save_flags(flags); cli();
+
+ /*
+ * We have to just ignore abort requests in some situations.
+ */
+ if (cmd->serial_number != cmd->serial_number_at_timeout) {
+ sts = SCSI_ABORT_NOT_RUNNING;
+ goto out;
+ }
+
+ sts = ncr_abort_command(cmd);
+out:
+ restore_flags(flags);
+ return sts;
+}
+#else
int ncr53c8xx_abort(Scsi_Cmnd *cmd)
{
printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid);
return ncr_abort_command(cmd);
}
+#endif
#ifdef MODULE
int ncr53c8xx_release(struct Scsi_Host *host)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov