mirror of https://github.com/xemu-project/xemu.git
[Core Change] Port USB fixes from XQEMU 1.x
commit761d06bab6
Author: espes <espes@pequalsnp.com> Date: Thu Sep 5 01:45:37 2013 +1000 ohci: fix handling of transfer underruns See: https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/USB/DevOHCI.cpp#L2343 https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/USB/DevOHCI.cpp#L2363 commitd532051a8e
Author: espes <espes@pequalsnp.com> Date: Mon Oct 19 17:38:38 2015 +1100 usb hub: don't return an overrun when there's no new status
This commit is contained in:
parent
eb4c0f18e9
commit
0ed317ff4b
|
@ -477,13 +477,6 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
|
|||
unsigned int status;
|
||||
uint8_t buf[4];
|
||||
int i, n;
|
||||
n = DIV_ROUND_UP(NUM_PORTS + 1, 8);
|
||||
if (p->iov.size == 1) { /* FreeBSD workaround */
|
||||
n = 1;
|
||||
} else if (n > p->iov.size) {
|
||||
p->status = USB_RET_BABBLE;
|
||||
return;
|
||||
}
|
||||
status = 0;
|
||||
for(i = 0; i < NUM_PORTS; i++) {
|
||||
port = &s->ports[i];
|
||||
|
@ -491,6 +484,13 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
|
|||
status |= (1 << (i + 1));
|
||||
}
|
||||
if (status != 0) {
|
||||
n = DIV_ROUND_UP(NUM_PORTS + 1, 8);
|
||||
if (p->iov.size == 1) { /* FreeBSD workaround */
|
||||
n = 1;
|
||||
} else if (n > p->iov.size) {
|
||||
p->status = USB_RET_BABBLE;
|
||||
return;
|
||||
}
|
||||
trace_usb_hub_status_report(s->dev.addr, status);
|
||||
for(i = 0; i < n; i++) {
|
||||
buf[i] = status >> (8 * i);
|
||||
|
|
|
@ -1102,17 +1102,19 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||
}
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
if ((td.cbp & 0xfff) + ret > 0xfff) {
|
||||
td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
|
||||
} else {
|
||||
td.cbp += ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Writeback */
|
||||
if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
|
||||
/* Transmission succeeded. */
|
||||
if (ret == len) {
|
||||
td.cbp = 0;
|
||||
} else {
|
||||
if ((td.cbp & 0xfff) + ret > 0xfff) {
|
||||
td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
|
||||
} else {
|
||||
td.cbp += ret;
|
||||
}
|
||||
}
|
||||
td.flags |= OHCI_TD_T1;
|
||||
td.flags ^= OHCI_TD_T0;
|
||||
|
@ -1168,6 +1170,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||
i = OHCI_BM(td.flags, TD_DI);
|
||||
if (i < ohci->done_count)
|
||||
ohci->done_count = i;
|
||||
if (OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR)
|
||||
ohci->done_count = 0;
|
||||
exit_no_retire:
|
||||
if (ohci_put_td(ohci, addr, &td)) {
|
||||
ohci_die(ohci);
|
||||
|
|
Loading…
Reference in New Issue