1 /* $FreeBSD: releng/12.2/sys/dev/usb/usb_process.c 326255 2017-11-27 14:52:40Z pfg $ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4 * 5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "implementation/global_implementation.h" 30 31 struct usb_process usb_process[USB_PROC_MAX]; 32 struct mtx sched_lock; 33 34 #undef USB_DEBUG_VAR 35 #define USB_DEBUG_VAR usb_proc_debug 36 #ifdef LOSCFG_USB_DEBUG 37 static int usb_proc_debug; 38 void 39 usb_process_debug_func(int level) 40 { 41 usb_proc_debug = level; 42 PRINTK("The level of usb process debug is %d\n", level); 43 } 44 DEBUG_MODULE(process, usb_process_debug_func); 45 #endif 46 47 SPIN_LOCK_INIT(g_usb_process_queue_spinlock); 48 49 /*------------------------------------------------------------------------* 50 * usb_process 51 * 52 * This function is the USB process dispatcher. 53 *------------------------------------------------------------------------*/ 54 static void* 55 usb_process_thread(UINTPTR para) 56 { 57 struct usb_process *up = (struct usb_process*)para; 58 struct usb_proc_msg *pm; 59 struct thread *td; 60 uint32_t int_save; 61 62 /* in case of attach error, check for suspended */ 63 USB_THREAD_SUSPEND_CHECK(); 64 65 /* adjust priority */ 66 td = (struct thread *)(UINTPTR)curthread; 67 thread_lock(td); 68 sched_prio(td, up->up_prio); 69 thread_unlock(td); 70 71 mtx_lock(up->up_mtx); 72 73 up->up_curtd = td; 74 while (1) { 75 if (up->up_gone) 76 break; 77 78 /* 79 * NOTE to reimplementors: dequeueing a command from the 80 * "used" queue and executing it must be atomic, with regard 81 * to the "up_mtx" mutex. That means any attempt to queue a 82 * command by another thread must be blocked until either: 83 * 84 * 1) the command sleeps 85 * 86 * 2) the command returns 87 * 88 * Here is a practical example that shows how this helps 89 * solving a problem: 90 * 91 * Assume that you want to set the baud rate on a USB serial 92 * device. During the programming of the device you don't 93 * want to receive nor transmit any data, because it will be 94 * garbage most likely anyway. The programming of our USB 95 * device takes 20 milliseconds and it needs to call 96 * functions that sleep. 97 * 98 * Non-working solution: Before we queue the programming 99 * command, we stop transmission and reception of data. Then 100 * we queue a programming command. At the end of the 101 * programming command we enable transmission and reception 102 * of data. 103 * 104 * Problem: If a second programming command is queued while the 105 * first one is sleeping, we end up enabling transmission 106 * and reception of data too early. 107 * 108 * Working solution: Before we queue the programming command, 109 * we stop transmission and reception of data. Then we queue 110 * a programming command. Then we queue a second command 111 * that only enables transmission and reception of data. 112 * 113 * Why it works: If a second programming command is queued 114 * while the first one is sleeping, then the queueing of a 115 * second command to enable the data transfers, will cause 116 * the previous one, which is still on the queue, to be 117 * removed from the queue, and re-inserted after the last 118 * baud rate programming command, which then gives the 119 * desired result. 120 */ 121 122 LOS_SpinLockSave(&g_usb_process_queue_spinlock, &int_save); 123 pm = TAILQ_FIRST(&up->up_qhead); 124 LOS_SpinUnlockRestore(&g_usb_process_queue_spinlock, int_save); 125 if (pm) { 126 DPRINTF("Message pm=%p, cb=%p (enter)\n", 127 pm, pm->pm_callback); 128 129 if (pm->pm_callback) 130 (pm->pm_callback) (pm); 131 132 LOS_SpinLockSave(&g_usb_process_queue_spinlock, &int_save); 133 if (pm == TAILQ_FIRST(&up->up_qhead)) { 134 /* nothing changed */ 135 TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry); 136 pm->pm_qentry.tqe_prev = NULL; 137 } 138 LOS_SpinUnlockRestore(&g_usb_process_queue_spinlock, int_save); 139 DPRINTF("Message pm=%p (leave)\n", pm); 140 141 continue; 142 } 143 /* end if messages - check if anyone is waiting for sync */ 144 if (up->up_dsleep) { 145 up->up_dsleep = 0; 146 (void)cv_broadcast(&up->up_drain); 147 } 148 up->up_msleep = 1; 149 (void)cv_wait(&up->up_cv, up->up_mtx); 150 } 151 152 up->up_ptr = NULL; 153 (void)cv_signal(&up->up_cv); 154 mtx_unlock(up->up_mtx); 155 USB_THREAD_EXIT(0); 156 return NULL; 157 } 158 159 uint32_t 160 usb_os_task_creat(pthread_t *taskid, TSK_ENTRY_FUNC func, uint32_t prio, const char *nm, UINTPTR para) 161 { 162 uint32_t ret; 163 TSK_INIT_PARAM_S attr; 164 165 (void)memset_s(&attr, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); 166 167 attr.pfnTaskEntry = func; 168 attr.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; 169 attr.auwArgs[0] = (UINTPTR)para; 170 attr.usTaskPrio = prio; 171 attr.pcName = (char *)nm; 172 attr.uwResved = LOS_TASK_STATUS_DETACHED; 173 174 ret = LOS_TaskCreate((uint32_t *)taskid, &attr); 175 if (ret != LOS_OK) { 176 PRINTK("create %s task error!\n",nm); 177 } 178 return (ret); 179 } 180 181 uint32_t 182 usb_os_task_delete(pthread_t taskid) 183 { 184 uint32_t ret; 185 186 ret = LOS_TaskDelete(taskid); 187 if (ret != LOS_OK) { 188 PRINTK("delete task error!\n"); 189 } 190 return (ret); 191 } 192 193 /*------------------------------------------------------------------------* 194 * usb_proc_create 195 * 196 * This function will create a process using the given "prio" that can 197 * execute callbacks. The mutex pointed to by "p_mtx" will be applied 198 * before calling the callbacks and released after that the callback 199 * has returned. The structure pointed to by "up" is assumed to be 200 * zeroed before this function is called. 201 * 202 * Return values: 203 * 0: success 204 * Else: failure 205 *------------------------------------------------------------------------*/ 206 int 207 usb_proc_create(struct usb_process *up, struct mtx *p_mtx, 208 const char *pmesg, uint8_t prio) 209 { 210 uint32_t ret; 211 pthread_t td = 0; 212 up->up_mtx = p_mtx; 213 up->up_prio = prio; 214 215 TAILQ_INIT(&up->up_qhead); 216 217 cv_init(&up->up_cv, "-"); 218 cv_init(&up->up_drain, "usbdrain"); 219 220 ret = usb_os_task_creat(&td, (TSK_ENTRY_FUNC)usb_process_thread, prio, pmesg, (UINTPTR)up); 221 if (ret != LOS_OK) { 222 DPRINTFN(0, "Unable to create USB process."); 223 up->up_ptr = NULL; 224 goto error; 225 } 226 up->up_ptr = (struct thread *)(UINTPTR)td; 227 return (0); 228 229 error: 230 usb_proc_free(up); 231 return (ENOMEM); 232 } 233 234 /*------------------------------------------------------------------------* 235 * usb_proc_free 236 * 237 * NOTE: If the structure pointed to by "up" is all zero, this 238 * function does nothing. 239 * 240 * NOTE: Messages that are pending on the process queue will not be 241 * removed nor called. 242 *------------------------------------------------------------------------*/ 243 void 244 usb_proc_free(struct usb_process *up) 245 { 246 /* check if not initialised */ 247 if (up->up_mtx == NULL) 248 return; 249 250 usb_proc_drain(up); 251 252 cv_destroy(&up->up_cv); 253 cv_destroy(&up->up_drain); 254 255 /* make sure that we do not enter here again */ 256 up->up_mtx = NULL; 257 } 258 259 /*------------------------------------------------------------------------* 260 * usb_proc_msignal 261 * 262 * This function will queue one of the passed USB process messages on 263 * the USB process queue. The first message that is not already queued 264 * will get queued. If both messages are already queued the one queued 265 * last will be removed from the queue and queued in the end. The USB 266 * process mutex must be locked when calling this function. This 267 * function exploits the fact that a process can only do one callback 268 * at a time. The message that was queued is returned. 269 *------------------------------------------------------------------------*/ 270 void * 271 usb_proc_msignal(struct usb_process *up, void *_pm0, void *_pm1) 272 { 273 struct usb_proc_msg *pm0 = _pm0; 274 struct usb_proc_msg *pm1 = _pm1; 275 struct usb_proc_msg *pm2; 276 usb_size_t d; 277 uint8_t t; 278 uint32_t int_save; 279 280 /* check if gone, return dummy value */ 281 if (up->up_gone) 282 return (_pm0); 283 284 t = 0; 285 286 LOS_SpinLockSave(&g_usb_process_queue_spinlock, &int_save); 287 if (pm0->pm_qentry.tqe_prev) { 288 t |= 1; 289 } 290 if (pm1->pm_qentry.tqe_prev) { 291 t |= 2; 292 } 293 if (t == 0) { 294 /* 295 * No entries are queued. Queue "pm0" and use the existing 296 * message number. 297 */ 298 pm2 = pm0; 299 } else if (t == 1) { 300 /* Check if we need to increment the message number. */ 301 if (pm0->pm_num == up->up_msg_num) { 302 up->up_msg_num++; 303 } 304 pm2 = pm1; 305 } else if (t == 2) { 306 /* Check if we need to increment the message number. */ 307 if (pm1->pm_num == up->up_msg_num) { 308 up->up_msg_num++; 309 } 310 pm2 = pm0; 311 } else if (t == 3) { 312 /* 313 * Both entries are queued. Re-queue the entry closest to 314 * the end. 315 */ 316 d = (pm1->pm_num - pm0->pm_num); 317 318 /* Check sign after subtraction */ 319 if (d & 0x80000000) { 320 pm2 = pm0; 321 } else { 322 pm2 = pm1; 323 } 324 325 TAILQ_REMOVE(&up->up_qhead, pm2, pm_qentry); 326 pm2->pm_qentry.tqe_prev = NULL; 327 } else { 328 pm2 = NULL; /* panic - should not happen */ 329 } 330 331 DPRINTF(" t=%u, num=%u\n", t, up->up_msg_num); 332 333 /* Put message last on queue */ 334 335 pm2->pm_num = up->up_msg_num; 336 TAILQ_INSERT_TAIL(&up->up_qhead, pm2, pm_qentry); 337 LOS_SpinUnlockRestore(&g_usb_process_queue_spinlock, int_save); 338 339 /* Check if we need to wakeup the USB process. */ 340 341 up->up_msleep = 0; /* save "cv_signal()" calls */ 342 (void)cv_signal(&up->up_cv); 343 344 return (pm2); 345 } 346 347 /*------------------------------------------------------------------------* 348 * usb_proc_is_gone 349 * 350 * Return values: 351 * 0: USB process is running 352 * Else: USB process is tearing down 353 *------------------------------------------------------------------------*/ 354 uint8_t 355 usb_proc_is_gone(struct usb_process *up) 356 { 357 if (up->up_gone) { 358 return (1); 359 } 360 361 /* 362 * Allow calls when up_mtx is NULL, before the USB process 363 * structure is initialised. 364 */ 365 if (up->up_mtx != NULL) { 366 mtx_assert(up->up_mtx, MA_OWNED); 367 } 368 return (0); 369 } 370 371 /*------------------------------------------------------------------------* 372 * usb_proc_mwait 373 * 374 * This function will return when the USB process message pointed to 375 * by "pm" is no longer on a queue. This function must be called 376 * having "up->up_mtx" locked. 377 *------------------------------------------------------------------------*/ 378 void 379 usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) 380 { 381 struct usb_proc_msg *pm0 = _pm0; 382 struct usb_proc_msg *pm1 = _pm1; 383 uint32_t int_save; 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 == (struct thread *)(UINTPTR)curthread) { 392 LOS_SpinLockSave(&g_usb_process_queue_spinlock, &int_save); 393 /* Just remove the messages from the queue. */ 394 if (pm0->pm_qentry.tqe_prev) { 395 TAILQ_REMOVE(&up->up_qhead, pm0, pm_qentry); 396 pm0->pm_qentry.tqe_prev = NULL; 397 } 398 if (pm1->pm_qentry.tqe_prev) { 399 TAILQ_REMOVE(&up->up_qhead, pm1, pm_qentry); 400 pm1->pm_qentry.tqe_prev = NULL; 401 } 402 LOS_SpinUnlockRestore(&g_usb_process_queue_spinlock, int_save); 403 } else 404 while (pm0->pm_qentry.tqe_prev || 405 pm1->pm_qentry.tqe_prev) { 406 /* check if config thread is gone */ 407 if (up->up_gone) 408 break; 409 up->up_dsleep = 1; 410 (void)cv_wait(&up->up_drain, up->up_mtx); 411 } 412 } 413 414 /*------------------------------------------------------------------------* 415 * usb_proc_drain 416 * 417 * This function will tear down an USB process, waiting for the 418 * currently executing command to return. 419 * 420 * NOTE: If the structure pointed to by "up" is all zero, 421 * this function does nothing. 422 *------------------------------------------------------------------------*/ 423 void 424 usb_proc_drain(struct usb_process *up) 425 { 426 /* check if not initialised */ 427 if (up->up_mtx == NULL) { 428 return; 429 } 430 431 /* handle special case with Giant */ 432 if (up->up_mtx != &Giant) { 433 mtx_assert(up->up_mtx, MA_NOTOWNED); 434 } 435 436 mtx_lock(up->up_mtx); 437 438 /* Set the gone flag */ 439 440 up->up_gone = 1; 441 442 while (up->up_ptr) { 443 444 /* Check if we need to wakeup the USB process */ 445 446 if (up->up_msleep || up->up_csleep) { 447 up->up_msleep = 0; 448 up->up_csleep = 0; 449 (void)cv_signal(&up->up_cv); 450 } 451 (void)cv_wait(&up->up_cv, up->up_mtx); 452 } 453 /* Check if someone is waiting - should not happen */ 454 455 if (up->up_dsleep) { 456 up->up_dsleep = 0; 457 (void)cv_broadcast(&up->up_drain); 458 DPRINTF("WARNING: Someone is waiting " 459 "for USB process drain!\n"); 460 } 461 mtx_unlock(up->up_mtx); 462 } 463 464 /*------------------------------------------------------------------------* 465 * usb_proc_rewakeup 466 * 467 * This function is called to re-wakeup the given USB 468 * process. This usually happens after that the USB system has been in 469 * polling mode, like during a panic. This function must be called 470 * having "up->up_mtx" locked. 471 *------------------------------------------------------------------------*/ 472 void 473 usb_proc_rewakeup(struct usb_process *up) 474 { 475 /* check if not initialised */ 476 if (up->up_mtx == NULL) 477 return; 478 /* check if gone */ 479 if (up->up_gone) 480 return; 481 482 mtx_assert(up->up_mtx, MA_OWNED); 483 484 if (up->up_msleep == 0) { 485 /* re-wakeup */ 486 (void)cv_signal(&up->up_cv); 487 } 488 } 489 490 /*------------------------------------------------------------------------* 491 * usb_proc_is_called_from 492 * 493 * This function will return non-zero if called from inside the USB 494 * process passed as first argument. Else this function returns zero. 495 *------------------------------------------------------------------------*/ 496 int 497 usb_proc_is_called_from(struct usb_process *up) 498 { 499 return (up->up_curtd == (struct thread *)(UINTPTR)curthread); 500 } 501 502 #undef USB_DEBUG_VAR 503