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…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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;
}
//