patch-2.4.19 linux-2.4.19/drivers/scsi/scsi.c

Next file: linux-2.4.19/drivers/scsi/scsi.h
Previous file: linux-2.4.19/drivers/scsi/qlogicfc.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/scsi/scsi.c linux-2.4.19/drivers/scsi/scsi.c
@@ -156,7 +156,12 @@
  */
 extern void scsi_old_done(Scsi_Cmnd * SCpnt);
 extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
+extern int scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag);
 
+/* 
+ * Private interface into the new error handling code.
+ */
+extern int scsi_new_reset(Scsi_Cmnd *SCpnt, unsigned int flag);
 
 /*
  * Function:    scsi_initialize_queue()
@@ -2726,6 +2731,102 @@
 }
 
 /*
+ * Function:	scsi_reset_provider_done_command
+ *
+ * Purpose:	Dummy done routine.
+ *
+ * Notes:	Some low level drivers will call scsi_done and end up here,
+ *		others won't bother.
+ *		We don't want the bogus command used for the bus/device
+ *		reset to find its way into the mid-layer so we intercept
+ *		it here.
+ */
+static void
+scsi_reset_provider_done_command(Scsi_Cmnd *SCpnt)
+{
+}
+
+/*
+ * Function:	scsi_reset_provider
+ *
+ * Purpose:	Send requested reset to a bus or device at any phase.
+ *
+ * Arguments:	device	- device to send reset to
+ *		flag - reset type (see scsi.h)
+ *
+ * Returns:	SUCCESS/FAILURE.
+ *
+ * Notes:	This is used by the SCSI Generic driver to provide
+ *		Bus/Device reset capability.
+ */
+int
+scsi_reset_provider(Scsi_Device *dev, int flag)
+{
+	Scsi_Cmnd SC, *SCpnt = ≻
+	int rtn;
+
+	memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout));
+	SCpnt->host                    	= dev->host;
+	SCpnt->device                  	= dev;
+	SCpnt->target                  	= dev->id;
+	SCpnt->lun                     	= dev->lun;
+	SCpnt->channel                 	= dev->channel;
+	SCpnt->request.rq_status       	= RQ_SCSI_BUSY;
+	SCpnt->request.waiting        	= NULL;
+	SCpnt->use_sg                  	= 0;
+	SCpnt->old_use_sg              	= 0;
+	SCpnt->old_cmd_len             	= 0;
+	SCpnt->underflow               	= 0;
+	SCpnt->transfersize            	= 0;
+	SCpnt->resid			= 0;
+	SCpnt->serial_number           	= 0;
+	SCpnt->serial_number_at_timeout	= 0;
+	SCpnt->host_scribble           	= NULL;
+	SCpnt->next                    	= NULL;
+	SCpnt->state                   	= SCSI_STATE_INITIALIZING;
+	SCpnt->owner	     		= SCSI_OWNER_MIDLEVEL;
+    
+	memset(&SCpnt->cmnd, '\0', sizeof(SCpnt->cmnd));
+    
+	SCpnt->scsi_done		= scsi_reset_provider_done_command;
+	SCpnt->done			= NULL;
+	SCpnt->reset_chain		= NULL;
+        
+	SCpnt->buffer			= NULL;
+	SCpnt->bufflen			= 0;
+	SCpnt->request_buffer		= NULL;
+	SCpnt->request_bufflen		= 0;
+
+	SCpnt->internal_timeout		= NORMAL_TIMEOUT;
+	SCpnt->abort_reason		= DID_ABORT;
+
+	SCpnt->cmd_len			= 0;
+
+	SCpnt->sc_data_direction	= SCSI_DATA_UNKNOWN;
+	SCpnt->sc_request		= NULL;
+	SCpnt->sc_magic			= SCSI_CMND_MAGIC;
+
+	/*
+	 * Sometimes the command can get back into the timer chain,
+	 * so use the pid as an identifier.
+	 */
+	SCpnt->pid			= 0;
+
+	if (dev->host->hostt->use_new_eh_code) {
+		rtn = scsi_new_reset(SCpnt, flag);
+	} else {
+		unsigned long flags;
+
+		spin_lock_irqsave(&io_request_lock, flags);
+		rtn = scsi_old_reset(SCpnt, flag);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+	}
+
+	scsi_delete_timer(SCpnt);
+	return rtn;
+}
+
+/*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)