ChangeSet 1.2181.22.22, 2005/03/30 13:52:14-06:00, [EMAIL PROTECTED](none)

        Fix SCSI internal requests hang
        
        When a device is being torn down (mostly in USB ejection)
        we hit conditions where SCSI hangs in wait_for_completion().
        The reason is that the scsi request prep function does a
        state check on the device and rejects it with BLKPREP_KILL if
        we're in the DEL (going away, no more I/O) state.
        
        Unfortunately, I/O submitted by scsi_wait_req() doesn't have
        its request->end_io initialised, so we're never notified of
        this (the submit path expects everything to come back via
        the scsi_request->sr_done() routine, which only happens
        if the I/O actually gets submitted.
        
        Note: almost everything that uses scsi_do_request() is wrong
        not only in this regard but also on other things, like ending
        tags.
        
        Problem Diagnosed with help from: Tejun Heo <[EMAIL PROTECTED]>
        
        Signed-off-by: James Bottomley <[EMAIL PROTECTED]>



 scsi_lib.c |   11 +++++++++++
 1 files changed, 11 insertions(+)


diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c   2005-03-30 16:23:58 -08:00
+++ b/drivers/scsi/scsi_lib.c   2005-03-30 16:23:58 -08:00
@@ -252,6 +252,16 @@
                complete(req->waiting);
 }
 
+/* This is the end routine we get to if a command was never attached
+ * to the request.  Simply complete the request without changing
+ * rq_status; this will cause a DRIVER_ERROR. */
+static void scsi_wait_req_end_io(struct request *req)
+{
+       BUG_ON(!req->waiting);
+
+       complete(req->waiting);
+}
+
 void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
                   unsigned bufflen, int timeout, int retries)
 {
@@ -259,6 +269,7 @@
        
        sreq->sr_request->waiting = &wait;
        sreq->sr_request->rq_status = RQ_SCSI_BUSY;
+       sreq->sr_request->end_io = scsi_wait_req_end_io;
        scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
                        timeout, retries);
        wait_for_completion(&wait);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to