aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h22
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h7
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c156
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c64
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c102
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c5
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
243struct srb_ctx { 265struct 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 *,
58extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *); 58extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
59extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, 59extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
60 uint16_t *); 60 uint16_t *);
61extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
62extern int qla2x00_async_marker(fc_port_t *, uint16_t, uint8_t);
61extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, 63extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
62 uint16_t *); 64 uint16_t *);
63extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, 65extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
64 uint16_t *); 66 uint16_t *);
65extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, 67extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
66 uint16_t *); 68 uint16_t *);
69extern void qla2x00_async_tm_cmd_done(struct scsi_qla_host *, fc_port_t *,
70 struct srb_iocb *);
71extern void qla2x00_async_marker_done(struct scsi_qla_host *, fc_port_t *,
72 struct srb_iocb *);
67 73
68extern fc_port_t * 74extern fc_port_t *
69qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); 75qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
@@ -87,6 +93,7 @@ extern int ql2xetsenable;
87extern int ql2xshiftctondsd; 93extern int ql2xshiftctondsd;
88extern int ql2xdbwr; 94extern int ql2xdbwr;
89extern int ql2xdontresethba; 95extern int ql2xdontresethba;
96extern int ql2xasynctmfenable;
90 97
91extern int qla2x00_loop_reset(scsi_qla_host_t *); 98extern int qla2x00_loop_reset(scsi_qla_host_t *);
92extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); 99extern 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
127static void 127static void
128qla2x00_async_logio_timeout(srb_t *sp) 128qla2x00_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
295static void
296qla2x00_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
305int
306qla2x00_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
343done_free_sp:
344 tcf->free(sp);
345done:
346 return rval;
347}
348
349static void
350qla2x00_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
359int
360qla2x00_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
395done_free_sp:
396 mrk->free(sp);
397done:
398 return rval;
399}
400
295void 401void
296qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, 402qla2x00_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
469void
470qla2x00_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
493void
494qla2x00_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
1088static void 1088static void
1089qla24xx_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
1121static void
1122qla24xx_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
1146static void
1089qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) 1147qla24xx_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
1164static void
1165qla24xx_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
1224static void
1225qla24xx_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,
2464int 2464int
2465qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag) 2465qla24xx_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
2470int 2475int
2471qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag) 2476qla24xx_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
145int ql2xasynctmfenable;
146module_param(ql2xasynctmfenable, int, S_IRUGO|S_IRUSR);
147MODULE_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 */