Author: mjmartin
Date: Fri Apr 2 06:49:01 2010
New Revision: 46660
URL:
http://svn.reactos.org/svn/reactos?rev=46660&view=rev
Log:
[usb/usbehci]
- Implement tracking port status and change status.
- When device has connected on port, set the port status. For now assume high speed
device.
- Fix returning root hubs Status Change Endpoint for
URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER.
- Implement USB_REQUEST_GET_STATUS for functions URB_FUNCTION_GET_STATUS_FROM_DEVICE and
URB_FUNCTION_CLASS_OTHER. Implement USB_REQUEST_CLEAR_FEATURE and
USB_REQUEST_SET_FEATURE.
- Implement IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE to return the root hubs device handle,
fix IOCTL_INTERNAL_USB_GET_HUB_COUNT to return 1 vice 0 as the root hub must be accounted
for.
- Code based on XEN PV Drivers by James Harper.
Modified:
trunk/reactos/drivers/usb/usbehci/fdo.c
trunk/reactos/drivers/usb/usbehci/irp.c
trunk/reactos/drivers/usb/usbehci/pdo.c
trunk/reactos/drivers/usb/usbehci/usbehci.h
Modified: trunk/reactos/drivers/usb/usbehci/fdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/fdo.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] Fri Apr 2 06:49:01 2010
@@ -100,9 +100,9 @@
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
- DPRINT("port tmp %x\n", tmp);
GetDeviceDescriptor(FdoDeviceExtension, 0, 0, FALSE);
PdoDeviceExtension->ChildDeviceCount++;
+ PdoDeviceExtension->Ports[i].PortStatus |=
USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
WorkItemData = ExAllocatePool(NonPagedPool, sizeof(WORKITEM_DATA));
if (!WorkItemData) ASSERT(FALSE);
WorkItemData->IoWorkItem =
IoAllocateWorkItem(PdoDeviceExtension->DeviceObject);
Modified: trunk/reactos/drivers/usb/usbehci/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/irp.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/irp.c [iso-8859-1] Fri Apr 2 06:49:01 2010
@@ -88,35 +88,65 @@
if (UsbDevice == NULL)
UsbDevice = DeviceExtension->UsbDevices[0];
+ /* Assume URB success */
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+ /* Set the DeviceHandle to the Internal Device */
+ Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
+
switch (Urb->UrbHeader.Function)
{
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
- /* Are we suppose to only return on this request when a device is
connected
- or is it the RootHubInitNotification Callback */
DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
DPRINT1("--->TransferBufferLength
%x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
DPRINT1("--->TransferBuffer
%x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
DPRINT1("--->PipeHandle
%x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
+ DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor
%x\n", (PVOID)&UsbDevice->EndPointDescriptor);
DPRINT1("--->TransferFlags %x\n",
Urb->UrbBulkOrInterruptTransfer.TransferFlags);
- /* FIXME */
+
RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
- ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1;
- /* Turn off Irp handling as nothing is handled beyond this */
- DeviceExtension->HaltUrbHandling = TRUE;
+ if (UsbDevice == DeviceExtension->UsbDevices[0])
+ {
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags &
(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
+ {
+ LONG i;
+ for (i = 0; i < 8; i++)
+ {
+ if (DeviceExtension->Ports[i].PortChange)
+ {
+ DPRINT1("Inform hub driver that port %d has
changed\n", i+1);
+
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << (i + 1);
+ }
+ }
+ }
+ else
+ {
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ }
break;
}
case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
{
- DPRINT1("Get Status from Device\n");
+ DPRINT("Get Status from Device\n");
+ DPRINT("Index : %d\n",
Urb->UrbControlGetStatusRequest.Index);
+
+ /* Copied from pvdrivers */
+ if (Urb->UrbControlGetStatusRequest.Index == 0)
+ {
+ *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer =
USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
+ }
+ else
+ {
+ DPRINT1("Uknown identifier\n");
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ Status = STATUS_UNSUCCESSFUL;
+ }
break;
}
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
{
- Urb->UrbHeader.Function = 0x08;
- Urb->UrbHeader.UsbdFlags = 0;
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
-
switch(Urb->UrbControlDescriptorRequest.DescriptorType)
{
case USB_DEVICE_DESCRIPTOR_TYPE:
@@ -130,9 +160,6 @@
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
&UsbDevice->DeviceDescriptor,
Urb->UrbControlDescriptorRequest.TransferBufferLength);
-
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
-
break;
}
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
@@ -150,9 +177,6 @@
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
&UsbDevice->ConfigurationDescriptor,
Urb->UrbControlDescriptorRequest.TransferBufferLength);
-
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
-
break;
}
case USB_STRING_DESCRIPTOR_TYPE:
@@ -232,10 +256,6 @@
}
InterfaceInfo =
(PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
}
-
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
- Urb->UrbHeader.UsbdFlags = 0;
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
}
else
{
@@ -251,7 +271,6 @@
{
DPRINT1("TransferFlags %x\n",
Urb->UrbControlVendorClassRequest.TransferFlags);
DPRINT1("Urb->UrbControlVendorClassRequest.Value
%x\n", Urb->UrbControlVendorClassRequest.Value);
-
switch (Urb->UrbControlVendorClassRequest.Value >> 8)
{
@@ -328,10 +347,16 @@
DPRINT1("Unknown UrbControlVendorClassRequest
Value\n");
}
}
- Urb->UrbHeader.Function = 0x08;
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
- Urb->UrbHeader.UsbdFlags = 0;
+ break;
+ }
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n",
Urb->UrbControlVendorClassRequest.Index);
+
+ if (Urb->UrbControlVendorClassRequest.Index == 1)
+ {
+
((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
+ }
break;
}
default:
@@ -348,22 +373,51 @@
{
case USB_REQUEST_GET_STATUS:
{
- DPRINT1("USB_REQUEST_GET_STATUS\n");
+ DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n",
Urb->UrbControlVendorClassRequest.Index);
+
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0]
= DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1]
= DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
break;
}
case USB_REQUEST_CLEAR_FEATURE:
{
- DPRINT1("USB_REQUEST_CLEAR_FEATURE\n");
+ DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value
%x\n", Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+ switch (Urb->UrbControlVendorClassRequest.Value)
+ {
+ case C_PORT_CONNECTION:
+
DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &=
~USB_PORT_STATUS_CONNECT;
+ break;
+ case C_PORT_RESET:
+
DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &=
~USB_PORT_STATUS_RESET;
+ break;
+ default:
+ DPRINT1("Unknown Value for Clear Feature %x
\n", Urb->UrbControlVendorClassRequest.Value);
+ break;
+ }
break;
}
case USB_REQUEST_SET_FEATURE:
{
- DPRINT1("USB_REQUEST_SET_FEATURE value %x\n",
Urb->UrbControlVendorClassRequest.Value);
+ DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n",
Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+
switch(Urb->UrbControlVendorClassRequest.Value)
{
- /* FIXME: Needs research */
- case 0x01:
- {
+ case PORT_RESET:
+ {
+
DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |=
USB_PORT_STATUS_RESET;
+ break;
+ }
+ case PORT_ENABLE:
+ {
+ DPRINT1("Unhandled Set Feature\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Set Feature!\n");
+ break;
}
}
break;
@@ -371,6 +425,7 @@
case USB_REQUEST_SET_ADDRESS:
{
DPRINT1("USB_REQUEST_SET_ADDRESS\n");
+ ASSERT(FALSE);
break;
}
case USB_REQUEST_GET_DESCRIPTOR:
@@ -406,6 +461,12 @@
case USB_REQUEST_SYNC_FRAME:
{
DPRINT1("USB_REQUEST_SYNC_FRAME\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Function Class Unknown request\n");
+ ASSERT(FALSE);
break;
}
}
@@ -415,6 +476,7 @@
{
DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ ASSERT(FALSE);
}
}
@@ -423,6 +485,13 @@
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
+
+ if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
+ {
+ /* Fake a successful Control Transfer */
+ Urb->UrbHeader.Function = 0x08;
+ Urb->UrbHeader.UsbdFlags = 0;
+ }
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
Modified: trunk/reactos/drivers/usb/usbehci/pdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/pdo.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] Fri Apr 2 06:49:01 2010
@@ -172,18 +172,24 @@
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
+ DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n",
IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
+ if (Stack->Parameters.Others.Argument1)
+ {
+ /* Return the root hubs devicehandle */
+ *(PVOID *)Stack->Parameters.Others.Argument1 =
(PVOID)PdoDeviceExtension->UsbDevices[0];
+ }
+ else
+ Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
-
+ DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n",
IOCTL_INTERNAL_USB_GET_HUB_COUNT);
if (Stack->Parameters.Others.Argument1)
{
/* FIXME: Determine the number of hubs between the usb device and root
hub */
- /* For now return 0 */
- *(PVOID *)Stack->Parameters.Others.Argument1 = 0;
+ /* For now return 1, the root hub */
+ *(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)1;
}
break;
}
@@ -216,9 +222,8 @@
if (Stack->Parameters.Others.Argument2)
*(PVOID *)Stack->Parameters.Others.Argument2 =
IoGetAttachedDevice(FdoDeviceExtension->DeviceObject);
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- return STATUS_SUCCESS;
+ Information = 0;
+ Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
@@ -287,7 +292,6 @@
}
}
- /* Lifted from hpoussin */
Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
&SourceString,
&String);
@@ -350,12 +354,19 @@
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
UNICODE_STRING InterfaceSymLinkName;
+ LONG i;
PdoDeviceExtension =
(PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FdoDeviceExtension =
(PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
/* Create the root hub */
RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
+
+ for (i = 0; i < 8; i++)
+ {
+ PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
+ PdoDeviceExtension->Ports[i].PortChange = 0;
+ }
RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
ROOTHUB2_DEVICE_DESCRIPTOR,
@@ -409,8 +420,16 @@
break;
}
case BusRelations:
+ DPRINT1("BusRelations!!!!!\n");
case RemovalRelations:
case EjectionRelations:
+ {
+ /* Ignore the request */
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ break;
+
+ }
default:
{
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled
type 0x%lx\n",
@@ -534,7 +553,8 @@
else
{
DPRINT1("Not Supported\n");
- Status = STATUS_NOT_SUPPORTED;
+ Status = Irp->IoStatus.Status;
+ Information = Irp->IoStatus.Information;
}
break;
}
Modified: trunk/reactos/drivers/usb/usbehci/usbehci.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehc…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] Fri Apr 2 06:49:01 2010
@@ -74,6 +74,25 @@
/* Ping States, OR with QUEUE_TRANSFER_DESCRIPTOR Token. */
#define PING_STATE_DO_OUT 0x00
#define PING_STATE_DO_PING 0x01
+
+#define C_HUB_LOCAL_POWER 0
+#define C_HUB_OVER_CURRENT 1
+#define PORT_CONNECTION 0
+#define PORT_ENABLE 1
+#define PORT_SUSPEND 2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define PORT_LOW_SPEED 9
+#define PORT_HIGH_SPEED 9
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
+#define PORT_TEST 21
+#define PORT_INDICATOR 22
+#define USB_PORT_STATUS_CHANGE 0x4000
/* QUEUE ELEMENT TRANSFER DESCRIPTOR TOKEN */
typedef struct _QETD_TOKEN_BITS
@@ -273,16 +292,16 @@
} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
typedef struct _EHCI_CAPS {
- UCHAR Length;
- UCHAR Reserved;
- USHORT HCIVersion;
+ UCHAR Length;
+ UCHAR Reserved;
+ USHORT HCIVersion;
union
{
- EHCI_HCS_CONTENT HCSParams;
- ULONG HCSParamsLong;
+ EHCI_HCS_CONTENT HCSParams;
+ ULONG HCSParamsLong;
};
- ULONG HCCParams;
- UCHAR PortRoute [8];
+ ULONG HCCParams;
+ UCHAR PortRoute [8];
} EHCI_CAPS, *PEHCI_CAPS;
typedef struct _COMMON_DEVICE_EXTENSION
@@ -291,6 +310,14 @@
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _EHCIPORTS
+{
+ ULONG PortNumber;
+ ULONG PortType;
+ USHORT PortStatus;
+ USHORT PortChange;
+} EHCIPORTS, *PEHCIPORTS;
typedef struct _FDO_DEVICE_EXTENSION
{
@@ -333,8 +360,8 @@
PULONG PeriodicFramList;
PULONG AsyncListQueueHeadPtr;
- PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
- PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
+ PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
+ PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
BOOLEAN AsyncComplete;
@@ -356,6 +383,8 @@
BOOLEAN HaltUrbHandling;
PVOID CallbackContext;
PRH_INIT_CALLBACK CallbackRoutine;
+ ULONG NumberOfPorts;
+ EHCIPORTS Ports[32];
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
typedef struct _WORKITEM_DATA