diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2009-10-15 20:46:44 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:42 -0500 |
commit | 42a6a91833f1e0f5ee5b5ef98e9f00167b615f46 (patch) | |
tree | 6173edb1fd2e4579d3223c7e3be1d0cc8430457c | |
parent | e881a172dac4d9ea3b2a1540041d872963c269bd (diff) |
[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>
-rw-r--r-- | drivers/scsi/scsi_error.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1b0060b791e8..7b1e20fee906 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -331,6 +331,28 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | static void scsi_handle_queue_full(struct scsi_device *sdev) | ||
335 | { | ||
336 | struct scsi_host_template *sht = sdev->host->hostt; | ||
337 | struct scsi_device *tmp_sdev; | ||
338 | |||
339 | if (!sht->change_queue_depth) | ||
340 | return; | ||
341 | |||
342 | shost_for_each_device(tmp_sdev, sdev->host) { | ||
343 | if (tmp_sdev->channel != sdev->channel || | ||
344 | tmp_sdev->id != sdev->id) | ||
345 | continue; | ||
346 | /* | ||
347 | * We do not know the number of commands that were at | ||
348 | * the device when we got the queue full so we start | ||
349 | * from the highest possible value and work our way down. | ||
350 | */ | ||
351 | sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1, | ||
352 | SCSI_QDEPTH_QFULL); | ||
353 | } | ||
354 | } | ||
355 | |||
334 | /** | 356 | /** |
335 | * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. | 357 | * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. |
336 | * @scmd: SCSI cmd to examine. | 358 | * @scmd: SCSI cmd to examine. |
@@ -387,8 +409,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) | |||
387 | * let issuer deal with this, it could be just fine | 409 | * let issuer deal with this, it could be just fine |
388 | */ | 410 | */ |
389 | return SUCCESS; | 411 | return SUCCESS; |
390 | case BUSY: | ||
391 | case QUEUE_FULL: | 412 | case QUEUE_FULL: |
413 | scsi_handle_queue_full(scmd->device); | ||
414 | /* fall through */ | ||
415 | case BUSY: | ||
392 | default: | 416 | default: |
393 | return FAILED; | 417 | return FAILED; |
394 | } | 418 | } |
@@ -1387,6 +1411,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1387 | */ | 1411 | */ |
1388 | switch (status_byte(scmd->result)) { | 1412 | switch (status_byte(scmd->result)) { |
1389 | case QUEUE_FULL: | 1413 | case QUEUE_FULL: |
1414 | scsi_handle_queue_full(scmd->device); | ||
1390 | /* | 1415 | /* |
1391 | * the case of trying to send too many commands to a | 1416 | * the case of trying to send too many commands to a |
1392 | * tagged queueing device. | 1417 | * tagged queueing device. |