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