ANDROID: GKI: usb: Add support to handle USB SMMU S1 address

Update helper APIs to return physical address as well as
USB SMMU stage 1 address. Physical address is used to map
it to iova for remote processor. S1 address is used by xHC.
Get sg table containing one or mode page sized physical
address corresponding to S1 address for event ring, xfer
ring and xfer buffers using dma_get_sgtable(). Accordingly
update QMI response buffer for XHCI event ring, xfer ring
memory info and xfer buffer.

Change-Id: I6c9ea39d8a87a5bdc5a760d2a1ca85ab3024d985
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
(cherry picked from commit 3e3d0ab182)
Signed-off-by: Mark Salyzyn <salyzyn@google.com>
Bug: 154042109
This commit is contained in:
Hemant Kumar 2017-09-22 15:03:45 -07:00 committed by Mark Salyzyn
parent 52b86b23cc
commit 27ac6136bc
5 changed files with 70 additions and 40 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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,
};

View File

@ -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,

View File

@ -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);