#include "usbport.h"
-//#define NDEBUG
+#define NDEBUG
#include <debug.h>
+static const UCHAR CMASKS[USB2_MICROFRAMES] = {
+ 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E
+};
+
BOOLEAN
NTAPI
USB2_AllocateCheck(IN OUT PULONG OutTimeUsed,
TransferType = TtEndpoint->TtEndpointParams.TransferType;
Direction = TtEndpoint->TtEndpointParams.Direction;
- DeviceSpeed = TtEndpoint->TtEndpointParams.Direction;
+ DeviceSpeed = TtEndpoint->TtEndpointParams.DeviceSpeed;
HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime;
if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
Overhead = HostDelay + USB2_HS_ISOCHRONOUS_IN_OVERHEAD;
else
- Overhead = HostDelay + USB2_HS_ISOCHRONOUS_OUT_OVERHEAD;
+ Overhead = HostDelay + USB2_HS_INTERRUPT_IN_OVERHEAD;
}
}
else if (DeviceSpeed == UsbFullSpeed)
*OverheadSS = HostDelay + USB2_HS_SS_INTERRUPT_IN_OVERHEAD;
*OverheadCS = HostDelay + USB2_HS_CS_INTERRUPT_IN_OVERHEAD;
}
-
- //DPRINT("USB2_GetHsOverhead: *OverheadSS - %X, *OverheadCS - %X\n",
- // *OverheadSS,
- // *OverheadCS);
}
}
ttEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint;
if (ttEndpoint)
- return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
+ return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
else
- return USB2_FS_SOF_TIME;
+ return USB2_FS_SOF_TIME;
}
else
{
frame = TtEndpoint->StartFrame + Frame;
uframe = TtEndpoint->StartMicroframe;
- if (TtEndpoint->StartMicroframe == 0xFF)
+ if (TtEndpoint->StartMicroframe == USB2_PREV_MICROFRAME)
USB2_GetPrevMicroFrame(&frame, &uframe);
for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
frame = TtEndpoint->StartFrame + Frame;
uframe = TtEndpoint->StartMicroframe;
- if (uframe == 0xFF)
+ if (uframe == USB2_PREV_MICROFRAME)
USB2_GetPrevMicroFrame(&frame, &uframe);
DataTime = 0;
USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint,
IN ULONG Frame)
{
- DPRINT("USB2_DeallocateHS: UNIMPLEMENTED FIXME\n");
- ASSERT(FALSE);
+ PUSB2_TT Tt;
+ PUSB2_HC_EXTENSION HcExtension;
+ ULONG OverheadCS;
+ ULONG OverheadSS;
+ ULONG Direction;
+ ULONG ix;
+ ULONG CurrentDataTime;
+ ULONG RemainDataTime;
+ ULONG DataTime;
+ ULONG DataSize;
+ USHORT PktSize;
+ USHORT PktSizeBitStuff;
+ UCHAR uframe;
+ UCHAR frame;
+
+ DPRINT("USB2_DeallocateHS: TtEndpoint - %p, Frame - %X\n",
+ TtEndpoint,
+ Frame);
+
+ Tt = TtEndpoint->Tt;
+ HcExtension = Tt->HcExtension;
+
+ USB2_GetHsOverhead(TtEndpoint, &OverheadSS, &OverheadCS);
+
+ frame = TtEndpoint->StartFrame + Frame;
+ uframe = TtEndpoint->StartMicroframe;
+
+ if (TtEndpoint->StartMicroframe == USB2_PREV_MICROFRAME)
+ USB2_GetPrevMicroFrame(&frame, &uframe);
+
+ for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
+ {
+ HcExtension->TimeUsed[frame][uframe] -= OverheadSS;
+ --Tt->NumStartSplits[frame][uframe];
+ USB2_IncMicroFrame(&frame, &uframe);
+ }
+
+ frame = TtEndpoint->StartFrame + Frame;
+ uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
+
+ for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
+ {
+ HcExtension->TimeUsed[frame][uframe] -= OverheadCS;
+ USB2_IncMicroFrame(&frame, &uframe);
+ }
+
+ Direction = TtEndpoint->TtEndpointParams.Direction;
+ PktSize = TtEndpoint->MaxPacketSize;
+ PktSizeBitStuff = USB2_AddDataBitStuff(PktSize);
+
+ if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
+ {
+ frame = TtEndpoint->StartFrame + Frame;
+ uframe = TtEndpoint->StartMicroframe;
+
+ if (TtEndpoint->StartMicroframe == USB2_PREV_MICROFRAME)
+ USB2_GetPrevMicroFrame(&frame, &uframe);
+
+ DataTime = 0;
+
+ for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
+ {
+ DataSize = PktSizeBitStuff - DataTime;
+
+ if (DataSize <= USB2_FS_RAW_BYTES_IN_MICROFRAME)
+ CurrentDataTime = PktSizeBitStuff - DataTime;
+ else
+ CurrentDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME;
+
+ HcExtension->TimeUsed[frame][uframe] -= CurrentDataTime;
+ USB2_IncMicroFrame(&frame, &uframe);
+ DataTime += USB2_FS_RAW_BYTES_IN_MICROFRAME;
+ }
+ }
+ else
+ {
+ frame = TtEndpoint->StartFrame + Frame;
+ uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
+
+ for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
+ {
+ if (PktSizeBitStuff >= USB2_FS_RAW_BYTES_IN_MICROFRAME)
+ CurrentDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME;
+ else
+ CurrentDataTime = PktSizeBitStuff;
+
+ Tt->TimeCS[frame][uframe] -= CurrentDataTime;
+
+ if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME)
+ {
+ RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME -
+ Tt->TimeCS[frame][uframe];
+
+ if (RemainDataTime >= PktSizeBitStuff)
+ RemainDataTime = PktSizeBitStuff;
+
+ HcExtension->TimeUsed[frame][uframe] -= RemainDataTime;
+ }
+
+ USB2_IncMicroFrame(&frame, &uframe);
+ }
+ }
+
+ return;
}
BOOLEAN
NTAPI
USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
- IN USHORT BusTime,
+ IN LONG BusTime,
IN PUSB2_REBALANCE Rebalance,
IN ULONG RebalanceListEntries,
OUT BOOLEAN * OutResult)
{
- DPRINT("USB2_MoveTtEndpoint: UNIMPLEMENTED FIXME\n");
- ASSERT(FALSE);
- return FALSE;
+ ULONG EndBusTime;
+ ULONG TransferType;
+ ULONG Num;
+ UCHAR ix;
+
+ DPRINT("USB2_MoveTtEndpoint: TtEndpoint - %p, BusTime - %X\n",
+ TtEndpoint,
+ BusTime);
+
+ *OutResult = TRUE;
+
+ for (Num = 0; Rebalance->RebalanceEndpoint[Num]; Num++)
+ {
+ if (Rebalance->RebalanceEndpoint[Num] == TtEndpoint)
+ break;
+ }
+
+ DPRINT("USB2_MoveTtEndpoint: Num - %X\n", Num);
+
+ TransferType = TtEndpoint->TtEndpointParams.TransferType;
+
+ if (Rebalance->RebalanceEndpoint[Num] &&
+ TtEndpoint->TtEndpointParams.EndpointMoved == TRUE &&
+ ((TransferType != USBPORT_TRANSFER_TYPE_INTERRUPT) || BusTime >= 0))
+ {
+ DPRINT("USB2_MoveTtEndpoint: result - FALSE\n");
+ return FALSE;
+ }
+
+ for (ix = 0;
+ (TtEndpoint->StartFrame + ix) < USB2_FRAMES;
+ ix += TtEndpoint->ActualPeriod)
+ {
+ USB2_DeallocateHS(TtEndpoint, ix);
+ }
+
+ TtEndpoint->StartTime += BusTime;
+
+ EndBusTime = TtEndpoint->StartTime + TtEndpoint->CalcBusTime;
+
+ if (EndBusTime > USB2_FS_MAX_PERIODIC_ALLOCATION)
+ {
+ DPRINT("USB2_MoveTtEndpoint: EndBusTime is too large!\n");
+ *OutResult = FALSE;
+ }
+
+ TtEndpoint->TtEndpointParams.EndpointMoved = TRUE;
+
+ if (Rebalance->RebalanceEndpoint[Num] == NULL)
+ {
+ if (Num >= RebalanceListEntries)
+ {
+ DPRINT("USB2_MoveTtEndpoint: Too many changes!\n");
+ *OutResult = FALSE;
+ }
+ else
+ {
+ Rebalance->RebalanceEndpoint[Num] = TtEndpoint;
+ Rebalance->RebalanceEndpoint[Num + 1] = NULL;
+ }
+ }
+
+ for (ix = 0;
+ (TtEndpoint->StartFrame + ix) < USB2_FRAMES;
+ ix += TtEndpoint->ActualPeriod)
+ {
+ if (!USB2_AllocateHS(TtEndpoint, ix))
+ {
+ DPRINT("USB2_MoveTtEndpoint: OutResult - FALSE\n");
+ OutResult = FALSE;
+ }
+ }
+
+ DPRINT("USB2_MoveTtEndpoint: result - TRUE\n");
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+USB2_CommonFrames(IN PUSB2_TT_ENDPOINT NextTtEndpoint,
+ IN PUSB2_TT_ENDPOINT TtEndpoint)
+{
+ UCHAR Frame;
+
+ DPRINT("USB2_CommonFrames: \n");
+
+ if (NextTtEndpoint->ActualPeriod == ENDPOINT_INTERRUPT_1ms ||
+ TtEndpoint->ActualPeriod == ENDPOINT_INTERRUPT_1ms)
+ {
+ return TRUE;
+ }
+
+ if (NextTtEndpoint->ActualPeriod < TtEndpoint->ActualPeriod)
+ Frame = TtEndpoint->StartFrame % TtEndpoint->ActualPeriod;
+ else
+ Frame = NextTtEndpoint->StartFrame % TtEndpoint->ActualPeriod;
+
+ return (Frame == TtEndpoint->StartFrame);
}
VOID
Frame,
Microframe);
- if (Microframe == 0xFF)
+ if (Microframe == USB2_PREV_MICROFRAME)
{
*HcFrame = Frame;
*HcMicroframe = 0;
}
- if (Microframe >= 0 &&
- Microframe <= (USB2_MICROFRAMES - 2))
+ if (Microframe <= (USB2_MICROFRAMES - 2))
{
*HcFrame = Frame;
*HcMicroframe = Microframe + 1;
UCHAR HcFrame;
UCHAR HcMicroFrame;
UCHAR MaskCS = 0;
- static const UCHAR CMASKS[USB2_MICROFRAMES] = {
- 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E
- };
TransferType = TtEndpoint->TtEndpointParams.TransferType;
DeviceSpeed = TtEndpoint->TtEndpointParams.DeviceSpeed;
Direction = TtEndpoint->TtEndpointParams.Direction;
if (DeviceSpeed == UsbHighSpeed)
- {
return 0;
- }
if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
{
else
{
if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
- {
return 0;
- }
USB2_ConvertFrame(TtEndpoint->StartFrame,
TtEndpoint->StartMicroframe,
NumCompletes--;
if (!NumCompletes)
- {
return MaskCS;
- }
}
for (; NumCompletes; NumCompletes--)
return Result;
}
-BOOLEAN
-NTAPI
-USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint,
- IN PUSB2_REBALANCE Rebalance,
- IN PULONG RebalanceListEntries,
- IN ULONG MaxFrames)
-{
- DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n");
- ASSERT(FALSE);
- return FALSE;
-}
-
-BOOLEAN
+VOID
NTAPI
-USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
- IN PUSB2_REBALANCE Rebalance,
- IN PULONG RebalanceListEntries)
+USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice,
+ IN PLIST_ENTRY List)
{
- PUSB2_TT Tt;
- PUSB2_HC_EXTENSION HcExtension;
- ULONG Speed;
- ULONG TimeUsed;
- ULONG MinTimeUsed;
+ PUSBPORT_DEVICE_EXTENSION FdoExtension;
+ PUSBPORT_REGISTRATION_PACKET Packet;
+ PUSBPORT_ENDPOINT Endpoint;
+ PLIST_ENTRY Entry;
+ ULONG AllocedBusTime;
+ ULONG EndpointBandwidth;
+ ULONG Factor;
+ ULONG ScheduleOffset;
+ ULONG Bandwidth;
+ ULONG n;
ULONG ix;
- ULONG frame;
- ULONG uframe;
- ULONG Microframe;
- ULONG TransferType;
- ULONG Overhead;
- ULONG LatestStart;
- PUSB2_TT_ENDPOINT prevTtEndpoint;
- PUSB2_TT_ENDPOINT nextTtEndpoint;
- PUSB2_TT_ENDPOINT IntEndpoint;
- ULONG StartTime;
- ULONG calcBusTime;
- BOOLEAN Result = TRUE;
+ KIRQL OldIrql;
+ UCHAR NewPeriod;
+ UCHAR SMask;
+ UCHAR CMask;
- DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint);
+ FdoExtension = FdoDevice->DeviceExtension;
+ Packet = &FdoExtension->MiniPortInterface->Packet;
- Tt = TtEndpoint->Tt;
- HcExtension = Tt->HcExtension;
+ while (!IsListEmpty(List))
+ {
+ Entry = RemoveHeadList(List);
- TtEndpoint->Nums.NumStarts = 0;
- TtEndpoint->Nums.NumCompletes = 0;
+ Endpoint = CONTAINING_RECORD(Entry,
+ USBPORT_ENDPOINT,
+ RebalanceLink.Flink);
- TtEndpoint->StartFrame = 0;
- TtEndpoint->StartMicroframe = 0;
+ DPRINT("USB2_RebalanceEndpoint: Endpoint - %p\n", Endpoint);
- if (TtEndpoint->CalcBusTime)
- {
- DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint already allocated!\n");
- return FALSE;
- }
+ Endpoint->RebalanceLink.Flink = NULL;
+ Endpoint->RebalanceLink.Blink = NULL;
- Speed = TtEndpoint->TtEndpointParams.DeviceSpeed;
+ KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
+ &Endpoint->EndpointOldIrql);
- if (Speed == UsbHighSpeed)
- {
- if (TtEndpoint->Period > USB2_MAX_MICROFRAMES)
- TtEndpoint->ActualPeriod = USB2_MAX_MICROFRAMES;
- else
- TtEndpoint->ActualPeriod = TtEndpoint->Period;
+ SMask = USB2_GetSMASK(Endpoint->TtEndpoint);
+ CMask = USB2_GetCMASK(Endpoint->TtEndpoint);
- MinTimeUsed = HcExtension->TimeUsed[0][0];
+ ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
+ NewPeriod = Endpoint->TtEndpoint->ActualPeriod;
- for (ix = 1; ix < TtEndpoint->ActualPeriod; ix++)
+ AllocedBusTime = Endpoint->TtEndpoint->CalcBusTime;
+ EndpointBandwidth = USB2_MICROFRAMES * AllocedBusTime;
+
+ Endpoint->EndpointProperties.InterruptScheduleMask = SMask;
+ Endpoint->EndpointProperties.SplitCompletionMask = CMask;
+
+ if (Endpoint->EndpointProperties.Period != NewPeriod)
{
- frame = ix / USB2_MICROFRAMES;
- uframe = ix % (USB2_MICROFRAMES - 1);
+ ASSERT(Endpoint->EndpointProperties.Period);
+ Factor = USB2_FRAMES / Endpoint->EndpointProperties.Period;
- TimeUsed = HcExtension->TimeUsed[frame][uframe];
+ for (ix = 0; ix < Factor; ix++)
+ {
+ Bandwidth = Endpoint->EndpointProperties.UsbBandwidth;
+ n = Factor * Endpoint->EndpointProperties.ScheduleOffset;
+ Endpoint->TtExtension->Bandwidth[n + ix] += Bandwidth;
+ }
- if (TimeUsed < MinTimeUsed)
+ Endpoint->EndpointProperties.Period = NewPeriod;
+ Endpoint->EndpointProperties.ScheduleOffset = ScheduleOffset;
+ Endpoint->EndpointProperties.UsbBandwidth = EndpointBandwidth;
+
+ ASSERT(NewPeriod);
+ Factor = USB2_FRAMES / NewPeriod;
+
+ for (ix = 0; ix < Factor; ix++)
{
- MinTimeUsed = TimeUsed;
- TtEndpoint->StartFrame = frame;
- TtEndpoint->StartMicroframe = uframe;
+ n = Factor * ScheduleOffset;
+ Endpoint->TtExtension->Bandwidth[n + ix] += EndpointBandwidth;
}
}
- TtEndpoint->CalcBusTime = USB2_GetOverhead(TtEndpoint) +
- USB2_AddDataBitStuff(TtEndpoint->MaxPacketSize);
+ KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
- DPRINT("USB2_AllocateTimeForEndpoint: StartFrame - %X, StartMicroframe - %X, CalcBusTime - %X\n",
- TtEndpoint->StartFrame,
- TtEndpoint->StartMicroframe,
- TtEndpoint->CalcBusTime);
+ Packet->RebalanceEndpoint(FdoExtension->MiniPortExt,
+ &Endpoint->EndpointProperties,
+ (PVOID)((ULONG_PTR)Endpoint + sizeof(USBPORT_ENDPOINT)));
- Microframe = TtEndpoint->StartFrame * USB2_MICROFRAMES +
- TtEndpoint->StartMicroframe;
+ KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
- if (Microframe >= USB2_MAX_MICROFRAMES)
- {
- DPRINT("USB2_AllocateTimeForEndpoint: Microframe >= 256. Result - TRUE\n");
- return TRUE;
- }
+ KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
+ Endpoint->EndpointOldIrql);
+ }
+}
- for (ix = Microframe;
- ix < USB2_MAX_MICROFRAMES;
- ix += TtEndpoint->ActualPeriod)
- {
- frame = ix / USB2_MICROFRAMES;
+VOID
+NTAPI
+USB2_Rebalance(IN PDEVICE_OBJECT FdoDevice,
+ IN PLIST_ENTRY RebalanceList)
+{
+ PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
+ PUSBPORT_ENDPOINT Endpoint;
+ PLIST_ENTRY Entry;
+ LIST_ENTRY BalanceListInt1;
+ LIST_ENTRY BalanceListInt2;
+ ULONG TransferType;
+ ULONG ScheduleOffset;
+ UCHAR SMask;
+ UCHAR CMask;
+ UCHAR ActualPeriod;
+
+ DPRINT("USB2_Rebalance: FdoDevice - %p, RebalanceList - %p\n",
+ FdoDevice,
+ RebalanceList);
+
+ InitializeListHead(&BalanceListInt1);
+ InitializeListHead(&BalanceListInt2);
+
+ while (!IsListEmpty(RebalanceList))
+ {
+ Entry = RebalanceList->Flink;
+
+ Endpoint = CONTAINING_RECORD(Entry,
+ USBPORT_ENDPOINT,
+ RebalanceLink.Flink);
+
+ DPRINT("USBPORT_Rebalance: Entry - %p, Endpoint - %p\n",
+ Entry,
+ Endpoint);
+
+ RemoveHeadList(RebalanceList);
+ Entry->Flink = NULL;
+ Entry->Blink = NULL;
+
+ SMask = USB2_GetSMASK(Endpoint->TtEndpoint);
+ CMask = USB2_GetCMASK(Endpoint->TtEndpoint);
+
+ ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
+ ActualPeriod = Endpoint->TtEndpoint->ActualPeriod;
+
+ EndpointProperties = &Endpoint->EndpointProperties;
+ TransferType = EndpointProperties->TransferType;
+
+ switch (TransferType)
+ {
+ case USBPORT_TRANSFER_TYPE_ISOCHRONOUS:
+ DPRINT("USBPORT_Rebalance: USBPORT_TRANSFER_TYPE_ISOCHRONOUS. FIXME\n");
+ ASSERT(FALSE);
+ break;
+
+ case USBPORT_TRANSFER_TYPE_INTERRUPT:
+ if (SMask != EndpointProperties->InterruptScheduleMask ||
+ CMask != EndpointProperties->SplitCompletionMask ||
+ ScheduleOffset != EndpointProperties->ScheduleOffset ||
+ ActualPeriod != EndpointProperties->Period)
+ {
+ if (ActualPeriod == EndpointProperties->Period &&
+ ScheduleOffset == EndpointProperties->ScheduleOffset)
+ {
+ InsertTailList(&BalanceListInt1, Entry);
+ }
+ else
+ {
+ InsertTailList(&BalanceListInt2, Entry);
+ }
+ }
+ break;
+
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+ }
+
+ USB2_RebalanceEndpoint(FdoDevice, &BalanceListInt2);
+ USB2_RebalanceEndpoint(FdoDevice, &BalanceListInt1);
+ //USB2_RebalanceEndpoint(FdoDevice, &BalanceListIso);
+}
+
+BOOLEAN
+NTAPI
+USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint,
+ IN PUSB2_REBALANCE Rebalance,
+ IN PULONG RebalanceListEntries,
+ IN ULONG MaxFrames)
+{
+ PUSB2_TT Tt;
+ PUSB2_HC_EXTENSION HcExtension;
+ ULONG Speed;
+ ULONG TransferType;
+ ULONG Frame;
+ ULONG StartMicroframe;
+ ULONG ix;
+ PUSB2_TT_ENDPOINT endpoint;
+ PUSB2_TT_ENDPOINT nextEndpoint;
+ PUSB2_TT_ENDPOINT lastEndpoint;
+ PUSB2_TT_ENDPOINT tmpEndpoint;
+ ULONG endTime;
+ ULONG maxEndTime;
+ ULONG lastEndTime;
+ ULONG Factor;
+ ULONG jx;
+ UCHAR frame;
+ UCHAR uframe;
+ USHORT Period;
+ BOOLEAN IsMoved = FALSE;
+
+ DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, MaxFrames - %X, CalcBusTime - %X\n",
+ TtEndpoint,
+ MaxFrames,
+ TtEndpoint->CalcBusTime);
+
+ if (TtEndpoint->CalcBusTime == 0)
+ {
+ DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint not allocated!\n");
+ return FALSE;
+ }
+
+ Tt = TtEndpoint->Tt;
+ HcExtension = Tt->HcExtension;
+
+ Speed = TtEndpoint->TtEndpointParams.DeviceSpeed;
+ DPRINT("USB2_DeallocateEndpointBudget: DeviceSpeed - %X\n", Speed);
+
+ StartMicroframe = TtEndpoint->StartFrame * USB2_MICROFRAMES +
+ TtEndpoint->StartMicroframe;
+
+ if (Speed == UsbHighSpeed)
+ {
+ for (ix = StartMicroframe;
+ ix < USB2_MAX_MICROFRAMES;
+ ix += TtEndpoint->ActualPeriod)
+ {
+ frame = ix / USB2_MICROFRAMES;
+ uframe = ix % (USB2_MICROFRAMES - 1);
+
+ HcExtension->TimeUsed[frame][uframe] -= TtEndpoint->CalcBusTime;
+ }
+
+ TtEndpoint->CalcBusTime = 0;
+
+ DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
+ return TRUE;
+ }
+
+ /* Speed != UsbHighSpeed (FS/LS) */
+
+ TransferType = TtEndpoint->TtEndpointParams.TransferType;
+
+ for (ix = MaxFrames, Frame = (MaxFrames - 1) - TtEndpoint->StartFrame;
+ ix > 0;
+ ix--, Frame--)
+ {
+ frame = TtEndpoint->StartFrame + Frame;
+
+ DPRINT("USB2_DeallocateEndpointBudget: frame - %X, Frame - %X, StartFrame - %X\n",
+ frame,
+ Frame,
+ TtEndpoint->StartFrame);
+
+ if ((Frame % TtEndpoint->ActualPeriod) == 0)
+ {
+ USB2_DeallocateHS(TtEndpoint, Frame);
+ Tt->FrameBudget[frame].TimeUsed -= TtEndpoint->CalcBusTime;
+ }
+
+ if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
+ endpoint = Tt->FrameBudget[frame].IntEndpoint;
+ else
+ endpoint = Tt->FrameBudget[frame].IsoEndpoint;
+
+ nextEndpoint = endpoint->NextTtEndpoint;
+
+ DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, nextEndpoint - %p\n",
+ TtEndpoint,
+ nextEndpoint);
+
+ if (TtEndpoint->CalcBusTime > (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
+ {
+ while (nextEndpoint)
+ {
+ endpoint = nextEndpoint;
+ nextEndpoint = nextEndpoint->NextTtEndpoint;
+ }
+
+ nextEndpoint = TtEndpoint;
+
+ DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
+ endpoint,
+ nextEndpoint);
+ }
+ else
+ {
+ while (nextEndpoint &&
+ !USB2_CheckTtEndpointInsert(nextEndpoint, TtEndpoint))
+ {
+ endpoint = nextEndpoint;
+ nextEndpoint = nextEndpoint->NextTtEndpoint;
+ }
+
+ if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS &&
+ nextEndpoint)
+ {
+ DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
+ ASSERT(FALSE);
+ }
+
+ DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
+ endpoint,
+ nextEndpoint);
+ }
+
+ if ((Frame % TtEndpoint->ActualPeriod) == 0)
+ {
+ if (TtEndpoint->CalcBusTime > (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
+ {
+ Tt->FrameBudget[frame].AltEndpoint = NULL;
+ }
+ else if (nextEndpoint)
+ {
+ nextEndpoint = nextEndpoint->NextTtEndpoint;
+ endpoint->NextTtEndpoint = nextEndpoint;
+
+ DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
+ endpoint,
+ nextEndpoint);
+ }
+ }
+
+ if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
+ {
+ if (endpoint == Tt->FrameBudget[frame].IntEndpoint)
+ {
+ if (Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint)
+ {
+ endpoint = Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint;
+ }
+ else if (Tt->FrameBudget[frame].AltEndpoint)
+ {
+ endpoint = Tt->FrameBudget[frame].AltEndpoint;
+ }
+ }
+ }
+ else
+ {
+ DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
+ ASSERT(FALSE);
+ }
+
+ Period = TtEndpoint->ActualPeriod;
+
+ for (;
+ nextEndpoint;
+ endpoint = nextEndpoint,
+ nextEndpoint = nextEndpoint->NextTtEndpoint)
+ {
+ DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
+ endpoint,
+ nextEndpoint);
+
+ endTime = endpoint->StartTime + endpoint->CalcBusTime;
+ maxEndTime = endTime;
+
+ if (Period > nextEndpoint->ActualPeriod ||
+ TtEndpoint->StartFrame != nextEndpoint->StartFrame)
+ {
+ if (USB2_CommonFrames(nextEndpoint, TtEndpoint))
+ Factor = Period / nextEndpoint->ActualPeriod;
+ else
+ Factor = USB2_FRAMES / nextEndpoint->ActualPeriod;
+
+ maxEndTime = endTime;
+
+ for (jx = 0, frame = nextEndpoint->StartFrame;
+ jx < Factor;
+ jx++, frame += nextEndpoint->ActualPeriod)
+ {
+ if (nextEndpoint->StartFrame != TtEndpoint->StartFrame)
+ {
+ lastEndpoint = Tt->FrameBudget[frame].IntEndpoint;
+
+ if (Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint)
+ {
+ lastEndpoint = Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint;
+ }
+ else if (Tt->FrameBudget[frame].AltEndpoint)
+ {
+ lastEndpoint = Tt->FrameBudget[frame].AltEndpoint;
+ }
+
+ for (tmpEndpoint = Tt->FrameBudget[frame].IntEndpoint->NextTtEndpoint;
+ tmpEndpoint && tmpEndpoint != nextEndpoint;
+ tmpEndpoint = tmpEndpoint->NextTtEndpoint)
+ {
+ lastEndpoint = tmpEndpoint;
+ }
+
+ lastEndTime = lastEndpoint->StartTime + lastEndpoint->CalcBusTime;
+
+ if (endTime < (lastEndTime - 1))
+ {
+ maxEndTime = lastEndTime;
+ endTime = maxEndTime;
+
+ if (nextEndpoint->StartTime == maxEndTime)
+ break;
+ }
+ else
+ {
+ maxEndTime = endTime;
+ }
+ }
+ }
+ }
+
+ if (maxEndTime >= nextEndpoint->StartTime)
+ break;
+
+ if (!USB2_MoveTtEndpoint(nextEndpoint,
+ maxEndTime - nextEndpoint->StartTime,
+ Rebalance,
+ *RebalanceListEntries,
+ &IsMoved))
+ {
+ if (!IsMoved)
+ {
+ DPRINT("USB2_DeallocateEndpointBudget: Not moved!\n");
+ }
+
+ break;
+ }
+
+ if (Period > nextEndpoint->ActualPeriod)
+ Period = nextEndpoint->ActualPeriod;
+ }
+ }
+
+ TtEndpoint->CalcBusTime = 0;
+
+ DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
+ IN PUSB2_REBALANCE Rebalance,
+ IN PULONG RebalanceListEntries)
+{
+ PUSB2_TT Tt;
+ PUSB2_HC_EXTENSION HcExtension;
+ ULONG Speed;
+ ULONG TimeUsed;
+ ULONG MinTimeUsed;
+ ULONG ix;
+ ULONG frame;
+ ULONG uframe;
+ ULONG Microframe;
+ ULONG TransferType;
+ ULONG Overhead;
+ ULONG LatestStart;
+ PUSB2_TT_ENDPOINT prevEndpoint;
+ PUSB2_TT_ENDPOINT nextEndpoint;
+ PUSB2_TT_ENDPOINT IntEndpoint;
+ ULONG StartTime;
+ ULONG calcBusTime;
+ BOOLEAN Result = TRUE;
+
+ DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint);
+
+ Tt = TtEndpoint->Tt;
+ HcExtension = Tt->HcExtension;
+
+ TtEndpoint->Nums.NumStarts = 0;
+ TtEndpoint->Nums.NumCompletes = 0;
+
+ TtEndpoint->StartFrame = 0;
+ TtEndpoint->StartMicroframe = 0;
+
+ if (TtEndpoint->CalcBusTime)
+ {
+ DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint already allocated!\n");
+ return FALSE;
+ }
+
+ Speed = TtEndpoint->TtEndpointParams.DeviceSpeed;
+
+ if (Speed == UsbHighSpeed)
+ {
+ if (TtEndpoint->Period > USB2_MAX_MICROFRAMES)
+ TtEndpoint->ActualPeriod = USB2_MAX_MICROFRAMES;
+ else
+ TtEndpoint->ActualPeriod = TtEndpoint->Period;
+
+ MinTimeUsed = HcExtension->TimeUsed[0][0];
+
+ for (ix = 1; ix < TtEndpoint->ActualPeriod; ix++)
+ {
+ frame = ix / USB2_MICROFRAMES;
+ uframe = ix % (USB2_MICROFRAMES - 1);
+
+ TimeUsed = HcExtension->TimeUsed[frame][uframe];
+
+ if (TimeUsed < MinTimeUsed)
+ {
+ MinTimeUsed = TimeUsed;
+ TtEndpoint->StartFrame = frame;
+ TtEndpoint->StartMicroframe = uframe;
+ }
+ }
+
+ TtEndpoint->CalcBusTime = USB2_GetOverhead(TtEndpoint) +
+ USB2_AddDataBitStuff(TtEndpoint->MaxPacketSize);
+
+ DPRINT("USB2_AllocateTimeForEndpoint: StartFrame - %X, StartMicroframe - %X, CalcBusTime - %X\n",
+ TtEndpoint->StartFrame,
+ TtEndpoint->StartMicroframe,
+ TtEndpoint->CalcBusTime);
+
+ Microframe = TtEndpoint->StartFrame * USB2_MICROFRAMES +
+ TtEndpoint->StartMicroframe;
+
+ if (Microframe >= USB2_MAX_MICROFRAMES)
+ {
+ DPRINT("USB2_AllocateTimeForEndpoint: Microframe >= 256. Result - TRUE\n");
+ return TRUE;
+ }
+
+ for (ix = Microframe;
+ ix < USB2_MAX_MICROFRAMES;
+ ix += TtEndpoint->ActualPeriod)
+ {
+ frame = ix / USB2_MICROFRAMES;
uframe = ix % (USB2_MICROFRAMES - 1);
DPRINT("USB2_AllocateTimeForEndpoint: frame - %X, uframe - %X, TimeUsed[f][uf] - %X\n",
}
if (Speed == UsbLowSpeed)
- {
TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize * 8 + Overhead;
- }
else
- {
TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead;
- }
LatestStart = USB2_HUB_DELAY + USB2_FS_SOF_TIME;
}
if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
- prevTtEndpoint = Tt->FrameBudget[frame].IsoEndpoint;
+ prevEndpoint = Tt->FrameBudget[frame].IsoEndpoint;
else
- prevTtEndpoint = Tt->FrameBudget[frame].IntEndpoint;
+ prevEndpoint = Tt->FrameBudget[frame].IntEndpoint;
- for (nextTtEndpoint = prevTtEndpoint->NextTtEndpoint;
- nextTtEndpoint;
- nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
+ for (nextEndpoint = prevEndpoint->NextTtEndpoint;
+ nextEndpoint;
+ nextEndpoint = nextEndpoint->NextTtEndpoint)
{
- if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint))
- {
+ if (USB2_CheckTtEndpointInsert(nextEndpoint, TtEndpoint))
break;
- }
- prevTtEndpoint = nextTtEndpoint;
+ prevEndpoint = nextEndpoint;
}
- StartTime = USB2_GetStartTime(nextTtEndpoint,
+ StartTime = USB2_GetStartTime(nextEndpoint,
TtEndpoint,
- prevTtEndpoint,
+ prevEndpoint,
frame);
- if (StartTime > LatestStart)
- LatestStart = StartTime;
+ LatestStart = max(LatestStart, StartTime);
}
TtEndpoint->StartTime = LatestStart;
else
{
IntEndpoint = Tt->FrameBudget[ix].IntEndpoint;
- nextTtEndpoint = IntEndpoint->NextTtEndpoint;
+ nextEndpoint = IntEndpoint->NextTtEndpoint;
- for (nextTtEndpoint = IntEndpoint->NextTtEndpoint;
- nextTtEndpoint;
- nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
+ for (nextEndpoint = IntEndpoint->NextTtEndpoint;
+ nextEndpoint;
+ nextEndpoint = nextEndpoint->NextTtEndpoint)
{
- if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint))
+ if (USB2_CheckTtEndpointInsert(nextEndpoint, TtEndpoint))
break;
- IntEndpoint = nextTtEndpoint;
+ IntEndpoint = nextEndpoint;
}
if ((frame % TtEndpoint->ActualPeriod) == 0)
}
else
{
- if (nextTtEndpoint)
+ if (nextEndpoint)
{
calcBusTime = LatestStart + TtEndpoint->CalcBusTime -
- nextTtEndpoint->StartTime;
+ nextEndpoint->StartTime;
}
else
{
}
}
- if (nextTtEndpoint != TtEndpoint)
+ if (nextEndpoint != TtEndpoint)
{
if ((frame % TtEndpoint->ActualPeriod) == 0)
{
if (frame == 0)
{
DPRINT("USB2_AllocateTimeForEndpoint: frame == 0\n");
- TtEndpoint->NextTtEndpoint = nextTtEndpoint;
+ TtEndpoint->NextTtEndpoint = nextEndpoint;
}
IntEndpoint->NextTtEndpoint = TtEndpoint;
- DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextTtEndpoint - %p\n",
+ DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextEndpoint - %p\n",
TtEndpoint,
- nextTtEndpoint);
+ nextEndpoint);
}
if (calcBusTime > 0)
BOOLEAN IsMoved;
BOOLEAN MoveResult;
- DPRINT("USB2_AllocateTimeForEndpoint: nextTtEndpoint - %p, calcBusTime - %X\n",
- nextTtEndpoint,
+ DPRINT("USB2_AllocateTimeForEndpoint: nextEndpoint - %p, calcBusTime - %X\n",
+ nextEndpoint,
calcBusTime);
for (;
- nextTtEndpoint;
- nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
+ nextEndpoint;
+ nextEndpoint = nextEndpoint->NextTtEndpoint)
{
- MoveResult = USB2_MoveTtEndpoint(nextTtEndpoint,
+ MoveResult = USB2_MoveTtEndpoint(nextEndpoint,
calcBusTime,
Rebalance,
*RebalanceListEntries,
return Result;
}
+BOOLEAN
+NTAPI
+USB2_ChangePeriod(IN PUSB2_TT_ENDPOINT TtEndpoint,
+ IN PUSB2_REBALANCE Rebalance,
+ IN PULONG RebalanceListEntries)
+{
+ BOOLEAN Result;
+
+ DPRINT("USB2_ChangePeriod: RebalanceListEntries - %X\n",
+ *RebalanceListEntries);
+
+ USB2_DeallocateEndpointBudget(TtEndpoint,
+ Rebalance,
+ RebalanceListEntries,
+ USB2_FRAMES);
+
+ TtEndpoint->PreviosPeriod = TtEndpoint->Period;
+ TtEndpoint->Period = ENDPOINT_INTERRUPT_1ms;
+
+ Result = USB2_AllocateTimeForEndpoint(TtEndpoint,
+ Rebalance,
+ RebalanceListEntries);
+
+ return Result;
+}
+
BOOLEAN
NTAPI
USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint,
IN PUSB2_REBALANCE Rebalance,
IN PULONG RebalanceListEntries)
{
- DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
- ASSERT(FALSE);
+ PUSB2_TT_ENDPOINT ttEndpoint;
+ ULONG TransferType;
+ ULONG ix;
+
+ TransferType = TtEndpoint->TtEndpointParams.TransferType;
+
+ if (TtEndpoint->ActualPeriod != ENDPOINT_INTERRUPT_1ms &&
+ TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT &&
+ (CHAR)TtEndpoint->StartMicroframe > 2 &&
+ !USB2_ChangePeriod(TtEndpoint, Rebalance, RebalanceListEntries))
+ {
+ DPRINT("USB2_PromotePeriods: return FALSE\n");
+ return FALSE;
+ }
+
+ if (Rebalance->RebalanceEndpoint[0] == NULL)
+ {
+ DPRINT("USB2_PromotePeriods: return TRUE\n");
+ return TRUE;
+ }
+
+ DPRINT("USB2_PromotePeriods: RebalanceListEntries - %X\n",
+ *RebalanceListEntries);
+
+ for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++)
+ {
+ Rebalance->RebalanceEndpoint[ix]->IsPromoted = FALSE;
+ }
+
+ for (ix = 0; ; ix++)
+ {
+ ttEndpoint = Rebalance->RebalanceEndpoint[ix];
+ TransferType = ttEndpoint->TtEndpointParams.TransferType;
+
+ if (ttEndpoint->ActualPeriod != ENDPOINT_INTERRUPT_1ms &&
+ TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT &&
+ (CHAR)ttEndpoint->StartMicroframe > 2)
+ {
+ USB2_DeallocateEndpointBudget(ttEndpoint,
+ Rebalance,
+ RebalanceListEntries,
+ USB2_FRAMES);
+
+ ttEndpoint->IsPromoted = TRUE;
+ ttEndpoint->PreviosPeriod = ttEndpoint->Period;
+ ttEndpoint->Period = ENDPOINT_INTERRUPT_1ms;
+
+ if (!USB2_AllocateTimeForEndpoint(ttEndpoint,
+ Rebalance,
+ RebalanceListEntries))
+ {
+ break;
+ }
+ }
+
+ if (Rebalance->RebalanceEndpoint[ix + 1] == NULL)
+ {
+ DPRINT("USB2_PromotePeriods: return TRUE\n");
+ return TRUE;
+ }
+ }
+
+ USB2_DeallocateEndpointBudget(TtEndpoint,
+ Rebalance,
+ RebalanceListEntries,
+ USB2_FRAMES);
+
+ TtEndpoint->Period = TtEndpoint->PreviosPeriod;
+ TtEndpoint->PreviosPeriod = 0;
+
+ for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++)
+ {
+ ttEndpoint = Rebalance->RebalanceEndpoint[ix];
+
+ if (ttEndpoint->IsPromoted)
+ {
+ if (ttEndpoint->CalcBusTime)
+ {
+ USB2_DeallocateEndpointBudget(ttEndpoint,
+ Rebalance,
+ RebalanceListEntries,
+ USB2_FRAMES);
+ }
+
+ TtEndpoint->Period = TtEndpoint->PreviosPeriod;
+ TtEndpoint->PreviosPeriod = 0;
+
+ USB2_AllocateTimeForEndpoint(ttEndpoint,
+ Rebalance,
+ RebalanceListEntries);
+ }
+ }
+
+ DPRINT("USB2_PromotePeriods: return FALSE\n");
return FALSE;
}
{
NewBusBandwidth = BusBandwidth - TtExtension->Bandwidth[ix];
- if (NewBusBandwidth > MaxBusBandwidth)
- MaxBusBandwidth = NewBusBandwidth;
-
- if (NewBusBandwidth < MinBusBandwidth)
- MinBusBandwidth = NewBusBandwidth;
+ MaxBusBandwidth = max(MaxBusBandwidth, NewBusBandwidth);
+ MinBusBandwidth = min(MinBusBandwidth, NewBusBandwidth);
}
TtExtension->MaxBandwidth = MaxBusBandwidth;
case UsbFullSpeed:
{
Tt = &TtExtension->Tt;
-
Period = USB2_FRAMES;
while (Period > 0 && Period > EndpointProperties->Period)
ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
EndpointProperties->ScheduleOffset = ScheduleOffset;
+ ASSERT(ActualPeriod);
Factor = USB2_FRAMES / ActualPeriod;
- ASSERT(Factor);
-
n = ScheduleOffset * Factor;
if (TtExtension)
}
}
- //USB2_Rebalance(FdoDevice, &RebalanceList);
+ USB2_Rebalance(FdoDevice, &RebalanceList);
if (!TtExtension)
{
USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
IN PUSBPORT_ENDPOINT Endpoint)
{
- DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
+ PUSBPORT_DEVICE_EXTENSION FdoExtension;
+ ULONG Period;
+ ULONG ScheduleOffset;
+ ULONG EndpointBandwidth;
+ LIST_ENTRY RebalanceList;
+ ULONG TransferType;
+ PUSB2_REBALANCE Rebalance;
+ ULONG RebalanceListEntries;
+ ULONG Factor;
+ ULONG ix;
+ ULONG n;
+ PUSB2_TT_EXTENSION TtExtension;
+ PUSB2_TT_ENDPOINT RebalanceTtEndpoint;
+
+ DPRINT("USBPORT_FreeBandwidthUSB2: Endpoint - %p\n", Endpoint);
+
+ FdoExtension = FdoDevice->DeviceExtension;
+
+ Period = Endpoint->EndpointProperties.Period;
+ ScheduleOffset = Endpoint->EndpointProperties.ScheduleOffset;
+ EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth;
+
+ InitializeListHead(&RebalanceList);
+
+ TransferType = Endpoint->EndpointProperties.TransferType;
+
+ if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
+ TransferType == USBPORT_TRANSFER_TYPE_BULK ||
+ (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
+ {
+ return;
+ }
+
+ Rebalance = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(USB2_REBALANCE),
+ USB_PORT_TAG);
+
+ if (!Rebalance)
+ {
+ DPRINT1("USBPORT_FreeBandwidthUSB2: Rebalance == NULL!\n");
+ return;
+ }
+
+ RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE));
+
+ ASSERT(Period != 0);
+ Factor = USB2_FRAMES / Period;
+ n = ScheduleOffset * Factor;
+
+ TtExtension = Endpoint->TtExtension;
+
+ if (TtExtension)
+ {
+ for (ix = 0; ix < Factor; ix++)
+ {
+ TtExtension->Bandwidth[n + ix] += EndpointBandwidth;
+ }
+ }
+ else
+ {
+ for (ix = 1; ix < Factor; ix++)
+ {
+ FdoExtension->Bandwidth[n + ix] += EndpointBandwidth;
+ }
+ }
+
+ RebalanceListEntries = USB2_FRAMES - 2;
+
+ USB2_DeallocateEndpointBudget(Endpoint->TtEndpoint,
+ Rebalance,
+ &RebalanceListEntries,
+ USB2_FRAMES);
+
+ RebalanceListEntries = 0;
+
+ for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++)
+ {
+ RebalanceListEntries = ix + 1;
+ }
+
+ for (ix = 0; ix < RebalanceListEntries; ix++)
+ {
+ RebalanceTtEndpoint = Rebalance->RebalanceEndpoint[ix];
+
+ DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
+ ix,
+ RebalanceTtEndpoint,
+ &RebalanceTtEndpoint->Endpoint->RebalanceLink);
+
+ InsertTailList(&RebalanceList,
+ &RebalanceTtEndpoint->Endpoint->RebalanceLink);
+ }
+
+ ExFreePoolWithTag(Rebalance, USB_PORT_TAG);
+
+ USB2_Rebalance(FdoDevice, &RebalanceList);
+
+ if (!TtExtension)
+ return;
+
+ for (ix = 0; ix < USB2_FRAMES; ix++)
+ {
+ FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
+ }
+
+ USBPORT_UpdateAllocatedBwTt(TtExtension);
+
+ for (ix = 0; ix < USB2_FRAMES; ix++)
+ {
+ FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth;
+ }
+
+ DPRINT1("USBPORT_FreeBandwidthUSB2: exit\n");
}
VOID
Tt->IsoEndpoint[ix].ActualPeriod = USB2_FRAMES;
Tt->IsoEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
Tt->IsoEndpoint[ix].StartFrame = ix;
- Tt->IsoEndpoint[ix].StartMicroframe = 0xFF;
+ Tt->IsoEndpoint[ix].StartMicroframe = USB2_PREV_MICROFRAME;
Tt->FrameBudget[ix].IntEndpoint = &Tt->IntEndpoint[ix];
Tt->IntEndpoint[ix].ActualPeriod = USB2_FRAMES;
Tt->IntEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
Tt->IntEndpoint[ix].StartFrame = ix;
- Tt->IntEndpoint[ix].StartMicroframe = 0xFF;
+ Tt->IntEndpoint[ix].StartMicroframe = USB2_PREV_MICROFRAME;
}
}