aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorbrking@us.ibm.com <brking@us.ibm.com>2005-11-01 18:02:55 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2005-11-06 14:12:56 -0500
commitdfed823eabf545795f04c8b5164d46a73c5b58ea (patch)
tree3f96a873d33df5fa748edac96bf95c96f9785ac0 /drivers/scsi
parentd71a8b0cba62eada61edce86670f8d63a1bef0c8 (diff)
[SCSI] ipr: Better handle failure of adapter bringup commands
Some new ipr adapters do not support some of the initialization commands currently sent to it from the driver. Handle these commands failing and continue on with the adapter initialization. Signed-off-by: Brian King <brking@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-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;