aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/ipr.c59
-rw-r--r--drivers/scsi/ipr.h2
2 files changed, 52 insertions, 9 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 8d364f232877..fa2cb3582cfa 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4884,6 +4884,51 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd,
4884} 4884}
4885 4885
4886/** 4886/**
4887 * ipr_reset_cmd_failed - Handle failure of IOA reset command
4888 * @ipr_cmd: ipr command struct
4889 *
4890 * This function handles the failure of an IOA bringup command.
4891 *
4892 * Return value:
4893 * IPR_RC_JOB_RETURN
4894 **/
4895static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd)
4896{
4897 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
4898 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
4899
4900 dev_err(&ioa_cfg->pdev->dev,
4901 "0x%02X failed with IOASC: 0x%08X\n",
4902 ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc);
4903
4904 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
4905 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
4906 return IPR_RC_JOB_RETURN;
4907}
4908
4909/**
4910 * ipr_reset_mode_sense_failed - Handle failure of IOAFP mode sense
4911 * @ipr_cmd: ipr command struct
4912 *
4913 * This function handles the failure of a Mode Sense to the IOAFP.
4914 * Some adapters do not handle all mode pages.
4915 *
4916 * Return value:
4917 * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN
4918 **/
4919static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd)
4920{
4921 u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
4922
4923 if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) {
4924 ipr_cmd->job_step = ipr_setup_write_cache;
4925 return IPR_RC_JOB_CONTINUE;
4926 }
4927
4928 return ipr_reset_cmd_failed(ipr_cmd);
4929}
4930
4931/**
4887 * ipr_ioafp_mode_sense_page28 - Issue Mode Sense Page 28 to IOA 4932 * ipr_ioafp_mode_sense_page28 - Issue Mode Sense Page 28 to IOA
4888 * @ipr_cmd: ipr command struct 4933 * @ipr_cmd: ipr command struct
4889 * 4934 *
@@ -4904,6 +4949,7 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd)
4904 sizeof(struct ipr_mode_pages)); 4949 sizeof(struct ipr_mode_pages));
4905 4950
4906 ipr_cmd->job_step = ipr_ioafp_mode_select_page28; 4951 ipr_cmd->job_step = ipr_ioafp_mode_select_page28;
4952 ipr_cmd->job_step_failed = ipr_reset_mode_sense_failed;
4907 4953
4908 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); 4954 ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT);
4909 4955
@@ -5716,7 +5762,6 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd)
5716static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) 5762static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd)
5717{ 5763{
5718 u32 rc, ioasc; 5764 u32 rc, ioasc;
5719 unsigned long scratch = ipr_cmd->u.scratch;
5720 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 5765 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
5721 5766
5722 do { 5767 do {
@@ -5732,17 +5777,13 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd)
5732 } 5777 }
5733 5778
5734 if (IPR_IOASC_SENSE_KEY(ioasc)) { 5779 if (IPR_IOASC_SENSE_KEY(ioasc)) {
5735 dev_err(&ioa_cfg->pdev->dev, 5780 rc = ipr_cmd->job_step_failed(ipr_cmd);
5736 "0x%02X failed with IOASC: 0x%08X\n", 5781 if (rc == IPR_RC_JOB_RETURN)
5737 ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc); 5782 return;
5738
5739 ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
5740 list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
5741 return;
5742 } 5783 }
5743 5784
5744 ipr_reinit_ipr_cmnd(ipr_cmd); 5785 ipr_reinit_ipr_cmnd(ipr_cmd);
5745 ipr_cmd->u.scratch = scratch; 5786 ipr_cmd->job_step_failed = ipr_reset_cmd_failed;
5746 rc = ipr_cmd->job_step(ipr_cmd); 5787 rc = ipr_cmd->job_step(ipr_cmd);
5747 } while(rc == IPR_RC_JOB_CONTINUE); 5788 } while(rc == IPR_RC_JOB_CONTINUE);
5748} 5789}
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 2f18284b6004..637b891eb50f 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -84,6 +84,7 @@
84#define IPR_IOASC_HW_DEV_BUS_STATUS 0x04448500 84#define IPR_IOASC_HW_DEV_BUS_STATUS 0x04448500
85#define IPR_IOASC_IOASC_MASK 0xFFFFFF00 85#define IPR_IOASC_IOASC_MASK 0xFFFFFF00
86#define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF 86#define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF
87#define IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT 0x05240000
87#define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000 88#define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000
88#define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100 89#define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100
89#define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000 90#define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000
@@ -1031,6 +1032,7 @@ struct ipr_cmnd {
1031 struct timer_list timer; 1032 struct timer_list timer;
1032 void (*done) (struct ipr_cmnd *); 1033 void (*done) (struct ipr_cmnd *);
1033 int (*job_step) (struct ipr_cmnd *); 1034 int (*job_step) (struct ipr_cmnd *);
1035 int (*job_step_failed) (struct ipr_cmnd *);
1034 u16 cmd_index; 1036 u16 cmd_index;
1035 u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; 1037 u8 sense_buffer[SCSI_SENSE_BUFFERSIZE];
1036 dma_addr_t sense_buffer_dma; 1038 dma_addr_t sense_buffer_dma;