[SCSI] scsi error: have scsi-ml call change_queue_depth to handle QUEUE_FULL

This has scsi-ml call the change_queue_depth functions when
we get a QUEUE_FULL. It will only change the queue depth if
change_queue_depth is set because the LLD may have to
modify some internal resources, so I thought this would
be the safest route.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>

-v2
Limits change_queue_depth to only all luns of target by adding
channel check while iterating for all luns of Scsi_Host. This is
same as currently qla2xxx FC HBA does on QUEUE_FULL event.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
Mike Christie 2009-10-15 17:46:44 -07:00 committed by James Bottomley
parent e881a172da
commit 42a6a91833

View file

@ -331,6 +331,28 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
} }
} }
static void scsi_handle_queue_full(struct scsi_device *sdev)
{
struct scsi_host_template *sht = sdev->host->hostt;
struct scsi_device *tmp_sdev;
if (!sht->change_queue_depth)
return;
shost_for_each_device(tmp_sdev, sdev->host) {
if (tmp_sdev->channel != sdev->channel ||
tmp_sdev->id != sdev->id)
continue;
/*
* We do not know the number of commands that were at
* the device when we got the queue full so we start
* from the highest possible value and work our way down.
*/
sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1,
SCSI_QDEPTH_QFULL);
}
}
/** /**
* scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD.
* @scmd: SCSI cmd to examine. * @scmd: SCSI cmd to examine.
@ -387,8 +409,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
* let issuer deal with this, it could be just fine * let issuer deal with this, it could be just fine
*/ */
return SUCCESS; return SUCCESS;
case BUSY:
case QUEUE_FULL: case QUEUE_FULL:
scsi_handle_queue_full(scmd->device);
/* fall through */
case BUSY:
default: default:
return FAILED; return FAILED;
} }
@ -1387,6 +1411,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
*/ */
switch (status_byte(scmd->result)) { switch (status_byte(scmd->result)) {
case QUEUE_FULL: case QUEUE_FULL:
scsi_handle_queue_full(scmd->device);
/* /*
* the case of trying to send too many commands to a * the case of trying to send too many commands to a
* tagged queueing device. * tagged queueing device.