diff options
-rw-r--r-- | drivers/scsi/ipr.c | 59 | ||||
-rw-r--r-- | drivers/scsi/ipr.h | 2 |
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 | **/ | ||
4895 | static 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 | **/ | ||
4919 | static 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) | |||
5716 | static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) | 5762 | static 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; |