tcmu_cmd
static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err)
struct tcmu_dev *udev = tcmu_cmd->tcmu_dev;
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
size_t data_length = (size_t)tcmu_cmd->dbi_cnt * blk_size;
iov_cnt = tcmu_alloc_data_space(udev, tcmu_cmd, &iov_bidi_cnt);
command_size = tcmu_cmd_get_cmd_size(tcmu_cmd, base_command_size);
tcmu_cmd_free_data(tcmu_cmd, tcmu_cmd->dbi_cur);
if (xa_alloc(&udev->commands, &cmd_id, tcmu_cmd, XA_LIMIT(1, 0xffff),
tcmu_cmd_free_data(tcmu_cmd, tcmu_cmd->dbi_cnt);
tcmu_cmd->cmd_id = cmd_id;
pr_debug("allocated cmd id %u for cmd %p dev %s\n", tcmu_cmd->cmd_id,
tcmu_cmd, udev->name);
tcmu_cmd_reset_dbi_cur(tcmu_cmd);
scatter_data_area(udev, tcmu_cmd, &iov);
tcmu_setup_iovs(udev, tcmu_cmd, &iov, se_cmd->data_length);
tcmu_setup_iovs(udev, tcmu_cmd, &iov, tcmu_cmd->data_len_bidi);
tcmu_setup_cmd_timer(tcmu_cmd, udev->cmd_time_out, &udev->cmd_timer);
entry->hdr.cmd_id = tcmu_cmd->cmd_id;
list_add_tail(&tcmu_cmd->queue_entry, &udev->inflight_queue);
tcmu_cmd_free_data(tcmu_cmd, tcmu_cmd->dbi_cur);
tcmu_cmd_reset_dbi_cur(tcmu_cmd);
if (add_to_qfull_queue(tcmu_cmd)) {
struct tcmu_cmd *tcmu_cmd;
tcmu_cmd = tcmu_alloc_cmd(se_cmd);
if (!tcmu_cmd)
ret = queue_cmd_ring(tcmu_cmd, &scsi_ret);
tcmu_free_cmd(tcmu_cmd);
se_cmd->priv = tcmu_cmd;
struct tcmu_cmd *cmd;
cmd = list_first_entry(queue, struct tcmu_cmd, queue_entry);
struct tcmu_cmd *cmd;
static bool tcmu_handle_completion(struct tcmu_cmd *cmd,
struct tcmu_cmd *cmd;
static void tcmu_check_expired_ring_cmd(struct tcmu_cmd *cmd)
static void tcmu_check_expired_queue_cmd(struct tcmu_cmd *cmd)
static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd)
struct tcmu_cmd *cmd;
struct tcmu_cmd *tcmu_cmd, *tmp_cmd;
list_for_each_entry_safe(tcmu_cmd, tmp_cmd, &cmds, queue_entry) {
list_del_init(&tcmu_cmd->queue_entry);
tcmu_cmd, udev->name);
tcmu_cmd->se_cmd->priv = NULL;
target_complete_cmd(tcmu_cmd->se_cmd, SAM_STAT_BUSY);
tcmu_free_cmd(tcmu_cmd);
ret = queue_cmd_ring(tcmu_cmd, &scsi_ret);
tcmu_cmd, udev->name, scsi_ret);
tcmu_cmd->se_cmd->priv = NULL;
target_complete_cmd(tcmu_cmd->se_cmd,
tcmu_free_cmd(tcmu_cmd);
struct tcmu_cmd *cmd;
struct tcmu_cmd *cmd;
struct tcmu_cmd *cmd;
struct tcmu_cmd *cmd, *tmp_cmd;
sizeof(struct tcmu_cmd),
__alignof__(struct tcmu_cmd),
static void tcmu_cmd_free_data(struct tcmu_cmd *tcmu_cmd, uint32_t len)
struct tcmu_dev *udev = tcmu_cmd->tcmu_dev;
clear_bit(tcmu_cmd->dbi[i], udev->data_bitmap);
struct tcmu_cmd *tcmu_cmd,
tcmu_cmd_set_dbi(tcmu_cmd, dbi);
struct tcmu_cmd *tcmu_cmd, int length)
dbi = tcmu_get_empty_block(udev, tcmu_cmd, dbi, blk_data_len,
static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd)
kfree(tcmu_cmd->dbi);
kmem_cache_free(tcmu_cmd_cache, tcmu_cmd);
static inline void tcmu_cmd_set_block_cnts(struct tcmu_cmd *cmd)
static int new_block_to_iov(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
static void tcmu_setup_iovs(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd)
struct tcmu_cmd *tcmu_cmd;
tcmu_cmd = kmem_cache_zalloc(tcmu_cmd_cache, GFP_NOIO);
if (!tcmu_cmd)
INIT_LIST_HEAD(&tcmu_cmd->queue_entry);
tcmu_cmd->se_cmd = se_cmd;
tcmu_cmd->tcmu_dev = udev;
tcmu_cmd_set_block_cnts(tcmu_cmd);
tcmu_cmd->dbi = kcalloc(tcmu_cmd->dbi_cnt, sizeof(uint32_t),
if (!tcmu_cmd->dbi) {
kmem_cache_free(tcmu_cmd_cache, tcmu_cmd);
return tcmu_cmd;
struct tcmu_cmd *tcmu_cmd, uint32_t direction,
dbi = new_block_to_iov(udev, tcmu_cmd, iov, dbi,
dbi = tcmu_cmd_get_dbi(tcmu_cmd);
static void scatter_data_area(struct tcmu_dev *udev, struct tcmu_cmd *tcmu_cmd,
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
tcmu_copy_data(udev, tcmu_cmd, TCMU_SG_TO_DATA_AREA, se_cmd->t_data_sg,
static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *tcmu_cmd,
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
tcmu_cmd_set_dbi_cur(tcmu_cmd,
tcmu_cmd->dbi_cnt - tcmu_cmd->dbi_bidi_cnt);
tcmu_copy_data(udev, tcmu_cmd, TCMU_DATA_AREA_TO_SG, data_sg,
static int tcmu_alloc_data_space(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
static inline size_t tcmu_cmd_get_cmd_size(struct tcmu_cmd *tcmu_cmd,
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
static void tcmu_setup_cmd_timer(struct tcmu_cmd *tcmu_cmd, unsigned int tmo,
tcmu_cmd->deadline = round_jiffies_up(jiffies + msecs_to_jiffies(tmo));
mod_timer(timer, tcmu_cmd->deadline);
pr_debug("Timeout set up for cmd %p, dev = %s, tmo = %lu\n", tcmu_cmd,
tcmu_cmd->tcmu_dev->name, tmo / MSEC_PER_SEC);
static int add_to_qfull_queue(struct tcmu_cmd *tcmu_cmd)
struct tcmu_dev *udev = tcmu_cmd->tcmu_dev;
tcmu_setup_cmd_timer(tcmu_cmd, tmo, &udev->qfull_timer);
list_add_tail(&tcmu_cmd->queue_entry, &udev->qfull_queue);
tcmu_cmd, udev->name);