1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4 * 5 * Copyright (c) 2007 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 /* 30 * This file contains sub-routines to build up USB descriptors from 31 * USB templates. 32 */ 33 34 #ifdef USB_GLOBAL_INCLUDE_FILE 35 #include USB_GLOBAL_INCLUDE_FILE 36 #else 37 #include <sys/stdint.h> 38 #include <sys/stddef.h> 39 #include <sys/param.h> 40 #include <sys/queue.h> 41 #include <sys/types.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/bus.h> 45 #include <sys/module.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <sys/condvar.h> 49 #include <sys/sysctl.h> 50 #include <sys/sx.h> 51 #include <sys/unistd.h> 52 #include <sys/callout.h> 53 #include <sys/malloc.h> 54 #include <sys/priv.h> 55 56 #include <dev/usb/usb.h> 57 #include <dev/usb/usb_ioctl.h> 58 #include <dev/usb/usbdi.h> 59 #include <dev/usb/usbdi_util.h> 60 #include "usbdevs.h" 61 62 #include <dev/usb/usb_cdc.h> 63 #include <dev/usb/usb_core.h> 64 #include <dev/usb/usb_dynamic.h> 65 #include <dev/usb/usb_busdma.h> 66 #include <dev/usb/usb_process.h> 67 #include <dev/usb/usb_device.h> 68 #include <dev/usb/usb_util.h> 69 70 #define USB_DEBUG_VAR usb_debug 71 #include <dev/usb/usb_debug.h> 72 73 #include <dev/usb/usb_controller.h> 74 #include <dev/usb/usb_bus.h> 75 #include <dev/usb/usb_request.h> 76 #include <dev/usb/template/usb_template.h> 77 #endif /* USB_GLOBAL_INCLUDE_FILE */ 78 79 SYSCTL_NODE(_hw_usb, OID_AUTO, templates, CTLFLAG_RW, 0, 80 "USB device side templates"); 81 82 MODULE_DEPEND(usb_template, usb, 1, 1, 1); 83 MODULE_VERSION(usb_template, 1); 84 85 /* function prototypes */ 86 87 static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *); 88 static void usb_make_endpoint_desc(struct usb_temp_setup *, 89 const struct usb_temp_endpoint_desc *); 90 static void usb_make_interface_desc(struct usb_temp_setup *, 91 const struct usb_temp_interface_desc *); 92 static void usb_make_config_desc(struct usb_temp_setup *, 93 const struct usb_temp_config_desc *); 94 static void usb_make_device_desc(struct usb_temp_setup *, 95 const struct usb_temp_device_desc *); 96 static uint8_t usb_hw_ep_match(const struct usb_hw_ep_profile *, uint8_t, 97 uint8_t); 98 static uint8_t usb_hw_ep_find_match(struct usb_hw_ep_scratch *, 99 struct usb_hw_ep_scratch_sub *, uint8_t); 100 static uint8_t usb_hw_ep_get_needs(struct usb_hw_ep_scratch *, uint8_t, 101 uint8_t); 102 static usb_error_t usb_hw_ep_resolve(struct usb_device *, 103 struct usb_descriptor *); 104 static const struct usb_temp_device_desc *usb_temp_get_tdd(struct usb_device *); 105 static void *usb_temp_get_device_desc(struct usb_device *); 106 static void *usb_temp_get_qualifier_desc(struct usb_device *); 107 static void *usb_temp_get_config_desc(struct usb_device *, uint16_t *, 108 uint8_t); 109 static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t, 110 uint8_t); 111 static const void *usb_temp_get_vendor_desc(struct usb_device *, 112 const struct usb_device_request *, uint16_t *plen); 113 static const void *usb_temp_get_hub_desc(struct usb_device *); 114 static usb_error_t usb_temp_get_desc(struct usb_device *, 115 struct usb_device_request *, const void **, uint16_t *); 116 static usb_error_t usb_temp_setup_by_index(struct usb_device *, 117 uint16_t index); 118 static void usb_temp_init(void *); 119 120 /*------------------------------------------------------------------------* 121 * usb_decode_str_desc 122 * 123 * Helper function to decode string descriptors into a C string. 124 *------------------------------------------------------------------------*/ 125 void 126 usb_decode_str_desc(struct usb_string_descriptor *sd, char *buf, size_t buflen) 127 { 128 size_t i; 129 130 for (i = 0; i < buflen - 1 && i < sd->bLength / 2; i++) 131 buf[i] = UGETW(sd->bString[i]); 132 133 buf[i] = '\0'; 134 } 135 136 /*------------------------------------------------------------------------* 137 * usb_temp_sysctl 138 * 139 * Callback for SYSCTL_PROC(9), to set and retrieve template string 140 * descriptors. 141 *------------------------------------------------------------------------*/ 142 int 143 usb_temp_sysctl(SYSCTL_HANDLER_ARGS) 144 { 145 char buf[128]; 146 struct usb_string_descriptor *sd = arg1; 147 size_t len, sdlen = arg2; 148 int error; 149 150 usb_decode_str_desc(sd, buf, sizeof(buf)); 151 152 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 153 if (error != 0 || req->newptr == NULL) 154 return (error); 155 156 len = usb_make_str_desc(sd, sdlen, buf); 157 if (len == 0) 158 return (EINVAL); 159 160 return (0); 161 } 162 163 164 /*------------------------------------------------------------------------* 165 * usb_make_raw_desc 166 * 167 * This function will insert a raw USB descriptor into the generated 168 * USB configuration. 169 *------------------------------------------------------------------------*/ 170 static void 171 usb_make_raw_desc(struct usb_temp_setup *temp, 172 const uint8_t *raw) 173 { 174 void *dst; 175 uint8_t len; 176 177 /* 178 * The first byte of any USB descriptor gives the length. 179 */ 180 if (raw) { 181 len = raw[0]; 182 if (temp->buf) { 183 dst = USB_ADD_BYTES(temp->buf, temp->size); 184 memcpy(dst, raw, len); 185 186 /* check if we have got a CDC union descriptor */ 187 188 if ((raw[0] == sizeof(struct usb_cdc_union_descriptor)) && 189 (raw[1] == UDESC_CS_INTERFACE) && 190 (raw[2] == UDESCSUB_CDC_UNION)) { 191 struct usb_cdc_union_descriptor *ud = (void *)dst; 192 193 /* update the interface numbers */ 194 195 ud->bMasterInterface += 196 temp->bInterfaceNumber; 197 ud->bSlaveInterface[0] += 198 temp->bInterfaceNumber; 199 } 200 201 /* check if we have got an interface association descriptor */ 202 203 if ((raw[0] == sizeof(struct usb_interface_assoc_descriptor)) && 204 (raw[1] == UDESC_IFACE_ASSOC)) { 205 struct usb_interface_assoc_descriptor *iad = (void *)dst; 206 207 /* update the interface number */ 208 209 iad->bFirstInterface += 210 temp->bInterfaceNumber; 211 } 212 213 /* check if we have got a call management descriptor */ 214 215 if ((raw[0] == sizeof(struct usb_cdc_cm_descriptor)) && 216 (raw[1] == UDESC_CS_INTERFACE) && 217 (raw[2] == UDESCSUB_CDC_CM)) { 218 struct usb_cdc_cm_descriptor *ccd = (void *)dst; 219 220 /* update the interface number */ 221 222 ccd->bDataInterface += 223 temp->bInterfaceNumber; 224 } 225 } 226 temp->size += len; 227 } 228 } 229 230 /*------------------------------------------------------------------------* 231 * usb_make_endpoint_desc 232 * 233 * This function will generate an USB endpoint descriptor from the 234 * given USB template endpoint descriptor, which will be inserted into 235 * the USB configuration. 236 *------------------------------------------------------------------------*/ 237 static void 238 usb_make_endpoint_desc(struct usb_temp_setup *temp, 239 const struct usb_temp_endpoint_desc *ted) 240 { 241 struct usb_endpoint_descriptor *ed; 242 const void **rd; 243 uint16_t old_size; 244 uint16_t mps; 245 uint8_t ea; /* Endpoint Address */ 246 uint8_t et; /* Endpiont Type */ 247 248 /* Reserve memory */ 249 old_size = temp->size; 250 251 ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT)); 252 et = (ted->bmAttributes & UE_XFERTYPE); 253 254 if (et == UE_ISOCHRONOUS) { 255 /* account for extra byte fields */ 256 temp->size += sizeof(*ed) + 2; 257 } else { 258 temp->size += sizeof(*ed); 259 } 260 261 /* Scan all Raw Descriptors first */ 262 rd = ted->ppRawDesc; 263 if (rd) { 264 while (*rd) { 265 usb_make_raw_desc(temp, *rd); 266 rd++; 267 } 268 } 269 if (ted->pPacketSize == NULL) { 270 /* not initialized */ 271 temp->err = USB_ERR_INVAL; 272 return; 273 } 274 mps = ted->pPacketSize->mps[temp->usb_speed]; 275 if (mps == 0) { 276 /* not initialized */ 277 temp->err = USB_ERR_INVAL; 278 return; 279 } else if (mps == UE_ZERO_MPS) { 280 /* escape for Zero Max Packet Size */ 281 mps = 0; 282 } 283 284 /* 285 * Fill out the real USB endpoint descriptor 286 * in case there is a buffer present: 287 */ 288 if (temp->buf) { 289 ed = USB_ADD_BYTES(temp->buf, old_size); 290 if (et == UE_ISOCHRONOUS) 291 ed->bLength = sizeof(*ed) + 2; 292 else 293 ed->bLength = sizeof(*ed); 294 ed->bDescriptorType = UDESC_ENDPOINT; 295 ed->bEndpointAddress = ea; 296 ed->bmAttributes = ted->bmAttributes; 297 USETW(ed->wMaxPacketSize, mps); 298 299 /* setup bInterval parameter */ 300 301 if (ted->pIntervals && 302 ted->pIntervals->bInterval[temp->usb_speed]) { 303 ed->bInterval = 304 ted->pIntervals->bInterval[temp->usb_speed]; 305 } else { 306 switch (et) { 307 case UE_BULK: 308 case UE_CONTROL: 309 ed->bInterval = 0; /* not used */ 310 break; 311 case UE_INTERRUPT: 312 switch (temp->usb_speed) { 313 case USB_SPEED_LOW: 314 case USB_SPEED_FULL: 315 ed->bInterval = 1; /* 1 ms */ 316 break; 317 default: 318 ed->bInterval = 4; /* 1 ms */ 319 break; 320 } 321 break; 322 default: /* UE_ISOCHRONOUS */ 323 switch (temp->usb_speed) { 324 case USB_SPEED_LOW: 325 case USB_SPEED_FULL: 326 ed->bInterval = 1; /* 1 ms */ 327 break; 328 default: 329 ed->bInterval = 1; /* 125 us */ 330 break; 331 } 332 break; 333 } 334 } 335 } 336 temp->bNumEndpoints++; 337 } 338 339 /*------------------------------------------------------------------------* 340 * usb_make_interface_desc 341 * 342 * This function will generate an USB interface descriptor from the 343 * given USB template interface descriptor, which will be inserted 344 * into the USB configuration. 345 *------------------------------------------------------------------------*/ 346 static void 347 usb_make_interface_desc(struct usb_temp_setup *temp, 348 const struct usb_temp_interface_desc *tid) 349 { 350 struct usb_interface_descriptor *id; 351 const struct usb_temp_endpoint_desc **ted; 352 const void **rd; 353 uint16_t old_size; 354 355 /* Reserve memory */ 356 357 old_size = temp->size; 358 temp->size += sizeof(*id); 359 360 /* Update interface and alternate interface numbers */ 361 362 if (tid->isAltInterface == 0) { 363 temp->bAlternateSetting = 0; 364 temp->bInterfaceNumber++; 365 } else { 366 temp->bAlternateSetting++; 367 } 368 369 /* Scan all Raw Descriptors first */ 370 371 rd = tid->ppRawDesc; 372 373 if (rd) { 374 while (*rd) { 375 usb_make_raw_desc(temp, *rd); 376 rd++; 377 } 378 } 379 /* Reset some counters */ 380 381 temp->bNumEndpoints = 0; 382 383 /* Scan all Endpoint Descriptors second */ 384 385 ted = tid->ppEndpoints; 386 if (ted) { 387 while (*ted) { 388 usb_make_endpoint_desc(temp, *ted); 389 ted++; 390 } 391 } 392 /* 393 * Fill out the real USB interface descriptor 394 * in case there is a buffer present: 395 */ 396 if (temp->buf) { 397 id = USB_ADD_BYTES(temp->buf, old_size); 398 id->bLength = sizeof(*id); 399 id->bDescriptorType = UDESC_INTERFACE; 400 id->bInterfaceNumber = temp->bInterfaceNumber; 401 id->bAlternateSetting = temp->bAlternateSetting; 402 id->bNumEndpoints = temp->bNumEndpoints; 403 id->bInterfaceClass = tid->bInterfaceClass; 404 id->bInterfaceSubClass = tid->bInterfaceSubClass; 405 id->bInterfaceProtocol = tid->bInterfaceProtocol; 406 id->iInterface = tid->iInterface; 407 } 408 } 409 410 /*------------------------------------------------------------------------* 411 * usb_make_config_desc 412 * 413 * This function will generate an USB config descriptor from the given 414 * USB template config descriptor, which will be inserted into the USB 415 * configuration. 416 *------------------------------------------------------------------------*/ 417 static void 418 usb_make_config_desc(struct usb_temp_setup *temp, 419 const struct usb_temp_config_desc *tcd) 420 { 421 struct usb_config_descriptor *cd; 422 const struct usb_temp_interface_desc **tid; 423 uint16_t old_size; 424 425 /* Reserve memory */ 426 427 old_size = temp->size; 428 temp->size += sizeof(*cd); 429 430 /* Reset some counters */ 431 432 temp->bInterfaceNumber = 0xFF; 433 temp->bAlternateSetting = 0; 434 435 /* Scan all the USB interfaces */ 436 437 tid = tcd->ppIfaceDesc; 438 if (tid) { 439 while (*tid) { 440 usb_make_interface_desc(temp, *tid); 441 tid++; 442 } 443 } 444 /* 445 * Fill out the real USB config descriptor 446 * in case there is a buffer present: 447 */ 448 if (temp->buf) { 449 cd = USB_ADD_BYTES(temp->buf, old_size); 450 451 /* compute total size */ 452 old_size = temp->size - old_size; 453 454 cd->bLength = sizeof(*cd); 455 cd->bDescriptorType = UDESC_CONFIG; 456 USETW(cd->wTotalLength, old_size); 457 cd->bNumInterface = temp->bInterfaceNumber + 1; 458 cd->bConfigurationValue = temp->bConfigurationValue; 459 cd->iConfiguration = tcd->iConfiguration; 460 cd->bmAttributes = tcd->bmAttributes; 461 cd->bMaxPower = tcd->bMaxPower; 462 cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED); 463 464 if (temp->self_powered) { 465 cd->bmAttributes |= UC_SELF_POWERED; 466 } else { 467 cd->bmAttributes &= ~UC_SELF_POWERED; 468 } 469 } 470 } 471 472 /*------------------------------------------------------------------------* 473 * usb_make_device_desc 474 * 475 * This function will generate an USB device descriptor from the 476 * given USB template device descriptor. 477 *------------------------------------------------------------------------*/ 478 static void 479 usb_make_device_desc(struct usb_temp_setup *temp, 480 const struct usb_temp_device_desc *tdd) 481 { 482 struct usb_temp_data *utd; 483 const struct usb_temp_config_desc **tcd; 484 uint16_t old_size; 485 486 /* Reserve memory */ 487 488 old_size = temp->size; 489 temp->size += sizeof(*utd); 490 491 /* Scan all the USB configs */ 492 493 temp->bConfigurationValue = 1; 494 tcd = tdd->ppConfigDesc; 495 if (tcd) { 496 while (*tcd) { 497 usb_make_config_desc(temp, *tcd); 498 temp->bConfigurationValue++; 499 tcd++; 500 } 501 } 502 /* 503 * Fill out the real USB device descriptor 504 * in case there is a buffer present: 505 */ 506 507 if (temp->buf) { 508 utd = USB_ADD_BYTES(temp->buf, old_size); 509 510 /* Store a pointer to our template device descriptor */ 511 utd->tdd = tdd; 512 513 /* Fill out USB device descriptor */ 514 utd->udd.bLength = sizeof(utd->udd); 515 utd->udd.bDescriptorType = UDESC_DEVICE; 516 utd->udd.bDeviceClass = tdd->bDeviceClass; 517 utd->udd.bDeviceSubClass = tdd->bDeviceSubClass; 518 utd->udd.bDeviceProtocol = tdd->bDeviceProtocol; 519 USETW(utd->udd.idVendor, tdd->idVendor); 520 USETW(utd->udd.idProduct, tdd->idProduct); 521 USETW(utd->udd.bcdDevice, tdd->bcdDevice); 522 utd->udd.iManufacturer = tdd->iManufacturer; 523 utd->udd.iProduct = tdd->iProduct; 524 utd->udd.iSerialNumber = tdd->iSerialNumber; 525 utd->udd.bNumConfigurations = temp->bConfigurationValue - 1; 526 527 /* 528 * Fill out the USB device qualifier. Pretend that we 529 * don't support any other speeds by setting 530 * "bNumConfigurations" equal to zero. That saves us 531 * generating an extra set of configuration 532 * descriptors. 533 */ 534 utd->udq.bLength = sizeof(utd->udq); 535 utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER; 536 utd->udq.bDeviceClass = tdd->bDeviceClass; 537 utd->udq.bDeviceSubClass = tdd->bDeviceSubClass; 538 utd->udq.bDeviceProtocol = tdd->bDeviceProtocol; 539 utd->udq.bNumConfigurations = 0; 540 USETW(utd->udq.bcdUSB, 0x0200); 541 utd->udq.bMaxPacketSize0 = 0; 542 543 switch (temp->usb_speed) { 544 case USB_SPEED_LOW: 545 USETW(utd->udd.bcdUSB, 0x0110); 546 utd->udd.bMaxPacketSize = 8; 547 break; 548 case USB_SPEED_FULL: 549 USETW(utd->udd.bcdUSB, 0x0110); 550 utd->udd.bMaxPacketSize = 32; 551 break; 552 case USB_SPEED_HIGH: 553 USETW(utd->udd.bcdUSB, 0x0200); 554 utd->udd.bMaxPacketSize = 64; 555 break; 556 case USB_SPEED_VARIABLE: 557 USETW(utd->udd.bcdUSB, 0x0250); 558 utd->udd.bMaxPacketSize = 255; /* 512 bytes */ 559 break; 560 case USB_SPEED_SUPER: 561 USETW(utd->udd.bcdUSB, 0x0300); 562 utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */ 563 break; 564 default: 565 temp->err = USB_ERR_INVAL; 566 break; 567 } 568 } 569 } 570 571 /*------------------------------------------------------------------------* 572 * usb_hw_ep_match 573 * 574 * Return values: 575 * 0: The endpoint profile does not match the criteria 576 * Else: The endpoint profile matches the criteria 577 *------------------------------------------------------------------------*/ 578 static uint8_t 579 usb_hw_ep_match(const struct usb_hw_ep_profile *pf, 580 uint8_t ep_type, uint8_t ep_dir_in) 581 { 582 if (ep_type == UE_CONTROL) { 583 /* special */ 584 return (pf->support_control); 585 } 586 if ((pf->support_in && ep_dir_in) || 587 (pf->support_out && !ep_dir_in)) { 588 if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) || 589 (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) || 590 (pf->support_bulk && (ep_type == UE_BULK))) { 591 return (1); 592 } 593 } 594 return (0); 595 } 596 597 /*------------------------------------------------------------------------* 598 * usb_hw_ep_find_match 599 * 600 * This function is used to find the best matching endpoint profile 601 * for and endpoint belonging to an USB descriptor. 602 * 603 * Return values: 604 * 0: Success. Got a match. 605 * Else: Failure. No match. 606 *------------------------------------------------------------------------*/ 607 static uint8_t 608 usb_hw_ep_find_match(struct usb_hw_ep_scratch *ues, 609 struct usb_hw_ep_scratch_sub *ep, uint8_t is_simplex) 610 { 611 const struct usb_hw_ep_profile *pf; 612 uint16_t distance; 613 uint16_t temp; 614 uint16_t max_frame_size; 615 uint8_t n; 616 uint8_t best_n; 617 uint8_t dir_in; 618 uint8_t dir_out; 619 620 distance = 0xFFFF; 621 best_n = 0; 622 623 if ((!ep->needs_in) && (!ep->needs_out)) { 624 return (0); /* we are done */ 625 } 626 if (ep->needs_ep_type == UE_CONTROL) { 627 dir_in = 1; 628 dir_out = 1; 629 } else { 630 if (ep->needs_in) { 631 dir_in = 1; 632 dir_out = 0; 633 } else { 634 dir_in = 0; 635 dir_out = 1; 636 } 637 } 638 639 for (n = 1; n != (USB_EP_MAX / 2); n++) { 640 641 /* get HW endpoint profile */ 642 (ues->methods->get_hw_ep_profile) (ues->udev, &pf, n); 643 if (pf == NULL) { 644 /* end of profiles */ 645 break; 646 } 647 /* check if IN-endpoint is reserved */ 648 if (dir_in || pf->is_simplex) { 649 if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) { 650 /* mismatch */ 651 continue; 652 } 653 } 654 /* check if OUT-endpoint is reserved */ 655 if (dir_out || pf->is_simplex) { 656 if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) { 657 /* mismatch */ 658 continue; 659 } 660 } 661 /* check simplex */ 662 if (pf->is_simplex == is_simplex) { 663 /* mismatch */ 664 continue; 665 } 666 /* check if HW endpoint matches */ 667 if (!usb_hw_ep_match(pf, ep->needs_ep_type, dir_in)) { 668 /* mismatch */ 669 continue; 670 } 671 /* get maximum frame size */ 672 if (dir_in) 673 max_frame_size = pf->max_in_frame_size; 674 else 675 max_frame_size = pf->max_out_frame_size; 676 677 /* check if we have a matching profile */ 678 if (max_frame_size >= ep->max_frame_size) { 679 temp = (max_frame_size - ep->max_frame_size); 680 if (distance > temp) { 681 distance = temp; 682 best_n = n; 683 ep->pf = pf; 684 } 685 } 686 } 687 688 /* see if we got a match */ 689 if (best_n != 0) { 690 /* get the correct profile */ 691 pf = ep->pf; 692 693 /* reserve IN-endpoint */ 694 if (dir_in) { 695 ues->bmInAlloc[best_n / 8] |= 696 (1 << (best_n % 8)); 697 ep->hw_endpoint_in = best_n | UE_DIR_IN; 698 ep->needs_in = 0; 699 } 700 /* reserve OUT-endpoint */ 701 if (dir_out) { 702 ues->bmOutAlloc[best_n / 8] |= 703 (1 << (best_n % 8)); 704 ep->hw_endpoint_out = best_n | UE_DIR_OUT; 705 ep->needs_out = 0; 706 } 707 return (0); /* got a match */ 708 } 709 return (1); /* failure */ 710 } 711 712 /*------------------------------------------------------------------------* 713 * usb_hw_ep_get_needs 714 * 715 * This function will figure out the type and number of endpoints 716 * which are needed for an USB configuration. 717 * 718 * Return values: 719 * 0: Success. 720 * Else: Failure. 721 *------------------------------------------------------------------------*/ 722 static uint8_t 723 usb_hw_ep_get_needs(struct usb_hw_ep_scratch *ues, 724 uint8_t ep_type, uint8_t is_complete) 725 { 726 const struct usb_hw_ep_profile *pf; 727 struct usb_hw_ep_scratch_sub *ep_iface; 728 struct usb_hw_ep_scratch_sub *ep_curr; 729 struct usb_hw_ep_scratch_sub *ep_max; 730 struct usb_hw_ep_scratch_sub *ep_end; 731 struct usb_descriptor *desc; 732 struct usb_interface_descriptor *id; 733 struct usb_endpoint_descriptor *ed; 734 enum usb_dev_speed speed; 735 uint16_t wMaxPacketSize; 736 uint16_t temp; 737 uint8_t ep_no; 738 739 ep_iface = ues->ep_max; 740 ep_curr = ues->ep_max; 741 ep_end = ues->ep + USB_EP_MAX; 742 ep_max = ues->ep_max; 743 desc = NULL; 744 speed = usbd_get_speed(ues->udev); 745 746 repeat: 747 748 while ((desc = usb_desc_foreach(ues->cd, desc))) { 749 750 if ((desc->bDescriptorType == UDESC_INTERFACE) && 751 (desc->bLength >= sizeof(*id))) { 752 753 id = (void *)desc; 754 755 if (id->bAlternateSetting == 0) { 756 /* going forward */ 757 ep_iface = ep_max; 758 } else { 759 /* reset */ 760 ep_curr = ep_iface; 761 } 762 } 763 if ((desc->bDescriptorType == UDESC_ENDPOINT) && 764 (desc->bLength >= sizeof(*ed))) { 765 766 ed = (void *)desc; 767 768 goto handle_endpoint_desc; 769 } 770 } 771 ues->ep_max = ep_max; 772 return (0); 773 774 handle_endpoint_desc: 775 temp = (ed->bmAttributes & UE_XFERTYPE); 776 777 if (temp == ep_type) { 778 779 if (ep_curr == ep_end) { 780 /* too many endpoints */ 781 return (1); /* failure */ 782 } 783 wMaxPacketSize = UGETW(ed->wMaxPacketSize); 784 if ((wMaxPacketSize & 0xF800) && 785 (speed == USB_SPEED_HIGH)) { 786 /* handle packet multiplier */ 787 temp = (wMaxPacketSize >> 11) & 3; 788 wMaxPacketSize &= 0x7FF; 789 if (temp == 1) { 790 wMaxPacketSize *= 2; 791 } else { 792 wMaxPacketSize *= 3; 793 } 794 } 795 /* 796 * Check if we have a fixed endpoint number, else the 797 * endpoint number is allocated dynamically: 798 */ 799 ep_no = (ed->bEndpointAddress & UE_ADDR); 800 if (ep_no != 0) { 801 802 /* get HW endpoint profile */ 803 (ues->methods->get_hw_ep_profile) 804 (ues->udev, &pf, ep_no); 805 if (pf == NULL) { 806 /* HW profile does not exist - failure */ 807 DPRINTFN(0, "Endpoint profile %u " 808 "does not exist\n", ep_no); 809 return (1); 810 } 811 /* reserve fixed endpoint number */ 812 if (ep_type == UE_CONTROL) { 813 ues->bmInAlloc[ep_no / 8] |= 814 (1 << (ep_no % 8)); 815 ues->bmOutAlloc[ep_no / 8] |= 816 (1 << (ep_no % 8)); 817 if ((pf->max_in_frame_size < wMaxPacketSize) || 818 (pf->max_out_frame_size < wMaxPacketSize)) { 819 DPRINTFN(0, "Endpoint profile %u " 820 "has too small buffer\n", ep_no); 821 return (1); 822 } 823 } else if (ed->bEndpointAddress & UE_DIR_IN) { 824 ues->bmInAlloc[ep_no / 8] |= 825 (1 << (ep_no % 8)); 826 if (pf->max_in_frame_size < wMaxPacketSize) { 827 DPRINTFN(0, "Endpoint profile %u " 828 "has too small buffer\n", ep_no); 829 return (1); 830 } 831 } else { 832 ues->bmOutAlloc[ep_no / 8] |= 833 (1 << (ep_no % 8)); 834 if (pf->max_out_frame_size < wMaxPacketSize) { 835 DPRINTFN(0, "Endpoint profile %u " 836 "has too small buffer\n", ep_no); 837 return (1); 838 } 839 } 840 } else if (is_complete) { 841 842 /* check if we have enough buffer space */ 843 if (wMaxPacketSize > 844 ep_curr->max_frame_size) { 845 return (1); /* failure */ 846 } 847 if (ed->bEndpointAddress & UE_DIR_IN) { 848 ed->bEndpointAddress = 849 ep_curr->hw_endpoint_in; 850 } else { 851 ed->bEndpointAddress = 852 ep_curr->hw_endpoint_out; 853 } 854 855 } else { 856 857 /* compute the maximum frame size */ 858 if (ep_curr->max_frame_size < wMaxPacketSize) { 859 ep_curr->max_frame_size = wMaxPacketSize; 860 } 861 if (temp == UE_CONTROL) { 862 ep_curr->needs_in = 1; 863 ep_curr->needs_out = 1; 864 } else { 865 if (ed->bEndpointAddress & UE_DIR_IN) { 866 ep_curr->needs_in = 1; 867 } else { 868 ep_curr->needs_out = 1; 869 } 870 } 871 ep_curr->needs_ep_type = ep_type; 872 } 873 874 ep_curr++; 875 if (ep_max < ep_curr) { 876 ep_max = ep_curr; 877 } 878 } 879 goto repeat; 880 } 881 882 /*------------------------------------------------------------------------* 883 * usb_hw_ep_resolve 884 * 885 * This function will try to resolve endpoint requirements by the 886 * given endpoint profiles that the USB hardware reports. 887 * 888 * Return values: 889 * 0: Success 890 * Else: Failure 891 *------------------------------------------------------------------------*/ 892 static usb_error_t 893 usb_hw_ep_resolve(struct usb_device *udev, 894 struct usb_descriptor *desc) 895 { 896 struct usb_hw_ep_scratch *ues; 897 struct usb_hw_ep_scratch_sub *ep; 898 const struct usb_hw_ep_profile *pf; 899 const struct usb_bus_methods *methods; 900 struct usb_device_descriptor *dd; 901 uint16_t mps; 902 903 if (desc == NULL) 904 return (USB_ERR_INVAL); 905 906 /* get bus methods */ 907 methods = udev->bus->methods; 908 909 if (methods->get_hw_ep_profile == NULL) 910 return (USB_ERR_INVAL); 911 912 if (desc->bDescriptorType == UDESC_DEVICE) { 913 914 if (desc->bLength < sizeof(*dd)) 915 return (USB_ERR_INVAL); 916 917 dd = (void *)desc; 918 919 /* get HW control endpoint 0 profile */ 920 (methods->get_hw_ep_profile) (udev, &pf, 0); 921 if (pf == NULL) { 922 return (USB_ERR_INVAL); 923 } 924 if (!usb_hw_ep_match(pf, UE_CONTROL, 0)) { 925 DPRINTFN(0, "Endpoint 0 does not " 926 "support control\n"); 927 return (USB_ERR_INVAL); 928 } 929 mps = dd->bMaxPacketSize; 930 931 if (udev->speed == USB_SPEED_FULL) { 932 /* 933 * We can optionally choose another packet size ! 934 */ 935 while (1) { 936 /* check if "mps" is ok */ 937 if (pf->max_in_frame_size >= mps) { 938 break; 939 } 940 /* reduce maximum packet size */ 941 mps /= 2; 942 943 /* check if "mps" is too small */ 944 if (mps < 8) { 945 return (USB_ERR_INVAL); 946 } 947 } 948 949 dd->bMaxPacketSize = mps; 950 951 } else { 952 /* We only have one choice */ 953 if (mps == 255) { 954 mps = 512; 955 } 956 /* Check if we support the specified wMaxPacketSize */ 957 if (pf->max_in_frame_size < mps) { 958 return (USB_ERR_INVAL); 959 } 960 } 961 return (0); /* success */ 962 } 963 if (desc->bDescriptorType != UDESC_CONFIG) 964 return (USB_ERR_INVAL); 965 if (desc->bLength < sizeof(*(ues->cd))) 966 return (USB_ERR_INVAL); 967 968 ues = udev->scratch.hw_ep_scratch; 969 970 memset(ues, 0, sizeof(*ues)); 971 972 ues->ep_max = ues->ep; 973 ues->cd = (void *)desc; 974 ues->methods = methods; 975 ues->udev = udev; 976 977 /* Get all the endpoints we need */ 978 979 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) || 980 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 0) || 981 usb_hw_ep_get_needs(ues, UE_CONTROL, 0) || 982 usb_hw_ep_get_needs(ues, UE_BULK, 0)) { 983 DPRINTFN(0, "Could not get needs\n"); 984 return (USB_ERR_INVAL); 985 } 986 for (ep = ues->ep; ep != ues->ep_max; ep++) { 987 988 while (ep->needs_in || ep->needs_out) { 989 990 /* 991 * First try to use a simplex endpoint. 992 * Then try to use a duplex endpoint. 993 */ 994 if (usb_hw_ep_find_match(ues, ep, 1) && 995 usb_hw_ep_find_match(ues, ep, 0)) { 996 DPRINTFN(0, "Could not find match\n"); 997 return (USB_ERR_INVAL); 998 } 999 } 1000 } 1001 1002 ues->ep_max = ues->ep; 1003 1004 /* Update all endpoint addresses */ 1005 1006 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) || 1007 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 1) || 1008 usb_hw_ep_get_needs(ues, UE_CONTROL, 1) || 1009 usb_hw_ep_get_needs(ues, UE_BULK, 1)) { 1010 DPRINTFN(0, "Could not update endpoint address\n"); 1011 return (USB_ERR_INVAL); 1012 } 1013 return (0); /* success */ 1014 } 1015 1016 /*------------------------------------------------------------------------* 1017 * usb_temp_get_tdd 1018 * 1019 * Returns: 1020 * NULL: No USB template device descriptor found. 1021 * Else: Pointer to the USB template device descriptor. 1022 *------------------------------------------------------------------------*/ 1023 static const struct usb_temp_device_desc * 1024 usb_temp_get_tdd(struct usb_device *udev) 1025 { 1026 if (udev->usb_template_ptr == NULL) { 1027 return (NULL); 1028 } 1029 return (udev->usb_template_ptr->tdd); 1030 } 1031 1032 /*------------------------------------------------------------------------* 1033 * usb_temp_get_device_desc 1034 * 1035 * Returns: 1036 * NULL: No USB device descriptor found. 1037 * Else: Pointer to USB device descriptor. 1038 *------------------------------------------------------------------------*/ 1039 static void * 1040 usb_temp_get_device_desc(struct usb_device *udev) 1041 { 1042 struct usb_device_descriptor *dd; 1043 1044 if (udev->usb_template_ptr == NULL) { 1045 return (NULL); 1046 } 1047 dd = &udev->usb_template_ptr->udd; 1048 if (dd->bDescriptorType != UDESC_DEVICE) { 1049 /* sanity check failed */ 1050 return (NULL); 1051 } 1052 return (dd); 1053 } 1054 1055 /*------------------------------------------------------------------------* 1056 * usb_temp_get_qualifier_desc 1057 * 1058 * Returns: 1059 * NULL: No USB device_qualifier descriptor found. 1060 * Else: Pointer to USB device_qualifier descriptor. 1061 *------------------------------------------------------------------------*/ 1062 static void * 1063 usb_temp_get_qualifier_desc(struct usb_device *udev) 1064 { 1065 struct usb_device_qualifier *dq; 1066 1067 if (udev->usb_template_ptr == NULL) { 1068 return (NULL); 1069 } 1070 dq = &udev->usb_template_ptr->udq; 1071 if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) { 1072 /* sanity check failed */ 1073 return (NULL); 1074 } 1075 return (dq); 1076 } 1077 1078 /*------------------------------------------------------------------------* 1079 * usb_temp_get_config_desc 1080 * 1081 * Returns: 1082 * NULL: No USB config descriptor found. 1083 * Else: Pointer to USB config descriptor having index "index". 1084 *------------------------------------------------------------------------*/ 1085 static void * 1086 usb_temp_get_config_desc(struct usb_device *udev, 1087 uint16_t *pLength, uint8_t index) 1088 { 1089 struct usb_device_descriptor *dd; 1090 struct usb_config_descriptor *cd; 1091 uint16_t temp; 1092 1093 if (udev->usb_template_ptr == NULL) { 1094 return (NULL); 1095 } 1096 dd = &udev->usb_template_ptr->udd; 1097 cd = (void *)(udev->usb_template_ptr + 1); 1098 1099 if (index >= dd->bNumConfigurations) { 1100 /* out of range */ 1101 return (NULL); 1102 } 1103 while (index--) { 1104 if (cd->bDescriptorType != UDESC_CONFIG) { 1105 /* sanity check failed */ 1106 return (NULL); 1107 } 1108 temp = UGETW(cd->wTotalLength); 1109 cd = USB_ADD_BYTES(cd, temp); 1110 } 1111 1112 if (pLength) { 1113 *pLength = UGETW(cd->wTotalLength); 1114 } 1115 return (cd); 1116 } 1117 1118 /*------------------------------------------------------------------------* 1119 * usb_temp_get_vendor_desc 1120 * 1121 * Returns: 1122 * NULL: No vendor descriptor found. 1123 * Else: Pointer to a vendor descriptor. 1124 *------------------------------------------------------------------------*/ 1125 static const void * 1126 usb_temp_get_vendor_desc(struct usb_device *udev, 1127 const struct usb_device_request *req, uint16_t *plen) 1128 { 1129 const struct usb_temp_device_desc *tdd; 1130 1131 tdd = usb_temp_get_tdd(udev); 1132 if (tdd == NULL) { 1133 return (NULL); 1134 } 1135 if (tdd->getVendorDesc == NULL) { 1136 return (NULL); 1137 } 1138 return ((tdd->getVendorDesc) (req, plen)); 1139 } 1140 1141 /*------------------------------------------------------------------------* 1142 * usb_temp_get_string_desc 1143 * 1144 * Returns: 1145 * NULL: No string descriptor found. 1146 * Else: Pointer to a string descriptor. 1147 *------------------------------------------------------------------------*/ 1148 static const void * 1149 usb_temp_get_string_desc(struct usb_device *udev, 1150 uint16_t lang_id, uint8_t string_index) 1151 { 1152 const struct usb_temp_device_desc *tdd; 1153 1154 tdd = usb_temp_get_tdd(udev); 1155 if (tdd == NULL) { 1156 return (NULL); 1157 } 1158 if (tdd->getStringDesc == NULL) { 1159 return (NULL); 1160 } 1161 return ((tdd->getStringDesc) (lang_id, string_index)); 1162 } 1163 1164 /*------------------------------------------------------------------------* 1165 * usb_temp_get_hub_desc 1166 * 1167 * Returns: 1168 * NULL: No USB HUB descriptor found. 1169 * Else: Pointer to a USB HUB descriptor. 1170 *------------------------------------------------------------------------*/ 1171 static const void * 1172 usb_temp_get_hub_desc(struct usb_device *udev) 1173 { 1174 return (NULL); /* needs to be implemented */ 1175 } 1176 1177 /*------------------------------------------------------------------------* 1178 * usb_temp_get_desc 1179 * 1180 * This function is a demultiplexer for local USB device side control 1181 * endpoint requests. 1182 *------------------------------------------------------------------------*/ 1183 static usb_error_t 1184 usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req, 1185 const void **pPtr, uint16_t *pLength) 1186 { 1187 const uint8_t *buf; 1188 uint16_t len; 1189 1190 buf = NULL; 1191 len = 0; 1192 1193 switch (req->bmRequestType) { 1194 case UT_READ_DEVICE: 1195 switch (req->bRequest) { 1196 case UR_GET_DESCRIPTOR: 1197 goto tr_handle_get_descriptor; 1198 default: 1199 goto tr_stalled; 1200 } 1201 case UT_READ_CLASS_DEVICE: 1202 switch (req->bRequest) { 1203 case UR_GET_DESCRIPTOR: 1204 goto tr_handle_get_class_descriptor; 1205 default: 1206 goto tr_stalled; 1207 } 1208 default: 1209 goto tr_stalled; 1210 } 1211 1212 tr_handle_get_descriptor: 1213 switch (req->wValue[1]) { 1214 case UDESC_DEVICE: 1215 if (req->wValue[0]) { 1216 goto tr_stalled; 1217 } 1218 buf = usb_temp_get_device_desc(udev); 1219 goto tr_valid; 1220 case UDESC_DEVICE_QUALIFIER: 1221 if (udev->speed != USB_SPEED_HIGH) { 1222 goto tr_stalled; 1223 } 1224 if (req->wValue[0]) { 1225 goto tr_stalled; 1226 } 1227 buf = usb_temp_get_qualifier_desc(udev); 1228 goto tr_valid; 1229 case UDESC_OTHER_SPEED_CONFIGURATION: 1230 if (udev->speed != USB_SPEED_HIGH) { 1231 goto tr_stalled; 1232 } 1233 case UDESC_CONFIG: 1234 buf = usb_temp_get_config_desc(udev, 1235 &len, req->wValue[0]); 1236 goto tr_valid; 1237 case UDESC_STRING: 1238 buf = usb_temp_get_string_desc(udev, 1239 UGETW(req->wIndex), req->wValue[0]); 1240 goto tr_valid; 1241 default: 1242 goto tr_stalled; 1243 } 1244 1245 tr_handle_get_class_descriptor: 1246 if (req->wValue[0]) { 1247 goto tr_stalled; 1248 } 1249 buf = usb_temp_get_hub_desc(udev); 1250 goto tr_valid; 1251 1252 tr_valid: 1253 if (buf == NULL) 1254 goto tr_stalled; 1255 if (len == 0) 1256 len = buf[0]; 1257 *pPtr = buf; 1258 *pLength = len; 1259 return (0); /* success */ 1260 1261 tr_stalled: 1262 /* try to get a vendor specific descriptor */ 1263 len = 0; 1264 buf = usb_temp_get_vendor_desc(udev, req, &len); 1265 if (buf != NULL) 1266 goto tr_valid; 1267 *pPtr = NULL; 1268 *pLength = 0; 1269 return (0); /* we ignore failures */ 1270 } 1271 1272 /*------------------------------------------------------------------------* 1273 * usb_temp_setup 1274 * 1275 * This function generates USB descriptors according to the given USB 1276 * template device descriptor. It will also try to figure out the best 1277 * matching endpoint addresses using the hardware endpoint profiles. 1278 * 1279 * Returns: 1280 * 0: Success 1281 * Else: Failure 1282 *------------------------------------------------------------------------*/ 1283 usb_error_t 1284 usb_temp_setup(struct usb_device *udev, 1285 const struct usb_temp_device_desc *tdd) 1286 { 1287 struct usb_temp_setup *uts; 1288 void *buf; 1289 usb_error_t error; 1290 uint8_t n; 1291 uint8_t do_unlock; 1292 1293 /* be NULL safe */ 1294 if (tdd == NULL) 1295 return (0); 1296 1297 /* Protect scratch area */ 1298 do_unlock = usbd_ctrl_lock(udev); 1299 1300 uts = udev->scratch.temp_setup; 1301 1302 memset(uts, 0, sizeof(*uts)); 1303 1304 uts->usb_speed = udev->speed; 1305 uts->self_powered = udev->flags.self_powered; 1306 1307 /* first pass */ 1308 1309 usb_make_device_desc(uts, tdd); 1310 1311 if (uts->err) { 1312 /* some error happened */ 1313 goto done; 1314 } 1315 /* sanity check */ 1316 if (uts->size == 0) { 1317 uts->err = USB_ERR_INVAL; 1318 goto done; 1319 } 1320 /* allocate zeroed memory */ 1321 uts->buf = usbd_alloc_config_desc(udev, uts->size); 1322 /* 1323 * Allow malloc() to return NULL regardless of M_WAITOK flag. 1324 * This helps when porting the software to non-FreeBSD 1325 * systems. 1326 */ 1327 if (uts->buf == NULL) { 1328 /* could not allocate memory */ 1329 uts->err = USB_ERR_NOMEM; 1330 goto done; 1331 } 1332 /* second pass */ 1333 1334 uts->size = 0; 1335 1336 usb_make_device_desc(uts, tdd); 1337 1338 /* 1339 * Store a pointer to our descriptors: 1340 */ 1341 udev->usb_template_ptr = uts->buf; 1342 1343 if (uts->err) { 1344 /* some error happened during second pass */ 1345 goto done; 1346 } 1347 /* 1348 * Resolve all endpoint addresses ! 1349 */ 1350 buf = usb_temp_get_device_desc(udev); 1351 uts->err = usb_hw_ep_resolve(udev, buf); 1352 if (uts->err) { 1353 DPRINTFN(0, "Could not resolve endpoints for " 1354 "Device Descriptor, error = %s\n", 1355 usbd_errstr(uts->err)); 1356 goto done; 1357 } 1358 for (n = 0;; n++) { 1359 1360 buf = usb_temp_get_config_desc(udev, NULL, n); 1361 if (buf == NULL) { 1362 break; 1363 } 1364 uts->err = usb_hw_ep_resolve(udev, buf); 1365 if (uts->err) { 1366 DPRINTFN(0, "Could not resolve endpoints for " 1367 "Config Descriptor %u, error = %s\n", n, 1368 usbd_errstr(uts->err)); 1369 goto done; 1370 } 1371 } 1372 done: 1373 error = uts->err; 1374 if (error) 1375 usb_temp_unsetup(udev); 1376 if (do_unlock) 1377 usbd_ctrl_unlock(udev); 1378 return (error); 1379 } 1380 1381 /*------------------------------------------------------------------------* 1382 * usb_temp_unsetup 1383 * 1384 * This function frees any memory associated with the currently 1385 * setup template, if any. 1386 *------------------------------------------------------------------------*/ 1387 void 1388 usb_temp_unsetup(struct usb_device *udev) 1389 { 1390 usbd_free_config_desc(udev, udev->usb_template_ptr); 1391 udev->usb_template_ptr = NULL; 1392 } 1393 1394 static usb_error_t 1395 usb_temp_setup_by_index(struct usb_device *udev, uint16_t index) 1396 { 1397 usb_error_t err; 1398 1399 switch (index) { 1400 case USB_TEMP_MSC: 1401 err = usb_temp_setup(udev, &usb_template_msc); 1402 break; 1403 case USB_TEMP_CDCE: 1404 err = usb_temp_setup(udev, &usb_template_cdce); 1405 break; 1406 case USB_TEMP_MTP: 1407 err = usb_temp_setup(udev, &usb_template_mtp); 1408 break; 1409 case USB_TEMP_MODEM: 1410 err = usb_temp_setup(udev, &usb_template_modem); 1411 break; 1412 case USB_TEMP_AUDIO: 1413 err = usb_temp_setup(udev, &usb_template_audio); 1414 break; 1415 case USB_TEMP_KBD: 1416 err = usb_temp_setup(udev, &usb_template_kbd); 1417 break; 1418 case USB_TEMP_MOUSE: 1419 err = usb_temp_setup(udev, &usb_template_mouse); 1420 break; 1421 case USB_TEMP_PHONE: 1422 err = usb_temp_setup(udev, &usb_template_phone); 1423 break; 1424 case USB_TEMP_SERIALNET: 1425 err = usb_temp_setup(udev, &usb_template_serialnet); 1426 break; 1427 case USB_TEMP_MIDI: 1428 err = usb_temp_setup(udev, &usb_template_midi); 1429 break; 1430 default: 1431 return (USB_ERR_INVAL); 1432 } 1433 1434 return (err); 1435 } 1436 1437 static void 1438 usb_temp_init(void *arg) 1439 { 1440 /* register our functions */ 1441 usb_temp_get_desc_p = &usb_temp_get_desc; 1442 usb_temp_setup_by_index_p = &usb_temp_setup_by_index; 1443 usb_temp_unsetup_p = &usb_temp_unsetup; 1444 } 1445 1446 SYSINIT(usb_temp_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_temp_init, NULL); 1447 SYSUNINIT(usb_temp_unload, SI_SUB_LOCK, SI_ORDER_ANY, usb_temp_unload, NULL); 1448