aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorArmen Baloyan <armen.baloyan@qlogic.com>2014-02-26 04:15:18 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:18:53 -0400
commit4440e46d5db7b445a961a84444849b2a31fa7fd1 (patch)
tree749aabd6001295df16788f7423351ead583c0b98 /drivers/scsi
parentfaef62d134631c1f390006d51d49c76033f9504f (diff)
[SCSI] qla2xxx: Add IOCB Abort command asynchronous handling.
Send aborts to the firmware via the request/response queue mechanism. Signed-off-by: Armen Baloyan <armen.baloyan@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c88
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c21
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c88
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
7 files changed, 140 insertions, 91 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index dcd084a4e5c1..e665e8109933 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -330,6 +330,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
330 dma_addr_t); 330 dma_addr_t);
331 331
332extern int qla24xx_abort_command(srb_t *); 332extern int qla24xx_abort_command(srb_t *);
333extern int qla24xx_async_abort_command(srb_t *);
333extern int 334extern int
334qla24xx_abort_target(struct fc_port *, unsigned int, int); 335qla24xx_abort_target(struct fc_port *, unsigned int, int);
335extern int 336extern int
@@ -604,7 +605,6 @@ extern char *qlafx00_fw_version_str(struct scsi_qla_host *, char *);
604extern irqreturn_t qlafx00_intr_handler(int, void *); 605extern irqreturn_t qlafx00_intr_handler(int, void *);
605extern void qlafx00_enable_intrs(struct qla_hw_data *); 606extern void qlafx00_enable_intrs(struct qla_hw_data *);
606extern void qlafx00_disable_intrs(struct qla_hw_data *); 607extern void qlafx00_disable_intrs(struct qla_hw_data *);
607extern int qlafx00_abort_command(srb_t *);
608extern int qlafx00_abort_target(fc_port_t *, unsigned int, int); 608extern int qlafx00_abort_target(fc_port_t *, unsigned int, int);
609extern int qlafx00_lun_reset(fc_port_t *, unsigned int, int); 609extern int qlafx00_lun_reset(fc_port_t *, unsigned int, int);
610extern int qlafx00_start_scsi(srb_t *); 610extern int qlafx00_start_scsi(srb_t *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 27248425f86c..0a25e8bd8729 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -347,6 +347,94 @@ done:
347 return rval; 347 return rval;
348} 348}
349 349
350static void
351qla24xx_abort_iocb_timeout(void *data)
352{
353 srb_t *sp = (srb_t *)data;
354 struct srb_iocb *abt = &sp->u.iocb_cmd;
355
356 abt->u.abt.comp_status = CS_TIMEOUT;
357 complete(&abt->u.abt.comp);
358}
359
360static void
361qla24xx_abort_sp_done(void *data, void *ptr, int res)
362{
363 srb_t *sp = (srb_t *)ptr;
364 struct srb_iocb *abt = &sp->u.iocb_cmd;
365
366 complete(&abt->u.abt.comp);
367}
368
369static int
370qla24xx_async_abort_cmd(srb_t *cmd_sp)
371{
372 scsi_qla_host_t *vha = cmd_sp->fcport->vha;
373 fc_port_t *fcport = cmd_sp->fcport;
374 struct srb_iocb *abt_iocb;
375 srb_t *sp;
376 int rval = QLA_FUNCTION_FAILED;
377
378 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
379 if (!sp)
380 goto done;
381
382 abt_iocb = &sp->u.iocb_cmd;
383 sp->type = SRB_ABT_CMD;
384 sp->name = "abort";
385 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
386 abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
387 sp->done = qla24xx_abort_sp_done;
388 abt_iocb->timeout = qla24xx_abort_iocb_timeout;
389 init_completion(&abt_iocb->u.abt.comp);
390
391 rval = qla2x00_start_sp(sp);
392 if (rval != QLA_SUCCESS)
393 goto done_free_sp;
394
395 ql_dbg(ql_dbg_async, vha, 0x507c,
396 "Abort command issued - hdl=%x, target_id=%x\n",
397 cmd_sp->handle, fcport->tgt_id);
398
399 wait_for_completion(&abt_iocb->u.abt.comp);
400
401 rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
402 QLA_SUCCESS : QLA_FUNCTION_FAILED;
403
404done_free_sp:
405 sp->free(vha, sp);
406done:
407 return rval;
408}
409
410int
411qla24xx_async_abort_command(srb_t *sp)
412{
413 unsigned long flags = 0;
414
415 uint32_t handle;
416 fc_port_t *fcport = sp->fcport;
417 struct scsi_qla_host *vha = fcport->vha;
418 struct qla_hw_data *ha = vha->hw;
419 struct req_que *req = vha->req;
420
421 spin_lock_irqsave(&ha->hardware_lock, flags);
422 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
423 if (req->outstanding_cmds[handle] == sp)
424 break;
425 }
426 spin_unlock_irqrestore(&ha->hardware_lock, flags);
427 if (handle == req->num_outstanding_cmds) {
428 /* Command not found. */
429 return QLA_FUNCTION_FAILED;
430 }
431 if (sp->type == SRB_FXIOCB_DCMD)
432 return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
433 FXDISC_ABORT_IOCTL);
434
435 return qla24xx_async_abort_cmd(sp);
436}
437
350void 438void
351qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, 439qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
352 uint16_t *data) 440 uint16_t *data)
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 0aad5e412aa7..8c5dec2e3b6d 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2585,6 +2585,29 @@ queuing_error:
2585 return QLA_FUNCTION_FAILED; 2585 return QLA_FUNCTION_FAILED;
2586} 2586}
2587 2587
2588void
2589qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
2590{
2591 struct srb_iocb *aio = &sp->u.iocb_cmd;
2592 scsi_qla_host_t *vha = sp->fcport->vha;
2593 struct req_que *req = vha->req;
2594
2595 memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
2596 abt_iocb->entry_type = ABORT_IOCB_TYPE;
2597 abt_iocb->entry_count = 1;
2598 abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
2599 abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
2600 abt_iocb->handle_to_abort =
2601 cpu_to_le32(MAKE_HANDLE(req->id, aio->u.abt.cmd_hndl));
2602 abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
2603 abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
2604 abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
2605 abt_iocb->vp_index = vha->vp_idx;
2606 abt_iocb->req_que_no = cpu_to_le16(req->id);
2607 /* Send the command to the firmware */
2608 wmb();
2609}
2610
2588int 2611int
2589qla2x00_start_sp(srb_t *sp) 2612qla2x00_start_sp(srb_t *sp)
2590{ 2613{
@@ -2638,7 +2661,9 @@ qla2x00_start_sp(srb_t *sp)
2638 qlafx00_fxdisc_iocb(sp, pkt); 2661 qlafx00_fxdisc_iocb(sp, pkt);
2639 break; 2662 break;
2640 case SRB_ABT_CMD: 2663 case SRB_ABT_CMD:
2641 qlafx00_abort_iocb(sp, pkt); 2664 IS_QLAFX00(ha) ?
2665 qlafx00_abort_iocb(sp, pkt) :
2666 qla24xx_abort_iocb(sp, pkt);
2642 break; 2667 break;
2643 default: 2668 default:
2644 break; 2669 break;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 293dbd565840..95314ef2e505 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2428,6 +2428,23 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
2428 } 2428 }
2429} 2429}
2430 2430
2431static void
2432qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
2433 struct abort_entry_24xx *pkt)
2434{
2435 const char func[] = "ABT_IOCB";
2436 srb_t *sp;
2437 struct srb_iocb *abt;
2438
2439 sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
2440 if (!sp)
2441 return;
2442
2443 abt = &sp->u.iocb_cmd;
2444 abt->u.abt.comp_status = le32_to_cpu(pkt->nport_handle);
2445 sp->done(vha, sp, 0);
2446}
2447
2431/** 2448/**
2432 * qla24xx_process_response_queue() - Process response queue entries. 2449 * qla24xx_process_response_queue() - Process response queue entries.
2433 * @ha: SCSI driver HA context 2450 * @ha: SCSI driver HA context
@@ -2496,6 +2513,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
2496 * from falling into default case 2513 * from falling into default case
2497 */ 2514 */
2498 break; 2515 break;
2516 case ABORT_IOCB_TYPE:
2517 qla24xx_abort_iocb_entry(vha, rsp->req,
2518 (struct abort_entry_24xx *)pkt);
2519 break;
2499 default: 2520 default:
2500 /* Type Not Supported. */ 2521 /* Type Not Supported. */
2501 ql_dbg(ql_dbg_async, vha, 0x5042, 2522 ql_dbg(ql_dbg_async, vha, 0x5042,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index b4f7cd5fa75c..2528709c4add 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2597,6 +2597,9 @@ qla24xx_abort_command(srb_t *sp)
2597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, 2597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2598 "Entered %s.\n", __func__); 2598 "Entered %s.\n", __func__);
2599 2599
2600 if (ql2xasynctmfenable)
2601 return qla24xx_async_abort_command(sp);
2602
2600 spin_lock_irqsave(&ha->hardware_lock, flags); 2603 spin_lock_irqsave(&ha->hardware_lock, flags);
2601 for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 2604 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
2602 if (req->outstanding_cmds[handle] == sp) 2605 if (req->outstanding_cmds[handle] == sp)
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index 165db12580af..0aaf6a9c87d3 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -1962,94 +1962,6 @@ done:
1962 return rval; 1962 return rval;
1963} 1963}
1964 1964
1965static void
1966qlafx00_abort_iocb_timeout(void *data)
1967{
1968 srb_t *sp = (srb_t *)data;
1969 struct srb_iocb *abt = &sp->u.iocb_cmd;
1970
1971 abt->u.abt.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
1972 complete(&abt->u.abt.comp);
1973}
1974
1975static void
1976qlafx00_abort_sp_done(void *data, void *ptr, int res)
1977{
1978 srb_t *sp = (srb_t *)ptr;
1979 struct srb_iocb *abt = &sp->u.iocb_cmd;
1980
1981 complete(&abt->u.abt.comp);
1982}
1983
1984static int
1985qlafx00_async_abt_cmd(srb_t *cmd_sp)
1986{
1987 scsi_qla_host_t *vha = cmd_sp->fcport->vha;
1988 fc_port_t *fcport = cmd_sp->fcport;
1989 struct srb_iocb *abt_iocb;
1990 srb_t *sp;
1991 int rval = QLA_FUNCTION_FAILED;
1992
1993 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
1994 if (!sp)
1995 goto done;
1996
1997 abt_iocb = &sp->u.iocb_cmd;
1998 sp->type = SRB_ABT_CMD;
1999 sp->name = "abort";
2000 qla2x00_init_timer(sp, FXDISC_TIMEOUT);
2001 abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
2002 sp->done = qlafx00_abort_sp_done;
2003 abt_iocb->timeout = qlafx00_abort_iocb_timeout;
2004 init_completion(&abt_iocb->u.abt.comp);
2005
2006 rval = qla2x00_start_sp(sp);
2007 if (rval != QLA_SUCCESS)
2008 goto done_free_sp;
2009
2010 ql_dbg(ql_dbg_async, vha, 0x507c,
2011 "Abort command issued - hdl=%x, target_id=%x\n",
2012 cmd_sp->handle, fcport->tgt_id);
2013
2014 wait_for_completion(&abt_iocb->u.abt.comp);
2015
2016 rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
2017 QLA_SUCCESS : QLA_FUNCTION_FAILED;
2018
2019done_free_sp:
2020 sp->free(vha, sp);
2021done:
2022 return rval;
2023}
2024
2025int
2026qlafx00_abort_command(srb_t *sp)
2027{
2028 unsigned long flags = 0;
2029
2030 uint32_t handle;
2031 fc_port_t *fcport = sp->fcport;
2032 struct scsi_qla_host *vha = fcport->vha;
2033 struct qla_hw_data *ha = vha->hw;
2034 struct req_que *req = vha->req;
2035
2036 spin_lock_irqsave(&ha->hardware_lock, flags);
2037 for (handle = 1; handle < DEFAULT_OUTSTANDING_COMMANDS; handle++) {
2038 if (req->outstanding_cmds[handle] == sp)
2039 break;
2040 }
2041 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2042 if (handle == DEFAULT_OUTSTANDING_COMMANDS) {
2043 /* Command not found. */
2044 return QLA_FUNCTION_FAILED;
2045 }
2046 if (sp->type == SRB_FXIOCB_DCMD)
2047 return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
2048 FXDISC_ABORT_IOCTL);
2049
2050 return qlafx00_async_abt_cmd(sp);
2051}
2052
2053/* 1965/*
2054 * qlafx00_initialize_adapter 1966 * qlafx00_initialize_adapter
2055 * Initialize board. 1967 * Initialize board.
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7b54e0acaac7..5feed53459f4 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2078,7 +2078,7 @@ static struct isp_operations qlafx00_isp_ops = {
2078 .intr_handler = qlafx00_intr_handler, 2078 .intr_handler = qlafx00_intr_handler,
2079 .enable_intrs = qlafx00_enable_intrs, 2079 .enable_intrs = qlafx00_enable_intrs,
2080 .disable_intrs = qlafx00_disable_intrs, 2080 .disable_intrs = qlafx00_disable_intrs,
2081 .abort_command = qlafx00_abort_command, 2081 .abort_command = qla24xx_async_abort_command,
2082 .target_reset = qlafx00_abort_target, 2082 .target_reset = qlafx00_abort_target,
2083 .lun_reset = qlafx00_lun_reset, 2083 .lun_reset = qlafx00_lun_reset,
2084 .fabric_login = NULL, 2084 .fabric_login = NULL,