https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9004e64b574adc8a575870f2faadd400cac21201
commit 9004e64b574adc8a575870f2faadd400cac21201 Author: Victor Perevertkin <vic...@perevertkin.ru> AuthorDate: Tue Jun 25 15:03:26 2019 +0300 Commit: Victor Perevertkin <vic...@perevertkin.ru> CommitDate: Tue Jun 25 15:03:26 2019 +0300 [USBOHCI_NEW] Zero out the transfer descriptor right after allocation. Cleaned up transfer routines and added some more docs. --- drivers/usb/usbohci_new/usbohci.c | 178 +++++++++++++------------------------- 1 file changed, 61 insertions(+), 117 deletions(-) diff --git a/drivers/usb/usbohci_new/usbohci.c b/drivers/usb/usbohci_new/usbohci.c index 8e05468ef44..6216f80b75f 100644 --- a/drivers/usb/usbohci_new/usbohci.c +++ b/drivers/usb/usbohci_new/usbohci.c @@ -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)); - - FirstTdPA = FirstTD->PhysicalAddress; - - FirstTD->HwTD.gTD.CurrentBuffer = FirstTdPA + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket); + sizeof(SetupTD->HwTD.SetupPacket)); - BufferEnd = FirstTdPA + FIELD_OFFSET(OHCI_HCD_TD, HwTD.SetupPacket) + - sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) - 1; + 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.BufferEnd = BufferEnd; + PrevTD = SetupTD; - 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; + /* Data packets follow a setup packet (if any) */ + TD = OHCI_AllocateTD(OhciExtension, OhciEndpoint); + TD->Flags |= OHCI_HCD_TD_FLAG_PROCESSED; + TD->OhciTransfer = OhciTransfer; - 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; + PrevTD->HwTD.gTD.NextTD = TD->PhysicalAddress; + PrevTD->NextHcdTD = TD; - 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,