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:
parent
50b74c6ef1
commit
0722247439
@ -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;
|
||||
|
@ -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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user