Implement IRP_MN_QUERY_DEVICE_RELATIONS for USB hubs
Implement IRP_MN_QUERY_ID for devices enumerated by USB hubs
Modified: trunk/reactos/drivers/usb/cromwell/hub/fdo.c
Modified: trunk/reactos/drivers/usb/cromwell/hub/pdo.c
Modified: trunk/reactos/drivers/usb/cromwell/hub/usbhub.h
_____
Modified: trunk/reactos/drivers/usb/cromwell/hub/fdo.c
--- trunk/reactos/drivers/usb/cromwell/hub/fdo.c 2005-06-19
14:12:59 UTC (rev 16092)
+++ trunk/reactos/drivers/usb/cromwell/hub/fdo.c 2005-06-19
14:15:39 UTC (rev 16093)
@@ -10,8 +10,6 @@
#define NDEBUG
#include "usbhub.h"
-extern struct usb_driver hub_driver;
-
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
static VOID
@@ -47,6 +45,147 @@
}
}
+static NTSTATUS
+UsbhubFdoQueryBusRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_RELATIONS DeviceRelations;
+ PDEVICE_OBJECT Pdo;
+ PHUB_DEVICE_EXTENSION PdoExtension;
+ struct usb_device* dev;
+ ULONG i;
+ ULONG Children = 0;
+ ULONG NeededSize;
+ NTSTATUS Status;
+ CHAR Buffer[3][40];
+
+ DeviceExtension =
(PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ dev = DeviceExtension->dev;
+
+ /* Create PDOs that are missing */
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+ if (dev->children[i] == NULL)
+ {
+ /* No child device at this place */
+ continue;
+ }
+ Children++;
+ if (DeviceExtension->Children[i] != NULL)
+ {
+ /* PDO already exists */
+ continue;
+ }
+ /* Need to create the PDO */
+ Status = IoCreateDevice(
+ DeviceObject->DriverObject,
+ sizeof(HUB_DEVICE_EXTENSION),
+ NULL, /* Device name */
+ FILE_DEVICE_CONTROLLER,
+ FILE_AUTOGENERATED_DEVICE_NAME,
+ FALSE,
+ &DeviceExtension->Children[i]);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Usbhub: IoCreateDevice() failed with
status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ Pdo = DeviceExtension->Children[i];
+ Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+
+ PdoExtension = Pdo->DeviceExtension;
+ RtlZeroMemory(PdoExtension,
sizeof(HUB_DEVICE_EXTENSION));
+
+ PdoExtension->IsFDO = FALSE;
+ PdoExtension->dev = dev->children[i];
+
+ RtlInitUnicodeString(
+ &PdoExtension->DeviceDescription,
+ L"USB device"); /* FIXME */
+
+ sprintf(Buffer[0], "%lu", i + 1);
+ Status = UsbhubInitMultiSzString(
+ &PdoExtension->InstanceId,
+ Buffer[0], NULL);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ /* FIXME: what if it is a multiple-interface usb device?
*/
+ sprintf(Buffer[0], "USB\\Vid_%04x&Pid_%04x&Rev_%04x",
+ PdoExtension->dev->descriptor.idVendor,
+ PdoExtension->dev->descriptor.idProduct,
+ 0 /* FIXME: need to put the revision */);
+ sprintf(Buffer[1], "USB\\Vid_%04x&Pid_%04x",
+ PdoExtension->dev->descriptor.idVendor,
+ PdoExtension->dev->descriptor.idProduct);
+ Status = UsbhubInitMultiSzString(
+ &PdoExtension->HardwareIds,
+ Buffer[0], Buffer[1], NULL);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ Status = UsbhubInitMultiSzString(
+ &PdoExtension->DeviceId,
+ Buffer[1], NULL);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ /* FIXME: what if it is a multiple-interface usb device?
*/
+ sprintf(Buffer[0],
"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
+ PdoExtension->dev->descriptor.bDeviceClass,
+ PdoExtension->dev->descriptor.bDeviceSubClass,
+ PdoExtension->dev->descriptor.bDeviceProtocol);
+ sprintf(Buffer[1], "USB\\Class_%02x&SubClass_%02x",
+ PdoExtension->dev->descriptor.bDeviceClass,
+ PdoExtension->dev->descriptor.bDeviceSubClass);
+ sprintf(Buffer[2], "USB\\Class_%02x",
+ PdoExtension->dev->descriptor.bDeviceClass);
+ Status = UsbhubInitMultiSzString(
+ &PdoExtension->CompatibleIds,
+ Buffer[0], Buffer[1], Buffer[2], NULL);
+ if (!NT_SUCCESS(Status))
+ goto ByeBye;
+
+ Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
+
+ /* Fill returned structure */
+ NeededSize = sizeof(DEVICE_RELATIONS);
+ if (Children > 1)
+ NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
+ DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
+ PagedPool,
+ NeededSize);
+ if (!DeviceRelations)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ DeviceRelations->Count = Children;
+ Children = 0;
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+ if (DeviceExtension->Children[i])
+ {
+ ObReferenceObject(DeviceExtension->Children[i]);
+ DeviceRelations->Objects[Children++] =
DeviceExtension->Children[i];
+ }
+ }
+ ASSERT(Children == DeviceRelations->Count);
+
+ *pDeviceRelations = DeviceRelations;
+ return STATUS_SUCCESS;
+
+ByeBye:
+ RtlFreeUnicodeString(&PdoExtension->DeviceDescription);
+ RtlFreeUnicodeString(&PdoExtension->DeviceId);
+ RtlFreeUnicodeString(&PdoExtension->InstanceId);
+ RtlFreeUnicodeString(&PdoExtension->HardwareIds);
+ RtlFreeUnicodeString(&PdoExtension->CompatibleIds);
+ IoDeleteDevice(Pdo);
+ return Status;
+}
+
NTSTATUS STDCALL
UsbhubPnpFdo(
IN PDEVICE_OBJECT DeviceObject,
@@ -62,35 +201,37 @@
switch (MinorFunction)
{
- case IRP_MN_START_DEVICE:
+ case IRP_MN_START_DEVICE: /* 0x0 */
{
DPRINT("Usbhub: IRP_MJ_PNP /
IRP_MN_START_DEVICE\n");
Status = ForwardIrpAndWait(DeviceObject, Irp);
- //if (NT_SUCCESS(Status) &&
NT_SUCCESS(Irp->IoStatus.Status))
- // Status =
OHCD_PnPStartDevice(DeviceObject, Irp);
break;
}
- case IRP_MN_REMOVE_DEVICE:
- //case IRP_MN_QUERY_REMOVE_DEVICE:
- //case IRP_MN_CANCEL_REMOVE_DEVICE:
- case IRP_MN_SURPRISE_REMOVAL:
-
- case IRP_MN_STOP_DEVICE:
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
{
- DPRINT("Usbhub: IRP_MJ_PNP /
IRP_MN_STOP_DEVICE\n");
- Status = ForwardIrpAndWait(DeviceObject, Irp);
- if (NT_SUCCESS(Status) &&
NT_SUCCESS(Irp->IoStatus.Status))
- Status = STATUS_SUCCESS;
- IoDeleteDevice(DeviceObject); // just delete
device for now
+ switch
(IrpSp->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusRelations:
+ {
+ PDEVICE_RELATIONS
DeviceRelations;
+ DPRINT("Usbhub: IRP_MJ_PNP /
IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
+ Status =
UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);
+ Information =
(ULONG_PTR)DeviceRelations;
+ break;
+ }
+ case RemovalRelations:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP /
IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
+ return
ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ default:
+ DPRINT1("Usbhub: IRP_MJ_PNP /
IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
+
IrpSp->Parameters.QueryDeviceRelations.Type);
+ return
ForwardIrpAndForget(DeviceObject, Irp);
+ }
break;
}
- case IRP_MN_QUERY_STOP_DEVICE:
- case IRP_MN_CANCEL_STOP_DEVICE:
- {
- Status = STATUS_SUCCESS;
- break;
- }
default:
{
@@ -104,11 +245,6 @@
return Status;
}
-static inline struct device *hubdev (struct usb_device *dev)
-{
- return &dev->actconfig->interface [0].dev;
-}
-
NTSTATUS
UsbhubDeviceControlFdo(
IN PDEVICE_OBJECT DeviceObject,
@@ -147,7 +283,7 @@
NodeInformation->NodeType = UsbHub;
RtlCopyMemory(
&NodeInformation->u.HubInformation.HubDescriptor,
- ((struct usb_hub
*)usb_get_intfdata(to_usb_interface(hubdev(dev))))->descriptor,
+ ((struct usb_hub
*)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))
->descriptor,
sizeof(USB_HUB_DESCRIPTOR));
NodeInformation->u.HubInformation.HubIsBusPowered = TRUE; /* FIXME */
Information =
sizeof(USB_NODE_INFORMATION);
@@ -189,17 +325,24 @@
ConnectionInformation =
(PUSB_NODE_CONNECTION_INFORMATION)BufferOut;
DPRINT1("Usbhub:
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION partially implemented\n");
dev =
((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
- ConnectionInformation->ConnectionIndex =
0; /* FIXME */
+ dev =
dev->children[ConnectionInformation->ConnectionIndex = 0];
+ if (dev == NULL)
+ {
+ /* No device connected to this
port */
+
RtlZeroMemory(ConnectionInformation,
sizeof(USB_NODE_CONNECTION_INFORMATION));
+ Status = STATUS_SUCCESS;
+ break;
+ }
RtlCopyMemory(
&ConnectionInformation->DeviceDescriptor,
&dev->descriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
ConnectionInformation->CurrentConfigurationValue = 0; /* FIXME */
- ConnectionInformation->LowSpeed = TRUE;
/* FIXME */
- ConnectionInformation->DeviceIsHub =
TRUE;
-
RtlZeroMemory(&ConnectionInformation->DeviceAddress,
sizeof(ConnectionInformation->DeviceAddress)); /* FIXME */
+ ConnectionInformation->LowSpeed =
dev->speed == USB_SPEED_LOW || dev->speed == USB_SPEED_FULL;
+ ConnectionInformation->DeviceIsHub =
dev->descriptor.bDeviceClass == USB_CLASS_HUB;
+ ConnectionInformation->DeviceAddress =
dev->devnum;
RtlZeroMemory(&ConnectionInformation->NumberOfOpenPipes,
sizeof(ConnectionInformation->NumberOfOpenPipes)); /* FIXME */
-
RtlZeroMemory(&ConnectionInformation->ConnectionStatus,
sizeof(ConnectionInformation->ConnectionStatus)); /* FIXME */
+ ConnectionInformation->ConnectionStatus
= DeviceConnected;
RtlZeroMemory(&ConnectionInformation->PipeList,
sizeof(ConnectionInformation->PipeList)); /* FIXME */
/*for (i = 0; i < 32; i++)
{
_____
Modified: trunk/reactos/drivers/usb/cromwell/hub/pdo.c
--- trunk/reactos/drivers/usb/cromwell/hub/pdo.c 2005-06-19
14:12:59 UTC (rev 16092)
+++ trunk/reactos/drivers/usb/cromwell/hub/pdo.c 2005-06-19
14:15:39 UTC (rev 16093)
@@ -8,10 +8,9 @@
*/
//#define NDEBUG
+#include <stdio.h>
#include "usbhub.h"
-extern struct usb_driver hub_driver;
-
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
NTSTATUS
@@ -44,6 +43,59 @@
return Status;
}
+static NTSTATUS
+UsbhubPdoQueryId(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
+{
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ ULONG IdType;
+ PUNICODE_STRING SourceString;
+ UNICODE_STRING String;
+ NTSTATUS Status;
+
+ IdType =
IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+ DeviceExtension =
(PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ RtlInitUnicodeString(&String, NULL);
+
+ switch (IdType)
+ {
+ case BusQueryDeviceID:
+ {
+ DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID /
BusQueryDeviceID\n");
+ SourceString = &DeviceExtension->DeviceId;
+ break;
+ }
+ case BusQueryHardwareIDs:
+ {
+ DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID /
BusQueryHardwareIDs\n");
+ SourceString = &DeviceExtension->HardwareIds;
+ break;
+ }
+ case BusQueryCompatibleIDs:
+ DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID /
BusQueryCompatibleIDs\n");
+ SourceString = &DeviceExtension->CompatibleIds;
+ break;
+ case BusQueryInstanceID:
+ {
+ DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID /
BusQueryInstanceID\n");
+ SourceString = &DeviceExtension->InstanceId;
+ break;
+ }
+ default:
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID /
unknown query id type 0x%lx\n", IdType);
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ Status = UsbhubDuplicateUnicodeString(
+ &String,
+ SourceString,
+ PagedPool);
+ *Information = (ULONG_PTR)String.Buffer;
+ return Status;
+}
+
NTSTATUS STDCALL
UsbhubPnpPdo(
IN PDEVICE_OBJECT DeviceObject,
@@ -59,6 +111,11 @@
switch (MinorFunction)
{
+ case IRP_MN_QUERY_ID: /* 0x13 */
+ {
+ Status = UsbhubPdoQueryId(DeviceObject, Irp,
&Information);
+ break;
+ }
default:
{
/* We can't forward request to the lower driver,
because
_____
Modified: trunk/reactos/drivers/usb/cromwell/hub/usbhub.h
--- trunk/reactos/drivers/usb/cromwell/hub/usbhub.h 2005-06-19
14:12:59 UTC (rev 16092)
+++ trunk/reactos/drivers/usb/cromwell/hub/usbhub.h 2005-06-19
14:15:39 UTC (rev 16093)
@@ -19,6 +19,15 @@
BOOLEAN IsFDO;
struct usb_device* dev;
PDEVICE_OBJECT LowerDevice;
+
+ PDEVICE_OBJECT Children[USB_MAXCHILDREN];
+
+ /* Fields valid only when IsFDO == FALSE */
+ UNICODE_STRING DeviceDescription; // REG_SZ
+ UNICODE_STRING DeviceId; // REG_SZ
+ UNICODE_STRING InstanceId; // REG_SZ
+ UNICODE_STRING HardwareIds; // REG_MULTI_SZ
+ UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
/* createclose.c */