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