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