[ros-diffs] [janderwald] 55483: [USBEHCI] - Don't set NumberOfTransaction 0x3 for the async queue head(Haiku doesnt do it too) - Also don't set maximum packet length or interrupt on complete - Stop the async /...

janderwald at svn.reactos.org janderwald at svn.reactos.org
Tue Feb 7 16:18:57 UTC 2012


Author: janderwald
Date: Tue Feb  7 16:18:56 2012
New Revision: 55483

URL: http://svn.reactos.org/svn/reactos?rev=55483&view=rev
Log:
[USBEHCI]
- Don't set NumberOfTransaction 0x3 for the async queue head(Haiku doesnt do it too)
- Also don't set maximum packet length or interrupt on complete
- Stop the async / periodic schedules after acquiring ownership from os (ported from the Pedigree OS)
- Remove unused structs from header 
- Allocate device descriptor from start of a page to prevent alignment issues
- Clear halted bit in the queue overlay transaction layer (usb_queue.cpp:507)
- Always set the alternative and next pointers in BuildControlTransferQueueHead
- Use data the toggle in the transfer requests
- Start using toggle in bulk requests, invert data toggle after each descriptor
- EHCI controller still reports error 0xA / 0xB which is USB Error Interrupt + Frame List Rollover + [USB Interrupt]
- Errors need to be researched more, though the control transfers results appear o.k.
- Tested in real hw + ros stack with USB Mass Storage Device
- Currently hangs after first completed CDB/Data/CSW block

Modified:
    branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp
    branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.h
    branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_device.cpp
    branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_queue.cpp
    branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp

Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp?rev=55483&r1=55482&r2=55483&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] Tue Feb  7 16:18:56 2012
@@ -467,18 +467,15 @@
     //
     m_MemoryManager->Allocate(sizeof(QUEUE_HEAD), (PVOID*)&AsyncQueueHead, &AsyncPhysicalAddress);
 
-    AsyncQueueHead->AlternateNextPointer = TERMINATE_POINTER;
-    AsyncQueueHead->NextPointer = TERMINATE_POINTER;
     AsyncQueueHead->PhysicalAddr = AsyncPhysicalAddress.LowPart;
     AsyncQueueHead->HorizontalLinkPointer = AsyncQueueHead->PhysicalAddr | QH_TYPE_QH;
-    AsyncQueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
-    AsyncQueueHead->Token.Bits.InterruptOnComplete = FALSE;
     AsyncQueueHead->EndPointCharacteristics.HeadOfReclamation = TRUE;
+    AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
     AsyncQueueHead->Token.Bits.Halted = TRUE;
-    AsyncQueueHead->EndPointCharacteristics.MaximumPacketLength = 64;
-    AsyncQueueHead->EndPointCharacteristics.NakCountReload = 0;
-    AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
-    AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
+
+    AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01;
+    AsyncQueueHead->NextPointer = TERMINATE_POINTER;
+    AsyncQueueHead->CurrentLinkPointer = TERMINATE_POINTER;
 
     InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
 
@@ -655,6 +652,39 @@
     }
 
     //
+    // get command register
+    //
+    GetCommandRegister(&UsbCmd);
+
+    //
+    // disable running schedules
+    //
+    UsbCmd.PeriodicEnable = FALSE;
+    UsbCmd.AsyncEnable = FALSE;
+    SetCommandRegister(&UsbCmd);
+
+    //
+    // Wait for execution to start
+    //
+    for (FailSafe = 100; FailSafe > 1; FailSafe--)
+    {
+        KeStallExecutionProcessor(100);
+        UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
+
+        if (!(UsbSts & EHCI_STS_PSS) && (UsbSts & EHCI_STS_ASS))
+        {
+            break;
+        }
+    }
+
+    if ((UsbSts & (EHCI_STS_PSS | EHCI_STS_ASS)))
+    {
+        DPRINT1("Failed to stop running schedules %x\n", UsbSts);
+        ASSERT(FALSE);
+    }
+
+
+    //
     // Stop the controller if its running
     //
     UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
@@ -1240,6 +1270,8 @@
     CStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
 
     CStatus &= (EHCI_ERROR_INT | EHCI_STS_INT | EHCI_STS_IAA | EHCI_STS_PCD | EHCI_STS_FLR);
+    DPRINT1("CStatus %x\n", CStatus);
+
     //
     // Check that it belongs to EHCI
     //
@@ -1307,9 +1339,6 @@
                 // controller reported error
                 //
                 DPRINT1("CStatus %x\n", CStatus);
-                Status = STATUS_UNSUCCESSFUL;
-                PC_ASSERT(FALSE);
-                return;
             }
 
             //

Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.h
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.h?rev=55483&r1=55482&r2=55483&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.h [iso-8859-1] Tue Feb  7 16:18:56 2012
@@ -152,6 +152,8 @@
     ULONG TotalBytesToTransfer;
 } QUEUE_TRANSFER_DESCRIPTOR, *PQUEUE_TRANSFER_DESCRIPTOR;
 
+C_ASSERT(FIELD_OFFSET(QUEUE_TRANSFER_DESCRIPTOR, PhysicalAddr) == 0x20);
+
 //
 // EndPointSpeeds Flags and END_POINT_CHARACTERISTICS
 //
@@ -216,6 +218,9 @@
     LIST_ENTRY LinkedQueueHeads;
     PVOID Request;
 } QUEUE_HEAD, *PQUEUE_HEAD;
+
+C_ASSERT(FIELD_OFFSET(QUEUE_HEAD, PhysicalAddr) == 0x30);
+
 
 //
 // Command register content
@@ -281,30 +286,6 @@
     UCHAR PortRoute [15];
 } EHCI_CAPS, *PEHCI_CAPS;
 
-
-typedef struct
-{
-    PKSPIN_LOCK Lock;
-    RTL_BITMAP Bitmap;
-    PULONG BitmapBuffer;
-    ULONG BlockSize;
-    PVOID VirtualBase;
-    PHYSICAL_ADDRESS PhysicalBase;
-    ULONG Length;
-}DMA_MEMORY_ALLOCATOR, *LPDMA_MEMORY_ALLOCATOR;
-
-typedef struct _EHCI_HOST_CONTROLLER
-{
-    ULONG OpRegisters;
-    EHCI_CAPS ECHICaps;
-    PVOID CommonBufferVA;
-    PHYSICAL_ADDRESS CommonBufferPA;
-    ULONG CommonBufferSize;
-    PQUEUE_HEAD AsyncListQueue;
-    KSPIN_LOCK Lock;
-    LPDMA_MEMORY_ALLOCATOR DmaMemAllocator;
-} EHCI_HOST_CONTROLLER, *PEHCI_HOST_CONTROLLER;
-
 typedef struct
 {
     ULONG PortStatus;

Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_device.cpp
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_device.cpp?rev=55483&r1=55482&r2=55483&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] Tue Feb  7 16:18:56 2012
@@ -617,6 +617,7 @@
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     PMDL Mdl;
     NTSTATUS Status;
+    PVOID Buffer;
 
     //
     // zero descriptor
@@ -633,9 +634,26 @@
     CtrlSetup.bmRequestType.B = 0x80;
 
     //
+    // allocate buffer
+    //
+    Buffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);
+    if (!Buffer)
+    {
+        //
+        // failed to allocate
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // zero buffer
+    //
+    RtlZeroMemory(Buffer, PAGE_SIZE);
+
+    //
     // allocate mdl describing the device descriptor
     //
-    Mdl = IoAllocateMdl(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR), FALSE, FALSE, 0);
+    Mdl = IoAllocateMdl(Buffer, sizeof(USB_DEVICE_DESCRIPTOR), FALSE, FALSE, 0);
     if (!Mdl)
     {
         //
@@ -664,8 +682,14 @@
         //
         // informal dbg print
         //
+        RtlCopyMemory(&m_DeviceDescriptor, Buffer, sizeof(USB_DEVICE_DESCRIPTOR));
         DumpDeviceDescriptor(&m_DeviceDescriptor);
     }
+
+    //
+    // free buffer
+    //
+    ExFreePool(Buffer);
 
     //
     // done

Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_queue.cpp
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_queue.cpp?rev=55483&r1=55482&r2=55483&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] Tue Feb  7 16:18:56 2012
@@ -447,7 +447,7 @@
     //
     // head queue head must be halted
     //
-    PC_ASSERT(HeadQueueHead->Token.Bits.Halted == TRUE);
+    //PC_ASSERT(HeadQueueHead->Token.Bits.Halted == TRUE);
 }
 
 //
@@ -463,7 +463,7 @@
     //
     // sanity check: there must be at least one queue head with halted bit set
     //
-    PC_ASSERT(QueueHead->Token.Bits.Halted == 0);
+    //PC_ASSERT(QueueHead->Token.Bits.Halted == 0);
 
     //
     // get previous link
@@ -499,6 +499,11 @@
     // remove software link
     //
     RemoveEntryList(&QueueHead->LinkedQueueHeads);
+
+    //
+    // FIXME: clear failure 
+    //
+    QueueHead->Token.Bits.Halted = FALSE;
 }
 
 //
@@ -653,7 +658,7 @@
         //
         IsQueueHeadComplete = Request->IsQueueHeadComplete(QueueHead);
 
-        DPRINT("Request %p QueueHead %p Complete %d\n", Request, QueueHead, IsQueueHeadComplete);
+        DPRINT1("Request %p QueueHead %p Complete %d\n", Request, QueueHead, IsQueueHeadComplete);
 
         //
         // check if queue head is complete

Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp?rev=55483&r1=55482&r2=55483&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] (original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] Tue Feb  7 16:18:56 2012
@@ -128,7 +128,7 @@
     //
     // DMA transfer descriptors linked to the queue head
     //
-    PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3];
+    PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[4];
 
     //
     // allocated setup packet from the DMA pool
@@ -690,14 +690,15 @@
         QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->wMaxPacketSize;
     }
 
-    QueueHead->Token.Bits.DataToggle = TRUE;
-
     //
     // setup descriptors
     //
     m_TransferDescriptors[0]->Token.Bits.PIDCode = PID_CODE_SETUP_TOKEN;
     m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer = sizeof(USB_DEFAULT_PIPE_SETUP_PACKET);
     m_TransferDescriptors[0]->Token.Bits.DataToggle = FALSE;
+    m_TransferDescriptors[0]->BufferPointer[0] = (ULONG)PtrToUlong(m_DescriptorSetupPacket.LowPart);
+    m_TransferDescriptors[0]->NextPointer = m_TransferDescriptors[1]->PhysicalAddr;
+    m_TransferDescriptors[0]->AlternateNextPointer = m_TransferDescriptors[1]->PhysicalAddr;
 
     if (m_TransferBufferMDL)
     {
@@ -706,6 +707,9 @@
         //
         m_TransferDescriptors[1]->Token.Bits.PIDCode = PID_CODE_IN_TOKEN;
         m_TransferDescriptors[1]->Token.Bits.TotalBytesToTransfer = m_TransferBufferLength;
+        m_TransferDescriptors[1]->NextPointer = m_TransferDescriptors[2]->PhysicalAddr;
+        m_TransferDescriptors[1]->Token.Bits.DataToggle = TRUE;
+        m_TransferDescriptors[1]->AlternateNextPointer = m_TransferDescriptors[2]->PhysicalAddr;
 
         //
         // FIXME: check if the request spawns over a page -> fill other members
@@ -718,63 +722,69 @@
         //
         m_TransferDescriptors[2]->Token.Bits.PIDCode = PID_CODE_OUT_TOKEN;
         m_TransferDescriptors[2]->Token.Bits.TotalBytesToTransfer = 0;
-
-        //
-        // link descriptors
-        //
-        m_TransferDescriptors[0]->NextPointer = m_TransferDescriptors[1]->PhysicalAddr;
+        m_TransferDescriptors[2]->Token.Bits.DataToggle = FALSE;
 
         //
         // special case, setup alternative next descriptor in case of error
         // HAIKU links to dead descriptor
         //
-        m_TransferDescriptors[0]->AlternateNextPointer = m_TransferDescriptors[2]->PhysicalAddr;
-        m_TransferDescriptors[1]->NextPointer = m_TransferDescriptors[2]->PhysicalAddr;
-        m_TransferDescriptors[1]->AlternateNextPointer = m_TransferDescriptors[2]->PhysicalAddr;
 
         //
         // interrupt on completion
         //
         m_TransferDescriptors[2]->Token.Bits.InterruptOnComplete = TRUE;
 
+	_TransferDescriptors[3]->Token.Bits.Halted = TRUE;
+
     }
     else
     {
         //
         // no buffer, setup in descriptor
         //
-        m_TransferDescriptors[1]->Token.Bits.PIDCode = PID_CODE_OUT_TOKEN;
+        m_TransferDescriptors[1]->Token.Bits.PIDCode = PID_CODE_IN_TOKEN;
         m_TransferDescriptors[1]->Token.Bits.TotalBytesToTransfer = 0;
 
         //
-        // link descriptors
-        //
-        m_TransferDescriptors[0]->NextPointer = m_TransferDescriptors[1]->PhysicalAddr;
-        m_TransferDescriptors[0]->AlternateNextPointer = m_TransferDescriptors[1]->PhysicalAddr;
-
-        //
         // interrupt on completion
         //
         m_TransferDescriptors[1]->Token.Bits.InterruptOnComplete = TRUE;
     }
 
     //
-    // link setup packet into buffer - Physical Address!!!
-    //
-    m_TransferDescriptors[0]->BufferPointer[0] = (ULONG)PtrToUlong(m_DescriptorSetupPacket.LowPart);
-
-    //
     // link transfer descriptors to queue head
     //
     QueueHead->NextPointer = m_TransferDescriptors[0]->PhysicalAddr;
-/*
-	if (m_TransferBufferMDL)
-	    QueueHead->AlternateNextPointer = m_TransferDescriptors[2]->PhysicalAddr;
-	else
-	    QueueHead->AlternateNextPointer = m_TransferDescriptors[1]->PhysicalAddr;
-
-	QueueHead->EndPointCapabilities.InterruptScheduleMask = 0x0;
-*/
+
+    DPRINT("QueueHead %p Addr %x\n", QueueHead, QueueHead->PhysicalAddr);
+    DPRINT("NumDescriptors %lu\n", NumTransferDescriptors);
+    DPRINT("QueueHead AlternateNextPointer %x\n", QueueHead->AlternateNextPointer);
+    DPRINT("QueueHead NextPointer %x\n", QueueHead->NextPointer);
+    DPRINT("m_DescriptorSetupPacket HiPart %x LoPart %x\n", m_DescriptorSetupPacket.HighPart, m_DescriptorSetupPacket.LowPart);
+
+
+    DPRINT("TransferDescriptor 0 Addr %x\n", m_TransferDescriptors[0]->PhysicalAddr);
+    DPRINT("TransferDescriptor 0 Next %x\n", m_TransferDescriptors[0]->NextPointer);
+    DPRINT("TransferDescriptor 0 AlternativeNext %x\n", m_TransferDescriptors[0]->AlternateNextPointer);
+    DPRINT("TransferDescriptor 0 Buffer Pointer %x\n", m_TransferDescriptors[0]->BufferPointer[0]);
+    DPRINT("TransferDescriptor 0 TotalBytesToTransfer 0x%x\n", m_TransferDescriptors[0]->Token.Bits.TotalBytesToTransfer);
+
+    DPRINT("TransferDescriptor 1 Addr %x\n", m_TransferDescriptors[1]->PhysicalAddr);
+    DPRINT("TransferDescriptor 1 Next %x\n", m_TransferDescriptors[1]->NextPointer);
+    DPRINT("TransferDescriptor 1 AlternativeNext %x\n", m_TransferDescriptors[1]->AlternateNextPointer);
+    DPRINT("TransferDescriptor 1 Buffer Pointer %x\n", m_TransferDescriptors[1]->BufferPointer[0]);
+    DPRINT("TransferDescriptor 1 TotalBytesToTransfer 0x%x\n", m_TransferDescriptors[1]->Token.Bits.TotalBytesToTransfer);
+
+    if (NumTransferDescriptors == 3)
+    {
+        DPRINT("TransferDescriptor 2 Addr %x\n", m_TransferDescriptors[2]->PhysicalAddr);
+        DPRINT("TransferDescriptor 2 Next %x\n", m_TransferDescriptors[2]->NextPointer);
+        DPRINT("TransferDescriptor 2 AlternativeNext %x\n", m_TransferDescriptors[2]->AlternateNextPointer);
+        DPRINT("TransferDescriptor 2 Buffer Pointer %x\n", m_TransferDescriptors[2]->BufferPointer[0]);
+        DPRINT("TransferDescriptor 2 TotalBytesToTransfer 0x%x\n", m_TransferDescriptors[2]->Token.Bits.TotalBytesToTransfer);
+    }
+
+
     //
     // store result
     //
@@ -797,6 +807,7 @@
     ULONG BytesAvailable, BufferIndex;
     PVOID Base;
     ULONG PageOffset, CurrentTransferBufferLength;
+    UCHAR DataToggle;
 
     //
     // Allocate the queue head
@@ -867,6 +878,8 @@
     //
     m_TransferBufferLengthCompleted += CurrentTransferBufferLength;
     BytesAvailable = CurrentTransferBufferLength;
+
+    DPRINT1("BuildBulkTransferQueueHead\n");
     DPRINT("CurrentTransferBufferLength %x, m_TransferBufferLengthCompleted %x\n", CurrentTransferBufferLength, m_TransferBufferLengthCompleted);
 
     DPRINT("EndPointAddress %x\n", m_EndpointDescriptor->bEndpointAddress);
@@ -877,6 +890,11 @@
     DPRINT("Irp %p QueueHead %p\n", m_Irp, QueueHead);
 
     //PC_ASSERT(InternalGetPidDirection() == USB_ENDPOINT_DIRECTION_IN(m_EndpointDescriptor->bEndpointAddress));
+
+    //
+    // DataToggle
+    //
+    DataToggle = FALSE;
 
     //
     // Allocated transfer descriptors
@@ -940,7 +958,7 @@
                 //
                 BytesAvailable -= m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
 
-                DPRINT("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                DPRINT1("TransferDescriptor %p Index %lu BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], Index, m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
                     BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
             }
             else
@@ -972,32 +990,35 @@
                     //
                     BytesAvailable -= PAGE_SIZE;
 
-                    DPRINT("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                    DPRINT1("TransferDescriptor %p Index %lu BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], Index, m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
                             BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
                 }
                 else
                 {
                     PC_ASSERT(BytesAvailable);
 
-                    //
-                    // store address
-                    //
-                    m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
-
-                    //
-                    // increment transfer descriptor bytes
-                    //
-                    m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += BytesAvailable;
-
-                    //
-                    // decrement available byte count
-                    //
-                    BytesAvailable -= BytesAvailable;
-
-                    //
-                    // done as this is the last partial or full page
-                    //
-                    DPRINT("TransferDescriptor %p BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
+                    if (BytesAvailable)
+                    {
+                        //
+                        // store address
+                        //
+                        m_TransferDescriptors[Index]->BufferPointer[BufferIndex] = MmGetPhysicalAddress(Base).LowPart;
+
+                       //
+                       // increment transfer descriptor bytes
+                       //
+                       m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer += BytesAvailable;
+
+                       //
+                       // decrement available byte count
+                       //
+                       BytesAvailable -= BytesAvailable;
+
+                       //
+                       // done as this is the last partial or full page
+                       //
+                    }
+                    DPRINT1("TransferDescriptor %p Index %lu BufferPointer %p BufferIndex %lu TotalBytes %lu Remaining %lu\n", m_TransferDescriptors[Index], Index, m_TransferDescriptors[Index]->BufferPointer[BufferIndex],
                             BufferIndex, m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer, BytesAvailable);
 
                     break;
@@ -1010,11 +1031,6 @@
             if (BytesAvailable == 0)
                 break;
         }
-
-        //
-        // store transfer bytes of descriptor
-        //
-        m_TransferDescriptors[Index]->TotalBytesToTransfer = m_TransferDescriptors[Index]->Token.Bits.TotalBytesToTransfer;
 
         //
         // Go ahead and link descriptors
@@ -1024,19 +1040,26 @@
             m_TransferDescriptors[Index - 1]->NextPointer = m_TransferDescriptors[Index]->PhysicalAddr;
         }
 
+
+        //
+        // status descriptor
+        //
+        m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
+
+        //
+        // FIXME: need status descriptor?
+        //
+
         //
         // setup direction
         //
         m_TransferDescriptors[Index]->Token.Bits.PIDCode = InternalGetPidDirection();
 
         //
-        // FIXME: performance penality?
-        //
-        m_TransferDescriptors[Index]->Token.Bits.InterruptOnComplete = TRUE;
-
-        //
-        // FIXME need dead queue transfer descriptor?
-        //
+        // set data toggle
+        //
+        m_TransferDescriptors[Index]->Token.Bits.DataToggle = DataToggle;
+        DataToggle = !DataToggle;
 
         //
         // Check if all bytes have been consumed
@@ -1064,7 +1087,10 @@
         QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->wMaxPacketSize;
     }
 
-    QueueHead->Token.Bits.DataToggle = TRUE;
+    //
+    // store number of transactions
+    //
+    QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = min(Index, 1);
 
     //
     // link descriptor with queue head
@@ -1168,7 +1194,7 @@
     //
     // Get the Initial Data Toggle from the QEDT
     //
-    QueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
+    QueueHead->EndPointCharacteristics.QEDTDataToggleControl = TRUE;
 
     //
     // FIXME: check if High Speed Device
@@ -1593,7 +1619,8 @@
         //
         // queue head is active (currently processed)
         //
-        return FALSE;
+        ASSERT(QueueHead->Token.Bits.Halted == FALSE);
+        //return FALSE;
     }
 
     //
@@ -1609,7 +1636,13 @@
             //
             // check for serious error
             //
-            //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Halted == 0);
+            DPRINT("Descriptor Addr %x\n", m_TransferDescriptors[Index]->PhysicalAddr);
+            DPRINT("Descriptor BabbleDetected %x\n", m_TransferDescriptors[Index]->Token.Bits.BabbleDetected);
+            DPRINT("Descriptor DataBufferError %x\n", m_TransferDescriptors[Index]->Token.Bits.DataBufferError);
+            DPRINT("Descriptor DataToggle %x\n", m_TransferDescriptors[Index]->Token.Bits.DataToggle);
+            DPRINT("Descriptor ErrorCounter %x\n", m_TransferDescriptors[Index]->Token.Bits.ErrorCounter);
+            DPRINT("Descriptor TransactionError %x\n", m_TransferDescriptors[Index]->Token.Bits.TransactionError);
+
 
             //
             // the transfer descriptor should be in the same state as the queue head
@@ -1617,6 +1650,7 @@
             //PC_ASSERT(m_TransferDescriptors[Index]->Token.Bits.Active == 0);
         }
     }
+    //ASSERT(FALSE);
 
     return TRUE;
 }




More information about the Ros-diffs mailing list