mirror of https://gitee.com/openkylin/linux.git
usb: add a HCD_DMA flag instead of guestimating DMA capabilities
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 <hch@lst.de> Link: https://lore.kernel.org/r/20190816062435.881-4-hch@lst.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0709831a50
commit
7b81cb6bdd
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 + \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue