2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS USB miniport driver (Cromwell type)
4 * FILE: drivers/usb/miniport/common/pdo.c
5 * PURPOSE: IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for PDOs
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org),
8 * James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net)
14 #include "usbcommon.h"
16 extern struct usb_driver hub_driver
;
18 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
21 UsbMpDeviceControlPdo(
22 IN PDEVICE_OBJECT DeviceObject
,
25 PIO_STACK_LOCATION Stack
;
26 ULONG_PTR Information
= 0;
29 DPRINT("USBMP: UsbMpDeviceControlPdo() called\n");
31 Stack
= IoGetCurrentIrpStackLocation(Irp
);
32 Status
= Irp
->IoStatus
.Status
;
34 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
36 case IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE
:
38 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
40 DPRINT("USBMP: IOCTL_INTERNAL_USB_GET_ROOT_USB_DEVICE\n");
41 if (Irp
->AssociatedIrp
.SystemBuffer
== NULL
42 || Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
!= sizeof(PVOID
))
44 Status
= STATUS_INVALID_PARAMETER
;
48 PVOID
* pRootHubPointer
;
49 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
50 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceExtension
->FunctionalDeviceObject
->DeviceExtension
;
52 pRootHubPointer
= (PVOID
*)Irp
->AssociatedIrp
.SystemBuffer
;
53 *pRootHubPointer
= ((struct usb_hcd
*)DeviceExtension
->pdev
->data
)->self
.root_hub
;
54 Information
= sizeof(PVOID
);
55 Status
= STATUS_SUCCESS
;
61 DPRINT1("USBMP: Unknown IOCTL code 0x%lx\n", Stack
->Parameters
.DeviceIoControl
.IoControlCode
);
62 Information
= Irp
->IoStatus
.Information
;
63 Status
= Irp
->IoStatus
.Status
;
67 Irp
->IoStatus
.Information
= Information
;
68 Irp
->IoStatus
.Status
= Status
;
69 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
75 IN PDEVICE_OBJECT DeviceObject
,
77 OUT ULONG_PTR
* Information
)
79 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
81 UNICODE_STRING SourceString
;
82 UNICODE_STRING String
;
83 struct usb_device
*roothub
;
84 NTSTATUS Status
= STATUS_SUCCESS
;
86 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
87 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
88 RtlInitUnicodeString(&String
, NULL
);
89 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceExtension
->FunctionalDeviceObject
->DeviceExtension
;
90 roothub
= ((struct usb_hcd
*)DeviceExtension
->pdev
->data
)->self
.root_hub
;
94 case BusQueryDeviceID
:
96 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
97 if (roothub
->speed
== USB_SPEED_LOW
|| roothub
->speed
== USB_SPEED_FULL
)
98 RtlInitUnicodeString(&SourceString
, L
"USB\\ROOT_HUB"); /* USB 1.1 */
100 RtlInitUnicodeString(&SourceString
, L
"USB\\ROOT_HUB20"); /* USB 2.0 */
103 case BusQueryHardwareIDs
:
107 PCI_COMMON_CONFIG PciData
;
108 ULONG BusNumber
, SlotNumber
;
112 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
114 Pdo
= DeviceExtension
->PhysicalDeviceObject
;
115 Status
= IoGetDeviceProperty(
117 DevicePropertyBusNumber
,
121 if (!NT_SUCCESS(Status
))
123 DPRINT("USBMP: IoGetDeviceProperty() failed with status 0x%08lx\n", Status
);
127 Status
= IoGetDeviceProperty(
129 DevicePropertyAddress
,
133 if (!NT_SUCCESS(Status
))
135 DPRINT("USBMP: IoGetDeviceProperty() failed with status 0x%08lx\n", Status
);
139 ret
= HalGetBusDataByOffset(PCIConfiguration
,
144 PCI_COMMON_HDR_LENGTH
);
145 if (ret
!= PCI_COMMON_HDR_LENGTH
)
147 DPRINT("USBMP: HalGetBusDataByOffset() failed (ret = %ld)\n", ret
);
148 Status
= STATUS_IO_DEVICE_ERROR
;
152 sprintf(Buffer
[0], "USB\\VID%04X&PID%04X&REV%04X",
153 PciData
.VendorID
, PciData
.DeviceID
, PciData
.RevisionID
);
154 sprintf(Buffer
[1], "USB\\VID%04X&PID%04X",
155 PciData
.VendorID
, PciData
.DeviceID
);
156 if (roothub
->speed
== USB_SPEED_LOW
|| roothub
->speed
== USB_SPEED_FULL
)
157 RootHubName
= "USB\\ROOT_HUB"; /* USB 1.1 */
159 RootHubName
= "USB\\ROOT_HUB20"; /* USB 2.0 */
160 Status
= UsbMpInitMultiSzString(
162 Buffer
[0], Buffer
[1], RootHubName
, NULL
);
165 case BusQueryCompatibleIDs
:
166 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
167 /* No compatible ID */
169 return STATUS_NOT_SUPPORTED
;
170 case BusQueryInstanceID
:
172 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
173 RtlInitUnicodeString(&SourceString
, L
"");
177 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
178 return STATUS_NOT_SUPPORTED
;
181 if (NT_SUCCESS(Status
))
183 Status
= UsbMpDuplicateUnicodeString(
187 *Information
= (ULONG_PTR
)String
.Buffer
;
194 IN PDEVICE_OBJECT DeviceObject
)
196 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
199 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
201 /* Register device interface for root hub */
202 Status
= IoRegisterDeviceInterface(
204 &GUID_DEVINTERFACE_USB_HUB
,
206 &DeviceExtension
->HcdInterfaceName
);
207 if (!NT_SUCCESS(Status
))
209 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
218 IN PDEVICE_OBJECT DeviceObject
,
222 PIO_STACK_LOCATION Stack
;
223 ULONG_PTR Information
= 0;
226 Stack
= IoGetCurrentIrpStackLocation(Irp
);
227 MinorFunction
= Stack
->MinorFunction
;
229 switch (MinorFunction
)
231 case IRP_MN_START_DEVICE
: /* 0x00 */
233 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
234 Status
= UsbMpPnpStartDevice(DeviceObject
);
237 case IRP_MN_QUERY_CAPABILITIES
: /* 0x09 */
239 PDEVICE_CAPABILITIES DeviceCapabilities
;
241 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
243 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
244 /* FIXME: capabilities can change with connected device */
245 DeviceCapabilities
->LockSupported
= FALSE
;
246 DeviceCapabilities
->EjectSupported
= FALSE
;
247 DeviceCapabilities
->Removable
= FALSE
;
248 DeviceCapabilities
->DockDevice
= FALSE
;
249 DeviceCapabilities
->UniqueID
= FALSE
;
250 DeviceCapabilities
->SilentInstall
= TRUE
;
251 DeviceCapabilities
->RawDeviceOK
= FALSE
;
252 DeviceCapabilities
->SurpriseRemovalOK
= FALSE
;
253 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
254 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
255 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
256 for (i
= 0; i
< PowerSystemMaximum
; i
++)
257 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
258 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
259 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
260 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
261 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
262 Status
= STATUS_SUCCESS
;
265 case IRP_MN_QUERY_RESOURCES
: /* 0x0a */
267 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
268 /* Root buses don't need resources, except the ones of
269 * the usb controller. This PDO is the root bus PDO, so
270 * report no resource by not changing Information and
273 Information
= Irp
->IoStatus
.Information
;
274 Status
= Irp
->IoStatus
.Status
;
277 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0x0b */
279 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
280 /* Root buses don't need resources, except the ones of
281 * the usb controller. This PDO is the root bus PDO, so
282 * report no resource by not changing Information and
285 Information
= Irp
->IoStatus
.Information
;
286 Status
= Irp
->IoStatus
.Status
;
289 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0x0c */
291 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
293 case DeviceTextDescription
:
295 UNICODE_STRING SourceString
= RTL_CONSTANT_STRING(L
"Root USB hub");
296 UNICODE_STRING Description
;
298 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
300 Status
= RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
, &SourceString
, &Description
);
301 if (NT_SUCCESS(Status
))
302 Information
= (ULONG_PTR
)Description
.Buffer
;
305 case DeviceTextLocationInformation
:
307 /* We don't have any text location to report,
308 * and this query is optional, so ignore it.
310 Information
= Irp
->IoStatus
.Information
;
311 Status
= Irp
->IoStatus
.Status
;
316 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
317 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
318 Status
= STATUS_NOT_SUPPORTED
;
323 case IRP_MN_QUERY_ID
: /* 0x13 */
325 Status
= UsbMpPdoQueryId(DeviceObject
, Irp
, &Information
);
330 /* We can't forward request to the lower driver, because
331 * we are a Pdo, so we don't have lower driver...
333 DPRINT1("USBMP: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
334 Information
= Irp
->IoStatus
.Information
;
335 Status
= Irp
->IoStatus
.Status
;
339 Irp
->IoStatus
.Information
= Information
;
340 Irp
->IoStatus
.Status
= Status
;
341 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);