Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Armen Baloyan and committed by
James Bottomley
4440e46d faef62d1

+140 -91
+1 -1
drivers/scsi/qla2xxx/qla_gbl.h
··· 330 330 dma_addr_t); 331 331 332 332 extern int qla24xx_abort_command(srb_t *); 333 + extern int qla24xx_async_abort_command(srb_t *); 333 334 extern int 334 335 qla24xx_abort_target(struct fc_port *, unsigned int, int); 335 336 extern int ··· 605 604 extern irqreturn_t qlafx00_intr_handler(int, void *); 606 605 extern void qlafx00_enable_intrs(struct qla_hw_data *); 607 606 extern void qlafx00_disable_intrs(struct qla_hw_data *); 608 - extern int qlafx00_abort_command(srb_t *); 609 607 extern int qlafx00_abort_target(fc_port_t *, unsigned int, int); 610 608 extern int qlafx00_lun_reset(fc_port_t *, unsigned int, int); 611 609 extern int qlafx00_start_scsi(srb_t *);
+88
drivers/scsi/qla2xxx/qla_init.c
··· 347 347 return rval; 348 348 } 349 349 350 + static void 351 + qla24xx_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 + 360 + static void 361 + qla24xx_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 + 369 + static int 370 + qla24xx_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 + 404 + done_free_sp: 405 + sp->free(vha, sp); 406 + done: 407 + return rval; 408 + } 409 + 410 + int 411 + qla24xx_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 + 350 438 void 351 439 qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, 352 440 uint16_t *data)
+26 -1
drivers/scsi/qla2xxx/qla_iocb.c
··· 2585 2585 return QLA_FUNCTION_FAILED; 2586 2586 } 2587 2587 2588 + void 2589 + qla24xx_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 + 2588 2611 int 2589 2612 qla2x00_start_sp(srb_t *sp) 2590 2613 { ··· 2661 2638 qlafx00_fxdisc_iocb(sp, pkt); 2662 2639 break; 2663 2640 case SRB_ABT_CMD: 2664 - qlafx00_abort_iocb(sp, pkt); 2641 + IS_QLAFX00(ha) ? 2642 + qlafx00_abort_iocb(sp, pkt) : 2643 + qla24xx_abort_iocb(sp, pkt); 2665 2644 break; 2666 2645 default: 2667 2646 break;
+21
drivers/scsi/qla2xxx/qla_isr.c
··· 2428 2428 } 2429 2429 } 2430 2430 2431 + static void 2432 + qla24xx_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 2449 * qla24xx_process_response_queue() - Process response queue entries. 2433 2450 * @ha: SCSI driver HA context ··· 2512 2495 /* Do nothing in this case, this check is to prevent it 2513 2496 * from falling into default case 2514 2497 */ 2498 + break; 2499 + case ABORT_IOCB_TYPE: 2500 + qla24xx_abort_iocb_entry(vha, rsp->req, 2501 + (struct abort_entry_24xx *)pkt); 2515 2502 break; 2516 2503 default: 2517 2504 /* Type Not Supported. */
+3
drivers/scsi/qla2xxx/qla_mbx.c
··· 2597 2597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, 2598 2598 "Entered %s.\n", __func__); 2599 2599 2600 + if (ql2xasynctmfenable) 2601 + return qla24xx_async_abort_command(sp); 2602 + 2600 2603 spin_lock_irqsave(&ha->hardware_lock, flags); 2601 2604 for (handle = 1; handle < req->num_outstanding_cmds; handle++) { 2602 2605 if (req->outstanding_cmds[handle] == sp)
-88
drivers/scsi/qla2xxx/qla_mr.c
··· 1962 1962 return rval; 1963 1963 } 1964 1964 1965 - static void 1966 - qlafx00_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 - 1975 - static void 1976 - qlafx00_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 - 1984 - static int 1985 - qlafx00_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 - 2019 - done_free_sp: 2020 - sp->free(vha, sp); 2021 - done: 2022 - return rval; 2023 - } 2024 - 2025 - int 2026 - qlafx00_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 1966 * qlafx00_initialize_adapter 2055 1967 * Initialize board.
+1 -1
drivers/scsi/qla2xxx/qla_os.c
··· 2078 2078 .intr_handler = qlafx00_intr_handler, 2079 2079 .enable_intrs = qlafx00_enable_intrs, 2080 2080 .disable_intrs = qlafx00_disable_intrs, 2081 - .abort_command = qlafx00_abort_command, 2081 + .abort_command = qla24xx_async_abort_command, 2082 2082 .target_reset = qlafx00_abort_target, 2083 2083 .lun_reset = qlafx00_lun_reset, 2084 2084 .fabric_login = NULL,