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