@@ -1117,6 +1117,11 @@ EHCI_InitializeSchedule(IN PEHCI_EXTENSION EhciExtension,
11171117
11181118 EhciExtension -> IsoDummyQHListVA = & HcResourcesVA -> IsoDummyQH [0 ];
11191119 EhciExtension -> IsoDummyQHListPA = HcResourcesPA + FIELD_OFFSET (EHCI_HC_RESOURCES , IsoDummyQH [0 ]);
1120+ EhciExtension -> IsoBitmapBuffer = ExAllocatePoolZero (NonPagedPool , EHCI_FRAME_LIST_MAX_ENTRIES * sizeof (UCHAR ), 0x12345678 );
1121+ if (!EhciExtension -> IsoBitmapBuffer )
1122+ return MP_STATUS_NO_RESOURCES ;
1123+
1124+ RtlInitializeBitMap (& EhciExtension -> IsoBitmap , EhciExtension -> IsoBitmapBuffer , EHCI_FRAME_LIST_MAX_ENTRIES );
11201125
11211126 EHCI_AddDummyQHs (EhciExtension );
11221127
@@ -2625,8 +2630,10 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
26252630 ULONG NumITDs ;
26262631 ULONG PacketIndex = 0 ;
26272632 ULONG ITDCount = 0 ;
2633+ ULONG Count = 0 ;
26282634 PEHCI_HCD_ITD ITD ;
26292635 PEHCI_HCD_ITD LastITD = NULL ;
2636+ PEHCI_HCD_ITD FirstITD = NULL ;
26302637 PEHCI_HC_RESOURCES HcResourcesVA ;
26312638 ULONG CurrentFrame ;
26322639 ULONG FrameIndex ;
@@ -2645,8 +2652,17 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
26452652 HcResourcesVA = EhciExtension -> HcResourcesVA ;
26462653
26472654 /* Use the first packet's FrameNumber for scheduling */
2648- CurrentFrame = IsoTransfer -> Packets [0 ].FrameNumber ;
2649- ASSERT (CurrentFrame );
2655+ CurrentFrame = IsoTransfer -> Packets [0 ].FrameNumber % EHCI_FRAME_LIST_MAX_ENTRIES ;
2656+
2657+ CurrentFrame = RtlFindClearBitsAndSet (& EhciExtension -> IsoBitmap , NumITDs , CurrentFrame );
2658+ if (CurrentFrame == (ULONG )- 1 )
2659+ {
2660+ /* no consecutive found */
2661+ DPRINT1 ("EHCI_SubmitIsoTransfer no consecutive gap found\n" );
2662+ return MP_STATUS_NO_RESOURCES ;
2663+ }
2664+ DPRINT ("OriginalFrame %u New FrameNumber %u\n" , IsoTransfer -> Packets [0 ].FrameNumber , CurrentFrame );
2665+
26502666 /* Allocate and program iTDs, one per frame */
26512667 while (PacketIndex < IsoTransfer -> TotalPackets )
26522668 {
@@ -2775,9 +2791,11 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27752791 /* Schedule this iTD in the periodic frame list */
27762792 FrameIndex = CurrentFrame % (EHCI_FRAME_LIST_MAX_ENTRIES );
27772793
2794+ /* link last ITD to dummy qh */
27782795 LinkPointer .AsULONG = HcResourcesVA -> PeriodicFrameList [FrameIndex ];
27792796 ITD -> HwTD .NextLink = LinkPointer ;
27802797
2798+ /* setup frame link */
27812799 LinkPointer .AsULONG = ITD -> PhysicalAddress ;
27822800 LinkPointer .Type = EHCI_LINK_TYPE_iTD ;
27832801 LinkPointer .Terminate = 0 ;
@@ -2787,27 +2805,27 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27872805
27882806 /* Store the frame index in the iTD for unlinking later */
27892807 ITD -> ScheduledFrame = FrameIndex ;
2808+ /* clear next itd software link */
2809+ ITD -> NextHcdTD = NULL ;
27902810
27912811 /* Track which frame this iTD was inserted at */
27922812 if (ITDCount == 0 )
27932813 EhciEndpoint -> StartingFrame = FrameIndex ;
27942814
2795- if (LastITD )
2815+ if (! FirstITD )
27962816 {
2797- LastITD -> NextHcdTD = ITD ;
2817+ FirstITD = ITD ;
27982818 }
2799- else
2819+ if ( LastITD )
28002820 {
2801- /* link in list */
2802- ITD -> NextHcdTD = EhciTransfer -> ActiveITD ;
2803- EhciTransfer -> ActiveITD = ITD ;
2821+ LastITD -> NextHcdTD = ITD ;
28042822 }
28052823 LastITD = ITD ;
28062824 PacketIndex += PacketsThisITD ;
28072825 CurrentFrame ++ ;
28082826 ITDCount ++ ;
28092827 }
2810-
2828+ EhciTransfer -> ActiveITD = FirstITD ;
28112829 EhciEndpoint -> FrameCount += ITDCount ;
28122830 EhciTransfer -> PendingTDs += ITDCount ;
28132831 EhciExtension -> PendingTransfers ++ ;
@@ -2847,9 +2865,10 @@ EHCI_AbortIsoTransfer(IN PEHCI_EXTENSION EhciExtension,
28472865 DPRINT ("EHCI_AbortIsoTransfer: Aborting high-speed ISO transfer\n" );
28482866
28492867 /* Find iTDs belonging to this transfer and abort them */
2850- ITD = EhciTransfer -> ActiveITD ;
2851- while (ITD != NULL )
2868+ while (EhciTransfer -> ActiveITD )
28522869 {
2870+ /* grab first */
2871+ ITD = EhciTransfer -> ActiveITD ;
28532872 /* Found an iTD for this transfer */
28542873 DPRINT ("EHCI_AbortIsoTransfer: Aborting iTD %p\n" , ITD );
28552874
@@ -2876,9 +2895,7 @@ EHCI_AbortIsoTransfer(IN PEHCI_EXTENSION EhciExtension,
28762895 {
28772896 EhciExtension -> PendingTransfers -- ;
28782897 }
2879- /* move to next */
2880- ITD = ITD -> NextHcdTD ;
2881- };
2898+ };
28822899 }
28832900 else
28842901 {
@@ -4416,7 +4433,7 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44164433 ITD , TotalBytesTransferred , EhciTransfer -> PendingTDs );
44174434
44184435 /* Complete the transfer only when ALL iTDs are done */
4419- if (EhciTransfer -> PendingTDs == 0 )
4436+ if (EhciTransfer -> ActiveITD == NULL )
44204437 {
44214438 EhciExtension -> PendingTransfers -- ;
44224439 ASSERT (EhciTransfer -> ActiveITD == NULL );
@@ -4426,7 +4443,7 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44264443 RegPacket .UsbPortCompleteIsoTransfer (EhciExtension ,
44274444 EhciEndpoint ,
44284445 EhciTransfer -> TransferParameters ,
4429- TotalBytesTransferred );
4446+ EhciTransfer -> TransferLen );
44304447 }
44314448 }
44324449}
@@ -4459,44 +4476,29 @@ EHCI_UnlinkITDFromFrameList(IN PEHCI_EXTENSION EhciExtension,
44594476 /* Found the iTD at the head of the frame list */
44604477 HcResourcesVA -> PeriodicFrameList [FrameIndex ] = ITD -> HwTD .NextLink .AsULONG ;
44614478 DPRINT_EHCI ("EHCI_UnlinkITDFromFrameList: Unlinked iTD from frame %d head\n" , FrameIndex );
4479+ EhciTransfer -> ActiveITD = EhciTransfer -> ActiveITD -> NextHcdTD ;
44624480 }
44634481 else
44644482 {
4465- FrameIndex = 0 ;
4483+ PrevITD = EhciTransfer -> ActiveITD ;
4484+ CurrentITD = PrevITD -> NextHcdTD ;
44664485 do
44674486 {
4468- CurrentLink .AsULONG = HcResourcesVA -> PeriodicFrameList [FrameIndex ];
4469- if ((CurrentLink .AsULONG & LINK_POINTER_MASK ) == TargetPhysicalAddress &&
4470- CurrentLink .Type == EHCI_LINK_TYPE_iTD )
4487+ if (CurrentITD == ITD )
44714488 {
4472- HcResourcesVA -> PeriodicFrameList [FrameIndex ] = ITD -> HwTD .NextLink .AsULONG ;
4489+ /* unlink */
4490+ PrevITD -> NextHcdTD = CurrentITD -> NextHcdTD ;
4491+ PrevITD -> HwTD .NextLink = CurrentITD -> HwTD .NextLink ;
44734492 break ;
44744493 }
4475- FrameIndex ++ ;
4476- } while (FrameIndex < EHCI_FRAME_LIST_MAX_ENTRIES );
4477- }
4478- if (!EhciTransfer )
4479- return ;
4480- PrevITD = NULL ;
4481- CurrentITD = EhciTransfer -> ActiveITD ;
4482- ASSERT (CurrentITD );
4483- do
4484- {
4485- if (CurrentITD == ITD )
4486- {
4487- if (PrevITD )
4488- {
4489- PrevITD -> NextHcdTD = ITD -> NextHcdTD ;
4490- }
4491- else
4494+ PrevITD = CurrentITD ;
4495+ if (CurrentITD )
44924496 {
4493- EhciTransfer -> ActiveITD = ITD -> NextHcdTD ;
4497+ CurrentITD = CurrentITD -> NextHcdTD ;
44944498 }
4495- break ;
4496- }
4497- PrevITD = CurrentITD ;
4498- CurrentITD = CurrentITD -> NextHcdTD ;
4499- } while (CurrentITD );
4499+ } while (CurrentITD != NULL );
4500+ }
4501+ RtlClearBits (& EhciExtension -> IsoBitmap , ITD -> ScheduledFrame , 1 );
45004502}
45014503
45024504BOOLEAN
0 commit comments