diff options
author | Marcin Juszkiewicz <hrw@openedhand.com> | 2007-10-29 11:00:19 +0000 |
---|---|---|
committer | Marcin Juszkiewicz <hrw@openedhand.com> | 2007-10-29 11:00:19 +0000 |
commit | 70abc059ebae6bd18399c0361d348f415a3f631a (patch) | |
tree | 86ae8bf44d64d40603b5bca6774eac7f1aaa3ce5 /meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch | |
parent | ce1e498f5d3a46642b6bb14c14ebae2a52f732a4 (diff) | |
download | poky-70abc059ebae6bd18399c0361d348f415a3f631a.tar.gz |
u-boot: import OpenMoko uboot from OE
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3014 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch')
-rw-r--r-- | meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch | 1607 |
1 files changed, 1607 insertions, 0 deletions
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch new file mode 100644 index 0000000000..722a227aa6 --- /dev/null +++ b/meta/packages/uboot/u-boot-mkimage-openmoko-native/uboot-usbtty-acm.patch | |||
@@ -0,0 +1,1607 @@ | |||
1 | This patch adds cdc_acm interoperability to u-boot usbtty. | ||
2 | |||
3 | It was taken (almost blindly) from the Linux for Siemens SX1 project on | ||
4 | handhelds.org. Please don't complain to me about coding style issues | ||
5 | or whitespace changes in this one - HW. | ||
6 | |||
7 | Index: u-boot/drivers/usbtty.c | ||
8 | =================================================================== | ||
9 | --- u-boot.orig/drivers/usbtty.c 2007-02-08 21:11:27.000000000 +0100 | ||
10 | +++ u-boot/drivers/usbtty.c 2007-02-08 21:11:55.000000000 +0100 | ||
11 | @@ -1,6 +1,9 @@ | ||
12 | /* | ||
13 | * (C) Copyright 2003 | ||
14 | * Gerry Hamel, geh@ti.com, Texas Instruments | ||
15 | + * | ||
16 | + * (C) Copyright 2006 | ||
17 | + * Bryan O'Donoghue, bodonoghue <at> codehermit.ie | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License as published by | ||
21 | @@ -22,26 +25,61 @@ | ||
22 | |||
23 | #ifdef CONFIG_USB_TTY | ||
24 | |||
25 | +#include <asm/io.h> | ||
26 | #include <circbuf.h> | ||
27 | #include <devices.h> | ||
28 | #include "usbtty.h" | ||
29 | +#include "usb_cdc_acm.h" | ||
30 | +#include "usbdescriptors.h" | ||
31 | +#include <config.h> /* If defined, override Linux identifiers with | ||
32 | + * vendor specific ones */ | ||
33 | |||
34 | #if 0 | ||
35 | -#define TTYDBG(fmt,args...) serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) | ||
36 | +//+++ debug print into memory buffer,like kernel log | ||
37 | +static char* log_buf = 0x10e00000; // somewhere in RAM | ||
38 | +static char log_str[512]; | ||
39 | +#define TTYDBG(fmt,args...)\ | ||
40 | + sprintf(log_str,"\n[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args);\ | ||
41 | + memcpy(log_buf, log_str, strlen(log_str));\ | ||
42 | + log_buf+=strlen(log_str);\ | ||
43 | + strcpy(log_buf,"\n---------------------------------------------------")\ | ||
44 | +//--- | ||
45 | #else | ||
46 | #define TTYDBG(fmt,args...) do{}while(0) | ||
47 | #endif | ||
48 | |||
49 | #if 0 | ||
50 | -#define TTYERR(fmt,args...) serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) | ||
51 | +#define TTYDBG(fmt,args...)\ | ||
52 | + serial_printf("[%s] %s %d: "fmt"\n", __FILE__,__FUNCTION__,__LINE__,##args) | ||
53 | +#endif | ||
54 | + | ||
55 | +#if 0 | ||
56 | +#define TTYERR(fmt,args...)\ | ||
57 | + serial_printf("ERROR![%s] %s %d: "fmt"\n", __FILE__,__FUNCTION__,\ | ||
58 | + __LINE__,##args) | ||
59 | #else | ||
60 | #define TTYERR(fmt,args...) do{}while(0) | ||
61 | #endif | ||
62 | |||
63 | /* | ||
64 | + * Defines | ||
65 | + */ | ||
66 | +#define NUM_CONFIGS 1 | ||
67 | +#define MAX_INTERFACES 2 | ||
68 | +#define NUM_ENDPOINTS 3 | ||
69 | +#define ACM_TX_ENDPOINT 3 | ||
70 | +#define ACM_RX_ENDPOINT 2 | ||
71 | +#define GSERIAL_TX_ENDPOINT 2 | ||
72 | +#define GSERIAL_RX_ENDPOINT 1 | ||
73 | +#define NUM_ACM_INTERFACES 2 | ||
74 | +#define NUM_GSERIAL_INTERFACES 1 | ||
75 | +#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface" | ||
76 | +#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface" | ||
77 | + | ||
78 | +/* | ||
79 | * Buffers to hold input and output data | ||
80 | */ | ||
81 | -#define USBTTY_BUFFER_SIZE 256 | ||
82 | +#define USBTTY_BUFFER_SIZE 2048 | ||
83 | static circbuf_t usbtty_input; | ||
84 | static circbuf_t usbtty_output; | ||
85 | |||
86 | @@ -50,157 +88,336 @@ | ||
87 | * Instance variables | ||
88 | */ | ||
89 | static device_t usbttydev; | ||
90 | -static struct usb_device_instance device_instance[1]; | ||
91 | -static struct usb_bus_instance bus_instance[1]; | ||
92 | +static struct usb_device_instance device_instance[1]; | ||
93 | +static struct usb_bus_instance bus_instance[1]; | ||
94 | static struct usb_configuration_instance config_instance[NUM_CONFIGS]; | ||
95 | -static struct usb_interface_instance interface_instance[NUM_INTERFACES]; | ||
96 | -static struct usb_alternate_instance alternate_instance[NUM_INTERFACES]; | ||
97 | -static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; /* one extra for control endpoint */ | ||
98 | - | ||
99 | -/* | ||
100 | - * Static allocation of urbs | ||
101 | - */ | ||
102 | -#define RECV_ENDPOINT 1 | ||
103 | -#define TX_ENDPOINT 2 | ||
104 | +static struct usb_interface_instance interface_instance[MAX_INTERFACES]; | ||
105 | +static struct usb_alternate_instance alternate_instance[MAX_INTERFACES]; | ||
106 | +/* one extra for control endpoint */ | ||
107 | +static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; | ||
108 | |||
109 | /* | ||
110 | * Global flag | ||
111 | */ | ||
112 | int usbtty_configured_flag = 0; | ||
113 | |||
114 | - | ||
115 | /* | ||
116 | * Serial number | ||
117 | */ | ||
118 | static char serial_number[16]; | ||
119 | |||
120 | + | ||
121 | /* | ||
122 | - * Descriptors | ||
123 | + * Descriptors, Strings, Local variables. | ||
124 | */ | ||
125 | + | ||
126 | +/* defined and used by usbdcore_ep0.c */ | ||
127 | +extern struct usb_string_descriptor **usb_strings; | ||
128 | + | ||
129 | +/* Indicies, References */ | ||
130 | +static unsigned short rx_endpoint = 0; | ||
131 | +static unsigned short tx_endpoint = 0; | ||
132 | +static unsigned short interface_count = 0; | ||
133 | +static struct usb_string_descriptor *usbtty_string_table[STR_COUNT]; | ||
134 | + | ||
135 | +/* USB Descriptor Strings */ | ||
136 | static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4}; | ||
137 | static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)]; | ||
138 | static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)]; | ||
139 | static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)]; | ||
140 | static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)]; | ||
141 | -static u8 wstrInterface[2 + 2*(sizeof(CONFIG_USBD_INTERFACE_STR)-1)]; | ||
142 | - | ||
143 | -static struct usb_string_descriptor *usbtty_string_table[] = { | ||
144 | - (struct usb_string_descriptor*)wstrLang, | ||
145 | - (struct usb_string_descriptor*)wstrManufacturer, | ||
146 | - (struct usb_string_descriptor*)wstrProduct, | ||
147 | - (struct usb_string_descriptor*)wstrSerial, | ||
148 | - (struct usb_string_descriptor*)wstrConfiguration, | ||
149 | - (struct usb_string_descriptor*)wstrInterface | ||
150 | -}; | ||
151 | -extern struct usb_string_descriptor **usb_strings; /* defined and used by omap1510_ep0.c */ | ||
152 | +static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; | ||
153 | +static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; | ||
154 | |||
155 | +/* Standard USB Data Structures */ | ||
156 | +static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES]; | ||
157 | +static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS]; | ||
158 | +static struct usb_configuration_descriptor *configuration_descriptor = 0; | ||
159 | static struct usb_device_descriptor device_descriptor = { | ||
160 | - bLength: sizeof(struct usb_device_descriptor), | ||
161 | - bDescriptorType: USB_DT_DEVICE, | ||
162 | - bcdUSB: USB_BCD_VERSION, | ||
163 | - bDeviceClass: USBTTY_DEVICE_CLASS, | ||
164 | - bDeviceSubClass: USBTTY_DEVICE_SUBCLASS, | ||
165 | - bDeviceProtocol: USBTTY_DEVICE_PROTOCOL, | ||
166 | - bMaxPacketSize0: EP0_MAX_PACKET_SIZE, | ||
167 | - idVendor: CONFIG_USBD_VENDORID, | ||
168 | - idProduct: CONFIG_USBD_PRODUCTID, | ||
169 | - bcdDevice: USBTTY_BCD_DEVICE, | ||
170 | - iManufacturer: STR_MANUFACTURER, | ||
171 | - iProduct: STR_PRODUCT, | ||
172 | - iSerialNumber: STR_SERIAL, | ||
173 | - bNumConfigurations: NUM_CONFIGS | ||
174 | - }; | ||
175 | -static struct usb_configuration_descriptor config_descriptors[NUM_CONFIGS] = { | ||
176 | - { | ||
177 | - bLength: sizeof(struct usb_configuration_descriptor), | ||
178 | - bDescriptorType: USB_DT_CONFIG, | ||
179 | - wTotalLength: (sizeof(struct usb_configuration_descriptor)*NUM_CONFIGS) + | ||
180 | - (sizeof(struct usb_interface_descriptor)*NUM_INTERFACES) + | ||
181 | - (sizeof(struct usb_endpoint_descriptor)*NUM_ENDPOINTS), | ||
182 | - bNumInterfaces: NUM_INTERFACES, | ||
183 | - bConfigurationValue: 1, | ||
184 | - iConfiguration: STR_CONFIG, | ||
185 | - bmAttributes: BMATTRIBUTE_SELF_POWERED | BMATTRIBUTE_RESERVED, | ||
186 | - bMaxPower: USBTTY_MAXPOWER | ||
187 | - }, | ||
188 | -}; | ||
189 | -static struct usb_interface_descriptor interface_descriptors[NUM_INTERFACES] = { | ||
190 | - { | ||
191 | - bLength: sizeof(struct usb_interface_descriptor), | ||
192 | - bDescriptorType: USB_DT_INTERFACE, | ||
193 | - bInterfaceNumber: 0, | ||
194 | - bAlternateSetting: 0, | ||
195 | - bNumEndpoints: NUM_ENDPOINTS, | ||
196 | - bInterfaceClass: USBTTY_INTERFACE_CLASS, | ||
197 | - bInterfaceSubClass: USBTTY_INTERFACE_SUBCLASS, | ||
198 | - bInterfaceProtocol: USBTTY_INTERFACE_PROTOCOL, | ||
199 | - iInterface: STR_INTERFACE | ||
200 | - }, | ||
201 | + .bLength = sizeof(struct usb_device_descriptor), | ||
202 | + .bDescriptorType = USB_DT_DEVICE, | ||
203 | + .bcdUSB = cpu_to_le16(USB_BCD_VERSION), | ||
204 | + .bDeviceSubClass = 0x00, | ||
205 | + .bDeviceProtocol = 0x00, | ||
206 | + .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE, | ||
207 | + .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID), | ||
208 | + .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE), | ||
209 | + .iManufacturer = STR_MANUFACTURER, | ||
210 | + .iProduct = STR_PRODUCT, | ||
211 | + .iSerialNumber = STR_SERIAL, | ||
212 | + .bNumConfigurations = NUM_CONFIGS | ||
213 | }; | ||
214 | -static struct usb_endpoint_descriptor ep_descriptors[NUM_ENDPOINTS] = { | ||
215 | - { | ||
216 | - bLength: sizeof(struct usb_endpoint_descriptor), | ||
217 | - bDescriptorType: USB_DT_ENDPOINT, | ||
218 | - bEndpointAddress: CONFIG_USBD_SERIAL_OUT_ENDPOINT | USB_DIR_OUT, | ||
219 | - bmAttributes: USB_ENDPOINT_XFER_BULK, | ||
220 | - wMaxPacketSize: CONFIG_USBD_SERIAL_OUT_PKTSIZE, | ||
221 | - bInterval: 0 | ||
222 | - }, | ||
223 | - { | ||
224 | - bLength: sizeof(struct usb_endpoint_descriptor), | ||
225 | - bDescriptorType: USB_DT_ENDPOINT, | ||
226 | - bEndpointAddress: CONFIG_USBD_SERIAL_IN_ENDPOINT | USB_DIR_IN, | ||
227 | - bmAttributes: USB_ENDPOINT_XFER_BULK, | ||
228 | - wMaxPacketSize: CONFIG_USBD_SERIAL_IN_PKTSIZE, | ||
229 | - bInterval: 0 | ||
230 | - }, | ||
231 | - { | ||
232 | - bLength: sizeof(struct usb_endpoint_descriptor), | ||
233 | - bDescriptorType: USB_DT_ENDPOINT, | ||
234 | - bEndpointAddress: CONFIG_USBD_SERIAL_INT_ENDPOINT | USB_DIR_IN, | ||
235 | - bmAttributes: USB_ENDPOINT_XFER_INT, | ||
236 | - wMaxPacketSize: CONFIG_USBD_SERIAL_INT_PKTSIZE, | ||
237 | - bInterval: 0 | ||
238 | - }, | ||
239 | -}; | ||
240 | -static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS] = { | ||
241 | - &(ep_descriptors[0]), | ||
242 | - &(ep_descriptors[1]), | ||
243 | - &(ep_descriptors[2]), | ||
244 | + | ||
245 | + | ||
246 | +/* | ||
247 | + * Static CDC ACM specific descriptors | ||
248 | + */ | ||
249 | + | ||
250 | +struct acm_config_desc { | ||
251 | + struct usb_configuration_descriptor configuration_desc; | ||
252 | + | ||
253 | + /* Master Interface */ | ||
254 | + struct usb_interface_descriptor interface_desc; | ||
255 | + | ||
256 | + struct usb_class_header_function_descriptor usb_class_header; | ||
257 | + struct usb_class_call_management_descriptor usb_class_call_mgt; | ||
258 | + struct usb_class_abstract_control_descriptor usb_class_acm; | ||
259 | + struct usb_class_union_function_descriptor usb_class_union; | ||
260 | + struct usb_endpoint_descriptor notification_endpoint; | ||
261 | + | ||
262 | + /* Slave Interface */ | ||
263 | + struct usb_interface_descriptor data_class_interface; | ||
264 | + struct usb_endpoint_descriptor | ||
265 | + data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed)); | ||
266 | +} __attribute__((packed)); | ||
267 | + | ||
268 | +static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = { | ||
269 | + { | ||
270 | + .configuration_desc ={ | ||
271 | + .bLength = | ||
272 | + sizeof(struct usb_configuration_descriptor), | ||
273 | + .bDescriptorType = USB_DT_CONFIG, | ||
274 | + .wTotalLength = | ||
275 | + cpu_to_le16(sizeof(struct acm_config_desc)), | ||
276 | + .bNumInterfaces = NUM_ACM_INTERFACES, | ||
277 | + .bConfigurationValue = 1, | ||
278 | + .iConfiguration = STR_CONFIG, | ||
279 | + .bmAttributes = | ||
280 | + BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, | ||
281 | + .bMaxPower = USBTTY_MAXPOWER | ||
282 | + }, | ||
283 | + /* Interface 1 */ | ||
284 | + .interface_desc = { | ||
285 | + .bLength = sizeof(struct usb_interface_descriptor), | ||
286 | + .bDescriptorType = USB_DT_INTERFACE, | ||
287 | + .bInterfaceNumber = 0, | ||
288 | + .bAlternateSetting = 0, | ||
289 | + .bNumEndpoints = 0x01, | ||
290 | + .bInterfaceClass = | ||
291 | + COMMUNICATIONS_INTERFACE_CLASS_CONTROL, | ||
292 | + .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS, | ||
293 | + .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL, | ||
294 | + .iInterface = STR_CTRL_INTERFACE, | ||
295 | + }, | ||
296 | + .usb_class_header = { | ||
297 | + .bFunctionLength = | ||
298 | + sizeof(struct usb_class_header_function_descriptor), | ||
299 | + .bDescriptorType = CS_INTERFACE, | ||
300 | + .bDescriptorSubtype = USB_ST_HEADER, | ||
301 | + .bcdCDC = cpu_to_le16(110), | ||
302 | + }, | ||
303 | + .usb_class_call_mgt = { | ||
304 | + .bFunctionLength = | ||
305 | + sizeof(struct usb_class_call_management_descriptor), | ||
306 | + .bDescriptorType = CS_INTERFACE, | ||
307 | + .bDescriptorSubtype = USB_ST_CMF, | ||
308 | + .bmCapabilities = 0x00, | ||
309 | + .bDataInterface = 0x01, | ||
310 | + }, | ||
311 | + .usb_class_acm = { | ||
312 | + .bFunctionLength = | ||
313 | + sizeof(struct usb_class_abstract_control_descriptor), | ||
314 | + .bDescriptorType = CS_INTERFACE, | ||
315 | + .bDescriptorSubtype = USB_ST_ACMF, | ||
316 | + .bmCapabilities = 0x00, | ||
317 | + }, | ||
318 | + .usb_class_union = { | ||
319 | + .bFunctionLength = | ||
320 | + sizeof(struct usb_class_union_function_descriptor), | ||
321 | + .bDescriptorType = CS_INTERFACE, | ||
322 | + .bDescriptorSubtype = USB_ST_UF, | ||
323 | + .bMasterInterface = 0x00, | ||
324 | + .bSlaveInterface0 = 0x01, | ||
325 | + }, | ||
326 | + .notification_endpoint = { | ||
327 | + .bLength = | ||
328 | + sizeof(struct usb_endpoint_descriptor), | ||
329 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
330 | + .bEndpointAddress = 0x01 | USB_DIR_IN, | ||
331 | + .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
332 | + .wMaxPacketSize | ||
333 | + = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), | ||
334 | + .bInterval = 0xFF, | ||
335 | + }, | ||
336 | + | ||
337 | + /* Interface 2 */ | ||
338 | + .data_class_interface = { | ||
339 | + .bLength = | ||
340 | + sizeof(struct usb_interface_descriptor), | ||
341 | + .bDescriptorType = USB_DT_INTERFACE, | ||
342 | + .bInterfaceNumber = 0x01, | ||
343 | + .bAlternateSetting = 0x00, | ||
344 | + .bNumEndpoints = 0x02, | ||
345 | + .bInterfaceClass = | ||
346 | + COMMUNICATIONS_INTERFACE_CLASS_DATA, | ||
347 | + .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE, | ||
348 | + .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE, | ||
349 | + .iInterface = STR_DATA_INTERFACE, | ||
350 | + }, | ||
351 | + .data_endpoints = { | ||
352 | + { | ||
353 | + .bLength = | ||
354 | + sizeof(struct usb_endpoint_descriptor), | ||
355 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
356 | + .bEndpointAddress = 0x02 | USB_DIR_OUT, | ||
357 | + .bmAttributes = | ||
358 | + USB_ENDPOINT_XFER_BULK, | ||
359 | + .wMaxPacketSize = | ||
360 | + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), | ||
361 | + .bInterval = 0xFF, | ||
362 | + }, | ||
363 | + { | ||
364 | + .bLength = | ||
365 | + sizeof(struct usb_endpoint_descriptor), | ||
366 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
367 | + .bEndpointAddress = 0x03 | USB_DIR_IN, | ||
368 | + .bmAttributes = | ||
369 | + USB_ENDPOINT_XFER_BULK, | ||
370 | + .wMaxPacketSize = | ||
371 | + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), | ||
372 | + .bInterval = 0xFF, | ||
373 | + }, | ||
374 | + }, | ||
375 | + }, | ||
376 | +}; | ||
377 | + | ||
378 | +static struct rs232_emu rs232_desc={ | ||
379 | + .dter = 115200, | ||
380 | + .stop_bits = 0x00, | ||
381 | + .parity = 0x00, | ||
382 | + .data_bits = 0x08 | ||
383 | }; | ||
384 | |||
385 | -/* utility function for converting char* to wide string used by USB */ | ||
386 | -static void str2wide (char *str, u16 * wide) | ||
387 | -{ | ||
388 | - int i; | ||
389 | |||
390 | - for (i = 0; i < strlen (str) && str[i]; i++) | ||
391 | - wide[i] = (u16) str[i]; | ||
392 | -} | ||
393 | +/* | ||
394 | + * Static Generic Serial specific data | ||
395 | + */ | ||
396 | + | ||
397 | + | ||
398 | +struct gserial_config_desc { | ||
399 | + | ||
400 | + struct usb_configuration_descriptor configuration_desc; | ||
401 | + struct usb_interface_descriptor | ||
402 | + interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed)); | ||
403 | + struct usb_endpoint_descriptor | ||
404 | + data_endpoints[NUM_ENDPOINTS] __attribute__((packed)); | ||
405 | + | ||
406 | +} __attribute__((packed)); | ||
407 | + | ||
408 | +static struct gserial_config_desc | ||
409 | +gserial_configuration_descriptors[NUM_CONFIGS] ={ | ||
410 | + { | ||
411 | + .configuration_desc ={ | ||
412 | + .bLength = sizeof(struct usb_configuration_descriptor), | ||
413 | + .bDescriptorType = USB_DT_CONFIG, | ||
414 | + .wTotalLength = | ||
415 | + cpu_to_le16(sizeof(struct gserial_config_desc)), | ||
416 | + .bNumInterfaces = NUM_GSERIAL_INTERFACES, | ||
417 | + .bConfigurationValue = 1, | ||
418 | + .iConfiguration = STR_CONFIG, | ||
419 | + .bmAttributes = | ||
420 | + BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, | ||
421 | + .bMaxPower = USBTTY_MAXPOWER | ||
422 | + }, | ||
423 | + .interface_desc = { | ||
424 | + { | ||
425 | + .bLength = | ||
426 | + sizeof(struct usb_interface_descriptor), | ||
427 | + .bDescriptorType = USB_DT_INTERFACE, | ||
428 | + .bInterfaceNumber = 0, | ||
429 | + .bAlternateSetting = 0, | ||
430 | + .bNumEndpoints = NUM_ENDPOINTS, | ||
431 | + .bInterfaceClass = | ||
432 | + COMMUNICATIONS_INTERFACE_CLASS_VENDOR, | ||
433 | + .bInterfaceSubClass = | ||
434 | + COMMUNICATIONS_NO_SUBCLASS, | ||
435 | + .bInterfaceProtocol = | ||
436 | + COMMUNICATIONS_NO_PROTOCOL, | ||
437 | + .iInterface = STR_DATA_INTERFACE | ||
438 | + }, | ||
439 | + }, | ||
440 | + .data_endpoints = { | ||
441 | + { | ||
442 | + .bLength = | ||
443 | + sizeof(struct usb_endpoint_descriptor), | ||
444 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
445 | + .bEndpointAddress = 0x01 | USB_DIR_OUT, | ||
446 | + .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
447 | + .wMaxPacketSize = | ||
448 | + cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE), | ||
449 | + .bInterval= 0xFF, | ||
450 | + }, | ||
451 | + { | ||
452 | + .bLength = | ||
453 | + sizeof(struct usb_endpoint_descriptor), | ||
454 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
455 | + .bEndpointAddress = 0x02 | USB_DIR_IN, | ||
456 | + .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
457 | + .wMaxPacketSize = | ||
458 | + cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE), | ||
459 | + .bInterval = 0xFF, | ||
460 | + }, | ||
461 | + { | ||
462 | + .bLength = | ||
463 | + sizeof(struct usb_endpoint_descriptor), | ||
464 | + .bDescriptorType = USB_DT_ENDPOINT, | ||
465 | + .bEndpointAddress = 0x03 | USB_DIR_IN, | ||
466 | + .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
467 | + .wMaxPacketSize = | ||
468 | + cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), | ||
469 | + .bInterval = 0xFF, | ||
470 | + }, | ||
471 | + }, | ||
472 | + }, | ||
473 | +}; | ||
474 | |||
475 | /* | ||
476 | - * Prototypes | ||
477 | + * Static Function Prototypes | ||
478 | */ | ||
479 | + | ||
480 | static void usbtty_init_strings (void); | ||
481 | static void usbtty_init_instances (void); | ||
482 | static void usbtty_init_endpoints (void); | ||
483 | - | ||
484 | +static void usbtty_init_terminal_type(short type); | ||
485 | static void usbtty_event_handler (struct usb_device_instance *device, | ||
486 | - usb_device_event_t event, int data); | ||
487 | + usb_device_event_t event, int data); | ||
488 | +static int usbtty_cdc_setup(struct usb_device_request *request, | ||
489 | + struct urb *urb); | ||
490 | static int usbtty_configured (void); | ||
491 | - | ||
492 | static int write_buffer (circbuf_t * buf); | ||
493 | static int fill_buffer (circbuf_t * buf); | ||
494 | |||
495 | void usbtty_poll (void); | ||
496 | -static void pretend_interrupts (void); | ||
497 | |||
498 | +/* utility function for converting char* to wide string used by USB */ | ||
499 | +static void str2wide (char *str, u16 * wide) | ||
500 | +{ | ||
501 | + int i; | ||
502 | + for (i = 0; i < strlen (str) && str[i]; i++){ | ||
503 | + #if defined(__LITTLE_ENDIAN) | ||
504 | + wide[i] = (u16) str[i]; | ||
505 | + #elif defined(__BIG_ENDIAN) | ||
506 | + wide[i] = ((u16)(str[i])<<8); | ||
507 | + #else | ||
508 | + #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined" | ||
509 | + #endif | ||
510 | + } | ||
511 | +} | ||
512 | |||
513 | /* | ||
514 | * Test whether a character is in the RX buffer | ||
515 | */ | ||
516 | + | ||
517 | int usbtty_tstc (void) | ||
518 | { | ||
519 | + struct usb_endpoint_instance *endpoint = | ||
520 | + &endpoint_instance[rx_endpoint]; | ||
521 | + | ||
522 | + /* If no input data exists, allow more RX to be accepted */ | ||
523 | + if(usbtty_input.size <= 0){ | ||
524 | + udc_unset_nak(endpoint->endpoint_address&0x03); | ||
525 | + } | ||
526 | + | ||
527 | usbtty_poll (); | ||
528 | return (usbtty_input.size > 0); | ||
529 | } | ||
530 | @@ -210,15 +427,21 @@ | ||
531 | * otherwise. When the function is succesfull, the character read is | ||
532 | * written into its argument c. | ||
533 | */ | ||
534 | + | ||
535 | int usbtty_getc (void) | ||
536 | { | ||
537 | char c; | ||
538 | + struct usb_endpoint_instance *endpoint = | ||
539 | + &endpoint_instance[rx_endpoint]; | ||
540 | |||
541 | while (usbtty_input.size <= 0) { | ||
542 | + udc_unset_nak(endpoint->endpoint_address&0x03); | ||
543 | usbtty_poll (); | ||
544 | } | ||
545 | |||
546 | buf_pop (&usbtty_input, &c, 1); | ||
547 | + udc_set_nak(endpoint->endpoint_address&0x03); | ||
548 | + | ||
549 | return c; | ||
550 | } | ||
551 | |||
552 | @@ -238,7 +461,6 @@ | ||
553 | } | ||
554 | } | ||
555 | |||
556 | - | ||
557 | /* usbtty_puts() helper function for finding the next '\n' in a string */ | ||
558 | static int next_nl_pos (const char *s) | ||
559 | { | ||
560 | @@ -252,8 +474,9 @@ | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | - * Output a string to the usb client port. | ||
565 | + * Output a string to the usb client port - implementing flow control | ||
566 | */ | ||
567 | + | ||
568 | static void __usbtty_puts (const char *str, int len) | ||
569 | { | ||
570 | int maxlen = usbtty_output.totalsize; | ||
571 | @@ -261,22 +484,19 @@ | ||
572 | |||
573 | /* break str into chunks < buffer size, if needed */ | ||
574 | while (len > 0) { | ||
575 | - space = maxlen - usbtty_output.size; | ||
576 | + usbtty_poll (); | ||
577 | |||
578 | + space = maxlen - usbtty_output.size; | ||
579 | /* Empty buffer here, if needed, to ensure space... */ | ||
580 | - if (space <= 0) { | ||
581 | + if (space) { | ||
582 | write_buffer (&usbtty_output); | ||
583 | - space = maxlen - usbtty_output.size; | ||
584 | - if (space <= 0) { | ||
585 | - space = len; /* allow old data to be overwritten. */ | ||
586 | - } | ||
587 | - } | ||
588 | - | ||
589 | - n = MIN (space, MIN (len, maxlen)); | ||
590 | - buf_push (&usbtty_output, str, n); | ||
591 | + | ||
592 | + n = MIN (space, MIN (len, maxlen)); | ||
593 | + buf_push (&usbtty_output, str, n); | ||
594 | |||
595 | - str += n; | ||
596 | - len -= n; | ||
597 | + str += n; | ||
598 | + len -= n; | ||
599 | + } | ||
600 | } | ||
601 | } | ||
602 | |||
603 | @@ -313,8 +533,10 @@ | ||
604 | { | ||
605 | int rc; | ||
606 | char * sn; | ||
607 | + char * tt; | ||
608 | int snlen; | ||
609 | |||
610 | + /* Get serial number */ | ||
611 | if (!(sn = getenv("serial#"))) { | ||
612 | sn = "000000000000"; | ||
613 | } | ||
614 | @@ -327,6 +549,14 @@ | ||
615 | memcpy (serial_number, sn, snlen); | ||
616 | serial_number[snlen] = '\0'; | ||
617 | |||
618 | + /* Decide on which type of UDC device to be. | ||
619 | + */ | ||
620 | + | ||
621 | + if(!(tt = getenv("usbtty"))) { | ||
622 | + tt = "generic"; | ||
623 | + } | ||
624 | + usbtty_init_terminal_type(strcmp(tt,"cdc_acm")); | ||
625 | + | ||
626 | /* prepare buffers... */ | ||
627 | buf_init (&usbtty_input, USBTTY_BUFFER_SIZE); | ||
628 | buf_init (&usbtty_output, USBTTY_BUFFER_SIZE); | ||
629 | @@ -337,7 +567,7 @@ | ||
630 | usbtty_init_strings (); | ||
631 | usbtty_init_instances (); | ||
632 | |||
633 | - udc_startup_events (device_instance); /* Enable our device, initialize udc pointers */ | ||
634 | + udc_startup_events (device_instance);/* Enable dev, init udc pointers */ | ||
635 | udc_connect (); /* Enable pullup for host detection */ | ||
636 | |||
637 | usbtty_init_endpoints (); | ||
638 | @@ -362,34 +592,52 @@ | ||
639 | { | ||
640 | struct usb_string_descriptor *string; | ||
641 | |||
642 | + usbtty_string_table[STR_LANG] = | ||
643 | + (struct usb_string_descriptor*)wstrLang; | ||
644 | + | ||
645 | string = (struct usb_string_descriptor *) wstrManufacturer; | ||
646 | - string->bLength = sizeof (wstrManufacturer); | ||
647 | + string->bLength = sizeof(wstrManufacturer); | ||
648 | string->bDescriptorType = USB_DT_STRING; | ||
649 | str2wide (CONFIG_USBD_MANUFACTURER, string->wData); | ||
650 | + usbtty_string_table[STR_MANUFACTURER]=string; | ||
651 | + | ||
652 | |||
653 | string = (struct usb_string_descriptor *) wstrProduct; | ||
654 | - string->bLength = sizeof (wstrProduct); | ||
655 | + string->bLength = sizeof(wstrProduct); | ||
656 | string->bDescriptorType = USB_DT_STRING; | ||
657 | str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData); | ||
658 | + usbtty_string_table[STR_PRODUCT]=string; | ||
659 | + | ||
660 | |||
661 | string = (struct usb_string_descriptor *) wstrSerial; | ||
662 | - string->bLength = 2 + 2*strlen(serial_number); | ||
663 | + string->bLength = sizeof(serial_number); | ||
664 | string->bDescriptorType = USB_DT_STRING; | ||
665 | str2wide (serial_number, string->wData); | ||
666 | + usbtty_string_table[STR_SERIAL]=string; | ||
667 | + | ||
668 | |||
669 | string = (struct usb_string_descriptor *) wstrConfiguration; | ||
670 | - string->bLength = sizeof (wstrConfiguration); | ||
671 | + string->bLength = sizeof(wstrConfiguration); | ||
672 | string->bDescriptorType = USB_DT_STRING; | ||
673 | str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData); | ||
674 | + usbtty_string_table[STR_CONFIG]=string; | ||
675 | + | ||
676 | + | ||
677 | + string = (struct usb_string_descriptor *) wstrDataInterface; | ||
678 | + string->bLength = sizeof(wstrDataInterface); | ||
679 | + string->bDescriptorType = USB_DT_STRING; | ||
680 | + str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData); | ||
681 | + usbtty_string_table[STR_DATA_INTERFACE]=string; | ||
682 | |||
683 | - string = (struct usb_string_descriptor *) wstrInterface; | ||
684 | - string->bLength = sizeof (wstrInterface); | ||
685 | + string = (struct usb_string_descriptor *) wstrCtrlInterface; | ||
686 | + string->bLength = sizeof(wstrCtrlInterface); | ||
687 | string->bDescriptorType = USB_DT_STRING; | ||
688 | - str2wide (CONFIG_USBD_INTERFACE_STR, string->wData); | ||
689 | + str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData); | ||
690 | + usbtty_string_table[STR_CTRL_INTERFACE]=string; | ||
691 | |||
692 | /* Now, initialize the string table for ep0 handling */ | ||
693 | usb_strings = usbtty_string_table; | ||
694 | -} | ||
695 | +} | ||
696 | |||
697 | static void usbtty_init_instances (void) | ||
698 | { | ||
699 | @@ -400,6 +648,7 @@ | ||
700 | device_instance->device_state = STATE_INIT; | ||
701 | device_instance->device_descriptor = &device_descriptor; | ||
702 | device_instance->event = usbtty_event_handler; | ||
703 | + device_instance->cdc_recv_setup = usbtty_cdc_setup; | ||
704 | device_instance->bus = bus_instance; | ||
705 | device_instance->configurations = NUM_CONFIGS; | ||
706 | device_instance->configuration_instance_array = config_instance; | ||
707 | @@ -415,8 +664,8 @@ | ||
708 | /* configuration instance */ | ||
709 | memset (config_instance, 0, | ||
710 | sizeof (struct usb_configuration_instance)); | ||
711 | - config_instance->interfaces = NUM_INTERFACES; | ||
712 | - config_instance->configuration_descriptor = config_descriptors; | ||
713 | + config_instance->interfaces = interface_count; | ||
714 | + config_instance->configuration_descriptor = configuration_descriptor; | ||
715 | config_instance->interface_instance_array = interface_instance; | ||
716 | |||
717 | /* interface instance */ | ||
718 | @@ -447,17 +696,22 @@ | ||
719 | sizeof (struct usb_endpoint_instance)); | ||
720 | |||
721 | endpoint_instance[i].endpoint_address = | ||
722 | - ep_descriptors[i - 1].bEndpointAddress; | ||
723 | + ep_descriptor_ptrs[i - 1]->bEndpointAddress; | ||
724 | |||
725 | - endpoint_instance[i].rcv_packetSize = | ||
726 | - ep_descriptors[i - 1].wMaxPacketSize; | ||
727 | endpoint_instance[i].rcv_attributes = | ||
728 | - ep_descriptors[i - 1].bmAttributes; | ||
729 | + ep_descriptor_ptrs[i - 1]->bmAttributes; | ||
730 | + | ||
731 | + endpoint_instance[i].rcv_packetSize = | ||
732 | + le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); | ||
733 | + | ||
734 | + endpoint_instance[i].tx_attributes = | ||
735 | + ep_descriptor_ptrs[i - 1]->bmAttributes; | ||
736 | |||
737 | endpoint_instance[i].tx_packetSize = | ||
738 | - ep_descriptors[i - 1].wMaxPacketSize; | ||
739 | + le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); | ||
740 | + | ||
741 | endpoint_instance[i].tx_attributes = | ||
742 | - ep_descriptors[i - 1].bmAttributes; | ||
743 | + ep_descriptor_ptrs[i - 1]->bmAttributes; | ||
744 | |||
745 | urb_link_init (&endpoint_instance[i].rcv); | ||
746 | urb_link_init (&endpoint_instance[i].rdy); | ||
747 | @@ -480,13 +734,79 @@ | ||
748 | int i; | ||
749 | |||
750 | bus_instance->max_endpoints = NUM_ENDPOINTS + 1; | ||
751 | - for (i = 0; i <= NUM_ENDPOINTS; i++) { | ||
752 | + for (i = 1; i <= NUM_ENDPOINTS; i++) { | ||
753 | udc_setup_ep (device_instance, i, &endpoint_instance[i]); | ||
754 | } | ||
755 | } | ||
756 | |||
757 | +/* usbtty_init_terminal_type | ||
758 | + * | ||
759 | + * Do some late binding for our device type. | ||
760 | + */ | ||
761 | +static void usbtty_init_terminal_type(short type) | ||
762 | +{ | ||
763 | + switch(type){ | ||
764 | + /* CDC ACM */ | ||
765 | + case 0: | ||
766 | + /* Assign endpoint descriptors */ | ||
767 | + ep_descriptor_ptrs[0] = | ||
768 | + &acm_configuration_descriptors[0].notification_endpoint; | ||
769 | + ep_descriptor_ptrs[1] = | ||
770 | + &acm_configuration_descriptors[0].data_endpoints[0]; | ||
771 | + ep_descriptor_ptrs[2] = | ||
772 | + &acm_configuration_descriptors[0].data_endpoints[1]; | ||
773 | + | ||
774 | + /* Enumerate Device Descriptor */ | ||
775 | + device_descriptor.bDeviceClass = | ||
776 | + COMMUNICATIONS_DEVICE_CLASS; | ||
777 | + device_descriptor.idProduct = | ||
778 | + cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM); | ||
779 | + | ||
780 | + /* Assign endpoint indices */ | ||
781 | + tx_endpoint = ACM_TX_ENDPOINT; | ||
782 | + rx_endpoint = ACM_RX_ENDPOINT; | ||
783 | + | ||
784 | + /* Configuration Descriptor */ | ||
785 | + configuration_descriptor = | ||
786 | + (struct usb_configuration_descriptor*) | ||
787 | + &acm_configuration_descriptors; | ||
788 | + | ||
789 | + /* Interface count */ | ||
790 | + interface_count = NUM_ACM_INTERFACES; | ||
791 | + break; | ||
792 | + | ||
793 | + /* BULK IN/OUT & Default */ | ||
794 | + case 1: | ||
795 | + default: | ||
796 | + /* Assign endpoint descriptors */ | ||
797 | + ep_descriptor_ptrs[0] = | ||
798 | + &gserial_configuration_descriptors[0].data_endpoints[0]; | ||
799 | + ep_descriptor_ptrs[1] = | ||
800 | + &gserial_configuration_descriptors[0].data_endpoints[1]; | ||
801 | + ep_descriptor_ptrs[2] = | ||
802 | + &gserial_configuration_descriptors[0].data_endpoints[2]; | ||
803 | + | ||
804 | + /* Enumerate Device Descriptor */ | ||
805 | + device_descriptor.bDeviceClass = 0xFF; | ||
806 | + device_descriptor.idProduct = | ||
807 | + cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL); | ||
808 | + | ||
809 | + /* Assign endpoint indices */ | ||
810 | + tx_endpoint = GSERIAL_TX_ENDPOINT; | ||
811 | + rx_endpoint = GSERIAL_RX_ENDPOINT; | ||
812 | + | ||
813 | + /* Configuration Descriptor */ | ||
814 | + configuration_descriptor = | ||
815 | + (struct usb_configuration_descriptor*) | ||
816 | + &gserial_configuration_descriptors; | ||
817 | + | ||
818 | + /* Interface count */ | ||
819 | + interface_count = NUM_GSERIAL_INTERFACES; | ||
820 | + break; | ||
821 | + } | ||
822 | +} | ||
823 | |||
824 | -/*********************************************************************************/ | ||
825 | +/******************************************************************************/ | ||
826 | |||
827 | static struct urb *next_urb (struct usb_device_instance *device, | ||
828 | struct usb_endpoint_instance *endpoint) | ||
829 | @@ -522,82 +842,179 @@ | ||
830 | |||
831 | static int write_buffer (circbuf_t * buf) | ||
832 | { | ||
833 | - if (!usbtty_configured ()) { | ||
834 | - return 0; | ||
835 | - } | ||
836 | + if (!usbtty_configured ()) { | ||
837 | + return 0; | ||
838 | + } | ||
839 | + | ||
840 | + if (buf->size) { | ||
841 | + | ||
842 | + struct usb_endpoint_instance *endpoint = | ||
843 | + &endpoint_instance[tx_endpoint]; | ||
844 | + struct urb *current_urb = NULL; | ||
845 | + char *dest; | ||
846 | + | ||
847 | + int space_avail; | ||
848 | + int popnum, popped; | ||
849 | + int total = 0; | ||
850 | + | ||
851 | + /* Break buffer into urb sized pieces, and link each to the endpoint */ | ||
852 | + while (buf->size > 0) { | ||
853 | + TTYDBG ("buf->size= %d",buf->size); | ||
854 | + current_urb = next_urb (device_instance, endpoint); | ||
855 | + if (!current_urb) { | ||
856 | + TTYDBG ("current_urb is NULL, buf->size %d\n", | ||
857 | + buf->size); | ||
858 | + return total; | ||
859 | + } | ||
860 | + | ||
861 | + dest = current_urb->buffer + | ||
862 | + current_urb->actual_length; | ||
863 | + | ||
864 | + space_avail = | ||
865 | + current_urb->buffer_length - | ||
866 | + current_urb->actual_length; | ||
867 | + TTYDBG ("space_avail= %d",space_avail); | ||
868 | + popnum = MIN (space_avail, buf->size); | ||
869 | + if (popnum == 0) | ||
870 | + break; | ||
871 | + | ||
872 | + popped = buf_pop (buf, dest, popnum); | ||
873 | + TTYDBG ("popped= %d, %s",popped, dest); | ||
874 | + if (popped == 0) | ||
875 | + break; | ||
876 | + current_urb->actual_length += popped; | ||
877 | + total += popped; | ||
878 | + | ||
879 | + /* If endpoint->last == 0, then transfers have not started on this endpoint */ | ||
880 | + if (endpoint->last == 0) { | ||
881 | + udc_endpoint_write (endpoint); | ||
882 | + } | ||
883 | + | ||
884 | + } /* end while */ | ||
885 | + TTYDBG (" total= %d",total); | ||
886 | + return total; | ||
887 | + } /* end if tx_urb */ | ||
888 | |||
889 | - if (buf->size) { | ||
890 | + return 0; | ||
891 | +} | ||
892 | +// static int write_buffer (circbuf_t * buf) | ||
893 | +// { | ||
894 | +// if (!usbtty_configured ()) { | ||
895 | +// return 0; | ||
896 | +// } | ||
897 | +// | ||
898 | +// struct usb_endpoint_instance *endpoint = | ||
899 | +// &endpoint_instance[tx_endpoint]; | ||
900 | +// struct urb *current_urb = NULL; | ||
901 | +// | ||
902 | +// current_urb = next_urb (device_instance, endpoint); | ||
903 | +// /* TX data still exists - send it now | ||
904 | +// */ | ||
905 | +// if(endpoint->sent < current_urb->actual_length){ | ||
906 | +// if(udc_endpoint_write (endpoint)){ | ||
907 | +// /* Write pre-empted by RX */ | ||
908 | +// return -1; | ||
909 | +// } | ||
910 | +// } | ||
911 | +// | ||
912 | +// if (buf->size) { | ||
913 | +// char *dest; | ||
914 | +// | ||
915 | +// int space_avail; | ||
916 | +// int popnum, popped; | ||
917 | +// int total = 0; | ||
918 | +// | ||
919 | +// /* Break buffer into urb sized pieces, | ||
920 | +// * and link each to the endpoint | ||
921 | +// */ | ||
922 | +// while (buf->size > 0) { | ||
923 | +// | ||
924 | +// if (!current_urb) { | ||
925 | +// TTYERR ("current_urb is NULL, buf->size %d\n", | ||
926 | +// buf->size); | ||
927 | +// return total; | ||
928 | +// } | ||
929 | +// | ||
930 | +// dest = (char*)current_urb->buffer + | ||
931 | +// current_urb->actual_length; | ||
932 | +// | ||
933 | +// space_avail = | ||
934 | +// current_urb->buffer_length - | ||
935 | +// current_urb->actual_length; | ||
936 | +// popnum = MIN (space_avail, buf->size); | ||
937 | +// if (popnum == 0) | ||
938 | +// break; | ||
939 | +// | ||
940 | +// popped = buf_pop (buf, dest, popnum); | ||
941 | +// if (popped == 0) | ||
942 | +// break; | ||
943 | +// current_urb->actual_length += popped; | ||
944 | +// total += popped; | ||
945 | +// | ||
946 | +// /* If endpoint->last == 0, then transfers have | ||
947 | +// * not started on this endpoint | ||
948 | +// */ | ||
949 | +// if (endpoint->last == 0) { | ||
950 | +// if(udc_endpoint_write (endpoint)){ | ||
951 | +// /* Write pre-empted by RX */ | ||
952 | +// return -1; | ||
953 | +// } | ||
954 | +// } | ||
955 | +// | ||
956 | +// }/* end while */ | ||
957 | +// return total; | ||
958 | +// } | ||
959 | +// | ||
960 | +// return 0; | ||
961 | +// } | ||
962 | |||
963 | - struct usb_endpoint_instance *endpoint = | ||
964 | - &endpoint_instance[TX_ENDPOINT]; | ||
965 | - struct urb *current_urb = NULL; | ||
966 | - char *dest; | ||
967 | - | ||
968 | - int space_avail; | ||
969 | - int popnum, popped; | ||
970 | - int total = 0; | ||
971 | - | ||
972 | - /* Break buffer into urb sized pieces, and link each to the endpoint */ | ||
973 | - while (buf->size > 0) { | ||
974 | - current_urb = next_urb (device_instance, endpoint); | ||
975 | - if (!current_urb) { | ||
976 | - TTYERR ("current_urb is NULL, buf->size %d\n", | ||
977 | - buf->size); | ||
978 | - return total; | ||
979 | - } | ||
980 | - | ||
981 | - dest = current_urb->buffer + | ||
982 | - current_urb->actual_length; | ||
983 | - | ||
984 | - space_avail = | ||
985 | - current_urb->buffer_length - | ||
986 | - current_urb->actual_length; | ||
987 | - popnum = MIN (space_avail, buf->size); | ||
988 | - if (popnum == 0) | ||
989 | - break; | ||
990 | - | ||
991 | - popped = buf_pop (buf, dest, popnum); | ||
992 | - if (popped == 0) | ||
993 | - break; | ||
994 | - current_urb->actual_length += popped; | ||
995 | - total += popped; | ||
996 | - | ||
997 | - /* If endpoint->last == 0, then transfers have not started on this endpoint */ | ||
998 | - if (endpoint->last == 0) { | ||
999 | - udc_endpoint_write (endpoint); | ||
1000 | - } | ||
1001 | - | ||
1002 | - } /* end while */ | ||
1003 | - return total; | ||
1004 | - } /* end if tx_urb */ | ||
1005 | +static int fill_buffer (circbuf_t * buf) | ||
1006 | +{ | ||
1007 | + struct usb_endpoint_instance *endpoint = | ||
1008 | + &endpoint_instance[rx_endpoint]; | ||
1009 | |||
1010 | - return 0; | ||
1011 | -} | ||
1012 | + if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) { | ||
1013 | + unsigned int nb = endpoint->rcv_urb->actual_length; | ||
1014 | + char *src = (char *) endpoint->rcv_urb->buffer; | ||
1015 | |||
1016 | + buf_push (buf, src, nb); | ||
1017 | + endpoint->rcv_urb->actual_length = 0; | ||
1018 | + | ||
1019 | + TTYDBG ("nb= %d",nb); | ||
1020 | + return nb; | ||
1021 | + } | ||
1022 | + | ||
1023 | + return 0; | ||
1024 | +} | ||
1025 | +/* | ||
1026 | static int fill_buffer (circbuf_t * buf) | ||
1027 | { | ||
1028 | struct usb_endpoint_instance *endpoint = | ||
1029 | - &endpoint_instance[RECV_ENDPOINT]; | ||
1030 | + &endpoint_instance[rx_endpoint]; | ||
1031 | |||
1032 | if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) { | ||
1033 | - unsigned int nb = endpoint->rcv_urb->actual_length; | ||
1034 | + unsigned int nb = 0; | ||
1035 | char *src = (char *) endpoint->rcv_urb->buffer; | ||
1036 | + unsigned int rx_avail = buf->totalsize - buf->size; | ||
1037 | |||
1038 | - buf_push (buf, src, nb); | ||
1039 | - endpoint->rcv_urb->actual_length = 0; | ||
1040 | + if(rx_avail >= endpoint->rcv_urb->actual_length){ | ||
1041 | |||
1042 | + nb = endpoint->rcv_urb->actual_length; | ||
1043 | + buf_push (buf, src, nb); | ||
1044 | + endpoint->rcv_urb->actual_length = 0; | ||
1045 | + | ||
1046 | + } | ||
1047 | return nb; | ||
1048 | } | ||
1049 | - | ||
1050 | return 0; | ||
1051 | } | ||
1052 | - | ||
1053 | +*/ | ||
1054 | static int usbtty_configured (void) | ||
1055 | { | ||
1056 | return usbtty_configured_flag; | ||
1057 | } | ||
1058 | |||
1059 | -/*********************************************************************************/ | ||
1060 | +/******************************************************************************/ | ||
1061 | |||
1062 | static void usbtty_event_handler (struct usb_device_instance *device, | ||
1063 | usb_device_event_t event, int data) | ||
1064 | @@ -619,8 +1036,34 @@ | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | -/*********************************************************************************/ | ||
1069 | +/******************************************************************************/ | ||
1070 | |||
1071 | +int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb) | ||
1072 | +{ | ||
1073 | + switch (request->bRequest){ | ||
1074 | + | ||
1075 | + case ACM_SET_CONTROL_LINE_STATE: /* Implies DTE ready */ | ||
1076 | + break; | ||
1077 | + case ACM_SEND_ENCAPSULATED_COMMAND : /* Required */ | ||
1078 | + break; | ||
1079 | + case ACM_SET_LINE_ENCODING : /* DTE stop/parity bits | ||
1080 | + * per character */ | ||
1081 | + break; | ||
1082 | + case ACM_GET_ENCAPSULATED_RESPONSE : /* request response */ | ||
1083 | + break; | ||
1084 | + case ACM_GET_LINE_ENCODING : /* request DTE rate, | ||
1085 | + * stop/parity bits */ | ||
1086 | + memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc)); | ||
1087 | + urb->actual_length = sizeof(rs232_desc); | ||
1088 | + | ||
1089 | + break; | ||
1090 | + default: | ||
1091 | + return 1; | ||
1092 | + } | ||
1093 | + return 0; | ||
1094 | +} | ||
1095 | + | ||
1096 | +/******************************************************************************/ | ||
1097 | |||
1098 | /* | ||
1099 | * Since interrupt handling has not yet been implemented, we use this function | ||
1100 | @@ -630,36 +1073,29 @@ | ||
1101 | void usbtty_poll (void) | ||
1102 | { | ||
1103 | /* New interrupts? */ | ||
1104 | - pretend_interrupts (); | ||
1105 | + udc_irq(); | ||
1106 | |||
1107 | - /* Write any output data to host buffer (do this before checking interrupts to avoid missing one) */ | ||
1108 | + /* Write any output data to host buffer | ||
1109 | + * (do this before checking interrupts to avoid missing one) | ||
1110 | + */ | ||
1111 | if (usbtty_configured ()) { | ||
1112 | write_buffer (&usbtty_output); | ||
1113 | } | ||
1114 | |||
1115 | /* New interrupts? */ | ||
1116 | - pretend_interrupts (); | ||
1117 | - | ||
1118 | - /* Check for new data from host.. (do this after checking interrupts to get latest data) */ | ||
1119 | + udc_irq(); | ||
1120 | + | ||
1121 | + /* Check for new data from host.. | ||
1122 | + * (do this after checking interrupts to get latest data) | ||
1123 | + */ | ||
1124 | if (usbtty_configured ()) { | ||
1125 | fill_buffer (&usbtty_input); | ||
1126 | } | ||
1127 | |||
1128 | /* New interrupts? */ | ||
1129 | - pretend_interrupts (); | ||
1130 | -} | ||
1131 | + udc_irq(); | ||
1132 | |||
1133 | -static void pretend_interrupts (void) | ||
1134 | -{ | ||
1135 | - /* Loop while we have interrupts. | ||
1136 | - * If we don't do this, the input chain | ||
1137 | - * polling delay is likely to miss | ||
1138 | - * host requests. | ||
1139 | - */ | ||
1140 | - while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) { | ||
1141 | - /* Handle any new IRQs */ | ||
1142 | - omap1510_udc_irq (); | ||
1143 | - omap1510_udc_noniso_irq (); | ||
1144 | - } | ||
1145 | } | ||
1146 | + | ||
1147 | + | ||
1148 | #endif | ||
1149 | Index: u-boot/drivers/usbtty.h | ||
1150 | =================================================================== | ||
1151 | --- u-boot.orig/drivers/usbtty.h 2007-02-08 21:11:27.000000000 +0100 | ||
1152 | +++ u-boot/drivers/usbtty.h 2007-02-08 21:11:55.000000000 +0100 | ||
1153 | @@ -2,6 +2,9 @@ | ||
1154 | * (C) Copyright 2003 | ||
1155 | * Gerry Hamel, geh@ti.com, Texas Instruments | ||
1156 | * | ||
1157 | + * (C) Copyright 2006 | ||
1158 | + * Bryan O'Donoghue, bodonoghue <at> codehermit.ie, CodeHermit | ||
1159 | + * | ||
1160 | * This program is free software; you can redistribute it and/or modify | ||
1161 | * it under the terms of the GNU General Public License as published by | ||
1162 | * the Free Software Foundation; either version 2 of the License, or | ||
1163 | @@ -21,44 +24,49 @@ | ||
1164 | #ifndef __USB_TTY_H__ | ||
1165 | #define __USB_TTY_H__ | ||
1166 | |||
1167 | - | ||
1168 | #include "usbdcore.h" | ||
1169 | +#if defined(CONFIG_PPC) | ||
1170 | +#include "usbdcore_mpc8xx.h" | ||
1171 | +#elif defined(CONFIG_OMAP1510) | ||
1172 | #include "usbdcore_omap1510.h" | ||
1173 | +#endif | ||
1174 | |||
1175 | +#include <config.h> | ||
1176 | +#include <version.h> | ||
1177 | |||
1178 | -#define NUM_CONFIGS 1 | ||
1179 | -#define NUM_INTERFACES 1 | ||
1180 | -#define NUM_ENDPOINTS 3 | ||
1181 | +/* If no VendorID/ProductID is defined in config.h, pretend to be Linux | ||
1182 | + * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */ | ||
1183 | |||
1184 | -#define EP0_MAX_PACKET_SIZE 64 | ||
1185 | +#ifndef CONFIG_USBD_VENDORID | ||
1186 | +#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ | ||
1187 | +#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ | ||
1188 | +#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ | ||
1189 | +#define CONFIG_USBD_MANUFACTURER "Das U-Boot" | ||
1190 | +#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION | ||
1191 | +#endif /* CONFIG_USBD_VENDORID */ | ||
1192 | |||
1193 | #define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" | ||
1194 | -#define CONFIG_USBD_INTERFACE_STR "Simple Serial Data Interface - Bulk Mode" | ||
1195 | - | ||
1196 | - | ||
1197 | -#define CONFIG_USBD_SERIAL_OUT_ENDPOINT 2 | ||
1198 | -#define CONFIG_USBD_SERIAL_OUT_PKTSIZE 64 | ||
1199 | -#define CONFIG_USBD_SERIAL_IN_ENDPOINT 1 | ||
1200 | -#define CONFIG_USBD_SERIAL_IN_PKTSIZE 64 | ||
1201 | -#define CONFIG_USBD_SERIAL_INT_ENDPOINT 5 | ||
1202 | -#define CONFIG_USBD_SERIAL_INT_PKTSIZE 16 | ||
1203 | |||
1204 | +#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT | ||
1205 | +#define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE | ||
1206 | +#define CONFIG_USBD_SERIAL_IN_ENDPOINT UDC_IN_ENDPOINT | ||
1207 | +#define CONFIG_USBD_SERIAL_IN_PKTSIZE UDC_IN_PACKET_SIZE | ||
1208 | +#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT | ||
1209 | +#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE | ||
1210 | +#define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE | ||
1211 | |||
1212 | #define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS | ||
1213 | -#define USBTTY_DEVICE_SUBCLASS COMMUNICATIONS_NO_SUBCLASS | ||
1214 | -#define USBTTY_DEVICE_PROTOCOL COMMUNICATIONS_NO_PROTOCOL | ||
1215 | |||
1216 | -#define USBTTY_INTERFACE_CLASS 0xFF /* Vendor Specific */ | ||
1217 | -#define USBTTY_INTERFACE_SUBCLASS 0x02 | ||
1218 | -#define USBTTY_INTERFACE_PROTOCOL 0x01 | ||
1219 | - | ||
1220 | -#define USBTTY_BCD_DEVICE 0x0 | ||
1221 | -#define USBTTY_MAXPOWER 0x0 | ||
1222 | - | ||
1223 | -#define STR_MANUFACTURER 1 | ||
1224 | -#define STR_PRODUCT 2 | ||
1225 | -#define STR_SERIAL 3 | ||
1226 | -#define STR_CONFIG 4 | ||
1227 | -#define STR_INTERFACE 5 | ||
1228 | +#define USBTTY_BCD_DEVICE 0x00 | ||
1229 | +#define USBTTY_MAXPOWER 0x00 | ||
1230 | + | ||
1231 | +#define STR_LANG 0x00 | ||
1232 | +#define STR_MANUFACTURER 0x01 | ||
1233 | +#define STR_PRODUCT 0x02 | ||
1234 | +#define STR_SERIAL 0x03 | ||
1235 | +#define STR_CONFIG 0x04 | ||
1236 | +#define STR_DATA_INTERFACE 0x05 | ||
1237 | +#define STR_CTRL_INTERFACE 0x06 | ||
1238 | +#define STR_COUNT 0x07 | ||
1239 | |||
1240 | #endif | ||
1241 | Index: u-boot/drivers/usbdcore_omap1510.c | ||
1242 | =================================================================== | ||
1243 | --- u-boot.orig/drivers/usbdcore_omap1510.c 2007-02-08 21:11:27.000000000 +0100 | ||
1244 | +++ u-boot/drivers/usbdcore_omap1510.c 2007-02-08 21:11:55.000000000 +0100 | ||
1245 | @@ -960,7 +960,7 @@ | ||
1246 | /* Handle general USB interrupts and dispatch according to type. | ||
1247 | * This function implements TRM Figure 14-13. | ||
1248 | */ | ||
1249 | -void omap1510_udc_irq (void) | ||
1250 | +static void omap1510_udc_irq (void) | ||
1251 | { | ||
1252 | u16 irq_src = inw (UDC_IRQ_SRC); | ||
1253 | int valid_irq = 0; | ||
1254 | @@ -1000,7 +1000,7 @@ | ||
1255 | } | ||
1256 | |||
1257 | /* This function implements TRM Figure 14-26. */ | ||
1258 | -void omap1510_udc_noniso_irq (void) | ||
1259 | +static void omap1510_udc_noniso_irq (void) | ||
1260 | { | ||
1261 | unsigned short epnum; | ||
1262 | unsigned short irq_src = inw (UDC_IRQ_SRC); | ||
1263 | @@ -1054,6 +1054,20 @@ | ||
1264 | irq_src); | ||
1265 | } | ||
1266 | |||
1267 | +void udc_irq(void) | ||
1268 | +{ | ||
1269 | + /* Loop while we have interrupts. | ||
1270 | + * If we don't do this, the input chain | ||
1271 | + * polling delay is likely to miss | ||
1272 | + * host requests. | ||
1273 | + */ | ||
1274 | + while (inw (UDC_IRQ_SRC) & ~UDC_SOF_Flg) { | ||
1275 | + /* Handle any new IRQs */ | ||
1276 | + omap1510_udc_irq (); | ||
1277 | + omap1510_udc_noniso_irq (); | ||
1278 | + } | ||
1279 | +} | ||
1280 | + | ||
1281 | /* | ||
1282 | ------------------------------------------------------------------------------- | ||
1283 | */ | ||
1284 | Index: u-boot/include/usb_cdc_acm.h | ||
1285 | =================================================================== | ||
1286 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | ||
1287 | +++ u-boot/include/usb_cdc_acm.h 2007-02-08 21:11:55.000000000 +0100 | ||
1288 | @@ -0,0 +1,43 @@ | ||
1289 | +/* | ||
1290 | + * (C) Copyright 2006 | ||
1291 | + * Bryan O'Donoghue, deckard <at> codehermit.ie, CodeHermit | ||
1292 | + * | ||
1293 | + * This program is free software; you can redistribute it and/or modify | ||
1294 | + * it under the terms of the GNU General Public License as published by | ||
1295 | + * the Free Software Foundation; either version 2 of the License, or | ||
1296 | + * (at your option) any later version. | ||
1297 | + * | ||
1298 | + * This program is distributed in the hope that it will be useful, | ||
1299 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1300 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1301 | + * GNU General Public License for more details. | ||
1302 | + * | ||
1303 | + * You should have received a copy of the GNU General Public License | ||
1304 | + * along with this program; if not, write to the Free Software | ||
1305 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
1306 | + * | ||
1307 | + */ | ||
1308 | + | ||
1309 | +/* ACM Control Requests */ | ||
1310 | +#define ACM_SEND_ENCAPSULATED_COMMAND 0x00 | ||
1311 | +#define ACM_GET_ENCAPSULATED_RESPONSE 0x01 | ||
1312 | +#define ACM_SET_COMM_FEATURE 0x02 | ||
1313 | +#define ACM_GET_COMM_FEATRUE 0x03 | ||
1314 | +#define ACM_CLEAR_COMM_FEATURE 0x04 | ||
1315 | +#define ACM_SET_LINE_ENCODING 0x20 | ||
1316 | +#define ACM_GET_LINE_ENCODING 0x21 | ||
1317 | +#define ACM_SET_CONTROL_LINE_STATE 0x22 | ||
1318 | +#define ACM_SEND_BREAK 0x23 | ||
1319 | + | ||
1320 | +/* ACM Notification Codes */ | ||
1321 | +#define ACM_NETWORK_CONNECTION 0x00 | ||
1322 | +#define ACM_RESPONSE_AVAILABLE 0x01 | ||
1323 | +#define ACM_SERIAL_STATE 0x20 | ||
1324 | + | ||
1325 | +/* Format of response expected by a ACM_GET_LINE_ENCODING request */ | ||
1326 | +struct rs232_emu{ | ||
1327 | + unsigned long dter; | ||
1328 | + unsigned char stop_bits; | ||
1329 | + unsigned char parity; | ||
1330 | + unsigned char data_bits; | ||
1331 | +}__attribute__((packed)); | ||
1332 | Index: u-boot/include/usbdcore_omap1510.h | ||
1333 | =================================================================== | ||
1334 | --- u-boot.orig/include/usbdcore_omap1510.h 2007-02-08 21:11:27.000000000 +0100 | ||
1335 | +++ u-boot/include/usbdcore_omap1510.h 2007-02-08 21:11:55.000000000 +0100 | ||
1336 | @@ -161,13 +161,23 @@ | ||
1337 | #define UDC_VBUS_CTRL (1 << 19) | ||
1338 | #define UDC_VBUS_MODE (1 << 18) | ||
1339 | |||
1340 | - | ||
1341 | -void omap1510_udc_irq(void); | ||
1342 | -void omap1510_udc_noniso_irq(void); | ||
1343 | - | ||
1344 | +/* OMAP Endpoint parameters */ | ||
1345 | +#define EP0_MAX_PACKET_SIZE 64 | ||
1346 | +#define UDC_OUT_ENDPOINT 2 | ||
1347 | +#define UDC_OUT_PACKET_SIZE 64 | ||
1348 | +#define UDC_IN_ENDPOINT 1 | ||
1349 | +#define UDC_IN_PACKET_SIZE 64 | ||
1350 | +#define UDC_INT_ENDPOINT 5 | ||
1351 | +#define UDC_INT_PACKET_SIZE 16 | ||
1352 | +#define UDC_BULK_PACKET_SIZE 16 | ||
1353 | + | ||
1354 | +void udc_irq (void); | ||
1355 | +/* Flow control */ | ||
1356 | +void udc_set_nak(int epid); | ||
1357 | +void udc_unset_nak (int epid); | ||
1358 | |||
1359 | /* Higher level functions for abstracting away from specific device */ | ||
1360 | -void udc_endpoint_write(struct usb_endpoint_instance *endpoint); | ||
1361 | +int udc_endpoint_write(struct usb_endpoint_instance *endpoint); | ||
1362 | |||
1363 | int udc_init (void); | ||
1364 | |||
1365 | Index: u-boot/include/usbdescriptors.h | ||
1366 | =================================================================== | ||
1367 | --- u-boot.orig/include/usbdescriptors.h 2007-02-08 21:11:27.000000000 +0100 | ||
1368 | +++ u-boot/include/usbdescriptors.h 2007-02-08 21:11:55.000000000 +0100 | ||
1369 | @@ -92,15 +92,17 @@ | ||
1370 | #define COMMUNICATIONS_DEVICE_CLASS 0x02 | ||
1371 | |||
1372 | /* c.f. CDC 4.2 Table 15 */ | ||
1373 | -#define COMMUNICATIONS_INTERFACE_CLASS 0x02 | ||
1374 | +#define COMMUNICATIONS_INTERFACE_CLASS_CONTROL 0x02 | ||
1375 | +#define COMMUNICATIONS_INTERFACE_CLASS_DATA 0x0A | ||
1376 | +#define COMMUNICATIONS_INTERFACE_CLASS_VENDOR 0x0FF | ||
1377 | |||
1378 | /* c.f. CDC 4.3 Table 16 */ | ||
1379 | -#define COMMUNICATIONS_NO_SUBCLASS 0x00 | ||
1380 | +#define COMMUNICATIONS_NO_SUBCLASS 0x00 | ||
1381 | #define COMMUNICATIONS_DLCM_SUBCLASS 0x01 | ||
1382 | -#define COMMUNICATIONS_ACM_SUBCLASS 0x02 | ||
1383 | -#define COMMUNICATIONS_TCM_SUBCLASS 0x03 | ||
1384 | +#define COMMUNICATIONS_ACM_SUBCLASS 0x02 | ||
1385 | +#define COMMUNICATIONS_TCM_SUBCLASS 0x03 | ||
1386 | #define COMMUNICATIONS_MCCM_SUBCLASS 0x04 | ||
1387 | -#define COMMUNICATIONS_CCM_SUBCLASS 0x05 | ||
1388 | +#define COMMUNICATIONS_CCM_SUBCLASS 0x05 | ||
1389 | #define COMMUNICATIONS_ENCM_SUBCLASS 0x06 | ||
1390 | #define COMMUNICATIONS_ANCM_SUBCLASS 0x07 | ||
1391 | |||
1392 | @@ -110,15 +112,22 @@ | ||
1393 | #define COMMUNICATIONS_MDLM_SUBCLASS 0x0a | ||
1394 | #define COMMUNICATIONS_OBEX_SUBCLASS 0x0b | ||
1395 | |||
1396 | -/* c.f. CDC 4.6 Table 18 */ | ||
1397 | +/* c.f. CDC 4.4 Table 17 */ | ||
1398 | +#define COMMUNICATIONS_NO_PROTOCOL 0x00 | ||
1399 | +#define COMMUNICATIONS_V25TER_PROTOCOL 0x01 /*Common AT Hayes compatible*/ | ||
1400 | + | ||
1401 | +/* c.f. CDC 4.5 Table 18 */ | ||
1402 | #define DATA_INTERFACE_CLASS 0x0a | ||
1403 | |||
1404 | +/* c.f. CDC 4.6 No Table */ | ||
1405 | +#define DATA_INTERFACE_SUBCLASS_NONE 0x00 /* No subclass pertinent */ | ||
1406 | + | ||
1407 | /* c.f. CDC 4.7 Table 19 */ | ||
1408 | -#define COMMUNICATIONS_NO_PROTOCOL 0x00 | ||
1409 | +#define DATA_INTERFACE_PROTOCOL_NONE 0x00 /* No class protcol required */ | ||
1410 | |||
1411 | |||
1412 | /* c.f. CDC 5.2.3 Table 24 */ | ||
1413 | -#define CS_INTERFACE 0x24 | ||
1414 | +#define CS_INTERFACE 0x24 | ||
1415 | #define CS_ENDPOINT 0x25 | ||
1416 | |||
1417 | /* | ||
1418 | @@ -128,7 +137,7 @@ | ||
1419 | * c.f. WMCD 5.3 Table 5.3 | ||
1420 | */ | ||
1421 | |||
1422 | -#define USB_ST_HEADER 0x00 | ||
1423 | +#define USB_ST_HEADER 0x00 | ||
1424 | #define USB_ST_CMF 0x01 | ||
1425 | #define USB_ST_ACMF 0x02 | ||
1426 | #define USB_ST_DLMF 0x03 | ||
1427 | @@ -137,18 +146,18 @@ | ||
1428 | #define USB_ST_UF 0x06 | ||
1429 | #define USB_ST_CSF 0x07 | ||
1430 | #define USB_ST_TOMF 0x08 | ||
1431 | -#define USB_ST_USBTF 0x09 | ||
1432 | +#define USB_ST_USBTF 0x09 | ||
1433 | #define USB_ST_NCT 0x0a | ||
1434 | #define USB_ST_PUF 0x0b | ||
1435 | #define USB_ST_EUF 0x0c | ||
1436 | #define USB_ST_MCMF 0x0d | ||
1437 | #define USB_ST_CCMF 0x0e | ||
1438 | #define USB_ST_ENF 0x0f | ||
1439 | -#define USB_ST_ATMNF 0x10 | ||
1440 | +#define USB_ST_ATMNF 0x10 | ||
1441 | |||
1442 | #define USB_ST_WHCM 0x11 | ||
1443 | #define USB_ST_MDLM 0x12 | ||
1444 | -#define USB_ST_MDLMD 0x13 | ||
1445 | +#define USB_ST_MDLMD 0x13 | ||
1446 | #define USB_ST_DMM 0x14 | ||
1447 | #define USB_ST_OBEX 0x15 | ||
1448 | #define USB_ST_CS 0x16 | ||
1449 | @@ -312,7 +321,8 @@ | ||
1450 | u8 bDescriptorType; | ||
1451 | u8 bDescriptorSubtype; /* 0x06 */ | ||
1452 | u8 bMasterInterface; | ||
1453 | - u8 bSlaveInterface0[0]; | ||
1454 | + //u8 bSlaveInterface0[0]; | ||
1455 | + u8 bSlaveInterface0; | ||
1456 | } __attribute__ ((packed)); | ||
1457 | |||
1458 | struct usb_class_country_selection_descriptor { | ||
1459 | Index: u-boot/include/usbdcore.h | ||
1460 | =================================================================== | ||
1461 | --- u-boot.orig/include/usbdcore.h 2007-02-08 21:11:27.000000000 +0100 | ||
1462 | +++ u-boot/include/usbdcore.h 2007-02-08 21:11:55.000000000 +0100 | ||
1463 | @@ -576,6 +576,9 @@ | ||
1464 | |||
1465 | void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data); | ||
1466 | |||
1467 | + /* Do cdc device specific control requests */ | ||
1468 | + int (*cdc_recv_setup)(struct usb_device_request *request, struct urb *urb); | ||
1469 | + | ||
1470 | /* bus interface */ | ||
1471 | struct usb_bus_instance *bus; /* which bus interface driver */ | ||
1472 | |||
1473 | Index: u-boot/drivers/usbdcore_ep0.c | ||
1474 | =================================================================== | ||
1475 | --- u-boot.orig/drivers/usbdcore_ep0.c 2007-02-08 21:12:05.000000000 +0100 | ||
1476 | +++ u-boot/drivers/usbdcore_ep0.c 2007-02-08 21:12:08.000000000 +0100 | ||
1477 | @@ -223,7 +223,6 @@ | ||
1478 | |||
1479 | case USB_DESCRIPTOR_TYPE_CONFIGURATION: | ||
1480 | { | ||
1481 | - int bNumInterface; | ||
1482 | struct usb_configuration_descriptor | ||
1483 | *configuration_descriptor; | ||
1484 | struct usb_device_descriptor *device_descriptor; | ||
1485 | @@ -256,105 +255,6 @@ | ||
1486 | usb_configuration_descriptor), | ||
1487 | max); | ||
1488 | |||
1489 | - | ||
1490 | - /* iterate across interfaces for specified configuration */ | ||
1491 | - dbg_ep0 (0, "bNumInterfaces: %d", | ||
1492 | - configuration_descriptor->bNumInterfaces); | ||
1493 | - for (bNumInterface = 0; | ||
1494 | - bNumInterface < | ||
1495 | - configuration_descriptor->bNumInterfaces; | ||
1496 | - bNumInterface++) { | ||
1497 | - | ||
1498 | - int bAlternateSetting; | ||
1499 | - struct usb_interface_instance | ||
1500 | - *interface_instance; | ||
1501 | - | ||
1502 | - dbg_ep0 (3, "[%d] bNumInterfaces: %d", | ||
1503 | - bNumInterface, | ||
1504 | - configuration_descriptor->bNumInterfaces); | ||
1505 | - | ||
1506 | - if (! (interface_instance = usbd_device_interface_instance (device, | ||
1507 | - port, index, bNumInterface))) | ||
1508 | - { | ||
1509 | - dbg_ep0 (3, "[%d] interface_instance NULL", | ||
1510 | - bNumInterface); | ||
1511 | - return -1; | ||
1512 | - } | ||
1513 | - /* iterate across interface alternates */ | ||
1514 | - for (bAlternateSetting = 0; | ||
1515 | - bAlternateSetting < interface_instance->alternates; | ||
1516 | - bAlternateSetting++) { | ||
1517 | - /*int class; */ | ||
1518 | - int bNumEndpoint; | ||
1519 | - struct usb_interface_descriptor *interface_descriptor; | ||
1520 | - | ||
1521 | - struct usb_alternate_instance *alternate_instance; | ||
1522 | - | ||
1523 | - dbg_ep0 (3, "[%d:%d] alternates: %d", | ||
1524 | - bNumInterface, | ||
1525 | - bAlternateSetting, | ||
1526 | - interface_instance->alternates); | ||
1527 | - | ||
1528 | - if (! (alternate_instance = usbd_device_alternate_instance (device, port, index, bNumInterface, bAlternateSetting))) { | ||
1529 | - dbg_ep0 (3, "[%d] alternate_instance NULL", | ||
1530 | - bNumInterface); | ||
1531 | - return -1; | ||
1532 | - } | ||
1533 | - /* copy descriptor for this interface */ | ||
1534 | - copy_config (urb, alternate_instance->interface_descriptor, | ||
1535 | - sizeof (struct usb_interface_descriptor), | ||
1536 | - max); | ||
1537 | - | ||
1538 | - /*dbg_ep0(3, "[%d:%d] classes: %d endpoints: %d", bNumInterface, bAlternateSetting, */ | ||
1539 | - /* alternate_instance->classes, alternate_instance->endpoints); */ | ||
1540 | - | ||
1541 | - /* iterate across classes for this alternate interface */ | ||
1542 | -#if 0 | ||
1543 | - for (class = 0; | ||
1544 | - class < alternate_instance->classes; | ||
1545 | - class++) { | ||
1546 | - struct usb_class_descriptor *class_descriptor; | ||
1547 | - /*dbg_ep0(3, "[%d:%d:%d] classes: %d", bNumInterface, bAlternateSetting, */ | ||
1548 | - /* class, alternate_instance->classes); */ | ||
1549 | - if (!(class_descriptor = usbd_device_class_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, class))) { | ||
1550 | - dbg_ep0 (3, "[%d] class NULL", | ||
1551 | - class); | ||
1552 | - return -1; | ||
1553 | - } | ||
1554 | - /* copy descriptor for this class */ | ||
1555 | - copy_config (urb, class_descriptor, | ||
1556 | - sizeof (struct usb_class_descriptor), | ||
1557 | - max); | ||
1558 | - } | ||
1559 | -#endif | ||
1560 | - | ||
1561 | - /* iterate across endpoints for this alternate interface */ | ||
1562 | - interface_descriptor = alternate_instance->interface_descriptor; | ||
1563 | - for (bNumEndpoint = 0; | ||
1564 | - bNumEndpoint < alternate_instance->endpoints; | ||
1565 | - bNumEndpoint++) { | ||
1566 | - struct usb_endpoint_descriptor *endpoint_descriptor; | ||
1567 | - dbg_ep0 (3, "[%d:%d:%d] endpoint: %d", | ||
1568 | - bNumInterface, | ||
1569 | - bAlternateSetting, | ||
1570 | - bNumEndpoint, | ||
1571 | - interface_descriptor-> | ||
1572 | - bNumEndpoints); | ||
1573 | - if (!(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, index, bNumInterface, bAlternateSetting, bNumEndpoint))) { | ||
1574 | - dbg_ep0 (3, "[%d] endpoint NULL", | ||
1575 | - bNumEndpoint); | ||
1576 | - return -1; | ||
1577 | - } | ||
1578 | - /* copy descriptor for this endpoint */ | ||
1579 | - copy_config (urb, endpoint_descriptor, | ||
1580 | - sizeof (struct usb_endpoint_descriptor), | ||
1581 | - max); | ||
1582 | - } | ||
1583 | - } | ||
1584 | - } | ||
1585 | - dbg_ep0 (3, "lengths: %d %d", | ||
1586 | - le16_to_cpu (configuration_descriptor->wTotalLength), | ||
1587 | - urb->actual_length); | ||
1588 | } | ||
1589 | break; | ||
1590 | |||
1591 | @@ -363,6 +263,7 @@ | ||
1592 | struct usb_string_descriptor *string_descriptor; | ||
1593 | |||
1594 | if (!(string_descriptor = usbd_get_string (index))) { | ||
1595 | + dbg_ep0(0, "Invalid string index %u\n", index); | ||
1596 | return -1; | ||
1597 | } | ||
1598 | /*dbg_ep0(3, "string_descriptor: %p", string_descriptor); */ | ||
1599 | @@ -495,6 +396,8 @@ | ||
1600 | |||
1601 | /* handle USB Standard Request (c.f. USB Spec table 9-2) */ | ||
1602 | if ((request->bmRequestType & USB_REQ_TYPE_MASK) != 0) { | ||
1603 | + if (device->device_state <= STATE_CONFIGURED) | ||
1604 | + return device->cdc_recv_setup(request, urb); | ||
1605 | dbg_ep0 (1, "non standard request: %x", | ||
1606 | request->bmRequestType & USB_REQ_TYPE_MASK); | ||
1607 | return -1; /* Stall here */ | ||