Skip to content

Commit 396e5d3

Browse files
committed
[USBEHCI]
- Rewrite linking of iso td [USBPORT] - Misc iso fixes [USBVIDEO] - Fix buffer calculation
1 parent 0764523 commit 396e5d3

7 files changed

Lines changed: 134 additions & 135 deletions

File tree

drivers/usb/usbehci/usbehci.c

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,7 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
26202620
EhciTransfer->TransferParameters = TransferParameters;
26212621
EhciTransfer->USBDStatus = USBD_STATUS_SUCCESS;
26222622
EhciTransfer->EhciEndpoint = EhciEndpoint;
2623+
InitializeListHead(&EhciTransfer->ActiveITDs);
26232624

26242625
DeviceSpeed = EhciEndpoint->EndpointProperties.DeviceSpeed;
26252626

@@ -2662,6 +2663,7 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
26622663
return MP_STATUS_NO_RESOURCES;
26632664
}
26642665
DPRINT("OriginalFrame %u New FrameNumber %u\n", IsoTransfer->Packets[0].FrameNumber, CurrentFrame);
2666+
EHCI_DisablePeriodicList(EhciExtension);
26652667

26662668
/* Allocate and program iTDs, one per frame */
26672669
while (PacketIndex < IsoTransfer->TotalPackets)
@@ -2681,6 +2683,7 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
26812683
/* TODO: free previously allocated iTDs */
26822684
return MP_STATUS_NO_RESOURCES;
26832685
}
2686+
26842687
DPRINT("ITD %p CurrentFrame %x\n", ITD, CurrentFrame);
26852688
EndpointProperties = &EhciEndpoint->EndpointProperties;
26862689
DeviceAddress = EndpointProperties->DeviceAddress;
@@ -2707,7 +2710,10 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27072710
ITD->HwTD.Buffer[1].Direction = Direction;
27082711

27092712
/* Setup buffer page 2 with multi (transactions per microframe) */
2710-
ITD->HwTD.Buffer[2].Multi = EndpointProperties->TransactionPerMicroframe;
2713+
ITD->HwTD.Buffer[2].Multi = IsoTransfer->Packets[PacketIndex].PacketLength / EndpointProperties->MaxPacketSize;
2714+
ASSERT(IsoTransfer->Packets[PacketIndex].PacketLength % EndpointProperties->MaxPacketSize == 0);
2715+
ASSERT(ITD->HwTD.Buffer[2].Multi > 0);
2716+
ASSERT(ITD->HwTD.Buffer[2].Multi <= 3);
27112717

27122718
/* Program each packet into a transaction slot */
27132719
for (p = 0; p < PacketsThisITD; p++)
@@ -2824,9 +2830,9 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
28242830
PacketIndex += PacketsThisITD;
28252831
CurrentFrame++;
28262832
ITDCount++;
2833+
InsertTailList(&EhciTransfer->ActiveITDs, &ITD->ActiveITDEntry);
2834+
//DPRINT1("Submitted ITD %p at Frame %u\n", ITD, ITD->ScheduledFrame);
28272835
}
2828-
ASSERT(EhciTransfer->ActiveITD == NULL);
2829-
EhciTransfer->ActiveITD = FirstITD;
28302836
EhciEndpoint->FrameCount += ITDCount;
28312837
EhciTransfer->PendingTDs += ITDCount;
28322838
EhciExtension->PendingTransfers++;
@@ -2866,10 +2872,11 @@ EHCI_AbortIsoTransfer(IN PEHCI_EXTENSION EhciExtension,
28662872
DPRINT("EHCI_AbortIsoTransfer: Aborting high-speed ISO transfer\n");
28672873

28682874
/* Find iTDs belonging to this transfer and abort them */
2869-
while(EhciTransfer->ActiveITD)
2875+
while(!IsListEmpty(&EhciTransfer->ActiveITDs))
28702876
{
28712877
/* grab first */
2872-
ITD = EhciTransfer->ActiveITD;
2878+
PLIST_ENTRY Entry = RemoveHeadList(&EhciTransfer->ActiveITDs);
2879+
ITD = CONTAINING_RECORD(Entry, EHCI_HCD_ITD, ActiveITDEntry);
28732880
/* Found an iTD for this transfer */
28742881
DPRINT("EHCI_AbortIsoTransfer: Aborting iTD %p\n", ITD);
28752882

@@ -3909,8 +3916,9 @@ EHCI_PollIsoEndpoint(IN PEHCI_EXTENSION EhciExtension,
39093916
if (ITD->PacketLength[TransIdx] > 0)
39103917
{
39113918
HasProgrammedTransactions = TRUE;
3912-
if (ITD->HwTD.Transaction[TransIdx].Status &
3913-
(EHCI_TOKEN_STATUS_ACTIVE >> 4))
3919+
3920+
ULONG Status = ITD->HwTD.Transaction[TransIdx].Status;
3921+
if (Status & (1 << 3))
39143922
{
39153923
StillActive = TRUE;
39163924
break;
@@ -3940,6 +3948,7 @@ EHCI_PollEndpoint(IN PVOID ehciExtension,
39403948
{
39413949
PEHCI_EXTENSION EhciExtension = ehciExtension;
39423950
PEHCI_ENDPOINT EhciEndpoint = ehciEndpoint;
3951+
39433952
ULONG TransferType;
39443953

39453954
//DPRINT_EHCI("EHCI_PollEndpoint: EhciEndpoint - %p\n", EhciEndpoint);
@@ -4427,6 +4436,10 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44274436
ITD->TdFlags &= ~EHCI_HCD_ITD_FLAG_ALLOCATED;
44284437
ITD->NextHcdTD = NULL;
44294438
ITD->EhciTransfer = NULL;
4439+
ITD->EhciEndpoint = NULL;
4440+
for(ULONG Index = 0; Index < EHCI_MAX_ITD_TRANSACTIONS; Index++)
4441+
ITD->PacketLength[Index] = 0;
4442+
44304443
EhciEndpoint->RemainITDs++;
44314444

44324445
/* Update per-iTD count */
@@ -4436,10 +4449,10 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44364449
ITD, TotalBytesTransferred, EhciTransfer->PendingTDs);
44374450

44384451
/* Complete the transfer only when ALL iTDs are done */
4439-
if (EhciTransfer->ActiveITD == NULL)
4452+
if (IsListEmpty(&EhciTransfer->ActiveITDs))
44404453
{
4454+
ASSERT(EhciTransfer->PendingTDs == 0);
44414455
EhciExtension->PendingTransfers--;
4442-
ASSERT(EhciTransfer->ActiveITD == NULL);
44434456
DPRINT("EHCI_ProcessCompletedITD: Transfer fully completed, %d total bytes\n",
44444457
EhciTransfer->TransferLen);
44454458

@@ -4462,7 +4475,7 @@ EHCI_UnlinkITDFromFrameList(IN PEHCI_EXTENSION EhciExtension,
44624475
ULONG FrameIndex;
44634476
ULONG TargetPhysicalAddress;
44644477
EHCI_LINK_POINTER CurrentLink;
4465-
PEHCI_HCD_ITD PrevITD, CurrentITD;
4478+
44664479

44674480
HcResourcesVA = EhciExtension->HcResourcesVA;
44684481
FrameIndex = Frame % EHCI_FRAME_LIST_MAX_ENTRIES;
@@ -4481,29 +4494,7 @@ EHCI_UnlinkITDFromFrameList(IN PEHCI_EXTENSION EhciExtension,
44814494
HcResourcesVA->PeriodicFrameList[FrameIndex] = ITD->HwTD.NextLink.AsULONG;
44824495
DPRINT_EHCI("EHCI_UnlinkITDFromFrameList: Unlinked iTD from frame %d head\n", FrameIndex);
44834496
}
4484-
PrevITD = NULL;
4485-
CurrentITD = EhciTransfer->ActiveITD;
4486-
do
4487-
{
4488-
ASSERT(CurrentITD->EhciTransfer == EhciTransfer);
4489-
if (CurrentITD == ITD)
4490-
{
4491-
/* unlink */
4492-
if (PrevITD)
4493-
{
4494-
PrevITD->NextHcdTD = CurrentITD->NextHcdTD;
4495-
}
4496-
else
4497-
{
4498-
EhciTransfer->ActiveITD = CurrentITD->NextHcdTD;
4499-
}
4500-
break;
4501-
}
4502-
PrevITD = CurrentITD;
4503-
CurrentITD = CurrentITD->NextHcdTD;
4504-
} while (CurrentITD != NULL);
4505-
4506-
ASSERT(CurrentITD == ITD);
4497+
RemoveEntryList(&ITD->ActiveITDEntry);
45074498
RtlClearBits(&EhciExtension->IsoBitmap, ITD->ScheduledFrame, 1);
45084499
ITD->NextHcdTD = NULL;
45094500
ITD->EhciTransfer = NULL;

drivers/usb/usbehci/usbehci.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,13 @@ typedef struct _EHCI_HCD_ITD {
107107
struct _EHCI_HCD_ITD * NextHcdTD;
108108
ULONG PacketLength[EHCI_MAX_ITD_TRANSACTIONS];
109109
ULONG PacketStatus[EHCI_MAX_ITD_TRANSACTIONS];
110+
LIST_ENTRY ActiveITDEntry;
110111
LIST_ENTRY DoneLink;
111112
ULONG ScheduledFrame; /* Frame list index where this iTD was inserted */
112113
#ifdef _WIN64
113-
ULONG Pad[23];
114+
ULONG Pad[16];
114115
#else
115-
ULONG Pad[41];
116+
ULONG Pad[23];
116117
#endif
117118
} EHCI_HCD_ITD, *PEHCI_HCD_ITD;
118119
C_ASSERT(sizeof(EHCI_HCD_ITD) == ROUND_UP(sizeof(EHCI_HCD_ITD), 32));
@@ -223,7 +224,7 @@ typedef struct _EHCI_TRANSFER {
223224
ULONG USBDStatus;
224225
ULONG TransferLen;
225226
PEHCI_ENDPOINT EhciEndpoint;
226-
PEHCI_HCD_ITD ActiveITD;
227+
LIST_ENTRY ActiveITDs;
227228
ULONG PendingTDs;
228229
ULONG TransferOnAsyncList;
229230
} EHCI_TRANSFER, *PEHCI_TRANSFER;

drivers/usb/usbport/iso.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ USBPORT_InitializeIsoTransfer(PDEVICE_OBJECT FdoDevice,
6060
ULONG TotalPackets, Idx;
6161
ULONG Period;
6262
BOOLEAN IsHighSpeed;
63-
//PUSBPORT_DEVICE_EXTENSION FdoExtension;
64-
//PUSBPORT_REGISTRATION_PACKET Packet;
63+
PUSBPORT_DEVICE_EXTENSION FdoExtension;
64+
PUSBPORT_REGISTRATION_PACKET Packet;
6565

6666
DPRINT("USBPORT_InitializeIsoTransfer: FdoDevice - %p, Urb - %p Irp - %p\n", FdoDevice, Urb, Transfer->Irp);
6767

@@ -99,15 +99,13 @@ USBPORT_InitializeIsoTransfer(PDEVICE_OBJECT FdoDevice,
9999

100100
IsoBlock->TotalPackets = TotalPackets;
101101
IsoBlock->MappedBuffer = (PVOID)SgTable->MappedSystemVa;
102-
#if 0
103102
if (Urb->TransferFlags & USBD_START_ISO_TRANSFER_ASAP)
104103
{
105104
FdoExtension = FdoDevice->DeviceExtension;
106105
Packet = &FdoExtension->MiniPortInterface->Packet;
107106
Urb->StartFrame = (Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt) + 64) & 0xFFFFFFF0;
108107
DPRINT("Urb StartFrame %u\n", Urb->StartFrame);
109108
}
110-
#endif
111109
/*
112110
* Walk each URB packet descriptor, compute its actual byte length
113111
* from the offset array, resolve the physical scatter/gather mapping,
@@ -274,7 +272,6 @@ USBPORT_CompleteIsoTransfer(IN PVOID MiniPortExtension,
274272
PacketLength = IsoUrb->TransferBufferLength - PacketDescriptor->Offset;
275273
}
276274

277-
278275
if (RemainingLength >= PacketLength)
279276
{
280277
PacketDescriptor->Status = USBD_STATUS_SUCCESS;
@@ -287,8 +284,11 @@ USBPORT_CompleteIsoTransfer(IN PVOID MiniPortExtension,
287284
PacketDescriptor->Status = USBD_STATUS_SUCCESS;
288285
PacketDescriptor->Length = RemainingLength;
289286
CompletedLength += RemainingLength;
290-
RemainingLength = 0;
291-
i++;
287+
if (RemainingLength > 0)
288+
{
289+
RemainingLength = 0;
290+
i++;
291+
}
292292
break;
293293
}
294294
}while(i++ < IsoUrb->NumberOfPackets);

drivers/usb/usbport/urb.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,33 @@ USBPORT_ValidateTransferParametersURB(IN PURB Urb)
637637

638638
DPRINT_URB("USBPORT_ValidateTransferParametersURB: Urb - %p\n", Urb);
639639

640+
if (Urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
641+
{
642+
if (Urb->UrbIsochronousTransfer.TransferBuffer != NULL &&
643+
Urb->UrbIsochronousTransfer.TransferBufferMDL == NULL &&
644+
Urb->UrbIsochronousTransfer.TransferBufferLength != 0)
645+
{
646+
Mdl = IoAllocateMdl(Urb->UrbIsochronousTransfer.TransferBuffer,
647+
Urb->UrbIsochronousTransfer.TransferBufferLength,
648+
FALSE,
649+
FALSE,
650+
NULL);
651+
652+
if (!Mdl)
653+
{
654+
DPRINT1("USBPORT_ValidateTransferParametersURB: Not allocated Mdl\n");
655+
return STATUS_INSUFFICIENT_RESOURCES;
656+
}
657+
658+
MmBuildMdlForNonPagedPool(Mdl);
659+
660+
Urb->UrbIsochronousTransfer.TransferBufferMDL = Mdl;
661+
Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_MDL;
662+
return STATUS_SUCCESS;
663+
}
664+
}
665+
666+
640667
UrbRequest = &Urb->UrbControlTransfer;
641668

642669
if (UrbRequest->TransferBuffer == NULL &&

0 commit comments

Comments
 (0)