Skip to content

Commit

Permalink
usb: add a HCD_DMA flag instead of guestimating DMA capabilities
Browse files Browse the repository at this point in the history
The usb core is the only major place in the kernel that checks for
a non-NULL device dma_mask to see if a device is DMA capable.  This
is generally a bad idea, as all major busses always set up a DMA mask,
even if the device is not DMA capable - in fact bus layers like PCI
can't even know if a device is DMA capable at enumeration time.  This
leads to lots of workaround in HCD drivers, and also prevented us from
setting up a DMA mask for platform devices by default last time we
tried.

Replace this guess with an explicit HCD_DMA that is set by drivers that
appear to have DMA support.

Signed-off-by: Christoph Hellwig <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Christoph Hellwig authored and gregkh committed Aug 21, 2019
1 parent 0709831 commit 7b81cb6
Show file tree
Hide file tree
Showing 35 changed files with 31 additions and 62 deletions.
2 changes: 1 addition & 1 deletion drivers/staging/octeon-usb/octeon-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3512,7 +3512,7 @@ static const struct hc_driver octeon_hc_driver = {
.product_desc = "Octeon Host Controller",
.hcd_priv_size = sizeof(struct octeon_hcd),
.irq = octeon_usb_irq,
.flags = HCD_MEMORY | HCD_USB2,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
.start = octeon_usb_start,
.stop = octeon_usb_stop,
.urb_enqueue = octeon_usb_urb_enqueue,
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2454,7 +2454,6 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
hcd->self.controller = dev;
hcd->self.sysdev = sysdev;
hcd->self.bus_name = bus_name;
hcd->self.uses_dma = (sysdev->dma_mask != NULL);

timer_setup(&hcd->rh_timer, rh_timer_func, 0);
#ifdef CONFIG_PM
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/dwc2/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -5062,13 +5062,13 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
dwc2_hc_driver.reset_device = dwc2_reset_device;
}

if (hsotg->params.host_dma)
dwc2_hc_driver.flags |= HCD_DMA;

hcd = usb_create_hcd(&dwc2_hc_driver, hsotg->dev, dev_name(hsotg->dev));
if (!hcd)
goto error1;

if (!hsotg->params.host_dma)
hcd->self.uses_dma = 0;

hcd->has_tt = 1;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-grlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static const struct hc_driver ehci_grlib_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ static const struct hc_driver ehci_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-pmcmsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static const struct hc_driver ehci_msp_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-ppc-of.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-ps3.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.product_desc = "PS3 EHCI Host Controller",
.hcd_priv_size = sizeof(struct ehci_hcd),
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,
.reset = ps3_ehci_hc_reset,
.start = ehci_run,
.stop = ehci_stop,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-sh.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static const struct hc_driver ehci_sh_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_USB2 | HCD_MEMORY | HCD_BH,
.flags = HCD_USB2 | HCD_DMA | HCD_MEMORY | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-xilinx-of.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
.flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2 | HCD_BH,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/fhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ static const struct hc_driver fhci_driver = {

/* generic hardware linkage */
.irq = fhci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.flags = HCD_DMA | HCD_USB11 | HCD_MEMORY,

/* basic lifecycle operation */
.start = fhci_start,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/fotg210-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -5508,7 +5508,7 @@ static const struct hc_driver fotg210_fotg210_hc_driver = {
* generic hardware linkage
*/
.irq = fotg210_irq,
.flags = HCD_MEMORY | HCD_USB2,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB2,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/imx21-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1771,7 +1771,7 @@ static const struct hc_driver imx21_hc_driver = {
.product_desc = "IMX21 USB Host Controller",
.hcd_priv_size = sizeof(struct imx21),

.flags = HCD_USB11,
.flags = HCD_DMA | HCD_USB11,
.irq = imx21_irq,

.reset = imx21_hc_reset,
Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/host/isp116x-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,12 +1581,6 @@ static int isp116x_probe(struct platform_device *pdev)
irq = ires->start;
irqflags = ires->flags & IRQF_TRIGGER_MASK;

if (pdev->dev.dma_mask) {
DBG("DMA not supported\n");
ret = -EINVAL;
goto err1;
}

if (!request_mem_region(addr->start, 2, hcd_name)) {
ret = -EBUSY;
goto err1;
Expand Down
5 changes: 0 additions & 5 deletions drivers/usb/host/isp1362-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2645,11 +2645,6 @@ static int isp1362_probe(struct platform_device *pdev)
if (pdev->num_resources < 3)
return -ENODEV;

if (pdev->dev.dma_mask) {
DBG(1, "won't do DMA");
return -ENODEV;
}

irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res)
return -ENODEV;
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,7 +1178,7 @@ static const struct hc_driver ohci_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB11,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-ppc-of.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-ps3.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
.product_desc = "PS3 OHCI Host Controller",
.hcd_priv_size = sizeof(struct ohci_hcd),
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB11,
.reset = ps3_ohci_hc_reset,
.start = ps3_ohci_hc_start,
.stop = ohci_stop,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-sa1111.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-sm501.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static const struct hc_driver ohci_sm501_hc_driver = {
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,

/*
* basic lifecycle operations
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ohci-tmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static const struct hc_driver ohci_tmio_hc_driver = {

/* generic hardware linkage */
.irq = ohci_irq,
.flags = HCD_USB11 | HCD_MEMORY,
.flags = HCD_USB11 | HCD_DMA | HCD_MEMORY,

/* basic lifecycle operations */
.start = ohci_tmio_start,
Expand Down
3 changes: 0 additions & 3 deletions drivers/usb/host/oxu210hp-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3088,9 +3088,6 @@ static int oxu_reset(struct usb_hcd *hcd)
INIT_LIST_HEAD(&oxu->urb_list);
oxu->urb_len = 0;

/* FIMXE */
hcd->self.controller->dma_mask = NULL;

if (oxu->is_otg) {
oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET;
oxu->regs = hcd->regs + OXU_OTG_CAP_OFFSET + \
Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/host/r8a66597-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2411,12 +2411,6 @@ static int r8a66597_probe(struct platform_device *pdev)
if (usb_disabled())
return -ENODEV;

if (pdev->dev.dma_mask) {
ret = -EINVAL;
dev_err(&pdev->dev, "dma not supported\n");
goto clean_up;
}

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
ret = -ENODEV;
Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/host/sl811-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,12 +1632,6 @@ sl811h_probe(struct platform_device *dev)
irq = ires->start;
irqflags = ires->flags & IRQF_TRIGGER_MASK;

/* refuse to confuse usbcore */
if (dev->dev.dma_mask) {
dev_dbg(&dev->dev, "no we won't dma\n");
return -EINVAL;
}

/* the chip may be wired for either kind of addressing */
addr = platform_get_resource(dev, IORESOURCE_MEM, 0);
data = platform_get_resource(dev, IORESOURCE_MEM, 1);
Expand Down
2 changes: 0 additions & 2 deletions drivers/usb/host/u132-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3077,8 +3077,6 @@ static int u132_probe(struct platform_device *pdev)
retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
if (retval)
return retval;
if (pdev->dev.dma_mask)
return -EINVAL;

hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/uhci-grlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static const struct hc_driver uhci_grlib_hc_driver = {

/* Generic hardware linkage */
.irq = uhci_irq,
.flags = HCD_MEMORY | HCD_USB11,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB11,

/* Basic lifecycle operations */
.reset = uhci_grlib_init,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/uhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ static const struct hc_driver uhci_driver = {

/* Generic hardware linkage */
.irq = uhci_irq,
.flags = HCD_USB11,
.flags = HCD_DMA | HCD_USB11,

/* Basic lifecycle operations */
.reset = uhci_pci_init,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/uhci-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static const struct hc_driver uhci_platform_hc_driver = {

/* Generic hardware linkage */
.irq = uhci_irq,
.flags = HCD_MEMORY | HCD_USB11,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB11,

/* Basic lifecycle operations */
.reset = uhci_platform_init,
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -5217,7 +5217,7 @@ static const struct hc_driver xhci_hc_driver = {
* generic hardware linkage
*/
.irq = xhci_irq,
.flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED,
.flags = HCD_MEMORY | HCD_DMA | HCD_USB3 | HCD_SHARED,

/*
* basic lifecycle operations
Expand Down
3 changes: 0 additions & 3 deletions drivers/usb/isp1760/isp1760-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
(!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled))
return -ENODEV;

/* prevent usb-core allocating DMA pages */
dev->dma_mask = NULL;

isp = devm_kzalloc(dev, sizeof(*isp), GFP_KERNEL);
if (!isp)
return -ENOMEM;
Expand Down
1 change: 0 additions & 1 deletion drivers/usb/isp1760/isp1760-if.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ static int isp1761_pci_probe(struct pci_dev *dev,

pci_set_master(dev);

dev->dev.dma_mask = NULL;
ret = isp1760_register(&dev->resource[3], dev->irq, 0, &dev->dev,
devflags);
if (ret < 0)
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/musb/musb_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -2689,7 +2689,7 @@ static const struct hc_driver musb_hc_driver = {
.description = "musb-hcd",
.product_desc = "MUSB HDRC host driver",
.hcd_priv_size = sizeof(struct musb *),
.flags = HCD_USB2 | HCD_MEMORY,
.flags = HCD_USB2 | HCD_DMA | HCD_MEMORY,

/* not using irq handler or reset hooks from usbcore, since
* those must be shared with peripheral code for OTG configs
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/renesas_usbhs/mod_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ static const struct hc_driver usbhsh_driver = {
/*
* generic hardware linkage
*/
.flags = HCD_USB2,
.flags = HCD_DMA | HCD_USB2,

.start = usbhsh_host_start,
.stop = usbhsh_host_stop,
Expand Down
1 change: 0 additions & 1 deletion include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ struct usb_bus {
struct device *sysdev; /* as seen from firmware or bus */
int busnum; /* Bus number (in order of reg) */
const char *bus_name; /* stable id (PCI slot_name etc) */
u8 uses_dma; /* Does the host controller use DMA? */
u8 uses_pio_for_control; /*
* Does the host controller use PIO
* for control transfers?
Expand Down
7 changes: 5 additions & 2 deletions include/linux/usb/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ struct hc_driver {

int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_DMA 0x0002 /* HC uses DMA */
#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
Expand Down Expand Up @@ -422,8 +423,10 @@ static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd,
return hcd->high_prio_bh.completing_ep == ep;
}

#define hcd_uses_dma(hcd) \
(IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
static inline bool hcd_uses_dma(struct usb_hcd *hcd)
{
return IS_ENABLED(CONFIG_HAS_DMA) && (hcd->driver->flags & HCD_DMA);
}

extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
Expand Down

0 comments on commit 7b81cb6

Please sign in to comment.