* the host is no longer able to accept any more requests.
*/
for (;;) {
- /*
- * Check this again - each time we loop through we will have
- * released the lock and grabbed it again, so each time
- * we need to check to see if the queue is plugged or not.
- */
- if (shost->in_recovery || blk_queue_plugged(q))
- return;
-
- if (sdev->device_busy >= sdev->queue_depth)
- break;
+ if (blk_queue_plugged(q))
+ goto completed;
- if (sdev->single_lun && check_all_luns(sdev))
- break;
- /*
- * get next queueable request. We do this early to make sure
- * that the request is fully prepared even if we cannot
- * accept it. If there is no request, we'll detect this
- * lower down.
- */
- req = elv_next_request(q);
-
+ if (!scsi_dev_queue_ready(q, sdev))
+ goto completed;
- if (shost->host_busy == 0 && shost->host_blocked) {
- /* unblock after host_blocked iterates to zero */
- if (--shost->host_blocked == 0) {
- SCSI_LOG_MLQUEUE(3,
- printk("scsi%d unblocking host at zero depth\n",
- shost->host_no));
- } else {
- blk_plug_device(q);
- break;
- }
- }
-
- if (sdev->device_busy == 0 && sdev->device_blocked) {
- /* unblock after device_blocked iterates to zero */
- if (--sdev->device_blocked == 0) {
- SCSI_LOG_MLQUEUE(3,
- printk("scsi%d (%d:%d) unblocking device at zero depth\n",
- shost->host_no, sdev->id, sdev->lun));
- } else {
- blk_plug_device(q);
- break;
- }
- }
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (!scsi_host_queue_ready(q, shost, sdev))
+ goto after_host_lock;
- /*
- * If the device cannot accept another request, then quit.
- */
- if (sdev->device_blocked)
- break;
- if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
- shost->host_blocked || shost->host_self_blocked) {
- /*
- * If we are unable to process any commands at all for
- * this device, then we consider it to be starved.
- * What this means is that there are no outstanding
- * commands for this device and hence we need a
- * little help getting it started again
- * once the host isn't quite so busy.
- */
- if (sdev->device_busy == 0) {
- sdev->starved = 1;
- shost->some_device_starved = 1;
- }
- break;
- } else
- sdev->starved = 0;
+ if (sdev->single_lun && !sdev->device_busy &&
+ sdev->sdev_target->starget_busy)
+ goto after_host_lock;
/*
- * If we couldn't find a request that could be queued, then we
- * can also quit.
+ * get next queueable request. We do this early to make sure
+ * that the request is fully prepared even if we cannot
+ * accept it. If there is no request, we'll detect this
+ * lower down.
*/
- if (blk_queue_empty(q))
- goto after_host_lock;
+ req = elv_next_request(q);
if (!req) {
/* If the device is busy, a returning I/O