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,7 +635,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
635 635
636 dprintf("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n", 636 dprintf("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n",
637 pid2str(p->pid), p->devaddr, p->devep, p->len); 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 dump_data(p->data, p->len); 639 dump_data(p->data, p->len);
640 640
641 ret = USB_RET_NODEV; 641 ret = USB_RET_NODEV;
@@ -755,7 +755,7 @@ out: @@ -755,7 +755,7 @@ out:
755 static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask) 755 static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
756 { 756 {
757 UHCIAsync *async; 757 UHCIAsync *async;
758 - int len = 0, max_len, ret = 0; 758 + int len = 0, max_len;
759 uint8_t pid; 759 uint8_t pid;
760 760
761 /* Is active ? */ 761 /* Is active ? */
@@ -798,12 +798,13 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in @@ -798,12 +798,13 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
798 case USB_TOKEN_OUT: 798 case USB_TOKEN_OUT:
799 case USB_TOKEN_SETUP: 799 case USB_TOKEN_SETUP:
800 cpu_physical_memory_read(td->buffer, async->buffer, max_len); 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 break; 804 break;
804 805
805 case USB_TOKEN_IN: 806 case USB_TOKEN_IN:
806 - ret = uhci_broadcast_packet(s, &async->packet); 807 + len = uhci_broadcast_packet(s, &async->packet);
807 break; 808 break;
808 809
809 default: 810 default:
@@ -814,17 +815,17 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in @@ -814,17 +815,17 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in
814 return -1; 815 return -1;
815 } 816 }
816 817
817 - if (ret == USB_RET_ASYNC) { 818 + if (len == USB_RET_ASYNC) {
818 uhci_async_link(s, async); 819 uhci_async_link(s, async);
819 return 2; 820 return 2;
820 } 821 }
821 822
822 - async->packet.len = ret; 823 + async->packet.len = len;
823 824
824 done: 825 done:
825 - ret = uhci_complete_td(s, td, async, int_mask); 826 + len = uhci_complete_td(s, td, async, int_mask);
826 uhci_async_free(s, async); 827 uhci_async_free(s, async);
827 - return ret; 828 + return len;
828 } 829 }
829 830
830 static void uhci_async_complete(USBPacket *packet, void *opaque) 831 static void uhci_async_complete(USBPacket *packet, void *opaque)