Skip to contentSkip to conversation

scsi_error update take 2

PATCH New Mike Anderson 1 participant 1 message Feb 19, 2003 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 scsi_error update take 2

This is an update of a previous patch I posted.
http://marc.theaimsgroup.com/?l=linux-scsi&m=104495114103628&w=2

This patch is against scsi-misc-2.5

The updates from the last patch include:
- Names changes:
eh_cmd_list => eh_cmd_q
eh_list => eh_entry

- Move shost->in_recovery = 0

- Switch from scsi_retry_command to scsi_queue_insert for retry to solve fast completions / serial start of retries.

- Use list_splice_init in scsi_unjam_host.

Sorry for the one large patch chunk :-(.

-andmike
--
Michael Anderson
[email protected]

 hosts.c      |   20 --
 hosts.h      |    2 
 scsi.c       |   46 ++++
 scsi.h       |   11 -
 scsi_error.c |  550 +++++++++++++++++++++++++++++++----------------------------
 scsi_lib.c   |    2 
 scsi_syms.c  |    1 
 7 files changed, 351 insertions(+), 281 deletions(-)

-------

drivers/scsi/hosts.c +4 -16
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
@@ -397,6 +397,7 @@
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
 	INIT_LIST_HEAD(&shost->my_devices);
+	INIT_LIST_HEAD(&shost->eh_cmd_q);
 
 	init_waitqueue_head(&shost->host_wait);
 	shost->dma_channel = 0xff;
@@ -634,22 +635,9 @@
 	spin_lock_irqsave(shost->host_lock, flags);
 	shost->host_busy--;
 	sdev->device_busy--;
-	if (shost->in_recovery && (shost->host_busy == shost->host_failed)) {
-		up(shost->eh_wait);
-		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
-					  " thread\n"));
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
-}
-
-void scsi_host_failed_inc_and_test(struct Scsi_Host *shost)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	shost->in_recovery = 1;
-	shost->host_failed++;
-	if (shost->host_busy == shost->host_failed) {
+	if (shost->in_recovery && shost->host_failed &&
+	    (shost->host_busy == shost->host_failed))
+	{
 		up(shost->eh_wait);
 		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
 					  " thread\n"));
drivers/scsi/hosts.h +1 -1
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
@@ -384,6 +384,7 @@
     spinlock_t		  default_lock;
     spinlock_t		  *host_lock;
 
+    struct list_head	eh_cmd_q;
     struct task_struct    * ehandler;  /* Error recovery thread. */
     struct semaphore      * eh_wait;   /* The error recovery thread waits on
                                           this. */
@@ -587,7 +588,6 @@
  */
 extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
 extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
-extern void scsi_host_failed_inc_and_test(struct Scsi_Host *);
 
 /**
  * scsi_find_device - find a device given the host
drivers/scsi/scsi.c +40 -6

59 lines not on this page · raw message

drivers/scsi/scsi.h +7 -4
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
@@ -455,6 +455,7 @@
 extern void scsi_slave_detach(struct scsi_device *);
 extern int scsi_device_get(struct scsi_device *);
 extern void scsi_device_put(struct scsi_device *);
+extern void scsi_set_device_offline(struct scsi_device *);
 extern void scsi_done(Scsi_Cmnd * SCpnt);
 extern void scsi_finish_command(Scsi_Cmnd *);
 extern int scsi_retry_command(Scsi_Cmnd *);
@@ -726,6 +727,7 @@
 
 	struct list_head list;  /* scsi_cmnd participates in queue lists */
 
+	struct list_head eh_entry; /* entry for the host eh_cmd_q */
 	int eh_state;		/* Used for state tracking in error handlr */
 	int eh_eflags;		/* Used by error handlr */
 	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
@@ -850,6 +852,7 @@
  */
 #define SCSI_MLQUEUE_HOST_BUSY   0x1055
 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
+#define SCSI_MLQUEUE_EH_RETRY    0x1057
 
 /*
  * old style reset request from external source
@@ -960,12 +963,12 @@
 /*
  * Scsi Error Handler Flags
  */
-#define SCSI_EH_CMD_ERR	0x0001	/* Orig cmd error'd */
-#define SCSI_EH_CMD_FAILED	0x0002	/* Orig cmd error type failed */
-#define SCSI_EH_CMD_TIMEOUT	0x0004	/* Orig cmd error type timeout */
-#define SCSI_EH_REC_TIMEOUT	0x0008	/* Recovery cmd timeout */
+#define SCSI_EH_CANCEL_CMD	0x0001	/* Cancel this cmd */
+#define SCSI_EH_REC_TIMEOUT	0x0002	/* EH retry timed out */
 
 #define SCSI_SENSE_VALID(scmd) ((scmd->sense_buffer[0] & 0x70) == 0x70)
+
+extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
 
 int scsi_set_medium_removal(Scsi_Device *dev, char state);
 
drivers/scsi/scsi_error.c +297 -253

805 lines not on this page · raw message

drivers/scsi/scsi_lib.c +1 -1
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
@@ -117,7 +117,7 @@
 	 */
 	if (reason == SCSI_MLQUEUE_HOST_BUSY)
 		host->host_blocked = host->max_host_blocked;
-	else
+	else if (reason == SCSI_MLQUEUE_DEVICE_BUSY)
 		device->device_blocked = device->max_device_blocked;
 
 	/*
drivers/scsi/scsi_syms.c +1 -0
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
@@ -80,6 +80,7 @@
 EXPORT_SYMBOL(scsi_slave_detach);
 EXPORT_SYMBOL(scsi_device_get);
 EXPORT_SYMBOL(scsi_device_put);
+EXPORT_SYMBOL(scsi_set_device_offline);
 
 /*
  * This symbol is for the highlevel drivers (e.g. sg) only.