[USBPORT] Check Period instead Factor.
[reactos.git] / drivers / usb / usbport / endpoint.c
index 2479cf9..2e9881b 100644 (file)
@@ -68,9 +68,19 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice,
     ULONG TransferType;
     ULONG TotalBusBandwidth;
     ULONG EndpointBandwidth;
+    ULONG MinBandwidth;
+    PULONG Bandwidth;
+    ULONG MaxBandwidth = 0;
+    ULONG ix;
+    ULONG Offset;
+    LONG ScheduleOffset = -1;
     ULONG Period;
+    ULONG Factor;
+    UCHAR Bit;
 
-    DPRINT("USBPORT_AllocateBandwidth: ... \n");
+    DPRINT("USBPORT_AllocateBandwidth: FdoDevice - %p, Endpoint - %p\n",
+           FdoDevice,
+           Endpoint);
 
     FdoExtension = FdoDevice->DeviceExtension;
     EndpointProperties = &Endpoint->EndpointProperties;
@@ -86,17 +96,74 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice,
 
     TotalBusBandwidth = FdoExtension->TotalBusBandwidth;
     EndpointBandwidth = EndpointProperties->UsbBandwidth;
+
     Period = EndpointProperties->Period;
+    ASSERT(Period != 0);
+    Factor = USB2_FRAMES / Period;
 
-    DPRINT1("USBPORT_AllocateBandwidth: FIXME. \n");
-    DPRINT1("USBPORT_AllocateBandwidth: Endpoint - %p, Type - %x, TotalBandwidth - %x, EpBandwidth - %x, Period - %x\n",
-           Endpoint,
-           TransferType,
-           TotalBusBandwidth,
-           EndpointBandwidth,
-           Period);
+    for (Offset = 0; Offset < Period; Offset++)
+    {
+        MinBandwidth = TotalBusBandwidth;
+        Bandwidth = &FdoExtension->Bandwidth[Offset * Factor];
+
+        for (ix = 1; *Bandwidth >= EndpointBandwidth; ix++)
+        {
+            MinBandwidth = min(MinBandwidth, *Bandwidth); 
+
+            Bandwidth++;
+
+            if (Factor <= ix)
+            {
+                if (MinBandwidth > MaxBandwidth)
+                {
+                    MaxBandwidth = MinBandwidth;
+                    ScheduleOffset = Offset;
+
+                    DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n",
+                           ScheduleOffset);
+                }
+
+                break;
+            }
+        }
+    }
+
+    DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset);
+
+    if (ScheduleOffset != -1)
+    {
+        EndpointProperties->ScheduleOffset = ScheduleOffset;
+
+        Bandwidth = &FdoExtension->Bandwidth[ScheduleOffset * Factor];
+
+        for (Factor = USB2_FRAMES / Period; Factor; Factor--)
+        {
+            FdoExtension->Bandwidth[ScheduleOffset * Factor] -= EndpointBandwidth;
+        }
 
-    return TRUE;
+        if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
+        {
+            for (Bit = 0x80; Bit != 0; Bit >>= 1)
+            {
+                if ((Period & Bit) != 0)
+                {
+                    Period = Bit;
+                    break;
+                }
+            }
+
+            DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
+        }
+        else
+        {
+            DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
+        }
+    }
+
+    DPRINT("USBPORT_AllocateBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
+
+    DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset);
+    return ScheduleOffset != -1;
 }
 
 VOID
@@ -104,7 +171,63 @@ NTAPI
 USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice,
                       IN PUSBPORT_ENDPOINT Endpoint)
 {
-    DPRINT1("USBPORT_FreeBandwidth: UNIMPLEMENTED. FIXME. \n");
+    PUSBPORT_DEVICE_EXTENSION FdoExtension;
+    PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
+    ULONG TransferType;
+    ULONG Offset;
+    ULONG EndpointBandwidth;
+    ULONG Period;
+    ULONG Factor;
+    UCHAR Bit;
+
+    DPRINT("USBPORT_FreeBandwidth: FdoDevice - %p, Endpoint - %p\n",
+           FdoDevice,
+           Endpoint);
+
+    FdoExtension = FdoDevice->DeviceExtension;
+
+    EndpointProperties = &Endpoint->EndpointProperties;
+    TransferType = EndpointProperties->TransferType;
+
+    if (TransferType == USBPORT_TRANSFER_TYPE_BULK ||
+        TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
+        (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
+    {
+        return;
+    }
+
+    Offset = Endpoint->EndpointProperties.ScheduleOffset;
+    EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth;
+
+    Period = Endpoint->EndpointProperties.Period;
+    ASSERT(Period != 0);
+
+    for (Factor = USB2_FRAMES / Period; Factor; Factor--)
+    {
+        FdoExtension->Bandwidth[Offset * Factor] += EndpointBandwidth;
+    }
+
+    if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
+    {
+        for (Bit = 0x80; Bit != 0; Bit >>= 1)
+        {
+            if ((Period & Bit) != 0)
+            {
+                Period = Bit;
+                break;
+            }
+        }
+
+        ASSERT(Period != 0);
+
+        DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
+    }
+    else
+    {
+        DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
+    }
+
+    DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
 }
 
 UCHAR
@@ -379,7 +502,7 @@ USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice,
     BOOLEAN Result;
     KIRQL OldIrql;
 
-    DPRINT("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint);
+    DPRINT1("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint);
 
     FdoExtension = FdoDevice->DeviceExtension;
 
@@ -471,10 +594,13 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
     PUSBPORT_DEVICE_EXTENSION FdoExtension;
     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
     PUSBPORT_ENDPOINT Endpoint;
+    PUSBPORT_REGISTRATION_PACKET Packet;
+    PUSB2_TT_EXTENSION TtExtension;
+    ULONG ix;
     BOOLEAN IsReady;
     KIRQL OldIrql;
 
-    DPRINT("USBPORT_ClosePipe \n");
+    DPRINT1("USBPORT_ClosePipe \n");
 
     FdoExtension = FdoDevice->DeviceExtension;
 
@@ -492,7 +618,6 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
     }
 
     Endpoint = PipeHandle->Endpoint;
-    DPRINT("USBPORT_ClosePipe: Endpoint - %p\n", Endpoint);
 
     KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
 
@@ -543,16 +668,46 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle,
     }
 
     Endpoint->DeviceHandle = NULL;
+    Packet = &FdoExtension->MiniPortInterface->Packet;
 
-    if (FdoExtension->MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
+    if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
     {
-        DPRINT("USBPORT_ClosePipe: FIXME USBPORT_FreeBandwidthUSB20\n");
-        //USBPORT_FreeBandwidthUSB20();
+        USBPORT_FreeBandwidthUSB2(FdoDevice, Endpoint);
+
+        KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql);
+
+        TtExtension = Endpoint->TtExtension;
+        DPRINT1("USBPORT_ClosePipe: TtExtension - %p\n", TtExtension);
+
+        if (TtExtension)
+        {
+            RemoveEntryList(&Endpoint->TtLink);
+
+            Endpoint->TtLink.Flink = NULL;
+            Endpoint->TtLink.Blink = NULL;
+
+            if (TtExtension->Flags & USB2_TT_EXTENSION_FLAG_DELETED)
+            {
+                if (IsListEmpty(&TtExtension->EndpointList))
+                {
+                    USBPORT_UpdateAllocatedBwTt(TtExtension);
+
+                    for (ix = 0; ix < USB2_FRAMES; ix++)
+                    {
+                        FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
+                    }
+
+                    DPRINT1("USBPORT_ClosePipe: ExFreePoolWithTag TtExtension - %p\n", TtExtension);
+                    ExFreePoolWithTag(TtExtension, USB_PORT_TAG);
+                }
+            }
+        }
+
+        KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql);
     }
     else
     {
-        DPRINT("USBPORT_ClosePipe: FIXME USBPORT_FreeBandwidthUSB11\n");
-        //USBPORT_FreeBandwidthUSB11();
+        USBPORT_FreeBandwidth(FdoDevice, Endpoint);
     }
 
     KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
@@ -630,7 +785,7 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice,
     USHORT AdditionalTransaction;
     BOOLEAN IsAllocatedBandwidth;
 
-    DPRINT("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
+    DPRINT1("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
            DeviceHandle,
            FdoDevice,
            PipeHandle);
@@ -676,7 +831,7 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice,
 
     if (DeviceHandle->TtExtension)
     {
-        ExInterlockedInsertTailList(&DeviceHandle->TtExtension->TtList,
+        ExInterlockedInsertTailList(&DeviceHandle->TtExtension->EndpointList,
                                     &Endpoint->TtLink,
                                     &FdoExtension->TtSpinLock);
     }
@@ -1017,7 +1172,7 @@ USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice,
     KIRQL MiniportOldIrql;
     NTSTATUS Status;
 
-    DPRINT("USBPORT_ReopenPipe ... \n");
+    DPRINT1("USBPORT_ReopenPipe ... \n");
 
     FdoExtension = FdoDevice->DeviceExtension;
     Packet = &FdoExtension->MiniPortInterface->Packet;