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 */