aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-08-03 07:33:27 -0400
committerFelipe Balbi <balbi@ti.com>2011-10-13 13:39:59 -0400
commit4bb99b7c82bac1488a0228d2363db1f68d90f6f3 (patch)
tree62741be3938a236aba3539402f7030d2eeb417bd /drivers/usb
parent089b837a39552ee49a4ea4c188e8c3517473f10c (diff)
usb: gadget: storage: add superspeed support
this patch adds superspeed descriptors for the storage gadgets. Acked-by: Michal Nazarewicz <mina86@mina86.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_mass_storage.c22
-rw-r--r--drivers/usb/gadget/file_storage.c59
-rw-r--r--drivers/usb/gadget/mass_storage.c2
-rw-r--r--drivers/usb/gadget/storage_common.c120
4 files changed, 190 insertions, 13 deletions
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 927ee88278bd..52583a235330 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -3023,6 +3023,28 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
3023 } 3023 }
3024 } 3024 }
3025 3025
3026 if (gadget_is_superspeed(gadget)) {
3027 unsigned max_burst;
3028
3029 /* Calculate bMaxBurst, we know packet size is 1024 */
3030 max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
3031
3032 fsg_ss_bulk_in_desc.bEndpointAddress =
3033 fsg_fs_bulk_in_desc.bEndpointAddress;
3034 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
3035
3036 fsg_ss_bulk_out_desc.bEndpointAddress =
3037 fsg_fs_bulk_out_desc.bEndpointAddress;
3038 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
3039
3040 f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
3041 if (unlikely(!f->ss_descriptors)) {
3042 usb_free_descriptors(f->hs_descriptors);
3043 usb_free_descriptors(f->descriptors);
3044 return -ENOMEM;
3045 }
3046 }
3047
3026 return 0; 3048 return 0;
3027 3049
3028autoconf_fail: 3050autoconf_fail:
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a230009db734..5779549d7dc6 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -586,7 +586,19 @@ dev_qualifier = {
586 .bNumConfigurations = 1, 586 .bNumConfigurations = 1,
587}; 587};
588 588
589static int populate_bos(struct fsg_dev *fsg, u8 *buf)
590{
591 memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE);
592 buf += USB_DT_BOS_SIZE;
593
594 memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE);
595 buf += USB_DT_USB_EXT_CAP_SIZE;
589 596
597 memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE);
598
599 return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE
600 + USB_DT_USB_EXT_CAP_SIZE;
601}
590 602
591/* 603/*
592 * Config descriptors must agree with the code that sets configurations 604 * Config descriptors must agree with the code that sets configurations
@@ -935,7 +947,8 @@ static int standard_setup_req(struct fsg_dev *fsg,
935 break; 947 break;
936 case USB_DT_DEVICE_QUALIFIER: 948 case USB_DT_DEVICE_QUALIFIER:
937 VDBG(fsg, "get device qualifier\n"); 949 VDBG(fsg, "get device qualifier\n");
938 if (!gadget_is_dualspeed(fsg->gadget)) 950 if (!gadget_is_dualspeed(fsg->gadget) ||
951 fsg->gadget->speed == USB_SPEED_SUPER)
939 break; 952 break;
940 /* 953 /*
941 * Assume ep0 uses the same maxpacket value for both 954 * Assume ep0 uses the same maxpacket value for both
@@ -948,7 +961,8 @@ static int standard_setup_req(struct fsg_dev *fsg,
948 961
949 case USB_DT_OTHER_SPEED_CONFIG: 962 case USB_DT_OTHER_SPEED_CONFIG:
950 VDBG(fsg, "get other-speed config descriptor\n"); 963 VDBG(fsg, "get other-speed config descriptor\n");
951 if (!gadget_is_dualspeed(fsg->gadget)) 964 if (!gadget_is_dualspeed(fsg->gadget) ||
965 fsg->gadget->speed == USB_SPEED_SUPER)
952 break; 966 break;
953 goto get_config; 967 goto get_config;
954 case USB_DT_CONFIG: 968 case USB_DT_CONFIG:
@@ -967,7 +981,15 @@ get_config:
967 value = usb_gadget_get_string(&fsg_stringtab, 981 value = usb_gadget_get_string(&fsg_stringtab,
968 w_value & 0xff, req->buf); 982 w_value & 0xff, req->buf);
969 break; 983 break;
984
985 case USB_DT_BOS:
986 VDBG(fsg, "get bos descriptor\n");
987
988 if (gadget_is_superspeed(fsg->gadget))
989 value = populate_bos(fsg, req->buf);
990 break;
970 } 991 }
992
971 break; 993 break;
972 994
973 /* One config, two speeds */ 995 /* One config, two speeds */
@@ -2777,13 +2799,15 @@ reset:
2777 2799
2778 /* Enable the endpoints */ 2800 /* Enable the endpoints */
2779 d = fsg_ep_desc(fsg->gadget, 2801 d = fsg_ep_desc(fsg->gadget,
2780 &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); 2802 &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc,
2803 &fsg_ss_bulk_in_desc);
2781 if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) 2804 if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
2782 goto reset; 2805 goto reset;
2783 fsg->bulk_in_enabled = 1; 2806 fsg->bulk_in_enabled = 1;
2784 2807
2785 d = fsg_ep_desc(fsg->gadget, 2808 d = fsg_ep_desc(fsg->gadget,
2786 &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); 2809 &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc,
2810 &fsg_ss_bulk_out_desc);
2787 if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) 2811 if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
2788 goto reset; 2812 goto reset;
2789 fsg->bulk_out_enabled = 1; 2813 fsg->bulk_out_enabled = 1;
@@ -2792,7 +2816,8 @@ reset:
2792 2816
2793 if (transport_is_cbi()) { 2817 if (transport_is_cbi()) {
2794 d = fsg_ep_desc(fsg->gadget, 2818 d = fsg_ep_desc(fsg->gadget,
2795 &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc); 2819 &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc,
2820 &fsg_ss_intr_in_desc);
2796 if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) 2821 if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
2797 goto reset; 2822 goto reset;
2798 fsg->intr_in_enabled = 1; 2823 fsg->intr_in_enabled = 1;
@@ -3424,6 +3449,24 @@ static int __init fsg_bind(struct usb_gadget *gadget)
3424 fsg_fs_intr_in_desc.bEndpointAddress; 3449 fsg_fs_intr_in_desc.bEndpointAddress;
3425 } 3450 }
3426 3451
3452 if (gadget_is_superspeed(gadget)) {
3453 unsigned max_burst;
3454
3455 fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL;
3456
3457 /* Calculate bMaxBurst, we know packet size is 1024 */
3458 max_burst = min_t(unsigned, mod_data.buflen / 1024, 15);
3459
3460 /* Assume endpoint addresses are the same for both speeds */
3461 fsg_ss_bulk_in_desc.bEndpointAddress =
3462 fsg_fs_bulk_in_desc.bEndpointAddress;
3463 fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
3464
3465 fsg_ss_bulk_out_desc.bEndpointAddress =
3466 fsg_fs_bulk_out_desc.bEndpointAddress;
3467 fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
3468 }
3469
3427 if (gadget_is_otg(gadget)) 3470 if (gadget_is_otg(gadget))
3428 fsg_otg_desc.bmAttributes |= USB_OTG_HNP; 3471 fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
3429 3472
@@ -3540,11 +3583,7 @@ static void fsg_resume(struct usb_gadget *gadget)
3540/*-------------------------------------------------------------------------*/ 3583/*-------------------------------------------------------------------------*/
3541 3584
3542static struct usb_gadget_driver fsg_driver = { 3585static struct usb_gadget_driver fsg_driver = {
3543#ifdef CONFIG_USB_GADGET_DUALSPEED 3586 .speed = USB_SPEED_SUPER,
3544 .speed = USB_SPEED_HIGH,
3545#else
3546 .speed = USB_SPEED_FULL,
3547#endif
3548 .function = (char *) fsg_string_product, 3587 .function = (char *) fsg_string_product,
3549 .unbind = fsg_unbind, 3588 .unbind = fsg_unbind,
3550 .disconnect = fsg_disconnect, 3589 .disconnect = fsg_disconnect,
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index d2a9dcb67088..e24f72f82a47 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -160,7 +160,7 @@ static struct usb_composite_driver msg_driver = {
160 .name = "g_mass_storage", 160 .name = "g_mass_storage",
161 .dev = &msg_device_desc, 161 .dev = &msg_device_desc,
162 .iProduct = DRIVER_DESC, 162 .iProduct = DRIVER_DESC,
163 .max_speed = USB_SPEED_HIGH, 163 .max_speed = USB_SPEED_SUPER,
164 .needs_serial = 1, 164 .needs_serial = 1,
165}; 165};
166 166
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 523626274c0f..c7f291a331df 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -515,12 +515,128 @@ static struct usb_descriptor_header *fsg_hs_function[] = {
515 NULL, 515 NULL,
516}; 516};
517 517
518static struct usb_endpoint_descriptor
519fsg_ss_bulk_in_desc = {
520 .bLength = USB_DT_ENDPOINT_SIZE,
521 .bDescriptorType = USB_DT_ENDPOINT,
522
523 /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
524 .bmAttributes = USB_ENDPOINT_XFER_BULK,
525 .wMaxPacketSize = cpu_to_le16(1024),
526};
527
528static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
529 .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
530 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
531
532 /*.bMaxBurst = DYNAMIC, */
533};
534
535static struct usb_endpoint_descriptor
536fsg_ss_bulk_out_desc = {
537 .bLength = USB_DT_ENDPOINT_SIZE,
538 .bDescriptorType = USB_DT_ENDPOINT,
539
540 /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
541 .bmAttributes = USB_ENDPOINT_XFER_BULK,
542 .wMaxPacketSize = cpu_to_le16(1024),
543};
544
545static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
546 .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
547 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
548
549 /*.bMaxBurst = DYNAMIC, */
550};
551
552#ifndef FSG_NO_INTR_EP
553
554static struct usb_endpoint_descriptor
555fsg_ss_intr_in_desc = {
556 .bLength = USB_DT_ENDPOINT_SIZE,
557 .bDescriptorType = USB_DT_ENDPOINT,
558
559 /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
560 .bmAttributes = USB_ENDPOINT_XFER_INT,
561 .wMaxPacketSize = cpu_to_le16(2),
562 .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
563};
564
565static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = {
566 .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
567 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
568
569 .wBytesPerInterval = cpu_to_le16(2),
570};
571
572#ifndef FSG_NO_OTG
573# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2
574#else
575# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1
576#endif
577
578#endif
579
580static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = {
581 .bLength = USB_DT_USB_EXT_CAP_SIZE,
582 .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
583 .bDevCapabilityType = USB_CAP_TYPE_EXT,
584
585 .bmAttributes = cpu_to_le32(USB_LPM_SUPPORT),
586};
587
588static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = {
589 .bLength = USB_DT_USB_SS_CAP_SIZE,
590 .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
591 .bDevCapabilityType = USB_SS_CAP_TYPE,
592
593 /* .bmAttributes = LTM is not supported yet */
594
595 .wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION
596 | USB_FULL_SPEED_OPERATION
597 | USB_HIGH_SPEED_OPERATION
598 | USB_5GBPS_OPERATION),
599 .bFunctionalitySupport = USB_LOW_SPEED_OPERATION,
600 .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT,
601 .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT,
602};
603
604static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
605 .bLength = USB_DT_BOS_SIZE,
606 .bDescriptorType = USB_DT_BOS,
607
608 .wTotalLength = USB_DT_BOS_SIZE
609 + USB_DT_USB_EXT_CAP_SIZE
610 + USB_DT_USB_SS_CAP_SIZE,
611
612 .bNumDeviceCaps = 2,
613};
614
615static struct usb_descriptor_header *fsg_ss_function[] = {
616#ifndef FSG_NO_OTG
617 (struct usb_descriptor_header *) &fsg_otg_desc,
618#endif
619 (struct usb_descriptor_header *) &fsg_intf_desc,
620 (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
621 (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
622 (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc,
623 (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
624#ifndef FSG_NO_INTR_EP
625 (struct usb_descriptor_header *) &fsg_ss_intr_in_desc,
626 (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc,
627#endif
628 NULL,
629};
630
518/* Maxpacket and other transfer characteristics vary by speed. */ 631/* Maxpacket and other transfer characteristics vary by speed. */
519static __maybe_unused struct usb_endpoint_descriptor * 632static __maybe_unused struct usb_endpoint_descriptor *
520fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, 633fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
521 struct usb_endpoint_descriptor *hs) 634 struct usb_endpoint_descriptor *hs,
635 struct usb_endpoint_descriptor *ss)
522{ 636{
523 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) 637 if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
638 return ss;
639 else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
524 return hs; 640 return hs;
525 return fs; 641 return fs;
526} 642}