Lines Matching +full:remote +full:- +full:endpoint
2 * USB redirector usb-guest
4 * Copyright (c) 2011-2012 Red Hat, Inc.
36 #include "qemu/error-report.h"
39 #include "chardev/char-fe.h"
44 #include "hw/qdev-properties.h"
45 #include "hw/qdev-properties-system.h"
47 #include "migration/qemu-file-types.h"
58 #define USBEP2I(usb_ep) (((usb_ep)->pid == USB_TOKEN_IN) ? \
59 ((usb_ep)->nr | 0x10) : ((usb_ep)->nr))
60 #define I2USBEP(d, i) (usb_ep_get(&(d)->dev, \
126 /* Active chardev-watch-tag */
135 struct endp_data endpoint[MAX_ENDPOINTS]; member
148 #define TYPE_USB_REDIR "usb-redir"
192 #define VERSION "qemu usb-redir guest " QEMU_VERSION
200 if (dev->debug >= usbredirparser_error) { \
201 error_report("usb-redir error: " __VA_ARGS__); \
206 if (dev->debug >= usbredirparser_warning) { \
212 if (dev->debug >= usbredirparser_info) { \
213 error_report("usb-redir: " __VA_ARGS__); \
218 if (dev->debug >= usbredirparser_debug) { \
219 error_report("usb-redir: " __VA_ARGS__); \
224 if (dev->debug >= usbredirparser_debug_data) { \
225 error_report("usb-redir: " __VA_ARGS__); \
233 if (dev->debug < level) { in usbredir_log()
243 if (dev->debug < usbredirparser_debug_data) { in usbredir_log_data()
257 if (dev->read_buf_size < count) { in usbredir_read()
258 count = dev->read_buf_size; in usbredir_read()
261 memcpy(data, dev->read_buf, count); in usbredir_read()
263 dev->read_buf_size -= count; in usbredir_read()
264 if (dev->read_buf_size) { in usbredir_read()
265 dev->read_buf += count; in usbredir_read()
267 dev->read_buf = NULL; in usbredir_read()
278 dev->watch = 0; in usbredir_write_unblocked()
279 usbredirparser_do_write(dev->parser); in usbredir_write_unblocked()
289 if (!qemu_chr_fe_backend_open(&dev->cs)) { in usbredir_write()
299 if (dev->in_write) { in usbredir_write()
303 dev->in_write = true; in usbredir_write()
305 r = qemu_chr_fe_write(&dev->cs, data, count); in usbredir_write()
307 if (!dev->watch) { in usbredir_write()
308 dev->watch = qemu_chr_fe_add_watch(&dev->cs, G_IO_OUT | G_IO_HUP, in usbredir_write()
315 dev->in_write = false; in usbredir_write()
326 q->dev = dev; in packet_id_queue_init()
327 q->name = name; in packet_id_queue_init()
328 QTAILQ_INIT(&q->head); in packet_id_queue_init()
329 q->size = 0; in packet_id_queue_init()
334 USBRedirDevice *dev = q->dev; in packet_id_queue_add()
337 DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name); in packet_id_queue_add()
340 e->id = id; in packet_id_queue_add()
341 QTAILQ_INSERT_TAIL(&q->head, e, next); in packet_id_queue_add()
342 q->size++; in packet_id_queue_add()
347 USBRedirDevice *dev = q->dev; in packet_id_queue_remove()
350 QTAILQ_FOREACH(e, &q->head, next) { in packet_id_queue_remove()
351 if (e->id == id) { in packet_id_queue_remove()
353 id, q->name); in packet_id_queue_remove()
354 QTAILQ_REMOVE(&q->head, e, next); in packet_id_queue_remove()
355 q->size--; in packet_id_queue_remove()
365 USBRedirDevice *dev = q->dev; in packet_id_queue_empty()
368 DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name); in packet_id_queue_empty()
370 QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) { in packet_id_queue_empty()
371 QTAILQ_REMOVE(&q->head, e, next); in packet_id_queue_empty()
374 q->size = 0; in packet_id_queue_empty()
380 int i = USBEP2I(p->ep); in usbredir_cancel_packet()
382 if (p->combined) { in usbredir_cancel_packet()
387 if (dev->endpoint[i].pending_async_packet) { in usbredir_cancel_packet()
388 assert(dev->endpoint[i].pending_async_packet == p); in usbredir_cancel_packet()
389 dev->endpoint[i].pending_async_packet = NULL; in usbredir_cancel_packet()
393 packet_id_queue_add(&dev->cancelled, p->id); in usbredir_cancel_packet()
394 usbredirparser_send_cancel_data_packet(dev->parser, p->id); in usbredir_cancel_packet()
395 usbredirparser_do_write(dev->parser); in usbredir_cancel_packet()
400 if (!dev->dev.attached) { in usbredir_is_cancelled()
403 return packet_id_queue_remove(&dev->cancelled, id); in usbredir_is_cancelled()
412 if (dev->endpoint[USBEP2I(ep)].bulk_receiving_started) { in usbredir_fill_already_in_flight_from_ep()
416 QTAILQ_FOREACH(p, &ep->queue, queue) { in usbredir_fill_already_in_flight_from_ep()
418 if (p->combined && p != p->combined->first) { in usbredir_fill_already_in_flight_from_ep()
421 if (p->state == USB_PACKET_ASYNC) { in usbredir_fill_already_in_flight_from_ep()
422 packet_id_queue_add(&dev->already_in_flight, p->id); in usbredir_fill_already_in_flight_from_ep()
430 struct USBDevice *udev = &dev->dev; in usbredir_fill_already_in_flight()
432 usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl); in usbredir_fill_already_in_flight()
435 usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]); in usbredir_fill_already_in_flight()
436 usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]); in usbredir_fill_already_in_flight()
442 return packet_id_queue_remove(&dev->already_in_flight, id); in usbredir_already_in_flight()
454 p = usb_ep_find_packet_by_id(&dev->dev, in usbredir_find_packet_by_id()
468 if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets && in bufp_alloc()
469 dev->endpoint[EP2I(ep)].bufpq_size > in bufp_alloc()
470 2 * dev->endpoint[EP2I(ep)].bufpq_target_size) { in bufp_alloc()
472 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1; in bufp_alloc()
476 if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) { in bufp_alloc()
477 if (dev->endpoint[EP2I(ep)].bufpq_size > in bufp_alloc()
478 dev->endpoint[EP2I(ep)].bufpq_target_size) { in bufp_alloc()
480 return -1; in bufp_alloc()
482 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; in bufp_alloc()
486 bufp->data = data; in bufp_alloc()
487 bufp->len = len; in bufp_alloc()
488 bufp->offset = 0; in bufp_alloc()
489 bufp->status = status; in bufp_alloc()
490 bufp->free_on_destroy = free_on_destroy; in bufp_alloc()
491 QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); in bufp_alloc()
492 dev->endpoint[EP2I(ep)].bufpq_size++; in bufp_alloc()
499 QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); in bufp_free()
500 dev->endpoint[EP2I(ep)].bufpq_size--; in bufp_free()
501 free(bufp->free_on_destroy); in bufp_free()
509 QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) { in usbredir_free_bufpq()
523 usbredirparser_send_reset(dev->parser); in usbredir_handle_reset()
524 usbredirparser_do_write(dev->parser); in usbredir_handle_reset()
531 if (!dev->endpoint[EP2I(ep)].iso_started && in usbredir_handle_iso_data()
532 !dev->endpoint[EP2I(ep)].iso_error) { in usbredir_handle_iso_data()
534 .endpoint = ep, in usbredir_handle_iso_data()
538 if (dev->dev.speed == USB_SPEED_HIGH) { in usbredir_handle_iso_data()
539 pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval; in usbredir_handle_iso_data()
541 pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval; in usbredir_handle_iso_data()
544 dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000; in usbredir_handle_iso_data()
556 dev->endpoint[EP2I(ep)].bufpq_target_size, in usbredir_handle_iso_data()
558 /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest in usbredir_handle_iso_data()
568 usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso); in usbredir_handle_iso_data()
569 usbredirparser_do_write(dev->parser); in usbredir_handle_iso_data()
572 dev->endpoint[EP2I(ep)].iso_started = 1; in usbredir_handle_iso_data()
573 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0; in usbredir_handle_iso_data()
574 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; in usbredir_handle_iso_data()
580 if (dev->endpoint[EP2I(ep)].iso_started && in usbredir_handle_iso_data()
581 !dev->endpoint[EP2I(ep)].bufpq_prefilled) { in usbredir_handle_iso_data()
582 if (dev->endpoint[EP2I(ep)].bufpq_size < in usbredir_handle_iso_data()
583 dev->endpoint[EP2I(ep)].bufpq_target_size) { in usbredir_handle_iso_data()
586 dev->endpoint[EP2I(ep)].bufpq_prefilled = 1; in usbredir_handle_iso_data()
589 isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); in usbredir_handle_iso_data()
591 DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n", in usbredir_handle_iso_data()
592 ep, dev->endpoint[EP2I(ep)].iso_error); in usbredir_handle_iso_data()
593 /* Re-fill the buffer */ in usbredir_handle_iso_data()
594 dev->endpoint[EP2I(ep)].bufpq_prefilled = 0; in usbredir_handle_iso_data()
596 status = dev->endpoint[EP2I(ep)].iso_error; in usbredir_handle_iso_data()
597 dev->endpoint[EP2I(ep)].iso_error = 0; in usbredir_handle_iso_data()
598 p->status = status ? USB_RET_IOERROR : USB_RET_SUCCESS; in usbredir_handle_iso_data()
601 DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep, in usbredir_handle_iso_data()
602 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size); in usbredir_handle_iso_data()
604 status = isop->status; in usbredir_handle_iso_data()
605 len = isop->len; in usbredir_handle_iso_data()
606 if (len > p->iov.size) { in usbredir_handle_iso_data()
608 ep, len, (int)p->iov.size); in usbredir_handle_iso_data()
609 len = p->iov.size; in usbredir_handle_iso_data()
612 usb_packet_copy(p, isop->data, len); in usbredir_handle_iso_data()
617 send the packet to the usb-host */ in usbredir_handle_iso_data()
618 if (dev->endpoint[EP2I(ep)].iso_started) { in usbredir_handle_iso_data()
620 .endpoint = ep, in usbredir_handle_iso_data()
621 .length = p->iov.size in usbredir_handle_iso_data()
623 g_autofree uint8_t *buf = g_malloc(p->iov.size); in usbredir_handle_iso_data()
625 usb_packet_copy(p, buf, p->iov.size); in usbredir_handle_iso_data()
626 usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet, in usbredir_handle_iso_data()
627 buf, p->iov.size); in usbredir_handle_iso_data()
628 usbredirparser_do_write(dev->parser); in usbredir_handle_iso_data()
630 status = dev->endpoint[EP2I(ep)].iso_error; in usbredir_handle_iso_data()
631 dev->endpoint[EP2I(ep)].iso_error = 0; in usbredir_handle_iso_data()
632 DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status, in usbredir_handle_iso_data()
633 p->iov.size); in usbredir_handle_iso_data()
641 .endpoint = ep in usbredir_stop_iso_stream()
643 if (dev->endpoint[EP2I(ep)].iso_started) { in usbredir_stop_iso_stream()
644 usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream); in usbredir_stop_iso_stream()
646 dev->endpoint[EP2I(ep)].iso_started = 0; in usbredir_stop_iso_stream()
648 dev->endpoint[EP2I(ep)].iso_error = 0; in usbredir_stop_iso_stream()
653 * The usb-host may poll the endpoint faster then our guest, resulting in lots
654 * of smaller bulkp-s. The below buffered_bulk_in_complete* functions combine
655 * data from multiple bulkp-s into a single packet, avoiding bufpq overflows.
660 usb_packet_copy(p, bulkp->data + bulkp->offset, count); in usbredir_buffered_bulk_add_data_to_packet()
661 bulkp->offset += count; in usbredir_buffered_bulk_add_data_to_packet()
662 if (bulkp->offset == bulkp->len) { in usbredir_buffered_bulk_add_data_to_packet()
664 usbredir_handle_status(dev, p, bulkp->status); in usbredir_buffered_bulk_add_data_to_packet()
675 while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) && in usbredir_buffered_bulk_in_complete_raw()
676 p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) { in usbredir_buffered_bulk_in_complete_raw()
677 count = bulkp->len - bulkp->offset; in usbredir_buffered_bulk_in_complete_raw()
678 if (count > (p->iov.size - p->actual_length)) { in usbredir_buffered_bulk_in_complete_raw()
679 count = p->iov.size - p->actual_length; in usbredir_buffered_bulk_in_complete_raw()
688 const int maxp = dev->endpoint[EP2I(ep)].max_packet_size; in usbredir_buffered_bulk_in_complete_ftdi()
693 while ((bulkp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) && in usbredir_buffered_bulk_in_complete_ftdi()
694 p->actual_length < p->iov.size && p->status == USB_RET_SUCCESS) { in usbredir_buffered_bulk_in_complete_ftdi()
695 if (bulkp->len < 2) { in usbredir_buffered_bulk_in_complete_ftdi()
701 if ((p->actual_length % maxp) == 0) { in usbredir_buffered_bulk_in_complete_ftdi()
702 usb_packet_copy(p, bulkp->data, 2); in usbredir_buffered_bulk_in_complete_ftdi()
703 memcpy(header, bulkp->data, 2); in usbredir_buffered_bulk_in_complete_ftdi()
705 if (bulkp->data[0] != header[0] || bulkp->data[1] != header[1]) { in usbredir_buffered_bulk_in_complete_ftdi()
710 if (bulkp->offset == 0) { in usbredir_buffered_bulk_in_complete_ftdi()
711 bulkp->offset = 2; /* Skip header */ in usbredir_buffered_bulk_in_complete_ftdi()
713 count = bulkp->len - bulkp->offset; in usbredir_buffered_bulk_in_complete_ftdi()
715 if (count > (maxp - (p->actual_length % maxp))) { in usbredir_buffered_bulk_in_complete_ftdi()
716 count = maxp - (p->actual_length % maxp); in usbredir_buffered_bulk_in_complete_ftdi()
725 p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */ in usbredir_buffered_bulk_in_complete()
726 dev->buffered_bulk_in_complete(dev, p, ep); in usbredir_buffered_bulk_in_complete()
727 DPRINTF("bulk-token-in ep %02X status %d len %d id %"PRIu64"\n", in usbredir_buffered_bulk_in_complete()
728 ep, p->status, p->actual_length, p->id); in usbredir_buffered_bulk_in_complete()
734 /* Input bulk endpoint, buffered packet input */ in usbredir_handle_buffered_bulk_in_data()
735 if (!dev->endpoint[EP2I(ep)].bulk_receiving_started) { in usbredir_handle_buffered_bulk_in_data()
738 .endpoint = ep, in usbredir_handle_buffered_bulk_in_data()
743 bpt = 512 + dev->endpoint[EP2I(ep)].max_packet_size - 1; in usbredir_handle_buffered_bulk_in_data()
744 bpt /= dev->endpoint[EP2I(ep)].max_packet_size; in usbredir_handle_buffered_bulk_in_data()
745 bpt *= dev->endpoint[EP2I(ep)].max_packet_size; in usbredir_handle_buffered_bulk_in_data()
748 usbredirparser_send_start_bulk_receiving(dev->parser, 0, &start); in usbredir_handle_buffered_bulk_in_data()
749 usbredirparser_do_write(dev->parser); in usbredir_handle_buffered_bulk_in_data()
752 dev->endpoint[EP2I(ep)].bulk_receiving_started = 1; in usbredir_handle_buffered_bulk_in_data()
755 dev->endpoint[EP2I(ep)].bufpq_target_size = 5000; in usbredir_handle_buffered_bulk_in_data()
756 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; in usbredir_handle_buffered_bulk_in_data()
759 if (QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) { in usbredir_handle_buffered_bulk_in_data()
760 DPRINTF("bulk-token-in ep %02X, no bulkp\n", ep); in usbredir_handle_buffered_bulk_in_data()
761 assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL); in usbredir_handle_buffered_bulk_in_data()
762 dev->endpoint[EP2I(ep)].pending_async_packet = p; in usbredir_handle_buffered_bulk_in_data()
763 p->status = USB_RET_ASYNC; in usbredir_handle_buffered_bulk_in_data()
772 .endpoint = ep, in usbredir_stop_bulk_receiving()
775 if (dev->endpoint[EP2I(ep)].bulk_receiving_started) { in usbredir_stop_bulk_receiving()
776 usbredirparser_send_stop_bulk_receiving(dev->parser, 0, &stop_bulk); in usbredir_stop_bulk_receiving()
778 dev->endpoint[EP2I(ep)].bulk_receiving_started = 0; in usbredir_stop_bulk_receiving()
788 const int maxp = dev->endpoint[EP2I(ep)].max_packet_size; in usbredir_handle_bulk_data()
790 if (usbredir_already_in_flight(dev, p->id)) { in usbredir_handle_bulk_data()
791 p->status = USB_RET_ASYNC; in usbredir_handle_bulk_data()
795 if (dev->endpoint[EP2I(ep)].bulk_receiving_enabled) { in usbredir_handle_bulk_data()
801 assert(dev->endpoint[EP2I(ep)].pending_async_packet == NULL); in usbredir_handle_bulk_data()
803 dev->endpoint[EP2I(ep)].bulk_receiving_enabled = 0; in usbredir_handle_bulk_data()
806 DPRINTF("bulk-out ep %02X stream %u len %zd id %"PRIu64"\n", in usbredir_handle_bulk_data()
807 ep, p->stream, size, p->id); in usbredir_handle_bulk_data()
809 bulk_packet.endpoint = ep; in usbredir_handle_bulk_data()
811 bulk_packet.stream_id = p->stream; in usbredir_handle_bulk_data()
814 usbredirparser_peer_has_cap(dev->parser, in usbredir_handle_bulk_data()
818 usbredirparser_send_bulk_packet(dev->parser, p->id, in usbredir_handle_bulk_data()
824 usbredirparser_send_bulk_packet(dev->parser, p->id, in usbredir_handle_bulk_data()
827 usbredirparser_do_write(dev->parser); in usbredir_handle_bulk_data()
828 p->status = USB_RET_ASYNC; in usbredir_handle_bulk_data()
834 /* Input interrupt endpoint, buffered packet input */ in usbredir_handle_interrupt_in_data()
838 if (!dev->endpoint[EP2I(ep)].interrupt_started && in usbredir_handle_interrupt_in_data()
839 !dev->endpoint[EP2I(ep)].interrupt_error) { in usbredir_handle_interrupt_in_data()
841 .endpoint = ep, in usbredir_handle_interrupt_in_data()
844 usbredirparser_send_start_interrupt_receiving(dev->parser, 0, in usbredir_handle_interrupt_in_data()
846 usbredirparser_do_write(dev->parser); in usbredir_handle_interrupt_in_data()
848 dev->endpoint[EP2I(ep)].interrupt_started = 1; in usbredir_handle_interrupt_in_data()
851 dev->endpoint[EP2I(ep)].bufpq_target_size = 1000; in usbredir_handle_interrupt_in_data()
852 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0; in usbredir_handle_interrupt_in_data()
857 QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { in usbredir_handle_interrupt_in_data()
858 sum += intp->len; in usbredir_handle_interrupt_in_data()
859 if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || in usbredir_handle_interrupt_in_data()
860 sum >= p->iov.size) in usbredir_handle_interrupt_in_data()
865 DPRINTF2("interrupt-token-in ep %02X, no intp, buffered %d\n", ep, sum); in usbredir_handle_interrupt_in_data()
867 status = dev->endpoint[EP2I(ep)].interrupt_error; in usbredir_handle_interrupt_in_data()
868 dev->endpoint[EP2I(ep)].interrupt_error = 0; in usbredir_handle_interrupt_in_data()
872 p->status = USB_RET_NAK; in usbredir_handle_interrupt_in_data()
881 QTAILQ_FOREACH(intp, &dev->endpoint[EP2I(ep)].bufpq, next) { in usbredir_handle_interrupt_in_data()
885 DPRINTF("interrupt-token-in ep %02X fragment status %d len %d\n", ep, in usbredir_handle_interrupt_in_data()
886 intp->status, intp->len); in usbredir_handle_interrupt_in_data()
888 sum += intp->len; in usbredir_handle_interrupt_in_data()
889 len = intp->len; in usbredir_handle_interrupt_in_data()
891 status = intp->status; in usbredir_handle_interrupt_in_data()
893 if (sum > p->iov.size) { in usbredir_handle_interrupt_in_data()
895 len -= (sum - p->iov.size); in usbredir_handle_interrupt_in_data()
896 sum = p->iov.size; in usbredir_handle_interrupt_in_data()
900 usb_packet_copy(p, intp->data, len); in usbredir_handle_interrupt_in_data()
903 if (intp->len < dev->endpoint[EP2I(ep)].max_packet_size || in usbredir_handle_interrupt_in_data()
904 sum >= p->iov.size) in usbredir_handle_interrupt_in_data()
910 DPRINTF("interrupt-token-in ep %02X summary status %d len %d\n", ep, in usbredir_handle_interrupt_in_data()
918 * expect immediate completion for an interrupt endpoint, and handling this
926 g_autofree uint8_t *buf = g_malloc(p->iov.size); in usbredir_handle_interrupt_out_data()
928 DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep, in usbredir_handle_interrupt_out_data()
929 p->iov.size, p->id); in usbredir_handle_interrupt_out_data()
931 interrupt_packet.endpoint = ep; in usbredir_handle_interrupt_out_data()
932 interrupt_packet.length = p->iov.size; in usbredir_handle_interrupt_out_data()
934 usb_packet_copy(p, buf, p->iov.size); in usbredir_handle_interrupt_out_data()
935 usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size); in usbredir_handle_interrupt_out_data()
936 usbredirparser_send_interrupt_packet(dev->parser, p->id, in usbredir_handle_interrupt_out_data()
937 &interrupt_packet, buf, p->iov.size); in usbredir_handle_interrupt_out_data()
938 usbredirparser_do_write(dev->parser); in usbredir_handle_interrupt_out_data()
945 .endpoint = ep in usbredir_stop_interrupt_receiving()
947 if (dev->endpoint[EP2I(ep)].interrupt_started) { in usbredir_stop_interrupt_receiving()
948 usbredirparser_send_stop_interrupt_receiving(dev->parser, 0, in usbredir_stop_interrupt_receiving()
951 dev->endpoint[EP2I(ep)].interrupt_started = 0; in usbredir_stop_interrupt_receiving()
953 dev->endpoint[EP2I(ep)].interrupt_error = 0; in usbredir_stop_interrupt_receiving()
962 ep = p->ep->nr; in usbredir_handle_data()
963 if (p->pid == USB_TOKEN_IN) { in usbredir_handle_data()
967 switch (dev->endpoint[EP2I(ep)].type) { in usbredir_handle_data()
970 p->status = USB_RET_NAK; in usbredir_handle_data()
973 if (p->state == USB_PACKET_SETUP && p->pid == USB_TOKEN_IN && in usbredir_handle_data()
974 p->ep->pipeline) { in usbredir_handle_data()
975 p->status = USB_RET_ADD_TO_QUEUE; in usbredir_handle_data()
992 dev->endpoint[EP2I(ep)].type); in usbredir_handle_data()
993 p->status = USB_RET_NAK; in usbredir_handle_data()
999 if (ep->pid == USB_TOKEN_IN && ep->pipeline) { in usbredir_flush_ep_queue()
1008 switch (dev->endpoint[i].type) { in usbredir_stop_ep()
1031 usbredirparser_do_write(dev->parser); in usbredir_ep_stopped()
1040 DPRINTF("set config %d id %"PRIu64"\n", config, p->id); in usbredir_set_config()
1047 usbredirparser_send_set_configuration(dev->parser, p->id, &set_config); in usbredir_set_config()
1048 usbredirparser_do_write(dev->parser); in usbredir_set_config()
1049 p->status = USB_RET_ASYNC; in usbredir_set_config()
1054 DPRINTF("get config id %"PRIu64"\n", p->id); in usbredir_get_config()
1056 usbredirparser_send_get_configuration(dev->parser, p->id); in usbredir_get_config()
1057 usbredirparser_do_write(dev->parser); in usbredir_get_config()
1058 p->status = USB_RET_ASYNC; in usbredir_get_config()
1067 DPRINTF("set interface %d alt %d id %"PRIu64"\n", interface, alt, p->id); in usbredir_set_interface()
1070 if (dev->endpoint[i].interface == interface) { in usbredir_set_interface()
1077 usbredirparser_send_set_alt_setting(dev->parser, p->id, &set_alt); in usbredir_set_interface()
1078 usbredirparser_do_write(dev->parser); in usbredir_set_interface()
1079 p->status = USB_RET_ASYNC; in usbredir_set_interface()
1087 DPRINTF("get interface %d id %"PRIu64"\n", interface, p->id); in usbredir_get_interface()
1090 usbredirparser_send_get_alt_setting(dev->parser, p->id, &get_alt); in usbredir_get_interface()
1091 usbredirparser_do_write(dev->parser); in usbredir_get_interface()
1092 p->status = USB_RET_ASYNC; in usbredir_get_interface()
1101 if (usbredir_already_in_flight(dev, p->id)) { in usbredir_handle_control()
1102 p->status = USB_RET_ASYNC; in usbredir_handle_control()
1110 dev->dev.addr = value; in usbredir_handle_control()
1128 "ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %"PRIu64"\n", in usbredir_handle_control()
1129 request >> 8, request & 0xff, value, index, length, p->id); in usbredir_handle_control()
1133 control_packet.endpoint = control_packet.requesttype & USB_DIR_IN; in usbredir_handle_control()
1139 usbredirparser_send_control_packet(dev->parser, p->id, in usbredir_handle_control()
1143 usbredirparser_send_control_packet(dev->parser, p->id, in usbredir_handle_control()
1146 usbredirparser_do_write(dev->parser); in usbredir_handle_control()
1147 p->status = USB_RET_ASYNC; in usbredir_handle_control()
1158 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_alloc_streams()
1166 return -1; in usbredir_alloc_streams()
1174 usbredirparser_send_alloc_bulk_streams(dev->parser, 0, &alloc_streams); in usbredir_alloc_streams()
1175 usbredirparser_do_write(dev->parser); in usbredir_alloc_streams()
1184 qemu_bh_schedule(dev->device_reject_bh); in usbredir_alloc_streams()
1185 return -1; in usbredir_alloc_streams()
1196 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_free_streams()
1205 usbredirparser_send_free_bulk_streams(dev->parser, 0, &free_streams); in usbredir_free_streams()
1206 usbredirparser_do_write(dev->parser); in usbredir_free_streams()
1221 qemu_bh_cancel(dev->device_reject_bh); in usbredir_chardev_close_bh()
1224 if (dev->parser) { in usbredir_chardev_close_bh()
1226 usbredirparser_destroy(dev->parser); in usbredir_chardev_close_bh()
1227 dev->parser = NULL; in usbredir_chardev_close_bh()
1229 if (dev->watch) { in usbredir_chardev_close_bh()
1230 g_source_remove(dev->watch); in usbredir_chardev_close_bh()
1231 dev->watch = 0; in usbredir_chardev_close_bh()
1242 dev->parser = usbredirparser_create(); in usbredir_create_parser()
1243 if (!dev->parser) { in usbredir_create_parser()
1247 dev->parser->priv = dev; in usbredir_create_parser()
1248 dev->parser->log_func = usbredir_log; in usbredir_create_parser()
1249 dev->parser->read_func = usbredir_read; in usbredir_create_parser()
1250 dev->parser->write_func = usbredir_write; in usbredir_create_parser()
1251 dev->parser->hello_func = usbredir_hello; in usbredir_create_parser()
1252 dev->parser->device_connect_func = usbredir_device_connect; in usbredir_create_parser()
1253 dev->parser->device_disconnect_func = usbredir_device_disconnect; in usbredir_create_parser()
1254 dev->parser->interface_info_func = usbredir_interface_info; in usbredir_create_parser()
1255 dev->parser->ep_info_func = usbredir_ep_info; in usbredir_create_parser()
1256 dev->parser->configuration_status_func = usbredir_configuration_status; in usbredir_create_parser()
1257 dev->parser->alt_setting_status_func = usbredir_alt_setting_status; in usbredir_create_parser()
1258 dev->parser->iso_stream_status_func = usbredir_iso_stream_status; in usbredir_create_parser()
1259 dev->parser->interrupt_receiving_status_func = in usbredir_create_parser()
1261 dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status; in usbredir_create_parser()
1262 dev->parser->bulk_receiving_status_func = usbredir_bulk_receiving_status; in usbredir_create_parser()
1263 dev->parser->control_packet_func = usbredir_control_packet; in usbredir_create_parser()
1264 dev->parser->bulk_packet_func = usbredir_bulk_packet; in usbredir_create_parser()
1265 dev->parser->iso_packet_func = usbredir_iso_packet; in usbredir_create_parser()
1266 dev->parser->interrupt_packet_func = usbredir_interrupt_packet; in usbredir_create_parser()
1267 dev->parser->buffered_bulk_packet_func = usbredir_buffered_bulk_packet; in usbredir_create_parser()
1268 dev->read_buf = NULL; in usbredir_create_parser()
1269 dev->read_buf_size = 0; in usbredir_create_parser()
1278 if (dev->enable_streams) { in usbredir_create_parser()
1286 usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, in usbredir_create_parser()
1288 usbredirparser_do_write(dev->parser); in usbredir_create_parser()
1294 if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) { in usbredir_reject_device()
1295 usbredirparser_send_filter_reject(dev->parser); in usbredir_reject_device()
1296 usbredirparser_do_write(dev->parser); in usbredir_reject_device()
1317 if ((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER) && !( in usbredir_do_attach()
1318 usbredirparser_peer_has_cap(dev->parser, in usbredir_do_attach()
1320 usbredirparser_peer_has_cap(dev->parser, in usbredir_do_attach()
1322 usbredirparser_peer_has_cap(dev->parser, in usbredir_do_attach()
1324 ERROR("usb-redir-host lacks capabilities needed for use with XHCI\n"); in usbredir_do_attach()
1329 usb_device_attach(&dev->dev, &local_err); in usbredir_do_attach()
1345 if (!dev->parser) { in usbredir_chardev_can_read()
1364 assert(dev->read_buf == NULL); in usbredir_chardev_read()
1366 dev->read_buf = buf; in usbredir_chardev_read()
1367 dev->read_buf_size = size; in usbredir_chardev_read()
1369 usbredirparser_do_read(dev->parser); in usbredir_chardev_read()
1371 usbredirparser_do_write(dev->parser); in usbredir_chardev_read()
1381 /* Make sure any pending closes are handled (no-op if none pending) */ in usbredir_chardev_event()
1383 qemu_bh_cancel(dev->chardev_close_bh); in usbredir_chardev_event()
1388 qemu_bh_schedule(dev->chardev_close_bh); in usbredir_chardev_event()
1406 if (running && dev->parser != NULL) { in usbredir_vm_state_change()
1407 usbredirparser_do_write(dev->parser); /* Flush any pending writes */ in usbredir_vm_state_change()
1415 usb_ep_init(&dev->dev); in usbredir_init_endpoints()
1416 memset(dev->endpoint, 0, sizeof(dev->endpoint)); in usbredir_init_endpoints()
1418 dev->endpoint[i].dev = dev; in usbredir_init_endpoints()
1419 QTAILQ_INIT(&dev->endpoint[i].bufpq); in usbredir_init_endpoints()
1428 if (!qemu_chr_fe_backend_connected(&dev->cs)) { in usbredir_realize()
1433 if (dev->filter_str) { in usbredir_realize()
1434 i = usbredirfilter_string_to_rules(dev->filter_str, ":", "|", in usbredir_realize()
1435 &dev->filter_rules, in usbredir_realize()
1436 &dev->filter_rules_count); in usbredir_realize()
1444 dev->chardev_close_bh = qemu_bh_new_guarded(usbredir_chardev_close_bh, dev, in usbredir_realize()
1445 &DEVICE(dev)->mem_reentrancy_guard); in usbredir_realize()
1446 dev->device_reject_bh = qemu_bh_new_guarded(usbredir_device_reject_bh, dev, in usbredir_realize()
1447 &DEVICE(dev)->mem_reentrancy_guard); in usbredir_realize()
1448 dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev); in usbredir_realize()
1450 packet_id_queue_init(&dev->cancelled, dev, "cancelled"); in usbredir_realize()
1451 packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight"); in usbredir_realize()
1454 /* We'll do the attach once we receive the speed from the usb-host */ in usbredir_realize()
1455 udev->auto_attach = 0; in usbredir_realize()
1458 dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH; in usbredir_realize()
1461 qemu_chr_fe_set_handlers(&dev->cs, usbredir_chardev_can_read, in usbredir_realize()
1465 dev->vmstate = in usbredir_realize()
1473 packet_id_queue_empty(&dev->cancelled); in usbredir_cleanup_device_queues()
1474 packet_id_queue_empty(&dev->already_in_flight); in usbredir_cleanup_device_queues()
1484 qemu_chr_fe_deinit(&dev->cs, true); in usbredir_unrealize()
1487 qemu_bh_delete(dev->chardev_close_bh); in usbredir_unrealize()
1488 qemu_bh_delete(dev->device_reject_bh); in usbredir_unrealize()
1490 timer_free(dev->attach_timer); in usbredir_unrealize()
1494 if (dev->parser) { in usbredir_unrealize()
1495 usbredirparser_destroy(dev->parser); in usbredir_unrealize()
1497 if (dev->watch) { in usbredir_unrealize()
1498 g_source_remove(dev->watch); in usbredir_unrealize()
1501 free(dev->filter_rules); in usbredir_unrealize()
1502 qemu_del_vm_change_state_handler(dev->vmstate); in usbredir_unrealize()
1507 if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { in usbredir_check_filter()
1512 if (dev->filter_rules) { in usbredir_check_filter()
1513 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_check_filter()
1521 dev->filter_rules, in usbredir_check_filter()
1522 dev->filter_rules_count, in usbredir_check_filter()
1523 dev->device_info.device_class, in usbredir_check_filter()
1524 dev->device_info.device_subclass, in usbredir_check_filter()
1525 dev->device_info.device_protocol, in usbredir_check_filter()
1526 dev->interface_info.interface_class, in usbredir_check_filter()
1527 dev->interface_info.interface_subclass, in usbredir_check_filter()
1528 dev->interface_info.interface_protocol, in usbredir_check_filter()
1529 dev->interface_info.interface_count, in usbredir_check_filter()
1530 dev->device_info.vendor_id, in usbredir_check_filter()
1531 dev->device_info.product_id, in usbredir_check_filter()
1532 dev->device_info.device_version_bcd, in usbredir_check_filter()
1542 return -1; in usbredir_check_filter()
1549 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_check_bulk_receiving()
1555 dev->endpoint[i].bulk_receiving_enabled = 0; in usbredir_check_bulk_receiving()
1558 if (dev->interface_info.interface_count == NO_INTERFACE_INFO) { in usbredir_check_bulk_receiving()
1562 for (i = 0; i < dev->interface_info.interface_count; i++) { in usbredir_check_bulk_receiving()
1563 quirks = usb_get_quirks(dev->device_info.vendor_id, in usbredir_check_bulk_receiving()
1564 dev->device_info.product_id, in usbredir_check_bulk_receiving()
1565 dev->interface_info.interface_class[i], in usbredir_check_bulk_receiving()
1566 dev->interface_info.interface_subclass[i], in usbredir_check_bulk_receiving()
1567 dev->interface_info.interface_protocol[i]); in usbredir_check_bulk_receiving()
1572 dev->buffered_bulk_in_complete = in usbredir_check_bulk_receiving()
1575 dev->buffered_bulk_in_complete = in usbredir_check_bulk_receiving()
1580 if (dev->endpoint[j].interface == in usbredir_check_bulk_receiving()
1581 dev->interface_info.interface[i] && in usbredir_check_bulk_receiving()
1582 dev->endpoint[j].type == USB_ENDPOINT_XFER_BULK && in usbredir_check_bulk_receiving()
1583 dev->endpoint[j].max_packet_size != 0) { in usbredir_check_bulk_receiving()
1584 dev->endpoint[j].bulk_receiving_enabled = 1; in usbredir_check_bulk_receiving()
1589 I2USBEP(dev, j)->pipeline = false; in usbredir_check_bulk_receiving()
1605 p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */ in usbredir_handle_status()
1608 p->status = USB_RET_STALL; in usbredir_handle_status()
1612 * When the usbredir-host unredirects a device, it will report a status in usbredir_handle_status()
1615 p->status = USB_RET_IOERROR; in usbredir_handle_status()
1618 WARNING("got invalid param error from usb-host?\n"); in usbredir_handle_status()
1619 p->status = USB_RET_IOERROR; in usbredir_handle_status()
1622 p->status = USB_RET_BABBLE; in usbredir_handle_status()
1627 p->status = USB_RET_IOERROR; in usbredir_handle_status()
1635 /* Try to send the filter info now that we've the usb-host's caps */ in usbredir_hello()
1636 if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter) && in usbredir_hello()
1637 dev->filter_rules) { in usbredir_hello()
1638 usbredirparser_send_filter_filter(dev->parser, dev->filter_rules, in usbredir_hello()
1639 dev->filter_rules_count); in usbredir_hello()
1640 usbredirparser_do_write(dev->parser); in usbredir_hello()
1650 if (timer_pending(dev->attach_timer) || dev->dev.attached) { in usbredir_device_connect()
1655 switch (device_connect->speed) { in usbredir_device_connect()
1658 dev->dev.speed = USB_SPEED_LOW; in usbredir_device_connect()
1659 dev->compatible_speedmask &= ~USB_SPEED_MASK_FULL; in usbredir_device_connect()
1660 dev->compatible_speedmask &= ~USB_SPEED_MASK_HIGH; in usbredir_device_connect()
1664 dev->dev.speed = USB_SPEED_FULL; in usbredir_device_connect()
1665 dev->compatible_speedmask &= ~USB_SPEED_MASK_HIGH; in usbredir_device_connect()
1669 dev->dev.speed = USB_SPEED_HIGH; in usbredir_device_connect()
1673 dev->dev.speed = USB_SPEED_SUPER; in usbredir_device_connect()
1677 dev->dev.speed = USB_SPEED_FULL; in usbredir_device_connect()
1680 if (usbredirparser_peer_has_cap(dev->parser, in usbredir_device_connect()
1683 speed, device_connect->vendor_id, device_connect->product_id, in usbredir_device_connect()
1684 ((device_connect->device_version_bcd & 0xf000) >> 12) * 10 + in usbredir_device_connect()
1685 ((device_connect->device_version_bcd & 0x0f00) >> 8), in usbredir_device_connect()
1686 ((device_connect->device_version_bcd & 0x00f0) >> 4) * 10 + in usbredir_device_connect()
1687 ((device_connect->device_version_bcd & 0x000f) >> 0), in usbredir_device_connect()
1688 device_connect->device_class); in usbredir_device_connect()
1691 device_connect->vendor_id, device_connect->product_id, in usbredir_device_connect()
1692 device_connect->device_class); in usbredir_device_connect()
1695 dev->dev.speedmask = (1 << dev->dev.speed) | dev->compatible_speedmask; in usbredir_device_connect()
1696 dev->device_info = *device_connect; in usbredir_device_connect()
1700 device_connect->vendor_id, device_connect->product_id); in usbredir_device_connect()
1705 timer_mod(dev->attach_timer, dev->next_attach_time); in usbredir_device_connect()
1713 timer_del(dev->attach_timer); in usbredir_device_disconnect()
1715 if (dev->dev.attached) { in usbredir_device_disconnect()
1717 usb_device_detach(&dev->dev); in usbredir_device_disconnect()
1722 dev->next_attach_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 200; in usbredir_device_disconnect()
1728 dev->interface_info.interface_count = NO_INTERFACE_INFO; in usbredir_device_disconnect()
1729 dev->dev.addr = 0; in usbredir_device_disconnect()
1730 dev->dev.speed = 0; in usbredir_device_disconnect()
1731 dev->compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH; in usbredir_device_disconnect()
1739 dev->interface_info = *interface_info; in usbredir_interface_info()
1743 * connected (ie on a set_config), re-check interface dependent things. in usbredir_interface_info()
1745 if (timer_pending(dev->attach_timer) || dev->dev.attached) { in usbredir_interface_info()
1756 dev->compatible_speedmask &= ~(1 << speed); in usbredir_mark_speed_incompatible()
1757 dev->dev.speedmask = (1 << dev->dev.speed) | dev->compatible_speedmask; in usbredir_mark_speed_incompatible()
1762 if (uep->type != USB_ENDPOINT_XFER_BULK) { in usbredir_set_pipeline()
1765 if (uep->pid == USB_TOKEN_OUT) { in usbredir_set_pipeline()
1766 uep->pipeline = true; in usbredir_set_pipeline()
1768 if (uep->pid == USB_TOKEN_IN && uep->max_packet_size != 0 && in usbredir_set_pipeline()
1769 usbredirparser_peer_has_cap(dev->parser, in usbredir_set_pipeline()
1771 uep->pipeline = true; in usbredir_set_pipeline()
1782 usb_ep->type = dev->endpoint[i].type; in usbredir_setup_usb_eps()
1783 usb_ep->ifnum = dev->endpoint[i].interface; in usbredir_setup_usb_eps()
1784 usb_ep->max_packet_size = dev->endpoint[i].max_packet_size; in usbredir_setup_usb_eps()
1785 usb_ep->max_streams = dev->endpoint[i].max_streams; in usbredir_setup_usb_eps()
1798 dev->endpoint[i].type = ep_info->type[i]; in usbredir_ep_info()
1799 dev->endpoint[i].interval = ep_info->interval[i]; in usbredir_ep_info()
1800 dev->endpoint[i].interface = ep_info->interface[i]; in usbredir_ep_info()
1801 if (usbredirparser_peer_has_cap(dev->parser, in usbredir_ep_info()
1803 dev->endpoint[i].max_packet_size = ep_info->max_packet_size[i]; in usbredir_ep_info()
1806 if (usbredirparser_peer_has_cap(dev->parser, in usbredir_ep_info()
1808 dev->endpoint[i].max_streams = ep_info->max_streams[i]; in usbredir_ep_info()
1811 switch (dev->endpoint[i].type) { in usbredir_ep_info()
1819 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_ep_info()
1821 ep_info->max_packet_size[i] > 64) { in usbredir_ep_info()
1824 if (!usbredirparser_peer_has_cap(dev->parser, in usbredir_ep_info()
1826 ep_info->max_packet_size[i] > 1024) { in usbredir_ep_info()
1829 if (dev->endpoint[i].interval == 0) { in usbredir_ep_info()
1830 ERROR("Received 0 interval for isoc or irq endpoint\n"); in usbredir_ep_info()
1838 dev->endpoint[i].type, dev->endpoint[i].interface); in usbredir_ep_info()
1841 ERROR("Received invalid endpoint type\n"); in usbredir_ep_info()
1847 if (dev->dev.attached && in usbredir_ep_info()
1848 !(dev->dev.port->speedmask & dev->dev.speedmask)) { in usbredir_ep_info()
1849 ERROR("Device no longer matches speed after endpoint info change, " in usbredir_ep_info()
1865 config_status->status, config_status->configuration, id); in usbredir_configuration_status()
1869 if (dev->dev.setup_buf[0] & USB_DIR_IN) { in usbredir_configuration_status()
1870 dev->dev.data_buf[0] = config_status->configuration; in usbredir_configuration_status()
1871 p->actual_length = 1; in usbredir_configuration_status()
1873 usbredir_handle_status(dev, p, config_status->status); in usbredir_configuration_status()
1874 usb_generic_async_ctrl_complete(&dev->dev, p); in usbredir_configuration_status()
1885 alt_setting_status->status, alt_setting_status->interface, in usbredir_alt_setting_status()
1886 alt_setting_status->alt, id); in usbredir_alt_setting_status()
1890 if (dev->dev.setup_buf[0] & USB_DIR_IN) { in usbredir_alt_setting_status()
1891 dev->dev.data_buf[0] = alt_setting_status->alt; in usbredir_alt_setting_status()
1892 p->actual_length = 1; in usbredir_alt_setting_status()
1894 usbredir_handle_status(dev, p, alt_setting_status->status); in usbredir_alt_setting_status()
1895 usb_generic_async_ctrl_complete(&dev->dev, p); in usbredir_alt_setting_status()
1903 uint8_t ep = iso_stream_status->endpoint; in usbredir_iso_stream_status()
1905 DPRINTF("iso status %d ep %02X id %"PRIu64"\n", iso_stream_status->status, in usbredir_iso_stream_status()
1908 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) { in usbredir_iso_stream_status()
1912 dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status; in usbredir_iso_stream_status()
1913 if (iso_stream_status->status == usb_redir_stall) { in usbredir_iso_stream_status()
1915 dev->endpoint[EP2I(ep)].iso_started = 0; in usbredir_iso_stream_status()
1924 uint8_t ep = interrupt_receiving_status->endpoint; in usbredir_interrupt_receiving_status()
1927 interrupt_receiving_status->status, ep, id); in usbredir_interrupt_receiving_status()
1929 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) { in usbredir_interrupt_receiving_status()
1933 dev->endpoint[EP2I(ep)].interrupt_error = in usbredir_interrupt_receiving_status()
1934 interrupt_receiving_status->status; in usbredir_interrupt_receiving_status()
1935 if (interrupt_receiving_status->status == usb_redir_stall) { in usbredir_interrupt_receiving_status()
1937 dev->endpoint[EP2I(ep)].interrupt_started = 0; in usbredir_interrupt_receiving_status()
1947 if (bulk_streams_status->status == usb_redir_success) { in usbredir_bulk_streams_status()
1949 bulk_streams_status->status, bulk_streams_status->endpoints); in usbredir_bulk_streams_status()
1952 (bulk_streams_status->no_streams == 0) ? "free" : "alloc", in usbredir_bulk_streams_status()
1953 bulk_streams_status->status, bulk_streams_status->endpoints); in usbredir_bulk_streams_status()
1954 ERROR("usb-redir-host does not provide streams, disconnecting\n"); in usbredir_bulk_streams_status()
1964 uint8_t ep = bulk_receiving_status->endpoint; in usbredir_bulk_receiving_status()
1967 bulk_receiving_status->status, ep, id); in usbredir_bulk_receiving_status()
1969 if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].bulk_receiving_started) { in usbredir_bulk_receiving_status()
1973 if (bulk_receiving_status->status == usb_redir_stall) { in usbredir_bulk_receiving_status()
1975 dev->endpoint[EP2I(ep)].bulk_receiving_started = 0; in usbredir_bulk_receiving_status()
1985 int len = control_packet->length; in usbredir_control_packet()
1987 DPRINTF("ctrl-in status %d len %d id %"PRIu64"\n", control_packet->status, in usbredir_control_packet()
1990 /* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices in usbredir_control_packet()
1992 if (dev->dev.speed == USB_SPEED_SUPER && in usbredir_control_packet()
1993 !((dev->dev.port->speedmask & USB_SPEED_MASK_SUPER)) && in usbredir_control_packet()
1994 control_packet->requesttype == 0x80 && in usbredir_control_packet()
1995 control_packet->request == 6 && in usbredir_control_packet()
1996 control_packet->value == 0x100 && control_packet->index == 0 && in usbredir_control_packet()
2003 usbredir_handle_status(dev, p, control_packet->status); in usbredir_control_packet()
2006 if (data_len > sizeof(dev->dev.data_buf)) { in usbredir_control_packet()
2008 data_len, sizeof(dev->dev.data_buf)); in usbredir_control_packet()
2009 p->status = USB_RET_STALL; in usbredir_control_packet()
2010 data_len = len = sizeof(dev->dev.data_buf); in usbredir_control_packet()
2012 memcpy(dev->dev.data_buf, data, data_len); in usbredir_control_packet()
2014 p->actual_length = len; in usbredir_control_packet()
2017 * remove 'remote wakeup' flag from it to prevent idle power down in usbredir_control_packet()
2020 if (dev->suppress_remote_wake && in usbredir_control_packet()
2021 control_packet->requesttype == USB_DIR_IN && in usbredir_control_packet()
2022 control_packet->request == USB_REQ_GET_DESCRIPTOR && in usbredir_control_packet()
2023 control_packet->value == (USB_DT_CONFIG << 8) && in usbredir_control_packet()
2024 control_packet->index == 0 && in usbredir_control_packet()
2026 len > 7 && (dev->dev.data_buf[7] & USB_CFG_ATT_WAKEUP)) { in usbredir_control_packet()
2027 DPRINTF("Removed remote wake %04X:%04X\n", in usbredir_control_packet()
2028 dev->device_info.vendor_id, in usbredir_control_packet()
2029 dev->device_info.product_id); in usbredir_control_packet()
2030 dev->dev.data_buf[7] &= ~USB_CFG_ATT_WAKEUP; in usbredir_control_packet()
2032 usb_generic_async_ctrl_complete(&dev->dev, p); in usbredir_control_packet()
2042 uint8_t ep = bulk_packet->endpoint; in usbredir_bulk_packet()
2043 int len = (bulk_packet->length_high << 16) | bulk_packet->length; in usbredir_bulk_packet()
2046 DPRINTF("bulk-in status %d ep %02X stream %u len %d id %"PRIu64"\n", in usbredir_bulk_packet()
2047 bulk_packet->status, ep, bulk_packet->stream_id, len, id); in usbredir_bulk_packet()
2052 usbredir_handle_status(dev, p, bulk_packet->status); in usbredir_bulk_packet()
2057 data_len, p->iov.size); in usbredir_bulk_packet()
2058 p->status = USB_RET_BABBLE; in usbredir_bulk_packet()
2063 p->actual_length = len; in usbredir_bulk_packet()
2064 if (p->pid == USB_TOKEN_IN && p->ep->pipeline) { in usbredir_bulk_packet()
2065 usb_combined_input_packet_complete(&dev->dev, p); in usbredir_bulk_packet()
2067 usb_packet_complete(&dev->dev, p); in usbredir_bulk_packet()
2078 uint8_t ep = iso_packet->endpoint; in usbredir_iso_packet()
2080 DPRINTF2("iso-in status %d ep %02X len %d id %"PRIu64"\n", in usbredir_iso_packet()
2081 iso_packet->status, ep, data_len, id); in usbredir_iso_packet()
2083 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) { in usbredir_iso_packet()
2084 ERROR("received iso packet for non iso endpoint %02X\n", ep); in usbredir_iso_packet()
2089 if (dev->endpoint[EP2I(ep)].iso_started == 0) { in usbredir_iso_packet()
2096 bufp_alloc(dev, data, data_len, iso_packet->status, ep, data); in usbredir_iso_packet()
2104 uint8_t ep = interrupt_packet->endpoint; in usbredir_interrupt_packet()
2106 DPRINTF("interrupt-in status %d ep %02X len %d id %"PRIu64"\n", in usbredir_interrupt_packet()
2107 interrupt_packet->status, ep, data_len, id); in usbredir_interrupt_packet()
2109 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) { in usbredir_interrupt_packet()
2110 ERROR("received int packet for non interrupt endpoint %02X\n", ep); in usbredir_interrupt_packet()
2116 if (dev->endpoint[EP2I(ep)].interrupt_started == 0) { in usbredir_interrupt_packet()
2123 bufp_alloc(dev, data, data_len, interrupt_packet->status, ep, data); in usbredir_interrupt_packet()
2126 usb_wakeup(usb_ep_get(&dev->dev, USB_TOKEN_IN, ep & 0x0f), 0); in usbredir_interrupt_packet()
2132 if (interrupt_packet->status) { in usbredir_interrupt_packet()
2134 interrupt_packet->status, ep, id); in usbredir_interrupt_packet()
2144 uint8_t status, ep = buffered_bulk_packet->endpoint; in usbredir_buffered_bulk_packet()
2148 DPRINTF("buffered-bulk-in status %d ep %02X len %d id %"PRIu64"\n", in usbredir_buffered_bulk_packet()
2149 buffered_bulk_packet->status, ep, data_len, id); in usbredir_buffered_bulk_packet()
2151 if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_BULK) { in usbredir_buffered_bulk_packet()
2152 ERROR("received buffered-bulk packet for non bulk ep %02X\n", ep); in usbredir_buffered_bulk_packet()
2157 if (dev->endpoint[EP2I(ep)].bulk_receiving_started == 0) { in usbredir_buffered_bulk_packet()
2158 DPRINTF("received buffered-bulk packet on not started ep %02X\n", ep); in usbredir_buffered_bulk_packet()
2164 len = dev->endpoint[EP2I(ep)].max_packet_size; in usbredir_buffered_bulk_packet()
2169 if (len >= (data_len - i)) { in usbredir_buffered_bulk_packet()
2170 len = data_len - i; in usbredir_buffered_bulk_packet()
2171 status = buffered_bulk_packet->status; in usbredir_buffered_bulk_packet()
2181 if (dev->endpoint[EP2I(ep)].pending_async_packet) { in usbredir_buffered_bulk_packet()
2182 USBPacket *p = dev->endpoint[EP2I(ep)].pending_async_packet; in usbredir_buffered_bulk_packet()
2183 dev->endpoint[EP2I(ep)].pending_async_packet = NULL; in usbredir_buffered_bulk_packet()
2185 usb_packet_complete(&dev->dev, p); in usbredir_buffered_bulk_packet()
2206 if (dev == NULL || dev->parser == NULL) { in usbredir_post_load()
2210 switch (dev->device_info.speed) { in usbredir_post_load()
2212 dev->dev.speed = USB_SPEED_LOW; in usbredir_post_load()
2215 dev->dev.speed = USB_SPEED_FULL; in usbredir_post_load()
2218 dev->dev.speed = USB_SPEED_HIGH; in usbredir_post_load()
2221 dev->dev.speed = USB_SPEED_SUPER; in usbredir_post_load()
2224 dev->dev.speed = USB_SPEED_FULL; in usbredir_post_load()
2226 dev->dev.speedmask = (1 << dev->dev.speed); in usbredir_post_load()
2242 if (dev->parser == NULL) { in usbredir_put_parser()
2247 usbredirparser_serialize(dev->parser, &data, &len); in usbredir_put_parser()
2281 if (dev->parser == NULL) { in usbredir_get_parser()
2282 WARNING("usb-redir connection broken during migration\n"); in usbredir_get_parser()
2284 qemu_bh_schedule(dev->chardev_close_bh); in usbredir_get_parser()
2290 ret = usbredirparser_unserialize(dev->parser, data, len); in usbredir_get_parser()
2298 .name = "usb-redir-parser",
2309 USBRedirDevice *dev = endp->dev; in usbredir_put_bufpq()
2313 qemu_put_be32(f, endp->bufpq_size); in usbredir_put_bufpq()
2314 QTAILQ_FOREACH(bufp, &endp->bufpq, next) { in usbredir_put_bufpq()
2315 len = bufp->len - bufp->offset; in usbredir_put_bufpq()
2316 DPRINTF("put_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size, in usbredir_put_bufpq()
2317 len, bufp->status); in usbredir_put_bufpq()
2319 qemu_put_be32(f, bufp->status); in usbredir_put_bufpq()
2320 qemu_put_buffer(f, bufp->data + bufp->offset, len); in usbredir_put_bufpq()
2323 assert(i == endp->bufpq_size); in usbredir_put_bufpq()
2332 USBRedirDevice *dev = endp->dev; in usbredir_get_bufpq()
2336 endp->bufpq_size = qemu_get_be32(f); in usbredir_get_bufpq()
2337 for (i = 0; i < endp->bufpq_size; i++) { in usbredir_get_bufpq()
2339 bufp->len = qemu_get_be32(f); in usbredir_get_bufpq()
2340 bufp->status = qemu_get_be32(f); in usbredir_get_bufpq()
2341 bufp->offset = 0; in usbredir_get_bufpq()
2342 bufp->data = malloc(bufp->len); /* regular malloc! */ in usbredir_get_bufpq()
2343 if (!bufp->data) { in usbredir_get_bufpq()
2347 bufp->free_on_destroy = bufp->data; in usbredir_get_bufpq()
2348 qemu_get_buffer(f, bufp->data, bufp->len); in usbredir_get_bufpq()
2349 QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next); in usbredir_get_bufpq()
2350 DPRINTF("get_bufpq %d/%d len %d status %d\n", i + 1, endp->bufpq_size, in usbredir_get_bufpq()
2351 bufp->len, bufp->status); in usbredir_get_bufpq()
2357 .name = "usb-redir-bufpq",
2368 return endp->bulk_receiving_started; in usbredir_bulk_receiving_needed()
2372 .name = "usb-redir-ep/bulk-receiving",
2386 return endp->max_streams; in usbredir_stream_needed()
2390 .name = "usb-redir-ep/stream-state",
2401 .name = "usb-redir-ep",
2441 USBRedirDevice *dev = q->dev; in usbredir_put_packet_id_q()
2443 int remain = q->size; in usbredir_put_packet_id_q()
2445 DPRINTF("put_packet_id_q %s size %d\n", q->name, q->size); in usbredir_put_packet_id_q()
2446 qemu_put_be32(f, q->size); in usbredir_put_packet_id_q()
2447 QTAILQ_FOREACH(e, &q->head, next) { in usbredir_put_packet_id_q()
2448 qemu_put_be64(f, e->id); in usbredir_put_packet_id_q()
2449 remain--; in usbredir_put_packet_id_q()
2460 USBRedirDevice *dev = q->dev; in usbredir_get_packet_id_q()
2465 DPRINTF("get_packet_id_q %s size %d\n", q->name, size); in usbredir_get_packet_id_q()
2470 assert(q->size == size); in usbredir_get_packet_id_q()
2475 .name = "usb-redir-packet-id-q",
2481 .name = "usb-redir-packet-id-queue",
2501 .name = "usb-redir-device-info",
2520 .name = "usb-redir-interface-info",
2541 .name = "usb-redir",
2558 VMSTATE_STRUCT_ARRAY(endpoint, USBRedirDevice, MAX_ENDPOINTS, 1,
2581 DEFINE_PROP_BOOL("suppress-remote-wake", USBRedirDevice,
2590 uc->realize = usbredir_realize; in usbredir_class_initfn()
2591 uc->product_desc = "USB Redirection Device"; in usbredir_class_initfn()
2592 uc->unrealize = usbredir_unrealize; in usbredir_class_initfn()
2593 uc->cancel_packet = usbredir_cancel_packet; in usbredir_class_initfn()
2594 uc->handle_reset = usbredir_handle_reset; in usbredir_class_initfn()
2595 uc->handle_data = usbredir_handle_data; in usbredir_class_initfn()
2596 uc->handle_control = usbredir_handle_control; in usbredir_class_initfn()
2597 uc->flush_ep_queue = usbredir_flush_ep_queue; in usbredir_class_initfn()
2598 uc->ep_stopped = usbredir_ep_stopped; in usbredir_class_initfn()
2599 uc->alloc_streams = usbredir_alloc_streams; in usbredir_class_initfn()
2600 uc->free_streams = usbredir_free_streams; in usbredir_class_initfn()
2601 dc->vmsd = &usbredir_vmstate; in usbredir_class_initfn()
2603 set_bit(DEVICE_CATEGORY_MISC, dc->categories); in usbredir_class_initfn()
2611 device_add_bootindex_property(obj, &dev->bootindex, in usbredir_instance_init()
2613 &udev->qdev); in usbredir_instance_init()