Author: mjmartin
Date: Wed Apr 20 04:30:22 2011
New Revision: 51407

URL: http://svn.reactos.org/svn/reactos?rev=51407&view=rev
Log:
[USBEHCI_NEW]
hub_controller: 
- Implement  StatusChangeEndpointCallBack called by HardwareDevice class when 
port status has changed on controller.
- Move Status Change Endpoint query code to IQueryStatusChageEndpoint as it is 
also needed by StatusChangeEndpointCallBack.
usb_request: 
- Implement InternalCreateUsbRequest.
usb_queue:
- Implement  CreateUsbRequest and AddUsbRequest
hardware:
- Implement GetAsyncListRegister and GetPeriodicListRegister.
- Implement SetStatusChangeEndpointCallBack for setting callback and context. 
Call the callback when a port status changes.
- Initialize the UsbQueue after creating the AsyncQueueHead, as the UsbQueue 
calls will call back with GetAsyncListRegister.



Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
    branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] Wed 
Apr 20 04:30:22 2011
@@ -12,6 +12,8 @@
 #include "usbehci.h"
 #include "hardware.h"
 
+typedef VOID __stdcall HD_INIT_CALLBACK(IN PVOID CallBackContext);
+
 BOOLEAN
 NTAPI
 InterruptServiceRoutine(
@@ -66,6 +68,10 @@
 
     VOID SetAsyncListRegister(ULONG PhysicalAddress);
     VOID SetPeriodicListRegister(ULONG PhysicalAddress);
+    ULONG GetAsyncListRegister();
+    ULONG GetPeriodicListRegister();
+
+    VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context);
 
     KIRQL AcquireDeviceLock(void);
     VOID ReleaseDeviceLock(KIRQL OldLevel);
@@ -100,7 +106,8 @@
     PQUEUE_HEAD AsyncQueueHead;
     PUSBQUEUE m_UsbQueue;
     PDMAMEMORYMANAGER m_MemoryManager;
-
+    HD_INIT_CALLBACK* m_SCECallBack;
+    PVOID m_SCEContext;
     VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
     VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
     ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset);
@@ -385,16 +392,6 @@
         return Status;
     }
 
-    //
-    // Initialize the UsbQueue now that we have an AdapterObject.
-    //
-    Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Failed to Initialize the UsbQueue\n");
-        return Status;
-    }
-
     // 
     // Create a queuehead for the Async Register
     //
@@ -413,7 +410,19 @@
     AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = 
QH_ENDPOINT_HIGHSPEED;
     AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
 
+    InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
+
     SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
+
+    //
+    // Initialize the UsbQueue now that we have an AdapterObject.
+    //
+    Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to Initialize the UsbQueue\n");
+        return Status;
+    }
 
     //
     // Start the controller
@@ -838,6 +847,26 @@
     EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress);
 }
 
+ULONG
+CUSBHardwareDevice::GetAsyncListRegister()
+{
+    return PhysicalAddress.LowPart;
+}
+
+ULONG CUSBHardwareDevice::GetPeriodicListRegister()
+{
+    UNIMPLEMENTED
+    return NULL;
+}
+
+VOID CUSBHardwareDevice::SetStatusChangeEndpointCallBack(
+    PVOID CallBack,
+    PVOID Context)
+{
+    m_SCECallBack = (HD_INIT_CALLBACK*)CallBack;
+    m_SCEContext = Context;
+}
+
 KIRQL
 CUSBHardwareDevice::AcquireDeviceLock(void)
 {
@@ -937,7 +966,7 @@
                 //
                 // Clear the port change status
                 //
-                This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), 
PortStatus | EHCI_PRT_CONNECTSTATUSCHANGE);
+                //This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), 
PortStatus | EHCI_PRT_CONNECTSTATUSCHANGE);
 
                 if (PortStatus & EHCI_PRT_CONNECTED)
                 {
@@ -964,6 +993,7 @@
                         // FIXME: Is a port reset needed, or does hub driver 
request this?
                         //
                     }
+                    This->m_SCECallBack(This->m_SCEContext);
                 }
                 else
                 {

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] Wed Apr 20 04:30:22 2011
@@ -10,6 +10,9 @@
 
 #define INITGUID
 #include "usbehci.h"
+
+VOID StatusChangeEndpointCallBack(
+    PVOID Context);
 
 class CHubController : public IHubController,
                        public IDispatchIrp
@@ -62,7 +65,8 @@
     NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
-
+    
+    friend VOID StatusChangeEndpointCallBack(PVOID Context);
 
     // constructor / destructor
     CHubController(IUnknown *OuterUnknown){}
@@ -91,6 +95,9 @@
     PULONG m_DeviceAddressBitmapBuffer;
     LIST_ENTRY m_UsbDeviceList;
     PIRP m_PendingSCEIrp;
+
+    //Internal Functions
+    BOOLEAN QueryStatusChageEndpoint(PIRP Irp);
 };
 
 typedef struct
@@ -254,12 +261,72 @@
     }
 
     //
+    // Set the SCE Callback that the Hardware Device will call on port status 
change
+    //
+    
Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, 
this);
+    //
     // clear init flag
     //
     m_HubControllerDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
 
     return STATUS_SUCCESS;
+}
+
+//
+// Queries the ports to see if there has been a device connected or removed.
+//
+BOOLEAN
+CHubController::QueryStatusChageEndpoint(
+    PIRP Irp)
+{
+    ULONG PortCount, PortId;
+    PIO_STACK_LOCATION IoStack;
+    USHORT PortStatus, PortChange;
+    PURB Urb;
+
+    //
+    // get current stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    ASSERT(IoStack);
+
+    //
+    // Get the Urb
+    //
+    Urb = (PURB)IoStack->Parameters.Others.Argument1;
+    ASSERT(Urb);
+
+    //
+    // Get the number of ports and check each one for device connected
+    //
+    m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
+    DPRINT1("SCE Request\n");
+    ((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
+    for (PortId = 0; PortId < PortCount; PortId++)
+    {
+        m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
+
+        DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, 
PortChange);
+
+        //
+        // Loop the ports
+        //
+        if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & 
USB_PORT_STATUS_CONNECT))
+        {
+            DPRINT1("Device is connected on port %d\n", PortId);
+            // Set the value for the port number
+            ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << 
((PortId + 1) & 7);
+        }
+    }
+
+    //
+    // If there were changes then return TRUE
+    //
+    if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
+        return TRUE;
+
+    return FALSE;
 }
 
 
//-----------------------------------------------------------------------------------------
@@ -693,9 +760,6 @@
     IN OUT PIRP Irp, 
     PURB Urb)
 {
-    ULONG PortCount, PortId;
-    USHORT PortStatus, PortChange;
-
     //
     // First check if the request is for the Status Change Endpoint
     //
@@ -703,42 +767,13 @@
     //
     // Is the Request for the root hub
     //
-    if (Urb->UrbHeader.UsbdDeviceHandle==0)
-    {
-        //
-        // There should only be one SCE request pending at a time
-        //
-        ASSERT (m_PendingSCEIrp == NULL);
-
-        //
-        // Get the number of ports and check each one for device connected
-        //
-        m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
-        DPRINT1("SCE Request\n");
-        DPRINT1("PortCount %d\n", PortCount);
-        ((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
-        for (PortId = 0; PortId < PortCount; PortId++)
-        {
-            m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
-
-            DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, 
PortChange);
-
-            //
-            // FIXME: Verify that this is correct.
-            //
-            if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & 
USB_PORT_STATUS_CONNECT))
-            {
-                DPRINT1("Device is connected on port %d\n", PortId);
-                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 
1 << ((PortId + 1) & 7);
-                break;
-            }
-        }
-
-        //
-        // If there were changes then return SUCCESS
-        //
-        if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
+    if (Urb->UrbHeader.UsbdDeviceHandle == 0)
+    {
+        ASSERT(m_PendingSCEIrp == NULL);
+        if (QueryStatusChageEndpoint(Irp))
+        {
             return STATUS_SUCCESS;
+        }
 
         //
         // Else pend the IRP, to be completed when a device connects or 
disconnects.
@@ -747,6 +782,7 @@
         IoMarkIrpPending(Irp);
         return STATUS_PENDING;
     }
+
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
 }
@@ -2843,3 +2879,22 @@
     //
     return STATUS_SUCCESS;
 }
+
+VOID StatusChangeEndpointCallBack(PVOID Context)
+{
+    CHubController* This;
+    PIRP Irp;
+    This = (CHubController*)Context;
+
+    ASSERT(This);
+
+    DPRINT1("SCE Notification!\n");
+    Irp = This->m_PendingSCEIrp;
+    This->m_PendingSCEIrp = NULL;
+
+    This->QueryStatusChageEndpoint(Irp);
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}

Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Wed 
Apr 20 04:30:22 2011
@@ -261,6 +261,30 @@
 // This is the location at which the controller will start executing the 
Periodic Schedule.
 //
     virtual VOID SetPeriodicListRegister(ULONG PhysicalAddress) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// GetAsyncListRegister
+//
+// Description: Returns the memory address used in the Asynchronous Register
+//
+    virtual ULONG GetAsyncListRegister() = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// GetPeriodicListRegister
+//
+// Description: Returns the the memory address used in the Periodic Register
+//
+    virtual ULONG GetPeriodicListRegister() = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// SetStatusChangeEndpointCallBack
+//
+// Description: Used to callback to the hub controller when SCE detected
+//
+    virtual VOID SetStatusChangeEndpointCallBack(PVOID CallBack,PVOID Context) 
= 0;
 
 
//-----------------------------------------------------------------------------------------
 //

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] Wed 
Apr 20 04:30:22 2011
@@ -48,8 +48,8 @@
     LONG m_Ref;
     KSPIN_LOCK m_Lock;
     PDMA_ADAPTER m_Adapter;
-    PQUEUE_HEAD AsyncQueueHead;
-    PQUEUE_HEAD PendingQueueHead;
+    PQUEUE_HEAD AsyncListQueueHead;
+    PQUEUE_HEAD PendingListQueueHead;
 
     VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
     VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead);
@@ -93,6 +93,26 @@
     //
     KeInitializeSpinLock(&m_Lock);
 
+    //
+    // Get the AsyncQueueHead
+    //
+    AsyncListQueueHead = (PQUEUE_HEAD)Hardware->GetAsyncListRegister();
+
+    //
+    // Create the PendingListQueueHead from NONPAGEDPOOL. It will never be 
linked into the Asynclist Schedule
+    //
+    PendingListQueueHead = (PQUEUE_HEAD)ExAllocatePoolWithTag(NonPagedPool, 
sizeof(QUEUE_HEAD), TAG_USBEHCI);
+    if (!PendingListQueueHead)
+    {
+        DPRINT1("Pool Allocation failed!\n");
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // Initialize the List Head
+    //
+    InitializeListHead(&PendingListQueueHead->LinkedQueueHeads);
+
     return Status;
 }
 
@@ -112,31 +132,50 @@
 CUSBQueue::AddUSBRequest(
     IUSBRequest * Request)
 {
+    PQUEUE_HEAD QueueHead;
+    ASSERT(Request != NULL);
+
+    Request->GetQueueHead(&QueueHead);
+
+    //
+    // Add it to the pending list
+    //
+    LinkQueueHead(PendingListQueueHead, QueueHead);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+CUSBQueue::AddUSBRequest(
+    PURB Urb)
+{
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
-CUSBQueue::AddUSBRequest(
-    PURB Urb)
+CUSBQueue::CancelRequests()
 {
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
-CUSBQueue::CancelRequests()
-{
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
 CUSBQueue::CreateUSBRequest(
     IUSBRequest **OutRequest)
 {
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
+    PUSBREQUEST UsbRequest;
+    NTSTATUS Status;
+
+    *OutRequest = NULL;
+    Status = InternalCreateUSBRequest(&UsbRequest);
+    
+    if (NT_SUCCESS(Status))
+    {
+        *OutRequest = UsbRequest;
+    }
+    
+    return Status;
 }
 
 //

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
Wed Apr 20 04:30:22 2011
@@ -934,4 +934,38 @@
         //
         return FALSE;
     }
-}
+}
+
+NTSTATUS
+InternalCreateUSBRequest(
+    PUSBREQUEST *OutRequest)
+{
+    PUSBREQUEST This;
+
+    //
+    // allocate requests
+    //
+    This = new(NonPagedPool, TAG_USBEHCI) CUSBRequest(0);
+    if (!This)
+    {
+        //
+        // failed to allocate
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // add reference count
+    //
+    This->AddRef();
+
+    //
+    // return result
+    //
+    *OutRequest = (PUSBREQUEST)This;
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h?rev=51407&r1=51406&r2=51407&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h [iso-8859-1] Wed Apr 
20 04:30:22 2011
@@ -95,4 +95,9 @@
 //
 NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue);
 
+//
+// usb_request.cpp
+//
+NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest);
+
 #endif


Reply via email to