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

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "qla2xxx target mode improvements"

Tony Battersby <tonyb@cybernetics.com> says:

This patch series improves the qla2xxx FC driver in target mode. I
developed these patches using the out-of-tree SCST target-mode
subsystem (https://scst.sourceforge.net/), although most of the
improvements will also apply to the other target-mode subsystems such
as the in-tree LIO. Unfortunately qla2xxx+LIO does not pass all of my
tests, but my patches do not make it any worse (results below). These
patches have been well-tested at my employer with qla2xxx+SCST in both
initiator mode and target mode and with a variety of FC HBAs and
initiators. Since SCST is out-of-tree, some of the patches have parts
that apply in-tree and other parts that apply out-of-tree to SCST. The
SCST patches can be found in the v2 posting linked above.

All patches apply to linux 6.17 and SCST 3.10 master branch.

Summary of patches:
- bugfixes
- cleanups
- improve handling of aborts and task management requests
- improve log message
- add back SLER / SRR support (removed in 2017)

Some of these patches improve handling of aborts and task management
requests. This is some of the testing that I did:

Test 1: Use /dev/sg to queue random disk I/O with short timeouts; make
sure cmds are aborted successfully.
Test 2: Queue lots of disk I/O, then use "sg_reset -N -d /dev/sg" on
initiator to reset logical unit.
Test 3: Queue lots of disk I/O, then use "sg_reset -N -t /dev/sg" on
initiator to reset target.
Test 4: Queue lots of disk I/O, then use "sg_reset -N -b /dev/sg" on
initiator to reset bus.
Test 5: Queue lots of disk I/O, then use "sg_reset -N -H /dev/sg" on
initiator to reset host.
Test 6: Use fiber channel attenuator to trigger SRR during
write/read/compare test; check data integrity.

With my patches, SCST passes all of these tests.

Results with in-tree LIO target-mode subsystem:

Test 1: Seems to abort the same cmd multiple times (both
qlt_24xx_retry_term_exchange() and __qlt_send_term_exchange()). But
cmds get aborted, so give it a pass?

Test 2: Seems to work; cmds are aborted.

Test 3: Target reset doesn't seem to abort cmds, instead, a few seconds
later:
qla2xxx [0000:04:00.0]-f058:9: qla_target(0): tag 1314312, op 2a: CTIO
with TIMEOUT status 0xb received (state 1, port 51:40:2e:c0:18:1d:9f:cc,
LUN 0)

Tests 4 and 5: The initiator is unable to log back in to the target; the
following messages are repeated over and over on the target:
qla2xxx [0000:04:00.0]-e01c:9: Sending TERM ELS CTIO (ha=00000000f8811390)
qla2xxx [0000:04:00.0]-f097:9: Linking sess 000000008df5aba8 [0] wwn
51:40:2e:c0:18:1d:9f:cc with PLOGI ACK to wwn 51:40:2e:c0:18:1d:9f:cc
s_id 00:00:01, ref=2 pla 00000000835a9271 link 0

Test 6: passes with my patches; SRR not supported previously.

So qla2xxx+LIO seems a bit flaky when handling exceptions, but my
patches do not make it any worse. Perhaps someone who is more familiar
with LIO can look at the difference between LIO and SCST and figure out
how to improve it.

Tony Battersby
https://www.cybernetics.com/

v1: https://lore.kernel.org/r/f8977250-638c-4d7d-ac0c-65f742b8d535@cybernetics.com/
v2: https://lore.kernel.org/linux-scsi/e95ee7d0-3580-4124-b854-7f73ca3a3a84@cybernetics.com/
Link: https://patch.msgid.link/aaea0ab0-da8b-4153-9369-60db7507ff7a@cybernetics.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+1647 -337
+2 -1
drivers/scsi/qla2xxx/qla_dbg.c
··· 54 54 * | Misc | 0xd303 | 0xd031-0xd0ff | 55 55 * | | | 0xd101-0xd1fe | 56 56 * | | | 0xd214-0xd2fe | 57 - * | Target Mode | 0xe081 | | 57 + * | Target Mode | 0xe089 | | 58 58 * | Target Mode Management | 0xf09b | 0xf002 | 59 59 * | | | 0xf046-0xf049 | 60 60 * | Target Mode Task Management | 0x1000d | | 61 + * | Target Mode SRR | 0x11038 | | 61 62 * ---------------------------------------------------------------------- 62 63 */ 63 64
-1
drivers/scsi/qla2xxx/qla_def.h
··· 3503 3503 #define QLA_MSIX_RSP_Q 0x01 3504 3504 #define QLA_ATIO_VECTOR 0x02 3505 3505 #define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x03 3506 - #define QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS 0x04 3507 3506 3508 3507 #define QLA_MIDX_DEFAULT 0 3509 3508 #define QLA_MIDX_RSP_Q 1
+1 -1
drivers/scsi/qla2xxx/qla_gbl.h
··· 766 766 767 767 /* Globa function prototypes for multi-q */ 768 768 extern int qla25xx_request_irq(struct qla_hw_data *, struct qla_qpair *, 769 - struct qla_msix_entry *, int); 769 + struct qla_msix_entry *); 770 770 extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *); 771 771 extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *); 772 772 extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
+1
drivers/scsi/qla2xxx/qla_init.c
··· 4369 4369 ha->max_npiv_vports = 4370 4370 MIN_MULTI_ID_FABRIC - 1; 4371 4371 } 4372 + qlt_config_nvram_with_fw_version(vha); 4372 4373 qla2x00_get_resource_cnts(vha); 4373 4374 qla_init_iocb_limit(vha); 4374 4375
+3 -29
drivers/scsi/qla2xxx/qla_isr.c
··· 4467 4467 return IRQ_HANDLED; 4468 4468 } 4469 4469 4470 - irqreturn_t 4471 - qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) 4472 - { 4473 - struct qla_hw_data *ha; 4474 - struct qla_qpair *qpair; 4475 - struct device_reg_24xx __iomem *reg; 4476 - unsigned long flags; 4477 - 4478 - qpair = dev_id; 4479 - if (!qpair) { 4480 - ql_log(ql_log_info, NULL, 0x505b, 4481 - "%s: NULL response queue pointer.\n", __func__); 4482 - return IRQ_NONE; 4483 - } 4484 - ha = qpair->hw; 4485 - 4486 - reg = &ha->iobase->isp24; 4487 - spin_lock_irqsave(&ha->hardware_lock, flags); 4488 - wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_INT); 4489 - spin_unlock_irqrestore(&ha->hardware_lock, flags); 4490 - 4491 - queue_work(ha->wq, &qpair->q_work); 4492 - 4493 - return IRQ_HANDLED; 4494 - } 4495 - 4496 4470 /* Interrupt handling helpers. */ 4497 4471 4498 4472 struct qla_init_msix_entry { ··· 4479 4505 { "rsp_q", qla24xx_msix_rsp_q }, 4480 4506 { "atio_q", qla83xx_msix_atio_q }, 4481 4507 { "qpair_multiq", qla2xxx_msix_rsp_q }, 4482 - { "qpair_multiq_hs", qla2xxx_msix_rsp_q_hs }, 4483 4508 }; 4484 4509 4485 4510 static const struct qla_init_msix_entry qla82xx_msix_entries[] = { ··· 4765 4792 } 4766 4793 4767 4794 int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair, 4768 - struct qla_msix_entry *msix, int vector_type) 4795 + struct qla_msix_entry *msix) 4769 4796 { 4770 - const struct qla_init_msix_entry *intr = &msix_entries[vector_type]; 4797 + const struct qla_init_msix_entry *intr = 4798 + &msix_entries[QLA_MSIX_QPAIR_MULTIQ_RSP_Q]; 4771 4799 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 4772 4800 int ret; 4773 4801
+2
drivers/scsi/qla2xxx/qla_mbx.c
··· 253 253 /* Issue set host interrupt command to send cmd out. */ 254 254 ha->flags.mbox_int = 0; 255 255 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 256 + reinit_completion(&ha->mbx_intr_comp); 256 257 257 258 /* Unlock mbx registers and wait for interrupt */ 258 259 ql_dbg(ql_dbg_mbx, vha, 0x100f, ··· 280 279 "cmd=%x Timeout.\n", command); 281 280 spin_lock_irqsave(&ha->hardware_lock, flags); 282 281 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 282 + reinit_completion(&ha->mbx_intr_comp); 283 283 spin_unlock_irqrestore(&ha->hardware_lock, flags); 284 284 285 285 if (chip_reset != ha->chip_reset) {
+1 -3
drivers/scsi/qla2xxx/qla_mid.c
··· 899 899 rsp->options, rsp->id, rsp->rsp_q_in, 900 900 rsp->rsp_q_out); 901 901 902 - ret = qla25xx_request_irq(ha, qpair, qpair->msix, 903 - ha->flags.disable_msix_handshake ? 904 - QLA_MSIX_QPAIR_MULTIQ_RSP_Q : QLA_MSIX_QPAIR_MULTIQ_RSP_Q_HS); 902 + ret = qla25xx_request_irq(ha, qpair, qpair->msix); 905 903 if (ret) 906 904 goto que_failed; 907 905
+20 -15
drivers/scsi/qla2xxx/qla_os.c
··· 1862 1862 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { 1863 1863 sp = req->outstanding_cmds[cnt]; 1864 1864 if (sp) { 1865 - if (qla2x00_chip_is_down(vha)) { 1866 - req->outstanding_cmds[cnt] = NULL; 1867 - sp->done(sp, res); 1868 - continue; 1869 - } 1870 - 1871 1865 switch (sp->cmd_type) { 1872 1866 case TYPE_SRB: 1873 1867 qla2x00_abort_srb(qp, sp, res, &flags); ··· 1875 1881 continue; 1876 1882 } 1877 1883 cmd = (struct qla_tgt_cmd *)sp; 1878 - cmd->aborted = 1; 1884 + 1885 + if (cmd->sg_mapped) 1886 + qlt_unmap_sg(vha, cmd); 1887 + 1888 + if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 1889 + cmd->aborted = 1; 1890 + cmd->write_data_transferred = 0; 1891 + cmd->state = QLA_TGT_STATE_DATA_IN; 1892 + ha->tgt.tgt_ops->handle_data(cmd); 1893 + } else { 1894 + ha->tgt.tgt_ops->free_cmd(cmd); 1895 + } 1879 1896 break; 1880 1897 case TYPE_TGT_TMCMD: 1881 - /* Skip task management functions. */ 1898 + /* 1899 + * Currently, only ABTS response gets on the 1900 + * outstanding_cmds[] 1901 + */ 1902 + qlt_free_ul_mcmd(ha, 1903 + (struct qla_tgt_mgmt_cmd *) sp); 1882 1904 break; 1883 1905 default: 1884 1906 break; ··· 3454 3444 ha->mqenable = 0; 3455 3445 3456 3446 if (ha->mqenable) { 3457 - bool startit = false; 3458 - 3459 - if (QLA_TGT_MODE_ENABLED()) 3460 - startit = false; 3461 - 3462 - if (ql2x_ini_mode == QLA2XXX_INI_MODE_ENABLED) 3463 - startit = true; 3447 + bool startit = !!(host->active_mode & MODE_INITIATOR); 3464 3448 3465 3449 /* Create start of day qpairs for Block MQ */ 3466 3450 for (i = 0; i < ha->max_qpairs; i++) ··· 7248 7244 if (!test_bit(UNLOADING, &vha->dpc_flags) && t) 7249 7245 wake_up_process(t); 7250 7246 } 7247 + EXPORT_SYMBOL(qla2xxx_wake_dpc); 7251 7248 7252 7249 /* 7253 7250 * qla2x00_rst_aen
+1495 -276
drivers/scsi/qla2xxx/qla_target.c
··· 104 104 response_t *pkt); 105 105 static int qlt_issue_task_mgmt(struct fc_port *sess, u64 lun, 106 106 int fn, void *iocb, int flags); 107 - static void qlt_send_term_exchange(struct qla_qpair *, struct qla_tgt_cmd 108 - *cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort); 109 107 static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, 110 108 struct atio_from_isp *atio, uint16_t status, int qfull); 111 109 static void qlt_disable_vha(struct scsi_qla_host *vha); ··· 133 135 static struct workqueue_struct *qla_tgt_wq; 134 136 static DEFINE_MUTEX(qla_tgt_mutex); 135 137 static LIST_HEAD(qla_tgt_glist); 136 - 137 - static const char *prot_op_str(u32 prot_op) 138 - { 139 - switch (prot_op) { 140 - case TARGET_PROT_NORMAL: return "NORMAL"; 141 - case TARGET_PROT_DIN_INSERT: return "DIN_INSERT"; 142 - case TARGET_PROT_DOUT_INSERT: return "DOUT_INSERT"; 143 - case TARGET_PROT_DIN_STRIP: return "DIN_STRIP"; 144 - case TARGET_PROT_DOUT_STRIP: return "DOUT_STRIP"; 145 - case TARGET_PROT_DIN_PASS: return "DIN_PASS"; 146 - case TARGET_PROT_DOUT_PASS: return "DOUT_PASS"; 147 - default: return "UNKNOWN"; 148 - } 149 - } 150 138 151 139 /* This API intentionally takes dest as a parameter, rather than returning 152 140 * int value to avoid caller forgetting to issue wmb() after the store */ ··· 210 226 struct qla_tgt_sess_op *u; 211 227 struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 212 228 unsigned long flags; 229 + unsigned int add_cdb_len = 0; 230 + 231 + /* atio must be the last member of qla_tgt_sess_op for add_cdb_len */ 232 + BUILD_BUG_ON(offsetof(struct qla_tgt_sess_op, atio) + sizeof(u->atio) != sizeof(*u)); 213 233 214 234 if (tgt->tgt_stop) { 215 235 ql_dbg(ql_dbg_async, vha, 0x502c, ··· 222 234 goto out_term; 223 235 } 224 236 225 - u = kzalloc(sizeof(*u), GFP_ATOMIC); 237 + if (atio->u.raw.entry_type == ATIO_TYPE7 && 238 + atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0) 239 + add_cdb_len = 240 + ((unsigned int) atio->u.isp24.fcp_cmnd.add_cdb_len) * 4; 241 + 242 + u = kzalloc(sizeof(*u) + add_cdb_len, GFP_ATOMIC); 226 243 if (u == NULL) 227 244 goto out_term; 228 245 229 246 u->vha = vha; 230 - memcpy(&u->atio, atio, sizeof(*atio)); 247 + memcpy(&u->atio, atio, sizeof(*atio) + add_cdb_len); 231 248 INIT_LIST_HEAD(&u->cmd_list); 232 249 233 250 spin_lock_irqsave(&vha->cmd_list_lock, flags); ··· 245 252 return; 246 253 247 254 out_term: 248 - qlt_send_term_exchange(vha->hw->base_qpair, NULL, atio, ha_locked, 0); 255 + qlt_send_term_exchange(vha->hw->base_qpair, NULL, atio, ha_locked); 249 256 goto out; 250 257 } 251 258 ··· 264 271 "Freeing unknown %s %p, because of Abort\n", 265 272 "ATIO_TYPE7", u); 266 273 qlt_send_term_exchange(vha->hw->base_qpair, NULL, 267 - &u->atio, ha_locked, 0); 274 + &u->atio, ha_locked); 268 275 goto abort; 269 276 } 270 277 ··· 278 285 "Freeing unknown %s %p, because tgt is being stopped\n", 279 286 "ATIO_TYPE7", u); 280 287 qlt_send_term_exchange(vha->hw->base_qpair, NULL, 281 - &u->atio, ha_locked, 0); 288 + &u->atio, ha_locked); 282 289 } else { 283 290 ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x503d, 284 291 "Reschedule u %p, vha %p, host %p\n", u, vha, host); ··· 1902 1909 * ABTS response. So, in it ID fields are reversed. 1903 1910 */ 1904 1911 1912 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe082, 1913 + "qla_target(%d): tag %u: Sending TERM EXCH CTIO for ABTS\n", 1914 + vha->vp_idx, le32_to_cpu(entry->exchange_addr_to_abort)); 1915 + 1905 1916 ctio->entry_type = CTIO_TYPE7; 1906 1917 ctio->entry_count = 1; 1907 1918 ctio->nport_handle = entry->nport_handle; ··· 1984 1987 cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id); 1985 1988 cmd_lun = scsilun_to_int( 1986 1989 (struct scsi_lun *)&cmd->atio.u.isp24.fcp_cmnd.lun); 1987 - if (cmd_key == key && cmd_lun == lun) 1990 + if (cmd_key == key && cmd_lun == lun) { 1991 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe085, 1992 + "qla_target(%d): tag %lld: aborted by TMR\n", 1993 + vha->vp_idx, cmd->se_cmd.tag); 1988 1994 cmd->aborted = 1; 1995 + } 1989 1996 } 1990 1997 spin_unlock_irqrestore(&vha->cmd_list_lock, flags); 1991 1998 } ··· 2018 2017 struct qla_hw_data *ha = mcmd->vha->hw; 2019 2018 int rc; 2020 2019 uint32_t tag; 2021 - unsigned long flags; 2022 2020 2023 2021 switch (mcmd->tmr_func) { 2024 2022 case QLA_TGT_ABTS: ··· 2032 2032 mcmd->tmr_func, tag); 2033 2033 2034 2034 if (rc != 0) { 2035 - spin_lock_irqsave(mcmd->qpair->qp_lock_ptr, flags); 2036 - switch (mcmd->tmr_func) { 2037 - case QLA_TGT_ABTS: 2038 - mcmd->fc_tm_rsp = FCP_TMF_REJECTED; 2039 - qlt_build_abts_resp_iocb(mcmd); 2040 - break; 2041 - case QLA_TGT_LUN_RESET: 2042 - case QLA_TGT_CLEAR_TS: 2043 - case QLA_TGT_ABORT_TS: 2044 - case QLA_TGT_CLEAR_ACA: 2045 - case QLA_TGT_TARGET_RESET: 2046 - qlt_send_busy(mcmd->qpair, &mcmd->orig_iocb.atio, 2047 - qla_sam_status); 2048 - break; 2049 - 2050 - case QLA_TGT_ABORT_ALL: 2051 - case QLA_TGT_NEXUS_LOSS_SESS: 2052 - case QLA_TGT_NEXUS_LOSS: 2053 - qlt_send_notify_ack(mcmd->qpair, 2054 - &mcmd->orig_iocb.imm_ntfy, 0, 0, 0, 0, 0, 0); 2055 - break; 2056 - } 2057 - spin_unlock_irqrestore(mcmd->qpair->qp_lock_ptr, flags); 2058 - 2059 2035 ql_dbg(ql_dbg_tgt_mgt, mcmd->vha, 0xf052, 2060 2036 "qla_target(%d): tgt_ops->handle_tmr() failed: %d\n", 2061 2037 mcmd->vha->vp_idx, rc); 2062 - mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 2038 + mcmd->flags |= QLA24XX_MGMT_LLD_OWNED; 2039 + mcmd->fc_tm_rsp = FCP_TMF_FAILED; 2040 + qlt_xmit_tm_rsp(mcmd); 2063 2041 } 2064 2042 } 2065 2043 ··· 2225 2247 EXPORT_SYMBOL(qlt_free_mcmd); 2226 2248 2227 2249 /* 2250 + * If the upper layer knows about this mgmt cmd, then call its ->free_cmd() 2251 + * callback, which will eventually call qlt_free_mcmd(). Otherwise, call 2252 + * qlt_free_mcmd() directly. 2253 + */ 2254 + void qlt_free_ul_mcmd(struct qla_hw_data *ha, struct qla_tgt_mgmt_cmd *mcmd) 2255 + { 2256 + if (!mcmd) 2257 + return; 2258 + if (mcmd->flags & QLA24XX_MGMT_LLD_OWNED) 2259 + qlt_free_mcmd(mcmd); 2260 + else 2261 + ha->tgt.tgt_ops->free_mcmd(mcmd); 2262 + } 2263 + 2264 + /* 2228 2265 * ha->hardware_lock supposed to be held on entry. Might drop it, then 2229 2266 * reacquire 2230 2267 */ ··· 2331 2338 "RESET-TMR online/active/old-count/new-count = %d/%d/%d/%d.\n", 2332 2339 vha->flags.online, qla2x00_reset_active(vha), 2333 2340 mcmd->reset_count, qpair->chip_reset); 2334 - ha->tgt.tgt_ops->free_mcmd(mcmd); 2341 + qlt_free_ul_mcmd(ha, mcmd); 2335 2342 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 2336 2343 return; 2337 2344 } 2338 2345 2339 - if (mcmd->flags == QLA24XX_MGMT_SEND_NACK) { 2346 + if (mcmd->flags & QLA24XX_MGMT_SEND_NACK) { 2340 2347 switch (mcmd->orig_iocb.imm_ntfy.u.isp24.status_subcode) { 2341 2348 case ELS_LOGO: 2342 2349 case ELS_PRLO: ··· 2369 2376 * qlt_xmit_tm_rsp() returns here.. 2370 2377 */ 2371 2378 if (free_mcmd) 2372 - ha->tgt.tgt_ops->free_mcmd(mcmd); 2379 + qlt_free_ul_mcmd(ha, mcmd); 2373 2380 2374 2381 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 2375 2382 } ··· 2436 2443 return -1; 2437 2444 } 2438 2445 2439 - static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) 2446 + void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) 2440 2447 { 2441 2448 struct qla_hw_data *ha; 2442 2449 struct qla_qpair *qpair; ··· 3211 3218 uint32_t full_req_cnt = 0; 3212 3219 unsigned long flags = 0; 3213 3220 int res; 3214 - 3215 - if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || 3216 - (cmd->sess && cmd->sess->deleted)) { 3217 - cmd->state = QLA_TGT_STATE_PROCESSED; 3218 - return 0; 3219 - } 3221 + int pre_xmit_res; 3220 3222 3221 3223 ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, 3222 3224 "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p] qp %d\n", ··· 3219 3231 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction, 3220 3232 &cmd->se_cmd, qpair->id); 3221 3233 3222 - res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, 3234 + pre_xmit_res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, 3223 3235 &full_req_cnt); 3224 - if (unlikely(res != 0)) { 3225 - return res; 3226 - } 3236 + /* 3237 + * Check pre_xmit_res later because we want to check other errors 3238 + * first. 3239 + */ 3240 + 3241 + /* Begin timer on the first call, not on SRR retry. */ 3242 + if (likely(cmd->jiffies_at_hw_st_entry == 0)) 3243 + cmd->jiffies_at_hw_st_entry = get_jiffies_64(); 3227 3244 3228 3245 spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3246 + 3247 + if (unlikely(cmd->sent_term_exchg || 3248 + cmd->sess->deleted || 3249 + !qpair->fw_started || 3250 + cmd->reset_count != qpair->chip_reset)) { 3251 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe101, 3252 + "qla_target(%d): tag %lld: skipping send response for aborted cmd\n", 3253 + vha->vp_idx, cmd->se_cmd.tag); 3254 + qlt_unmap_sg(vha, cmd); 3255 + cmd->state = QLA_TGT_STATE_PROCESSED; 3256 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 3257 + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3258 + return 0; 3259 + } 3260 + 3261 + /* Check for errors from qlt_pre_xmit_response(). */ 3262 + res = pre_xmit_res; 3263 + if (unlikely(res)) 3264 + goto out_unmap_unlock; 3229 3265 3230 3266 if (xmit_type == QLA_TGT_XMIT_STATUS) 3231 3267 qpair->tgt_counters.core_qla_snd_status++; 3232 3268 else 3233 3269 qpair->tgt_counters.core_qla_que_buf++; 3234 - 3235 - if (!qpair->fw_started || cmd->reset_count != qpair->chip_reset) { 3236 - /* 3237 - * Either the port is not online or this request was from 3238 - * previous life, just abort the processing. 3239 - */ 3240 - cmd->state = QLA_TGT_STATE_PROCESSED; 3241 - ql_dbg_qp(ql_dbg_async, qpair, 0xe101, 3242 - "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", 3243 - vha->flags.online, qla2x00_reset_active(vha), 3244 - cmd->reset_count, qpair->chip_reset); 3245 - res = 0; 3246 - goto out_unmap_unlock; 3247 - } 3248 3270 3249 3271 /* Does F/W have an IOCBs for this request */ 3250 3272 res = qlt_check_reserve_free_req(qpair, full_req_cnt); ··· 3370 3372 struct qla_tgt_prm prm; 3371 3373 unsigned long flags = 0; 3372 3374 int res = 0; 3375 + int pci_map_res; 3373 3376 struct qla_qpair *qpair = cmd->qpair; 3377 + 3378 + /* Begin timer on the first call, not on SRR retry. */ 3379 + if (likely(cmd->jiffies_at_hw_st_entry == 0)) 3380 + cmd->jiffies_at_hw_st_entry = get_jiffies_64(); 3374 3381 3375 3382 memset(&prm, 0, sizeof(prm)); 3376 3383 prm.cmd = cmd; ··· 3383 3380 prm.sg = NULL; 3384 3381 prm.req_cnt = 1; 3385 3382 3386 - if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || 3387 - (cmd->sess && cmd->sess->deleted)) { 3388 - /* 3389 - * Either the port is not online or this request was from 3390 - * previous life, just abort the processing. 3391 - */ 3383 + /* Calculate number of entries and segments required */ 3384 + pci_map_res = qlt_pci_map_calc_cnt(&prm); 3385 + /* 3386 + * Check pci_map_res later because we want to check other errors first. 3387 + */ 3388 + 3389 + spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3390 + 3391 + if (unlikely(cmd->sent_term_exchg || 3392 + cmd->sess->deleted || 3393 + !qpair->fw_started || 3394 + cmd->reset_count != qpair->chip_reset)) { 3395 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe102, 3396 + "qla_target(%d): tag %lld: skipping data-out for aborted cmd\n", 3397 + vha->vp_idx, cmd->se_cmd.tag); 3398 + qlt_unmap_sg(vha, cmd); 3392 3399 cmd->aborted = 1; 3393 3400 cmd->write_data_transferred = 0; 3394 3401 cmd->state = QLA_TGT_STATE_DATA_IN; 3402 + cmd->jiffies_at_hw_st_entry = 0; 3395 3403 vha->hw->tgt.tgt_ops->handle_data(cmd); 3396 - ql_dbg_qp(ql_dbg_async, qpair, 0xe102, 3397 - "RESET-XFR online/active/old-count/new-count = %d/%d/%d/%d.\n", 3398 - vha->flags.online, qla2x00_reset_active(vha), 3399 - cmd->reset_count, qpair->chip_reset); 3404 + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3400 3405 return 0; 3401 3406 } 3402 3407 3403 - /* Calculate number of entries and segments required */ 3404 - if (qlt_pci_map_calc_cnt(&prm) != 0) 3405 - return -EAGAIN; 3408 + /* Check for errors from qlt_pci_map_calc_cnt(). */ 3409 + if (unlikely(pci_map_res != 0)) { 3410 + res = -EAGAIN; 3411 + goto out_unlock_free_unmap; 3412 + } 3406 3413 3407 - spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3408 3414 /* Does F/W have an IOCBs for this request */ 3409 3415 res = qlt_check_reserve_free_req(qpair, prm.req_cnt); 3410 3416 if (res != 0) ··· 3450 3438 return res; 3451 3439 3452 3440 out_unlock_free_unmap: 3441 + cmd->jiffies_at_hw_st_entry = 0; 3453 3442 qlt_unmap_sg(vha, cmd); 3454 3443 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3455 3444 ··· 3470 3457 uint8_t *ep = &sts->expected_dif[0]; 3471 3458 uint64_t lba = cmd->se_cmd.t_task_lba; 3472 3459 uint8_t scsi_status, sense_key, asc, ascq; 3473 - unsigned long flags; 3474 3460 struct scsi_qla_host *vha = cmd->vha; 3475 3461 3476 3462 cmd->trc_flags |= TRC_DIF_ERR; ··· 3540 3528 case QLA_TGT_STATE_NEED_DATA: 3541 3529 /* handle_data will load DIF error code */ 3542 3530 cmd->state = QLA_TGT_STATE_DATA_IN; 3531 + cmd->jiffies_at_hw_st_entry = 0; 3543 3532 vha->hw->tgt.tgt_ops->handle_data(cmd); 3544 3533 break; 3545 3534 default: 3546 - spin_lock_irqsave(&cmd->cmd_lock, flags); 3547 - if (cmd->aborted) { 3548 - spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3535 + if (cmd->sent_term_exchg) { 3549 3536 vha->hw->tgt.tgt_ops->free_cmd(cmd); 3550 3537 break; 3551 3538 } 3552 - spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3553 3539 3554 3540 qlt_send_resp_ctio(qpair, cmd, scsi_status, sense_key, asc, 3555 3541 ascq); ··· 3621 3611 } 3622 3612 3623 3613 /* 3614 + * Handle a SRR that had been previously associated with a command when the 3615 + * command has been aborted or otherwise cannot process the SRR. 3616 + * 3617 + * If reject is true, then attempt to reject the SRR. Otherwise abort the 3618 + * immediate notify exchange. 3619 + */ 3620 + void qlt_srr_abort(struct qla_tgt_cmd *cmd, bool reject) 3621 + { 3622 + struct scsi_qla_host *vha = cmd->vha; 3623 + struct qla_tgt_srr *srr = cmd->srr; 3624 + 3625 + if (srr->imm_ntfy_recvd) { 3626 + if (reject) 3627 + srr->reject = true; 3628 + else 3629 + srr->aborted = true; 3630 + 3631 + if (srr->ctio_recvd) { 3632 + /* 3633 + * The SRR should already be scheduled for processing, 3634 + * and the SRR processing code should see that the cmd 3635 + * has been aborted and take appropriate action. In 3636 + * addition, the cmd refcount should have been 3637 + * incremented, preventing the cmd from being freed 3638 + * until SRR processing is done. 3639 + */ 3640 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1102e, 3641 + "qla_target(%d): tag %lld: %s: SRR already scheduled\n", 3642 + vha->vp_idx, cmd->se_cmd.tag, __func__); 3643 + } else { 3644 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 3645 + unsigned long flags; 3646 + 3647 + /* Shedule processing for the SRR immediate notify. */ 3648 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1102f, 3649 + "qla_target(%d): tag %lld: %s: schedule SRR %s\n", 3650 + vha->vp_idx, cmd->se_cmd.tag, __func__, 3651 + reject ? "reject" : "abort"); 3652 + cmd->srr = NULL; 3653 + srr->cmd = NULL; 3654 + spin_lock_irqsave(&tgt->srr_lock, flags); 3655 + list_add_tail(&srr->srr_list_entry, &tgt->srr_list); 3656 + queue_work(qla_tgt_wq, &tgt->srr_work); 3657 + spin_unlock_irqrestore(&tgt->srr_lock, flags); 3658 + } 3659 + } else { 3660 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11030, 3661 + "qla_target(%d): tag %lld: %s: no IMM SRR; free SRR\n", 3662 + vha->vp_idx, cmd->se_cmd.tag, __func__); 3663 + cmd->srr = NULL; 3664 + kfree(srr); 3665 + } 3666 + } 3667 + EXPORT_SYMBOL(qlt_srr_abort); 3668 + 3669 + /* 3624 3670 * If hardware_lock held on entry, might drop it, then reaquire 3625 3671 * This function sends the appropriate CTIO to ISP 2xxx or 24xx 3626 3672 */ ··· 3684 3618 struct qla_tgt_cmd *cmd, 3685 3619 struct atio_from_isp *atio) 3686 3620 { 3687 - struct scsi_qla_host *vha = qpair->vha; 3688 3621 struct ctio7_to_24xx *ctio24; 3689 - struct qla_hw_data *ha = vha->hw; 3690 - request_t *pkt; 3691 - int ret = 0; 3622 + struct scsi_qla_host *vha; 3623 + uint16_t loop_id; 3692 3624 uint16_t temp; 3693 3625 3694 - ql_dbg(ql_dbg_tgt, vha, 0xe009, "Sending TERM EXCH CTIO (ha=%p)\n", ha); 3695 - 3696 - if (cmd) 3626 + if (cmd) { 3697 3627 vha = cmd->vha; 3628 + loop_id = cmd->loop_id; 3629 + } else { 3630 + port_id_t id = be_to_port_id(atio->u.isp24.fcp_hdr.s_id); 3631 + struct qla_hw_data *ha; 3632 + struct fc_port *sess; 3633 + unsigned long flags; 3698 3634 3699 - pkt = (request_t *)qla2x00_alloc_iocbs_ready(qpair, NULL); 3700 - if (pkt == NULL) { 3635 + vha = qpair->vha; 3636 + ha = vha->hw; 3637 + 3638 + /* 3639 + * CTIO7_NHANDLE_UNRECOGNIZED works when aborting an idle 3640 + * command but not when aborting a command with an active CTIO 3641 + * exchange. 3642 + */ 3643 + loop_id = CTIO7_NHANDLE_UNRECOGNIZED; 3644 + spin_lock_irqsave(&ha->tgt.sess_lock, flags); 3645 + sess = qla2x00_find_fcport_by_nportid(vha, &id, 1); 3646 + if (sess) 3647 + loop_id = sess->loop_id; 3648 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 3649 + } 3650 + 3651 + if (cmd) { 3652 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe009, 3653 + "qla_target(%d): tag %lld: Sending TERM EXCH CTIO state %d cmd_sent_to_fw %u\n", 3654 + vha->vp_idx, cmd->se_cmd.tag, cmd->state, 3655 + cmd->cmd_sent_to_fw); 3656 + } else { 3657 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe009, 3658 + "qla_target(%d): tag %u: Sending TERM EXCH CTIO (no cmd)\n", 3659 + vha->vp_idx, le32_to_cpu(atio->u.isp24.exchange_addr)); 3660 + } 3661 + 3662 + ctio24 = qla2x00_alloc_iocbs_ready(qpair, NULL); 3663 + if (!ctio24) { 3701 3664 ql_dbg(ql_dbg_tgt, vha, 0xe050, 3702 3665 "qla_target(%d): %s failed: unable to allocate " 3703 3666 "request packet\n", vha->vp_idx, __func__); 3704 3667 return -ENOMEM; 3705 3668 } 3706 3669 3707 - if (cmd != NULL) { 3708 - if (cmd->state < QLA_TGT_STATE_PROCESSED) { 3709 - ql_dbg(ql_dbg_tgt, vha, 0xe051, 3710 - "qla_target(%d): Terminating cmd %p with " 3711 - "incorrect state %d\n", vha->vp_idx, cmd, 3712 - cmd->state); 3713 - } else 3714 - ret = 1; 3715 - } 3716 - 3717 3670 qpair->tgt_counters.num_term_xchg_sent++; 3718 - pkt->entry_count = 1; 3719 - pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 3720 3671 3721 - ctio24 = (struct ctio7_to_24xx *)pkt; 3722 3672 ctio24->entry_type = CTIO_TYPE7; 3723 - ctio24->nport_handle = cpu_to_le16(CTIO7_NHANDLE_UNRECOGNIZED); 3673 + ctio24->entry_count = 1; 3674 + ctio24->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 3675 + ctio24->nport_handle = cpu_to_le16(loop_id); 3724 3676 ctio24->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); 3725 3677 ctio24->vp_index = vha->vp_idx; 3726 3678 ctio24->initiator_id = be_id_to_le(atio->u.isp24.fcp_hdr.s_id); ··· 3755 3671 qpair->reqq_start_iocbs(qpair); 3756 3672 else 3757 3673 qla2x00_start_iocbs(vha, qpair->req); 3758 - return ret; 3674 + return 0; 3759 3675 } 3760 3676 3761 - static void qlt_send_term_exchange(struct qla_qpair *qpair, 3762 - struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked, 3763 - int ul_abort) 3677 + /* 3678 + * Aborting a command that is active in the FW (i.e. cmd->cmd_sent_to_fw == 1) 3679 + * will usually trigger the FW to send a completion CTIO with error status, 3680 + * and the driver will then call the ->handle_data() or ->free_cmd() callbacks. 3681 + * This can be used to clear a command that is locked up in the FW unless there 3682 + * is something more seriously wrong. 3683 + * 3684 + * Aborting a command that is not active in the FW (i.e. 3685 + * cmd->cmd_sent_to_fw == 0) will not directly trigger any callbacks. Instead, 3686 + * when the target mode midlevel calls qlt_rdy_to_xfer() or 3687 + * qlt_xmit_response(), the driver will see that the cmd has been aborted and 3688 + * call the appropriate callback immediately without performing the requested 3689 + * operation. 3690 + */ 3691 + void qlt_send_term_exchange(struct qla_qpair *qpair, 3692 + struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) 3764 3693 { 3765 3694 struct scsi_qla_host *vha; 3766 3695 unsigned long flags = 0; ··· 3797 3700 qlt_alloc_qfull_cmd(vha, atio, 0, 0); 3798 3701 3799 3702 done: 3800 - if (cmd && !ul_abort && !cmd->aborted) { 3801 - if (cmd->sg_mapped) 3802 - qlt_unmap_sg(vha, cmd); 3803 - vha->hw->tgt.tgt_ops->free_cmd(cmd); 3703 + if (cmd) { 3704 + /* 3705 + * Set this even if -ENOMEM above, since term exchange will be 3706 + * sent eventually... 3707 + */ 3708 + cmd->sent_term_exchg = 1; 3709 + cmd->aborted = 1; 3710 + cmd->jiffies_at_term_exchg = jiffies; 3804 3711 } 3805 3712 3806 3713 if (!ha_locked) ··· 3812 3711 3813 3712 return; 3814 3713 } 3714 + EXPORT_SYMBOL(qlt_send_term_exchange); 3815 3715 3816 3716 static void qlt_init_term_exchange(struct scsi_qla_host *vha) 3817 3717 { ··· 3863 3761 3864 3762 int qlt_abort_cmd(struct qla_tgt_cmd *cmd) 3865 3763 { 3866 - struct qla_tgt *tgt = cmd->tgt; 3867 - struct scsi_qla_host *vha = tgt->vha; 3868 - struct se_cmd *se_cmd = &cmd->se_cmd; 3764 + struct scsi_qla_host *vha = cmd->vha; 3765 + struct qla_qpair *qpair = cmd->qpair; 3869 3766 unsigned long flags; 3870 3767 3768 + spin_lock_irqsave(qpair->qp_lock_ptr, flags); 3769 + 3871 3770 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, 3872 - "qla_target(%d): terminating exchange for aborted cmd=%p " 3873 - "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd, 3874 - se_cmd->tag); 3771 + "qla_target(%d): tag %lld: cmd being aborted (state %d) %s; %s\n", 3772 + vha->vp_idx, cmd->se_cmd.tag, cmd->state, 3773 + cmd->cmd_sent_to_fw ? "sent to fw" : "not sent to fw", 3774 + cmd->aborted ? "aborted" : "not aborted"); 3875 3775 3876 - spin_lock_irqsave(&cmd->cmd_lock, flags); 3877 - if (cmd->aborted) { 3878 - if (cmd->sg_mapped) 3879 - qlt_unmap_sg(vha, cmd); 3880 - 3881 - spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3882 - /* 3883 - * It's normal to see 2 calls in this path: 3884 - * 1) XFER Rdy completion + CMD_T_ABORT 3885 - * 2) TCM TMR - drain_state_list 3886 - */ 3887 - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf016, 3888 - "multiple abort. %p transport_state %x, t_state %x, " 3889 - "se_cmd_flags %x\n", cmd, cmd->se_cmd.transport_state, 3890 - cmd->se_cmd.t_state, cmd->se_cmd.se_cmd_flags); 3891 - return -EIO; 3776 + if (cmd->state != QLA_TGT_STATE_DONE && !cmd->sent_term_exchg) { 3777 + if (!qpair->fw_started || 3778 + cmd->reset_count != qpair->chip_reset) { 3779 + /* 3780 + * Chip was reset; just pretend that we sent the term 3781 + * exchange. 3782 + */ 3783 + cmd->sent_term_exchg = 1; 3784 + cmd->aborted = 1; 3785 + cmd->jiffies_at_term_exchg = jiffies; 3786 + } else { 3787 + qlt_send_term_exchange(qpair, cmd, &cmd->atio, 1); 3788 + } 3892 3789 } 3893 - cmd->aborted = 1; 3894 - cmd->trc_flags |= TRC_ABORT; 3895 - spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3896 3790 3897 - qlt_send_term_exchange(cmd->qpair, cmd, &cmd->atio, 0, 1); 3791 + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 3792 + 3898 3793 return 0; 3899 3794 } 3900 3795 EXPORT_SYMBOL(qlt_abort_cmd); ··· 3911 3812 qlt_decr_num_pend_cmds(cmd->vha); 3912 3813 3913 3814 BUG_ON(cmd->sg_mapped); 3815 + if (unlikely(cmd->free_sg)) { 3816 + cmd->free_sg = 0; 3817 + qlt_free_sg(cmd); 3818 + } 3819 + if (unlikely(cmd->srr)) 3820 + qlt_srr_abort(cmd, false); 3821 + 3822 + if (unlikely(cmd->aborted || 3823 + (cmd->trc_flags & (TRC_CTIO_STRANGE | TRC_CTIO_ERR | 3824 + TRC_SRR_CTIO | TRC_SRR_IMM)))) { 3825 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xe086, 3826 + "qla_target(%d): tag %lld: free cmd (trc_flags %x, aborted %u, sent_term_exchg %u, rsp_sent %u)\n", 3827 + cmd->vha->vp_idx, cmd->se_cmd.tag, 3828 + cmd->trc_flags, cmd->aborted, cmd->sent_term_exchg, 3829 + cmd->rsp_sent); 3830 + } 3831 + 3832 + if (unlikely(cmd->cdb != &cmd->atio.u.isp24.fcp_cmnd.cdb[0])) { 3833 + kfree(cmd->cdb); 3834 + cmd->cdb = &cmd->atio.u.isp24.fcp_cmnd.cdb[0]; 3835 + cmd->cdb_len = 16; 3836 + } 3837 + 3914 3838 cmd->jiffies_at_free = get_jiffies_64(); 3915 3839 3916 3840 if (!sess || !sess->se_sess) { 3917 3841 WARN_ON(1); 3918 3842 return; 3919 3843 } 3920 - cmd->jiffies_at_free = get_jiffies_64(); 3921 3844 cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd); 3922 3845 } 3923 3846 EXPORT_SYMBOL(qlt_free_cmd); 3924 3847 3925 3848 /* 3926 - * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 3849 + * Process a CTIO response for a SCSI command that failed due to SRR. 3850 + * 3851 + * qpair->qp_lock_ptr supposed to be held on entry 3927 3852 */ 3928 - static int qlt_term_ctio_exchange(struct qla_qpair *qpair, void *ctio, 3929 - struct qla_tgt_cmd *cmd, uint32_t status) 3853 + static int qlt_prepare_srr_ctio(struct qla_qpair *qpair, 3854 + struct qla_tgt_cmd *cmd) 3930 3855 { 3931 - int term = 0; 3932 - struct scsi_qla_host *vha = qpair->vha; 3856 + struct scsi_qla_host *vha = cmd->vha; 3857 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 3858 + struct qla_tgt_srr *srr; 3933 3859 3934 - if (cmd->se_cmd.prot_op) 3935 - ql_dbg(ql_dbg_tgt_dif, vha, 0xe013, 3936 - "Term DIF cmd: lba[0x%llx|%lld] len[0x%x] " 3937 - "se_cmd=%p tag[%x] op %#x/%s", 3938 - cmd->lba, cmd->lba, 3939 - cmd->num_blks, &cmd->se_cmd, 3940 - cmd->atio.u.isp24.exchange_addr, 3941 - cmd->se_cmd.prot_op, 3942 - prot_op_str(cmd->se_cmd.prot_op)); 3860 + cmd->trc_flags |= TRC_SRR_CTIO; 3943 3861 3944 - if (ctio != NULL) { 3945 - struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; 3862 + srr = cmd->srr; 3863 + if (srr != NULL) { 3864 + /* qlt_prepare_srr_imm() was called first. */ 3946 3865 3947 - term = !(c->flags & 3948 - cpu_to_le16(OF_TERM_EXCH)); 3949 - } else 3950 - term = 1; 3866 + WARN_ON(srr->ctio_recvd); 3867 + WARN_ON(!srr->imm_ntfy_recvd); 3951 3868 3952 - if (term) 3953 - qlt_send_term_exchange(qpair, cmd, &cmd->atio, 1, 0); 3869 + if (vha->hw->tgt.tgt_ops->get_cmd_ref(cmd)) { 3870 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11037, 3871 + "qla_target(%d): tag %lld: unable to get cmd ref for SRR processing\n", 3872 + vha->vp_idx, cmd->se_cmd.tag); 3873 + qlt_srr_abort(cmd, true); 3874 + return -ESHUTDOWN; 3875 + } 3954 3876 3955 - return term; 3877 + srr->ctio_recvd = true; 3878 + 3879 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100f, 3880 + "qla_target(%d): tag %lld: Scheduling SRR work\n", 3881 + vha->vp_idx, cmd->se_cmd.tag); 3882 + 3883 + /* Schedule the srr for processing in qlt_handle_srr(). */ 3884 + /* IRQ is already OFF */ 3885 + spin_lock(&tgt->srr_lock); 3886 + list_add_tail(&srr->srr_list_entry, &tgt->srr_list); 3887 + queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &tgt->srr_work); 3888 + spin_unlock(&tgt->srr_lock); 3889 + return 0; 3890 + } 3891 + 3892 + srr = kzalloc(sizeof(*srr), GFP_ATOMIC); 3893 + if (!srr) 3894 + return -ENOMEM; 3895 + 3896 + /* Expect qlt_prepare_srr_imm() to be called. */ 3897 + srr->ctio_recvd = true; 3898 + srr->cmd = cmd; 3899 + srr->reset_count = cmd->reset_count; 3900 + cmd->srr = srr; 3901 + return 0; 3956 3902 } 3957 - 3958 3903 3959 3904 /* ha->hardware_lock supposed to be held on entry */ 3960 3905 static void *qlt_ctio_to_cmd(struct scsi_qla_host *vha, 3961 - struct rsp_que *rsp, uint32_t handle, void *ctio) 3906 + struct rsp_que *rsp, uint32_t handle, uint8_t cmd_type, 3907 + const void *ctio) 3962 3908 { 3963 3909 void *cmd = NULL; 3964 3910 struct req_que *req; ··· 4026 3882 4027 3883 h &= QLA_CMD_HANDLE_MASK; 4028 3884 4029 - if (h != QLA_TGT_NULL_HANDLE) { 4030 - if (unlikely(h >= req->num_outstanding_cmds)) { 4031 - ql_dbg(ql_dbg_tgt, vha, 0xe052, 4032 - "qla_target(%d): Wrong handle %x received\n", 4033 - vha->vp_idx, handle); 4034 - return NULL; 4035 - } 4036 - 4037 - cmd = req->outstanding_cmds[h]; 4038 - if (unlikely(cmd == NULL)) { 4039 - ql_dbg(ql_dbg_async, vha, 0xe053, 4040 - "qla_target(%d): Suspicious: unable to find the command with handle %x req->id %d rsp->id %d\n", 4041 - vha->vp_idx, handle, req->id, rsp->id); 4042 - return NULL; 4043 - } 4044 - req->outstanding_cmds[h] = NULL; 4045 - } else if (ctio != NULL) { 3885 + if (h == QLA_TGT_NULL_HANDLE) { 4046 3886 /* We can't get loop ID from CTIO7 */ 4047 3887 ql_dbg(ql_dbg_tgt, vha, 0xe054, 4048 3888 "qla_target(%d): Wrong CTIO received: QLA24xx doesn't " 4049 3889 "support NULL handles\n", vha->vp_idx); 4050 3890 return NULL; 4051 3891 } 3892 + if (unlikely(h >= req->num_outstanding_cmds)) { 3893 + ql_dbg(ql_dbg_tgt, vha, 0xe052, 3894 + "qla_target(%d): Wrong handle %x received\n", 3895 + vha->vp_idx, handle); 3896 + return NULL; 3897 + } 3898 + 3899 + /* 3900 + * We passed a numeric handle for a cmd to the hardware, and the 3901 + * hardware passed the handle back to us. Look up the associated cmd, 3902 + * and validate that the cmd_type and exchange address match what the 3903 + * caller expects. This guards against buggy HBA firmware that returns 3904 + * the same CTIO multiple times. 3905 + */ 3906 + 3907 + cmd = req->outstanding_cmds[h]; 3908 + 3909 + if (unlikely(cmd == NULL)) { 3910 + if (cmd_type == TYPE_TGT_CMD) { 3911 + __le32 ctio_exchange_addr = 3912 + ((const struct ctio7_from_24xx *)ctio)-> 3913 + exchange_address; 3914 + 3915 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe053, 3916 + "qla_target(%d): tag %u: handle %x: cmd detached; ignoring CTIO (handle %x req->id %d rsp->id %d)\n", 3917 + vha->vp_idx, le32_to_cpu(ctio_exchange_addr), h, 3918 + handle, req->id, rsp->id); 3919 + } else { 3920 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe053, 3921 + "qla_target(%d): cmd detached; ignoring CTIO (handle %x req->id %d rsp->id %d)\n", 3922 + vha->vp_idx, handle, req->id, rsp->id); 3923 + } 3924 + return NULL; 3925 + } 3926 + 3927 + if (unlikely(((srb_t *)cmd)->cmd_type != cmd_type)) { 3928 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe087, 3929 + "qla_target(%d): handle %x: cmd detached; ignoring CTIO (cmd_type mismatch)\n", 3930 + vha->vp_idx, h); 3931 + return NULL; 3932 + } 3933 + 3934 + switch (cmd_type) { 3935 + case TYPE_TGT_CMD: { 3936 + __le32 ctio_exchange_addr = 3937 + ((const struct ctio7_from_24xx *)ctio)-> 3938 + exchange_address; 3939 + __le32 cmd_exchange_addr = 3940 + ((struct qla_tgt_cmd *)cmd)-> 3941 + atio.u.isp24.exchange_addr; 3942 + 3943 + BUILD_BUG_ON(offsetof(struct ctio7_from_24xx, 3944 + exchange_address) != 3945 + offsetof(struct ctio_crc_from_fw, 3946 + exchange_address)); 3947 + 3948 + if (unlikely(ctio_exchange_addr != cmd_exchange_addr)) { 3949 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe088, 3950 + "qla_target(%d): tag %u: handle %x: cmd detached; ignoring CTIO (exchange address mismatch)\n", 3951 + vha->vp_idx, le32_to_cpu(ctio_exchange_addr), h); 3952 + return NULL; 3953 + } 3954 + break; 3955 + } 3956 + 3957 + case TYPE_TGT_TMCMD: { 3958 + __le32 ctio_exchange_addr = 3959 + ((const struct abts_resp_from_24xx_fw *)ctio)-> 3960 + exchange_address; 3961 + __le32 cmd_exchange_addr = 3962 + ((struct qla_tgt_mgmt_cmd *)cmd)-> 3963 + orig_iocb.abts.exchange_address; 3964 + 3965 + if (unlikely(ctio_exchange_addr != cmd_exchange_addr)) { 3966 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe089, 3967 + "qla_target(%d): ABTS: handle %x: cmd detached; ignoring CTIO (exchange address mismatch)\n", 3968 + vha->vp_idx, h); 3969 + return NULL; 3970 + } 3971 + break; 3972 + } 3973 + } 3974 + 3975 + req->outstanding_cmds[h] = NULL; 4052 3976 4053 3977 return cmd; 4054 3978 } ··· 4125 3913 * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 4126 3914 */ 4127 3915 static void qlt_do_ctio_completion(struct scsi_qla_host *vha, 4128 - struct rsp_que *rsp, uint32_t handle, uint32_t status, void *ctio) 3916 + struct rsp_que *rsp, uint32_t handle, uint32_t status, 3917 + struct ctio7_from_24xx *ctio) 4129 3918 { 4130 3919 struct qla_hw_data *ha = vha->hw; 4131 - struct se_cmd *se_cmd; 4132 3920 struct qla_tgt_cmd *cmd; 4133 3921 struct qla_qpair *qpair = rsp->qpair; 3922 + uint16_t ctio_flags; 4134 3923 4135 3924 if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { 4136 3925 /* That could happen only in case of an error/reset/abort */ ··· 4143 3930 return; 4144 3931 } 4145 3932 4146 - cmd = qlt_ctio_to_cmd(vha, rsp, handle, ctio); 4147 - if (cmd == NULL) 4148 - return; 3933 + ctio_flags = le16_to_cpu(ctio->flags); 4149 3934 4150 - if ((le16_to_cpu(((struct ctio7_from_24xx *)ctio)->flags) & CTIO7_FLAGS_DATA_OUT) && 4151 - cmd->sess) { 4152 - qlt_chk_edif_rx_sa_delete_pending(vha, cmd->sess, 4153 - (struct ctio7_from_24xx *)ctio); 3935 + cmd = qlt_ctio_to_cmd(vha, rsp, handle, TYPE_TGT_CMD, ctio); 3936 + if (unlikely(cmd == NULL)) { 3937 + if ((handle & ~QLA_TGT_HANDLE_MASK) == QLA_TGT_SKIP_HANDLE && 3938 + (ctio_flags & 0xe1ff) == (CTIO7_FLAGS_STATUS_MODE_1 | 3939 + CTIO7_FLAGS_TERMINATE)) { 3940 + u32 tag = le32_to_cpu(ctio->exchange_address); 3941 + 3942 + if (status == CTIO_SUCCESS) 3943 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe083, 3944 + "qla_target(%d): tag %u: term exchange successful\n", 3945 + vha->vp_idx, tag); 3946 + else 3947 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xe084, 3948 + "qla_target(%d): tag %u: term exchange failed; status = 0x%x\n", 3949 + vha->vp_idx, tag, status); 3950 + } 3951 + return; 4154 3952 } 4155 3953 4156 - se_cmd = &cmd->se_cmd; 3954 + if ((ctio_flags & CTIO7_FLAGS_DATA_OUT) && cmd->sess) 3955 + qlt_chk_edif_rx_sa_delete_pending(vha, cmd->sess, ctio); 3956 + 4157 3957 cmd->cmd_sent_to_fw = 0; 4158 3958 4159 3959 qlt_unmap_sg(vha, cmd); 4160 3960 4161 3961 if (unlikely(status != CTIO_SUCCESS)) { 3962 + u8 op = cmd->cdb ? cmd->cdb[0] : 0; 3963 + bool term_exchg = false; 3964 + 3965 + /* 3966 + * If the hardware terminated the exchange, then we don't need 3967 + * to send an explicit term exchange message. 3968 + */ 3969 + if (ctio_flags & OF_TERM_EXCH) { 3970 + cmd->sent_term_exchg = 1; 3971 + cmd->aborted = 1; 3972 + cmd->jiffies_at_term_exchg = jiffies; 3973 + } 3974 + 4162 3975 switch (status & 0xFFFF) { 4163 3976 case CTIO_INVALID_RX_ID: 3977 + term_exchg = true; 4164 3978 if (printk_ratelimit()) 4165 3979 dev_info(&vha->hw->pdev->dev, 4166 - "qla_target(%d): CTIO with INVALID_RX_ID ATIO attr %x CTIO Flags %x|%x\n", 4167 - vha->vp_idx, cmd->atio.u.isp24.attr, 3980 + "qla_target(%d): tag %lld, op %x: CTIO with INVALID_RX_ID status 0x%x received (state %d, port %8phC, LUN %lld, ATIO attr %x, CTIO Flags %x|%x)\n", 3981 + vha->vp_idx, cmd->se_cmd.tag, op, 3982 + status, cmd->state, cmd->sess->port_name, 3983 + cmd->unpacked_lun, cmd->atio.u.isp24.attr, 4168 3984 ((cmd->ctio_flags >> 9) & 0xf), 4169 3985 cmd->ctio_flags); 4170 - 4171 3986 break; 3987 + 4172 3988 case CTIO_LIP_RESET: 4173 3989 case CTIO_TARGET_RESET: 4174 3990 case CTIO_ABORTED: 4175 - /* driver request abort via Terminate exchange */ 3991 + term_exchg = true; 3992 + fallthrough; 4176 3993 case CTIO_TIMEOUT: 4177 - /* They are OK */ 3994 + { 3995 + const char *status_str; 3996 + 3997 + switch (status & 0xFFFF) { 3998 + case CTIO_LIP_RESET: 3999 + status_str = "LIP_RESET"; 4000 + break; 4001 + case CTIO_TARGET_RESET: 4002 + status_str = "TARGET_RESET"; 4003 + break; 4004 + case CTIO_ABORTED: 4005 + status_str = "ABORTED"; 4006 + break; 4007 + case CTIO_TIMEOUT: 4008 + default: 4009 + status_str = "TIMEOUT"; 4010 + break; 4011 + } 4178 4012 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf058, 4179 - "qla_target(%d): CTIO with " 4180 - "status %#x received, state %x, se_cmd %p, " 4181 - "(LIP_RESET=e, ABORTED=2, TARGET_RESET=17, " 4182 - "TIMEOUT=b, INVALID_RX_ID=8)\n", vha->vp_idx, 4183 - status, cmd->state, se_cmd); 4013 + "qla_target(%d): tag %lld, op %x: CTIO with %s status 0x%x received (state %d, port %8phC, LUN %lld)\n", 4014 + vha->vp_idx, cmd->se_cmd.tag, op, 4015 + status_str, status, cmd->state, 4016 + cmd->sess->port_name, cmd->unpacked_lun); 4184 4017 break; 4018 + } 4185 4019 4186 4020 case CTIO_PORT_LOGGED_OUT: 4187 4021 case CTIO_PORT_UNAVAILABLE: ··· 4237 3977 (status & 0xFFFF) == CTIO_PORT_LOGGED_OUT; 4238 3978 4239 3979 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059, 4240 - "qla_target(%d): CTIO with %s status %x " 4241 - "received (state %x, se_cmd %p)\n", vha->vp_idx, 3980 + "qla_target(%d): tag %lld, op %x: CTIO with %s status 0x%x received (state %d, port %8phC, LUN %lld)\n", 3981 + vha->vp_idx, cmd->se_cmd.tag, op, 4242 3982 logged_out ? "PORT LOGGED OUT" : "PORT UNAVAILABLE", 4243 - status, cmd->state, se_cmd); 3983 + status, cmd->state, cmd->sess->port_name, 3984 + cmd->unpacked_lun); 4244 3985 3986 + term_exchg = true; 4245 3987 if (logged_out && cmd->sess) { 4246 3988 /* 4247 3989 * Session is already logged out, but we need ··· 4258 3996 } 4259 3997 break; 4260 3998 } 3999 + 4000 + case CTIO_SRR_RECEIVED: 4001 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100e, 4002 + "qla_target(%d): tag %lld, op %x: CTIO with SRR status 0x%x received (state %d, port %8phC, LUN %lld, bufflen %d)\n", 4003 + vha->vp_idx, cmd->se_cmd.tag, op, status, 4004 + cmd->state, cmd->sess->port_name, 4005 + cmd->unpacked_lun, cmd->bufflen); 4006 + 4007 + if (qlt_prepare_srr_ctio(qpair, cmd) == 0) 4008 + return; 4009 + break; 4010 + 4261 4011 case CTIO_DIF_ERROR: { 4262 4012 struct ctio_crc_from_fw *crc = 4263 4013 (struct ctio_crc_from_fw *)ctio; 4264 4014 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073, 4265 - "qla_target(%d): CTIO with DIF_ERROR status %x " 4266 - "received (state %x, ulp_cmd %p) actual_dif[0x%llx] " 4267 - "expect_dif[0x%llx]\n", 4268 - vha->vp_idx, status, cmd->state, se_cmd, 4015 + "qla_target(%d): tag %lld, op %x: CTIO with DIF_ERROR status 0x%x received (state %d, port %8phC, LUN %lld, actual_dif[0x%llx] expect_dif[0x%llx])\n", 4016 + vha->vp_idx, cmd->se_cmd.tag, op, status, 4017 + cmd->state, cmd->sess->port_name, 4018 + cmd->unpacked_lun, 4269 4019 *((u64 *)&crc->actual_dif[0]), 4270 4020 *((u64 *)&crc->expected_dif[0])); 4271 4021 4272 - qlt_handle_dif_error(qpair, cmd, ctio); 4022 + qlt_handle_dif_error(qpair, cmd, crc); 4273 4023 return; 4274 4024 } 4275 4025 ··· 4290 4016 case CTIO_FAST_INVALID_REQ: 4291 4017 case CTIO_FAST_SPI_ERR: 4292 4018 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, 4293 - "qla_target(%d): CTIO with EDIF error status 0x%x received (state %x, se_cmd %p\n", 4294 - vha->vp_idx, status, cmd->state, se_cmd); 4019 + "qla_target(%d): tag %lld, op %x: CTIO with EDIF error status 0x%x received (state %d, port %8phC, LUN %lld)\n", 4020 + vha->vp_idx, cmd->se_cmd.tag, op, status, 4021 + cmd->state, cmd->sess->port_name, 4022 + cmd->unpacked_lun); 4295 4023 break; 4296 4024 4297 4025 default: 4298 4026 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, 4299 - "qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n", 4300 - vha->vp_idx, status, cmd->state, se_cmd); 4027 + "qla_target(%d): tag %lld, op %x: CTIO with error status 0x%x received (state %d, port %8phC, LUN %lld)\n", 4028 + vha->vp_idx, cmd->se_cmd.tag, op, status, 4029 + cmd->state, cmd->sess->port_name, 4030 + cmd->unpacked_lun); 4301 4031 break; 4302 4032 } 4303 4033 4034 + cmd->trc_flags |= TRC_CTIO_ERR; 4304 4035 4305 - /* "cmd->aborted" means 4306 - * cmd is already aborted/terminated, we don't 4307 - * need to terminate again. The exchange is already 4308 - * cleaned up/freed at FW level. Just cleanup at driver 4309 - * level. 4036 + /* 4037 + * In state QLA_TGT_STATE_NEED_DATA the failed CTIO was for 4038 + * Data-Out, so either abort the exchange or try sending check 4039 + * condition with sense data depending on the severity of 4040 + * the error. In state QLA_TGT_STATE_PROCESSED the failed CTIO 4041 + * was for status (and possibly Data-In), so don't try sending 4042 + * an error status again in that case (if the error was for 4043 + * Data-In with status, we could try sending status without 4044 + * Data-In, but we don't do that currently). 4310 4045 */ 4311 - if ((cmd->state != QLA_TGT_STATE_NEED_DATA) && 4312 - (!cmd->aborted)) { 4313 - cmd->trc_flags |= TRC_CTIO_ERR; 4314 - if (qlt_term_ctio_exchange(qpair, ctio, cmd, status)) 4315 - return; 4316 - } 4046 + if (!cmd->sent_term_exchg && 4047 + (term_exchg || cmd->state != QLA_TGT_STATE_NEED_DATA)) 4048 + qlt_send_term_exchange(qpair, cmd, &cmd->atio, 1); 4049 + } 4050 + 4051 + if (unlikely(cmd->srr != NULL)) { 4052 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11031, 4053 + "qla_target(%d): tag %lld, op %x: expected CTIO with SRR status; got status 0x%x: state %d, bufflen %d\n", 4054 + vha->vp_idx, cmd->se_cmd.tag, 4055 + cmd->cdb ? cmd->cdb[0] : 0, status, cmd->state, 4056 + cmd->bufflen); 4057 + qlt_srr_abort(cmd, true); 4317 4058 } 4318 4059 4319 4060 if (cmd->state == QLA_TGT_STATE_PROCESSED) { 4320 4061 cmd->trc_flags |= TRC_CTIO_DONE; 4062 + 4063 + if (likely(status == CTIO_SUCCESS)) 4064 + cmd->rsp_sent = 1; 4065 + 4321 4066 } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 4322 4067 cmd->state = QLA_TGT_STATE_DATA_IN; 4323 4068 4324 4069 if (status == CTIO_SUCCESS) 4325 4070 cmd->write_data_transferred = 1; 4326 4071 4072 + cmd->jiffies_at_hw_st_entry = 0; 4327 4073 ha->tgt.tgt_ops->handle_data(cmd); 4328 4074 return; 4329 4075 } else if (cmd->aborted) { 4330 4076 cmd->trc_flags |= TRC_CTIO_ABORTED; 4331 4077 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e, 4332 - "Aborted command %p (tag %lld) finished\n", cmd, se_cmd->tag); 4078 + "qla_target(%d): tag %lld: Aborted command finished\n", 4079 + vha->vp_idx, cmd->se_cmd.tag); 4333 4080 } else { 4334 4081 cmd->trc_flags |= TRC_CTIO_STRANGE; 4335 4082 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c, 4336 - "qla_target(%d): A command in state (%d) should " 4337 - "not return a CTIO complete\n", vha->vp_idx, cmd->state); 4083 + "qla_target(%d): tag %lld: A command in state (%d) should not return a CTIO complete\n", 4084 + vha->vp_idx, cmd->se_cmd.tag, cmd->state); 4338 4085 } 4339 4086 4340 4087 if (unlikely(status != CTIO_SUCCESS) && ··· 4408 4113 struct qla_hw_data *ha = vha->hw; 4409 4114 struct fc_port *sess = cmd->sess; 4410 4115 struct atio_from_isp *atio = &cmd->atio; 4411 - unsigned char *cdb; 4412 4116 unsigned long flags; 4413 4117 uint32_t data_length; 4414 4118 int ret, fcp_task_attr, data_dir, bidi = 0; ··· 4423 4129 goto out_term; 4424 4130 } 4425 4131 4426 - spin_lock_init(&cmd->cmd_lock); 4427 - cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; 4428 4132 cmd->se_cmd.tag = le32_to_cpu(atio->u.isp24.exchange_addr); 4429 4133 4430 4134 if (atio->u.isp24.fcp_cmnd.rddata && ··· 4440 4148 atio->u.isp24.fcp_cmnd.task_attr); 4441 4149 data_length = get_datalen_for_atio(atio); 4442 4150 4443 - ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length, 4151 + ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cmd->cdb, data_length, 4444 4152 fcp_task_attr, data_dir, bidi); 4445 4153 if (ret != 0) 4446 4154 goto out_term; ··· 4458 4166 */ 4459 4167 cmd->trc_flags |= TRC_DO_WORK_ERR; 4460 4168 spin_lock_irqsave(qpair->qp_lock_ptr, flags); 4461 - qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1, 0); 4169 + qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1); 4462 4170 4463 4171 qlt_decr_num_pend_cmds(vha); 4172 + if (unlikely(cmd->cdb != &cmd->atio.u.isp24.fcp_cmnd.cdb[0])) { 4173 + kfree(cmd->cdb); 4174 + cmd->cdb = &cmd->atio.u.isp24.fcp_cmnd.cdb[0]; 4175 + cmd->cdb_len = 16; 4176 + } 4464 4177 cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd); 4465 4178 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); 4466 4179 ··· 4589 4292 cmd->se_cmd.cpuid = h->cpuid; 4590 4293 } 4591 4294 4295 + /* 4296 + * Safely make a fixed-length copy of a variable-length atio by truncating the 4297 + * CDB if necessary. 4298 + */ 4299 + static void memcpy_atio(struct atio_from_isp *dst, 4300 + const struct atio_from_isp *src) 4301 + { 4302 + int len; 4303 + 4304 + memcpy(dst, src, sizeof(*dst)); 4305 + 4306 + /* 4307 + * If the CDB was truncated, prevent get_datalen_for_atio() from 4308 + * accessing invalid memory. 4309 + */ 4310 + len = src->u.isp24.fcp_cmnd.add_cdb_len; 4311 + if (unlikely(len != 0)) { 4312 + dst->u.isp24.fcp_cmnd.add_cdb_len = 0; 4313 + memcpy(&dst->u.isp24.fcp_cmnd.add_cdb[0], 4314 + &src->u.isp24.fcp_cmnd.add_cdb[len * 4], 4315 + 4); 4316 + } 4317 + } 4318 + 4592 4319 static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, 4593 4320 struct fc_port *sess, 4594 4321 struct atio_from_isp *atio) 4595 4322 { 4596 4323 struct qla_tgt_cmd *cmd; 4324 + int add_cdb_len; 4597 4325 4598 4326 cmd = vha->hw->tgt.tgt_ops->get_cmd(sess); 4599 4327 if (!cmd) 4600 4328 return NULL; 4601 4329 4602 4330 cmd->cmd_type = TYPE_TGT_CMD; 4603 - memcpy(&cmd->atio, atio, sizeof(*atio)); 4331 + memcpy_atio(&cmd->atio, atio); 4604 4332 INIT_LIST_HEAD(&cmd->sess_cmd_list); 4605 4333 cmd->state = QLA_TGT_STATE_NEW; 4606 4334 cmd->tgt = vha->vha_tgt.qla_tgt; ··· 4644 4322 cmd->reset_count = vha->hw->base_qpair->chip_reset; 4645 4323 cmd->vp_idx = vha->vp_idx; 4646 4324 cmd->edif = sess->edif.enable; 4325 + 4326 + cmd->cdb = &cmd->atio.u.isp24.fcp_cmnd.cdb[0]; 4327 + cmd->cdb_len = 16; 4328 + 4329 + /* 4330 + * NOTE: memcpy_atio() set cmd->atio.u.isp24.fcp_cmnd.add_cdb_len to 0, 4331 + * so use the original value here. 4332 + */ 4333 + add_cdb_len = atio->u.isp24.fcp_cmnd.add_cdb_len; 4334 + if (unlikely(add_cdb_len != 0)) { 4335 + int cdb_len = 16 + add_cdb_len * 4; 4336 + u8 *cdb; 4337 + 4338 + cdb = kmalloc(cdb_len, GFP_ATOMIC); 4339 + if (unlikely(!cdb)) { 4340 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 4341 + return NULL; 4342 + } 4343 + /* CAUTION: copy CDB from atio not cmd->atio */ 4344 + memcpy(cdb, atio->u.isp24.fcp_cmnd.cdb, cdb_len); 4345 + cmd->cdb = cdb; 4346 + cmd->cdb_len = cdb_len; 4347 + } 4647 4348 4648 4349 return cmd; 4649 4350 } ··· 5245 4900 } 5246 4901 5247 4902 /* 4903 + * Return true if the HBA firmware version is known to have bugs that 4904 + * prevent Sequence Level Error Recovery (SLER) / Sequence Retransmission 4905 + * Request (SRR) from working. 4906 + * 4907 + * Some bad versions are based on testing and some are based on "Marvell Fibre 4908 + * Channel Firmware Release Notes". 4909 + */ 4910 + static bool qlt_has_sler_fw_bug(struct qla_hw_data *ha) 4911 + { 4912 + bool has_sler_fw_bug = false; 4913 + 4914 + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { 4915 + /* 4916 + * In the fw release notes: 4917 + * ER147301 was added to v9.05.00 causing SLER regressions 4918 + * FCD-259 was fixed in v9.08.00 4919 + * FCD-371 was fixed in v9.08.00 4920 + * FCD-1183 was fixed in v9.09.00 4921 + * 4922 + * QLE2694L (ISP2071) known bad firmware (tested): 4923 + * 9.06.02 4924 + * 9.07.00 4925 + * 9.08.02 4926 + * SRRs trigger hundreds of bogus entries in the response 4927 + * queue and various other problems. 4928 + * 4929 + * QLE2694L known good firmware (tested): 4930 + * 8.08.05 4931 + * 9.09.00 4932 + * 4933 + * Suspected bad firmware (not confirmed by testing): 4934 + * v9.05.xx 4935 + * 4936 + * unknown firmware: 4937 + * 9.00.00 - 9.04.xx 4938 + */ 4939 + if (ha->fw_major_version == 9 && 4940 + ha->fw_minor_version >= 5 && 4941 + ha->fw_minor_version <= 8) 4942 + has_sler_fw_bug = true; 4943 + } 4944 + 4945 + return has_sler_fw_bug; 4946 + } 4947 + 4948 + /* 4949 + * Return true and print a message if the HA has been reset since the SRR 4950 + * immediate notify was received; else return false. 4951 + */ 4952 + static bool qlt_srr_is_chip_reset(struct scsi_qla_host *vha, 4953 + struct qla_qpair *qpair, struct qla_tgt_srr *srr) 4954 + { 4955 + if (!vha->flags.online || 4956 + !qpair->fw_started || 4957 + srr->reset_count != qpair->chip_reset) { 4958 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100d, 4959 + "qla_target(%d): chip reset; discarding IMM SRR\n", 4960 + vha->vp_idx); 4961 + return true; 4962 + } 4963 + return false; 4964 + } 4965 + 4966 + /* Find and return the command associated with a SRR immediate notify. */ 4967 + static struct qla_tgt_cmd *qlt_srr_to_cmd(struct scsi_qla_host *vha, 4968 + const struct imm_ntfy_from_isp *iocb) 4969 + { 4970 + struct qla_hw_data *ha = vha->hw; 4971 + struct fc_port *sess; 4972 + struct qla_tgt_cmd *cmd; 4973 + uint32_t tag = le32_to_cpu(iocb->u.isp24.exchange_address); 4974 + uint16_t loop_id; 4975 + be_id_t s_id; 4976 + unsigned long flags; 4977 + 4978 + if (tag == ATIO_EXCHANGE_ADDRESS_UNKNOWN) { 4979 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11009, 4980 + "qla_target(%d): IMM SRR with unknown exchange address; reject SRR\n", 4981 + vha->vp_idx); 4982 + return NULL; 4983 + } 4984 + 4985 + loop_id = le16_to_cpu(iocb->u.isp24.nport_handle); 4986 + 4987 + s_id.domain = iocb->u.isp24.port_id[2]; 4988 + s_id.area = iocb->u.isp24.port_id[1]; 4989 + s_id.al_pa = iocb->u.isp24.port_id[0]; 4990 + 4991 + spin_lock_irqsave(&ha->tgt.sess_lock, flags); 4992 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); 4993 + if (!sess) 4994 + sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id); 4995 + if (!sess || sess->deleted) { 4996 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100a, 4997 + "qla_target(%d): could not find session for IMM SRR; reject SRR\n", 4998 + vha->vp_idx); 4999 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5000 + return NULL; 5001 + } 5002 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5003 + 5004 + cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess, tag); 5005 + if (!cmd) { 5006 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100b, 5007 + "qla_target(%d): could not find cmd for IMM SRR; reject SRR\n", 5008 + vha->vp_idx); 5009 + } else { 5010 + u16 srr_ox_id = le16_to_cpu(iocb->u.isp24.srr_ox_id); 5011 + u16 cmd_ox_id = be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id); 5012 + 5013 + if (srr_ox_id != cmd_ox_id) { 5014 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1100c, 5015 + "qla_target(%d): tag %lld: IMM SRR: srr_ox_id[%04x] != cmd_ox_id[%04x]; reject SRR\n", 5016 + vha->vp_idx, cmd->se_cmd.tag, 5017 + srr_ox_id, cmd_ox_id); 5018 + cmd = NULL; 5019 + } 5020 + } 5021 + 5022 + return cmd; 5023 + } 5024 + 5025 + /* 5026 + * Handle an immediate notify SRR (Sequence Retransmission Request) message from 5027 + * the hardware. The hardware will also send a CTIO with CTIO_SRR_RECEIVED status 5028 + * for the affected command. 5029 + * 5030 + * This may be called a second time for the same immediate notify SRR if 5031 + * CTIO_SRR_RECEIVED is never received and qlt_srr_abort() is called. 5032 + * 5033 + * Process context, no locks 5034 + */ 5035 + static void qlt_handle_srr_imm(struct scsi_qla_host *vha, 5036 + struct qla_tgt_srr *srr) 5037 + { 5038 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 5039 + struct qla_hw_data *ha = vha->hw; 5040 + struct qla_qpair *qpair; 5041 + struct qla_tgt_cmd *cmd; 5042 + uint8_t srr_explain = NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL; 5043 + 5044 + /* handle qlt_srr_abort() */ 5045 + if (srr->aborted) { 5046 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11004, 5047 + "qla_target(%d): IMM SRR: terminating SRR for aborted cmd\n", 5048 + vha->vp_idx); 5049 + spin_lock_irq(&ha->hardware_lock); 5050 + if (!qlt_srr_is_chip_reset(vha, ha->base_qpair, srr)) 5051 + qlt_send_term_imm_notif(vha, &srr->imm_ntfy, 1); 5052 + spin_unlock_irq(&ha->hardware_lock); 5053 + kfree(srr); 5054 + return; 5055 + } 5056 + if (srr->reject) { 5057 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11005, 5058 + "qla_target(%d): IMM SRR: rejecting SRR for unknown cmd\n", 5059 + vha->vp_idx); 5060 + goto out_reject; 5061 + } 5062 + 5063 + /* Find the command associated with the SRR. */ 5064 + cmd = qlt_srr_to_cmd(vha, &srr->imm_ntfy); 5065 + if (cmd == NULL) { 5066 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11005, 5067 + "qla_target(%d): IMM SRR: rejecting SRR for unknown cmd\n", 5068 + vha->vp_idx); 5069 + srr_explain = NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_INVALID_OX_ID_RX_ID; 5070 + goto out_reject; 5071 + } 5072 + 5073 + if (ha->tgt.tgt_ops->get_cmd_ref(cmd)) { 5074 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11038, 5075 + "qla_target(%d): IMM SRR: unable to get cmd ref; rejecting SRR\n", 5076 + vha->vp_idx); 5077 + cmd = NULL; 5078 + goto out_reject; 5079 + } 5080 + 5081 + qpair = cmd->qpair; 5082 + 5083 + spin_lock_irq(qpair->qp_lock_ptr); 5084 + 5085 + if (cmd->reset_count != srr->reset_count) { 5086 + /* force a miscompare */ 5087 + srr->reset_count = qpair->chip_reset ^ 1; 5088 + } 5089 + if (qlt_srr_is_chip_reset(vha, qpair, srr)) { 5090 + spin_unlock_irq(qpair->qp_lock_ptr); 5091 + ha->tgt.tgt_ops->put_cmd_ref(cmd); 5092 + kfree(srr); 5093 + return; 5094 + } 5095 + 5096 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11001, 5097 + "qla_target(%d): tag %lld, op %x: received IMM SRR\n", 5098 + vha->vp_idx, cmd->se_cmd.tag, cmd->cdb ? cmd->cdb[0] : 0); 5099 + 5100 + cmd->trc_flags |= TRC_SRR_IMM; 5101 + 5102 + if (cmd->srr != NULL) { 5103 + if (cmd->srr->imm_ntfy_recvd) { 5104 + /* 5105 + * Received another immediate notify SRR message for 5106 + * this command before the previous one could be processed 5107 + * (not expected to happen). 5108 + */ 5109 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11006, 5110 + "qla_target(%d): tag %lld: received multiple IMM SRR; reject SRR\n", 5111 + vha->vp_idx, cmd->se_cmd.tag); 5112 + spin_unlock_irq(qpair->qp_lock_ptr); 5113 + ha->tgt.tgt_ops->put_cmd_ref(cmd); 5114 + goto out_reject; 5115 + } 5116 + 5117 + /* qlt_prepare_srr_ctio() was called first. */ 5118 + WARN_ON(!cmd->srr->ctio_recvd); 5119 + 5120 + /* 5121 + * The immediate notify and CTIO handlers both allocated 5122 + * separate srr structs; combine them. 5123 + */ 5124 + memcpy(&cmd->srr->imm_ntfy, &srr->imm_ntfy, 5125 + sizeof(srr->imm_ntfy)); 5126 + kfree(srr); 5127 + srr = cmd->srr; 5128 + srr->imm_ntfy_recvd = true; 5129 + 5130 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11002, 5131 + "qla_target(%d): tag %lld: schedule SRR work\n", 5132 + vha->vp_idx, cmd->se_cmd.tag); 5133 + 5134 + /* Schedule the srr for processing in qlt_handle_srr(). */ 5135 + spin_lock(&tgt->srr_lock); 5136 + list_add_tail(&srr->srr_list_entry, &tgt->srr_list); 5137 + /* 5138 + * Already running the work function; no need to schedule 5139 + * tgt->srr_work. 5140 + */ 5141 + spin_unlock(&tgt->srr_lock); 5142 + spin_unlock_irq(qpair->qp_lock_ptr); 5143 + /* return with cmd refcount incremented */ 5144 + return; 5145 + } 5146 + 5147 + /* The CTIO SRR for this command has not yet been received. */ 5148 + 5149 + if (cmd->sent_term_exchg) { 5150 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11007, 5151 + "qla_target(%d): tag %lld: IMM SRR: cmd already aborted\n", 5152 + vha->vp_idx, cmd->se_cmd.tag); 5153 + spin_unlock_irq(qpair->qp_lock_ptr); 5154 + spin_lock_irq(&ha->hardware_lock); 5155 + if (!qlt_srr_is_chip_reset(vha, ha->base_qpair, srr)) 5156 + qlt_send_term_imm_notif(vha, &srr->imm_ntfy, 1); 5157 + spin_unlock_irq(&ha->hardware_lock); 5158 + kfree(srr); 5159 + ha->tgt.tgt_ops->put_cmd_ref(cmd); 5160 + return; 5161 + } 5162 + 5163 + /* If not expecting a CTIO, then reject IMM SRR. */ 5164 + if (!cmd->cmd_sent_to_fw) { 5165 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11008, 5166 + "qla_target(%d): tag %lld: IMM SRR but !cmd_sent_to_fw (state %d); reject SRR\n", 5167 + vha->vp_idx, cmd->se_cmd.tag, cmd->state); 5168 + spin_unlock_irq(qpair->qp_lock_ptr); 5169 + ha->tgt.tgt_ops->put_cmd_ref(cmd); 5170 + goto out_reject; 5171 + } 5172 + 5173 + /* Expect qlt_prepare_srr_ctio() to be called. */ 5174 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11003, 5175 + "qla_target(%d): tag %lld: wait for CTIO SRR (state %d)\n", 5176 + vha->vp_idx, cmd->se_cmd.tag, cmd->state); 5177 + srr->cmd = cmd; 5178 + cmd->srr = srr; 5179 + 5180 + spin_unlock_irq(qpair->qp_lock_ptr); 5181 + 5182 + ha->tgt.tgt_ops->put_cmd_ref(cmd); 5183 + return; 5184 + 5185 + out_reject: 5186 + qpair = vha->hw->base_qpair; 5187 + spin_lock_irq(qpair->qp_lock_ptr); 5188 + if (!qlt_srr_is_chip_reset(vha, qpair, srr)) 5189 + qlt_send_notify_ack(qpair, &srr->imm_ntfy, 0, 0, 0, 5190 + NOTIFY_ACK_SRR_FLAGS_REJECT, 5191 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 5192 + srr_explain); 5193 + spin_unlock_irq(qpair->qp_lock_ptr); 5194 + kfree(srr); 5195 + } 5196 + 5197 + /* 5198 + * Handle an immediate notify SRR (Sequence Retransmission Request) message from 5199 + * the hardware. The hardware will also send a CTIO with CTIO_SRR_RECEIVED status 5200 + * for the affected command. 5201 + * 5202 + * ha->hardware_lock supposed to be held on entry 5203 + */ 5204 + static void qlt_prepare_srr_imm(struct scsi_qla_host *vha, 5205 + struct imm_ntfy_from_isp *iocb) 5206 + { 5207 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 5208 + struct qla_tgt_srr *srr; 5209 + 5210 + ql_log(ql_log_warn, vha, 0x11000, "qla_target(%d): received IMM SRR\n", 5211 + vha->vp_idx); 5212 + 5213 + /* 5214 + * Need cmd->qpair->qp_lock_ptr, but have ha->hardware_lock. Defer 5215 + * processing to a workqueue so that the right lock can be acquired 5216 + * safely. 5217 + */ 5218 + 5219 + srr = kzalloc(sizeof(*srr), GFP_ATOMIC); 5220 + if (!srr) 5221 + goto out_reject; 5222 + 5223 + memcpy(&srr->imm_ntfy, iocb, sizeof(srr->imm_ntfy)); 5224 + srr->imm_ntfy_recvd = true; 5225 + srr->reset_count = vha->hw->base_qpair->chip_reset; 5226 + spin_lock(&tgt->srr_lock); 5227 + list_add_tail(&srr->srr_list_entry, &tgt->srr_list); 5228 + queue_work(qla_tgt_wq, &tgt->srr_work); 5229 + spin_unlock(&tgt->srr_lock); 5230 + /* resume processing in qlt_handle_srr_imm() */ 5231 + return; 5232 + 5233 + out_reject: 5234 + qlt_send_notify_ack(vha->hw->base_qpair, iocb, 0, 0, 0, 5235 + NOTIFY_ACK_SRR_FLAGS_REJECT, 5236 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 5237 + NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); 5238 + } 5239 + 5240 + /* 5241 + * If possible, undo the effect of qlt_set_data_offset() and restore the cmd 5242 + * data buffer back to its full size. 5243 + */ 5244 + static int qlt_restore_orig_sg(struct qla_tgt_cmd *cmd) 5245 + { 5246 + struct scsi_qla_host *vha = cmd->vha; 5247 + struct se_cmd *se_cmd = &cmd->se_cmd; 5248 + 5249 + WARN_ON(cmd->sg_mapped); 5250 + 5251 + if (cmd->offset == 0) { 5252 + /* qlt_set_data_offset() has not been called. */ 5253 + return 0; 5254 + } 5255 + 5256 + if (se_cmd->t_data_sg == NULL || 5257 + se_cmd->t_data_nents == 0 || 5258 + se_cmd->data_length == 0) { 5259 + /* The original scatterlist is not available. */ 5260 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1102c, 5261 + "qla_target(%d): tag %lld: cannot restore original cmd buffer; keep modified buffer at offset %d\n", 5262 + vha->vp_idx, cmd->se_cmd.tag, cmd->offset); 5263 + return -ENOENT; 5264 + } 5265 + 5266 + /* Restore the original scatterlist. */ 5267 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1102d, 5268 + "qla_target(%d): tag %lld: restore original cmd buffer: offset %d -> 0\n", 5269 + vha->vp_idx, cmd->se_cmd.tag, cmd->offset); 5270 + if (cmd->free_sg) { 5271 + cmd->free_sg = 0; 5272 + qlt_free_sg(cmd); 5273 + } 5274 + cmd->offset = 0; 5275 + cmd->sg = se_cmd->t_data_sg; 5276 + cmd->sg_cnt = se_cmd->t_data_nents; 5277 + cmd->bufflen = se_cmd->data_length; 5278 + return 0; 5279 + } 5280 + 5281 + /* 5282 + * Adjust the data buffer of the given command to skip over offset bytes from 5283 + * the beginning while also reducing the length by offset bytes. 5284 + * 5285 + * This may be called multiple times for a single command if there are multiple 5286 + * SRRs, which each call reducing the buffer size further relative to the 5287 + * previous call. Note that the buffer may be reset back to its original size 5288 + * by calling qlt_restore_orig_sg(). 5289 + */ 5290 + static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset) 5291 + { 5292 + struct scsi_qla_host *vha = cmd->vha; 5293 + struct scatterlist *sg_srr_start = NULL, *sg; 5294 + uint32_t first_offset = offset; 5295 + int sg_srr_cnt, i; 5296 + int bufflen = 0; 5297 + 5298 + WARN_ON(cmd->sg_mapped); 5299 + 5300 + ql_dbg(ql_dbg_tgt, vha, 0x11020, 5301 + "qla_target(%d): tag %lld: %s: sg %p sg_cnt %d dir %d cmd->offset %d cmd->bufflen %d add offset %u\n", 5302 + vha->vp_idx, cmd->se_cmd.tag, __func__, cmd->sg, 5303 + cmd->sg_cnt, cmd->dma_data_direction, cmd->offset, cmd->bufflen, 5304 + offset); 5305 + 5306 + if (cmd->se_cmd.prot_op != TARGET_PROT_NORMAL) { 5307 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11021, 5308 + "qla_target(%d): tag %lld: %s: SRR with protection information at nonzero offset not implemented\n", 5309 + vha->vp_idx, cmd->se_cmd.tag, __func__); 5310 + return -EINVAL; 5311 + } 5312 + 5313 + if (!cmd->sg || !cmd->sg_cnt) { 5314 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11022, 5315 + "qla_target(%d): tag %lld: %s: Missing cmd->sg or zero cmd->sg_cnt\n", 5316 + vha->vp_idx, cmd->se_cmd.tag, __func__); 5317 + return -EINVAL; 5318 + } 5319 + 5320 + /* 5321 + * Walk the current cmd->sg list until we locate the new sg_srr_start 5322 + */ 5323 + for_each_sg(cmd->sg, sg, cmd->sg_cnt, i) { 5324 + ql_dbg(ql_dbg_tgt, vha, 0x11023, 5325 + "sg[%d]: %p page: %p, length: %d, offset: %d\n", 5326 + i, sg, sg_page(sg), sg->length, sg->offset); 5327 + 5328 + if (first_offset < sg->length) { 5329 + sg_srr_start = sg; 5330 + break; 5331 + } 5332 + first_offset -= sg->length; 5333 + } 5334 + 5335 + if (!sg_srr_start) { 5336 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11024, 5337 + "qla_target(%d): tag %lld: Unable to locate sg_srr_start for offset: %u\n", 5338 + vha->vp_idx, cmd->se_cmd.tag, offset); 5339 + return -EINVAL; 5340 + } 5341 + 5342 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11025, 5343 + "qla_target(%d): tag %lld: prepare SRR sgl at sg index %d of %d byte offset %u of %u\n", 5344 + vha->vp_idx, cmd->se_cmd.tag, i, cmd->sg_cnt, 5345 + first_offset, sg_srr_start->length); 5346 + 5347 + sg_srr_cnt = cmd->sg_cnt - i; 5348 + 5349 + if (first_offset == 0 && !cmd->free_sg) { 5350 + /* 5351 + * The offset points to the beginning of a scatterlist element. 5352 + * In this case there is no need to modify the first scatterlist 5353 + * element, so we can just point directly inside the original 5354 + * unmodified scatterlist. 5355 + */ 5356 + ql_dbg(ql_dbg_tgt, vha, 0x11026, "point directly to old sgl\n"); 5357 + cmd->sg = sg_srr_start; 5358 + } else { 5359 + /* 5360 + * Allocate at most 2 new scatterlist elements to reduce memory 5361 + * requirements. 5362 + */ 5363 + int n_alloc_sg = min(sg_srr_cnt, 2); 5364 + struct scatterlist *sg_srr = 5365 + kmalloc_array(n_alloc_sg, sizeof(*sg_srr), GFP_ATOMIC); 5366 + if (!sg_srr) { 5367 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11027, 5368 + "qla_target(%d): tag %lld: Unable to allocate SRR scatterlist\n", 5369 + vha->vp_idx, cmd->se_cmd.tag); 5370 + return -ENOMEM; 5371 + } 5372 + sg_init_table(sg_srr, n_alloc_sg); 5373 + 5374 + /* Init the first sg element to skip over the unneeded data. */ 5375 + sg_set_page(&sg_srr[0], sg_page(sg_srr_start), 5376 + sg_srr_start->length - first_offset, 5377 + sg_srr_start->offset + first_offset); 5378 + if (sg_srr_cnt == 1) { 5379 + ql_dbg(ql_dbg_tgt, vha, 0x11028, 5380 + "single-element array\n"); 5381 + } else if (sg_srr_cnt == 2) { 5382 + /* Only two elements; copy the last element. */ 5383 + ql_dbg(ql_dbg_tgt, vha, 0x11029, 5384 + "complete two-element array\n"); 5385 + sg = sg_next(sg_srr_start); 5386 + sg_set_page(&sg_srr[1], sg_page(sg), sg->length, 5387 + sg->offset); 5388 + } else { 5389 + /* 5390 + * Three or more elements; chain our newly-allocated 5391 + * 2-entry array to the rest of the original 5392 + * scatterlist at the splice point. 5393 + */ 5394 + ql_dbg(ql_dbg_tgt, vha, 0x1102a, 5395 + "chain to original scatterlist\n"); 5396 + sg = sg_next(sg_srr_start); 5397 + sg_chain(sg_srr, 2, sg); 5398 + } 5399 + 5400 + /* 5401 + * If the previous scatterlist was allocated here on a previous 5402 + * call, then it should be safe to free now. 5403 + */ 5404 + if (cmd->free_sg) 5405 + qlt_free_sg(cmd); 5406 + cmd->sg = sg_srr; 5407 + cmd->free_sg = 1; 5408 + } 5409 + 5410 + /* Note that sg_cnt doesn't include any extra chain elements. */ 5411 + cmd->sg_cnt = sg_srr_cnt; 5412 + cmd->offset += offset; 5413 + cmd->bufflen -= offset; 5414 + 5415 + /* Check the scatterlist length for consistency. */ 5416 + for_each_sg(cmd->sg, sg, cmd->sg_cnt, i) { 5417 + bufflen += sg->length; 5418 + } 5419 + if (bufflen != cmd->bufflen) { 5420 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1102b, 5421 + "qla_target(%d): tag %lld: %s: bad sgl length: expected %d got %d\n", 5422 + vha->vp_idx, cmd->se_cmd.tag, __func__, cmd->bufflen, bufflen); 5423 + return -EINVAL; 5424 + } 5425 + 5426 + return 0; 5427 + } 5428 + 5429 + /* 5430 + * Given the "SRR relative offset" (offset of data to retry), determine what 5431 + * needs to be retransmitted (data and/or status) and return the mask in 5432 + * xmit_type. If retrying data, adjust the command buffer to point to only the 5433 + * data that need to be retried, skipping over the data that don't need to be 5434 + * retried. 5435 + * 5436 + * Returns 0 for success or a negative error number. 5437 + */ 5438 + static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd, 5439 + uint32_t srr_rel_offs, int *xmit_type) 5440 + { 5441 + struct scsi_qla_host *vha = cmd->vha; 5442 + int res = 0, rel_offs; 5443 + 5444 + if (srr_rel_offs < cmd->offset || 5445 + srr_rel_offs > cmd->offset + cmd->bufflen) { 5446 + *xmit_type = 0; 5447 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101e, 5448 + "qla_target(%d): tag %lld: srr_rel_offs %u outside accepted range %u - %u\n", 5449 + vha->vp_idx, cmd->se_cmd.tag, srr_rel_offs, 5450 + cmd->offset, cmd->offset + cmd->bufflen); 5451 + return -EINVAL; 5452 + } 5453 + 5454 + /* 5455 + * srr_rel_offs is the offset of the data we need from the beginning of 5456 + * the *original* buffer. 5457 + * 5458 + * cmd->offset is the offset of the current cmd scatterlist from the 5459 + * beginning of the *original* buffer, which might be nonzero if there 5460 + * was a previous SRR and the buffer could not be reset back to its 5461 + * original size. 5462 + * 5463 + * rel_offs is the offset of the data we need from the beginning of the 5464 + * current cmd scatterlist. 5465 + */ 5466 + rel_offs = srr_rel_offs - cmd->offset; 5467 + 5468 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101f, 5469 + "qla_target(%d): tag %lld: current buffer [%u - %u); srr_rel_offs=%d, rel_offs=%d\n", 5470 + vha->vp_idx, cmd->se_cmd.tag, cmd->offset, 5471 + cmd->offset + cmd->bufflen, srr_rel_offs, rel_offs); 5472 + 5473 + *xmit_type = QLA_TGT_XMIT_ALL; 5474 + 5475 + if (rel_offs == cmd->bufflen) 5476 + *xmit_type = QLA_TGT_XMIT_STATUS; 5477 + else if (rel_offs > 0) 5478 + res = qlt_set_data_offset(cmd, rel_offs); 5479 + 5480 + return res; 5481 + } 5482 + 5483 + /* 5484 + * Process a SRR (Sequence Retransmission Request) for a SCSI command once both 5485 + * the immediate notify SRR and CTIO SRR have been received from the hw. 5486 + * 5487 + * Process context, no locks 5488 + */ 5489 + static void qlt_handle_srr(struct scsi_qla_host *vha, struct qla_tgt_srr *srr) 5490 + { 5491 + struct qla_tgt_cmd *cmd = srr->cmd; 5492 + struct se_cmd *se_cmd = &cmd->se_cmd; 5493 + struct qla_qpair *qpair = cmd->qpair; 5494 + struct qla_hw_data *ha = vha->hw; 5495 + uint8_t op = cmd->cdb ? cmd->cdb[0] : 0; 5496 + uint32_t srr_rel_offs = le32_to_cpu(srr->imm_ntfy.u.isp24.srr_rel_offs); 5497 + uint16_t srr_ui = le16_to_cpu(srr->imm_ntfy.u.isp24.srr_ui); 5498 + int xmit_type = 0; 5499 + bool xmit_response = false; 5500 + bool rdy_to_xfer = false; 5501 + bool did_timeout; 5502 + bool send_term_exch = false; 5503 + 5504 + spin_lock_irq(qpair->qp_lock_ptr); 5505 + 5506 + WARN_ON(cmd->cmd_sent_to_fw); 5507 + 5508 + cmd->srr = NULL; 5509 + 5510 + if (qlt_srr_is_chip_reset(vha, qpair, srr)) 5511 + goto out_advance_cmd; 5512 + 5513 + if (cmd->sent_term_exchg || cmd->sess->deleted || srr->aborted) { 5514 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11010, 5515 + "qla_target(%d): tag %lld: IMM SRR: cmd already aborted\n", 5516 + vha->vp_idx, cmd->se_cmd.tag); 5517 + 5518 + spin_unlock_irq(qpair->qp_lock_ptr); 5519 + 5520 + spin_lock_irq(&ha->hardware_lock); 5521 + if (!qlt_srr_is_chip_reset(vha, ha->base_qpair, srr)) 5522 + qlt_send_term_imm_notif(vha, &srr->imm_ntfy, 1); 5523 + spin_unlock_irq(&ha->hardware_lock); 5524 + 5525 + send_term_exch = true; 5526 + 5527 + spin_lock_irq(qpair->qp_lock_ptr); 5528 + goto out_advance_cmd; 5529 + } 5530 + 5531 + if (srr->reject) 5532 + goto out_reject; 5533 + 5534 + /* 5535 + * If we receive multiple SRRs for the same command, place a time limit 5536 + * on how long we are willing to retry. This timeout should be less 5537 + * than SQA_MAX_HW_PENDING_TIME in scst_qla2xxx.c. 5538 + */ 5539 + did_timeout = time_is_before_jiffies64((cmd->jiffies_at_hw_st_entry ? : 5540 + cmd->jiffies_at_alloc) + 30 * HZ); 5541 + 5542 + qlt_restore_orig_sg(cmd); 5543 + 5544 + switch (srr_ui) { 5545 + case SRR_IU_STATUS: 5546 + if (cmd->state != QLA_TGT_STATE_PROCESSED) { 5547 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11011, 5548 + "qla_target(%d): tag %lld, op %x: reject SRR_IU_STATUS due to unexpected state %d\n", 5549 + vha->vp_idx, se_cmd->tag, op, 5550 + cmd->state); 5551 + goto out_reject; 5552 + } 5553 + 5554 + if (did_timeout) { 5555 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11033, 5556 + "qla_target(%d): tag %lld, op %x: reject SRR_IU_STATUS due to timeout\n", 5557 + vha->vp_idx, se_cmd->tag, op); 5558 + goto out_reject; 5559 + } 5560 + 5561 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11012, 5562 + "qla_target(%d): tag %lld, op %x: accept SRR_IU_STATUS and retransmit scsi_status=%x\n", 5563 + vha->vp_idx, se_cmd->tag, op, 5564 + se_cmd->scsi_status); 5565 + xmit_type = QLA_TGT_XMIT_STATUS; 5566 + xmit_response = true; 5567 + cmd->trc_flags |= TRC_SRR_RSP; 5568 + break; 5569 + 5570 + case SRR_IU_DATA_IN: 5571 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11013, 5572 + "qla_target(%d): tag %lld, op %x: process SRR_IU_DATA_IN: bufflen=%d, sg_cnt=%d, offset=%d, srr_offset=%d, scsi_status=%x\n", 5573 + vha->vp_idx, se_cmd->tag, op, cmd->bufflen, 5574 + cmd->sg_cnt, cmd->offset, srr_rel_offs, 5575 + se_cmd->scsi_status); 5576 + 5577 + if (cmd->state != QLA_TGT_STATE_PROCESSED) { 5578 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11014, 5579 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_IN due to unexpected state %d\n", 5580 + vha->vp_idx, se_cmd->tag, cmd->state); 5581 + goto out_reject; 5582 + } 5583 + 5584 + /* 5585 + * QLA_TGT_STATE_PROCESSED does not necessarily imply data-in 5586 + */ 5587 + if (!qlt_has_data(cmd)) { 5588 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11015, 5589 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_IN because cmd has no data to send\n", 5590 + vha->vp_idx, se_cmd->tag); 5591 + goto out_reject; 5592 + } 5593 + 5594 + if (!cmd->sg || !cmd->sg_cnt) { 5595 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11016, 5596 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_IN because buffer is missing\n", 5597 + vha->vp_idx, se_cmd->tag); 5598 + goto out_reject; 5599 + } 5600 + 5601 + if (did_timeout) { 5602 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11034, 5603 + "qla_target(%d): tag %lld, op %x: reject SRR_IU_DATA_IN due to timeout\n", 5604 + vha->vp_idx, se_cmd->tag, op); 5605 + goto out_reject; 5606 + } 5607 + 5608 + if (qlt_srr_adjust_data(cmd, srr_rel_offs, &xmit_type) != 0) 5609 + goto out_reject; 5610 + 5611 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11017, 5612 + "qla_target(%d): tag %lld: accept SRR_IU_DATA_IN and retransmit data: bufflen=%d, offset=%d\n", 5613 + vha->vp_idx, se_cmd->tag, cmd->bufflen, 5614 + cmd->offset); 5615 + xmit_response = true; 5616 + cmd->trc_flags |= TRC_SRR_RSP; 5617 + break; 5618 + 5619 + case SRR_IU_DATA_OUT: 5620 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11018, 5621 + "qla_target(%d): tag %lld, op %x: process SRR_IU_DATA_OUT: bufflen=%d, sg_cnt=%d, offset=%d, srr_offset=%d\n", 5622 + vha->vp_idx, se_cmd->tag, op, cmd->bufflen, 5623 + cmd->sg_cnt, cmd->offset, srr_rel_offs); 5624 + 5625 + if (cmd->state != QLA_TGT_STATE_NEED_DATA) { 5626 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11019, 5627 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_OUT due to unexpected state %d\n", 5628 + vha->vp_idx, se_cmd->tag, cmd->state); 5629 + goto out_reject; 5630 + } 5631 + 5632 + /* 5633 + * QLA_TGT_STATE_NEED_DATA implies there should be data-out 5634 + */ 5635 + if (!qlt_has_data(cmd) || !cmd->sg || !cmd->sg_cnt) { 5636 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101a, 5637 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_OUT because buffer is missing\n", 5638 + vha->vp_idx, se_cmd->tag); 5639 + goto out_reject; 5640 + } 5641 + 5642 + if (did_timeout) { 5643 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11035, 5644 + "qla_target(%d): tag %lld, op %x: reject SRR_IU_DATA_OUT due to timeout\n", 5645 + vha->vp_idx, se_cmd->tag, op); 5646 + goto out_reject; 5647 + } 5648 + 5649 + if (qlt_srr_adjust_data(cmd, srr_rel_offs, &xmit_type) != 0) 5650 + goto out_reject; 5651 + 5652 + if (!(xmit_type & QLA_TGT_XMIT_DATA)) { 5653 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101b, 5654 + "qla_target(%d): tag %lld: reject SRR_IU_DATA_OUT: bad offset\n", 5655 + vha->vp_idx, se_cmd->tag); 5656 + goto out_reject; 5657 + } 5658 + 5659 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101c, 5660 + "qla_target(%d): tag %lld: accept SRR_IU_DATA_OUT and receive data again: bufflen=%d, offset=%d\n", 5661 + vha->vp_idx, se_cmd->tag, cmd->bufflen, 5662 + cmd->offset); 5663 + cmd->trc_flags |= TRC_SRR_XRDY; 5664 + rdy_to_xfer = true; 5665 + break; 5666 + 5667 + default: 5668 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x1101d, 5669 + "qla_target(%d): tag %lld, op %x: reject unknown srr_ui value 0x%x: state=%d, bufflen=%d, offset=%d, srr_offset=%d\n", 5670 + vha->vp_idx, se_cmd->tag, op, srr_ui, cmd->state, 5671 + cmd->bufflen, cmd->offset, srr_rel_offs); 5672 + goto out_reject; 5673 + } 5674 + 5675 + qlt_send_notify_ack(qpair, &srr->imm_ntfy, 0, 0, 0, 5676 + NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); 5677 + 5678 + spin_unlock_irq(qpair->qp_lock_ptr); 5679 + 5680 + if (xmit_response) { 5681 + /* For status and data-in, retransmit the response. */ 5682 + if (qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status)) { 5683 + send_term_exch = true; 5684 + spin_lock_irq(qpair->qp_lock_ptr); 5685 + goto out_advance_cmd; 5686 + } 5687 + } else if (rdy_to_xfer) { 5688 + /* For data-out, receive data again. */ 5689 + if (qlt_rdy_to_xfer(cmd)) { 5690 + send_term_exch = true; 5691 + spin_lock_irq(qpair->qp_lock_ptr); 5692 + goto out_advance_cmd; 5693 + } 5694 + } 5695 + 5696 + return; 5697 + 5698 + out_reject: 5699 + qlt_send_notify_ack(qpair, &srr->imm_ntfy, 0, 0, 0, 5700 + NOTIFY_ACK_SRR_FLAGS_REJECT, 5701 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 5702 + NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); 5703 + 5704 + out_advance_cmd: 5705 + if (!cmd->sent_term_exchg && 5706 + (send_term_exch || cmd->state != QLA_TGT_STATE_NEED_DATA) && 5707 + !qlt_srr_is_chip_reset(vha, qpair, srr)) { 5708 + cmd->trc_flags |= TRC_SRR_TERM; 5709 + qlt_send_term_exchange(qpair, cmd, &cmd->atio, 1); 5710 + } 5711 + if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 5712 + /* 5713 + * The initiator should abort the command, but if not, try to 5714 + * return an error. 5715 + */ 5716 + cmd->srr_failed = 1; 5717 + cmd->write_data_transferred = 0; 5718 + cmd->state = QLA_TGT_STATE_DATA_IN; 5719 + cmd->jiffies_at_hw_st_entry = 0; 5720 + vha->hw->tgt.tgt_ops->handle_data(cmd); 5721 + } else { 5722 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 5723 + } 5724 + spin_unlock_irq(qpair->qp_lock_ptr); 5725 + } 5726 + 5727 + /* Workqueue function for processing SRR work in process context. */ 5728 + static void qlt_handle_srr_work(struct work_struct *work) 5729 + { 5730 + struct qla_tgt *tgt = container_of(work, struct qla_tgt, srr_work); 5731 + struct scsi_qla_host *vha = tgt->vha; 5732 + 5733 + ql_dbg(ql_dbg_tgt_mgt, vha, 0x11032, 5734 + "qla_target(%d): Entering SRR work\n", vha->vp_idx); 5735 + 5736 + for (;;) { 5737 + struct qla_tgt_srr *srr; 5738 + 5739 + spin_lock_irq(&tgt->srr_lock); 5740 + srr = list_first_entry_or_null(&tgt->srr_list, typeof(*srr), 5741 + srr_list_entry); 5742 + if (!srr) { 5743 + spin_unlock_irq(&tgt->srr_lock); 5744 + break; 5745 + } 5746 + list_del(&srr->srr_list_entry); 5747 + spin_unlock_irq(&tgt->srr_lock); 5748 + 5749 + if (!srr->cmd) { 5750 + qlt_handle_srr_imm(vha, srr); 5751 + } else { 5752 + qlt_handle_srr(vha, srr); 5753 + vha->hw->tgt.tgt_ops->put_cmd_ref(srr->cmd); 5754 + kfree(srr); 5755 + } 5756 + } 5757 + } 5758 + 5759 + /* 5248 5760 * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 5249 5761 */ 5250 5762 static int qlt_24xx_handle_els(struct scsi_qla_host *vha, ··· 6527 5325 if (qlt_24xx_handle_els(vha, iocb) == 0) 6528 5326 send_notify_ack = 0; 6529 5327 break; 5328 + 5329 + case IMM_NTFY_SRR: 5330 + qlt_prepare_srr_imm(vha, iocb); 5331 + send_notify_ack = 0; 5332 + break; 5333 + 6530 5334 default: 6531 5335 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06d, 6532 5336 "qla_target(%d): Received unknown immediate " ··· 6567 5359 sess = qla2x00_find_fcport_by_nportid(vha, &id, 1); 6568 5360 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 6569 5361 if (!sess) { 6570 - qlt_send_term_exchange(qpair, NULL, atio, 1, 0); 5362 + qlt_send_term_exchange(qpair, NULL, atio, 1); 6571 5363 return 0; 6572 5364 } 6573 5365 /* Sending marker isn't necessary, since we called from ISR */ ··· 6677 5469 6678 5470 qlt_incr_num_pend_cmds(vha); 6679 5471 INIT_LIST_HEAD(&cmd->cmd_list); 6680 - memcpy(&cmd->atio, atio, sizeof(*atio)); 5472 + memcpy_atio(&cmd->atio, atio); 6681 5473 6682 5474 cmd->tgt = vha->vha_tgt.qla_tgt; 6683 5475 cmd->vha = vha; 6684 5476 cmd->reset_count = ha->base_qpair->chip_reset; 6685 5477 cmd->q_full = 1; 6686 5478 cmd->qpair = ha->base_qpair; 5479 + cmd->cdb = &cmd->atio.u.isp24.fcp_cmnd.cdb[0]; 5480 + cmd->cdb_len = 16; 6687 5481 6688 5482 if (qfull) { 6689 5483 cmd->q_full = 1; ··· 6798 5588 ql_dbg(ql_dbg_tgt, vha, 0xe05f, 6799 5589 "qla_target: Unable to send command to target, sending TERM EXCHANGE for rsp\n"); 6800 5590 qlt_send_term_exchange(ha->base_qpair, NULL, 6801 - atio, 1, 0); 5591 + atio, 1); 6802 5592 break; 6803 5593 case -EBUSY: 6804 5594 ql_dbg(ql_dbg_tgt, vha, 0xe060, ··· 6907 5697 struct qla_tgt_mgmt_cmd *mcmd; 6908 5698 struct qla_hw_data *ha = vha->hw; 6909 5699 6910 - mcmd = qlt_ctio_to_cmd(vha, rsp, pkt->handle, pkt); 5700 + mcmd = qlt_ctio_to_cmd(vha, rsp, pkt->handle, TYPE_TGT_TMCMD, pkt); 6911 5701 if (mcmd == NULL && h != QLA_TGT_SKIP_HANDLE) { 6912 5702 ql_dbg(ql_dbg_async, vha, 0xe064, 6913 5703 "qla_target(%d): ABTS Comp without mcmd\n", ··· 6927 5717 if (le32_to_cpu(entry->error_subcode1) == 0x1E && 6928 5718 le32_to_cpu(entry->error_subcode2) == 0) { 6929 5719 if (qlt_chk_unresolv_exchg(vha, rsp->qpair, entry)) { 6930 - ha->tgt.tgt_ops->free_mcmd(mcmd); 5720 + qlt_free_ul_mcmd(ha, mcmd); 6931 5721 return; 6932 5722 } 6933 5723 qlt_24xx_retry_term_exchange(vha, rsp->qpair, ··· 6938 5728 vha->vp_idx, entry->compl_status, 6939 5729 entry->error_subcode1, 6940 5730 entry->error_subcode2); 6941 - ha->tgt.tgt_ops->free_mcmd(mcmd); 5731 + qlt_free_ul_mcmd(ha, mcmd); 6942 5732 } 6943 5733 } else if (mcmd) { 6944 - ha->tgt.tgt_ops->free_mcmd(mcmd); 5734 + qlt_free_ul_mcmd(ha, mcmd); 6945 5735 } 6946 5736 } 6947 5737 ··· 7005 5795 ql_dbg(ql_dbg_tgt, vha, 0xe05f, 7006 5796 "qla_target: Unable to send command to target, sending TERM EXCHANGE for rsp\n"); 7007 5797 qlt_send_term_exchange(rsp->qpair, NULL, 7008 - atio, 1, 0); 5798 + atio, 1); 7009 5799 break; 7010 5800 case -EBUSY: 7011 5801 ql_dbg(ql_dbg_tgt, vha, 0xe060, ··· 7025 5815 } 7026 5816 } 7027 5817 break; 7028 - 7029 - case CONTINUE_TGT_IO_TYPE: 7030 - { 7031 - struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; 7032 - 7033 - qlt_do_ctio_completion(vha, rsp, entry->handle, 7034 - le16_to_cpu(entry->status)|(pkt->entry_status << 16), 7035 - entry); 7036 - break; 7037 - } 7038 - 7039 - case CTIO_A64_TYPE: 7040 - { 7041 - struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; 7042 - 7043 - qlt_do_ctio_completion(vha, rsp, entry->handle, 7044 - le16_to_cpu(entry->status)|(pkt->entry_status << 16), 7045 - entry); 7046 - break; 7047 - } 7048 5818 7049 5819 case IMMED_NOTIFY_TYPE: 7050 5820 ql_dbg(ql_dbg_tgt, vha, 0xe035, "%s", "IMMED_NOTIFY\n"); ··· 7513 6323 spin_lock_init(&tgt->sess_work_lock); 7514 6324 INIT_WORK(&tgt->sess_work, qlt_sess_work_fn); 7515 6325 INIT_LIST_HEAD(&tgt->sess_works_list); 6326 + spin_lock_init(&tgt->srr_lock); 6327 + INIT_LIST_HEAD(&tgt->srr_list); 6328 + INIT_WORK(&tgt->srr_work, qlt_handle_srr_work); 7516 6329 atomic_set(&tgt->tgt_global_resets_count, 0); 7517 6330 7518 6331 base_vha->vha_tgt.qla_tgt = tgt; ··· 7898 6705 7899 6706 adjust_corrupted_atio(pkt); 7900 6707 qlt_send_term_exchange(ha->base_qpair, NULL, pkt, 7901 - ha_locked, 0); 6708 + ha_locked); 7902 6709 } else { 7903 6710 qlt_24xx_atio_pkt_all_vps(vha, 7904 6711 (struct atio_from_isp *)pkt, ha_locked); ··· 8161 6968 if (ha->tgt.node_name_set) { 8162 6969 memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE); 8163 6970 icb->firmware_options_1 |= cpu_to_le32(BIT_14); 6971 + } 6972 + } 6973 + 6974 + /* Update any settings that depend on ha->fw_*_version. */ 6975 + void 6976 + qlt_config_nvram_with_fw_version(struct scsi_qla_host *vha) 6977 + { 6978 + struct qla_hw_data *ha = vha->hw; 6979 + 6980 + if (!QLA_TGT_MODE_ENABLED()) 6981 + return; 6982 + 6983 + if (ql2xtgt_tape_enable && qlt_has_sler_fw_bug(ha)) { 6984 + ql_log(ql_log_warn, vha, 0x11036, 6985 + "WARNING: ignoring ql2xtgt_tape_enable due to buggy HBA firmware; please upgrade FW\n"); 6986 + 6987 + /* Disable FC Tape support */ 6988 + if (ha->isp_ops->nvram_config == qla81xx_nvram_config) { 6989 + struct init_cb_81xx *icb = 6990 + (struct init_cb_81xx *)ha->init_cb; 6991 + icb->firmware_options_2 &= cpu_to_le32(~BIT_12); 6992 + } else { 6993 + struct init_cb_24xx *icb = 6994 + (struct init_cb_24xx *)ha->init_cb; 6995 + icb->firmware_options_2 &= cpu_to_le32(~BIT_12); 6996 + } 8164 6997 } 8165 6998 } 8166 6999
+105 -11
drivers/scsi/qla2xxx/qla_target.h
··· 184 184 #define NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM 0x9 185 185 186 186 #define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL 0 187 + #define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_INVALID_OX_ID_RX_ID 0x17 187 188 #define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_UNABLE_TO_SUPPLY_DATA 0x2a 188 189 189 190 #define NOTIFY_ACK_SUCCESS 0x01 ··· 687 686 int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, u64, uint16_t, 688 687 uint32_t); 689 688 struct qla_tgt_cmd *(*get_cmd)(struct fc_port *); 689 + int (*get_cmd_ref)(struct qla_tgt_cmd *cmd); 690 + void (*put_cmd_ref)(struct qla_tgt_cmd *cmd); 690 691 void (*rel_cmd)(struct qla_tgt_cmd *); 691 692 void (*free_cmd)(struct qla_tgt_cmd *); 692 693 void (*free_mcmd)(struct qla_tgt_mgmt_cmd *); ··· 757 754 #define QLA_TGT_STATE_NEED_DATA 1 /* target needs data to continue */ 758 755 #define QLA_TGT_STATE_DATA_IN 2 /* Data arrived + target processing */ 759 756 #define QLA_TGT_STATE_PROCESSED 3 /* target done processing */ 757 + #define QLA_TGT_STATE_DONE 4 /* cmd being freed */ 760 758 761 759 /* ATIO task_codes field */ 762 760 #define ATIO_SIMPLE_QUEUE 0 ··· 826 822 int notify_ack_expected; 827 823 int abts_resp_expected; 828 824 int modify_lun_expected; 825 + 826 + spinlock_t srr_lock; 827 + struct list_head srr_list; 828 + struct work_struct srr_work; 829 + 829 830 atomic_t tgt_global_resets_count; 831 + 830 832 struct list_head tgt_list_entry; 831 833 }; 832 834 833 835 struct qla_tgt_sess_op { 834 836 struct scsi_qla_host *vha; 835 837 uint32_t chip_reset; 836 - struct atio_from_isp atio; 837 838 struct work_struct work; 838 839 struct list_head cmd_list; 839 840 bool aborted; 840 841 struct rsp_que *rsp; 842 + 843 + struct atio_from_isp atio; 844 + /* DO NOT ADD ANYTHING ELSE HERE - atio must be last member */ 841 845 }; 842 846 843 847 enum trace_flags { ··· 870 858 TRC_DATA_IN = BIT_18, 871 859 TRC_ABORT = BIT_19, 872 860 TRC_DIF_ERR = BIT_20, 861 + TRC_SRR_IMM = BIT_21, 873 862 }; 874 863 875 864 struct qla_tgt_cmd { ··· 889 876 /* Sense buffer that will be mapped into outgoing status */ 890 877 unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; 891 878 892 - spinlock_t cmd_lock; 893 - /* to save extra sess dereferences */ 894 879 unsigned int conf_compl_supported:1; 895 880 unsigned int sg_mapped:1; 881 + 882 + /* Call qlt_free_sg() if set. */ 883 + unsigned int free_sg:1; 884 + 896 885 unsigned int write_data_transferred:1; 886 + 887 + /* Set if the SCSI status was sent successfully. */ 888 + unsigned int rsp_sent:1; 889 + 897 890 unsigned int q_full:1; 898 891 unsigned int term_exchg:1; 899 892 unsigned int cmd_sent_to_fw:1; 900 893 unsigned int cmd_in_wq:1; 901 894 unsigned int edif:1; 902 895 903 - /* 904 - * This variable may be set from outside the LIO and I/O completion 905 - * callback functions. Do not declare this member variable as a 906 - * bitfield to avoid a read-modify-write operation when this variable 907 - * is set. 908 - */ 909 - unsigned int aborted; 896 + /* Set if a SRR was rejected. */ 897 + unsigned int srr_failed:1; 910 898 899 + /* Set if the exchange has been terminated. */ 900 + unsigned int sent_term_exchg:1; 901 + 902 + /* 903 + * Set if sent_term_exchg is set, or if the cmd was aborted by a TMR, 904 + * or if some other error prevents normal processing of the command. 905 + */ 906 + unsigned int aborted:1; 907 + 908 + struct qla_tgt_srr *srr; 911 909 struct scatterlist *sg; /* cmd data buffer SG vector */ 912 910 int sg_cnt; /* SG segments count */ 913 911 int bufflen; /* cmd buffer length */ ··· 949 925 uint8_t scsi_status, sense_key, asc, ascq; 950 926 951 927 struct crc_context *ctx; 952 - const uint8_t *cdb; 928 + uint8_t *cdb; 953 929 uint64_t lba; 930 + int cdb_len; 954 931 uint16_t a_guard, e_guard, a_app_tag, e_app_tag; 955 932 uint32_t a_ref_tag, e_ref_tag; 956 933 #define DIF_BUNDL_DMA_VALID 1 957 934 uint16_t prot_flags; 935 + 936 + unsigned long jiffies_at_term_exchg; 937 + 938 + /* 939 + * jiffies64 when qlt_rdy_to_xfer() or qlt_xmit_response() first 940 + * called, or 0 when not in those states. Used to limit the number of 941 + * SRR retries. 942 + */ 943 + uint64_t jiffies_at_hw_st_entry; 958 944 959 945 uint64_t jiffies_at_alloc; 960 946 uint64_t jiffies_at_free; ··· 999 965 unsigned int flags; 1000 966 #define QLA24XX_MGMT_SEND_NACK BIT_0 1001 967 #define QLA24XX_MGMT_ABORT_IO_ATTR_VALID BIT_1 968 + #define QLA24XX_MGMT_LLD_OWNED BIT_2 1002 969 uint32_t reset_count; 1003 970 struct work_struct work; 1004 971 uint64_t unpacked_lun; ··· 1026 991 struct scatterlist *prot_sg; 1027 992 uint16_t prot_seg_cnt; 1028 993 uint16_t tot_dsds; 994 + }; 995 + 996 + /* 997 + * SRR (Sequence Retransmission Request) - resend or re-receive some or all 998 + * data or status to recover from a transient I/O error. 999 + */ 1000 + struct qla_tgt_srr { 1001 + /* 1002 + * Copy of immediate notify SRR message received from hw; valid only if 1003 + * imm_ntfy_recvd is true. 1004 + */ 1005 + struct imm_ntfy_from_isp imm_ntfy; 1006 + 1007 + struct list_head srr_list_entry; 1008 + 1009 + /* The command affected by this SRR, or NULL if not yet determined. */ 1010 + struct qla_tgt_cmd *cmd; 1011 + 1012 + /* Used to detect if the HBA has been reset since receiving the SRR. */ 1013 + uint32_t reset_count; 1014 + 1015 + /* 1016 + * The hardware sends two messages for each SRR - an immediate notify 1017 + * and a CTIO with CTIO_SRR_RECEIVED status. These keep track of which 1018 + * messages have been received. The SRR can be processed once both of 1019 + * these are true. 1020 + */ 1021 + bool imm_ntfy_recvd; 1022 + bool ctio_recvd; 1023 + 1024 + /* 1025 + * This is set to true if the affected command was aborted (cmd may be 1026 + * set to NULL), in which case the immediate notify exchange also needs 1027 + * to be aborted. 1028 + */ 1029 + bool aborted; 1030 + 1031 + /* This is set to true to force the SRR to be rejected. */ 1032 + bool reject; 1029 1033 }; 1030 1034 1031 1035 /* Check for Switch reserved address */ ··· 1122 1048 } 1123 1049 1124 1050 /* 1051 + * Free the scatterlist allocated by qlt_set_data_offset(). Call this only if 1052 + * cmd->free_sg is set. 1053 + */ 1054 + static inline void qlt_free_sg(struct qla_tgt_cmd *cmd) 1055 + { 1056 + /* 1057 + * The scatterlist may be chained to the original scatterlist, but we 1058 + * only need to free the first segment here since that is the only part 1059 + * allocated by qlt_set_data_offset(). 1060 + */ 1061 + kfree(cmd->sg); 1062 + } 1063 + 1064 + /* 1125 1065 * Exported symbols from qla_target.c LLD logic used by qla2xxx code.. 1126 1066 */ 1127 1067 extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, struct rsp_que *, ··· 1143 1055 extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); 1144 1056 extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); 1145 1057 extern int qlt_abort_cmd(struct qla_tgt_cmd *); 1058 + void qlt_srr_abort(struct qla_tgt_cmd *cmd, bool reject); 1059 + void qlt_send_term_exchange(struct qla_qpair *qpair, 1060 + struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked); 1146 1061 extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); 1062 + void qlt_free_ul_mcmd(struct qla_hw_data *ha, struct qla_tgt_mgmt_cmd *mcmd); 1147 1063 extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); 1148 1064 extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); 1065 + extern void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd); 1149 1066 extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *); 1150 1067 extern void qlt_enable_vha(struct scsi_qla_host *); 1151 1068 extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); ··· 1166 1073 struct init_cb_81xx *); 1167 1074 extern void qlt_81xx_config_nvram_stage1(struct scsi_qla_host *, 1168 1075 struct nvram_81xx *); 1076 + void qlt_config_nvram_with_fw_version(struct scsi_qla_host *vha); 1169 1077 extern void qlt_modify_vp_config(struct scsi_qla_host *, 1170 1078 struct vp_config_entry_24xx *); 1171 1079 extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *);
+17
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 291 291 return cmd; 292 292 } 293 293 294 + static int tcm_qla2xxx_get_cmd_ref(struct qla_tgt_cmd *cmd) 295 + { 296 + return target_get_sess_cmd(&cmd->se_cmd, true); 297 + } 298 + 299 + static void tcm_qla2xxx_put_cmd_ref(struct qla_tgt_cmd *cmd) 300 + { 301 + target_put_sess_cmd(&cmd->se_cmd); 302 + } 303 + 294 304 static void tcm_qla2xxx_rel_cmd(struct qla_tgt_cmd *cmd) 295 305 { 296 306 target_free_tag(cmd->sess->se_sess, &cmd->se_cmd); ··· 313 303 */ 314 304 static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) 315 305 { 306 + cmd->state = QLA_TGT_STATE_DONE; 307 + 316 308 cmd->qpair->tgt_counters.core_qla_free_cmd++; 317 309 cmd->cmd_in_wq = 1; 318 310 ··· 541 529 if (cmd->se_cmd.pi_err) 542 530 transport_generic_request_failure(&cmd->se_cmd, 543 531 cmd->se_cmd.pi_err); 532 + else if (cmd->srr_failed) 533 + transport_generic_request_failure(&cmd->se_cmd, 534 + TCM_SNACK_REJECTED); 544 535 else 545 536 transport_generic_request_failure(&cmd->se_cmd, 546 537 TCM_CHECK_CONDITION_ABORT_CMD); ··· 1539 1524 .handle_data = tcm_qla2xxx_handle_data, 1540 1525 .handle_tmr = tcm_qla2xxx_handle_tmr, 1541 1526 .get_cmd = tcm_qla2xxx_get_cmd, 1527 + .get_cmd_ref = tcm_qla2xxx_get_cmd_ref, 1528 + .put_cmd_ref = tcm_qla2xxx_put_cmd_ref, 1542 1529 .rel_cmd = tcm_qla2xxx_rel_cmd, 1543 1530 .free_cmd = tcm_qla2xxx_free_cmd, 1544 1531 .free_mcmd = tcm_qla2xxx_free_mcmd,