Author: mjmartin
Date: Tue Apr 19 13:57:32 2011
New Revision: 51401

URL: http://svn.reactos.org/svn/reactos?rev=51401&view=rev
Log:
[USBEHCI_NEW]
- hub_controller: Implement Status Change Endpoint for RootHub. 
Handling the URB can return STATUS_PENDING, as in the new SCE code. Check for 
this before completing the Irp.
Uncomment calls to PortStatus, SetPortFeature, and ClearPortStatus now that 
they are implemented.
- For function receiving a port number check that its not larger than the 
actual number of ports on the controller.

Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp?rev=51401&r1=51400&r2=51401&view=diff
==============================================================================
--- 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 13:57:32 2011
@@ -602,6 +602,9 @@
 {
     ULONG PortStatus;
 
+    if (PortIndex > m_Capabilities.HCSParams.PortCount)
+        return STATUS_UNSUCCESSFUL;
+
     PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
     if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
     {
@@ -640,7 +643,8 @@
     return STATUS_SUCCESS;
 }
 
-NTSTATUS CUSBHardwareDevice::GetPortStatus(
+NTSTATUS
+CUSBHardwareDevice::GetPortStatus(
     ULONG PortId,
     OUT USHORT *PortStatus,
     OUT USHORT *PortChange)
@@ -648,6 +652,11 @@
     ULONG Value;
     USHORT Status = 0, Change = 0;
 
+    DPRINT1("CUSBHardwareDevice::GetPortStatus\n");
+
+    if (PortId > m_Capabilities.HCSParams.PortCount)
+        return STATUS_UNSUCCESSFUL;
+    
     //
     // Get the value of the Port Status and Control Register
     //
@@ -703,15 +712,27 @@
     if (Value & EHCI_PRT_ENABLEDSTATUSCHANGE)
         Change |= USB_PORT_STATUS_ENABLE;
 
+    *PortStatus = Status;
+    *PortChange = Change;
+
+    //HACK: Maybe
+    if (Status == (USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | 
USB_PORT_STATUS_POWER))
+        *PortChange = USB_PORT_STATUS_CONNECT;
     
     return STATUS_SUCCESS;
 }
 
-NTSTATUS CUSBHardwareDevice::ClearPortStatus(
+NTSTATUS
+CUSBHardwareDevice::ClearPortStatus(
     ULONG PortId,
     ULONG Status)
 {
     ULONG Value;
+
+    DPRINT1("CUSBHardwareDevice::ClearPortStatus\n");
+
+    if (PortId > m_Capabilities.HCSParams.PortCount)
+        return STATUS_UNSUCCESSFUL;
 
     Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
 
@@ -737,18 +758,26 @@
 }
 
 
-NTSTATUS CUSBHardwareDevice::SetPortFeature(
+NTSTATUS
+CUSBHardwareDevice::SetPortFeature(
     ULONG PortId,
     ULONG Feature)
 {
     ULONG Value;
 
+    DPRINT1("CUSBHardwareDevice::SetPortFeature\n");
+
+    if (PortId > m_Capabilities.HCSParams.PortCount)
+        return STATUS_UNSUCCESSFUL;
+
     Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+
     if (Feature == PORT_ENABLE)
     {
         //
         // FIXME: EHCI Ports can only be disabled via reset
         //
+        DPRINT1("PORT_ENABLE not supported for EHCI\n");
     }
     
     if (Feature == PORT_RESET)
@@ -757,7 +786,6 @@
         {
             DPRINT1("Non HighSpeed device. Releasing Ownership\n");
         }
-
         //
         // Reset and clean enable
         //
@@ -769,17 +797,21 @@
     }
     
     if (Feature == PORT_POWER)
-        DPRINT1("Not implemented\n");
-
-    return STATUS_SUCCESS;
-}
-
-VOID CUSBHardwareDevice::SetAsyncListRegister(ULONG PhysicalAddress)
+        DPRINT1("PORT_POWER Not implemented\n");
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+CUSBHardwareDevice::SetAsyncListRegister(
+    ULONG PhysicalAddress)
 {
     EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, PhysicalAddress);
 }
 
-VOID CUSBHardwareDevice::SetPeriodicListRegister(ULONG PhysicalAddress)
+VOID
+CUSBHardwareDevice::SetPeriodicListRegister(
+    ULONG PhysicalAddress)
 {
     EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress);
 }

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp?rev=51401&r1=51400&r2=51401&view=diff
==============================================================================
--- 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 13:57:32 2011
@@ -90,6 +90,7 @@
     RTL_BITMAP m_DeviceAddressBitmap;
     PULONG m_DeviceAddressBitmapBuffer;
     LIST_ENTRY m_UsbDeviceList;
+    PIRP m_PendingSCEIrp;
 };
 
 typedef struct
@@ -692,6 +693,60 @@
     IN OUT PIRP Irp, 
     PURB Urb)
 {
+    ULONG PortCount, PortId;
+    USHORT PortStatus, PortChange;
+
+    //
+    // First check if the request is for the Status Change Endpoint
+    //
+
+    //
+    // Is the Request for the root hub
+    //
+    if (Urb->UrbHeader.UsbdDeviceHandle==0)
+    {
+        //
+        // There should only be one SCE request pending at a time
+        //
+        ASSERT (m_PendingSCEIrp == NULL);
+
+        //
+        // Get the number of ports and check each one for device connected
+        //
+        m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
+        DPRINT1("SCE Request\n");
+        DPRINT1("PortCount %d\n", PortCount);
+        ((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
+        for (PortId = 0; PortId < PortCount; PortId++)
+        {
+            m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
+
+            DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, 
PortChange);
+
+            //
+            // FIXME: Verify that this is correct.
+            //
+            if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & 
USB_PORT_STATUS_CONNECT))
+            {
+                DPRINT1("Device is connected on port %d\n", PortId);
+                ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 
1 << ((PortId + 1) & 7);
+                break;
+            }
+        }
+
+        //
+        // If there were changes then return SUCCESS
+        //
+        if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
+            return STATUS_SUCCESS;
+
+        //
+        // Else pend the IRP, to be completed when a device connects or 
disconnects.
+        //
+        m_PendingSCEIrp = Irp;
+        IoMarkIrpPending(Irp);
+        return STATUS_PENDING;
+    }
     UNIMPLEMENTED
     return STATUS_NOT_IMPLEMENTED;
 }
@@ -743,9 +798,8 @@
             //
             // get port status
             //
-            //Status = m_Hardware->GetPortStatus(PortId, &PortStatus, 
&PortChange);
-
-            Status = STATUS_SUCCESS;
+            Status = m_Hardware->GetPortStatus(PortId, &PortStatus, 
&PortChange);
+
             if (NT_SUCCESS(Status))
             {
                 //
@@ -771,10 +825,10 @@
             switch (Urb->UrbControlVendorClassRequest.Value)
             {
                 case C_PORT_CONNECTION:
-                    //Status = m_Hardware->ClearPortStatus(PortId, 
C_PORT_CONNECTION);
+                    Status = m_Hardware->ClearPortStatus(PortId, 
C_PORT_CONNECTION);
                     break;
                 case C_PORT_RESET:
-                    //Status= m_Hardware->ClearPortStatus(PortId, 
C_PORT_RESET);
+                    Status= m_Hardware->ClearPortStatus(PortId, C_PORT_RESET);
                     break;
                 default:
                     DPRINT("Unknown Value for Clear Feature %x \n", 
Urb->UrbControlVendorClassRequest.Value);
@@ -806,7 +860,7 @@
                     //
                     // set suspend port feature
                     //
-                    Status = STATUS_SUCCESS; 
//m_Hardware->SetPortFeature(PortId, PORT_SUSPEND);
+                    Status = m_Hardware->SetPortFeature(PortId, PORT_SUSPEND);
                     break;
                 }
                 case PORT_POWER:
@@ -814,7 +868,7 @@
                     //
                     // set power feature on port
                     //
-                    Status = STATUS_SUCCESS; 
//m_Hardware->SetPortFeature(PortId, PORT_POWER);
+                    Status = m_Hardware->SetPortFeature(PortId, PORT_POWER);
                     break;
                 }
 
@@ -1232,9 +1286,12 @@
             break;
         }
     }
-
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    if (Status != STATUS_PENDING)
+    {
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
     return Status;
 }
 

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp?rev=51401&r1=51400&r2=51401&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
Tue Apr 19 13:57:32 2011
@@ -70,6 +70,7 @@
     PQUEUE_HEAD m_QueueHead;
     PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3];
     PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket;
+    PHYSICAL_ADDRESS m_DescriptorSetupPacket;
 };
 
 
//----------------------------------------------------------------------------------------
@@ -570,14 +571,15 @@
     }
 
     //
-    // FIXME: where put MDL virtual address?
-    //
-
-
-    //
-    // link setup packet into buffer - VIRTUAL Address!!!
-    //
-    m_TransferDescriptors[0]->BufferPointer[0] = 
(ULONG)PtrToUlong(m_DescriptorPacket);
+    // Control Transfers have only one in or out buffer if one at all. Put in 
the QueueHead the
+    // same as BulkTransfers. USBQueue will use the Mdl to fill in the 
BufferPointers
+    //
+    QueueHead->Mdl = m_TransferBufferMDL;
+
+    //
+    // link setup packet into buffer - Physical Address!!!
+    //
+    m_TransferDescriptors[0]->BufferPointer[0] = 
(ULONG)PtrToUlong(m_DescriptorSetupPacket.LowPart);
 
     //
     // link transfer descriptors to queue head
@@ -791,6 +793,7 @@
         // copy setup packet
         //
         RtlCopyMemory(m_DescriptorPacket, m_SetupPacket, 
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
+        m_DescriptorSetupPacket = PhysicalAddress;
     }
 
     //


Reply via email to