11378df79SJean-Christophe PLAGNIOL-VILLARD /* 21378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2003 31378df79SJean-Christophe PLAGNIOL-VILLARD * Gerry Hamel, geh@ti.com, Texas Instruments 41378df79SJean-Christophe PLAGNIOL-VILLARD * 51378df79SJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2006 61378df79SJean-Christophe PLAGNIOL-VILLARD * Bryan O'Donoghue, bodonoghue@codehermit.ie 71378df79SJean-Christophe PLAGNIOL-VILLARD * 81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 91378df79SJean-Christophe PLAGNIOL-VILLARD */ 101378df79SJean-Christophe PLAGNIOL-VILLARD 111378df79SJean-Christophe PLAGNIOL-VILLARD #include <common.h> 12dedacc18SJean-Christophe PLAGNIOL-VILLARD #include <config.h> 131378df79SJean-Christophe PLAGNIOL-VILLARD #include <circbuf.h> 1452cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h> 15b2fb47f1STom Rini #include <asm/unaligned.h> 161378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbtty.h" 171378df79SJean-Christophe PLAGNIOL-VILLARD #include "usb_cdc_acm.h" 181378df79SJean-Christophe PLAGNIOL-VILLARD #include "usbdescriptors.h" 191378df79SJean-Christophe PLAGNIOL-VILLARD 20dedacc18SJean-Christophe PLAGNIOL-VILLARD #ifdef DEBUG 211378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...)\ 221378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) 231378df79SJean-Christophe PLAGNIOL-VILLARD #else 241378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYDBG(fmt,args...) do{}while(0) 251378df79SJean-Christophe PLAGNIOL-VILLARD #endif 261378df79SJean-Christophe PLAGNIOL-VILLARD 271378df79SJean-Christophe PLAGNIOL-VILLARD #if 1 281378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...)\ 291378df79SJean-Christophe PLAGNIOL-VILLARD serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\ 301378df79SJean-Christophe PLAGNIOL-VILLARD __LINE__,##args) 311378df79SJean-Christophe PLAGNIOL-VILLARD #else 321378df79SJean-Christophe PLAGNIOL-VILLARD #define TTYERR(fmt,args...) do{}while(0) 331378df79SJean-Christophe PLAGNIOL-VILLARD #endif 341378df79SJean-Christophe PLAGNIOL-VILLARD 351378df79SJean-Christophe PLAGNIOL-VILLARD /* 361378df79SJean-Christophe PLAGNIOL-VILLARD * Defines 371378df79SJean-Christophe PLAGNIOL-VILLARD */ 381378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_CONFIGS 1 391378df79SJean-Christophe PLAGNIOL-VILLARD #define MAX_INTERFACES 2 401378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ENDPOINTS 3 411378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_TX_ENDPOINT 3 421378df79SJean-Christophe PLAGNIOL-VILLARD #define ACM_RX_ENDPOINT 2 431378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_TX_ENDPOINT 2 441378df79SJean-Christophe PLAGNIOL-VILLARD #define GSERIAL_RX_ENDPOINT 1 451378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_ACM_INTERFACES 2 461378df79SJean-Christophe PLAGNIOL-VILLARD #define NUM_GSERIAL_INTERFACES 1 471378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface" 481378df79SJean-Christophe PLAGNIOL-VILLARD #define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface" 491378df79SJean-Christophe PLAGNIOL-VILLARD 501378df79SJean-Christophe PLAGNIOL-VILLARD /* 511378df79SJean-Christophe PLAGNIOL-VILLARD * Buffers to hold input and output data 521378df79SJean-Christophe PLAGNIOL-VILLARD */ 53b2caefbbSShiraz Hashim #define USBTTY_BUFFER_SIZE 2048 541378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_input; 551378df79SJean-Christophe PLAGNIOL-VILLARD static circbuf_t usbtty_output; 561378df79SJean-Christophe PLAGNIOL-VILLARD 571378df79SJean-Christophe PLAGNIOL-VILLARD 581378df79SJean-Christophe PLAGNIOL-VILLARD /* 591378df79SJean-Christophe PLAGNIOL-VILLARD * Instance variables 601378df79SJean-Christophe PLAGNIOL-VILLARD */ 6152cb4d4fSJean-Christophe PLAGNIOL-VILLARD static struct stdio_dev usbttydev; 621378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_instance device_instance[1]; 631378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_bus_instance bus_instance[1]; 641378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_instance config_instance[NUM_CONFIGS]; 651378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_instance interface_instance[MAX_INTERFACES]; 661378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_alternate_instance alternate_instance[MAX_INTERFACES]; 671378df79SJean-Christophe PLAGNIOL-VILLARD /* one extra for control endpoint */ 681378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; 691378df79SJean-Christophe PLAGNIOL-VILLARD 701378df79SJean-Christophe PLAGNIOL-VILLARD /* 711378df79SJean-Christophe PLAGNIOL-VILLARD * Global flag 721378df79SJean-Christophe PLAGNIOL-VILLARD */ 731378df79SJean-Christophe PLAGNIOL-VILLARD int usbtty_configured_flag = 0; 741378df79SJean-Christophe PLAGNIOL-VILLARD 751378df79SJean-Christophe PLAGNIOL-VILLARD /* 761378df79SJean-Christophe PLAGNIOL-VILLARD * Serial number 771378df79SJean-Christophe PLAGNIOL-VILLARD */ 781378df79SJean-Christophe PLAGNIOL-VILLARD static char serial_number[16]; 791378df79SJean-Christophe PLAGNIOL-VILLARD 801378df79SJean-Christophe PLAGNIOL-VILLARD 811378df79SJean-Christophe PLAGNIOL-VILLARD /* 821378df79SJean-Christophe PLAGNIOL-VILLARD * Descriptors, Strings, Local variables. 831378df79SJean-Christophe PLAGNIOL-VILLARD */ 841378df79SJean-Christophe PLAGNIOL-VILLARD 852731b9a8SJean-Christophe PLAGNIOL-VILLARD /* defined and used by gadget/ep0.c */ 861378df79SJean-Christophe PLAGNIOL-VILLARD extern struct usb_string_descriptor **usb_strings; 871378df79SJean-Christophe PLAGNIOL-VILLARD 881378df79SJean-Christophe PLAGNIOL-VILLARD /* Indicies, References */ 891378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short rx_endpoint = 0; 901378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short tx_endpoint = 0; 911378df79SJean-Christophe PLAGNIOL-VILLARD static unsigned short interface_count = 0; 921378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_string_descriptor *usbtty_string_table[STR_COUNT]; 931378df79SJean-Christophe PLAGNIOL-VILLARD 941378df79SJean-Christophe PLAGNIOL-VILLARD /* USB Descriptor Strings */ 951378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4}; 961378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)]; 971378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)]; 981378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)]; 991378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)]; 1001378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; 1011378df79SJean-Christophe PLAGNIOL-VILLARD static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; 1021378df79SJean-Christophe PLAGNIOL-VILLARD 1031378df79SJean-Christophe PLAGNIOL-VILLARD /* Standard USB Data Structures */ 1041378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES]; 1051378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS]; 1061378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_configuration_descriptor *configuration_descriptor = 0; 1071378df79SJean-Christophe PLAGNIOL-VILLARD static struct usb_device_descriptor device_descriptor = { 1081378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_device_descriptor), 1091378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_DEVICE, 1101378df79SJean-Christophe PLAGNIOL-VILLARD .bcdUSB = cpu_to_le16(USB_BCD_VERSION), 1111378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceSubClass = 0x00, 1121378df79SJean-Christophe PLAGNIOL-VILLARD .bDeviceProtocol = 0x00, 1131378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE, 1141378df79SJean-Christophe PLAGNIOL-VILLARD .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID), 1151378df79SJean-Christophe PLAGNIOL-VILLARD .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE), 1161378df79SJean-Christophe PLAGNIOL-VILLARD .iManufacturer = STR_MANUFACTURER, 1171378df79SJean-Christophe PLAGNIOL-VILLARD .iProduct = STR_PRODUCT, 1181378df79SJean-Christophe PLAGNIOL-VILLARD .iSerialNumber = STR_SERIAL, 1191378df79SJean-Christophe PLAGNIOL-VILLARD .bNumConfigurations = NUM_CONFIGS 1201378df79SJean-Christophe PLAGNIOL-VILLARD }; 1211378df79SJean-Christophe PLAGNIOL-VILLARD 1221378df79SJean-Christophe PLAGNIOL-VILLARD 123f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS) 124f9da0f89SVipin KUMAR static struct usb_qualifier_descriptor qualifier_descriptor = { 125f9da0f89SVipin KUMAR .bLength = sizeof(struct usb_qualifier_descriptor), 126f9da0f89SVipin KUMAR .bDescriptorType = USB_DT_QUAL, 127f9da0f89SVipin KUMAR .bcdUSB = cpu_to_le16(USB_BCD_VERSION), 128f9da0f89SVipin KUMAR .bDeviceClass = COMMUNICATIONS_DEVICE_CLASS, 129f9da0f89SVipin KUMAR .bDeviceSubClass = 0x00, 130f9da0f89SVipin KUMAR .bDeviceProtocol = 0x00, 131f9da0f89SVipin KUMAR .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE, 132f9da0f89SVipin KUMAR .bNumConfigurations = NUM_CONFIGS 133f9da0f89SVipin KUMAR }; 134f9da0f89SVipin KUMAR #endif 135f9da0f89SVipin KUMAR 1361378df79SJean-Christophe PLAGNIOL-VILLARD /* 1371378df79SJean-Christophe PLAGNIOL-VILLARD * Static CDC ACM specific descriptors 1381378df79SJean-Christophe PLAGNIOL-VILLARD */ 1391378df79SJean-Christophe PLAGNIOL-VILLARD 1401378df79SJean-Christophe PLAGNIOL-VILLARD struct acm_config_desc { 1411378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc; 1421378df79SJean-Christophe PLAGNIOL-VILLARD 1431378df79SJean-Christophe PLAGNIOL-VILLARD /* Master Interface */ 1441378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor interface_desc; 1451378df79SJean-Christophe PLAGNIOL-VILLARD 1461378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_header_function_descriptor usb_class_header; 1471378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_call_management_descriptor usb_class_call_mgt; 1481378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_abstract_control_descriptor usb_class_acm; 1491378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_class_union_function_descriptor usb_class_union; 1501378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_descriptor notification_endpoint; 1511378df79SJean-Christophe PLAGNIOL-VILLARD 1521378df79SJean-Christophe PLAGNIOL-VILLARD /* Slave Interface */ 1531378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_interface_descriptor data_class_interface; 154f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS-1]; 1551378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed)); 1561378df79SJean-Christophe PLAGNIOL-VILLARD 1571378df79SJean-Christophe PLAGNIOL-VILLARD static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = { 1581378df79SJean-Christophe PLAGNIOL-VILLARD { 1591378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={ 1601378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 1611378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_configuration_descriptor), 1621378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG, 1631378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength = 1641378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct acm_config_desc)), 1651378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_ACM_INTERFACES, 1661378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1, 1671378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG, 1681378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = 1691378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, 1701378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER 1711378df79SJean-Christophe PLAGNIOL-VILLARD }, 1721378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 1 */ 1731378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = { 1741378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_interface_descriptor), 1751378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE, 1761378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0, 1771378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0, 1781378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x01, 1791378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass = 1801378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_CONTROL, 1811378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS, 1821378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL, 1831378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_CTRL_INTERFACE, 1841378df79SJean-Christophe PLAGNIOL-VILLARD }, 1851378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_header = { 1861378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength = 1871378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_header_function_descriptor), 1881378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE, 1891378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_HEADER, 1901378df79SJean-Christophe PLAGNIOL-VILLARD .bcdCDC = cpu_to_le16(110), 1911378df79SJean-Christophe PLAGNIOL-VILLARD }, 1921378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_call_mgt = { 1931378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength = 1941378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_call_management_descriptor), 1951378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE, 1961378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_CMF, 1971378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00, 1981378df79SJean-Christophe PLAGNIOL-VILLARD .bDataInterface = 0x01, 1991378df79SJean-Christophe PLAGNIOL-VILLARD }, 2001378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_acm = { 2011378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength = 2021378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_abstract_control_descriptor), 2031378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE, 2041378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_ACMF, 2051378df79SJean-Christophe PLAGNIOL-VILLARD .bmCapabilities = 0x00, 2061378df79SJean-Christophe PLAGNIOL-VILLARD }, 2071378df79SJean-Christophe PLAGNIOL-VILLARD .usb_class_union = { 2081378df79SJean-Christophe PLAGNIOL-VILLARD .bFunctionLength = 2091378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_class_union_function_descriptor), 2101378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = CS_INTERFACE, 2111378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorSubtype = USB_ST_UF, 2121378df79SJean-Christophe PLAGNIOL-VILLARD .bMasterInterface = 0x00, 2131378df79SJean-Christophe PLAGNIOL-VILLARD .bSlaveInterface0 = 0x01, 2141378df79SJean-Christophe PLAGNIOL-VILLARD }, 2151378df79SJean-Christophe PLAGNIOL-VILLARD .notification_endpoint = { 2161378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 2171378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 2181378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 2199e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN, 2201378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT, 2211378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize 2221378df79SJean-Christophe PLAGNIOL-VILLARD = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), 2231378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF, 2241378df79SJean-Christophe PLAGNIOL-VILLARD }, 2251378df79SJean-Christophe PLAGNIOL-VILLARD 2261378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface 2 */ 2271378df79SJean-Christophe PLAGNIOL-VILLARD .data_class_interface = { 2281378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 2291378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor), 2301378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE, 2311378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0x01, 2321378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0x00, 2331378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = 0x02, 2341378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass = 2351378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_DATA, 2361378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE, 2371378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE, 2381378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE, 2391378df79SJean-Christophe PLAGNIOL-VILLARD }, 2401378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = { 2411378df79SJean-Christophe PLAGNIOL-VILLARD { 2421378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 2431378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 2441378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 2459e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT, 2461378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = 2471378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK, 2481378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize = 2491378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), 2501378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF, 2511378df79SJean-Christophe PLAGNIOL-VILLARD }, 2521378df79SJean-Christophe PLAGNIOL-VILLARD { 2531378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 2541378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 2551378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 2569e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN, 2571378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = 2581378df79SJean-Christophe PLAGNIOL-VILLARD USB_ENDPOINT_XFER_BULK, 2591378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize = 2601378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), 2611378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF, 2621378df79SJean-Christophe PLAGNIOL-VILLARD }, 2631378df79SJean-Christophe PLAGNIOL-VILLARD }, 2641378df79SJean-Christophe PLAGNIOL-VILLARD }, 2651378df79SJean-Christophe PLAGNIOL-VILLARD }; 2661378df79SJean-Christophe PLAGNIOL-VILLARD 2671378df79SJean-Christophe PLAGNIOL-VILLARD static struct rs232_emu rs232_desc={ 2681378df79SJean-Christophe PLAGNIOL-VILLARD .dter = 115200, 2691378df79SJean-Christophe PLAGNIOL-VILLARD .stop_bits = 0x00, 2701378df79SJean-Christophe PLAGNIOL-VILLARD .parity = 0x00, 2711378df79SJean-Christophe PLAGNIOL-VILLARD .data_bits = 0x08 2721378df79SJean-Christophe PLAGNIOL-VILLARD }; 2731378df79SJean-Christophe PLAGNIOL-VILLARD 2741378df79SJean-Christophe PLAGNIOL-VILLARD 2751378df79SJean-Christophe PLAGNIOL-VILLARD /* 2761378df79SJean-Christophe PLAGNIOL-VILLARD * Static Generic Serial specific data 2771378df79SJean-Christophe PLAGNIOL-VILLARD */ 2781378df79SJean-Christophe PLAGNIOL-VILLARD 2791378df79SJean-Christophe PLAGNIOL-VILLARD 2801378df79SJean-Christophe PLAGNIOL-VILLARD struct gserial_config_desc { 2811378df79SJean-Christophe PLAGNIOL-VILLARD 2821378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_configuration_descriptor configuration_desc; 283f3c0de63SAtin Malaviya struct usb_interface_descriptor interface_desc[NUM_GSERIAL_INTERFACES]; 284f3c0de63SAtin Malaviya struct usb_endpoint_descriptor data_endpoints[NUM_ENDPOINTS]; 2851378df79SJean-Christophe PLAGNIOL-VILLARD 2861378df79SJean-Christophe PLAGNIOL-VILLARD } __attribute__((packed)); 2871378df79SJean-Christophe PLAGNIOL-VILLARD 2881378df79SJean-Christophe PLAGNIOL-VILLARD static struct gserial_config_desc 2891378df79SJean-Christophe PLAGNIOL-VILLARD gserial_configuration_descriptors[NUM_CONFIGS] ={ 2901378df79SJean-Christophe PLAGNIOL-VILLARD { 2911378df79SJean-Christophe PLAGNIOL-VILLARD .configuration_desc ={ 2921378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = sizeof(struct usb_configuration_descriptor), 2931378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_CONFIG, 2941378df79SJean-Christophe PLAGNIOL-VILLARD .wTotalLength = 2951378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(sizeof(struct gserial_config_desc)), 2961378df79SJean-Christophe PLAGNIOL-VILLARD .bNumInterfaces = NUM_GSERIAL_INTERFACES, 2971378df79SJean-Christophe PLAGNIOL-VILLARD .bConfigurationValue = 1, 2981378df79SJean-Christophe PLAGNIOL-VILLARD .iConfiguration = STR_CONFIG, 2991378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = 3001378df79SJean-Christophe PLAGNIOL-VILLARD BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, 3011378df79SJean-Christophe PLAGNIOL-VILLARD .bMaxPower = USBTTY_MAXPOWER 3021378df79SJean-Christophe PLAGNIOL-VILLARD }, 3031378df79SJean-Christophe PLAGNIOL-VILLARD .interface_desc = { 3041378df79SJean-Christophe PLAGNIOL-VILLARD { 3051378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 3061378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_interface_descriptor), 3071378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_INTERFACE, 3081378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceNumber = 0, 3091378df79SJean-Christophe PLAGNIOL-VILLARD .bAlternateSetting = 0, 3101378df79SJean-Christophe PLAGNIOL-VILLARD .bNumEndpoints = NUM_ENDPOINTS, 3111378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceClass = 3121378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_INTERFACE_CLASS_VENDOR, 3131378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceSubClass = 3141378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_SUBCLASS, 3151378df79SJean-Christophe PLAGNIOL-VILLARD .bInterfaceProtocol = 3161378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_NO_PROTOCOL, 3171378df79SJean-Christophe PLAGNIOL-VILLARD .iInterface = STR_DATA_INTERFACE 3181378df79SJean-Christophe PLAGNIOL-VILLARD }, 3191378df79SJean-Christophe PLAGNIOL-VILLARD }, 3201378df79SJean-Christophe PLAGNIOL-VILLARD .data_endpoints = { 3211378df79SJean-Christophe PLAGNIOL-VILLARD { 3221378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 3231378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 3241378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 3259e78dae2SVivek Kutal .bEndpointAddress = UDC_OUT_ENDPOINT | USB_DIR_OUT, 3261378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK, 3271378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize = 3281378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE), 3291378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval= 0xFF, 3301378df79SJean-Christophe PLAGNIOL-VILLARD }, 3311378df79SJean-Christophe PLAGNIOL-VILLARD { 3321378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 3331378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 3341378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 3359e78dae2SVivek Kutal .bEndpointAddress = UDC_IN_ENDPOINT | USB_DIR_IN, 3361378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_BULK, 3371378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize = 3381378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE), 3391378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF, 3401378df79SJean-Christophe PLAGNIOL-VILLARD }, 3411378df79SJean-Christophe PLAGNIOL-VILLARD { 3421378df79SJean-Christophe PLAGNIOL-VILLARD .bLength = 3431378df79SJean-Christophe PLAGNIOL-VILLARD sizeof(struct usb_endpoint_descriptor), 3441378df79SJean-Christophe PLAGNIOL-VILLARD .bDescriptorType = USB_DT_ENDPOINT, 3459e78dae2SVivek Kutal .bEndpointAddress = UDC_INT_ENDPOINT | USB_DIR_IN, 3461378df79SJean-Christophe PLAGNIOL-VILLARD .bmAttributes = USB_ENDPOINT_XFER_INT, 3471378df79SJean-Christophe PLAGNIOL-VILLARD .wMaxPacketSize = 3481378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), 3491378df79SJean-Christophe PLAGNIOL-VILLARD .bInterval = 0xFF, 3501378df79SJean-Christophe PLAGNIOL-VILLARD }, 3511378df79SJean-Christophe PLAGNIOL-VILLARD }, 3521378df79SJean-Christophe PLAGNIOL-VILLARD }, 3531378df79SJean-Christophe PLAGNIOL-VILLARD }; 3541378df79SJean-Christophe PLAGNIOL-VILLARD 3551378df79SJean-Christophe PLAGNIOL-VILLARD /* 3561378df79SJean-Christophe PLAGNIOL-VILLARD * Static Function Prototypes 3571378df79SJean-Christophe PLAGNIOL-VILLARD */ 3581378df79SJean-Christophe PLAGNIOL-VILLARD 3591378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void); 3601378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void); 3611378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void); 3621378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type); 3631378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_event_handler (struct usb_device_instance *device, 3641378df79SJean-Christophe PLAGNIOL-VILLARD usb_device_event_t event, int data); 3651378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_cdc_setup(struct usb_device_request *request, 3661378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *urb); 3671378df79SJean-Christophe PLAGNIOL-VILLARD static int usbtty_configured (void); 3681378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf); 3691378df79SJean-Christophe PLAGNIOL-VILLARD static int fill_buffer (circbuf_t * buf); 3701378df79SJean-Christophe PLAGNIOL-VILLARD 3711378df79SJean-Christophe PLAGNIOL-VILLARD void usbtty_poll (void); 3721378df79SJean-Christophe PLAGNIOL-VILLARD 3731378df79SJean-Christophe PLAGNIOL-VILLARD /* utility function for converting char* to wide string used by USB */ 3741378df79SJean-Christophe PLAGNIOL-VILLARD static void str2wide (char *str, u16 * wide) 3751378df79SJean-Christophe PLAGNIOL-VILLARD { 3761378df79SJean-Christophe PLAGNIOL-VILLARD int i; 3771378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < strlen (str) && str[i]; i++){ 3781378df79SJean-Christophe PLAGNIOL-VILLARD #if defined(__LITTLE_ENDIAN) 3791378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = (u16) str[i]; 3801378df79SJean-Christophe PLAGNIOL-VILLARD #elif defined(__BIG_ENDIAN) 3811378df79SJean-Christophe PLAGNIOL-VILLARD wide[i] = ((u16)(str[i])<<8); 3821378df79SJean-Christophe PLAGNIOL-VILLARD #else 3831378df79SJean-Christophe PLAGNIOL-VILLARD #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined" 3841378df79SJean-Christophe PLAGNIOL-VILLARD #endif 3851378df79SJean-Christophe PLAGNIOL-VILLARD } 3861378df79SJean-Christophe PLAGNIOL-VILLARD } 3871378df79SJean-Christophe PLAGNIOL-VILLARD 3881378df79SJean-Christophe PLAGNIOL-VILLARD /* 3891378df79SJean-Christophe PLAGNIOL-VILLARD * Test whether a character is in the RX buffer 3901378df79SJean-Christophe PLAGNIOL-VILLARD */ 3911378df79SJean-Christophe PLAGNIOL-VILLARD 392709ea543SSimon Glass int usbtty_tstc(struct stdio_dev *dev) 3931378df79SJean-Christophe PLAGNIOL-VILLARD { 3941378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint = 3951378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint]; 3961378df79SJean-Christophe PLAGNIOL-VILLARD 3971378df79SJean-Christophe PLAGNIOL-VILLARD /* If no input data exists, allow more RX to be accepted */ 3981378df79SJean-Christophe PLAGNIOL-VILLARD if(usbtty_input.size <= 0){ 3991378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03); 4001378df79SJean-Christophe PLAGNIOL-VILLARD } 4011378df79SJean-Christophe PLAGNIOL-VILLARD 4021378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll (); 4031378df79SJean-Christophe PLAGNIOL-VILLARD return (usbtty_input.size > 0); 4041378df79SJean-Christophe PLAGNIOL-VILLARD } 4051378df79SJean-Christophe PLAGNIOL-VILLARD 4061378df79SJean-Christophe PLAGNIOL-VILLARD /* 4071378df79SJean-Christophe PLAGNIOL-VILLARD * Read a single byte from the usb client port. Returns 1 on success, 0 4081378df79SJean-Christophe PLAGNIOL-VILLARD * otherwise. When the function is succesfull, the character read is 4091378df79SJean-Christophe PLAGNIOL-VILLARD * written into its argument c. 4101378df79SJean-Christophe PLAGNIOL-VILLARD */ 4111378df79SJean-Christophe PLAGNIOL-VILLARD 412709ea543SSimon Glass int usbtty_getc(struct stdio_dev *dev) 4131378df79SJean-Christophe PLAGNIOL-VILLARD { 4141378df79SJean-Christophe PLAGNIOL-VILLARD char c; 4151378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint = 4161378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[rx_endpoint]; 4171378df79SJean-Christophe PLAGNIOL-VILLARD 4181378df79SJean-Christophe PLAGNIOL-VILLARD while (usbtty_input.size <= 0) { 4191378df79SJean-Christophe PLAGNIOL-VILLARD udc_unset_nak(endpoint->endpoint_address&0x03); 4201378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_poll (); 4211378df79SJean-Christophe PLAGNIOL-VILLARD } 4221378df79SJean-Christophe PLAGNIOL-VILLARD 4231378df79SJean-Christophe PLAGNIOL-VILLARD buf_pop (&usbtty_input, &c, 1); 4241378df79SJean-Christophe PLAGNIOL-VILLARD udc_set_nak(endpoint->endpoint_address&0x03); 4251378df79SJean-Christophe PLAGNIOL-VILLARD 4261378df79SJean-Christophe PLAGNIOL-VILLARD return c; 4271378df79SJean-Christophe PLAGNIOL-VILLARD } 4281378df79SJean-Christophe PLAGNIOL-VILLARD 4291378df79SJean-Christophe PLAGNIOL-VILLARD /* 4301378df79SJean-Christophe PLAGNIOL-VILLARD * Output a single byte to the usb client port. 4311378df79SJean-Christophe PLAGNIOL-VILLARD */ 432709ea543SSimon Glass void usbtty_putc(struct stdio_dev *dev, const char c) 4331378df79SJean-Christophe PLAGNIOL-VILLARD { 434f3c0de63SAtin Malaviya if (!usbtty_configured ()) 435f3c0de63SAtin Malaviya return; 436f3c0de63SAtin Malaviya 4371378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, &c, 1); 4381378df79SJean-Christophe PLAGNIOL-VILLARD /* If \n, also do \r */ 4391378df79SJean-Christophe PLAGNIOL-VILLARD if (c == '\n') 4401378df79SJean-Christophe PLAGNIOL-VILLARD buf_push (&usbtty_output, "\r", 1); 4411378df79SJean-Christophe PLAGNIOL-VILLARD 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 */ 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 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 478*c79cba37SMasahiro 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 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 (str, n + 1); 5021378df79SJean-Christophe PLAGNIOL-VILLARD __usbtty_puts ("\r", 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 */ 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 5271378df79SJean-Christophe PLAGNIOL-VILLARD /* Ger seiral number */ 5281378df79SJean-Christophe PLAGNIOL-VILLARD if (!(sn = getenv("serial#"))) { 5291378df79SJean-Christophe PLAGNIOL-VILLARD sn = "000000000000"; 5301378df79SJean-Christophe PLAGNIOL-VILLARD } 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 */ 5421378df79SJean-Christophe PLAGNIOL-VILLARD 5431378df79SJean-Christophe PLAGNIOL-VILLARD if(!(tt = getenv("usbtty"))) { 5441378df79SJean-Christophe PLAGNIOL-VILLARD tt = "generic"; 5451378df79SJean-Christophe PLAGNIOL-VILLARD } 5461378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_terminal_type(strcmp(tt,"cdc_acm")); 5471378df79SJean-Christophe PLAGNIOL-VILLARD 5481378df79SJean-Christophe PLAGNIOL-VILLARD /* prepare buffers... */ 5491378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_input, USBTTY_BUFFER_SIZE); 5501378df79SJean-Christophe PLAGNIOL-VILLARD buf_init (&usbtty_output, USBTTY_BUFFER_SIZE); 5511378df79SJean-Christophe PLAGNIOL-VILLARD 5521378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, set up USB controller and infrastructure */ 5531378df79SJean-Christophe PLAGNIOL-VILLARD udc_init (); /* Basic USB initialization */ 5541378df79SJean-Christophe PLAGNIOL-VILLARD 5551378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_strings (); 5561378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_init_instances (); 5571378df79SJean-Christophe PLAGNIOL-VILLARD 558241d9a61SStefan Herbrechtsmeier usbtty_init_endpoints (); 559241d9a61SStefan Herbrechtsmeier 5601378df79SJean-Christophe PLAGNIOL-VILLARD udc_startup_events (device_instance);/* Enable dev, init udc pointers */ 5611378df79SJean-Christophe PLAGNIOL-VILLARD udc_connect (); /* Enable pullup for host detection */ 5621378df79SJean-Christophe PLAGNIOL-VILLARD 5631378df79SJean-Christophe PLAGNIOL-VILLARD /* Device initialization */ 5641378df79SJean-Christophe PLAGNIOL-VILLARD memset (&usbttydev, 0, sizeof (usbttydev)); 5651378df79SJean-Christophe PLAGNIOL-VILLARD 5661378df79SJean-Christophe PLAGNIOL-VILLARD strcpy (usbttydev.name, "usbtty"); 5671378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.ext = 0; /* No extensions */ 5681378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT; 5691378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.tstc = usbtty_tstc; /* 'tstc' function */ 5701378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.getc = usbtty_getc; /* 'getc' function */ 5711378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.putc = usbtty_putc; /* 'putc' function */ 5721378df79SJean-Christophe PLAGNIOL-VILLARD usbttydev.puts = usbtty_puts; /* 'puts' function */ 5731378df79SJean-Christophe PLAGNIOL-VILLARD 57452cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register (&usbttydev); 5751378df79SJean-Christophe PLAGNIOL-VILLARD 5761378df79SJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc; 5771378df79SJean-Christophe PLAGNIOL-VILLARD } 5781378df79SJean-Christophe PLAGNIOL-VILLARD 5791378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_strings (void) 5801378df79SJean-Christophe PLAGNIOL-VILLARD { 5811378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_string_descriptor *string; 5821378df79SJean-Christophe PLAGNIOL-VILLARD 5831378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_LANG] = 5841378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_string_descriptor*)wstrLang; 5851378df79SJean-Christophe PLAGNIOL-VILLARD 5861378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrManufacturer; 5871378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrManufacturer); 5881378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 5891378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_MANUFACTURER, string->wData); 5901378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_MANUFACTURER]=string; 5911378df79SJean-Christophe PLAGNIOL-VILLARD 5921378df79SJean-Christophe PLAGNIOL-VILLARD 5931378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrProduct; 5941378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrProduct); 5951378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 5961378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData); 5971378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_PRODUCT]=string; 5981378df79SJean-Christophe PLAGNIOL-VILLARD 5991378df79SJean-Christophe PLAGNIOL-VILLARD 6001378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrSerial; 6011378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(serial_number); 6021378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 6031378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (serial_number, string->wData); 6041378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_SERIAL]=string; 6051378df79SJean-Christophe PLAGNIOL-VILLARD 6061378df79SJean-Christophe PLAGNIOL-VILLARD 6071378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrConfiguration; 6081378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrConfiguration); 6091378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 6101378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData); 6111378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CONFIG]=string; 6121378df79SJean-Christophe PLAGNIOL-VILLARD 6131378df79SJean-Christophe PLAGNIOL-VILLARD 6141378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrDataInterface; 6151378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrDataInterface); 6161378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 6171378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData); 6181378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_DATA_INTERFACE]=string; 6191378df79SJean-Christophe PLAGNIOL-VILLARD 6201378df79SJean-Christophe PLAGNIOL-VILLARD string = (struct usb_string_descriptor *) wstrCtrlInterface; 6211378df79SJean-Christophe PLAGNIOL-VILLARD string->bLength = sizeof(wstrCtrlInterface); 6221378df79SJean-Christophe PLAGNIOL-VILLARD string->bDescriptorType = USB_DT_STRING; 6231378df79SJean-Christophe PLAGNIOL-VILLARD str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData); 6241378df79SJean-Christophe PLAGNIOL-VILLARD usbtty_string_table[STR_CTRL_INTERFACE]=string; 6251378df79SJean-Christophe PLAGNIOL-VILLARD 6261378df79SJean-Christophe PLAGNIOL-VILLARD /* Now, initialize the string table for ep0 handling */ 6271378df79SJean-Christophe PLAGNIOL-VILLARD usb_strings = usbtty_string_table; 6281378df79SJean-Christophe PLAGNIOL-VILLARD } 6291378df79SJean-Christophe PLAGNIOL-VILLARD 630b2fb47f1STom Rini #define init_wMaxPacketSize(x) le16_to_cpu(get_unaligned(\ 631b2fb47f1STom Rini &ep_descriptor_ptrs[(x) - 1]->wMaxPacketSize)); 632b2fb47f1STom Rini 6331378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_instances (void) 6341378df79SJean-Christophe PLAGNIOL-VILLARD { 6351378df79SJean-Christophe PLAGNIOL-VILLARD int i; 6361378df79SJean-Christophe PLAGNIOL-VILLARD 6371378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize device instance */ 6381378df79SJean-Christophe PLAGNIOL-VILLARD memset (device_instance, 0, sizeof (struct usb_device_instance)); 6391378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_state = STATE_INIT; 6401378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->device_descriptor = &device_descriptor; 641f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS) 642f9da0f89SVipin KUMAR device_instance->qualifier_descriptor = &qualifier_descriptor; 643f9da0f89SVipin KUMAR #endif 6441378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->event = usbtty_event_handler; 6451378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->cdc_recv_setup = usbtty_cdc_setup; 6461378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->bus = bus_instance; 6471378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configurations = NUM_CONFIGS; 6481378df79SJean-Christophe PLAGNIOL-VILLARD device_instance->configuration_instance_array = config_instance; 6491378df79SJean-Christophe PLAGNIOL-VILLARD 6501378df79SJean-Christophe PLAGNIOL-VILLARD /* initialize bus instance */ 6511378df79SJean-Christophe PLAGNIOL-VILLARD memset (bus_instance, 0, sizeof (struct usb_bus_instance)); 6521378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->device = device_instance; 6531378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->endpoint_array = endpoint_instance; 6541378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = 1; 6551378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->maxpacketsize = 64; 6561378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->serial_number_str = serial_number; 6571378df79SJean-Christophe PLAGNIOL-VILLARD 6581378df79SJean-Christophe PLAGNIOL-VILLARD /* configuration instance */ 6591378df79SJean-Christophe PLAGNIOL-VILLARD memset (config_instance, 0, 6601378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_configuration_instance)); 6611378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interfaces = interface_count; 6621378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->configuration_descriptor = configuration_descriptor; 6631378df79SJean-Christophe PLAGNIOL-VILLARD config_instance->interface_instance_array = interface_instance; 6641378df79SJean-Christophe PLAGNIOL-VILLARD 6651378df79SJean-Christophe PLAGNIOL-VILLARD /* interface instance */ 6661378df79SJean-Christophe PLAGNIOL-VILLARD memset (interface_instance, 0, 6671378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_interface_instance)); 6681378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates = 1; 6691378df79SJean-Christophe PLAGNIOL-VILLARD interface_instance->alternates_instance_array = alternate_instance; 6701378df79SJean-Christophe PLAGNIOL-VILLARD 6711378df79SJean-Christophe PLAGNIOL-VILLARD /* alternates instance */ 6721378df79SJean-Christophe PLAGNIOL-VILLARD memset (alternate_instance, 0, 6731378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_alternate_instance)); 6741378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->interface_descriptor = interface_descriptors; 6751378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints = NUM_ENDPOINTS; 6761378df79SJean-Christophe PLAGNIOL-VILLARD alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs; 6771378df79SJean-Christophe PLAGNIOL-VILLARD 6781378df79SJean-Christophe PLAGNIOL-VILLARD /* endpoint instances */ 6791378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[0], 0, 6801378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance)); 6811378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].endpoint_address = 0; 6821378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE; 6831378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL; 6841378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE; 6851378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL; 6861378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, 0, &endpoint_instance[0]); 6871378df79SJean-Christophe PLAGNIOL-VILLARD 6881378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) { 6891378df79SJean-Christophe PLAGNIOL-VILLARD memset (&endpoint_instance[i], 0, 6901378df79SJean-Christophe PLAGNIOL-VILLARD sizeof (struct usb_endpoint_instance)); 6911378df79SJean-Christophe PLAGNIOL-VILLARD 6921378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].endpoint_address = 6931378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bEndpointAddress; 6941378df79SJean-Christophe PLAGNIOL-VILLARD 6951378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_attributes = 6961378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes; 6971378df79SJean-Christophe PLAGNIOL-VILLARD 698b2fb47f1STom Rini endpoint_instance[i].rcv_packetSize = init_wMaxPacketSize(i); 6991378df79SJean-Christophe PLAGNIOL-VILLARD 7001378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes = 7011378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes; 7021378df79SJean-Christophe PLAGNIOL-VILLARD 703b2fb47f1STom Rini endpoint_instance[i].tx_packetSize = init_wMaxPacketSize(i); 7041378df79SJean-Christophe PLAGNIOL-VILLARD 7051378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_attributes = 7061378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[i - 1]->bmAttributes; 7071378df79SJean-Christophe PLAGNIOL-VILLARD 7081378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rcv); 7091378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].rdy); 7101378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].tx); 7111378df79SJean-Christophe PLAGNIOL-VILLARD urb_link_init (&endpoint_instance[i].done); 7121378df79SJean-Christophe PLAGNIOL-VILLARD 7131378df79SJean-Christophe PLAGNIOL-VILLARD if (endpoint_instance[i].endpoint_address & USB_DIR_IN) 7141378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].tx_urb = 7151378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance, 7161378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]); 7171378df79SJean-Christophe PLAGNIOL-VILLARD else 7181378df79SJean-Christophe PLAGNIOL-VILLARD endpoint_instance[i].rcv_urb = 7191378df79SJean-Christophe PLAGNIOL-VILLARD usbd_alloc_urb (device_instance, 7201378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[i]); 7211378df79SJean-Christophe PLAGNIOL-VILLARD } 7221378df79SJean-Christophe PLAGNIOL-VILLARD } 7231378df79SJean-Christophe PLAGNIOL-VILLARD 7241378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_endpoints (void) 7251378df79SJean-Christophe PLAGNIOL-VILLARD { 7261378df79SJean-Christophe PLAGNIOL-VILLARD int i; 7271378df79SJean-Christophe PLAGNIOL-VILLARD 7281378df79SJean-Christophe PLAGNIOL-VILLARD bus_instance->max_endpoints = NUM_ENDPOINTS + 1; 7291378df79SJean-Christophe PLAGNIOL-VILLARD for (i = 1; i <= NUM_ENDPOINTS; i++) { 7301378df79SJean-Christophe PLAGNIOL-VILLARD udc_setup_ep (device_instance, i, &endpoint_instance[i]); 7311378df79SJean-Christophe PLAGNIOL-VILLARD } 7321378df79SJean-Christophe PLAGNIOL-VILLARD } 7331378df79SJean-Christophe PLAGNIOL-VILLARD 7341378df79SJean-Christophe PLAGNIOL-VILLARD /* usbtty_init_terminal_type 7351378df79SJean-Christophe PLAGNIOL-VILLARD * 7361378df79SJean-Christophe PLAGNIOL-VILLARD * Do some late binding for our device type. 7371378df79SJean-Christophe PLAGNIOL-VILLARD */ 7381378df79SJean-Christophe PLAGNIOL-VILLARD static void usbtty_init_terminal_type(short type) 7391378df79SJean-Christophe PLAGNIOL-VILLARD { 7401378df79SJean-Christophe PLAGNIOL-VILLARD switch(type){ 7411378df79SJean-Christophe PLAGNIOL-VILLARD /* CDC ACM */ 7421378df79SJean-Christophe PLAGNIOL-VILLARD case 0: 7431378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */ 7441378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] = 7451378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].notification_endpoint; 7461378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] = 7471378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[0]; 7481378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] = 7491378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors[0].data_endpoints[1]; 7501378df79SJean-Christophe PLAGNIOL-VILLARD 7511378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */ 7521378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass = 7531378df79SJean-Christophe PLAGNIOL-VILLARD COMMUNICATIONS_DEVICE_CLASS; 7541378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct = 7551378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM); 7561378df79SJean-Christophe PLAGNIOL-VILLARD 757f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS) 758f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass = 759f9da0f89SVipin KUMAR COMMUNICATIONS_DEVICE_CLASS; 760f9da0f89SVipin KUMAR #endif 7611378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */ 7621378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = ACM_TX_ENDPOINT; 7631378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = ACM_RX_ENDPOINT; 7641378df79SJean-Christophe PLAGNIOL-VILLARD 7651378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */ 7661378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor = 7671378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*) 7681378df79SJean-Christophe PLAGNIOL-VILLARD &acm_configuration_descriptors; 7691378df79SJean-Christophe PLAGNIOL-VILLARD 7701378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */ 7711378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_ACM_INTERFACES; 7721378df79SJean-Christophe PLAGNIOL-VILLARD break; 7731378df79SJean-Christophe PLAGNIOL-VILLARD 7741378df79SJean-Christophe PLAGNIOL-VILLARD /* BULK IN/OUT & Default */ 7751378df79SJean-Christophe PLAGNIOL-VILLARD case 1: 7761378df79SJean-Christophe PLAGNIOL-VILLARD default: 7771378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint descriptors */ 7781378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[0] = 7791378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[0]; 7801378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[1] = 7811378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[1]; 7821378df79SJean-Christophe PLAGNIOL-VILLARD ep_descriptor_ptrs[2] = 7831378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors[0].data_endpoints[2]; 7841378df79SJean-Christophe PLAGNIOL-VILLARD 7851378df79SJean-Christophe PLAGNIOL-VILLARD /* Enumerate Device Descriptor */ 7861378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.bDeviceClass = 0xFF; 7871378df79SJean-Christophe PLAGNIOL-VILLARD device_descriptor.idProduct = 7881378df79SJean-Christophe PLAGNIOL-VILLARD cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL); 789f9da0f89SVipin KUMAR #if defined(CONFIG_USBD_HS) 790f9da0f89SVipin KUMAR qualifier_descriptor.bDeviceClass = 0xFF; 791f9da0f89SVipin KUMAR #endif 7921378df79SJean-Christophe PLAGNIOL-VILLARD /* Assign endpoint indices */ 7931378df79SJean-Christophe PLAGNIOL-VILLARD tx_endpoint = GSERIAL_TX_ENDPOINT; 7941378df79SJean-Christophe PLAGNIOL-VILLARD rx_endpoint = GSERIAL_RX_ENDPOINT; 7951378df79SJean-Christophe PLAGNIOL-VILLARD 7961378df79SJean-Christophe PLAGNIOL-VILLARD /* Configuration Descriptor */ 7971378df79SJean-Christophe PLAGNIOL-VILLARD configuration_descriptor = 7981378df79SJean-Christophe PLAGNIOL-VILLARD (struct usb_configuration_descriptor*) 7991378df79SJean-Christophe PLAGNIOL-VILLARD &gserial_configuration_descriptors; 8001378df79SJean-Christophe PLAGNIOL-VILLARD 8011378df79SJean-Christophe PLAGNIOL-VILLARD /* Interface count */ 8021378df79SJean-Christophe PLAGNIOL-VILLARD interface_count = NUM_GSERIAL_INTERFACES; 8031378df79SJean-Christophe PLAGNIOL-VILLARD break; 8041378df79SJean-Christophe PLAGNIOL-VILLARD } 8051378df79SJean-Christophe PLAGNIOL-VILLARD } 8061378df79SJean-Christophe PLAGNIOL-VILLARD 8071378df79SJean-Christophe PLAGNIOL-VILLARD /******************************************************************************/ 8081378df79SJean-Christophe PLAGNIOL-VILLARD 8091378df79SJean-Christophe PLAGNIOL-VILLARD static struct urb *next_urb (struct usb_device_instance *device, 8101378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint) 8111378df79SJean-Christophe PLAGNIOL-VILLARD { 8121378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL; 8131378df79SJean-Christophe PLAGNIOL-VILLARD int space; 8141378df79SJean-Christophe PLAGNIOL-VILLARD 8151378df79SJean-Christophe PLAGNIOL-VILLARD /* If there's a queue, then we should add to the last urb */ 8161378df79SJean-Christophe PLAGNIOL-VILLARD if (!endpoint->tx_queue) { 8171378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = endpoint->tx_urb; 8181378df79SJean-Christophe PLAGNIOL-VILLARD } else { 8191378df79SJean-Christophe PLAGNIOL-VILLARD /* Last urb from tx chain */ 8201378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = 8211378df79SJean-Christophe PLAGNIOL-VILLARD p2surround (struct urb, link, endpoint->tx.prev); 8221378df79SJean-Christophe PLAGNIOL-VILLARD } 8231378df79SJean-Christophe PLAGNIOL-VILLARD 8241378df79SJean-Christophe PLAGNIOL-VILLARD /* Make sure this one has enough room */ 8251378df79SJean-Christophe PLAGNIOL-VILLARD space = current_urb->buffer_length - current_urb->actual_length; 8261378df79SJean-Christophe PLAGNIOL-VILLARD if (space > 0) { 8271378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb; 8281378df79SJean-Christophe PLAGNIOL-VILLARD } else { /* No space here */ 8291378df79SJean-Christophe PLAGNIOL-VILLARD /* First look at done list */ 8301378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = first_urb_detached (&endpoint->done); 8311378df79SJean-Christophe PLAGNIOL-VILLARD if (!current_urb) { 8321378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = usbd_alloc_urb (device, endpoint); 8331378df79SJean-Christophe PLAGNIOL-VILLARD } 8341378df79SJean-Christophe PLAGNIOL-VILLARD 8351378df79SJean-Christophe PLAGNIOL-VILLARD urb_append (&endpoint->tx, current_urb); 8361378df79SJean-Christophe PLAGNIOL-VILLARD endpoint->tx_queue++; 8371378df79SJean-Christophe PLAGNIOL-VILLARD } 8381378df79SJean-Christophe PLAGNIOL-VILLARD return current_urb; 8391378df79SJean-Christophe PLAGNIOL-VILLARD } 8401378df79SJean-Christophe PLAGNIOL-VILLARD 8411378df79SJean-Christophe PLAGNIOL-VILLARD static int write_buffer (circbuf_t * buf) 8421378df79SJean-Christophe PLAGNIOL-VILLARD { 8431378df79SJean-Christophe PLAGNIOL-VILLARD if (!usbtty_configured ()) { 8441378df79SJean-Christophe PLAGNIOL-VILLARD return 0; 8451378df79SJean-Christophe PLAGNIOL-VILLARD } 8461378df79SJean-Christophe PLAGNIOL-VILLARD 8471378df79SJean-Christophe PLAGNIOL-VILLARD struct usb_endpoint_instance *endpoint = 8481378df79SJean-Christophe PLAGNIOL-VILLARD &endpoint_instance[tx_endpoint]; 8491378df79SJean-Christophe PLAGNIOL-VILLARD struct urb *current_urb = NULL; 8501378df79SJean-Christophe PLAGNIOL-VILLARD 8511378df79SJean-Christophe PLAGNIOL-VILLARD current_urb = next_urb (device_instance, endpoint); 8521378df79SJean-Christophe PLAGNIOL-VILLARD /* TX data still exists - send it now 8531378df79SJean-Christophe PLAGNIOL-VILLARD */ 8541378df79SJean-Christophe PLAGNIOL-VILLARD if(endpoint->sent < current_urb->actual_length){ 8551378df79SJean-Christophe PLAGNIOL-VILLARD if(udc_endpoint_write (endpoint)){ 8561378df79SJean-Christophe PLAGNIOL-VILLARD /* Write pre-empted by RX */ 8571378df79SJean-Christophe PLAGNIOL-VILLARD return -1; 8581378df79SJean-Christophe PLAGNIOL-VILLARD } 8591378df79SJean-Christophe PLAGNIOL-VILLARD } 8601378df79SJean-Christophe PLAGNIOL-VILLARD 8611378df79SJean-Christophe PLAGNIOL-VILLARD if (buf->size) { 8621378df79SJean-Christophe PLAGNIOL-VILLARD char *dest; 8631378df79SJean-Christophe PLAGNIOL-VILLARD 8641378df79SJean-Christophe PLAGNIOL-VILLARD int space_avail; 8651378df79SJean-Christophe PLAGNIOL-VILLARD int popnum, popped; 8661378df79SJean-Christophe PLAGNIOL-VILLARD int total = 0; 8671378df79SJean-Christophe PLAGNIOL-VILLARD 8681378df79SJean-Christophe PLAGNIOL-VILLARD /* Break buffer into urb sized pieces, 8691378df79SJean-Christophe PLAGNIOL-VILLARD * and link each to the endpoint 8701378df79SJean-Christophe PLAGNIOL-VILLARD */ 8711378df79SJean-Christophe PLAGNIOL-VILLARD while (buf->size > 0) { 8721378df79SJean-Christophe PLAGNIOL-VILLARD 8731378df79SJean-Christophe PLAGNIOL-VILLARD if (!current_urb) { 8741378df79SJean-Christophe PLAGNIOL-VILLARD TTYERR ("current_urb is NULL, buf->size %d\n", 8751378df79SJean-Christophe PLAGNIOL-VILLARD buf->size); 8761378df79SJean-Christophe PLAGNIOL-VILLARD return total; 8771378df79SJean-Christophe PLAGNIOL-VILLARD } 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; 885*c79cba37SMasahiro Yamada popnum = min(space_avail, 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 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 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 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 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 */ 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