Commit 5d808245630e2dbbe9a330ec088af94a72601d50

Authored by aurel32
1 parent 7da76bce

uhci: Fixed length handling for SETUP and OUT tokens

Fixes regression reported agains Linux 2.6.18.
Looks like XP and newer Linux kernels are less sensitive
to length returned for control transfers.

Signed-off-by: Max Krasnyansky <maxk@kernel.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5070 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 10 additions and 9 deletions
hw/usb-uhci.c
... ... @@ -635,7 +635,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
635 635  
636 636 dprintf("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n",
637 637 pid2str(p->pid), p->devaddr, p->devep, p->len);
638   - if (p->pid == USB_TOKEN_OUT)
  638 + if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP)
639 639 dump_data(p->data, p->len);
640 640  
641 641 ret = USB_RET_NODEV;
... ... @@ -755,7 +755,7 @@ out:
755 755 static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
756 756 {
757 757 UHCIAsync *async;
758   - int len = 0, max_len, ret = 0;
  758 + int len = 0, max_len;
759 759 uint8_t pid;
760 760  
761 761 /* Is active ? */
... ... @@ -798,12 +798,13 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
798 798 case USB_TOKEN_OUT:
799 799 case USB_TOKEN_SETUP:
800 800 cpu_physical_memory_read(td->buffer, async->buffer, max_len);
801   - ret = uhci_broadcast_packet(s, &async->packet);
802   - len = max_len;
  801 + len = uhci_broadcast_packet(s, &async->packet);
  802 + if (len >= 0)
  803 + len = max_len;
803 804 break;
804 805  
805 806 case USB_TOKEN_IN:
806   - ret = uhci_broadcast_packet(s, &async->packet);
  807 + len = uhci_broadcast_packet(s, &async->packet);
807 808 break;
808 809  
809 810 default:
... ... @@ -814,17 +815,17 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
814 815 return -1;
815 816 }
816 817  
817   - if (ret == USB_RET_ASYNC) {
  818 + if (len == USB_RET_ASYNC) {
818 819 uhci_async_link(s, async);
819 820 return 2;
820 821 }
821 822  
822   - async->packet.len = ret;
  823 + async->packet.len = len;
823 824  
824 825 done:
825   - ret = uhci_complete_td(s, td, async, int_mask);
  826 + len = uhci_complete_td(s, td, async, int_mask);
826 827 uhci_async_free(s, async);
827   - return ret;
  828 + return len;
828 829 }
829 830  
830 831 static void uhci_async_complete(USBPacket *packet, void *opaque)
... ...