summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001/pm8001_sas.c
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@opensource.wdc.com>2022-02-20 12:17:58 +0900
committerMartin K. Petersen <martin.petersen@oracle.com>2022-02-22 21:31:20 -0500
commit7fb23a785ba38dea907323a039123f231195b297 (patch)
treeafa6f63f72700d112f405b588bba3ddadc293fbf /drivers/scsi/pm8001/pm8001_sas.c
parent7e6b7e740addcea450041b5be8e42f0a4ceece0f (diff)
downloadlinux-7fb23a785ba38dea907323a039123f231195b297.tar.bz2
scsi: pm8001: Fix tag values handling
The function pm8001_tag_alloc() determines free tags using the function find_first_zero_bit() which can return 0 when the first bit of the bitmap being inspected is 0. As such, tag 0 is a valid tag value that should not be dismissed as invalid. Fix the functions pm8001_work_fn(), mpi_sata_completion(), pm8001_mpi_task_abort_resp() and pm8001_open_reject_retry() to not dismiss 0 tags as invalid. The value 0xffffffff is used for invalid tags for unused ccb information structures. Add the macro definition PM8001_INVALID_TAG to define this value. Link: https://lore.kernel.org/r/20220220031810.738362-20-damien.lemoal@opensource.wdc.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.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index f5678be4c17b..f409dfa049c0 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -553,7 +553,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
task->lldd_task = NULL;
ccb->task = NULL;
- ccb->ccb_tag = 0xFFFFFFFF;
+ ccb->ccb_tag = PM8001_INVALID_TAG;
ccb->open_retry = 0;
pm8001_tag_free(pm8001_ha, ccb_idx);
}
@@ -831,9 +831,11 @@ void pm8001_open_reject_retry(
struct task_status_struct *ts;
struct pm8001_device *pm8001_dev;
unsigned long flags1;
- u32 tag;
struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i];
+ if (ccb->ccb_tag == PM8001_INVALID_TAG)
+ continue;
+
pm8001_dev = ccb->device;
if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))
continue;
@@ -845,9 +847,6 @@ void pm8001_open_reject_retry(
continue;
} else if (pm8001_dev != device_to_close)
continue;
- tag = ccb->ccb_tag;
- if (!tag || (tag == 0xFFFFFFFF))
- continue;
task = ccb->task;
if (!task || !task->task_done)
continue;
@@ -867,11 +866,11 @@ void pm8001_open_reject_retry(
& SAS_TASK_STATE_ABORTED))) {
spin_unlock_irqrestore(&task->task_state_lock,
flags1);
- pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+ pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
} else {
spin_unlock_irqrestore(&task->task_state_lock,
flags1);
- pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+ pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb->ccb_tag);
mb();/* in order to force CPU ordering */
spin_unlock_irqrestore(&pm8001_ha->lock, flags);
task->task_done(task);