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