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