1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
21378df79SJean-Christophe PLAGNIOL-VILLARD /*
31378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2003
41378df79SJean-Christophe PLAGNIOL-VILLARD * Gerry Hamel, geh@ti.com, Texas Instruments
51378df79SJean-Christophe PLAGNIOL-VILLARD *
61378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2006
71378df79SJean-Christophe PLAGNIOL-VILLARD * Bryan O'Donoghue, bodonoghue@codehermit.ie
81378df79SJean-Christophe PLAGNIOL-VILLARD */
91378df79SJean-Christophe PLAGNIOL-VILLARD
101378df79SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
11dedacc18SJean-Christophe PLAGNIOL-VILLARD #include <config.h>
121378df79SJean-Christophe PLAGNIOL-VILLARD #include <circbuf.h>
1352cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h>
14b2fb47f1STom Rini #include <asm/unaligned.h>
151378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbtty.h"
161378df79SJean-Christophe PLAGNIOL-VILLARD #include "usb_cdc_acm.h"
171378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbdescriptors.h"
181378df79SJean-Christophe PLAGNIOL-VILLARD
19dedacc18SJean-Christophe PLAGNIOL-VILLARD #ifdef DEBUG
201378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...)\
211378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args)
221378df79SJean-Christophe PLAGNIOL-VILLARD #else
231378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...) do{}while(0)
241378df79SJean-Christophe PLAGNIOL-VILLARD #endif
251378df79SJean-Christophe PLAGNIOL-VILLARD
261378df79SJean-Christophe PLAGNIOL-VILLARD #if 1
271378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...)\
281378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\
291378df79SJean-Christophe PLAGNIOL-VILLARD __LINE__,##args)
301378df79SJean-Christophe PLAGNIOL-VILLARD #else
311378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...) do{}while(0)
321378df79SJean-Christophe PLAGNIOL-VILLARD #endif
331378df79SJean-Christophe PLAGNIOL-VILLARD
341378df79SJean-Christophe PLAGNIOL-VILLARD /*
351378df79SJean-Christophe PLAGNIOL-VILLARD * Defines
361378df79SJean-Christophe PLAGNIOL-VILLARD */
371378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_CONFIGS 1
381378df79SJean-Christophe PLAGNIOL-VILLARD #define MAX_INTERFACES 2
391378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ENDPOINTS 3
401378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_TX_ENDPOINT 3
411378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_RX_ENDPOINT 2
421378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_TX_ENDPOINT 2
431378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_RX_ENDPOINT 1
441378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ACM_INTERFACES 2
451378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_GSERIAL_INTERFACES 1
461378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface"
471378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface"
481378df79SJean-Christophe PLAGNIOL-VILLARD
491378df79SJean-Christophe PLAGNIOL-VILLARD /*
501378df79SJean-Christophe PLAGNIOL-VILLARD * Buffers to hold input and output data
511378df79SJean-Christophe PLAGNIOL-VILLARD */
52b2caefbbSShiraz Hashim #define USBTTY_BUFFER_SIZE 2048
531378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_input;
541378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_output;
551378df79SJean-Christophe PLAGNIOL-VILLARD
561378df79SJean-Christophe PLAGNIOL-VILLARD
571378df79SJean-Christophe PLAGNIOL-VILLARD /*
581378df79SJean-Christophe PLAGNIOL-VILLARD * Instance variables
591378df79SJean-Christophe PLAGNIOL-VILLARD */
6052cb4d4fSJean-Christophe PLAGNIOL-VILLARD static struct stdio_dev usbttydev;
611378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_instance device_instance[1];
621378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_bus_instance bus_instance[1];
631378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_instance config_instance[NUM_CONFIGS];
641378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_instance interface_instance[MAX_INTERFACES];
651378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_alternate_instance alternate_instance[MAX_INTERFACES];
661378df79SJean-Christophe PLAGNIOL-VILLARD /* one extra for control endpoint */
671378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1];
681378df79SJean-Christophe PLAGNIOL-VILLARD
691378df79SJean-Christophe PLAGNIOL-VILLARD /*
701378df79SJean-Christophe PLAGNIOL-VILLARD * Global flag
711378df79SJean-Christophe PLAGNIOL-VILLARD */
721378df79SJean-Christophe PLAGNIOL-VILLARD int usbtty_configured_flag = 0;
731378df79SJean-Christophe PLAGNIOL-VILLARD
741378df79SJean-Christophe PLAGNIOL-VILLARD /*
751378df79SJean-Christophe PLAGNIOL-VILLARD * Serial number
761378df79SJean-Christophe PLAGNIOL-VILLARD */
771378df79SJean-Christophe PLAGNIOL-VILLARD static char serial_number[16];
781378df79SJean-Christophe PLAGNIOL-VILLARD
791378df79SJean-Christophe PLAGNIOL-VILLARD
801378df79SJean-Christophe PLAGNIOL-VILLARD /*
811378df79SJean-Christophe PLAGNIOL-VILLARD * Descriptors, Strings, Local variables.
821378df79SJean-Christophe PLAGNIOL-VILLARD */
831378df79SJean-Christophe PLAGNIOL-VILLARD
842731b9a8SJean-Christophe PLAGNIOL-VILLARD /* defined and used by gadget/ep0.c */
851378df79SJean-Christophe PLAGNIOL-VILLARD extern struct usb_string_descriptor **usb_strings;
861378df79SJean-Christophe PLAGNIOL-VILLARD
871378df79SJean-Christophe PLAGNIOL-VILLARD /* Indicies, References */
881378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short rx_endpoint = 0;
891378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short tx_endpoint = 0;
901378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short interface_count = 0;
911378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_string_descriptor *usbtty_string_table[STR_COUNT];
921378df79SJean-Christophe PLAGNIOL-VILLARD
931378df79SJean-Christophe PLAGNIOL-VILLARD /* USB Descriptor Strings */
941378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4};
951378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)];
961378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)];
971378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)];
981378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)];
991378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
1001378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)];
1011378df79SJean-Christophe PLAGNIOL-VILLARD
1021378df79SJean-Christophe PLAGNIOL-VILLARD /* Standard USB Data Structures */
1031378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES];
1041378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS];
1051378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_descriptor *configuration_descriptor = 0;
1061378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_descriptor device_descriptor = {
1071378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_device_descriptor),
1081378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_DEVICE,
1091378df79SJean-Christophe PLAGNIOL-VILLARD .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
1101378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceSubClass = 0x00,
1111378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceProtocol = 0x00,
1121378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
1131378df79SJean-Christophe PLAGNIOL-VILLARD .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID),
1141378df79SJean-Christophe PLAGNIOL-VILLARD .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE),
1151378df79SJean-Christophe PLAGNIOL-VILLARD .iManufacturer = STR_MANUFACTURER,
1161378df79SJean-Christophe PLAGNIOL-VILLARD .iProduct = STR_PRODUCT,
1171378df79SJean-Christophe PLAGNIOL-VILLARD .iSerialNumber = STR_SERIAL,
1181378df79SJean-Christophe PLAGNIOL-VILLARD .bNumConfigurations = NUM_CONFIGS
1191378df79SJean-Christophe PLAGNIOL-VILLARD };
1201378df79SJean-Christophe PLAGNIOL-VILLARD
1211378df79SJean-Christophe PLAGNIOL-VILLARD
122f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
123f9da0f89SVipin KUMAR static struct usb_qualifier_descriptor qualifier_descriptor = {
124f9da0f89SVipin KUMAR .bLength = sizeof(struct usb_qualifier_descriptor),
125f9da0f89SVipin KUMAR .bDescriptorType = USB_DT_QUAL,
126f9da0f89SVipin KUMAR .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
127f9da0f89SVipin KUMAR .bDeviceClass = COMMUNICATIONS_DEVICE_CLASS,
128f9da0f89SVipin KUMAR .bDeviceSubClass = 0x00,
129f9da0f89SVipin KUMAR .bDeviceProtocol = 0x00,
130f9da0f89SVipin KUMAR .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
131f9da0f89SVipin KUMAR .bNumConfigurations = NUM_CONFIGS
132f9da0f89SVipin KUMAR };
133f9da0f89SVipin KUMAR #endif
134f9da0f89SVipin KUMAR
1351378df79SJean-Christophe PLAGNIOL-VILLARD /*
1361378df79SJean-Christophe PLAGNIOL-VILLARD * Static CDC ACM specific descriptors
1371378df79SJean-Christophe PLAGNIOL-VILLARD */
1381378df79SJean-Christophe PLAGNIOL-VILLARD
1391378df79SJean-Christophe PLAGNIOL-VILLARD struct acm_config_desc {
1401378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc;
1411378df79SJean-Christophe PLAGNIOL-VILLARD
1421378df79SJean-Christophe PLAGNIOL-VILLARD /* Master Interface */
1431378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor interface_desc;
1441378df79SJean-Christophe PLAGNIOL-VILLARD
1451378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_header_function_descriptor usb_class_header;
1461378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_call_management_descriptor usb_class_call_mgt;
1471378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_abstract_control_descriptor usb_class_acm;
1481378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_union_function_descriptor usb_class_union;
1491378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_descriptor notification_endpoint;
1501378df79SJean-Christophe PLAGNIOL-VILLARD
1511378df79SJean-Christophe PLAGNIOL-VILLARD /* Slave Interface */
1521378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor data_class_interface;
153f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1];
1541378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed));
1551378df79SJean-Christophe PLAGNIOL-VILLARD
1561378df79SJean-Christophe PLAGNIOL-VILLARD static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = {
1571378df79SJean-Christophe PLAGNIOL-VILLARD {
1581378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={
1591378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
1601378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_configuration_descriptor),
1611378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG,
1621378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength =
1631378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct acm_config_desc)),
1641378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_ACM_INTERFACES,
1651378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1,
1661378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG,
1671378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
1681378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
1691378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER
1701378df79SJean-Christophe PLAGNIOL-VILLARD },
1711378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 1 */
1721378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = {
1731378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_interface_descriptor),
1741378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
1751378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0,
1761378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0,
1771378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x01,
1781378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
1791378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
1801378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
1811378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
1821378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_CTRL_INTERFACE,
1831378df79SJean-Christophe PLAGNIOL-VILLARD },
1841378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_header = {
1851378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
1861378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_header_function_descriptor),
1871378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
1881378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_HEADER,
1891378df79SJean-Christophe PLAGNIOL-VILLARD .bcdCDC = cpu_to_le16(110),
1901378df79SJean-Christophe PLAGNIOL-VILLARD },
1911378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_call_mgt = {
1921378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
1931378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_call_management_descriptor),
1941378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
1951378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_CMF,
1961378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00,
1971378df79SJean-Christophe PLAGNIOL-VILLARD .bDataInterface = 0x01,
1981378df79SJean-Christophe PLAGNIOL-VILLARD },
1991378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_acm = {
2001378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
2011378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_abstract_control_descriptor),
2021378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
2031378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_ACMF,
2041378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00,
2051378df79SJean-Christophe PLAGNIOL-VILLARD },
2061378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_union = {
2071378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength =
2081378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_union_function_descriptor),
2091378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE,
2101378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_UF,
2111378df79SJean-Christophe PLAGNIOL-VILLARD .bMasterInterface = 0x00,
2121378df79SJean-Christophe PLAGNIOL-VILLARD .bSlaveInterface0 = 0x01,
2131378df79SJean-Christophe PLAGNIOL-VILLARD },
2141378df79SJean-Christophe PLAGNIOL-VILLARD .notification_endpoint = {
2151378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2161378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2171378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2189e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN,
2191378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT,
2201378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize
2211378df79SJean-Christophe PLAGNIOL-VILLARD = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
2221378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2231378df79SJean-Christophe PLAGNIOL-VILLARD },
2241378df79SJean-Christophe PLAGNIOL-VILLARD
2251378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 2 */
2261378df79SJean-Christophe PLAGNIOL-VILLARD .data_class_interface = {
2271378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2281378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor),
2291378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
2301378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0x01,
2311378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0x00,
2321378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x02,
2331378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
2341378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_DATA,
2351378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE,
2361378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE,
2371378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE,
2381378df79SJean-Christophe PLAGNIOL-VILLARD },
2391378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = {
2401378df79SJean-Christophe PLAGNIOL-VILLARD {
2411378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2421378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2431378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2449e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT,
2451378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
2461378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK,
2471378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
2481378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
2491378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2501378df79SJean-Christophe PLAGNIOL-VILLARD },
2511378df79SJean-Christophe PLAGNIOL-VILLARD {
2521378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
2531378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
2541378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
2559e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN,
2561378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
2571378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK,
2581378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
2591378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
2601378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
2611378df79SJean-Christophe PLAGNIOL-VILLARD },
2621378df79SJean-Christophe PLAGNIOL-VILLARD },
2631378df79SJean-Christophe PLAGNIOL-VILLARD },
2641378df79SJean-Christophe PLAGNIOL-VILLARD };
2651378df79SJean-Christophe PLAGNIOL-VILLARD
2661378df79SJean-Christophe PLAGNIOL-VILLARD static struct rs232_emu rs232_desc={
2671378df79SJean-Christophe PLAGNIOL-VILLARD .dter = 115200,
2681378df79SJean-Christophe PLAGNIOL-VILLARD .stop_bits = 0x00,
2691378df79SJean-Christophe PLAGNIOL-VILLARD .parity = 0x00,
2701378df79SJean-Christophe PLAGNIOL-VILLARD .data_bits = 0x08
2711378df79SJean-Christophe PLAGNIOL-VILLARD };
2721378df79SJean-Christophe PLAGNIOL-VILLARD
2731378df79SJean-Christophe PLAGNIOL-VILLARD
2741378df79SJean-Christophe PLAGNIOL-VILLARD /*
2751378df79SJean-Christophe PLAGNIOL-VILLARD * Static Generic Serial specific data
2761378df79SJean-Christophe PLAGNIOL-VILLARD */
2771378df79SJean-Christophe PLAGNIOL-VILLARD
2781378df79SJean-Christophe PLAGNIOL-VILLARD
2791378df79SJean-Christophe PLAGNIOL-VILLARD struct gserial_config_desc {
2801378df79SJean-Christophe PLAGNIOL-VILLARD
2811378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc;
282f3c0de63SAtin Malaviya struct usb_interface_descriptor interface_desc[NUM_GSERIAL_INTERFACES];
283f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS];
2841378df79SJean-Christophe PLAGNIOL-VILLARD
2851378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed));
2861378df79SJean-Christophe PLAGNIOL-VILLARD
2871378df79SJean-Christophe PLAGNIOL-VILLARD static struct gserial_config_desc
2881378df79SJean-Christophe PLAGNIOL-VILLARD gserial_configuration_descriptors[NUM_CONFIGS] ={
2891378df79SJean-Christophe PLAGNIOL-VILLARD {
2901378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={
2911378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_configuration_descriptor),
2921378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG,
2931378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength =
2941378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct gserial_config_desc)),
2951378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_GSERIAL_INTERFACES,
2961378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1,
2971378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG,
2981378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes =
2991378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
3001378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER
3011378df79SJean-Christophe PLAGNIOL-VILLARD },
3021378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = {
3031378df79SJean-Christophe PLAGNIOL-VILLARD {
3041378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3051378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor),
3061378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE,
3071378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0,
3081378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0,
3091378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = NUM_ENDPOINTS,
3101378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass =
3111378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
3121378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass =
3131378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_SUBCLASS,
3141378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol =
3151378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_PROTOCOL,
3161378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE
3171378df79SJean-Christophe PLAGNIOL-VILLARD },
3181378df79SJean-Christophe PLAGNIOL-VILLARD },
3191378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = {
3201378df79SJean-Christophe PLAGNIOL-VILLARD {
3211378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3221378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3231378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3249e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT,
3251378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK,
3261378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3271378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
3281378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval= 0xFF,
3291378df79SJean-Christophe PLAGNIOL-VILLARD },
3301378df79SJean-Christophe PLAGNIOL-VILLARD {
3311378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3321378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3331378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3349e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN,
3351378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK,
3361378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3371378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
3381378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
3391378df79SJean-Christophe PLAGNIOL-VILLARD },
3401378df79SJean-Christophe PLAGNIOL-VILLARD {
3411378df79SJean-Christophe PLAGNIOL-VILLARD .bLength =
3421378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor),
3431378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT,
3449e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN,
3451378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT,
3461378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize =
3471378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
3481378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF,
3491378df79SJean-Christophe PLAGNIOL-VILLARD },
3501378df79SJean-Christophe PLAGNIOL-VILLARD },
3511378df79SJean-Christophe PLAGNIOL-VILLARD },
3521378df79SJean-Christophe PLAGNIOL-VILLARD };
3531378df79SJean-Christophe PLAGNIOL-VILLARD
3541378df79SJean-Christophe PLAGNIOL-VILLARD /*
3551378df79SJean-Christophe PLAGNIOL-VILLARD * Static Function Prototypes
3561378df79SJean-Christophe PLAGNIOL-VILLARD */
3571378df79SJean-Christophe PLAGNIOL-VILLARD
3581378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void);
3591378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void);
3601378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void);
3611378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type);
3621378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_event_handler (struct usb_device_instance *device,
3631378df79SJean-Christophe PLAGNIOL-VILLARD usb_device_event_t event, int data);
3641378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_cdc_setup(struct usb_device_request *request,
3651378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *urb);
3661378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_configured (void);
3671378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf);
3681378df79SJean-Christophe PLAGNIOL-VILLARD static int fill_buffer (circbuf_t * buf);
3691378df79SJean-Christophe PLAGNIOL-VILLARD
3701378df79SJean-Christophe PLAGNIOL-VILLARD void usbtty_poll (void);
3711378df79SJean-Christophe PLAGNIOL-VILLARD
3721378df79SJean-Christophe PLAGNIOL-VILLARD /* utility function for converting char* to wide string used by USB */
str2wide(char * str,u16 * wide)3731378df79SJean-Christophe PLAGNIOL-VILLARD static void str2wide (char *str, u16 * wide)
3741378df79SJean-Christophe PLAGNIOL-VILLARD {
3751378df79SJean-Christophe PLAGNIOL-VILLARD int i;
3761378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < strlen (str) && str[i]; i++){
3771378df79SJean-Christophe PLAGNIOL-VILLARD #if defined(__LITTLE_ENDIAN)
3781378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = (u16) str[i];
3791378df79SJean-Christophe PLAGNIOL-VILLARD #elif defined(__BIG_ENDIAN)
3801378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = ((u16)(str[i])<<8);
3811378df79SJean-Christophe PLAGNIOL-VILLARD #else
3821378df79SJean-Christophe PLAGNIOL-VILLARD #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined"
3831378df79SJean-Christophe PLAGNIOL-VILLARD #endif
3841378df79SJean-Christophe PLAGNIOL-VILLARD }
3851378df79SJean-Christophe PLAGNIOL-VILLARD }
3861378df79SJean-Christophe PLAGNIOL-VILLARD
3871378df79SJean-Christophe PLAGNIOL-VILLARD /*
3881378df79SJean-Christophe PLAGNIOL-VILLARD * Test whether a character is in the RX buffer
3891378df79SJean-Christophe PLAGNIOL-VILLARD */
3901378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_tstc(struct stdio_dev * dev)391709ea543SSimon Glass int usbtty_tstc(struct stdio_dev *dev)
3921378df79SJean-Christophe PLAGNIOL-VILLARD {
3931378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
3941378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
3951378df79SJean-Christophe PLAGNIOL-VILLARD
3961378df79SJean-Christophe PLAGNIOL-VILLARD /* If no input data exists, allow more RX to be accepted */
3971378df79SJean-Christophe PLAGNIOL-VILLARD if(usbtty_input.size <= 0){
3981378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03);
3991378df79SJean-Christophe PLAGNIOL-VILLARD }
4001378df79SJean-Christophe PLAGNIOL-VILLARD
4011378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4021378df79SJean-Christophe PLAGNIOL-VILLARD return (usbtty_input.size > 0);
4031378df79SJean-Christophe PLAGNIOL-VILLARD }
4041378df79SJean-Christophe PLAGNIOL-VILLARD
4051378df79SJean-Christophe PLAGNIOL-VILLARD /*
4061378df79SJean-Christophe PLAGNIOL-VILLARD * Read a single byte from the usb client port. Returns 1 on success, 0
4071378df79SJean-Christophe PLAGNIOL-VILLARD * otherwise. When the function is succesfull, the character read is
4081378df79SJean-Christophe PLAGNIOL-VILLARD * written into its argument c.
4091378df79SJean-Christophe PLAGNIOL-VILLARD */
4101378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_getc(struct stdio_dev * dev)411709ea543SSimon Glass int usbtty_getc(struct stdio_dev *dev)
4121378df79SJean-Christophe PLAGNIOL-VILLARD {
4131378df79SJean-Christophe PLAGNIOL-VILLARD char c;
4141378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
4151378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
4161378df79SJean-Christophe PLAGNIOL-VILLARD
4171378df79SJean-Christophe PLAGNIOL-VILLARD while (usbtty_input.size <= 0) {
4181378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03);
4191378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4201378df79SJean-Christophe PLAGNIOL-VILLARD }
4211378df79SJean-Christophe PLAGNIOL-VILLARD
4221378df79SJean-Christophe PLAGNIOL-VILLARD buf_pop (&usbtty_input, &c, 1);
4231378df79SJean-Christophe PLAGNIOL-VILLARD udc_set_nak(endpoint->endpoint_address&0x03);
4241378df79SJean-Christophe PLAGNIOL-VILLARD
4251378df79SJean-Christophe PLAGNIOL-VILLARD return c;
4261378df79SJean-Christophe PLAGNIOL-VILLARD }
4271378df79SJean-Christophe PLAGNIOL-VILLARD
4281378df79SJean-Christophe PLAGNIOL-VILLARD /*
4291378df79SJean-Christophe PLAGNIOL-VILLARD * Output a single byte to the usb client port.
4301378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_putc(struct stdio_dev * dev,const char c)431709ea543SSimon Glass void usbtty_putc(struct stdio_dev *dev, const char c)
4321378df79SJean-Christophe PLAGNIOL-VILLARD {
433f3c0de63SAtin Malaviya if (!usbtty_configured ())
434f3c0de63SAtin Malaviya return;
435f3c0de63SAtin Malaviya
4361378df79SJean-Christophe PLAGNIOL-VILLARD /* If \n, also do \r */
4371378df79SJean-Christophe PLAGNIOL-VILLARD if (c == '\n')
4381378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, "\r", 1);
4391378df79SJean-Christophe PLAGNIOL-VILLARD
440055457efSAlison Wang buf_push(&usbtty_output, &c, 1);
441055457efSAlison Wang
4421378df79SJean-Christophe PLAGNIOL-VILLARD /* Poll at end to handle new data... */
4431378df79SJean-Christophe PLAGNIOL-VILLARD if ((usbtty_output.size + 2) >= usbtty_output.totalsize) {
4441378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4451378df79SJean-Christophe PLAGNIOL-VILLARD }
4461378df79SJean-Christophe PLAGNIOL-VILLARD }
4471378df79SJean-Christophe PLAGNIOL-VILLARD
4481378df79SJean-Christophe PLAGNIOL-VILLARD /* usbtty_puts() helper function for finding the next '\n' in a string */
next_nl_pos(const char * s)4491378df79SJean-Christophe PLAGNIOL-VILLARD static int next_nl_pos (const char *s)
4501378df79SJean-Christophe PLAGNIOL-VILLARD {
4511378df79SJean-Christophe PLAGNIOL-VILLARD int i;
4521378df79SJean-Christophe PLAGNIOL-VILLARD
4531378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 0; s[i] != '\0'; i++) {
4541378df79SJean-Christophe PLAGNIOL-VILLARD if (s[i] == '\n')
4551378df79SJean-Christophe PLAGNIOL-VILLARD return i;
4561378df79SJean-Christophe PLAGNIOL-VILLARD }
4571378df79SJean-Christophe PLAGNIOL-VILLARD return i;
4581378df79SJean-Christophe PLAGNIOL-VILLARD }
4591378df79SJean-Christophe PLAGNIOL-VILLARD
4601378df79SJean-Christophe PLAGNIOL-VILLARD /*
4611378df79SJean-Christophe PLAGNIOL-VILLARD * Output a string to the usb client port - implementing flow control
4621378df79SJean-Christophe PLAGNIOL-VILLARD */
4631378df79SJean-Christophe PLAGNIOL-VILLARD
__usbtty_puts(const char * str,int len)4641378df79SJean-Christophe PLAGNIOL-VILLARD static void __usbtty_puts (const char *str, int len)
4651378df79SJean-Christophe PLAGNIOL-VILLARD {
4661378df79SJean-Christophe PLAGNIOL-VILLARD int maxlen = usbtty_output.totalsize;
4671378df79SJean-Christophe PLAGNIOL-VILLARD int space, n;
4681378df79SJean-Christophe PLAGNIOL-VILLARD
4691378df79SJean-Christophe PLAGNIOL-VILLARD /* break str into chunks < buffer size, if needed */
4701378df79SJean-Christophe PLAGNIOL-VILLARD while (len > 0) {
4711378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
4721378df79SJean-Christophe PLAGNIOL-VILLARD
4731378df79SJean-Christophe PLAGNIOL-VILLARD space = maxlen - usbtty_output.size;
4741378df79SJean-Christophe PLAGNIOL-VILLARD /* Empty buffer here, if needed, to ensure space... */
4751378df79SJean-Christophe PLAGNIOL-VILLARD if (space) {
4761378df79SJean-Christophe PLAGNIOL-VILLARD write_buffer (&usbtty_output);
4771378df79SJean-Christophe PLAGNIOL-VILLARD
478c79cba37SMasahiro Yamada n = min(space, min(len, maxlen));
4791378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, str, n);
4801378df79SJean-Christophe PLAGNIOL-VILLARD
4811378df79SJean-Christophe PLAGNIOL-VILLARD str += n;
4821378df79SJean-Christophe PLAGNIOL-VILLARD len -= n;
4831378df79SJean-Christophe PLAGNIOL-VILLARD }
4841378df79SJean-Christophe PLAGNIOL-VILLARD }
4851378df79SJean-Christophe PLAGNIOL-VILLARD }
4861378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_puts(struct stdio_dev * dev,const char * str)487709ea543SSimon Glass void usbtty_puts(struct stdio_dev *dev, const char *str)
4881378df79SJean-Christophe PLAGNIOL-VILLARD {
4891378df79SJean-Christophe PLAGNIOL-VILLARD int n;
490f3c0de63SAtin Malaviya int len;
4911378df79SJean-Christophe PLAGNIOL-VILLARD
492f3c0de63SAtin Malaviya if (!usbtty_configured ())
493f3c0de63SAtin Malaviya return;
494f3c0de63SAtin Malaviya
495f3c0de63SAtin Malaviya len = strlen (str);
4961378df79SJean-Christophe PLAGNIOL-VILLARD /* add '\r' for each '\n' */
4971378df79SJean-Christophe PLAGNIOL-VILLARD while (len > 0) {
4981378df79SJean-Christophe PLAGNIOL-VILLARD n = next_nl_pos (str);
4991378df79SJean-Christophe PLAGNIOL-VILLARD
5001378df79SJean-Christophe PLAGNIOL-VILLARD if (str[n] == '\n') {
5011378df79SJean-Christophe PLAGNIOL-VILLARD __usbtty_puts("\r", 1);
502055457efSAlison Wang __usbtty_puts(str, n + 1);
5031378df79SJean-Christophe PLAGNIOL-VILLARD str += (n + 1);
5041378df79SJean-Christophe PLAGNIOL-VILLARD len -= (n + 1);
5051378df79SJean-Christophe PLAGNIOL-VILLARD } else {
5061378df79SJean-Christophe PLAGNIOL-VILLARD /* No \n found. All done. */
5071378df79SJean-Christophe PLAGNIOL-VILLARD __usbtty_puts (str, n);
5081378df79SJean-Christophe PLAGNIOL-VILLARD break;
5091378df79SJean-Christophe PLAGNIOL-VILLARD }
5101378df79SJean-Christophe PLAGNIOL-VILLARD }
5111378df79SJean-Christophe PLAGNIOL-VILLARD
5121378df79SJean-Christophe PLAGNIOL-VILLARD /* Poll at end to handle new data... */
5131378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll ();
5141378df79SJean-Christophe PLAGNIOL-VILLARD }
5151378df79SJean-Christophe PLAGNIOL-VILLARD
5161378df79SJean-Christophe PLAGNIOL-VILLARD /*
5171378df79SJean-Christophe PLAGNIOL-VILLARD * Initialize the usb client port.
5181378df79SJean-Christophe PLAGNIOL-VILLARD *
5191378df79SJean-Christophe PLAGNIOL-VILLARD */
drv_usbtty_init(void)5201378df79SJean-Christophe PLAGNIOL-VILLARD int drv_usbtty_init (void)
5211378df79SJean-Christophe PLAGNIOL-VILLARD {
5221378df79SJean-Christophe PLAGNIOL-VILLARD int rc;
5231378df79SJean-Christophe PLAGNIOL-VILLARD char * sn;
5241378df79SJean-Christophe PLAGNIOL-VILLARD char * tt;
5251378df79SJean-Christophe PLAGNIOL-VILLARD int snlen;
5261378df79SJean-Christophe PLAGNIOL-VILLARD
527c409336dSHeinrich Schuchardt /* Get serial number */
52800caae6dSSimon Glass sn = env_get("serial#");
52900caae6dSSimon Glass if (!sn)
5301378df79SJean-Christophe PLAGNIOL-VILLARD sn = "000000000000";
5311378df79SJean-Christophe PLAGNIOL-VILLARD snlen = strlen(sn);
5321378df79SJean-Christophe PLAGNIOL-VILLARD if (snlen > sizeof(serial_number) - 1) {
533b64f190bSWolfgang Denk printf ("Warning: serial number %s is too long (%d > %lu)\n",
534b64f190bSWolfgang Denk sn, snlen, (ulong)(sizeof(serial_number) - 1));
5351378df79SJean-Christophe PLAGNIOL-VILLARD snlen = sizeof(serial_number) - 1;
5361378df79SJean-Christophe PLAGNIOL-VILLARD }
5371378df79SJean-Christophe PLAGNIOL-VILLARD memcpy (serial_number, sn, snlen);
5381378df79SJean-Christophe PLAGNIOL-VILLARD serial_number[snlen] = '\0';
5391378df79SJean-Christophe PLAGNIOL-VILLARD
5401378df79SJean-Christophe PLAGNIOL-VILLARD /* Decide on which type of UDC device to be.
5411378df79SJean-Christophe PLAGNIOL-VILLARD */
54200caae6dSSimon Glass tt = env_get("usbtty");
54300caae6dSSimon Glass if (!tt)
5441378df79SJean-Christophe PLAGNIOL-VILLARD tt = "generic";
5451378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_terminal_type(strcmp(tt,"cdc_acm"));
5461378df79SJean-Christophe PLAGNIOL-VILLARD
5471378df79SJean-Christophe PLAGNIOL-VILLARD /* prepare buffers... */
5481378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_input, USBTTY_BUFFER_SIZE);
5491378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_output, USBTTY_BUFFER_SIZE);
5501378df79SJean-Christophe PLAGNIOL-VILLARD
5511378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, set up USB controller and infrastructure */
5521378df79SJean-Christophe PLAGNIOL-VILLARD udc_init (); /* Basic USB initialization */
5531378df79SJean-Christophe PLAGNIOL-VILLARD
5541378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_strings ();
5551378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_instances ();
5561378df79SJean-Christophe PLAGNIOL-VILLARD
557241d9a61SStefan Herbrechtsmeier usbtty_init_endpoints ();
558241d9a61SStefan Herbrechtsmeier
5591378df79SJean-Christophe PLAGNIOL-VILLARD udc_startup_events (device_instance);/* Enable dev, init udc pointers */
5601378df79SJean-Christophe PLAGNIOL-VILLARD udc_connect (); /* Enable pullup for host detection */
5611378df79SJean-Christophe PLAGNIOL-VILLARD
5621378df79SJean-Christophe PLAGNIOL-VILLARD /* Device initialization */
5631378df79SJean-Christophe PLAGNIOL-VILLARD memset (&usbttydev, 0, sizeof (usbttydev));
5641378df79SJean-Christophe PLAGNIOL-VILLARD
5651378df79SJean-Christophe PLAGNIOL-VILLARD strcpy (usbttydev.name, "usbtty");
5661378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.ext = 0; /* No extensions */
5671378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT;
5681378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.tstc = usbtty_tstc; /* 'tstc' function */
5691378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.getc = usbtty_getc; /* 'getc' function */
5701378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.putc = usbtty_putc; /* 'putc' function */
5711378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.puts = usbtty_puts; /* 'puts' function */
5721378df79SJean-Christophe PLAGNIOL-VILLARD
57352cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register (&usbttydev);
5741378df79SJean-Christophe PLAGNIOL-VILLARD
5751378df79SJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc;
5761378df79SJean-Christophe PLAGNIOL-VILLARD }
5771378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_init_strings(void)5781378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void)
5791378df79SJean-Christophe PLAGNIOL-VILLARD {
5801378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_string_descriptor *string;
5811378df79SJean-Christophe PLAGNIOL-VILLARD
5821378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_LANG] =
5831378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_string_descriptor*)wstrLang;
5841378df79SJean-Christophe PLAGNIOL-VILLARD
5851378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrManufacturer;
5861378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrManufacturer);
5871378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
5881378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_MANUFACTURER, string->wData);
5891378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_MANUFACTURER]=string;
5901378df79SJean-Christophe PLAGNIOL-VILLARD
5911378df79SJean-Christophe PLAGNIOL-VILLARD
5921378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrProduct;
5931378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrProduct);
5941378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
5951378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData);
5961378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_PRODUCT]=string;
5971378df79SJean-Christophe PLAGNIOL-VILLARD
5981378df79SJean-Christophe PLAGNIOL-VILLARD
5991378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrSerial;
6001378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(serial_number);
6011378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6021378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (serial_number, string->wData);
6031378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_SERIAL]=string;
6041378df79SJean-Christophe PLAGNIOL-VILLARD
6051378df79SJean-Christophe PLAGNIOL-VILLARD
6061378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrConfiguration;
6071378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrConfiguration);
6081378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6091378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData);
6101378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CONFIG]=string;
6111378df79SJean-Christophe PLAGNIOL-VILLARD
6121378df79SJean-Christophe PLAGNIOL-VILLARD
6131378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrDataInterface;
6141378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrDataInterface);
6151378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6161378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData);
6171378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_DATA_INTERFACE]=string;
6181378df79SJean-Christophe PLAGNIOL-VILLARD
6191378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrCtrlInterface;
6201378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrCtrlInterface);
6211378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING;
6221378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData);
6231378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CTRL_INTERFACE]=string;
6241378df79SJean-Christophe PLAGNIOL-VILLARD
6251378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, initialize the string table for ep0 handling */
6261378df79SJean-Christophe PLAGNIOL-VILLARD usb_strings = usbtty_string_table;
6271378df79SJean-Christophe PLAGNIOL-VILLARD }
6281378df79SJean-Christophe PLAGNIOL-VILLARD
629b2fb47f1STom Rini #define init_wMaxPacketSize(x) le16_to_cpu(get_unaligned(\
630b2fb47f1STom Rini &ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize));
631b2fb47f1STom Rini
usbtty_init_instances(void)6321378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void)
6331378df79SJean-Christophe PLAGNIOL-VILLARD {
6341378df79SJean-Christophe PLAGNIOL-VILLARD int i;
6351378df79SJean-Christophe PLAGNIOL-VILLARD
6361378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize device instance */
6371378df79SJean-Christophe PLAGNIOL-VILLARD memset (device_instance, 0, sizeof (struct usb_device_instance));
6381378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_state = STATE_INIT;
6391378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_descriptor = &device_descriptor;
640f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
641f9da0f89SVipin KUMAR device_instance->qualifier_descriptor = &qualifier_descriptor;
642f9da0f89SVipin KUMAR #endif
6431378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->event = usbtty_event_handler;
6441378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->cdc_recv_setup = usbtty_cdc_setup;
6451378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->bus = bus_instance;
6461378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configurations = NUM_CONFIGS;
6471378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configuration_instance_array = config_instance;
6481378df79SJean-Christophe PLAGNIOL-VILLARD
6491378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize bus instance */
6501378df79SJean-Christophe PLAGNIOL-VILLARD memset (bus_instance, 0, sizeof (struct usb_bus_instance));
6511378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->device = device_instance;
6521378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->endpoint_array = endpoint_instance;
6531378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = 1;
6541378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->maxpacketsize = 64;
6551378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->serial_number_str = serial_number;
6561378df79SJean-Christophe PLAGNIOL-VILLARD
6571378df79SJean-Christophe PLAGNIOL-VILLARD /* configuration instance */
6581378df79SJean-Christophe PLAGNIOL-VILLARD memset (config_instance, 0,
6591378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_configuration_instance));
6601378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interfaces = interface_count;
6611378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->configuration_descriptor = configuration_descriptor;
6621378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interface_instance_array = interface_instance;
6631378df79SJean-Christophe PLAGNIOL-VILLARD
6641378df79SJean-Christophe PLAGNIOL-VILLARD /* interface instance */
6651378df79SJean-Christophe PLAGNIOL-VILLARD memset (interface_instance, 0,
6661378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_interface_instance));
6671378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates = 1;
6681378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates_instance_array = alternate_instance;
6691378df79SJean-Christophe PLAGNIOL-VILLARD
6701378df79SJean-Christophe PLAGNIOL-VILLARD /* alternates instance */
6711378df79SJean-Christophe PLAGNIOL-VILLARD memset (alternate_instance, 0,
6721378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_alternate_instance));
6731378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->interface_descriptor = interface_descriptors;
6741378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints = NUM_ENDPOINTS;
6751378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs;
6761378df79SJean-Christophe PLAGNIOL-VILLARD
6771378df79SJean-Christophe PLAGNIOL-VILLARD /* endpoint instances */
6781378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[0], 0,
6791378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance));
6801378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].endpoint_address = 0;
6811378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE;
6821378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL;
6831378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE;
6841378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL;
6851378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, 0, &endpoint_instance[0]);
6861378df79SJean-Christophe PLAGNIOL-VILLARD
6871378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) {
6881378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[i], 0,
6891378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance));
6901378df79SJean-Christophe PLAGNIOL-VILLARD
6911378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].endpoint_address =
6921378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bEndpointAddress;
6931378df79SJean-Christophe PLAGNIOL-VILLARD
6941378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_attributes =
6951378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
6961378df79SJean-Christophe PLAGNIOL-VILLARD
697b2fb47f1STom Rini endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i);
6981378df79SJean-Christophe PLAGNIOL-VILLARD
6991378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes =
7001378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
7011378df79SJean-Christophe PLAGNIOL-VILLARD
702b2fb47f1STom Rini endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i);
7031378df79SJean-Christophe PLAGNIOL-VILLARD
7041378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes =
7051378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes;
7061378df79SJean-Christophe PLAGNIOL-VILLARD
7071378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rcv);
7081378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rdy);
7091378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].tx);
7101378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].done);
7111378df79SJean-Christophe PLAGNIOL-VILLARD
7121378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint_instance[i].endpoint_address & USB_DIR_IN)
7131378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_urb =
7141378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance,
7151378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]);
7161378df79SJean-Christophe PLAGNIOL-VILLARD else
7171378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_urb =
7181378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance,
7191378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]);
7201378df79SJean-Christophe PLAGNIOL-VILLARD }
7211378df79SJean-Christophe PLAGNIOL-VILLARD }
7221378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_init_endpoints(void)7231378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void)
7241378df79SJean-Christophe PLAGNIOL-VILLARD {
7251378df79SJean-Christophe PLAGNIOL-VILLARD int i;
7261378df79SJean-Christophe PLAGNIOL-VILLARD
7271378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = NUM_ENDPOINTS + 1;
7281378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) {
7291378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, i, &endpoint_instance[i]);
7301378df79SJean-Christophe PLAGNIOL-VILLARD }
7311378df79SJean-Christophe PLAGNIOL-VILLARD }
7321378df79SJean-Christophe PLAGNIOL-VILLARD
7331378df79SJean-Christophe PLAGNIOL-VILLARD /* usbtty_init_terminal_type
7341378df79SJean-Christophe PLAGNIOL-VILLARD *
7351378df79SJean-Christophe PLAGNIOL-VILLARD * Do some late binding for our device type.
7361378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_init_terminal_type(short type)7371378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type)
7381378df79SJean-Christophe PLAGNIOL-VILLARD {
7391378df79SJean-Christophe PLAGNIOL-VILLARD switch(type){
7401378df79SJean-Christophe PLAGNIOL-VILLARD /* CDC ACM */
7411378df79SJean-Christophe PLAGNIOL-VILLARD case 0:
7421378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */
7431378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] =
7441378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].notification_endpoint;
7451378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] =
7461378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[0];
7471378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] =
7481378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[1];
7491378df79SJean-Christophe PLAGNIOL-VILLARD
7501378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */
7511378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass =
7521378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_DEVICE_CLASS;
7531378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct =
7541378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
7551378df79SJean-Christophe PLAGNIOL-VILLARD
756f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
757f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass =
758f9da0f89SVipin KUMAR COMMUNICATIONS_DEVICE_CLASS;
759f9da0f89SVipin KUMAR #endif
7601378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */
7611378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = ACM_TX_ENDPOINT;
7621378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = ACM_RX_ENDPOINT;
7631378df79SJean-Christophe PLAGNIOL-VILLARD
7641378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */
7651378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor =
7661378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*)
7671378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors;
7681378df79SJean-Christophe PLAGNIOL-VILLARD
7691378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */
7701378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_ACM_INTERFACES;
7711378df79SJean-Christophe PLAGNIOL-VILLARD break;
7721378df79SJean-Christophe PLAGNIOL-VILLARD
7731378df79SJean-Christophe PLAGNIOL-VILLARD /* BULK IN/OUT & Default */
7741378df79SJean-Christophe PLAGNIOL-VILLARD case 1:
7751378df79SJean-Christophe PLAGNIOL-VILLARD default:
7761378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */
7771378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] =
7781378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[0];
7791378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] =
7801378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[1];
7811378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] =
7821378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[2];
7831378df79SJean-Christophe PLAGNIOL-VILLARD
7841378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */
7851378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass = 0xFF;
7861378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct =
7871378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
788f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
789f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass = 0xFF;
790f9da0f89SVipin KUMAR #endif
7911378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */
7921378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = GSERIAL_TX_ENDPOINT;
7931378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = GSERIAL_RX_ENDPOINT;
7941378df79SJean-Christophe PLAGNIOL-VILLARD
7951378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */
7961378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor =
7971378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*)
7981378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors;
7991378df79SJean-Christophe PLAGNIOL-VILLARD
8001378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */
8011378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_GSERIAL_INTERFACES;
8021378df79SJean-Christophe PLAGNIOL-VILLARD break;
8031378df79SJean-Christophe PLAGNIOL-VILLARD }
8041378df79SJean-Christophe PLAGNIOL-VILLARD }
8051378df79SJean-Christophe PLAGNIOL-VILLARD
8061378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
8071378df79SJean-Christophe PLAGNIOL-VILLARD
next_urb(struct usb_device_instance * device,struct usb_endpoint_instance * endpoint)8081378df79SJean-Christophe PLAGNIOL-VILLARD static struct urb *next_urb (struct usb_device_instance *device,
8091378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint)
8101378df79SJean-Christophe PLAGNIOL-VILLARD {
8111378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL;
8121378df79SJean-Christophe PLAGNIOL-VILLARD int space;
8131378df79SJean-Christophe PLAGNIOL-VILLARD
8141378df79SJean-Christophe PLAGNIOL-VILLARD /* If there's a queue, then we should add to the last urb */
8151378df79SJean-Christophe PLAGNIOL-VILLARD if (!endpoint->tx_queue) {
8161378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = endpoint->tx_urb;
8171378df79SJean-Christophe PLAGNIOL-VILLARD } else {
8181378df79SJean-Christophe PLAGNIOL-VILLARD /* Last urb from tx chain */
8191378df79SJean-Christophe PLAGNIOL-VILLARD current_urb =
8201378df79SJean-Christophe PLAGNIOL-VILLARD p2surround (struct urb, link, endpoint->tx.prev);
8211378df79SJean-Christophe PLAGNIOL-VILLARD }
8221378df79SJean-Christophe PLAGNIOL-VILLARD
8231378df79SJean-Christophe PLAGNIOL-VILLARD /* Make sure this one has enough room */
8241378df79SJean-Christophe PLAGNIOL-VILLARD space = current_urb->buffer_length - current_urb->actual_length;
8251378df79SJean-Christophe PLAGNIOL-VILLARD if (space > 0) {
8261378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb;
8271378df79SJean-Christophe PLAGNIOL-VILLARD } else { /* No space here */
8281378df79SJean-Christophe PLAGNIOL-VILLARD /* First look at done list */
8291378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = first_urb_detached (&endpoint->done);
8301378df79SJean-Christophe PLAGNIOL-VILLARD if (!current_urb) {
8311378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = usbd_alloc_urb (device, endpoint);
8321378df79SJean-Christophe PLAGNIOL-VILLARD }
8331378df79SJean-Christophe PLAGNIOL-VILLARD
8341378df79SJean-Christophe PLAGNIOL-VILLARD urb_append (&endpoint->tx, current_urb);
8351378df79SJean-Christophe PLAGNIOL-VILLARD endpoint->tx_queue++;
8361378df79SJean-Christophe PLAGNIOL-VILLARD }
8371378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb;
8381378df79SJean-Christophe PLAGNIOL-VILLARD }
8391378df79SJean-Christophe PLAGNIOL-VILLARD
write_buffer(circbuf_t * buf)8401378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf)
8411378df79SJean-Christophe PLAGNIOL-VILLARD {
8421378df79SJean-Christophe PLAGNIOL-VILLARD if (!usbtty_configured ()) {
8431378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
8441378df79SJean-Christophe PLAGNIOL-VILLARD }
8451378df79SJean-Christophe PLAGNIOL-VILLARD
8461378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
8471378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[tx_endpoint];
8481378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL;
8491378df79SJean-Christophe PLAGNIOL-VILLARD
8501378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = next_urb (device_instance, endpoint);
85173be5b3fSxypron.glpk@gmx.de
85273be5b3fSxypron.glpk@gmx.de if (!current_urb) {
85373be5b3fSxypron.glpk@gmx.de TTYERR ("current_urb is NULL, buf->size %d\n",
85473be5b3fSxypron.glpk@gmx.de buf->size);
85573be5b3fSxypron.glpk@gmx.de return 0;
85673be5b3fSxypron.glpk@gmx.de }
85773be5b3fSxypron.glpk@gmx.de
8581378df79SJean-Christophe PLAGNIOL-VILLARD /* TX data still exists - send it now
8591378df79SJean-Christophe PLAGNIOL-VILLARD */
8601378df79SJean-Christophe PLAGNIOL-VILLARD if(endpoint->sent < current_urb->actual_length){
8611378df79SJean-Christophe PLAGNIOL-VILLARD if(udc_endpoint_write (endpoint)){
8621378df79SJean-Christophe PLAGNIOL-VILLARD /* Write pre-empted by RX */
8631378df79SJean-Christophe PLAGNIOL-VILLARD return -1;
8641378df79SJean-Christophe PLAGNIOL-VILLARD }
8651378df79SJean-Christophe PLAGNIOL-VILLARD }
8661378df79SJean-Christophe PLAGNIOL-VILLARD
8671378df79SJean-Christophe PLAGNIOL-VILLARD if (buf->size) {
8681378df79SJean-Christophe PLAGNIOL-VILLARD char *dest;
8691378df79SJean-Christophe PLAGNIOL-VILLARD
8701378df79SJean-Christophe PLAGNIOL-VILLARD int space_avail;
8711378df79SJean-Christophe PLAGNIOL-VILLARD int popnum, popped;
8721378df79SJean-Christophe PLAGNIOL-VILLARD int total = 0;
8731378df79SJean-Christophe PLAGNIOL-VILLARD
8741378df79SJean-Christophe PLAGNIOL-VILLARD /* Break buffer into urb sized pieces,
8751378df79SJean-Christophe PLAGNIOL-VILLARD * and link each to the endpoint
8761378df79SJean-Christophe PLAGNIOL-VILLARD */
8771378df79SJean-Christophe PLAGNIOL-VILLARD while (buf->size > 0) {
8781378df79SJean-Christophe PLAGNIOL-VILLARD
8791378df79SJean-Christophe PLAGNIOL-VILLARD dest = (char*)current_urb->buffer +
8801378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length;
8811378df79SJean-Christophe PLAGNIOL-VILLARD
8821378df79SJean-Christophe PLAGNIOL-VILLARD space_avail =
8831378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->buffer_length -
8841378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length;
885b4141195SMasahiro Yamada popnum = min(space_avail, (int)buf->size);
8861378df79SJean-Christophe PLAGNIOL-VILLARD if (popnum == 0)
8871378df79SJean-Christophe PLAGNIOL-VILLARD break;
8881378df79SJean-Christophe PLAGNIOL-VILLARD
8891378df79SJean-Christophe PLAGNIOL-VILLARD popped = buf_pop (buf, dest, popnum);
8901378df79SJean-Christophe PLAGNIOL-VILLARD if (popped == 0)
8911378df79SJean-Christophe PLAGNIOL-VILLARD break;
8921378df79SJean-Christophe PLAGNIOL-VILLARD current_urb->actual_length += popped;
8931378df79SJean-Christophe PLAGNIOL-VILLARD total += popped;
8941378df79SJean-Christophe PLAGNIOL-VILLARD
8951378df79SJean-Christophe PLAGNIOL-VILLARD /* If endpoint->last == 0, then transfers have
8961378df79SJean-Christophe PLAGNIOL-VILLARD * not started on this endpoint
8971378df79SJean-Christophe PLAGNIOL-VILLARD */
8981378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint->last == 0) {
8991378df79SJean-Christophe PLAGNIOL-VILLARD if(udc_endpoint_write (endpoint)){
9001378df79SJean-Christophe PLAGNIOL-VILLARD /* Write pre-empted by RX */
9011378df79SJean-Christophe PLAGNIOL-VILLARD return -1;
9021378df79SJean-Christophe PLAGNIOL-VILLARD }
9031378df79SJean-Christophe PLAGNIOL-VILLARD }
9041378df79SJean-Christophe PLAGNIOL-VILLARD
9051378df79SJean-Christophe PLAGNIOL-VILLARD }/* end while */
9061378df79SJean-Christophe PLAGNIOL-VILLARD return total;
9071378df79SJean-Christophe PLAGNIOL-VILLARD }
9081378df79SJean-Christophe PLAGNIOL-VILLARD
9091378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
9101378df79SJean-Christophe PLAGNIOL-VILLARD }
9111378df79SJean-Christophe PLAGNIOL-VILLARD
fill_buffer(circbuf_t * buf)9121378df79SJean-Christophe PLAGNIOL-VILLARD static int fill_buffer (circbuf_t * buf)
9131378df79SJean-Christophe PLAGNIOL-VILLARD {
9141378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint =
9151378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint];
9161378df79SJean-Christophe PLAGNIOL-VILLARD
9171378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) {
9181378df79SJean-Christophe PLAGNIOL-VILLARD unsigned int nb = 0;
9191378df79SJean-Christophe PLAGNIOL-VILLARD char *src = (char *) endpoint->rcv_urb->buffer;
9201378df79SJean-Christophe PLAGNIOL-VILLARD unsigned int rx_avail = buf->totalsize - buf->size;
9211378df79SJean-Christophe PLAGNIOL-VILLARD
9221378df79SJean-Christophe PLAGNIOL-VILLARD if(rx_avail >= endpoint->rcv_urb->actual_length){
9231378df79SJean-Christophe PLAGNIOL-VILLARD
9241378df79SJean-Christophe PLAGNIOL-VILLARD nb = endpoint->rcv_urb->actual_length;
9251378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (buf, src, nb);
9261378df79SJean-Christophe PLAGNIOL-VILLARD endpoint->rcv_urb->actual_length = 0;
9271378df79SJean-Christophe PLAGNIOL-VILLARD
9281378df79SJean-Christophe PLAGNIOL-VILLARD }
9291378df79SJean-Christophe PLAGNIOL-VILLARD return nb;
9301378df79SJean-Christophe PLAGNIOL-VILLARD }
9311378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
9321378df79SJean-Christophe PLAGNIOL-VILLARD }
9331378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_configured(void)9341378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_configured (void)
9351378df79SJean-Christophe PLAGNIOL-VILLARD {
9361378df79SJean-Christophe PLAGNIOL-VILLARD return usbtty_configured_flag;
9371378df79SJean-Christophe PLAGNIOL-VILLARD }
9381378df79SJean-Christophe PLAGNIOL-VILLARD
9391378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
9401378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_event_handler(struct usb_device_instance * device,usb_device_event_t event,int data)9411378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_event_handler (struct usb_device_instance *device,
9421378df79SJean-Christophe PLAGNIOL-VILLARD usb_device_event_t event, int data)
9431378df79SJean-Christophe PLAGNIOL-VILLARD {
944f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
945f9da0f89SVipin KUMAR int i;
946f9da0f89SVipin KUMAR #endif
9471378df79SJean-Christophe PLAGNIOL-VILLARD switch (event) {
9481378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_RESET:
9491378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_BUS_INACTIVE:
9501378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_configured_flag = 0;
9511378df79SJean-Christophe PLAGNIOL-VILLARD break;
9521378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_CONFIGURED:
9531378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_configured_flag = 1;
9541378df79SJean-Christophe PLAGNIOL-VILLARD break;
9551378df79SJean-Christophe PLAGNIOL-VILLARD
9561378df79SJean-Christophe PLAGNIOL-VILLARD case DEVICE_ADDRESS_ASSIGNED:
957f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS)
958f9da0f89SVipin KUMAR /*
959f9da0f89SVipin KUMAR * is_usbd_high_speed routine needs to be defined by
960f9da0f89SVipin KUMAR * specific gadget driver
961472d5460SYork Sun * It returns true if device enumerates at High speed
962472d5460SYork Sun * Retuns false otherwise
963f9da0f89SVipin KUMAR */
964f9da0f89SVipin KUMAR for (i = 0; i < NUM_ENDPOINTS; i++) {
965f9da0f89SVipin KUMAR if (((ep_descriptor_ptrs[i]->bmAttributes &
966f9da0f89SVipin KUMAR USB_ENDPOINT_XFERTYPE_MASK) ==
967f9da0f89SVipin KUMAR USB_ENDPOINT_XFER_BULK)
968f9da0f89SVipin KUMAR && is_usbd_high_speed()) {
969f9da0f89SVipin KUMAR
970f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize =
971f9da0f89SVipin KUMAR CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
972f9da0f89SVipin KUMAR }
973f9da0f89SVipin KUMAR
974f9da0f89SVipin KUMAR endpoint_instance[i + 1].tx_packetSize =
975f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize;
976f9da0f89SVipin KUMAR endpoint_instance[i + 1].rcv_packetSize =
977f9da0f89SVipin KUMAR ep_descriptor_ptrs[i]->wMaxPacketSize;
978f9da0f89SVipin KUMAR }
979f9da0f89SVipin KUMAR #endif
9801378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_endpoints ();
9811378df79SJean-Christophe PLAGNIOL-VILLARD
9821378df79SJean-Christophe PLAGNIOL-VILLARD default:
9831378df79SJean-Christophe PLAGNIOL-VILLARD break;
9841378df79SJean-Christophe PLAGNIOL-VILLARD }
9851378df79SJean-Christophe PLAGNIOL-VILLARD }
9861378df79SJean-Christophe PLAGNIOL-VILLARD
9871378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
9881378df79SJean-Christophe PLAGNIOL-VILLARD
usbtty_cdc_setup(struct usb_device_request * request,struct urb * urb)9891378df79SJean-Christophe PLAGNIOL-VILLARD int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb)
9901378df79SJean-Christophe PLAGNIOL-VILLARD {
9911378df79SJean-Christophe PLAGNIOL-VILLARD switch (request->bRequest){
9921378df79SJean-Christophe PLAGNIOL-VILLARD
9931378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SET_CONTROL_LINE_STATE: /* Implies DTE ready */
9941378df79SJean-Christophe PLAGNIOL-VILLARD break;
9951378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SEND_ENCAPSULATED_COMMAND : /* Required */
9961378df79SJean-Christophe PLAGNIOL-VILLARD break;
9971378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_SET_LINE_ENCODING : /* DTE stop/parity bits
9981378df79SJean-Christophe PLAGNIOL-VILLARD * per character */
9991378df79SJean-Christophe PLAGNIOL-VILLARD break;
10001378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_GET_ENCAPSULATED_RESPONSE : /* request response */
10011378df79SJean-Christophe PLAGNIOL-VILLARD break;
10021378df79SJean-Christophe PLAGNIOL-VILLARD case ACM_GET_LINE_ENCODING : /* request DTE rate,
10031378df79SJean-Christophe PLAGNIOL-VILLARD * stop/parity bits */
10041378df79SJean-Christophe PLAGNIOL-VILLARD memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc));
10051378df79SJean-Christophe PLAGNIOL-VILLARD urb->actual_length = sizeof(rs232_desc);
10061378df79SJean-Christophe PLAGNIOL-VILLARD
10071378df79SJean-Christophe PLAGNIOL-VILLARD break;
10081378df79SJean-Christophe PLAGNIOL-VILLARD default:
10091378df79SJean-Christophe PLAGNIOL-VILLARD return 1;
10101378df79SJean-Christophe PLAGNIOL-VILLARD }
10111378df79SJean-Christophe PLAGNIOL-VILLARD return 0;
10121378df79SJean-Christophe PLAGNIOL-VILLARD }
10131378df79SJean-Christophe PLAGNIOL-VILLARD
10141378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/
10151378df79SJean-Christophe PLAGNIOL-VILLARD
10161378df79SJean-Christophe PLAGNIOL-VILLARD /*
10171378df79SJean-Christophe PLAGNIOL-VILLARD * Since interrupt handling has not yet been implemented, we use this function
10181378df79SJean-Christophe PLAGNIOL-VILLARD * to handle polling. This is called by the tstc,getc,putc,puts routines to
10191378df79SJean-Christophe PLAGNIOL-VILLARD * update the USB state.
10201378df79SJean-Christophe PLAGNIOL-VILLARD */
usbtty_poll(void)10211378df79SJean-Christophe PLAGNIOL-VILLARD void usbtty_poll (void)
10221378df79SJean-Christophe PLAGNIOL-VILLARD {
10231378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10241378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10251378df79SJean-Christophe PLAGNIOL-VILLARD
10261378df79SJean-Christophe PLAGNIOL-VILLARD /* Write any output data to host buffer
10271378df79SJean-Christophe PLAGNIOL-VILLARD * (do this before checking interrupts to avoid missing one)
10281378df79SJean-Christophe PLAGNIOL-VILLARD */
10291378df79SJean-Christophe PLAGNIOL-VILLARD if (usbtty_configured ()) {
10301378df79SJean-Christophe PLAGNIOL-VILLARD write_buffer (&usbtty_output);
10311378df79SJean-Christophe PLAGNIOL-VILLARD }
10321378df79SJean-Christophe PLAGNIOL-VILLARD
10331378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10341378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10351378df79SJean-Christophe PLAGNIOL-VILLARD
10361378df79SJean-Christophe PLAGNIOL-VILLARD /* Check for new data from host..
10371378df79SJean-Christophe PLAGNIOL-VILLARD * (do this after checking interrupts to get latest data)
10381378df79SJean-Christophe PLAGNIOL-VILLARD */
10391378df79SJean-Christophe PLAGNIOL-VILLARD if (usbtty_configured ()) {
10401378df79SJean-Christophe PLAGNIOL-VILLARD fill_buffer (&usbtty_input);
10411378df79SJean-Christophe PLAGNIOL-VILLARD }
10421378df79SJean-Christophe PLAGNIOL-VILLARD
10431378df79SJean-Christophe PLAGNIOL-VILLARD /* New interrupts? */
10441378df79SJean-Christophe PLAGNIOL-VILLARD udc_irq();
10451378df79SJean-Christophe PLAGNIOL-VILLARD
10461378df79SJean-Christophe PLAGNIOL-VILLARD }
1047