aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorMadhuranath Iyengar <madhuranath.iyengar@qlogic.com>2010-05-04 18:01:29 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-16 18:21:57 -0400
commit3822263eb1e74821ad1ae886ddd2184ae9395ff7 (patch)
tree7b8ff05127a579bb0c3de9c8848f4052c0604d60 /drivers/scsi/qla2xxx/qla_init.c
parent4916392b56921b4aaaeaca3ef492135f42fbb5f2 (diff)
[SCSI] qla2xxx: Support for asynchronous TM and Marker IOCBs.
Currently we can only issue the task management (TM) commands via the mailbox mechanism. This is a limitation, since only one mailbox command can be issued at a time. The purpose of this effort is to provide support for issuing and processing the respose to TM and Marker IOCBs asynchronously. Towards achieving this, the consolidated srb architecture that is currently used for BSG and IOCB/Logio commands has been enhanced and used. Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c156
1 files changed, 152 insertions, 4 deletions
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/****************************************************************************/