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; |
