Author: janderwald
Date: Tue May 24 17:57:00 2011
New Revision: 51888

URL: http://svn.reactos.org/svn/reactos?rev=51888&view=rev
Log:
[USBOHCI]
- Add sanity checks
- Preserve  command status value when notifying the hc that a control / bulk 
endpoint was added
- Re-enable root hub notification interrupt when reset port has been completed
- Dispatch processing to USBQeueu when DoneHead event arrives
- Scan endpoints to find the logical endpoint which was completed by the 
hardware
- Signal completion to IUSBRequest by calling CompletionCallback
- Create a final transfer descriptor which is linked to the endpoint descriptor
- Control transfers now appear to be working (Device retrieves device 
descriptor / configuration descriptor and succeeds in setting device address)
- Configuration parsing code needs more work now (currently fails there due to 
invalid / unexpected configuration descriptor from device)

Modified:
    branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
    branches/usb-bringup/drivers/usb/usbohci/hardware.h
    branches/usb-bringup/drivers/usb/usbohci/interfaces.h
    branches/usb-bringup/drivers/usb/usbohci/usb_device.cpp
    branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
    branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.cpp?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Tue May 
24 17:57:00 2011
@@ -540,6 +540,7 @@
     // assert that the controller has been started
     //
     ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == 
OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
+    ASSERT((Control & OHCI_ENABLE_LIST) == OHCI_ENABLE_LIST);
 
     //
     // get frame interval
@@ -689,20 +690,30 @@
 CUSBHardwareDevice::HeadEndpointDescriptorModified(
     ULONG Type)
 {
+    ULONG Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET));
+
     if (Type == USB_ENDPOINT_TYPE_CONTROL)
     {
         //
         // notify controller
         //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET), OHCI_CONTROL_LIST_FILLED);
+        //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_CONTROL_HEAD_ED_OFFSET), 
m_ControlEndpointDescriptor->NextPhysicalEndpoint);
+        //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_CONTROL_CURRENT_ED_OFFSET), 
m_ControlEndpointDescriptor->NextPhysicalEndpoint);
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_CONTROL_LIST_FILLED);
     }
     else if (Type == USB_ENDPOINT_TYPE_BULK)
     {
         //
         // notify controller
         //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET), OHCI_BULK_LIST_FILLED);
-    }
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_BULK_LIST_FILLED);
+    }
+
+    Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_COMMAND_STATUS_OFFSET));
+
+
+    DPRINT1("HeadEndpointDescriptorModified Value %x Type %x\n", Value, Type);
+
 }
 
 NTSTATUS
@@ -1035,7 +1046,9 @@
         //
         // re-enable root hub change
         //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
+        Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET));
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), Value | OHCI_ROOT_HUB_STATUS_CHANGE);
+
     }
 
     if (Status == C_PORT_CONNECTION)
@@ -1231,11 +1244,6 @@
      {
          //
          // head completed
-         //
-         DPRINT1("InterruptServiceRoutine> Done Head completion\n");
-         ASSERT(FALSE);
-         //
-         // FIXME: handle event
          //
          Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
     }
@@ -1307,6 +1315,8 @@
 {
     CUSBHardwareDevice *This;
     ULONG CStatus, Index, PortStatus;
+    POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+    ULONG DoneHead;
 
     //
     // get parameters
@@ -1314,6 +1324,25 @@
     This = (CUSBHardwareDevice*) SystemArgument1;
     CStatus = (ULONG) SystemArgument2;
 
+       DPRINT1("OhciDefferedRoutine Status %x\n", CStatus);
+
+    if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
+    {
+        //
+        // descriptor completion, get done head
+        //
+        DoneHead = This->m_HCCA->DoneHead;
+
+        //
+        // clear out lower bits, ed are 16 byte aligned
+        //
+        DoneHead &= ~0xF;
+
+        //
+        // notify queue of event
+        //
+        This->m_UsbQueue->TransferDescriptorCompletionCallback(DoneHead);
+    }
     if (CStatus & OHCI_ROOT_HUB_STATUS_CHANGE)
     {
         //

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.h?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] Tue May 24 
17:57:00 2011
@@ -202,8 +202,9 @@
 
     // Software part
     PHYSICAL_ADDRESS  PhysicalAddress;
+    PVOID HeadLogicalDescriptor;
+    PVOID NextDescriptor;
     PVOID Request;
-    PVOID NextDescriptor;
 }OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
 
 
@@ -238,9 +239,9 @@
     ULONG LastPhysicalByteAddress; // Physical pointer to buffer end
     // Software part
     PHYSICAL_ADDRESS  PhysicalAddress;           // Physical address of this 
descriptor
+    PVOID NextLogicalDescriptor;
     ULONG  BufferSize;                // Size of the buffer
     PVOID    BufferLogical;            // Logical pointer to the buffer
-    PVOID  Request;                   // pointer to IUSBRequest
 }OHCI_GENERAL_TD, *POHCI_GENERAL_TD;
 
 

Modified: branches/usb-bringup/drivers/usb/usbohci/interfaces.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/interfaces.h?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/interfaces.h [iso-8859-1] Tue May 
24 17:57:00 2011
@@ -436,6 +436,13 @@
 
     virtual BOOLEAN IsRequestInitialized() = 0;
 
+//-----------------------------------------------------------------------------------------
+//
+// CompletionCallback
+//
+// Description: notifies request that the endpoint descriptor is complete
+
+    virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * 
OutDescriptor) = 0;
 };
 
 
@@ -495,6 +502,14 @@
 // Description: creates an usb request
 
     virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// TransferDescriptorCompletionCallback
+//
+// Description: notifies the queue that a transfer was completed
+
+    virtual VOID TransferDescriptorCompletionCallback(ULONG 
TransferDescriptorLogicalAddress) = 0;
 
 };
 

Modified: branches/usb-bringup/drivers/usb/usbohci/usb_device.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usb_device.cpp?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] Tue 
May 24 17:57:00 2011
@@ -707,6 +707,11 @@
     }
 
     //
+    // zero buffer
+    //
+    RtlZeroMemory(Buffer, PAGE_SIZE);
+
+    //
     // build setup packet
     //
     CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;

Modified: branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_queue.cpp [iso-8859-1] Tue May 
24 17:57:00 2011
@@ -33,11 +33,17 @@
         return m_Ref;
     }
 
+    // com
     virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER 
AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock);
     virtual ULONG GetPendingRequestCount();
     virtual NTSTATUS AddUSBRequest(IUSBRequest * Request);
     virtual NTSTATUS CancelRequests();
     virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
+    virtual VOID TransferDescriptorCompletionCallback(ULONG 
TransferDescriptorLogicalAddress);
+
+    // local functions
+    BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
+    NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR 
EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT 
POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR 
*OutPreviousEndpointDescriptor);
 
     // constructor / destructor
     CUSBQueue(IUnknown *OuterUnknown){}
@@ -218,13 +224,14 @@
     // set descriptor active
     //
     Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
+    //HeadDescriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
 
     //
     // notify hardware of our request
     //
     m_Hardware->HeadEndpointDescriptorModified(Type);
 
-    DPRINT1("Request added to queue\n");
+    DPRINT1("Request %x %x added to queue\n", Descriptor, 
Descriptor->PhysicalAddress);
 
 
     return STATUS_SUCCESS;
@@ -255,6 +262,142 @@
     return Status;
 }
 
+NTSTATUS
+CUSBQueue::FindTransferDescriptorInEndpoint(
+    IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+    IN ULONG TransferDescriptorLogicalAddress,
+    OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor,
+    OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor)
+{
+    POHCI_ENDPOINT_DESCRIPTOR LastDescriptor = EndpointDescriptor;
+
+
+    //
+    // skip first endpoint head
+    //
+    EndpointDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
+
+    while(EndpointDescriptor)
+    {
+        //
+        // check if the transfer descriptor is inside the list
+        //
+        if (IsTransferDescriptorInEndpoint(EndpointDescriptor, 
TransferDescriptorLogicalAddress))
+        {
+            //
+            // found endpoint
+            //
+            *OutEndpointDescriptor = EndpointDescriptor;
+            *OutPreviousEndpointDescriptor = LastDescriptor;
+
+            //
+            // done
+            //
+            return STATUS_SUCCESS;
+        }
+
+        //
+        // store last endpoint
+        //
+        LastDescriptor = EndpointDescriptor;
+
+        //
+        // move to next
+        //
+        EndpointDescriptor = 
(POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
+    }
+
+    //
+    // failed to endpoint
+    //
+    return STATUS_NOT_FOUND;
+}
+
+
+BOOLEAN
+CUSBQueue::IsTransferDescriptorInEndpoint(
+    IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+    IN ULONG TransferDescriptorLogicalAddress)
+{
+    POHCI_GENERAL_TD Descriptor;
+
+    //
+    // get first general transfer descriptor
+    //
+    Descriptor = (POHCI_GENERAL_TD)EndpointDescriptor->HeadLogicalDescriptor;
+
+    //
+    // sanity check
+    //
+    ASSERT(Descriptor);
+
+    do
+    {
+        if (Descriptor->PhysicalAddress.LowPart == 
TransferDescriptorLogicalAddress)
+        {
+            //
+            // found descriptor
+            //
+            return TRUE;
+        }
+
+        //
+        // move to next
+        //
+        Descriptor = (POHCI_GENERAL_TD)Descriptor->NextLogicalDescriptor;
+    }while(Descriptor);
+
+
+    //
+    // no descriptor found
+    //
+    return FALSE;
+}
+
+
+VOID
+CUSBQueue::TransferDescriptorCompletionCallback(
+    ULONG TransferDescriptorLogicalAddress)
+{
+    POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
+    NTSTATUS Status;
+    PUSBREQUEST Request;
+
+    //
+    // find transfer descriptor in control list
+    //
+    Status = FindTransferDescriptorInEndpoint(m_ControlHeadEndpointDescriptor, 
TransferDescriptorLogicalAddress, &EndpointDescriptor, 
&PreviousEndpointDescriptor);
+    if (NT_SUCCESS(Status))
+    {
+        //
+        // FIXME: make sure this is ok
+        // unlink descriptor
+        //
+        PreviousEndpointDescriptor->NextDescriptor = 
EndpointDescriptor->NextDescriptor;
+        PreviousEndpointDescriptor->NextPhysicalEndpoint = 
EndpointDescriptor->NextPhysicalEndpoint;
+
+        //
+        // get corresponding request
+        //
+        Request = PUSBREQUEST(EndpointDescriptor->Request);
+
+        //
+        // notify of completion
+        //
+        Request->CompletionCallback(EndpointDescriptor);
+
+        //
+        // FIXME: check if complete
+        //
+
+        //
+        // release request
+        //
+        Request->Release();
+    }
+
+}
+
 
 NTSTATUS
 CreateUSBQueue(

Modified: branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp?rev=51888&r1=51887&r2=51888&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/usb_request.cpp [iso-8859-1] Tue 
May 24 17:57:00 2011
@@ -44,7 +44,7 @@
     virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT 
OPTIONAL PULONG UrbStatusCode);
     virtual BOOLEAN IsRequestInitialized();
     virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
-
+    virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * 
OutDescriptor);
 
     // local functions
     ULONG InternalGetTransferType();
@@ -635,7 +635,7 @@
 CUSBRequest::BuildControlTransferDescriptor(
     POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
 {
-    POHCI_GENERAL_TD SetupDescriptor, StatusDescriptor, DataDescriptor = NULL;
+    POHCI_GENERAL_TD SetupDescriptor, StatusDescriptor, DataDescriptor = NULL, 
LastDescriptor;
     POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
     NTSTATUS Status;
 
@@ -680,6 +680,22 @@
         return Status;
     }
 
+    //
+    // finally create the last descriptor
+    //
+    Status = CreateGeneralTransferDescriptor(&LastDescriptor, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to create status descriptor
+        //
+        FreeDescriptor(SetupDescriptor);
+        FreeDescriptor(StatusDescriptor);
+        m_DmaManager->Release(EndpointDescriptor, 
sizeof(OHCI_ENDPOINT_DESCRIPTOR));
+        return Status;
+    }
+
+
     if (m_TransferBufferLength)
     {
         //
@@ -690,7 +706,7 @@
         //
         // now create the data descriptor
         //
-        Status = CreateGeneralTransferDescriptor(&DataDescriptor, 0);
+        Status = CreateGeneralTransferDescriptor(&DataDescriptor, 
m_TransferBufferLength);
         if (!NT_SUCCESS(Status))
         {
             //
@@ -699,6 +715,7 @@
             m_DmaManager->Release(EndpointDescriptor, 
sizeof(OHCI_ENDPOINT_DESCRIPTOR));
             FreeDescriptor(SetupDescriptor);
             FreeDescriptor(StatusDescriptor);
+            FreeDescriptor(LastDescriptor);
             return Status;
         }
 
@@ -762,11 +779,20 @@
          // link setup descriptor to data descriptor
          //
          SetupDescriptor->NextPhysicalDescriptor = 
DataDescriptor->PhysicalAddress.LowPart;
-
-         //
-         // FIXME: should link to last data descriptor to status descriptor
+         SetupDescriptor->NextLogicalDescriptor = DataDescriptor;
+
+         //
+         // link data descriptor to status descriptor
+         // FIXME: check if there are more data descriptors
          //
          DataDescriptor->NextPhysicalDescriptor = 
StatusDescriptor->PhysicalAddress.LowPart;
+         DataDescriptor->NextLogicalDescriptor = StatusDescriptor;
+
+         //
+         // link status descriptor to last descriptor
+         //
+         StatusDescriptor->NextPhysicalDescriptor = 
LastDescriptor->PhysicalAddress.LowPart;
+         StatusDescriptor->NextLogicalDescriptor = LastDescriptor;
     }
     else
     {
@@ -774,14 +800,21 @@
          // link setup descriptor to status descriptor
          //
          SetupDescriptor->NextPhysicalDescriptor = 
StatusDescriptor->PhysicalAddress.LowPart;
+         SetupDescriptor->NextLogicalDescriptor = StatusDescriptor;
+
+         //
+         // link status descriptor to last descriptor
+         //
+         StatusDescriptor->NextPhysicalDescriptor = 
LastDescriptor->PhysicalAddress.LowPart;
+         StatusDescriptor->NextLogicalDescriptor = LastDescriptor;
     }
 
     //
     // now link descriptor to endpoint
     //
     EndpointDescriptor->HeadPhysicalDescriptor = 
SetupDescriptor->PhysicalAddress.LowPart;
-    EndpointDescriptor->TailPhysicalDescriptor = 
SetupDescriptor->PhysicalAddress.LowPart;
-    DPRINT1("CUSBRequest::BuildControlTransferDescriptor done\n");
+    EndpointDescriptor->TailPhysicalDescriptor = 
LastDescriptor->PhysicalAddress.LowPart;
+    EndpointDescriptor->HeadLogicalDescriptor = SetupDescriptor;
 
     //
     // store result
@@ -887,6 +920,32 @@
 }
 
 
+VOID
+CUSBRequest::CompletionCallback(
+    struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
+{
+    DPRINT1("CUSBRequest::CompletionCallback\n");
+
+    //
+    // set status code
+    //
+    m_NtStatusCode = STATUS_SUCCESS;
+    m_UrbStatusCode = USBD_STATUS_SUCCESS;
+
+    ASSERT(!m_Irp);
+
+    //
+    // FIXME: cleanup descriptors
+    //
+
+    //
+    // signal completion event
+    //
+    PC_ASSERT(m_CompletionEvent);
+    KeSetEvent(m_CompletionEvent, 0, FALSE);
+}
+
+
 
//-----------------------------------------------------------------------------------------
 BOOLEAN
 CUSBRequest::IsRequestInitialized()


Reply via email to