diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8e7a846ae688..ebc4a84a2221 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2257,28 +2257,28 @@ int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev, /*-------------------------------------------------------------------------*/ -dma_addr_t -usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev, - unsigned int intr_num) +phys_addr_t +usb_hcd_get_sec_event_ring_phys_addr(struct usb_device *udev, + unsigned int intr_num, dma_addr_t *dma) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); if (!HCD_RH_RUNNING(hcd)) return 0; - return hcd->driver->get_sec_event_ring_dma_addr(hcd, intr_num); + return hcd->driver->get_sec_event_ring_phys_addr(hcd, intr_num, dma); } -dma_addr_t -usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev, - unsigned int intr_num) +phys_addr_t +usb_hcd_get_xfer_ring_phys_addr(struct usb_device *udev, + struct usb_host_endpoint *ep, dma_addr_t *dma) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); if (!HCD_RH_RUNNING(hcd)) return 0; - return hcd->driver->get_xfer_ring_dma_addr(hcd, udev, ep); + return hcd->driver->get_xfer_ring_phys_addr(hcd, udev, ep, dma); } int usb_hcd_get_controller_id(struct usb_device *udev) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 7822b8b44ffd..35f632165c8f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -842,26 +842,26 @@ int usb_sec_event_ring_cleanup(struct usb_device *dev, } EXPORT_SYMBOL(usb_sec_event_ring_cleanup); -dma_addr_t -usb_get_sec_event_ring_dma_addr(struct usb_device *dev, - unsigned int intr_num) +phys_addr_t +usb_get_sec_event_ring_phys_addr(struct usb_device *dev, + unsigned int intr_num, dma_addr_t *dma) { if (dev->state == USB_STATE_NOTATTACHED) return 0; - return usb_hcd_get_sec_event_ring_dma_addr(dev, intr_num); + return usb_hcd_get_sec_event_ring_phys_addr(dev, intr_num, dma); } -EXPORT_SYMBOL_GPL(usb_get_sec_event_ring_dma_addr); +EXPORT_SYMBOL_GPL(usb_get_sec_event_ring_phys_addr); -dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev, - struct usb_host_endpoint *ep) +phys_addr_t usb_get_xfer_ring_phys_addr(struct usb_device *dev, + struct usb_host_endpoint *ep, dma_addr_t *dma) { if (dev->state == USB_STATE_NOTATTACHED) return 0; - return usb_hcd_get_xfer_ring_dma_addr(dev, ep); + return usb_hcd_get_xfer_ring_phys_addr(dev, ep, dma); } -EXPORT_SYMBOL_GPL(usb_get_xfer_ring_dma_addr); +EXPORT_SYMBOL_GPL(usb_get_xfer_ring_phys_addr); /** * usb_get_controller_id - returns the host controller id. diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f8ea67ac9c84..5929e2b566b4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5183,10 +5183,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) } EXPORT_SYMBOL_GPL(xhci_gen_setup); -dma_addr_t xhci_get_sec_event_ring_dma_addr(struct usb_hcd *hcd, - unsigned int intr_num) +static phys_addr_t xhci_get_sec_event_ring_phys_addr(struct usb_hcd *hcd, + unsigned int intr_num, dma_addr_t *dma) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct device *dev = hcd->self.sysdev; + struct sg_table sgt; + phys_addr_t pa; if (intr_num > xhci->max_interrupters) { xhci_err(xhci, "intr num %d > max intrs %d\n", intr_num, @@ -5196,20 +5199,34 @@ dma_addr_t xhci_get_sec_event_ring_dma_addr(struct usb_hcd *hcd, if (!(xhci->xhc_state & XHCI_STATE_HALTED) && xhci->sec_event_ring && xhci->sec_event_ring[intr_num] - && xhci->sec_event_ring[intr_num]->first_seg) - return xhci->sec_event_ring[intr_num]->first_seg->dma; + && xhci->sec_event_ring[intr_num]->first_seg) { + + dma_get_sgtable(dev, &sgt, + xhci->sec_event_ring[intr_num]->first_seg->trbs, + xhci->sec_event_ring[intr_num]->first_seg->dma, + TRB_SEGMENT_SIZE); + + *dma = xhci->sec_event_ring[intr_num]->first_seg->dma; + + pa = page_to_phys(sg_page(sgt.sgl)); + sg_free_table(&sgt); + + return pa; + } return 0; } -dma_addr_t xhci_get_xfer_ring_dma_addr(struct usb_hcd *hcd, - struct usb_device *udev, struct usb_host_endpoint *ep) +static phys_addr_t xhci_get_xfer_ring_phys_addr(struct usb_hcd *hcd, + struct usb_device *udev, struct usb_host_endpoint *ep, dma_addr_t *dma) { int ret; unsigned int ep_index; struct xhci_virt_device *virt_dev; - + struct device *dev = hcd->self.sysdev; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct sg_table sgt; + phys_addr_t pa; ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); if (ret <= 0) { @@ -5221,8 +5238,20 @@ dma_addr_t xhci_get_xfer_ring_dma_addr(struct usb_hcd *hcd, ep_index = xhci_get_endpoint_index(&ep->desc); if (virt_dev->eps[ep_index].ring && - virt_dev->eps[ep_index].ring->first_seg) - return virt_dev->eps[ep_index].ring->first_seg->dma; + virt_dev->eps[ep_index].ring->first_seg) { + + dma_get_sgtable(dev, &sgt, + virt_dev->eps[ep_index].ring->first_seg->trbs, + virt_dev->eps[ep_index].ring->first_seg->dma, + TRB_SEGMENT_SIZE); + + *dma = virt_dev->eps[ep_index].ring->first_seg->dma; + + pa = page_to_phys(sg_page(sgt.sgl)); + sg_free_table(&sgt); + + return pa; + } return 0; } @@ -5346,8 +5375,8 @@ static const struct hc_driver xhci_hc_driver = { .find_raw_port_number = xhci_find_raw_port_number, .sec_event_ring_setup = xhci_sec_event_ring_setup, .sec_event_ring_cleanup = xhci_sec_event_ring_cleanup, - .get_sec_event_ring_dma_addr = xhci_get_sec_event_ring_dma_addr, - .get_xfer_ring_dma_addr = xhci_get_xfer_ring_dma_addr, + .get_sec_event_ring_phys_addr = xhci_get_sec_event_ring_phys_addr, + .get_xfer_ring_phys_addr = xhci_get_xfer_ring_phys_addr, .stop_endpoint = xhci_stop_endpoint, }; diff --git a/include/linux/usb.h b/include/linux/usb.h index 25a8cb676ba2..7e634dc59d6d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -838,10 +838,10 @@ extern int usb_sec_event_ring_setup(struct usb_device *dev, extern int usb_sec_event_ring_cleanup(struct usb_device *dev, unsigned int intr_num); -extern dma_addr_t usb_get_sec_event_ring_dma_addr(struct usb_device *dev, - unsigned int intr_num); -extern dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev, - struct usb_host_endpoint *ep); +extern phys_addr_t usb_get_sec_event_ring_phys_addr( + struct usb_device *dev, unsigned int intr_num, dma_addr_t *dma); +extern phys_addr_t usb_get_xfer_ring_phys_addr(struct usb_device *dev, + struct usb_host_endpoint *ep, dma_addr_t *dma); extern int usb_get_controller_id(struct usb_device *dev); extern int usb_stop_endpoint(struct usb_device *dev, diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 59584fe85c1c..059817cee1d1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -410,10 +410,11 @@ struct hc_driver { int (*sec_event_ring_setup)(struct usb_hcd *hcd, unsigned int intr_num); int (*sec_event_ring_cleanup)(struct usb_hcd *hcd, unsigned int intr_num); - dma_addr_t (*get_sec_event_ring_dma_addr)(struct usb_hcd *hcd, - unsigned int intr_num); - dma_addr_t (*get_xfer_ring_dma_addr)(struct usb_hcd *hcd, - struct usb_device *udev, struct usb_host_endpoint *ep); + phys_addr_t (*get_sec_event_ring_phys_addr)(struct usb_hcd *hcd, + unsigned int intr_num, dma_addr_t *dma); + phys_addr_t (*get_xfer_ring_phys_addr)(struct usb_hcd *hcd, + struct usb_device *udev, struct usb_host_endpoint *ep, + dma_addr_t *dma); int (*get_core_id)(struct usb_hcd *hcd); int (*stop_endpoint)(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); @@ -459,10 +460,10 @@ extern int usb_hcd_sec_event_ring_setup(struct usb_device *udev, unsigned int intr_num); extern int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev, unsigned int intr_num); -extern dma_addr_t usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev, - unsigned int intr_num); -extern dma_addr_t usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev, - struct usb_host_endpoint *ep); +extern phys_addr_t usb_hcd_get_sec_event_ring_phys_addr( + struct usb_device *udev, unsigned int intr_num, dma_addr_t *dma); +extern phys_addr_t usb_hcd_get_xfer_ring_phys_addr( + struct usb_device *udev, struct usb_host_endpoint *ep, dma_addr_t *dma); extern int usb_hcd_get_controller_id(struct usb_device *udev); extern int usb_hcd_stop_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep);