diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 22 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 156 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 64 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 102 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 5 |
8 files changed, 366 insertions, 4 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 951db816ee45..b905dfe5ea61 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -317,6 +317,9 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) | |||
317 | els->type = | 317 | els->type = |
318 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? | 318 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? |
319 | SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); | 319 | SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST); |
320 | els->name = | ||
321 | (bsg_job->request->msgcode == FC_BSG_RPT_ELS ? | ||
322 | "bsg_els_rpt" : "bsg_els_hst"); | ||
320 | els->u.bsg_job = bsg_job; | 323 | els->u.bsg_job = bsg_job; |
321 | 324 | ||
322 | DEBUG2(qla_printk(KERN_INFO, ha, | 325 | DEBUG2(qla_printk(KERN_INFO, ha, |
@@ -450,6 +453,7 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job) | |||
450 | 453 | ||
451 | ct = sp->ctx; | 454 | ct = sp->ctx; |
452 | ct->type = SRB_CT_CMD; | 455 | ct->type = SRB_CT_CMD; |
456 | ct->name = "bsg_ct"; | ||
453 | ct->u.bsg_job = bsg_job; | 457 | ct->u.bsg_job = bsg_job; |
454 | 458 | ||
455 | DEBUG2(qla_printk(KERN_INFO, ha, | 459 | DEBUG2(qla_printk(KERN_INFO, ha, |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 08f5fd5359dd..0d2cecbb8f47 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -223,6 +223,26 @@ struct srb_iocb { | |||
223 | #define SRB_LOGIN_SKIP_PRLI BIT_2 | 223 | #define SRB_LOGIN_SKIP_PRLI BIT_2 |
224 | uint16_t data[2]; | 224 | uint16_t data[2]; |
225 | } logio; | 225 | } logio; |
226 | struct { | ||
227 | /* | ||
228 | * Values for flags field below are as | ||
229 | * defined in tsk_mgmt_entry struct | ||
230 | * for control_flags field in qla_fw.h. | ||
231 | */ | ||
232 | uint32_t flags; | ||
233 | uint32_t lun; | ||
234 | uint32_t data; | ||
235 | } tmf; | ||
236 | struct { | ||
237 | /* | ||
238 | * values for modif field below are as | ||
239 | * defined in mrk_entry_24xx struct | ||
240 | * for the modifier field in qla_fw.h. | ||
241 | */ | ||
242 | uint8_t modif; | ||
243 | uint16_t lun; | ||
244 | uint32_t data; | ||
245 | } marker; | ||
226 | } u; | 246 | } u; |
227 | 247 | ||
228 | struct timer_list timer; | 248 | struct timer_list timer; |
@@ -239,6 +259,8 @@ struct srb_iocb { | |||
239 | #define SRB_ELS_CMD_HST 4 | 259 | #define SRB_ELS_CMD_HST 4 |
240 | #define SRB_CT_CMD 5 | 260 | #define SRB_CT_CMD 5 |
241 | #define SRB_ADISC_CMD 6 | 261 | #define SRB_ADISC_CMD 6 |
262 | #define SRB_TM_CMD 7 | ||
263 | #define SRB_MARKER_CMD 8 | ||
242 | 264 | ||
243 | struct srb_ctx { | 265 | struct srb_ctx { |
244 | uint16_t type; | 266 | uint16_t type; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 408e5f0a53c1..3dbefe1a6b5f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -58,12 +58,18 @@ extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_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 *, | 59 | extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, |
60 | uint16_t *); | 60 | uint16_t *); |
61 | extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t); | ||
62 | extern int qla2x00_async_marker(fc_port_t *, uint16_t, uint8_t); | ||
61 | extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, | 63 | extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, |
62 | uint16_t *); | 64 | uint16_t *); |
63 | extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, | 65 | extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, |
64 | uint16_t *); | 66 | uint16_t *); |
65 | extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, | 67 | extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, |
66 | uint16_t *); | 68 | uint16_t *); |
69 | extern void qla2x00_async_tm_cmd_done(struct scsi_qla_host *, fc_port_t *, | ||
70 | struct srb_iocb *); | ||
71 | extern void qla2x00_async_marker_done(struct scsi_qla_host *, fc_port_t *, | ||
72 | struct srb_iocb *); | ||
67 | 73 | ||
68 | extern fc_port_t * | 74 | extern fc_port_t * |
69 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); | 75 | qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); |
@@ -87,6 +93,7 @@ extern int ql2xetsenable; | |||
87 | extern int ql2xshiftctondsd; | 93 | extern int ql2xshiftctondsd; |
88 | extern int ql2xdbwr; | 94 | extern int ql2xdbwr; |
89 | extern int ql2xdontresethba; | 95 | extern int ql2xdontresethba; |
96 | extern int ql2xasynctmfenable; | ||
90 | 97 | ||
91 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 98 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
92 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 99 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 72b4ef270158..e78089ded517 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -125,7 +125,7 @@ done: | |||
125 | #define ELS_TMO_2_RATOV(ha) ((ha)->r_a_tov / 10 * 2) | 125 | #define ELS_TMO_2_RATOV(ha) ((ha)->r_a_tov / 10 * 2) |
126 | 126 | ||
127 | static void | 127 | static void |
128 | qla2x00_async_logio_timeout(srb_t *sp) | 128 | qla2x00_async_iocb_timeout(srb_t *sp) |
129 | { | 129 | { |
130 | fc_port_t *fcport = sp->fcport; | 130 | fc_port_t *fcport = sp->fcport; |
131 | struct srb_ctx *ctx = sp->ctx; | 131 | struct srb_ctx *ctx = sp->ctx; |
@@ -170,7 +170,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
170 | ctx->type = SRB_LOGIN_CMD; | 170 | ctx->type = SRB_LOGIN_CMD; |
171 | ctx->name = "login"; | 171 | ctx->name = "login"; |
172 | lio = ctx->u.iocb_cmd; | 172 | lio = ctx->u.iocb_cmd; |
173 | lio->timeout = qla2x00_async_logio_timeout; | 173 | lio->timeout = qla2x00_async_iocb_timeout; |
174 | lio->done = qla2x00_async_login_ctx_done; | 174 | lio->done = qla2x00_async_login_ctx_done; |
175 | lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; | 175 | lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; |
176 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 176 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
@@ -222,7 +222,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
222 | ctx->type = SRB_LOGOUT_CMD; | 222 | ctx->type = SRB_LOGOUT_CMD; |
223 | ctx->name = "logout"; | 223 | ctx->name = "logout"; |
224 | lio = ctx->u.iocb_cmd; | 224 | lio = ctx->u.iocb_cmd; |
225 | lio->timeout = qla2x00_async_logio_timeout; | 225 | lio->timeout = qla2x00_async_iocb_timeout; |
226 | lio->done = qla2x00_async_logout_ctx_done; | 226 | lio->done = qla2x00_async_logout_ctx_done; |
227 | rval = qla2x00_start_sp(sp); | 227 | rval = qla2x00_start_sp(sp); |
228 | if (rval != QLA_SUCCESS) | 228 | if (rval != QLA_SUCCESS) |
@@ -271,7 +271,7 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
271 | ctx->type = SRB_ADISC_CMD; | 271 | ctx->type = SRB_ADISC_CMD; |
272 | ctx->name = "adisc"; | 272 | ctx->name = "adisc"; |
273 | lio = ctx->u.iocb_cmd; | 273 | lio = ctx->u.iocb_cmd; |
274 | lio->timeout = qla2x00_async_logio_timeout; | 274 | lio->timeout = qla2x00_async_iocb_timeout; |
275 | lio->done = qla2x00_async_adisc_ctx_done; | 275 | lio->done = qla2x00_async_adisc_ctx_done; |
276 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 276 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
277 | lio->u.logio.flags |= SRB_LOGIN_RETRIED; | 277 | lio->u.logio.flags |= SRB_LOGIN_RETRIED; |
@@ -292,6 +292,112 @@ done: | |||
292 | return rval; | 292 | return rval; |
293 | } | 293 | } |
294 | 294 | ||
295 | static void | ||
296 | qla2x00_async_tm_cmd_ctx_done(srb_t *sp) | ||
297 | { | ||
298 | struct srb_ctx *ctx = sp->ctx; | ||
299 | struct srb_iocb *iocb = (struct srb_iocb *)ctx->u.iocb_cmd; | ||
300 | |||
301 | qla2x00_async_tm_cmd_done(sp->fcport->vha, sp->fcport, iocb); | ||
302 | iocb->free(sp); | ||
303 | } | ||
304 | |||
305 | int | ||
306 | qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, | ||
307 | uint32_t tag) | ||
308 | { | ||
309 | struct scsi_qla_host *vha = fcport->vha; | ||
310 | struct qla_hw_data *ha = vha->hw; | ||
311 | srb_t *sp; | ||
312 | struct srb_ctx *ctx; | ||
313 | struct srb_iocb *tcf; | ||
314 | int rval; | ||
315 | |||
316 | rval = QLA_FUNCTION_FAILED; | ||
317 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), | ||
318 | ELS_TMO_2_RATOV(ha) + 2); | ||
319 | if (!sp) | ||
320 | goto done; | ||
321 | |||
322 | ctx = sp->ctx; | ||
323 | ctx->type = SRB_TM_CMD; | ||
324 | ctx->name = "tmf"; | ||
325 | tcf = ctx->u.iocb_cmd; | ||
326 | tcf->u.tmf.flags = flags; | ||
327 | tcf->u.tmf.lun = lun; | ||
328 | tcf->u.tmf.data = tag; | ||
329 | tcf->timeout = qla2x00_async_iocb_timeout; | ||
330 | tcf->done = qla2x00_async_tm_cmd_ctx_done; | ||
331 | |||
332 | rval = qla2x00_start_sp(sp); | ||
333 | if (rval != QLA_SUCCESS) | ||
334 | goto done_free_sp; | ||
335 | |||
336 | DEBUG2(printk(KERN_DEBUG | ||
337 | "scsi(%ld:%x): Async-tmf - loop-id=%x portid=%02x%02x%02x.\n", | ||
338 | fcport->vha->host_no, sp->handle, fcport->loop_id, | ||
339 | fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa)); | ||
340 | |||
341 | return rval; | ||
342 | |||
343 | done_free_sp: | ||
344 | tcf->free(sp); | ||
345 | done: | ||
346 | return rval; | ||
347 | } | ||
348 | |||
349 | static void | ||
350 | qla2x00_async_marker_ctx_done(srb_t *sp) | ||
351 | { | ||
352 | struct srb_ctx *ctx = sp->ctx; | ||
353 | struct srb_iocb *iocb = (struct srb_iocb *)ctx->u.iocb_cmd; | ||
354 | |||
355 | qla2x00_async_marker_done(sp->fcport->vha, sp->fcport, iocb); | ||
356 | iocb->free(sp); | ||
357 | } | ||
358 | |||
359 | int | ||
360 | qla2x00_async_marker(fc_port_t *fcport, uint16_t lun, uint8_t modif) | ||
361 | { | ||
362 | struct scsi_qla_host *vha = fcport->vha; | ||
363 | srb_t *sp; | ||
364 | struct srb_ctx *ctx; | ||
365 | struct srb_iocb *mrk; | ||
366 | int rval; | ||
367 | |||
368 | rval = QLA_FUNCTION_FAILED; | ||
369 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), 0); | ||
370 | if (!sp) | ||
371 | goto done; | ||
372 | |||
373 | ctx = sp->ctx; | ||
374 | ctx->type = SRB_MARKER_CMD; | ||
375 | ctx->name = "marker"; | ||
376 | mrk = ctx->u.iocb_cmd; | ||
377 | mrk->u.marker.lun = lun; | ||
378 | mrk->u.marker.modif = modif; | ||
379 | mrk->timeout = qla2x00_async_iocb_timeout; | ||
380 | mrk->done = qla2x00_async_marker_ctx_done; | ||
381 | |||
382 | rval = qla2x00_start_sp(sp); | ||
383 | if (rval != QLA_SUCCESS) | ||
384 | goto done_free_sp; | ||
385 | |||
386 | DEBUG2(printk(KERN_DEBUG | ||
387 | "scsi(%ld:%x): Async-marker - loop-id=%x " | ||
388 | "portid=%02x%02x%02x.\n", | ||
389 | fcport->vha->host_no, sp->handle, fcport->loop_id, | ||
390 | fcport->d_id.b.domain, fcport->d_id.b.area, | ||
391 | fcport->d_id.b.al_pa)); | ||
392 | |||
393 | return rval; | ||
394 | |||
395 | done_free_sp: | ||
396 | mrk->free(sp); | ||
397 | done: | ||
398 | return rval; | ||
399 | } | ||
400 | |||
295 | void | 401 | void |
296 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 402 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
297 | uint16_t *data) | 403 | uint16_t *data) |
@@ -360,6 +466,48 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
360 | return; | 466 | return; |
361 | } | 467 | } |
362 | 468 | ||
469 | void | ||
470 | qla2x00_async_tm_cmd_done(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
471 | struct srb_iocb *iocb) | ||
472 | { | ||
473 | int rval; | ||
474 | uint32_t flags; | ||
475 | uint16_t lun; | ||
476 | |||
477 | flags = iocb->u.tmf.flags; | ||
478 | lun = (uint16_t)iocb->u.tmf.lun; | ||
479 | |||
480 | /* Issue Marker IOCB */ | ||
481 | rval = qla2x00_async_marker(fcport, lun, | ||
482 | flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID); | ||
483 | |||
484 | if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) { | ||
485 | DEBUG2_3_11(printk(KERN_WARNING | ||
486 | "%s(%ld): TM IOCB failed (%x).\n", | ||
487 | __func__, vha->host_no, rval)); | ||
488 | } | ||
489 | |||
490 | return; | ||
491 | } | ||
492 | |||
493 | void | ||
494 | qla2x00_async_marker_done(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
495 | struct srb_iocb *iocb) | ||
496 | { | ||
497 | /* | ||
498 | * Currently we dont have any specific post response processing | ||
499 | * for this IOCB. We'll just return success or failed | ||
500 | * depending on whether the IOCB command succeeded or failed. | ||
501 | */ | ||
502 | if (iocb->u.tmf.data) { | ||
503 | DEBUG2_3_11(printk(KERN_WARNING | ||
504 | "%s(%ld): Marker IOCB failed (%x).\n", | ||
505 | __func__, vha->host_no, iocb->u.tmf.data)); | ||
506 | } | ||
507 | |||
508 | return; | ||
509 | } | ||
510 | |||
363 | /****************************************************************************/ | 511 | /****************************************************************************/ |
364 | /* QLogic ISP2x00 Hardware Support Functions. */ | 512 | /* QLogic ISP2x00 Hardware Support Functions. */ |
365 | /****************************************************************************/ | 513 | /****************************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8861b88319fb..d7a9fff15ad5 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1086,6 +1086,64 @@ qla2x00_adisc_iocb(srb_t *sp, struct mbx_entry *mbx) | |||
1086 | } | 1086 | } |
1087 | 1087 | ||
1088 | static void | 1088 | static void |
1089 | qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk) | ||
1090 | { | ||
1091 | uint32_t flags; | ||
1092 | unsigned int lun; | ||
1093 | struct fc_port *fcport = sp->fcport; | ||
1094 | scsi_qla_host_t *vha = fcport->vha; | ||
1095 | struct qla_hw_data *ha = vha->hw; | ||
1096 | struct srb_ctx *ctx = sp->ctx; | ||
1097 | struct srb_iocb *iocb = ctx->u.iocb_cmd; | ||
1098 | struct req_que *req = vha->req; | ||
1099 | |||
1100 | flags = iocb->u.tmf.flags; | ||
1101 | lun = iocb->u.tmf.lun; | ||
1102 | |||
1103 | tsk->entry_type = TSK_MGMT_IOCB_TYPE; | ||
1104 | tsk->entry_count = 1; | ||
1105 | tsk->handle = MAKE_HANDLE(req->id, tsk->handle); | ||
1106 | tsk->nport_handle = cpu_to_le16(fcport->loop_id); | ||
1107 | tsk->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | ||
1108 | tsk->control_flags = cpu_to_le32(flags); | ||
1109 | tsk->port_id[0] = fcport->d_id.b.al_pa; | ||
1110 | tsk->port_id[1] = fcport->d_id.b.area; | ||
1111 | tsk->port_id[2] = fcport->d_id.b.domain; | ||
1112 | tsk->vp_index = fcport->vp_idx; | ||
1113 | |||
1114 | if (flags == TCF_LUN_RESET) { | ||
1115 | int_to_scsilun(lun, &tsk->lun); | ||
1116 | host_to_fcp_swap((uint8_t *)&tsk->lun, | ||
1117 | sizeof(tsk->lun)); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | static void | ||
1122 | qla24xx_marker_iocb(srb_t *sp, struct mrk_entry_24xx *mrk) | ||
1123 | { | ||
1124 | uint16_t lun; | ||
1125 | uint8_t modif; | ||
1126 | struct fc_port *fcport = sp->fcport; | ||
1127 | scsi_qla_host_t *vha = fcport->vha; | ||
1128 | struct srb_ctx *ctx = sp->ctx; | ||
1129 | struct srb_iocb *iocb = ctx->u.iocb_cmd; | ||
1130 | struct req_que *req = vha->req; | ||
1131 | |||
1132 | lun = iocb->u.marker.lun; | ||
1133 | modif = iocb->u.marker.modif; | ||
1134 | mrk->entry_type = MARKER_TYPE; | ||
1135 | mrk->modifier = modif; | ||
1136 | if (modif != MK_SYNC_ALL) { | ||
1137 | mrk->nport_handle = cpu_to_le16(fcport->loop_id); | ||
1138 | mrk->lun[1] = LSB(lun); | ||
1139 | mrk->lun[2] = MSB(lun); | ||
1140 | host_to_fcp_swap(mrk->lun, sizeof(mrk->lun)); | ||
1141 | mrk->vp_index = vha->vp_idx; | ||
1142 | mrk->handle = MAKE_HANDLE(req->id, mrk->handle); | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | static void | ||
1089 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | 1147 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) |
1090 | { | 1148 | { |
1091 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; | 1149 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; |
@@ -1239,6 +1297,12 @@ qla2x00_start_sp(srb_t *sp) | |||
1239 | qla24xx_adisc_iocb(sp, pkt) : | 1297 | qla24xx_adisc_iocb(sp, pkt) : |
1240 | qla2x00_adisc_iocb(sp, pkt); | 1298 | qla2x00_adisc_iocb(sp, pkt); |
1241 | break; | 1299 | break; |
1300 | case SRB_TM_CMD: | ||
1301 | qla24xx_tm_iocb(sp, pkt); | ||
1302 | break; | ||
1303 | case SRB_MARKER_CMD: | ||
1304 | qla24xx_marker_iocb(sp, pkt); | ||
1305 | break; | ||
1242 | default: | 1306 | default: |
1243 | break; | 1307 | break; |
1244 | } | 1308 | } |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 166bb2045fd4..eed71ea1d947 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1161,6 +1161,99 @@ logio_done: | |||
1161 | lio->done(sp); | 1161 | lio->done(sp); |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static void | ||
1165 | qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | ||
1166 | struct tsk_mgmt_entry *tsk) | ||
1167 | { | ||
1168 | const char func[] = "TMF-IOCB"; | ||
1169 | const char *type; | ||
1170 | fc_port_t *fcport; | ||
1171 | srb_t *sp; | ||
1172 | struct srb_iocb *iocb; | ||
1173 | struct srb_ctx *ctx; | ||
1174 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; | ||
1175 | int error = 1; | ||
1176 | |||
1177 | sp = qla2x00_get_sp_from_handle(vha, func, req, tsk); | ||
1178 | if (!sp) | ||
1179 | return; | ||
1180 | |||
1181 | ctx = sp->ctx; | ||
1182 | iocb = ctx->u.iocb_cmd; | ||
1183 | type = ctx->name; | ||
1184 | fcport = sp->fcport; | ||
1185 | |||
1186 | if (sts->entry_status) { | ||
1187 | DEBUG2(printk(KERN_WARNING | ||
1188 | "scsi(%ld:%x): Async-%s error - entry-status(%x).\n", | ||
1189 | fcport->vha->host_no, sp->handle, type, | ||
1190 | sts->entry_status)); | ||
1191 | } else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { | ||
1192 | DEBUG2(printk(KERN_WARNING | ||
1193 | "scsi(%ld:%x): Async-%s error - completion status(%x).\n", | ||
1194 | fcport->vha->host_no, sp->handle, type, | ||
1195 | sts->comp_status)); | ||
1196 | } else if (!(le16_to_cpu(sts->scsi_status) & | ||
1197 | SS_RESPONSE_INFO_LEN_VALID)) { | ||
1198 | DEBUG2(printk(KERN_WARNING | ||
1199 | "scsi(%ld:%x): Async-%s error - no response info(%x).\n", | ||
1200 | fcport->vha->host_no, sp->handle, type, | ||
1201 | sts->scsi_status)); | ||
1202 | } else if (le32_to_cpu(sts->rsp_data_len) < 4) { | ||
1203 | DEBUG2(printk(KERN_WARNING | ||
1204 | "scsi(%ld:%x): Async-%s error - not enough response(%d).\n", | ||
1205 | fcport->vha->host_no, sp->handle, type, | ||
1206 | sts->rsp_data_len)); | ||
1207 | } else if (sts->data[3]) { | ||
1208 | DEBUG2(printk(KERN_WARNING | ||
1209 | "scsi(%ld:%x): Async-%s error - response(%x).\n", | ||
1210 | fcport->vha->host_no, sp->handle, type, | ||
1211 | sts->data[3])); | ||
1212 | } else { | ||
1213 | error = 0; | ||
1214 | } | ||
1215 | |||
1216 | if (error) { | ||
1217 | iocb->u.tmf.data = error; | ||
1218 | DEBUG2(qla2x00_dump_buffer((uint8_t *)sts, sizeof(*sts))); | ||
1219 | } | ||
1220 | |||
1221 | iocb->done(sp); | ||
1222 | } | ||
1223 | |||
1224 | static void | ||
1225 | qla24xx_marker_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | ||
1226 | struct mrk_entry_24xx *mrk) | ||
1227 | { | ||
1228 | const char func[] = "MRK-IOCB"; | ||
1229 | const char *type; | ||
1230 | fc_port_t *fcport; | ||
1231 | srb_t *sp; | ||
1232 | struct srb_iocb *iocb; | ||
1233 | struct srb_ctx *ctx; | ||
1234 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)mrk; | ||
1235 | |||
1236 | sp = qla2x00_get_sp_from_handle(vha, func, req, mrk); | ||
1237 | if (!sp) | ||
1238 | return; | ||
1239 | |||
1240 | ctx = sp->ctx; | ||
1241 | iocb = ctx->u.iocb_cmd; | ||
1242 | type = ctx->name; | ||
1243 | fcport = sp->fcport; | ||
1244 | |||
1245 | if (sts->entry_status) { | ||
1246 | iocb->u.marker.data = 1; | ||
1247 | DEBUG2(printk(KERN_WARNING | ||
1248 | "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n", | ||
1249 | fcport->vha->host_no, sp->handle, type, | ||
1250 | sts->entry_status)); | ||
1251 | DEBUG2(qla2x00_dump_buffer((uint8_t *)mrk, sizeof(*sts))); | ||
1252 | } | ||
1253 | |||
1254 | iocb->done(sp); | ||
1255 | } | ||
1256 | |||
1164 | /** | 1257 | /** |
1165 | * qla2x00_process_response_queue() - Process response queue entries. | 1258 | * qla2x00_process_response_queue() - Process response queue entries. |
1166 | * @ha: SCSI driver HA context | 1259 | * @ha: SCSI driver HA context |
@@ -1225,6 +1318,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
1225 | case MBX_IOCB_TYPE: | 1318 | case MBX_IOCB_TYPE: |
1226 | qla2x00_mbx_iocb_entry(vha, rsp->req, | 1319 | qla2x00_mbx_iocb_entry(vha, rsp->req, |
1227 | (struct mbx_entry *)pkt); | 1320 | (struct mbx_entry *)pkt); |
1321 | break; | ||
1228 | default: | 1322 | default: |
1229 | /* Type Not Supported. */ | 1323 | /* Type Not Supported. */ |
1230 | DEBUG4(printk(KERN_WARNING | 1324 | DEBUG4(printk(KERN_WARNING |
@@ -1751,6 +1845,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, | |||
1751 | qla24xx_logio_entry(vha, rsp->req, | 1845 | qla24xx_logio_entry(vha, rsp->req, |
1752 | (struct logio_entry_24xx *)pkt); | 1846 | (struct logio_entry_24xx *)pkt); |
1753 | break; | 1847 | break; |
1848 | case TSK_MGMT_IOCB_TYPE: | ||
1849 | qla24xx_tm_iocb_entry(vha, rsp->req, | ||
1850 | (struct tsk_mgmt_entry *)pkt); | ||
1851 | break; | ||
1852 | case MARKER_TYPE: | ||
1853 | qla24xx_marker_iocb_entry(vha, rsp->req, | ||
1854 | (struct mrk_entry_24xx *)pkt); | ||
1855 | break; | ||
1754 | case CT_IOCB_TYPE: | 1856 | case CT_IOCB_TYPE: |
1755 | qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); | 1857 | qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); |
1756 | clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags); | 1858 | clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags); |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 2f3033228061..f3650d0434ca 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2464,12 +2464,22 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, | |||
2464 | int | 2464 | int |
2465 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag) | 2465 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag) |
2466 | { | 2466 | { |
2467 | struct qla_hw_data *ha = fcport->vha->hw; | ||
2468 | |||
2469 | if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) | ||
2470 | return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag); | ||
2471 | |||
2467 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag); | 2472 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag); |
2468 | } | 2473 | } |
2469 | 2474 | ||
2470 | int | 2475 | int |
2471 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag) | 2476 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag) |
2472 | { | 2477 | { |
2478 | struct qla_hw_data *ha = fcport->vha->hw; | ||
2479 | |||
2480 | if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha)) | ||
2481 | return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag); | ||
2482 | |||
2473 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag); | 2483 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag); |
2474 | } | 2484 | } |
2475 | 2485 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 70651f9fa653..523d414b59af 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -142,6 +142,11 @@ MODULE_PARM_DESC(ql2xdontresethba, | |||
142 | " 1 -- Do not reset on failure.\n"); | 142 | " 1 -- Do not reset on failure.\n"); |
143 | 143 | ||
144 | 144 | ||
145 | int ql2xasynctmfenable; | ||
146 | module_param(ql2xasynctmfenable, int, S_IRUGO|S_IRUSR); | ||
147 | MODULE_PARM_DESC(ql2xasynctmfenable, | ||
148 | "Enables issue of TM IOCBs asynchronously via IOCB mechanism" | ||
149 | "Default is 0 - Issue TM IOCBs via mailbox mechanism."); | ||
145 | /* | 150 | /* |
146 | * SCSI host template entry points | 151 | * SCSI host template entry points |
147 | */ | 152 | */ |