Author: hselasky
Date: Sat Jul 26 19:08:52 2014
New Revision: 269139
URL: http://svnweb.freebsd.org/changeset/base/269139

Log:
  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 <[email protected]>

Modified:
  head/sys/dev/usb/controller/xhci.c
  head/sys/dev/usb/controller/xhci.h

Modified: head/sys/dev/usb/controller/xhci.c
==============================================================================
--- head/sys/dev/usb/controller/xhci.c  Sat Jul 26 19:07:08 2014        
(r269138)
+++ head/sys/dev/usb/controller/xhci.c  Sat Jul 26 19:08:52 2014        
(r269139)
@@ -2678,24 +2678,23 @@ xhci_alloc_device_ext(struct usb_device 
                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 
                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 *
 {
        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 
 
        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;

Modified: head/sys/dev/usb/controller/xhci.h
==============================================================================
--- head/sys/dev/usb/controller/xhci.h  Sat Jul 26 19:07:08 2014        
(r269138)
+++ head/sys/dev/usb/controller/xhci.h  Sat Jul 26 19:08:52 2014        
(r269139)
@@ -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];
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to