Author: mjmartin
Date: Sat Apr 16 05:55:02 2011
New Revision: 51366
URL:
http://svn.reactos.org/svn/reactos?rev=51366&view=rev
Log:
[USBEHCI_NEW]
- Add flags for Port Status Control Register and remove structiures for Port Status
Control Register.
- Remove USB Status Register and use the flags instead.
- Remove functions that are not used and never will be.
- Implement InterruptServiceRoutine and Deffered Procedure Routine.
- Partially implement port status change to detect device insert and removal.
Modified:
branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
branches/usb-bringup/drivers/usb/usbehci_new/hardware.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] Sat Apr 16
05:55:02 2011
@@ -17,6 +17,13 @@
InterruptServiceRoutine(
IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext);
+
+VOID NTAPI
+EhciDefferedRoutine(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2);
class CUSBHardwareDevice : public IUSBHardwareDevice
{
@@ -58,6 +65,7 @@
// friend function
friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID
ServiceContext);
+ friend VOID NTAPI EhciDefferedRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN
PVOID SystemArgument1, IN PVOID SystemArgument2);
// constructor / destructor
CUSBHardwareDevice(IUnknown *OuterUnknown){}
@@ -71,24 +79,17 @@
PDEVICE_OBJECT m_NextDeviceObject;
KSPIN_LOCK m_Lock;
PKINTERRUPT m_Interrupt;
+ KDPC m_IntDpcObject;
PULONG m_Base;
PDMA_ADAPTER m_Adapter;
ULONG m_MapRegisters;
- PQUEUE_HEAD AsyncListQueueHead;
+ PQUEUE_HEAD m_AsyncListQueueHead;
EHCI_CAPS m_Capabilities;
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
- VOID SetStatusRegister(PEHCI_USBSTS_CONTENT UsbSts);
- VOID GetStatusRegister(PEHCI_USBSTS_CONTENT UsbSts);
- //VOID SetPortRegister(PEHCI_USBPORTSC_CONTENT UsbPort);
- //VOID GetPortRegister(PEHCI_USBPORTSC_CONTENT UsbPort);
ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset);
- ULONG EHCI_READ_REGISTER_USHORT(ULONG Offset);
- ULONG EHCI_READ_REGISTER_UCHAR(ULONG Offset);
VOID EHCI_WRITE_REGISTER_ULONG(ULONG Offset, ULONG Value);
- VOID EHCI_WRITE_REGISTER_USHORT(ULONG Offset, ULONG Value);
- VOID EHCI_WRITE_REGISTER_UCHAR(ULONG Offset, ULONG Value);
};
//=================================================================================================
@@ -152,57 +153,16 @@
*Register = READ_REGISTER_ULONG((PULONG)((ULONG)m_Base + EHCI_USBCMD));
}
-
-VOID
-CUSBHardwareDevice::SetStatusRegister(PEHCI_USBSTS_CONTENT UsbSts)
-{
- PULONG Register;
- Register = (PULONG)UsbSts;
- WRITE_REGISTER_ULONG((PULONG)((ULONG)m_Base + EHCI_USBSTS), *Register);
-}
-
-VOID
-CUSBHardwareDevice::GetStatusRegister(PEHCI_USBSTS_CONTENT UsbSts)
-{
- PULONG CmdRegister;
- CmdRegister = (PULONG)UsbSts;
- *CmdRegister = READ_REGISTER_ULONG((PULONG)((ULONG)m_Base + EHCI_USBSTS));
-}
-
ULONG
CUSBHardwareDevice::EHCI_READ_REGISTER_ULONG(ULONG Offset)
{
return READ_REGISTER_ULONG((PULONG)((ULONG)m_Base + Offset));
}
-ULONG
-CUSBHardwareDevice::EHCI_READ_REGISTER_USHORT(ULONG Offset)
-{
- return READ_REGISTER_USHORT((PUSHORT)((ULONG)m_Base + Offset));
-}
-
-ULONG
-CUSBHardwareDevice::EHCI_READ_REGISTER_UCHAR(ULONG Offset)
-{
- return READ_REGISTER_UCHAR((PUCHAR)((ULONG)m_Base + Offset));
-}
-
VOID
CUSBHardwareDevice::EHCI_WRITE_REGISTER_ULONG(ULONG Offset, ULONG Value)
{
WRITE_REGISTER_ULONG((PULONG)((ULONG)m_Base + Offset), Value);
-}
-
-VOID
-CUSBHardwareDevice::EHCI_WRITE_REGISTER_USHORT(ULONG Offset, ULONG Value)
-{
- WRITE_REGISTER_USHORT((PUSHORT)((ULONG)m_Base + Offset), Value);
-}
-
-VOID
-CUSBHardwareDevice::EHCI_WRITE_REGISTER_UCHAR(ULONG Offset, ULONG Value)
-{
- WRITE_REGISTER_UCHAR((PUCHAR)((ULONG)m_Base + Offset), Value);
}
NTSTATUS
@@ -228,6 +188,10 @@
{
case CmResourceTypeInterrupt:
{
+ KeInitializeDpc(&m_IntDpcObject,
+ EhciDefferedRoutine,
+ this);
+
Status = IoConnectInterrupt(&m_Interrupt,
InterruptServiceRoutine,
(PVOID)this,
@@ -324,7 +288,7 @@
//
// FIXME: Create a QueueHead that will always be the address of the AsyncList
//
- AsyncListQueueHead = NULL;
+ m_AsyncListQueueHead = NULL;
//
// Start the controller
@@ -381,20 +345,19 @@
CUSBHardwareDevice::StartController(void)
{
EHCI_USBCMD_CONTENT UsbCmd;
- EHCI_USBSTS_CONTENT UsbSts;
- LONG FailSafe;
+ ULONG UsbSts, FailSafe;
//
// Stop the controller if its running
//
- GetStatusRegister(&UsbSts);
- if (UsbSts.HCHalted)
+ UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
+ if (!(UsbSts & EHCI_STS_HALT))
StopController();
//
// Reset the device. Bit is set to 0 on completion.
//
- SetCommandRegister(&UsbCmd);
+ GetCommandRegister(&UsbCmd);
UsbCmd.HCReset = TRUE;
SetCommandRegister(&UsbCmd);
@@ -438,7 +401,7 @@
UsbCmd.AsyncEnable = FALSE; //FIXME: Need USB Memory Manager
UsbCmd.IntThreshold = 1;
- // FIXME: Set framlistsize when periodic is implemented.
+ // FIXME: Set framelistsize when periodic is implemented.
SetCommandRegister(&UsbCmd);
//
@@ -456,15 +419,15 @@
for (FailSafe = 100; FailSafe > 1; FailSafe--)
{
KeStallExecutionProcessor(10);
- GetStatusRegister(&UsbSts);
+ UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
- if (!UsbSts.HCHalted)
+ if (!(UsbSts & EHCI_STS_HALT))
{
break;
}
}
- if (!UsbSts.HCHalted)
+ if (UsbSts & EHCI_STS_HALT)
{
DPRINT1("Could not start execution on the controller\n");
return STATUS_UNSUCCESSFUL;
@@ -482,8 +445,7 @@
CUSBHardwareDevice::StopController(void)
{
EHCI_USBCMD_CONTENT UsbCmd;
- EHCI_USBSTS_CONTENT UsbSts;
- LONG FailSafe;
+ ULONG UsbSts, FailSafe;
//
// Disable Interrupts and stop execution
@@ -496,14 +458,14 @@
for (FailSafe = 100; FailSafe > 1; FailSafe--)
{
KeStallExecutionProcessor(10);
- GetStatusRegister(&UsbSts);
- if (UsbSts.HCHalted)
+ UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
+ if (UsbSts & EHCI_STS_HALT)
{
break;
}
}
- if (!UsbSts.HCHalted)
+ if (!(UsbSts & EHCI_STS_HALT))
{
DPRINT1("EHCI ERROR: Controller is not responding to Stop
request!\n");
return STATUS_UNSUCCESSFUL;
@@ -557,8 +519,114 @@
IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext)
{
- UNIMPLEMENTED
- return FALSE;
+ CUSBHardwareDevice *This;
+ ULONG CStatus;
+
+ This = (CUSBHardwareDevice*) ServiceContext;
+ CStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_USBSTS);
+
+ CStatus &= (EHCI_ERROR_INT | EHCI_STS_INT | EHCI_STS_IAA | EHCI_STS_PCD |
EHCI_STS_FLR);
+ //
+ // Check that it belongs to EHCI
+ //
+ if (!CStatus)
+ return FALSE;
+
+ //
+ // Clear the Status
+ //
+ This->EHCI_WRITE_REGISTER_ULONG(EHCI_USBSTS, CStatus);
+
+ if (CStatus & EHCI_STS_FATAL)
+ {
+ This->StopController();
+ DPRINT1("EHCI: Host System Error!\n");
+ return TRUE;
+ }
+
+ if (CStatus & EHCI_ERROR_INT)
+ {
+ DPRINT1("EHCI Status = 0x%x\n", CStatus);
+ }
+
+ if (CStatus & EHCI_STS_HALT)
+ {
+ DPRINT1("Host Error Unexpected Halt\n");
+ // FIXME: Reset controller\n");
+ return TRUE;
+ }
+
+ KeInsertQueueDpc(&This->m_IntDpcObject, This, (PVOID)CStatus);
+ return TRUE;
+}
+
+VOID NTAPI
+EhciDefferedRoutine(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2)
+{
+ CUSBHardwareDevice *This;
+ ULONG CStatus, PortStatus, i;
+
+ This = (CUSBHardwareDevice*) SystemArgument1;
+ CStatus = (ULONG) SystemArgument2;
+
+ if (CStatus & EHCI_STS_PCD)
+ {
+ for (i = 0; i < This->m_Capabilities.HCSParams.PortCount; i++)
+ {
+ PortStatus = This->EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * i));
+
+ //
+ // Device connected or removed
+ //
+ if (PortStatus & EHCI_PRT_CONNECTSTATUSCHAGE)
+ {
+ //
+ // Clear the port change status
+ //
+ This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus
& EHCI_PRT_CONNECTSTATUSCHAGE);
+
+ if (PortStatus & EHCI_PRT_CONNECTED)
+ {
+ DPRINT1("Device connected on port %d\n", i);
+
+ //
+ //FIXME: Determine device speed
+ //
+ if (This->m_Capabilities.HCSParams.CHCCount)
+ {
+ if (PortStatus & EHCI_PRT_ENABLED)
+ {
+ DPRINT1("Misbeaving controller. Port should be disabled
at this point\n");
+ }
+
+ if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
+ {
+ DPRINT1("Non HighSeped device connected. Release
ownership\n");
+ This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i),
EHCI_PRT_RELEASEOWNERSHIP);
+ continue;
+ }
+
+ //
+ // FIXME: Is a port reset needed, or does hub driver request
this?
+ //
+ }
+ }
+ else
+ {
+ DPRINT1("Device disconnected on port %d\n", i);
+ }
+
+ //
+ // FIXME: This needs to be saved somewhere
+ //
+ }
+ }
+ }
+ return;
}
NTSTATUS
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] Sat Apr 16
05:55:02 2011
@@ -41,6 +41,22 @@
#define EHCI_STS_PSS 0x4000
#define EHCI_STS_ASS 0x8000
#define EHCI_ERROR_INT (EHCI_STS_FATAL | EHCI_STS_ERR)
+
+//
+// Port Register Flags
+//
+#define EHCI_PRT_CONNECTED 0x01
+#define EHCI_PRT_CONNECTSTATUSCHAGE 0x02
+#define EHCI_PRT_ENABLED 0x04
+#define EHCI_PRT_ENABLEDSTATUSCHANGE 0x08
+#define EHCI_PRT_OVERCURRENTACTIVE 0x10
+#define EHCI_PRT_OVERCURRENTCHANGE 0x20
+#define EHCI_PRT_FORCERESUME 0x40
+#define EHCI_PRT_SUSPEND 0x80
+#define EHCI_PRT_RESET 0x100
+#define EHCI_PRT_SLOWSPEEDLINE 0x400
+#define EHCI_PRT_POWER 0x1000
+#define EHCI_PRT_RELEASEOWNERSHIP 0x2000
//
// Terminate Pointer used for QueueHeads and Element Transfer Descriptors to mark
Pointers as the end
@@ -202,41 +218,6 @@
ULONG Reserved2 : 8;
} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
-//
-// Status register content
-//
-typedef struct _EHCI_USBSTS_CONTENT
-{
- ULONG USBInterrupt:1;
- ULONG ErrorInterrupt:1;
- ULONG DetectChangeInterrupt:1;
- ULONG FrameListRolloverInterrupt:1;
- ULONG HostSystemErrorInterrupt:1;
- ULONG AsyncAdvanceInterrupt:1;
- ULONG Reserved:6;
- ULONG HCHalted:1;
- ULONG Reclamation:1;
- ULONG PeriodicScheduleStatus:1;
- ULONG AsynchronousScheduleStatus:1;
-} EHCI_USBSTS_CONTENT, *PEHCI_USBSTS_CONTENT;
-
-typedef struct _EHCI_USBPORTSC_CONTENT
-{
- ULONG CurrentConnectStatus:1;
- ULONG ConnectStatusChange:1;
- ULONG PortEnabled:1;
- ULONG PortEnableChanged:1;
- ULONG OverCurrentActive:1;
- ULONG OverCurrentChange:1;
- ULONG ForcePortResume:1;
- ULONG Suspend:1;
- ULONG PortReset:1;
- ULONG Reserved:1;
- ULONG LineStatus:2;
- ULONG PortPower:1;
- ULONG PortOwner:1;
-} EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
-
typedef struct _EHCI_HCS_CONTENT
{
ULONG PortCount : 4;