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