
From: Vipin KUMAR vipin.kumar@st.com
This patch adds the support for high speed in usb device framework and usbtty driver. This feature has been kept within a macro CONFIG_USBD_HS, so the board configuration files have to define this macro to enable high speed support.
Along with that specific peripheral drivers also need to define a function to let the framework know that the enumeration has happened at high speed. This function prototype is "int is_usbd_high_speed(void)"
Signed-off-by: Vipin Kumar vipin.kumar@st.com Signed-off-by: Amit Virdi amit.virdi@st.com
README | 8 +++++++ drivers/serial/usbtty.c | 50 ++++++++++++++++++++++++++++++++++++++++++++- drivers/serial/usbtty.h | 4 +++ drivers/usb/gadget/core.c | 14 ++++++++++++ drivers/usb/gadget/ep0.c | 24 ++++++++++++++++++--- include/usbdescriptors.h | 15 +++++++++++++ include/usbdevice.h | 24 ++++++++++++++++++++- 7 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/README b/README index eba6378..d54bb68 100644 --- a/README +++ b/README @@ -1165,6 +1165,14 @@ The following options need to be configured: Define this to have a tty type of device available to talk to the UDC device
CONFIG_USBD_HS
Define this to enable the high speed support for usb
device and usbtty. If this feature is enabled, a routine
int is_usbd_high_speed(void)
also needs to be defined by the driver to dynamically
poll
whether the enumeration has succeded at high speed or
full
speed.
CONFIG_SYS_CONSOLE_IS_IN_ENV Define this if you want stdin, stdout &/or stderr to be set to usbtty.
diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index 550bc58..0374c7d 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -133,6 +133,19 @@ static struct usb_device_descriptor device_descriptor = { };
+#if defined(CONFIG_USBD_HS) +static struct usb_qualifier_descriptor qualifier_descriptor = {
- .bLength = sizeof(struct usb_qualifier_descriptor),
- .bDescriptorType = USB_DT_QUAL,
- .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
- .bDeviceClass = COMMUNICATIONS_DEVICE_CLASS,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
- .bNumConfigurations = NUM_CONFIGS
+}; +#endif
/*
- Static CDC ACM specific descriptors
*/ @@ -638,6 +651,9 @@ static void usbtty_init_instances (void) memset (device_instance, 0, sizeof (struct usb_device_instance)); device_instance->device_state = STATE_INIT; device_instance->device_descriptor = &device_descriptor; +#if defined(CONFIG_USBD_HS)
- device_instance->qualifier_descriptor = &qualifier_descriptor;
+#endif device_instance->event = usbtty_event_handler; device_instance->cdc_recv_setup = usbtty_cdc_setup; device_instance->bus = bus_instance; @@ -751,6 +767,10 @@ static void usbtty_init_terminal_type(short type) device_descriptor.idProduct = cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
+#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass =
COMMUNICATIONS_DEVICE_CLASS;
+#endif /* Assign endpoint indices */ tx_endpoint = ACM_TX_ENDPOINT; rx_endpoint = ACM_RX_ENDPOINT; @@ -779,7 +799,9 @@ static void usbtty_init_terminal_type(short type) device_descriptor.bDeviceClass = 0xFF; device_descriptor.idProduct = cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
+#if defined(CONFIG_USBD_HS)
qualifier_descriptor.bDeviceClass = 0xFF;
+#endif /* Assign endpoint indices */ tx_endpoint = GSERIAL_TX_ENDPOINT; rx_endpoint = GSERIAL_RX_ENDPOINT; @@ -932,6 +954,9 @@ static int usbtty_configured (void) static void usbtty_event_handler (struct usb_device_instance *device, usb_device_event_t event, int data) { +#if defined(CONFIG_USBD_HS)
- int i;
+#endif switch (event) { case DEVICE_RESET: case DEVICE_BUS_INACTIVE: @@ -942,6 +967,29 @@ static void usbtty_event_handler (struct usb_device_instance *device, break;
case DEVICE_ADDRESS_ASSIGNED: +#if defined(CONFIG_USBD_HS)
/*
* is_usbd_high_speed routine needs to be defined by
* specific gadget driver
* It returns TRUE if device enumerates at High speed
* Retuns FALSE otherwise
*/
for (i = 1; i <= NUM_ENDPOINTS; i++) {
Start with i = 0 and end with i < NUM_ENDPOINTS to avoid these i-1 below. Then fix those [i] with [i+1], there's less of those.
if (((ep_descriptor_ptrs[i - 1]->bmAttributes &
USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)
&& is_usbd_high_speed()) {
ep_descriptor_ptrs[i - 1]->wMaxPacketSize =
CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
}
endpoint_instance[i].tx_packetSize =
ep_descriptor_ptrs[i - 1]->wMaxPacketSize;
endpoint_instance[i].rcv_packetSize =
ep_descriptor_ptrs[i - 1]->wMaxPacketSize;
}
+#endif usbtty_init_endpoints ();
default: diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index 6731c38..bd3bcbc 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -72,6 +72,10 @@ #define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE #define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE
+#if defined(CONFIG_USBD_HS) +#define CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE UDC_BULK_HS_PACKET_SIZE +#endif
#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS
#define USBTTY_BCD_DEVICE 0x00 diff --git a/drivers/usb/gadget/core.c b/drivers/usb/gadget/core.c index 4f2ebab..b2212b4 100644 --- a/drivers/usb/gadget/core.c +++ b/drivers/usb/gadget/core.c @@ -212,6 +212,20 @@ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_i return (device->device_descriptor); }
+#if defined(CONFIG_USBD_HS) +/**
- usbd_device_qualifier_descriptor
- @device: which device
- @port: which port
- Return the specified qualifier descriptor for the specified device.
- */
+struct usb_qualifier_descriptor *usbd_device_qualifier_descriptor(
struct usb_device_instance *device, int port)
Make this static, but do you really need this function at all?
Otherwise seems ok
+{
- return device->qualifier_descriptor;
+} +#endif
/**
- usbd_device_configuration_descriptor
diff --git a/drivers/usb/gadget/ep0.c b/drivers/usb/gadget/ep0.c index 22499d3..ba8f906 100644 --- a/drivers/usb/gadget/ep0.c +++ b/drivers/usb/gadget/ep0.c @@ -338,12 +338,28 @@ static int ep0_get_descriptor (struct usb_device_instance *device, } break; case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: +#if defined(CONFIG_USBD_HS) {
/* If a USB device supports both a full speed and low
speed operation
* we must send a Device_Qualifier descriptor here
*/
return -1;
struct usb_qualifier_descriptor *qualifier_descriptor;
qualifier_descriptor = usbd_device_qualifier_descriptor
(device, port);
if (!qualifier_descriptor)
return -1;
/* copy descriptor for this device */
copy_config(urb, qualifier_descriptor,
sizeof(struct usb_qualifier_descriptor),
max);
- }
dbg_ep0(3, "copied qualifier descriptor, actual_length: 0x%x",
urb->actual_length);
+#else
return -1;
+#endif
break;
- default: return -1; }
diff --git a/include/usbdescriptors.h b/include/usbdescriptors.h index 2dec3b9..de1069f 100644 --- a/include/usbdescriptors.h +++ b/include/usbdescriptors.h @@ -241,6 +241,21 @@ struct usb_device_descriptor { u8 bNumConfigurations; } __attribute__ ((packed));
+#if defined(CONFIG_USBD_HS) +struct usb_qualifier_descriptor {
- u8 bLength;
- u8 bDescriptorType;
- u16 bcdUSB;
- u8 bDeviceClass;
- u8 bDeviceSubClass;
- u8 bDeviceProtocol;
- u8 bMaxPacketSize0;
- u8 bNumConfigurations;
- u8 breserved;
+} __attribute__ ((packed)); +#endif
struct usb_string_descriptor { u8 bLength; u8 bDescriptorType; /* 0x03 */ diff --git a/include/usbdevice.h b/include/usbdevice.h index 9eb8849..e3eb748 100644 --- a/include/usbdevice.h +++ b/include/usbdevice.h @@ -210,6 +210,10 @@ struct usb_bus_instance; #define USB_DT_INTERFACE 0x04 #define USB_DT_ENDPOINT 0x05
+#if defined(CONFIG_USBD_HS) +#define USB_DT_QUAL 0x06 +#endif
#define USB_DT_HID (USB_TYPE_CLASS | 0x01) #define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) #define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) @@ -291,7 +295,11 @@ struct usb_bus_instance;
- USB Spec Release number
*/
+#if defined(CONFIG_USBD_HS) +#define USB_BCD_VERSION 0x0200 +#else #define USB_BCD_VERSION 0x0110 +#endif
/* @@ -567,6 +575,9 @@ struct usb_device_instance { /* generic */ char *name; struct usb_device_descriptor *device_descriptor; /* per device
descriptor
*/ +#if defined(CONFIG_USBD_HS)
- struct usb_qualifier_descriptor *qualifier_descriptor;
+#endif
void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
@@ -659,8 +670,19 @@ struct usb_class_report_descriptor *usbd_device_class_report_descriptor_index( s struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *, int, int, int, int, int); int usbd_device_endpoint_transfersize (struct
usb_device_instance *,
int, int, int, int, int); struct usb_string_descriptor *usbd_get_string (u8); -struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *, int); +struct usb_device_descriptor *usbd_device_device_descriptor(struct + usb_device_instance *,
int);
+#if defined(CONFIG_USBD_HS) +struct usb_qualifier_descriptor *usbd_device_qualifier_descriptor(
struct usb_device_instance *, int);
+/*
- is_usbd_high_speed routine needs to be defined by specific gadget
driver + * It returns TRUE if device enumerates at High speed
- Retuns FALSE otherwise
- */
+int is_usbd_high_speed(void); +#endif int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint); void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad); void usbd_tx_complete (struct usb_endpoint_instance *endpoint);