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.c256
1 files changed, 135 insertions, 121 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 2ecb6ff42444..b8edcf5b5451 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -359,6 +359,11 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
359 return SUCCESS; 359 return SUCCESS;
360 360
361 case MEDIUM_ERROR: 361 case MEDIUM_ERROR:
362 if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */
363 sshdr.asc == 0x13 || /* AMNF DATA FIELD */
364 sshdr.asc == 0x14) { /* RECORD NOT FOUND */
365 return SUCCESS;
366 }
362 return NEEDS_RETRY; 367 return NEEDS_RETRY;
363 368
364 case HARDWARE_ERROR: 369 case HARDWARE_ERROR:
@@ -453,6 +458,128 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
453} 458}
454 459
455/** 460/**
461 * scsi_try_host_reset - ask host adapter to reset itself
462 * @scmd: SCSI cmd to send hsot reset.
463 **/
464static int scsi_try_host_reset(struct scsi_cmnd *scmd)
465{
466 unsigned long flags;
467 int rtn;
468
469 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
470 __FUNCTION__));
471
472 if (!scmd->device->host->hostt->eh_host_reset_handler)
473 return FAILED;
474
475 rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
476
477 if (rtn == SUCCESS) {
478 if (!scmd->device->host->hostt->skip_settle_delay)
479 ssleep(HOST_RESET_SETTLE_TIME);
480 spin_lock_irqsave(scmd->device->host->host_lock, flags);
481 scsi_report_bus_reset(scmd->device->host,
482 scmd_channel(scmd));
483 spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
484 }
485
486 return rtn;
487}
488
489/**
490 * scsi_try_bus_reset - ask host to perform a bus reset
491 * @scmd: SCSI cmd to send bus reset.
492 **/
493static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
494{
495 unsigned long flags;
496 int rtn;
497
498 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
499 __FUNCTION__));
500
501 if (!scmd->device->host->hostt->eh_bus_reset_handler)
502 return FAILED;
503
504 rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
505
506 if (rtn == SUCCESS) {
507 if (!scmd->device->host->hostt->skip_settle_delay)
508 ssleep(BUS_RESET_SETTLE_TIME);
509 spin_lock_irqsave(scmd->device->host->host_lock, flags);
510 scsi_report_bus_reset(scmd->device->host,
511 scmd_channel(scmd));
512 spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
513 }
514
515 return rtn;
516}
517
518/**
519 * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
520 * @scmd: SCSI cmd used to send BDR
521 *
522 * Notes:
523 * There is no timeout for this operation. if this operation is
524 * unreliable for a given host, then the host itself needs to put a
525 * timer on it, and set the host back to a consistent state prior to
526 * returning.
527 **/
528static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
529{
530 int rtn;
531
532 if (!scmd->device->host->hostt->eh_device_reset_handler)
533 return FAILED;
534
535 rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
536 if (rtn == SUCCESS) {
537 scmd->device->was_reset = 1;
538 scmd->device->expecting_cc_ua = 1;
539 }
540
541 return rtn;
542}
543
544static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
545{
546 if (!scmd->device->host->hostt->eh_abort_handler)
547 return FAILED;
548
549 return scmd->device->host->hostt->eh_abort_handler(scmd);
550}
551
552/**
553 * scsi_try_to_abort_cmd - Ask host to abort a running command.
554 * @scmd: SCSI cmd to abort from Lower Level.
555 *
556 * Notes:
557 * This function will not return until the user's completion function
558 * has been called. there is no timeout on this operation. if the
559 * author of the low-level driver wishes this operation to be timed,
560 * they can provide this facility themselves. helper functions in
561 * scsi_error.c can be supplied to make this easier to do.
562 **/
563static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
564{
565 /*
566 * scsi_done was called just after the command timed out and before
567 * we had a chance to process it. (db)
568 */
569 if (scmd->serial_number == 0)
570 return SUCCESS;
571 return __scsi_try_to_abort_cmd(scmd);
572}
573
574static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
575{
576 if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
577 if (scsi_try_bus_device_reset(scmd) != SUCCESS)
578 if (scsi_try_bus_reset(scmd) != SUCCESS)
579 scsi_try_host_reset(scmd);
580}
581
582/**
456 * scsi_send_eh_cmnd - submit a scsi command as part of error recory 583 * scsi_send_eh_cmnd - submit a scsi command as part of error recory
457 * @scmd: SCSI command structure to hijack 584 * @scmd: SCSI command structure to hijack
458 * @cmnd: CDB to send 585 * @cmnd: CDB to send
@@ -579,13 +706,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
579 break; 706 break;
580 } 707 }
581 } else { 708 } else {
582 /* 709 scsi_abort_eh_cmnd(scmd);
583 * FIXME(eric) - we are not tracking whether we could
584 * abort a timed out command or not. not sure how
585 * we should treat them differently anyways.
586 */
587 if (shost->hostt->eh_abort_handler)
588 shost->hostt->eh_abort_handler(scmd);
589 rtn = FAILED; 710 rtn = FAILED;
590 } 711 }
591 712
@@ -672,8 +793,8 @@ EXPORT_SYMBOL(scsi_eh_finish_cmd);
672 * XXX: Long term this code should go away, but that needs an audit of 793 * XXX: Long term this code should go away, but that needs an audit of
673 * all LLDDs first. 794 * all LLDDs first.
674 **/ 795 **/
675static int scsi_eh_get_sense(struct list_head *work_q, 796int scsi_eh_get_sense(struct list_head *work_q,
676 struct list_head *done_q) 797 struct list_head *done_q)
677{ 798{
678 struct scsi_cmnd *scmd, *next; 799 struct scsi_cmnd *scmd, *next;
679 int rtn; 800 int rtn;
@@ -715,31 +836,7 @@ static int scsi_eh_get_sense(struct list_head *work_q,
715 836
716 return list_empty(work_q); 837 return list_empty(work_q);
717} 838}
718 839EXPORT_SYMBOL_GPL(scsi_eh_get_sense);
719/**
720 * scsi_try_to_abort_cmd - Ask host to abort a running command.
721 * @scmd: SCSI cmd to abort from Lower Level.
722 *
723 * Notes:
724 * This function will not return until the user's completion function
725 * has been called. there is no timeout on this operation. if the
726 * author of the low-level driver wishes this operation to be timed,
727 * they can provide this facility themselves. helper functions in
728 * scsi_error.c can be supplied to make this easier to do.
729 **/
730static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
731{
732 if (!scmd->device->host->hostt->eh_abort_handler)
733 return FAILED;
734
735 /*
736 * scsi_done was called just after the command timed out and before
737 * we had a chance to process it. (db)
738 */
739 if (scmd->serial_number == 0)
740 return SUCCESS;
741 return scmd->device->host->hostt->eh_abort_handler(scmd);
742}
743 840
744/** 841/**
745 * scsi_eh_tur - Send TUR to device. 842 * scsi_eh_tur - Send TUR to device.
@@ -815,32 +912,6 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
815} 912}
816 913
817/** 914/**
818 * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
819 * @scmd: SCSI cmd used to send BDR
820 *
821 * Notes:
822 * There is no timeout for this operation. if this operation is
823 * unreliable for a given host, then the host itself needs to put a
824 * timer on it, and set the host back to a consistent state prior to
825 * returning.
826 **/
827static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
828{
829 int rtn;
830
831 if (!scmd->device->host->hostt->eh_device_reset_handler)
832 return FAILED;
833
834 rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
835 if (rtn == SUCCESS) {
836 scmd->device->was_reset = 1;
837 scmd->device->expecting_cc_ua = 1;
838 }
839
840 return rtn;
841}
842
843/**
844 * scsi_eh_try_stu - Send START_UNIT to device. 915 * scsi_eh_try_stu - Send START_UNIT to device.
845 * @scmd: Scsi cmd to send START_UNIT 916 * @scmd: Scsi cmd to send START_UNIT
846 * 917 *
@@ -971,64 +1042,6 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
971} 1042}
972 1043
973/** 1044/**
974 * scsi_try_bus_reset - ask host to perform a bus reset
975 * @scmd: SCSI cmd to send bus reset.
976 **/
977static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
978{
979 unsigned long flags;
980 int rtn;
981
982 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
983 __FUNCTION__));
984
985 if (!scmd->device->host->hostt->eh_bus_reset_handler)
986 return FAILED;
987
988 rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
989
990 if (rtn == SUCCESS) {
991 if (!scmd->device->host->hostt->skip_settle_delay)
992 ssleep(BUS_RESET_SETTLE_TIME);
993 spin_lock_irqsave(scmd->device->host->host_lock, flags);
994 scsi_report_bus_reset(scmd->device->host,
995 scmd_channel(scmd));
996 spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
997 }
998
999 return rtn;
1000}
1001
1002/**
1003 * scsi_try_host_reset - ask host adapter to reset itself
1004 * @scmd: SCSI cmd to send hsot reset.
1005 **/
1006static int scsi_try_host_reset(struct scsi_cmnd *scmd)
1007{
1008 unsigned long flags;
1009 int rtn;
1010
1011 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
1012 __FUNCTION__));
1013
1014 if (!scmd->device->host->hostt->eh_host_reset_handler)
1015 return FAILED;
1016
1017 rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
1018
1019 if (rtn == SUCCESS) {
1020 if (!scmd->device->host->hostt->skip_settle_delay)
1021 ssleep(HOST_RESET_SETTLE_TIME);
1022 spin_lock_irqsave(scmd->device->host->host_lock, flags);
1023 scsi_report_bus_reset(scmd->device->host,
1024 scmd_channel(scmd));
1025 spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
1026 }
1027
1028 return rtn;
1029}
1030
1031/**
1032 * scsi_eh_bus_reset - send a bus reset 1045 * scsi_eh_bus_reset - send a bus reset
1033 * @shost: scsi host being recovered. 1046 * @shost: scsi host being recovered.
1034 * @eh_done_q: list_head for processed commands. 1047 * @eh_done_q: list_head for processed commands.
@@ -1411,9 +1424,9 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
1411 * @eh_done_q: list_head for processed commands. 1424 * @eh_done_q: list_head for processed commands.
1412 * 1425 *
1413 **/ 1426 **/
1414static void scsi_eh_ready_devs(struct Scsi_Host *shost, 1427void scsi_eh_ready_devs(struct Scsi_Host *shost,
1415 struct list_head *work_q, 1428 struct list_head *work_q,
1416 struct list_head *done_q) 1429 struct list_head *done_q)
1417{ 1430{
1418 if (!scsi_eh_stu(shost, work_q, done_q)) 1431 if (!scsi_eh_stu(shost, work_q, done_q))
1419 if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) 1432 if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
@@ -1421,6 +1434,7 @@ static void scsi_eh_ready_devs(struct Scsi_Host *shost,
1421 if (!scsi_eh_host_reset(work_q, done_q)) 1434 if (!scsi_eh_host_reset(work_q, done_q))
1422 scsi_eh_offline_sdevs(work_q, done_q); 1435 scsi_eh_offline_sdevs(work_q, done_q);
1423} 1436}
1437EXPORT_SYMBOL_GPL(scsi_eh_ready_devs);
1424 1438
1425/** 1439/**
1426 * scsi_eh_flush_done_q - finish processed commands or retry them. 1440 * scsi_eh_flush_done_q - finish processed commands or retry them.