1/*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2008-2023 Hans Petter Selasky 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include "implementation/global_implementation.h" 29 30#if USB_HAVE_UGEN 31 32/* defines */ 33 34#define UGEN_BULK_FS_BUFFER_SIZE (64*32) /* bytes */ 35#define UGEN_BULK_HS_BUFFER_SIZE (1024*32) /* bytes */ 36#define UGEN_HW_FRAMES 50 /* number of milliseconds per transfer */ 37 38/* function prototypes */ 39 40static usb_callback_t ugen_read_clear_stall_callback; 41static usb_callback_t ugen_write_clear_stall_callback; 42static usb_callback_t ugen_ctrl_read_callback; 43static usb_callback_t ugen_ctrl_write_callback; 44static usb_callback_t ugen_isoc_read_callback; 45static usb_callback_t ugen_isoc_write_callback; 46static usb_callback_t ugen_ctrl_fs_callback; 47 48static usb_fifo_open_t ugen_open; 49static usb_fifo_close_t ugen_close; 50static usb_fifo_ioctl_t ugen_ioctl; 51static usb_fifo_ioctl_t ugen_ioctl_post; 52static usb_fifo_cmd_t ugen_start_read; 53static usb_fifo_cmd_t ugen_start_write; 54static usb_fifo_cmd_t ugen_stop_io; 55 56static int ugen_transfer_setup(struct usb_fifo *, 57 const struct usb_config *, uint8_t); 58static int ugen_open_pipe_write(struct usb_fifo *); 59static int ugen_open_pipe_read(struct usb_fifo *); 60static int ugen_set_config(struct usb_fifo *, uint8_t); 61static int ugen_set_interface(struct usb_fifo *, uint8_t, uint8_t); 62static int ugen_get_cdesc(struct usb_fifo *, struct usb_gen_descriptor *); 63static int ugen_get_sdesc(struct usb_fifo *, struct usb_gen_descriptor *); 64static int ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd); 65static int ugen_re_enumerate(struct usb_fifo *); 66static int ugen_iface_ioctl(struct usb_fifo *, u_long, void *, int); 67static uint8_t ugen_fs_get_complete(struct usb_fifo *, uint8_t *); 68static int ugen_fs_uninit(struct usb_fifo *f); 69 70/* structures */ 71 72struct usb_fifo_methods usb_ugen_methods = { 73 .f_open = &ugen_open, 74 .f_close = &ugen_close, 75 .f_ioctl = &ugen_ioctl, 76 .f_ioctl_post = &ugen_ioctl_post, 77 .f_start_read = &ugen_start_read, 78 .f_stop_read = &ugen_stop_io, 79 .f_start_write = &ugen_start_write, 80 .f_stop_write = &ugen_stop_io, 81}; 82 83/* prototypes */ 84 85static int 86ugen_transfer_setup(struct usb_fifo *f, 87 const struct usb_config *setup, uint8_t n_setup) 88{ 89 struct usb_endpoint *ep = usb_fifo_softc(f); 90 struct usb_device *udev = f->udev; 91 uint8_t iface_index = ep->iface_index; 92 int error; 93 94 mtx_unlock(f->priv_mtx); 95 96 /* 97 * "usbd_transfer_setup()" can sleep so one needs to make a wrapper, 98 * exiting the mutex and checking things 99 */ 100 error = usbd_transfer_setup(udev, &iface_index, f->xfer, 101 setup, n_setup, f, f->priv_mtx); 102 if (error == 0) { 103 if (f->xfer[0]->nframes == 1) { 104 error = usb_fifo_alloc_buffer(f, 105 f->xfer[0]->max_data_length, 2); 106 } else { 107 error = usb_fifo_alloc_buffer(f, 108 f->xfer[0]->max_frame_size, 109 2 * f->xfer[0]->nframes); 110 } 111 if (error) { 112 usbd_transfer_unsetup(f->xfer, n_setup); 113 } 114 } 115 mtx_lock(f->priv_mtx); 116 117 return (error); 118} 119 120static int 121ugen_open(struct usb_fifo *f, int fflags) 122{ 123 struct usb_endpoint *ep = usb_fifo_softc(f); 124 struct usb_endpoint_descriptor *ed = ep->edesc; 125 uint8_t type; 126 127 DPRINTFN(1, "flag=0x%x pid=%d\n", fflags, curthread); 128 129 mtx_lock(f->priv_mtx); 130 switch (usbd_get_speed(f->udev)) { 131 case USB_SPEED_LOW: 132 case USB_SPEED_FULL: 133 f->nframes = UGEN_HW_FRAMES; 134 f->bufsize = UGEN_BULK_FS_BUFFER_SIZE; 135 break; 136 default: 137 f->nframes = UGEN_HW_FRAMES * 8; 138 f->bufsize = UGEN_BULK_HS_BUFFER_SIZE; 139 break; 140 } 141 142 type = ed->bmAttributes & UE_XFERTYPE; 143 if (type == UE_INTERRUPT) { 144 f->bufsize = 0; /* use "wMaxPacketSize" */ 145 } 146 f->timeout = USB_NO_TIMEOUT; 147 f->flag_short = 0; 148 f->fifo_zlp = 0; 149 mtx_unlock(f->priv_mtx); 150 151 return (0); 152} 153 154static void 155ugen_close(struct usb_fifo *f, int fflags) 156{ 157 158 DPRINTFN(1, "flag=0x%x pid=%d\n", fflags, curthread); 159 160 /* cleanup */ 161 162 mtx_lock(f->priv_mtx); 163 usbd_transfer_stop(f->xfer[0]); 164 usbd_transfer_stop(f->xfer[1]); 165 mtx_unlock(f->priv_mtx); 166 167 usbd_transfer_unsetup(f->xfer, 2); 168 usb_fifo_free_buffer(f); 169 170 if (ugen_fs_uninit(f)) { 171 /* ignore any errors - we are closing */ 172 DPRINTFN(6, "no FIFOs\n"); 173 } 174} 175 176static int 177ugen_open_pipe_write(struct usb_fifo *f) 178{ 179 struct usb_config usb_config[2]; 180 struct usb_endpoint *ep = usb_fifo_softc(f); 181 struct usb_endpoint_descriptor *ed = ep->edesc; 182 183 USB_MTX_ASSERT(f->priv_mtx, MA_OWNED); 184 185 if (f->xfer[0] || f->xfer[1]) { 186 /* transfers are already opened */ 187 return (0); 188 } 189 (void)memset_s(usb_config, sizeof(usb_config), 0, sizeof(usb_config)); 190 191 usb_config[1].type = UE_CONTROL; 192 usb_config[1].endpoint = 0; 193 usb_config[1].direction = UE_DIR_ANY; 194 usb_config[1].timeout = 1000; /* 1 second */ 195 usb_config[1].interval = 50;/* 50 milliseconds */ 196 usb_config[1].bufsize = sizeof(struct usb_device_request); 197 usb_config[1].callback = &ugen_write_clear_stall_callback; 198 usb_config[1].usb_mode = USB_MODE_HOST; 199 200 usb_config[0].type = ed->bmAttributes & UE_XFERTYPE; 201 usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR; 202 usb_config[0].stream_id = 0; /* XXX support more stream ID's */ 203 usb_config[0].direction = UE_DIR_TX; 204 usb_config[0].interval = USB_DEFAULT_INTERVAL; 205 usb_config[0].flags.proxy_buffer = 1; 206 usb_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ 207 208 switch (ed->bmAttributes & UE_XFERTYPE) { 209 case UE_INTERRUPT: 210 case UE_BULK: 211 if (f->flag_short) { 212 usb_config[0].flags.force_short_xfer = 1; 213 } 214 usb_config[0].callback = &ugen_ctrl_write_callback; 215 usb_config[0].timeout = f->timeout; 216 usb_config[0].frames = 1; 217 usb_config[0].bufsize = f->bufsize; 218 if (ugen_transfer_setup(f, usb_config, 2)) { 219 return (EIO); 220 } 221 /* first transfer does not clear stall */ 222 f->flag_stall = 0; 223 break; 224 225 case UE_ISOCHRONOUS: 226 usb_config[0].flags.short_xfer_ok = 1; 227 usb_config[0].bufsize = 0; /* use default */ 228 usb_config[0].frames = f->nframes; 229 usb_config[0].callback = &ugen_isoc_write_callback; 230 usb_config[0].timeout = 0; 231 232 /* clone configuration */ 233 usb_config[1] = usb_config[0]; 234 235 if (ugen_transfer_setup(f, usb_config, 2)) { 236 return (EIO); 237 } 238 break; 239 default: 240 return (EINVAL); 241 } 242 return (0); 243} 244 245static int 246ugen_open_pipe_read(struct usb_fifo *f) 247{ 248 struct usb_config usb_config[2]; 249 struct usb_endpoint *ep = usb_fifo_softc(f); 250 struct usb_endpoint_descriptor *ed = ep->edesc; 251 252 USB_MTX_ASSERT(f->priv_mtx, MA_OWNED); 253 254 if (f->xfer[0] || f->xfer[1]) { 255 /* transfers are already opened */ 256 return (0); 257 } 258 (void)memset_s(usb_config, sizeof(usb_config), 0, sizeof(usb_config)); 259 260 usb_config[1].type = UE_CONTROL; 261 usb_config[1].endpoint = 0; 262 usb_config[1].direction = UE_DIR_ANY; 263 usb_config[1].timeout = 1000; /* 1 second */ 264 usb_config[1].interval = 50;/* 50 milliseconds */ 265 usb_config[1].bufsize = sizeof(struct usb_device_request); 266 usb_config[1].callback = &ugen_read_clear_stall_callback; 267 usb_config[1].usb_mode = USB_MODE_HOST; 268 269 usb_config[0].type = ed->bmAttributes & UE_XFERTYPE; 270 usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR; 271 usb_config[0].stream_id = 0; /* XXX support more stream ID's */ 272 usb_config[0].direction = UE_DIR_RX; 273 usb_config[0].interval = USB_DEFAULT_INTERVAL; 274 usb_config[0].flags.proxy_buffer = 1; 275 usb_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ 276 277 switch (ed->bmAttributes & UE_XFERTYPE) { 278 case UE_INTERRUPT: 279 case UE_BULK: 280 if (f->flag_short) { 281 usb_config[0].flags.short_xfer_ok = 1; 282 } 283 usb_config[0].timeout = f->timeout; 284 usb_config[0].frames = 1; 285 usb_config[0].callback = &ugen_ctrl_read_callback; 286 usb_config[0].bufsize = f->bufsize; 287 288 if (ugen_transfer_setup(f, usb_config, 2)) { 289 return (EIO); 290 } 291 /* first transfer does not clear stall */ 292 f->flag_stall = 0; 293 break; 294 295 case UE_ISOCHRONOUS: 296 usb_config[0].flags.short_xfer_ok = 1; 297 usb_config[0].bufsize = 0; /* use default */ 298 usb_config[0].frames = f->nframes; 299 usb_config[0].callback = &ugen_isoc_read_callback; 300 usb_config[0].timeout = 0; 301 302 /* clone configuration */ 303 usb_config[1] = usb_config[0]; 304 305 if (ugen_transfer_setup(f, usb_config, 2)) { 306 return (EIO); 307 } 308 break; 309 310 default: 311 return (EINVAL); 312 } 313 return (0); 314} 315 316static void 317ugen_start_read(struct usb_fifo *f) 318{ 319 /* check that pipes are open */ 320 if (ugen_open_pipe_read(f)) { 321 /* signal error */ 322 usb_fifo_put_data_error(f); 323 } 324 /* start transfers */ 325 usbd_transfer_start(f->xfer[0]); 326 usbd_transfer_start(f->xfer[1]); 327} 328 329static void 330ugen_start_write(struct usb_fifo *f) 331{ 332 /* check that pipes are open */ 333 if (ugen_open_pipe_write(f)) { 334 /* signal error */ 335 usb_fifo_get_data_error(f); 336 } 337 /* start transfers */ 338 usbd_transfer_start(f->xfer[0]); 339 usbd_transfer_start(f->xfer[1]); 340} 341 342static void 343ugen_stop_io(struct usb_fifo *f) 344{ 345 /* stop transfers */ 346 usbd_transfer_stop(f->xfer[0]); 347 usbd_transfer_stop(f->xfer[1]); 348} 349 350static void 351ugen_ctrl_read_callback(struct usb_xfer *xfer, usb_error_t error) 352{ 353 struct usb_fifo *f = usbd_xfer_softc(xfer); 354 struct usb_mbuf *m; 355 356 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes); 357 358 switch (USB_GET_STATE(xfer)) { 359 case USB_ST_TRANSFERRED: 360 if (xfer->actlen == 0) { 361 if (f->fifo_zlp != 4) { 362 f->fifo_zlp++; 363 } else { 364 /* 365 * Throttle a little bit we have multiple ZLPs 366 * in a row! 367 */ 368 xfer->interval = 64; /* ms */ 369 } 370 } else { 371 /* clear throttle */ 372 xfer->interval = 0; 373 f->fifo_zlp = 0; 374 } 375 usb_fifo_put_data(f, xfer->frbuffers, 0, 376 xfer->actlen, 1); 377 378 case USB_ST_SETUP: 379 if (f->flag_stall) { 380 usbd_transfer_start(f->xfer[1]); 381 break; 382 } 383 USB_IF_POLL(&f->free_q, m); 384 if (m) { 385 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 386 usbd_transfer_submit(xfer); 387 } 388 break; 389 390 default: /* Error */ 391 if (xfer->error != USB_ERR_CANCELLED) { 392 /* send a zero length packet to userland */ 393 usb_fifo_put_data(f, xfer->frbuffers, 0, 0, 1); 394 f->flag_stall = 1; 395 f->fifo_zlp = 0; 396 usbd_transfer_start(f->xfer[1]); 397 } 398 break; 399 } 400} 401 402static void 403ugen_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error) 404{ 405 struct usb_fifo *f = usbd_xfer_softc(xfer); 406 usb_frlength_t actlen; 407 408 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes); 409 410 switch (USB_GET_STATE(xfer)) { 411 case USB_ST_SETUP: 412 case USB_ST_TRANSFERRED: 413 /* 414 * If writing is in stall, just jump to clear stall 415 * callback and solve the situation. 416 */ 417 if (f->flag_stall) { 418 usbd_transfer_start(f->xfer[1]); 419 break; 420 } 421 /* 422 * Write data, setup and perform hardware transfer. 423 */ 424 if (usb_fifo_get_data(f, xfer->frbuffers, 0, 425 xfer->max_data_length, &actlen, 0)) { 426 usbd_xfer_set_frame_len(xfer, 0, actlen); 427 usbd_transfer_submit(xfer); 428 } 429 break; 430 431 default: /* Error */ 432 if (xfer->error != USB_ERR_CANCELLED) { 433 f->flag_stall = 1; 434 usbd_transfer_start(f->xfer[1]); 435 } 436 break; 437 } 438} 439 440static void 441ugen_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) 442{ 443 struct usb_fifo *f = usbd_xfer_softc(xfer); 444 struct usb_xfer *xfer_other = f->xfer[0]; 445 446 if (f->flag_stall == 0) { 447 /* nothing to do */ 448 return; 449 } 450 if (usbd_clear_stall_callback(xfer, xfer_other)) { 451 DPRINTFN(5, "f=%p: stall cleared\n", f); 452 f->flag_stall = 0; 453 usbd_transfer_start(xfer_other); 454 } 455} 456 457static void 458ugen_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) 459{ 460 struct usb_fifo *f = usbd_xfer_softc(xfer); 461 struct usb_xfer *xfer_other = f->xfer[0]; 462 463 if (f->flag_stall == 0) { 464 /* nothing to do */ 465 return; 466 } 467 if (usbd_clear_stall_callback(xfer, xfer_other)) { 468 DPRINTFN(5, "f=%p: stall cleared\n", f); 469 f->flag_stall = 0; 470 usbd_transfer_start(xfer_other); 471 } 472} 473 474static void 475ugen_isoc_read_callback(struct usb_xfer *xfer, usb_error_t error) 476{ 477 struct usb_fifo *f = usbd_xfer_softc(xfer); 478 usb_frlength_t offset; 479 usb_frcount_t n; 480 481 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes); 482 483 switch (USB_GET_STATE(xfer)) { 484 case USB_ST_TRANSFERRED: 485 486 DPRINTFN(6, "actlen=%d\n", xfer->actlen); 487 488 offset = 0; 489 490 for (n = 0; n != xfer->aframes; n++) { 491 usb_fifo_put_data(f, xfer->frbuffers, offset, 492 xfer->frlengths[n], 1); 493 offset += xfer->max_frame_size; 494 } 495 496 case USB_ST_SETUP: 497tr_setup: 498 for (n = 0; n != xfer->nframes; n++) { 499 /* setup size for next transfer */ 500 usbd_xfer_set_frame_len(xfer, n, xfer->max_frame_size); 501 } 502 usbd_transfer_submit(xfer); 503 break; 504 505 default: /* Error */ 506 if (xfer->error == USB_ERR_CANCELLED) { 507 break; 508 } 509 goto tr_setup; 510 } 511} 512 513static void 514ugen_isoc_write_callback(struct usb_xfer *xfer, usb_error_t error) 515{ 516 struct usb_fifo *f = usbd_xfer_softc(xfer); 517 usb_frlength_t actlen; 518 usb_frlength_t offset; 519 usb_frcount_t n; 520 521 DPRINTFN(4, "actlen=%u, aframes=%u\n", xfer->actlen, xfer->aframes); 522 523 switch (USB_GET_STATE(xfer)) { 524 case USB_ST_TRANSFERRED: 525 case USB_ST_SETUP: 526tr_setup: 527 offset = 0; 528 for (n = 0; n != xfer->nframes; n++) { 529 if (usb_fifo_get_data(f, xfer->frbuffers, offset, 530 xfer->max_frame_size, &actlen, 1)) { 531 usbd_xfer_set_frame_len(xfer, n, actlen); 532 offset += actlen; 533 } else { 534 break; 535 } 536 } 537 538 for (; n != xfer->nframes; n++) { 539 /* fill in zero frames */ 540 usbd_xfer_set_frame_len(xfer, n, 0); 541 } 542 usbd_transfer_submit(xfer); 543 break; 544 545 default: /* Error */ 546 if (xfer->error == USB_ERR_CANCELLED) { 547 break; 548 } 549 goto tr_setup; 550 } 551} 552 553static int 554ugen_set_config(struct usb_fifo *f, uint8_t index) 555{ 556 DPRINTFN(2, "index %u\n", index); 557 558 if (f->udev->flags.usb_mode != USB_MODE_HOST) { 559 /* not possible in device side mode */ 560 return (ENOTTY); 561 } 562 563 /* make sure all FIFO's are gone */ 564 /* else there can be a deadlock */ 565 if (ugen_fs_uninit(f)) { 566 /* ignore any errors */ 567 DPRINTFN(6, "no FIFOs\n"); 568 } 569 570 if (usbd_start_set_config(f->udev, index) != 0) 571 return (EIO); 572 573 return (0); 574} 575 576static int 577ugen_set_interface(struct usb_fifo *f, 578 uint8_t iface_index, uint8_t alt_index) 579{ 580 DPRINTFN(2, "%u, %u\n", iface_index, alt_index); 581 582 if (f->udev->flags.usb_mode != USB_MODE_HOST) { 583 /* not possible in device side mode */ 584 return (ENOTTY); 585 } 586 /* make sure all FIFO's are gone */ 587 /* else there can be a deadlock */ 588 if (ugen_fs_uninit(f)) { 589 /* ignore any errors */ 590 DPRINTFN(6, "no FIFOs\n"); 591 } 592 /* change setting - will free generic FIFOs, if any */ 593 if (usbd_set_alt_interface_index(f->udev, iface_index, alt_index)) { 594 return (EIO); 595 } 596 /* probe and attach */ 597 if (usb_probe_and_attach(f->udev, iface_index)) { 598 return (EIO); 599 } 600 return (0); 601} 602 603/*------------------------------------------------------------------------* 604 * ugen_get_cdesc 605 * 606 * This function will retrieve the complete configuration descriptor 607 * at the given index. 608 *------------------------------------------------------------------------*/ 609static int 610ugen_get_cdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd) 611{ 612 struct usb_config_descriptor *cdesc = NULL; 613 struct usb_device *udev = f->udev; 614 int error; 615 uint16_t len; 616 uint8_t free_data; 617 618 DPRINTFN(6, "\n"); 619 620 if (ugd->ugd_data == NULL) { 621 /* userland pointer should not be zero */ 622 return (EINVAL); 623 } 624 if ((ugd->ugd_config_index == USB_UNCONFIG_INDEX) || 625 (ugd->ugd_config_index == udev->curr_config_index)) { 626 cdesc = usbd_get_config_descriptor(udev); 627 if (cdesc == NULL) 628 return (ENXIO); 629 free_data = 0; 630 631 } else { 632#if (USB_HAVE_FIXED_CONFIG == 0) 633 if (usbd_req_get_config_desc_full(udev, 634 NULL, &cdesc, ugd->ugd_config_index)) { 635 return (ENXIO); 636 } 637 free_data = 1; 638#else 639 /* configuration descriptor data is shared */ 640 return (EINVAL); 641#endif 642 } 643 644 len = UGETW(cdesc->wTotalLength); 645 if (len > ugd->ugd_maxlen) { 646 len = ugd->ugd_maxlen; 647 } 648 DPRINTFN(6, "len=%u\n", len); 649 650 ugd->ugd_actlen = len; 651 ugd->ugd_offset = 0; 652 653 error = copyout(cdesc, ugd->ugd_data, len); 654 655 if (free_data) 656 usbd_free_config_desc(udev, cdesc); 657 658 return (error); 659} 660 661static int 662ugen_get_sdesc(struct usb_fifo *f, struct usb_gen_descriptor *ugd) 663{ 664 void *ptr; 665 uint16_t size; 666 int error; 667 uint8_t do_unlock; 668 669 /* Protect scratch area */ 670 do_unlock = usbd_ctrl_lock(f->udev); 671 672 ptr = f->udev->scratch.data; 673 size = sizeof(f->udev->scratch.data); 674 675 if (usbd_req_get_string_desc(f->udev, NULL, ptr, 676 size, ugd->ugd_lang_id, ugd->ugd_string_index)) { 677 error = EINVAL; 678 } else { 679 if (size > ((uint8_t *)ptr)[0]) { 680 size = ((uint8_t *)ptr)[0]; 681 } 682 if (size > ugd->ugd_maxlen) { 683 size = ugd->ugd_maxlen; 684 } 685 ugd->ugd_actlen = size; 686 ugd->ugd_offset = 0; 687 688 error = copyout(ptr, ugd->ugd_data, size); 689 } 690 if (do_unlock) 691 usbd_ctrl_unlock(f->udev); 692 693 return (error); 694} 695 696/*------------------------------------------------------------------------* 697 * ugen_get_iface_driver 698 * 699 * This function generates an USB interface description for userland. 700 * 701 * Returns: 702 * 0: Success 703 * Else: Failure 704 *------------------------------------------------------------------------*/ 705static int 706ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd) 707{ 708 struct usb_device *udev = f->udev; 709 struct usb_interface *iface = NULL; 710 const char *ptr = NULL; 711 const char *desc = NULL; 712 unsigned int len; 713 unsigned int maxlen; 714 char buf[128]; 715 int error; 716 717 DPRINTFN(6, "\n"); 718 719 if ((ugd->ugd_data == NULL) || (ugd->ugd_maxlen == 0)) { 720 /* userland pointer should not be zero */ 721 return (EINVAL); 722 } 723 724 iface = usbd_get_iface(udev, ugd->ugd_iface_index); 725 if ((iface == NULL) || (iface->idesc == NULL)) { 726 /* invalid interface index */ 727 return (EINVAL); 728 } 729 730 /* read out device nameunit string, if any */ 731 if ((iface->subdev != NULL) && 732 device_is_attached(iface->subdev) && 733 (ptr = device_get_nameunit(iface->subdev)) && 734 (desc = device_get_desc(iface->subdev))) { 735 /* print description */ 736 error = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%s: <%s>", ptr, desc); 737 if (error != EOK) { 738 return (EFAULT); 739 } 740 741 /* range checks */ 742 maxlen = ugd->ugd_maxlen - 1; 743 len = strlen(buf); 744 if (len > maxlen) 745 len = maxlen; 746 747 /* update actual length, including terminating zero */ 748 ugd->ugd_actlen = len + 1; 749 750 /* copy out interface description */ 751 error = copyout(buf, ugd->ugd_data, ugd->ugd_actlen); 752 } else { 753 /* zero length string is default */ 754 error = copyout("", ugd->ugd_data, 1); 755 } 756 return (error); 757} 758 759/*------------------------------------------------------------------------* 760 * ugen_fill_deviceinfo 761 * 762 * This function dumps information about an USB device to the 763 * structure pointed to by the "di" argument. 764 * 765 * Returns: 766 * 0: Success 767 * Else: Failure 768 *------------------------------------------------------------------------*/ 769int 770ugen_fill_deviceinfo(struct usb_fifo *f, struct usb_device_info *di) 771{ 772 struct usb_device *udev = NULL; 773 struct usb_device *hub = NULL; 774 775 udev = f->udev; 776 777 (void)memset_s(di, sizeof(di[0]), 0, sizeof(di[0])); 778 779 di->udi_bus = device_get_unit(udev->bus->bdev); 780 di->udi_addr = udev->address; 781 di->udi_index = udev->device_index; 782 strlcpy(di->udi_serial, usb_get_serial(udev), sizeof(di->udi_serial)); 783 strlcpy(di->udi_vendor, usb_get_manufacturer(udev), sizeof(di->udi_vendor)); 784 strlcpy(di->udi_product, usb_get_product(udev), sizeof(di->udi_product)); 785 usb_printbcd(di->udi_release, sizeof(di->udi_release), 786 UGETW(udev->ddesc.bcdDevice)); 787 di->udi_vendorNo = UGETW(udev->ddesc.idVendor); 788 di->udi_productNo = UGETW(udev->ddesc.idProduct); 789 di->udi_releaseNo = UGETW(udev->ddesc.bcdDevice); 790 di->udi_class = udev->ddesc.bDeviceClass; 791 di->udi_subclass = udev->ddesc.bDeviceSubClass; 792 di->udi_protocol = udev->ddesc.bDeviceProtocol; 793 di->udi_config_no = udev->curr_config_no; 794 di->udi_config_index = udev->curr_config_index; 795 di->udi_power = udev->flags.self_powered ? 0 : udev->power; 796 di->udi_speed = udev->speed; 797 di->udi_mode = udev->flags.usb_mode; 798 di->udi_power_mode = udev->power_mode; 799 di->udi_suspended = udev->flags.peer_suspended; 800 801 hub = udev->parent_hub; 802 if (hub) { 803 di->udi_hubaddr = hub->address; 804 di->udi_hubindex = hub->device_index; 805 di->udi_hubport = udev->port_no; 806 } 807 return (0); 808} 809 810int 811ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur) 812{ 813 int error; 814 uint16_t len; 815 uint16_t actlen; 816 817 if (usb_check_request(f->udev, &ur->ucr_request)) { 818 return (EPERM); 819 } 820 len = UGETW(ur->ucr_request.wLength); 821 822 /* check if "ucr_data" is valid */ 823 if (len != 0) { 824 if (ur->ucr_data == NULL) { 825 return (EFAULT); 826 } 827 } 828 /* do the USB request */ 829 error = usbd_do_request_flags 830 (f->udev, NULL, &ur->ucr_request, ur->ucr_data, 831 (ur->ucr_flags & USB_SHORT_XFER_OK) | 832 USB_USER_DATA_PTR, &actlen, 833 USB_DEFAULT_TIMEOUT); 834 835 ur->ucr_actlen = actlen; 836 837 if (error) { 838 error = EIO; 839 } 840 return (error); 841} 842 843/*------------------------------------------------------------------------ 844 * ugen_re_enumerate 845 *------------------------------------------------------------------------*/ 846static int 847ugen_re_enumerate(struct usb_fifo *f) 848{ 849 struct usb_device *udev = f->udev; 850 int error; 851 852 /* 853 * This request can be useful for testing USB drivers: 854 */ 855 error = priv_check(curthread, PRIV_DRIVER); 856 if (error) { 857 return (error); 858 } 859 if (udev->flags.usb_mode != USB_MODE_HOST) { 860 /* not possible in device side mode */ 861 DPRINTFN(6, "device mode\n"); 862 return (ENOTTY); 863 } 864 /* make sure all FIFO's are gone */ 865 /* else there can be a deadlock */ 866 if (ugen_fs_uninit(f)) { 867 /* ignore any errors */ 868 DPRINTFN(6, "no FIFOs\n"); 869 } 870 /* start re-enumeration of device */ 871 usbd_start_re_enumerate(udev); 872 return (0); 873} 874 875int 876ugen_fs_uninit(struct usb_fifo *f) 877{ 878 if (f->fs_xfer == NULL) { 879 return (EINVAL); 880 } 881 usbd_transfer_unsetup(f->fs_xfer, f->fs_ep_max); 882 bsd_free(f->fs_xfer, M_USB); 883 f->fs_xfer = NULL; 884 f->fs_ep_max = 0; 885 f->fs_ep_ptr = NULL; 886 f->flag_iscomplete = 0; 887 usb_fifo_free_buffer(f); 888 return (0); 889} 890 891static uint8_t 892ugen_fs_get_complete(struct usb_fifo *f, uint8_t *pindex) 893{ 894 struct usb_mbuf *m = NULL; 895 896 USB_IF_DEQUEUE(&f->used_q, m); 897 898 if (m) { 899 *pindex = *((uint8_t *)(m->cur_data_ptr)); 900 901 USB_IF_ENQUEUE(&f->free_q, m); 902 903 return (0); /* success */ 904 } else { 905 *pindex = 0; /* fix compiler warning */ 906 907 f->flag_iscomplete = 0; 908 } 909 return (1); /* failure */ 910} 911 912static void 913ugen_fs_set_complete(struct usb_fifo *f, uint8_t index) 914{ 915 struct usb_mbuf *m = NULL; 916 917 USB_IF_DEQUEUE(&f->free_q, m); 918 919 if (m == NULL) { 920 /* can happen during close */ 921 DPRINTF("out of buffers\n"); 922 return; 923 } 924 USB_MBUF_RESET(m); 925 926 *((uint8_t *)(m->cur_data_ptr)) = index; 927 928 USB_IF_ENQUEUE(&f->used_q, m); 929 930 f->flag_iscomplete = 1; 931 932 usb_fifo_wakeup(f); 933} 934 935static int 936ugen_fs_copy_in(struct usb_fifo *f, uint8_t ep_index) 937{ 938 struct usb_device_request *req = NULL; 939 struct usb_xfer *xfer = NULL; 940 struct usb_fs_endpoint fs_ep; 941 void *uaddr = NULL; /* userland pointer */ 942 void *kaddr = NULL; 943 usb_frlength_t offset; 944 usb_frlength_t rem; 945 usb_frcount_t n; 946 uint32_t length; 947 int error; 948 uint8_t isread; 949 950 if (ep_index >= f->fs_ep_max) { 951 return (EINVAL); 952 } 953 xfer = f->fs_xfer[ep_index]; 954 if (xfer == NULL) { 955 return (EINVAL); 956 } 957 mtx_lock(f->priv_mtx); 958 if (usbd_transfer_pending(xfer)) { 959 mtx_unlock(f->priv_mtx); 960 return (EBUSY); /* should not happen */ 961 } 962 mtx_unlock(f->priv_mtx); 963 964 error = copyin(f->fs_ep_ptr + 965 ep_index, &fs_ep, sizeof(fs_ep)); 966 if (error) { 967 return (error); 968 } 969 /* security checks */ 970 971 if (fs_ep.nFrames > xfer->max_frame_count) { 972 xfer->error = USB_ERR_INVAL; 973 goto complete; 974 } 975 if (fs_ep.nFrames == 0) { 976 xfer->error = USB_ERR_INVAL; 977 goto complete; 978 } 979 error = copyin(fs_ep.ppBuffer, &uaddr, sizeof(void *)); 980 if (error) { 981 return (error); 982 } 983 /* reset first frame */ 984 usbd_xfer_set_frame_offset(xfer, 0, 0); 985 986 if (xfer->flags_int.control_xfr) { 987 req = xfer->frbuffers[0].buffer; 988 989 error = copyin(fs_ep.pLength, 990 &length, sizeof(length)); 991 if (error) { 992 return (error); 993 } 994 if (length != sizeof(*req)) { 995 xfer->error = USB_ERR_INVAL; 996 goto complete; 997 } 998 if (length != 0) { 999 error = copyin(uaddr, req, length); 1000 if (error) { 1001 return (error); 1002 } 1003 } 1004 if (usb_check_request(f->udev, req)) { 1005 xfer->error = USB_ERR_INVAL; 1006 goto complete; 1007 } 1008 usbd_xfer_set_frame_len(xfer, 0, length); 1009 1010 /* Host mode only ! */ 1011 if ((req->bmRequestType & 1012 (UT_READ | UT_WRITE)) == UT_READ) { 1013 isread = 1; 1014 } else { 1015 isread = 0; 1016 } 1017 n = 1; 1018 offset = sizeof(*req); 1019 1020 } else { 1021 /* Device and Host mode */ 1022 if (USB_GET_DATA_ISREAD(xfer)) { 1023 isread = 1; 1024 } else { 1025 isread = 0; 1026 } 1027 n = 0; 1028 offset = 0; 1029 } 1030 1031 rem = usbd_xfer_max_len(xfer); 1032 xfer->nframes = fs_ep.nFrames; 1033 xfer->timeout = fs_ep.timeout; 1034 if (xfer->timeout > 65535) { 1035 xfer->timeout = 65535; 1036 } 1037 if (fs_ep.flags & USB_FS_FLAG_SINGLE_SHORT_OK) 1038 xfer->flags.short_xfer_ok = 1; 1039 else 1040 xfer->flags.short_xfer_ok = 0; 1041 1042 if (fs_ep.flags & USB_FS_FLAG_MULTI_SHORT_OK) 1043 xfer->flags.short_frames_ok = 1; 1044 else 1045 xfer->flags.short_frames_ok = 0; 1046 1047 if (fs_ep.flags & USB_FS_FLAG_FORCE_SHORT) 1048 xfer->flags.force_short_xfer = 1; 1049 else 1050 xfer->flags.force_short_xfer = 0; 1051 1052 if (fs_ep.flags & USB_FS_FLAG_CLEAR_STALL) 1053 usbd_xfer_set_stall(xfer); 1054 else 1055 xfer->flags.stall_pipe = 0; 1056 1057 for (; n != xfer->nframes; n++) { 1058 error = copyin(fs_ep.pLength + n, 1059 &length, sizeof(length)); 1060 if (error) { 1061 break; 1062 } 1063 usbd_xfer_set_frame_len(xfer, n, length); 1064 1065 if (length > rem) { 1066 xfer->error = USB_ERR_INVAL; 1067 goto complete; 1068 } 1069 rem -= length; 1070 1071 if (!isread) { 1072 /* we need to know the source buffer */ 1073 error = copyin(fs_ep.ppBuffer + n, &uaddr, sizeof(void *)); 1074 if (error) { 1075 break; 1076 } 1077 if (xfer->flags_int.isochronous_xfr) { 1078 /* get kernel buffer address */ 1079 kaddr = xfer->frbuffers[0].buffer; 1080 kaddr = USB_ADD_BYTES(kaddr, offset); 1081 } else { 1082 /* set current frame offset */ 1083 usbd_xfer_set_frame_offset(xfer, offset, n); 1084 1085 /* get kernel buffer address */ 1086 kaddr = xfer->frbuffers[n].buffer; 1087 } 1088 1089 /* move data */ 1090 error = copyin(uaddr, kaddr, length); 1091 if (error) { 1092 break; 1093 } 1094 } 1095 offset += length; 1096 } 1097 return (error); 1098 1099complete: 1100 mtx_lock(f->priv_mtx); 1101 ugen_fs_set_complete(f, ep_index); 1102 mtx_unlock(f->priv_mtx); 1103 return (0); 1104} 1105 1106static int 1107ugen_fs_copy_out_cancelled(struct usb_fs_endpoint *fs_ep_uptr) 1108{ 1109 struct usb_fs_endpoint fs_ep; 1110 int error; 1111 1112 error = copyin(fs_ep_uptr, &fs_ep, sizeof(fs_ep)); 1113 if (error) 1114 return (error); 1115 1116 fs_ep.status = USB_ERR_CANCELLED; 1117 fs_ep.aFrames = 0; 1118 fs_ep.isoc_time_complete = 0; 1119 1120 /* update "aFrames" */ 1121 error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames, 1122 sizeof(fs_ep.aFrames)); 1123 if (error) 1124 goto done; 1125 1126 /* update "isoc_time_complete" */ 1127 error = copyout(&fs_ep.isoc_time_complete, 1128 &fs_ep_uptr->isoc_time_complete, 1129 sizeof(fs_ep.isoc_time_complete)); 1130 if (error) 1131 goto done; 1132 1133 /* update "status" */ 1134 error = copyout(&fs_ep.status, &fs_ep_uptr->status, 1135 sizeof(fs_ep.status)); 1136done: 1137 return (error); 1138} 1139 1140static int 1141ugen_fs_copy_out(struct usb_fifo *f, uint8_t ep_index) 1142{ 1143 struct usb_device_request *req = NULL; 1144 struct usb_xfer *xfer = NULL; 1145 struct usb_fs_endpoint fs_ep; 1146 struct usb_fs_endpoint *fs_ep_uptr = NULL; /* userland ptr */ 1147 void *uaddr = NULL; /* userland ptr */ 1148 void *kaddr = NULL; 1149 usb_frlength_t offset; 1150 usb_frlength_t rem; 1151 usb_frcount_t n; 1152 uint32_t length; 1153 uint32_t temp; 1154 int error; 1155 uint8_t isread; 1156 1157 if (ep_index >= f->fs_ep_max) 1158 return (EINVAL); 1159 1160 xfer = f->fs_xfer[ep_index]; 1161 if (xfer == NULL) 1162 return (EINVAL); 1163 1164 mtx_lock(f->priv_mtx); 1165 if (!xfer->flags_int.transferring && 1166 !xfer->flags_int.started) { 1167 mtx_unlock(f->priv_mtx); 1168 DPRINTF("Returning fake cancel event\n"); 1169 return (ugen_fs_copy_out_cancelled(f->fs_ep_ptr + ep_index)); 1170 } else if (usbd_transfer_pending(xfer)) { 1171 mtx_unlock(f->priv_mtx); 1172 return (EBUSY); /* should not happen */ 1173 } 1174 mtx_unlock(f->priv_mtx); 1175 1176 fs_ep_uptr = f->fs_ep_ptr + ep_index; 1177 error = copyin(fs_ep_uptr, &fs_ep, sizeof(fs_ep)); 1178 if (error) { 1179 return (error); 1180 } 1181 fs_ep.status = xfer->error; 1182 fs_ep.aFrames = xfer->aframes; 1183 fs_ep.isoc_time_complete = xfer->isoc_time_complete; 1184 if (xfer->error) { 1185 goto complete; 1186 } 1187 if (xfer->flags_int.control_xfr) { 1188 req = xfer->frbuffers[0].buffer; 1189 1190 /* Host mode only ! */ 1191 if ((req->bmRequestType & (UT_READ | UT_WRITE)) == UT_READ) { 1192 isread = 1; 1193 } else { 1194 isread = 0; 1195 } 1196 if (xfer->nframes == 0) 1197 n = 0; /* should never happen */ 1198 else 1199 n = 1; 1200 } else { 1201 /* Device and Host mode */ 1202 if (USB_GET_DATA_ISREAD(xfer)) { 1203 isread = 1; 1204 } else { 1205 isread = 0; 1206 } 1207 n = 0; 1208 } 1209 1210 /* Update lengths and copy out data */ 1211 1212 rem = usbd_xfer_max_len(xfer); 1213 offset = 0; 1214 1215 for (; n != xfer->nframes; n++) { 1216 /* get initial length into "temp" */ 1217 error = copyin(fs_ep.pLength + n, 1218 &temp, sizeof(temp)); 1219 if (error) { 1220 return (error); 1221 } 1222 if (temp > rem) { 1223 /* the userland length has been corrupted */ 1224 DPRINTF("corrupt userland length " 1225 "%u > %u\n", temp, rem); 1226 fs_ep.status = USB_ERR_INVAL; 1227 goto complete; 1228 } 1229 rem -= temp; 1230 1231 /* get actual transfer length */ 1232 length = xfer->frlengths[n]; 1233 if (length > temp) { 1234 /* data overflow */ 1235 fs_ep.status = USB_ERR_INVAL; 1236 DPRINTF("data overflow %u > %u\n", 1237 length, temp); 1238 goto complete; 1239 } 1240 if (isread) { 1241 /* we need to know the destination buffer */ 1242 error = copyin(fs_ep.ppBuffer + n, &uaddr, sizeof(void *)); 1243 if (error) { 1244 return (error); 1245 } 1246 if (xfer->flags_int.isochronous_xfr) { 1247 /* only one frame buffer */ 1248 kaddr = USB_ADD_BYTES( 1249 xfer->frbuffers[0].buffer, offset); 1250 } else { 1251 /* multiple frame buffers */ 1252 kaddr = xfer->frbuffers[n].buffer; 1253 } 1254 1255 /* move data */ 1256 error = copyout(kaddr, uaddr, length); 1257 if (error) { 1258 return (error); 1259 } 1260 } 1261 /* 1262 * Update offset according to initial length, which is 1263 * needed by isochronous transfers! 1264 */ 1265 offset += temp; 1266 1267 /* update length */ 1268 error = copyout(&length, 1269 fs_ep.pLength + n, sizeof(length)); 1270 if (error) { 1271 return (error); 1272 } 1273 } 1274 1275complete: 1276 /* update "aFrames" */ 1277 error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames, 1278 sizeof(fs_ep.aFrames)); 1279 if (error) 1280 goto done; 1281 1282 /* update "isoc_time_complete" */ 1283 error = copyout(&fs_ep.isoc_time_complete, 1284 &fs_ep_uptr->isoc_time_complete, 1285 sizeof(fs_ep.isoc_time_complete)); 1286 if (error) 1287 goto done; 1288 1289 /* update "status" */ 1290 error = copyout(&fs_ep.status, &fs_ep_uptr->status, 1291 sizeof(fs_ep.status)); 1292done: 1293 return (error); 1294} 1295 1296static uint8_t 1297ugen_fifo_in_use(struct usb_fifo *f, int fflags) 1298{ 1299 struct usb_fifo *f_rx; 1300 struct usb_fifo *f_tx; 1301 1302 f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX]; 1303 f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX]; 1304 1305 if (((unsigned int)fflags & FREAD) && f_rx && 1306 (f_rx->xfer[0] || f_rx->xfer[1])) { 1307 return (1); /* RX FIFO in use */ 1308 } 1309 if (((unsigned int)fflags & FWRITE) && f_tx && 1310 (f_tx->xfer[0] || f_tx->xfer[1])) { 1311 return (1); /* TX FIFO in use */ 1312 } 1313 return (0); /* not in use */ 1314} 1315 1316static int 1317ugen_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags) 1318{ 1319 struct usb_config usb_config[1]; 1320 struct usb_device_request req; 1321 union { 1322 struct usb_fs_complete *pcomp; 1323 struct usb_fs_start *pstart; 1324 struct usb_fs_stop *pstop; 1325 struct usb_fs_open *popen; 1326 struct usb_fs_open_stream *popen_stream; 1327 struct usb_fs_close *pclose; 1328 struct usb_fs_clear_stall_sync *pstall; 1329 void *addr; 1330 } u; 1331 struct usb_endpoint *ep; 1332 struct usb_endpoint_descriptor *ed; 1333 struct usb_xfer *xfer; 1334 int error = 0; 1335 uint8_t iface_index; 1336 uint8_t isread; 1337 uint8_t ep_index; 1338 uint8_t pre_scale; 1339 1340 u.addr = addr; 1341 DPRINTFN(6, "cmd=0x%08lx\n", cmd); 1342 1343 switch (cmd) { 1344 case USB_FS_COMPLETE: { 1345 struct usb_fs_complete comp; 1346 mtx_lock(f->priv_mtx); 1347 error = ugen_fs_get_complete(f, &ep_index); 1348 mtx_unlock(f->priv_mtx); 1349 1350 if (error) { 1351 error = EBUSY; 1352 break; 1353 } 1354 error = copyin((const void *)u.addr, &comp, sizeof(struct usb_fs_complete)); 1355 if (error != ENOERR) { 1356 break; 1357 } 1358 u.pcomp = ∁ 1359 u.pcomp->ep_index = ep_index; 1360 error = ugen_fs_copy_out(f, u.pcomp->ep_index); 1361 break; 1362 } 1363 1364 case USB_FS_START: { 1365 struct usb_fs_start start; 1366 error = copyin((const void *)u.addr, &start, sizeof(struct usb_fs_start)); 1367 if (error != ENOERR) { 1368 break; 1369 } 1370 u.pstart = &start; 1371 error = ugen_fs_copy_in(f, u.pstart->ep_index); 1372 if (error) 1373 break; 1374 mtx_lock(f->priv_mtx); 1375 xfer = f->fs_xfer[u.pstart->ep_index]; 1376 usbd_transfer_start(xfer); 1377 mtx_unlock(f->priv_mtx); 1378 break; 1379 } 1380 1381 case USB_FS_STOP: { 1382 struct usb_fs_stop stop; 1383 error = copyin((const void *)u.addr, &stop, sizeof(struct usb_fs_stop)); 1384 if (error != ENOERR) { 1385 break; 1386 } 1387 u.pstop = &stop; 1388 if (u.pstop->ep_index >= f->fs_ep_max) { 1389 error = EINVAL; 1390 break; 1391 } 1392 mtx_lock(f->priv_mtx); 1393 xfer = f->fs_xfer[u.pstart->ep_index]; 1394 if (usbd_transfer_pending(xfer)) { 1395 usbd_transfer_stop(xfer); 1396 1397 /* 1398 * Check if the USB transfer was stopped 1399 * before it was even started and fake a 1400 * cancel event. 1401 */ 1402 if (!xfer->flags_int.transferring && 1403 !xfer->flags_int.started) { 1404 DPRINTF("Issuing fake completion event\n"); 1405 ugen_fs_set_complete(xfer->priv_sc, 1406 USB_P2U(xfer->priv_fifo)); 1407 } 1408 } 1409 mtx_unlock(f->priv_mtx); 1410 break; 1411 } 1412 1413 case USB_FS_OPEN: 1414 case USB_FS_OPEN_STREAM: { 1415 struct usb_fs_open_stream open; 1416 error = copyin((const void *)u.addr, &open.fs_open, sizeof(struct usb_fs_open)); 1417 if (error != ENOERR) { 1418 break; 1419 } 1420 u.popen = &open.fs_open; 1421 if (u.popen->ep_index >= f->fs_ep_max) { 1422 error = EINVAL; 1423 break; 1424 } 1425 if (f->fs_xfer[u.popen->ep_index] != NULL) { 1426 error = EBUSY; 1427 break; 1428 } 1429 if (u.popen->max_bufsize > USB_FS_MAX_BUFSIZE) { 1430 u.popen->max_bufsize = USB_FS_MAX_BUFSIZE; 1431 } 1432 if (u.popen->max_frames & USB_FS_MAX_FRAMES_PRE_SCALE) { 1433 pre_scale = 1; 1434 u.popen->max_frames &= ~USB_FS_MAX_FRAMES_PRE_SCALE; 1435 } else { 1436 pre_scale = 0; 1437 } 1438 if (u.popen->max_frames > USB_FS_MAX_FRAMES) { 1439 u.popen->max_frames = USB_FS_MAX_FRAMES; 1440 error = copyout((const void *)&open.fs_open, addr, sizeof(struct usb_fs_open)); 1441 break; 1442 } 1443 if (u.popen->max_frames == 0) { 1444 error = EINVAL; 1445 break; 1446 } 1447 ep = usbd_get_ep_by_addr(f->udev, u.popen->ep_no); 1448 if (ep == NULL) { 1449 error = EINVAL; 1450 break; 1451 } 1452 ed = ep->edesc; 1453 if (ed == NULL) { 1454 error = ENXIO; 1455 break; 1456 } 1457 iface_index = ep->iface_index; 1458 1459 (void)memset_s(usb_config, sizeof(usb_config), 0, sizeof(usb_config)); 1460 1461 usb_config[0].type = ed->bmAttributes & UE_XFERTYPE; 1462 usb_config[0].endpoint = ed->bEndpointAddress & UE_ADDR; 1463 usb_config[0].direction = ed->bEndpointAddress & (UE_DIR_OUT | UE_DIR_IN); 1464 usb_config[0].interval = USB_DEFAULT_INTERVAL; 1465 usb_config[0].flags.proxy_buffer = 1; 1466 if (pre_scale != 0) 1467 usb_config[0].flags.pre_scale_frames = 1; 1468 usb_config[0].callback = &ugen_ctrl_fs_callback; 1469 usb_config[0].timeout = 0; /* no timeout */ 1470 usb_config[0].frames = u.popen->max_frames; 1471 usb_config[0].bufsize = u.popen->max_bufsize; 1472 usb_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ 1473 if (cmd == USB_FS_OPEN_STREAM) { 1474 error = copyin((const void *)u.addr, &open, sizeof(struct usb_fs_open_stream)); 1475 if (error != ENOERR) { 1476 break; 1477 } 1478 u.popen_stream = &open; 1479 usb_config[0].stream_id = u.popen_stream->stream_id; 1480 } 1481 1482 if (usb_config[0].type == UE_CONTROL) { 1483 if (f->udev->flags.usb_mode != USB_MODE_HOST) { 1484 error = EINVAL; 1485 break; 1486 } 1487 } else { 1488 isread = ((usb_config[0].endpoint & 1489 (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN); 1490 1491 if (f->udev->flags.usb_mode != USB_MODE_HOST) { 1492 isread = !isread; 1493 } 1494 /* check permissions */ 1495 if (isread) { 1496 if (!((unsigned int)fflags & FREAD)) { 1497 error = EPERM; 1498 break; 1499 } 1500 } else { 1501 if (!((unsigned int)fflags & FWRITE)) { 1502 error = EPERM; 1503 break; 1504 } 1505 } 1506 } 1507 error = usbd_transfer_setup(f->udev, &iface_index, 1508 f->fs_xfer + u.popen->ep_index, usb_config, 1, 1509 f, f->priv_mtx); 1510 if (error == 0) { 1511 /* update maximums */ 1512 u.popen->max_packet_length = 1513 f->fs_xfer[u.popen->ep_index]->max_frame_size; 1514 u.popen->max_bufsize = 1515 f->fs_xfer[u.popen->ep_index]->max_data_length; 1516 /* update number of frames */ 1517 u.popen->max_frames = 1518 f->fs_xfer[u.popen->ep_index]->nframes; 1519 /* store index of endpoint */ 1520 f->fs_xfer[u.popen->ep_index]->priv_fifo = 1521 ((uint8_t *)0) + u.popen->ep_index; 1522 error = copyout((const void *)&open.fs_open, addr, sizeof(struct usb_fs_open)); 1523 } else { 1524 error = ENOMEM; 1525 } 1526 break; 1527 } 1528 1529 case USB_FS_CLOSE: { 1530 struct usb_fs_close close; 1531 error = copyin((const void *)u.addr, &close, sizeof(struct usb_fs_close)); 1532 if (error != ENOERR) { 1533 break; 1534 } 1535 u.pclose = &close; 1536 if (u.pclose->ep_index >= f->fs_ep_max) { 1537 error = EINVAL; 1538 break; 1539 } 1540 if (f->fs_xfer[u.pclose->ep_index] == NULL) { 1541 error = EINVAL; 1542 break; 1543 } 1544 usbd_transfer_unsetup(f->fs_xfer + u.pclose->ep_index, 1); 1545 break; 1546 } 1547 1548 case USB_FS_CLEAR_STALL_SYNC: { 1549 struct usb_fs_clear_stall_sync stall; 1550 error = copyin((const void *)u.addr, &stall, sizeof(struct usb_fs_clear_stall_sync)); 1551 if (error != ENOERR) { 1552 break; 1553 } 1554 u.pstall = &stall; 1555 if (u.pstall->ep_index >= f->fs_ep_max) { 1556 error = EINVAL; 1557 break; 1558 } 1559 if (f->fs_xfer[u.pstall->ep_index] == NULL) { 1560 error = EINVAL; 1561 break; 1562 } 1563 if (f->udev->flags.usb_mode != USB_MODE_HOST) { 1564 error = EINVAL; 1565 break; 1566 } 1567 mtx_lock(f->priv_mtx); 1568 error = usbd_transfer_pending(f->fs_xfer[u.pstall->ep_index]); 1569 mtx_unlock(f->priv_mtx); 1570 1571 if (error) { 1572 return (EBUSY); 1573 } 1574 ep = f->fs_xfer[u.pstall->ep_index]->endpoint; 1575 1576 /* setup a clear-stall packet */ 1577 req.bmRequestType = UT_WRITE_ENDPOINT; 1578 req.bRequest = UR_CLEAR_FEATURE; 1579 USETW(req.wValue, UF_ENDPOINT_HALT); 1580 req.wIndex[0] = ep->edesc->bEndpointAddress; 1581 req.wIndex[1] = 0; 1582 USETW(req.wLength, 0); 1583 1584 error = usbd_do_request(f->udev, NULL, &req, NULL); 1585 if (error == 0) { 1586 usbd_clear_data_toggle(f->udev, ep); 1587 } else { 1588 error = ENXIO; 1589 } 1590 break; 1591 } 1592 1593 default: 1594 error = ENOIOCTL; 1595 break; 1596 } 1597 1598 DPRINTFN(6, "error=%d\n", error); 1599 1600 return (error); 1601} 1602 1603static int 1604ugen_set_short_xfer(struct usb_fifo *f, const void *addr) 1605{ 1606 uint8_t t; 1607 1608 if (*(int *)addr) 1609 t = 1; 1610 else 1611 t = 0; 1612 1613 if (f->flag_short == t) { 1614 /* same value like before - accept */ 1615 return (0); 1616 } 1617 if (f->xfer[0] || f->xfer[1]) { 1618 /* cannot change this during transfer */ 1619 return (EBUSY); 1620 } 1621 f->flag_short = t; 1622 return (0); 1623} 1624 1625static int 1626ugen_set_timeout(struct usb_fifo *f, const void *addr) 1627{ 1628 f->timeout = *(int *)addr; 1629 if (f->timeout > 65535) { 1630 /* limit user input */ 1631 f->timeout = 65535; 1632 } 1633 return (0); 1634} 1635 1636static int 1637ugen_get_frame_size(struct usb_fifo *f, void *addr) 1638{ 1639 if (f->xfer[0]) { 1640 *(int *)addr = f->xfer[0]->max_frame_size; 1641 } else { 1642 return (EINVAL); 1643 } 1644 return (0); 1645} 1646 1647static int 1648ugen_set_buffer_size(struct usb_fifo *f, const void *addr) 1649{ 1650 usb_frlength_t t; 1651 1652 if (*(int *)addr < 0) 1653 t = 0; /* use "wMaxPacketSize" */ 1654 else if (*(int *)addr < (256 * 1024)) 1655 t = *(int *)addr; 1656 else 1657 t = 256 * 1024; 1658 1659 if (f->bufsize == t) { 1660 /* same value like before - accept */ 1661 return (0); 1662 } 1663 if (f->xfer[0] || f->xfer[1]) { 1664 /* cannot change this during transfer */ 1665 return (EBUSY); 1666 } 1667 f->bufsize = t; 1668 return (0); 1669} 1670 1671static int 1672ugen_get_buffer_size(struct usb_fifo *f, void *addr) 1673{ 1674 *(int *)addr = f->bufsize; 1675 return (0); 1676} 1677 1678static int 1679ugen_get_iface_desc(struct usb_fifo *f, 1680 struct usb_interface_descriptor *idesc) 1681{ 1682 struct usb_interface *iface; 1683 1684 iface = usbd_get_iface(f->udev, f->iface_index); 1685 if (iface && iface->idesc) { 1686 *idesc = *(iface->idesc); 1687 } else { 1688 return (EIO); 1689 } 1690 return (0); 1691} 1692 1693static int 1694ugen_get_endpoint_desc(struct usb_fifo *f, 1695 struct usb_endpoint_descriptor *ed) 1696{ 1697 struct usb_endpoint *ep; 1698 1699 ep = usb_fifo_softc(f); 1700 1701 if (ep && ep->edesc) { 1702 *ed = *ep->edesc; 1703 } else { 1704 return (EINVAL); 1705 } 1706 return (0); 1707} 1708 1709static int 1710ugen_set_power_mode(struct usb_fifo *f, int mode) 1711{ 1712 struct usb_device *udev = f->udev; 1713 int err; 1714 uint8_t old_mode; 1715 1716 if ((udev == NULL) || 1717 (udev->parent_hub == NULL)) { 1718 return (EINVAL); 1719 } 1720 err = priv_check(curthread, PRIV_DRIVER); 1721 if (err) 1722 return (err); 1723 1724 /* get old power mode */ 1725 old_mode = udev->power_mode; 1726 1727 /* if no change, then just return */ 1728 if (old_mode == mode) 1729 return (0); 1730 1731 switch (mode) { 1732 case USB_POWER_MODE_OFF: 1733 if (udev->flags.usb_mode == USB_MODE_HOST && 1734 udev->re_enumerate_wait == USB_RE_ENUM_DONE) { 1735 udev->re_enumerate_wait = USB_RE_ENUM_PWR_OFF; 1736 } 1737 /* set power mode will wake up the explore thread */ 1738 break; 1739 1740 case USB_POWER_MODE_ON: 1741 case USB_POWER_MODE_SAVE: 1742 break; 1743 1744 case USB_POWER_MODE_RESUME: 1745#if USB_HAVE_POWERD 1746 /* let USB-powerd handle resume */ 1747 USB_BUS_LOCK(udev->bus); 1748 udev->pwr_save.write_refs++; 1749 udev->pwr_save.last_xfer_time = LOS_TickCountGet(); 1750 USB_BUS_UNLOCK(udev->bus); 1751 1752 /* set new power mode */ 1753 usbd_set_power_mode(udev, USB_POWER_MODE_SAVE); 1754 1755 /* wait for resume to complete */ 1756 usb_pause_mtx(NULL, hz / 4); 1757 1758 /* clear write reference */ 1759 USB_BUS_LOCK(udev->bus); 1760 udev->pwr_save.write_refs--; 1761 USB_BUS_UNLOCK(udev->bus); 1762#endif 1763 mode = USB_POWER_MODE_SAVE; 1764 break; 1765 1766 case USB_POWER_MODE_SUSPEND: 1767#if USB_HAVE_POWERD 1768 /* let USB-powerd handle suspend */ 1769 USB_BUS_LOCK(udev->bus); 1770 udev->pwr_save.last_xfer_time = LOS_TickCountGet() - (256 * hz); 1771 USB_BUS_UNLOCK(udev->bus); 1772#endif 1773 mode = USB_POWER_MODE_SAVE; 1774 break; 1775 1776 default: 1777 return (EINVAL); 1778 } 1779 1780 if (err) 1781 return (ENXIO); /* I/O failure */ 1782 1783 /* if we are powered off we need to re-enumerate first */ 1784 if (old_mode == USB_POWER_MODE_OFF) { 1785 if (udev->flags.usb_mode == USB_MODE_HOST && 1786 udev->re_enumerate_wait == USB_RE_ENUM_DONE) { 1787 udev->re_enumerate_wait = USB_RE_ENUM_START; 1788 } 1789 /* set power mode will wake up the explore thread */ 1790 } 1791 1792 /* set new power mode */ 1793 usbd_set_power_mode(udev, mode); 1794 1795 return (0); /* success */ 1796} 1797 1798static int 1799ugen_get_power_mode(struct usb_fifo *f) 1800{ 1801 struct usb_device *udev = f->udev; 1802 1803 if (udev == NULL) 1804 return (USB_POWER_MODE_ON); 1805 1806 return (udev->power_mode); 1807} 1808 1809static int 1810ugen_get_port_path(struct usb_fifo *f, struct usb_device_port_path *dpp) 1811{ 1812 struct usb_device *udev = f->udev; 1813 struct usb_device *next = NULL; 1814 unsigned int nlevel = 0; 1815 1816 if (udev == NULL) 1817 goto error; 1818 1819 dpp->udp_bus = device_get_unit(udev->bus->bdev); 1820 dpp->udp_index = udev->device_index; 1821 1822 /* count port levels */ 1823 next = udev; 1824 while (next->parent_hub != NULL) { 1825 nlevel++; 1826 next = next->parent_hub; 1827 } 1828 1829 /* check if too many levels */ 1830 if (nlevel > USB_DEVICE_PORT_PATH_MAX) 1831 goto error; 1832 1833 /* store total level of ports */ 1834 dpp->udp_port_level = nlevel; 1835 1836 /* store port index array */ 1837 next = udev; 1838 while (next->parent_hub != NULL) { 1839 dpp->udp_port_no[--nlevel] = next->port_no; 1840 next = next->parent_hub; 1841 } 1842 return (0); /* success */ 1843 1844error: 1845 return (EINVAL); /* failure */ 1846} 1847 1848static int 1849ugen_get_power_usage(struct usb_fifo *f) 1850{ 1851 struct usb_device *udev = f->udev; 1852 1853 if (udev == NULL) 1854 return (0); 1855 1856 return (udev->power); 1857} 1858 1859static int 1860ugen_do_port_feature(struct usb_fifo *f, uint8_t port_no, 1861 uint8_t set, uint16_t feature) 1862{ 1863 struct usb_device *udev = f->udev; 1864 struct usb_hub *hub = NULL; 1865 int err; 1866 1867 err = priv_check(curthread, PRIV_DRIVER); 1868 if (err) { 1869 return (err); 1870 } 1871 if (port_no == 0) { 1872 return (EINVAL); 1873 } 1874 if ((udev == NULL) || 1875 (udev->hub == NULL)) { 1876 return (EINVAL); 1877 } 1878 hub = udev->hub; 1879 1880 if (port_no > hub->nports) { 1881 return (EINVAL); 1882 } 1883 if (set) 1884 err = usbd_req_set_port_feature(udev, 1885 NULL, port_no, feature); 1886 else 1887 err = usbd_req_clear_port_feature(udev, 1888 NULL, port_no, feature); 1889 1890 if (err) 1891 return (ENXIO); /* failure */ 1892 1893 return (0); /* success */ 1894} 1895 1896static int 1897ugen_iface_ioctl(struct usb_fifo *f, u_long cmd, void *addr, int fflags) 1898{ 1899 struct usb_fifo *f_rx; 1900 struct usb_fifo *f_tx; 1901 int error = 0; 1902 int data; 1903 1904 f_rx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_RX]; 1905 f_tx = f->udev->fifo[(f->fifo_index & ~1) + USB_FIFO_TX]; 1906 1907 switch (cmd) { 1908 case USB_SET_RX_SHORT_XFER: 1909 error = copyin((const void *)addr, &data, sizeof(data)); 1910 if (error != ENOERR) { 1911 break; 1912 } 1913 if ((unsigned int)fflags & FREAD) { 1914 error = ugen_set_short_xfer(f_rx, &data); 1915 } else { 1916 error = EINVAL; 1917 } 1918 break; 1919 1920 case USB_SET_TX_FORCE_SHORT: 1921 error = copyin((const void *)addr, &data, sizeof(data)); 1922 if (error != ENOERR) { 1923 break; 1924 } 1925 if ((unsigned int)fflags & FWRITE) { 1926 error = ugen_set_short_xfer(f_tx, &data); 1927 } else { 1928 error = EINVAL; 1929 } 1930 break; 1931 1932 case USB_SET_RX_TIMEOUT: 1933 error = copyin((const void *)addr, &data, sizeof(data)); 1934 if (error != ENOERR) { 1935 break; 1936 } 1937 if ((unsigned int)fflags & FREAD) { 1938 error = ugen_set_timeout(f_rx, &data); 1939 } else { 1940 error = EINVAL; 1941 } 1942 break; 1943 1944 case USB_SET_TX_TIMEOUT: 1945 error = copyin((const void *)addr, &data, sizeof(data)); 1946 if (error != ENOERR) { 1947 break; 1948 } 1949 if ((unsigned int)fflags & FWRITE) { 1950 error = ugen_set_timeout(f_tx, &data); 1951 } else { 1952 error = EINVAL; 1953 } 1954 break; 1955 1956 case USB_GET_RX_FRAME_SIZE: 1957 if ((unsigned int)fflags & FREAD) { 1958 error = ugen_get_frame_size(f_rx, &data); 1959 } else { 1960 error = EINVAL; 1961 } 1962 if (error == ENOERR) { 1963 error = copyout((const void *)&data, addr, sizeof(data)); 1964 } 1965 break; 1966 1967 case USB_GET_TX_FRAME_SIZE: 1968 if ((unsigned int)fflags & FWRITE) { 1969 error = ugen_get_frame_size(f_tx, &data); 1970 } else { 1971 error = EINVAL; 1972 } 1973 if (error == ENOERR) { 1974 error = copyout((const void *)&data, addr, sizeof(data)); 1975 } 1976 break; 1977 1978 case USB_SET_RX_BUFFER_SIZE: 1979 error = copyin((const void *)addr, &data, sizeof(data)); 1980 if (error != ENOERR) { 1981 break; 1982 } 1983 if ((unsigned int)fflags & FREAD) { 1984 error = ugen_set_buffer_size(f_rx, &data); 1985 } else { 1986 error = EINVAL; 1987 } 1988 break; 1989 1990 case USB_SET_TX_BUFFER_SIZE: 1991 error = copyin((const void *)addr, &data, sizeof(data)); 1992 if (error != ENOERR) { 1993 break; 1994 } 1995 if ((unsigned int)fflags & FWRITE) { 1996 error = ugen_set_buffer_size(f_tx, &data); 1997 } else { 1998 error = EINVAL; 1999 } 2000 break; 2001 2002 case USB_GET_RX_BUFFER_SIZE: 2003 if ((unsigned int)fflags & FREAD) { 2004 error = ugen_get_buffer_size(f_rx, &data); 2005 } else { 2006 error = EINVAL; 2007 } 2008 if (error == ENOERR) { 2009 error = copyout((const void *)&data, addr, sizeof(data)); 2010 } 2011 break; 2012 2013 case USB_GET_TX_BUFFER_SIZE: 2014 if ((unsigned int)fflags & FWRITE) { 2015 error = ugen_get_buffer_size(f_tx, &data); 2016 } else { 2017 error = EINVAL; 2018 } 2019 if (error == ENOERR) { 2020 error = copyout((const void *)&data, addr, sizeof(data)); 2021 } 2022 break; 2023 2024 case USB_GET_RX_INTERFACE_DESC: { 2025 struct usb_interface_descriptor desc; 2026 if ((unsigned int)fflags & FREAD) { 2027 error = ugen_get_iface_desc(f_rx, &desc); 2028 } else { 2029 error = EINVAL; 2030 } 2031 if (error == ENOERR) { 2032 error = copyout((const void *)&desc, addr, sizeof(struct usb_interface_descriptor)); 2033 } 2034 break; 2035 } 2036 2037 case USB_GET_TX_INTERFACE_DESC: { 2038 struct usb_interface_descriptor desc; 2039 if ((unsigned int)fflags & FWRITE) { 2040 error = ugen_get_iface_desc(f_tx, &desc); 2041 } else { 2042 error = EINVAL; 2043 } 2044 if (error == ENOERR) { 2045 error = copyout((const void *)&desc, addr, sizeof(struct usb_interface_descriptor)); 2046 } 2047 break; 2048 } 2049 2050 case USB_GET_RX_ENDPOINT_DESC: { 2051 struct usb_endpoint_descriptor ed; 2052 if ((unsigned int)fflags & FREAD) { 2053 error = ugen_get_endpoint_desc(f_rx, &ed); 2054 } else { 2055 error = EINVAL; 2056 } 2057 if (error == ENOERR) { 2058 error = copyout((const void *)&ed, addr, sizeof(struct usb_endpoint_descriptor)); 2059 } 2060 break; 2061 } 2062 2063 case USB_GET_TX_ENDPOINT_DESC: { 2064 struct usb_endpoint_descriptor ed; 2065 if ((unsigned int)fflags & FWRITE) { 2066 error = ugen_get_endpoint_desc(f_tx, &ed); 2067 } else { 2068 error = EINVAL; 2069 } 2070 if (error == ENOERR) { 2071 error = copyout((const void *)&ed, addr, sizeof(struct usb_endpoint_descriptor)); 2072 } 2073 break; 2074 } 2075 2076 case USB_SET_RX_STALL_FLAG: 2077 error = copyin((const void *)addr, &data, sizeof(data)); 2078 if (error != ENOERR) { 2079 break; 2080 } 2081 if (((unsigned int)fflags & FREAD) && data) { 2082 f_rx->flag_stall = 1; 2083 } 2084 break; 2085 2086 case USB_SET_TX_STALL_FLAG: 2087 error = copyin((const void *)addr, &data, sizeof(data)); 2088 if (error != ENOERR) { 2089 break; 2090 } 2091 if (((unsigned int)fflags & FWRITE) && data) { 2092 f_tx->flag_stall = 1; 2093 } 2094 break; 2095 2096 default: 2097 error = ENOIOCTL; 2098 break; 2099 } 2100 return (error); 2101} 2102 2103static int 2104ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) 2105{ 2106 union { 2107 struct usb_interface_descriptor *idesc; 2108 struct usb_alt_interface *ai; 2109 struct usb_device_descriptor *ddesc; 2110 struct usb_config_descriptor *cdesc; 2111 struct usb_device_stats *stat; 2112 struct usb_fs_init *pinit; 2113 struct usb_fs_uninit *puninit; 2114 struct usb_device_port_path *dpp; 2115 uint32_t *ptime; 2116 void *addr; 2117 int *pint; 2118 } u; 2119 struct usb_device_descriptor *dtemp; 2120 struct usb_config_descriptor *ctemp; 2121 struct usb_interface *iface; 2122 int error = 0; 2123 uint8_t n; 2124 2125 u.addr = addr; 2126 DPRINTFN(6, "cmd=0x%08lx\n", cmd); 2127 2128 switch (cmd) { 2129 case USB_DISCOVER: 2130 usb_needs_explore_all(); 2131 break; 2132 2133 case USB_SETDEBUG: 2134 if (!((unsigned int)fflags & FWRITE)) { 2135 error = EPERM; 2136 break; 2137 } 2138 error = copyin((const void *)addr, &usb_debug, sizeof(usb_debug)); 2139 break; 2140 2141 case USB_GET_CONFIG: { 2142 int index = f->udev->curr_config_index; 2143 error = copyout((const void *)&index, addr, sizeof(index)); 2144 break; 2145 } 2146 2147 case USB_SET_CONFIG: { 2148 int index; 2149 if (!((unsigned int)fflags & FWRITE)) { 2150 error = EPERM; 2151 break; 2152 } 2153 error = copyin((const void *)addr, &index, sizeof(index)); 2154 if (error) { 2155 break; 2156 } 2157 error = ugen_set_config(f, index); 2158 break; 2159 } 2160 2161 case USB_GET_ALTINTERFACE: { 2162 struct usb_alt_interface ai; 2163 error = copyin((const void *)u.addr, &ai, sizeof(struct usb_alt_interface)); 2164 if (error != ENOERR) { 2165 break; 2166 } 2167 u.ai = &ai; 2168 iface = usbd_get_iface(f->udev, 2169 u.ai->uai_interface_index); 2170 if (iface && iface->idesc) { 2171 u.ai->uai_alt_index = iface->alt_index; 2172 } else { 2173 error = EINVAL; 2174 } 2175 if (error == ENOERR) { 2176 error = copyout((const void *)&ai, addr, sizeof(struct usb_alt_interface)); 2177 } 2178 break; 2179 } 2180 2181 case USB_SET_ALTINTERFACE: { 2182 struct usb_alt_interface ai; 2183 if (!((unsigned int)fflags & FWRITE)) { 2184 error = EPERM; 2185 break; 2186 } 2187 error = copyin((const void *)u.addr, &ai, sizeof(struct usb_alt_interface)); 2188 if (error != ENOERR) { 2189 break; 2190 } 2191 u.ai = &ai; 2192 error = ugen_set_interface(f, 2193 u.ai->uai_interface_index, u.ai->uai_alt_index); 2194 break; 2195 } 2196 2197 case USB_GET_DEVICE_DESC: 2198 dtemp = usbd_get_device_descriptor(f->udev); 2199 if (!dtemp) { 2200 error = EIO; 2201 break; 2202 } 2203 error = copyout((const void *)dtemp, u.ddesc, sizeof(struct usb_device_descriptor)); 2204 break; 2205 2206 case USB_GET_CONFIG_DESC: 2207 ctemp = usbd_get_config_descriptor(f->udev); 2208 if (!ctemp) { 2209 error = EIO; 2210 break; 2211 } 2212 error = copyout((const void *)ctemp, u.cdesc, sizeof(struct usb_config_descriptor)); 2213 break; 2214 2215 case USB_GET_FULL_DESC: { 2216 struct usb_gen_descriptor ugd; 2217 error = copyin((const void *)u.addr, &ugd, sizeof(struct usb_gen_descriptor)); 2218 if (error != ENOERR) { 2219 break; 2220 } 2221 error = ugen_get_cdesc(f, &ugd); 2222 if (error != ENOERR) { 2223 break; 2224 } 2225 error = copyout((const void *)&ugd, addr, sizeof(struct usb_gen_descriptor)); 2226 break; 2227 } 2228 2229 case USB_GET_STRING_DESC: { 2230 struct usb_gen_descriptor ugd; 2231 error = copyin((const void *)u.addr, &ugd, sizeof(struct usb_gen_descriptor)); 2232 if (error != ENOERR) { 2233 break; 2234 } 2235 error = ugen_get_sdesc(f, &ugd); 2236 if (error != ENOERR) { 2237 break; 2238 } 2239 error = copyout((const void *)&ugd, addr, sizeof(struct usb_gen_descriptor)); 2240 break; 2241 } 2242 2243 case USB_GET_IFACE_DRIVER: { 2244 struct usb_gen_descriptor ugd; 2245 error = copyin((const void *)u.addr, &ugd, sizeof(struct usb_gen_descriptor)); 2246 if (error != ENOERR) { 2247 break; 2248 } 2249 error = ugen_get_iface_driver(f, &ugd); 2250 if (error != ENOERR) { 2251 break; 2252 } 2253 error = copyout((const void *)&ugd, addr, sizeof(struct usb_gen_descriptor)); 2254 break; 2255 } 2256 2257 case USB_REQUEST: 2258 case USB_DO_REQUEST: { 2259 struct usb_ctl_request ur; 2260 if (!((unsigned int)fflags & FWRITE)) { 2261 error = EPERM; 2262 break; 2263 } 2264 error = copyin((const void *)u.addr, &ur, sizeof(struct usb_ctl_request)); 2265 if (error != ENOERR) { 2266 break; 2267 } 2268 error = ugen_do_request(f, &ur); 2269 if (error != ENOERR) { 2270 break; 2271 } 2272 error = copyout((const void *)&ur, addr, sizeof(struct usb_ctl_request)); 2273 break; 2274 } 2275 2276 case USB_DEVICEINFO: 2277 case USB_GET_DEVICEINFO: { 2278 struct usb_device_info di; 2279 error = ugen_fill_deviceinfo(f, &di); 2280 if (error != ENOERR) { 2281 break; 2282 } 2283 error = copyout((const void *)&di, addr, sizeof(struct usb_device_info)); 2284 break; 2285 } 2286 2287 case USB_DEVICESTATS: { 2288 struct usb_device_stats stat; 2289 error = copyin((const void *)u.addr, &stat, sizeof(struct usb_device_stats)); 2290 if (error != ENOERR) { 2291 break; 2292 } 2293 u.stat = &stat; 2294 for (n = 0; n != 4; n++) { 2295 u.stat->uds_requests_fail[n] = 2296 f->udev->stats_err.uds_requests[n]; 2297 u.stat->uds_requests_ok[n] = 2298 f->udev->stats_ok.uds_requests[n]; 2299 } 2300 error = copyout((const void *)&stat, addr, sizeof(struct usb_device_stats)); 2301 break; 2302 } 2303 2304 case USB_DEVICEENUMERATE: 2305 error = ugen_re_enumerate(f); 2306 break; 2307 2308 case USB_GET_PLUGTIME: 2309 error = copyout((const void *)&f->udev->plugtime, u.ptime, sizeof(uint32_t)); 2310 break; 2311 2312 case USB_CLAIM_INTERFACE: 2313 case USB_RELEASE_INTERFACE: 2314 /* TODO */ 2315 break; 2316 2317 case USB_IFACE_DRIVER_ACTIVE: { 2318 int pint; 2319 error = copyin((const void *)u.pint, &pint, sizeof(pint)); 2320 if (error != ENOERR) { 2321 break; 2322 } 2323 n = pint & 0xFF; 2324 2325 iface = usbd_get_iface(f->udev, n); 2326 2327 if (iface && iface->subdev) 2328 error = 0; 2329 else 2330 error = ENXIO; 2331 break; 2332 } 2333 2334 case USB_IFACE_DRIVER_DETACH: { 2335 int pint; 2336 error = priv_check(curthread, PRIV_DRIVER); 2337 2338 if (error) 2339 break; 2340 2341 error = copyin((const void *)u.pint, &pint, sizeof(pint)); 2342 if (error != ENOERR) { 2343 break; 2344 } 2345 n = pint & 0xFF; 2346 2347 if (n == USB_IFACE_INDEX_ANY) { 2348 error = EINVAL; 2349 break; 2350 } 2351 2352 /* 2353 * Detach the currently attached driver. 2354 */ 2355 usb_detach_device(f->udev, n, 0); 2356 2357 /* 2358 * Set parent to self, this should keep attach away 2359 * until the next set configuration event. 2360 */ 2361 usbd_set_parent_iface(f->udev, n, n); 2362 break; 2363 } 2364 2365 case USB_SET_POWER_MODE: { 2366 int mode; 2367 error = copyin((const void *)u.pint, &mode, sizeof(mode)); 2368 if (error != ENOERR) { 2369 break; 2370 } 2371 error = ugen_set_power_mode(f, mode); 2372 break; 2373 } 2374 2375 case USB_GET_POWER_MODE: { 2376 int mode = ugen_get_power_mode(f); 2377 error = copyout((const void *)&mode, u.pint, sizeof(mode)); 2378 break; 2379 } 2380 2381 case USB_GET_DEV_PORT_PATH: { 2382 struct usb_device_port_path dpp; 2383 error = copyin((const void *)u.dpp, &dpp, sizeof(struct usb_device_port_path)); 2384 if (error != ENOERR) { 2385 break; 2386 } 2387 error = ugen_get_port_path(f, &dpp); 2388 if (error != ENOERR) { 2389 break; 2390 } 2391 error = copyout((const void *)&dpp, u.dpp, sizeof(struct usb_device_port_path)); 2392 break; 2393 } 2394 2395 case USB_GET_POWER_USAGE: { 2396 int usage = ugen_get_power_usage(f); 2397 error = copyout((const void *)&usage, u.pint, sizeof(usage)); 2398 break; 2399 } 2400 2401 case USB_SET_PORT_ENABLE: { 2402 int port; 2403 error = copyin((const void *)u.pint, &port, sizeof(port)); 2404 if (error != ENOERR) { 2405 break; 2406 } 2407 error = ugen_do_port_feature(f, 2408 port, 1, UHF_PORT_ENABLE); 2409 break; 2410 } 2411 2412 case USB_SET_PORT_DISABLE: { 2413 int port; 2414 error = copyin((const void *)u.pint, &port, sizeof(port)); 2415 if (error != ENOERR) { 2416 break; 2417 } 2418 error = ugen_do_port_feature(f, 2419 port, 0, UHF_PORT_ENABLE); 2420 break; 2421 } 2422 2423 case USB_FS_INIT: { 2424 /* verify input parameters */ 2425 struct usb_fs_init init; 2426 error = copyin((const void *)u.addr, &init, sizeof(struct usb_fs_init)); 2427 if (error != ENOERR) { 2428 break; 2429 } 2430 u.pinit = &init; 2431 if (u.pinit->pEndpoints == NULL) { 2432 error = EINVAL; 2433 break; 2434 } 2435 if (u.pinit->ep_index_max > 127) { 2436 error = EINVAL; 2437 break; 2438 } 2439 if (u.pinit->ep_index_max == 0) { 2440 error = EINVAL; 2441 break; 2442 } 2443 if (f->fs_xfer != NULL) { 2444 error = EBUSY; 2445 break; 2446 } 2447 if (f->dev_ep_index != 0) { 2448 error = EINVAL; 2449 break; 2450 } 2451 if (ugen_fifo_in_use(f, fflags)) { 2452 error = EBUSY; 2453 break; 2454 } 2455 error = usb_fifo_alloc_buffer(f, 1, u.pinit->ep_index_max); 2456 if (error) { 2457 break; 2458 } 2459 f->fs_xfer = bsd_malloc(sizeof(f->fs_xfer[0]) * 2460 u.pinit->ep_index_max, M_USB, M_WAITOK | M_ZERO); 2461 if (f->fs_xfer == NULL) { 2462 usb_fifo_free_buffer(f); 2463 error = ENOMEM; 2464 break; 2465 } 2466 f->fs_ep_max = u.pinit->ep_index_max; 2467 f->fs_ep_ptr = u.pinit->pEndpoints; 2468 break; 2469 } 2470 2471 case USB_FS_UNINIT: { 2472 struct usb_fs_uninit uninit; 2473 error = copyin((const void *)u.addr, &uninit, sizeof(struct usb_fs_uninit)); 2474 if (error != ENOERR) { 2475 break; 2476 } 2477 u.puninit = &uninit; 2478 if (u.puninit->dummy != 0) { 2479 error = EINVAL; 2480 break; 2481 } 2482 error = ugen_fs_uninit(f); 2483 break; 2484 } 2485 2486 default: 2487 mtx_lock(f->priv_mtx); 2488 error = ugen_iface_ioctl(f, cmd, addr, fflags); 2489 mtx_unlock(f->priv_mtx); 2490 break; 2491 } 2492 DPRINTFN(6, "error=%d\n", error); 2493 return (error); 2494} 2495 2496static void 2497ugen_ctrl_fs_callback(struct usb_xfer *xfer, usb_error_t error) 2498{ 2499 ; /* workaround for a bug in "indent" */ 2500 2501 DPRINTF("st=%u alen=%u aframes=%u\n", 2502 USB_GET_STATE(xfer), xfer->actlen, xfer->aframes); 2503 2504 switch (USB_GET_STATE(xfer)) { 2505 case USB_ST_SETUP: 2506 usbd_transfer_submit(xfer); 2507 break; 2508 default: 2509 ugen_fs_set_complete(xfer->priv_sc, USB_P2U(xfer->priv_fifo)); 2510 break; 2511 } 2512} 2513#endif /* USB_HAVE_UGEN */ 2514