diff options
| -rw-r--r-- | README | 8 | ||||
| -rw-r--r-- | drivers/serial/usbtty.c | 50 | ||||
| -rw-r--r-- | drivers/serial/usbtty.h | 4 | ||||
| -rw-r--r-- | drivers/usb/gadget/core.c | 1 | ||||
| -rw-r--r-- | drivers/usb/gadget/ep0.c | 23 | ||||
| -rw-r--r-- | include/usbdescriptors.h | 15 | ||||
| -rw-r--r-- | include/usbdevice.h | 22 | 
7 files changed, 116 insertions, 7 deletions
| @@ -1148,6 +1148,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 a263b2c1f..e47cb9a9e 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 = 0; i < NUM_ENDPOINTS; i++) { +			if (((ep_descriptor_ptrs[i]->bmAttributes & +			      USB_ENDPOINT_XFERTYPE_MASK) == +			      USB_ENDPOINT_XFER_BULK) +			    && is_usbd_high_speed()) { + +				ep_descriptor_ptrs[i]->wMaxPacketSize = +					CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE; +			} + +			endpoint_instance[i + 1].tx_packetSize = +				ep_descriptor_ptrs[i]->wMaxPacketSize; +			endpoint_instance[i + 1].rcv_packetSize = +				ep_descriptor_ptrs[i]->wMaxPacketSize; +		} +#endif  		usbtty_init_endpoints ();  	default: diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index 60347d788..eb670dad9 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -70,6 +70,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 4f2ebab9e..46ab3f67f 100644 --- a/drivers/usb/gadget/core.c +++ b/drivers/usb/gadget/core.c @@ -212,7 +212,6 @@ struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_i  	return (device->device_descriptor);  } -  /**   * usbd_device_configuration_descriptor   * @device: which device diff --git a/drivers/usb/gadget/ep0.c b/drivers/usb/gadget/ep0.c index 22499d36b..aa8f91600 100644 --- a/drivers/usb/gadget/ep0.c +++ b/drivers/usb/gadget/ep0.c @@ -338,12 +338,27 @@ 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 = +				device->qualifier_descriptor; + +			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 2dec3b93d..de1069f0e 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 41716364b..3edaf8bcc 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  /* @@ -565,6 +573,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); @@ -657,8 +668,17 @@ 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) +/* + * 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); |