| .. | .. |
|---|
| 13 | 13 | #include <linux/module.h> |
|---|
| 14 | 14 | #include <linux/device.h> |
|---|
| 15 | 15 | #include <linux/utsname.h> |
|---|
| 16 | +#include <linux/bitfield.h> |
|---|
| 16 | 17 | |
|---|
| 17 | 18 | #include <linux/usb/composite.h> |
|---|
| 18 | 19 | #include <linux/usb/otg.h> |
|---|
| .. | .. |
|---|
| 72 | 73 | descriptors = f->ssp_descriptors; |
|---|
| 73 | 74 | if (descriptors) |
|---|
| 74 | 75 | break; |
|---|
| 75 | | - /* FALLTHROUGH */ |
|---|
| 76 | + fallthrough; |
|---|
| 76 | 77 | case USB_SPEED_SUPER: |
|---|
| 77 | 78 | descriptors = f->ss_descriptors; |
|---|
| 78 | 79 | if (descriptors) |
|---|
| 79 | 80 | break; |
|---|
| 80 | | - /* FALLTHROUGH */ |
|---|
| 81 | + fallthrough; |
|---|
| 81 | 82 | case USB_SPEED_HIGH: |
|---|
| 82 | 83 | descriptors = f->hs_descriptors; |
|---|
| 83 | 84 | if (descriptors) |
|---|
| 84 | 85 | break; |
|---|
| 85 | | - /* FALLTHROUGH */ |
|---|
| 86 | + fallthrough; |
|---|
| 86 | 87 | default: |
|---|
| 87 | 88 | descriptors = f->fs_descriptors; |
|---|
| 88 | 89 | } |
|---|
| .. | .. |
|---|
| 158 | 159 | int want_comp_desc = 0; |
|---|
| 159 | 160 | |
|---|
| 160 | 161 | struct usb_descriptor_header **d_spd; /* cursor for speed desc */ |
|---|
| 162 | + struct usb_composite_dev *cdev; |
|---|
| 163 | + bool incomplete_desc = false; |
|---|
| 161 | 164 | |
|---|
| 162 | 165 | if (!g || !f || !_ep) |
|---|
| 163 | 166 | return -EIO; |
|---|
| .. | .. |
|---|
| 166 | 169 | switch (g->speed) { |
|---|
| 167 | 170 | case USB_SPEED_SUPER_PLUS: |
|---|
| 168 | 171 | if (gadget_is_superspeed_plus(g)) { |
|---|
| 169 | | - speed_desc = f->ssp_descriptors; |
|---|
| 170 | | - want_comp_desc = 1; |
|---|
| 171 | | - break; |
|---|
| 172 | + if (f->ssp_descriptors) { |
|---|
| 173 | + speed_desc = f->ssp_descriptors; |
|---|
| 174 | + want_comp_desc = 1; |
|---|
| 175 | + break; |
|---|
| 176 | + } |
|---|
| 177 | + incomplete_desc = true; |
|---|
| 172 | 178 | } |
|---|
| 173 | | - /* fall through */ |
|---|
| 179 | + fallthrough; |
|---|
| 174 | 180 | case USB_SPEED_SUPER: |
|---|
| 175 | 181 | if (gadget_is_superspeed(g)) { |
|---|
| 176 | | - speed_desc = f->ss_descriptors; |
|---|
| 177 | | - want_comp_desc = 1; |
|---|
| 178 | | - break; |
|---|
| 182 | + if (f->ss_descriptors) { |
|---|
| 183 | + speed_desc = f->ss_descriptors; |
|---|
| 184 | + want_comp_desc = 1; |
|---|
| 185 | + break; |
|---|
| 186 | + } |
|---|
| 187 | + incomplete_desc = true; |
|---|
| 179 | 188 | } |
|---|
| 180 | | - /* fall through */ |
|---|
| 189 | + fallthrough; |
|---|
| 181 | 190 | case USB_SPEED_HIGH: |
|---|
| 182 | 191 | if (gadget_is_dualspeed(g)) { |
|---|
| 183 | | - speed_desc = f->hs_descriptors; |
|---|
| 184 | | - break; |
|---|
| 192 | + if (f->hs_descriptors) { |
|---|
| 193 | + speed_desc = f->hs_descriptors; |
|---|
| 194 | + break; |
|---|
| 195 | + } |
|---|
| 196 | + incomplete_desc = true; |
|---|
| 185 | 197 | } |
|---|
| 186 | | - /* fall through */ |
|---|
| 198 | + fallthrough; |
|---|
| 187 | 199 | default: |
|---|
| 188 | 200 | speed_desc = f->fs_descriptors; |
|---|
| 189 | 201 | } |
|---|
| 202 | + |
|---|
| 203 | + cdev = get_gadget_data(g); |
|---|
| 204 | + if (incomplete_desc) |
|---|
| 205 | + WARNING(cdev, |
|---|
| 206 | + "%s doesn't hold the descriptors for current speed\n", |
|---|
| 207 | + f->name); |
|---|
| 190 | 208 | |
|---|
| 191 | 209 | /* find correct alternate setting descriptor */ |
|---|
| 192 | 210 | for_each_desc(speed_desc, d_spd, USB_DT_INTERFACE) { |
|---|
| .. | .. |
|---|
| 237 | 255 | case USB_ENDPOINT_XFER_ISOC: |
|---|
| 238 | 256 | /* mult: bits 1:0 of bmAttributes */ |
|---|
| 239 | 257 | _ep->mult = (comp_desc->bmAttributes & 0x3) + 1; |
|---|
| 240 | | - /* fall through */ |
|---|
| 258 | + fallthrough; |
|---|
| 241 | 259 | case USB_ENDPOINT_XFER_BULK: |
|---|
| 242 | 260 | case USB_ENDPOINT_XFER_INT: |
|---|
| 243 | 261 | _ep->maxburst = comp_desc->bMaxBurst + 1; |
|---|
| 244 | 262 | break; |
|---|
| 245 | 263 | default: |
|---|
| 246 | | - if (comp_desc->bMaxBurst != 0) { |
|---|
| 247 | | - struct usb_composite_dev *cdev; |
|---|
| 248 | | - |
|---|
| 249 | | - cdev = get_gadget_data(g); |
|---|
| 264 | + if (comp_desc->bMaxBurst != 0) |
|---|
| 250 | 265 | ERROR(cdev, "ep0 bMaxBurst must be 0\n"); |
|---|
| 251 | | - } |
|---|
| 252 | 266 | _ep->maxburst = 1; |
|---|
| 253 | 267 | break; |
|---|
| 254 | 268 | } |
|---|
| .. | .. |
|---|
| 476 | 490 | } |
|---|
| 477 | 491 | EXPORT_SYMBOL_GPL(usb_interface_id); |
|---|
| 478 | 492 | |
|---|
| 479 | | -static int usb_func_wakeup_int(struct usb_function *func) |
|---|
| 480 | | -{ |
|---|
| 481 | | - int ret; |
|---|
| 482 | | - struct usb_gadget *gadget; |
|---|
| 483 | | - |
|---|
| 484 | | - if (!func || !func->config || !func->config->cdev || |
|---|
| 485 | | - !func->config->cdev->gadget) |
|---|
| 486 | | - return -EINVAL; |
|---|
| 487 | | - |
|---|
| 488 | | - pr_debug("%s - %s function wakeup\n", |
|---|
| 489 | | - __func__, func->name ? func->name : ""); |
|---|
| 490 | | - |
|---|
| 491 | | - gadget = func->config->cdev->gadget; |
|---|
| 492 | | - if ((gadget->speed != USB_SPEED_SUPER) || !func->func_wakeup_allowed) { |
|---|
| 493 | | - DBG(func->config->cdev, |
|---|
| 494 | | - "Function Wakeup is not possible. speed=%u, func_wakeup_allowed=%u\n", |
|---|
| 495 | | - gadget->speed, |
|---|
| 496 | | - func->func_wakeup_allowed); |
|---|
| 497 | | - |
|---|
| 498 | | - return -ENOTSUPP; |
|---|
| 499 | | - } |
|---|
| 500 | | - |
|---|
| 501 | | - ret = usb_gadget_func_wakeup(gadget, func->intf_id); |
|---|
| 502 | | - |
|---|
| 503 | | - return ret; |
|---|
| 504 | | -} |
|---|
| 505 | | - |
|---|
| 506 | | -/** |
|---|
| 507 | | - * usb_func_wakeup - wakes up a composite device function. |
|---|
| 508 | | - * @func: composite device function to wake up. |
|---|
| 509 | | - * |
|---|
| 510 | | - * Returns 0 on success or a negative error value. |
|---|
| 511 | | - */ |
|---|
| 512 | | -int usb_func_wakeup(struct usb_function *func) |
|---|
| 513 | | -{ |
|---|
| 514 | | - int ret; |
|---|
| 515 | | - unsigned long flags; |
|---|
| 516 | | - |
|---|
| 517 | | - if (!func || !func->config || !func->config->cdev) |
|---|
| 518 | | - return -EINVAL; |
|---|
| 519 | | - |
|---|
| 520 | | - pr_debug("%s function wakeup\n", |
|---|
| 521 | | - func->name ? func->name : ""); |
|---|
| 522 | | - |
|---|
| 523 | | - spin_lock_irqsave(&func->config->cdev->lock, flags); |
|---|
| 524 | | - ret = usb_func_wakeup_int(func); |
|---|
| 525 | | - if (ret == -EAGAIN) { |
|---|
| 526 | | - DBG(func->config->cdev, |
|---|
| 527 | | - "Function wakeup for %s could not complete due to suspend state. Delayed until after bus resume.\n", |
|---|
| 528 | | - func->name ? func->name : ""); |
|---|
| 529 | | - ret = 0; |
|---|
| 530 | | - } else if (ret < 0 && ret != -ENOTSUPP) { |
|---|
| 531 | | - ERROR(func->config->cdev, |
|---|
| 532 | | - "Failed to wake function %s from suspend state. ret=%d. Canceling USB request.\n", |
|---|
| 533 | | - func->name ? func->name : "", ret); |
|---|
| 534 | | - } |
|---|
| 535 | | - |
|---|
| 536 | | - spin_unlock_irqrestore(&func->config->cdev->lock, flags); |
|---|
| 537 | | - return ret; |
|---|
| 538 | | -} |
|---|
| 539 | | -EXPORT_SYMBOL_GPL(usb_func_wakeup); |
|---|
| 540 | | - |
|---|
| 541 | | -/** |
|---|
| 542 | | - * usb_func_ep_queue - queues (submits) an I/O request to a function endpoint. |
|---|
| 543 | | - * This function is similar to the usb_ep_queue function, but in addition it |
|---|
| 544 | | - * also checks whether the function is in Super Speed USB Function Suspend |
|---|
| 545 | | - * state, and if so a Function Wake notification is sent to the host |
|---|
| 546 | | - * (USB 3.0 spec, section 9.2.5.2). |
|---|
| 547 | | - * @func: the function which issues the USB I/O request. |
|---|
| 548 | | - * @ep:the endpoint associated with the request |
|---|
| 549 | | - * @req:the request being submitted |
|---|
| 550 | | - * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't |
|---|
| 551 | | - * pre-allocate all necessary memory with the request. |
|---|
| 552 | | - */ |
|---|
| 553 | | -int usb_func_ep_queue(struct usb_function *func, struct usb_ep *ep, |
|---|
| 554 | | - struct usb_request *req, gfp_t gfp_flags) |
|---|
| 555 | | -{ |
|---|
| 556 | | - int ret; |
|---|
| 557 | | - struct usb_gadget *gadget; |
|---|
| 558 | | - |
|---|
| 559 | | - if (!func || !func->config || !func->config->cdev || |
|---|
| 560 | | - !func->config->cdev->gadget || !ep || !req) { |
|---|
| 561 | | - ret = -EINVAL; |
|---|
| 562 | | - goto done; |
|---|
| 563 | | - } |
|---|
| 564 | | - |
|---|
| 565 | | - pr_debug("Function %s queueing new data into ep %u\n", |
|---|
| 566 | | - func->name ? func->name : "", ep->address); |
|---|
| 567 | | - |
|---|
| 568 | | - gadget = func->config->cdev->gadget; |
|---|
| 569 | | - if (func->func_is_suspended && func->func_wakeup_allowed) { |
|---|
| 570 | | - ret = usb_gadget_func_wakeup(gadget, func->intf_id); |
|---|
| 571 | | - if (ret == -EAGAIN) { |
|---|
| 572 | | - pr_debug("bus suspended func wakeup for %s delayed until bus resume.\n", |
|---|
| 573 | | - func->name ? func->name : ""); |
|---|
| 574 | | - } else if (ret < 0 && ret != -ENOTSUPP) { |
|---|
| 575 | | - pr_err("Failed to wake function %s from suspend state. ret=%d.\n", |
|---|
| 576 | | - func->name ? func->name : "", ret); |
|---|
| 577 | | - } |
|---|
| 578 | | - goto done; |
|---|
| 579 | | - } |
|---|
| 580 | | - |
|---|
| 581 | | - if (!func->func_is_suspended) |
|---|
| 582 | | - ret = 0; |
|---|
| 583 | | - |
|---|
| 584 | | - if (func->func_is_suspended && !func->func_wakeup_allowed) { |
|---|
| 585 | | - ret = -ENOTSUPP; |
|---|
| 586 | | - goto done; |
|---|
| 587 | | - } |
|---|
| 588 | | - |
|---|
| 589 | | - ret = usb_ep_queue(ep, req, gfp_flags); |
|---|
| 590 | | -done: |
|---|
| 591 | | - return ret; |
|---|
| 592 | | -} |
|---|
| 593 | | -EXPORT_SYMBOL_GPL(usb_func_ep_queue); |
|---|
| 594 | | - |
|---|
| 595 | 493 | static u8 encode_bMaxPower(enum usb_device_speed speed, |
|---|
| 596 | 494 | struct usb_configuration *c) |
|---|
| 597 | 495 | { |
|---|
| .. | .. |
|---|
| 780 | 678 | struct usb_ext_cap_descriptor *usb_ext; |
|---|
| 781 | 679 | struct usb_dcd_config_params dcd_config_params; |
|---|
| 782 | 680 | struct usb_bos_descriptor *bos = cdev->req->buf; |
|---|
| 681 | + unsigned int besl = 0; |
|---|
| 783 | 682 | |
|---|
| 784 | 683 | bos->bLength = USB_DT_BOS_SIZE; |
|---|
| 785 | 684 | bos->bDescriptorType = USB_DT_BOS; |
|---|
| 786 | 685 | |
|---|
| 787 | 686 | bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE); |
|---|
| 788 | 687 | bos->bNumDeviceCaps = 0; |
|---|
| 688 | + |
|---|
| 689 | + /* Get Controller configuration */ |
|---|
| 690 | + if (cdev->gadget->ops->get_config_params) { |
|---|
| 691 | + cdev->gadget->ops->get_config_params(cdev->gadget, |
|---|
| 692 | + &dcd_config_params); |
|---|
| 693 | + } else { |
|---|
| 694 | + dcd_config_params.besl_baseline = |
|---|
| 695 | + USB_DEFAULT_BESL_UNSPECIFIED; |
|---|
| 696 | + dcd_config_params.besl_deep = |
|---|
| 697 | + USB_DEFAULT_BESL_UNSPECIFIED; |
|---|
| 698 | + dcd_config_params.bU1devExitLat = |
|---|
| 699 | + USB_DEFAULT_U1_DEV_EXIT_LAT; |
|---|
| 700 | + dcd_config_params.bU2DevExitLat = |
|---|
| 701 | + cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT); |
|---|
| 702 | + } |
|---|
| 703 | + |
|---|
| 704 | + if (dcd_config_params.besl_baseline != USB_DEFAULT_BESL_UNSPECIFIED) |
|---|
| 705 | + besl = USB_BESL_BASELINE_VALID | |
|---|
| 706 | + USB_SET_BESL_BASELINE(dcd_config_params.besl_baseline); |
|---|
| 707 | + |
|---|
| 708 | + if (dcd_config_params.besl_deep != USB_DEFAULT_BESL_UNSPECIFIED) |
|---|
| 709 | + besl |= USB_BESL_DEEP_VALID | |
|---|
| 710 | + USB_SET_BESL_DEEP(dcd_config_params.besl_deep); |
|---|
| 789 | 711 | |
|---|
| 790 | 712 | /* |
|---|
| 791 | 713 | * A SuperSpeed device shall include the USB2.0 extension descriptor |
|---|
| .. | .. |
|---|
| 797 | 719 | usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; |
|---|
| 798 | 720 | usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; |
|---|
| 799 | 721 | usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; |
|---|
| 800 | | - usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | USB_BESL_SUPPORT); |
|---|
| 722 | + usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | |
|---|
| 723 | + USB_BESL_SUPPORT | besl); |
|---|
| 801 | 724 | |
|---|
| 802 | 725 | /* |
|---|
| 803 | 726 | * The Superspeed USB Capability descriptor shall be implemented by all |
|---|
| .. | .. |
|---|
| 818 | 741 | USB_HIGH_SPEED_OPERATION | |
|---|
| 819 | 742 | USB_5GBPS_OPERATION); |
|---|
| 820 | 743 | ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION; |
|---|
| 821 | | - |
|---|
| 822 | | - /* Get Controller configuration */ |
|---|
| 823 | | - if (cdev->gadget->ops->get_config_params) { |
|---|
| 824 | | - cdev->gadget->ops->get_config_params( |
|---|
| 825 | | - &dcd_config_params); |
|---|
| 826 | | - } else { |
|---|
| 827 | | - dcd_config_params.bU1devExitLat = |
|---|
| 828 | | - USB_DEFAULT_U1_DEV_EXIT_LAT; |
|---|
| 829 | | - dcd_config_params.bU2DevExitLat = |
|---|
| 830 | | - cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT); |
|---|
| 831 | | - } |
|---|
| 832 | 744 | ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat; |
|---|
| 833 | 745 | ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat; |
|---|
| 834 | 746 | } |
|---|
| .. | .. |
|---|
| 836 | 748 | /* The SuperSpeedPlus USB Device Capability descriptor */ |
|---|
| 837 | 749 | if (gadget_is_superspeed_plus(cdev->gadget)) { |
|---|
| 838 | 750 | struct usb_ssp_cap_descriptor *ssp_cap; |
|---|
| 751 | + u8 ssac = 1; |
|---|
| 752 | + u8 ssic; |
|---|
| 753 | + int i; |
|---|
| 754 | + |
|---|
| 755 | + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x2) |
|---|
| 756 | + ssac = 3; |
|---|
| 757 | + |
|---|
| 758 | + /* |
|---|
| 759 | + * Paired RX and TX sublink speed attributes share |
|---|
| 760 | + * the same SSID. |
|---|
| 761 | + */ |
|---|
| 762 | + ssic = (ssac + 1) / 2 - 1; |
|---|
| 839 | 763 | |
|---|
| 840 | 764 | ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); |
|---|
| 841 | 765 | bos->bNumDeviceCaps++; |
|---|
| 842 | 766 | |
|---|
| 843 | | - /* |
|---|
| 844 | | - * Report typical values. |
|---|
| 845 | | - */ |
|---|
| 846 | | - |
|---|
| 847 | | - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1)); |
|---|
| 848 | | - ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); |
|---|
| 767 | + le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(ssac)); |
|---|
| 768 | + ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(ssac); |
|---|
| 849 | 769 | ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; |
|---|
| 850 | 770 | ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; |
|---|
| 851 | 771 | ssp_cap->bReserved = 0; |
|---|
| 852 | 772 | ssp_cap->wReserved = 0; |
|---|
| 853 | 773 | |
|---|
| 854 | | - /* SSAC = 1 (2 attributes) */ |
|---|
| 855 | | - ssp_cap->bmAttributes = cpu_to_le32(1); |
|---|
| 774 | + ssp_cap->bmAttributes = |
|---|
| 775 | + cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_ATTRIBS, ssac) | |
|---|
| 776 | + FIELD_PREP(USB_SSP_SUBLINK_SPEED_IDS, ssic)); |
|---|
| 856 | 777 | |
|---|
| 857 | | - /* Min RX/TX Lane Count = 1 */ |
|---|
| 858 | 778 | ssp_cap->wFunctionalitySupport = |
|---|
| 859 | | - cpu_to_le16((1 << 8) | (1 << 12)); |
|---|
| 779 | + cpu_to_le16(FIELD_PREP(USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID, 0) | |
|---|
| 780 | + FIELD_PREP(USB_SSP_MIN_RX_LANE_COUNT, 1) | |
|---|
| 781 | + FIELD_PREP(USB_SSP_MIN_TX_LANE_COUNT, 1)); |
|---|
| 860 | 782 | |
|---|
| 861 | 783 | /* |
|---|
| 862 | | - * bmSublinkSpeedAttr[0]: |
|---|
| 863 | | - * ST = Symmetric, RX |
|---|
| 864 | | - * LSE = 3 (Gbps) |
|---|
| 865 | | - * LP = 1 (SuperSpeedPlus) |
|---|
| 866 | | - * LSM = 10 (10 Gbps) |
|---|
| 784 | + * Use 1 SSID if the gadget supports up to gen2x1 or not |
|---|
| 785 | + * specified: |
|---|
| 786 | + * - SSID 0 for symmetric RX/TX sublink speed of 10 Gbps. |
|---|
| 787 | + * |
|---|
| 788 | + * Use 1 SSID if the gadget supports up to gen1x2: |
|---|
| 789 | + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. |
|---|
| 790 | + * |
|---|
| 791 | + * Use 2 SSIDs if the gadget supports up to gen2x2: |
|---|
| 792 | + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. |
|---|
| 793 | + * - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps. |
|---|
| 867 | 794 | */ |
|---|
| 868 | | - ssp_cap->bmSublinkSpeedAttr[0] = |
|---|
| 869 | | - cpu_to_le32((3 << 4) | (1 << 14) | (0xa << 16)); |
|---|
| 870 | | - /* |
|---|
| 871 | | - * bmSublinkSpeedAttr[1] = |
|---|
| 872 | | - * ST = Symmetric, TX |
|---|
| 873 | | - * LSE = 3 (Gbps) |
|---|
| 874 | | - * LP = 1 (SuperSpeedPlus) |
|---|
| 875 | | - * LSM = 10 (10 Gbps) |
|---|
| 876 | | - */ |
|---|
| 877 | | - ssp_cap->bmSublinkSpeedAttr[1] = |
|---|
| 878 | | - cpu_to_le32((3 << 4) | (1 << 14) | |
|---|
| 879 | | - (0xa << 16) | (1 << 7)); |
|---|
| 795 | + for (i = 0; i < ssac + 1; i++) { |
|---|
| 796 | + u8 ssid; |
|---|
| 797 | + u8 mantissa; |
|---|
| 798 | + u8 type; |
|---|
| 799 | + |
|---|
| 800 | + ssid = i >> 1; |
|---|
| 801 | + |
|---|
| 802 | + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x1 || |
|---|
| 803 | + cdev->gadget->max_ssp_rate == USB_SSP_GEN_UNKNOWN) |
|---|
| 804 | + mantissa = 10; |
|---|
| 805 | + else |
|---|
| 806 | + mantissa = 5 << ssid; |
|---|
| 807 | + |
|---|
| 808 | + if (i % 2) |
|---|
| 809 | + type = USB_SSP_SUBLINK_SPEED_ST_SYM_TX; |
|---|
| 810 | + else |
|---|
| 811 | + type = USB_SSP_SUBLINK_SPEED_ST_SYM_RX; |
|---|
| 812 | + |
|---|
| 813 | + ssp_cap->bmSublinkSpeedAttr[i] = |
|---|
| 814 | + cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_SSID, ssid) | |
|---|
| 815 | + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSE, |
|---|
| 816 | + USB_SSP_SUBLINK_SPEED_LSE_GBPS) | |
|---|
| 817 | + FIELD_PREP(USB_SSP_SUBLINK_SPEED_ST, type) | |
|---|
| 818 | + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LP, |
|---|
| 819 | + USB_SSP_SUBLINK_SPEED_LP_SSP) | |
|---|
| 820 | + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSM, mantissa)); |
|---|
| 821 | + } |
|---|
| 880 | 822 | } |
|---|
| 881 | 823 | |
|---|
| 882 | 824 | return le16_to_cpu(bos->wTotalLength); |
|---|
| .. | .. |
|---|
| 948 | 890 | result = 0; |
|---|
| 949 | 891 | } |
|---|
| 950 | 892 | |
|---|
| 951 | | - INFO(cdev, "%s config #%d: %s\n", |
|---|
| 952 | | - usb_speed_string(gadget->speed), |
|---|
| 953 | | - number, c ? c->label : "unconfigured"); |
|---|
| 893 | + DBG(cdev, "%s config #%d: %s\n", |
|---|
| 894 | + usb_speed_string(gadget->speed), |
|---|
| 895 | + number, c ? c->label : "unconfigured"); |
|---|
| 954 | 896 | |
|---|
| 955 | 897 | if (!c) |
|---|
| 956 | 898 | goto done; |
|---|
| .. | .. |
|---|
| 1357 | 1299 | EXPORT_SYMBOL_GPL(usb_string_id); |
|---|
| 1358 | 1300 | |
|---|
| 1359 | 1301 | /** |
|---|
| 1360 | | - * usb_string_ids() - allocate unused string IDs in batch |
|---|
| 1302 | + * usb_string_ids_tab() - allocate unused string IDs in batch |
|---|
| 1361 | 1303 | * @cdev: the device whose string descriptor IDs are being allocated |
|---|
| 1362 | 1304 | * @str: an array of usb_string objects to assign numbers to |
|---|
| 1363 | 1305 | * Context: single threaded during gadget setup |
|---|
| .. | .. |
|---|
| 1821 | 1763 | if (!gadget_is_dualspeed(gadget) || |
|---|
| 1822 | 1764 | gadget->speed >= USB_SPEED_SUPER) |
|---|
| 1823 | 1765 | break; |
|---|
| 1824 | | - /* FALLTHROUGH */ |
|---|
| 1766 | + fallthrough; |
|---|
| 1825 | 1767 | case USB_DT_CONFIG: |
|---|
| 1826 | 1768 | value = config_desc(cdev, w_value); |
|---|
| 1827 | 1769 | if (value >= 0) |
|---|
| .. | .. |
|---|
| 2163 | 2105 | return value; |
|---|
| 2164 | 2106 | } |
|---|
| 2165 | 2107 | |
|---|
| 2166 | | -void composite_disconnect(struct usb_gadget *gadget) |
|---|
| 2108 | +static void __composite_disconnect(struct usb_gadget *gadget) |
|---|
| 2167 | 2109 | { |
|---|
| 2168 | 2110 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
|---|
| 2169 | 2111 | unsigned long flags; |
|---|
| .. | .. |
|---|
| 2178 | 2120 | if (cdev->driver->disconnect) |
|---|
| 2179 | 2121 | cdev->driver->disconnect(cdev); |
|---|
| 2180 | 2122 | spin_unlock_irqrestore(&cdev->lock, flags); |
|---|
| 2123 | +} |
|---|
| 2124 | + |
|---|
| 2125 | +void composite_disconnect(struct usb_gadget *gadget) |
|---|
| 2126 | +{ |
|---|
| 2127 | + usb_gadget_vbus_draw(gadget, 0); |
|---|
| 2128 | + __composite_disconnect(gadget); |
|---|
| 2129 | +} |
|---|
| 2130 | + |
|---|
| 2131 | +void composite_reset(struct usb_gadget *gadget) |
|---|
| 2132 | +{ |
|---|
| 2133 | + /* |
|---|
| 2134 | + * Section 1.4.13 Standard Downstream Port of the USB battery charging |
|---|
| 2135 | + * specification v1.2 states that a device connected on a SDP shall only |
|---|
| 2136 | + * draw at max 100mA while in a connected, but unconfigured state. |
|---|
| 2137 | + */ |
|---|
| 2138 | + usb_gadget_vbus_draw(gadget, 100); |
|---|
| 2139 | + __composite_disconnect(gadget); |
|---|
| 2181 | 2140 | } |
|---|
| 2182 | 2141 | |
|---|
| 2183 | 2142 | /*-------------------------------------------------------------------------*/ |
|---|
| .. | .. |
|---|
| 2500 | 2459 | .unbind = composite_unbind, |
|---|
| 2501 | 2460 | |
|---|
| 2502 | 2461 | .setup = composite_setup, |
|---|
| 2503 | | - .reset = composite_disconnect, |
|---|
| 2462 | + .reset = composite_reset, |
|---|
| 2504 | 2463 | .disconnect = composite_disconnect, |
|---|
| 2505 | 2464 | |
|---|
| 2506 | 2465 | .suspend = composite_suspend, |
|---|