Commit be25152c authored by Quinn Tran's avatar Quinn Tran Committed by Nicholas Bellinger

qla2xxx: Improve T10-DIF/PI handling in driver.

Add routines to support T10 DIF tag.
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarAnil Gurumurthy <anil.gurumurthy@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 5b33469a
...@@ -348,6 +348,7 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); ...@@ -348,6 +348,7 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...);
#define ql_dbg_tgt 0x00004000 /* Target mode */ #define ql_dbg_tgt 0x00004000 /* Target mode */
#define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */
#define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
#define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */
extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
uint32_t, void **); uint32_t, void **);
......
...@@ -3127,6 +3127,16 @@ struct bidi_statistics { ...@@ -3127,6 +3127,16 @@ struct bidi_statistics {
unsigned long long transfer_bytes; unsigned long long transfer_bytes;
}; };
struct qla_tc_param {
struct scsi_qla_host *vha;
uint32_t blk_sz;
uint32_t bufflen;
struct scatterlist *sg;
struct scatterlist *prot_sg;
struct crc_context *ctx;
uint8_t *ctx_dsd_alloced;
};
/* Multi queue support */ /* Multi queue support */
#define MBC_INITIALIZE_MULTIQ 0x1f #define MBC_INITIALIZE_MULTIQ 0x1f
#define QLA_QUE_PAGE 0X1000 #define QLA_QUE_PAGE 0X1000
......
...@@ -256,11 +256,11 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); ...@@ -256,11 +256,11 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);
extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
extern int qla2x00_issue_marker(scsi_qla_host_t *, int); extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
uint32_t *, uint16_t, struct qla_tgt_cmd *); uint32_t *, uint16_t, struct qla_tc_param *);
extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *,
uint32_t *, uint16_t, struct qla_tgt_cmd *); uint32_t *, uint16_t, struct qla_tc_param *);
extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
uint32_t *, uint16_t, struct qla_tgt_cmd *); uint32_t *, uint16_t, struct qla_tc_param *);
extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *);
extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *, extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *,
......
...@@ -889,7 +889,7 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, ...@@ -889,7 +889,7 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
int int
qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc)
{ {
void *next_dsd; void *next_dsd;
uint8_t avail_dsds = 0; uint8_t avail_dsds = 0;
...@@ -898,7 +898,6 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, ...@@ -898,7 +898,6 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
struct scatterlist *sg_prot; struct scatterlist *sg_prot;
uint32_t *cur_dsd = dsd; uint32_t *cur_dsd = dsd;
uint16_t used_dsds = tot_dsds; uint16_t used_dsds = tot_dsds;
uint32_t prot_int; /* protection interval */ uint32_t prot_int; /* protection interval */
uint32_t partial; uint32_t partial;
struct qla2_sgx sgx; struct qla2_sgx sgx;
...@@ -966,7 +965,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, ...@@ -966,7 +965,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
} else { } else {
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&(tc->ctx->dsd_list)); &(tc->ctx->dsd_list));
tc->ctx_dsd_alloced = 1; *tc->ctx_dsd_alloced = 1;
} }
...@@ -1005,7 +1004,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, ...@@ -1005,7 +1004,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
int int
qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
uint16_t tot_dsds, struct qla_tgt_cmd *tc) uint16_t tot_dsds, struct qla_tc_param *tc)
{ {
void *next_dsd; void *next_dsd;
uint8_t avail_dsds = 0; uint8_t avail_dsds = 0;
...@@ -1066,7 +1065,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, ...@@ -1066,7 +1065,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
} else { } else {
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&(tc->ctx->dsd_list)); &(tc->ctx->dsd_list));
tc->ctx_dsd_alloced = 1; *tc->ctx_dsd_alloced = 1;
} }
/* add new list to cmd iocb or last list */ /* add new list to cmd iocb or last list */
...@@ -1092,7 +1091,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, ...@@ -1092,7 +1091,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
int int
qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc)
{ {
void *next_dsd; void *next_dsd;
uint8_t avail_dsds = 0; uint8_t avail_dsds = 0;
...@@ -1158,7 +1157,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, ...@@ -1158,7 +1157,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
} else { } else {
list_add_tail(&dsd_ptr->list, list_add_tail(&dsd_ptr->list,
&(tc->ctx->dsd_list)); &(tc->ctx->dsd_list));
tc->ctx_dsd_alloced = 1; *tc->ctx_dsd_alloced = 1;
} }
/* add new list to cmd iocb or last list */ /* add new list to cmd iocb or last list */
......
This diff is collapsed.
...@@ -378,6 +378,14 @@ static inline void adjust_corrupted_atio(struct atio_from_isp *atio) ...@@ -378,6 +378,14 @@ static inline void adjust_corrupted_atio(struct atio_from_isp *atio)
atio->u.isp24.fcp_cmnd.add_cdb_len = 0; atio->u.isp24.fcp_cmnd.add_cdb_len = 0;
} }
static inline int get_datalen_for_atio(struct atio_from_isp *atio)
{
int len = atio->u.isp24.fcp_cmnd.add_cdb_len;
return (be32_to_cpu(get_unaligned((uint32_t *)
&atio->u.isp24.fcp_cmnd.add_cdb[len * 4])));
}
#define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */
/* /*
...@@ -667,7 +675,6 @@ struct qla_tgt_func_tmpl { ...@@ -667,7 +675,6 @@ struct qla_tgt_func_tmpl {
int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
unsigned char *, uint32_t, int, int, int); unsigned char *, uint32_t, int, int, int);
void (*handle_data)(struct qla_tgt_cmd *); void (*handle_data)(struct qla_tgt_cmd *);
void (*handle_dif_err)(struct qla_tgt_cmd *);
int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t, int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t,
uint32_t); uint32_t);
void (*free_cmd)(struct qla_tgt_cmd *); void (*free_cmd)(struct qla_tgt_cmd *);
...@@ -684,6 +691,8 @@ struct qla_tgt_func_tmpl { ...@@ -684,6 +691,8 @@ struct qla_tgt_func_tmpl {
void (*clear_nacl_from_fcport_map)(struct fc_port *); void (*clear_nacl_from_fcport_map)(struct fc_port *);
void (*put_sess)(struct fc_port *); void (*put_sess)(struct fc_port *);
void (*shutdown_sess)(struct fc_port *); void (*shutdown_sess)(struct fc_port *);
int (*get_dif_tags)(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts);
int (*chk_dif_tags)(uint32_t tag);
}; };
int qla2x00_wait_for_hba_online(struct scsi_qla_host *); int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
...@@ -845,6 +854,7 @@ enum trace_flags { ...@@ -845,6 +854,7 @@ enum trace_flags {
TRC_CMD_FREE = BIT_17, TRC_CMD_FREE = BIT_17,
TRC_DATA_IN = BIT_18, TRC_DATA_IN = BIT_18,
TRC_ABORT = BIT_19, TRC_ABORT = BIT_19,
TRC_DIF_ERR = BIT_20,
}; };
struct qla_tgt_cmd { struct qla_tgt_cmd {
...@@ -862,7 +872,6 @@ struct qla_tgt_cmd { ...@@ -862,7 +872,6 @@ struct qla_tgt_cmd {
unsigned int sg_mapped:1; unsigned int sg_mapped:1;
unsigned int free_sg:1; unsigned int free_sg:1;
unsigned int write_data_transferred:1; unsigned int write_data_transferred:1;
unsigned int ctx_dsd_alloced:1;
unsigned int q_full:1; unsigned int q_full:1;
unsigned int term_exchg:1; unsigned int term_exchg:1;
unsigned int cmd_sent_to_fw:1; unsigned int cmd_sent_to_fw:1;
...@@ -885,11 +894,25 @@ struct qla_tgt_cmd { ...@@ -885,11 +894,25 @@ struct qla_tgt_cmd {
struct list_head cmd_list; struct list_head cmd_list;
struct atio_from_isp atio; struct atio_from_isp atio;
/* t10dif */
uint8_t ctx_dsd_alloced;
/* T10-DIF */
#define DIF_ERR_NONE 0
#define DIF_ERR_GRD 1
#define DIF_ERR_REF 2
#define DIF_ERR_APP 3
int8_t dif_err_code;
struct scatterlist *prot_sg; struct scatterlist *prot_sg;
uint32_t prot_sg_cnt; uint32_t prot_sg_cnt;
uint32_t blk_sz; uint32_t blk_sz, num_blks;
uint8_t scsi_status, sense_key, asc, ascq;
struct crc_context *ctx; struct crc_context *ctx;
uint8_t *cdb;
uint64_t lba;
uint16_t a_guard, e_guard, a_app_tag, e_app_tag;
uint32_t a_ref_tag, e_ref_tag;
uint64_t jiffies_at_alloc; uint64_t jiffies_at_alloc;
uint64_t jiffies_at_free; uint64_t jiffies_at_free;
...@@ -1053,4 +1076,7 @@ extern int qlt_free_qfull_cmds(struct scsi_qla_host *); ...@@ -1053,4 +1076,7 @@ extern int qlt_free_qfull_cmds(struct scsi_qla_host *);
extern void qlt_logo_completion_handler(fc_port_t *, int); extern void qlt_logo_completion_handler(fc_port_t *, int);
extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
void qlt_send_resp_ctio(scsi_qla_host_t *, struct qla_tgt_cmd *, uint8_t,
uint8_t, uint8_t, uint8_t);
#endif /* __QLA_TARGET_H */ #endif /* __QLA_TARGET_H */
...@@ -531,6 +531,24 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) ...@@ -531,6 +531,24 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
return; return;
} }
switch (cmd->dif_err_code) {
case DIF_ERR_GRD:
cmd->se_cmd.pi_err =
TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
break;
case DIF_ERR_REF:
cmd->se_cmd.pi_err =
TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
break;
case DIF_ERR_APP:
cmd->se_cmd.pi_err =
TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
break;
case DIF_ERR_NONE:
default:
break;
}
if (cmd->se_cmd.pi_err) if (cmd->se_cmd.pi_err)
transport_generic_request_failure(&cmd->se_cmd, transport_generic_request_failure(&cmd->se_cmd,
cmd->se_cmd.pi_err); cmd->se_cmd.pi_err);
...@@ -555,25 +573,23 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) ...@@ -555,25 +573,23 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work);
} }
static void tcm_qla2xxx_handle_dif_work(struct work_struct *work) static int tcm_qla2xxx_chk_dif_tags(uint32_t tag)
{ {
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); return 0;
/* 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);
} }
/* static int tcm_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd,
* Called from qla_target.c:qlt_do_ctio_completion() uint16_t *pfw_prot_opts)
*/
static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd)
{ {
INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work); struct se_cmd *se_cmd = &cmd->se_cmd;
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_GUARD))
*pfw_prot_opts |= PO_DISABLE_GUARD_CHECK;
if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_APPTAG))
*pfw_prot_opts |= PO_DIS_APP_TAG_VALD;
return 0;
} }
/* /*
...@@ -1610,7 +1626,6 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id, ...@@ -1610,7 +1626,6 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id,
static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
.handle_cmd = tcm_qla2xxx_handle_cmd, .handle_cmd = tcm_qla2xxx_handle_cmd,
.handle_data = tcm_qla2xxx_handle_data, .handle_data = tcm_qla2xxx_handle_data,
.handle_dif_err = tcm_qla2xxx_handle_dif_err,
.handle_tmr = tcm_qla2xxx_handle_tmr, .handle_tmr = tcm_qla2xxx_handle_tmr,
.free_cmd = tcm_qla2xxx_free_cmd, .free_cmd = tcm_qla2xxx_free_cmd,
.free_mcmd = tcm_qla2xxx_free_mcmd, .free_mcmd = tcm_qla2xxx_free_mcmd,
...@@ -1622,6 +1637,8 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { ...@@ -1622,6 +1637,8 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
.clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map,
.put_sess = tcm_qla2xxx_put_sess, .put_sess = tcm_qla2xxx_put_sess,
.shutdown_sess = tcm_qla2xxx_shutdown_sess, .shutdown_sess = tcm_qla2xxx_shutdown_sess,
.get_dif_tags = tcm_qla2xxx_dif_tags,
.chk_dif_tags = tcm_qla2xxx_chk_dif_tags,
}; };
static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment