[USBEHCI_NEW]
authorMichael Martin <michael.martin@reactos.org>
Sun, 8 May 2011 12:42:15 +0000 (12:42 +0000)
committerMichael Martin <michael.martin@reactos.org>
Sun, 8 May 2011 12:42:15 +0000 (12:42 +0000)
- When clearing feature port reset, remove the flag from Change and if the port is hardware enabled set the enable flag in Status.
- When checking port status, if Change has any flags set an SCE request most be completed. Verified while writing usbhub driver in xp.
- Probably fixes a case where an endless loop of completing SCE requests.

svn path=/branches/usb-bringup/; revision=51642

drivers/usb/usbehci_new/hardware.cpp
drivers/usb/usbehci_new/hub_controller.cpp

index 99dd9fe..2a08a5d 100644 (file)
@@ -713,7 +713,7 @@ CUSBHardwareDevice::GetPortStatus(
 
     if (PortId > m_Capabilities.HCSParams.PortCount)
         return STATUS_UNSUCCESSFUL;
-    
+
     //
     // Get the value of the Port Status and Control Register
     //
@@ -799,12 +799,18 @@ CUSBHardwareDevice::ClearPortStatus(
             Value &= ~EHCI_PRT_RESET;
             EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
             KeStallExecutionProcessor(100);
+        }
 
-            //
-            // update port status
-            //
-            m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET;
+        Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+        //
+        // update port status
+        //
+        m_PortStatus[PortId].PortChange &= ~USB_PORT_STATUS_RESET;
+        if (Value & EHCI_PRT_ENABLED) 
             m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
+        else
+        {
+            DPRINT1("Port is not enabled.\n");
         }
     }
 
@@ -843,7 +849,7 @@ CUSBHardwareDevice::SetPortFeature(
         //
         DPRINT1("PORT_ENABLE not supported for EHCI\n");
     }
-    
+
     if (Feature == PORT_RESET)
     {
         if (Value & EHCI_PRT_SLOWSPEEDLINE)
@@ -870,7 +876,7 @@ CUSBHardwareDevice::SetPortFeature(
             m_SCECallBack(m_SCEContext);
         }
     }
-    
+
     if (Feature == PORT_POWER)
         DPRINT1("PORT_POWER Not implemented\n");
 
index 5e37d4a..b76a00f 100644 (file)
@@ -67,7 +67,7 @@ public:
     NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
-    
+
     friend VOID StatusChangeEndpointCallBack(PVOID Context);
 
     // constructor / destructor
@@ -305,31 +305,30 @@ CHubController::QueryStatusChageEndpoint(
     DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
 
     TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
+
+    //
+    // Loop the ports
+    //
     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 theres a flag in PortChange return TRUE so the SCE Irp will be completed
         //
-        if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT))
+        if (PortChange != 0)
         {
-            DPRINT1("Device is connected on port %d\n", PortId);
+            DPRINT1("Change state on port %d\n", PortId);
             // Set the value for the port number
              *TransferBuffer = 1 << ((PortId + 1) & 7);
             Changed = TRUE;
         }
     }
 
-    //
-    // If there were changes then return TRUE
-    //
-    if (Changed != 0)
-        return TRUE;
-
-    return FALSE;
+    return Changed;
 }
 
 //-----------------------------------------------------------------------------------------
@@ -777,6 +776,7 @@ CHubController::HandleBulkOrInterruptTransfer(
         ASSERT(m_PendingSCEIrp == NULL);
         if (QueryStatusChageEndpoint(Irp))
         {
+            StatusChangeEndpointCallBack(this);
             return STATUS_SUCCESS;
         }
 
@@ -2094,7 +2094,7 @@ USBHI_InitializeUsbDevice(
         if (NT_SUCCESS(Status))
             break;
 
-    }while(Index++ < 3 );
+    }while(Index++ < 3    );
 
     //
     // check for failure
@@ -2705,11 +2705,6 @@ USBHI_SetDeviceHandleData(
         //
         DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
 
-        //
-        // fixup device stack voodoo part #1
-        //
-        UsbDevicePdo->StackSize++;
-
         //
         // sanity check
         //
@@ -3152,6 +3147,11 @@ CHubController::CreatePDO(
 
     DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
 
+    //
+    // fixup device stack voodoo part #1
+    //
+    (*OutDeviceObject)->StackSize++;
+
     /* done */
     return Status;
 }