diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index e9b61087b72b..3eaa3be43d24 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -158,6 +158,7 @@ struct afu_cmd { u32 hwq_index; u8 cmd_tmf:1; + struct list_head list; /* Pending commands link */ /* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned. * However for performance reasons the IOARCB/IOASA should be @@ -193,6 +194,7 @@ struct hwq { struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ ctx_hndl_t ctx_hndl; /* master's context handle */ u32 index; /* Index of this hwq */ + struct list_head pending_cmds; /* Commands pending completion */ atomic_t hsq_credits; spinlock_t hsq_slock; /* Hardware send queue lock */ diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 20c2c5e111b4..1446fabe4cf6 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -162,8 +162,13 @@ static void cmd_complete(struct afu_cmd *cmd) struct afu *afu = cmd->parent; struct cxlflash_cfg *cfg = afu->parent; struct device *dev = &cfg->dev->dev; + struct hwq *hwq = get_hwq(afu, cmd->hwq_index); bool cmd_is_tmf; + spin_lock_irqsave(&hwq->hsq_slock, lock_flags); + list_del(&cmd->list); + spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); + if (cmd->scp) { scp = cmd->scp; if (unlikely(cmd->sa.ioasc)) @@ -279,6 +284,7 @@ static int send_cmd_ioarrin(struct afu *afu, struct afu_cmd *cmd) hwq->room = room - 1; } + list_add(&cmd->list, &hwq->pending_cmds); writeq_be((u64)&cmd->rcb, &hwq->host_map->ioarrin); out: spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); @@ -319,6 +325,8 @@ static int send_cmd_sq(struct afu *afu, struct afu_cmd *cmd) hwq->hsq_curr++; else hwq->hsq_curr = hwq->hsq_start; + + list_add(&cmd->list, &hwq->pending_cmds); writeq_be((u64)hwq->hsq_curr, &hwq->host_map->sq_tail); spin_unlock_irqrestore(&hwq->hsq_slock, lock_flags); @@ -1840,6 +1848,7 @@ static int init_mc(struct cxlflash_cfg *cfg, u32 index) hwq->afu = cfg->afu; hwq->index = index; + INIT_LIST_HEAD(&hwq->pending_cmds); if (index == PRIMARY_HWQ) ctx = cxl_get_context(cfg->dev);