aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 1b0060b791e8..08ed506e6059 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -331,6 +331,64 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
331 } 331 }
332} 332}
333 333
334static void scsi_handle_queue_ramp_up(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 sdev->queue_depth >= sdev->max_queue_depth)
341 return;
342
343 if (time_before(jiffies,
344 sdev->last_queue_ramp_up + sdev->queue_ramp_up_period))
345 return;
346
347 if (time_before(jiffies,
348 sdev->last_queue_full_time + sdev->queue_ramp_up_period))
349 return;
350
351 /*
352 * Walk all devices of a target and do
353 * ramp up on them.
354 */
355 shost_for_each_device(tmp_sdev, sdev->host) {
356 if (tmp_sdev->channel != sdev->channel ||
357 tmp_sdev->id != sdev->id ||
358 tmp_sdev->queue_depth == sdev->max_queue_depth)
359 continue;
360 /*
361 * call back into LLD to increase queue_depth by one
362 * with ramp up reason code.
363 */
364 sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1,
365 SCSI_QDEPTH_RAMP_UP);
366 sdev->last_queue_ramp_up = jiffies;
367 }
368}
369
370static void scsi_handle_queue_full(struct scsi_device *sdev)
371{
372 struct scsi_host_template *sht = sdev->host->hostt;
373 struct scsi_device *tmp_sdev;
374
375 if (!sht->change_queue_depth)
376 return;
377
378 shost_for_each_device(tmp_sdev, sdev->host) {
379 if (tmp_sdev->channel != sdev->channel ||
380 tmp_sdev->id != sdev->id)
381 continue;
382 /*
383 * We do not know the number of commands that were at
384 * the device when we got the queue full so we start
385 * from the highest possible value and work our way down.
386 */
387 sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1,
388 SCSI_QDEPTH_QFULL);
389 }
390}
391
334/** 392/**
335 * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. 393 * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD.
336 * @scmd: SCSI cmd to examine. 394 * @scmd: SCSI cmd to examine.
@@ -371,6 +429,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
371 */ 429 */
372 switch (status_byte(scmd->result)) { 430 switch (status_byte(scmd->result)) {
373 case GOOD: 431 case GOOD:
432 scsi_handle_queue_ramp_up(scmd->device);
374 case COMMAND_TERMINATED: 433 case COMMAND_TERMINATED:
375 return SUCCESS; 434 return SUCCESS;
376 case CHECK_CONDITION: 435 case CHECK_CONDITION:
@@ -387,8 +446,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
387 * let issuer deal with this, it could be just fine 446 * let issuer deal with this, it could be just fine
388 */ 447 */
389 return SUCCESS; 448 return SUCCESS;
390 case BUSY:
391 case QUEUE_FULL: 449 case QUEUE_FULL:
450 scsi_handle_queue_full(scmd->device);
451 /* fall through */
452 case BUSY:
392 default: 453 default:
393 return FAILED; 454 return FAILED;
394 } 455 }
@@ -1387,6 +1448,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1387 */ 1448 */
1388 switch (status_byte(scmd->result)) { 1449 switch (status_byte(scmd->result)) {
1389 case QUEUE_FULL: 1450 case QUEUE_FULL:
1451 scsi_handle_queue_full(scmd->device);
1390 /* 1452 /*
1391 * the case of trying to send too many commands to a 1453 * the case of trying to send too many commands to a
1392 * tagged queueing device. 1454 * tagged queueing device.
@@ -1400,6 +1462,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
1400 */ 1462 */
1401 return ADD_TO_MLQUEUE; 1463 return ADD_TO_MLQUEUE;
1402 case GOOD: 1464 case GOOD:
1465 scsi_handle_queue_ramp_up(scmd->device);
1403 case COMMAND_TERMINATED: 1466 case COMMAND_TERMINATED:
1404 return SUCCESS; 1467 return SUCCESS;
1405 case TASK_ABORTED: 1468 case TASK_ABORTED: