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