diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-01-23 14:40:45 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-01-23 14:40:45 +0000 |
| commit | e93c65a6c64fa18b0c61fb9338d364cbea32b6ef (patch) | |
| tree | 5f1c30bca7461c74fdb80ae941adae550aea8d1b /hw/usb/core.c | |
| parent | 0e32462630687a18039464511bd0447ada5709c3 (diff) | |
| parent | 2980a316734c420e7398aec026909dcfc8614c1d (diff) | |
| download | focaccia-qemu-e93c65a6c64fa18b0c61fb9338d364cbea32b6ef.tar.gz focaccia-qemu-e93c65a6c64fa18b0c61fb9338d364cbea32b6ef.zip | |
Merge remote-tracking branch 'remotes/kraxel/tags/usb-20210122-pull-request' into staging
usb: cleanups and fixes. usb: add pcap support. # gpg: Signature made Fri 22 Jan 2021 17:48:35 GMT # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20210122-pull-request: usb-host: map LIBUSB_SPEED_SUPER_PLUS to USB_SPEED_SUPER usb: add pcap support. hw/usb/dev-uas: Report command additional adb length as unsupported scsi/utils: Add INVALID_PARAM_VALUE sense code definition hw/usb/hcd-xhci: Fix extraneous format-truncation error on 32-bit hosts hw/usb: Convert to qdev_realize() hw/usb: Fix bad printf format specifiers hw/usb/host-libusb.c: fix build with kernel < 5.0 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/usb/core.c')
| -rw-r--r-- | hw/usb/core.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/hw/usb/core.c b/hw/usb/core.c index e960036f4d..975f76250a 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -142,7 +142,7 @@ static void do_token_setup(USBDevice *s, USBPacket *p) setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6]; if (setup_len > sizeof(s->data_buf)) { fprintf(stderr, - "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n", + "usb_generic_handle_packet: ctrl buffer too small (%u > %zu)\n", setup_len, sizeof(s->data_buf)); p->status = USB_RET_STALL; return; @@ -154,6 +154,7 @@ static void do_token_setup(USBDevice *s, USBPacket *p) index = (s->setup_buf[5] << 8) | s->setup_buf[4]; if (s->setup_buf[0] & USB_DIR_IN) { + usb_pcap_ctrl(p, true); usb_device_handle_control(s, p, request, value, index, s->setup_len, s->data_buf); if (p->status == USB_RET_ASYNC) { @@ -190,6 +191,7 @@ static void do_token_in(USBDevice *s, USBPacket *p) switch(s->setup_state) { case SETUP_STATE_ACK: if (!(s->setup_buf[0] & USB_DIR_IN)) { + usb_pcap_ctrl(p, true); usb_device_handle_control(s, p, request, value, index, s->setup_len, s->data_buf); if (p->status == USB_RET_ASYNC) { @@ -197,6 +199,7 @@ static void do_token_in(USBDevice *s, USBPacket *p) } s->setup_state = SETUP_STATE_IDLE; p->actual_length = 0; + usb_pcap_ctrl(p, false); } break; @@ -215,6 +218,7 @@ static void do_token_in(USBDevice *s, USBPacket *p) } s->setup_state = SETUP_STATE_IDLE; p->status = USB_RET_STALL; + usb_pcap_ctrl(p, false); break; default: @@ -230,6 +234,7 @@ static void do_token_out(USBDevice *s, USBPacket *p) case SETUP_STATE_ACK: if (s->setup_buf[0] & USB_DIR_IN) { s->setup_state = SETUP_STATE_IDLE; + usb_pcap_ctrl(p, false); /* transfer OK */ } else { /* ignore additional output */ @@ -251,6 +256,7 @@ static void do_token_out(USBDevice *s, USBPacket *p) } s->setup_state = SETUP_STATE_IDLE; p->status = USB_RET_STALL; + usb_pcap_ctrl(p, false); break; default: @@ -277,7 +283,7 @@ static void do_parameter(USBDevice *s, USBPacket *p) setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6]; if (setup_len > sizeof(s->data_buf)) { fprintf(stderr, - "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n", + "usb_generic_handle_packet: ctrl buffer too small (%u > %zu)\n", setup_len, sizeof(s->data_buf)); p->status = USB_RET_STALL; return; @@ -288,6 +294,7 @@ static void do_parameter(USBDevice *s, USBPacket *p) usb_packet_copy(p, s->data_buf, s->setup_len); } + usb_pcap_ctrl(p, true); usb_device_handle_control(s, p, request, value, index, s->setup_len, s->data_buf); if (p->status == USB_RET_ASYNC) { @@ -301,6 +308,7 @@ static void do_parameter(USBDevice *s, USBPacket *p) p->actual_length = 0; usb_packet_copy(p, s->data_buf, s->setup_len); } + usb_pcap_ctrl(p, false); } /* ctrl complete function for devices which use usb_generic_handle_packet and @@ -311,6 +319,7 @@ void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p) { if (p->status < 0) { s->setup_state = SETUP_STATE_IDLE; + usb_pcap_ctrl(p, false); } switch (s->setup_state) { @@ -325,6 +334,7 @@ void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p) case SETUP_STATE_ACK: s->setup_state = SETUP_STATE_IDLE; p->actual_length = 0; + usb_pcap_ctrl(p, false); break; case SETUP_STATE_PARAM: @@ -359,12 +369,14 @@ USBDevice *usb_find_device(USBPort *port, uint8_t addr) static void usb_process_one(USBPacket *p) { USBDevice *dev = p->ep->dev; + bool nak; /* * Handlers expect status to be initialized to USB_RET_SUCCESS, but it * can be USB_RET_NAK here from a previous usb_process_one() call, * or USB_RET_ASYNC from going through usb_queue_one(). */ + nak = (p->status == USB_RET_NAK); p->status = USB_RET_SUCCESS; if (p->ep->nr == 0) { @@ -388,6 +400,9 @@ static void usb_process_one(USBPacket *p) } } else { /* data pipe */ + if (!nak) { + usb_pcap_data(p, true); + } usb_device_handle_data(dev, p); } } @@ -439,6 +454,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p) assert(p->stream || !p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue)); if (p->status != USB_RET_NAK) { + usb_pcap_data(p, false); usb_packet_set_state(p, USB_PACKET_COMPLETE); } } @@ -458,6 +474,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p) (p->short_not_ok && (p->actual_length < p->iov.size))) { ep->halted = true; } + usb_pcap_data(p, false); usb_packet_set_state(p, USB_PACKET_COMPLETE); QTAILQ_REMOVE(&ep->queue, p, queue); dev->port->ops->complete(dev->port, p); |