xref: /openbmc/qemu/hw/usb/dev-serial.c (revision 0ed93f4c)
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 licensed under the LGPL.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qapi/error.h"
13 #include "qemu/cutils.h"
14 #include "qemu/error-report.h"
15 #include "qemu/module.h"
16 #include "hw/qdev-properties.h"
17 #include "hw/usb.h"
18 #include "migration/vmstate.h"
19 #include "desc.h"
20 #include "chardev/char-serial.h"
21 #include "chardev/char-fe.h"
22 #include "qom/object.h"
23 
24 //#define DEBUG_Serial
25 
26 #ifdef DEBUG_Serial
27 #define DPRINTF(fmt, ...) \
28 do { printf("usb-serial: " fmt , ## __VA_ARGS__); } while (0)
29 #else
30 #define DPRINTF(fmt, ...) do {} while(0)
31 #endif
32 
33 #define RECV_BUF (512 - (2 * 8))
34 
35 /* Commands */
36 #define FTDI_RESET		0
37 #define FTDI_SET_MDM_CTRL	1
38 #define FTDI_SET_FLOW_CTRL	2
39 #define FTDI_SET_BAUD		3
40 #define FTDI_SET_DATA		4
41 #define FTDI_GET_MDM_ST		5
42 #define FTDI_SET_EVENT_CHR	6
43 #define FTDI_SET_ERROR_CHR	7
44 #define FTDI_SET_LATENCY	9
45 #define FTDI_GET_LATENCY	10
46 
47 #define DeviceOutVendor	((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
48 #define DeviceInVendor	((USB_DIR_IN |USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
49 
50 /* RESET */
51 
52 #define FTDI_RESET_SIO	0
53 #define FTDI_RESET_RX	1
54 #define FTDI_RESET_TX	2
55 
56 /* SET_MDM_CTRL */
57 
58 #define FTDI_DTR	1
59 #define FTDI_SET_DTR	(FTDI_DTR << 8)
60 #define FTDI_RTS	2
61 #define FTDI_SET_RTS	(FTDI_RTS << 8)
62 
63 /* SET_FLOW_CTRL */
64 
65 #define FTDI_RTS_CTS_HS		1
66 #define FTDI_DTR_DSR_HS		2
67 #define FTDI_XON_XOFF_HS	4
68 
69 /* SET_DATA */
70 
71 #define FTDI_PARITY	(0x7 << 8)
72 #define FTDI_ODD	(0x1 << 8)
73 #define FTDI_EVEN	(0x2 << 8)
74 #define FTDI_MARK	(0x3 << 8)
75 #define FTDI_SPACE	(0x4 << 8)
76 
77 #define FTDI_STOP	(0x3 << 11)
78 #define FTDI_STOP1	(0x0 << 11)
79 #define FTDI_STOP15	(0x1 << 11)
80 #define FTDI_STOP2	(0x2 << 11)
81 
82 /* GET_MDM_ST */
83 /* TODO: should be sent every 40ms */
84 #define FTDI_CTS  (1<<4)        // CTS line status
85 #define FTDI_DSR  (1<<5)        // DSR line status
86 #define FTDI_RI   (1<<6)        // RI line status
87 #define FTDI_RLSD (1<<7)        // Receive Line Signal Detect
88 
89 /* Status */
90 
91 #define FTDI_DR   (1<<0)        // Data Ready
92 #define FTDI_OE   (1<<1)        // Overrun Err
93 #define FTDI_PE   (1<<2)        // Parity Err
94 #define FTDI_FE   (1<<3)        // Framing Err
95 #define FTDI_BI   (1<<4)        // Break Interrupt
96 #define FTDI_THRE (1<<5)        // Transmitter Holding Register
97 #define FTDI_TEMT (1<<6)        // Transmitter Empty
98 #define FTDI_FIFO (1<<7)        // Error in FIFO
99 
100 struct USBSerialState {
101     USBDevice dev;
102     USBEndpoint *intr;
103     uint8_t recv_buf[RECV_BUF];
104     uint16_t recv_ptr;
105     uint16_t recv_used;
106     uint8_t event_chr;
107     uint8_t error_chr;
108     uint8_t event_trigger;
109     QEMUSerialSetParams params;
110     int latency;        /* ms */
111     CharBackend cs;
112 };
113 
114 #define TYPE_USB_SERIAL "usb-serial-dev"
115 OBJECT_DECLARE_SIMPLE_TYPE(USBSerialState, USB_SERIAL)
116 
117 enum {
118     STR_MANUFACTURER = 1,
119     STR_PRODUCT_SERIAL,
120     STR_PRODUCT_BRAILLE,
121     STR_SERIALNUMBER,
122 };
123 
124 static const USBDescStrings desc_strings = {
125     [STR_MANUFACTURER]    = "QEMU",
126     [STR_PRODUCT_SERIAL]  = "QEMU USB SERIAL",
127     [STR_PRODUCT_BRAILLE] = "QEMU USB BAUM BRAILLE",
128     [STR_SERIALNUMBER]    = "1",
129 };
130 
131 static const USBDescIface desc_iface0 = {
132     .bInterfaceNumber              = 0,
133     .bNumEndpoints                 = 2,
134     .bInterfaceClass               = 0xff,
135     .bInterfaceSubClass            = 0xff,
136     .bInterfaceProtocol            = 0xff,
137     .eps = (USBDescEndpoint[]) {
138         {
139             .bEndpointAddress      = USB_DIR_IN | 0x01,
140             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
141             .wMaxPacketSize        = 64,
142         },{
143             .bEndpointAddress      = USB_DIR_OUT | 0x02,
144             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
145             .wMaxPacketSize        = 64,
146         },
147     }
148 };
149 
150 static const USBDescDevice desc_device = {
151     .bcdUSB                        = 0x0200,
152     .bMaxPacketSize0               = 8,
153     .bNumConfigurations            = 1,
154     .confs = (USBDescConfig[]) {
155         {
156             .bNumInterfaces        = 1,
157             .bConfigurationValue   = 1,
158             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_WAKEUP,
159             .bMaxPower             = 50,
160             .nif = 1,
161             .ifs = &desc_iface0,
162         },
163     },
164 };
165 
166 static const USBDesc desc_serial = {
167     .id = {
168         .idVendor          = 0x0403,
169         .idProduct         = 0x6001,
170         .bcdDevice         = 0x0400,
171         .iManufacturer     = STR_MANUFACTURER,
172         .iProduct          = STR_PRODUCT_SERIAL,
173         .iSerialNumber     = STR_SERIALNUMBER,
174     },
175     .full = &desc_device,
176     .str  = desc_strings,
177 };
178 
179 static const USBDesc desc_braille = {
180     .id = {
181         .idVendor          = 0x0403,
182         .idProduct         = 0xfe72,
183         .bcdDevice         = 0x0400,
184         .iManufacturer     = STR_MANUFACTURER,
185         .iProduct          = STR_PRODUCT_BRAILLE,
186         .iSerialNumber     = STR_SERIALNUMBER,
187     },
188     .full = &desc_device,
189     .str  = desc_strings,
190 };
191 
192 static void usb_serial_reset(USBSerialState *s)
193 {
194     /* TODO: Set flow control to none */
195     s->event_chr = 0x0d;
196     s->event_trigger = 0;
197     s->recv_ptr = 0;
198     s->recv_used = 0;
199     /* TODO: purge in char driver */
200 }
201 
202 static void usb_serial_handle_reset(USBDevice *dev)
203 {
204     USBSerialState *s = (USBSerialState *)dev;
205 
206     DPRINTF("Reset\n");
207 
208     usb_serial_reset(s);
209     /* TODO: Reset char device, send BREAK? */
210 }
211 
212 static uint8_t usb_get_modem_lines(USBSerialState *s)
213 {
214     int flags;
215     uint8_t ret;
216 
217     if (qemu_chr_fe_ioctl(&s->cs,
218                           CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
219         return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
220     }
221 
222     ret = 0;
223     if (flags & CHR_TIOCM_CTS)
224         ret |= FTDI_CTS;
225     if (flags & CHR_TIOCM_DSR)
226         ret |= FTDI_DSR;
227     if (flags & CHR_TIOCM_RI)
228         ret |= FTDI_RI;
229     if (flags & CHR_TIOCM_CAR)
230         ret |= FTDI_RLSD;
231 
232     return ret;
233 }
234 
235 static void usb_serial_handle_control(USBDevice *dev, USBPacket *p,
236                int request, int value, int index, int length, uint8_t *data)
237 {
238     USBSerialState *s = (USBSerialState *)dev;
239     int ret;
240 
241     DPRINTF("got control %x, value %x\n",request, value);
242     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
243     if (ret >= 0) {
244         return;
245     }
246 
247     switch (request) {
248     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
249         break;
250 
251         /* Class specific requests.  */
252     case DeviceOutVendor | FTDI_RESET:
253         switch (value) {
254         case FTDI_RESET_SIO:
255             usb_serial_reset(s);
256             break;
257         case FTDI_RESET_RX:
258             s->recv_ptr = 0;
259             s->recv_used = 0;
260             /* TODO: purge from char device */
261             break;
262         case FTDI_RESET_TX:
263             /* TODO: purge from char device */
264             break;
265         }
266         break;
267     case DeviceOutVendor | FTDI_SET_MDM_CTRL:
268     {
269         static int flags;
270         qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
271         if (value & FTDI_SET_RTS) {
272             if (value & FTDI_RTS)
273                 flags |= CHR_TIOCM_RTS;
274             else
275                 flags &= ~CHR_TIOCM_RTS;
276         }
277         if (value & FTDI_SET_DTR) {
278             if (value & FTDI_DTR)
279                 flags |= CHR_TIOCM_DTR;
280             else
281                 flags &= ~CHR_TIOCM_DTR;
282         }
283         qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
284         break;
285     }
286     case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
287         /* TODO: ioctl */
288         break;
289     case DeviceOutVendor | FTDI_SET_BAUD: {
290         static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
291         int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
292                                      | ((index & 1) << 2)];
293         int divisor = value & 0x3fff;
294 
295         /* chip special cases */
296         if (divisor == 1 && subdivisor8 == 0)
297             subdivisor8 = 4;
298         if (divisor == 0 && subdivisor8 == 0)
299             divisor = 1;
300 
301         s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
302         qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
303         break;
304     }
305     case DeviceOutVendor | FTDI_SET_DATA:
306         switch (value & FTDI_PARITY) {
307             case 0:
308                 s->params.parity = 'N';
309                 break;
310             case FTDI_ODD:
311                 s->params.parity = 'O';
312                 break;
313             case FTDI_EVEN:
314                 s->params.parity = 'E';
315                 break;
316             default:
317                 DPRINTF("unsupported parity %d\n", value & FTDI_PARITY);
318                 goto fail;
319         }
320         switch (value & FTDI_STOP) {
321             case FTDI_STOP1:
322                 s->params.stop_bits = 1;
323                 break;
324             case FTDI_STOP2:
325                 s->params.stop_bits = 2;
326                 break;
327             default:
328                 DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
329                 goto fail;
330         }
331         qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
332         /* TODO: TX ON/OFF */
333         break;
334     case DeviceInVendor | FTDI_GET_MDM_ST:
335         data[0] = usb_get_modem_lines(s) | 1;
336         data[1] = FTDI_THRE | FTDI_TEMT;
337         p->actual_length = 2;
338         break;
339     case DeviceOutVendor | FTDI_SET_EVENT_CHR:
340         /* TODO: handle it */
341         s->event_chr = value;
342         break;
343     case DeviceOutVendor | FTDI_SET_ERROR_CHR:
344         /* TODO: handle it */
345         s->error_chr = value;
346         break;
347     case DeviceOutVendor | FTDI_SET_LATENCY:
348         s->latency = value;
349         break;
350     case DeviceInVendor | FTDI_GET_LATENCY:
351         data[0] = s->latency;
352         p->actual_length = 1;
353         break;
354     default:
355     fail:
356         DPRINTF("got unsupported/bogus control %x, value %x\n", request, value);
357         p->status = USB_RET_STALL;
358         break;
359     }
360 }
361 
362 static void usb_serial_token_in(USBSerialState *s, USBPacket *p)
363 {
364     const int max_packet_size = desc_iface0.eps[0].wMaxPacketSize;
365     int packet_len;
366     uint8_t header[2];
367 
368     packet_len = p->iov.size;
369     if (packet_len <= 2) {
370         p->status = USB_RET_NAK;
371         return;
372     }
373 
374     header[0] = usb_get_modem_lines(s) | 1;
375     /* We do not have the uart details */
376     /* handle serial break */
377     if (s->event_trigger && s->event_trigger & FTDI_BI) {
378         s->event_trigger &= ~FTDI_BI;
379         header[1] = FTDI_BI;
380         usb_packet_copy(p, header, 2);
381         return;
382     } else {
383         header[1] = 0;
384     }
385 
386     if (!s->recv_used) {
387         p->status = USB_RET_NAK;
388         return;
389     }
390 
391     while (s->recv_used && packet_len > 2) {
392         int first_len, len;
393 
394         len = MIN(packet_len, max_packet_size);
395         len -= 2;
396         if (len > s->recv_used) {
397             len = s->recv_used;
398         }
399 
400         first_len = RECV_BUF - s->recv_ptr;
401         if (first_len > len) {
402             first_len = len;
403         }
404         usb_packet_copy(p, header, 2);
405         usb_packet_copy(p, s->recv_buf + s->recv_ptr, first_len);
406         if (len > first_len) {
407             usb_packet_copy(p, s->recv_buf, len - first_len);
408         }
409         s->recv_used -= len;
410         s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;
411         packet_len -= len + 2;
412     }
413 
414     return;
415 }
416 
417 static void usb_serial_handle_data(USBDevice *dev, USBPacket *p)
418 {
419     USBSerialState *s = (USBSerialState *)dev;
420     uint8_t devep = p->ep->nr;
421     struct iovec *iov;
422     int i;
423 
424     switch (p->pid) {
425     case USB_TOKEN_OUT:
426         if (devep != 2)
427             goto fail;
428         for (i = 0; i < p->iov.niov; i++) {
429             iov = p->iov.iov + i;
430             /* XXX this blocks entire thread. Rewrite to use
431              * qemu_chr_fe_write and background I/O callbacks */
432             qemu_chr_fe_write_all(&s->cs, iov->iov_base, iov->iov_len);
433         }
434         p->actual_length = p->iov.size;
435         break;
436 
437     case USB_TOKEN_IN:
438         if (devep != 1)
439             goto fail;
440         usb_serial_token_in(s, p);
441         break;
442 
443     default:
444         DPRINTF("Bad token\n");
445     fail:
446         p->status = USB_RET_STALL;
447         break;
448     }
449 }
450 
451 static int usb_serial_can_read(void *opaque)
452 {
453     USBSerialState *s = opaque;
454 
455     if (!s->dev.attached) {
456         return 0;
457     }
458     return RECV_BUF - s->recv_used;
459 }
460 
461 static void usb_serial_read(void *opaque, const uint8_t *buf, int size)
462 {
463     USBSerialState *s = opaque;
464     int first_size, start;
465 
466     /* room in the buffer? */
467     if (size > (RECV_BUF - s->recv_used))
468         size = RECV_BUF - s->recv_used;
469 
470     start = s->recv_ptr + s->recv_used;
471     if (start < RECV_BUF) {
472         /* copy data to end of buffer */
473         first_size = RECV_BUF - start;
474         if (first_size > size)
475             first_size = size;
476 
477         memcpy(s->recv_buf + start, buf, first_size);
478 
479         /* wrap around to front if needed */
480         if (size > first_size)
481             memcpy(s->recv_buf, buf + first_size, size - first_size);
482     } else {
483         start -= RECV_BUF;
484         memcpy(s->recv_buf + start, buf, size);
485     }
486     s->recv_used += size;
487 
488     usb_wakeup(s->intr, 0);
489 }
490 
491 static void usb_serial_event(void *opaque, QEMUChrEvent event)
492 {
493     USBSerialState *s = opaque;
494 
495     switch (event) {
496         case CHR_EVENT_BREAK:
497             s->event_trigger |= FTDI_BI;
498             break;
499         case CHR_EVENT_OPENED:
500             if (!s->dev.attached) {
501                 usb_device_attach(&s->dev, &error_abort);
502             }
503             break;
504         case CHR_EVENT_CLOSED:
505             if (s->dev.attached) {
506                 usb_device_detach(&s->dev);
507             }
508             break;
509         case CHR_EVENT_MUX_IN:
510         case CHR_EVENT_MUX_OUT:
511             /* Ignore */
512             break;
513     }
514 }
515 
516 static void usb_serial_realize(USBDevice *dev, Error **errp)
517 {
518     USBSerialState *s = USB_SERIAL(dev);
519     Error *local_err = NULL;
520 
521     usb_desc_create_serial(dev);
522     usb_desc_init(dev);
523     dev->auto_attach = 0;
524 
525     if (!qemu_chr_fe_backend_connected(&s->cs)) {
526         error_setg(errp, "Property chardev is required");
527         return;
528     }
529 
530     usb_check_attach(dev, &local_err);
531     if (local_err) {
532         error_propagate(errp, local_err);
533         return;
534     }
535 
536     qemu_chr_fe_set_handlers(&s->cs, usb_serial_can_read, usb_serial_read,
537                              usb_serial_event, NULL, s, NULL, true);
538     usb_serial_handle_reset(dev);
539 
540     if (qemu_chr_fe_backend_open(&s->cs) && !dev->attached) {
541         usb_device_attach(dev, &error_abort);
542     }
543     s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
544 }
545 
546 static USBDevice *usb_braille_init(const char *unused)
547 {
548     USBDevice *dev;
549     Chardev *cdrv;
550 
551     cdrv = qemu_chr_new("braille", "braille", NULL);
552     if (!cdrv)
553         return NULL;
554 
555     dev = usb_new("usb-braille");
556     qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
557     return dev;
558 }
559 
560 static const VMStateDescription vmstate_usb_serial = {
561     .name = "usb-serial",
562     .unmigratable = 1,
563 };
564 
565 static Property serial_properties[] = {
566     DEFINE_PROP_CHR("chardev", USBSerialState, cs),
567     DEFINE_PROP_END_OF_LIST(),
568 };
569 
570 static void usb_serial_dev_class_init(ObjectClass *klass, void *data)
571 {
572     DeviceClass *dc = DEVICE_CLASS(klass);
573     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
574 
575     uc->realize        = usb_serial_realize;
576     uc->handle_reset   = usb_serial_handle_reset;
577     uc->handle_control = usb_serial_handle_control;
578     uc->handle_data    = usb_serial_handle_data;
579     dc->vmsd = &vmstate_usb_serial;
580     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
581 }
582 
583 static const TypeInfo usb_serial_dev_type_info = {
584     .name = TYPE_USB_SERIAL,
585     .parent = TYPE_USB_DEVICE,
586     .instance_size = sizeof(USBSerialState),
587     .abstract = true,
588     .class_init = usb_serial_dev_class_init,
589 };
590 
591 static void usb_serial_class_initfn(ObjectClass *klass, void *data)
592 {
593     DeviceClass *dc = DEVICE_CLASS(klass);
594     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
595 
596     uc->product_desc   = "QEMU USB Serial";
597     uc->usb_desc       = &desc_serial;
598     device_class_set_props(dc, serial_properties);
599 }
600 
601 static const TypeInfo serial_info = {
602     .name          = "usb-serial",
603     .parent        = TYPE_USB_SERIAL,
604     .class_init    = usb_serial_class_initfn,
605 };
606 
607 static Property braille_properties[] = {
608     DEFINE_PROP_CHR("chardev", USBSerialState, cs),
609     DEFINE_PROP_END_OF_LIST(),
610 };
611 
612 static void usb_braille_class_initfn(ObjectClass *klass, void *data)
613 {
614     DeviceClass *dc = DEVICE_CLASS(klass);
615     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
616 
617     uc->product_desc   = "QEMU USB Braille";
618     uc->usb_desc       = &desc_braille;
619     device_class_set_props(dc, braille_properties);
620 }
621 
622 static const TypeInfo braille_info = {
623     .name          = "usb-braille",
624     .parent        = TYPE_USB_SERIAL,
625     .class_init    = usb_braille_class_initfn,
626 };
627 
628 static void usb_serial_register_types(void)
629 {
630     type_register_static(&usb_serial_dev_type_info);
631     type_register_static(&serial_info);
632     type_register_static(&braille_info);
633     usb_legacy_register("usb-braille", "braille", usb_braille_init);
634 }
635 
636 type_init(usb_serial_register_types)
637