[USBOHCI_NEW] Zero out the transfer descriptor right after allocation.

Cleaned up transfer routines and added some more docs.
This commit is contained in:
Victor Perevertkin 2019-06-25 15:03:26 +03:00
parent 3fe397818a
commit 9004e64b57
No known key found for this signature in database
GPG key ID: C750B7222E9C7830

View file

@ -1246,6 +1246,8 @@ OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension,
TD->Flags |= OHCI_HCD_TD_FLAG_ALLOCATED;
RtlSecureZeroMemory(&TD->HwTD, sizeof(TD->HwTD));
return TD;
}
@ -1277,23 +1279,19 @@ OHCI_RemainTDs(IN POHCI_EXTENSION OhciExtension,
return RemainTDs;
}
static
MPSTATUS
NTAPI
OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint,
IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
IN POHCI_TRANSFER OhciTransfer,
IN PUSBPORT_SCATTER_GATHER_LIST SGList)
{
POHCI_HCD_TD FirstTD;
ULONG FirstTdPA;
POHCI_HCD_TD SetupTD;
POHCI_HCD_TD TD;
POHCI_HCD_TD TD2;
POHCI_HCD_TD PrevTD;
POHCI_HCD_TD NextTD;
ULONG MaxTDs;
ULONG TransferedLen;
ULONG BufferEnd;
UCHAR DataToggle;
DPRINT_OHCI("OHCI_ControlTransfer: Ext %p, Endpoint %p\n",
@ -1305,65 +1303,39 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
if ((SGList->SgElementCount + OHCI_NON_DATA_CONTROL_TDS) > MaxTDs)
return MP_STATUS_FAILURE;
FirstTD = OhciEndpoint->HcdTailP;
FirstTD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
/* Form a setup packet first */
SetupTD = OhciEndpoint->HcdTailP;
RtlSecureZeroMemory(&SetupTD->HwTD, sizeof(SetupTD->HwTD));
FirstTD->HwTD.gTD.NextTD = 0;
FirstTD->HwTD.gTD.CurrentBuffer = 0;
FirstTD->HwTD.gTD.BufferEnd = 0;
FirstTD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
FirstTD->NextHcdTD = 0;
FirstTD->OhciTransfer = OhciTransfer;
FirstTD->HwTD.Padded[0] = 0;
FirstTD->HwTD.Padded[1] = 0;
SetupTD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
SetupTD->OhciTransfer = OhciTransfer;
OhciTransfer->PendingTDs++;
RtlCopyMemory(&FirstTD->HwTD.SetupPacket,
RtlCopyMemory(&SetupTD->HwTD.SetupPacket,
&TransferParameters->SetupPacket,
sizeof(FirstTD->HwTD.SetupPacket));
sizeof(SetupTD->HwTD.SetupPacket));
FirstTdPA = FirstTD->PhysicalAddress;
SetupTD->HwTD.gTD.CurrentBuffer = SetupTD->PhysicalAddress + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket);
SetupTD->HwTD.gTD.BufferEnd = SetupTD->PhysicalAddress + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket) +
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) - 1;
SetupTD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
SetupTD->HwTD.gTD.Control.ConditionCode = OHCI_TD_CONDITION_NOT_ACCESSED;
SetupTD->HwTD.gTD.Control.DataToggle = OHCI_TD_DATA_TOGGLE_DATA0;
FirstTD->HwTD.gTD.CurrentBuffer = FirstTdPA + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket);
PrevTD = SetupTD;
BufferEnd = FirstTdPA + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket) +
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) - 1;
/* Data packets follow a setup packet (if any) */
TD = OHCI_AllocateTD(OhciExtension, OhciEndpoint);
TD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
TD->OhciTransfer = OhciTransfer;
FirstTD->HwTD.gTD.BufferEnd = BufferEnd;
PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress;
PrevTD->NextHcdTD = TD;
FirstTD->HwTD.gTD.Control.AsULONG = 0;
FirstTD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
FirstTD->HwTD.gTD.Control.ConditionCode = OHCI_TD_CONDITION_NOT_ACCESSED;
FirstTD->HwTD.gTD.Control.DataToggle = OHCI_TD_DATA_TOGGLE_DATA0;
TD2 = OHCI_AllocateTD(OhciExtension, OhciEndpoint);
TD2->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
TD2->HwTD.gTD.CurrentBuffer = 0;
TD2->HwTD.gTD.BufferEnd = 0;
TD2->HwTD.gTD.NextTD = 0;
TD2->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
TD2->NextHcdTD = 0;
TD2->OhciTransfer = OhciTransfer;
RtlZeroMemory(&TD2->HwTD.SetupPacket,
sizeof(TD2->HwTD.SetupPacket));
TD2->HwTD.Padded[0] = 0;
TD2->HwTD.Padded[1] = 0;
PrevTD = FirstTD;
TD = TD2;
PrevTD->HwTD.gTD.NextTD = TD2->PhysicalAddress;
PrevTD->NextHcdTD = TD2;
TransferedLen = 0;
/* The first data packet should use DATA1, subsequent ones use DATA0 (OpenHCI spec, 4.3.1.3.4) */
DataToggle = OHCI_TD_DATA_TOGGLE_DATA1;
TransferedLen = 0;
while (TransferedLen < TransferParameters->TransferBufferLength)
{
@ -1375,10 +1347,8 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
TD->HwTD.gTD.Control.DirectionPID = OHCI_TD_DIRECTION_PID_OUT;
TD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
TD->HwTD.gTD.Control.DataToggle = DataToggle;
TD->HwTD.gTD.Control.ConditionCode = OHCI_TD_CONDITION_NOT_ACCESSED;
DataToggle = OHCI_TD_DATA_TOGGLE_FROM_ED;
TD->HwTD.gTD.Control.DataToggle = DataToggle;
TransferedLen = OHCI_MapTransferToTD(OhciExtension,
TransferedLen,
@ -1389,26 +1359,14 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
PrevTD = TD;
TD = OHCI_AllocateTD(OhciExtension, OhciEndpoint);
TD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
TD->HwTD.gTD.NextTD = 0;
TD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
TD->NextHcdTD = 0;
TD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
TD->OhciTransfer = OhciTransfer;
TD->HwTD.gTD.CurrentBuffer = 0;
TD->HwTD.gTD.BufferEnd = 0;
RtlZeroMemory(&TD->HwTD.SetupPacket,
sizeof(TD->HwTD.SetupPacket));
TD->HwTD.Padded[0] = 0;
TD->HwTD.Padded[1] = 0;
PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress;
PrevTD->NextHcdTD = TD;
DataToggle = OHCI_TD_DATA_TOGGLE_DATA0;
}
if (TransferParameters->TransferFlags & USBD_SHORT_TRANSFER_OK)
@ -1417,16 +1375,14 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
OhciTransfer->Flags |= OHCI_TRANSFER_FLAGS_SHORT_TRANSFER_OK;
}
TD->HwTD.gTD.CurrentBuffer = 0;
TD->HwTD.gTD.BufferEnd = 0;
/* After data packets, goes a status packet */
TD->Flags |= OHCI_HCD_TD_FLAG_CONTROL_STATUS;
TD->TransferLen = 0;
TD->HwTD.gTD.Control.AsULONG = 0;
if ((TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN) != 0)
{
TD->HwTD.gTD.Control.BufferRounding = FALSE;
TD->HwTD.gTD.Control.DirectionPID = OHCI_TD_DIRECTION_PID_OUT;
}
else
@ -1435,44 +1391,37 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
TD->HwTD.gTD.Control.DirectionPID = OHCI_TD_DIRECTION_PID_IN;
}
/* OpenHCI spec, 4.3.1.3.4 */
TD->HwTD.gTD.Control.DataToggle = OHCI_TD_DATA_TOGGLE_DATA1;
TD->HwTD.gTD.Control.ConditionCode = OHCI_TD_CONDITION_NOT_ACCESSED;
TD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_IMMEDIATE;
OhciTransfer->PendingTDs++;
OhciTransfer->ControlStatusTD = TD;
NextTD = OHCI_AllocateTD(OhciExtension, OhciEndpoint);
PrevTD = TD;
TD->HwTD.gTD.NextTD = NextTD->PhysicalAddress;
TD->NextHcdTD = NextTD;
/* And the last descriptor, which is not used in the current transfer (OpenHCI spec, 4.6) */
TD = OHCI_AllocateTD(OhciExtension, OhciEndpoint);
NextTD->NextHcdTD = 0;
NextTD->HwTD.gTD.NextTD = 0;
PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress;
PrevTD->NextHcdTD = TD;
OhciTransfer->NextTD = NextTD;
OhciEndpoint->HcdTailP = NextTD;
TD->NextHcdTD = 0;
/* TD->HwTD.gTD.NextTD = 0; */
OhciEndpoint->HcdED->HwED.TailPointer = NextTD->PhysicalAddress;
OhciTransfer->NextTD = TD;
OhciEndpoint->HcdTailP = TD;
OhciEndpoint->HcdED->HwED.TailPointer = TD->PhysicalAddress;
OHCI_EnableList(OhciExtension, OhciEndpoint);
return MP_STATUS_SUCCESS;
}
/**
* @brief Creates the transfer descriptor chain for the given transfer's buffer
* and attaches it to a given endpoint (for bulk or interrupt transfers)
*
* @param[in] OhciExtension The ohci extension
* @param[in] OhciEndpoint The ohci endpoint
* @param[in] TransferParameters The transfer parameters
* @param[in] OhciTransfer The ohci transfer
* @param[in] SGList The scatter/gather list
*
* @return MP_STATUS_SUCCESS or MP_STATUS_FAILURE if there are not enough TDs left
*/
static
MPSTATUS
NTAPI
OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint,
IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
@ -1497,13 +1446,12 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
do
{
TD->HwTD.gTD.Control.AsULONG = 0;
TD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_NONE;
TD->HwTD.gTD.Control.ConditionCode = OHCI_TD_CONDITION_NOT_ACCESSED;
if (TransferParameters->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
{
TD->HwTD.gTD.Control.BufferRounding = 0;
TD->HwTD.gTD.Control.BufferRounding = FALSE;
TD->HwTD.gTD.Control.DirectionPID = OHCI_TD_DIRECTION_PID_IN;
}
else
@ -1512,19 +1460,8 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
TD->HwTD.gTD.Control.DirectionPID = OHCI_TD_DIRECTION_PID_OUT;
}
TD->HwTD.gTD.CurrentBuffer = 0;
TD->HwTD.gTD.NextTD = 0;
TD->HwTD.gTD.BufferEnd = 0;
RtlZeroMemory(&TD->HwTD.SetupPacket,
sizeof(TD->HwTD.SetupPacket));
TD->HwTD.Padded[0] = 0;
TD->HwTD.Padded[1] = 0;
TD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED;
TD->OhciTransfer = OhciTransfer;
TD->NextHcdTD = 0;
if (TransferParameters->TransferBufferLength)
{
@ -1537,10 +1474,6 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
else
{
ASSERT(SGList->SgElementCount == 0);
TD->HwTD.gTD.CurrentBuffer = 0;
TD->HwTD.gTD.BufferEnd = 0;
TD->TransferLen = 0;
}
@ -1561,13 +1494,11 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
}
PrevTD->HwTD.gTD.Control.DelayInterrupt = OHCI_TD_INTERRUPT_IMMEDIATE;
PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress;
PrevTD->NextHcdTD = TD;
/* The last TD in a chain is not used in a transfer. The controller does not access it
* so it will be used for chaining a next transfer to it (OpenHCI spec, 4.6)
*/
TD->HwTD.gTD.NextTD = 0;
/* TD->HwTD.gTD.NextTD = 0; */
TD->NextHcdTD = 0;
OhciTransfer->NextTD = TD;
@ -1580,6 +1511,19 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
return MP_STATUS_SUCCESS;
}
/**
* @brief Creates the transfer descriptor chain for the given transfer's buffer
* and attaches it to a given endpoint (for control, bulk or interrupt transfers)
*
* @param[in] OhciExtension The ohci extension
* @param[in] OhciEndpoint The ohci endpoint
* @param[in] TransferParameters The transfer parameters
* @param[in] OhciTransfer The ohci transfer
* @param[in] SGList The scatter/gather list
*
* @return MP_STATUS_SUCCESS or MP_STATUS_FAILURE if there are not enough TDs left
* or wrong transfer type given
*/
MPSTATUS
NTAPI
OHCI_SubmitTransfer(IN PVOID ohciExtension,