aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_mbx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c158
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(&reg->isp82.hint, HINT_MBX_INT_PENDING); 164 WRT_REG_DWORD(&reg->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(&reg->isp82.hint, HINT_MBX_INT_PENDING); 190 WRT_REG_DWORD(&reg->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
344premature_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
3952int 3986int
3987qla81xx_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
4021int
4022qla81xx_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
4052int
3953qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority, 4053qla24xx_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;