diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 158 |
1 files changed, 129 insertions, 29 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index f3650d0434ca..6009b0c69488 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2008 QLogic Corporation | 3 | * Copyright (c) 2003-2010 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -37,7 +37,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
37 | device_reg_t __iomem *reg; | 37 | device_reg_t __iomem *reg; |
38 | uint8_t abort_active; | 38 | uint8_t abort_active; |
39 | uint8_t io_lock_on; | 39 | uint8_t io_lock_on; |
40 | uint16_t command; | 40 | uint16_t command = 0; |
41 | uint16_t *iptr; | 41 | uint16_t *iptr; |
42 | uint16_t __iomem *optr; | 42 | uint16_t __iomem *optr; |
43 | uint32_t cnt; | 43 | uint32_t cnt; |
@@ -83,6 +83,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
83 | return QLA_FUNCTION_TIMEOUT; | 83 | return QLA_FUNCTION_TIMEOUT; |
84 | } | 84 | } |
85 | 85 | ||
86 | if (IS_QLA82XX(ha) && ha->flags.fw_hung) { | ||
87 | /* Setting Link-Down error */ | ||
88 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; | ||
89 | rval = QLA_FUNCTION_FAILED; | ||
90 | goto premature_exit; | ||
91 | } | ||
92 | |||
86 | ha->flags.mbox_busy = 1; | 93 | ha->flags.mbox_busy = 1; |
87 | /* Save mailbox command for debug */ | 94 | /* Save mailbox command for debug */ |
88 | ha->mcp = mcp; | 95 | ha->mcp = mcp; |
@@ -151,7 +158,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
151 | DEBUG2_3_11(printk(KERN_INFO | 158 | DEBUG2_3_11(printk(KERN_INFO |
152 | "%s(%ld): Pending Mailbox timeout. " | 159 | "%s(%ld): Pending Mailbox timeout. " |
153 | "Exiting.\n", __func__, base_vha->host_no)); | 160 | "Exiting.\n", __func__, base_vha->host_no)); |
154 | return QLA_FUNCTION_TIMEOUT; | 161 | rval = QLA_FUNCTION_TIMEOUT; |
162 | goto premature_exit; | ||
155 | } | 163 | } |
156 | WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); | 164 | WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); |
157 | } else if (IS_FWI2_CAPABLE(ha)) | 165 | } else if (IS_FWI2_CAPABLE(ha)) |
@@ -176,7 +184,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
176 | DEBUG2_3_11(printk(KERN_INFO | 184 | DEBUG2_3_11(printk(KERN_INFO |
177 | "%s(%ld): Pending Mailbox timeout. " | 185 | "%s(%ld): Pending Mailbox timeout. " |
178 | "Exiting.\n", __func__, base_vha->host_no)); | 186 | "Exiting.\n", __func__, base_vha->host_no)); |
179 | return QLA_FUNCTION_TIMEOUT; | 187 | rval = QLA_FUNCTION_TIMEOUT; |
188 | goto premature_exit; | ||
180 | } | 189 | } |
181 | WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); | 190 | WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); |
182 | } else if (IS_FWI2_CAPABLE(ha)) | 191 | } else if (IS_FWI2_CAPABLE(ha)) |
@@ -214,6 +223,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
214 | ha->flags.mbox_int = 0; | 223 | ha->flags.mbox_int = 0; |
215 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 224 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
216 | 225 | ||
226 | if (IS_QLA82XX(ha) && ha->flags.fw_hung) { | ||
227 | ha->flags.mbox_busy = 0; | ||
228 | /* Setting Link-Down error */ | ||
229 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; | ||
230 | ha->mcp = NULL; | ||
231 | rval = QLA_FUNCTION_FAILED; | ||
232 | goto premature_exit; | ||
233 | } | ||
234 | |||
217 | if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) | 235 | if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) |
218 | rval = QLA_FUNCTION_FAILED; | 236 | rval = QLA_FUNCTION_FAILED; |
219 | 237 | ||
@@ -279,35 +297,51 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
279 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " | 297 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " |
280 | "isp_abort_needed.\n", __func__, | 298 | "isp_abort_needed.\n", __func__, |
281 | base_vha->host_no)); | 299 | base_vha->host_no)); |
282 | qla_printk(KERN_WARNING, ha, | 300 | |
283 | "Mailbox command timeout occurred. Scheduling ISP " | 301 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && |
284 | "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); | 302 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
285 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 303 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { |
286 | qla2xxx_wake_dpc(vha); | 304 | |
305 | qla_printk(KERN_WARNING, ha, | ||
306 | "Mailbox command timeout occured. " | ||
307 | "Scheduling ISP " "abort. eeh_busy: 0x%x\n", | ||
308 | ha->flags.eeh_busy); | ||
309 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
310 | qla2xxx_wake_dpc(vha); | ||
311 | } | ||
287 | } else if (!abort_active) { | 312 | } else if (!abort_active) { |
288 | /* call abort directly since we are in the DPC thread */ | 313 | /* call abort directly since we are in the DPC thread */ |
289 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", | 314 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", |
290 | __func__, base_vha->host_no)); | 315 | __func__, base_vha->host_no)); |
291 | DEBUG2_3_11(printk("%s(%ld): timeout calling " | 316 | DEBUG2_3_11(printk("%s(%ld): timeout calling " |
292 | "abort_isp\n", __func__, base_vha->host_no)); | 317 | "abort_isp\n", __func__, base_vha->host_no)); |
293 | qla_printk(KERN_WARNING, ha, | 318 | |
294 | "Mailbox command timeout occurred. Issuing ISP " | 319 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && |
295 | "abort.\n"); | 320 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
296 | 321 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { | |
297 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 322 | |
298 | clear_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 323 | qla_printk(KERN_WARNING, ha, |
299 | if (ha->isp_ops->abort_isp(base_vha)) { | 324 | "Mailbox command timeout occured. " |
300 | /* Failed. retry later. */ | 325 | "Issuing ISP abort.\n"); |
301 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 326 | |
327 | set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); | ||
328 | clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
329 | if (ha->isp_ops->abort_isp(vha)) { | ||
330 | /* Failed. retry later. */ | ||
331 | set_bit(ISP_ABORT_NEEDED, | ||
332 | &vha->dpc_flags); | ||
333 | } | ||
334 | clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); | ||
335 | DEBUG(printk("%s(%ld): finished abort_isp\n", | ||
336 | __func__, vha->host_no)); | ||
337 | DEBUG2_3_11(printk( | ||
338 | "%s(%ld): finished abort_isp\n", | ||
339 | __func__, vha->host_no)); | ||
302 | } | 340 | } |
303 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | ||
304 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, | ||
305 | base_vha->host_no)); | ||
306 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", | ||
307 | __func__, base_vha->host_no)); | ||
308 | } | 341 | } |
309 | } | 342 | } |
310 | 343 | ||
344 | premature_exit: | ||
311 | /* Allow next mbx cmd to come in. */ | 345 | /* Allow next mbx cmd to come in. */ |
312 | complete(&ha->mbx_cmd_comp); | 346 | complete(&ha->mbx_cmd_comp); |
313 | 347 | ||
@@ -866,8 +900,8 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag) | |||
866 | 900 | ||
867 | l = l; | 901 | l = l; |
868 | vha = fcport->vha; | 902 | vha = fcport->vha; |
869 | req = vha->hw->req_q_map[tag]; | 903 | req = vha->hw->req_q_map[0]; |
870 | rsp = vha->hw->rsp_q_map[tag]; | 904 | rsp = req->rsp; |
871 | mcp->mb[0] = MBC_ABORT_TARGET; | 905 | mcp->mb[0] = MBC_ABORT_TARGET; |
872 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; | 906 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; |
873 | if (HAS_EXTENDED_IDS(vha->hw)) { | 907 | if (HAS_EXTENDED_IDS(vha->hw)) { |
@@ -915,8 +949,8 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag) | |||
915 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no)); | 949 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->vha->host_no)); |
916 | 950 | ||
917 | vha = fcport->vha; | 951 | vha = fcport->vha; |
918 | req = vha->hw->req_q_map[tag]; | 952 | req = vha->hw->req_q_map[0]; |
919 | rsp = vha->hw->rsp_q_map[tag]; | 953 | rsp = req->rsp; |
920 | mcp->mb[0] = MBC_LUN_RESET; | 954 | mcp->mb[0] = MBC_LUN_RESET; |
921 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | 955 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; |
922 | if (HAS_EXTENDED_IDS(vha->hw)) | 956 | if (HAS_EXTENDED_IDS(vha->hw)) |
@@ -3950,6 +3984,72 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha) | |||
3950 | } | 3984 | } |
3951 | 3985 | ||
3952 | int | 3986 | int |
3987 | qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb) | ||
3988 | { | ||
3989 | int rval; | ||
3990 | mbx_cmd_t mc; | ||
3991 | mbx_cmd_t *mcp = &mc; | ||
3992 | struct qla_hw_data *ha = vha->hw; | ||
3993 | |||
3994 | DEBUG11(printk(KERN_INFO | ||
3995 | "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3996 | |||
3997 | if (!IS_QLA81XX(ha)) | ||
3998 | return QLA_FUNCTION_FAILED; | ||
3999 | mcp->mb[0] = MBC_GET_PORT_CONFIG; | ||
4000 | mcp->out_mb = MBX_0; | ||
4001 | mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
4002 | mcp->tov = MBX_TOV_SECONDS; | ||
4003 | mcp->flags = 0; | ||
4004 | |||
4005 | rval = qla2x00_mailbox_command(vha, mcp); | ||
4006 | |||
4007 | if (rval != QLA_SUCCESS) { | ||
4008 | DEBUG2_3_11(printk(KERN_WARNING | ||
4009 | "%s(%ld): failed=%x (%x).\n", __func__, | ||
4010 | vha->host_no, rval, mcp->mb[0])); | ||
4011 | } else { | ||
4012 | /* Copy all bits to preserve original value */ | ||
4013 | memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4); | ||
4014 | |||
4015 | DEBUG11(printk(KERN_INFO | ||
4016 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
4017 | } | ||
4018 | return rval; | ||
4019 | } | ||
4020 | |||
4021 | int | ||
4022 | qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb) | ||
4023 | { | ||
4024 | int rval; | ||
4025 | mbx_cmd_t mc; | ||
4026 | mbx_cmd_t *mcp = &mc; | ||
4027 | |||
4028 | DEBUG11(printk(KERN_INFO | ||
4029 | "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
4030 | |||
4031 | mcp->mb[0] = MBC_SET_PORT_CONFIG; | ||
4032 | /* Copy all bits to preserve original setting */ | ||
4033 | memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4); | ||
4034 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | ||
4035 | mcp->in_mb = MBX_0; | ||
4036 | mcp->tov = MBX_TOV_SECONDS; | ||
4037 | mcp->flags = 0; | ||
4038 | rval = qla2x00_mailbox_command(vha, mcp); | ||
4039 | |||
4040 | if (rval != QLA_SUCCESS) { | ||
4041 | DEBUG2_3_11(printk(KERN_WARNING | ||
4042 | "%s(%ld): failed=%x (%x).\n", __func__, | ||
4043 | vha->host_no, rval, mcp->mb[0])); | ||
4044 | } else | ||
4045 | DEBUG11(printk(KERN_INFO | ||
4046 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
4047 | |||
4048 | return rval; | ||
4049 | } | ||
4050 | |||
4051 | |||
4052 | int | ||
3953 | qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, | 4053 | qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, |
3954 | uint16_t *mb) | 4054 | uint16_t *mb) |
3955 | { | 4055 | { |
@@ -4011,7 +4111,7 @@ qla82xx_mbx_intr_enable(scsi_qla_host_t *vha) | |||
4011 | "%s(%ld): entered.\n", __func__, vha->host_no)); | 4111 | "%s(%ld): entered.\n", __func__, vha->host_no)); |
4012 | 4112 | ||
4013 | memset(mcp, 0, sizeof(mbx_cmd_t)); | 4113 | memset(mcp, 0, sizeof(mbx_cmd_t)); |
4014 | mcp->mb[0] = MBC_TOGGLE_INTR; | 4114 | mcp->mb[0] = MBC_TOGGLE_INTERRUPT; |
4015 | mcp->mb[1] = 1; | 4115 | mcp->mb[1] = 1; |
4016 | 4116 | ||
4017 | mcp->out_mb = MBX_1|MBX_0; | 4117 | mcp->out_mb = MBX_1|MBX_0; |
@@ -4047,7 +4147,7 @@ qla82xx_mbx_intr_disable(scsi_qla_host_t *vha) | |||
4047 | "%s(%ld): entered.\n", __func__, vha->host_no)); | 4147 | "%s(%ld): entered.\n", __func__, vha->host_no)); |
4048 | 4148 | ||
4049 | memset(mcp, 0, sizeof(mbx_cmd_t)); | 4149 | memset(mcp, 0, sizeof(mbx_cmd_t)); |
4050 | mcp->mb[0] = MBC_TOGGLE_INTR; | 4150 | mcp->mb[0] = MBC_TOGGLE_INTERRUPT; |
4051 | mcp->mb[1] = 0; | 4151 | mcp->mb[1] = 0; |
4052 | 4152 | ||
4053 | mcp->out_mb = MBX_1|MBX_0; | 4153 | mcp->out_mb = MBX_1|MBX_0; |