Merge branch 'devel'
[deliverable/linux.git] / drivers / scsi / scsi_lib.c
index 5dfd7495d1a1bc4231123760090aa3d38eb9a764..6dfb9785d34581eb06395ef1d4b372b243de5d87 100644 (file)
@@ -1378,16 +1378,19 @@ static int scsi_lld_busy(struct request_queue *q)
 {
        struct scsi_device *sdev = q->queuedata;
        struct Scsi_Host *shost;
-       struct scsi_target *starget;
 
        if (!sdev)
                return 0;
 
        shost = sdev->host;
-       starget = scsi_target(sdev);
 
-       if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) ||
-           scsi_target_is_busy(starget) || scsi_device_is_busy(sdev))
+       /*
+        * Ignore host/starget busy state.
+        * Since block layer does not have a concept of fairness across
+        * multiple queues, congestion of host/starget needs to be handled
+        * in SCSI layer.
+        */
+       if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev))
                return 1;
 
        return 0;
@@ -2348,10 +2351,14 @@ EXPORT_SYMBOL(scsi_device_quiesce);
  *
  *     Must be called with user context, may sleep.
  */
-void
-scsi_device_resume(struct scsi_device *sdev)
+void scsi_device_resume(struct scsi_device *sdev)
 {
-       if(scsi_device_set_state(sdev, SDEV_RUNNING))
+       /* check if the device state was mutated prior to resume, and if
+        * so assume the state is being managed elsewhere (for example
+        * device deleted during suspend)
+        */
+       if (sdev->sdev_state != SDEV_QUIESCE ||
+           scsi_device_set_state(sdev, SDEV_RUNNING))
                return;
        scsi_run_queue(sdev->request_queue);
 }
This page took 0.024176 seconds and 5 git commands to generate.