While we really should be killing the block layer bounce buffering ASAP, I even more urgently need to stop the drivers to fiddle with the limits from ->slave_configure. Add a no_highmem flag to the Scsi_Host to centralize this setting and switch the remaining four drivers that use block layer bounce buffering to it. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- drivers/scsi/aha152x.c | 8 +------- drivers/scsi/imm.c | 12 +----------- drivers/scsi/ppa.c | 8 +------- drivers/scsi/scsi_lib.c | 3 +++ drivers/usb/storage/scsiglue.c | 10 ---------- drivers/usb/storage/usb.c | 10 ++++++++++ include/scsi/scsi_host.h | 2 ++ 7 files changed, 18 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 055adb349b0e41..83f16fc14d9630 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -746,6 +746,7 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) /* need to have host registered before triggering any interrupt */ list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list); + shpnt->no_highmem = true; shpnt->io_port = setup->io_port; shpnt->n_io_port = IO_RANGE; shpnt->irq = setup->irq; @@ -2940,12 +2941,6 @@ static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt) return 0; } -static int aha152x_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, @@ -2961,7 +2956,6 @@ static const struct scsi_host_template aha152x_driver_template = { .this_id = 7, .sg_tablesize = SG_ALL, .dma_boundary = PAGE_SIZE - 1, - .slave_alloc = aha152x_adjust_queue, .cmd_size = sizeof(struct aha152x_cmd_priv), }; diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 180a5ddedb2cda..21339da505f1ea 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1100,16 +1100,6 @@ static int device_check(imm_struct *dev, bool autodetect) return -ENODEV; } -/* - * imm cannot deal with highmem, so this causes all IO pages for this host - * to reside in low memory (hence mapped) - */ -static int imm_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template imm_template = { .module = THIS_MODULE, .proc_name = "imm", @@ -1123,7 +1113,6 @@ static const struct scsi_host_template imm_template = { .this_id = 7, .sg_tablesize = SG_ALL, .can_queue = 1, - .slave_alloc = imm_adjust_queue, .cmd_size = sizeof(struct scsi_pointer), }; @@ -1235,6 +1224,7 @@ static int __imm_attach(struct parport *pb) host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); if (!host) goto out1; + host->no_highmem = true; host->io_port = pb->base; host->n_io_port = ports; host->dma_channel = -1; diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index d592ee9170c11f..8300f0bdddb37a 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -986,12 +986,6 @@ static int device_check(ppa_struct *dev, bool autodetect) return -ENODEV; } -static int ppa_adjust_queue(struct scsi_device *device) -{ - blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); - return 0; -} - static const struct scsi_host_template ppa_template = { .module = THIS_MODULE, .proc_name = "ppa", @@ -1005,7 +999,6 @@ static const struct scsi_host_template ppa_template = { .this_id = -1, .sg_tablesize = SG_ALL, .can_queue = 1, - .slave_alloc = ppa_adjust_queue, .cmd_size = sizeof(struct scsi_pointer), }; @@ -1111,6 +1104,7 @@ static int __ppa_attach(struct parport *pb) host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *)); if (!host) goto out1; + host->no_highmem = true; host->io_port = pb->base; host->n_io_port = ports; host->dma_channel = -1; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1deca84914e87a..f1936f98abe3e2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1995,6 +1995,9 @@ void scsi_init_limits(struct Scsi_Host *shost, struct queue_limits *lim) */ lim->dma_alignment = max(4, dma_get_cache_alignment()) - 1; + if (shost->no_highmem) + lim->bounce = BLK_BOUNCE_HIGH; + dma_set_seg_boundary(dev, shost->dma_boundary); dma_set_max_seg_size(dev, shost->max_segment_size); } diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 12cf9940e5b675..1d14c678f3d3e3 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -40,7 +40,6 @@ #include <scsi/scsi_eh.h> #include "usb.h" -#include <linux/usb/hcd.h> #include "scsiglue.h" #include "debug.h" #include "transport.h" @@ -130,15 +129,6 @@ static int slave_configure(struct scsi_device *sdev) min_t(size_t, queue_max_hw_sectors(sdev->request_queue), dma_max_mapping_size(dev) >> SECTOR_SHIFT)); - /* - * Some USB host controllers can't do DMA; they have to use PIO. - * For such controllers we need to make sure the block layer sets - * up bounce buffers in addressable memory. - */ - if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) || - (bus_to_hcd(us->pusb_dev->bus)->localmem_pool != NULL)) - blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH); - /* * We can't put these settings in slave_alloc() because that gets * called before the device type is known. Consequently these diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index d1ad6a2509ab7f..a49a31639f6f0c 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -47,6 +47,7 @@ #include <scsi/scsi_device.h> #include "usb.h" +#include <linux/usb/hcd.h> #include "scsiglue.h" #include "transport.h" #include "protocol.h" @@ -961,6 +962,15 @@ int usb_stor_probe1(struct us_data **pus, if (result) goto BadDevice; + /* + * Some USB host controllers can't do DMA; they have to use PIO. + * For such controllers we need to make sure the block layer sets + * up bounce buffers in addressable memory. + */ + if (!hcd_uses_dma(bus_to_hcd(us->pusb_dev->bus)) || + bus_to_hcd(us->pusb_dev->bus)->localmem_pool) + host->no_highmem = true; + /* Get the unusual_devs entries and the descriptors */ result = get_device_info(us, id, unusual_dev); if (result) diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index b259d42a1e1aff..6d77c48e8311fb 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -665,6 +665,8 @@ struct Scsi_Host { /* The transport requires the LUN bits NOT to be stored in CDB[1] */ unsigned no_scsi2_lun_in_cdb:1; + unsigned no_highmem:1; + /* * Optional work queue to be utilized by the transport */ -- 2.39.2