Diff for /qemu/usb-redir.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2018/04/24 18:55:44 version 1.1.1.2, 2018/04/24 19:16:47
Line 225  static int usbredir_write(void *priv, ui Line 225  static int usbredir_write(void *priv, ui
 {  {
     USBRedirDevice *dev = priv;      USBRedirDevice *dev = priv;
   
     return qemu_chr_write(dev->cs, data, count);      if (!dev->cs->opened) {
           return 0;
       }
   
       return qemu_chr_fe_write(dev->cs, data, count);
 }  }
   
 /*  /*
Line 234  static int usbredir_write(void *priv, ui Line 238  static int usbredir_write(void *priv, ui
   
 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)  static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
 {  {
     AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));      AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
     aurb->dev = dev;      aurb->dev = dev;
     aurb->packet = p;      aurb->packet = p;
     aurb->packet_id = dev->packet_id;      aurb->packet_id = dev->packet_id;
Line 247  static AsyncURB *async_alloc(USBRedirDev Line 251  static AsyncURB *async_alloc(USBRedirDev
 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)  static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
 {  {
     QTAILQ_REMOVE(&dev->asyncq, aurb, next);      QTAILQ_REMOVE(&dev->asyncq, aurb, next);
     qemu_free(aurb);      g_free(aurb);
 }  }
   
 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)  static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
Line 286  static void usbredir_cancel_packet(USBDe Line 290  static void usbredir_cancel_packet(USBDe
 static struct buf_packet *bufp_alloc(USBRedirDevice *dev,  static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
     uint8_t *data, int len, int status, uint8_t ep)      uint8_t *data, int len, int status, uint8_t ep)
 {  {
     struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet));      struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
     bufp->data   = data;      bufp->data   = data;
     bufp->len    = len;      bufp->len    = len;
     bufp->status = status;      bufp->status = status;
Line 299  static void bufp_free(USBRedirDevice *de Line 303  static void bufp_free(USBRedirDevice *de
 {  {
     QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);      QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
     free(bufp->data);      free(bufp->data);
     qemu_free(bufp);      g_free(bufp);
 }  }
   
 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)  static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
Line 365  static int usbredir_handle_iso_data(USBR Line 369  static int usbredir_handle_iso_data(USBR
         }          }
   
         len = isop->len;          len = isop->len;
         if (len > p->len) {          if (len > p->iov.size) {
             ERROR("received iso data is larger then packet ep %02X\n", ep);              ERROR("received iso data is larger then packet ep %02X\n", ep);
             bufp_free(dev, isop, ep);              bufp_free(dev, isop, ep);
             return USB_RET_NAK;              return USB_RET_NAK;
         }          }
         memcpy(p->data, isop->data, len);          usb_packet_copy(p, isop->data, len);
         bufp_free(dev, isop, ep);          bufp_free(dev, isop, ep);
         return len;          return len;
     } else {      } else {
Line 379  static int usbredir_handle_iso_data(USBR Line 383  static int usbredir_handle_iso_data(USBR
         if (dev->endpoint[EP2I(ep)].iso_started) {          if (dev->endpoint[EP2I(ep)].iso_started) {
             struct usb_redir_iso_packet_header iso_packet = {              struct usb_redir_iso_packet_header iso_packet = {
                 .endpoint = ep,                  .endpoint = ep,
                 .length = p->len                  .length = p->iov.size
             };              };
               uint8_t buf[p->iov.size];
             /* No id, we look at the ep when receiving a status back */              /* No id, we look at the ep when receiving a status back */
               usb_packet_copy(p, buf, p->iov.size);
             usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,              usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
                                            p->data, p->len);                                             buf, p->iov.size);
             usbredirparser_do_write(dev->parser);              usbredirparser_do_write(dev->parser);
         }          }
         status = dev->endpoint[EP2I(ep)].iso_error;          status = dev->endpoint[EP2I(ep)].iso_error;
         dev->endpoint[EP2I(ep)].iso_error = 0;          dev->endpoint[EP2I(ep)].iso_error = 0;
         DPRINTF2("iso-token-out ep %02X status %d len %d\n", ep, status,          DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
                  p->len);                   p->iov.size);
         return usbredir_handle_status(dev, status, p->len);          return usbredir_handle_status(dev, status, p->iov.size);
     }      }
 }  }
   
Line 413  static int usbredir_handle_bulk_data(USB Line 419  static int usbredir_handle_bulk_data(USB
     AsyncURB *aurb = async_alloc(dev, p);      AsyncURB *aurb = async_alloc(dev, p);
     struct usb_redir_bulk_packet_header bulk_packet;      struct usb_redir_bulk_packet_header bulk_packet;
   
     DPRINTF("bulk-out ep %02X len %d id %u\n", ep, p->len, aurb->packet_id);      DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
               p->iov.size, aurb->packet_id);
   
     bulk_packet.endpoint  = ep;      bulk_packet.endpoint  = ep;
     bulk_packet.length    = p->len;      bulk_packet.length    = p->iov.size;
     bulk_packet.stream_id = 0;      bulk_packet.stream_id = 0;
     aurb->bulk_packet = bulk_packet;      aurb->bulk_packet = bulk_packet;
   
Line 424  static int usbredir_handle_bulk_data(USB Line 431  static int usbredir_handle_bulk_data(USB
         usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,          usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
                                         &bulk_packet, NULL, 0);                                          &bulk_packet, NULL, 0);
     } else {      } else {
         usbredir_log_data(dev, "bulk data out:", p->data, p->len);          uint8_t buf[p->iov.size];
           usb_packet_copy(p, buf, p->iov.size);
           usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
         usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,          usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
                                         &bulk_packet, p->data, p->len);                                          &bulk_packet, buf, p->iov.size);
     }      }
     usbredirparser_do_write(dev->parser);      usbredirparser_do_write(dev->parser);
     return USB_RET_ASYNC;      return USB_RET_ASYNC;
Line 471  static int usbredir_handle_interrupt_dat Line 480  static int usbredir_handle_interrupt_dat
         }          }
   
         len = intp->len;          len = intp->len;
         if (len > p->len) {          if (len > p->iov.size) {
             ERROR("received int data is larger then packet ep %02X\n", ep);              ERROR("received int data is larger then packet ep %02X\n", ep);
             bufp_free(dev, intp, ep);              bufp_free(dev, intp, ep);
             return USB_RET_NAK;              return USB_RET_NAK;
         }          }
         memcpy(p->data, intp->data, len);          usb_packet_copy(p, intp->data, len);
         bufp_free(dev, intp, ep);          bufp_free(dev, intp, ep);
         return len;          return len;
     } else {      } else {
         /* Output interrupt endpoint, normal async operation */          /* Output interrupt endpoint, normal async operation */
         AsyncURB *aurb = async_alloc(dev, p);          AsyncURB *aurb = async_alloc(dev, p);
         struct usb_redir_interrupt_packet_header interrupt_packet;          struct usb_redir_interrupt_packet_header interrupt_packet;
           uint8_t buf[p->iov.size];
   
         DPRINTF("interrupt-out ep %02X len %d id %u\n", ep, p->len,          DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
                 aurb->packet_id);                  aurb->packet_id);
   
         interrupt_packet.endpoint  = ep;          interrupt_packet.endpoint  = ep;
         interrupt_packet.length    = p->len;          interrupt_packet.length    = p->iov.size;
         aurb->interrupt_packet     = interrupt_packet;          aurb->interrupt_packet     = interrupt_packet;
   
         usbredir_log_data(dev, "interrupt data out:", p->data, p->len);          usb_packet_copy(p, buf, p->iov.size);
           usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
         usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,          usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
                                         &interrupt_packet, p->data, p->len);                                          &interrupt_packet, buf, p->iov.size);
         usbredirparser_do_write(dev->parser);          usbredirparser_do_write(dev->parser);
         return USB_RET_ASYNC;          return USB_RET_ASYNC;
     }      }
Line 807  static int usbredir_initfn(USBDevice *ud Line 818  static int usbredir_initfn(USBDevice *ud
     /* We'll do the attach once we receive the speed from the usb-host */      /* We'll do the attach once we receive the speed from the usb-host */
     udev->auto_attach = 0;      udev->auto_attach = 0;
   
       /* Let the backend know we are ready */
       qemu_chr_fe_open(dev->cs);
     qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,      qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
                           usbredir_chardev_read, usbredir_chardev_event, dev);                            usbredir_chardev_read, usbredir_chardev_event, dev);
   
Line 830  static void usbredir_handle_destroy(USBD Line 843  static void usbredir_handle_destroy(USBD
 {  {
     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);      USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
   
     qemu_chr_close(dev->cs);      qemu_chr_fe_close(dev->cs);
       qemu_chr_delete(dev->cs);
     /* Note must be done after qemu_chr_close, as that causes a close event */      /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->open_close_bh);      qemu_bh_delete(dev->open_close_bh);
   
Line 871  static void usbredir_device_connect(void Line 885  static void usbredir_device_connect(void
 {  {
     USBRedirDevice *dev = priv;      USBRedirDevice *dev = priv;
   
       if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
           ERROR("Received device connect while already connected\n");
           return;
       }
   
     switch (device_connect->speed) {      switch (device_connect->speed) {
     case usb_redir_speed_low:      case usb_redir_speed_low:
         DPRINTF("attaching low speed device\n");          DPRINTF("attaching low speed device\n");
Line 899  static void usbredir_device_connect(void Line 918  static void usbredir_device_connect(void
 static void usbredir_device_disconnect(void *priv)  static void usbredir_device_disconnect(void *priv)
 {  {
     USBRedirDevice *dev = priv;      USBRedirDevice *dev = priv;
       int i;
   
     /* Stop any pending attaches */      /* Stop any pending attaches */
     qemu_del_timer(dev->attach_timer);      qemu_del_timer(dev->attach_timer);
   
     if (dev->dev.attached) {      if (dev->dev.attached) {
         usb_device_detach(&dev->dev);          usb_device_detach(&dev->dev);
         usbredir_cleanup_device_queues(dev);  
         /*          /*
          * Delay next usb device attach to give the guest a chance to see           * Delay next usb device attach to give the guest a chance to see
          * see the detach / attach in case of quick close / open succession           * see the detach / attach in case of quick close / open succession
          */           */
         dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;          dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
     }      }
   
       /* Reset state so that the next dev connected starts with a clean slate */
       usbredir_cleanup_device_queues(dev);
       memset(dev->endpoint, 0, sizeof(dev->endpoint));
       for (i = 0; i < MAX_ENDPOINTS; i++) {
           QTAILQ_INIT(&dev->endpoint[i].bufpq);
       }
 }  }
   
 static void usbredir_interface_info(void *priv,  static void usbredir_interface_info(void *priv,
Line 959  static void usbredir_configuration_statu Line 985  static void usbredir_configuration_statu
             dev->dev.data_buf[0] = config_status->configuration;              dev->dev.data_buf[0] = config_status->configuration;
             len = 1;              len = 1;
         }          }
         aurb->packet->len =          aurb->packet->result =
             usbredir_handle_status(dev, config_status->status, len);              usbredir_handle_status(dev, config_status->status, len);
         usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);          usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
     }      }
Line 987  static void usbredir_alt_setting_status( Line 1013  static void usbredir_alt_setting_status(
             dev->dev.data_buf[0] = alt_setting_status->alt;              dev->dev.data_buf[0] = alt_setting_status->alt;
             len = 1;              len = 1;
         }          }
         aurb->packet->len =          aurb->packet->result =
             usbredir_handle_status(dev, alt_setting_status->status, len);              usbredir_handle_status(dev, alt_setting_status->status, len);
         usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);          usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
     }      }
Line 1003  static void usbredir_iso_stream_status(v Line 1029  static void usbredir_iso_stream_status(v
     DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,      DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
             ep, id);              ep, id);
   
       if (!dev->dev.attached) {
           return;
       }
   
     dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;      dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
     if (iso_stream_status->status == usb_redir_stall) {      if (iso_stream_status->status == usb_redir_stall) {
         DPRINTF("iso stream stopped by peer ep %02X\n", ep);          DPRINTF("iso stream stopped by peer ep %02X\n", ep);
Line 1020  static void usbredir_interrupt_receiving Line 1050  static void usbredir_interrupt_receiving
     DPRINTF("interrupt recv status %d ep %02X id %u\n",      DPRINTF("interrupt recv status %d ep %02X id %u\n",
             interrupt_receiving_status->status, ep, id);              interrupt_receiving_status->status, ep, id);
   
       if (!dev->dev.attached) {
           return;
       }
   
     dev->endpoint[EP2I(ep)].interrupt_error =      dev->endpoint[EP2I(ep)].interrupt_error =
         interrupt_receiving_status->status;          interrupt_receiving_status->status;
     if (interrupt_receiving_status->status == usb_redir_stall) {      if (interrupt_receiving_status->status == usb_redir_stall) {
Line 1070  static void usbredir_control_packet(void Line 1104  static void usbredir_control_packet(void
                 len = USB_RET_STALL;                  len = USB_RET_STALL;
             }              }
         }          }
         aurb->packet->len = len;          aurb->packet->result = len;
         usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);          usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
     }      }
     async_free(dev, aurb);      async_free(dev, aurb);
Line 1105  static void usbredir_bulk_packet(void *p Line 1139  static void usbredir_bulk_packet(void *p
         len = usbredir_handle_status(dev, bulk_packet->status, len);          len = usbredir_handle_status(dev, bulk_packet->status, len);
         if (len > 0) {          if (len > 0) {
             usbredir_log_data(dev, "bulk data in:", data, data_len);              usbredir_log_data(dev, "bulk data in:", data, data_len);
             if (data_len <= aurb->packet->len) {              if (data_len <= aurb->packet->iov.size) {
                 memcpy(aurb->packet->data, data, data_len);                  usb_packet_copy(aurb->packet, data, data_len);
             } else {              } else {
                 ERROR("bulk buffer too small (%d > %d)\n", data_len,                  ERROR("bulk buffer too small (%d > %zd)\n", data_len,
                       aurb->packet->len);                        aurb->packet->iov.size);
                 len = USB_RET_STALL;                  len = USB_RET_STALL;
             }              }
         }          }
         aurb->packet->len = len;          aurb->packet->result = len;
         usb_packet_complete(&dev->dev, aurb->packet);          usb_packet_complete(&dev->dev, aurb->packet);
     }      }
     async_free(dev, aurb);      async_free(dev, aurb);
Line 1185  static void usbredir_interrupt_packet(vo Line 1219  static void usbredir_interrupt_packet(vo
         }          }
   
         if (aurb->packet) {          if (aurb->packet) {
             aurb->packet->len = usbredir_handle_status(dev,              aurb->packet->result = usbredir_handle_status(dev,
                                                interrupt_packet->status, len);                                                 interrupt_packet->status, len);
             usb_packet_complete(&dev->dev, aurb->packet);              usb_packet_complete(&dev->dev, aurb->packet);
         }          }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


unix.superglobalmegacorp.com