diff options
Diffstat (limited to 'hw/usb/hcd-uhci.c')
-rw-r--r-- | hw/usb/hcd-uhci.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index f4b555a..2838d21 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -780,22 +780,21 @@ static int uhci_handle_td_error(UHCIState *s, UHCI_TD *td, uint32_t td_addr, static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask) { - int len = 0, max_len, ret; + int len = 0, max_len; uint8_t pid; max_len = ((td->token >> 21) + 1) & 0x7ff; pid = td->token & 0xff; - ret = async->packet.result; - if (td->ctrl & TD_CTRL_IOS) td->ctrl &= ~TD_CTRL_ACTIVE; - if (ret < 0) { - return uhci_handle_td_error(s, td, async->td_addr, ret, int_mask); + if (async->packet.status != USB_RET_SUCCESS) { + return uhci_handle_td_error(s, td, async->td_addr, + async->packet.status, int_mask); } - len = async->packet.result; + len = async->packet.actual_length; td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff); /* The NAK bit may have been set by a previous frame, so clear it @@ -824,7 +823,7 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, UHCI_TD *td, uint32_t td_addr, uint32_t *int_mask) { - int len = 0, max_len; + int ret, max_len; bool spd; bool queuing = (q != NULL); uint8_t pid = td->token & 0xff; @@ -915,13 +914,14 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, switch(pid) { case USB_TOKEN_OUT: case USB_TOKEN_SETUP: - len = usb_handle_packet(q->ep->dev, &async->packet); - if (len >= 0) - len = max_len; + usb_handle_packet(q->ep->dev, &async->packet); + if (async->packet.status == USB_RET_SUCCESS) { + async->packet.actual_length = max_len; + } break; case USB_TOKEN_IN: - len = usb_handle_packet(q->ep->dev, &async->packet); + usb_handle_packet(q->ep->dev, &async->packet); break; default: @@ -932,8 +932,8 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, uhci_update_irq(s); return TD_RESULT_STOP_FRAME; } - - if (len == USB_RET_ASYNC) { + + if (async->packet.status == USB_RET_ASYNC) { uhci_async_link(async); if (!queuing) { uhci_queue_fill(q, td); @@ -941,13 +941,11 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr, return TD_RESULT_ASYNC_START; } - async->packet.result = len; - done: - len = uhci_complete_td(s, td, async, int_mask); + ret = uhci_complete_td(s, td, async, int_mask); usb_packet_unmap(&async->packet, &async->sgl); uhci_async_free(async); - return len; + return ret; } static void uhci_async_complete(USBPort *port, USBPacket *packet) @@ -955,7 +953,7 @@ static void uhci_async_complete(USBPort *port, USBPacket *packet) UHCIAsync *async = container_of(packet, UHCIAsync, packet); UHCIState *s = async->queue->uhci; - if (packet->result == USB_RET_REMOVE_FROM_QUEUE) { + if (packet->status == USB_RET_REMOVE_FROM_QUEUE) { uhci_async_unlink(async); uhci_async_cancel(async); return; |