aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2014-07-26 19:08:52 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2014-07-26 19:08:52 +0000
commit0722247439b4e2c9aa9342dc59b93a9bffb18c5a (patch)
tree1ecf7c30e35e3b328cc93e53401a9d5235f2f92d /sys
parent50b74c6ef15ce805efd193683c682b25107d78dc (diff)
downloadsrc-0722247439b4e2c9aa9342dc59b93a9bffb18c5a.tar.gz
src-0722247439b4e2c9aa9342dc59b93a9bffb18c5a.zip
Split the XHCI TRB allocations into smaller parts, so that we don't
end up allocating contiguous busdma buffers above PAGE_SIZE bytes. MFC after: 1 week Tested by: Ruslan Bukin <br@bsdpad.com>
Notes
Notes: svn path=/head/; revision=269139
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/controller/xhci.c36
-rw-r--r--sys/dev/usb/controller/xhci.h8
2 files changed, 22 insertions, 22 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index cdfa7d406288..5e9029c5abe9 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -2678,24 +2678,23 @@ xhci_alloc_device_ext(struct usb_device *udev)
goto error;
}
- pc = &sc->sc_hw.devs[index].endpoint_pc;
- pg = &sc->sc_hw.devs[index].endpoint_pg;
+ /* initialise all endpoint LINK TRBs */
- /* need to initialize the page cache */
- pc->tag_parent = sc->sc_bus.dma_parent_tag;
+ for (i = 0; i != XHCI_MAX_ENDPOINTS; i++) {
- if (usb_pc_alloc_mem(pc, pg,
- sizeof(struct xhci_dev_endpoint_trbs), XHCI_PAGE_SIZE)) {
- goto error;
- }
+ pc = &sc->sc_hw.devs[index].endpoint_pc[i];
+ pg = &sc->sc_hw.devs[index].endpoint_pg[i];
- /* initialise all endpoint LINK TRBs */
+ /* need to initialize the page cache */
+ pc->tag_parent = sc->sc_bus.dma_parent_tag;
- for (i = 0; i != XHCI_MAX_ENDPOINTS; i++) {
+ if (usb_pc_alloc_mem(pc, pg,
+ sizeof(struct xhci_dev_endpoint_trbs), XHCI_TRB_ALIGN)) {
+ goto error;
+ }
/* lookup endpoint TRB ring */
- usbd_get_page(pc, (uintptr_t)&
- ((struct xhci_dev_endpoint_trbs *)0)->trb[i][0], &buf_ep);
+ usbd_get_page(pc, 0, &buf_ep);
/* get TRB pointer */
trb = buf_ep.buffer;
@@ -2709,9 +2708,9 @@ xhci_alloc_device_ext(struct usb_device *udev)
trb->dwTrb2 = htole32(XHCI_TRB_2_IRQ_SET(0));
trb->dwTrb3 = htole32(XHCI_TRB_3_CYCLE_BIT |
XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK));
- }
- usb_pc_cpu_flush(pc);
+ usb_pc_cpu_flush(pc);
+ }
xhci_set_slot_pointer(sc, index, buf_dev.physaddr);
@@ -2728,13 +2727,15 @@ xhci_free_device_ext(struct usb_device *udev)
{
struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
uint8_t index;
+ uint8_t i;
index = udev->controller_slot_id;
xhci_set_slot_pointer(sc, index, 0);
usb_pc_free_mem(&sc->sc_hw.devs[index].device_pc);
usb_pc_free_mem(&sc->sc_hw.devs[index].input_pc);
- usb_pc_free_mem(&sc->sc_hw.devs[index].endpoint_pc);
+ for (i = 0; i != XHCI_MAX_ENDPOINTS; i++)
+ usb_pc_free_mem(&sc->sc_hw.devs[index].endpoint_pc[i]);
}
static struct xhci_endpoint_ext *
@@ -2755,10 +2756,9 @@ xhci_get_endpoint_ext(struct usb_device *udev, struct usb_endpoint_descriptor *e
index = udev->controller_slot_id;
- pc = &sc->sc_hw.devs[index].endpoint_pc;
+ pc = &sc->sc_hw.devs[index].endpoint_pc[epno];
- usbd_get_page(pc, (uintptr_t)&((struct xhci_dev_endpoint_trbs *)0)->
- trb[epno][0], &buf_ep);
+ usbd_get_page(pc, 0, &buf_ep);
pepext = &sc->sc_hw.devs[index].endp[epno];
pepext->page_cache = pc;
diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h
index b000e4f11dd6..408b429dff0a 100644
--- a/sys/dev/usb/controller/xhci.h
+++ b/sys/dev/usb/controller/xhci.h
@@ -316,8 +316,8 @@ struct xhci_trb {
} __aligned(4);
struct xhci_dev_endpoint_trbs {
- struct xhci_trb trb[XHCI_MAX_ENDPOINTS]
- [(XHCI_MAX_STREAMS * XHCI_MAX_TRANSFERS) + XHCI_MAX_STREAMS];
+ struct xhci_trb trb[(XHCI_MAX_STREAMS *
+ XHCI_MAX_TRANSFERS) + XHCI_MAX_STREAMS];
};
#define XHCI_TD_PAGE_NBUF 17 /* units, room enough for 64Kbytes */
@@ -385,11 +385,11 @@ enum {
struct xhci_hw_dev {
struct usb_page_cache device_pc;
struct usb_page_cache input_pc;
- struct usb_page_cache endpoint_pc;
+ struct usb_page_cache endpoint_pc[XHCI_MAX_ENDPOINTS];
struct usb_page device_pg;
struct usb_page input_pg;
- struct usb_page endpoint_pg;
+ struct usb_page endpoint_pg[XHCI_MAX_ENDPOINTS];
struct xhci_endpoint_ext endp[XHCI_MAX_ENDPOINTS];