[USBOHCI_NEW] Zero out the transfer descriptor right after allocation.
authorVictor Perevertkin <victor@perevertkin.ru>
Tue, 25 Jun 2019 12:03:26 +0000 (15:03 +0300)
committerVictor Perevertkin <victor@perevertkin.ru>
Tue, 25 Jun 2019 12:03:26 +0000 (15:03 +0300)
Cleaned up transfer routines and added some more docs.

drivers/usb/usbohci_new/usbohci.c

index 8e05468..6216f80 100644 (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));
-
-    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,