symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/usb-serial.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 licenced under the LGPL.
       
     9  */
       
    10 
       
    11 #include "qemu-common.h"
       
    12 #include "usb.h"
       
    13 #include "qemu-char.h"
       
    14 
       
    15 //#define DEBUG_Serial
       
    16 
       
    17 #ifdef DEBUG_Serial
       
    18 #define DPRINTF(fmt, args...) \
       
    19 do { printf("usb-serial: " fmt , ##args); } while (0)
       
    20 #else
       
    21 #define DPRINTF(fmt, args...) do {} while(0)
       
    22 #endif
       
    23 
       
    24 #define RECV_BUF 384
       
    25 
       
    26 /* Commands */
       
    27 #define FTDI_RESET		0
       
    28 #define FTDI_SET_MDM_CTRL	1
       
    29 #define FTDI_SET_FLOW_CTRL	2
       
    30 #define FTDI_SET_BAUD		3
       
    31 #define FTDI_SET_DATA		4
       
    32 #define FTDI_GET_MDM_ST		5
       
    33 #define FTDI_SET_EVENT_CHR	6
       
    34 #define FTDI_SET_ERROR_CHR	7
       
    35 #define FTDI_SET_LATENCY	9
       
    36 #define FTDI_GET_LATENCY	10
       
    37 
       
    38 #define DeviceOutVendor	((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
       
    39 #define DeviceInVendor	((USB_DIR_IN |USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8)
       
    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_RTS_CTS_HS		1
       
    57 #define FTDI_DTR_DSR_HS		2
       
    58 #define FTDI_XON_XOFF_HS	4
       
    59 
       
    60 /* SET_DATA */
       
    61 
       
    62 #define FTDI_PARITY	(0x7 << 8)
       
    63 #define FTDI_ODD	(0x1 << 8)
       
    64 #define FTDI_EVEN	(0x2 << 8)
       
    65 #define FTDI_MARK	(0x3 << 8)
       
    66 #define FTDI_SPACE	(0x4 << 8)
       
    67 
       
    68 #define FTDI_STOP	(0x3 << 11)
       
    69 #define FTDI_STOP1	(0x0 << 11)
       
    70 #define FTDI_STOP15	(0x1 << 11)
       
    71 #define FTDI_STOP2	(0x2 << 11)
       
    72 
       
    73 /* GET_MDM_ST */
       
    74 /* TODO: should be sent every 40ms */
       
    75 #define FTDI_CTS  (1<<4)        // CTS line status
       
    76 #define FTDI_DSR  (1<<5)        // DSR line status
       
    77 #define FTDI_RI   (1<<6)        // RI line status
       
    78 #define FTDI_RLSD (1<<7)        // Receive Line Signal Detect
       
    79 
       
    80 /* Status */
       
    81 
       
    82 #define FTDI_DR   (1<<0)        // Data Ready
       
    83 #define FTDI_OE   (1<<1)        // Overrun Err
       
    84 #define FTDI_PE   (1<<2)        // Parity Err
       
    85 #define FTDI_FE   (1<<3)        // Framing Err
       
    86 #define FTDI_BI   (1<<4)        // Break Interrupt
       
    87 #define FTDI_THRE (1<<5)        // Transmitter Holding Register
       
    88 #define FTDI_TEMT (1<<6)        // Transmitter Empty
       
    89 #define FTDI_FIFO (1<<7)        // Error in FIFO
       
    90 
       
    91 typedef struct {
       
    92     USBDevice dev;
       
    93     uint16_t vendorid;
       
    94     uint16_t productid;
       
    95     uint8_t recv_buf[RECV_BUF];
       
    96     uint16_t recv_ptr;
       
    97     uint16_t recv_used;
       
    98     uint8_t event_chr;
       
    99     uint8_t error_chr;
       
   100     uint8_t event_trigger;
       
   101     QEMUSerialSetParams params;
       
   102     int latency;        /* ms */
       
   103     CharDriverState *cs;
       
   104 } USBSerialState;
       
   105 
       
   106 static const uint8_t qemu_serial_dev_descriptor[] = {
       
   107         0x12,       /*  u8 bLength; */
       
   108         0x01,       /*  u8 bDescriptorType; Device */
       
   109         0x00, 0x02, /*  u16 bcdUSB; v2.0 */
       
   110 
       
   111         0x00,       /*  u8  bDeviceClass; */
       
   112         0x00,       /*  u8  bDeviceSubClass; */
       
   113         0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
       
   114         0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
       
   115 
       
   116         /* Vendor and product id are arbitrary.  */
       
   117         0x03, 0x04, /*  u16 idVendor; */
       
   118         0x00, 0xFF, /*  u16 idProduct; */
       
   119         0x00, 0x04, /*  u16 bcdDevice */
       
   120 
       
   121         0x01,       /*  u8  iManufacturer; */
       
   122         0x02,       /*  u8  iProduct; */
       
   123         0x03,       /*  u8  iSerialNumber; */
       
   124         0x01        /*  u8  bNumConfigurations; */
       
   125 };
       
   126 
       
   127 static const uint8_t qemu_serial_config_descriptor[] = {
       
   128 
       
   129         /* one configuration */
       
   130         0x09,       /*  u8  bLength; */
       
   131         0x02,       /*  u8  bDescriptorType; Configuration */
       
   132         0x20, 0x00, /*  u16 wTotalLength; */
       
   133         0x01,       /*  u8  bNumInterfaces; (1) */
       
   134         0x01,       /*  u8  bConfigurationValue; */
       
   135         0x00,       /*  u8  iConfiguration; */
       
   136         0x80,       /*  u8  bmAttributes;
       
   137                                  Bit 7: must be set,
       
   138                                      6: Self-powered,
       
   139                                      5: Remote wakeup,
       
   140                                      4..0: resvd */
       
   141         100/2,       /*  u8  MaxPower; */
       
   142 
       
   143         /* one interface */
       
   144         0x09,       /*  u8  if_bLength; */
       
   145         0x04,       /*  u8  if_bDescriptorType; Interface */
       
   146         0x00,       /*  u8  if_bInterfaceNumber; */
       
   147         0x00,       /*  u8  if_bAlternateSetting; */
       
   148         0x02,       /*  u8  if_bNumEndpoints; */
       
   149         0xff,       /*  u8  if_bInterfaceClass; Vendor Specific */
       
   150         0xff,       /*  u8  if_bInterfaceSubClass; Vendor Specific */
       
   151         0xff,       /*  u8  if_bInterfaceProtocol; Vendor Specific */
       
   152         0x02,       /*  u8  if_iInterface; */
       
   153 
       
   154         /* Bulk-In endpoint */
       
   155         0x07,       /*  u8  ep_bLength; */
       
   156         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
       
   157         0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
       
   158         0x02,       /*  u8  ep_bmAttributes; Bulk */
       
   159         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
       
   160         0x00,       /*  u8  ep_bInterval; */
       
   161 
       
   162         /* Bulk-Out endpoint */
       
   163         0x07,       /*  u8  ep_bLength; */
       
   164         0x05,       /*  u8  ep_bDescriptorType; Endpoint */
       
   165         0x02,       /*  u8  ep_bEndpointAddress; OUT Endpoint 2 */
       
   166         0x02,       /*  u8  ep_bmAttributes; Bulk */
       
   167         0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
       
   168         0x00        /*  u8  ep_bInterval; */
       
   169 };
       
   170 
       
   171 static void usb_serial_reset(USBSerialState *s)
       
   172 {
       
   173     /* TODO: Set flow control to none */
       
   174     s->event_chr = 0x0d;
       
   175     s->event_trigger = 0;
       
   176     s->recv_ptr = 0;
       
   177     s->recv_used = 0;
       
   178     /* TODO: purge in char driver */
       
   179 }
       
   180 
       
   181 static void usb_serial_handle_reset(USBDevice *dev)
       
   182 {
       
   183     USBSerialState *s = (USBSerialState *)dev;
       
   184 
       
   185     DPRINTF("Reset\n");
       
   186 
       
   187     usb_serial_reset(s);
       
   188     /* TODO: Reset char device, send BREAK? */
       
   189 }
       
   190 
       
   191 static uint8_t usb_get_modem_lines(USBSerialState *s)
       
   192 {
       
   193     int flags;
       
   194     uint8_t ret;
       
   195 
       
   196     if (qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP)
       
   197         return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
       
   198 
       
   199     ret = 0;
       
   200     if (flags & CHR_TIOCM_CTS)
       
   201         ret |= FTDI_CTS;
       
   202     if (flags & CHR_TIOCM_DSR)
       
   203         ret |= FTDI_DSR;
       
   204     if (flags & CHR_TIOCM_RI)
       
   205         ret |= FTDI_RI;
       
   206     if (flags & CHR_TIOCM_CAR)
       
   207         ret |= FTDI_RLSD;
       
   208 
       
   209     return ret;
       
   210 }
       
   211 
       
   212 static int usb_serial_handle_control(USBDevice *dev, int request, int value,
       
   213                                   int index, int length, uint8_t *data)
       
   214 {
       
   215     USBSerialState *s = (USBSerialState *)dev;
       
   216     int ret = 0;
       
   217 
       
   218     //DPRINTF("got control %x, value %x\n",request, value);
       
   219     switch (request) {
       
   220     case DeviceRequest | USB_REQ_GET_STATUS:
       
   221         data[0] = (0 << USB_DEVICE_SELF_POWERED) |
       
   222             (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
       
   223         data[1] = 0x00;
       
   224         ret = 2;
       
   225         break;
       
   226     case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
       
   227         if (value == USB_DEVICE_REMOTE_WAKEUP) {
       
   228             dev->remote_wakeup = 0;
       
   229         } else {
       
   230             goto fail;
       
   231         }
       
   232         ret = 0;
       
   233         break;
       
   234     case DeviceOutRequest | USB_REQ_SET_FEATURE:
       
   235         if (value == USB_DEVICE_REMOTE_WAKEUP) {
       
   236             dev->remote_wakeup = 1;
       
   237         } else {
       
   238             goto fail;
       
   239         }
       
   240         ret = 0;
       
   241         break;
       
   242     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
       
   243         dev->addr = value;
       
   244         ret = 0;
       
   245         break;
       
   246     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
       
   247         switch(value >> 8) {
       
   248         case USB_DT_DEVICE:
       
   249             memcpy(data, qemu_serial_dev_descriptor,
       
   250                    sizeof(qemu_serial_dev_descriptor));
       
   251             data[8] = s->vendorid & 0xff;
       
   252             data[9] = ((s->vendorid) >> 8) & 0xff;
       
   253             data[10] = s->productid & 0xff;
       
   254             data[11] = ((s->productid) >> 8) & 0xff;
       
   255             ret = sizeof(qemu_serial_dev_descriptor);
       
   256             break;
       
   257         case USB_DT_CONFIG:
       
   258             memcpy(data, qemu_serial_config_descriptor,
       
   259                    sizeof(qemu_serial_config_descriptor));
       
   260             ret = sizeof(qemu_serial_config_descriptor);
       
   261             break;
       
   262         case USB_DT_STRING:
       
   263             switch(value & 0xff) {
       
   264             case 0:
       
   265                 /* language ids */
       
   266                 data[0] = 4;
       
   267                 data[1] = 3;
       
   268                 data[2] = 0x09;
       
   269                 data[3] = 0x04;
       
   270                 ret = 4;
       
   271                 break;
       
   272             case 1:
       
   273                 /* vendor description */
       
   274                 ret = set_usb_string(data, "QEMU " QEMU_VERSION);
       
   275                 break;
       
   276             case 2:
       
   277                 /* product description */
       
   278                 ret = set_usb_string(data, "QEMU USB SERIAL");
       
   279                 break;
       
   280             case 3:
       
   281                 /* serial number */
       
   282                 ret = set_usb_string(data, "1");
       
   283                 break;
       
   284             default:
       
   285                 goto fail;
       
   286             }
       
   287             break;
       
   288         default:
       
   289             goto fail;
       
   290         }
       
   291         break;
       
   292     case DeviceRequest | USB_REQ_GET_CONFIGURATION:
       
   293         data[0] = 1;
       
   294         ret = 1;
       
   295         break;
       
   296     case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
       
   297         ret = 0;
       
   298         break;
       
   299     case DeviceRequest | USB_REQ_GET_INTERFACE:
       
   300         data[0] = 0;
       
   301         ret = 1;
       
   302         break;
       
   303     case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
       
   304         ret = 0;
       
   305         break;
       
   306     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
       
   307         ret = 0;
       
   308         break;
       
   309 
       
   310         /* Class specific requests.  */
       
   311     case DeviceOutVendor | FTDI_RESET:
       
   312         switch (value) {
       
   313         case FTDI_RESET_SIO:
       
   314             usb_serial_reset(s);
       
   315             break;
       
   316         case FTDI_RESET_RX:
       
   317             s->recv_ptr = 0;
       
   318             s->recv_used = 0;
       
   319             /* TODO: purge from char device */
       
   320             break;
       
   321         case FTDI_RESET_TX:
       
   322             /* TODO: purge from char device */
       
   323             break;
       
   324         }
       
   325         break;
       
   326     case DeviceOutVendor | FTDI_SET_MDM_CTRL:
       
   327     {
       
   328         static int flags;
       
   329         qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
       
   330         if (value & FTDI_SET_RTS) {
       
   331             if (value & FTDI_RTS)
       
   332                 flags |= CHR_TIOCM_RTS;
       
   333             else
       
   334                 flags &= ~CHR_TIOCM_RTS;
       
   335         }
       
   336         if (value & FTDI_SET_DTR) {
       
   337             if (value & FTDI_DTR)
       
   338                 flags |= CHR_TIOCM_DTR;
       
   339             else
       
   340                 flags &= ~CHR_TIOCM_DTR;
       
   341         }
       
   342         qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
       
   343         break;
       
   344     }
       
   345     case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
       
   346         /* TODO: ioctl */
       
   347         break;
       
   348     case DeviceOutVendor | FTDI_SET_BAUD: {
       
   349         static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
       
   350         int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
       
   351                                      | ((index & 1) << 2)];
       
   352         int divisor = value & 0x3fff;
       
   353 
       
   354         /* chip special cases */
       
   355         if (divisor == 1 && subdivisor8 == 0)
       
   356             subdivisor8 = 4;
       
   357         if (divisor == 0 && subdivisor8 == 0)
       
   358             divisor = 1;
       
   359 
       
   360         s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
       
   361         qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
       
   362         break;
       
   363     }
       
   364     case DeviceOutVendor | FTDI_SET_DATA:
       
   365         switch (value & FTDI_PARITY) {
       
   366             case 0:
       
   367                 s->params.parity = 'N';
       
   368                 break;
       
   369             case FTDI_ODD:
       
   370                 s->params.parity = 'O';
       
   371                 break;
       
   372             case FTDI_EVEN:
       
   373                 s->params.parity = 'E';
       
   374                 break;
       
   375             default:
       
   376                 DPRINTF("unsupported parity %d\n", value & FTDI_PARITY);
       
   377                 goto fail;
       
   378         }
       
   379         switch (value & FTDI_STOP) {
       
   380             case FTDI_STOP1:
       
   381                 s->params.stop_bits = 1;
       
   382                 break;
       
   383             case FTDI_STOP2:
       
   384                 s->params.stop_bits = 2;
       
   385                 break;
       
   386             default:
       
   387                 DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
       
   388                 goto fail;
       
   389         }
       
   390         qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
       
   391         /* TODO: TX ON/OFF */
       
   392         break;
       
   393     case DeviceInVendor | FTDI_GET_MDM_ST:
       
   394         data[0] = usb_get_modem_lines(s) | 1;
       
   395         data[1] = 0;
       
   396         ret = 2;
       
   397         break;
       
   398     case DeviceOutVendor | FTDI_SET_EVENT_CHR:
       
   399         /* TODO: handle it */
       
   400         s->event_chr = value;
       
   401         break;
       
   402     case DeviceOutVendor | FTDI_SET_ERROR_CHR:
       
   403         /* TODO: handle it */
       
   404         s->error_chr = value;
       
   405         break;
       
   406     case DeviceOutVendor | FTDI_SET_LATENCY:
       
   407         s->latency = value;
       
   408         break;
       
   409     case DeviceInVendor | FTDI_GET_LATENCY:
       
   410         data[0] = s->latency;
       
   411         ret = 1;
       
   412         break;
       
   413     default:
       
   414     fail:
       
   415         DPRINTF("got unsupported/bogus control %x, value %x\n", request, value);
       
   416         ret = USB_RET_STALL;
       
   417         break;
       
   418     }
       
   419     return ret;
       
   420 }
       
   421 
       
   422 static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
       
   423 {
       
   424     USBSerialState *s = (USBSerialState *)dev;
       
   425     int ret = 0;
       
   426     uint8_t devep = p->devep;
       
   427     uint8_t *data = p->data;
       
   428     int len = p->len;
       
   429     int first_len;
       
   430 
       
   431     switch (p->pid) {
       
   432     case USB_TOKEN_OUT:
       
   433         if (devep != 2)
       
   434             goto fail;
       
   435         qemu_chr_write(s->cs, data, len);
       
   436         break;
       
   437 
       
   438     case USB_TOKEN_IN:
       
   439         if (devep != 1)
       
   440             goto fail;
       
   441         first_len = RECV_BUF - s->recv_ptr;
       
   442         if (len <= 2) {
       
   443             ret = USB_RET_NAK;
       
   444             break;
       
   445         }
       
   446         *data++ = usb_get_modem_lines(s) | 1;
       
   447         /* We do not have the uart details */
       
   448         *data++ = 0;
       
   449         len -= 2;
       
   450         if (len > s->recv_used)
       
   451             len = s->recv_used;
       
   452         if (!len) {
       
   453             ret = USB_RET_NAK;
       
   454             break;
       
   455         }
       
   456         if (first_len > len)
       
   457             first_len = len;
       
   458         memcpy(data, s->recv_buf + s->recv_ptr, first_len);
       
   459         if (len > first_len)
       
   460             memcpy(data + first_len, s->recv_buf, len - first_len);
       
   461         s->recv_used -= len;
       
   462         s->recv_ptr = (s->recv_ptr + len) % RECV_BUF;
       
   463         ret = len + 2;
       
   464         break;
       
   465 
       
   466     default:
       
   467         DPRINTF("Bad token\n");
       
   468     fail:
       
   469         ret = USB_RET_STALL;
       
   470         break;
       
   471     }
       
   472 
       
   473     return ret;
       
   474 }
       
   475 
       
   476 static void usb_serial_handle_destroy(USBDevice *dev)
       
   477 {
       
   478     USBSerialState *s = (USBSerialState *)dev;
       
   479 
       
   480     qemu_chr_close(s->cs);
       
   481     qemu_free(s);
       
   482 }
       
   483 
       
   484 static int usb_serial_can_read(void *opaque)
       
   485 {
       
   486     USBSerialState *s = opaque;
       
   487     return RECV_BUF - s->recv_used;
       
   488 }
       
   489 
       
   490 static void usb_serial_read(void *opaque, const uint8_t *buf, int size)
       
   491 {
       
   492     USBSerialState *s = opaque;
       
   493     int first_size = RECV_BUF - s->recv_ptr;
       
   494     if (first_size > size)
       
   495         first_size = size;
       
   496     memcpy(s->recv_buf + s->recv_ptr + s->recv_used, buf, first_size);
       
   497     if (size > first_size)
       
   498         memcpy(s->recv_buf, buf + first_size, size - first_size);
       
   499     s->recv_used += size;
       
   500 }
       
   501 
       
   502 static void usb_serial_event(void *opaque, int event)
       
   503 {
       
   504     USBSerialState *s = opaque;
       
   505 
       
   506     switch (event) {
       
   507         case CHR_EVENT_BREAK:
       
   508             /* TODO: Send Break to USB */
       
   509             break;
       
   510         case CHR_EVENT_FOCUS:
       
   511             break;
       
   512         case CHR_EVENT_RESET:
       
   513             usb_serial_reset(s);
       
   514             /* TODO: Reset USB port */
       
   515             break;
       
   516     }
       
   517 }
       
   518 
       
   519 USBDevice *usb_serial_init(const char *filename)
       
   520 {
       
   521     USBSerialState *s;
       
   522     CharDriverState *cdrv;
       
   523     unsigned short vendorid = 0x0403, productid = 0x6001;
       
   524     char label[32];
       
   525     static int index;
       
   526 
       
   527     while (*filename && *filename != ':') {
       
   528         const char *p;
       
   529         char *e;
       
   530         if (strstart(filename, "vendorid=", &p)) {
       
   531             vendorid = strtol(p, &e, 16);
       
   532             if (e == p || (*e && *e != ',' && *e != ':')) {
       
   533                 printf("bogus vendor ID %s\n", p);
       
   534                 return NULL;
       
   535             }
       
   536             filename = e;
       
   537         } else if (strstart(filename, "productid=", &p)) {
       
   538             productid = strtol(p, &e, 16);
       
   539             if (e == p || (*e && *e != ',' && *e != ':')) {
       
   540                 printf("bogus product ID %s\n", p);
       
   541                 return NULL;
       
   542             }
       
   543             filename = e;
       
   544         } else {
       
   545             printf("unrecognized serial USB option %s\n", filename);
       
   546             return NULL;
       
   547         }
       
   548         while(*filename == ',')
       
   549             filename++;
       
   550     }
       
   551     if (!*filename) {
       
   552         printf("character device specification needed\n");
       
   553         return NULL;
       
   554     }
       
   555     filename++;
       
   556     s = qemu_mallocz(sizeof(USBSerialState));
       
   557     if (!s)
       
   558         return NULL;
       
   559 
       
   560     snprintf(label, sizeof(label), "usbserial%d", index++);
       
   561     cdrv = qemu_chr_open(label, filename);
       
   562     if (!cdrv)
       
   563         goto fail;
       
   564     s->cs = cdrv;
       
   565     qemu_chr_add_handlers(cdrv, usb_serial_can_read, usb_serial_read, usb_serial_event, s);
       
   566 
       
   567     s->dev.speed = USB_SPEED_FULL;
       
   568     s->dev.handle_packet = usb_generic_handle_packet;
       
   569 
       
   570     s->dev.handle_reset = usb_serial_handle_reset;
       
   571     s->dev.handle_control = usb_serial_handle_control;
       
   572     s->dev.handle_data = usb_serial_handle_data;
       
   573     s->dev.handle_destroy = usb_serial_handle_destroy;
       
   574 
       
   575     s->vendorid = vendorid;
       
   576     s->productid = productid;
       
   577 
       
   578     snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Serial(%.16s)",
       
   579              filename);
       
   580 
       
   581     usb_serial_handle_reset((USBDevice *)s);
       
   582     return (USBDevice *)s;
       
   583  fail:
       
   584     qemu_free(s);
       
   585     return NULL;
       
   586 }