Author: hselasky
Date: Sat Aug 29 06:23:40 2015
New Revision: 287274
URL: https://svnweb.freebsd.org/changeset/base/287274

Log:
  MFC r286773:
  Improve the realtime properties of USB transfers for embedded systems
  like RPI-B and RPI-2.

Modified:
  stable/10/sys/boot/usb/bsd_kernel.h
  stable/10/sys/dev/usb/controller/usb_controller.c
  stable/10/sys/dev/usb/usb_bus.h
  stable/10/sys/dev/usb/usb_device.c
  stable/10/sys/dev/usb/usb_hub.c
  stable/10/sys/dev/usb/usb_process.h
  stable/10/sys/dev/usb/usb_transfer.c
  stable/10/sys/dev/usb/usbdi.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/usb/bsd_kernel.h
==============================================================================
--- stable/10/sys/boot/usb/bsd_kernel.h Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/boot/usb/bsd_kernel.h Sat Aug 29 06:23:40 2015        
(r287274)
@@ -42,7 +42,8 @@
 #define        M_USBDEV 0
 #define        USB_PROC_MAX 3
 #define        USB_BUS_GIANT_PROC(bus) (usb_process + 2)
-#define        USB_BUS_NON_GIANT_PROC(bus) (usb_process + 2)
+#define        USB_BUS_NON_GIANT_BULK_PROC(bus) (usb_process + 2)
+#define        USB_BUS_NON_GIANT_ISOC_PROC(bus) (usb_process + 2)
 #define        USB_BUS_EXPLORE_PROC(bus) (usb_process + 0)
 #define        USB_BUS_CONTROL_XFER_PROC(bus) (usb_process + 1)
 #define        SYSCTL_DECL(...)

Modified: stable/10/sys/dev/usb/controller/usb_controller.c
==============================================================================
--- stable/10/sys/dev/usb/controller/usb_controller.c   Sat Aug 29 06:17:39 
2015        (r287273)
+++ stable/10/sys/dev/usb/controller/usb_controller.c   Sat Aug 29 06:23:40 
2015        (r287274)
@@ -233,7 +233,8 @@ usb_detach(device_t dev)
        /* Get rid of USB callback processes */
 
        usb_proc_free(USB_BUS_GIANT_PROC(bus));
-       usb_proc_free(USB_BUS_NON_GIANT_PROC(bus));
+       usb_proc_free(USB_BUS_NON_GIANT_ISOC_PROC(bus));
+       usb_proc_free(USB_BUS_NON_GIANT_BULK_PROC(bus));
 
        /* Get rid of USB explore process */
 
@@ -397,7 +398,8 @@ usb_bus_explore(struct usb_proc_msg *pm)
                 */
                usb_proc_rewakeup(USB_BUS_CONTROL_XFER_PROC(bus));
                usb_proc_rewakeup(USB_BUS_GIANT_PROC(bus));
-               usb_proc_rewakeup(USB_BUS_NON_GIANT_PROC(bus));
+               usb_proc_rewakeup(USB_BUS_NON_GIANT_ISOC_PROC(bus));
+               usb_proc_rewakeup(USB_BUS_NON_GIANT_BULK_PROC(bus));
 #endif
 
                USB_BUS_UNLOCK(bus);
@@ -862,9 +864,13 @@ usb_attach_sub(device_t dev, struct usb_
            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {
                device_printf(dev, "WARNING: Creation of USB Giant "
                    "callback process failed.\n");
-       } else if (usb_proc_create(USB_BUS_NON_GIANT_PROC(bus),
+       } else if (usb_proc_create(USB_BUS_NON_GIANT_ISOC_PROC(bus),
+           &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGHEST)) {
+               device_printf(dev, "WARNING: Creation of USB non-Giant ISOC "
+                   "callback process failed.\n");
+       } else if (usb_proc_create(USB_BUS_NON_GIANT_BULK_PROC(bus),
            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_HIGH)) {
-               device_printf(dev, "WARNING: Creation of USB non-Giant "
+               device_printf(dev, "WARNING: Creation of USB non-Giant BULK "
                    "callback process failed.\n");
        } else if (usb_proc_create(USB_BUS_EXPLORE_PROC(bus),
            &bus->bus_mtx, device_get_nameunit(dev), USB_PRI_MED)) {

Modified: stable/10/sys/dev/usb/usb_bus.h
==============================================================================
--- stable/10/sys/dev/usb/usb_bus.h     Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usb_bus.h     Sat Aug 29 06:23:40 2015        
(r287274)
@@ -57,19 +57,26 @@ struct usb_bus {
        struct root_hold_token *bus_roothold;
 #endif
 
+/* convenience macros */
+#define        USB_BUS_TT_PROC(bus) USB_BUS_NON_GIANT_ISOC_PROC(bus)
+#define        USB_BUS_CS_PROC(bus) USB_BUS_NON_GIANT_ISOC_PROC(bus)
+  
 #if USB_HAVE_PER_BUS_PROCESS
 #define        USB_BUS_GIANT_PROC(bus) (&(bus)->giant_callback_proc)
-#define        USB_BUS_NON_GIANT_PROC(bus) (&(bus)->non_giant_callback_proc)
+#define        USB_BUS_NON_GIANT_ISOC_PROC(bus) 
(&(bus)->non_giant_isoc_callback_proc)
+#define        USB_BUS_NON_GIANT_BULK_PROC(bus) 
(&(bus)->non_giant_bulk_callback_proc)
 #define        USB_BUS_EXPLORE_PROC(bus) (&(bus)->explore_proc)
 #define        USB_BUS_CONTROL_XFER_PROC(bus) (&(bus)->control_xfer_proc)
-
        /*
-        * There are two callback processes. One for Giant locked
-        * callbacks. One for non-Giant locked callbacks. This should
-        * avoid congestion and reduce response time in most cases.
+        * There are three callback processes. One for Giant locked
+        * callbacks. One for non-Giant locked non-periodic callbacks
+        * and one for non-Giant locked periodic callbacks. This
+        * should avoid congestion and reduce response time in most
+        * cases.
         */
        struct usb_process giant_callback_proc;
-       struct usb_process non_giant_callback_proc;
+       struct usb_process non_giant_isoc_callback_proc;
+       struct usb_process non_giant_bulk_callback_proc;
 
        /* Explore process */
        struct usb_process explore_proc;

Modified: stable/10/sys/dev/usb/usb_device.c
==============================================================================
--- stable/10/sys/dev/usb/usb_device.c  Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usb_device.c  Sat Aug 29 06:23:40 2015        
(r287274)
@@ -2184,7 +2184,7 @@ usb_free_device(struct usb_device *udev,
         * anywhere:
         */
        USB_BUS_LOCK(udev->bus);
-       usb_proc_mwait(USB_BUS_NON_GIANT_PROC(udev->bus),
+       usb_proc_mwait(USB_BUS_CS_PROC(udev->bus),
            &udev->cs_msg[0], &udev->cs_msg[1]);
        USB_BUS_UNLOCK(udev->bus);
 

Modified: stable/10/sys/dev/usb/usb_hub.c
==============================================================================
--- stable/10/sys/dev/usb/usb_hub.c     Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usb_hub.c     Sat Aug 29 06:23:40 2015        
(r287274)
@@ -349,7 +349,7 @@ uhub_tt_buffer_reset_async_locked(struct
        }
        up->req_reset_tt = req;
        /* get reset transfer started */
-       usb_proc_msignal(USB_BUS_NON_GIANT_PROC(udev->bus),
+       usb_proc_msignal(USB_BUS_TT_PROC(udev->bus),
            &hub->tt_msg[0], &hub->tt_msg[1]);
 }
 #endif
@@ -1592,7 +1592,7 @@ uhub_detach(device_t dev)
 #if USB_HAVE_TT_SUPPORT
        /* Make sure our TT messages are not queued anywhere */
        USB_BUS_LOCK(bus);
-       usb_proc_mwait(USB_BUS_NON_GIANT_PROC(bus),
+       usb_proc_mwait(USB_BUS_TT_PROC(bus),
            &hub->tt_msg[0], &hub->tt_msg[1]);
        USB_BUS_UNLOCK(bus);
 #endif

Modified: stable/10/sys/dev/usb/usb_process.h
==============================================================================
--- stable/10/sys/dev/usb/usb_process.h Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usb_process.h Sat Aug 29 06:23:40 2015        
(r287274)
@@ -34,6 +34,7 @@
 #endif
 
 /* defines */
+#define        USB_PRI_HIGHEST PI_SWI(SWI_TTY)
 #define        USB_PRI_HIGH    PI_SWI(SWI_NET)
 #define        USB_PRI_MED     PI_SWI(SWI_CAMBIO)
 

Modified: stable/10/sys/dev/usb/usb_transfer.c
==============================================================================
--- stable/10/sys/dev/usb/usb_transfer.c        Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usb_transfer.c        Sat Aug 29 06:23:40 2015        
(r287274)
@@ -872,6 +872,19 @@ done:
        }
 }
 
+static uint8_t
+usbd_transfer_setup_has_bulk(const struct usb_config *setup_start,
+    uint16_t n_setup)
+{
+       while (n_setup--) {
+               uint8_t type = setup_start[n_setup].type;
+               if (type == UE_BULK || type == UE_BULK_INTR ||
+                   type == UE_TYPE_ANY)
+                       return (1);
+       }
+       return (0);
+}
+
 /*------------------------------------------------------------------------*
  *     usbd_transfer_setup - setup an array of USB transfers
  *
@@ -1013,9 +1026,12 @@ usbd_transfer_setup(struct usb_device *u
                        else if (xfer_mtx == &Giant)
                                info->done_p =
                                    USB_BUS_GIANT_PROC(udev->bus);
+                       else if (usbd_transfer_setup_has_bulk(setup_start, 
n_setup))
+                               info->done_p =
+                                   USB_BUS_NON_GIANT_BULK_PROC(udev->bus);
                        else
                                info->done_p =
-                                   USB_BUS_NON_GIANT_PROC(udev->bus);
+                                   USB_BUS_NON_GIANT_ISOC_PROC(udev->bus);
                }
                /* reset sizes */
 
@@ -2280,10 +2296,8 @@ usbd_callback_ss_done_defer(struct usb_x
                 * will have a Lock Order Reversal, LOR, if we try to
                 * proceed !
                 */
-               if (usb_proc_msignal(info->done_p,
-                   &info->done_m[0], &info->done_m[1])) {
-                       /* ignore */
-               }
+               (void) usb_proc_msignal(info->done_p,
+                   &info->done_m[0], &info->done_m[1]);
        } else {
                /* clear second recurse flag */
                pq->recurse_2 = 0;
@@ -2307,23 +2321,26 @@ usbd_callback_wrapper(struct usb_xfer_qu
        struct usb_xfer_root *info = xfer->xroot;
 
        USB_BUS_LOCK_ASSERT(info->bus, MA_OWNED);
-       if (!mtx_owned(info->xfer_mtx) && !SCHEDULER_STOPPED()) {
+       if ((pq->recurse_3 != 0 || mtx_owned(info->xfer_mtx) == 0) &&
+           SCHEDULER_STOPPED() == 0) {
                /*
                 * Cases that end up here:
                 *
                 * 5) HW interrupt done callback or other source.
+                * 6) HW completed transfer during callback
                 */
-               DPRINTFN(3, "case 5\n");
+               DPRINTFN(3, "case 5 and 6\n");
 
                /*
                 * We have to postpone the callback due to the fact we
                 * will have a Lock Order Reversal, LOR, if we try to
-                * proceed !
+                * proceed!
+                *
+                * Postponing the callback also ensures that other USB
+                * transfer queues get a chance.
                 */
-               if (usb_proc_msignal(info->done_p,
-                   &info->done_m[0], &info->done_m[1])) {
-                       /* ignore */
-               }
+               (void) usb_proc_msignal(info->done_p,
+                   &info->done_m[0], &info->done_m[1]);
                return;
        }
        /*
@@ -2697,7 +2714,7 @@ usbd_pipe_start(struct usb_xfer_queue *p
                        } else if (udev->ctrl_xfer[1]) {
                                info = udev->ctrl_xfer[1]->xroot;
                                usb_proc_msignal(
-                                   USB_BUS_NON_GIANT_PROC(info->bus),
+                                   USB_BUS_CS_PROC(info->bus),
                                    &udev->cs_msg[0], &udev->cs_msg[1]);
                        } else {
                                /* should not happen */
@@ -3022,9 +3039,11 @@ usb_command_wrapper(struct usb_xfer_queu
 
        if (!pq->recurse_1) {
 
-               do {
+               /* clear third recurse flag */
+               pq->recurse_3 = 0;
 
-                       /* set both recurse flags */
+               do {
+                       /* set two first recurse flags */
                        pq->recurse_1 = 1;
                        pq->recurse_2 = 1;
 
@@ -3043,6 +3062,12 @@ usb_command_wrapper(struct usb_xfer_queu
                        (pq->command) (pq);
                        DPRINTFN(6, "cb %p (leave)\n", pq->curr);
 
+                       /*
+                        * Set third recurse flag to indicate
+                        * recursion happened:
+                        */
+                       pq->recurse_3 = 1;
+
                } while (!pq->recurse_2);
 
                /* clear first recurse flag */
@@ -3318,7 +3343,8 @@ usbd_transfer_poll(struct usb_xfer **ppx
                USB_BUS_CONTROL_XFER_PROC(udev->bus)->up_msleep = 0;
                USB_BUS_EXPLORE_PROC(udev->bus)->up_msleep = 0;
                USB_BUS_GIANT_PROC(udev->bus)->up_msleep = 0;
-               USB_BUS_NON_GIANT_PROC(udev->bus)->up_msleep = 0;
+               USB_BUS_NON_GIANT_ISOC_PROC(udev->bus)->up_msleep = 0;
+               USB_BUS_NON_GIANT_BULK_PROC(udev->bus)->up_msleep = 0;
 
                /* poll USB hardware */
                (udev->bus->methods->xfer_poll) (udev->bus);

Modified: stable/10/sys/dev/usb/usbdi.h
==============================================================================
--- stable/10/sys/dev/usb/usbdi.h       Sat Aug 29 06:17:39 2015        
(r287273)
+++ stable/10/sys/dev/usb/usbdi.h       Sat Aug 29 06:23:40 2015        
(r287274)
@@ -128,6 +128,8 @@ struct usb_xfer_queue {
        void    (*command) (struct usb_xfer_queue *pq);
        uint8_t recurse_1:1;
        uint8_t recurse_2:1;
+       uint8_t recurse_3:1;
+       uint8_t reserved:5;
 };
 
 /*
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to