mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[USBOHCI_NEW] Zero out the transfer descriptor right after allocation.
Cleaned up transfer routines and added some more docs.
This commit is contained in:
parent
3fe397818a
commit
9004e64b57
1 changed files with 61 additions and 117 deletions
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue