@@ -106,8 +106,6 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
int fn, void *iocb, int flags);
static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
*cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
-static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
- struct qla_tgt_srr_imm *imm, int ha_lock);
static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
struct qla_tgt_cmd *cmd);
static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
@@ -2171,95 +2169,6 @@ static inline int qlt_need_explicit_conf(struct qla_hw_data *ha,
cmd->conf_compl_supported;
}
-#ifdef CONFIG_QLA_TGT_DEBUG_SRR
-/*
- * Original taken from the XFS code
- */
-static unsigned long qlt_srr_random(void)
-{
- static int Inited;
- static unsigned long RandomValue;
- static DEFINE_SPINLOCK(lock);
- /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
- register long rv;
- register long lo;
- register long hi;
- unsigned long flags;
-
- spin_lock_irqsave(&lock, flags);
- if (!Inited) {
- RandomValue = jiffies;
- Inited = 1;
- }
- rv = RandomValue;
- hi = rv / 127773;
- lo = rv % 127773;
- rv = 16807 * lo - 2836 * hi;
- if (rv <= 0)
- rv += 2147483647;
- RandomValue = rv;
- spin_unlock_irqrestore(&lock, flags);
- return rv;
-}
-
-static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type)
-{
-#if 0 /* This is not a real status packets lost, so it won't lead to SRR */
- if ((*xmit_type & QLA_TGT_XMIT_STATUS) && (qlt_srr_random() % 200)
- == 50) {
- *xmit_type &= ~QLA_TGT_XMIT_STATUS;
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf015,
- "Dropping cmd %p (tag %d) status", cmd, se_cmd->tag);
- }
-#endif
- /*
- * It's currently not possible to simulate SRRs for FCP_WRITE without
- * a physical link layer failure, so don't even try here..
- */
- if (cmd->dma_data_direction != DMA_FROM_DEVICE)
- return;
-
- if (qlt_has_data(cmd) && (cmd->sg_cnt > 1) &&
- ((qlt_srr_random() % 100) == 20)) {
- int i, leave = 0;
- unsigned int tot_len = 0;
-
- while (leave == 0)
- leave = qlt_srr_random() % cmd->sg_cnt;
-
- for (i = 0; i < leave; i++)
- tot_len += cmd->sg[i].length;
-
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf016,
- "Cutting cmd %p (tag %d) buffer"
- " tail to len %d, sg_cnt %d (cmd->bufflen %d,"
- " cmd->sg_cnt %d)", cmd, se_cmd->tag, tot_len, leave,
- cmd->bufflen, cmd->sg_cnt);
-
- cmd->bufflen = tot_len;
- cmd->sg_cnt = leave;
- }
-
- if (qlt_has_data(cmd) && ((qlt_srr_random() % 100) == 70)) {
- unsigned int offset = qlt_srr_random() % cmd->bufflen;
-
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf017,
- "Cutting cmd %p (tag %d) buffer head "
- "to offset %d (cmd->bufflen %d)", cmd, se_cmd->tag, offset,
- cmd->bufflen);
- if (offset == 0)
- *xmit_type &= ~QLA_TGT_XMIT_DATA;
- else if (qlt_set_data_offset(cmd, offset)) {
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf018,
- "qlt_set_data_offset() failed (tag %d)", se_cmd->tag);
- }
- }
-}
-#else
-static inline void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type)
-{}
-#endif
-
static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
struct qla_tgt_prm *prm)
{
@@ -2365,8 +2274,7 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
static inline void
qlt_set_t10dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx)
{
- struct se_cmd *se_cmd = &cmd->se_cmd;
- uint32_t lba = 0xffffffff & se_cmd->t_task_lba;
+ uint32_t lba = 0xffffffff & cmd->lba;
/* wait til Mode Sense/Select cmd, modepage Ah, subpage 2
* have been immplemented by TCM, before AppTag is avail.
@@ -2450,7 +2358,6 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
dma_addr_t crc_ctx_dma;
uint16_t fw_prot_opts = 0;
struct qla_tgt_cmd *cmd = prm->cmd;
- struct se_cmd *se_cmd = &cmd->se_cmd;
uint32_t h;
struct atio_from_isp *atio = &prm->cmd->atio;
uint16_t t16;
@@ -2462,19 +2369,19 @@ static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio,
memset(pkt, 0, sizeof(*pkt));
ql_dbg(ql_dbg_tgt, vha, 0xe071,
- "qla_target(%d):%s: se_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n",
- vha->vp_idx, __func__, se_cmd, se_cmd->prot_op,
+ "qla_target(%d):%s: ulp_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n",
+ vha->vp_idx, __func__, cmd->ulp_cmd, cmd->prot_op,
prm->prot_sg, prm->prot_seg_cnt, cmd->lba);
- if ((se_cmd->prot_op == TARGET_PROT_DIN_INSERT) ||
- (se_cmd->prot_op == TARGET_PROT_DOUT_STRIP))
+ if ((cmd->prot_op == TARGET_PROT_DIN_INSERT) ||
+ (cmd->prot_op == TARGET_PROT_DOUT_STRIP))
bundling = 0;
/* Compute dif len and adjust data len to incude protection */
data_bytes = cmd->bufflen;
dif_bytes = (data_bytes / cmd->blk_sz) * 8;
- switch (se_cmd->prot_op) {
+ switch (cmd->prot_op) {
case TARGET_PROT_DIN_INSERT:
case TARGET_PROT_DOUT_STRIP:
transfer_length = data_bytes;
@@ -2675,13 +2582,12 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
spin_unlock_irqrestore(&ha->hardware_lock, flags);
memset(&prm, 0, sizeof(prm));
- qlt_check_srr_debug(cmd, &xmit_type);
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
- "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n",
+ "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d ulp_cmd[%p]\n",
(xmit_type & QLA_TGT_XMIT_STATUS) ?
1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction,
- &cmd->se_cmd);
+ cmd->ulp_cmd);
res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
&full_req_cnt);
@@ -2934,8 +2840,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
/* 2TB boundary case covered automatically with this */
blocks_done = cmd->e_ref_tag - (uint32_t)lba + 1;
- cmd->se_cmd.bad_sector = cmd->e_ref_tag;
- cmd->se_cmd.pi_err = 0;
ql_dbg(ql_dbg_tgt, vha, 0xf074,
"need to return scsi good\n");
@@ -2944,7 +2848,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
uint32_t i, k = 0, num_ent;
struct scatterlist *sg, *sgl;
-
sgl = cmd->prot_sg;
/* Patch the corresponding protection tags */
@@ -2965,45 +2868,8 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
goto out;
}
}
-
return 0;
}
-
- /* check guard */
- if (cmd->e_guard != cmd->a_guard) {
- cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
- cmd->se_cmd.bad_sector = cmd->lba;
- ql_log(ql_log_warn, vha, 0xe076,
- "Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
- cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
- cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag,
- cmd->a_guard, cmd->e_guard, cmd);
- goto out;
- }
-
- /* check ref tag */
- if (cmd->e_ref_tag != cmd->a_ref_tag) {
- cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
- cmd->se_cmd.bad_sector = cmd->e_ref_tag;
- ql_log(ql_log_warn, vha, 0xe077,
- "Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
- cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
- cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag,
- cmd->a_guard, cmd->e_guard, cmd);
- goto out;
- }
-
- /* check appl tag */
- if (cmd->e_app_tag != cmd->a_app_tag) {
- cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
- cmd->se_cmd.bad_sector = cmd->lba;
- ql_log(ql_log_warn, vha, 0xe078,
- "App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
- cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
- cmd->a_ref_tag, cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag,
- cmd->a_guard, cmd->e_guard, cmd);
- goto out;
- }
out:
return 1;
}
@@ -3241,13 +3107,12 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
{
struct qla_tgt *tgt = cmd->tgt;
struct scsi_qla_host *vha = tgt->vha;
- struct se_cmd *se_cmd = &cmd->se_cmd;
unsigned long flags;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
"qla_target(%d): terminating exchange for aborted cmd=%p "
- "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
- se_cmd->tag);
+ "(ulp_cmd=%p, tag=%d)", vha->vp_idx, cmd, cmd->ulp_cmd,
+ cmd->atio.u.isp24.exchange_addr);
spin_lock_irqsave(&cmd->cmd_lock, flags);
if (cmd->aborted) {
@@ -3257,10 +3122,6 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
* 1) XFER Rdy completion + CMD_T_ABORT
* 2) TCM TMR - drain_state_list
*/
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
- "multiple abort. %p transport_state %x, t_state %x,"
- " se_cmd_flags %x \n", cmd, cmd->se_cmd.transport_state,
- cmd->se_cmd.t_state,cmd->se_cmd.se_cmd_flags);
return EIO;
}
cmd->aborted = 1;
@@ -3275,8 +3136,8 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
void qlt_free_cmd(struct qla_tgt_cmd *cmd)
{
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe074,
- "%s: se_cmd[%p] ox_id %04x\n",
- __func__, &cmd->se_cmd,
+ "%s: ulp_cmd[%p] ox_id %04x\n",
+ __func__, cmd->ulp_cmd,
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
BUG_ON(cmd->cmd_in_wq);
@@ -3294,90 +3155,6 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
}
EXPORT_SYMBOL(qlt_free_cmd);
-/* ha->hardware_lock supposed to be held on entry */
-static int qlt_prepare_srr_ctio(struct scsi_qla_host *vha,
- struct qla_tgt_cmd *cmd, void *ctio)
-{
- struct qla_tgt_srr_ctio *sc;
- struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
- struct qla_tgt_srr_imm *imm;
-
- tgt->ctio_srr_id++;
- cmd->cmd_flags |= BIT_15;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019,
- "qla_target(%d): CTIO with SRR status received\n", vha->vp_idx);
-
- if (!ctio) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf055,
- "qla_target(%d): SRR CTIO, but ctio is NULL\n",
- vha->vp_idx);
- return -EINVAL;
- }
-
- sc = kzalloc(sizeof(*sc), GFP_ATOMIC);
- if (sc != NULL) {
- sc->cmd = cmd;
- /* IRQ is already OFF */
- spin_lock(&tgt->srr_lock);
- sc->srr_id = tgt->ctio_srr_id;
- list_add_tail(&sc->srr_list_entry,
- &tgt->srr_ctio_list);
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a,
- "CTIO SRR %p added (id %d)\n", sc, sc->srr_id);
- if (tgt->imm_srr_id == tgt->ctio_srr_id) {
- int found = 0;
- list_for_each_entry(imm, &tgt->srr_imm_list,
- srr_list_entry) {
- if (imm->srr_id == sc->srr_id) {
- found = 1;
- break;
- }
- }
- if (found) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01b,
- "Scheduling srr work\n");
- schedule_work(&tgt->srr_work);
- } else {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf056,
- "qla_target(%d): imm_srr_id "
- "== ctio_srr_id (%d), but there is no "
- "corresponding SRR IMM, deleting CTIO "
- "SRR %p\n", vha->vp_idx,
- tgt->ctio_srr_id, sc);
- list_del(&sc->srr_list_entry);
- spin_unlock(&tgt->srr_lock);
-
- kfree(sc);
- return -EINVAL;
- }
- }
- spin_unlock(&tgt->srr_lock);
- } else {
- struct qla_tgt_srr_imm *ti;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf057,
- "qla_target(%d): Unable to allocate SRR CTIO entry\n",
- vha->vp_idx);
- spin_lock(&tgt->srr_lock);
- list_for_each_entry_safe(imm, ti, &tgt->srr_imm_list,
- srr_list_entry) {
- if (imm->srr_id == tgt->ctio_srr_id) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01c,
- "IMM SRR %p deleted (id %d)\n",
- imm, imm->srr_id);
- list_del(&imm->srr_list_entry);
- qlt_reject_free_srr_imm(vha, imm, 1);
- }
- }
- spin_unlock(&tgt->srr_lock);
-
- return -ENOMEM;
- }
-
- return 0;
-}
-
/*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/
@@ -3533,7 +3310,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
uint32_t status, void *ctio)
{
struct qla_hw_data *ha = vha->hw;
- struct se_cmd *se_cmd;
+ void *ulp_cmd;
struct qla_tgt_cmd *cmd;
if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) {
@@ -3550,7 +3327,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
if (cmd == NULL)
return;
- se_cmd = &cmd->se_cmd;
+ ulp_cmd = (void *)cmd->ulp_cmd;
cmd->cmd_sent_to_fw = 0;
qlt_unmap_sg(vha, cmd);
@@ -3566,10 +3343,10 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
/* They are OK */
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf058,
"qla_target(%d): CTIO with "
- "status %#x received, state %x, se_cmd %p, "
+ "status %#x received, state %x, ulp_cmd %p, "
"(LIP_RESET=e, ABORTED=2, TARGET_RESET=17, "
"TIMEOUT=b, INVALID_RX_ID=8)\n", vha->vp_idx,
- status, cmd->state, se_cmd);
+ status, cmd->state, ulp_cmd);
break;
case CTIO_PORT_LOGGED_OUT:
@@ -3579,10 +3356,11 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
(status & 0xFFFF) == CTIO_PORT_LOGGED_OUT;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059,
- "qla_target(%d): CTIO with %s status %x "
- "received (state %x, se_cmd %p)\n", vha->vp_idx,
- logged_out ? "PORT LOGGED OUT" : "PORT UNAVAILABLE",
- status, cmd->state, se_cmd);
+ "qla_target(%d): CTIO with PORT LOGGED "
+ "OUT (29) or PORT UNAVAILABLE (28) status %x "
+ "received (state %x, ulp_cmd %p)\n", vha->vp_idx,
+ status, cmd->state, ulp_cmd);
+ break;
if (logged_out && cmd->sess) {
/*
@@ -3598,19 +3376,16 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
case CTIO_SRR_RECEIVED:
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a,
"qla_target(%d): CTIO with SRR_RECEIVED"
- " status %x received (state %x, se_cmd %p)\n",
- vha->vp_idx, status, cmd->state, se_cmd);
- if (qlt_prepare_srr_ctio(vha, cmd, ctio) != 0)
- break;
- else
- return;
+ " status %x received (state %x, ulp_cmd %p)\n",
+ vha->vp_idx, status, cmd->state, ulp_cmd);
+ return;
case CTIO_DIF_ERROR: {
struct ctio_crc_from_fw *crc =
(struct ctio_crc_from_fw *)ctio;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073,
- "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n",
- vha->vp_idx, status, cmd->state, se_cmd,
+ "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, ulp_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n",
+ vha->vp_idx, status, cmd->state, ulp_cmd,
*((u64 *)&crc->actual_dif[0]),
*((u64 *)&crc->expected_dif[0]));
@@ -3638,8 +3413,9 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
}
default:
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
- "qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n",
- vha->vp_idx, status, cmd->state, se_cmd);
+ "qla_target(%d): CTIO with error status 0x%x received "
+ "(state %x, ulp_cmd %p\n",
+ vha->vp_idx, status, cmd->state, ulp_cmd);
break;
}
@@ -3672,7 +3448,8 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
} else if (cmd->aborted) {
cmd->cmd_flags |= BIT_18;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e,
- "Aborted command %p (tag %lld) finished\n", cmd, se_cmd->tag);
+ "Aborted command %p (tag %d) finished\n",
+ cmd, cmd->atio.u.isp24.exchange_addr);
} else {
cmd->cmd_flags |= BIT_19;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c,
@@ -3752,7 +3529,6 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
spin_lock_init(&cmd->cmd_lock);
cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
- cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
cmd->unpacked_lun = scsilun_to_int(
(struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun);
@@ -3973,8 +3749,6 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
cmd->cmd_in_wq = 1;
cmd->cmd_flags |= BIT_0;
- cmd->se_cmd.cpuid = ha->msix_count ?
- ha->tgt.rspq_vector_cpuid : WORK_CPU_UNBOUND;
spin_lock(&vha->cmd_list_lock);
list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
@@ -3986,8 +3760,8 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
queue_work_on(smp_processor_id(), qla_tgt_wq,
&cmd->work);
else
- queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq,
- &cmd->work);
+ queue_work_on(ha->tgt.rspq_vector_cpuid,
+ qla_tgt_wq, &cmd->work);
} else {
queue_work(qla_tgt_wq, &cmd->work);
}
@@ -4451,453 +4225,6 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
return res;
}
-static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
-{
-#if 1
- /*
- * FIXME: Reject non zero SRR relative offset until we can test
- * this code properly.
- */
- pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset);
- return -1;
-#else
- struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL;
- size_t first_offset = 0, rem_offset = offset, tmp = 0;
- int i, sg_srr_cnt, bufflen = 0;
-
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe023,
- "Entering qla_tgt_set_data_offset: cmd: %p, cmd->sg: %p, "
- "cmd->sg_cnt: %u, direction: %d\n",
- cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
-
- if (!cmd->sg || !cmd->sg_cnt) {
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055,
- "Missing cmd->sg or zero cmd->sg_cnt in"
- " qla_tgt_set_data_offset\n");
- return -EINVAL;
- }
- /*
- * Walk the current cmd->sg list until we locate the new sg_srr_start
- */
- for_each_sg(cmd->sg, sg, cmd->sg_cnt, i) {
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe024,
- "sg[%d]: %p page: %p, length: %d, offset: %d\n",
- i, sg, sg_page(sg), sg->length, sg->offset);
-
- if ((sg->length + tmp) > offset) {
- first_offset = rem_offset;
- sg_srr_start = sg;
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe025,
- "Found matching sg[%d], using %p as sg_srr_start, "
- "and using first_offset: %zu\n", i, sg,
- first_offset);
- break;
- }
- tmp += sg->length;
- rem_offset -= sg->length;
- }
-
- if (!sg_srr_start) {
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe056,
- "Unable to locate sg_srr_start for offset: %u\n", offset);
- return -EINVAL;
- }
- sg_srr_cnt = (cmd->sg_cnt - i);
-
- sg_srr = kzalloc(sizeof(struct scatterlist) * sg_srr_cnt, GFP_KERNEL);
- if (!sg_srr) {
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe057,
- "Unable to allocate sgp\n");
- return -ENOMEM;
- }
- sg_init_table(sg_srr, sg_srr_cnt);
- sgp = &sg_srr[0];
- /*
- * Walk the remaining list for sg_srr_start, mapping to the newly
- * allocated sg_srr taking first_offset into account.
- */
- for_each_sg(sg_srr_start, sg, sg_srr_cnt, i) {
- if (first_offset) {
- sg_set_page(sgp, sg_page(sg),
- (sg->length - first_offset), first_offset);
- first_offset = 0;
- } else {
- sg_set_page(sgp, sg_page(sg), sg->length, 0);
- }
- bufflen += sgp->length;
-
- sgp = sg_next(sgp);
- if (!sgp)
- break;
- }
-
- cmd->sg = sg_srr;
- cmd->sg_cnt = sg_srr_cnt;
- cmd->bufflen = bufflen;
- cmd->offset += offset;
- cmd->free_sg = 1;
-
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe026, "New cmd->sg: %p\n", cmd->sg);
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe027, "New cmd->sg_cnt: %u\n",
- cmd->sg_cnt);
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe028, "New cmd->bufflen: %u\n",
- cmd->bufflen);
- ql_dbg(ql_dbg_tgt, cmd->vha, 0xe029, "New cmd->offset: %u\n",
- cmd->offset);
-
- if (cmd->sg_cnt < 0)
- BUG();
-
- if (cmd->bufflen < 0)
- BUG();
-
- return 0;
-#endif
-}
-
-static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd,
- uint32_t srr_rel_offs, int *xmit_type)
-{
- int res = 0, rel_offs;
-
- rel_offs = srr_rel_offs - cmd->offset;
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf027, "srr_rel_offs=%d, rel_offs=%d",
- srr_rel_offs, rel_offs);
-
- *xmit_type = QLA_TGT_XMIT_ALL;
-
- if (rel_offs < 0) {
- ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf062,
- "qla_target(%d): SRR rel_offs (%d) < 0",
- cmd->vha->vp_idx, rel_offs);
- res = -1;
- } else if (rel_offs == cmd->bufflen)
- *xmit_type = QLA_TGT_XMIT_STATUS;
- else if (rel_offs > 0)
- res = qlt_set_data_offset(cmd, rel_offs);
-
- return res;
-}
-
-/* No locks, thread context */
-static void qlt_handle_srr(struct scsi_qla_host *vha,
- struct qla_tgt_srr_ctio *sctio, struct qla_tgt_srr_imm *imm)
-{
- struct imm_ntfy_from_isp *ntfy =
- (struct imm_ntfy_from_isp *)&imm->imm_ntfy;
- struct qla_hw_data *ha = vha->hw;
- struct qla_tgt_cmd *cmd = sctio->cmd;
- struct se_cmd *se_cmd = &cmd->se_cmd;
- unsigned long flags;
- int xmit_type = 0, resp = 0;
- uint32_t offset;
- uint16_t srr_ui;
-
- offset = le32_to_cpu(ntfy->u.isp24.srr_rel_offs);
- srr_ui = ntfy->u.isp24.srr_ui;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf028, "SRR cmd %p, srr_ui %x\n",
- cmd, srr_ui);
-
- switch (srr_ui) {
- case SRR_IU_STATUS:
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qlt_send_notify_ack(vha, ntfy,
- 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- xmit_type = QLA_TGT_XMIT_STATUS;
- resp = 1;
- break;
- case SRR_IU_DATA_IN:
- if (!cmd->sg || !cmd->sg_cnt) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf063,
- "Unable to process SRR_IU_DATA_IN due to"
- " missing cmd->sg, state: %d\n", cmd->state);
- dump_stack();
- goto out_reject;
- }
- if (se_cmd->scsi_status != 0) {
- ql_dbg(ql_dbg_tgt, vha, 0xe02a,
- "Rejecting SRR_IU_DATA_IN with non GOOD "
- "scsi_status\n");
- goto out_reject;
- }
- cmd->bufflen = se_cmd->data_length;
-
- if (qlt_has_data(cmd)) {
- if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0)
- goto out_reject;
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qlt_send_notify_ack(vha, ntfy,
- 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- resp = 1;
- } else {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf064,
- "qla_target(%d): SRR for in data for cmd without them (tag %lld, SCSI status %d), reject",
- vha->vp_idx, se_cmd->tag,
- cmd->se_cmd.scsi_status);
- goto out_reject;
- }
- break;
- case SRR_IU_DATA_OUT:
- if (!cmd->sg || !cmd->sg_cnt) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf065,
- "Unable to process SRR_IU_DATA_OUT due to"
- " missing cmd->sg\n");
- dump_stack();
- goto out_reject;
- }
- if (se_cmd->scsi_status != 0) {
- ql_dbg(ql_dbg_tgt, vha, 0xe02b,
- "Rejecting SRR_IU_DATA_OUT"
- " with non GOOD scsi_status\n");
- goto out_reject;
- }
- cmd->bufflen = se_cmd->data_length;
-
- if (qlt_has_data(cmd)) {
- if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0)
- goto out_reject;
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qlt_send_notify_ack(vha, ntfy,
- 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0);
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (xmit_type & QLA_TGT_XMIT_DATA) {
- cmd->cmd_flags |= BIT_8;
- qlt_rdy_to_xfer(cmd);
- }
- } else {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066,
- "qla_target(%d): SRR for out data for cmd without them (tag %lld, SCSI status %d), reject",
- vha->vp_idx, se_cmd->tag, cmd->se_cmd.scsi_status);
- goto out_reject;
- }
- break;
- default:
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf067,
- "qla_target(%d): Unknown srr_ui value %x",
- vha->vp_idx, srr_ui);
- goto out_reject;
- }
-
- /* Transmit response in case of status and data-in cases */
- if (resp) {
- cmd->cmd_flags |= BIT_7;
- qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status);
- }
-
- return;
-
-out_reject:
- spin_lock_irqsave(&ha->hardware_lock, flags);
- qlt_send_notify_ack(vha, ntfy, 0, 0, 0,
- NOTIFY_ACK_SRR_FLAGS_REJECT,
- NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM,
- NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL);
- if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
- cmd->state = QLA_TGT_STATE_DATA_IN;
- dump_stack();
- } else {
- cmd->cmd_flags |= BIT_9;
- qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
- }
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-static void qlt_reject_free_srr_imm(struct scsi_qla_host *vha,
- struct qla_tgt_srr_imm *imm, int ha_locked)
-{
- struct qla_hw_data *ha = vha->hw;
- unsigned long flags = 0;
-
-#ifndef __CHECKER__
- if (!ha_locked)
- spin_lock_irqsave(&ha->hardware_lock, flags);
-#endif
-
- qlt_send_notify_ack(vha, (void *)&imm->imm_ntfy, 0, 0, 0,
- NOTIFY_ACK_SRR_FLAGS_REJECT,
- NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM,
- NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL);
-
-#ifndef __CHECKER__
- if (!ha_locked)
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
-#endif
-
- kfree(imm);
-}
-
-static void qlt_handle_srr_work(struct work_struct *work)
-{
- struct qla_tgt *tgt = container_of(work, struct qla_tgt, srr_work);
- struct scsi_qla_host *vha = tgt->vha;
- struct qla_tgt_srr_ctio *sctio;
- unsigned long flags;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf029, "Entering SRR work (tgt %p)\n",
- tgt);
-
-restart:
- spin_lock_irqsave(&tgt->srr_lock, flags);
- list_for_each_entry(sctio, &tgt->srr_ctio_list, srr_list_entry) {
- struct qla_tgt_srr_imm *imm, *i, *ti;
- struct qla_tgt_cmd *cmd;
- struct se_cmd *se_cmd;
-
- imm = NULL;
- list_for_each_entry_safe(i, ti, &tgt->srr_imm_list,
- srr_list_entry) {
- if (i->srr_id == sctio->srr_id) {
- list_del(&i->srr_list_entry);
- if (imm) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf068,
- "qla_target(%d): There must be "
- "only one IMM SRR per CTIO SRR "
- "(IMM SRR %p, id %d, CTIO %p\n",
- vha->vp_idx, i, i->srr_id, sctio);
- qlt_reject_free_srr_imm(tgt->vha, i, 0);
- } else
- imm = i;
- }
- }
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02a,
- "IMM SRR %p, CTIO SRR %p (id %d)\n", imm, sctio,
- sctio->srr_id);
-
- if (imm == NULL) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02b,
- "Not found matching IMM for SRR CTIO (id %d)\n",
- sctio->srr_id);
- continue;
- } else
- list_del(&sctio->srr_list_entry);
-
- spin_unlock_irqrestore(&tgt->srr_lock, flags);
-
- cmd = sctio->cmd;
- /*
- * Reset qla_tgt_cmd SRR values and SGL pointer+count to follow
- * tcm_qla2xxx_write_pending() and tcm_qla2xxx_queue_data_in()
- * logic..
- */
- cmd->offset = 0;
- if (cmd->free_sg) {
- kfree(cmd->sg);
- cmd->sg = NULL;
- cmd->free_sg = 0;
- }
- se_cmd = &cmd->se_cmd;
-
- cmd->sg_cnt = se_cmd->t_data_nents;
- cmd->sg = se_cmd->t_data_sg;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c,
- "SRR cmd %p (se_cmd %p, tag %d, op %x), "
- "sg_cnt=%d, offset=%d",
- cmd, &cmd->se_cmd, cmd->atio.u.isp24.exchange_addr,
- cmd->cdb ? cmd->cdb[0] : 0,
- cmd->sg_cnt, cmd->offset);
-
- qlt_handle_srr(vha, sctio, imm);
-
- kfree(imm);
- kfree(sctio);
- goto restart;
- }
- spin_unlock_irqrestore(&tgt->srr_lock, flags);
-}
-
-/* ha->hardware_lock supposed to be held on entry */
-static void qlt_prepare_srr_imm(struct scsi_qla_host *vha,
- struct imm_ntfy_from_isp *iocb)
-{
- struct qla_tgt_srr_imm *imm;
- struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
- struct qla_tgt_srr_ctio *sctio;
-
- tgt->imm_srr_id++;
-
- ql_log(ql_log_warn, vha, 0xf02d, "qla_target(%d): SRR received\n",
- vha->vp_idx);
-
- imm = kzalloc(sizeof(*imm), GFP_ATOMIC);
- if (imm != NULL) {
- memcpy(&imm->imm_ntfy, iocb, sizeof(imm->imm_ntfy));
-
- /* IRQ is already OFF */
- spin_lock(&tgt->srr_lock);
- imm->srr_id = tgt->imm_srr_id;
- list_add_tail(&imm->srr_list_entry,
- &tgt->srr_imm_list);
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02e,
- "IMM NTFY SRR %p added (id %d, ui %x)\n",
- imm, imm->srr_id, iocb->u.isp24.srr_ui);
- if (tgt->imm_srr_id == tgt->ctio_srr_id) {
- int found = 0;
- list_for_each_entry(sctio, &tgt->srr_ctio_list,
- srr_list_entry) {
- if (sctio->srr_id == imm->srr_id) {
- found = 1;
- break;
- }
- }
- if (found) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02f, "%s",
- "Scheduling srr work\n");
- schedule_work(&tgt->srr_work);
- } else {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf030,
- "qla_target(%d): imm_srr_id "
- "== ctio_srr_id (%d), but there is no "
- "corresponding SRR CTIO, deleting IMM "
- "SRR %p\n", vha->vp_idx, tgt->ctio_srr_id,
- imm);
- list_del(&imm->srr_list_entry);
-
- kfree(imm);
-
- spin_unlock(&tgt->srr_lock);
- goto out_reject;
- }
- }
- spin_unlock(&tgt->srr_lock);
- } else {
- struct qla_tgt_srr_ctio *ts;
-
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf069,
- "qla_target(%d): Unable to allocate SRR IMM "
- "entry, SRR request will be rejected\n", vha->vp_idx);
-
- /* IRQ is already OFF */
- spin_lock(&tgt->srr_lock);
- list_for_each_entry_safe(sctio, ts, &tgt->srr_ctio_list,
- srr_list_entry) {
- if (sctio->srr_id == tgt->imm_srr_id) {
- ql_dbg(ql_dbg_tgt_mgt, vha, 0xf031,
- "CTIO SRR %p deleted (id %d)\n",
- sctio, sctio->srr_id);
- list_del(&sctio->srr_list_entry);
- qlt_send_term_exchange(vha, sctio->cmd,
- &sctio->cmd->atio, 1, 0);
- kfree(sctio);
- }
- }
- spin_unlock(&tgt->srr_lock);
- goto out_reject;
- }
-
- return;
-
-out_reject:
- qlt_send_notify_ack(vha, iocb, 0, 0, 0,
- NOTIFY_ACK_SRR_FLAGS_REJECT,
- NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM,
- NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL);
-}
-
/*
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
*/
@@ -5021,8 +4348,6 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
break;
case IMM_NTFY_SRR:
- qlt_prepare_srr_imm(vha, iocb);
- send_notify_ack = 0;
break;
default:
@@ -5965,10 +5290,6 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
spin_lock_init(&tgt->sess_work_lock);
INIT_WORK(&tgt->sess_work, qlt_sess_work_fn);
INIT_LIST_HEAD(&tgt->sess_works_list);
- spin_lock_init(&tgt->srr_lock);
- INIT_LIST_HEAD(&tgt->srr_ctio_list);
- INIT_LIST_HEAD(&tgt->srr_imm_list);
- INIT_WORK(&tgt->srr_work, qlt_handle_srr_work);
atomic_set(&tgt->tgt_global_resets_count, 0);
base_vha->vha_tgt.qla_tgt = tgt;
@@ -709,10 +709,8 @@ struct abts_resp_from_24xx_fw {
/********************************************************************\
* Type Definitions used by initiator & target halves
\********************************************************************/
-
struct qla_tgt_mgmt_cmd;
struct qla_tgt_sess;
-
/*
* This structure provides a template of function calls that the
* target driver (from within qla_target.c) can issue to the
@@ -979,7 +977,7 @@ struct qla_tgt_sess {
} cmd_flags_t;
struct qla_tgt_cmd {
- struct se_cmd se_cmd;
+ void *ulp_cmd;
struct qla_tgt_sess *sess;
int state;
struct work_struct free_work;
@@ -1051,7 +1049,7 @@ struct qla_tgt_mgmt_cmd {
uint16_t tmr_func;
uint8_t fc_tm_rsp;
struct qla_tgt_sess *sess;
- struct se_cmd se_cmd;
+ void *ulp_cmd;
struct work_struct free_work;
unsigned int flags;
uint32_t reset_count;
@@ -1082,18 +1080,6 @@ struct qla_tgt_prm {
uint16_t tot_dsds;
};
-struct qla_tgt_srr_imm {
- struct list_head srr_list_entry;
- int srr_id;
- struct imm_ntfy_from_isp imm_ntfy;
-};
-
-struct qla_tgt_srr_ctio {
- struct list_head srr_list_entry;
- int srr_id;
- struct qla_tgt_cmd *cmd;
-};
-
/* Check for Switch reserved address */
#define IS_SW_RESV_ADDR(_s_id) \
((_s_id.b.domain == 0xff) && (_s_id.b.area == 0xfc))
@@ -51,6 +51,38 @@
static struct workqueue_struct *tcm_qla2xxx_free_wq;
static struct workqueue_struct *tcm_qla2xxx_cmd_wq;
+inline struct se_cmd *Q_TO_SE_CMD(struct qla_tgt_cmd *qcmd)
+{
+ struct tcm_qla_tgt_cmd *tc =
+ container_of(qcmd, struct tcm_qla_tgt_cmd, qcmd);
+
+ return &tc->se_cmd;
+}
+
+inline struct qla_tgt_cmd *SE_TO_Q_CMD(struct se_cmd *se_cmd)
+{
+ struct tcm_qla_tgt_cmd *tc =
+ container_of(se_cmd, struct tcm_qla_tgt_cmd, se_cmd);
+
+ return &tc->qcmd;
+}
+
+inline struct se_cmd *QMGT_TO_SE_CMD(struct qla_tgt_mgmt_cmd *qcmd)
+{
+ struct tcm_qla_tgt_mgmt_cmd *tc =
+ container_of(qcmd, struct tcm_qla_tgt_mgmt_cmd, mgt_cmd);
+
+ return &tc->se_cmd;
+}
+
+inline struct qla_tgt_mgmt_cmd *SE_TO_QMGT_CMD(struct se_cmd *se_cmd)
+{
+ struct tcm_qla_tgt_mgmt_cmd *tc =
+ container_of(se_cmd, struct tcm_qla_tgt_mgmt_cmd, se_cmd);
+
+ return &tc->mgt_cmd;
+}
+
/*
* Parse WWN.
* If strict, we require lower-case hex and colon separators to be sure
@@ -262,7 +294,7 @@ static void tcm_qla2xxx_complete_mcmd(struct work_struct *work)
struct qla_tgt_mgmt_cmd *mcmd = container_of(work,
struct qla_tgt_mgmt_cmd, free_work);
- transport_generic_free_cmd(&mcmd->se_cmd, 0);
+ transport_generic_free_cmd(QMGT_TO_SE_CMD(mcmd), 0);
}
static void tcm_qla2xxx_check_resid(struct se_cmd *se_cmd,
@@ -295,7 +327,7 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
cmd->vha->tgt_counters.qla_core_ret_sta_ctio++;
cmd->cmd_flags |= BIT_16;
- transport_generic_free_cmd(&cmd->se_cmd, 0);
+ transport_generic_free_cmd(Q_TO_SE_CMD(cmd), 0);
}
/*
@@ -323,7 +355,7 @@ static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
struct qla_tgt_cmd *cmd;
if ((se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) == 0) {
- cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+ cmd = SE_TO_Q_CMD(se_cmd);
cmd->cmd_flags |= BIT_14;
}
@@ -347,13 +379,12 @@ static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
struct se_session *se_sess;
if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) {
- struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
- struct qla_tgt_mgmt_cmd, se_cmd);
+ struct qla_tgt_mgmt_cmd *mcmd = SE_TO_QMGT_CMD(se_cmd);
qlt_free_mcmd(mcmd);
return;
}
- cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+ cmd = SE_TO_Q_CMD(se_cmd);
qlt_free_cmd(cmd);
if (!cmd->sess || !cmd->sess->se_sess) {
@@ -369,7 +400,7 @@ static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd)
static void tcm_qla2xxx_rel_cmd(struct qla_tgt_cmd *cmd)
{
- tcm_qla2xxx_release_cmd(&cmd->se_cmd);
+ tcm_qla2xxx_release_cmd(Q_TO_SE_CMD(cmd));
}
static struct qla_tgt_cmd *tcm_qla2xxx_alloc_cmd(struct qla_tgt_sess *sess)
@@ -377,15 +408,23 @@ static struct qla_tgt_cmd *tcm_qla2xxx_alloc_cmd(struct qla_tgt_sess *sess)
struct se_session *se_sess = (struct se_session *)sess->se_sess;
int tag;
struct qla_tgt_cmd *cmd = NULL;
+ struct tcm_qla_tgt_cmd *tc = NULL;
+ struct qla_hw_data *ha = sess->vha->hw;
tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
if (tag < 0)
return NULL;
- cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
- if (cmd) {
- memset(cmd, 0, sizeof(struct qla_tgt_cmd));
- cmd->se_cmd.map_tag = tag;
+ tc = &((struct tcm_qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
+ if (tc) {
+ memset(tc, 0, sizeof(struct tcm_qla_tgt_cmd));
+ tc->se_cmd.map_tag = tag;
+ tc->se_cmd.cpuid = -1;
+
+ if (ha->msix_count)
+ tc->se_cmd.cpuid = ha->tgt.rspq_vector_cpuid;
+
+ tc->qcmd.ulp_cmd = (void *)&tc->se_cmd;
}
return cmd;
}
@@ -412,8 +451,7 @@ static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
{
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
if (cmd->aborted) {
/* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
@@ -422,10 +460,10 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
*/
pr_debug("write_pending aborted cmd[%p] refcount %d "
"transport_state %x, t_state %x, se_cmd_flags %x\n",
- cmd,cmd->se_cmd.cmd_kref.refcount.counter,
- cmd->se_cmd.transport_state,
- cmd->se_cmd.t_state,
- cmd->se_cmd.se_cmd_flags);
+ cmd, se_cmd->cmd_kref.refcount.counter,
+ se_cmd->transport_state,
+ se_cmd->t_state,
+ se_cmd->se_cmd_flags);
return 0;
}
cmd->cmd_flags |= BIT_3;
@@ -477,8 +515,7 @@ static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl)
static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd)
{
if (!(se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
return cmd->state;
}
@@ -492,7 +529,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
unsigned char *cdb, uint32_t data_length, int fcp_task_attr,
int data_dir, int bidi)
{
- struct se_cmd *se_cmd = &cmd->se_cmd;
+ struct se_cmd *se_cmd = Q_TO_SE_CMD(cmd);
struct se_session *se_sess;
struct qla_tgt_sess *sess;
#ifdef CONFIG_TCM_QLA2XXX_DEBUG
@@ -513,6 +550,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
return -EINVAL;
}
+ se_cmd->tag = cmd->atio.u.isp24.exchange_addr;
se_sess = sess->se_sess;
if (!se_sess) {
pr_err("Unable to locate active struct se_session\n");
@@ -534,10 +572,58 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
data_dir, flags);
}
+static void tcm_qla2xxx_check_dif_err(struct qla_tgt_cmd *cmd)
+{
+ struct se_cmd *se_cmd = Q_TO_SE_CMD(cmd);
+
+ if ((cmd->a_app_tag == 0xffff) &&
+ ((cmd->prot_type != TARGET_DIF_TYPE3_PROT) ||
+ (cmd->a_ref_tag == 0xffffffff))) {
+ se_cmd->bad_sector = cmd->e_ref_tag;
+ se_cmd->pi_err = 0;
+ return;
+ }
+
+ /* check guard */
+ if (cmd->e_guard != cmd->a_guard) {
+ se_cmd->pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
+ se_cmd->bad_sector = cmd->lba;
+ pr_err("Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
+ cmd->atio.u.isp24.fcp_cmnd.cdb[0], cmd->lba, cmd->a_ref_tag,
+ cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag, cmd->a_guard, cmd->e_guard, cmd);
+ goto out;
+ }
+
+ /* check ref tag */
+ if (cmd->e_ref_tag != cmd->a_ref_tag) {
+ se_cmd->pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
+ se_cmd->bad_sector = cmd->e_ref_tag;
+ pr_err("Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
+ cmd->atio.u.isp24.fcp_cmnd.cdb[0], cmd->lba, cmd->a_ref_tag,
+ cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag,
+ cmd->a_guard, cmd->e_guard, cmd);
+ goto out;
+ }
+
+ /* check appl tag */
+ if (cmd->e_app_tag != cmd->a_app_tag) {
+ se_cmd->pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
+ se_cmd->bad_sector = cmd->lba;
+ pr_err("App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
+ cmd->atio.u.isp24.fcp_cmnd.cdb[0], cmd->lba, cmd->a_ref_tag,
+ cmd->e_ref_tag, cmd->a_app_tag, cmd->e_app_tag,
+ cmd->a_guard, cmd->e_guard, cmd);
+ goto out;
+ }
+out:
+ return;
+}
+
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
unsigned long flags;
+ struct se_cmd *se_cmd = Q_TO_SE_CMD(cmd);
/*
* Ensure that the complete FCP WRITE payload has been received.
@@ -557,27 +643,31 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
spin_unlock_irqrestore(&cmd->cmd_lock, flags);
cmd->vha->tgt_counters.qla_core_ret_ctio++;
+
+ if (cmd->prot_op)
+ tcm_qla2xxx_check_dif_err(cmd);
+
if (!cmd->write_data_transferred) {
/*
* Check if se_cmd has already been aborted via LUN_RESET, and
* waiting upon completion in tcm_qla2xxx_write_pending_status()
*/
- if (cmd->se_cmd.transport_state & CMD_T_ABORTED) {
- complete(&cmd->se_cmd.t_transport_stop_comp);
+ if (se_cmd->transport_state & CMD_T_ABORTED) {
+ complete(&se_cmd->t_transport_stop_comp);
return;
}
- if (cmd->se_cmd.pi_err)
- transport_generic_request_failure(&cmd->se_cmd,
- cmd->se_cmd.pi_err);
+ if (se_cmd->pi_err)
+ transport_generic_request_failure(se_cmd,
+ se_cmd->pi_err);
else
- transport_generic_request_failure(&cmd->se_cmd,
+ transport_generic_request_failure(se_cmd,
TCM_CHECK_CONDITION_ABORT_CMD);
return;
}
- return target_execute_cmd(&cmd->se_cmd);
+ return target_execute_cmd(se_cmd);
}
/*
@@ -594,13 +684,16 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+ struct se_cmd *se_cmd = Q_TO_SE_CMD(cmd);
+
+ tcm_qla2xxx_check_dif_err(cmd);
/* take an extra kref to prevent cmd free too early.
* need to wait for SCSI status/check condition to
* finish responding generate by transport_generic_request_failure.
*/
- kref_get(&cmd->se_cmd.cmd_kref);
- transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err);
+ kref_get(&se_cmd->cmd_kref);
+ transport_generic_request_failure(se_cmd, se_cmd->pi_err);
}
/*
@@ -619,7 +712,7 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun,
uint16_t tmr_func, uint32_t tag)
{
struct qla_tgt_sess *sess = mcmd->sess;
- struct se_cmd *se_cmd = &mcmd->se_cmd;
+ struct se_cmd *se_cmd = QMGT_TO_SE_CMD(mcmd);
struct se_session *se_sess = sess->se_sess;
bool found_lun = false;
int transl_tmr_func;
@@ -628,8 +721,7 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun,
case QLA_TGT_ABTS:
spin_lock(&se_sess->sess_cmd_lock);
list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
- struct qla_tgt_cmd *cmd =
- container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
struct abts_recv_from_24xx *abts = &mcmd->orig_iocb.abts;
if (se_cmd->tag == abts->exchange_addr_to_abort) {
@@ -682,8 +774,7 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun,
static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
{
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
if (cmd->aborted) {
/* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task
@@ -692,10 +783,10 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
*/
pr_debug("queue_data_in aborted cmd[%p] refcount %d "
"transport_state %x, t_state %x, se_cmd_flags %x\n",
- cmd,cmd->se_cmd.cmd_kref.refcount.counter,
- cmd->se_cmd.transport_state,
- cmd->se_cmd.t_state,
- cmd->se_cmd.se_cmd_flags);
+ cmd, se_cmd->cmd_kref.refcount.counter,
+ se_cmd->transport_state,
+ se_cmd->t_state,
+ se_cmd->se_cmd_flags);
return 0;
}
@@ -725,8 +816,8 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
{
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
+
int xmit_type = QLA_TGT_XMIT_STATUS;
cmd->bufflen = se_cmd->data_length;
@@ -766,8 +857,8 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
{
struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
- struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
- struct qla_tgt_mgmt_cmd, se_cmd);
+ struct qla_tgt_mgmt_cmd *mcmd = SE_TO_QMGT_CMD(se_cmd);
+
pr_debug("queue_tm_rsp: mcmd: %p func: 0x%02x response: 0x%02x\n",
mcmd, se_tmr->function, se_tmr->response);
@@ -803,8 +894,7 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
CMD_FLAG_DATA_WORK)
static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd = SE_TO_Q_CMD(se_cmd);
unsigned long flags;
if (qlt_abort_cmd(cmd))
@@ -1585,9 +1675,9 @@ static int tcm_qla2xxx_check_initiator_node_acl(
* via ConfigFS, or via running in TPG demo mode.
*/
se_sess = target_alloc_session(&tpg->se_tpg, num_tags,
- sizeof(struct qla_tgt_cmd),
- TARGET_PROT_ALL, port_name,
- qlat_sess, tcm_qla2xxx_session_cb);
+ sizeof(struct tcm_qla_tgt_cmd), TARGET_PROT_ALL, port_name,
+ qlat_sess, tcm_qla2xxx_session_cb);
+
if (IS_ERR(se_sess))
return PTR_ERR(se_sess);
@@ -81,3 +81,13 @@ struct tcm_qla2xxx_lport {
/* Returned by tcm_qla2xxx_make_lport() */
struct se_wwn lport_wwn;
};
+
+struct tcm_qla_tgt_cmd {
+ struct se_cmd se_cmd;
+ struct qla_tgt_cmd qcmd;
+};
+
+struct tcm_qla_tgt_mgmt_cmd {
+ struct se_cmd se_cmd;
+ struct qla_tgt_mgmt_cmd mgt_cmd;
+};