Author: janderwald
Date: Tue May 24 12:51:03 2011
New Revision: 51883

URL: http://svn.reactos.org/svn/reactos?rev=51883&view=rev
Log:
[USBOHCI]
- Enable global power mode
- Wait untill reset is complete
- Clear reset complete bit when reset is done
- Enable port
- Reset port now works
- USBOHCI still hangs after adding first control request, needs more 
investigation

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

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=51883&r1=51882&r2=51883&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] Tue May 
24 12:51:03 2011
@@ -489,7 +489,7 @@
 NTSTATUS
 CUSBHardwareDevice::StartController(void)
 {
-    ULONG Control, NumberOfPorts, Index, Descriptor;
+    ULONG Control, NumberOfPorts, Index, Descriptor, FrameInterval, Periodic, 
IntervalValue;
 
     //
     // first write address of HCCA
@@ -540,6 +540,48 @@
     // assert that the controller has been started
     //
     ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == 
OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
+
+    //
+    // get frame interval
+    //
+    //FrameInterval = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET)) & OHCI_FRAME_INTERVAL_TOGGLE) ^ 
OHCI_FRAME_INTERVAL_TOGGLE;
+    //FrameInterval |= OHCI_FSMPS(IntervalValue) | IntervalValue;
+
+    //
+    // write frame interval
+    //
+    //WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_FRAME_INTERVAL_OFFSET), FrameInterval);
+    // 90% periodic
+    //Periodic = OHCI_PERIODIC(intervalValue);
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 0x40 
/*OHCI_PERIODIC_START_OFFSET*/), 0x3E67);
+
+
+    //
+    // read descriptor
+    //
+    Descriptor = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_DESCRIPTOR_A_OFFSET));
+
+    //
+    // no over current protection
+    //
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
+
+    //
+    // enable power on all ports
+    //
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_STATUS_OFFSET), 
OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
+
+    //
+    // wait a bit
+    //
+    KeStallExecutionProcessor(10);
+
+    //
+    // write descriptor
+    //
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor);
+
+
 
     //
     // retrieve number of ports
@@ -913,19 +955,11 @@
     if (PortId > m_NumberOfPorts)
         return STATUS_UNSUCCESSFUL;
 
-    //
-    // read port status
-    //
     Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)));
     KeStallExecutionProcessor(100);
 
     if (Status == C_PORT_RESET)
     {
-        //
-        // complete reset
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
-
         do
         {
            //
@@ -945,16 +979,45 @@
            // wait a bit
            //
            KeStallExecutionProcessor(100);
-           DPRINT1("Wait...\n");
-
-        }while(Index++ < 10);
-
-        if ((Value & OHCI_RH_PORTSTATUS_PRS))
+
+           //DPRINT1("Value %x Index %lu\n", Value, Index);
+
+        }while(TRUE);
+
+        //
+        // check if reset bit is still set
+        //
+        if (Value & OHCI_RH_PORTSTATUS_PRS)
         {
-            DPRINT1("Failed to reset\n");
+            //
+            // reset failed
+            //
+            DPRINT1("PortId %lu Reset failed\n", PortId);
+            return STATUS_UNSUCCESSFUL;
         }
 
         //
+        // sanity checks
+        //
+        ASSERT((Value & OHCI_RH_PORTSTATUS_PRS) == 0);
+        ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC));
+
+        //
+        // clear reset bit complete
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
+
+        //
+        // read status register
+        //
+        Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)));
+
+        //
+        // reset complete bit should be cleared
+        //
+        ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC) == 0);
+
+        //
         // update port status
         //
         m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET;
@@ -964,13 +1027,15 @@
         //
         ASSERT((Value & OHCI_RH_PORTSTATUS_PES));
 
-        if (Value & OHCI_RH_PORTSTATUS_PES) 
-        {
-            //
-            // port is enabled
-            //
-            m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
-         }
+        //
+        // port is enabled
+        //
+        m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
+
+        //
+        // re-enable root hub change
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
     }
 
     if (Status == C_PORT_CONNECTION)
@@ -1275,6 +1340,12 @@
                     // device connected
                     //
                     DPRINT1("New device arrival at Port %d LowSpeed %x\n", 
Index, (PortStatus & OHCI_RH_PORTSTATUS_LSDA));
+
+                    //
+                    // enable port
+                    //
+                    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + 
OHCI_RH_PORT_STATUS(Index)), OHCI_RH_PORTSTATUS_PES);
+
 
                     //
                     // store change

Modified: branches/usb-bringup/drivers/usb/usbohci/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hardware.h?rev=51883&r1=51882&r2=51883&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbohci/hardware.h [iso-8859-1] Tue May 24 
12:51:03 2011
@@ -100,7 +100,7 @@
 //
 //  Root Hub status register (section 7.4.3)
 //
-#define OHCI_RH_STATUS                          0x50
+#define OHCI_RH_STATUS_OFFSET                          0x50
 #define OHCI_RH_LOCAL_POWER_STATUS              0x00000001
 #define OHCI_RH_OVER_CURRENT_INDICATOR          0x00000002
 #define OHCI_RH_DEVICE_REMOTE_WAKEUP_ENABLE     0x00008000

Modified: branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp?rev=51883&r1=51882&r2=51883&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] 
Tue May 24 12:51:03 2011
@@ -922,9 +922,9 @@
                 case PORT_ENABLE:
                 {
                     //
-                    // port enable is a no-op for OHCI
-                    //
-                    Status = STATUS_SUCCESS;
+                    // port enable
+                    //
+                    Status = m_Hardware->SetPortFeature(PortId, PORT_ENABLE);
                     break;
                 }
 


Reply via email to