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.c162
1 files changed, 92 insertions, 70 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 8a525abda30..d29f8464b74 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -37,6 +37,7 @@
37 37
38#include "scsi_priv.h" 38#include "scsi_priv.h"
39#include "scsi_logging.h" 39#include "scsi_logging.h"
40#include "scsi_transport_api.h"
40 41
41#define SENSE_TIMEOUT (10*HZ) 42#define SENSE_TIMEOUT (10*HZ)
42 43
@@ -589,39 +590,23 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
589} 590}
590 591
591/** 592/**
592 * scsi_send_eh_cmnd - submit a scsi command as part of error recory 593 * scsi_eh_prep_cmnd - Save a scsi command info as part of error recory
593 * @scmd: SCSI command structure to hijack 594 * @scmd: SCSI command structure to hijack
594 * @cmnd: CDB to send 595 * @ses: structure to save restore information
596 * @cmnd: CDB to send. Can be NULL if no new cmnd is needed
595 * @cmnd_size: size in bytes of @cmnd 597 * @cmnd_size: size in bytes of @cmnd
596 * @timeout: timeout for this request 598 * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
597 * @copy_sense: request sense data if set to 1
598 *
599 * This function is used to send a scsi command down to a target device
600 * as part of the error recovery process. If @copy_sense is 0 the command
601 * sent must be one that does not transfer any data. If @copy_sense is 1
602 * the command must be REQUEST_SENSE and this functions copies out the
603 * sense buffer it got into @scmd->sense_buffer.
604 * 599 *
605 * Return value: 600 * This function is used to save a scsi command information before re-execution
606 * SUCCESS or FAILED or NEEDS_RETRY 601 * as part of the error recovery process. If @sense_bytes is 0 the command
602 * sent must be one that does not transfer any data. If @sense_bytes != 0
603 * @cmnd is ignored and this functions sets up a REQUEST_SENSE command
604 * and cmnd buffers to read @sense_bytes into @scmd->sense_buffer.
607 **/ 605 **/
608static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, 606void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
609 int cmnd_size, int timeout, int copy_sense) 607 unsigned char *cmnd, int cmnd_size, unsigned sense_bytes)
610{ 608{
611 struct scsi_device *sdev = scmd->device; 609 struct scsi_device *sdev = scmd->device;
612 struct Scsi_Host *shost = sdev->host;
613 int old_result = scmd->result;
614 DECLARE_COMPLETION_ONSTACK(done);
615 unsigned long timeleft;
616 unsigned long flags;
617 struct scatterlist sgl;
618 unsigned char old_cmnd[MAX_COMMAND_SIZE];
619 enum dma_data_direction old_data_direction;
620 unsigned short old_use_sg;
621 unsigned char old_cmd_len;
622 unsigned old_bufflen;
623 void *old_buffer;
624 int rtn;
625 610
626 /* 611 /*
627 * We need saved copies of a number of fields - this is because 612 * We need saved copies of a number of fields - this is because
@@ -630,35 +615,42 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
630 * we will need to restore these values prior to running the actual 615 * we will need to restore these values prior to running the actual
631 * command. 616 * command.
632 */ 617 */
633 old_buffer = scmd->request_buffer; 618 ses->cmd_len = scmd->cmd_len;
634 old_bufflen = scmd->request_bufflen; 619 memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd));
635 memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); 620 ses->data_direction = scmd->sc_data_direction;
636 old_data_direction = scmd->sc_data_direction; 621 ses->bufflen = scmd->request_bufflen;
637 old_cmd_len = scmd->cmd_len; 622 ses->buffer = scmd->request_buffer;
638 old_use_sg = scmd->use_sg; 623 ses->use_sg = scmd->use_sg;
639 624 ses->resid = scmd->resid;
640 memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); 625 ses->result = scmd->result;
641 memcpy(scmd->cmnd, cmnd, cmnd_size); 626
642 627 if (sense_bytes) {
643 if (copy_sense) { 628 scmd->request_bufflen = min_t(unsigned,
644 sg_init_one(&sgl, scmd->sense_buffer, 629 sizeof(scmd->sense_buffer), sense_bytes);
645 sizeof(scmd->sense_buffer)); 630 sg_init_one(&ses->sense_sgl, scmd->sense_buffer,
646 631 scmd->request_bufflen);
632 scmd->request_buffer = &ses->sense_sgl;
647 scmd->sc_data_direction = DMA_FROM_DEVICE; 633 scmd->sc_data_direction = DMA_FROM_DEVICE;
648 scmd->request_bufflen = sgl.length;
649 scmd->request_buffer = &sgl;
650 scmd->use_sg = 1; 634 scmd->use_sg = 1;
635 memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
636 scmd->cmnd[0] = REQUEST_SENSE;
637 scmd->cmnd[4] = scmd->request_bufflen;
638 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
651 } else { 639 } else {
652 scmd->request_buffer = NULL; 640 scmd->request_buffer = NULL;
653 scmd->request_bufflen = 0; 641 scmd->request_bufflen = 0;
654 scmd->sc_data_direction = DMA_NONE; 642 scmd->sc_data_direction = DMA_NONE;
655 scmd->use_sg = 0; 643 scmd->use_sg = 0;
644 if (cmnd) {
645 memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
646 memcpy(scmd->cmnd, cmnd, cmnd_size);
647 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
648 }
656 } 649 }
657 650
658 scmd->underflow = 0; 651 scmd->underflow = 0;
659 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
660 652
661 if (sdev->scsi_level <= SCSI_2) 653 if (sdev->scsi_level <= SCSI_2 && sdev->scsi_level != SCSI_UNKNOWN)
662 scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | 654 scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
663 (sdev->lun << 5 & 0xe0); 655 (sdev->lun << 5 & 0xe0);
664 656
@@ -667,7 +659,58 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
667 * untransferred sense data should be interpreted as being zero. 659 * untransferred sense data should be interpreted as being zero.
668 */ 660 */
669 memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); 661 memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
662}
663EXPORT_SYMBOL(scsi_eh_prep_cmnd);
664
665/**
666 * scsi_eh_restore_cmnd - Restore a scsi command info as part of error recory
667 * @scmd: SCSI command structure to restore
668 * @ses: saved information from a coresponding call to scsi_prep_eh_cmnd
669 *
670 * Undo any damage done by above scsi_prep_eh_cmnd().
671 **/
672void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
673{
674 /*
675 * Restore original data
676 */
677 scmd->cmd_len = ses->cmd_len;
678 memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd));
679 scmd->sc_data_direction = ses->data_direction;
680 scmd->request_bufflen = ses->bufflen;
681 scmd->request_buffer = ses->buffer;
682 scmd->use_sg = ses->use_sg;
683 scmd->resid = ses->resid;
684 scmd->result = ses->result;
685}
686EXPORT_SYMBOL(scsi_eh_restore_cmnd);
670 687
688/**
689 * scsi_send_eh_cmnd - submit a scsi command as part of error recory
690 * @scmd: SCSI command structure to hijack
691 * @cmnd: CDB to send
692 * @cmnd_size: size in bytes of @cmnd
693 * @timeout: timeout for this request
694 * @sense_bytes: size of sense data to copy or 0
695 *
696 * This function is used to send a scsi command down to a target device
697 * as part of the error recovery process. See also scsi_eh_prep_cmnd() above.
698 *
699 * Return value:
700 * SUCCESS or FAILED or NEEDS_RETRY
701 **/
702static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
703 int cmnd_size, int timeout, unsigned sense_bytes)
704{
705 struct scsi_device *sdev = scmd->device;
706 struct Scsi_Host *shost = sdev->host;
707 DECLARE_COMPLETION_ONSTACK(done);
708 unsigned long timeleft;
709 unsigned long flags;
710 struct scsi_eh_save ses;
711 int rtn;
712
713 scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes);
671 shost->eh_action = &done; 714 shost->eh_action = &done;
672 715
673 spin_lock_irqsave(shost->host_lock, flags); 716 spin_lock_irqsave(shost->host_lock, flags);
@@ -711,17 +754,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
711 rtn = FAILED; 754 rtn = FAILED;
712 } 755 }
713 756
714 757 scsi_eh_restore_cmnd(scmd, &ses);
715 /*
716 * Restore original data
717 */
718 scmd->request_buffer = old_buffer;
719 scmd->request_bufflen = old_bufflen;
720 memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd));
721 scmd->sc_data_direction = old_data_direction;
722 scmd->cmd_len = old_cmd_len;
723 scmd->use_sg = old_use_sg;
724 scmd->result = old_result;
725 return rtn; 758 return rtn;
726} 759}
727 760
@@ -736,10 +769,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
736 **/ 769 **/
737static int scsi_request_sense(struct scsi_cmnd *scmd) 770static int scsi_request_sense(struct scsi_cmnd *scmd)
738{ 771{
739 static unsigned char generic_sense[6] = 772 return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0);
740 {REQUEST_SENSE, 0, 0, 0, 252, 0};
741
742 return scsi_send_eh_cmnd(scmd, generic_sense, 6, SENSE_TIMEOUT, 1);
743} 773}
744 774
745/** 775/**
@@ -1136,9 +1166,8 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
1136 struct scsi_cmnd *scmd, *next; 1166 struct scsi_cmnd *scmd, *next;
1137 1167
1138 list_for_each_entry_safe(scmd, next, work_q, eh_entry) { 1168 list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
1139 sdev_printk(KERN_INFO, scmd->device, 1169 sdev_printk(KERN_INFO, scmd->device, "Device offlined - "
1140 "scsi: Device offlined - not" 1170 "not ready after error recovery\n");
1141 " ready after error recovery\n");
1142 scsi_device_set_state(scmd->device, SDEV_OFFLINE); 1171 scsi_device_set_state(scmd->device, SDEV_OFFLINE);
1143 if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) { 1172 if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) {
1144 /* 1173 /*
@@ -1671,7 +1700,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
1671 memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); 1700 memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
1672 1701
1673 scmd->scsi_done = scsi_reset_provider_done_command; 1702 scmd->scsi_done = scsi_reset_provider_done_command;
1674 scmd->done = NULL;
1675 scmd->request_buffer = NULL; 1703 scmd->request_buffer = NULL;
1676 scmd->request_bufflen = 0; 1704 scmd->request_bufflen = 0;
1677 1705
@@ -1681,12 +1709,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
1681 1709
1682 init_timer(&scmd->eh_timeout); 1710 init_timer(&scmd->eh_timeout);
1683 1711
1684 /*
1685 * Sometimes the command can get back into the timer chain,
1686 * so use the pid as an identifier.
1687 */
1688 scmd->pid = 0;
1689
1690 spin_lock_irqsave(shost->host_lock, flags); 1712 spin_lock_irqsave(shost->host_lock, flags);
1691 shost->tmf_in_progress = 1; 1713 shost->tmf_in_progress = 1;
1692 spin_unlock_irqrestore(shost->host_lock, flags); 1714 spin_unlock_irqrestore(shost->host_lock, flags);