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 #define USB_THREAD_CREATE(f, s, p, ...) \ 67 kproc_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__) 68 #define USB_THREAD_SUSPEND(p) kproc_suspend(p,0) 69 #define USB_THREAD_EXIT(err) kproc_exit(err) 70 #else 71 #define USB_THREAD_CREATE(f, s, p, ...) \ 72 kthread_create((f), (s), (p), RFHIGHPID, 0, __VA_ARGS__) 73 #define USB_THREAD_SUSPEND(p) kthread_suspend(p,0) 74 #define USB_THREAD_EXIT(err) kthread_exit(err) 75 #endif 76 77 #ifdef USB_DEBUG 78 static int usb_proc_debug; 79 80 SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process"); 81 SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RW, &usb_proc_debug, 0, 82 "Debug level"); 83 #endif 84 85 /*------------------------------------------------------------------------* 86 * usb_process 87 * 88 * This function is the USB process dispatcher. 89 *------------------------------------------------------------------------*/ 90 static void 91 usb_process(void *arg) 92 { 93 struct usb_process *up = arg; 94 struct usb_proc_msg *pm; 95 struct thread *td; 96 97 /* adjust priority */ 98 td = curthread; 99 thread_lock(td); 100 sched_prio(td, up->up_prio); 101 thread_unlock(td); 102 103 mtx_lock(up->up_mtx); 104 105 up->up_curtd = td; 106 107 while (1) { 108 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 if 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 mtx_unlock(up->up_mtx); 184 185 USB_THREAD_EXIT(0); 186 } 187 188 /*------------------------------------------------------------------------* 189 * usb_proc_create 190 * 191 * This function will create a process using the given "prio" that can 192 * execute callbacks. The mutex pointed to by "p_mtx" will be applied 193 * before calling the callbacks and released after that the callback 194 * has returned. The structure pointed to by "up" is assumed to be 195 * zeroed before this function is called. 196 * 197 * Return values: 198 * 0: success 199 * Else: failure 200 *------------------------------------------------------------------------*/ 201 int 202 usb_proc_create(struct usb_process *up, struct mtx *p_mtx, 203 const char *pmesg, uint8_t prio) 204 { 205 up->up_mtx = p_mtx; 206 up->up_prio = prio; 207 208 TAILQ_INIT(&up->up_qhead); 209 210 cv_init(&up->up_cv, "wmsg"); 211 cv_init(&up->up_drain, "dmsg"); 212 213 if (USB_THREAD_CREATE(&usb_process, up, 214 &up->up_ptr, pmesg)) { 215 DPRINTFN(0, "Unable to create USB process."); 216 up->up_ptr = NULL; 217 goto error; 218 } 219 return (0); 220 221 error: 222 usb_proc_free(up); 223 return (ENOMEM); 224 } 225 226 /*------------------------------------------------------------------------* 227 * usb_proc_free 228 * 229 * NOTE: If the structure pointed to by "up" is all zero, this 230 * function does nothing. 231 * 232 * NOTE: Messages that are pending on the process queue will not be 233 * removed nor called. 234 *------------------------------------------------------------------------*/ 235 void 236 usb_proc_free(struct usb_process *up) 237 { 238 /* check if not initialised */ 239 if (up->up_mtx == NULL) 240 return; 241 242 usb_proc_drain(up); 243 244 cv_destroy(&up->up_cv); 245 cv_destroy(&up->up_drain); 246 247 /* make sure that we do not enter here again */ 248 up->up_mtx = NULL; 249 } 250 251 /*------------------------------------------------------------------------* 252 * usb_proc_msignal 253 * 254 * This function will queue one of the passed USB process messages on 255 * the USB process queue. The first message that is not already queued 256 * will get queued. If both messages are already queued the one queued 257 * last will be removed from the queue and queued in the end. The USB 258 * process mutex must be locked when calling this function. This 259 * function exploits the fact that a process can only do one callback 260 * at a time. The message that was queued is returned. 261 *------------------------------------------------------------------------*/ 262 void * 263 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) 264 { 265 struct usb_proc_msg *pm0 = _pm0; 266 struct usb_proc_msg *pm1 = _pm1; 267 struct usb_proc_msg *pm2; 268 usb_size_t d; 269 uint8_t t; 270 271 /* check if gone, return dummy value */ 272 if (up->up_gone) 273 return (_pm0); 274 275 mtx_assert(up->up_mtx, MA_OWNED); 276 277 t = 0; 278 279 if (pm0->pm_qentry.tqe_prev) { 280 t |= 1; 281 } 282 if (pm1->pm_qentry.tqe_prev) { 283 t |= 2; 284 } 285 if (t == 0) { 286 /* 287 * No entries are queued. Queue "pm0" and use the existing 288 * message number. 289 */ 290 pm2 = pm0; 291 } else if (t == 1) { 292 /* Check if we need to increment the message number. */ 293 if (pm0->pm_num == up->up_msg_num) { 294 up->up_msg_num++; 295 } 296 pm2 = pm1; 297 } else if (t == 2) { 298 /* Check if we need to increment the message number. */ 299 if (pm1->pm_num == up->up_msg_num) { 300 up->up_msg_num++; 301 } 302 pm2 = pm0; 303 } else if (t == 3) { 304 /* 305 * Both entries are queued. Re-queue the entry closest to 306 * the end. 307 */ 308 d = (pm1->pm_num - pm0->pm_num); 309 310 /* Check sign after subtraction */ 311 if (d & 0x80000000) { 312 pm2 = pm0; 313 } else { 314 pm2 = pm1; 315 } 316 317 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry); 318 } else { 319 pm2 = NULL; /* panic - should not happen */ 320 } 321 322 DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num); 323 324 /* Put message last on queue */ 325 326 pm2->pm_num = up->up_msg_num; 327 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry); 328 329 /* Check if we need to wakeup the USB process. */ 330 331 if (up->up_msleep) { 332 up->up_msleep = 0; /* save "cv_signal()" calls */ 333 cv_signal(&up->up_cv); 334 } 335 return (pm2); 336 } 337 338 /*------------------------------------------------------------------------* 339 * usb_proc_is_gone 340 * 341 * Return values: 342 * 0: USB process is running 343 * Else: USB process is tearing down 344 *------------------------------------------------------------------------*/ 345 uint8_t 346 usb_proc_is_gone(struct usb_process *up) 347 { 348 if (up->up_gone) 349 return (1); 350 351 mtx_assert(up->up_mtx, MA_OWNED); 352 return (0); 353 } 354 355 /*------------------------------------------------------------------------* 356 * usb_proc_mwait 357 * 358 * This function will return when the USB process message pointed to 359 * by "pm" is no longer on a queue. This function must be called 360 * having "up->up_mtx" locked. 361 *------------------------------------------------------------------------*/ 362 void 363 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) 364 { 365 struct usb_proc_msg *pm0 = _pm0; 366 struct usb_proc_msg *pm1 = _pm1; 367 368 /* check if gone */ 369 if (up->up_gone) 370 return; 371 372 mtx_assert(up->up_mtx, MA_OWNED); 373 374 if (up->up_curtd == curthread) { 375 /* Just remove the messages from the queue. */ 376 if (pm0->pm_qentry.tqe_prev) { 377 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); 378 pm0->pm_qentry.tqe_prev = NULL; 379 } 380 if (pm1->pm_qentry.tqe_prev) { 381 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry); 382 pm1->pm_qentry.tqe_prev = NULL; 383 } 384 } else 385 while (pm0->pm_qentry.tqe_prev || 386 pm1->pm_qentry.tqe_prev) { 387 /* check if config thread is gone */ 388 if (up->up_gone) 389 break; 390 up->up_dsleep = 1; 391 cv_wait(&up->up_drain, up->up_mtx); 392 } 393 } 394 395 /*------------------------------------------------------------------------* 396 * usb_proc_drain 397 * 398 * This function will tear down an USB process, waiting for the 399 * currently executing command to return. 400 * 401 * NOTE: If the structure pointed to by "up" is all zero, 402 * this function does nothing. 403 *------------------------------------------------------------------------*/ 404 void 405 usb_proc_drain(struct usb_process *up) 406 { 407 /* check if not initialised */ 408 if (up->up_mtx == NULL) 409 return; 410 /* handle special case with Giant */ 411 if (up->up_mtx != &Giant) 412 mtx_assert(up->up_mtx, MA_NOTOWNED); 413 414 mtx_lock(up->up_mtx); 415 416 /* Set the gone flag */ 417 418 up->up_gone = 1; 419 420 while (up->up_ptr) { 421 422 /* Check if we need to wakeup the USB process */ 423 424 if (up->up_msleep || up->up_csleep) { 425 up->up_msleep = 0; 426 up->up_csleep = 0; 427 cv_signal(&up->up_cv); 428 } 429 /* Check if we are still cold booted */ 430 431 if (cold) { 432 USB_THREAD_SUSPEND(up->up_ptr); 433 printf("WARNING: A USB process has " 434 "been left suspended!\n"); 435 break; 436 } 437 cv_wait(&up->up_cv, up->up_mtx); 438 } 439 /* Check if someone is waiting - should not happen */ 440 441 if (up->up_dsleep) { 442 up->up_dsleep = 0; 443 cv_broadcast(&up->up_drain); 444 DPRINTF("WARNING: Someone is waiting " 445 "for USB process drain!\n"); 446 } 447 mtx_unlock(up->up_mtx); 448 } 449