Add quirk for frame rollover specific to VirtualBox

It rolls over frames faster than it reports. This causes that
timeout on operations is too short and certain transfer fails.
Without this fix, installation process to pen driver under
VirtualBox will always lead some error when copying files
at a random moment.
This commit is contained in:
deadwood 2021-02-19 16:38:41 +01:00
parent 64f5a8f3a4
commit 0459242611
3 changed files with 18 additions and 4 deletions

View File

@ -338,7 +338,8 @@ void ehciHandleFinishedTDs(struct PCIController *hc) {
etd = eqh->eqh_FirstTD;
eqh->eqh_NextTD = etd->etd_Self;
SYNC;
unit->hu_NakTimeoutFrame[devadrep] = (ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<3) : 0;
unit->hu_NakTimeoutFrame[devadrep] =
(ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<hc->hc_EhciTimeoutShift) : 0;
}
else
{
@ -661,7 +662,8 @@ void ehciScheduleCtrlTDs(struct PCIController *hc) {
// manage endpoint going busy
unit->hu_DevBusyReq[devadrep] = ioreq;
unit->hu_NakTimeoutFrame[devadrep] = (ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<3) : 0;
unit->hu_NakTimeoutFrame[devadrep] =
(ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<hc->hc_EhciTimeoutShift) : 0;
Disable();
AddTail(&hc->hc_TDQueue, (struct Node *) ioreq);
@ -882,7 +884,8 @@ void ehciScheduleIntTDs(struct PCIController *hc) {
// manage endpoint going busy
unit->hu_DevBusyReq[devadrep] = ioreq;
unit->hu_NakTimeoutFrame[devadrep] = (ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<3) : 0;
unit->hu_NakTimeoutFrame[devadrep] =
(ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<hc->hc_EhciTimeoutShift) : 0;
Disable();
AddTail(&hc->hc_PeriodicTDQueue, (struct Node *) ioreq);
@ -1071,7 +1074,8 @@ void ehciScheduleBulkTDs(struct PCIController *hc) {
// manage endpoint going busy
unit->hu_DevBusyReq[devadrep] = ioreq;
unit->hu_NakTimeoutFrame[devadrep] = (ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<3) : 0;
unit->hu_NakTimeoutFrame[devadrep] =
(ioreq->iouh_Flags & UHFF_NAKTIMEOUT) ? hc->hc_FrameCounter + (ioreq->iouh_NakTimeout<<hc->hc_EhciTimeoutShift) : 0;
Disable();
AddTail(&hc->hc_TDQueue, (struct Node *) ioreq);
@ -1526,6 +1530,10 @@ BOOL ehciInit(struct PCIController *hc, struct PCIUnit *hu) {
(hccparams & EHCF_ASYNCSCHEDPARK) ? "Yes" : "No"));
hc->hc_EhciUsbCmd = (1UL<<EHUS_INTTHRESHOLD);
hc->hc_EhciTimeoutShift = 3;
if (hc->hc_Quirks & HCQ_EHCI_VBOX_FRAMEROOLOVER) {
hc->hc_EhciTimeoutShift += 2;
}
/* FIXME HERE: Process EHCF_64BITS flag and implement 64-bit addressing */

View File

@ -51,6 +51,9 @@ static void handleQuirks(struct PCIController *hc)
{
/* This is needed for EHCI to work in VirtualBox */
hc->hc_Quirks &= ~(HCQ_EHCI_OVERLAY_CTRL_FILL|HCQ_EHCI_OVERLAY_INT_FILL|HCQ_EHCI_OVERLAY_BULK_FILL);
/* VirtualBox reports frame list size of 1024, but still issues interrupts at
speed of around 4 per second instead of ever 1024 ms */
hc->hc_Quirks |= HCQ_EHCI_VBOX_FRAMEROOLOVER;
}
}

View File

@ -139,6 +139,8 @@ struct PCIController
volatile BOOL hc_AsyncAdvanced;
struct EhciQH *hc_EhciAsyncFreeQH;
struct EhciTD *hc_ShortPktEndTD;
UWORD hc_EhciTimeoutShift;
struct OhciED *hc_OhciCtrlHeadED;
struct OhciED *hc_OhciCtrlTailED;
@ -186,6 +188,7 @@ struct PCIController
#define HCQ_EHCI_OVERLAY_CTRL_FILL (1 << 0)
#define HCQ_EHCI_OVERLAY_INT_FILL (1 << 1)
#define HCQ_EHCI_OVERLAY_BULK_FILL (1 << 2)
#define HCQ_EHCI_VBOX_FRAMEROOLOVER (1 << 3)
/* The device node - private