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 USHORT Vendor
, Product
, Revision
;
109 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
111 Vendor
= DeviceExtension
->pdev
->vendor
;
112 Product
= DeviceExtension
->pdev
->device
;
113 Revision
= 0; /* FIXME */
115 sprintf(Buffer
[0], "USB\\VID%04X&PID%04X&REV%04X",
116 Vendor
, Product
, Revision
);
117 sprintf(Buffer
[1], "USB\\VID%04X&PID%04X",
119 if (roothub
->speed
== USB_SPEED_LOW
|| roothub
->speed
== USB_SPEED_FULL
)
120 RootHubName
= "USB\\ROOT_HUB"; /* USB 1.1 */
122 RootHubName
= "USB\\ROOT_HUB20"; /* USB 2.0 */
123 Status
= UsbMpInitMultiSzString(
125 Buffer
[0], Buffer
[1], RootHubName
, NULL
);
128 case BusQueryCompatibleIDs
:
129 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
130 /* No compatible ID */
132 return STATUS_NOT_SUPPORTED
;
133 case BusQueryInstanceID
:
135 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
136 RtlInitUnicodeString(&SourceString
, L
"0000"); /* FIXME */
140 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
141 return STATUS_NOT_SUPPORTED
;
144 if (NT_SUCCESS(Status
))
146 Status
= UsbMpDuplicateUnicodeString(
150 *Information
= (ULONG_PTR
)String
.Buffer
;
157 IN PDEVICE_OBJECT DeviceObject
)
159 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
162 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
164 /* Register device interface for root hub */
165 Status
= IoRegisterDeviceInterface(
167 &GUID_DEVINTERFACE_USB_HUB
,
169 &DeviceExtension
->HcdInterfaceName
);
170 if (!NT_SUCCESS(Status
))
172 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
181 IN PDEVICE_OBJECT DeviceObject
,
185 PIO_STACK_LOCATION Stack
;
186 ULONG_PTR Information
= 0;
189 Stack
= IoGetCurrentIrpStackLocation(Irp
);
190 MinorFunction
= Stack
->MinorFunction
;
192 switch (MinorFunction
)
194 case IRP_MN_START_DEVICE
: /* 0x00 */
196 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
197 Status
= UsbMpPnpStartDevice(DeviceObject
);
200 case IRP_MN_QUERY_CAPABILITIES
: /* 0x09 */
202 PDEVICE_CAPABILITIES DeviceCapabilities
;
204 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
206 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
207 /* FIXME: capabilities can change with connected device */
208 DeviceCapabilities
->LockSupported
= FALSE
;
209 DeviceCapabilities
->EjectSupported
= FALSE
;
210 DeviceCapabilities
->Removable
= FALSE
;
211 DeviceCapabilities
->DockDevice
= FALSE
;
212 DeviceCapabilities
->UniqueID
= FALSE
;
213 DeviceCapabilities
->SilentInstall
= TRUE
;
214 DeviceCapabilities
->RawDeviceOK
= FALSE
;
215 DeviceCapabilities
->SurpriseRemovalOK
= FALSE
;
216 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
217 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
218 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
219 for (i
= 0; i
< PowerSystemMaximum
; i
++)
220 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
221 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
222 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
223 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
224 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
225 Status
= STATUS_SUCCESS
;
228 case IRP_MN_QUERY_RESOURCES
: /* 0x0a */
230 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
231 /* Root buses don't need resources, except the ones of
232 * the usb controller. This PDO is the root bus PDO, so
233 * report no resource by not changing Information and
236 Information
= Irp
->IoStatus
.Information
;
237 Status
= Irp
->IoStatus
.Status
;
240 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0x0b */
242 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
243 /* Root buses don't need resources, except the ones of
244 * the usb controller. This PDO is the root bus PDO, so
245 * report no resource by not changing Information and
248 Information
= Irp
->IoStatus
.Information
;
249 Status
= Irp
->IoStatus
.Status
;
253 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0x0c */
255 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
257 case DeviceTextDescription
:
259 ULONG DescriptionSize
;
261 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
263 Status
= IoGetDeviceProperty(
265 DevicePropertyDeviceDescription
,
268 if (Status
== STATUS_BUFFER_TOO_SMALL
)
270 Description
= ExAllocatePool(PagedPool
, DescriptionSize
);
272 Status
= STATUS_INSUFFICIENT_RESOURCES
;
275 Status
= IoGetDeviceProperty(
277 DevicePropertyDeviceDescription
,
278 DescriptionSize
, Description
,
280 Information
= DescriptionSize
;
285 case DeviceTextLocationInformation
:
287 /* We don't have any text location to report,
288 * and this query is optional, so ignore it.
290 Information
= Irp
->IoStatus
.Information
;
291 Status
= Irp
->IoStatus
.Status
;
296 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
297 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
298 Status
= STATUS_NOT_SUPPORTED
;
304 case IRP_MN_QUERY_ID
: /* 0x13 */
306 Status
= UsbMpPdoQueryId(DeviceObject
, Irp
, &Information
);
311 /* We can't forward request to the lower driver, because
312 * we are a Pdo, so we don't have lower driver...
314 DPRINT1("USBMP: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
315 Information
= Irp
->IoStatus
.Information
;
316 Status
= Irp
->IoStatus
.Status
;
320 Irp
->IoStatus
.Information
= Information
;
321 Irp
->IoStatus
.Status
= Status
;
322 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);