> From: Vipin KUMAR <vipin.ku...@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.ku...@st.com> > Signed-off-by: Amit Virdi <amit.vi...@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); _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot