[USBEHCI]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 16 Feb 2012 14:49:59 +0000 (14:49 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 16 Feb 2012 14:49:59 +0000 (14:49 +0000)
- Abort pipe when performing sync reset request
- add assert to check for bogus interface descriptors
- use endpoint max packet size when available
- flip data toggle after each transfer
- remove dead code
- use maximum of 4 pages or rest current buffer size when performing a bulk requests
- use nak reload count 3
- perform 1 transaction per frame

svn path=/trunk/; revision=55634

reactos/drivers/usb/usbehci/hub_controller.cpp
reactos/drivers/usb/usbehci/usb_device.cpp
reactos/drivers/usb/usbehci/usb_queue.cpp
reactos/drivers/usb/usbehci/usb_request.cpp

index acde656..7fe6b01 100644 (file)
@@ -1740,7 +1740,7 @@ CHubController::HandleSyncResetAndClearStall(
     //
     if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
     {
-        DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+        DPRINT1("HandleSyncResetAndClearStall invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
 
         //
         // invalid device handle
@@ -1748,6 +1748,19 @@ CHubController::HandleSyncResetAndClearStall(
         return STATUS_DEVICE_NOT_CONNECTED;
     }
 
+    //
+    // abort pipe
+    //
+    Status = HandleAbortPipe(Irp, Urb);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        DPRINT1("[USBEHCI] failed to reset pipe %x\n", Status)
+    }
+
     //
     // get endpoint descriptor
     //
index b75f970..8e1077a 100644 (file)
@@ -819,6 +819,7 @@ CUSBDevice::CreateConfigurationDescriptor(
             //
             // move to next descriptor
             //
+            ASSERT(InterfaceDescriptor->bLength);
             InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
         }
 
index 3c7d4db..3f1348b 100644 (file)
@@ -427,7 +427,7 @@ CUSBQueue::LinkQueueHead(
     //
     // Link the LIST_ENTRYs
     //
-    ASSERT(IsListEmpty(&HeadQueueHead->LinkedQueueHeads));
+    //ASSERT(IsListEmpty(&HeadQueueHead->LinkedQueueHeads));
     InsertTailList(&HeadQueueHead->LinkedQueueHeads, &NewQueueHead->LinkedQueueHeads);
 
     //
@@ -435,7 +435,7 @@ CUSBQueue::LinkQueueHead(
     //
     Entry = NewQueueHead->LinkedQueueHeads.Blink;
     LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
-    ASSERT(LastQueueHead == HeadQueueHead);
+    //ASSERT(LastQueueHead == HeadQueueHead);
     LastQueueHead->HorizontalLinkPointer = (NewQueueHead->PhysicalAddr | QH_TYPE_QH);
 
     //
@@ -443,7 +443,7 @@ CUSBQueue::LinkQueueHead(
     //
     Entry = NewQueueHead->LinkedQueueHeads.Flink;
     NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
-    ASSERT(NextQueueHead == HeadQueueHead);
+    //ASSERT(NextQueueHead == HeadQueueHead);
     NewQueueHead->HorizontalLinkPointer = (NextQueueHead->PhysicalAddr | QH_TYPE_QH);
 
     //
@@ -858,7 +858,6 @@ CUSBQueue::CompleteAsyncRequests()
     KIRQL OldLevel;
     PLIST_ENTRY Entry;
     PQUEUE_HEAD CurrentQH;
-    IUSBRequest *Request;
 
     DPRINT("CUSBQueue::CompleteAsyncRequests\n");
 
@@ -884,11 +883,6 @@ CUSBQueue::CompleteAsyncRequests()
         //
         CurrentQH = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
 
-        //
-        // Get the Request for this QueueHead
-        //
-        Request = (IUSBRequest*) CurrentQH->Request;
-
         //
         // release lock
         //
@@ -937,8 +931,82 @@ CUSBQueue::AbortDevicePipe(
     IN UCHAR DeviceAddress,
     IN PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    KIRQL OldLevel;
+    PLIST_ENTRY Entry;
+    PQUEUE_HEAD QueueHead;
+    LIST_ENTRY ListHead;
+
+    //
+    // lock completed async list
+    //
+    KeAcquireSpinLock(m_Lock, &OldLevel);
+
+    DPRINT1("AbortDevicePipe DeviceAddress %x EndpointDescriptor %p Addr %x\n", DeviceAddress, EndpointDescriptor, EndpointDescriptor->bEndpointAddress);
+
+    //
+    // init list head  
+    //
+    InitializeListHead(&ListHead);
+
+
+    //
+    // walk async list 
+    //
+    ASSERT(AsyncListQueueHead);
+    Entry = AsyncListQueueHead->LinkedQueueHeads.Flink;
+
+    while(Entry != &AsyncListQueueHead->LinkedQueueHeads)
+    {
+        //
+        // get queue head structure
+        //
+        QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+        ASSERT(QueueHead);
+
+        //
+        // move to next entry
+        //
+        Entry = Entry->Flink;
+
+        if (QueueHead->EndPointCharacteristics.DeviceAddress == DeviceAddress &&
+            QueueHead->EndPointCharacteristics.EndPointNumber == (EndpointDescriptor->bEndpointAddress & 0xF) && QueueHead->Token.Bits.Halted)
+        {
+            //
+            // unlink queue head
+            //
+            UnlinkQueueHead(QueueHead);
+
+            //
+            // add to temp list
+            //
+            InsertTailList(&ListHead, &QueueHead->LinkedQueueHeads);
+        }
+    }
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(m_Lock, OldLevel);
+
+    while(!IsListEmpty(&ListHead))
+    {
+        //
+        // remove entry
+        //
+        Entry = RemoveHeadList(&ListHead);
+
+        //
+        // get queue head structure
+        //
+        QueueHead = (PQUEUE_HEAD)CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+        ASSERT(QueueHead);
+
+        //
+        // cleanup queue head
+        //
+        QueueHeadCleanup(QueueHead);
+    }
+    return STATUS_SUCCESS;
 }
 
 
index 46ed3a4..27be373 100644 (file)
@@ -62,11 +62,10 @@ public:
     NTSTATUS BuildSetupPacket();
     NTSTATUS BuildSetupPacketFromURB();
     ULONG InternalCalculateTransferLength();
-    NTSTATUS BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset);
+    NTSTATUS BuildTransferDescriptorChain(IN PQUEUE_HEAD QueueHead, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, IN PQUEUE_TRANSFER_DESCRIPTOR AlternativeDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PUCHAR OutDataToggle, OUT PULONG OutTransferBufferOffset);
     VOID InitDescriptor(IN PQUEUE_TRANSFER_DESCRIPTOR CurrentDescriptor, IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR DataToggle, OUT PULONG OutDescriptorLength);
     VOID DumpQueueHead(IN PQUEUE_HEAD QueueHead);
 
-
     // constructor / destructor
     CUSBRequest(IUnknown *OuterUnknown){}
     virtual ~CUSBRequest(){}
@@ -734,6 +733,7 @@ CUSBRequest::BuildTransferDescriptorChain(
     IN ULONG TransferBufferLength,
     IN UCHAR PidCode,
     IN UCHAR InitialDataToggle,
+    IN  PQUEUE_TRANSFER_DESCRIPTOR AlternativeDescriptor,
     OUT PQUEUE_TRANSFER_DESCRIPTOR * OutFirstDescriptor,
     OUT PQUEUE_TRANSFER_DESCRIPTOR * OutLastDescriptor,
     OUT PUCHAR OutDataToggle,
@@ -742,6 +742,19 @@ CUSBRequest::BuildTransferDescriptorChain(
     PQUEUE_TRANSFER_DESCRIPTOR FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL;
     NTSTATUS Status;
     ULONG DescriptorLength, TransferBufferOffset  = 0;
+    ULONG MaxPacketSize = 0, TransferSize;
+
+    //
+    // is there an endpoint descriptor
+    //
+    if (m_EndpointDescriptor)
+    {
+        //
+        // use endpoint packet size
+        //
+        MaxPacketSize = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
+    }
+
 
     do
     {
@@ -754,8 +767,22 @@ CUSBRequest::BuildTransferDescriptorChain(
             //
             // failed to allocate transfer descriptor
             //
-            ASSERT(FALSE);
-            return Status;
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        if (MaxPacketSize)
+        {
+            //
+            // transfer size is minimum available buffer or endpoint size
+            //
+            TransferSize = min(TransferBufferLength - TransferBufferOffset, MaxPacketSize);
+        }
+        else
+        {
+            //
+            // use available buffer
+            //
+            TransferSize = TransferBufferLength - TransferBufferOffset;
         }
 
         //
@@ -763,7 +790,7 @@ CUSBRequest::BuildTransferDescriptorChain(
         //
         InitDescriptor(CurrentDescriptor, 
                        (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset),
-                       TransferBufferLength - TransferBufferOffset,
+                       TransferSize,
                        PidCode,
                        InitialDataToggle,
                        &DescriptorLength);
@@ -783,9 +810,17 @@ CUSBRequest::BuildTransferDescriptorChain(
             //
             // link to current descriptor
             //
-            LastDescriptor->AlternateNextPointer = CurrentDescriptor->PhysicalAddr;
             LastDescriptor->NextPointer = CurrentDescriptor->PhysicalAddr;
             LastDescriptor = CurrentDescriptor;
+
+            if (AlternativeDescriptor)
+            {
+                //
+                // link to alternative next pointer
+                //
+                LastDescriptor->AlternateNextPointer = AlternativeDescriptor->PhysicalAddr;
+            }
+
         }
         else
         {
@@ -795,6 +830,11 @@ CUSBRequest::BuildTransferDescriptorChain(
             LastDescriptor = FirstDescriptor = CurrentDescriptor;
         }
 
+        //
+        // flip data toggle
+        //
+        InitialDataToggle = !InitialDataToggle;
+
         if(TransferBufferLength == TransferBufferOffset)
         {
             //
@@ -802,6 +842,7 @@ CUSBRequest::BuildTransferDescriptorChain(
             //
             break;
         }
+
     }while(TRUE);
 
     if (OutFirstDescriptor)
@@ -822,11 +863,6 @@ CUSBRequest::BuildTransferDescriptorChain(
 
     if (OutDataToggle)
     {
-        //
-        // flip data toggle
-        //
-        InitialDataToggle = !InitialDataToggle;
-
         //
         // store result data toggle
         //
@@ -918,14 +954,7 @@ CUSBRequest::BuildControlTransferQueueHead(
     //
     QueueHead->EndPointCharacteristics.DeviceAddress = GetDeviceAddress();
 
-    if (m_EndpointDescriptor)
-    {
-        //
-        // set endpoint address and max packet length
-        //
-        QueueHead->EndPointCharacteristics.EndPointNumber = m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0x0F;
-        QueueHead->EndPointCharacteristics.MaximumPacketLength = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
-    }
+    ASSERT(m_EndpointDescriptor == FALSE);
 
     //
     // init setup descriptor
@@ -954,6 +983,7 @@ CUSBRequest::BuildControlTransferQueueHead(
                                               m_TransferBufferLength,
                                               InternalGetPidDirection(),
                                               TRUE,
+                                              NULL,
                                               &FirstDescriptor,
                                               &LastDescriptor,
                                               NULL,
@@ -1136,14 +1166,20 @@ CUSBRequest::BuildBulkTransferQueueHead(
     //
     ASSERT(m_EndpointDescriptor);
 
+    //
+    // use 4 * PAGE_SIZE at max for each new request
+    //
+    ULONG MaxTransferLength = min(4 * PAGE_SIZE, m_TransferBufferLength - m_TransferBufferLengthCompleted);
+
     //
     // build bulk transfer descriptor chain
     //
     Status = BuildTransferDescriptorChain(QueueHead,
                                           Base,
-                                          m_TransferBufferLength - m_TransferBufferLengthCompleted,
+                                          MaxTransferLength,
                                           InternalGetPidDirection(),
                                           m_EndpointDescriptor->DataToggle,
+                                          NULL,
                                           &FirstDescriptor,
                                           &LastDescriptor,
                                           &m_EndpointDescriptor->DataToggle,
@@ -1152,7 +1188,7 @@ CUSBRequest::BuildBulkTransferQueueHead(
     //
     // FIXME: handle errors
     //
-    ASSERT(ChainDescriptorLength == m_TransferBufferLength);
+    //ASSERT(ChainDescriptorLength == m_TransferBufferLength);
 
     //
     // move to next offset
@@ -1279,7 +1315,7 @@ CUSBRequest::CreateQueueHead(
     //
     // Set NakCountReload to max value possible
     //
-    QueueHead->EndPointCharacteristics.NakCountReload = 0xF;
+    QueueHead->EndPointCharacteristics.NakCountReload = 0x3;
 
     //
     // Get the Initial Data Toggle from the QEDT
@@ -1290,7 +1326,7 @@ CUSBRequest::CreateQueueHead(
     // FIXME: check if High Speed Device
     //
     QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
-    QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
+    QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x01;
     QueueHead->Token.DWord = 0;
     QueueHead->Token.Bits.InterruptOnComplete = FALSE;