dev-serial.c (19544B)
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/qdev-properties-system.h" 18#include "hw/usb.h" 19#include "migration/vmstate.h" 20#include "desc.h" 21#include "chardev/char-serial.h" 22#include "chardev/char-fe.h" 23#include "qom/object.h" 24#include "trace.h" 25 26 27#define RECV_BUF (512 - (2 * 8)) 28 29/* Commands */ 30#define FTDI_RESET 0 31#define FTDI_SET_MDM_CTRL 1 32#define FTDI_SET_FLOW_CTRL 2 33#define FTDI_SET_BAUD 3 34#define FTDI_SET_DATA 4 35#define FTDI_GET_MDM_ST 5 36#define FTDI_SET_EVENT_CHR 6 37#define FTDI_SET_ERROR_CHR 7 38#define FTDI_SET_LATENCY 9 39#define FTDI_GET_LATENCY 10 40 41/* RESET */ 42 43#define FTDI_RESET_SIO 0 44#define FTDI_RESET_RX 1 45#define FTDI_RESET_TX 2 46 47/* SET_MDM_CTRL */ 48 49#define FTDI_DTR 1 50#define FTDI_SET_DTR (FTDI_DTR << 8) 51#define FTDI_RTS 2 52#define FTDI_SET_RTS (FTDI_RTS << 8) 53 54/* SET_FLOW_CTRL */ 55 56#define FTDI_NO_HS 0 57#define FTDI_RTS_CTS_HS 1 58#define FTDI_DTR_DSR_HS 2 59#define FTDI_XON_XOFF_HS 4 60 61/* SET_DATA */ 62 63#define FTDI_PARITY (0x7 << 8) 64#define FTDI_ODD (0x1 << 8) 65#define FTDI_EVEN (0x2 << 8) 66#define FTDI_MARK (0x3 << 8) 67#define FTDI_SPACE (0x4 << 8) 68 69#define FTDI_STOP (0x3 << 11) 70#define FTDI_STOP1 (0x0 << 11) 71#define FTDI_STOP15 (0x1 << 11) 72#define FTDI_STOP2 (0x2 << 11) 73 74/* GET_MDM_ST */ 75/* TODO: should be sent every 40ms */ 76#define FTDI_CTS (1 << 4) /* CTS line status */ 77#define FTDI_DSR (1 << 5) /* DSR line status */ 78#define FTDI_RI (1 << 6) /* RI line status */ 79#define FTDI_RLSD (1 << 7) /* Receive Line Signal Detect */ 80 81/* Status */ 82 83#define FTDI_DR (1 << 0) /* Data Ready */ 84#define FTDI_OE (1 << 1) /* Overrun Err */ 85#define FTDI_PE (1 << 2) /* Parity Err */ 86#define FTDI_FE (1 << 3) /* Framing Err */ 87#define FTDI_BI (1 << 4) /* Break Interrupt */ 88#define FTDI_THRE (1 << 5) /* Transmitter Holding Register */ 89#define FTDI_TEMT (1 << 6) /* Transmitter Empty */ 90#define FTDI_FIFO (1 << 7) /* Error in FIFO */ 91 92struct USBSerialState { 93 USBDevice dev; 94 95 USBEndpoint *intr; 96 uint8_t recv_buf[RECV_BUF]; 97 uint16_t recv_ptr; 98 uint16_t recv_used; 99 uint8_t event_chr; 100 uint8_t error_chr; 101 uint8_t event_trigger; 102 bool always_plugged; 103 uint8_t flow_control; 104 uint8_t xon; 105 uint8_t xoff; 106 QEMUSerialSetParams params; 107 int latency; /* ms */ 108 CharBackend cs; 109}; 110 111#define TYPE_USB_SERIAL "usb-serial-dev" 112OBJECT_DECLARE_SIMPLE_TYPE(USBSerialState, USB_SERIAL) 113 114enum { 115 STR_MANUFACTURER = 1, 116 STR_PRODUCT_SERIAL, 117 STR_PRODUCT_BRAILLE, 118 STR_SERIALNUMBER, 119}; 120 121static 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 128static 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 147static 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 | USB_CFG_ATT_WAKEUP, 156 .bMaxPower = 50, 157 .nif = 1, 158 .ifs = &desc_iface0, 159 }, 160 }, 161}; 162 163static 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 176static 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 189static void usb_serial_set_flow_control(USBSerialState *s, 190 uint8_t flow_control) 191{ 192 USBDevice *dev = USB_DEVICE(s); 193 USBBus *bus = usb_bus_from_device(dev); 194 195 /* TODO: ioctl */ 196 s->flow_control = flow_control; 197 trace_usb_serial_set_flow_control(bus->busnr, dev->addr, flow_control); 198} 199 200static void usb_serial_set_xonxoff(USBSerialState *s, int xonxoff) 201{ 202 USBDevice *dev = USB_DEVICE(s); 203 USBBus *bus = usb_bus_from_device(dev); 204 205 s->xon = xonxoff & 0xff; 206 s->xoff = (xonxoff >> 8) & 0xff; 207 208 trace_usb_serial_set_xonxoff(bus->busnr, dev->addr, s->xon, s->xoff); 209} 210 211static void usb_serial_reset(USBSerialState *s) 212{ 213 s->event_chr = 0x0d; 214 s->event_trigger = 0; 215 s->recv_ptr = 0; 216 s->recv_used = 0; 217 /* TODO: purge in char driver */ 218 usb_serial_set_flow_control(s, FTDI_NO_HS); 219} 220 221static void usb_serial_handle_reset(USBDevice *dev) 222{ 223 USBSerialState *s = USB_SERIAL(dev); 224 USBBus *bus = usb_bus_from_device(dev); 225 226 trace_usb_serial_reset(bus->busnr, dev->addr); 227 228 usb_serial_reset(s); 229 /* TODO: Reset char device, send BREAK? */ 230} 231 232static uint8_t usb_get_modem_lines(USBSerialState *s) 233{ 234 int flags; 235 uint8_t ret; 236 237 if (qemu_chr_fe_ioctl(&s->cs, 238 CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) { 239 return FTDI_CTS | FTDI_DSR | FTDI_RLSD; 240 } 241 242 ret = 0; 243 if (flags & CHR_TIOCM_CTS) { 244 ret |= FTDI_CTS; 245 } 246 if (flags & CHR_TIOCM_DSR) { 247 ret |= FTDI_DSR; 248 } 249 if (flags & CHR_TIOCM_RI) { 250 ret |= FTDI_RI; 251 } 252 if (flags & CHR_TIOCM_CAR) { 253 ret |= FTDI_RLSD; 254 } 255 256 return ret; 257} 258 259static void usb_serial_handle_control(USBDevice *dev, USBPacket *p, 260 int request, int value, int index, 261 int length, uint8_t *data) 262{ 263 USBSerialState *s = USB_SERIAL(dev); 264 USBBus *bus = usb_bus_from_device(dev); 265 int ret; 266 267 trace_usb_serial_handle_control(bus->busnr, dev->addr, request, value); 268 269 ret = usb_desc_handle_control(dev, p, request, value, index, length, data); 270 if (ret >= 0) { 271 return; 272 } 273 274 switch (request) { 275 case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: 276 break; 277 278 /* Class specific requests. */ 279 case VendorDeviceOutRequest | FTDI_RESET: 280 switch (value) { 281 case FTDI_RESET_SIO: 282 usb_serial_reset(s); 283 break; 284 case FTDI_RESET_RX: 285 s->recv_ptr = 0; 286 s->recv_used = 0; 287 /* TODO: purge from char device */ 288 break; 289 case FTDI_RESET_TX: 290 /* TODO: purge from char device */ 291 break; 292 } 293 break; 294 case VendorDeviceOutRequest | FTDI_SET_MDM_CTRL: 295 { 296 static int flags; 297 qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags); 298 if (value & FTDI_SET_RTS) { 299 if (value & FTDI_RTS) { 300 flags |= CHR_TIOCM_RTS; 301 } else { 302 flags &= ~CHR_TIOCM_RTS; 303 } 304 } 305 if (value & FTDI_SET_DTR) { 306 if (value & FTDI_DTR) { 307 flags |= CHR_TIOCM_DTR; 308 } else { 309 flags &= ~CHR_TIOCM_DTR; 310 } 311 } 312 qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_TIOCM, &flags); 313 break; 314 } 315 case VendorDeviceOutRequest | FTDI_SET_FLOW_CTRL: { 316 uint8_t flow_control = index >> 8; 317 318 usb_serial_set_flow_control(s, flow_control); 319 if (flow_control & FTDI_XON_XOFF_HS) { 320 usb_serial_set_xonxoff(s, value); 321 } 322 break; 323 } 324 case VendorDeviceOutRequest | FTDI_SET_BAUD: { 325 static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 }; 326 int subdivisor8 = subdivisors8[((value & 0xc000) >> 14) 327 | ((index & 1) << 2)]; 328 int divisor = value & 0x3fff; 329 330 /* chip special cases */ 331 if (divisor == 1 && subdivisor8 == 0) { 332 subdivisor8 = 4; 333 } 334 if (divisor == 0 && subdivisor8 == 0) { 335 divisor = 1; 336 } 337 338 s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8); 339 trace_usb_serial_set_baud(bus->busnr, dev->addr, s->params.speed); 340 qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); 341 break; 342 } 343 case VendorDeviceOutRequest | FTDI_SET_DATA: 344 switch (value & 0xff) { 345 case 7: 346 s->params.data_bits = 7; 347 break; 348 case 8: 349 s->params.data_bits = 8; 350 break; 351 default: 352 /* 353 * According to a comment in Linux's ftdi_sio.c original FTDI 354 * chips fall back to 8 data bits for unsupported data_bits 355 */ 356 trace_usb_serial_unsupported_data_bits(bus->busnr, dev->addr, 357 value & 0xff); 358 s->params.data_bits = 8; 359 } 360 361 switch (value & FTDI_PARITY) { 362 case 0: 363 s->params.parity = 'N'; 364 break; 365 case FTDI_ODD: 366 s->params.parity = 'O'; 367 break; 368 case FTDI_EVEN: 369 s->params.parity = 'E'; 370 break; 371 default: 372 trace_usb_serial_unsupported_parity(bus->busnr, dev->addr, 373 value & FTDI_PARITY); 374 goto fail; 375 } 376 377 switch (value & FTDI_STOP) { 378 case FTDI_STOP1: 379 s->params.stop_bits = 1; 380 break; 381 case FTDI_STOP2: 382 s->params.stop_bits = 2; 383 break; 384 default: 385 trace_usb_serial_unsupported_stopbits(bus->busnr, dev->addr, 386 value & FTDI_STOP); 387 goto fail; 388 } 389 390 trace_usb_serial_set_data(bus->busnr, dev->addr, s->params.parity, 391 s->params.data_bits, s->params.stop_bits); 392 qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params); 393 /* TODO: TX ON/OFF */ 394 break; 395 case VendorDeviceRequest | FTDI_GET_MDM_ST: 396 data[0] = usb_get_modem_lines(s) | 1; 397 data[1] = FTDI_THRE | FTDI_TEMT; 398 p->actual_length = 2; 399 break; 400 case VendorDeviceOutRequest | FTDI_SET_EVENT_CHR: 401 /* TODO: handle it */ 402 s->event_chr = value; 403 break; 404 case VendorDeviceOutRequest | FTDI_SET_ERROR_CHR: 405 /* TODO: handle it */ 406 s->error_chr = value; 407 break; 408 case VendorDeviceOutRequest | FTDI_SET_LATENCY: 409 s->latency = value; 410 break; 411 case VendorDeviceRequest | FTDI_GET_LATENCY: 412 data[0] = s->latency; 413 p->actual_length = 1; 414 break; 415 default: 416 fail: 417 trace_usb_serial_unsupported_control(bus->busnr, dev->addr, request, 418 value); 419 p->status = USB_RET_STALL; 420 break; 421 } 422} 423 424static void usb_serial_token_in(USBSerialState *s, USBPacket *p) 425{ 426 const int max_packet_size = desc_iface0.eps[0].wMaxPacketSize; 427 int packet_len; 428 uint8_t header[2]; 429 430 packet_len = p->iov.size; 431 if (packet_len <= 2) { 432 p->status = USB_RET_NAK; 433 return; 434 } 435 436 header[0] = usb_get_modem_lines(s) | 1; 437 /* We do not have the uart details */ 438 /* handle serial break */ 439 if (s->event_trigger && s->event_trigger & FTDI_BI) { 440 s->event_trigger &= ~FTDI_BI; 441 header[1] = FTDI_BI; 442 usb_packet_copy(p, header, 2); 443 return; 444 } else { 445 header[1] = 0; 446 } 447 448 if (!s->recv_used) { 449 p->status = USB_RET_NAK; 450 return; 451 } 452 453 while (s->recv_used && packet_len > 2) { 454 int first_len, len; 455 456 len = MIN(packet_len, max_packet_size); 457 len -= 2; 458 if (len > s->recv_used) { 459 len = s->recv_used; 460 } 461 462 first_len = RECV_BUF - s->recv_ptr; 463 if (first_len > len) { 464 first_len = len; 465 } 466 usb_packet_copy(p, header, 2); 467 usb_packet_copy(p, s->recv_buf + s->recv_ptr, first_len); 468 if (len > first_len) { 469 usb_packet_copy(p, s->recv_buf, len - first_len); 470 } 471 s->recv_used -= len; 472 s->recv_ptr = (s->recv_ptr + len) % RECV_BUF; 473 packet_len -= len + 2; 474 } 475 476 return; 477} 478 479static void usb_serial_handle_data(USBDevice *dev, USBPacket *p) 480{ 481 USBSerialState *s = USB_SERIAL(dev); 482 USBBus *bus = usb_bus_from_device(dev); 483 uint8_t devep = p->ep->nr; 484 struct iovec *iov; 485 int i; 486 487 switch (p->pid) { 488 case USB_TOKEN_OUT: 489 if (devep != 2) { 490 goto fail; 491 } 492 for (i = 0; i < p->iov.niov; i++) { 493 iov = p->iov.iov + i; 494 /* 495 * XXX this blocks entire thread. Rewrite to use 496 * qemu_chr_fe_write and background I/O callbacks 497 */ 498 qemu_chr_fe_write_all(&s->cs, iov->iov_base, iov->iov_len); 499 } 500 p->actual_length = p->iov.size; 501 break; 502 503 case USB_TOKEN_IN: 504 if (devep != 1) { 505 goto fail; 506 } 507 usb_serial_token_in(s, p); 508 break; 509 510 default: 511 trace_usb_serial_bad_token(bus->busnr, dev->addr); 512 fail: 513 p->status = USB_RET_STALL; 514 break; 515 } 516} 517 518static int usb_serial_can_read(void *opaque) 519{ 520 USBSerialState *s = opaque; 521 522 if (!s->dev.attached) { 523 return 0; 524 } 525 return RECV_BUF - s->recv_used; 526} 527 528static void usb_serial_read(void *opaque, const uint8_t *buf, int size) 529{ 530 USBSerialState *s = opaque; 531 int first_size, start; 532 533 /* room in the buffer? */ 534 if (size > (RECV_BUF - s->recv_used)) { 535 size = RECV_BUF - s->recv_used; 536 } 537 538 start = s->recv_ptr + s->recv_used; 539 if (start < RECV_BUF) { 540 /* copy data to end of buffer */ 541 first_size = RECV_BUF - start; 542 if (first_size > size) { 543 first_size = size; 544 } 545 546 memcpy(s->recv_buf + start, buf, first_size); 547 548 /* wrap around to front if needed */ 549 if (size > first_size) { 550 memcpy(s->recv_buf, buf + first_size, size - first_size); 551 } 552 } else { 553 start -= RECV_BUF; 554 memcpy(s->recv_buf + start, buf, size); 555 } 556 s->recv_used += size; 557 558 usb_wakeup(s->intr, 0); 559} 560 561static void usb_serial_event(void *opaque, QEMUChrEvent event) 562{ 563 USBSerialState *s = opaque; 564 565 switch (event) { 566 case CHR_EVENT_BREAK: 567 s->event_trigger |= FTDI_BI; 568 break; 569 case CHR_EVENT_OPENED: 570 if (!s->always_plugged && !s->dev.attached) { 571 usb_device_attach(&s->dev, &error_abort); 572 } 573 break; 574 case CHR_EVENT_CLOSED: 575 if (!s->always_plugged && s->dev.attached) { 576 usb_device_detach(&s->dev); 577 } 578 break; 579 case CHR_EVENT_MUX_IN: 580 case CHR_EVENT_MUX_OUT: 581 /* Ignore */ 582 break; 583 } 584} 585 586static void usb_serial_realize(USBDevice *dev, Error **errp) 587{ 588 USBSerialState *s = USB_SERIAL(dev); 589 Error *local_err = NULL; 590 591 usb_desc_create_serial(dev); 592 usb_desc_init(dev); 593 dev->auto_attach = 0; 594 595 if (!qemu_chr_fe_backend_connected(&s->cs)) { 596 error_setg(errp, "Property chardev is required"); 597 return; 598 } 599 600 usb_check_attach(dev, &local_err); 601 if (local_err) { 602 error_propagate(errp, local_err); 603 return; 604 } 605 606 qemu_chr_fe_set_handlers(&s->cs, usb_serial_can_read, usb_serial_read, 607 usb_serial_event, NULL, s, NULL, true); 608 usb_serial_handle_reset(dev); 609 610 if ((s->always_plugged || qemu_chr_fe_backend_open(&s->cs)) && 611 !dev->attached) { 612 usb_device_attach(dev, &error_abort); 613 } 614 s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); 615} 616 617static USBDevice *usb_braille_init(void) 618{ 619 USBDevice *dev; 620 Chardev *cdrv; 621 622 cdrv = qemu_chr_new("braille", "braille", NULL); 623 if (!cdrv) { 624 return NULL; 625 } 626 627 dev = usb_new("usb-braille"); 628 qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); 629 return dev; 630} 631 632static const VMStateDescription vmstate_usb_serial = { 633 .name = "usb-serial", 634 .unmigratable = 1, 635}; 636 637static Property serial_properties[] = { 638 DEFINE_PROP_CHR("chardev", USBSerialState, cs), 639 DEFINE_PROP_BOOL("always-plugged", USBSerialState, always_plugged, false), 640 DEFINE_PROP_END_OF_LIST(), 641}; 642 643static void usb_serial_dev_class_init(ObjectClass *klass, void *data) 644{ 645 DeviceClass *dc = DEVICE_CLASS(klass); 646 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 647 648 uc->realize = usb_serial_realize; 649 uc->handle_reset = usb_serial_handle_reset; 650 uc->handle_control = usb_serial_handle_control; 651 uc->handle_data = usb_serial_handle_data; 652 dc->vmsd = &vmstate_usb_serial; 653 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 654} 655 656static const TypeInfo usb_serial_dev_type_info = { 657 .name = TYPE_USB_SERIAL, 658 .parent = TYPE_USB_DEVICE, 659 .instance_size = sizeof(USBSerialState), 660 .abstract = true, 661 .class_init = usb_serial_dev_class_init, 662}; 663 664static void usb_serial_class_initfn(ObjectClass *klass, void *data) 665{ 666 DeviceClass *dc = DEVICE_CLASS(klass); 667 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 668 669 uc->product_desc = "QEMU USB Serial"; 670 uc->usb_desc = &desc_serial; 671 device_class_set_props(dc, serial_properties); 672} 673 674static const TypeInfo serial_info = { 675 .name = "usb-serial", 676 .parent = TYPE_USB_SERIAL, 677 .class_init = usb_serial_class_initfn, 678}; 679 680static Property braille_properties[] = { 681 DEFINE_PROP_CHR("chardev", USBSerialState, cs), 682 DEFINE_PROP_END_OF_LIST(), 683}; 684 685static void usb_braille_class_initfn(ObjectClass *klass, void *data) 686{ 687 DeviceClass *dc = DEVICE_CLASS(klass); 688 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 689 690 uc->product_desc = "QEMU USB Braille"; 691 uc->usb_desc = &desc_braille; 692 device_class_set_props(dc, braille_properties); 693} 694 695static const TypeInfo braille_info = { 696 .name = "usb-braille", 697 .parent = TYPE_USB_SERIAL, 698 .class_init = usb_braille_class_initfn, 699}; 700 701static void usb_serial_register_types(void) 702{ 703 type_register_static(&usb_serial_dev_type_info); 704 type_register_static(&serial_info); 705 type_register_static(&braille_info); 706 usb_legacy_register("usb-braille", "braille", usb_braille_init); 707} 708 709type_init(usb_serial_register_types)