diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/scsi_error.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1b0060b791e8..7ad53fa42766 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/gfp.h> | ||
19 | #include <linux/timer.h> | 20 | #include <linux/timer.h> |
20 | #include <linux/string.h> | 21 | #include <linux/string.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
@@ -301,7 +302,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
301 | if (scmd->device->allow_restart && | 302 | if (scmd->device->allow_restart && |
302 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) | 303 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) |
303 | return FAILED; | 304 | return FAILED; |
304 | return SUCCESS; | 305 | |
306 | if (blk_barrier_rq(scmd->request)) | ||
307 | /* | ||
308 | * barrier requests should always retry on UA | ||
309 | * otherwise block will get a spurious error | ||
310 | */ | ||
311 | return NEEDS_RETRY; | ||
312 | else | ||
313 | /* | ||
314 | * for normal (non barrier) commands, pass the | ||
315 | * UA upwards for a determination in the | ||
316 | * completion functions | ||
317 | */ | ||
318 | return SUCCESS; | ||
305 | 319 | ||
306 | /* these three are not supported */ | 320 | /* these three are not supported */ |
307 | case COPY_ABORTED: | 321 | case COPY_ABORTED: |
@@ -331,6 +345,64 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
331 | } | 345 | } |
332 | } | 346 | } |
333 | 347 | ||
348 | static void scsi_handle_queue_ramp_up(struct scsi_device *sdev) | ||
349 | { | ||
350 | struct scsi_host_template *sht = sdev->host->hostt; | ||
351 | struct scsi_device *tmp_sdev; | ||
352 | |||
353 | if (!sht->change_queue_depth || | ||
354 | sdev->queue_depth >= sdev->max_queue_depth) | ||
355 | return; | ||
356 | |||
357 | if (time_before(jiffies, | ||
358 | sdev->last_queue_ramp_up + sdev->queue_ramp_up_period)) | ||
359 | return; | ||
360 | |||
361 | if (time_before(jiffies, | ||
362 | sdev->last_queue_full_time + sdev->queue_ramp_up_period)) | ||
363 | return; | ||
364 | |||
365 | /* | ||
366 | * Walk all devices of a target and do | ||
367 | * ramp up on them. | ||
368 | */ | ||
369 | shost_for_each_device(tmp_sdev, sdev->host) { | ||
370 | if (tmp_sdev->channel != sdev->channel || | ||
371 | tmp_sdev->id != sdev->id || | ||
372 | tmp_sdev->queue_depth == sdev->max_queue_depth) | ||
373 | continue; | ||
374 | /* | ||
375 | * call back into LLD to increase queue_depth by one | ||
376 | * with ramp up reason code. | ||
377 | */ | ||
378 | sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1, | ||
379 | SCSI_QDEPTH_RAMP_UP); | ||
380 | sdev->last_queue_ramp_up = jiffies; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | static void scsi_handle_queue_full(struct scsi_device *sdev) | ||
385 | { | ||
386 | struct scsi_host_template *sht = sdev->host->hostt; | ||
387 | struct scsi_device *tmp_sdev; | ||
388 | |||
389 | if (!sht->change_queue_depth) | ||
390 | return; | ||
391 | |||
392 | shost_for_each_device(tmp_sdev, sdev->host) { | ||
393 | if (tmp_sdev->channel != sdev->channel || | ||
394 | tmp_sdev->id != sdev->id) | ||
395 | continue; | ||
396 | /* | ||
397 | * We do not know the number of commands that were at | ||
398 | * the device when we got the queue full so we start | ||
399 | * from the highest possible value and work our way down. | ||
400 | */ | ||
401 | sht->change_queue_depth(tmp_sdev, tmp_sdev->queue_depth - 1, | ||
402 | SCSI_QDEPTH_QFULL); | ||
403 | } | ||
404 | } | ||
405 | |||
334 | /** | 406 | /** |
335 | * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. | 407 | * scsi_eh_completed_normally - Disposition a eh cmd on return from LLD. |
336 | * @scmd: SCSI cmd to examine. | 408 | * @scmd: SCSI cmd to examine. |
@@ -371,6 +443,7 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) | |||
371 | */ | 443 | */ |
372 | switch (status_byte(scmd->result)) { | 444 | switch (status_byte(scmd->result)) { |
373 | case GOOD: | 445 | case GOOD: |
446 | scsi_handle_queue_ramp_up(scmd->device); | ||
374 | case COMMAND_TERMINATED: | 447 | case COMMAND_TERMINATED: |
375 | return SUCCESS; | 448 | return SUCCESS; |
376 | case CHECK_CONDITION: | 449 | case CHECK_CONDITION: |
@@ -387,8 +460,10 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) | |||
387 | * let issuer deal with this, it could be just fine | 460 | * let issuer deal with this, it could be just fine |
388 | */ | 461 | */ |
389 | return SUCCESS; | 462 | return SUCCESS; |
390 | case BUSY: | ||
391 | case QUEUE_FULL: | 463 | case QUEUE_FULL: |
464 | scsi_handle_queue_full(scmd->device); | ||
465 | /* fall through */ | ||
466 | case BUSY: | ||
392 | default: | 467 | default: |
393 | return FAILED; | 468 | return FAILED; |
394 | } | 469 | } |
@@ -1387,6 +1462,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1387 | */ | 1462 | */ |
1388 | switch (status_byte(scmd->result)) { | 1463 | switch (status_byte(scmd->result)) { |
1389 | case QUEUE_FULL: | 1464 | case QUEUE_FULL: |
1465 | scsi_handle_queue_full(scmd->device); | ||
1390 | /* | 1466 | /* |
1391 | * the case of trying to send too many commands to a | 1467 | * the case of trying to send too many commands to a |
1392 | * tagged queueing device. | 1468 | * tagged queueing device. |
@@ -1400,6 +1476,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
1400 | */ | 1476 | */ |
1401 | return ADD_TO_MLQUEUE; | 1477 | return ADD_TO_MLQUEUE; |
1402 | case GOOD: | 1478 | case GOOD: |
1479 | scsi_handle_queue_ramp_up(scmd->device); | ||
1403 | case COMMAND_TERMINATED: | 1480 | case COMMAND_TERMINATED: |
1404 | return SUCCESS; | 1481 | return SUCCESS; |
1405 | case TASK_ABORTED: | 1482 | case TASK_ABORTED: |