scsi: usb-storage: Switch to using ->device_configure
authorChristoph Hellwig <hch@lst.de>
Tue, 9 Apr 2024 14:37:42 +0000 (16:37 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 12 Apr 2024 01:37:49 +0000 (21:37 -0400)
Switch to the ->device_configure method instead of ->slave_configure and
update the block limits on the passed in queue_limits instead of using the
per-limit accessors.

Also use the proper atomic queue limit update helpers and freeze the queue
when updating max_hw_sectors from sysfs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20240409143748.980206-18-hch@lst.de
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/usb/storage/scsiglue.c

index eb4ba03e082d8930181c5a4b1dce1c058f901e73..b31464740f6c869b6a762f05958d3710cecebfe5 100644 (file)
@@ -82,7 +82,7 @@ static int slave_alloc (struct scsi_device *sdev)
        return 0;
 }
 
-static int slave_configure(struct scsi_device *sdev)
+static int device_configure(struct scsi_device *sdev, struct queue_limits *lim)
 {
        struct us_data *us = host_to_us(sdev->host);
        struct device *dev = us->pusb_dev->bus->sysdev;
@@ -97,31 +97,28 @@ static int slave_configure(struct scsi_device *sdev)
 
                if (us->fflags & US_FL_MAX_SECTORS_MIN)
                        max_sectors = PAGE_SIZE >> 9;
-               if (queue_max_hw_sectors(sdev->request_queue) > max_sectors)
-                       blk_queue_max_hw_sectors(sdev->request_queue,
-                                             max_sectors);
+               lim->max_hw_sectors = min(lim->max_hw_sectors, max_sectors);
        } else if (sdev->type == TYPE_TAPE) {
                /*
                 * Tapes need much higher max_sector limits, so just
                 * raise it to the maximum possible (4 GB / 512) and
                 * let the queue segment size sort out the real limit.
                 */
-               blk_queue_max_hw_sectors(sdev->request_queue, 0x7FFFFF);
+               lim->max_hw_sectors = 0x7FFFFF;
        } else if (us->pusb_dev->speed >= USB_SPEED_SUPER) {
                /*
                 * USB3 devices will be limited to 2048 sectors. This gives us
                 * better throughput on most devices.
                 */
-               blk_queue_max_hw_sectors(sdev->request_queue, 2048);
+               lim->max_hw_sectors = 2048;
        }
 
        /*
         * The max_hw_sectors should be up to maximum size of a mapping for
         * the device. Otherwise, a DMA API might fail on swiotlb environment.
         */
-       blk_queue_max_hw_sectors(sdev->request_queue,
-               min_t(size_t, queue_max_hw_sectors(sdev->request_queue),
-                     dma_max_mapping_size(dev) >> SECTOR_SHIFT));
+       lim->max_hw_sectors = min_t(size_t,
+               lim->max_hw_sectors, dma_max_mapping_size(dev) >> SECTOR_SHIFT);
 
        /*
         * We can't put these settings in slave_alloc() because that gets
@@ -582,13 +579,22 @@ static ssize_t max_sectors_store(struct device *dev, struct device_attribute *at
                size_t count)
 {
        struct scsi_device *sdev = to_scsi_device(dev);
+       struct queue_limits lim;
        unsigned short ms;
+       int ret;
 
-       if (sscanf(buf, "%hu", &ms) > 0) {
-               blk_queue_max_hw_sectors(sdev->request_queue, ms);
-               return count;
-       }
-       return -EINVAL;
+       if (sscanf(buf, "%hu", &ms) <= 0)
+               return -EINVAL;
+
+       blk_mq_freeze_queue(sdev->request_queue);
+       lim = queue_limits_start_update(sdev->request_queue);
+       lim.max_hw_sectors = ms;
+       ret = queue_limits_commit_update(sdev->request_queue, &lim);
+       blk_mq_unfreeze_queue(sdev->request_queue);
+
+       if (ret)
+               return ret;
+       return count;
 }
 static DEVICE_ATTR_RW(max_sectors);
 
@@ -626,7 +632,7 @@ static const struct scsi_host_template usb_stor_host_template = {
        .this_id =                      -1,
 
        .slave_alloc =                  slave_alloc,
-       .slave_configure =              slave_configure,
+       .device_configure =             device_configure,
        .target_alloc =                 target_alloc,
 
        /* lots of sg segments can be handled */