From d4ff198c7c620e39f12b60c04005a48cfe4bad42 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 15:41:44 +0900 Subject: [PATCH 01/76] [PSDK] Add USB hub class-specific request type codes. --- sdk/include/psdk/usb200.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdk/include/psdk/usb200.h b/sdk/include/psdk/usb200.h index 8babb868e2d..c2afc73b815 100644 --- a/sdk/include/psdk/usb200.h +++ b/sdk/include/psdk/usb200.h @@ -279,6 +279,14 @@ C_ASSERT(sizeof(USB_HUB_STATUS_AND_CHANGE) == sizeof(ULONG)); #define USB_20_HUB_DESCRIPTOR_TYPE 0x29 #define USB_30_HUB_DESCRIPTOR_TYPE 0x2A +#define USB_REQUEST_CLEAR_TT_BUFFER 0x08 +#define USB_REQUEST_RESET_TT 0x09 +#define USB_REQUEST_GET_TT_STATE 0x0A +#define USB_REQUEST_STOP_TT 0x0B + +#define USB_REQUEST_SET_HUB_DEPTH 0x0C +#define USB_REQUEST_GET_PORT_ERR_COUNT 0x0D + #define USB_DEVICE_CLASS_RESERVED 0x00 #define USB_DEVICE_CLASS_AUDIO 0x01 #define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 From 41f4814c441bb6e6ccfbc3e66546c23cb5517c93 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 16:03:20 +0900 Subject: [PATCH 02/76] [USBPORT] Define constants for Transaction Translator. --- drivers/usb/usbport/usbport.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 26e021cb14d..0db831b0b9e 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -430,6 +430,30 @@ typedef struct _TIMER_WORK_QUEUE_ITEM { ULONG Context; } TIMER_WORK_QUEUE_ITEM, *PTIMER_WORK_QUEUE_ITEM; +/* Transaction Translator */ +/* See Chapter 5 - USB Data Flow Model and Chapter 11 - Hub Specification */ + +#define USB2_FRAMES 32 +#define USB2_MICROFRAMES 8 +#define USB2_MAX_MICROFRAMES (USB2_FRAMES * USB2_MICROFRAMES) + +#define USB2_MAX_MICROFRAME_ALLOCATION 7000 // bytes +#define USB2_CONTROLLER_DELAY 100 +#define USB2_FS_MAX_PERIODIC_ALLOCATION 1157 // ((12000 / 8 bits) * 0.9) / (7/6) - 90% max, and bits stuffing +#define USB2_FS_SOF_TIME 6 +#define USB2_HUB_DELAY 30 +#define USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME 16 +#define USB2_FS_RAW_BYTES_IN_MICROFRAME 188 // (12000 / 8 bits / USB2_MICROFRAMES) = 187,5. But we use "best case budget" + +/* Overheads */ +#define USB2_LS_INTERRUPT_OVERHEAD 117 // FS-bytes +#define USB2_FS_INTERRUPT_OVERHEAD 13 +#define USB2_HS_INTERRUPT_OUT_OVERHEAD 45 +#define USB2_HS_INTERRUPT_IN_OVERHEAD 25 +#define USB2_FS_ISOCHRONOUS_OVERHEAD 9 +#define USB2_HS_ISOCHRONOUS_OUT_OVERHEAD 38 +#define USB2_HS_ISOCHRONOUS_IN_OVERHEAD 18 + /* usbport.c */ NTSTATUS NTAPI From a3dd5620d3758a45e3afd29c9b4a45a9633330d6 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 16:27:49 +0900 Subject: [PATCH 03/76] [USBPORT] Use constants in USBPORT_CalculateUsbBandwidth(). --- drivers/usb/usbport/endpoint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 7cf250e76ca..d2005a87d2d 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -20,7 +20,7 @@ USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice, { PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties; ULONG Bandwidth; - ULONG Additional; + ULONG Overhead; DPRINT("USBPORT_CalculateUsbBandwidth ... \n"); @@ -29,25 +29,25 @@ USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice, 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) From d2b088e9d6df771bedc7fc4ca68b713f8f233bd5 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 16:54:18 +0900 Subject: [PATCH 04/76] [USBPORT] Define structures for Transaction Translator. --- drivers/usb/usbport/usbport.h | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 0db831b0b9e..b838baff0d3 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -454,6 +454,87 @@ typedef struct _TIMER_WORK_QUEUE_ITEM { #define USB2_HS_ISOCHRONOUS_OUT_OVERHEAD 38 #define USB2_HS_ISOCHRONOUS_IN_OVERHEAD 18 +typedef union _USB2_TT_ENDPOINT_PARAMS { + struct { + ULONG TransferType : 4; + ULONG Direction : 1; + USB_DEVICE_SPEED DeviceSpeed : 2; + ULONG EndpointMoved : 1; + ULONG Reserved : 24; + }; + ULONG AsULONG; +} USB2_TT_ENDPOINT_PARAMS; + +C_ASSERT(sizeof(USB2_TT_ENDPOINT_PARAMS) == sizeof(ULONG)); + +typedef union _USB2_TT_ENDPOINT_NUMS { + struct { + ULONG NumStarts : 4; + ULONG NumCompletes : 4; + ULONG Reserved : 24; + }; + ULONG AsULONG; +} USB2_TT_ENDPOINT_NUMS; + +C_ASSERT(sizeof(USB2_TT_ENDPOINT_NUMS) == sizeof(ULONG)); + +typedef struct _USB2_TT_ENDPOINT { + PUSB2_TT Tt; + PUSBPORT_ENDPOINT Endpoint; + struct _USB2_TT_ENDPOINT * NextTtEndpoint; + USB2_TT_ENDPOINT_PARAMS TtEndpointParams; + USB2_TT_ENDPOINT_NUMS Nums; + USHORT MaxPacketSize; + USHORT PreviosPeriod; + USHORT Period; + USHORT ActualPeriod; + USHORT CalcBusTime; + USHORT StartTime; + USHORT Reserved2; + UCHAR StartFrame; + UCHAR StartMicroframe; +} USB2_TT_ENDPOINT, *PUSB2_TT_ENDPOINT; + +typedef struct _USB2_FRAME_BUDGET { + PUSB2_TT_ENDPOINT IsoEndpoint; + PUSB2_TT_ENDPOINT IntEndpoint; + PUSB2_TT_ENDPOINT AltEndpoint; + USHORT TimeUsed; + USHORT Reserved2; +} USB2_FRAME_BUDGET, *PUSB2_FRAME_BUDGET; + +typedef struct _USB2_TT { + PUSB2_HC_EXTENSION HcExtension; + ULONG DelayTime; + ULONG MaxTime; + USB2_TT_ENDPOINT IntEndpoint[USB2_FRAMES]; + USB2_TT_ENDPOINT IsoEndpoint[USB2_FRAMES]; + USB2_FRAME_BUDGET FrameBudget[USB2_FRAMES]; + ULONG NumStartSplits[USB2_FRAMES][USB2_MICROFRAMES]; + ULONG TimeCS[USB2_FRAMES][USB2_MICROFRAMES]; +} USB2_TT, *PUSB2_TT; + +typedef struct _USB2_TT_EXTENSION { + PDEVICE_OBJECT RootHubPdo; + ULONG Flags; + ULONG BusBandwidth; + ULONG Bandwidth[USB2_FRAMES]; + ULONG MaxBandwidth; + ULONG MinBandwidth; + USHORT DeviceAddress; + USHORT TtNumber; + LIST_ENTRY TtList; + LIST_ENTRY Link; + USB2_TT Tt; +} USB2_TT_EXTENSION, *PUSB2_TT_EXTENSION; + +typedef struct _USB2_HC_EXTENSION { + ULONG MaxHsBusAllocation; + ULONG HcDelayTime; + ULONG TimeUsed[USB2_FRAMES][USB2_MICROFRAMES]; + USB2_TT HcTt; +} USB2_HC_EXTENSION, *PUSB2_HC_EXTENSION; + /* usbport.c */ NTSTATUS NTAPI From 0b78ad8eb27dc9259f757277a9398a113ff603d6 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 16:56:19 +0900 Subject: [PATCH 05/76] [USBPORT] Use constants in USBPORT_OpenPipe(). --- drivers/usb/usbport/endpoint.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index d2005a87d2d..be2c7eab6d8 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -642,13 +642,13 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, 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; @@ -739,14 +739,14 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, 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; @@ -761,7 +761,7 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, } else { - EndpointProperties->Period = 8; + EndpointProperties->Period = ENDPOINT_INTERRUPT_8ms; } } } @@ -770,15 +770,20 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, { 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); From faa792987b0cfab49415498bcc066d3931266c91 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 17:41:08 +0900 Subject: [PATCH 06/76] [USBPORT] Add initial support for transaction translators in USBPORT_AddDevice(). --- drivers/usb/usbport/usbport.c | 19 ++++++++++++++++++- drivers/usb/usbport/usbport.h | 7 ++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usbport.c b/drivers/usb/usbport/usbport.c index 09286465bbe..1dbe779daa5 100644 --- a/drivers/usb/usbport/usbport.c +++ b/drivers/usb/usbport/usbport.c @@ -1845,7 +1845,8 @@ USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject, RtlInitUnicodeString(&DeviceName, CharDeviceName); Length = sizeof(USBPORT_DEVICE_EXTENSION) + - MiniPortInterface->Packet.MiniPortExtensionSize; + MiniPortInterface->Packet.MiniPortExtensionSize + + sizeof(USB2_HC_EXTENSION); /* Create device */ Status = IoCreateDevice(DriverObject, @@ -1903,6 +1904,22 @@ USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject, FdoExtension->MiniPortExt = (PVOID)((ULONG_PTR)FdoExtension + sizeof(USBPORT_DEVICE_EXTENSION)); + if (MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2) + { + FdoExtension->Usb2Extension = + (PUSB2_HC_EXTENSION)FdoExtension->MiniPortExt + + MiniPortInterface->Packet.MiniPortExtensionSize; + + DPRINT("USBPORT_AddDevice: Usb2Extension - %p\n", + FdoExtension->Usb2Extension); + + USB2_InitController(FdoExtension->Usb2Extension); + } + else + { + FdoExtension->Usb2Extension = NULL; + } + FdoExtension->MiniPortInterface = MiniPortInterface; FdoExtension->FdoNameNumber = DeviceNumber; diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index b838baff0d3..5145c26e92e 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -153,6 +153,9 @@ typedef struct _USBPORT_COMMON_BUFFER_HEADER { typedef struct _USBPORT_ENDPOINT *PUSBPORT_ENDPOINT; +typedef struct _USB2_HC_EXTENSION *PUSB2_HC_EXTENSION; +typedef struct _USB2_TT *PUSB2_TT; + typedef struct _USBPORT_PIPE_HANDLE { ULONG Flags; ULONG PipeFlags; @@ -374,10 +377,12 @@ typedef struct _USBPORT_DEVICE_EXTENSION { KSPIN_LOCK SetPowerD0SpinLock; KDPC WorkerRequestDpc; KDPC HcWakeDpc; + /* Usb 2.0 HC Extension */ + PUSB2_HC_EXTENSION Usb2Extension; /* Miniport extension should be aligned on 0x100 */ #if !defined(_M_X64) - ULONG Padded[34]; + ULONG Padded[33]; #else ULONG Padded[0]; #endif From 0f2f4c6ca227ff4d1d080f84c9084cd75d222450 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 17:47:25 +0900 Subject: [PATCH 07/76] [USBPORT] Add USB2_InitController(). --- drivers/usb/usbport/usb2.c | 24 ++++++++++++++++++++++++ drivers/usb/usbport/usbport.h | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 920d01a2199..c274e6959be 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -26,3 +26,27 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, { DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n"); } + +VOID +NTAPI +USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension) +{ + ULONG ix; + ULONG jx; + + DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension); + + HcExtension->MaxHsBusAllocation = USB2_MAX_MICROFRAME_ALLOCATION; + + for (ix = 0; ix < USB2_FRAMES; ix++) + { + for (jx = 0; jx < USB2_MICROFRAMES; jx++) + { + HcExtension->TimeUsed[ix][jx] = 0; + } + } + + HcExtension->HcDelayTime = USB2_CONTROLLER_DELAY; + + USB2_InitTT(HcExtension, &HcExtension->HcTt); +} diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 5145c26e92e..93c71a9516a 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -1294,4 +1294,9 @@ USBPORT_FreeBandwidthUSB2( IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint); +VOID +NTAPI +USB2_InitController( + IN PUSB2_HC_EXTENSION HcExtension); + #endif /* USBPORT_H__ */ From 9cdc1d64b3e2f9f26baeb7632de2e4b07696bb62 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 17:50:47 +0900 Subject: [PATCH 08/76] [USBPORT] Add USB2_InitTT(). --- drivers/usb/usbport/usb2.c | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index c274e6959be..6d71769376b 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -27,6 +27,63 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n"); } +VOID +NTAPI +USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension, + IN PUSB2_TT Tt) +{ + ULONG ix; + ULONG jx; + + DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension, Tt); + + Tt->HcExtension = HcExtension; + Tt->DelayTime = 1; + Tt->MaxTime = USB2_FS_MAX_PERIODIC_ALLOCATION; + + for (ix = 0; ix < USB2_FRAMES; ix++) + { + Tt->FrameBudget[ix].TimeUsed = USB2_MAX_MICROFRAMES; + Tt->FrameBudget[ix].AltEndpoint = NULL; + + for (jx = 0; jx < USB2_MICROFRAMES; jx++) + { + Tt->TimeCS[ix][jx] = 0; + Tt->NumStartSplits[ix][jx] = 0; + } + + Tt->FrameBudget[ix].IsoEndpoint = &Tt->IsoEndpoint[ix]; + + USB2_InitTtEndpoint(&Tt->IsoEndpoint[ix], + USBPORT_TRANSFER_TYPE_ISOCHRONOUS, + USBPORT_TRANSFER_DIRECTION_OUT, + UsbFullSpeed, + USB2_FRAMES, + 0, + Tt); + + 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->FrameBudget[ix].IntEndpoint = &Tt->IntEndpoint[ix]; + + USB2_InitTtEndpoint(&Tt->IntEndpoint[ix], + USBPORT_TRANSFER_TYPE_INTERRUPT, + USBPORT_TRANSFER_DIRECTION_OUT, + UsbFullSpeed, + USB2_FRAMES, + 0, + Tt); + + 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; + } +} + VOID NTAPI USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension) From da1e283837ada49a0d214f8cb1ba5e84782d40d8 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 18:19:05 +0900 Subject: [PATCH 09/76] [USBPORT] Add USB2_InitTtEndpoint(). --- drivers/usb/usbport/usb2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 6d71769376b..1c4cd042de3 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -10,6 +10,27 @@ //#define NDEBUG #include +VOID +NTAPI +USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN UCHAR TransferType, + IN UCHAR Direction, + IN UCHAR DeviceSpeed, + IN USHORT Period, + IN USHORT MaxPacketSize, + IN PUSB2_TT Tt) +{ + RtlZeroMemory(TtEndpoint, sizeof(USB2_TT_ENDPOINT)); + + TtEndpoint->TtEndpointParams.TransferType = TransferType; + TtEndpoint->TtEndpointParams.Direction = Direction; + TtEndpoint->TtEndpointParams.DeviceSpeed = DeviceSpeed; + + TtEndpoint->Period = Period; + TtEndpoint->MaxPacketSize = MaxPacketSize; + TtEndpoint->Tt = Tt; +} + BOOLEAN NTAPI USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, From 18702047a16f49053de4597a56879edb357a3a24 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 18:20:28 +0900 Subject: [PATCH 10/76] [USBPORT] Implement USBPORT_InitializeTT(). --- drivers/usb/usbport/device.c | 52 +++++++++++++++++++++++++++++++++-- drivers/usb/usbport/usbport.h | 10 ++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index f7180aaf96e..268571fd7fd 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -1770,7 +1770,55 @@ USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, IN ULONG TtNumber) { - DPRINT1("USBPORT_InitializeTT: UNIMPLEMENTED. FIXME. \n"); + PUSBPORT_DEVICE_EXTENSION FdoExtension; + PUSB2_TT_EXTENSION TtExtension; + ULONG ix; + + DPRINT("USBPORT_InitializeTT: HubDeviceHandle - %p, TtNumber - %X\n", + HubDeviceHandle, + TtNumber); + + FdoExtension = FdoDevice->DeviceExtension; + + TtExtension = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB2_TT_EXTENSION), + USB_PORT_TAG); + + if (!TtExtension) + { + DPRINT1("USBPORT_InitializeTT: ExAllocatePoolWithTag return NULL\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + DPRINT("USBPORT_InitializeTT: TtExtension - %p\n", TtExtension); + + RtlZeroMemory(TtExtension, sizeof(USB2_TT_EXTENSION)); + + TtExtension->DeviceAddress = HubDeviceHandle->DeviceAddress; + TtExtension->TtNumber = TtNumber; + TtExtension->RootHubPdo = FdoExtension->RootHubPdo; + TtExtension->BusBandwidth = TOTAL_USB11_BUS_BANDWIDTH; + + InitializeListHead(&TtExtension->TtList); + + /* 90% maximum allowed for periodic endpoints */ + for (ix = 0; ix < USB2_FRAMES; ix++) + { + TtExtension->Bandwidth[ix] = TtExtension->BusBandwidth - + TtExtension->BusBandwidth / 10; + } + + USBPORT_UpdateAllocatedBwTt(TtExtension); + + for (ix = 0; ix < USB2_FRAMES; ix++) + { + FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth; + } + + USB2_InitTT(FdoExtension->Usb2Extension, &TtExtension->Tt); + + InsertTailList(&HubDeviceHandle->TtList, &TtExtension->Link); + return STATUS_SUCCESS; } @@ -1783,7 +1831,7 @@ USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice, NTSTATUS Status; ULONG ix; - DPRINT("USBPORT_Initialize20Hub \n"); + DPRINT("USBPORT_Initialize20Hub: TtCount - %X\n", TtCount); if (!HubDeviceHandle) { diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 93c71a9516a..026b297f171 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -194,6 +194,7 @@ typedef struct _USBPORT_DEVICE_HANDLE { LIST_ENTRY DeviceHandleLink; LONG DeviceHandleLock; ULONG TtCount; + LIST_ENTRY TtList; } USBPORT_DEVICE_HANDLE, *PUSBPORT_DEVICE_HANDLE; typedef struct _USBPORT_ENDPOINT { @@ -379,10 +380,11 @@ typedef struct _USBPORT_DEVICE_EXTENSION { KDPC HcWakeDpc; /* Usb 2.0 HC Extension */ PUSB2_HC_EXTENSION Usb2Extension; + ULONG Bandwidth[32]; /* Miniport extension should be aligned on 0x100 */ #if !defined(_M_X64) - ULONG Padded[33]; + ULONG Padded[1]; #else ULONG Padded[0]; #endif @@ -1294,6 +1296,12 @@ USBPORT_FreeBandwidthUSB2( IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint); +VOID +NTAPI +USB2_InitTT( + IN PUSB2_HC_EXTENSION HcExtension, + IN PUSB2_TT Tt); + VOID NTAPI USB2_InitController( From e48d6136ec9984305a444f62968431fa5b2afe1d Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 18:30:58 +0900 Subject: [PATCH 11/76] [USBPORT] Add USBPORT_UpdateAllocatedBwTt(). --- drivers/usb/usbport/usb2.c | 34 ++++++++++++++++++++++++++++++++++ drivers/usb/usbport/usbport.h | 5 +++++ 2 files changed, 39 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 1c4cd042de3..2e511b5d9ac 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -31,6 +31,40 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, TtEndpoint->Tt = Tt; } +VOID +NTAPI +USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension) +{ + ULONG BusBandwidth; + ULONG NewBusBandwidth; + ULONG MaxBusBandwidth = 0; + ULONG MinBusBandwidth; + ULONG ix; + + DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension); + + BusBandwidth = TtExtension->BusBandwidth; + MinBusBandwidth = BusBandwidth; + + for (ix = 0; ix < USB2_FRAMES; ix++) + { + NewBusBandwidth = BusBandwidth - TtExtension->Bandwidth[ix]; + + if (NewBusBandwidth > MaxBusBandwidth) + MaxBusBandwidth = NewBusBandwidth; + + if (NewBusBandwidth < MinBusBandwidth) + MinBusBandwidth = NewBusBandwidth; + } + + TtExtension->MaxBandwidth = MaxBusBandwidth; + + if (MinBusBandwidth == BusBandwidth) + TtExtension->MinBandwidth = 0; + else + TtExtension->MinBandwidth = MinBusBandwidth; +} + BOOLEAN NTAPI USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 026b297f171..85636b24bff 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -1296,6 +1296,11 @@ USBPORT_FreeBandwidthUSB2( IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint); +VOID +NTAPI +USBPORT_UpdateAllocatedBwTt( + IN PUSB2_TT_EXTENSION TtExtension); + VOID NTAPI USB2_InitTT( From 3fcbd7744c8e595fb7aecbb066f5e0197ba280e9 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 18:53:46 +0900 Subject: [PATCH 12/76] [USBPORT] Add support for transaction translators in USBPORT_OpenPipe(). --- drivers/usb/usbport/endpoint.c | 38 ++++++++++++++++++++++++++++++++++ drivers/usb/usbport/usbport.h | 11 ++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index be2c7eab6d8..2479cf9dea0 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -672,6 +672,26 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, Endpoint->DeviceHandle = DeviceHandle; Endpoint->LockCounter = -1; + Endpoint->TtExtension = DeviceHandle->TtExtension; + + if (DeviceHandle->TtExtension) + { + ExInterlockedInsertTailList(&DeviceHandle->TtExtension->TtList, + &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); @@ -695,6 +715,17 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, 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: @@ -960,6 +991,13 @@ ExitWithError: } } + if (Endpoint->TtExtension) + { + KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql); + RemoveEntryList(&Endpoint->TtLink); + KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql); + } + ExFreePoolWithTag(Endpoint, USB_PORT_TAG); } diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 85636b24bff..2f37634468e 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -154,7 +154,9 @@ typedef struct _USBPORT_COMMON_BUFFER_HEADER { typedef struct _USBPORT_ENDPOINT *PUSBPORT_ENDPOINT; typedef struct _USB2_HC_EXTENSION *PUSB2_HC_EXTENSION; +typedef struct _USB2_TT_EXTENSION *PUSB2_TT_EXTENSION; typedef struct _USB2_TT *PUSB2_TT; +typedef struct _USB2_TT_ENDPOINT *PUSB2_TT_ENDPOINT; typedef struct _USBPORT_PIPE_HANDLE { ULONG Flags; @@ -194,6 +196,7 @@ typedef struct _USBPORT_DEVICE_HANDLE { LIST_ENTRY DeviceHandleLink; LONG DeviceHandleLock; ULONG TtCount; + PUSB2_TT_EXTENSION TtExtension; // Transaction Translator LIST_ENTRY TtList; } USBPORT_DEVICE_HANDLE, *PUSBPORT_DEVICE_HANDLE; @@ -202,6 +205,8 @@ typedef struct _USBPORT_ENDPOINT { PDEVICE_OBJECT FdoDevice; PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer; PUSBPORT_DEVICE_HANDLE DeviceHandle; + PUSB2_TT_EXTENSION TtExtension; // Transaction Translator + PUSB2_TT_ENDPOINT TtEndpoint; USBPORT_ENDPOINT_PROPERTIES EndpointProperties; ULONG EndpointWorker; ULONG FrameNumber; @@ -230,6 +235,7 @@ typedef struct _USBPORT_ENDPOINT { LIST_ENTRY FlushLink; LIST_ENTRY FlushControllerLink; LIST_ENTRY FlushAbortLink; + LIST_ENTRY TtLink; } USBPORT_ENDPOINT, *PUSBPORT_ENDPOINT; typedef struct _USBPORT_ISO_BLOCK *PUSBPORT_ISO_BLOCK; @@ -381,10 +387,11 @@ typedef struct _USBPORT_DEVICE_EXTENSION { /* Usb 2.0 HC Extension */ PUSB2_HC_EXTENSION Usb2Extension; ULONG Bandwidth[32]; + KSPIN_LOCK TtSpinLock; /* Miniport extension should be aligned on 0x100 */ #if !defined(_M_X64) - ULONG Padded[1]; + ULONG Padded[64]; #else ULONG Padded[0]; #endif @@ -392,7 +399,7 @@ typedef struct _USBPORT_DEVICE_EXTENSION { } USBPORT_DEVICE_EXTENSION, *PUSBPORT_DEVICE_EXTENSION; #if !defined(_M_X64) -C_ASSERT(sizeof(USBPORT_DEVICE_EXTENSION) == 0x400); +C_ASSERT(sizeof(USBPORT_DEVICE_EXTENSION) == 0x500); #else C_ASSERT(sizeof(USBPORT_DEVICE_EXTENSION) == 0x600); #endif From c92f591144df00d7bd9669c817930c2f95d8784a Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 19:29:38 +0900 Subject: [PATCH 13/76] [USBPORT] Add support for transaction translators in USBPORT_CreateDevice(). --- drivers/usb/usbport/device.c | 55 ++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index 268571fd7fd..aa70c184cd2 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -893,6 +893,9 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, IN USHORT PortStatus, IN USHORT Port) { + PUSBPORT_DEVICE_HANDLE TtDeviceHandle = NULL; + PUSB2_TT_EXTENSION TtExtension = NULL; + USHORT port; PUSBPORT_DEVICE_HANDLE DeviceHandle; PUSBPORT_PIPE_HANDLE PipeHandle; BOOL IsOpenedPipe; @@ -902,7 +905,7 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, SIZE_T DescriptorMinSize; UCHAR MaxPacketSize; PUSBPORT_DEVICE_EXTENSION FdoExtension; - + PUSBPORT_REGISTRATION_PACKET Packet; NTSTATUS Status; DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n", @@ -910,6 +913,7 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, Port); FdoExtension = FdoDevice->DeviceExtension; + Packet = &FdoExtension->MiniPortInterface->Packet; KeWaitForSingleObject(&FdoExtension->DeviceSemaphore, Executive, @@ -928,11 +932,21 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, return STATUS_DEVICE_NOT_CONNECTED; } - if (FdoExtension->MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2 && + port = Port; + + if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2 && !(PortStatus & USB_PORT_STATUS_HIGH_SPEED)) { - DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port. FIXME: Transaction Translator.\n"); - DbgBreakPoint(); + DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port\n"); + + TtExtension = USBPORT_GetTt(FdoDevice, + HubDeviceHandle, + &port, + &TtDeviceHandle); + + DPRINT("USBPORT_CreateDevice: TtDeviceHandle - %p, port - %x\n", + TtDeviceHandle, + port); } KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, @@ -954,6 +968,7 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, *pUsbdDeviceHandle = NULL; + DeviceHandle->TtExtension = TtExtension; DeviceHandle->PortNumber = Port; DeviceHandle->HubDeviceHandle = HubDeviceHandle; @@ -993,6 +1008,7 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, } InitializeListHead(&DeviceHandle->PipeHandleList); + InitializeListHead(&DeviceHandle->TtList); Status = USBPORT_OpenPipe(FdoDevice, DeviceHandle, @@ -1089,7 +1105,36 @@ USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, ErrorExit: - // FIXME: if Transaction Translator + if (TtExtension && TtDeviceHandle) + { + SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_OTHER; + SetupPacket.bmRequestType.Reserved = 0; + SetupPacket.bmRequestType.Type = BMREQUEST_CLASS; + SetupPacket.bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE; + + /* Table 11-15. Hub Class Requests */ + if (TtDeviceHandle == HubDeviceHandle) + { + SetupPacket.bRequest = USB_REQUEST_RESET_TT; + } + else + { + SetupPacket.bRequest = USB_REQUEST_CLEAR_TT_BUFFER; + } + + SetupPacket.wValue.LowByte = 0; + SetupPacket.wValue.HiByte = 0; + SetupPacket.wIndex.W = port; + SetupPacket.wLength = 0; + + USBPORT_SendSetupPacket(TtDeviceHandle, + FdoDevice, + &SetupPacket, + NULL, + 0, + NULL, + NULL); + } Status = STATUS_DEVICE_DATA_ERROR; From 0f8425ed442c604c9f72038e4b10dc9b5c02a397 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 20:35:03 +0900 Subject: [PATCH 14/76] [USBPORT] Add USBPORT_GetTt(). --- drivers/usb/usbport/device.c | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index aa70c184cd2..fdeac978462 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -885,6 +885,76 @@ USBPORT_AbortTransfers(IN PDEVICE_OBJECT FdoDevice, } } +PUSB2_TT_EXTENSION +NTAPI +USBPORT_GetTt(IN PDEVICE_OBJECT FdoDevice, + IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle, + OUT PUSHORT OutPort, + OUT PUSBPORT_DEVICE_HANDLE * OutHubDeviceHandle) +{ + PUSBPORT_DEVICE_HANDLE DeviceHandle = HubDeviceHandle; + ULONG TtCount; + PLIST_ENTRY Entry; + PUSB2_TT_EXTENSION TtExtension = NULL; + + DPRINT("USBPORT_GetTt: HubDeviceHandle - %p\n", HubDeviceHandle); + + *OutHubDeviceHandle = NULL; + + while (DeviceHandle->DeviceSpeed != UsbHighSpeed) + { + DPRINT("USBPORT_GetTt: DeviceHandle - %p, DeviceHandle->PortNumber - %X\n", + DeviceHandle, + DeviceHandle->PortNumber); + + *OutPort = DeviceHandle->PortNumber; + + DeviceHandle = DeviceHandle->HubDeviceHandle; + + if (!DeviceHandle) + return NULL; + } + + TtCount = DeviceHandle->TtCount; + + if (!TtCount) + return NULL; + + if (IsListEmpty(&DeviceHandle->TtList)) + return NULL; + + Entry = DeviceHandle->TtList.Flink; + + if (TtCount > 1) + { + while (Entry != &DeviceHandle->TtList) + { + ASSERT(Entry != NULL); + + TtExtension = CONTAINING_RECORD(Entry, + USB2_TT_EXTENSION, + Link); + + if (TtExtension->TtNumber == *OutPort) + break; + + Entry = Entry->Flink; + + TtExtension = NULL; + } + } + else + { + TtExtension = CONTAINING_RECORD(Entry, + USB2_TT_EXTENSION, + Link); + } + + *OutHubDeviceHandle = DeviceHandle; + + return TtExtension; +} + NTSTATUS NTAPI USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE *pUsbdDeviceHandle, From 7c398f6eb7251c8bb88e50f06aced4b26bc9fdf4 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 27 Nov 2017 20:44:13 +0900 Subject: [PATCH 15/76] [USBPORT] Initialize FdoExtension->Bandwidth[] in USBPORT_StartDevice(). --- drivers/usb/usbport/pnp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/usbport/pnp.c b/drivers/usb/usbport/pnp.c index e7ec3117fc6..7b0c5dd20e8 100644 --- a/drivers/usb/usbport/pnp.c +++ b/drivers/usb/usbport/pnp.c @@ -519,6 +519,7 @@ USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice, BOOLEAN IsCompanion = FALSE; ULONG LegacyBIOS; ULONG MiniportFlags; + ULONG ix; DPRINT("USBPORT_StartDevice: FdoDevice - %p, UsbPortResources - %p\n", FdoDevice, @@ -610,6 +611,7 @@ USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice, KeInitializeSpinLock(&FdoExtension->PowerWakeSpinLock); KeInitializeSpinLock(&FdoExtension->SetPowerD0SpinLock); KeInitializeSpinLock(&FdoExtension->RootHubCallbackSpinLock); + KeInitializeSpinLock(&FdoExtension->TtSpinLock); KeInitializeDpc(&FdoExtension->IsrDpc, USBPORT_IsrDpc, FdoDevice); @@ -754,6 +756,12 @@ USBPORT_StartDevice(IN PDEVICE_OBJECT FdoDevice, FdoExtension->TotalBusBandwidth = TotalBusBandwidth; } + for (ix = 0; ix < USB2_FRAMES; ix++) + { + FdoExtension->Bandwidth[ix] = FdoExtension->TotalBusBandwidth - + FdoExtension->TotalBusBandwidth / 10; + } + FdoExtension->ActiveIrpTable = ExAllocatePoolWithTag(NonPagedPool, sizeof(USBPORT_IRP_TABLE), USB_PORT_TAG); From c6ca2a8f027e22091fd08b1825a9298ec63ee5d8 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 28 Nov 2017 14:41:05 +0900 Subject: [PATCH 16/76] [USBPORT] Add support for transaction translators in USBPORT_OpenPipe() and USBPORT_ClosePipe(). --- drivers/usb/usbport/device.c | 2 +- drivers/usb/usbport/endpoint.c | 44 ++++++++++++++++++++++++++++------ drivers/usb/usbport/usbport.h | 4 +++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index fdeac978462..f1cb04eb47f 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -1914,7 +1914,7 @@ USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice, TtExtension->RootHubPdo = FdoExtension->RootHubPdo; TtExtension->BusBandwidth = TOTAL_USB11_BUS_BANDWIDTH; - InitializeListHead(&TtExtension->TtList); + InitializeListHead(&TtExtension->EndpointList); /* 90% maximum allowed for periodic endpoints */ for (ix = 0; ix < USB2_FRAMES; ix++) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 2479cf9dea0..49124ae763b 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -471,6 +471,9 @@ 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; @@ -492,7 +495,6 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, } Endpoint = PipeHandle->Endpoint; - DPRINT("USBPORT_ClosePipe: Endpoint - %p\n", Endpoint); KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql); @@ -543,16 +545,44 @@ 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; + + 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; + } + + ExFreePool(TtExtension); + } + } + } + + KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql); } else { - DPRINT("USBPORT_ClosePipe: FIXME USBPORT_FreeBandwidthUSB11\n"); - //USBPORT_FreeBandwidthUSB11(); + USBPORT_FreeBandwidth(FdoDevice, Endpoint); } KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql); @@ -676,7 +706,7 @@ USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice, if (DeviceHandle->TtExtension) { - ExInterlockedInsertTailList(&DeviceHandle->TtExtension->TtList, + ExInterlockedInsertTailList(&DeviceHandle->TtExtension->EndpointList, &Endpoint->TtLink, &FdoExtension->TtSpinLock); } diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 2f37634468e..3bba591f069 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -528,6 +528,8 @@ typedef struct _USB2_TT { ULONG TimeCS[USB2_FRAMES][USB2_MICROFRAMES]; } USB2_TT, *PUSB2_TT; +#define USB2_TT_EXTENSION_FLAG_DELETED 1 + typedef struct _USB2_TT_EXTENSION { PDEVICE_OBJECT RootHubPdo; ULONG Flags; @@ -537,7 +539,7 @@ typedef struct _USB2_TT_EXTENSION { ULONG MinBandwidth; USHORT DeviceAddress; USHORT TtNumber; - LIST_ENTRY TtList; + LIST_ENTRY EndpointList; LIST_ENTRY Link; USB2_TT Tt; } USB2_TT_EXTENSION, *PUSB2_TT_EXTENSION; From aae6dd6073971af6411f1fc5ee9cb0ae70c30503 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 28 Nov 2017 15:02:47 +0900 Subject: [PATCH 17/76] [USBPORT] Implement USBPORT_AllocateBandwidth(). --- drivers/usb/usbport/endpoint.c | 87 ++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 49124ae763b..1e037f9ff43 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -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; @@ -87,16 +97,75 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, TotalBusBandwidth = FdoExtension->TotalBusBandwidth; EndpointBandwidth = EndpointProperties->UsbBandwidth; Period = EndpointProperties->Period; + Factor = USB2_FRAMES / Period; + ASSERT(Factor); - 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]; - return TRUE; + for (ix = 0; *Bandwidth >= EndpointBandwidth; ix++) + { + if (MinBandwidth > *Bandwidth) + { + MinBandwidth = *Bandwidth; + } + + Bandwidth++; + + if (Factor <= (ix + 1)) + { + 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; + } + + if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT) + { + for (Bit = 0x80; Bit != 0; Bit >>= 1) + { + if ((Period & Bit) != 0) + { + Period = Bit; + break; + } + } + + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedInterrupt_XXms\n"); + } + else + { + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n"); + } + } + + DPRINT("USBPORT_AllocateBandwidth: FIXME USBPORT_UpdateAllocatedBw\n"); + + DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset); + return ScheduleOffset != -1; } VOID From 664e48cad50ae7a707f2dcaf7562fa460380b201 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 28 Nov 2017 15:13:22 +0900 Subject: [PATCH 18/76] [USBPORT] Implement USBPORT_FreeBandwidth(). --- drivers/usb/usbport/endpoint.c | 58 +++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 1e037f9ff43..23bccb14c32 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -173,7 +173,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(USB2_FRAMES / Period); + + 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 AllocedInterrupt_XXms\n"); + } + else + { + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n"); + } + + DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n"); } UCHAR From cbba6e80fce48aaf1163603738d1b09a8eef88f5 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 28 Nov 2017 15:19:46 +0900 Subject: [PATCH 19/76] [USBPORT] Correcting USBPORT_InitializeDevice() and USBPORT_RestoreDevice() (DEVICE_HANDLE_FLAG_USB2HUB). --- drivers/usb/usbport/device.c | 12 +++++++++++- drivers/usb/usbport/usbport.h | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index f1cb04eb47f..7ba54f594e4 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -1377,6 +1377,12 @@ USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, (MaxPacketSize == 16) || (MaxPacketSize == 32) || (MaxPacketSize == 64)); + + if (DeviceHandle->DeviceSpeed == UsbHighSpeed && + DeviceHandle->DeviceDescriptor.bDeviceClass == USB_DEVICE_CLASS_HUB) + { + DeviceHandle->Flags |= DEVICE_HANDLE_FLAG_USB2HUB; + } } else { @@ -1761,10 +1767,14 @@ USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice, } } - if (NewDeviceHandle->Flags & DEVICE_HANDLE_FLAG_INITIALIZED) + if (NewDeviceHandle->Flags & DEVICE_HANDLE_FLAG_USB2HUB) { DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n"); NewDeviceHandle->TtCount = OldDeviceHandle->TtCount; + +#ifndef NDEBUG + DbgBreakPoint(); +#endif } while (!IsListEmpty(&OldDeviceHandle->PipeHandleList)) diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 3bba591f069..940c944c485 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -104,7 +104,7 @@ /* Device handle Flags (USBPORT_DEVICE_HANDLE) */ #define DEVICE_HANDLE_FLAG_ROOTHUB 0x00000002 #define DEVICE_HANDLE_FLAG_REMOVED 0x00000008 -#define DEVICE_HANDLE_FLAG_INITIALIZED 0x00000010 +#define DEVICE_HANDLE_FLAG_USB2HUB 0x00000010 /* Endpoint Flags (USBPORT_ENDPOINT) */ #define ENDPOINT_FLAG_DMA_TYPE 0x00000001 From 5e15ba48b9ea8460a0929e4c2092c3137b1d811d Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 03:30:46 +0900 Subject: [PATCH 20/76] [USBPORT] Add support for transaction translators in USBPORT_RemoveDevice(). --- drivers/usb/usbport/device.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index 7ba54f594e4..ec6dbc33b35 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -1564,6 +1564,9 @@ USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, IN ULONG Flags) { PUSBPORT_DEVICE_EXTENSION FdoExtension; + PUSB2_TT_EXTENSION TtExtension; + ULONG ix; + KIRQL OldIrql; DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n", DeviceHandle, @@ -1623,6 +1626,37 @@ USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, USBPORT_FreeUsbAddress(FdoDevice, DeviceHandle->DeviceAddress); } + DPRINT("USBPORT_RemoveDevice: DeviceHandle->TtList.Flink - %p\n", DeviceHandle->TtList.Flink); + + while (!IsListEmpty(&DeviceHandle->TtList)) + { + TtExtension = CONTAINING_RECORD(DeviceHandle->TtList.Flink, + USB2_TT_EXTENSION, + Link); + + RemoveHeadList(&DeviceHandle->TtList); + + DPRINT("USBPORT_RemoveDevice: TtExtension - %p\n", TtExtension); + + KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql); + + 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; + } + + ExFreePool(TtExtension); + } + + KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql); + } + KeReleaseSemaphore(&FdoExtension->DeviceSemaphore, LOW_REALTIME_PRIORITY, 1, From 02d1cfd37f15c3fbec8a54eb11a56b25a544da2b Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 03:51:25 +0900 Subject: [PATCH 21/76] [USBPORT] Change debug message in USBPORT_RemoveDevice((). --- drivers/usb/usbport/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index ec6dbc33b35..7ea2fda5ca5 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -1626,7 +1626,10 @@ USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, USBPORT_FreeUsbAddress(FdoDevice, DeviceHandle->DeviceAddress); } - DPRINT("USBPORT_RemoveDevice: DeviceHandle->TtList.Flink - %p\n", DeviceHandle->TtList.Flink); + if (!IsListEmpty(&DeviceHandle->TtList)) + { + DPRINT1("USBPORT_RemoveDevice: DeviceHandle->TtList not empty\n"); + } while (!IsListEmpty(&DeviceHandle->TtList)) { From c2ae849dab4689fcff2db3ea98d5ddc5ac954cef Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 06:54:22 +0900 Subject: [PATCH 22/76] [USBPORT] Start implementation USBPORT_AllocateBandwidthUSB2(). --- drivers/usb/usbport/endpoint.c | 4 +- drivers/usb/usbport/usb2.c | 210 ++++++++++++++++++++++++++++++++- drivers/usb/usbport/usbport.h | 5 + 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 23bccb14c32..8633d9be8f2 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -105,7 +105,7 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, MinBandwidth = TotalBusBandwidth; Bandwidth = &FdoExtension->Bandwidth[Offset * Factor]; - for (ix = 0; *Bandwidth >= EndpointBandwidth; ix++) + for (ix = 1; *Bandwidth >= EndpointBandwidth; ix++) { if (MinBandwidth > *Bandwidth) { @@ -114,7 +114,7 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, Bandwidth++; - if (Factor <= (ix + 1)) + if (Factor <= ix) { if (MinBandwidth > MaxBandwidth) { diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 2e511b5d9ac..11429ec108c 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -31,6 +31,28 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, TtEndpoint->Tt = Tt; } +BOOLEAN +NTAPI +USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN PUSB2_REBALANCE Rebalance, + IN PULONG RebalanceListEntries) +{ + DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n"); + ASSERT(FALSE); + return FALSE; +} + +BOOLEAN +NTAPI +USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN PUSB2_REBALANCE Rebalance, + IN PULONG RebalanceListEntries) +{ + DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n"); + ASSERT(FALSE); + return FALSE; +} + VOID NTAPI USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension) @@ -70,8 +92,192 @@ NTAPI USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, IN PUSBPORT_ENDPOINT Endpoint) { - DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n"); - return TRUE; + PUSBPORT_DEVICE_EXTENSION FdoExtension; + PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties; + PUSB2_TT_EXTENSION TtExtension; + ULONG TransferType; + PUSB2_REBALANCE Rebalance; + LIST_ENTRY RebalanceList; + ULONG RebalanceListEntries; + PUSB2_TT_ENDPOINT TtEndpoint; + PUSB2_TT_ENDPOINT RebalanceTtEndpoint; + + PUSB2_TT Tt; + USB_DEVICE_SPEED DeviceSpeed; + ULONG Period; + + ULONG ix; + BOOLEAN Direction; + BOOLEAN Result; + + DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n", + FdoDevice, + Endpoint); + + EndpointProperties = &Endpoint->EndpointProperties; + EndpointProperties->ScheduleOffset = 0; + + if (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0) + { + DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n"); + return TRUE; + } + + FdoExtension = FdoDevice->DeviceExtension; + + TransferType = EndpointProperties->TransferType; + DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType); + + if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL || + TransferType == USBPORT_TRANSFER_TYPE_BULK) + { + return TRUE; + } + + if (Endpoint->TtExtension) + TtExtension = Endpoint->TtExtension; + else + TtExtension = NULL; + + InitializeListHead(&RebalanceList); + + Rebalance = ExAllocatePoolWithTag(NonPagedPool, + sizeof(USB2_REBALANCE), + USB_PORT_TAG); + + DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n", + Rebalance, + TtExtension); + + if (Rebalance) + { + RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE)); + + TtEndpoint = Endpoint->TtEndpoint; + TtEndpoint->Endpoint = Endpoint; + + Direction = EndpointProperties->Direction == USBPORT_TRANSFER_DIRECTION_OUT; + DeviceSpeed = EndpointProperties->DeviceSpeed; + + switch (DeviceSpeed) + { + case UsbLowSpeed: + case UsbFullSpeed: + { + Tt = &TtExtension->Tt; + Period = USB2_FRAMES; + + while (Period && Period > EndpointProperties->Period); + { + Period >>= 1; + } + + DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period); + break; + } + + case UsbHighSpeed: + { + Tt = &FdoExtension->Usb2Extension->HcTt; + Period = EndpointProperties->Period; + + if (EndpointProperties->Period > USB2_MAX_MICROFRAMES) + Period = USB2_MAX_MICROFRAMES; + + break; + } + + default: + { + DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed); + DbgBreakPoint(); + Tt = &TtExtension->Tt; + break; + } + } + + USB2_InitTtEndpoint(TtEndpoint, + TransferType, + Direction, + DeviceSpeed, + Period, + EndpointProperties->MaxPacketSize, + Tt); + + RebalanceListEntries = USB2_FRAMES - 2; + + Result = USB2_AllocateTimeForEndpoint(TtEndpoint, + Rebalance, + &RebalanceListEntries); + + if (Result) + { + Result = USB2_PromotePeriods(TtEndpoint, + Rebalance, + &RebalanceListEntries); + } + + RebalanceListEntries = 0; + + for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++) + { + RebalanceListEntries = ix + 1; + } + } + else + { + RebalanceListEntries = 0; + Result = FALSE; + } + + DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n", + RebalanceListEntries, + Result); + + for (ix = 0; ix < RebalanceListEntries; ix++) + { + DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n", + ix, + Rebalance->RebalanceEndpoint[ix]); + + RebalanceTtEndpoint = Rebalance->RebalanceEndpoint[ix]; + + InsertTailList(&RebalanceList, + &RebalanceTtEndpoint->Endpoint->RebalanceLink); + } + + if (Rebalance) + ExFreePool(Rebalance); + + if (Result) + { + DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n"); + ASSERT(FALSE); + } + + //USB2_Rebalance(FdoDevice, &RebalanceList); + + if (!TtExtension) + { + DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result); + return Result; + } + + 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; + } + + DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result); + + return Result; } VOID diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 940c944c485..bb686802160 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -236,6 +236,7 @@ typedef struct _USBPORT_ENDPOINT { LIST_ENTRY FlushControllerLink; LIST_ENTRY FlushAbortLink; LIST_ENTRY TtLink; + LIST_ENTRY RebalanceLink; } USBPORT_ENDPOINT, *PUSBPORT_ENDPOINT; typedef struct _USBPORT_ISO_BLOCK *PUSBPORT_ISO_BLOCK; @@ -551,6 +552,10 @@ typedef struct _USB2_HC_EXTENSION { USB2_TT HcTt; } USB2_HC_EXTENSION, *PUSB2_HC_EXTENSION; +typedef struct _USB2_REBALANCE { + PUSB2_TT_ENDPOINT RebalanceEndpoint[USB2_FRAMES - 2]; +} USB2_REBALANCE, *PUSB2_REBALANCE; + /* usbport.c */ NTSTATUS NTAPI From 754f749cfd5ec4b40659293eb3d5d7ac96dbbdea Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 21:50:43 +0900 Subject: [PATCH 23/76] [USBPORT] Add USB2_GetOverhead(). --- drivers/usb/usbport/usb2.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 11429ec108c..3755fb4e805 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -10,6 +10,54 @@ //#define NDEBUG #include +ULONG +NTAPI +USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) +{ + ULONG TransferType; + ULONG Direction; + ULONG DeviceSpeed; + ULONG Overhead; + ULONG HostDelay; + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + Direction = TtEndpoint->TtEndpointParams.Direction; + DeviceSpeed = TtEndpoint->TtEndpointParams.Direction; + + HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime; + + if (DeviceSpeed == UsbHighSpeed) + { + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) + { + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + Overhead = HostDelay + USB2_HS_ISOCHRONOUS_OUT_OVERHEAD; + else + Overhead = HostDelay + USB2_HS_INTERRUPT_OUT_OVERHEAD; + } + else + { + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + Overhead = HostDelay + USB2_HS_ISOCHRONOUS_IN_OVERHEAD; + else + Overhead = HostDelay + USB2_HS_ISOCHRONOUS_OUT_OVERHEAD; + } + } + else if (DeviceSpeed == UsbFullSpeed) + { + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + Overhead = HostDelay + USB2_FS_ISOCHRONOUS_OVERHEAD; + else + Overhead = HostDelay + USB2_FS_INTERRUPT_OVERHEAD; + } + else + { + Overhead = HostDelay + USB2_LS_INTERRUPT_OVERHEAD; + } + + return Overhead; +} + VOID NTAPI USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, From c034297f2d4e0bd0f378899e163ee1debbdef544 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 22:21:58 +0900 Subject: [PATCH 24/76] [USBPORT] Add USB2_AddDataBitStuff(). --- drivers/usb/usbport/usb2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 3755fb4e805..ace40d1e1c2 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -10,6 +10,13 @@ //#define NDEBUG #include +USHORT +NTAPI +USB2_AddDataBitStuff(IN USHORT DataTime) +{ + return (DataTime + (DataTime / 16)); +} + ULONG NTAPI USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) From e701da4923f0ba5061d67649219771d8510d91d0 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 22:33:35 +0900 Subject: [PATCH 25/76] [USBPORT] Add USB2_AllocateCheck(). --- drivers/usb/usbport/usb2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index ace40d1e1c2..080d48cf219 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -10,6 +10,27 @@ //#define NDEBUG #include +BOOLEAN +NTAPI +USB2_AllocateCheck(IN OUT PULONG OutTimeUsed, + IN ULONG CalcBusTime, + IN ULONG LimitAllocation) +{ + ULONG BusTime; + BOOLEAN Result = TRUE; + + BusTime = *OutTimeUsed + CalcBusTime; + *OutTimeUsed += CalcBusTime; + + if (BusTime > LimitAllocation) + { + DPRINT("USB2_AllocateCheck: BusTime > LimitAllocation\n"); + Result = FALSE; + } + + return Result; +} + USHORT NTAPI USB2_AddDataBitStuff(IN USHORT DataTime) From c3803bed8a31f9ac138b1625d5c86187676d7bca Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 23:25:12 +0900 Subject: [PATCH 26/76] [USBPORT] Add USB2_CheckTtEndpointInsert(). --- drivers/usb/usbport/usb2.c | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 080d48cf219..ad8375db208 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -38,6 +38,52 @@ USB2_AddDataBitStuff(IN USHORT DataTime) return (DataTime + (DataTime / 16)); } +BOOLEAN +NTAPI +USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint, + IN PUSB2_TT_ENDPOINT TtEndpoint) +{ + ULONG TransferType; + + DPRINT("USB2_CheckTtEndpointInsert: nextTtEndpoint - %p, TtEndpoint - %p\n", + nextTtEndpoint, + TtEndpoint); + + ASSERT(TtEndpoint); + + if (TtEndpoint->CalcBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2)) + { + DPRINT1("USB2_CheckTtEndpointInsert: Result - FALSE\n"); + return FALSE; + } + + if (!nextTtEndpoint) + { + DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n"); + return TRUE; + } + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + + if (nextTtEndpoint->ActualPeriod < TtEndpoint->ActualPeriod && + TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT) + { + DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n"); + return TRUE; + } + + if ((nextTtEndpoint->ActualPeriod <= TtEndpoint->ActualPeriod && + TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) || + nextTtEndpoint == TtEndpoint) + { + DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n"); + return TRUE; + } + + DPRINT("USB2_CheckTtEndpointInsert: Result - FALSE\n"); + return FALSE; +} + ULONG NTAPI USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) From 0216b033ccdd886d10395279766a87907e830881 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 29 Nov 2017 23:50:26 +0900 Subject: [PATCH 27/76] [USBPORT] Add USB2_GetLastIsoTime(). --- drivers/usb/usbport/usb2.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index ad8375db208..94c2844bd73 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -132,6 +132,33 @@ USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) return Overhead; } +ULONG +NTAPI +USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN ULONG Frame) +{ + PUSB2_TT_ENDPOINT nextTtEndpoint; + ULONG Result; + + DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n", + TtEndpoint, + Frame); + + nextTtEndpoint = TtEndpoint->Tt->FrameBudget[Frame].IsoEndpoint->NextTtEndpoint; + + if (nextTtEndpoint || + (nextTtEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint) != NULL) + { + Result = nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime; + } + else + { + Result = USB2_FS_SOF_TIME; + } + + return Result; +} + VOID NTAPI USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, From 22b8777f8498a0bfa657af86ef3c08bbc4a414d9 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 30 Nov 2017 00:11:48 +0900 Subject: [PATCH 28/76] [USBPORT] Add USB2_GetStartTime(). --- drivers/usb/usbport/usb2.c | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 94c2844bd73..b70ac11851b 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -159,6 +159,49 @@ USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint, return Result; } +ULONG +NTAPI +USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint, + IN PUSB2_TT_ENDPOINT TtEndpoint, + IN PUSB2_TT_ENDPOINT prevTtEndpoint, + IN ULONG Frame) +{ + PUSB2_TT_ENDPOINT ttEndpoint; + ULONG TransferType; + + DPRINT("USB2_GetStartTime: nextTtEndpoint - %p, TtEndpoint - %p, prevTtEndpoint - %p, Frame - %X\n", + nextTtEndpoint, + TtEndpoint, + prevTtEndpoint, + Frame); + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + + if (nextTtEndpoint && TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + return nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime; + } + + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + ttEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint; + + if (ttEndpoint) + return ttEndpoint->StartTime + ttEndpoint->CalcBusTime; + else + return USB2_FS_SOF_TIME; + } + else + { + ttEndpoint = prevTtEndpoint; + + if (ttEndpoint == TtEndpoint->Tt->FrameBudget[Frame].IntEndpoint) + return USB2_GetLastIsoTime(TtEndpoint, Frame); + else + return ttEndpoint->StartTime + ttEndpoint->CalcBusTime; + } +} + VOID NTAPI USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, From 71a7208f693ff9af09cc3852ac4baed5a903e055 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 1 Dec 2017 10:13:10 +0900 Subject: [PATCH 29/76] [USBPORT] Add USB2_IncMicroFrame(). --- drivers/usb/usbport/usb2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index b70ac11851b..d8d5da9af19 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -38,6 +38,20 @@ USB2_AddDataBitStuff(IN USHORT DataTime) return (DataTime + (DataTime / 16)); } +VOID +NTAPI +USB2_IncMicroFrame(OUT PUCHAR frame, + OUT PUCHAR uframe) +{ + ++*uframe; + + if (*uframe > (USB2_MICROFRAMES - 1)) + { + *uframe = 0; + *frame = (*frame + 1) & (USB2_FRAMES - 1); + } +} + BOOLEAN NTAPI USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint, From e39b88e3e79f832ba4d52b3f4766772e148c8679 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 1 Dec 2017 10:16:24 +0900 Subject: [PATCH 30/76] [USBPORT] Add USB2_GetPrevMicroFrame(). --- drivers/usb/usbport/usb2.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index d8d5da9af19..a3c0d1449db 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -52,6 +52,19 @@ USB2_IncMicroFrame(OUT PUCHAR frame, } } +VOID +NTAPI +USB2_GetPrevMicroFrame(OUT PUCHAR frame, + OUT PUCHAR uframe) +{ + *uframe = USB2_MICROFRAMES - 1; + + if (*frame) + --*frame; + else + *frame = USB2_FRAMES - 1; +} + BOOLEAN NTAPI USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint, From 5654674e8c711e02a60922007ec3954c4eca94e4 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 1 Dec 2017 10:18:50 +0900 Subject: [PATCH 31/76] [USBPORT] Add stubs for USB2_AllocateHS() and USB2_DeallocateEndpointBudget(). --- drivers/usb/usbport/usb2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a3c0d1449db..5e0ace37c69 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -250,6 +250,27 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, TtEndpoint->Tt = Tt; } +BOOLEAN +NTAPI +USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN ULONG Frame) +{ + DPRINT("USB2_AllocateHS: UNIMPLEMENTED FIXME\n"); + return FALSE; +} + +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 NTAPI USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, From 816b3a572c67922a6fa6428dda2a487b578d2046 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sun, 3 Dec 2017 13:59:59 +0900 Subject: [PATCH 32/76] [USBPORT] Remove unnecessary semicolon. --- drivers/usb/usbport/usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 5e0ace37c69..a91650ebdd2 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -407,7 +407,7 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, Tt = &TtExtension->Tt; Period = USB2_FRAMES; - while (Period && Period > EndpointProperties->Period); + while (Period && Period > EndpointProperties->Period) { Period >>= 1; } From 2d4bd7b74449bb5af1f82551ec31985aae9825b2 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sun, 3 Dec 2017 14:06:06 +0900 Subject: [PATCH 33/76] [USBPORT] Reduces output of debug messages. --- drivers/usb/usbport/ioctl.c | 8 ++++---- drivers/usb/usbport/trfsplit.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/usbport/ioctl.c b/drivers/usb/usbport/ioctl.c index 7322958889f..6502c6549ab 100644 --- a/drivers/usb/usbport/ioctl.c +++ b/drivers/usb/usbport/ioctl.c @@ -326,10 +326,10 @@ USBPORT_PdoInternalDeviceControl(IN PDEVICE_OBJECT PdoDevice, IoStack = IoGetCurrentIrpStackLocation(Irp); IoCtl = IoStack->Parameters.DeviceIoControl.IoControlCode; - DPRINT("USBPORT_PdoInternalDeviceControl: PdoDevice - %p, Irp - %p, IoCtl - %x\n", - PdoDevice, - Irp, - IoCtl); + //DPRINT("USBPORT_PdoInternalDeviceControl: PdoDevice - %p, Irp - %p, IoCtl - %x\n", + // PdoDevice, + // Irp, + // IoCtl); if (IoCtl == IOCTL_INTERNAL_USB_SUBMIT_URB) { diff --git a/drivers/usb/usbport/trfsplit.c b/drivers/usb/usbport/trfsplit.c index 1964e8d2dd5..bc1efe34e2e 100644 --- a/drivers/usb/usbport/trfsplit.c +++ b/drivers/usb/usbport/trfsplit.c @@ -148,8 +148,8 @@ USBPORT_SplitBulkInterruptTransfer(IN PDEVICE_OBJECT FdoDevice, InitializeListHead(&tmplist); - DPRINT1("USBPORT_SplitBulkInterruptTransfer: TransferBufferLength - %x, NeedSplits - %x\n", - TransferBufferLength, NeedSplits); + DPRINT("USBPORT_SplitBulkInterruptTransfer: TransferBufferLength - %x, NeedSplits - %x\n", + TransferBufferLength, NeedSplits); if (!NeedSplits) { @@ -214,7 +214,7 @@ Exit: while (!IsListEmpty(&tmplist)) { - DPRINT1("USBPORT_SplitBulkInterruptTransfer: ... \n"); + DPRINT("USBPORT_SplitBulkInterruptTransfer: ... \n"); SplitTransfer = CONTAINING_RECORD(tmplist.Flink, USBPORT_TRANSFER, From 720d7cfd9b95b20f8cb1bb534a4c4160a4457266 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 5 Dec 2017 16:56:07 +0900 Subject: [PATCH 34/76] [USBPORT] Add USB2_GetHsOverhead(). --- drivers/usb/usbport/usb2.c | 47 +++++++++++++++++++++++++++++++++++ drivers/usb/usbport/usbport.h | 9 +++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a91650ebdd2..0ca831befe4 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -159,6 +159,53 @@ USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) return Overhead; } +VOID +NTAPI +USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN PULONG OverheadSS, + IN PULONG OverheadCS) +{ + ULONG TransferType; + ULONG Direction; + ULONG HostDelay; + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + Direction = TtEndpoint->TtEndpointParams.Direction; + + HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime; + + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) + { + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + *OverheadSS = HostDelay + USB2_HS_SS_ISOCHRONOUS_OUT_OVERHEAD; + *OverheadCS = 0; + } + else + { + *OverheadSS = HostDelay + USB2_HS_SS_INTERRUPT_OUT_OVERHEAD; + *OverheadCS = HostDelay + USB2_HS_CS_INTERRUPT_OUT_OVERHEAD; + } + } + else + { + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + *OverheadSS = HostDelay + USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD; + *OverheadCS = HostDelay + USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD; + } + else + { + *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); + } +} + ULONG NTAPI USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint, diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index bb686802160..88277167c47 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -469,6 +469,15 @@ typedef struct _TIMER_WORK_QUEUE_ITEM { #define USB2_HS_ISOCHRONOUS_OUT_OVERHEAD 38 #define USB2_HS_ISOCHRONOUS_IN_OVERHEAD 18 +#define USB2_HS_SS_INTERRUPT_OUT_OVERHEAD 58 +#define USB2_HS_CS_INTERRUPT_OUT_OVERHEAD 36 +#define USB2_HS_SS_INTERRUPT_IN_OVERHEAD 39 +#define USB2_HS_CS_INTERRUPT_IN_OVERHEAD 38 + +#define USB2_HS_SS_ISOCHRONOUS_OUT_OVERHEAD 58 +#define USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD 39 +#define USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD 38 + typedef union _USB2_TT_ENDPOINT_PARAMS { struct { ULONG TransferType : 4; From 698f092ab17c33051f162ff3f2ac4468efad99d9 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Tue, 5 Dec 2017 18:13:37 +0900 Subject: [PATCH 35/76] [USBPORT] Implement USB2_AllocateHS(). --- drivers/usb/usbport/usb2.c | 173 ++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 0ca831befe4..a4a87455370 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -300,10 +300,177 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, BOOLEAN NTAPI USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, - IN ULONG Frame) + IN LONG Frame) { - DPRINT("USB2_AllocateHS: UNIMPLEMENTED FIXME\n"); - return FALSE; + PUSB2_HC_EXTENSION HcExtension; + PUSB2_TT Tt; + ULONG TransferType; + ULONG Direction; + ULONG DataTime; + ULONG RemainDataTime; + ULONG OverheadCS; + ULONG OverheadSS; + ULONG ix; + USHORT PktSize; + UCHAR frame; + UCHAR uframe; + BOOL Result = TRUE; + + DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, TtEndpoint->StartFrame - %X\n", + TtEndpoint, + Frame, + TtEndpoint->StartFrame); + + Tt = TtEndpoint->Tt; + HcExtension = Tt->HcExtension; + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + Direction = TtEndpoint->TtEndpointParams.Direction; + + if (Frame == 0) + { + TtEndpoint->StartMicroframe = + TtEndpoint->StartTime / USB2_FS_RAW_BYTES_IN_MICROFRAME - 1; + + DPRINT("USB2_AllocateHS: TtEndpoint->StartMicroframe - %X\n", + TtEndpoint->StartMicroframe); + } + + USB2_GetHsOverhead(TtEndpoint, &OverheadSS, &OverheadCS); + + if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT) + { + if (Frame == 0) + { + TtEndpoint->Nums.NumStarts = 1; + + if ((CHAR)TtEndpoint->StartMicroframe < 5) + { + TtEndpoint->Nums.NumCompletes = 3; + } + else + { + TtEndpoint->Nums.NumCompletes = 2; + } + } + } + else + { + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) + { + DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n"); + ASSERT(FALSE); + } + else + { + DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n"); + ASSERT(FALSE); + } + } + + frame = TtEndpoint->StartFrame + Frame; + uframe = TtEndpoint->StartMicroframe; + + if (TtEndpoint->StartMicroframe == 0xFF) + USB2_GetPrevMicroFrame(&frame, &uframe); + + for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++) + { + if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], + OverheadSS, + USB2_MAX_MICROFRAME_ALLOCATION)) + { + Result = FALSE; + } + + if (Tt->NumStartSplits[frame][uframe] > (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME - 1)) + { + DPRINT1("USB2_AllocateHS: Num Start Splits - %X\n", + Tt->NumStartSplits[frame][uframe] + 1); + + ASSERT(FALSE); + Result = FALSE; + } + + ++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++) + { + if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], + OverheadCS, + USB2_MAX_MICROFRAME_ALLOCATION)) + { + Result = FALSE; + } + + USB2_IncMicroFrame(&frame, &uframe); + } + + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) + { + DPRINT("USB2_AllocateHS: DIRECTION OUT UNIMPLEMENTED\n"); + ASSERT(FALSE); + } + else + { + frame = TtEndpoint->StartFrame + Frame; + uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1; + + for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++) + { + if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME) + { + if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME) + { + RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME - + Tt->TimeCS[frame][uframe]; + } + else + { + RemainDataTime = 0; + } + + PktSize = TtEndpoint->MaxPacketSize; + + if (RemainDataTime >= USB2_AddDataBitStuff(PktSize)) + { + DataTime = USB2_AddDataBitStuff(PktSize); + } + else + { + DataTime = RemainDataTime; + } + + if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], + DataTime, + USB2_MAX_MICROFRAME_ALLOCATION)) + { + Result = FALSE; + } + } + + PktSize = TtEndpoint->MaxPacketSize; + + if (USB2_AddDataBitStuff(PktSize) < USB2_FS_RAW_BYTES_IN_MICROFRAME) + { + Tt->TimeCS[frame][uframe] += USB2_AddDataBitStuff(PktSize); + } + else + { + Tt->TimeCS[frame][uframe] += USB2_FS_RAW_BYTES_IN_MICROFRAME; + } + + USB2_IncMicroFrame(&frame, &uframe); + } + } + + DPRINT("USB2_AllocateHS: Result - %X\n", Result); + return Result; } BOOLEAN From 3bda39fcb84c7bd731b12937695a658849490559 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 8 Dec 2017 18:16:49 +0900 Subject: [PATCH 36/76] [USBPORT] Add USBPORT_DumpingEndpointProperties() and USBPORT_DumpingTtEndpoint(). --- drivers/usb/usbport/debug.c | 37 ++++++++++++++++++++++++++++++++++ drivers/usb/usbport/usbdebug.h | 19 +++++++++++++++++ drivers/usb/usbport/usbport.h | 10 +++++++++ 3 files changed, 66 insertions(+) diff --git a/drivers/usb/usbport/debug.c b/drivers/usb/usbport/debug.c index 67ca9f6f989..1d2662d5e33 100644 --- a/drivers/usb/usbport/debug.c +++ b/drivers/usb/usbport/debug.c @@ -12,6 +12,7 @@ #define NDEBUG_USBPORT_MINIPORT #define NDEBUG_USBPORT_URB +//#define NDEBUG_USBPORT_USB2 #include "usbdebug.h" ULONG @@ -275,3 +276,39 @@ USBPORT_DumpingIDs(IN PVOID Buffer) DPRINT("\n"); } +VOID +NTAPI +USBPORT_DumpingEndpointProperties(IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties) +{ + DPRINT_USB2("DeviceAddress - %X\n", EndpointProperties->DeviceAddress); + DPRINT_USB2("EndpointAddress - %X\n", EndpointProperties->EndpointAddress); + DPRINT_USB2("TotalMaxPacketSize - %X\n", EndpointProperties->TotalMaxPacketSize); + DPRINT_USB2("Period - %X\n", EndpointProperties->Period); + DPRINT_USB2("DeviceSpeed - %X\n", EndpointProperties->DeviceSpeed); + DPRINT_USB2("UsbBandwidth - %X\n", EndpointProperties->UsbBandwidth); + DPRINT_USB2("ScheduleOffset - %X\n", EndpointProperties->ScheduleOffset); + DPRINT_USB2("TransferType - %X\n", EndpointProperties->TransferType); + DPRINT_USB2("MaxTransferSize - %X\n", EndpointProperties->MaxTransferSize); + DPRINT_USB2("HubAddr - %X\n", EndpointProperties->HubAddr); + DPRINT_USB2("PortNumber - %X\n", EndpointProperties->PortNumber); + DPRINT_USB2("InterruptScheduleMask - %X\n", EndpointProperties->InterruptScheduleMask); + DPRINT_USB2("SplitCompletionMask - %X\n", EndpointProperties->SplitCompletionMask); + DPRINT_USB2("MaxPacketSize - %X\n", EndpointProperties->MaxPacketSize); +} + +VOID +NTAPI +USBPORT_DumpingTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint) +{ + DPRINT_USB2("MaxPacketSize - %X\n", TtEndpoint->MaxPacketSize); + DPRINT_USB2("Period - %X\n", TtEndpoint->Period); + DPRINT_USB2("TtEndpointParams- %X\n", TtEndpoint->TtEndpointParams.AsULONG); + DPRINT_USB2("CalcBusTime - %X\n", TtEndpoint->CalcBusTime); + DPRINT_USB2("StartTime - %X\n", TtEndpoint->StartTime); + DPRINT_USB2("ActualPeriod - %X\n", TtEndpoint->ActualPeriod); + DPRINT_USB2("StartFrame - %X\n", TtEndpoint->StartFrame); + DPRINT_USB2("StartMicroframe - %X\n", TtEndpoint->StartMicroframe); + DPRINT_USB2("Nums - %X\n", TtEndpoint->Nums.AsULONG); + DPRINT_USB2("nextTtEndpoint - %X\n", TtEndpoint->NextTtEndpoint); +} + diff --git a/drivers/usb/usbport/usbdebug.h b/drivers/usb/usbport/usbdebug.h index 98484f64f3c..53e65b25db1 100644 --- a/drivers/usb/usbport/usbdebug.h +++ b/drivers/usb/usbport/usbdebug.h @@ -112,6 +112,23 @@ #endif + #ifndef NDEBUG_USBPORT_USB2 + + #define DPRINT_USB2(fmt, ...) do { \ + if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \ + DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \ + } while (0) + + #else + +#if defined(_MSC_VER) + #define DPRINT_USB2 __noop +#else + #define DPRINT_USB2(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) +#endif + + #endif + #else /* not DBG */ #if defined(_MSC_VER) @@ -121,6 +138,7 @@ #define DPRINT_INT __noop #define DPRINT_TIMER __noop #define DPRINT_QUEUE __noop + #define DPRINT_USB2 __noop #else #define DPRINT_MINIPORT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) #define DPRINT_CORE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) @@ -128,6 +146,7 @@ #define DPRINT_INT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) #define DPRINT_TIMER(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) #define DPRINT_QUEUE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) + #define DPRINT_USB2(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) #endif /* _MSC_VER */ #endif /* not DBG */ diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 88277167c47..8df658b12d1 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -1335,4 +1335,14 @@ NTAPI USB2_InitController( IN PUSB2_HC_EXTENSION HcExtension); +VOID +NTAPI +USBPORT_DumpingEndpointProperties( + IN PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties); + +VOID +NTAPI +USBPORT_DumpingTtEndpoint( + IN PUSB2_TT_ENDPOINT TtEndpoint); + #endif /* USBPORT_H__ */ From 67138e7d547469b6ac127626ab975a47e6186833 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 8 Dec 2017 18:19:55 +0900 Subject: [PATCH 37/76] [USBPORT] Use ExFreePoolWithTag() instead ExFreePool() for TtExtension. Add debug info. --- drivers/usb/usbport/device.c | 5 +++-- drivers/usb/usbport/endpoint.c | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index 7ea2fda5ca5..43ec4a58dce 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -7,7 +7,7 @@ #include "usbport.h" -#define NDEBUG +//#define NDEBUG #include NTSTATUS @@ -1654,7 +1654,8 @@ USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice, FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth; } - ExFreePool(TtExtension); + DPRINT("USBPORT_RemoveDevice: ExFreePoolWithTag TtExtension - %p\n", TtExtension); + ExFreePoolWithTag(TtExtension, USB_PORT_TAG); } KeReleaseSpinLock(&FdoExtension->TtSpinLock, OldIrql); diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 8633d9be8f2..8bf9ca9cf7c 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -504,7 +504,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; @@ -602,7 +602,7 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, BOOLEAN IsReady; KIRQL OldIrql; - DPRINT("USBPORT_ClosePipe \n"); + DPRINT1("USBPORT_ClosePipe \n"); FdoExtension = FdoDevice->DeviceExtension; @@ -679,6 +679,7 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, KeAcquireSpinLock(&FdoExtension->TtSpinLock, &OldIrql); TtExtension = Endpoint->TtExtension; + DPRINT1("USBPORT_ClosePipe: TtExtension - %p\n", TtExtension); if (TtExtension) { @@ -698,7 +699,8 @@ USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle, FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth; } - ExFreePool(TtExtension); + DPRINT1("USBPORT_ClosePipe: ExFreePoolWithTag TtExtension - %p\n", TtExtension); + ExFreePoolWithTag(TtExtension, USB_PORT_TAG); } } } @@ -785,7 +787,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); @@ -1172,7 +1174,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; From 65f8f961a3c0f59400808634596709e6fa501333 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 8 Dec 2017 18:28:36 +0900 Subject: [PATCH 38/76] [USBPORT] Continue implementation USBPORT_AllocateBandwidthUSB2(). --- drivers/usb/usbport/usb2.c | 78 ++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a4a87455370..86e45a1adc4 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -555,13 +555,19 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, ULONG RebalanceListEntries; PUSB2_TT_ENDPOINT TtEndpoint; PUSB2_TT_ENDPOINT RebalanceTtEndpoint; - PUSB2_TT Tt; USB_DEVICE_SPEED DeviceSpeed; ULONG Period; - + ULONG AllocedBusTime; + ULONG EndpointBandwidth; + ULONG ScheduleOffset; + ULONG Factor; ULONG ix; + ULONG n; BOOLEAN Direction; + UCHAR SMask; + UCHAR CMask; + UCHAR ActualPeriod; BOOLEAN Result; DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n", @@ -619,9 +625,10 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, case UsbFullSpeed: { Tt = &TtExtension->Tt; + Period = USB2_FRAMES; - while (Period && Period > EndpointProperties->Period) + while (Period > 0 && Period > EndpointProperties->Period) { Period >>= 1; } @@ -633,18 +640,22 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, case UsbHighSpeed: { Tt = &FdoExtension->Usb2Extension->HcTt; - Period = EndpointProperties->Period; if (EndpointProperties->Period > USB2_MAX_MICROFRAMES) Period = USB2_MAX_MICROFRAMES; + else + Period = EndpointProperties->Period; break; } default: { - DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed); + DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", + DeviceSpeed); + DbgBreakPoint(); + Tt = &TtExtension->Tt; break; } @@ -690,23 +701,66 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, for (ix = 0; ix < RebalanceListEntries; ix++) { - DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n", - ix, - Rebalance->RebalanceEndpoint[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); } if (Rebalance) - ExFreePool(Rebalance); + ExFreePoolWithTag(Rebalance, USB_PORT_TAG); if (Result) { - DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n"); - ASSERT(FALSE); + SMask = USB2_GetSMASK(Endpoint->TtEndpoint); + EndpointProperties->InterruptScheduleMask = SMask; + + CMask = USB2_GetCMASK(Endpoint->TtEndpoint); + EndpointProperties->SplitCompletionMask = CMask; + + AllocedBusTime = TtEndpoint->CalcBusTime; + + EndpointBandwidth = USB2_MICROFRAMES * AllocedBusTime; + EndpointProperties->UsbBandwidth = EndpointBandwidth; + + ActualPeriod = Endpoint->TtEndpoint->ActualPeriod; + EndpointProperties->Period = ActualPeriod; + + ScheduleOffset = Endpoint->TtEndpoint->StartFrame; + EndpointProperties->ScheduleOffset = ScheduleOffset; + + Factor = USB2_FRAMES / ActualPeriod; + ASSERT(Factor); + + n = ScheduleOffset * Factor; + + 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; + } + } + + USBPORT_DumpingEndpointProperties(EndpointProperties); + USBPORT_DumpingTtEndpoint(Endpoint->TtEndpoint); + + if (AllocedBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2)) + { + DPRINT1("USBPORT_AllocateBandwidthUSB2: AllocedBusTime >= 0.5 * MAX_ALLOCATION \n"); + } } //USB2_Rebalance(FdoDevice, &RebalanceList); From 7553e5419936d978b3f5ec3408feee067c48afb1 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 8 Dec 2017 20:21:08 +0900 Subject: [PATCH 39/76] [USBPORT] Start implementation USB2_AllocateTimeForEndpoint(). --- drivers/usb/usbport/usb2.c | 161 +++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 86e45a1adc4..1811b541c03 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -491,6 +491,167 @@ 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; + 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", + frame, + uframe, + HcExtension->TimeUsed[frame][uframe]); + + if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], + TtEndpoint->CalcBusTime, + USB2_MAX_MICROFRAME_ALLOCATION)) + { + DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n"); + Result = FALSE; + } + } + + if (!Result) + { + for (ix = Microframe; + ix < USB2_MAX_MICROFRAMES; + ix += TtEndpoint->ActualPeriod) + { + frame = ix / USB2_MICROFRAMES; + uframe = ix % (USB2_MICROFRAMES - 1); + + HcExtension->TimeUsed[frame][uframe] -= TtEndpoint->CalcBusTime; + } + } + + DPRINT("USB2_AllocateTimeForEndpoint: Result - TRUE\n"); + return TRUE; + } + + /* Speed != UsbHighSpeed (FS/LS) */ + + if (TtEndpoint->Period > USB2_FRAMES) + TtEndpoint->ActualPeriod = USB2_FRAMES; + else + TtEndpoint->ActualPeriod = TtEndpoint->Period; + + MinTimeUsed = Tt->FrameBudget[0].TimeUsed; + + for (ix = 1; ix < TtEndpoint->ActualPeriod; ix++) + { + if ((Tt->FrameBudget[ix].TimeUsed) < MinTimeUsed) + { + MinTimeUsed = Tt->FrameBudget[ix].TimeUsed; + TtEndpoint->StartFrame = ix; + } + } + + TransferType = TtEndpoint->TtEndpointParams.TransferType; + + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + if (Speed == UsbFullSpeed) + { + Overhead = USB2_FS_ISOCHRONOUS_OVERHEAD + Tt->DelayTime; + } + else + { + DPRINT("USB2_AllocateTimeForEndpoint: ISO can not be on a LS bus!\n"); + return FALSE; + } + } + else + { + if (Speed == UsbFullSpeed) + Overhead = USB2_FS_INTERRUPT_OVERHEAD + Tt->DelayTime; + else + Overhead = USB2_LS_INTERRUPT_OVERHEAD + Tt->DelayTime; + } + + if (Speed == UsbLowSpeed) + { + TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize * 8 + Overhead; + } + else + { + TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead; + } + + DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n"); ASSERT(FALSE); return FALSE; From 2be475db5d374d6a54d6a8d58027f510c2eb9b54 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 15:00:04 +0900 Subject: [PATCH 40/76] [USBPORT] Correcting USB2_GetStartTime(). --- drivers/usb/usbport/usb2.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 1811b541c03..edc91c1d701 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -251,13 +251,11 @@ USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint, TransferType = TtEndpoint->TtEndpointParams.TransferType; - if (nextTtEndpoint && TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) - { - return nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime; - } - if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) { + if (nextTtEndpoint) + return nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime; + ttEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint; if (ttEndpoint) From e262bb610dfb13f2b4e65ef8d7e750a9ad3cff60 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 16:27:19 +0900 Subject: [PATCH 41/76] [USBPORT] End implementation USB2_AllocateTimeForEndpoint(). --- drivers/usb/usbport/usb2.c | 190 ++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index edc91c1d701..b9423258749 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -500,6 +500,12 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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; DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint); @@ -649,10 +655,188 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead; } + LatestStart = USB2_HUB_DELAY + USB2_FS_SOF_TIME; - DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n"); - ASSERT(FALSE); - return FALSE; + for (ix = 0; + (TtEndpoint->StartFrame + ix) < USB2_FRAMES; + ix += TtEndpoint->ActualPeriod) + { + frame = TtEndpoint->StartFrame + ix; + + if (Tt->FrameBudget[frame].AltEndpoint && + TtEndpoint->CalcBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2)) + { + DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n"); + return FALSE; + } + + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + prevTtEndpoint = Tt->FrameBudget[frame].IsoEndpoint; + else + prevTtEndpoint = Tt->FrameBudget[frame].IntEndpoint; + + for (nextTtEndpoint = prevTtEndpoint->NextTtEndpoint; + nextTtEndpoint; + nextTtEndpoint = nextTtEndpoint->NextTtEndpoint) + { + if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint)) + { + break; + } + + prevTtEndpoint = nextTtEndpoint; + } + + StartTime = USB2_GetStartTime(nextTtEndpoint, + TtEndpoint, + prevTtEndpoint, + frame); + + if (StartTime > LatestStart) + LatestStart = StartTime; + } + + TtEndpoint->StartTime = LatestStart; + + if ((LatestStart + TtEndpoint->CalcBusTime) > USB2_FS_MAX_PERIODIC_ALLOCATION) + { + TtEndpoint->CalcBusTime = 0; + DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n"); + return FALSE; + } + + for (ix = 0, frame = -TtEndpoint->StartFrame; + ix < USB2_FRAMES; + ix++, frame++) + { + DPRINT("USB2_AllocateTimeForEndpoint: ix - %X, frame - %X, StartFrame - %X\n", + ix, + frame, + TtEndpoint->StartFrame); + + if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) + { + DPRINT1("USB2_AllocateTimeForEndpoint: Iso Ep UNIMPLEMENTED. FIXME\n"); + ASSERT(FALSE); + } + else + { + IntEndpoint = Tt->FrameBudget[ix].IntEndpoint; + nextTtEndpoint = IntEndpoint->NextTtEndpoint; + + for (nextTtEndpoint = IntEndpoint->NextTtEndpoint; + nextTtEndpoint; + nextTtEndpoint = nextTtEndpoint->NextTtEndpoint) + { + if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint)) + break; + IntEndpoint = nextTtEndpoint; + } + + if ((frame % TtEndpoint->ActualPeriod) == 0) + { + calcBusTime = 0; + } + else + { + if (nextTtEndpoint) + { + calcBusTime = LatestStart + TtEndpoint->CalcBusTime - + nextTtEndpoint->StartTime; + } + else + { + calcBusTime = TtEndpoint->CalcBusTime; + } + + if (calcBusTime > 0) + { + TimeUsed = Tt->FrameBudget[ix].TimeUsed; + + if (!USB2_AllocateCheck(&TimeUsed, + calcBusTime, + USB2_FS_MAX_PERIODIC_ALLOCATION)) + { + DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n"); + Result = FALSE; + } + } + } + + if (nextTtEndpoint != TtEndpoint) + { + if ((frame % TtEndpoint->ActualPeriod) == 0) + { + if (frame == 0) + { + DPRINT("USB2_AllocateTimeForEndpoint: frame == 0\n"); + TtEndpoint->NextTtEndpoint = nextTtEndpoint; + } + + IntEndpoint->NextTtEndpoint = TtEndpoint; + + DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextTtEndpoint - %p\n", + TtEndpoint, + nextTtEndpoint); + } + + if (calcBusTime > 0) + { + BOOLEAN IsMoved; + BOOLEAN MoveResult; + + DPRINT("USB2_AllocateTimeForEndpoint: nextTtEndpoint - %p, calcBusTime - %X\n", + nextTtEndpoint, + calcBusTime); + + for (; + nextTtEndpoint; + nextTtEndpoint = nextTtEndpoint->NextTtEndpoint) + { + MoveResult = USB2_MoveTtEndpoint(nextTtEndpoint, + calcBusTime, + Rebalance, + *RebalanceListEntries, + &IsMoved); + + if (!IsMoved) + { + DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n"); + Result = FALSE; + } + + if (!MoveResult) + break; + } + } + } + } + + if ((frame % TtEndpoint->ActualPeriod) == 0) + { + if (!USB2_AllocateHS(TtEndpoint, frame)) + { + DPRINT1("USB2_AllocateTimeForEndpoint: USB2_AllocateHS return FALSE\n"); + Result = FALSE; + } + + Tt->FrameBudget[ix].TimeUsed += TtEndpoint->CalcBusTime; + } + + if (Result == FALSE) + { + USB2_DeallocateEndpointBudget(TtEndpoint, + Rebalance, + RebalanceListEntries, + ix + 1); + + DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n"); + return FALSE; + } + } + + DPRINT("USB2_AllocateTimeForEndpoint: Result - %X\n", Result); + return Result; } BOOLEAN From 8b9d5d1514d2e9ee6a8d1814939ed0191e5a1186 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 16:46:34 +0900 Subject: [PATCH 42/76] [USBPORT] Correcting USB2_InitTtEndpoint(). --- drivers/usb/usbport/usb2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index b9423258749..b3d7f4d80c1 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -284,8 +284,6 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, IN USHORT MaxPacketSize, IN PUSB2_TT Tt) { - RtlZeroMemory(TtEndpoint, sizeof(USB2_TT_ENDPOINT)); - TtEndpoint->TtEndpointParams.TransferType = TransferType; TtEndpoint->TtEndpointParams.Direction = Direction; TtEndpoint->TtEndpointParams.DeviceSpeed = DeviceSpeed; @@ -293,6 +291,18 @@ USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, TtEndpoint->Period = Period; TtEndpoint->MaxPacketSize = MaxPacketSize; TtEndpoint->Tt = Tt; + + TtEndpoint->CalcBusTime = 0; + TtEndpoint->StartTime = 0; + TtEndpoint->ActualPeriod = 0; + TtEndpoint->StartFrame = 0; + TtEndpoint->StartMicroframe = 0; + + TtEndpoint->Nums.AsULONG = 0; + TtEndpoint->NextTtEndpoint = NULL; + TtEndpoint->Reserved2 = 0; + TtEndpoint->PreviosPeriod = 0; + TtEndpoint->IsPromoted = FALSE; } BOOLEAN From ab5810576f96491af5ecc24fc1b2870c491bf7d0 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 16:58:52 +0900 Subject: [PATCH 43/76] [USBPORT] Add stub for USB2_DeallocateHS(). --- drivers/usb/usbport/usb2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index b3d7f4d80c1..e36bf1b1651 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -481,6 +481,15 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, return Result; } +VOID +NTAPI +USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN ULONG Frame) +{ + DPRINT("USB2_DeallocateHS: UNIMPLEMENTED FIXME\n"); + ASSERT(FALSE); +} + BOOLEAN NTAPI USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, From df44bc6d845d8411c2b26e88dbed036e7f071397 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 17:00:22 +0900 Subject: [PATCH 44/76] [USBPORT] Add stub for USB2_MoveTtEndpoint(). --- drivers/usb/usbport/usb2.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index e36bf1b1651..79ae518ca19 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -490,6 +490,19 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, ASSERT(FALSE); } +BOOLEAN +NTAPI +USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, + IN USHORT BusTime, + IN PUSB2_REBALANCE Rebalance, + IN ULONG RebalanceListEntries, + OUT BOOLEAN * OutResult) +{ + DPRINT("USB2_MoveTtEndpoint: UNIMPLEMENTED FIXME\n"); + ASSERT(FALSE); + return FALSE; +} + BOOLEAN NTAPI USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, From f3c869a16bed36e267e2838f7349cd78d5019b10 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 17:06:52 +0900 Subject: [PATCH 45/76] [USBPORT] Add USB2_GetSMASK()and USB2_ConvertFrame(). --- drivers/usb/usbport/usb2.c | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 79ae518ca19..d9742388545 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -503,6 +503,67 @@ USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, return FALSE; } +VOID +NTAPI +USB2_ConvertFrame(IN UCHAR Frame, + IN UCHAR Microframe, + OUT PUCHAR HcFrame, + OUT PUCHAR HcMicroframe) +{ + DPRINT("USB2_ConvertFrame: Frame - %x, Microframe - %x\n", + Frame, + Microframe); + + if (Microframe == 0xFF) + { + *HcFrame = Frame; + *HcMicroframe = 0; + } + + if (Microframe >= 0 && + Microframe <= (USB2_MICROFRAMES - 2)) + { + *HcFrame = Frame; + *HcMicroframe = Microframe + 1; + } + + if (Microframe == (USB2_MICROFRAMES - 1)) + { + *HcFrame = Frame + 1; + *HcMicroframe = 0; + } +} + +UCHAR +NTAPI +USB2_GetSMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) +{ + ULONG ix; + UCHAR SMask = 0; + UCHAR HcFrame; + UCHAR HcMicroFrame; + + if (TtEndpoint->TtEndpointParams.DeviceSpeed == UsbHighSpeed) + { + SMask = (1 << TtEndpoint->StartMicroframe); + } + else + { + USB2_ConvertFrame(TtEndpoint->StartFrame, + TtEndpoint->StartMicroframe, + &HcFrame, + &HcMicroFrame); + + for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++) + { + SMask |= (1 << HcMicroFrame); + HcMicroFrame++; + } + } + + return SMask; +} + BOOLEAN NTAPI USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, From 5ffefbe9456217f4dbeb655137fc040605ba89c0 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 17:15:40 +0900 Subject: [PATCH 46/76] [USBPORT] Add USB2_GetCMASK(). --- drivers/usb/usbport/usb2.c | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index d9742388545..d234c7e3904 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -564,6 +564,79 @@ USB2_GetSMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) return SMask; } +UCHAR +NTAPI +USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) +{ + ULONG NumCompletes; + ULONG TransferType; + ULONG DeviceSpeed; + ULONG Direction; + UCHAR Result; + UCHAR MicroFrameCS; + 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) + { + USB2_ConvertFrame(TtEndpoint->StartFrame, + TtEndpoint->StartMicroframe, + &HcFrame, + &HcMicroFrame); + + Result = CMASKS[HcMicroFrame]; + } + else + { + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) + { + return 0; + } + + USB2_ConvertFrame(TtEndpoint->StartFrame, + TtEndpoint->StartMicroframe, + &HcFrame, + &HcMicroFrame); + + NumCompletes = TtEndpoint->Nums.NumCompletes; + + for (MicroFrameCS = HcMicroFrame + 2; + MicroFrameCS < USB2_MICROFRAMES; + MicroFrameCS++) + { + MaskCS |= (1 << MicroFrameCS); + NumCompletes--; + + if (!NumCompletes) + { + return MaskCS; + } + } + + for (; NumCompletes; NumCompletes--) + { + MaskCS |= (1 << (MicroFrameCS - USB2_MICROFRAMES)); + } + + Result = MaskCS; + } + + return Result; +} + BOOLEAN NTAPI USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, From 1926238056b49263756988c6dc6f1bd2528aebb3 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 17:23:25 +0900 Subject: [PATCH 47/76] [USBPORT] Reduces output of debug messages. --- drivers/usb/usbport/usb2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index d234c7e3904..f440c0355a0 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -200,9 +200,9 @@ USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint, *OverheadCS = HostDelay + USB2_HS_CS_INTERRUPT_IN_OVERHEAD; } - DPRINT("USB2_GetHsOverhead: *OverheadSS - %X, *OverheadCS - %X\n", - *OverheadSS, - *OverheadCS); + //DPRINT("USB2_GetHsOverhead: *OverheadSS - %X, *OverheadCS - %X\n", + // *OverheadSS, + // *OverheadCS); } } @@ -214,9 +214,9 @@ USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint, PUSB2_TT_ENDPOINT nextTtEndpoint; ULONG Result; - DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n", - TtEndpoint, - Frame); + //DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n", + // TtEndpoint, + // Frame); nextTtEndpoint = TtEndpoint->Tt->FrameBudget[Frame].IsoEndpoint->NextTtEndpoint; From 00dd0c67b6a7365872b6fbbd79f85992189d65b7 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 9 Dec 2017 18:42:16 +0900 Subject: [PATCH 48/76] [USBPORT] Correcting USB2_AllocateHS(). --- drivers/usb/usbport/usb2.c | 84 ++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index f440c0355a0..f0bee68394f 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -315,16 +315,18 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, ULONG TransferType; ULONG Direction; ULONG DataTime; + ULONG DataSize; ULONG RemainDataTime; ULONG OverheadCS; ULONG OverheadSS; ULONG ix; USHORT PktSize; + USHORT PktSizeBitStuff; UCHAR frame; UCHAR uframe; BOOL Result = TRUE; - DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, TtEndpoint->StartFrame - %X\n", + DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, StartFrame - %X\n", TtEndpoint, Frame, TtEndpoint->StartFrame); @@ -352,14 +354,10 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, { TtEndpoint->Nums.NumStarts = 1; - if ((CHAR)TtEndpoint->StartMicroframe < 5) - { + if ((CHAR)TtEndpoint->StartMicroframe < (USB2_MICROFRAMES - 3)) TtEndpoint->Nums.NumCompletes = 3; - } else - { TtEndpoint->Nums.NumCompletes = 2; - } } } else @@ -391,7 +389,8 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, Result = FALSE; } - if (Tt->NumStartSplits[frame][uframe] > (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME - 1)) + if (Tt->NumStartSplits[frame][uframe] > + (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME - 1)) { DPRINT1("USB2_AllocateHS: Num Start Splits - %X\n", Tt->NumStartSplits[frame][uframe] + 1); @@ -419,10 +418,44 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, USB2_IncMicroFrame(&frame, &uframe); } + PktSize = TtEndpoint->MaxPacketSize; + PktSizeBitStuff = USB2_AddDataBitStuff(PktSize); + if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) { - DPRINT("USB2_AllocateHS: DIRECTION OUT UNIMPLEMENTED\n"); - ASSERT(FALSE); + frame = TtEndpoint->StartFrame + Frame; + uframe = TtEndpoint->StartMicroframe; + + if (uframe == 0xFF) + 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) + DataTime = DataSize; + else + DataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME; + + DPRINT("USB2_AllocateHS: ix - %X, frame - %X, uframe - %X, TimeUsed - %X\n", + ix, + frame, + uframe, + HcExtension->TimeUsed[frame][uframe]); + + if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], + DataTime, + USB2_MAX_MICROFRAME_ALLOCATION)) + { + Result = FALSE; + } + + USB2_IncMicroFrame(&frame, &uframe); + DataTime += USB2_FS_RAW_BYTES_IN_MICROFRAME; + } } else { @@ -433,26 +466,21 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, { if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME) { - if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME) - { - RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME - - Tt->TimeCS[frame][uframe]; - } - else - { - RemainDataTime = 0; - } + RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME - + Tt->TimeCS[frame][uframe]; - PktSize = TtEndpoint->MaxPacketSize; - - if (RemainDataTime >= USB2_AddDataBitStuff(PktSize)) + if (RemainDataTime >= PktSizeBitStuff) { - DataTime = USB2_AddDataBitStuff(PktSize); + DataTime = PktSizeBitStuff; } - else + else if (RemainDataTime > 0) { DataTime = RemainDataTime; } + else + { + DataTime = 0; + } if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe], DataTime, @@ -462,16 +490,10 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, } } - PktSize = TtEndpoint->MaxPacketSize; - - if (USB2_AddDataBitStuff(PktSize) < USB2_FS_RAW_BYTES_IN_MICROFRAME) - { - Tt->TimeCS[frame][uframe] += USB2_AddDataBitStuff(PktSize); - } + if (PktSizeBitStuff < USB2_FS_RAW_BYTES_IN_MICROFRAME) + Tt->TimeCS[frame][uframe] += PktSizeBitStuff; else - { Tt->TimeCS[frame][uframe] += USB2_FS_RAW_BYTES_IN_MICROFRAME; - } USB2_IncMicroFrame(&frame, &uframe); } From c48093573bd6eb660ff83022029db1276a70daa1 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sun, 10 Dec 2017 11:49:40 +0900 Subject: [PATCH 49/76] [USBPORT] Implement USB2_DeallocateHS(). --- drivers/usb/usbport/usb2.c | 118 ++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index f0bee68394f..14512d771d4 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -508,8 +508,122 @@ NTAPI 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 == 0xFF) + { + 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 == 0xFF) + { + 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 From ae800da85bd34ad2ce6b19cb049090f95e1787bc Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 11 Dec 2017 16:24:26 +0900 Subject: [PATCH 50/76] [USBPORT] Implement USB2_MoveTtEndpoint(). --- drivers/usb/usbport/usb2.c | 78 +++++++++++++++++++++++++++++++++-- drivers/usb/usbport/usbport.h | 2 +- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 14512d771d4..ade65b43570 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -634,9 +634,81 @@ USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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; } VOID diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 8df658b12d1..b98ac15e002 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -483,7 +483,7 @@ typedef union _USB2_TT_ENDPOINT_PARAMS { ULONG TransferType : 4; ULONG Direction : 1; USB_DEVICE_SPEED DeviceSpeed : 2; - ULONG EndpointMoved : 1; + BOOL EndpointMoved : 1; ULONG Reserved : 24; }; ULONG AsULONG; From 3031695100f018ffb6f648fc0fda0a85bf5e42d1 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 11 Dec 2017 18:01:07 +0900 Subject: [PATCH 51/76] [USBPORT] Add USB2_CommonFrames(). --- drivers/usb/usbport/usb2.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index ade65b43570..0e305b4d11e 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -711,6 +711,33 @@ USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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 NTAPI USB2_ConvertFrame(IN UCHAR Frame, From 3ba9fffbb2594b1909366fba1ce5af69ab28a44b Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 13 Dec 2017 03:51:54 +0900 Subject: [PATCH 52/76] [USBPORT] Start implementation USB2_DeallocateEndpointBudget(). --- drivers/usb/usbport/usb2.c | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 0e305b4d11e..a6a2f218eef 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -879,9 +879,60 @@ USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, IN PULONG RebalanceListEntries, IN ULONG MaxFrames) { + PUSB2_TT Tt; + PUSB2_HC_EXTENSION HcExtension; + ULONG Speed; + ULONG StartMicroframe; + ULONG ix; + + UCHAR frame; + UCHAR uframe; + + DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, MaxFrames - %X\n", + TtEndpoint, + MaxFrames); + + if (TtEndpoint->CalcBusTime == 0) + { + DPRINT("USB2_DeallocateEndpointBudget: endpoint not allocated\n");//error((int)"endpoint not allocated"); + 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) */ + DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n"); ASSERT(FALSE); - return FALSE; + + TtEndpoint->CalcBusTime = 0; + DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n"); + return TRUE; } BOOLEAN From bbbcb1dc7567e84485e9264a3de3e4a93594f20e Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 13 Dec 2017 19:46:18 +0900 Subject: [PATCH 53/76] [USBPORT] Rename variables only in USB2_AllocateTimeForEndpoint(). --- drivers/usb/usbport/usb2.c | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a6a2f218eef..ebdd2594fe2 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -953,8 +953,8 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, ULONG TransferType; ULONG Overhead; ULONG LatestStart; - PUSB2_TT_ENDPOINT prevTtEndpoint; - PUSB2_TT_ENDPOINT nextTtEndpoint; + PUSB2_TT_ENDPOINT prevEndpoint; + PUSB2_TT_ENDPOINT nextEndpoint; PUSB2_TT_ENDPOINT IntEndpoint; ULONG StartTime; ULONG calcBusTime; @@ -1123,25 +1123,25 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, } 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) @@ -1174,15 +1174,15 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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) @@ -1191,10 +1191,10 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, } else { - if (nextTtEndpoint) + if (nextEndpoint) { calcBusTime = LatestStart + TtEndpoint->CalcBusTime - - nextTtEndpoint->StartTime; + nextEndpoint->StartTime; } else { @@ -1215,21 +1215,21 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, } } - 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) @@ -1237,15 +1237,15 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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, From 5d12e3040c5ee4543b360f27fad17e1ac5439357 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 14 Dec 2017 04:05:06 +0900 Subject: [PATCH 54/76] [USBPORT] Add stub for USB2_RebalanceEndpoint(). --- drivers/usb/usbport/usb2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index ebdd2594fe2..de399d8a529 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -872,6 +872,15 @@ USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) return Result; } +VOID +NTAPI +USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice, + IN PLIST_ENTRY List) +{ + DPRINT1("USB2_RebalanceEndpoint: UNIMPLEMENTED. FIXME\n"); + ASSERT(FALSE); +} + BOOLEAN NTAPI USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, From 522c0d3c69dc3993b851d8aa3fa77b95deb93a9a Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 14 Dec 2017 04:06:48 +0900 Subject: [PATCH 55/76] [USBPORT] Implement USB2_Rebalance(). --- drivers/usb/usbport/usb2.c | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index de399d8a529..d1dce19f3fd 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -881,6 +881,90 @@ USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice, ASSERT(FALSE); } +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, @@ -1567,7 +1651,7 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, } } - //USB2_Rebalance(FdoDevice, &RebalanceList); + USB2_Rebalance(FdoDevice, &RebalanceList); if (!TtExtension) { From 5ad7a2faa535316595e962da72ed497934fdd233 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 15 Dec 2017 19:01:36 +0900 Subject: [PATCH 56/76] [USBPORT] Implement USB2_RebalanceEndpoint(). --- drivers/usb/usbport/usb2.c | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index d1dce19f3fd..459b2937368 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -877,8 +877,90 @@ NTAPI USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice, IN PLIST_ENTRY List) { - DPRINT1("USB2_RebalanceEndpoint: UNIMPLEMENTED. FIXME\n"); - ASSERT(FALSE); + 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) + { + Factor = USB2_FRAMES / Endpoint->EndpointProperties.Period; + ASSERT(Factor); + + 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; + + Factor = USB2_FRAMES / NewPeriod; + ASSERT(Factor); + + 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 From 69406c26280eea5a096aada5c8bc104c9e946458 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 16 Dec 2017 13:03:00 +0900 Subject: [PATCH 57/76] [USBPORT] Implement USB2_DeallocateEndpointBudget(). --- drivers/usb/usbport/usb2.c | 198 ++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 459b2937368..a9ba071b08e 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1102,10 +1102,204 @@ USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, /* 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; + DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint); + } + else if (Tt->FrameBudget[frame].AltEndpoint) + { + endpoint = Tt->FrameBudget[frame].AltEndpoint; + DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint); + } + } + } + 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; } From 0558635f98c236568a7fe36ca297b377962b5348 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 16 Dec 2017 22:26:50 +0900 Subject: [PATCH 58/76] [USBPORT] Add USB2_ChangePeriod(). --- drivers/usb/usbport/usb2.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a9ba071b08e..642271903ac 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1660,6 +1660,32 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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, From bc9046c635c69d97ffc4247678497e4c3cc39853 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sat, 16 Dec 2017 22:30:13 +0900 Subject: [PATCH 59/76] [USBPORT] Implement USB2_PromotePeriods(). --- drivers/usb/usbport/usb2.c | 96 +++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 642271903ac..cfaf122fba1 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1692,8 +1692,100 @@ 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 && + 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; } From 57f092106a86643726140a60cb2e217d2496c816 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sun, 17 Dec 2017 14:54:46 +0900 Subject: [PATCH 60/76] [USBPORT] Correcting USB2_DeallocateEndpointBudget(). --- drivers/usb/usbport/usb2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index cfaf122fba1..c0a218b8672 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1057,11 +1057,23 @@ 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", TtEndpoint, From 7b92b8a6e241b323cbddfec8a57f1ecf2a557281 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Sun, 17 Dec 2017 18:57:34 +0900 Subject: [PATCH 61/76] [USBPORT] Implement USBPORT_FreeBandwidthUSB2(). --- drivers/usb/usbport/usb2.c | 124 ++++++++++++++++++++++++++++++++-- drivers/usb/usbport/usbport.h | 1 + 2 files changed, 121 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index c0a218b8672..a382d519bbd 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1075,13 +1075,14 @@ USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, 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; } @@ -2087,7 +2088,122 @@ NTAPI 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)); + + Factor = USB2_FRAMES / Period; + ASSERT(Factor); + + 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 diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index b98ac15e002..682e4e1f74e 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -508,6 +508,7 @@ typedef struct _USB2_TT_ENDPOINT { struct _USB2_TT_ENDPOINT * NextTtEndpoint; USB2_TT_ENDPOINT_PARAMS TtEndpointParams; USB2_TT_ENDPOINT_NUMS Nums; + BOOL IsPromoted; USHORT MaxPacketSize; USHORT PreviosPeriod; USHORT Period; From 9426d2986de5174b73bf470372bfc84fcd6bdb95 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 25 Dec 2017 15:19:43 +0900 Subject: [PATCH 62/76] [USBPORT] Fixing calculation pointer for FdoExtension->Usb2Extension. --- drivers/usb/usbport/usbport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usbport.c b/drivers/usb/usbport/usbport.c index 1dbe779daa5..3be8e951ef3 100644 --- a/drivers/usb/usbport/usbport.c +++ b/drivers/usb/usbport/usbport.c @@ -1907,8 +1907,8 @@ USBPORT_AddDevice(IN PDRIVER_OBJECT DriverObject, if (MiniPortInterface->Packet.MiniPortFlags & USB_MINIPORT_FLAGS_USB2) { FdoExtension->Usb2Extension = - (PUSB2_HC_EXTENSION)FdoExtension->MiniPortExt + - MiniPortInterface->Packet.MiniPortExtensionSize; + (PUSB2_HC_EXTENSION)((ULONG_PTR)FdoExtension->MiniPortExt + + MiniPortInterface->Packet.MiniPortExtensionSize); DPRINT("USBPORT_AddDevice: Usb2Extension - %p\n", FdoExtension->Usb2Extension); From 18f4fc71c85ac817d224d6b5b30b4742a2e71cba Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 01:31:47 +0900 Subject: [PATCH 63/76] [USBPORT] Use min() macro. --- drivers/usb/usbport/endpoint.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 8bf9ca9cf7c..e599e87b50a 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -107,10 +107,7 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, for (ix = 1; *Bandwidth >= EndpointBandwidth; ix++) { - if (MinBandwidth > *Bandwidth) - { - MinBandwidth = *Bandwidth; - } + MinBandwidth = min(MinBandwidth, *Bandwidth); Bandwidth++; From 954cc021dad049793724487124b6bc5f12c18b29 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 01:44:38 +0900 Subject: [PATCH 64/76] [USBPORT] Proper naming. --- drivers/usb/usbport/endpoint.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index e599e87b50a..18293a763de 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -151,11 +151,11 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, } } - DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedInterrupt_XXms\n"); + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n"); } else { - DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n"); + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n"); } } @@ -219,11 +219,11 @@ USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice, ASSERT(Period != 0); - DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedInterrupt_XXms\n"); + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n"); } else { - DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n"); + DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n"); } DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n"); From ab88f25048d3b34ae7039581368b2ac2e166376e Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 01:53:45 +0900 Subject: [PATCH 65/76] [USBPORT] Check Period instead Factor. --- drivers/usb/usbport/endpoint.c | 7 ++++--- drivers/usb/usbport/usb2.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 18293a763de..2e9881bff2f 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -96,9 +96,10 @@ USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice, TotalBusBandwidth = FdoExtension->TotalBusBandwidth; EndpointBandwidth = EndpointProperties->UsbBandwidth; + Period = EndpointProperties->Period; + ASSERT(Period != 0); Factor = USB2_FRAMES / Period; - ASSERT(Factor); for (Offset = 0; Offset < Period; Offset++) { @@ -197,9 +198,9 @@ USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice, Offset = Endpoint->EndpointProperties.ScheduleOffset; EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth; - Period = Endpoint->EndpointProperties.Period; - ASSERT(USB2_FRAMES / Period); + Period = Endpoint->EndpointProperties.Period; + ASSERT(Period != 0); for (Factor = USB2_FRAMES / Period; Factor; Factor--) { diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index a382d519bbd..6259cf487e9 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -2107,6 +2107,8 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, FdoExtension = FdoDevice->DeviceExtension; Period = Endpoint->EndpointProperties.Period; + ASSERT(Period != 0); + ScheduleOffset = Endpoint->EndpointProperties.ScheduleOffset; EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth; @@ -2134,8 +2136,6 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE)); Factor = USB2_FRAMES / Period; - ASSERT(Factor); - n = ScheduleOffset * Factor; TtExtension = Endpoint->TtExtension; From dd1297f0d0f47a6f1ac8a894b283308b7ecc9874 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 02:01:21 +0900 Subject: [PATCH 66/76] [USBPORT] Use min(), max() macro. --- drivers/usb/usbport/usb2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 6259cf487e9..92568f7e48b 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -1821,11 +1821,8 @@ USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension) { 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; From c86210e8003b9af41fa9f33f70682e246010d06a Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 02:40:56 +0900 Subject: [PATCH 67/76] [USBPORT] Correcting check Period. --- drivers/usb/usbport/usb2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 92568f7e48b..8158c70d612 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -7,7 +7,7 @@ #include "usbport.h" -//#define NDEBUG +#define NDEBUG #include BOOLEAN @@ -2104,8 +2104,6 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, FdoExtension = FdoDevice->DeviceExtension; Period = Endpoint->EndpointProperties.Period; - ASSERT(Period != 0); - ScheduleOffset = Endpoint->EndpointProperties.ScheduleOffset; EndpointBandwidth = Endpoint->EndpointProperties.UsbBandwidth; @@ -2132,6 +2130,7 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE)); + ASSERT(Period != 0); Factor = USB2_FRAMES / Period; n = ScheduleOffset * Factor; From 2c73523b76abb1fe03fa14b45dc3924460876375 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 03:14:22 +0900 Subject: [PATCH 68/76] [USBPORT] Removing optional braces. --- drivers/usb/usbport/usb2.c | 47 ++++---------------------------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 8158c70d612..4de18b7b124 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -199,10 +199,6 @@ USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint, *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); } } @@ -536,9 +532,7 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, uframe = TtEndpoint->StartMicroframe; if (TtEndpoint->StartMicroframe == 0xFF) - { USB2_GetPrevMicroFrame(&frame, &uframe); - } for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++) { @@ -566,9 +560,7 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, uframe = TtEndpoint->StartMicroframe; if (TtEndpoint->StartMicroframe == 0xFF) - { USB2_GetPrevMicroFrame(&frame, &uframe); - } DataTime = 0; @@ -577,13 +569,9 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, 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); @@ -598,13 +586,9 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, 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; @@ -727,13 +711,9 @@ USB2_CommonFrames(IN PUSB2_TT_ENDPOINT NextTtEndpoint, } if (NextTtEndpoint->ActualPeriod < TtEndpoint->ActualPeriod) - { Frame = TtEndpoint->StartFrame % TtEndpoint->ActualPeriod; - } else - { Frame = NextTtEndpoint->StartFrame % TtEndpoint->ActualPeriod; - } return (Frame == TtEndpoint->StartFrame); } @@ -821,9 +801,7 @@ USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) Direction = TtEndpoint->TtEndpointParams.Direction; if (DeviceSpeed == UsbHighSpeed) - { return 0; - } if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT) { @@ -837,9 +815,7 @@ USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) else { if (Direction == USBPORT_TRANSFER_DIRECTION_OUT) - { return 0; - } USB2_ConvertFrame(TtEndpoint->StartFrame, TtEndpoint->StartMicroframe, @@ -856,9 +832,7 @@ USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) NumCompletes--; if (!NumCompletes) - { return MaskCS; - } } for (; NumCompletes; NumCompletes--) @@ -926,8 +900,8 @@ USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice, if (Endpoint->EndpointProperties.Period != NewPeriod) { + ASSERT(Endpoint->EndpointProperties.Period); Factor = USB2_FRAMES / Endpoint->EndpointProperties.Period; - ASSERT(Factor); for (ix = 0; ix < Factor; ix++) { @@ -940,8 +914,8 @@ USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice, Endpoint->EndpointProperties.ScheduleOffset = ScheduleOffset; Endpoint->EndpointProperties.UsbBandwidth = EndpointBandwidth; + ASSERT(NewPeriod); Factor = USB2_FRAMES / NewPeriod; - ASSERT(Factor); for (ix = 0; ix < Factor; ix++) { @@ -1135,13 +1109,9 @@ USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, } if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT) - { endpoint = Tt->FrameBudget[frame].IntEndpoint; - } else - { endpoint = Tt->FrameBudget[frame].IsoEndpoint; - } nextEndpoint = endpoint->NextTtEndpoint; @@ -1481,13 +1451,9 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, } if (Speed == UsbLowSpeed) - { TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize * 8 + Overhead; - } else - { TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead; - } LatestStart = USB2_HUB_DELAY + USB2_FS_SOF_TIME; @@ -1514,9 +1480,7 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, nextEndpoint = nextEndpoint->NextTtEndpoint) { if (USB2_CheckTtEndpointInsert(nextEndpoint, TtEndpoint)) - { break; - } prevEndpoint = nextEndpoint; } @@ -1526,8 +1490,7 @@ USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, prevEndpoint, frame); - if (StartTime > LatestStart) - LatestStart = StartTime; + LatestStart = max(LatestStart, StartTime); } TtEndpoint->StartTime = LatestStart; @@ -2026,8 +1989,8 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, ScheduleOffset = Endpoint->TtEndpoint->StartFrame; EndpointProperties->ScheduleOffset = ScheduleOffset; + ASSERT(ActualPeriod); Factor = USB2_FRAMES / ActualPeriod; - ASSERT(Factor); n = ScheduleOffset * Factor; @@ -2183,9 +2146,7 @@ USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, USB2_Rebalance(FdoDevice, &RebalanceList); if (!TtExtension) - { return; - } for (ix = 0; ix < USB2_FRAMES; ix++) { From fd5beb559374007e51747917cdb09828ff970927 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 03:18:17 +0900 Subject: [PATCH 69/76] [USBPORT] Moving array CMASKS[] to start file. --- drivers/usb/usbport/usb2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 4de18b7b124..cc833e308ff 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -10,6 +10,10 @@ #define NDEBUG #include +static const UCHAR CMASKS[USB2_MICROFRAMES] = { + 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E +}; + BOOLEAN NTAPI USB2_AllocateCheck(IN OUT PULONG OutTimeUsed, @@ -792,9 +796,6 @@ USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint) 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; From 0f8079df3a98336576dadc06d2d7fd99a13499b7 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 14:23:49 +0900 Subject: [PATCH 70/76] [USBPORT] Add USB2_PREV_MICROFRAME constant. --- drivers/usb/usbport/usb2.c | 14 +++++++------- drivers/usb/usbport/usbport.h | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index cc833e308ff..6c1e23ddbb4 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -377,7 +377,7 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, 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++) @@ -426,7 +426,7 @@ USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, frame = TtEndpoint->StartFrame + Frame; uframe = TtEndpoint->StartMicroframe; - if (uframe == 0xFF) + if (uframe == USB2_PREV_MICROFRAME) USB2_GetPrevMicroFrame(&frame, &uframe); DataTime = 0; @@ -535,7 +535,7 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, 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++) @@ -563,7 +563,7 @@ USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint, frame = TtEndpoint->StartFrame + Frame; uframe = TtEndpoint->StartMicroframe; - if (TtEndpoint->StartMicroframe == 0xFF) + if (TtEndpoint->StartMicroframe == USB2_PREV_MICROFRAME) USB2_GetPrevMicroFrame(&frame, &uframe); DataTime = 0; @@ -733,7 +733,7 @@ USB2_ConvertFrame(IN UCHAR Frame, Frame, Microframe); - if (Microframe == 0xFF) + if (Microframe == USB2_PREV_MICROFRAME) { *HcFrame = Frame; *HcMicroframe = 0; @@ -2202,7 +2202,7 @@ USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension, 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]; @@ -2217,7 +2217,7 @@ USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension, 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; } } diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 682e4e1f74e..55c97e53307 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -451,6 +451,7 @@ typedef struct _TIMER_WORK_QUEUE_ITEM { #define USB2_FRAMES 32 #define USB2_MICROFRAMES 8 #define USB2_MAX_MICROFRAMES (USB2_FRAMES * USB2_MICROFRAMES) +#define USB2_PREV_MICROFRAME 0xFF #define USB2_MAX_MICROFRAME_ALLOCATION 7000 // bytes #define USB2_CONTROLLER_DELAY 100 From ecd0097e37cc0fd277a385bbc9c3fc2b2b1a3987 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Thu, 11 Jan 2018 17:12:16 +0900 Subject: [PATCH 71/76] [USBPORT] Delete DPRINTs. --- drivers/usb/usbport/usb2.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 6c1e23ddbb4..f8bfc04dad0 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -645,7 +645,7 @@ USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint, 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; @@ -1179,12 +1179,10 @@ USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint, if (Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint) { endpoint = Tt->FrameBudget[frame].IsoEndpoint->NextTtEndpoint; - DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint); } else if (Tt->FrameBudget[frame].AltEndpoint) { endpoint = Tt->FrameBudget[frame].AltEndpoint; - DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint); } } } @@ -1705,7 +1703,7 @@ USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint, if (ttEndpoint->ActualPeriod != ENDPOINT_INTERRUPT_1ms && TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT && - ttEndpoint->StartMicroframe > 2) + (CHAR)ttEndpoint->StartMicroframe > 2) { USB2_DeallocateEndpointBudget(ttEndpoint, Rebalance, @@ -1881,7 +1879,6 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, case UsbFullSpeed: { Tt = &TtExtension->Tt; - Period = USB2_FRAMES; while (Period > 0 && Period > EndpointProperties->Period) @@ -1992,7 +1989,6 @@ USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice, ASSERT(ActualPeriod); Factor = USB2_FRAMES / ActualPeriod; - n = ScheduleOffset * Factor; if (TtExtension) From a4dee8e3ac894062b4eb3e86c6333c071c2e9b77 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 17 Jan 2018 06:50:04 +0900 Subject: [PATCH 72/76] [USBPORT] Add a space in indentation. --- drivers/usb/usbport/usb2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index f8bfc04dad0..86cd1e1474a 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -259,9 +259,9 @@ USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint, 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 { From 797ebcab724adf1616cba79c5384e8c8c8568c77 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 17 Jan 2018 14:22:49 +0900 Subject: [PATCH 73/76] [USBPORT] Fixing use DeviceSpeed instead Direction. --- drivers/usb/usbport/usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 86cd1e1474a..7d2c9a308dc 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -127,7 +127,7 @@ USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) TransferType = TtEndpoint->TtEndpointParams.TransferType; Direction = TtEndpoint->TtEndpointParams.Direction; - DeviceSpeed = TtEndpoint->TtEndpointParams.Direction; + DeviceSpeed = TtEndpoint->TtEndpointParams.DeviceSpeed; HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime; From f37a3dc42fb08d7c4ebdeefb8c369b6c2f21a2e4 Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Mon, 22 Jan 2018 14:15:57 +0900 Subject: [PATCH 74/76] [USBPORT] Add USB2_BIT_STUFFING_OVERHEAD constant. --- drivers/usb/usbport/endpoint.c | 2 +- drivers/usb/usbport/usbport.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 2e9881bff2f..56ad3411b21 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -47,7 +47,7 @@ USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice, } else { - Bandwidth = (EndpointProperties->TotalMaxPacketSize + Overhead) * 8 * 7 / 6; + Bandwidth = (EndpointProperties->TotalMaxPacketSize + Overhead) * USB2_BIT_STUFFING_OVERHEAD; } if (EndpointProperties->DeviceSpeed == UsbLowSpeed) diff --git a/drivers/usb/usbport/usbport.h b/drivers/usb/usbport/usbport.h index 55c97e53307..20386f4845e 100644 --- a/drivers/usb/usbport/usbport.h +++ b/drivers/usb/usbport/usbport.h @@ -479,6 +479,8 @@ typedef struct _TIMER_WORK_QUEUE_ITEM { #define USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD 39 #define USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD 38 +#define USB2_BIT_STUFFING_OVERHEAD (8 * (7/6)) // 7.1.9 Bit Stuffing + typedef union _USB2_TT_ENDPOINT_PARAMS { struct { ULONG TransferType : 4; From 11772da783546c032b0393818747154d23fb6bae Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Fri, 26 Jan 2018 20:46:34 +0900 Subject: [PATCH 75/76] [USBPORT] Small changes for debugging. --- drivers/usb/usbport/device.c | 2 +- drivers/usb/usbport/endpoint.c | 2 +- drivers/usb/usbport/ioctl.c | 2 +- drivers/usb/usbport/power.c | 2 -- drivers/usb/usbport/usbport.c | 8 ++++---- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usbport/device.c b/drivers/usb/usbport/device.c index 43ec4a58dce..070a6c98168 100644 --- a/drivers/usb/usbport/device.c +++ b/drivers/usb/usbport/device.c @@ -7,7 +7,7 @@ #include "usbport.h" -//#define NDEBUG +#define NDEBUG #include NTSTATUS diff --git a/drivers/usb/usbport/endpoint.c b/drivers/usb/usbport/endpoint.c index 56ad3411b21..0386bd0f149 100644 --- a/drivers/usb/usbport/endpoint.c +++ b/drivers/usb/usbport/endpoint.c @@ -1279,7 +1279,7 @@ USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice) PLIST_ENTRY ClosedList; PUSBPORT_ENDPOINT Endpoint; - DPRINT("USBPORT_FlushClosedEndpointList: ... \n"); + DPRINT_CORE("USBPORT_FlushClosedEndpointList: ... \n"); FdoExtension = FdoDevice->DeviceExtension; diff --git a/drivers/usb/usbport/ioctl.c b/drivers/usb/usbport/ioctl.c index 6502c6549ab..7e29d3d6188 100644 --- a/drivers/usb/usbport/ioctl.c +++ b/drivers/usb/usbport/ioctl.c @@ -7,7 +7,7 @@ #include "usbport.h" -//#define NDEBUG +#define NDEBUG #include VOID diff --git a/drivers/usb/usbport/power.c b/drivers/usb/usbport/power.c index 56f150d8dd2..0dca45334dd 100644 --- a/drivers/usb/usbport/power.c +++ b/drivers/usb/usbport/power.c @@ -105,8 +105,6 @@ USBPORT_DoSetPowerD0(IN PDEVICE_OBJECT FdoDevice) { DPRINT("USBPORT_DoSetPowerD0: FIXME!\n"); return; - DbgBreakPoint(); - //ASSERT(FALSE); } VOID diff --git a/drivers/usb/usbport/usbport.c b/drivers/usb/usbport/usbport.c index 3be8e951ef3..cc85e73bca6 100644 --- a/drivers/usb/usbport/usbport.c +++ b/drivers/usb/usbport/usbport.c @@ -637,8 +637,8 @@ USBPORT_InvalidateControllerHandler(IN PDEVICE_OBJECT FdoDevice, { PUSBPORT_DEVICE_EXTENSION FdoExtension; - DPRINT("USBPORT_InvalidateControllerHandler: Invalidate Type - %x\n", - Type); + DPRINT_CORE("USBPORT_InvalidateControllerHandler: Invalidate Type - %x\n", + Type); FdoExtension = FdoDevice->DeviceExtension; @@ -869,7 +869,7 @@ USBPORT_DpcHandler(IN PDEVICE_OBJECT FdoDevice) LIST_ENTRY List; LONG LockCounter; - DPRINT("USBPORT_DpcHandler: ... \n"); + DPRINT_CORE("USBPORT_DpcHandler: ... \n"); FdoExtension = FdoDevice->DeviceExtension; @@ -1953,7 +1953,7 @@ USBPORT_Unload(IN PDRIVER_OBJECT DriverObject) if (!MiniPortInterface) { - DPRINT("USBPORT_Unload: CRITICAL ERROR!!! USBPORT_FindMiniPort not found MiniPortInterface\n"); + DPRINT("USBPORT_Unload: CRITICAL ERROR!!! Not found MiniPortInterface\n"); KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0); } From 62612a7e45fa2bdfa254cf9eaf2bd81634f4d4ee Mon Sep 17 00:00:00 2001 From: Vadim Galyant Date: Wed, 21 Feb 2018 13:35:25 +0900 Subject: [PATCH 76/76] [USBPORT] Use USB2_HS_INTERRUPT_IN_OVERHEAD instead USB2_HS_ISOCHRONOUS_OUT_OVERHEAD. --- drivers/usb/usbport/usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usbport/usb2.c b/drivers/usb/usbport/usb2.c index 7d2c9a308dc..be13000112c 100644 --- a/drivers/usb/usbport/usb2.c +++ b/drivers/usb/usbport/usb2.c @@ -145,7 +145,7 @@ USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint) 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)