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