Author: mjmartin
Date: Tue Apr 19 06:56:30 2011
New Revision: 51397
URL:
http://svn.reactos.org/svn/reactos?rev=51397&view=rev
Log:
[USBEHCI_NEW]
- Move USB_REQUEST_SET_FEATURE / USB_REQUEST_GET_FEATURE flags to header file.
- Remove QueueHead and Descriptor creation as its in UsbRequest.
- Move DMACommon Buffer allocation back to UsbHardwareDevice class.
- Implement Port Handling functions GetPortStatus, ClearPortStatus and SetPortFeature.
- Implement GetUSBQueue for returning pointer to UsbQueue and GetDMA to return
DMAMemoryManager.
- Fix a typo in one of the defines for Port Register Flags.
Modified:
branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
branches/usb-bringup/drivers/usb/usbehci_new/hardware.h
branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.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] Tue Apr 19
06:56:30 2011
@@ -52,13 +52,17 @@
NTSTATUS PnpStop(void);
NTSTATUS HandlePower(PIRP Irp);
NTSTATUS GetDeviceDetails(PUSHORT VendorId, PUSHORT DeviceId, PULONG NumberOfPorts,
PULONG Speed);
- NTSTATUS GetDmaAdapter(OUT PDMA_ADAPTER AdapterObject);
+ NTSTATUS GetDMA(OUT struct IDMAMemoryManager **m_DmaManager);
NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue);
NTSTATUS StartController();
NTSTATUS StopController();
NTSTATUS ResetController();
NTSTATUS ResetPort(ULONG PortIndex);
+
+ NTSTATUS GetPortStatus(ULONG PortId, OUT USHORT *PortStatus, OUT USHORT
*PortChange);
+ NTSTATUS ClearPortStatus(ULONG PortId, ULONG Status);
+ NTSTATUS SetPortFeature(ULONG PortId, ULONG Feature);
VOID SetAsyncListRegister(ULONG PhysicalAddress);
VOID SetPeriodicListRegister(ULONG PhysicalAddress);
@@ -85,6 +89,8 @@
KSPIN_LOCK m_Lock;
PKINTERRUPT m_Interrupt;
KDPC m_IntDpcObject;
+ PVOID VirtualBase;
+ PHYSICAL_ADDRESS PhysicalAddress;
PULONG m_Base;
PDMA_ADAPTER m_Adapter;
ULONG m_MapRegisters;
@@ -92,7 +98,7 @@
USHORT m_VendorID;
USHORT m_DeviceID;
PUSBQUEUE m_UsbQueue;
-
+ PDMAMEMORYMANAGER m_MemoryManager;
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset);
@@ -133,12 +139,32 @@
DPRINT1("CUSBHardwareDevice::Initialize\n");
//
+ // Create DMAMemoryManager for use with QueueHeads and Transfer Descriptors.
+ //
+ Status = CreateDMAMemoryManager(&m_MemoryManager);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create DMAMemoryManager Object\n");
+ return Status;
+ }
+
+ //
// Create the UsbQueue class that will handle the Asynchronous and Periodic
Schedules
//
Status = CreateUSBQueue(&m_UsbQueue);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create UsbQueue!\n");
+ return Status;
+ }
+
+ //
+ // Initialize the DMAMemoryManager
+ //
+ Status = m_MemoryManager->Initialize(this, &m_Lock, PAGE_SIZE * 4,
VirtualBase, PhysicalAddress, 32);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to initialize the DMAMemoryManager\n");
return Status;
}
@@ -337,6 +363,19 @@
}
//
+ // Create Common Buffer
+ //
+ VirtualBase = m_Adapter->DmaOperations->AllocateCommonBuffer(m_Adapter,
+ PAGE_SIZE * 4,
+ &PhysicalAddress,
+ FALSE);
+ if (!VirtualBase)
+ {
+ DPRINT1("Failed to allocate a common buffer\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
// Stop the controller before modifying schedules
//
Status = StopController();
@@ -395,13 +434,25 @@
return STATUS_SUCCESS;
}
+NTSTATUS CUSBHardwareDevice::GetDMA(
+ OUT struct IDMAMemoryManager **OutDMAMemoryManager)
+{
+ if (!m_MemoryManager)
+ return STATUS_UNSUCCESSFUL;
+ *OutDMAMemoryManager = m_MemoryManager;
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
CUSBHardwareDevice::GetUSBQueue(
OUT struct IUSBQueue **OutUsbQueue)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
+ if (!m_UsbQueue)
+ return STATUS_UNSUCCESSFUL;
+ *OutUsbQueue = m_UsbQueue;
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
CUSBHardwareDevice::StartController(void)
@@ -589,6 +640,140 @@
return STATUS_SUCCESS;
}
+NTSTATUS CUSBHardwareDevice::GetPortStatus(
+ ULONG PortId,
+ OUT USHORT *PortStatus,
+ OUT USHORT *PortChange)
+{
+ ULONG Value;
+ USHORT Status = 0, Change = 0;
+
+ //
+ // Get the value of the Port Status and Control Register
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+
+ //
+ // If the PowerPortControl is 0 then host controller does not have power control
switches
+ if (!m_Capabilities.HCSParams.PortPowerControl)
+ {
+ Status |= USB_PORT_STATUS_POWER;
+ }
+ else
+ {
+ // Check the value of PortPower
+ if (Value & EHCI_PRT_POWER)
+ {
+ Status |= USB_PORT_STATUS_POWER;
+ }
+ }
+
+ // Get Speed. If SlowSpeedLine flag is there then its a slow speed device
+ if (Value & EHCI_PRT_SLOWSPEEDLINE)
+ Status |= USB_PORT_STATUS_LOW_SPEED;
+ else
+ Status |= USB_PORT_STATUS_HIGH_SPEED;
+
+ // Get Connected Status
+ if (Value & EHCI_PRT_CONNECTED)
+ Status |= USB_PORT_STATUS_CONNECT;
+
+ // Get Enabled Status
+ if (Value & EHCI_PRT_ENABLED)
+ Status |= USB_PORT_STATUS_ENABLE;
+
+ // Is it suspended?
+ if (Value & EHCI_PRT_SUSPEND)
+ Status |= USB_PORT_STATUS_SUSPEND;
+
+ // a overcurrent is active?
+ if (Value & EHCI_PRT_OVERCURRENTACTIVE)
+ Status |= USB_PORT_STATUS_OVER_CURRENT;
+
+ // In a reset state?
+ if (Value & EHCI_PRT_RESET)
+ Status |= USB_PORT_STATUS_RESET;
+
+ //
+ // FIXME: Is the Change here correct?
+ //
+ if (Value & EHCI_PRT_CONNECTSTATUSCHANGE)
+ Change |= USB_PORT_STATUS_CONNECT;
+
+ if (Value & EHCI_PRT_ENABLEDSTATUSCHANGE)
+ Change |= USB_PORT_STATUS_ENABLE;
+
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS CUSBHardwareDevice::ClearPortStatus(
+ ULONG PortId,
+ ULONG Status)
+{
+ ULONG Value;
+
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+
+ if (Status == C_PORT_RESET)
+ {
+ if (Value & EHCI_PRT_RESET)
+ {
+ Value &= ~EHCI_PRT_RESET;
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+ KeStallExecutionProcessor(100);
+ }
+ }
+
+ if (Status == C_PORT_CONNECTION)
+ {
+ // FIXME: Make sure its the Connection and Enable Change status.
+ Value |= EHCI_PRT_CONNECTSTATUSCHANGE;
+ Value |= EHCI_PRT_ENABLEDSTATUSCHANGE;
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS CUSBHardwareDevice::SetPortFeature(
+ ULONG PortId,
+ ULONG Feature)
+{
+ ULONG Value;
+
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ if (Feature == PORT_ENABLE)
+ {
+ //
+ // FIXME: EHCI Ports can only be disabled via reset
+ //
+ }
+
+ if (Feature == PORT_RESET)
+ {
+ if (Value & EHCI_PRT_SLOWSPEEDLINE)
+ {
+ DPRINT1("Non HighSpeed device. Releasing Ownership\n");
+ }
+
+ //
+ // Reset and clean enable
+ //
+ Value |= EHCI_PRT_RESET;
+ Value &= ~EHCI_PRT_ENABLED;
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+
+ KeStallExecutionProcessor(100);
+ }
+
+ if (Feature == PORT_POWER)
+ DPRINT1("Not implemented\n");
+
+ return STATUS_SUCCESS;
+}
+
VOID CUSBHardwareDevice::SetAsyncListRegister(ULONG PhysicalAddress)
{
EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, PhysicalAddress);
@@ -693,12 +878,12 @@
//
// Device connected or removed
//
- if (PortStatus & EHCI_PRT_CONNECTSTATUSCHAGE)
+ if (PortStatus & EHCI_PRT_CONNECTSTATUSCHANGE)
{
//
// Clear the port change status
//
- This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus
& EHCI_PRT_CONNECTSTATUSCHAGE);
+ This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus |
EHCI_PRT_CONNECTSTATUSCHANGE);
if (PortStatus & EHCI_PRT_CONNECTED)
{
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hardware.h [iso-8859-1] Tue Apr 19
06:56:30 2011
@@ -46,7 +46,7 @@
// Port Register Flags
//
#define EHCI_PRT_CONNECTED 0x01
-#define EHCI_PRT_CONNECTSTATUSCHAGE 0x02
+#define EHCI_PRT_CONNECTSTATUSCHANGE 0x02
#define EHCI_PRT_ENABLED 0x04
#define EHCI_PRT_ENABLEDSTATUSCHANGE 0x08
#define EHCI_PRT_OVERCURRENTACTIVE 0x10
@@ -192,7 +192,7 @@
LIST_ENTRY LinkedQueueHeads;
PQUEUE_TRANSFER_DESCRIPTOR TransferDescriptor;
PIRP IrpToComplete;
- PMDL MdlToFree;
+ PMDL Mdl;
PKEVENT Event;
} QUEUE_HEAD, *PQUEUE_HEAD;
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] Tue Apr
19 06:56:30 2011
@@ -156,20 +156,6 @@
0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
0xFF /* bInterval; (255ms -- usb 2.0 spec) */
};
-
-//
-// flags for handling USB_REQUEST_SET_FEATURE / USB_REQUEST_GET_FEATURE
-//
-#define PORT_ENABLE 1
-#define PORT_SUSPEND 2
-#define PORT_OVER_CURRENT 3
-#define PORT_RESET 4
-#define PORT_POWER 8
-#define C_PORT_CONNECTION 16
-#define C_PORT_ENABLE 17
-#define C_PORT_SUSPEND 18
-#define C_PORT_OVER_CURRENT 19
-#define C_PORT_RESET 20
//----------------------------------------------------------------------------------------
NTSTATUS
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] Tue Apr 19
06:56:30 2011
@@ -48,14 +48,9 @@
LONG m_Ref;
KSPIN_LOCK m_Lock;
PDMA_ADAPTER m_Adapter;
- PVOID VirtualBase;
- PHYSICAL_ADDRESS PhysicalAddress;
PQUEUE_HEAD AsyncQueueHead;
PQUEUE_HEAD PendingQueueHead;
- IDMAMemoryManager *m_MemoryManager;
-
- PQUEUE_HEAD CreateQueueHead();
- PQUEUE_TRANSFER_DESCRIPTOR CreateDescriptor(UCHAR PIDCode, ULONG
TotalBytesToTransfer);
+
VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead);
VOID LinkQueueHeadChain(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
@@ -87,35 +82,11 @@
PDMA_ADAPTER AdapterObject,
IN OPTIONAL PKSPIN_LOCK Lock)
{
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("CUSBQueue::Initialize()\n");
ASSERT(Hardware);
- ASSERT(AdapterObject);
-
- //
- // Create Common Buffer
- //
- VirtualBase =
AdapterObject->DmaOperations->AllocateCommonBuffer(AdapterObject,
- PAGE_SIZE * 4,
-
&PhysicalAddress,
- FALSE);
- if (!VirtualBase)
- {
- DPRINT1("Failed to allocate a common buffer\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- //
- // Create DMAMemoryManager for use with QueueHeads and Transfer Descriptors.
- //
- Status = CreateDMAMemoryManager(&m_MemoryManager);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create DMAMemoryManager Object\n");
- return Status;
- }
//
// initialize device lock
@@ -123,46 +94,20 @@
KeInitializeSpinLock(&m_Lock);
//
- // Initialize the DMAMemoryManager
- //
- Status = m_MemoryManager->Initialize(Hardware, &m_Lock, PAGE_SIZE * 4,
VirtualBase, PhysicalAddress, 32);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize the DMAMemoryManager\n");
- return Status;
- }
-
- //
- // Create a QueueHead for use in Async Register
- //
- AsyncQueueHead = CreateQueueHead();
- AsyncQueueHead->HorizontalLinkPointer = AsyncQueueHead->PhysicalAddr |
QH_TYPE_QH;
- AsyncQueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
- AsyncQueueHead->Token.Bits.InterruptOnComplete = FALSE;
- AsyncQueueHead->EndPointCharacteristics.HeadOfReclamation = TRUE;
- AsyncQueueHead->Token.Bits.Halted = TRUE;
-
- Hardware->SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
-
- //
- // Create a Unused QueueHead to hold pending QueueHeads
- //
- PendingQueueHead = CreateQueueHead();
- PendingQueueHead->Token.Bits.Halted = TRUE;
-
- //
- // Initialize ListHead in QueueHeads
- //
- InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
- InitializeListHead(&PendingQueueHead->LinkedQueueHeads);
-
- return STATUS_SUCCESS;
+ // FIXME: Need to set AsyncRegister with a QUEUEHEAD
+ //
+ return Status;
}
ULONG
CUSBQueue::GetPendingRequestCount()
{
- UNIMPLEMENTED
+ //
+ // Loop through the pending list and iterrate one for each QueueHead that
+ // has a IRP to complete.
+ //
+
+
return 0;
}
@@ -195,84 +140,6 @@
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
-}
-
-PQUEUE_HEAD
-CUSBQueue::CreateQueueHead()
-{
- PQUEUE_HEAD QueueHead;
- PHYSICAL_ADDRESS PhysicalAddress;
- NTSTATUS Status;
- //
- // Create the QueueHead from Common Buffer
- //
- Status = m_MemoryManager->Allocate(sizeof(QUEUE_HEAD),
- (PVOID*)&QueueHead,
- &PhysicalAddress);
- if (!NT_SUCCESS(Status))
- return NULL;
-
- //
- // Initialize default values
- //
-
- QueueHead->PhysicalAddr = PhysicalAddress.LowPart;
- QueueHead->HorizontalLinkPointer = TERMINATE_POINTER;
- QueueHead->AlternateNextPointer = TERMINATE_POINTER;
- QueueHead->NextPointer = TERMINATE_POINTER;
-
- // 1 for non high speed, 0 for high speed device
- QueueHead->EndPointCharacteristics.ControlEndPointFlag = 0;
- QueueHead->EndPointCharacteristics.HeadOfReclamation = FALSE;
- QueueHead->EndPointCharacteristics.MaximumPacketLength = 64;
-
- // Set NakCountReload to max value possible
- QueueHead->EndPointCharacteristics.NakCountReload = 0xF;
-
- // Get the Initial Data Toggle from the Queue Element Desriptor
- QueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
-
- QueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
-
- QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
-
- // Interrupt when QueueHead is processed
- QueueHead->Token.Bits.InterruptOnComplete = FALSE;
-
- return QueueHead;
-}
-
-PQUEUE_TRANSFER_DESCRIPTOR
-CUSBQueue::CreateDescriptor(
- UCHAR PIDCode,
- ULONG TotalBytesToTransfer)
-{
- PQUEUE_TRANSFER_DESCRIPTOR Descriptor;
- PHYSICAL_ADDRESS PhysicalAddress;
- NTSTATUS Status;
-
- //
- // Create the Descriptor from Common Buffer
- //
- Status = m_MemoryManager->Allocate(sizeof(QUEUE_TRANSFER_DESCRIPTOR),
- (PVOID*)&Descriptor,
- &PhysicalAddress);
- if (!NT_SUCCESS(Status))
- return NULL;
-
- //
- // Set default values
- //
- Descriptor->NextPointer = TERMINATE_POINTER;
- Descriptor->AlternateNextPointer = TERMINATE_POINTER;
- Descriptor->Token.Bits.DataToggle = TRUE;
- Descriptor->Token.Bits.ErrorCounter = 0x03;
- Descriptor->Token.Bits.Active = TRUE;
- Descriptor->Token.Bits.PIDCode = PIDCode;
- Descriptor->Token.Bits.TotalBytesToTransfer = TotalBytesToTransfer;
- Descriptor->PhysicalAddr = PhysicalAddress.LowPart;
-
- return Descriptor;
}
//
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] Tue Apr 19
06:56:30 2011
@@ -7,6 +7,10 @@
#include <hubbusif.h>
#include <usbbusif.h>
#include <usbioctl.h>
+//
+// FIXME:
+// #include <usbprotocoldefs.h>
+//
#include <usb.h>
#include <stdio.h>
#include <wdmguid.h>
@@ -20,6 +24,20 @@
#include <kcom.h>
#include "interfaces.h"
+
+//
+// flags for handling USB_REQUEST_SET_FEATURE / USB_REQUEST_GET_FEATURE
+//
+#define PORT_ENABLE 1
+#define PORT_SUSPEND 2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
typedef struct
{