diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 88 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 39 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 33 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 31 |
6 files changed, 178 insertions, 28 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index b3cf6099600b..a491338e1bfe 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -219,6 +219,7 @@ typedef struct srb { | |||
219 | #define SRB_ELS_CMD_RPT 3 | 219 | #define SRB_ELS_CMD_RPT 3 |
220 | #define SRB_ELS_CMD_HST 4 | 220 | #define SRB_ELS_CMD_HST 4 |
221 | #define SRB_CT_CMD 5 | 221 | #define SRB_CT_CMD 5 |
222 | #define SRB_ADISC_CMD 6 | ||
222 | 223 | ||
223 | struct srb_ctx { | 224 | struct srb_ctx { |
224 | uint16_t type; | 225 | uint16_t type; |
@@ -1623,6 +1624,7 @@ typedef struct fc_port { | |||
1623 | #define FCF_FABRIC_DEVICE BIT_0 | 1624 | #define FCF_FABRIC_DEVICE BIT_0 |
1624 | #define FCF_LOGIN_NEEDED BIT_1 | 1625 | #define FCF_LOGIN_NEEDED BIT_1 |
1625 | #define FCF_FCP2_DEVICE BIT_2 | 1626 | #define FCF_FCP2_DEVICE BIT_2 |
1627 | #define FCF_ASYNC_SENT BIT_3 | ||
1626 | 1628 | ||
1627 | /* No loop ID flag. */ | 1629 | /* No loop ID flag. */ |
1628 | #define FC_NO_LOOP_ID 0x1000 | 1630 | #define FC_NO_LOOP_ID 0x1000 |
@@ -2156,6 +2158,8 @@ enum qla_work_type { | |||
2156 | QLA_EVT_ASYNC_LOGIN_DONE, | 2158 | QLA_EVT_ASYNC_LOGIN_DONE, |
2157 | QLA_EVT_ASYNC_LOGOUT, | 2159 | QLA_EVT_ASYNC_LOGOUT, |
2158 | QLA_EVT_ASYNC_LOGOUT_DONE, | 2160 | QLA_EVT_ASYNC_LOGOUT_DONE, |
2161 | QLA_EVT_ASYNC_ADISC, | ||
2162 | QLA_EVT_ASYNC_ADISC_DONE, | ||
2159 | QLA_EVT_UEVENT, | 2163 | QLA_EVT_UEVENT, |
2160 | }; | 2164 | }; |
2161 | 2165 | ||
@@ -2514,6 +2518,9 @@ struct qla_hw_data { | |||
2514 | dma_addr_t ex_init_cb_dma; | 2518 | dma_addr_t ex_init_cb_dma; |
2515 | struct ex_init_cb_81xx *ex_init_cb; | 2519 | struct ex_init_cb_81xx *ex_init_cb; |
2516 | 2520 | ||
2521 | void *async_pd; | ||
2522 | dma_addr_t async_pd_dma; | ||
2523 | |||
2517 | /* These are used by mailbox operations. */ | 2524 | /* These are used by mailbox operations. */ |
2518 | volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; | 2525 | volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; |
2519 | 2526 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index cff5a4ae7626..03be29841902 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -56,10 +56,14 @@ extern void qla84xx_put_chip(struct scsi_qla_host *); | |||
56 | extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *, | 56 | extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *, |
57 | uint16_t *); | 57 | uint16_t *); |
58 | extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *); | 58 | extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *); |
59 | extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, | ||
60 | uint16_t *); | ||
59 | extern int qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, | 61 | extern int qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, |
60 | uint16_t *); | 62 | uint16_t *); |
61 | extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, | 63 | extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, |
62 | uint16_t *); | 64 | uint16_t *); |
65 | extern int qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, | ||
66 | uint16_t *); | ||
63 | 67 | ||
64 | extern fc_port_t * | 68 | extern fc_port_t * |
65 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); | 69 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); |
@@ -97,6 +101,10 @@ extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, | |||
97 | uint16_t *); | 101 | uint16_t *); |
98 | extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, | 102 | extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, |
99 | fc_port_t *, uint16_t *); | 103 | fc_port_t *, uint16_t *); |
104 | extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *, | ||
105 | uint16_t *); | ||
106 | extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *, | ||
107 | fc_port_t *, uint16_t *); | ||
100 | extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); | 108 | extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); |
101 | 109 | ||
102 | extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); | 110 | extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index c3c2c3627a70..4e7a3d5493e6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -119,6 +119,7 @@ qla2x00_async_logio_timeout(srb_t *sp) | |||
119 | "scsi(%ld:%x): Async-%s timeout.\n", | 119 | "scsi(%ld:%x): Async-%s timeout.\n", |
120 | fcport->vha->host_no, sp->handle, lio->ctx.name)); | 120 | fcport->vha->host_no, sp->handle, lio->ctx.name)); |
121 | 121 | ||
122 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
122 | if (lio->ctx.type == SRB_LOGIN_CMD) | 123 | if (lio->ctx.type == SRB_LOGIN_CMD) |
123 | qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); | 124 | qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); |
124 | } | 125 | } |
@@ -220,6 +221,56 @@ done: | |||
220 | return rval; | 221 | return rval; |
221 | } | 222 | } |
222 | 223 | ||
224 | static void | ||
225 | qla2x00_async_adisc_ctx_done(srb_t *sp) | ||
226 | { | ||
227 | struct srb_logio *lio = sp->ctx; | ||
228 | |||
229 | qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport, | ||
230 | lio->data); | ||
231 | lio->ctx.free(sp); | ||
232 | } | ||
233 | |||
234 | int | ||
235 | qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
236 | uint16_t *data) | ||
237 | { | ||
238 | struct qla_hw_data *ha = vha->hw; | ||
239 | srb_t *sp; | ||
240 | struct srb_logio *lio; | ||
241 | int rval; | ||
242 | |||
243 | rval = QLA_FUNCTION_FAILED; | ||
244 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio), | ||
245 | ELS_TMO_2_RATOV(ha) + 2); | ||
246 | if (!sp) | ||
247 | goto done; | ||
248 | |||
249 | lio = sp->ctx; | ||
250 | lio->ctx.type = SRB_ADISC_CMD; | ||
251 | lio->ctx.name = "adisc"; | ||
252 | lio->ctx.timeout = qla2x00_async_logio_timeout; | ||
253 | lio->ctx.done = qla2x00_async_adisc_ctx_done; | ||
254 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | ||
255 | lio->flags |= SRB_LOGIN_RETRIED; | ||
256 | rval = qla2x00_start_sp(sp); | ||
257 | if (rval != QLA_SUCCESS) | ||
258 | goto done_free_sp; | ||
259 | |||
260 | DEBUG2(printk(KERN_DEBUG | ||
261 | "scsi(%ld:%x): Async-adisc - loop-id=%x portid=%02x%02x%02x.\n", | ||
262 | fcport->vha->host_no, sp->handle, fcport->loop_id, | ||
263 | fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa)); | ||
264 | |||
265 | return rval; | ||
266 | |||
267 | done_free_sp: | ||
268 | del_timer_sync(&lio->ctx.timer); | ||
269 | lio->ctx.free(sp); | ||
270 | done: | ||
271 | return rval; | ||
272 | } | ||
273 | |||
223 | int | 274 | int |
224 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 275 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
225 | uint16_t *data) | 276 | uint16_t *data) |
@@ -229,15 +280,14 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
229 | switch (data[0]) { | 280 | switch (data[0]) { |
230 | case MBS_COMMAND_COMPLETE: | 281 | case MBS_COMMAND_COMPLETE: |
231 | if (fcport->flags & FCF_FCP2_DEVICE) { | 282 | if (fcport->flags & FCF_FCP2_DEVICE) { |
232 | rval = qla2x00_get_port_database(vha, fcport, BIT_1); | 283 | fcport->flags |= FCF_ASYNC_SENT; |
233 | if (rval != QLA_SUCCESS) { | 284 | qla2x00_post_async_adisc_work(vha, fcport, data); |
234 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 285 | break; |
235 | break; | ||
236 | } | ||
237 | } | 286 | } |
238 | qla2x00_update_fcport(vha, fcport); | 287 | qla2x00_update_fcport(vha, fcport); |
239 | break; | 288 | break; |
240 | case MBS_COMMAND_ERROR: | 289 | case MBS_COMMAND_ERROR: |
290 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
241 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 291 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
242 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | 292 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
243 | else | 293 | else |
@@ -251,6 +301,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
251 | fcport->loop_id++; | 301 | fcport->loop_id++; |
252 | rval = qla2x00_find_new_loop_id(vha, fcport); | 302 | rval = qla2x00_find_new_loop_id(vha, fcport); |
253 | if (rval != QLA_SUCCESS) { | 303 | if (rval != QLA_SUCCESS) { |
304 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
254 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 305 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
255 | break; | 306 | break; |
256 | } | 307 | } |
@@ -268,6 +319,26 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
268 | return QLA_SUCCESS; | 319 | return QLA_SUCCESS; |
269 | } | 320 | } |
270 | 321 | ||
322 | int | ||
323 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
324 | uint16_t *data) | ||
325 | { | ||
326 | if (data[0] == MBS_COMMAND_COMPLETE) { | ||
327 | qla2x00_update_fcport(vha, fcport); | ||
328 | |||
329 | return QLA_SUCCESS; | ||
330 | } | ||
331 | |||
332 | /* Retry login. */ | ||
333 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
334 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | ||
335 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | ||
336 | else | ||
337 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | ||
338 | |||
339 | return QLA_SUCCESS; | ||
340 | } | ||
341 | |||
271 | /****************************************************************************/ | 342 | /****************************************************************************/ |
272 | /* QLogic ISP2x00 Hardware Support Functions. */ | 343 | /* QLogic ISP2x00 Hardware Support Functions. */ |
273 | /****************************************************************************/ | 344 | /****************************************************************************/ |
@@ -2062,6 +2133,7 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) | |||
2062 | if (IS_QLA23XX(ha)) { | 2133 | if (IS_QLA23XX(ha)) { |
2063 | nv->firmware_options[0] |= BIT_2; | 2134 | nv->firmware_options[0] |= BIT_2; |
2064 | nv->firmware_options[0] &= ~BIT_3; | 2135 | nv->firmware_options[0] &= ~BIT_3; |
2136 | nv->firmware_options[0] &= ~BIT_6; | ||
2065 | nv->add_firmware_options[1] |= BIT_5 | BIT_4; | 2137 | nv->add_firmware_options[1] |= BIT_5 | BIT_4; |
2066 | 2138 | ||
2067 | if (IS_QLA2300(ha)) { | 2139 | if (IS_QLA2300(ha)) { |
@@ -2680,7 +2752,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
2680 | PORT_RETRY_TIME; | 2752 | PORT_RETRY_TIME; |
2681 | atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * | 2753 | atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * |
2682 | PORT_RETRY_TIME); | 2754 | PORT_RETRY_TIME); |
2683 | fcport->flags &= ~FCF_LOGIN_NEEDED; | 2755 | fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); |
2684 | 2756 | ||
2685 | qla2x00_iidma_fcport(vha, fcport); | 2757 | qla2x00_iidma_fcport(vha, fcport); |
2686 | 2758 | ||
@@ -3326,11 +3398,15 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
3326 | retry = 0; | 3398 | retry = 0; |
3327 | 3399 | ||
3328 | if (IS_ALOGIO_CAPABLE(ha)) { | 3400 | if (IS_ALOGIO_CAPABLE(ha)) { |
3401 | if (fcport->flags & FCF_ASYNC_SENT) | ||
3402 | return rval; | ||
3403 | fcport->flags |= FCF_ASYNC_SENT; | ||
3329 | rval = qla2x00_post_async_login_work(vha, fcport, NULL); | 3404 | rval = qla2x00_post_async_login_work(vha, fcport, NULL); |
3330 | if (!rval) | 3405 | if (!rval) |
3331 | return rval; | 3406 | return rval; |
3332 | } | 3407 | } |
3333 | 3408 | ||
3409 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
3334 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); | 3410 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); |
3335 | if (rval == QLA_SUCCESS) { | 3411 | if (rval == QLA_SUCCESS) { |
3336 | /* Send an ADISC to FCP2 devices.*/ | 3412 | /* Send an ADISC to FCP2 devices.*/ |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index d792ae32ed69..8112e41065f2 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1054,6 +1054,36 @@ qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx) | |||
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | static void | 1056 | static void |
1057 | qla24xx_adisc_iocb(srb_t *sp, struct logio_entry_24xx *logio) | ||
1058 | { | ||
1059 | logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; | ||
1060 | logio->control_flags = cpu_to_le16(LCF_COMMAND_ADISC); | ||
1061 | logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); | ||
1062 | logio->vp_index = sp->fcport->vp_idx; | ||
1063 | } | ||
1064 | |||
1065 | static void | ||
1066 | qla2x00_adisc_iocb(srb_t *sp, struct mbx_entry *mbx) | ||
1067 | { | ||
1068 | struct qla_hw_data *ha = sp->fcport->vha->hw; | ||
1069 | |||
1070 | mbx->entry_type = MBX_IOCB_TYPE; | ||
1071 | SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id); | ||
1072 | mbx->mb0 = cpu_to_le16(MBC_GET_PORT_DATABASE); | ||
1073 | if (HAS_EXTENDED_IDS(ha)) { | ||
1074 | mbx->mb1 = cpu_to_le16(sp->fcport->loop_id); | ||
1075 | mbx->mb10 = cpu_to_le16(BIT_0); | ||
1076 | } else { | ||
1077 | mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | BIT_0); | ||
1078 | } | ||
1079 | mbx->mb2 = cpu_to_le16(MSW(ha->async_pd_dma)); | ||
1080 | mbx->mb3 = cpu_to_le16(LSW(ha->async_pd_dma)); | ||
1081 | mbx->mb6 = cpu_to_le16(MSW(MSD(ha->async_pd_dma))); | ||
1082 | mbx->mb7 = cpu_to_le16(LSW(MSD(ha->async_pd_dma))); | ||
1083 | mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); | ||
1084 | } | ||
1085 | |||
1086 | static void | ||
1057 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | 1087 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) |
1058 | { | 1088 | { |
1059 | struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job; | 1089 | struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job; |
@@ -1185,12 +1215,12 @@ qla2x00_start_sp(srb_t *sp) | |||
1185 | switch (ctx->type) { | 1215 | switch (ctx->type) { |
1186 | case SRB_LOGIN_CMD: | 1216 | case SRB_LOGIN_CMD: |
1187 | IS_FWI2_CAPABLE(ha) ? | 1217 | IS_FWI2_CAPABLE(ha) ? |
1188 | qla24xx_login_iocb(sp, pkt): | 1218 | qla24xx_login_iocb(sp, pkt) : |
1189 | qla2x00_login_iocb(sp, pkt); | 1219 | qla2x00_login_iocb(sp, pkt); |
1190 | break; | 1220 | break; |
1191 | case SRB_LOGOUT_CMD: | 1221 | case SRB_LOGOUT_CMD: |
1192 | IS_FWI2_CAPABLE(ha) ? | 1222 | IS_FWI2_CAPABLE(ha) ? |
1193 | qla24xx_logout_iocb(sp, pkt): | 1223 | qla24xx_logout_iocb(sp, pkt) : |
1194 | qla2x00_logout_iocb(sp, pkt); | 1224 | qla2x00_logout_iocb(sp, pkt); |
1195 | break; | 1225 | break; |
1196 | case SRB_ELS_CMD_RPT: | 1226 | case SRB_ELS_CMD_RPT: |
@@ -1200,6 +1230,11 @@ qla2x00_start_sp(srb_t *sp) | |||
1200 | case SRB_CT_CMD: | 1230 | case SRB_CT_CMD: |
1201 | qla24xx_ct_iocb(sp, pkt); | 1231 | qla24xx_ct_iocb(sp, pkt); |
1202 | break; | 1232 | break; |
1233 | case SRB_ADISC_CMD: | ||
1234 | IS_FWI2_CAPABLE(ha) ? | ||
1235 | qla24xx_adisc_iocb(sp, pkt) : | ||
1236 | qla2x00_adisc_iocb(sp, pkt); | ||
1237 | break; | ||
1203 | default: | 1238 | default: |
1204 | break; | 1239 | break; |
1205 | } | 1240 | } |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 037bc41eef57..a1968eb5e9ce 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -899,6 +899,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
899 | srb_t *sp; | 899 | srb_t *sp; |
900 | struct srb_logio *lio; | 900 | struct srb_logio *lio; |
901 | uint16_t *data; | 901 | uint16_t *data; |
902 | uint16_t status; | ||
902 | 903 | ||
903 | sp = qla2x00_get_sp_from_handle(vha, func, req, mbx); | 904 | sp = qla2x00_get_sp_from_handle(vha, func, req, mbx); |
904 | if (!sp) | 905 | if (!sp) |
@@ -910,7 +911,9 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
910 | fcport = sp->fcport; | 911 | fcport = sp->fcport; |
911 | data = lio->data; | 912 | data = lio->data; |
912 | 913 | ||
913 | data[0] = data[1] = 0; | 914 | data[0] = MBS_COMMAND_ERROR; |
915 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
916 | QLA_LOGIO_LOGIN_RETRIED : 0; | ||
914 | if (mbx->entry_status) { | 917 | if (mbx->entry_status) { |
915 | DEBUG2(printk(KERN_WARNING | 918 | DEBUG2(printk(KERN_WARNING |
916 | "scsi(%ld:%x): Async-%s error entry - entry-status=%x " | 919 | "scsi(%ld:%x): Async-%s error entry - entry-status=%x " |
@@ -921,26 +924,27 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
921 | le16_to_cpu(mbx->status_flags))); | 924 | le16_to_cpu(mbx->status_flags))); |
922 | DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx))); | 925 | DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx))); |
923 | 926 | ||
924 | data[0] = MBS_COMMAND_ERROR; | ||
925 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
926 | QLA_LOGIO_LOGIN_RETRIED: 0; | ||
927 | goto logio_done; | 927 | goto logio_done; |
928 | } | 928 | } |
929 | 929 | ||
930 | if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { | 930 | status = le16_to_cpu(mbx->status); |
931 | if (status == 0x30 && lio->ctx.type == SRB_LOGIN_CMD && | ||
932 | le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) | ||
933 | status = 0; | ||
934 | if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { | ||
931 | DEBUG2(printk(KERN_DEBUG | 935 | DEBUG2(printk(KERN_DEBUG |
932 | "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n", | 936 | "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n", |
933 | fcport->vha->host_no, sp->handle, type, | 937 | fcport->vha->host_no, sp->handle, type, |
934 | le16_to_cpu(mbx->mb1))); | 938 | le16_to_cpu(mbx->mb1))); |
935 | 939 | ||
936 | data[0] = MBS_COMMAND_COMPLETE; | 940 | data[0] = MBS_COMMAND_COMPLETE; |
937 | if (lio->ctx.type == SRB_LOGIN_CMD) | 941 | if (lio->ctx.type == SRB_LOGIN_CMD) { |
938 | fcport->port_type = FCT_TARGET; | 942 | fcport->port_type = FCT_TARGET; |
939 | if (le16_to_cpu(mbx->mb1) & BIT_0) | 943 | if (le16_to_cpu(mbx->mb1) & BIT_0) |
940 | fcport->port_type = FCT_INITIATOR; | 944 | fcport->port_type = FCT_INITIATOR; |
941 | if (le16_to_cpu(mbx->mb1) & BIT_1) | 945 | if (le16_to_cpu(mbx->mb1) & BIT_1) |
942 | fcport->flags |= FCF_FCP2_DEVICE; | 946 | fcport->flags |= FCF_FCP2_DEVICE; |
943 | 947 | } | |
944 | goto logio_done; | 948 | goto logio_done; |
945 | } | 949 | } |
946 | 950 | ||
@@ -953,15 +957,13 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
953 | break; | 957 | break; |
954 | default: | 958 | default: |
955 | data[0] = MBS_COMMAND_ERROR; | 959 | data[0] = MBS_COMMAND_ERROR; |
956 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
957 | QLA_LOGIO_LOGIN_RETRIED: 0; | ||
958 | break; | 960 | break; |
959 | } | 961 | } |
960 | 962 | ||
961 | DEBUG2(printk(KERN_WARNING | 963 | DEBUG2(printk(KERN_WARNING |
962 | "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x " | 964 | "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x " |
963 | "mb6=%x mb7=%x.\n", | 965 | "mb6=%x mb7=%x.\n", |
964 | fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status), | 966 | fcport->vha->host_no, sp->handle, type, status, |
965 | le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1), | 967 | le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1), |
966 | le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6), | 968 | le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6), |
967 | le16_to_cpu(mbx->mb7))); | 969 | le16_to_cpu(mbx->mb7))); |
@@ -1086,7 +1088,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1086 | fcport = sp->fcport; | 1088 | fcport = sp->fcport; |
1087 | data = lio->data; | 1089 | data = lio->data; |
1088 | 1090 | ||
1089 | data[0] = data[1] = 0; | 1091 | data[0] = MBS_COMMAND_ERROR; |
1092 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
1093 | QLA_LOGIO_LOGIN_RETRIED : 0; | ||
1090 | if (logio->entry_status) { | 1094 | if (logio->entry_status) { |
1091 | DEBUG2(printk(KERN_WARNING | 1095 | DEBUG2(printk(KERN_WARNING |
1092 | "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n", | 1096 | "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n", |
@@ -1094,9 +1098,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1094 | logio->entry_status)); | 1098 | logio->entry_status)); |
1095 | DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio))); | 1099 | DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio))); |
1096 | 1100 | ||
1097 | data[0] = MBS_COMMAND_ERROR; | ||
1098 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
1099 | QLA_LOGIO_LOGIN_RETRIED: 0; | ||
1100 | goto logio_done; | 1101 | goto logio_done; |
1101 | } | 1102 | } |
1102 | 1103 | ||
@@ -1107,7 +1108,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1107 | le32_to_cpu(logio->io_parameter[0]))); | 1108 | le32_to_cpu(logio->io_parameter[0]))); |
1108 | 1109 | ||
1109 | data[0] = MBS_COMMAND_COMPLETE; | 1110 | data[0] = MBS_COMMAND_COMPLETE; |
1110 | if (lio->ctx.type == SRB_LOGOUT_CMD) | 1111 | if (lio->ctx.type != SRB_LOGIN_CMD) |
1111 | goto logio_done; | 1112 | goto logio_done; |
1112 | 1113 | ||
1113 | iop[0] = le32_to_cpu(logio->io_parameter[0]); | 1114 | iop[0] = le32_to_cpu(logio->io_parameter[0]); |
@@ -1144,8 +1145,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1144 | /* Fall through. */ | 1145 | /* Fall through. */ |
1145 | default: | 1146 | default: |
1146 | data[0] = MBS_COMMAND_ERROR; | 1147 | data[0] = MBS_COMMAND_ERROR; |
1147 | data[1] = lio->flags & SRB_LOGIN_RETRIED ? | ||
1148 | QLA_LOGIO_LOGIN_RETRIED: 0; | ||
1149 | break; | 1148 | break; |
1150 | } | 1149 | } |
1151 | 1150 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 10c14af2235b..2e083c0d9215 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2639,9 +2639,19 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
2639 | 2639 | ||
2640 | INIT_LIST_HEAD(&ha->gbl_dsd_list); | 2640 | INIT_LIST_HEAD(&ha->gbl_dsd_list); |
2641 | 2641 | ||
2642 | /* Get consistent memory allocated for Async Port-Database. */ | ||
2643 | if (!IS_FWI2_CAPABLE(ha)) { | ||
2644 | ha->async_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | ||
2645 | &ha->async_pd_dma); | ||
2646 | if (!ha->async_pd) | ||
2647 | goto fail_async_pd; | ||
2648 | } | ||
2649 | |||
2642 | INIT_LIST_HEAD(&ha->vp_list); | 2650 | INIT_LIST_HEAD(&ha->vp_list); |
2643 | return 1; | 2651 | return 1; |
2644 | 2652 | ||
2653 | fail_async_pd: | ||
2654 | dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); | ||
2645 | fail_ex_init_cb: | 2655 | fail_ex_init_cb: |
2646 | kfree(ha->npiv_info); | 2656 | kfree(ha->npiv_info); |
2647 | fail_npiv_info: | 2657 | fail_npiv_info: |
@@ -2757,6 +2767,9 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
2757 | dma_pool_free(ha->s_dma_pool, | 2767 | dma_pool_free(ha->s_dma_pool, |
2758 | ha->ex_init_cb, ha->ex_init_cb_dma); | 2768 | ha->ex_init_cb, ha->ex_init_cb_dma); |
2759 | 2769 | ||
2770 | if (ha->async_pd) | ||
2771 | dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); | ||
2772 | |||
2760 | if (ha->s_dma_pool) | 2773 | if (ha->s_dma_pool) |
2761 | dma_pool_destroy(ha->s_dma_pool); | 2774 | dma_pool_destroy(ha->s_dma_pool); |
2762 | 2775 | ||
@@ -2809,6 +2822,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
2809 | ha->init_cb_dma = 0; | 2822 | ha->init_cb_dma = 0; |
2810 | ha->ex_init_cb = NULL; | 2823 | ha->ex_init_cb = NULL; |
2811 | ha->ex_init_cb_dma = 0; | 2824 | ha->ex_init_cb_dma = 0; |
2825 | ha->async_pd = NULL; | ||
2826 | ha->async_pd_dma = 0; | ||
2812 | 2827 | ||
2813 | ha->s_dma_pool = NULL; | 2828 | ha->s_dma_pool = NULL; |
2814 | ha->dl_dma_pool = NULL; | 2829 | ha->dl_dma_pool = NULL; |
@@ -2935,6 +2950,8 @@ qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN); | |||
2935 | qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE); | 2950 | qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE); |
2936 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); | 2951 | qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); |
2937 | qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); | 2952 | qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); |
2953 | qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC); | ||
2954 | qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE); | ||
2938 | 2955 | ||
2939 | int | 2956 | int |
2940 | qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code) | 2957 | qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code) |
@@ -3004,6 +3021,14 @@ qla2x00_do_work(struct scsi_qla_host *vha) | |||
3004 | qla2x00_async_logout_done(vha, e->u.logio.fcport, | 3021 | qla2x00_async_logout_done(vha, e->u.logio.fcport, |
3005 | e->u.logio.data); | 3022 | e->u.logio.data); |
3006 | break; | 3023 | break; |
3024 | case QLA_EVT_ASYNC_ADISC: | ||
3025 | qla2x00_async_adisc(vha, e->u.logio.fcport, | ||
3026 | e->u.logio.data); | ||
3027 | break; | ||
3028 | case QLA_EVT_ASYNC_ADISC_DONE: | ||
3029 | qla2x00_async_adisc_done(vha, e->u.logio.fcport, | ||
3030 | e->u.logio.data); | ||
3031 | break; | ||
3007 | case QLA_EVT_UEVENT: | 3032 | case QLA_EVT_UEVENT: |
3008 | qla2x00_uevent_emit(vha, e->u.uevent.code); | 3033 | qla2x00_uevent_emit(vha, e->u.uevent.code); |
3009 | break; | 3034 | break; |
@@ -3029,9 +3054,8 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | |||
3029 | * If the port is not ONLINE then try to login | 3054 | * If the port is not ONLINE then try to login |
3030 | * to it if we haven't run out of retries. | 3055 | * to it if we haven't run out of retries. |
3031 | */ | 3056 | */ |
3032 | if (atomic_read(&fcport->state) != | 3057 | if (atomic_read(&fcport->state) != FCS_ONLINE && |
3033 | FCS_ONLINE && fcport->login_retry) { | 3058 | fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) { |
3034 | |||
3035 | fcport->login_retry--; | 3059 | fcport->login_retry--; |
3036 | if (fcport->flags & FCF_FABRIC_DEVICE) { | 3060 | if (fcport->flags & FCF_FABRIC_DEVICE) { |
3037 | if (fcport->flags & FCF_FCP2_DEVICE) | 3061 | if (fcport->flags & FCF_FCP2_DEVICE) |
@@ -3042,6 +3066,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | |||
3042 | fcport->d_id.b.al_pa); | 3066 | fcport->d_id.b.al_pa); |
3043 | 3067 | ||
3044 | if (IS_ALOGIO_CAPABLE(ha)) { | 3068 | if (IS_ALOGIO_CAPABLE(ha)) { |
3069 | fcport->flags |= FCF_ASYNC_SENT; | ||
3045 | data[0] = 0; | 3070 | data[0] = 0; |
3046 | data[1] = QLA_LOGIO_LOGIN_RETRIED; | 3071 | data[1] = QLA_LOGIO_LOGIN_RETRIED; |
3047 | status = qla2x00_post_async_login_work( | 3072 | status = qla2x00_post_async_login_work( |