diff options
author | Damien Le Moal <damien.lemoal@opensource.wdc.com> | 2022-02-20 06:18:05 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2022-02-23 05:31:21 +0300 |
commit | 99df0edb5a9849ef8d63b972e3ccba463b0053de (patch) | |
tree | 3077126da13982b263926ebd9a6251a35dc39b31 /drivers/scsi/pm8001/pm8001_sas.c | |
parent | bf67e693fc40d7b2e32f79427f1284d98ba1c809 (diff) | |
download | linux-99df0edb5a9849ef8d63b972e3ccba463b0053de.tar.xz |
scsi: pm8001: Introduce ccb alloc/free helpers
Introduce the pm8001_ccb_alloc() and pm8001_ccb_free() helpers to replace
the typical code patterns:
res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
if (res)
...
ccb = &pm8001_ha->ccb_info[ccb_tag];
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
ccb->task = task;
ccb->n_elem = 0;
and
ccb->task = NULL;
ccb->ccb_tag = PM8001_INVALID_TAG;
pm8001_tag_free(pm8001_ha, tag);
With the simpler function calls:
ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
if (!ccb)
...
and
pm8001_ccb_free(pm8001_ha, ccb);
The pm8001_ccb_alloc() helper ensures that all fields of the ccb info
structure for the newly allocated tag are all initialized, except the
buf_prd field. The pm8001_ccb_free() helper clears the initialized fields
and the ccb tag to ensure that iteration over the adapter ccb_info array
detects ccbs that are in use.
All call site of the pm8001_tag_alloc() function that use a ccb info
associated with an allocated tag are converted to use the new helpers.
Link: https://lore.kernel.org/r/20220220031810.738362-27-damien.lemoal@opensource.wdc.com
Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_sas.c')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 55859d24edd3..6e5d1af12230 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -74,7 +74,7 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag) * @pm8001_ha: our hba struct * @tag_out: the found empty tag . */ -inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out) +int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out) { unsigned int tag; void *bitmap = pm8001_ha->tags; @@ -381,7 +381,7 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) struct pm8001_port *port = NULL; struct sas_task *t = task; struct pm8001_ccb_info *ccb; - u32 tag = 0xdeadbeef, rc = 0, n_elem = 0; + u32 rc = 0, n_elem = 0; unsigned long flags = 0; enum sas_protocol task_proto = t->task_proto; struct sas_tmf_task *tmf = task->tmf; @@ -427,10 +427,12 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) continue; } } - rc = pm8001_tag_alloc(pm8001_ha, &tag); - if (rc) + + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t); + if (!ccb) { + rc = -SAS_QUEUE_FULL; goto err_out; - ccb = &pm8001_ha->ccb_info[tag]; + } if (!sas_protocol_ata(task_proto)) { if (t->num_scatter) { @@ -440,7 +442,7 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) t->data_dir); if (!n_elem) { rc = -ENOMEM; - goto err_out_tag; + goto err_out_ccb; } } } else { @@ -449,9 +451,7 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) t->lldd_task = ccb; ccb->n_elem = n_elem; - ccb->ccb_tag = tag; - ccb->task = t; - ccb->device = pm8001_dev; + switch (task_proto) { case SAS_PROTOCOL_SMP: atomic_inc(&pm8001_dev->running_req); @@ -480,15 +480,15 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) if (rc) { pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc); atomic_dec(&pm8001_dev->running_req); - goto err_out_tag; + goto err_out_ccb; } /* TODO: select normal or high priority */ } while (0); rc = 0; goto out_done; -err_out_tag: - pm8001_tag_free(pm8001_ha, tag); +err_out_ccb: + pm8001_ccb_free(pm8001_ha, ccb); err_out: dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc); if (!sas_protocol_ata(task_proto)) @@ -548,10 +548,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha, } task->lldd_task = NULL; - ccb->task = NULL; - ccb->ccb_tag = PM8001_INVALID_TAG; - ccb->open_retry = 0; - pm8001_tag_free(pm8001_ha, ccb_idx); + pm8001_ccb_free(pm8001_ha, ccb); } /** @@ -707,7 +704,6 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, u32 task_tag) { int res, retry; - u32 ccb_tag; struct pm8001_ccb_info *ccb; struct sas_task *task = NULL; @@ -724,23 +720,19 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, jiffies + PM8001_TASK_TIMEOUT * HZ; add_timer(&task->slow_task->timer); - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); - if (res) + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task); + if (!ccb) { + res = -SAS_QUEUE_FULL; break; - - ccb = &pm8001_ha->ccb_info[ccb_tag]; - ccb->device = pm8001_dev; - ccb->ccb_tag = ccb_tag; - ccb->task = task; - ccb->n_elem = 0; + } res = PM8001_CHIP_DISP->task_abort(pm8001_ha, pm8001_dev, flag, - task_tag, ccb_tag); + task_tag, ccb->ccb_tag); if (res) { del_timer(&task->slow_task->timer); pm8001_dbg(pm8001_ha, FAIL, "Executing internal task failed\n"); - pm8001_tag_free(pm8001_ha, ccb_tag); + pm8001_ccb_free(pm8001_ha, ccb); break; } |