#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;
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 (TtEndpoint->StartMicroframe == 0xFF)
- {
+ if (TtEndpoint->StartMicroframe == USB2_PREV_MICROFRAME)
USB2_GetPrevMicroFrame(&frame, &uframe);
- }
DataTime = 0;
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);
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;
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)
if (Rebalance->RebalanceEndpoint[Num] &&
TtEndpoint->TtEndpointParams.EndpointMoved == TRUE &&
- (TransferType != USBPORT_TRANSFER_TYPE_INTERRUPT || BusTime >= 0))
+ ((TransferType != USBPORT_TRANSFER_TYPE_INTERRUPT) || BusTime >= 0))
{
DPRINT("USB2_MoveTtEndpoint: result - FALSE\n");
return FALSE;
}
if (NextTtEndpoint->ActualPeriod < TtEndpoint->ActualPeriod)
- {
Frame = TtEndpoint->StartFrame % TtEndpoint->ActualPeriod;
- }
else
- {
Frame = NextTtEndpoint->StartFrame % TtEndpoint->ActualPeriod;
- }
return (Frame == TtEndpoint->StartFrame);
}
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;
}
+VOID
+NTAPI
+USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice,
+ IN PLIST_ENTRY List)
+{
+ 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;
+ KIRQL OldIrql;
+ UCHAR NewPeriod;
+ UCHAR SMask;
+ UCHAR CMask;
+
+ FdoExtension = FdoDevice->DeviceExtension;
+ Packet = &FdoExtension->MiniPortInterface->Packet;
+
+ while (!IsListEmpty(List))
+ {
+ Entry = RemoveHeadList(List);
+
+ Endpoint = CONTAINING_RECORD(Entry,
+ USBPORT_ENDPOINT,
+ RebalanceLink.Flink);
+
+ DPRINT("USB2_RebalanceEndpoint: Endpoint - %p\n", Endpoint);
+
+ Endpoint->RebalanceLink.Flink = NULL;
+ Endpoint->RebalanceLink.Blink = NULL;
+
+ KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
+ &Endpoint->EndpointOldIrql);
+
+ SMask = USB2_GetSMASK(Endpoint->TtEndpoint);
+ CMask = USB2_GetCMASK(Endpoint->TtEndpoint);
+
+ ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
+ NewPeriod = Endpoint->TtEndpoint->ActualPeriod;
+
+ AllocedBusTime = Endpoint->TtEndpoint->CalcBusTime;
+ EndpointBandwidth = USB2_MICROFRAMES * AllocedBusTime;
+
+ Endpoint->EndpointProperties.InterruptScheduleMask = SMask;
+ Endpoint->EndpointProperties.SplitCompletionMask = CMask;
+
+ if (Endpoint->EndpointProperties.Period != NewPeriod)
+ {
+ ASSERT(Endpoint->EndpointProperties.Period);
+ Factor = USB2_FRAMES / Endpoint->EndpointProperties.Period;
+
+ for (ix = 0; ix < Factor; ix++)
+ {
+ Bandwidth = Endpoint->EndpointProperties.UsbBandwidth;
+ n = Factor * Endpoint->EndpointProperties.ScheduleOffset;
+ Endpoint->TtExtension->Bandwidth[n + ix] += Bandwidth;
+ }
+
+ Endpoint->EndpointProperties.Period = NewPeriod;
+ Endpoint->EndpointProperties.ScheduleOffset = ScheduleOffset;
+ Endpoint->EndpointProperties.UsbBandwidth = EndpointBandwidth;
+
+ ASSERT(NewPeriod);
+ Factor = USB2_FRAMES / NewPeriod;
+
+ for (ix = 0; ix < Factor; ix++)
+ {
+ n = Factor * ScheduleOffset;
+ Endpoint->TtExtension->Bandwidth[n + ix] += EndpointBandwidth;
+ }
+ }
+
+ KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
+
+ Packet->RebalanceEndpoint(FdoExtension->MiniPortExt,
+ &Endpoint->EndpointProperties,
+ (PVOID)((ULONG_PTR)Endpoint + sizeof(USBPORT_ENDPOINT)));
+
+ KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
+
+ KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
+ Endpoint->EndpointOldIrql);
+ }
+}
+
+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,
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\n",
+ DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, MaxFrames - %X, CalcBusTime - %X\n",
TtEndpoint,
- MaxFrames);
+ MaxFrames,
+ TtEndpoint->CalcBusTime);
if (TtEndpoint->CalcBusTime == 0)
{
- DPRINT("USB2_DeallocateEndpointBudget: endpoint not allocated\n");//error((int)"endpoint not allocated");
+ DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint not allocated!\n");
return FALSE;
}
/* Speed != UsbHighSpeed (FS/LS) */
- DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n");
- ASSERT(FALSE);
+ 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;
}
}
if (Speed == UsbLowSpeed)
- {
TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize * 8 + Overhead;
- }
else
- {
TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead;
- }
LatestStart = USB2_HUB_DELAY + USB2_FS_SOF_TIME;
nextEndpoint = nextEndpoint->NextTtEndpoint)
{
if (USB2_CheckTtEndpointInsert(nextEndpoint, TtEndpoint))
- {
break;
- }
prevEndpoint = nextEndpoint;
}
prevEndpoint,
frame);
- if (StartTime > LatestStart)
- LatestStart = StartTime;
+ LatestStart = max(LatestStart, StartTime);
}
TtEndpoint->StartTime = LatestStart;
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;
}
}