Commit 13a390f2 authored by Patrick Mansfield's avatar Patrick Mansfield Committed by James Bottomley

[PATCH] 3/7 consolidate single_lun code

Consolidate scsi single_lun code.
parent 1848dd12
......@@ -322,6 +322,49 @@ void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
cmd->underflow = cmd->old_underflow;
}
/*
* Called for single_lun devices. The target associated with current_sdev can
* only handle one active command at a time. Scan through all of the luns
* on the same target as current_sdev, return 1 if any are active.
*/
static int scsi_single_lun_check(struct scsi_device *current_sdev)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &current_sdev->same_target_siblings,
same_target_siblings)
if (sdev->device_busy)
return 1;
return 0;
}
/*
* Called for single_lun devices on IO completion. If no requests
* outstanding for current_sdev, call __blk_run_queue for the next
* scsi_device on the same target that has requests.
*
* Called with queue_lock held.
*/
static void scsi_single_lun_run(struct scsi_device *current_sdev,
struct request_queue *q)
{
struct scsi_device *sdev;
struct Scsi_Host *shost;
shost = current_sdev->host;
if (blk_queue_empty(q) && current_sdev->device_busy == 0 &&
!shost->host_blocked && !shost->host_self_blocked &&
!((shost->can_queue > 0) &&
(shost->host_busy >= shost->can_queue)))
list_for_each_entry(sdev, &current_sdev->same_target_siblings,
same_target_siblings)
if (!sdev->device_blocked &&
!blk_queue_empty(sdev->request_queue)) {
__blk_run_queue(sdev->request_queue);
break;
}
}
/*
* Function: scsi_queue_next_request()
*
......@@ -390,29 +433,11 @@ void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd)
}
sdev = q->queuedata;
shost = sdev->host;
/*
* If this is a single-lun device, and we are currently finished
* with this device, then see if we need to get another device
* started. FIXME(eric) - if this function gets too cluttered
* with special case code, then spin off separate versions and
* use function pointers to pick the right one.
*/
if (sdev->single_lun && blk_queue_empty(q) && sdev->device_busy ==0 &&
!shost->host_blocked && !shost->host_self_blocked &&
!((shost->can_queue > 0) && (shost->host_busy >=
shost->can_queue))) {
list_for_each_entry(sdev2, &sdev->same_target_siblings,
same_target_siblings) {
if (!sdev2->device_blocked &&
!blk_queue_empty(sdev2->request_queue)) {
__blk_run_queue(sdev2->request_queue);
break;
}
}
}
if (sdev->single_lun)
scsi_single_lun_run(sdev, q);
shost = sdev->host;
while (!list_empty(&shost->starved_list) &&
!shost->host_blocked && !shost->host_self_blocked &&
!((shost->can_queue > 0) &&
......@@ -917,22 +942,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
return BLKPREP_KILL;
}
/*
* The target associated with myself can only handle one active command at
* a time. Scan through all of the luns on the same target as myself,
* return 1 if any are active.
*/
static int check_all_luns(struct scsi_device *myself)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &myself->same_target_siblings,
same_target_siblings)
if (sdev->device_busy)
return 1;
return 0;
}
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct Scsi_Device_Template *sdt;
......@@ -1077,9 +1086,6 @@ static void scsi_request_fn(request_queue_t *q)
if (sdev->device_busy >= sdev->queue_depth)
break;
if (sdev->single_lun && check_all_luns(sdev))
break;
if (shost->host_busy == 0 && shost->host_blocked) {
/* unblock after host_blocked iterates to zero */
if (--shost->host_blocked == 0) {
......@@ -1120,6 +1126,9 @@ static void scsi_request_fn(request_queue_t *q)
break;
}
if (sdev->single_lun && scsi_single_lun_check(sdev))
break;
/*
* If we couldn't find a request that could be queued, then we
* can also quit.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment