diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 21 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 41 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 52 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 45 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 191 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 57 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 4 |
9 files changed, 301 insertions, 120 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ccfc8e78be21..6c51c0a35b9e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2402,13 +2402,13 @@ struct qla_hw_data { | |||
2402 | volatile struct { | 2402 | volatile struct { |
2403 | uint32_t mbox_int :1; | 2403 | uint32_t mbox_int :1; |
2404 | uint32_t mbox_busy :1; | 2404 | uint32_t mbox_busy :1; |
2405 | |||
2406 | uint32_t disable_risc_code_load :1; | 2405 | uint32_t disable_risc_code_load :1; |
2407 | uint32_t enable_64bit_addressing :1; | 2406 | uint32_t enable_64bit_addressing :1; |
2408 | uint32_t enable_lip_reset :1; | 2407 | uint32_t enable_lip_reset :1; |
2409 | uint32_t enable_target_reset :1; | 2408 | uint32_t enable_target_reset :1; |
2410 | uint32_t enable_lip_full_login :1; | 2409 | uint32_t enable_lip_full_login :1; |
2411 | uint32_t enable_led_scheme :1; | 2410 | uint32_t enable_led_scheme :1; |
2411 | |||
2412 | uint32_t msi_enabled :1; | 2412 | uint32_t msi_enabled :1; |
2413 | uint32_t msix_enabled :1; | 2413 | uint32_t msix_enabled :1; |
2414 | uint32_t disable_serdes :1; | 2414 | uint32_t disable_serdes :1; |
@@ -2417,6 +2417,7 @@ struct qla_hw_data { | |||
2417 | uint32_t pci_channel_io_perm_failure :1; | 2417 | uint32_t pci_channel_io_perm_failure :1; |
2418 | uint32_t fce_enabled :1; | 2418 | uint32_t fce_enabled :1; |
2419 | uint32_t fac_supported :1; | 2419 | uint32_t fac_supported :1; |
2420 | |||
2420 | uint32_t chip_reset_done :1; | 2421 | uint32_t chip_reset_done :1; |
2421 | uint32_t port0 :1; | 2422 | uint32_t port0 :1; |
2422 | uint32_t running_gold_fw :1; | 2423 | uint32_t running_gold_fw :1; |
@@ -2424,9 +2425,11 @@ struct qla_hw_data { | |||
2424 | uint32_t cpu_affinity_enabled :1; | 2425 | uint32_t cpu_affinity_enabled :1; |
2425 | uint32_t disable_msix_handshake :1; | 2426 | uint32_t disable_msix_handshake :1; |
2426 | uint32_t fcp_prio_enabled :1; | 2427 | uint32_t fcp_prio_enabled :1; |
2427 | uint32_t fw_hung :1; | 2428 | uint32_t isp82xx_fw_hung:1; |
2428 | uint32_t quiesce_owner:1; | 2429 | |
2430 | uint32_t quiesce_owner:1; | ||
2429 | uint32_t thermal_supported:1; | 2431 | uint32_t thermal_supported:1; |
2432 | uint32_t isp82xx_reset_hdlr_active:1; | ||
2430 | /* 26 bits */ | 2433 | /* 26 bits */ |
2431 | } flags; | 2434 | } flags; |
2432 | 2435 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 89e900adb679..d48326ee3f61 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -565,6 +565,7 @@ extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *); | |||
565 | extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *); | 565 | extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *); |
566 | extern void qla82xx_start_iocbs(srb_t *); | 566 | extern void qla82xx_start_iocbs(srb_t *); |
567 | extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *); | 567 | extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *); |
568 | extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *); | ||
568 | 569 | ||
569 | /* BSG related functions */ | 570 | /* BSG related functions */ |
570 | extern int qla24xx_bsg_request(struct fc_bsg_job *); | 571 | extern int qla24xx_bsg_request(struct fc_bsg_job *); |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 4c083928c2fb..74a91b6dfc68 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -121,8 +121,11 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | |||
121 | 121 | ||
122 | rval = QLA_FUNCTION_FAILED; | 122 | rval = QLA_FUNCTION_FAILED; |
123 | if (ms_pkt->entry_status != 0) { | 123 | if (ms_pkt->entry_status != 0) { |
124 | DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", | 124 | DEBUG2_3(printk(KERN_WARNING "scsi(%ld): %s failed, error status " |
125 | vha->host_no, routine, ms_pkt->entry_status)); | 125 | "(%x) on port_id: %02x%02x%02x.\n", |
126 | vha->host_no, routine, ms_pkt->entry_status, | ||
127 | vha->d_id.b.domain, vha->d_id.b.area, | ||
128 | vha->d_id.b.al_pa)); | ||
126 | } else { | 129 | } else { |
127 | if (IS_FWI2_CAPABLE(ha)) | 130 | if (IS_FWI2_CAPABLE(ha)) |
128 | comp_status = le16_to_cpu( | 131 | comp_status = le16_to_cpu( |
@@ -136,8 +139,10 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | |||
136 | if (ct_rsp->header.response != | 139 | if (ct_rsp->header.response != |
137 | __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { | 140 | __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { |
138 | DEBUG2_3(printk("scsi(%ld): %s failed, " | 141 | DEBUG2_3(printk("scsi(%ld): %s failed, " |
139 | "rejected request:\n", vha->host_no, | 142 | "rejected request on port_id: %02x%02x%02x\n", |
140 | routine)); | 143 | vha->host_no, routine, |
144 | vha->d_id.b.domain, vha->d_id.b.area, | ||
145 | vha->d_id.b.al_pa)); | ||
141 | DEBUG2_3(qla2x00_dump_buffer( | 146 | DEBUG2_3(qla2x00_dump_buffer( |
142 | (uint8_t *)&ct_rsp->header, | 147 | (uint8_t *)&ct_rsp->header, |
143 | sizeof(struct ct_rsp_hdr))); | 148 | sizeof(struct ct_rsp_hdr))); |
@@ -147,8 +152,10 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | |||
147 | break; | 152 | break; |
148 | default: | 153 | default: |
149 | DEBUG2_3(printk("scsi(%ld): %s failed, completion " | 154 | DEBUG2_3(printk("scsi(%ld): %s failed, completion " |
150 | "status (%x).\n", vha->host_no, routine, | 155 | "status (%x) on port_id: %02x%02x%02x.\n", |
151 | comp_status)); | 156 | vha->host_no, routine, comp_status, |
157 | vha->d_id.b.domain, vha->d_id.b.area, | ||
158 | vha->d_id.b.al_pa)); | ||
152 | break; | 159 | break; |
153 | } | 160 | } |
154 | } | 161 | } |
@@ -1965,7 +1972,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) | |||
1965 | "scsi(%ld): GFF_ID issue IOCB failed " | 1972 | "scsi(%ld): GFF_ID issue IOCB failed " |
1966 | "(%d).\n", vha->host_no, rval)); | 1973 | "(%d).\n", vha->host_no, rval)); |
1967 | } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, | 1974 | } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, |
1968 | "GPN_ID") != QLA_SUCCESS) { | 1975 | "GFF_ID") != QLA_SUCCESS) { |
1969 | DEBUG2_3(printk(KERN_INFO | 1976 | DEBUG2_3(printk(KERN_INFO |
1970 | "scsi(%ld): GFF_ID IOCB status had a " | 1977 | "scsi(%ld): GFF_ID IOCB status had a " |
1971 | "failure status code\n", vha->host_no)); | 1978 | "failure status code\n", vha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d9479c3fe5f8..8575808dbae0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1967,7 +1967,7 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) | |||
1967 | } else { | 1967 | } else { |
1968 | /* Mailbox cmd failed. Timeout on min_wait. */ | 1968 | /* Mailbox cmd failed. Timeout on min_wait. */ |
1969 | if (time_after_eq(jiffies, mtime) || | 1969 | if (time_after_eq(jiffies, mtime) || |
1970 | (IS_QLA82XX(ha) && ha->flags.fw_hung)) | 1970 | ha->flags.isp82xx_fw_hung) |
1971 | break; | 1971 | break; |
1972 | } | 1972 | } |
1973 | 1973 | ||
@@ -3945,8 +3945,13 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3945 | struct qla_hw_data *ha = vha->hw; | 3945 | struct qla_hw_data *ha = vha->hw; |
3946 | struct scsi_qla_host *vp; | 3946 | struct scsi_qla_host *vp; |
3947 | unsigned long flags; | 3947 | unsigned long flags; |
3948 | fc_port_t *fcport; | ||
3948 | 3949 | ||
3949 | vha->flags.online = 0; | 3950 | /* For ISP82XX, driver waits for completion of the commands. |
3951 | * online flag should be set. | ||
3952 | */ | ||
3953 | if (!IS_QLA82XX(ha)) | ||
3954 | vha->flags.online = 0; | ||
3950 | ha->flags.chip_reset_done = 0; | 3955 | ha->flags.chip_reset_done = 0; |
3951 | clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 3956 | clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
3952 | ha->qla_stats.total_isp_aborts++; | 3957 | ha->qla_stats.total_isp_aborts++; |
@@ -3954,7 +3959,10 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3954 | qla_printk(KERN_INFO, ha, | 3959 | qla_printk(KERN_INFO, ha, |
3955 | "Performing ISP error recovery - ha= %p.\n", ha); | 3960 | "Performing ISP error recovery - ha= %p.\n", ha); |
3956 | 3961 | ||
3957 | /* Chip reset does not apply to 82XX */ | 3962 | /* For ISP82XX, reset_chip is just disabling interrupts. |
3963 | * Driver waits for the completion of the commands. | ||
3964 | * the interrupts need to be enabled. | ||
3965 | */ | ||
3958 | if (!IS_QLA82XX(ha)) | 3966 | if (!IS_QLA82XX(ha)) |
3959 | ha->isp_ops->reset_chip(vha); | 3967 | ha->isp_ops->reset_chip(vha); |
3960 | 3968 | ||
@@ -3980,14 +3988,31 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3980 | LOOP_DOWN_TIME); | 3988 | LOOP_DOWN_TIME); |
3981 | } | 3989 | } |
3982 | 3990 | ||
3991 | /* Clear all async request states across all VPs. */ | ||
3992 | list_for_each_entry(fcport, &vha->vp_fcports, list) | ||
3993 | fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); | ||
3994 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3995 | list_for_each_entry(vp, &ha->vp_list, list) { | ||
3996 | atomic_inc(&vp->vref_count); | ||
3997 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3998 | |||
3999 | list_for_each_entry(fcport, &vp->vp_fcports, list) | ||
4000 | fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); | ||
4001 | |||
4002 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
4003 | atomic_dec(&vp->vref_count); | ||
4004 | } | ||
4005 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
4006 | |||
3983 | if (!ha->flags.eeh_busy) { | 4007 | if (!ha->flags.eeh_busy) { |
3984 | /* Make sure for ISP 82XX IO DMA is complete */ | 4008 | /* Make sure for ISP 82XX IO DMA is complete */ |
3985 | if (IS_QLA82XX(ha)) { | 4009 | if (IS_QLA82XX(ha)) { |
3986 | if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, | 4010 | qla82xx_chip_reset_cleanup(vha); |
3987 | WAIT_HOST) == QLA_SUCCESS) { | 4011 | |
3988 | DEBUG2(qla_printk(KERN_INFO, ha, | 4012 | /* Done waiting for pending commands. |
3989 | "Done wait for pending commands\n")); | 4013 | * Reset the online flag. |
3990 | } | 4014 | */ |
4015 | vha->flags.online = 0; | ||
3991 | } | 4016 | } |
3992 | 4017 | ||
3993 | /* Requeue all commands in outstanding command list. */ | 4018 | /* Requeue all commands in outstanding command list. */ |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 4c1ba6263eb3..d78d5896fc33 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -328,6 +328,7 @@ qla2x00_start_scsi(srb_t *sp) | |||
328 | struct qla_hw_data *ha; | 328 | struct qla_hw_data *ha; |
329 | struct req_que *req; | 329 | struct req_que *req; |
330 | struct rsp_que *rsp; | 330 | struct rsp_que *rsp; |
331 | char tag[2]; | ||
331 | 332 | ||
332 | /* Setup device pointers. */ | 333 | /* Setup device pointers. */ |
333 | ret = 0; | 334 | ret = 0; |
@@ -406,7 +407,22 @@ qla2x00_start_scsi(srb_t *sp) | |||
406 | cmd_pkt->lun = cpu_to_le16(sp->cmd->device->lun); | 407 | cmd_pkt->lun = cpu_to_le16(sp->cmd->device->lun); |
407 | 408 | ||
408 | /* Update tagged queuing modifier */ | 409 | /* Update tagged queuing modifier */ |
409 | cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG); | 410 | if (scsi_populate_tag_msg(cmd, tag)) { |
411 | switch (tag[0]) { | ||
412 | case HEAD_OF_QUEUE_TAG: | ||
413 | cmd_pkt->control_flags = | ||
414 | __constant_cpu_to_le16(CF_HEAD_TAG); | ||
415 | break; | ||
416 | case ORDERED_QUEUE_TAG: | ||
417 | cmd_pkt->control_flags = | ||
418 | __constant_cpu_to_le16(CF_ORDERED_TAG); | ||
419 | break; | ||
420 | default: | ||
421 | cmd_pkt->control_flags = | ||
422 | __constant_cpu_to_le16(CF_SIMPLE_TAG); | ||
423 | break; | ||
424 | } | ||
425 | } | ||
410 | 426 | ||
411 | /* Load SCSI command packet. */ | 427 | /* Load SCSI command packet. */ |
412 | memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len); | 428 | memcpy(cmd_pkt->scsi_cdb, cmd->cmnd, cmd->cmd_len); |
@@ -971,6 +987,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
971 | uint16_t fcp_cmnd_len; | 987 | uint16_t fcp_cmnd_len; |
972 | struct fcp_cmnd *fcp_cmnd; | 988 | struct fcp_cmnd *fcp_cmnd; |
973 | dma_addr_t crc_ctx_dma; | 989 | dma_addr_t crc_ctx_dma; |
990 | char tag[2]; | ||
974 | 991 | ||
975 | cmd = sp->cmd; | 992 | cmd = sp->cmd; |
976 | 993 | ||
@@ -1068,9 +1085,27 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1068 | LSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); | 1085 | LSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); |
1069 | cmd_pkt->fcp_cmnd_dseg_address[1] = cpu_to_le32( | 1086 | cmd_pkt->fcp_cmnd_dseg_address[1] = cpu_to_le32( |
1070 | MSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); | 1087 | MSD(crc_ctx_dma + CRC_CONTEXT_FCPCMND_OFF)); |
1071 | fcp_cmnd->task_attribute = 0; | ||
1072 | fcp_cmnd->task_management = 0; | 1088 | fcp_cmnd->task_management = 0; |
1073 | 1089 | ||
1090 | /* | ||
1091 | * Update tagged queuing modifier if using command tag queuing | ||
1092 | */ | ||
1093 | if (scsi_populate_tag_msg(cmd, tag)) { | ||
1094 | switch (tag[0]) { | ||
1095 | case HEAD_OF_QUEUE_TAG: | ||
1096 | fcp_cmnd->task_attribute = TSK_HEAD_OF_QUEUE; | ||
1097 | break; | ||
1098 | case ORDERED_QUEUE_TAG: | ||
1099 | fcp_cmnd->task_attribute = TSK_ORDERED; | ||
1100 | break; | ||
1101 | default: | ||
1102 | fcp_cmnd->task_attribute = 0; | ||
1103 | break; | ||
1104 | } | ||
1105 | } else { | ||
1106 | fcp_cmnd->task_attribute = 0; | ||
1107 | } | ||
1108 | |||
1074 | cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ | 1109 | cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ |
1075 | 1110 | ||
1076 | DEBUG18(printk(KERN_INFO "%s(%ld): Total SG(s) Entries %d, Data" | 1111 | DEBUG18(printk(KERN_INFO "%s(%ld): Total SG(s) Entries %d, Data" |
@@ -1177,6 +1212,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
1177 | struct scsi_cmnd *cmd = sp->cmd; | 1212 | struct scsi_cmnd *cmd = sp->cmd; |
1178 | struct scsi_qla_host *vha = sp->fcport->vha; | 1213 | struct scsi_qla_host *vha = sp->fcport->vha; |
1179 | struct qla_hw_data *ha = vha->hw; | 1214 | struct qla_hw_data *ha = vha->hw; |
1215 | char tag[2]; | ||
1180 | 1216 | ||
1181 | /* Setup device pointers. */ | 1217 | /* Setup device pointers. */ |
1182 | ret = 0; | 1218 | ret = 0; |
@@ -1260,6 +1296,18 @@ qla24xx_start_scsi(srb_t *sp) | |||
1260 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 1296 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
1261 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | 1297 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); |
1262 | 1298 | ||
1299 | /* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */ | ||
1300 | if (scsi_populate_tag_msg(cmd, tag)) { | ||
1301 | switch (tag[0]) { | ||
1302 | case HEAD_OF_QUEUE_TAG: | ||
1303 | cmd_pkt->task = TSK_HEAD_OF_QUEUE; | ||
1304 | break; | ||
1305 | case ORDERED_QUEUE_TAG: | ||
1306 | cmd_pkt->task = TSK_ORDERED; | ||
1307 | break; | ||
1308 | } | ||
1309 | } | ||
1310 | |||
1263 | /* Load SCSI command packet. */ | 1311 | /* Load SCSI command packet. */ |
1264 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); | 1312 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); |
1265 | host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); | 1313 | host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index e473e9fb363c..7a7c0ecfe7dd 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -71,6 +71,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
71 | return QLA_FUNCTION_TIMEOUT; | 71 | return QLA_FUNCTION_TIMEOUT; |
72 | } | 72 | } |
73 | 73 | ||
74 | if (ha->flags.isp82xx_fw_hung) { | ||
75 | /* Setting Link-Down error */ | ||
76 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; | ||
77 | rval = QLA_FUNCTION_FAILED; | ||
78 | goto premature_exit; | ||
79 | } | ||
80 | |||
74 | /* | 81 | /* |
75 | * Wait for active mailbox commands to finish by waiting at most tov | 82 | * Wait for active mailbox commands to finish by waiting at most tov |
76 | * seconds. This is to serialize actual issuing of mailbox cmds during | 83 | * seconds. This is to serialize actual issuing of mailbox cmds during |
@@ -83,13 +90,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
83 | return QLA_FUNCTION_TIMEOUT; | 90 | return QLA_FUNCTION_TIMEOUT; |
84 | } | 91 | } |
85 | 92 | ||
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 | |||
93 | ha->flags.mbox_busy = 1; | 93 | ha->flags.mbox_busy = 1; |
94 | /* Save mailbox command for debug */ | 94 | /* Save mailbox command for debug */ |
95 | ha->mcp = mcp; | 95 | ha->mcp = mcp; |
@@ -223,7 +223,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
223 | ha->flags.mbox_int = 0; | 223 | ha->flags.mbox_int = 0; |
224 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); | 224 | clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); |
225 | 225 | ||
226 | if (IS_QLA82XX(ha) && ha->flags.fw_hung) { | 226 | if (ha->flags.isp82xx_fw_hung) { |
227 | ha->flags.mbox_busy = 0; | 227 | ha->flags.mbox_busy = 0; |
228 | /* Setting Link-Down error */ | 228 | /* Setting Link-Down error */ |
229 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; | 229 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; |
@@ -2462,22 +2462,19 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, | |||
2462 | "-- completion status (%x).\n", __func__, | 2462 | "-- completion status (%x).\n", __func__, |
2463 | vha->host_no, le16_to_cpu(sts->comp_status))); | 2463 | vha->host_no, le16_to_cpu(sts->comp_status))); |
2464 | rval = QLA_FUNCTION_FAILED; | 2464 | rval = QLA_FUNCTION_FAILED; |
2465 | } else if (!(le16_to_cpu(sts->scsi_status) & | 2465 | } else if (le16_to_cpu(sts->scsi_status) & |
2466 | SS_RESPONSE_INFO_LEN_VALID)) { | 2466 | SS_RESPONSE_INFO_LEN_VALID) { |
2467 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2467 | if (le32_to_cpu(sts->rsp_data_len) < 4) { |
2468 | "-- no response info (%x).\n", __func__, vha->host_no, | 2468 | DEBUG2_3_11(printk("%s(%ld): ignoring inconsistent " |
2469 | le16_to_cpu(sts->scsi_status))); | 2469 | "data length -- not enough response info (%d).\n", |
2470 | rval = QLA_FUNCTION_FAILED; | 2470 | __func__, vha->host_no, |
2471 | } else if (le32_to_cpu(sts->rsp_data_len) < 4) { | 2471 | le32_to_cpu(sts->rsp_data_len))); |
2472 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2472 | } else if (sts->data[3]) { |
2473 | "-- not enough response info (%d).\n", __func__, | 2473 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2474 | vha->host_no, le32_to_cpu(sts->rsp_data_len))); | 2474 | "-- response (%x).\n", __func__, |
2475 | rval = QLA_FUNCTION_FAILED; | 2475 | vha->host_no, sts->data[3])); |
2476 | } else if (sts->data[3]) { | 2476 | rval = QLA_FUNCTION_FAILED; |
2477 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2477 | } |
2478 | "-- response (%x).\n", __func__, | ||
2479 | vha->host_no, sts->data[3])); | ||
2480 | rval = QLA_FUNCTION_FAILED; | ||
2481 | } | 2478 | } |
2482 | 2479 | ||
2483 | /* Issue marker IOCB. */ | 2480 | /* Issue marker IOCB. */ |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index fdb96a3584a5..76ec876e6b21 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
9 | #include <linux/pci.h> | 9 | #include <linux/pci.h> |
10 | #include <scsi/scsi_tcq.h> | ||
10 | 11 | ||
11 | #define MASK(n) ((1ULL<<(n))-1) | 12 | #define MASK(n) ((1ULL<<(n))-1) |
12 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \ | 13 | #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \ |
@@ -2547,7 +2548,7 @@ qla2xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, | |||
2547 | dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; | 2548 | dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address; |
2548 | *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 2549 | *dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); |
2549 | *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 2550 | *dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); |
2550 | *dsd_seg++ = dsd_list_len; | 2551 | cmd_pkt->fcp_data_dseg_len = dsd_list_len; |
2551 | } else { | 2552 | } else { |
2552 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 2553 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); |
2553 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | 2554 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); |
@@ -2620,6 +2621,7 @@ qla82xx_start_scsi(srb_t *sp) | |||
2620 | struct qla_hw_data *ha = vha->hw; | 2621 | struct qla_hw_data *ha = vha->hw; |
2621 | struct req_que *req = NULL; | 2622 | struct req_que *req = NULL; |
2622 | struct rsp_que *rsp = NULL; | 2623 | struct rsp_que *rsp = NULL; |
2624 | char tag[2]; | ||
2623 | 2625 | ||
2624 | /* Setup device pointers. */ | 2626 | /* Setup device pointers. */ |
2625 | ret = 0; | 2627 | ret = 0; |
@@ -2770,6 +2772,22 @@ sufficient_dsds: | |||
2770 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 2772 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
2771 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | 2773 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); |
2772 | 2774 | ||
2775 | /* | ||
2776 | * Update tagged queuing modifier -- default is TSK_SIMPLE (0). | ||
2777 | */ | ||
2778 | if (scsi_populate_tag_msg(cmd, tag)) { | ||
2779 | switch (tag[0]) { | ||
2780 | case HEAD_OF_QUEUE_TAG: | ||
2781 | ctx->fcp_cmnd->task_attribute = | ||
2782 | TSK_HEAD_OF_QUEUE; | ||
2783 | break; | ||
2784 | case ORDERED_QUEUE_TAG: | ||
2785 | ctx->fcp_cmnd->task_attribute = | ||
2786 | TSK_ORDERED; | ||
2787 | break; | ||
2788 | } | ||
2789 | } | ||
2790 | |||
2773 | /* build FCP_CMND IU */ | 2791 | /* build FCP_CMND IU */ |
2774 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | 2792 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); |
2775 | int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); | 2793 | int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); |
@@ -2835,6 +2853,20 @@ sufficient_dsds: | |||
2835 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, | 2853 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, |
2836 | sizeof(cmd_pkt->lun)); | 2854 | sizeof(cmd_pkt->lun)); |
2837 | 2855 | ||
2856 | /* | ||
2857 | * Update tagged queuing modifier -- default is TSK_SIMPLE (0). | ||
2858 | */ | ||
2859 | if (scsi_populate_tag_msg(cmd, tag)) { | ||
2860 | switch (tag[0]) { | ||
2861 | case HEAD_OF_QUEUE_TAG: | ||
2862 | cmd_pkt->task = TSK_HEAD_OF_QUEUE; | ||
2863 | break; | ||
2864 | case ORDERED_QUEUE_TAG: | ||
2865 | cmd_pkt->task = TSK_ORDERED; | ||
2866 | break; | ||
2867 | } | ||
2868 | } | ||
2869 | |||
2838 | /* Load SCSI command packet. */ | 2870 | /* Load SCSI command packet. */ |
2839 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); | 2871 | memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len); |
2840 | host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); | 2872 | host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb)); |
@@ -3457,46 +3489,28 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha) | |||
3457 | } | 3489 | } |
3458 | } | 3490 | } |
3459 | 3491 | ||
3460 | static void | 3492 | int |
3461 | qla82xx_check_fw_alive(scsi_qla_host_t *vha) | 3493 | qla82xx_check_fw_alive(scsi_qla_host_t *vha) |
3462 | { | 3494 | { |
3463 | uint32_t fw_heartbeat_counter, halt_status; | 3495 | uint32_t fw_heartbeat_counter; |
3464 | struct qla_hw_data *ha = vha->hw; | 3496 | int status = 0; |
3465 | 3497 | ||
3466 | fw_heartbeat_counter = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | 3498 | fw_heartbeat_counter = qla82xx_rd_32(vha->hw, |
3499 | QLA82XX_PEG_ALIVE_COUNTER); | ||
3467 | /* all 0xff, assume AER/EEH in progress, ignore */ | 3500 | /* all 0xff, assume AER/EEH in progress, ignore */ |
3468 | if (fw_heartbeat_counter == 0xffffffff) | 3501 | if (fw_heartbeat_counter == 0xffffffff) |
3469 | return; | 3502 | return status; |
3470 | if (vha->fw_heartbeat_counter == fw_heartbeat_counter) { | 3503 | if (vha->fw_heartbeat_counter == fw_heartbeat_counter) { |
3471 | vha->seconds_since_last_heartbeat++; | 3504 | vha->seconds_since_last_heartbeat++; |
3472 | /* FW not alive after 2 seconds */ | 3505 | /* FW not alive after 2 seconds */ |
3473 | if (vha->seconds_since_last_heartbeat == 2) { | 3506 | if (vha->seconds_since_last_heartbeat == 2) { |
3474 | vha->seconds_since_last_heartbeat = 0; | 3507 | vha->seconds_since_last_heartbeat = 0; |
3475 | halt_status = qla82xx_rd_32(ha, | 3508 | status = 1; |
3476 | QLA82XX_PEG_HALT_STATUS1); | ||
3477 | if (halt_status & HALT_STATUS_UNRECOVERABLE) { | ||
3478 | set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); | ||
3479 | } else { | ||
3480 | qla_printk(KERN_INFO, ha, | ||
3481 | "scsi(%ld): %s - detect abort needed\n", | ||
3482 | vha->host_no, __func__); | ||
3483 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | ||
3484 | } | ||
3485 | qla2xxx_wake_dpc(vha); | ||
3486 | ha->flags.fw_hung = 1; | ||
3487 | if (ha->flags.mbox_busy) { | ||
3488 | ha->flags.mbox_int = 1; | ||
3489 | DEBUG2(qla_printk(KERN_ERR, ha, | ||
3490 | "Due to fw hung, doing premature " | ||
3491 | "completion of mbx command\n")); | ||
3492 | if (test_bit(MBX_INTR_WAIT, | ||
3493 | &ha->mbx_cmd_flags)) | ||
3494 | complete(&ha->mbx_intr_comp); | ||
3495 | } | ||
3496 | } | 3509 | } |
3497 | } else | 3510 | } else |
3498 | vha->seconds_since_last_heartbeat = 0; | 3511 | vha->seconds_since_last_heartbeat = 0; |
3499 | vha->fw_heartbeat_counter = fw_heartbeat_counter; | 3512 | vha->fw_heartbeat_counter = fw_heartbeat_counter; |
3513 | return status; | ||
3500 | } | 3514 | } |
3501 | 3515 | ||
3502 | /* | 3516 | /* |
@@ -3557,6 +3571,8 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha) | |||
3557 | break; | 3571 | break; |
3558 | case QLA82XX_DEV_NEED_RESET: | 3572 | case QLA82XX_DEV_NEED_RESET: |
3559 | qla82xx_need_reset_handler(vha); | 3573 | qla82xx_need_reset_handler(vha); |
3574 | dev_init_timeout = jiffies + | ||
3575 | (ha->nx_dev_init_timeout * HZ); | ||
3560 | break; | 3576 | break; |
3561 | case QLA82XX_DEV_NEED_QUIESCENT: | 3577 | case QLA82XX_DEV_NEED_QUIESCENT: |
3562 | qla82xx_need_qsnt_handler(vha); | 3578 | qla82xx_need_qsnt_handler(vha); |
@@ -3596,30 +3612,18 @@ exit: | |||
3596 | 3612 | ||
3597 | void qla82xx_watchdog(scsi_qla_host_t *vha) | 3613 | void qla82xx_watchdog(scsi_qla_host_t *vha) |
3598 | { | 3614 | { |
3599 | uint32_t dev_state; | 3615 | uint32_t dev_state, halt_status; |
3600 | struct qla_hw_data *ha = vha->hw; | 3616 | struct qla_hw_data *ha = vha->hw; |
3601 | 3617 | ||
3602 | dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); | ||
3603 | |||
3604 | /* don't poll if reset is going on */ | 3618 | /* don't poll if reset is going on */ |
3605 | if (!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) || | 3619 | if (!ha->flags.isp82xx_reset_hdlr_active) { |
3606 | test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || | 3620 | dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); |
3607 | test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))) { | 3621 | if (dev_state == QLA82XX_DEV_NEED_RESET && |
3608 | if (dev_state == QLA82XX_DEV_NEED_RESET) { | 3622 | !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) { |
3609 | qla_printk(KERN_WARNING, ha, | 3623 | qla_printk(KERN_WARNING, ha, |
3610 | "%s(): Adapter reset needed!\n", __func__); | 3624 | "%s(): Adapter reset needed!\n", __func__); |
3611 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 3625 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
3612 | qla2xxx_wake_dpc(vha); | 3626 | qla2xxx_wake_dpc(vha); |
3613 | ha->flags.fw_hung = 1; | ||
3614 | if (ha->flags.mbox_busy) { | ||
3615 | ha->flags.mbox_int = 1; | ||
3616 | DEBUG2(qla_printk(KERN_ERR, ha, | ||
3617 | "Need reset, doing premature " | ||
3618 | "completion of mbx command\n")); | ||
3619 | if (test_bit(MBX_INTR_WAIT, | ||
3620 | &ha->mbx_cmd_flags)) | ||
3621 | complete(&ha->mbx_intr_comp); | ||
3622 | } | ||
3623 | } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && | 3627 | } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && |
3624 | !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { | 3628 | !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { |
3625 | DEBUG(qla_printk(KERN_INFO, ha, | 3629 | DEBUG(qla_printk(KERN_INFO, ha, |
@@ -3629,6 +3633,31 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) | |||
3629 | qla2xxx_wake_dpc(vha); | 3633 | qla2xxx_wake_dpc(vha); |
3630 | } else { | 3634 | } else { |
3631 | qla82xx_check_fw_alive(vha); | 3635 | qla82xx_check_fw_alive(vha); |
3636 | if (qla82xx_check_fw_alive(vha)) { | ||
3637 | halt_status = qla82xx_rd_32(ha, | ||
3638 | QLA82XX_PEG_HALT_STATUS1); | ||
3639 | if (halt_status & HALT_STATUS_UNRECOVERABLE) { | ||
3640 | set_bit(ISP_UNRECOVERABLE, | ||
3641 | &vha->dpc_flags); | ||
3642 | } else { | ||
3643 | qla_printk(KERN_INFO, ha, | ||
3644 | "scsi(%ld): %s - detect abort needed\n", | ||
3645 | vha->host_no, __func__); | ||
3646 | set_bit(ISP_ABORT_NEEDED, | ||
3647 | &vha->dpc_flags); | ||
3648 | } | ||
3649 | qla2xxx_wake_dpc(vha); | ||
3650 | ha->flags.isp82xx_fw_hung = 1; | ||
3651 | if (ha->flags.mbox_busy) { | ||
3652 | ha->flags.mbox_int = 1; | ||
3653 | DEBUG2(qla_printk(KERN_ERR, ha, | ||
3654 | "Due to fw hung, doing premature " | ||
3655 | "completion of mbx command\n")); | ||
3656 | if (test_bit(MBX_INTR_WAIT, | ||
3657 | &ha->mbx_cmd_flags)) | ||
3658 | complete(&ha->mbx_intr_comp); | ||
3659 | } | ||
3660 | } | ||
3632 | } | 3661 | } |
3633 | } | 3662 | } |
3634 | } | 3663 | } |
@@ -3663,6 +3692,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha) | |||
3663 | "Exiting.\n", __func__, vha->host_no); | 3692 | "Exiting.\n", __func__, vha->host_no); |
3664 | return QLA_SUCCESS; | 3693 | return QLA_SUCCESS; |
3665 | } | 3694 | } |
3695 | ha->flags.isp82xx_reset_hdlr_active = 1; | ||
3666 | 3696 | ||
3667 | qla82xx_idc_lock(ha); | 3697 | qla82xx_idc_lock(ha); |
3668 | dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); | 3698 | dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); |
@@ -3683,7 +3713,8 @@ qla82xx_abort_isp(scsi_qla_host_t *vha) | |||
3683 | qla82xx_idc_unlock(ha); | 3713 | qla82xx_idc_unlock(ha); |
3684 | 3714 | ||
3685 | if (rval == QLA_SUCCESS) { | 3715 | if (rval == QLA_SUCCESS) { |
3686 | ha->flags.fw_hung = 0; | 3716 | ha->flags.isp82xx_fw_hung = 0; |
3717 | ha->flags.isp82xx_reset_hdlr_active = 0; | ||
3687 | qla82xx_restart_isp(vha); | 3718 | qla82xx_restart_isp(vha); |
3688 | } | 3719 | } |
3689 | 3720 | ||
@@ -3791,3 +3822,71 @@ int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha) | |||
3791 | 3822 | ||
3792 | return status; | 3823 | return status; |
3793 | } | 3824 | } |
3825 | |||
3826 | void | ||
3827 | qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) | ||
3828 | { | ||
3829 | int i; | ||
3830 | unsigned long flags; | ||
3831 | struct qla_hw_data *ha = vha->hw; | ||
3832 | |||
3833 | /* Check if 82XX firmware is alive or not | ||
3834 | * We may have arrived here from NEED_RESET | ||
3835 | * detection only | ||
3836 | */ | ||
3837 | if (!ha->flags.isp82xx_fw_hung) { | ||
3838 | for (i = 0; i < 2; i++) { | ||
3839 | msleep(1000); | ||
3840 | if (qla82xx_check_fw_alive(vha)) { | ||
3841 | ha->flags.isp82xx_fw_hung = 1; | ||
3842 | if (ha->flags.mbox_busy) { | ||
3843 | ha->flags.mbox_int = 1; | ||
3844 | complete(&ha->mbx_intr_comp); | ||
3845 | } | ||
3846 | break; | ||
3847 | } | ||
3848 | } | ||
3849 | } | ||
3850 | |||
3851 | /* Abort all commands gracefully if fw NOT hung */ | ||
3852 | if (!ha->flags.isp82xx_fw_hung) { | ||
3853 | int cnt, que; | ||
3854 | srb_t *sp; | ||
3855 | struct req_que *req; | ||
3856 | |||
3857 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
3858 | for (que = 0; que < ha->max_req_queues; que++) { | ||
3859 | req = ha->req_q_map[que]; | ||
3860 | if (!req) | ||
3861 | continue; | ||
3862 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
3863 | sp = req->outstanding_cmds[cnt]; | ||
3864 | if (sp) { | ||
3865 | if (!sp->ctx || | ||
3866 | (sp->flags & SRB_FCP_CMND_DMA_VALID)) { | ||
3867 | spin_unlock_irqrestore( | ||
3868 | &ha->hardware_lock, flags); | ||
3869 | if (ha->isp_ops->abort_command(sp)) { | ||
3870 | qla_printk(KERN_INFO, ha, | ||
3871 | "scsi(%ld): mbx abort command failed in %s\n", | ||
3872 | vha->host_no, __func__); | ||
3873 | } else { | ||
3874 | qla_printk(KERN_INFO, ha, | ||
3875 | "scsi(%ld): mbx abort command success in %s\n", | ||
3876 | vha->host_no, __func__); | ||
3877 | } | ||
3878 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
3879 | } | ||
3880 | } | ||
3881 | } | ||
3882 | } | ||
3883 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
3884 | |||
3885 | /* Wait for pending cmds (physical and virtual) to complete */ | ||
3886 | if (!qla2x00_eh_wait_for_pending_commands(vha, 0, 0, | ||
3887 | WAIT_HOST) == QLA_SUCCESS) { | ||
3888 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
3889 | "Done wait for pending commands\n")); | ||
3890 | } | ||
3891 | } | ||
3892 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e90f7c16b956..75a966c94860 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -506,7 +506,7 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str) | |||
506 | 506 | ||
507 | static inline srb_t * | 507 | static inline srb_t * |
508 | qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, | 508 | qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, |
509 | struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 509 | struct scsi_cmnd *cmd) |
510 | { | 510 | { |
511 | srb_t *sp; | 511 | srb_t *sp; |
512 | struct qla_hw_data *ha = vha->hw; | 512 | struct qla_hw_data *ha = vha->hw; |
@@ -520,14 +520,13 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
520 | sp->cmd = cmd; | 520 | sp->cmd = cmd; |
521 | sp->flags = 0; | 521 | sp->flags = 0; |
522 | CMD_SP(cmd) = (void *)sp; | 522 | CMD_SP(cmd) = (void *)sp; |
523 | cmd->scsi_done = done; | ||
524 | sp->ctx = NULL; | 523 | sp->ctx = NULL; |
525 | 524 | ||
526 | return sp; | 525 | return sp; |
527 | } | 526 | } |
528 | 527 | ||
529 | static int | 528 | static int |
530 | qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 529 | qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
531 | { | 530 | { |
532 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 531 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
533 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 532 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
@@ -537,7 +536,6 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) | |||
537 | srb_t *sp; | 536 | srb_t *sp; |
538 | int rval; | 537 | int rval; |
539 | 538 | ||
540 | spin_unlock_irq(vha->host->host_lock); | ||
541 | if (ha->flags.eeh_busy) { | 539 | if (ha->flags.eeh_busy) { |
542 | if (ha->flags.pci_channel_io_perm_failure) | 540 | if (ha->flags.pci_channel_io_perm_failure) |
543 | cmd->result = DID_NO_CONNECT << 16; | 541 | cmd->result = DID_NO_CONNECT << 16; |
@@ -569,40 +567,32 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) | |||
569 | goto qc24_target_busy; | 567 | goto qc24_target_busy; |
570 | } | 568 | } |
571 | 569 | ||
572 | sp = qla2x00_get_new_sp(base_vha, fcport, cmd, done); | 570 | sp = qla2x00_get_new_sp(base_vha, fcport, cmd); |
573 | if (!sp) | 571 | if (!sp) |
574 | goto qc24_host_busy_lock; | 572 | goto qc24_host_busy; |
575 | 573 | ||
576 | rval = ha->isp_ops->start_scsi(sp); | 574 | rval = ha->isp_ops->start_scsi(sp); |
577 | if (rval != QLA_SUCCESS) | 575 | if (rval != QLA_SUCCESS) |
578 | goto qc24_host_busy_free_sp; | 576 | goto qc24_host_busy_free_sp; |
579 | 577 | ||
580 | spin_lock_irq(vha->host->host_lock); | ||
581 | |||
582 | return 0; | 578 | return 0; |
583 | 579 | ||
584 | qc24_host_busy_free_sp: | 580 | qc24_host_busy_free_sp: |
585 | qla2x00_sp_free_dma(sp); | 581 | qla2x00_sp_free_dma(sp); |
586 | mempool_free(sp, ha->srb_mempool); | 582 | mempool_free(sp, ha->srb_mempool); |
587 | 583 | ||
588 | qc24_host_busy_lock: | 584 | qc24_host_busy: |
589 | spin_lock_irq(vha->host->host_lock); | ||
590 | return SCSI_MLQUEUE_HOST_BUSY; | 585 | return SCSI_MLQUEUE_HOST_BUSY; |
591 | 586 | ||
592 | qc24_target_busy: | 587 | qc24_target_busy: |
593 | spin_lock_irq(vha->host->host_lock); | ||
594 | return SCSI_MLQUEUE_TARGET_BUSY; | 588 | return SCSI_MLQUEUE_TARGET_BUSY; |
595 | 589 | ||
596 | qc24_fail_command: | 590 | qc24_fail_command: |
597 | spin_lock_irq(vha->host->host_lock); | 591 | cmd->scsi_done(cmd); |
598 | done(cmd); | ||
599 | 592 | ||
600 | return 0; | 593 | return 0; |
601 | } | 594 | } |
602 | 595 | ||
603 | static DEF_SCSI_QCMD(qla2xxx_queuecommand) | ||
604 | |||
605 | |||
606 | /* | 596 | /* |
607 | * qla2x00_eh_wait_on_command | 597 | * qla2x00_eh_wait_on_command |
608 | * Waits for the command to be returned by the Firmware for some | 598 | * Waits for the command to be returned by the Firmware for some |
@@ -821,17 +811,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
821 | { | 811 | { |
822 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 812 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
823 | srb_t *sp; | 813 | srb_t *sp; |
824 | int ret = SUCCESS; | 814 | int ret; |
825 | unsigned int id, lun; | 815 | unsigned int id, lun; |
826 | unsigned long flags; | 816 | unsigned long flags; |
827 | int wait = 0; | 817 | int wait = 0; |
828 | struct qla_hw_data *ha = vha->hw; | 818 | struct qla_hw_data *ha = vha->hw; |
829 | 819 | ||
830 | fc_block_scsi_eh(cmd); | ||
831 | |||
832 | if (!CMD_SP(cmd)) | 820 | if (!CMD_SP(cmd)) |
833 | return SUCCESS; | 821 | return SUCCESS; |
834 | 822 | ||
823 | ret = fc_block_scsi_eh(cmd); | ||
824 | if (ret != 0) | ||
825 | return ret; | ||
826 | ret = SUCCESS; | ||
827 | |||
835 | id = cmd->device->id; | 828 | id = cmd->device->id; |
836 | lun = cmd->device->lun; | 829 | lun = cmd->device->lun; |
837 | 830 | ||
@@ -940,11 +933,13 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | |||
940 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 933 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
941 | int err; | 934 | int err; |
942 | 935 | ||
943 | fc_block_scsi_eh(cmd); | ||
944 | |||
945 | if (!fcport) | 936 | if (!fcport) |
946 | return FAILED; | 937 | return FAILED; |
947 | 938 | ||
939 | err = fc_block_scsi_eh(cmd); | ||
940 | if (err != 0) | ||
941 | return err; | ||
942 | |||
948 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", | 943 | qla_printk(KERN_INFO, vha->hw, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", |
949 | vha->host_no, cmd->device->id, cmd->device->lun, name); | 944 | vha->host_no, cmd->device->id, cmd->device->lun, name); |
950 | 945 | ||
@@ -1018,14 +1013,17 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
1018 | int ret = FAILED; | 1013 | int ret = FAILED; |
1019 | unsigned int id, lun; | 1014 | unsigned int id, lun; |
1020 | 1015 | ||
1021 | fc_block_scsi_eh(cmd); | ||
1022 | |||
1023 | id = cmd->device->id; | 1016 | id = cmd->device->id; |
1024 | lun = cmd->device->lun; | 1017 | lun = cmd->device->lun; |
1025 | 1018 | ||
1026 | if (!fcport) | 1019 | if (!fcport) |
1027 | return ret; | 1020 | return ret; |
1028 | 1021 | ||
1022 | ret = fc_block_scsi_eh(cmd); | ||
1023 | if (ret != 0) | ||
1024 | return ret; | ||
1025 | ret = FAILED; | ||
1026 | |||
1029 | qla_printk(KERN_INFO, vha->hw, | 1027 | qla_printk(KERN_INFO, vha->hw, |
1030 | "scsi(%ld:%d:%d): BUS RESET ISSUED.\n", vha->host_no, id, lun); | 1028 | "scsi(%ld:%d:%d): BUS RESET ISSUED.\n", vha->host_no, id, lun); |
1031 | 1029 | ||
@@ -1078,14 +1076,17 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1078 | unsigned int id, lun; | 1076 | unsigned int id, lun; |
1079 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | 1077 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
1080 | 1078 | ||
1081 | fc_block_scsi_eh(cmd); | ||
1082 | |||
1083 | id = cmd->device->id; | 1079 | id = cmd->device->id; |
1084 | lun = cmd->device->lun; | 1080 | lun = cmd->device->lun; |
1085 | 1081 | ||
1086 | if (!fcport) | 1082 | if (!fcport) |
1087 | return ret; | 1083 | return ret; |
1088 | 1084 | ||
1085 | ret = fc_block_scsi_eh(cmd); | ||
1086 | if (ret != 0) | ||
1087 | return ret; | ||
1088 | ret = FAILED; | ||
1089 | |||
1089 | qla_printk(KERN_INFO, ha, | 1090 | qla_printk(KERN_INFO, ha, |
1090 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", vha->host_no, id, lun); | 1091 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", vha->host_no, id, lun); |
1091 | 1092 | ||
@@ -3805,7 +3806,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |||
3805 | ha->flags.eeh_busy = 1; | 3806 | ha->flags.eeh_busy = 1; |
3806 | /* For ISP82XX complete any pending mailbox cmd */ | 3807 | /* For ISP82XX complete any pending mailbox cmd */ |
3807 | if (IS_QLA82XX(ha)) { | 3808 | if (IS_QLA82XX(ha)) { |
3808 | ha->flags.fw_hung = 1; | 3809 | ha->flags.isp82xx_fw_hung = 1; |
3809 | if (ha->flags.mbox_busy) { | 3810 | if (ha->flags.mbox_busy) { |
3810 | ha->flags.mbox_int = 1; | 3811 | ha->flags.mbox_int = 1; |
3811 | DEBUG2(qla_printk(KERN_ERR, ha, | 3812 | DEBUG2(qla_printk(KERN_ERR, ha, |
@@ -3945,7 +3946,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha) | |||
3945 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | 3946 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, |
3946 | QLA82XX_DEV_READY); | 3947 | QLA82XX_DEV_READY); |
3947 | qla82xx_idc_unlock(ha); | 3948 | qla82xx_idc_unlock(ha); |
3948 | ha->flags.fw_hung = 0; | 3949 | ha->flags.isp82xx_fw_hung = 0; |
3949 | rval = qla82xx_restart_isp(base_vha); | 3950 | rval = qla82xx_restart_isp(base_vha); |
3950 | qla82xx_idc_lock(ha); | 3951 | qla82xx_idc_lock(ha); |
3951 | /* Clear driver state register */ | 3952 | /* Clear driver state register */ |
@@ -3958,7 +3959,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha) | |||
3958 | "This devfn is not reset owner = 0x%x\n", ha->pdev->devfn)); | 3959 | "This devfn is not reset owner = 0x%x\n", ha->pdev->devfn)); |
3959 | if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == | 3960 | if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == |
3960 | QLA82XX_DEV_READY)) { | 3961 | QLA82XX_DEV_READY)) { |
3961 | ha->flags.fw_hung = 0; | 3962 | ha->flags.isp82xx_fw_hung = 0; |
3962 | rval = qla82xx_restart_isp(base_vha); | 3963 | rval = qla82xx_restart_isp(base_vha); |
3963 | qla82xx_idc_lock(ha); | 3964 | qla82xx_idc_lock(ha); |
3964 | qla82xx_set_drv_active(base_vha); | 3965 | qla82xx_set_drv_active(base_vha); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index cf0075a2d0c2..3a260c3f055a 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.05-k0" | 10 | #define QLA2XXX_VERSION "8.03.07.00" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
14 | #define QLA_DRIVER_PATCH_VER 5 | 14 | #define QLA_DRIVER_PATCH_VER 7 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |