[USBOHCI_NEW] Simplify the MapTransferToTD routine and add some docs

This commit is contained in:
Victor Perevertkin 2019-06-25 13:02:35 +03:00
parent 3fb5ca3bee
commit 3fe397818a
No known key found for this signature in database
GPG key ID: C750B7222E9C7830

View file

@ -34,7 +34,7 @@ static const UCHAR Balance[OHCI_NUMBER_OF_INTERRUPTS] =
}; };
VOID VOID
NTAPI NTAPI
OHCI_DumpHcdED(POHCI_HCD_ED ED) OHCI_DumpHcdED(POHCI_HCD_ED ED)
{ {
DPRINT("ED - %p\n", ED); DPRINT("ED - %p\n", ED);
@ -45,7 +45,7 @@ OHCI_DumpHcdED(POHCI_HCD_ED ED)
} }
VOID VOID
NTAPI NTAPI
OHCI_DumpHcdTD(POHCI_HCD_TD TD) OHCI_DumpHcdTD(POHCI_HCD_TD TD)
{ {
DPRINT("TD - %p\n", TD); DPRINT("TD - %p\n", TD);
@ -235,7 +235,7 @@ OHCI_InitializeTDs(IN POHCI_ENDPOINT OhciEndpoint,
ASSERT(EndpointProperties->BufferLength > sizeof(OHCI_HCD_ED)); ASSERT(EndpointProperties->BufferLength > sizeof(OHCI_HCD_ED));
TdCount = (EndpointProperties->BufferLength - sizeof(OHCI_HCD_ED)) / TdCount = (EndpointProperties->BufferLength - sizeof(OHCI_HCD_ED)) /
sizeof(OHCI_HCD_TD); sizeof(OHCI_HCD_TD);
OhciEndpoint->MaxTransferDescriptors = TdCount; OhciEndpoint->MaxTransferDescriptors = TdCount;
@ -689,7 +689,7 @@ OHCI_StartController(IN PVOID ohciExtension,
/* 5.2.7.2 Interrupt */ /* 5.2.7.2 Interrupt */
/* Build structure of interrupt static EDs */ /* Build structure of interrupt static EDs */
for (ix = 0; ix < INTERRUPT_ENDPOINTs; ix++) for (ix = 0; ix < INTERRUPT_ENDPOINTs; ix++)
{ {
IntED = &OhciExtension->HcResourcesVA->InterrruptHeadED[ix]; IntED = &OhciExtension->HcResourcesVA->InterrruptHeadED[ix];
IntEdPA = OhciExtension->HcResourcesPA + FIELD_OFFSET(OHCI_HC_RESOURCES, InterrruptHeadED[ix]); IntEdPA = OhciExtension->HcResourcesPA + FIELD_OFFSET(OHCI_HC_RESOURCES, InterrruptHeadED[ix]);
@ -770,7 +770,7 @@ OHCI_StartController(IN PVOID ohciExtension,
FrameInterval.FrameIntervalToggle = 1; FrameInterval.FrameIntervalToggle = 1;
/* OHCI_MAXIMUM_OVERHEAD is the maximum overhead per frame */ /* OHCI_MAXIMUM_OVERHEAD is the maximum overhead per frame */
FrameInterval.FSLargestDataPacket = FrameInterval.FSLargestDataPacket =
((FrameInterval.FrameInterval - OHCI_MAXIMUM_OVERHEAD) * 6) / 7; ((FrameInterval.FrameInterval - OHCI_MAXIMUM_OVERHEAD) * 6) / 7;
OhciExtension->FrameInterval = FrameInterval; OhciExtension->FrameInterval = FrameInterval;
@ -1141,23 +1141,28 @@ OHCI_InterruptDpc(IN PVOID ohciExtension,
} }
} }
/**
* @brief Forms the next General Transfer Descriptor for the current transfer
*
* @param[in] OhciExtension The ohci extension
* @param[in] TransferedLen The consolidated length of all previous descriptors' buffers
* @param[in] OhciTransfer The ohci transfer
* @param[out] TD The transfer descriptor we are forming
* @param[in] SGList The scatter/gather list
*
* @return The length of all previous buffers summed with the length of the current buffer
*/
static
ULONG ULONG
NTAPI
OHCI_MapTransferToTD(IN POHCI_EXTENSION OhciExtension, OHCI_MapTransferToTD(IN POHCI_EXTENSION OhciExtension,
IN ULONG MaxPacketSize, IN ULONG TransferedLen,
IN OUT ULONG TransferedLen,
IN POHCI_TRANSFER OhciTransfer, IN POHCI_TRANSFER OhciTransfer,
IN POHCI_HCD_TD TD, OUT POHCI_HCD_TD TD,
IN PUSBPORT_SCATTER_GATHER_LIST SGList) IN PUSBPORT_SCATTER_GATHER_LIST SGList)
{ {
PUSBPORT_SCATTER_GATHER_ELEMENT SgElement; PUSBPORT_SCATTER_GATHER_ELEMENT SgElement;
ULONG SgIdx; ULONG SgIdx, CurrentTransferLen, BufferEnd, CurrentBuffer;
ULONG SgRemain; ULONG TransferDataLeft = OhciTransfer->TransferParameters->TransferBufferLength - TransferedLen;
ULONG LengthThisTd;
ULONG BufferEnd;
ULONG Offset;
ULONG TransferLength;
ULONG Buffer;
DPRINT_OHCI("OHCI_MapTransferToTD: TransferedLen - %x\n", TransferedLen); DPRINT_OHCI("OHCI_MapTransferToTD: TransferedLen - %x\n", TransferedLen);
@ -1177,53 +1182,54 @@ OHCI_MapTransferToTD(IN POHCI_EXTENSION OhciExtension,
SGList->SgElementCount); SGList->SgElementCount);
ASSERT(SgIdx < SGList->SgElementCount); ASSERT(SgIdx < SGList->SgElementCount);
ASSERT(TransferedLen == SgElement->SgOffset);
Offset = TransferedLen - SGList->SgElement[SgIdx].SgOffset; /* The buffer for a TD can be 0 to 8192 bytes long,
Buffer = SGList->SgElement[SgIdx].SgPhysicalAddress.LowPart + Offset; * and can span within mo more than two 4k pages (see OpenHCI spec 3.3.2)
* CurrentBuffer - the (physical) address of the first byte in the buffer
* BufferEnd - the address of the last byte in the buffer. It can be on a different physical 4k page
* when a controller will reach the end of a page from CurrentBuffer, it will take the first 20 bits
* of the BufferEnd as a next address (OpenHCI spec, 4.3.1.3.1)
*/
SgRemain = SGList->SgElementCount - SgIdx; CurrentBuffer = SgElement->SgPhysicalAddress.LowPart;
if (SgRemain == 1) if (TransferDataLeft <= SgElement->SgTransferLength)
{ {
LengthThisTd = OhciTransfer->TransferParameters->TransferBufferLength - CurrentTransferLen = TransferDataLeft;
TransferedLen - BufferEnd = SgElement->SgPhysicalAddress.LowPart + CurrentTransferLen - 1;
Offset;
BufferEnd = SGList->SgElement[SgIdx].SgPhysicalAddress.LowPart +
LengthThisTd;
}
else if (SgRemain == 2)
{
LengthThisTd = OhciTransfer->TransferParameters->TransferBufferLength -
TransferedLen;
BufferEnd = SGList->SgElement[SgIdx + 1].SgPhysicalAddress.LowPart +
SGList->SgElement[SgIdx + 1].SgTransferLength;
} }
else else
{ {
TransferLength = SGList->SgElement[SgIdx].SgTransferLength + PUSBPORT_SCATTER_GATHER_ELEMENT SgNextElement;
SGList->SgElement[SgIdx+1].SgTransferLength - ASSERT(SGList->SgElementCount - SgIdx > 1);
Offset;
BufferEnd = SGList->SgElement[SgIdx + 1].SgPhysicalAddress.LowPart + SgNextElement = &SGList->SgElement[SgIdx + 1];
SGList->SgElement[SgIdx + 1].SgTransferLength;
LengthThisTd = MaxPacketSize * (TransferLength / MaxPacketSize); TransferDataLeft -= SgElement->SgTransferLength;
CurrentTransferLen = SgElement->SgTransferLength;
if (TransferLength > LengthThisTd) if (TransferDataLeft <= SgNextElement->SgTransferLength)
BufferEnd -= (TransferLength - LengthThisTd); {
CurrentTransferLen += TransferDataLeft;
BufferEnd = SgNextElement->SgPhysicalAddress.LowPart + TransferDataLeft - 1;
}
else
{
CurrentTransferLen += SgNextElement->SgTransferLength;
BufferEnd = SgNextElement->SgPhysicalAddress.LowPart + SgNextElement->SgTransferLength - 1;
}
} }
TD->HwTD.gTD.CurrentBuffer = Buffer; TD->HwTD.gTD.CurrentBuffer = CurrentBuffer;
TD->HwTD.gTD.BufferEnd = BufferEnd - 1; TD->HwTD.gTD.BufferEnd = BufferEnd;
TD->TransferLen = LengthThisTd; TD->TransferLen = CurrentTransferLen;
return TransferedLen + LengthThisTd; return TransferedLen + CurrentTransferLen;
} }
POHCI_HCD_TD POHCI_HCD_TD
NTAPI NTAPI
OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension, OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint) IN POHCI_ENDPOINT OhciEndpoint)
{ {
@ -1244,7 +1250,7 @@ OHCI_AllocateTD(IN POHCI_EXTENSION OhciExtension,
} }
ULONG ULONG
NTAPI NTAPI
OHCI_RemainTDs(IN POHCI_EXTENSION OhciExtension, OHCI_RemainTDs(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint) IN POHCI_ENDPOINT OhciEndpoint)
{ {
@ -1287,7 +1293,6 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
POHCI_HCD_TD NextTD; POHCI_HCD_TD NextTD;
ULONG MaxTDs; ULONG MaxTDs;
ULONG TransferedLen; ULONG TransferedLen;
ULONG MaxPacketSize;
ULONG BufferEnd; ULONG BufferEnd;
UCHAR DataToggle; UCHAR DataToggle;
@ -1357,8 +1362,6 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
PrevTD->HwTD.gTD.NextTD = TD2->PhysicalAddress; PrevTD->HwTD.gTD.NextTD = TD2->PhysicalAddress;
PrevTD->NextHcdTD = TD2; PrevTD->NextHcdTD = TD2;
MaxPacketSize = OhciEndpoint->EndpointProperties.TotalMaxPacketSize;
TransferedLen = 0; TransferedLen = 0;
DataToggle = OHCI_TD_DATA_TOGGLE_DATA1; DataToggle = OHCI_TD_DATA_TOGGLE_DATA1;
@ -1378,7 +1381,6 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
DataToggle = OHCI_TD_DATA_TOGGLE_FROM_ED; DataToggle = OHCI_TD_DATA_TOGGLE_FROM_ED;
TransferedLen = OHCI_MapTransferToTD(OhciExtension, TransferedLen = OHCI_MapTransferToTD(OhciExtension,
MaxPacketSize,
TransferedLen, TransferedLen,
OhciTransfer, OhciTransfer,
TD, TD,
@ -1457,8 +1459,20 @@ OHCI_ControlTransfer(IN POHCI_EXTENSION OhciExtension,
return MP_STATUS_SUCCESS; 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
*/
MPSTATUS MPSTATUS
NTAPI NTAPI
OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension, OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint, IN POHCI_ENDPOINT OhciEndpoint,
IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters, IN PUSBPORT_TRANSFER_PARAMETERS TransferParameters,
@ -1469,7 +1483,6 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
POHCI_HCD_TD PrevTD; POHCI_HCD_TD PrevTD;
ULONG TransferedLen; ULONG TransferedLen;
ULONG MaxTDs; ULONG MaxTDs;
ULONG MaxPacketSize;
DPRINT_OHCI("OHCI_BulkOrInterruptTransfer: ... \n"); DPRINT_OHCI("OHCI_BulkOrInterruptTransfer: ... \n");
@ -1515,10 +1528,7 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
if (TransferParameters->TransferBufferLength) if (TransferParameters->TransferBufferLength)
{ {
MaxPacketSize = OhciEndpoint->EndpointProperties.TotalMaxPacketSize;
TransferedLen = OHCI_MapTransferToTD(OhciExtension, TransferedLen = OHCI_MapTransferToTD(OhciExtension,
MaxPacketSize,
TransferedLen, TransferedLen,
OhciTransfer, OhciTransfer,
TD, TD,
@ -1554,6 +1564,9 @@ OHCI_BulkOrInterruptTransfer(IN POHCI_EXTENSION OhciExtension,
PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress; PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress;
PrevTD->NextHcdTD = TD; 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; TD->NextHcdTD = 0;
@ -1956,7 +1969,7 @@ OHCI_SetEndpointState(IN PVOID ohciExtension,
} }
VOID VOID
NTAPI NTAPI
OHCI_PollAsyncEndpoint(IN POHCI_EXTENSION OhciExtension, OHCI_PollAsyncEndpoint(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint) IN POHCI_ENDPOINT OhciEndpoint)
{ {
@ -2151,7 +2164,7 @@ HandleDoneList:
} }
VOID VOID
NTAPI NTAPI
OHCI_PollIsoEndpoint(IN POHCI_EXTENSION OhciExtension, OHCI_PollIsoEndpoint(IN POHCI_EXTENSION OhciExtension,
IN POHCI_ENDPOINT OhciEndpoint) IN POHCI_ENDPOINT OhciEndpoint)
{ {
@ -2371,7 +2384,7 @@ OHCI_GetEndpointStatus(IN PVOID ohciExtension,
ED = OhciEndpoint->HcdED; ED = OhciEndpoint->HcdED;
if ((ED->HwED.HeadPointer & OHCI_ED_HEAD_POINTER_HALT) && if ((ED->HwED.HeadPointer & OHCI_ED_HEAD_POINTER_HALT) &&
!(ED->Flags & OHCI_HCD_ED_FLAG_RESET_ON_HALT)) !(ED->Flags & OHCI_HCD_ED_FLAG_RESET_ON_HALT))
{ {
EndpointStatus = USBPORT_ENDPOINT_HALT; EndpointStatus = USBPORT_ENDPOINT_HALT;
} }