scsi: pm8001: Use sas_task_find_rq() for tagging
authorJohn Garry <john.garry@huawei.com>
Tue, 18 Oct 2022 11:16:01 +0000 (19:16 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 22 Oct 2022 03:02:51 +0000 (03:02 +0000)
The request associated with a SCSI command coming from the block layer has
a unique tag, so use that when possible for getting a CCB.

Unfortunately we don't support reserved commands in the SCSI midlayer yet,
so in the interim continue to manage those tags internally (along with
tags for private commands).

Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1666091763-11023-6-git-send-email-john.garry@huawei.com
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.c
drivers/scsi/pm8001/pm8001_sas.h
drivers/scsi/pm8001/pm80xx_hwi.c

index 040a828..a1df612 100644 (file)
@@ -196,7 +196,7 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha)
        }
        PM8001_CHIP_DISP->chip_iounmap(pm8001_ha);
        flush_workqueue(pm8001_wq);
-       bitmap_free(pm8001_ha->tags);
+       bitmap_free(pm8001_ha->rsvd_tags);
        kfree(pm8001_ha);
 }
 
@@ -1208,18 +1208,15 @@ static int pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha)
        struct Scsi_Host *shost = pm8001_ha->shost;
        struct device *dev = pm8001_ha->dev;
        u32 max_out_io, ccb_count;
-       u32 can_queue;
        int i;
 
        max_out_io = pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io;
        ccb_count = min_t(int, PM8001_MAX_CCB, max_out_io);
 
-       /* Update to the scsi host*/
-       can_queue = ccb_count - PM8001_RESERVE_SLOT;
-       shost->can_queue = can_queue;
+       shost->can_queue = ccb_count - PM8001_RESERVE_SLOT;
 
-       pm8001_ha->tags = bitmap_zalloc(ccb_count, GFP_KERNEL);
-       if (!pm8001_ha->tags)
+       pm8001_ha->rsvd_tags = bitmap_zalloc(PM8001_RESERVE_SLOT, GFP_KERNEL);
+       if (!pm8001_ha->rsvd_tags)
                goto err_out;
 
        /* Memory region for ccb_info*/
@@ -1244,7 +1241,6 @@ static int pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha)
                pm8001_ha->ccb_info[i].task = NULL;
                pm8001_ha->ccb_info[i].ccb_tag = PM8001_INVALID_TAG;
                pm8001_ha->ccb_info[i].device = NULL;
-               ++pm8001_ha->tags_num;
        }
 
        return 0;
index c9fa332..2359e82 100644 (file)
@@ -65,9 +65,12 @@ static int pm8001_find_tag(struct sas_task *task, u32 *tag)
   */
 void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
 {
-       void *bitmap = pm8001_ha->tags;
+       void *bitmap = pm8001_ha->rsvd_tags;
        unsigned long flags;
 
+       if (tag >= PM8001_RESERVE_SLOT)
+               return;
+
        spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags);
        __clear_bit(tag, bitmap);
        spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
@@ -80,18 +83,20 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
   */
 int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
 {
-       void *bitmap = pm8001_ha->tags;
+       void *bitmap = pm8001_ha->rsvd_tags;
        unsigned long flags;
        unsigned int tag;
 
        spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags);
-       tag = find_first_zero_bit(bitmap, pm8001_ha->tags_num);
-       if (tag >= pm8001_ha->tags_num) {
+       tag = find_first_zero_bit(bitmap, PM8001_RESERVE_SLOT);
+       if (tag >= PM8001_RESERVE_SLOT) {
                spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
                return -SAS_QUEUE_FULL;
        }
        __set_bit(tag, bitmap);
        spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
+
+       /* reserved tags are in the lower region of the tagset */
        *tag_out = tag;
        return 0;
 }
index ecb98bc..cf5f1b0 100644 (file)
@@ -510,8 +510,7 @@ struct pm8001_hba_info {
        u32                     chip_id;
        const struct pm8001_chip_info   *chip;
        struct completion       *nvmd_completion;
-       int                     tags_num;
-       unsigned long           *tags;
+       unsigned long           *rsvd_tags;
        struct pm8001_phy       phy[PM8001_MAX_PHYS];
        struct pm8001_port      port[PM8001_MAX_PHYS];
        u32                     id;
@@ -736,9 +735,15 @@ pm8001_ccb_alloc(struct pm8001_hba_info *pm8001_ha,
                 struct pm8001_device *dev, struct sas_task *task)
 {
        struct pm8001_ccb_info *ccb;
+       struct request *rq = NULL;
        u32 tag;
 
-       if (pm8001_tag_alloc(pm8001_ha, &tag)) {
+       if (task)
+               rq = sas_task_find_rq(task);
+
+       if (rq) {
+               tag = rq->tag + PM8001_RESERVE_SLOT;
+       } else if (pm8001_tag_alloc(pm8001_ha, &tag)) {
                pm8001_dbg(pm8001_ha, FAIL, "Failed to allocate a tag\n");
                return NULL;
        }
index 4484c49..bc71db4 100644 (file)
@@ -4247,25 +4247,12 @@ static int check_enc_sat_cmd(struct sas_task *task)
 
 static u32 pm80xx_chip_get_q_index(struct sas_task *task)
 {
-       struct scsi_cmnd *scmd = NULL;
-       u32 blk_tag;
+       struct request *rq = sas_task_find_rq(task);
 
-       if (task->uldd_task) {
-               struct ata_queued_cmd *qc;
-
-               if (dev_is_sata(task->dev)) {
-                       qc = task->uldd_task;
-                       scmd = qc->scsicmd;
-               } else {
-                       scmd = task->uldd_task;
-               }
-       }
-
-       if (!scmd)
+       if (!rq)
                return 0;
 
-       blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));
-       return blk_mq_unique_tag_to_hwq(blk_tag);
+       return blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(rq));
 }
 
 /**