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