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) ...@@ -322,6 +322,49 @@ void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
cmd->underflow = cmd->old_underflow; 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() * Function: scsi_queue_next_request()
* *
...@@ -390,29 +433,11 @@ void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd) ...@@ -390,29 +433,11 @@ void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd)
} }
sdev = q->queuedata; sdev = q->queuedata;
shost = sdev->host;
/* if (sdev->single_lun)
* If this is a single-lun device, and we are currently finished scsi_single_lun_run(sdev, q);
* 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;
}
}
}
shost = sdev->host;
while (!list_empty(&shost->starved_list) && while (!list_empty(&shost->starved_list) &&
!shost->host_blocked && !shost->host_self_blocked && !shost->host_blocked && !shost->host_self_blocked &&
!((shost->can_queue > 0) && !((shost->can_queue > 0) &&
...@@ -917,22 +942,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd) ...@@ -917,22 +942,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
return BLKPREP_KILL; 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) static int scsi_prep_fn(struct request_queue *q, struct request *req)
{ {
struct Scsi_Device_Template *sdt; struct Scsi_Device_Template *sdt;
...@@ -1077,9 +1086,6 @@ static void scsi_request_fn(request_queue_t *q) ...@@ -1077,9 +1086,6 @@ static void scsi_request_fn(request_queue_t *q)
if (sdev->device_busy >= sdev->queue_depth) if (sdev->device_busy >= sdev->queue_depth)
break; break;
if (sdev->single_lun && check_all_luns(sdev))
break;
if (shost->host_busy == 0 && shost->host_blocked) { if (shost->host_busy == 0 && shost->host_blocked) {
/* unblock after host_blocked iterates to zero */ /* unblock after host_blocked iterates to zero */
if (--shost->host_blocked == 0) { if (--shost->host_blocked == 0) {
...@@ -1120,6 +1126,9 @@ static void scsi_request_fn(request_queue_t *q) ...@@ -1120,6 +1126,9 @@ static void scsi_request_fn(request_queue_t *q)
break; break;
} }
if (sdev->single_lun && scsi_single_lun_check(sdev))
break;
/* /*
* If we couldn't find a request that could be queued, then we * If we couldn't find a request that could be queued, then we
* can also quit. * 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