The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/usb_process.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD$ */
    2 /*-
    3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    4  *
    5  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #ifdef USB_GLOBAL_INCLUDE_FILE
   30 #include USB_GLOBAL_INCLUDE_FILE
   31 #else
   32 #include <sys/stdint.h>
   33 #include <sys/stddef.h>
   34 #include <sys/param.h>
   35 #include <sys/queue.h>
   36 #include <sys/types.h>
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 #include <sys/bus.h>
   40 #include <sys/module.h>
   41 #include <sys/lock.h>
   42 #include <sys/mutex.h>
   43 #include <sys/condvar.h>
   44 #include <sys/sysctl.h>
   45 #include <sys/sx.h>
   46 #include <sys/unistd.h>
   47 #include <sys/callout.h>
   48 #include <sys/malloc.h>
   49 #include <sys/priv.h>
   50 
   51 #include <dev/usb/usb.h>
   52 #include <dev/usb/usbdi.h>
   53 #include <dev/usb/usbdi_util.h>
   54 #include <dev/usb/usb_process.h>
   55 
   56 #define USB_DEBUG_VAR usb_proc_debug
   57 #include <dev/usb/usb_debug.h>
   58 #include <dev/usb/usb_util.h>
   59 
   60 #include <sys/proc.h>
   61 #include <sys/kthread.h>
   62 #include <sys/sched.h>
   63 #endif                  /* USB_GLOBAL_INCLUDE_FILE */
   64 
   65 #if (__FreeBSD_version < 700000)
   66 #define thread_lock(td) mtx_lock_spin(&sched_lock)
   67 #define thread_unlock(td) mtx_unlock_spin(&sched_lock)
   68 #endif
   69 
   70 #if (__FreeBSD_version >= 800000)
   71 static struct proc *usbproc;
   72 static int usb_pcount;
   73 #define USB_THREAD_CREATE(f, s, p, ...) \
   74                 kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \
   75                     0, "usb", __VA_ARGS__)
   76 #if (__FreeBSD_version >= 900000)
   77 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check()
   78 #else
   79 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curthread)
   80 #endif
   81 #define USB_THREAD_SUSPEND(p)   kthread_suspend(p,0)
   82 #define USB_THREAD_EXIT(err)    kthread_exit()
   83 #else
   84 #define USB_THREAD_CREATE(f, s, p, ...) \
   85                 kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__)
   86 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check(curproc)
   87 #define USB_THREAD_SUSPEND(p)   kthread_suspend(p,0)
   88 #define USB_THREAD_EXIT(err)    kthread_exit(err)
   89 #endif
   90 
   91 #ifdef USB_DEBUG
   92 static int usb_proc_debug;
   93 
   94 static SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   95     "USB process");
   96 SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_proc_debug, 0,
   97     "Debug level");
   98 #endif
   99 
  100 /*------------------------------------------------------------------------*
  101  *      usb_process
  102  *
  103  * This function is the USB process dispatcher.
  104  *------------------------------------------------------------------------*/
  105 static void
  106 usb_process(void *arg)
  107 {
  108         struct usb_process *up = arg;
  109         struct usb_proc_msg *pm;
  110         struct thread *td;
  111 
  112         /* in case of attach error, check for suspended */
  113         USB_THREAD_SUSPEND_CHECK();
  114 
  115         /* adjust priority */
  116         td = curthread;
  117         thread_lock(td);
  118         sched_prio(td, up->up_prio);
  119         thread_unlock(td);
  120 
  121         USB_MTX_LOCK(up->up_mtx);
  122 
  123         up->up_curtd = td;
  124 
  125         while (1) {
  126                 if (up->up_gone)
  127                         break;
  128 
  129                 /*
  130                  * NOTE to reimplementors: dequeueing a command from the
  131                  * "used" queue and executing it must be atomic, with regard
  132                  * to the "up_mtx" mutex. That means any attempt to queue a
  133                  * command by another thread must be blocked until either:
  134                  *
  135                  * 1) the command sleeps
  136                  *
  137                  * 2) the command returns
  138                  *
  139                  * Here is a practical example that shows how this helps
  140                  * solving a problem:
  141                  *
  142                  * Assume that you want to set the baud rate on a USB serial
  143                  * device. During the programming of the device you don't
  144                  * want to receive nor transmit any data, because it will be
  145                  * garbage most likely anyway. The programming of our USB
  146                  * device takes 20 milliseconds and it needs to call
  147                  * functions that sleep.
  148                  *
  149                  * Non-working solution: Before we queue the programming
  150                  * command, we stop transmission and reception of data. Then
  151                  * we queue a programming command. At the end of the
  152                  * programming command we enable transmission and reception
  153                  * of data.
  154                  *
  155                  * Problem: If a second programming command is queued while the
  156                  * first one is sleeping, we end up enabling transmission
  157                  * and reception of data too early.
  158                  *
  159                  * Working solution: Before we queue the programming command,
  160                  * we stop transmission and reception of data. Then we queue
  161                  * a programming command. Then we queue a second command
  162                  * that only enables transmission and reception of data.
  163                  *
  164                  * Why it works: If a second programming command is queued
  165                  * while the first one is sleeping, then the queueing of a
  166                  * second command to enable the data transfers, will cause
  167                  * the previous one, which is still on the queue, to be
  168                  * removed from the queue, and re-inserted after the last
  169                  * baud rate programming command, which then gives the
  170                  * desired result.
  171                  */
  172                 pm = TAILQ_FIRST(&up->up_qhead);
  173 
  174                 if (pm) {
  175                         DPRINTF("Message pm=%p, cb=%p (enter)\n",
  176                             pm, pm->pm_callback);
  177 
  178                         (pm->pm_callback) (pm);
  179 
  180                         if (pm == TAILQ_FIRST(&up->up_qhead)) {
  181                                 /* nothing changed */
  182                                 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
  183                                 pm->pm_qentry.tqe_prev = NULL;
  184                         }
  185                         DPRINTF("Message pm=%p (leave)\n", pm);
  186 
  187                         continue;
  188                 }
  189                 /* end of messages - check if anyone is waiting for sync */
  190                 if (up->up_dsleep) {
  191                         up->up_dsleep = 0;
  192                         cv_broadcast(&up->up_drain);
  193                 }
  194                 up->up_msleep = 1;
  195                 cv_wait(&up->up_cv, up->up_mtx);
  196         }
  197 
  198         up->up_ptr = NULL;
  199         cv_signal(&up->up_cv);
  200         USB_MTX_UNLOCK(up->up_mtx);
  201 #if (__FreeBSD_version >= 800000)
  202         /* Clear the proc pointer if this is the last thread. */
  203         if (--usb_pcount == 0)
  204                 usbproc = NULL;
  205 #endif
  206 
  207         USB_THREAD_EXIT(0);
  208 }
  209 
  210 /*------------------------------------------------------------------------*
  211  *      usb_proc_create
  212  *
  213  * This function will create a process using the given "prio" that can
  214  * execute callbacks. The mutex pointed to by "p_mtx" will be applied
  215  * before calling the callbacks and released after that the callback
  216  * has returned. The structure pointed to by "up" is assumed to be
  217  * zeroed before this function is called.
  218  *
  219  * Return values:
  220  *    0: success
  221  * Else: failure
  222  *------------------------------------------------------------------------*/
  223 int
  224 usb_proc_create(struct usb_process *up, struct mtx *p_mtx,
  225     const char *pmesg, uint8_t prio)
  226 {
  227         up->up_mtx = p_mtx;
  228         up->up_prio = prio;
  229 
  230         TAILQ_INIT(&up->up_qhead);
  231 
  232         cv_init(&up->up_cv, "-");
  233         cv_init(&up->up_drain, "usbdrain");
  234 
  235         if (USB_THREAD_CREATE(&usb_process, up,
  236             &up->up_ptr, "%s", pmesg)) {
  237                 DPRINTFN(0, "Unable to create USB process.");
  238                 up->up_ptr = NULL;
  239                 goto error;
  240         }
  241 #if (__FreeBSD_version >= 800000)
  242         usb_pcount++;
  243 #endif
  244         return (0);
  245 
  246 error:
  247         usb_proc_free(up);
  248         return (ENOMEM);
  249 }
  250 
  251 /*------------------------------------------------------------------------*
  252  *      usb_proc_free
  253  *
  254  * NOTE: If the structure pointed to by "up" is all zero, this
  255  * function does nothing.
  256  *
  257  * NOTE: Messages that are pending on the process queue will not be
  258  * removed nor called.
  259  *------------------------------------------------------------------------*/
  260 void
  261 usb_proc_free(struct usb_process *up)
  262 {
  263         /* check if not initialised */
  264         if (up->up_mtx == NULL)
  265                 return;
  266 
  267         usb_proc_drain(up);
  268 
  269         cv_destroy(&up->up_cv);
  270         cv_destroy(&up->up_drain);
  271 
  272         /* make sure that we do not enter here again */
  273         up->up_mtx = NULL;
  274 }
  275 
  276 /*------------------------------------------------------------------------*
  277  *      usb_proc_msignal
  278  *
  279  * This function will queue one of the passed USB process messages on
  280  * the USB process queue. The first message that is not already queued
  281  * will get queued. If both messages are already queued the one queued
  282  * last will be removed from the queue and queued in the end. The USB
  283  * process mutex must be locked when calling this function. This
  284  * function exploits the fact that a process can only do one callback
  285  * at a time. The message that was queued is returned.
  286  *------------------------------------------------------------------------*/
  287 void   *
  288 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1)
  289 {
  290         struct usb_proc_msg *pm0 = _pm0;
  291         struct usb_proc_msg *pm1 = _pm1;
  292         struct usb_proc_msg *pm2;
  293         usb_size_t d;
  294         uint8_t t;
  295 
  296         /* check if gone or in polling mode, return dummy value */
  297         if (up->up_gone != 0 ||
  298             USB_IN_POLLING_MODE_FUNC() != 0)
  299                 return (_pm0);
  300 
  301         USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
  302 
  303         t = 0;
  304 
  305         if (pm0->pm_qentry.tqe_prev) {
  306                 t |= 1;
  307         }
  308         if (pm1->pm_qentry.tqe_prev) {
  309                 t |= 2;
  310         }
  311         if (t == 0) {
  312                 /*
  313                  * No entries are queued. Queue "pm0" and use the existing
  314                  * message number.
  315                  */
  316                 pm2 = pm0;
  317         } else if (t == 1) {
  318                 /* Check if we need to increment the message number. */
  319                 if (pm0->pm_num == up->up_msg_num) {
  320                         up->up_msg_num++;
  321                 }
  322                 pm2 = pm1;
  323         } else if (t == 2) {
  324                 /* Check if we need to increment the message number. */
  325                 if (pm1->pm_num == up->up_msg_num) {
  326                         up->up_msg_num++;
  327                 }
  328                 pm2 = pm0;
  329         } else if (t == 3) {
  330                 /*
  331                  * Both entries are queued. Re-queue the entry closest to
  332                  * the end.
  333                  */
  334                 d = (pm1->pm_num - pm0->pm_num);
  335 
  336                 /* Check sign after subtraction */
  337                 if (d & 0x80000000) {
  338                         pm2 = pm0;
  339                 } else {
  340                         pm2 = pm1;
  341                 }
  342 
  343                 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry);
  344         } else {
  345                 pm2 = NULL;             /* panic - should not happen */
  346         }
  347 
  348         DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num);
  349 
  350         /* Put message last on queue */
  351 
  352         pm2->pm_num = up->up_msg_num;
  353         TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry);
  354 
  355         /* Check if we need to wakeup the USB process. */
  356 
  357         if (up->up_msleep) {
  358                 up->up_msleep = 0;      /* save "cv_signal()" calls */
  359                 cv_signal(&up->up_cv);
  360         }
  361         return (pm2);
  362 }
  363 
  364 /*------------------------------------------------------------------------*
  365  *      usb_proc_is_gone
  366  *
  367  * Return values:
  368  *    0: USB process is running
  369  * Else: USB process is tearing down
  370  *------------------------------------------------------------------------*/
  371 uint8_t
  372 usb_proc_is_gone(struct usb_process *up)
  373 {
  374         if (up->up_gone)
  375                 return (1);
  376 
  377         /*
  378          * Allow calls when up_mtx is NULL, before the USB process
  379          * structure is initialised.
  380          */
  381         if (up->up_mtx != NULL)
  382                 USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
  383         return (0);
  384 }
  385 
  386 /*------------------------------------------------------------------------*
  387  *      usb_proc_mwait
  388  *
  389  * This function will return when the USB process message pointed to
  390  * by "pm" is no longer on a queue. This function must be called
  391  * having "up->up_mtx" locked.
  392  *------------------------------------------------------------------------*/
  393 void
  394 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1)
  395 {
  396         struct usb_proc_msg *pm0 = _pm0;
  397         struct usb_proc_msg *pm1 = _pm1;
  398 
  399         /* check if gone */
  400         if (up->up_gone)
  401                 return;
  402 
  403         USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
  404 
  405         if (up->up_curtd == curthread) {
  406                 /* Just remove the messages from the queue. */
  407                 if (pm0->pm_qentry.tqe_prev) {
  408                         TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry);
  409                         pm0->pm_qentry.tqe_prev = NULL;
  410                 }
  411                 if (pm1->pm_qentry.tqe_prev) {
  412                         TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry);
  413                         pm1->pm_qentry.tqe_prev = NULL;
  414                 }
  415         } else
  416                 while (pm0->pm_qentry.tqe_prev ||
  417                     pm1->pm_qentry.tqe_prev) {
  418                         /* check if config thread is gone */
  419                         if (up->up_gone)
  420                                 break;
  421                         up->up_dsleep = 1;
  422                         cv_wait(&up->up_drain, up->up_mtx);
  423                 }
  424 }
  425 
  426 /*------------------------------------------------------------------------*
  427  *      usb_proc_drain
  428  *
  429  * This function will tear down an USB process, waiting for the
  430  * currently executing command to return.
  431  *
  432  * NOTE: If the structure pointed to by "up" is all zero,
  433  * this function does nothing.
  434  *------------------------------------------------------------------------*/
  435 void
  436 usb_proc_drain(struct usb_process *up)
  437 {
  438         /* check if not initialised */
  439         if (up->up_mtx == NULL)
  440                 return;
  441         /* handle special case with Giant */
  442         if (up->up_mtx != &Giant)
  443                 USB_MTX_ASSERT(up->up_mtx, MA_NOTOWNED);
  444 
  445         USB_MTX_LOCK(up->up_mtx);
  446 
  447         /* Set the gone flag */
  448 
  449         up->up_gone = 1;
  450 
  451         while (up->up_ptr) {
  452                 /* Check if we need to wakeup the USB process */
  453 
  454                 if (up->up_msleep || up->up_csleep) {
  455                         up->up_msleep = 0;
  456                         up->up_csleep = 0;
  457                         cv_signal(&up->up_cv);
  458                 }
  459 #ifndef EARLY_AP_STARTUP
  460                 /* Check if we are still cold booted */
  461                 if (cold) {
  462                         USB_THREAD_SUSPEND(up->up_ptr);
  463                         printf("WARNING: A USB process has "
  464                             "been left suspended\n");
  465                         break;
  466                 }
  467 #endif
  468                 cv_wait(&up->up_cv, up->up_mtx);
  469         }
  470         /* Check if someone is waiting - should not happen */
  471 
  472         if (up->up_dsleep) {
  473                 up->up_dsleep = 0;
  474                 cv_broadcast(&up->up_drain);
  475                 DPRINTF("WARNING: Someone is waiting "
  476                     "for USB process drain!\n");
  477         }
  478         USB_MTX_UNLOCK(up->up_mtx);
  479 }
  480 
  481 /*------------------------------------------------------------------------*
  482  *      usb_proc_rewakeup
  483  *
  484  * This function is called to re-wakeup the given USB
  485  * process. This usually happens after that the USB system has been in
  486  * polling mode, like during a panic. This function must be called
  487  * having "up->up_mtx" locked.
  488  *------------------------------------------------------------------------*/
  489 void
  490 usb_proc_rewakeup(struct usb_process *up)
  491 {
  492         /* check if not initialised */
  493         if (up->up_mtx == NULL)
  494                 return;
  495         /* check if gone */
  496         if (up->up_gone)
  497                 return;
  498 
  499         USB_MTX_ASSERT(up->up_mtx, MA_OWNED);
  500 
  501         if (up->up_msleep == 0) {
  502                 /* re-wakeup */
  503                 cv_signal(&up->up_cv);
  504         }
  505 }
  506 
  507 /*------------------------------------------------------------------------*
  508  *      usb_proc_is_called_from
  509  *
  510  * This function will return non-zero if called from inside the USB
  511  * process passed as first argument. Else this function returns zero.
  512  *------------------------------------------------------------------------*/
  513 int
  514 usb_proc_is_called_from(struct usb_process *up)
  515 {
  516         return (up->up_curtd == curthread);
  517 }

Cache object: 311f3a672918db3ee38c23af67e39ba6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.