1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause 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 static struct proc *usbproc; 66 static int usb_pcount; 67 #define USB_THREAD_CREATE(f, s, p, ...) \ 68 kproc_kthread_add((f), (s), &usbproc, (p), RFHIGHPID, \ 69 0, "usb", __VA_ARGS__) 70 #define USB_THREAD_SUSPEND_CHECK() kthread_suspend_check() 71 #define USB_THREAD_SUSPEND(p) kthread_suspend(p,0) 72 #define USB_THREAD_EXIT(err) kthread_exit() 73 74 #ifdef USB_DEBUG 75 static int usb_proc_debug; 76 77 static SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 78 "USB process"); 79 SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RWTUN, &usb_proc_debug, 0, 80 "Debug level"); 81 #endif 82 83 /*------------------------------------------------------------------------* 84 * usb_process 85 * 86 * This function is the USB process dispatcher. 87 *------------------------------------------------------------------------*/ 88 static void 89 usb_process(void *arg) 90 { 91 struct usb_process *up = arg; 92 struct usb_proc_msg *pm; 93 struct thread *td; 94 95 /* in case of attach error, check for suspended */ 96 USB_THREAD_SUSPEND_CHECK(); 97 98 /* adjust priority */ 99 td = curthread; 100 thread_lock(td); 101 sched_prio(td, up->up_prio); 102 thread_unlock(td); 103 104 USB_MTX_LOCK(up->up_mtx); 105 106 up->up_curtd = td; 107 108 while (1) { 109 if (up->up_gone) 110 break; 111 112 /* 113 * NOTE to reimplementors: dequeueing a command from the 114 * "used" queue and executing it must be atomic, with regard 115 * to the "up_mtx" mutex. That means any attempt to queue a 116 * command by another thread must be blocked until either: 117 * 118 * 1) the command sleeps 119 * 120 * 2) the command returns 121 * 122 * Here is a practical example that shows how this helps 123 * solving a problem: 124 * 125 * Assume that you want to set the baud rate on a USB serial 126 * device. During the programming of the device you don't 127 * want to receive nor transmit any data, because it will be 128 * garbage most likely anyway. The programming of our USB 129 * device takes 20 milliseconds and it needs to call 130 * functions that sleep. 131 * 132 * Non-working solution: Before we queue the programming 133 * command, we stop transmission and reception of data. Then 134 * we queue a programming command. At the end of the 135 * programming command we enable transmission and reception 136 * of data. 137 * 138 * Problem: If a second programming command is queued while the 139 * first one is sleeping, we end up enabling transmission 140 * and reception of data too early. 141 * 142 * Working solution: Before we queue the programming command, 143 * we stop transmission and reception of data. Then we queue 144 * a programming command. Then we queue a second command 145 * that only enables transmission and reception of data. 146 * 147 * Why it works: If a second programming command is queued 148 * while the first one is sleeping, then the queueing of a 149 * second command to enable the data transfers, will cause 150 * the previous one, which is still on the queue, to be 151 * removed from the queue, and re-inserted after the last 152 * baud rate programming command, which then gives the 153 * desired result. 154 */ 155 pm = TAILQ_FIRST(&up->up_qhead); 156 157 if (pm) { 158 DPRINTF("Message pm=%p, cb=%p (enter)\n", 159 pm, pm->pm_callback); 160 161 (pm->pm_callback) (pm); 162 163 if (pm == TAILQ_FIRST(&up->up_qhead)) { 164 /* nothing changed */ 165 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry); 166 pm->pm_qentry.tqe_prev = NULL; 167 } 168 DPRINTF("Message pm=%p (leave)\n", pm); 169 170 continue; 171 } 172 /* end of messages - check if anyone is waiting for sync */ 173 if (up->up_dsleep) { 174 up->up_dsleep = 0; 175 cv_broadcast(&up->up_drain); 176 } 177 up->up_msleep = 1; 178 cv_wait(&up->up_cv, up->up_mtx); 179 } 180 181 up->up_ptr = NULL; 182 cv_signal(&up->up_cv); 183 USB_MTX_UNLOCK(up->up_mtx); 184 /* Clear the proc pointer if this is the last thread. */ 185 if (--usb_pcount == 0) 186 usbproc = NULL; 187 188 USB_THREAD_EXIT(0); 189 } 190 191 /*------------------------------------------------------------------------* 192 * usb_proc_create 193 * 194 * This function will create a process using the given "prio" that can 195 * execute callbacks. The mutex pointed to by "p_mtx" will be applied 196 * before calling the callbacks and released after that the callback 197 * has returned. The structure pointed to by "up" is assumed to be 198 * zeroed before this function is called. 199 * 200 * Return values: 201 * 0: success 202 * Else: failure 203 *------------------------------------------------------------------------*/ 204 int 205 usb_proc_create(struct usb_process *up, struct mtx *p_mtx, 206 const char *pmesg, uint8_t prio) 207 { 208 up->up_mtx = p_mtx; 209 up->up_prio = prio; 210 211 TAILQ_INIT(&up->up_qhead); 212 213 cv_init(&up->up_cv, "-"); 214 cv_init(&up->up_drain, "usbdrain"); 215 216 if (USB_THREAD_CREATE(&usb_process, up, 217 &up->up_ptr, "%s", pmesg)) { 218 DPRINTFN(0, "Unable to create USB process."); 219 up->up_ptr = NULL; 220 goto error; 221 } 222 usb_pcount++; 223 return (0); 224 225 error: 226 usb_proc_free(up); 227 return (ENOMEM); 228 } 229 230 /*------------------------------------------------------------------------* 231 * usb_proc_free 232 * 233 * NOTE: If the structure pointed to by "up" is all zero, this 234 * function does nothing. 235 * 236 * NOTE: Messages that are pending on the process queue will not be 237 * removed nor called. 238 *------------------------------------------------------------------------*/ 239 void 240 usb_proc_free(struct usb_process *up) 241 { 242 /* check if not initialised */ 243 if (up->up_mtx == NULL) 244 return; 245 246 usb_proc_drain(up); 247 248 cv_destroy(&up->up_cv); 249 cv_destroy(&up->up_drain); 250 251 /* make sure that we do not enter here again */ 252 up->up_mtx = NULL; 253 } 254 255 /*------------------------------------------------------------------------* 256 * usb_proc_msignal 257 * 258 * This function will queue one of the passed USB process messages on 259 * the USB process queue. The first message that is not already queued 260 * will get queued. If both messages are already queued the one queued 261 * last will be removed from the queue and queued in the end. The USB 262 * process mutex must be locked when calling this function. This 263 * function exploits the fact that a process can only do one callback 264 * at a time. The message that was queued is returned. 265 *------------------------------------------------------------------------*/ 266 void * 267 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) 268 { 269 struct usb_proc_msg *pm0 = _pm0; 270 struct usb_proc_msg *pm1 = _pm1; 271 struct usb_proc_msg *pm2; 272 usb_size_t d; 273 uint8_t t; 274 275 /* check if gone or in polling mode, return dummy value */ 276 if (up->up_gone != 0 || 277 USB_IN_POLLING_MODE_FUNC() != 0) 278 return (_pm0); 279 280 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); 281 282 t = 0; 283 284 if (pm0->pm_qentry.tqe_prev) { 285 t |= 1; 286 } 287 if (pm1->pm_qentry.tqe_prev) { 288 t |= 2; 289 } 290 if (t == 0) { 291 /* 292 * No entries are queued. Queue "pm0" and use the existing 293 * message number. 294 */ 295 pm2 = pm0; 296 } else if (t == 1) { 297 /* Check if we need to increment the message number. */ 298 if (pm0->pm_num == up->up_msg_num) { 299 up->up_msg_num++; 300 } 301 pm2 = pm1; 302 } else if (t == 2) { 303 /* Check if we need to increment the message number. */ 304 if (pm1->pm_num == up->up_msg_num) { 305 up->up_msg_num++; 306 } 307 pm2 = pm0; 308 } else if (t == 3) { 309 /* 310 * Both entries are queued. Re-queue the entry closest to 311 * the end. 312 */ 313 d = (pm1->pm_num - pm0->pm_num); 314 315 /* Check sign after subtraction */ 316 if (d & 0x80000000) { 317 pm2 = pm0; 318 } else { 319 pm2 = pm1; 320 } 321 322 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry); 323 } else { 324 pm2 = NULL; /* panic - should not happen */ 325 } 326 327 DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num); 328 329 /* Put message last on queue */ 330 331 pm2->pm_num = up->up_msg_num; 332 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry); 333 334 /* Check if we need to wakeup the USB process. */ 335 336 if (up->up_msleep) { 337 up->up_msleep = 0; /* save "cv_signal()" calls */ 338 cv_signal(&up->up_cv); 339 } 340 return (pm2); 341 } 342 343 /*------------------------------------------------------------------------* 344 * usb_proc_is_gone 345 * 346 * Return values: 347 * 0: USB process is running 348 * Else: USB process is tearing down 349 *------------------------------------------------------------------------*/ 350 uint8_t 351 usb_proc_is_gone(struct usb_process *up) 352 { 353 if (up->up_gone) 354 return (1); 355 356 /* 357 * Allow calls when up_mtx is NULL, before the USB process 358 * structure is initialised. 359 */ 360 if (up->up_mtx != NULL) 361 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); 362 return (0); 363 } 364 365 /*------------------------------------------------------------------------* 366 * usb_proc_mwait 367 * 368 * This function will return when the USB process message pointed to 369 * by "pm" is no longer on a queue. This function must be called 370 * having "up->up_mtx" locked. 371 *------------------------------------------------------------------------*/ 372 void 373 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) 374 { 375 struct usb_proc_msg *pm0 = _pm0; 376 struct usb_proc_msg *pm1 = _pm1; 377 378 /* check if gone */ 379 if (up->up_gone) 380 return; 381 382 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); 383 384 if (up->up_curtd == curthread) { 385 /* Just remove the messages from the queue. */ 386 if (pm0->pm_qentry.tqe_prev) { 387 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); 388 pm0->pm_qentry.tqe_prev = NULL; 389 } 390 if (pm1->pm_qentry.tqe_prev) { 391 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry); 392 pm1->pm_qentry.tqe_prev = NULL; 393 } 394 } else 395 while (pm0->pm_qentry.tqe_prev || 396 pm1->pm_qentry.tqe_prev) { 397 /* check if config thread is gone */ 398 if (up->up_gone) 399 break; 400 up->up_dsleep = 1; 401 cv_wait(&up->up_drain, up->up_mtx); 402 } 403 } 404 405 /*------------------------------------------------------------------------* 406 * usb_proc_drain 407 * 408 * This function will tear down an USB process, waiting for the 409 * currently executing command to return. 410 * 411 * NOTE: If the structure pointed to by "up" is all zero, 412 * this function does nothing. 413 *------------------------------------------------------------------------*/ 414 void 415 usb_proc_drain(struct usb_process *up) 416 { 417 /* check if not initialised */ 418 if (up->up_mtx == NULL) 419 return; 420 /* handle special case with Giant */ 421 if (up->up_mtx != &Giant) 422 USB_MTX_ASSERT(up->up_mtx, MA_NOTOWNED); 423 424 USB_MTX_LOCK(up->up_mtx); 425 426 /* Set the gone flag */ 427 428 up->up_gone = 1; 429 430 while (up->up_ptr) { 431 /* Check if we need to wakeup the USB process */ 432 433 if (up->up_msleep || up->up_csleep) { 434 up->up_msleep = 0; 435 up->up_csleep = 0; 436 cv_signal(&up->up_cv); 437 } 438 #ifndef EARLY_AP_STARTUP 439 /* Check if we are still cold booted */ 440 if (cold) { 441 USB_THREAD_SUSPEND(up->up_ptr); 442 printf("WARNING: A USB process has " 443 "been left suspended\n"); 444 break; 445 } 446 #endif 447 cv_wait(&up->up_cv, up->up_mtx); 448 } 449 /* Check if someone is waiting - should not happen */ 450 451 if (up->up_dsleep) { 452 up->up_dsleep = 0; 453 cv_broadcast(&up->up_drain); 454 DPRINTF("WARNING: Someone is waiting " 455 "for USB process drain!\n"); 456 } 457 USB_MTX_UNLOCK(up->up_mtx); 458 } 459 460 /*------------------------------------------------------------------------* 461 * usb_proc_rewakeup 462 * 463 * This function is called to re-wakeup the given USB 464 * process. This usually happens after that the USB system has been in 465 * polling mode, like during a panic. This function must be called 466 * having "up->up_mtx" locked. 467 *------------------------------------------------------------------------*/ 468 void 469 usb_proc_rewakeup(struct usb_process *up) 470 { 471 /* check if not initialised */ 472 if (up->up_mtx == NULL) 473 return; 474 /* check if gone */ 475 if (up->up_gone) 476 return; 477 478 USB_MTX_ASSERT(up->up_mtx, MA_OWNED); 479 480 if (up->up_msleep == 0) { 481 /* re-wakeup */ 482 cv_signal(&up->up_cv); 483 } 484 } 485 486 /*------------------------------------------------------------------------* 487 * usb_proc_is_called_from 488 * 489 * This function will return non-zero if called from inside the USB 490 * process passed as first argument. Else this function returns zero. 491 *------------------------------------------------------------------------*/ 492 int 493 usb_proc_is_called_from(struct usb_process *up) 494 { 495 return (up->up_curtd == curthread); 496 } 497