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