{
PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
ULONG Bandwidth;
- ULONG Additional;
+ ULONG Overhead;
DPRINT("USBPORT_CalculateUsbBandwidth ... \n");
switch (EndpointProperties->TransferType)
{
case USBPORT_TRANSFER_TYPE_ISOCHRONOUS:
- Additional = 9;
+ Overhead = USB2_FS_ISOCHRONOUS_OVERHEAD;
break;
case USBPORT_TRANSFER_TYPE_INTERRUPT:
- Additional = 13;
+ Overhead = USB2_FS_INTERRUPT_OVERHEAD;
break;
default: //USBPORT_TRANSFER_TYPE_CONTROL or USBPORT_TRANSFER_TYPE_BULK
- Additional = 0;
+ Overhead = 0;
break;
}
- if (Additional == 0)
+ if (Overhead == 0)
{
Bandwidth = 0;
}
else
{
- Bandwidth = (EndpointProperties->TotalMaxPacketSize + Additional) * 8 * 7 / 6;
+ Bandwidth = (EndpointProperties->TotalMaxPacketSize + Overhead) * 8 * 7 / 6;
}
if (EndpointProperties->DeviceSpeed == UsbLowSpeed)
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;
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
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
BOOLEAN Result;
KIRQL OldIrql;
- DPRINT("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint);
+ DPRINT1("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint);
FdoExtension = FdoDevice->DeviceExtension;
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;
}
Endpoint = PipeHandle->Endpoint;
- DPRINT("USBPORT_ClosePipe: Endpoint - %p\n", Endpoint);
KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
}
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);
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);
if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
{
- DPRINT1("USBPORT_OpenPipe: FIXME USB2 EndpointSize\n");
+ EndpointSize += sizeof(USB2_TT_ENDPOINT);
}
if (PipeHandle->EndpointDescriptor.wMaxPacketSize == 0)
{
USBPORT_AddPipeHandle(DeviceHandle, PipeHandle);
-
+
PipeHandle->Flags = (PipeHandle->Flags & ~PIPE_HANDLE_FLAG_CLOSED) |
PIPE_HANDLE_FLAG_NULL_PACKET_SIZE;
Endpoint->DeviceHandle = DeviceHandle;
Endpoint->LockCounter = -1;
+ Endpoint->TtExtension = DeviceHandle->TtExtension;
+
+ if (DeviceHandle->TtExtension)
+ {
+ ExInterlockedInsertTailList(&DeviceHandle->TtExtension->EndpointList,
+ &Endpoint->TtLink,
+ &FdoExtension->TtSpinLock);
+ }
+
+ if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
+ {
+ Endpoint->TtEndpoint = (PUSB2_TT_ENDPOINT)((ULONG_PTR)Endpoint +
+ sizeof(USBPORT_ENDPOINT) +
+ Packet->MiniPortEndpointSize);
+ }
+ else
+ {
+ Endpoint->TtEndpoint = NULL;
+ }
+
KeInitializeSpinLock(&Endpoint->EndpointSpinLock);
KeInitializeSpinLock(&Endpoint->StateChangeSpinLock);
EndpointProperties->TotalMaxPacketSize = MaxPacketSize *
(AdditionalTransaction + 1);
+ if (Endpoint->TtExtension)
+ {
+ EndpointProperties->HubAddr = Endpoint->TtExtension->DeviceAddress;
+ }
+ else
+ {
+ EndpointProperties->HubAddr = -1;
+ }
+
+ EndpointProperties->PortNumber = DeviceHandle->PortNumber;
+
switch (EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
{
case USB_ENDPOINT_TYPE_CONTROL:
Interval = EndpointDescriptor->bInterval;
}
- EndpointProperties->Period = 32;
+ EndpointProperties->Period = ENDPOINT_INTERRUPT_32ms;
- if (Interval && (Interval < 32))
+ if (Interval && (Interval < USB2_FRAMES))
{
if ((EndpointProperties->DeviceSpeed != UsbLowSpeed) ||
- (Interval >= 8))
+ (Interval >= ENDPOINT_INTERRUPT_8ms))
{
- if (!(Interval & 0x20))
+ if (!(Interval & ENDPOINT_INTERRUPT_32ms))
{
Period = EndpointProperties->Period;
}
else
{
- EndpointProperties->Period = 8;
+ EndpointProperties->Period = ENDPOINT_INTERRUPT_8ms;
}
}
}
{
if (EndpointProperties->DeviceSpeed == UsbHighSpeed)
{
- EndpointProperties->Period =
+ EndpointProperties->Period =
USBPORT_NormalizeHsInterval(EndpointDescriptor->bInterval);
}
else
{
- EndpointProperties->Period = 1;
+ EndpointProperties->Period = ENDPOINT_INTERRUPT_1ms;
}
}
+ if ((DeviceHandle->Flags & DEVICE_HANDLE_FLAG_ROOTHUB) != 0)
+ {
+ Endpoint->Flags |= ENDPOINT_FLAG_ROOTHUB_EP0;
+ }
+
if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
{
IsAllocatedBandwidth = USBPORT_AllocateBandwidthUSB2(FdoDevice, Endpoint);
}
}
+ if (Endpoint->TtExtension)
+ {
+ KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql);
+ RemoveEntryList(&Endpoint->TtLink);
+ KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql);
+ }
+
ExFreePoolWithTag(Endpoint, USB_PORT_TAG);
}
KIRQL MiniportOldIrql;
NTSTATUS Status;
- DPRINT("USBPORT_ReopenPipe ... \n");
+ DPRINT1("USBPORT_ReopenPipe ... \n");
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;