USB-to-serial device (Samuel Thibault).
[qemu] / hw / usb-serial.c
1 /*
2  * FTDI FT232BM Device emulation
3  *
4  * Copyright (c) 2006 CodeSourcery.
5  * Copyright (c) 2008 Samuel Thibault <samuel.thibault@ens-lyon.org>
6  * Written by Paul Brook, reused for FTDI by Samuel Thibault
7  *
8  * This code is licenced under the LGPL.
9  */
10
11 #include "qemu-common.h"
12 #include "usb.h"
13 #include "qemu-char.h"
14
15 //#define DEBUG_Serial
16
17 #ifdef DEBUG_Serial
18 #define DPRINTF(fmt, args...) \
19 do { printf("usb-serial: " fmt , ##args); } while (0)
20 #else
21 #define DPRINTF(fmt, args...) do {} while(0)
22 #endif
23
24 #define RECV_BUF 384
25 #define SEND_BUF 128        // Not used for now
26
27 /* Commands */
28 #define FTDI_RESET              0
29 #define FTDI_SET_MDM_CTRL       1
30 #define FTDI_SET_FLOW_CTRL      2
31 #define FTDI_SET_BAUD           3
32 #define FTDI_SET_DATA           4
33 #define FTDI_GET_MDM_ST         5
34 #define FTDI_SET_EVENT_CHR      6
35 #define FTDI_SET_ERROR_CHR      7
36 #define FTDI_SET_LATENCY        9
37 #define FTDI_GET_LATENCY        10
38
39 #define DeviceOutVendor ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
40 #define DeviceInVendor  ((USB_DIR_IN |USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
41
42 /* RESET */
43
44 #define FTDI_RESET_SIO  0
45 #define FTDI_RESET_RX   1
46 #define FTDI_RESET_TX   2
47
48 /* SET_MDM_CTRL */
49
50 #define FTDI_MDM_CTRL   3
51 #define FTDI_DTR        1
52 #define FTDI_RTS        2
53
54 /* SET_FLOW_CTRL */
55
56 #define FTDI_RTS_CTS_HS         1
57 #define FTDI_DTR_DSR_HS         2
58 #define FTDI_XON_XOFF_HS        4
59
60 /* SET_DATA */
61
62 #define FTDI_PARITY     (0x7 << 8)
63 #define FTDI_ODD        (0x1 << 8)
64 #define FTDI_EVEN       (0x2 << 8)
65 #define FTDI_MARK       (0x3 << 8)
66 #define FTDI_SPACE      (0x4 << 8)
67
68 #define FTDI_STOP       (0x3 << 11)
69 #define FTDI_STOP1      (0x0 << 11)
70 #define FTDI_STOP15     (0x1 << 11)
71 #define FTDI_STOP2      (0x2 << 11)
72
73 /* GET_MDM_ST */
74 /* TODO: should be sent every 40ms */
75 #define FTDI_CTS  (1<<4)        // CTS line status
76 #define FTDI_DSR  (1<<5)        // DSR line status
77 #define FTDI_RI   (1<<6)        // RI line status
78 #define FTDI_RLSD (1<<7)        // Receive Line Signal Detect
79
80 /* Status */
81
82 #define FTDI_DR   (1<<0)        // Data Ready
83 #define FTDI_OE   (1<<1)        // Overrun Err
84 #define FTDI_PE   (1<<2)        // Parity Err
85 #define FTDI_FE   (1<<3)        // Framing Err
86 #define FTDI_BI   (1<<4)        // Break Interrupt
87 #define FTDI_THRE (1<<5)        // Transmitter Holding Register
88 #define FTDI_TEMT (1<<6)        // Transmitter Empty
89 #define FTDI_FIFO (1<<7)        // Error in FIFO
90
91 typedef struct {
92     USBDevice dev;
93     uint16_t vendorid;
94     uint16_t productid;
95     uint8_t recv_buf[RECV_BUF];
96     uint8_t recv_ptr;
97     uint8_t recv_used;
98     uint8_t send_buf[SEND_BUF];
99     uint8_t event_chr;
100     uint8_t error_chr;
101     uint8_t event_trigger;
102     uint8_t lines;
103     QEMUSerialSetParams params;
104     int latency;        /* ms */
105     CharDriverState *cs;
106 } USBSerialState;
107
108 static const uint8_t qemu_serial_dev_descriptor[] = {
109         0x12,       /*  u8 bLength; */
110         0x01,       /*  u8 bDescriptorType; Device */
111         0x00, 0x02, /*  u16 bcdUSB; v2.0 */
112
113         0x00,       /*  u8  bDeviceClass; */
114         0x00,       /*  u8  bDeviceSubClass; */
115         0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
116         0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
117
118         /* Vendor and product id are arbitrary.  */
119         0x03, 0x04, /*  u16 idVendor; */
120         0x00, 0xFF, /*  u16 idProduct; */
121         0x00, 0x04, /*  u16 bcdDevice */
122
123         0x01,       /*  u8  iManufacturer; */
124         0x02,       /*  u8  iProduct; */
125         0x03,       /*  u8  iSerialNumber; */
126         0x01        /*  u8  bNumConfigurations; */
127 };
128
129 static const uint8_t qemu_serial_config_descriptor[] = {
130
131         /* one configuration */
132         0x09,       /*  u8  bLength; */
133         0x02,       /*  u8  bDescriptorType; Configuration */
134         0x20, 0x00, /*  u16 wTotalLength; */
135         0x01,       /*  u8  bNumInterfaces; (1) */
136         0x01,       /*  u8  bConfigurationValue; */
137         0x00,       /*  u8  iConfiguration; */
138         0x80,       /*  u8  bmAttributes;
139                                  Bit 7: must be set,
140                                      6: Self-powered,
141                                      5: Remote wakeup,
142                                      4..0: resvd */
143         100/2,       /*  u8  MaxPower; */
144
145         /* one interface */
146         0x09,       /*  u8  if_bLength; */
147         0x04,       /*  u8  if_bDescriptorType; Interface */
148         0x00,       /*  u8  if_bInterfaceNumber; */
149         0x00,       /*  u8  if_bAlternateSetting; */
150         0x02,       /*  u8  if_bNumEndpoints; */
151         0xff,       /*  u8  if_bInterfaceClass; Vendor Specific */
152         0xff,       /*  u8  if_bInterfaceSubClass; Vendor Specific */
153         0xff,       /*  u8  if_bInterfaceProtocol; Vendor Specific */
154         0x02,       /*  u8  if_iInterface; */
155
156         /* Bulk-In endpoint */
157         0x07,       /*  u8  ep_bLength; */
158         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
159         0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
160         0x02,       /*  u8  ep_bmAttributes; Bulk */
161         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
162         0x00,       /*  u8  ep_bInterval; */
163
164         /* Bulk-Out endpoint */
165         0x07,       /*  u8  ep_bLength; */
166         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
167         0x02,       /*  u8  ep_bEndpointAddress; OUT Endpoint 2 */
168         0x02,       /*  u8  ep_bmAttributes; Bulk */
169         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
170         0x00        /*  u8  ep_bInterval; */
171 };
172
173 static void usb_serial_reset(USBSerialState *s)
174 {
175     /* TODO: Set flow control to none */
176     s->event_chr = 0x0d;
177     s->event_trigger = 0;
178     s->recv_ptr = 0;
179     s->recv_used = 0;
180     /* TODO: purge in char driver */
181     s->lines &= ~(FTDI_DTR|FTDI_RTS);
182 }
183
184 static void usb_serial_handle_reset(USBDevice *dev)
185 {
186     USBSerialState *s = (USBSerialState *)dev;
187
188     DPRINTF("Reset\n");
189
190     usb_serial_reset(s);
191     /* TODO: Reset char device, send BREAK? */
192 }
193
194 static int usb_serial_handle_control(USBDevice *dev, int request, int value,
195                                   int index, int length, uint8_t *data)
196 {
197     USBSerialState *s = (USBSerialState *)dev;
198     int ret = 0;
199
200     //DPRINTF("got control %x, value %x\n",request, value);
201     switch (request) {
202     case DeviceRequest | USB_REQ_GET_STATUS:
203         data[0] = (0 << USB_DEVICE_SELF_POWERED) |
204             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
205         data[1] = 0x00;
206         ret = 2;
207         break;
208     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
209         if (value == USB_DEVICE_REMOTE_WAKEUP) {
210             dev->remote_wakeup = 0;
211         } else {
212             goto fail;
213         }
214         ret = 0;
215         break;
216     case DeviceOutRequest | USB_REQ_SET_FEATURE:
217         if (value == USB_DEVICE_REMOTE_WAKEUP) {
218             dev->remote_wakeup = 1;
219         } else {
220             goto fail;
221         }
222         ret = 0;
223         break;
224     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
225         dev->addr = value;
226         ret = 0;
227         break;
228     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
229         switch(value >> 8) {
230         case USB_DT_DEVICE:
231             memcpy(data, qemu_serial_dev_descriptor,
232                    sizeof(qemu_serial_dev_descriptor));
233             data[8] = s->vendorid & 0xff;
234             data[9] = ((s->vendorid) >> 8) & 0xff;
235             data[10] = s->productid & 0xff;
236             data[11] = ((s->productid) >> 8) & 0xff;
237             ret = sizeof(qemu_serial_dev_descriptor);
238             break;
239         case USB_DT_CONFIG:
240             memcpy(data, qemu_serial_config_descriptor,
241                    sizeof(qemu_serial_config_descriptor));
242             ret = sizeof(qemu_serial_config_descriptor);
243             break;
244         case USB_DT_STRING:
245             switch(value & 0xff) {
246             case 0:
247                 /* language ids */
248                 data[0] = 4;
249                 data[1] = 3;
250                 data[2] = 0x09;
251                 data[3] = 0x04;
252                 ret = 4;
253                 break;
254             case 1:
255                 /* vendor description */
256                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
257                 break;
258             case 2:
259                 /* product description */
260                 ret = set_usb_string(data, "QEMU USB SERIAL");
261                 break;
262             case 3:
263                 /* serial number */
264                 ret = set_usb_string(data, "1");
265                 break;
266             default:
267                 goto fail;
268             }
269             break;
270         default:
271             goto fail;
272         }
273         break;
274     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
275         data[0] = 1;
276         ret = 1;
277         break;
278     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
279         ret = 0;
280         break;
281     case DeviceRequest | USB_REQ_GET_INTERFACE:
282         data[0] = 0;
283         ret = 1;
284         break;
285     case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
286         ret = 0;
287         break;
288     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
289         ret = 0;
290         break;
291
292         /* Class specific requests.  */
293     case DeviceOutVendor | FTDI_RESET:
294         switch (value) {
295         case FTDI_RESET_SIO:
296             usb_serial_reset(s);
297             break;
298         case FTDI_RESET_RX:
299             s->recv_ptr = 0;
300             s->recv_used = 0;
301             /* TODO: purge from char device */
302             break;
303         case FTDI_RESET_TX:
304             /* TODO: purge from char device */
305             break;
306         }
307         break;
308     case DeviceOutVendor | FTDI_SET_MDM_CTRL:
309         s->lines = value & FTDI_MDM_CTRL;
310         break;
311     case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
312         /* TODO: ioctl */
313         break;
314     case DeviceOutVendor | FTDI_SET_BAUD: {
315         static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
316         int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
317                                      | ((index & 1) << 2)];
318         int divisor = value & 0x3fff;
319
320         /* chip special cases */
321         if (divisor == 1 && subdivisor8 == 0)
322             subdivisor8 = 4;
323         if (divisor == 0 && subdivisor8 == 0)
324             divisor = 1;
325
326         s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
327         qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
328         break;
329     }
330     case DeviceOutVendor | FTDI_SET_DATA:
331         switch (value & FTDI_PARITY) {
332             case 0:
333                 s->params.parity = 'N';
334                 break;
335             case FTDI_ODD:
336                 s->params.parity = 'O';
337                 break;
338             case FTDI_EVEN:
339                 s->params.parity = 'E';
340                 break;
341             default:
342                 DPRINTF("unsupported parity %d\n", value & FTDI_PARITY);
343                 goto fail;
344         }
345         switch (value & FTDI_STOP) {
346             case FTDI_STOP1:
347                 s->params.stop_bits = 1;
348                 break;
349             case FTDI_STOP2:
350                 s->params.stop_bits = 2;
351                 break;
352             default:
353                 DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
354                 goto fail;
355         }
356         qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
357         /* TODO: TX ON/OFF */
358         break;
359     case DeviceInVendor | FTDI_GET_MDM_ST:
360         /* TODO: return modem status */
361         data[0] = 0;
362         ret = 1;
363         break;
364     case DeviceOutVendor | FTDI_SET_EVENT_CHR:
365         /* TODO: handle it */
366         s->event_chr = value;
367         break;
368     case DeviceOutVendor | FTDI_SET_ERROR_CHR:
369         /* TODO: handle it */
370         s->error_chr = value;
371         break;
372     case DeviceOutVendor | FTDI_SET_LATENCY:
373         s->latency = value;
374         break;
375     case DeviceInVendor | FTDI_GET_LATENCY:
376         data[0] = s->latency;
377         ret = 1;
378         break;
379     default:
380     fail:
381         DPRINTF("got unsupported/bogus control %x, value %x\n", request, value);
382         ret = USB_RET_STALL;
383         break;
384     }
385     return ret;
386 }
387
388 static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
389 {
390     USBSerialState *s = (USBSerialState *)dev;
391     int ret = 0;
392     uint8_t devep = p->devep;
393     uint8_t *data = p->data;
394     int len = p->len;
395     int first_len;
396
397     switch (p->pid) {
398     case USB_TOKEN_OUT:
399         if (devep != 2)
400             goto fail;
401         qemu_chr_write(s->cs, data, len);
402         break;
403
404     case USB_TOKEN_IN:
405         if (devep != 1)
406             goto fail;
407         first_len = RECV_BUF - s->recv_ptr;
408         if (len <= 2) {
409             ret = USB_RET_NAK;
410             break;
411         }
412         /* TODO: Report serial line status */
413         *data++ = 0;
414         *data++ = 0;
415         len -= 2;
416         if (len > s->recv_used)
417             len = s->recv_used;
418         if (!len) {
419             ret = USB_RET_NAK;
420             break;
421         }
422         if (first_len > len)
423             first_len = len;
424         memcpy(data, s->recv_buf + s->recv_ptr, first_len);
425         if (len > first_len)
426             memcpy(data + first_len, s->recv_buf, len - first_len);
427         s->recv_used -= len;
428         s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;
429         ret = len + 2;
430         break;
431
432     default:
433         DPRINTF("Bad token\n");
434     fail:
435         ret = USB_RET_STALL;
436         break;
437     }
438
439     return ret;
440 }
441
442 static void usb_serial_handle_destroy(USBDevice *dev)
443 {
444     USBSerialState *s = (USBSerialState *)dev;
445
446     qemu_chr_close(s->cs);
447     qemu_free(s);
448 }
449
450 int usb_serial_can_read(void *opaque)
451 {
452     USBSerialState *s = opaque;
453     return RECV_BUF - s->recv_used;
454 }
455
456 void usb_serial_read(void *opaque, const uint8_t *buf, int size)
457 {
458     USBSerialState *s = opaque;
459     int first_size = RECV_BUF - s->recv_ptr;
460     if (first_size > size)
461         first_size = size;
462     memcpy(s->recv_buf + s->recv_ptr + s->recv_used, buf, first_size);
463     if (size > first_size)
464         memcpy(s->recv_buf, buf + first_size, size - first_size);
465     s->recv_used += size;
466 }
467
468 void usb_serial_event(void *opaque, int event)
469 {
470     USBSerialState *s = opaque;
471
472     switch (event) {
473         case CHR_EVENT_BREAK:
474             /* TODO: Send Break to USB */
475             break;
476         case CHR_EVENT_FOCUS:
477             break;
478         case CHR_EVENT_RESET:
479             usb_serial_reset(s);
480             /* TODO: Reset USB port */
481             break;
482     }
483 }
484
485 USBDevice *usb_serial_init(const char *filename)
486 {
487     USBSerialState *s;
488     CharDriverState *cdrv;
489     unsigned short vendorid = 0x0403, productid = 0xFF00;
490
491     while (*filename && *filename != ':') {
492         const char *p;
493         char *e;
494         if (strstart(filename, "vendorid=", &p)) {
495             vendorid = strtol(p, &e, 16);
496             if (e == p || (*e && *e != ',' && *e != ':')) {
497                 printf("bogus vendor ID %s\n", p);
498                 return NULL;
499             }
500             filename = e;
501         } else if (strstart(filename, "productid=", &p)) {
502             productid = strtol(p, &e, 16);
503             if (e == p || (*e && *e != ',' && *e != ':')) {
504                 printf("bogus product ID %s\n", p);
505                 return NULL;
506             }
507             filename = e;
508         } else {
509             printf("unrecognized serial USB option %s\n", filename);
510             return NULL;
511         }
512         while(*filename == ',')
513             filename++;
514     }
515     if (!*filename) {
516         printf("character device specification needed\n");
517         return NULL;
518     }
519     filename++;
520     s = qemu_mallocz(sizeof(USBSerialState));
521     if (!s)
522         return NULL;
523
524     cdrv = qemu_chr_open(filename);
525     if (!cdrv)
526         goto fail;
527     s->cs = cdrv;
528     qemu_chr_add_handlers(cdrv, usb_serial_can_read, usb_serial_read, usb_serial_event, s);
529
530     s->dev.speed = USB_SPEED_FULL;
531     s->dev.handle_packet = usb_generic_handle_packet;
532
533     s->dev.handle_reset = usb_serial_handle_reset;
534     s->dev.handle_control = usb_serial_handle_control;
535     s->dev.handle_data = usb_serial_handle_data;
536     s->dev.handle_destroy = usb_serial_handle_destroy;
537
538     s->vendorid = vendorid;
539     s->productid = productid;
540
541     snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Serial(%.16s)",
542              filename);
543
544     usb_serial_handle_reset((USBDevice *)s);
545     return (USBDevice *)s;
546  fail:
547     qemu_free(s);
548     return NULL;
549 }