[PATCH] libata: clear sdev->locked on door lock failure
authorTejun Heo <htejun@gmail.com>
Tue, 8 Aug 2006 05:08:59 +0000 (14:08 +0900)
committerJeff Garzik <jeff@garzik.org>
Wed, 9 Aug 2006 05:16:27 +0000 (01:16 -0400)
SCSI EH locks door if sdev->locked is set.  Sometimes door lock
command fails continuously (e.g. when medium is not present) and as
libata uses EH to acquire sense data, this easily creates a loop where
a failed lock door invokes EH and EH issues lock door on completion.

This patch clears sdev->locked on door lock failure to break this
loop.  This problem has been spotted and diagnosed by Unicorn Chang
<uchang@tw.ibm.com>.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/scsi/libata-scsi.c

index 7ced41ecde860c0c4c58ce0c5cb7d9afc0d05051..e92c31d698ff6c983b7a817afe190d10a7f1de6c 100644 (file)
@@ -2353,6 +2353,19 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
                        ata_gen_ata_desc_sense(qc);
                }
 
+               /* SCSI EH automatically locks door if sdev->locked is
+                * set.  Sometimes door lock request continues to
+                * fail, for example, when no media is present.  This
+                * creates a loop - SCSI EH issues door lock which
+                * fails and gets invoked again to acquire sense data
+                * for the failed command.
+                *
+                * If door lock fails, always clear sdev->locked to
+                * avoid this infinite loop.
+                */
+               if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
+                       qc->dev->sdev->locked = 0;
+
                qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
                qc->scsidone(cmd);
                ata_qc_free(qc);