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…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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