@@ -2703,6 +2703,7 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27032703 if (PacketsThisITD > PacketsPerITD )
27042704 PacketsThisITD = PacketsPerITD ;
27052705 ASSERT (PacketsThisITD <= 8 );
2706+ ASSERT (PacketsThisITD > 0 );
27062707
27072708 /* Setup buffer page 0 with device/endpoint info */
27082709 ITD -> HwTD .Buffer [0 ].DeviceAddress = DeviceAddress ;
@@ -2718,6 +2719,9 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27182719 ASSERT (ITD -> HwTD .Buffer [2 ].Multi > 0 );
27192720 ASSERT (ITD -> HwTD .Buffer [2 ].Multi <= 3 );
27202721
2722+ // store number of packets
2723+ ITD -> PacketsThisITD = PacketsThisITD ;
2724+
27212725 /* Program each packet into a transaction slot */
27222726 for (p = 0 ; p < PacketsThisITD ; p ++ )
27232727 {
@@ -2727,6 +2731,9 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27272731 ULONG Offset ;
27282732 ULONG ThisPageSelect ;
27292733
2734+ /* store USBPORT iso packet ref*/
2735+ ITD -> IsoPacket [p ] = Packet ;
2736+
27302737 /* Determine microframe slot: for period=1, slots 0,1,2,...7 */
27312738 MicroFrame = p * Period ;
27322739
@@ -2792,7 +2799,7 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
27922799 ITD -> HwTD .Transaction [MicroFrame ].xOffset = Offset ;
27932800 ITD -> HwTD .Transaction [MicroFrame ].PageSelect = ThisPageSelect ;
27942801 ITD -> HwTD .Transaction [MicroFrame ].xLength = Packet -> PacketLength ;
2795- ITD -> HwTD .Transaction [MicroFrame ].Status = EHCI_TOKEN_STATUS_ACTIVE >> 4 ;
2802+ ITD -> HwTD .Transaction [MicroFrame ].Status = 1 << 3 ;
27962803
27972804 /* Set IOC on the last transaction of the last iTD */
27982805 if (p == PacketsThisITD - 1 )
@@ -2823,22 +2830,11 @@ EHCI_SubmitIsoTransfer(IN PVOID ehciExtension,
28232830 KeMemoryBarrier ();
28242831 /* Store the frame index in the iTD for unlinking later */
28252832 ITD -> ScheduledFrame = FrameIndex ;
2826- /* clear next itd software link */
2827- ITD -> NextHcdTD = NULL ;
28282833
28292834 /* Track which frame this iTD was inserted at */
28302835 if (ITDCount == 0 )
28312836 EhciEndpoint -> StartingFrame = FrameIndex ;
28322837
2833- if (!FirstITD )
2834- {
2835- FirstITD = ITD ;
2836- }
2837- if (LastITD )
2838- {
2839- LastITD -> NextHcdTD = ITD ;
2840- }
2841- LastITD = ITD ;
28422838 PacketIndex += PacketsThisITD ;
28432839 CurrentFrame ++ ;
28442840 ITDCount ++ ;
@@ -3917,18 +3913,18 @@ EHCI_PollIsoEndpoint(IN PEHCI_EXTENSION EhciExtension,
39173913 ITD = (PEHCI_HCD_ITD )((ULONG_PTR )ITD + Size );
39183914 continue ;
39193915 }
3920-
3916+ KeMemoryBarrier ();
39213917 /* Check if any initialized transaction in this iTD is still active.
39223918 * Also verify at least one transaction was programmed to avoid
39233919 * false-completing an allocated but not-yet-programmed iTD. */
39243920 StillActive = FALSE;
39253921 BOOLEAN HasProgrammedTransactions = FALSE;
3926- for (TransIdx = 0 ; TransIdx < EHCI_MAX_ITD_TRANSACTIONS ; TransIdx ++ )
3922+ ASSERT (ITD -> PacketsThisITD );
3923+ for (TransIdx = 0 ; TransIdx < ITD -> PacketsThisITD ; TransIdx ++ )
39273924 {
39283925 if (ITD -> PacketLength [TransIdx ] > 0 )
39293926 {
39303927 HasProgrammedTransactions = TRUE;
3931-
39323928 ULONG Status = ITD -> HwTD .Transaction [TransIdx ].Status ;
39333929 if (Status & (1 << 3 ))
39343930 {
@@ -3937,7 +3933,7 @@ EHCI_PollIsoEndpoint(IN PEHCI_EXTENSION EhciExtension,
39373933 }
39383934 }
39393935 }
3940-
3936+ KeMemoryBarrier ();
39413937 if (HasProgrammedTransactions && !StillActive )
39423938 {
39433939 /* All programmed transactions completed, process this iTD */
@@ -4397,8 +4393,12 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
43974393 if (!EhciTransfer || !EhciEndpoint )
43984394 return ;
43994395
4396+ /* make sure we are in sync */
4397+ KeMemoryBarrier ();
4398+
44004399 /* Check all transactions in the iTD */
4401- for (TransactionIndex = 0 ; TransactionIndex < EHCI_MAX_ITD_TRANSACTIONS ; TransactionIndex ++ )
4400+ ASSERT (ITD -> PacketsThisITD );
4401+ for (TransactionIndex = 0 ; TransactionIndex < ITD -> PacketsThisITD ; TransactionIndex ++ )
44024402 {
44034403 /* Use PacketLength[] (original programmed length) to detect used transactions.
44044404 * The hardware xLength field contains REMAINING bytes after transfer, so a
@@ -4408,7 +4408,7 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44084408 {
44094409 ULONG Status = ITD -> HwTD .Transaction [TransactionIndex ].Status ;
44104410 ULONG Remaining = ITD -> HwTD .Transaction [TransactionIndex ].xLength ;
4411-
4411+ ULONG Completed ;
44124412 if ((Status & (1 << 3 ))) //EHCI_TOKEN_STATUS_ACTIVE >> 4))
44134413 {
44144414 /* Transaction still active, not complete yet */
@@ -4421,20 +4421,27 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44214421 ASSERT ((Status & (1 << 1 )) == 0 );
44224422
44234423 /* Transaction completed - bytes transferred = programmed - remaining */
4424- TotalBytesTransferred += ITD -> PacketLength [TransactionIndex ] - Remaining ;
4424+ Completed = ITD -> PacketLength [TransactionIndex ] - Remaining ;
4425+ TotalBytesTransferred += Completed ;
44254426
44264427 /* Check for errors (bit 2 = Transaction Error in 4-bit status) */
44274428 if (Status & 0x04 )
44284429 {
44294430 DPRINT1 ("EHCI_ProcessCompletedITD: Transaction %d error, status 0x%x\n" ,
44304431 TransactionIndex , Status );
44314432 EhciTransfer -> USBDStatus = USBD_STATUS_XACT_ERROR ;
4433+ ITD -> IsoPacket [TransactionIndex ]-> CompletionStatus = USBD_STATUS_XACT_ERROR ;
4434+ }
4435+ else
4436+ {
4437+ ITD -> IsoPacket [TransactionIndex ]-> CompletionStatus = USBD_STATUS_SUCCESS ;
4438+ ITD -> IsoPacket [TransactionIndex ]-> BytesTransferred = Completed ;
44324439 }
4433-
44344440 ITD -> PacketStatus [TransactionIndex ] = Status ;
44354441 }
44364442 }
44374443 }
4444+ KeMemoryBarrier ();
44384445
44394446 if (TransferComplete )
44404447 {
@@ -4443,14 +4450,15 @@ EHCI_ProcessCompletedITD(IN PEHCI_EXTENSION EhciExtension,
44434450
44444451 /* Remove iTD from frame list */
44454452 EHCI_UnlinkITDFromFrameList (EhciExtension , ITD , ITD -> ScheduledFrame , EhciTransfer );
4446-
4447- /* Mark iTD as free */
4448- ITD -> TdFlags &= ~EHCI_HCD_ITD_FLAG_ALLOCATED ;
4449- ITD -> NextHcdTD = NULL ;
44504453 ITD -> EhciTransfer = NULL ;
44514454 ITD -> EhciEndpoint = NULL ;
44524455 for (ULONG Index = 0 ; Index < EHCI_MAX_ITD_TRANSACTIONS ; Index ++ )
4456+ {
44534457 ITD -> PacketLength [Index ] = 0 ;
4458+ ITD -> IsoPacket [Index ] = NULL ;
4459+ }
4460+ /* Mark iTD as free */
4461+ ITD -> TdFlags &= ~EHCI_HCD_ITD_FLAG_ALLOCATED ;
44544462
44554463 EhciEndpoint -> RemainITDs ++ ;
44564464
@@ -4508,9 +4516,13 @@ EHCI_UnlinkITDFromFrameList(IN PEHCI_EXTENSION EhciExtension,
45084516 DPRINT_EHCI ("EHCI_UnlinkITDFromFrameList: Unlinked iTD from frame %d head\n" , FrameIndex );
45094517 KeMemoryBarrier ();
45104518 }
4519+ else
4520+ {
4521+ // LINKING ERROR
4522+ ASSERT (FALSE);
4523+ }
45114524 RemoveEntryList (& ITD -> ActiveITDEntry );
45124525 RtlClearBits (& EhciExtension -> IsoBitmap , ITD -> ScheduledFrame , 1 );
4513- ITD -> NextHcdTD = NULL ;
45144526 ITD -> EhciTransfer = NULL ;
45154527}
45164528
0 commit comments