Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OHCI Toggle function #82

Merged
merged 1 commit into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions bochs/iodev/usb/usb_ohci.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ void bx_usb_ohci_c::process_lists(void)
bool bx_usb_ohci_c::process_ed(struct OHCI_ED *ed, const Bit32u ed_address)
{
struct OHCI_TD cur_td;
int toggle;
bool ret = 0;

if (!ED_GET_H(ed) && !ED_GET_K(ed) && (ED_GET_HEADP(ed) != ED_GET_TAILP(ed))) {
Expand All @@ -1171,12 +1172,20 @@ bool bx_usb_ohci_c::process_ed(struct OHCI_ED *ed, const Bit32u ed_address)
BX_DEBUG(("Found a valid ED that points to an control/bulk/int TD"));
ret = 1;
while (ED_GET_HEADP(ed) != ED_GET_TAILP(ed)) {
toggle = ED_GET_C(ed);
DEV_MEM_READ_PHYSICAL(ED_GET_HEADP(ed), 4, (Bit8u*) &cur_td.dword0);
DEV_MEM_READ_PHYSICAL(ED_GET_HEADP(ed) + 4, 4, (Bit8u*) &cur_td.dword1);
DEV_MEM_READ_PHYSICAL(ED_GET_HEADP(ed) + 8, 4, (Bit8u*) &cur_td.dword2);
DEV_MEM_READ_PHYSICAL(ED_GET_HEADP(ed) + 12, 4, (Bit8u*) &cur_td.dword3);
BX_DEBUG(("Head: 0x%08X Tail: 0x%08X Next: 0x%08X", ED_GET_HEADP(ed), ED_GET_TAILP(ed), TD_GET_NEXTTD(&cur_td)));
if (process_td(&cur_td, ed)) {
if (TD_GET_T(&cur_td) & 2)
toggle = TD_GET_T(&cur_td) & 1;
int td_ret = process_td(&cur_td, ed, toggle);
if (td_ret == 0) {
// USB_RET_ASYNC or already processed TD, so done with ED (for now)
break;
} else if (td_ret > 0) {
// Processed TD with no error
const Bit32u temp = ED_GET_HEADP(ed);
if (TD_GET_CC(&cur_td) < NotAccessed) {
ED_SET_HEADP(ed, TD_GET_NEXTTD(&cur_td));
Expand All @@ -1185,11 +1194,15 @@ bool bx_usb_ohci_c::process_ed(struct OHCI_ED *ed, const Bit32u ed_address)
if (TD_GET_DI(&cur_td) < BX_OHCI_THIS hub.ohci_done_count)
BX_OHCI_THIS hub.ohci_done_count = TD_GET_DI(&cur_td);
}
ED_SET_C(ed, toggle ^ 1);
DEV_MEM_WRITE_PHYSICAL(temp, 4, (Bit8u*) &cur_td.dword0);
DEV_MEM_WRITE_PHYSICAL(temp + 4, 4, (Bit8u*) &cur_td.dword1);
DEV_MEM_WRITE_PHYSICAL(temp + 8, 4, (Bit8u*) &cur_td.dword2);
} else
} else {
// Processed TD with error, advance the toggle anyway
ED_SET_C(ed, toggle ^ 1);
break;
}
}
}
DEV_MEM_WRITE_PHYSICAL(ed_address + 8, 4, (Bit8u*) &ed->dword2);
Expand Down Expand Up @@ -1252,10 +1265,10 @@ int bx_usb_ohci_c::event_handler(int event, void *ptr, int port)
return ret;
}

bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
int bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed, int toggle)
{
unsigned pid = 0, len = 0, len1, len2;
bool ret2 = 1;
int ret2 = 1;
int ilen, ret = 0;
Bit32u addr;
Bit16u maxlen = 0;
Expand Down Expand Up @@ -1320,7 +1333,7 @@ bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
p->packet.devep = ED_GET_EN(ed);
p->packet.speed = ED_GET_S(ed) ? USB_SPEED_LOW : USB_SPEED_FULL;
#if HANDLE_TOGGLE_CONTROL
p->packet.toggle = (TD_GET_T(td) & 2) ? ((TD_GET_T(td) & 1) > 0) : (ED_GET_C(ed) > 0);
p->packet.toggle = toggle;
#endif
p->packet.complete_cb = ohci_event_handler;
p->packet.complete_dev = this;
Expand Down Expand Up @@ -1383,11 +1396,6 @@ bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
TD_SET_CBP(td, TD_GET_CBP(td) + ret);
}
}
if (TD_GET_T(td) & 2) {
TD_SET_T(td, TD_GET_T(td) ^ 1);
ED_SET_C(ed, (TD_GET_T(td) & 1));
} else
ED_SET_C(ed, (ED_GET_C(ed) ^ 1));
if ((pid != USB_TOKEN_OUT) || (ret == (int) len)) {
TD_SET_CC(td, NoError);
TD_SET_EC(td, 0);
Expand All @@ -1401,7 +1409,6 @@ bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
TD_SET_CC(td, DeviceNotResponding);
break;
case USB_RET_NAK: // (-2)
ret2 = 0;
break;
case USB_RET_STALL: // (-3)
TD_SET_CC(td, Stall);
Expand All @@ -1413,6 +1420,7 @@ bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
BX_ERROR(("Unknown error returned: %d", ret));
break;
}
ret2 = ret;
}
if (ret != USB_RET_NAK) {
TD_SET_EC(td, 3);
Expand Down
2 changes: 1 addition & 1 deletion bochs/iodev/usb/usb_ohci.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class bx_usb_ohci_c : public bx_pci_device_c {

void process_lists();
bool process_ed(struct OHCI_ED *, const Bit32u);
bool process_td(struct OHCI_TD *, struct OHCI_ED *);
int process_td(struct OHCI_TD *, struct OHCI_ED *, int);

#if BX_USE_USB_OHCI_SMF
static bool read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
Expand Down