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
= (PVOID
)DeviceExtension
->pdev
->bus
; /* struct usb_device* */
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
;
85 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
86 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
87 RtlInitUnicodeString(&String
, NULL
);
91 case BusQueryDeviceID
:
93 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
94 RtlInitUnicodeString(&SourceString
, L
"USB\\ROOT_HUB");
97 case BusQueryHardwareIDs
:
99 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
100 /* FIXME: Should return
101 USB\ROOT_HUB&VID????&PID????&REV????
102 USB\ROOT_HUB&VID????&PID????
105 UsbMpInitMultiSzString(&SourceString
, "USB\\ROOT_HUB", NULL
);
108 case BusQueryCompatibleIDs
:
109 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
110 /* No compatible ID */
112 return STATUS_NOT_SUPPORTED
;
113 case BusQueryInstanceID
:
115 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
116 RtlInitUnicodeString(&SourceString
, L
"0000"); /* FIXME */
120 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
121 return STATUS_NOT_SUPPORTED
;
124 Status
= UsbMpDuplicateUnicodeString(
128 *Information
= (ULONG_PTR
)String
.Buffer
;
134 IN PDEVICE_OBJECT DeviceObject
)
136 PUSBMP_DEVICE_EXTENSION DeviceExtension
;
139 DeviceExtension
= (PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
141 /* Register device interface for root hub */
142 Status
= IoRegisterDeviceInterface(
144 &GUID_DEVINTERFACE_USB_HUB
,
146 &DeviceExtension
->HcdInterfaceName
);
147 if (!NT_SUCCESS(Status
))
149 DPRINT("USBMP: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status
);
158 IN PDEVICE_OBJECT DeviceObject
,
162 PIO_STACK_LOCATION Stack
;
163 ULONG_PTR Information
= 0;
166 Stack
= IoGetCurrentIrpStackLocation(Irp
);
167 MinorFunction
= Stack
->MinorFunction
;
169 switch (MinorFunction
)
171 case IRP_MN_START_DEVICE
: /* 0x00 */
173 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
174 Status
= UsbMpPnpStartDevice(DeviceObject
);
177 case IRP_MN_QUERY_CAPABILITIES
: /* 0x09 */
179 PDEVICE_CAPABILITIES DeviceCapabilities
;
181 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
183 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
184 /* FIXME: capabilities can change with connected device */
185 DeviceCapabilities
->LockSupported
= FALSE
;
186 DeviceCapabilities
->EjectSupported
= FALSE
;
187 DeviceCapabilities
->Removable
= TRUE
;
188 DeviceCapabilities
->DockDevice
= FALSE
;
189 DeviceCapabilities
->UniqueID
= FALSE
;
190 DeviceCapabilities
->SilentInstall
= FALSE
;
191 DeviceCapabilities
->RawDeviceOK
= TRUE
;
192 DeviceCapabilities
->SurpriseRemovalOK
= TRUE
;
193 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
194 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
195 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
196 for (i
= 0; i
< PowerSystemMaximum
; i
++)
197 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
198 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
199 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
200 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
201 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
202 Status
= STATUS_SUCCESS
;
205 case IRP_MN_QUERY_RESOURCES
: /* 0x0a */
207 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
208 /* Root buses don't need resources, except the ones of
209 * the usb controller. This PDO is the root bus PDO, so
210 * report no resource by not changing Information and
213 Information
= Irp
->IoStatus
.Information
;
214 Status
= Irp
->IoStatus
.Status
;
217 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0x0b */
219 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
220 /* Root buses don't need resources, except the ones of
221 * the usb controller. This PDO is the root bus PDO, so
222 * report no resource by not changing Information and
225 Information
= Irp
->IoStatus
.Information
;
226 Status
= Irp
->IoStatus
.Status
;
230 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0x0c */
232 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
234 case DeviceTextDescription
:
236 ULONG DescriptionSize
;
238 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
240 Status
= IoGetDeviceProperty(
242 DevicePropertyDeviceDescription
,
245 if (Status
== STATUS_BUFFER_TOO_SMALL
)
247 Description
= ExAllocatePool(PagedPool
, DescriptionSize
);
249 Status
= STATUS_INSUFFICIENT_RESOURCES
;
252 Status
= IoGetDeviceProperty(
254 DevicePropertyDeviceDescription
,
255 DescriptionSize
, Description
,
257 Information
= DescriptionSize
;
262 case DeviceTextLocationInformation
:
264 /* We don't have any text location to report,
265 * and this query is optional, so ignore it.
267 Information
= Irp
->IoStatus
.Information
;
268 Status
= Irp
->IoStatus
.Status
;
273 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
274 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
275 Status
= STATUS_NOT_SUPPORTED
;
281 case IRP_MN_QUERY_ID
: /* 0x13 */
283 Status
= UsbMpPdoQueryId(DeviceObject
, Irp
, &Information
);
288 /* We can't forward request to the lower driver, because
289 * we are a Pdo, so we don't have lower driver...
291 DPRINT1("USBMP: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
292 Information
= Irp
->IoStatus
.Information
;
293 Status
= Irp
->IoStatus
.Status
;
297 Irp
->IoStatus
.Information
= Information
;
298 Irp
->IoStatus
.Status
= Status
;
299 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);