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>
This commit is contained in:
Hans Petter Selasky 2014-07-26 19:08:52 +00:00
parent 50b74c6ef1
commit 0722247439
2 changed files with 23 additions and 23 deletions

View File

@ -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;
/* need to initialize the page cache */
pc->tag_parent = sc->sc_bus.dma_parent_tag;
if (usb_pc_alloc_mem(pc, pg,
sizeof(struct xhci_dev_endpoint_trbs), XHCI_PAGE_SIZE)) {
goto error;
}
/* initialise all endpoint LINK TRBs */
for (i = 0; i != XHCI_MAX_ENDPOINTS; i++) {
pc = &sc->sc_hw.devs[index].endpoint_pc[i];
pg = &sc->sc_hw.devs[index].endpoint_pg[i];
/* need to initialize the page cache */
pc->tag_parent = sc->sc_bus.dma_parent_tag;
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;

View File

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