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