Author: janderwald
Date: Sun May 22 20:48:50 2011
New Revision: 51852

URL: http://svn.reactos.org/svn/reactos?rev=51852&view=rev
Log:
[OHCI]
- Add check that controller is functional state
- enable interrupts after the controller has been started
- partly implement isr routine

Modified:
    branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
    branches/usb-bringup/drivers/usb/usbohci/usbohci.h

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.cpp?rev=51852&r1=51851&r2=51852&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Sun May 
22 20:48:50 2011
@@ -22,7 +22,7 @@
 
 VOID
 NTAPI
-EhciDefferedRoutine(
+OhciDefferedRoutine(
     IN PKDPC Dpc,
     IN PVOID DeferredContext,
     IN PVOID SystemArgument1,
@@ -82,7 +82,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);
+    friend VOID NTAPI OhciDefferedRoutine(IN PKDPC Dpc, IN PVOID 
DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
     friend VOID NTAPI StatusChangeWorkItemRoutine(PVOID Context);
     // constructor / destructor
     CUSBHardwareDevice(IUnknown *OuterUnknown){}
@@ -249,7 +249,7 @@
             case CmResourceTypeInterrupt:
             {
                 KeInitializeDpc(&m_IntDpcObject,
-                                EhciDefferedRoutine,
+                                OhciDefferedRoutine,
                                 this);
 
                 Status = IoConnectInterrupt(&m_Interrupt,
@@ -522,6 +522,21 @@
     WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET), 
Control);
 
     //
+    // wait a bit
+    //
+    KeStallExecutionProcessor(100);
+
+    //
+    // is the controller started
+    //
+    Control = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_CONTROL_OFFSET));
+
+    //
+    // assert that the controller has been started
+    //
+    ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == 
OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
+
+    //
     // retrieve number of ports
     //
     for(Index = 0; Index < 10; Index++)
@@ -562,6 +577,12 @@
     // print out number ports
     //
     DPRINT1("NumberOfPorts %lu\n", m_NumberOfPorts);
+
+
+    //
+    // now enable the interrupts
+    //
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_NORMAL_INTERRUPTS | 
OHCI_MASTER_INTERRUPT_ENABLE);
 
     //
     // done
@@ -938,19 +959,150 @@
     IN PKINTERRUPT  Interrupt,
     IN PVOID  ServiceContext)
 {
-    ASSERT(FALSE);
+    CUSBHardwareDevice *This;
+    ULONG DoneHead, Status, Acknowledge = 0;
+
+    //
+    // get context
+    //
+    This = (CUSBHardwareDevice*) ServiceContext;
+
+    DPRINT1("InterruptServiceRoutine\n");
+
+    //
+    // get done head
+    //
+    DoneHead = This->m_HCCA->DoneHead;
+
+    //
+    // check if zero
+    //
+    if (DoneHead == 0)
+    {
+        //
+        // the interrupt was not caused by DoneHead update
+        // check if something important happened
+        //
+        Status = READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + 
OHCI_INTERRUPT_STATUS_OFFSET)) & 
READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET)) & (~OHCI_WRITEBACK_DONE_HEAD); 
+        if (Status == 0)
+        {
+            //
+            // nothing happened, appears to be shared interrupt
+            //
+            return FALSE;
+        }
+    }
+    else
+    {
+        //
+        // DoneHead update happened, check if there are other events too
+        //
+        Status = OHCI_WRITEBACK_DONE_HEAD;
+
+        //
+        // since ed descriptors are 16 byte aligned, the controller sets the 
lower bits if there were other interrupt requests
+        //
+        if (DoneHead & OHCI_DONE_INTERRUPTS)
+        {
+            //
+            // get other events
+            //
+            Status |= READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + 
OHCI_INTERRUPT_STATUS_OFFSET)) & 
READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET));
+        }
+    }
+
+    //
+    // sanity check
+    //
+    ASSERT(Status != 0);
+
+     if (Status & OHCI_WRITEBACK_DONE_HEAD)
+     {
+         //
+         // head completed
+         //
+         DPRINT1("InterruptServiceRoutine> Done Head completion\n");
+
+         //
+         // FIXME: handle event
+         //
+         Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
+    }
+
+    if (Status & OHCI_RESUME_DETECTED)
+    {
+        //
+        // resume
+        //
+        DPRINT1("InterruptServiceRoutine> Resume\n");
+        Acknowledge |= OHCI_RESUME_DETECTED;
+    }
+
+
+    if (Status & OHCI_UNRECOVERABLE_ERROR)
+    {
+        DPRINT1("InterruptServiceRoutine> Controller error\n");
+        //
+        // halt controller
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + 
OHCI_CONTROL_OFFSET)), OHCI_HC_FUNCTIONAL_STATE_RESET);
+    }
+
+    if (Status & OHCI_ROOT_HUB_STATUS_CHANGE) 
+    {
+        //
+        // new device has arrived
+        //
+        DPRINT1("InterruptServiceRoutine> New Device arrival\n");
+
+        //
+        // disable interrupt as it will fire untill the port has been reset
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + 
OHCI_INTERRUPT_DISABLE_OFFSET)), OHCI_ROOT_HUB_STATUS_CHANGE);
+        Acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
+    }
+
+    //
+    // is there something to acknowledge
+    //
+    if (Acknowledge)
+    {
+        //
+        // ack change
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)(This->m_Base + 
OHCI_INTERRUPT_STATUS_OFFSET)), Acknowledge);
+    }
+
+    //
+    // defer processing
+    //
+    DPRINT1("Status %x\n", Status);
+    KeInsertQueueDpc(&This->m_IntDpcObject, This, (PVOID)Status);
+
+    //
+    // interrupt handled
+    //
     return TRUE;
 }
 
-VOID NTAPI
-EhciDefferedRoutine(
+VOID
+NTAPI
+OhciDefferedRoutine(
     IN PKDPC Dpc,
     IN PVOID DeferredContext,
     IN PVOID SystemArgument1,
     IN PVOID SystemArgument2)
 {
-    ASSERT(FALSE);
-    return;
+    CUSBHardwareDevice *This;
+    ULONG CStatus;
+
+    //
+    // get parameters
+    //
+    This = (CUSBHardwareDevice*) SystemArgument1;
+    CStatus = (ULONG) SystemArgument2;
+
+
 }
 
 VOID

Modified: branches/usb-bringup/drivers/usb/usbohci/usbohci.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/usbohci.h?rev=51852&r1=51851&r2=51852&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/usbohci.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/usbohci.h [iso-8859-1] Sun May 22 
20:48:50 2011
@@ -49,7 +49,7 @@
 //
 // tag for allocations
 //
-#define TAG_USBOHCI 'ICHE'
+#define TAG_USBOHCI 'ICHO'
 
 //
 // assert for c++ - taken from portcls


Reply via email to