[WLAN-BRINGUP]
[reactos.git] / drivers / usb / usbhub / pdo.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: USB hub driver
4 * FILE: drivers/usb/cromwell/hub/pdo.c
5 * PURPOSE: IRP_MJ_PNP operations for PDOs
6 *
7 * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
8 * 2010 Michael Martin (michael.martin@reactos.org)
9 */
10
11 #define NDEBUG
12 #include <stdio.h>
13 #include "usbhub.h"
14
15 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
16
17 NTSTATUS
18 UsbhubInternalDeviceControlPdo(
19 IN PDEVICE_OBJECT DeviceObject,
20 IN PIRP Irp)
21 {
22 PIO_STACK_LOCATION Stack;
23 ULONG_PTR Information = 0;
24 NTSTATUS Status;
25
26 DPRINT1("Usbhub: UsbhubInternalDeviceControlPdo() called\n");
27
28 Stack = IoGetCurrentIrpStackLocation(Irp);
29 Status = Irp->IoStatus.Status;
30
31 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
32 {
33 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
34 {
35 PHUB_DEVICE_EXTENSION DeviceExtension;
36
37 DPRINT1("Usbhub: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
38 if (Irp->AssociatedIrp.SystemBuffer == NULL
39 || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
40 {
41 Status = STATUS_INVALID_PARAMETER;
42 }
43 else
44 {
45 PVOID* pHubPointer;
46 DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
47
48 pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
49 *pHubPointer = DeviceExtension->dev;
50 Information = sizeof(PVOID);
51 Status = STATUS_SUCCESS;
52 }
53 break;
54 }
55 default:
56 {
57 DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
58 Information = Irp->IoStatus.Information;
59 Status = Irp->IoStatus.Status;
60 }
61 }
62
63 Irp->IoStatus.Information = Information;
64 Irp->IoStatus.Status = Status;
65 IoCompleteRequest(Irp, IO_NO_INCREMENT);
66 return Status;
67 }
68
69 static NTSTATUS
70 UsbhubPdoStartDevice(
71 IN PDEVICE_OBJECT DeviceObject,
72 IN PIRP Irp)
73 {
74 PHUB_DEVICE_EXTENSION DeviceExtension;
75 NTSTATUS Status = STATUS_UNSUCCESSFUL;
76
77 DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
78
79 /* Register and activate device interface */
80 /*
81 Status = IoRegisterDeviceInterface(
82 DeviceObject,
83 DeviceExtension->dev->descriptor.bDeviceClass == USB_CLASS_HUB ?
84 &GUID_DEVINTERFACE_USB_HUB :
85 &GUID_DEVINTERFACE_USB_DEVICE,
86 NULL,
87 &DeviceExtension->SymbolicLinkName);
88 */
89 if (!NT_SUCCESS(Status))
90 {
91 DPRINT1("Usbhub: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
92 return Status;
93 }
94
95 //Status = IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, TRUE);
96 if (!NT_SUCCESS(Status))
97 {
98 DPRINT1("Usbhub: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
99 return Status;
100 }
101
102 return STATUS_SUCCESS;
103 }
104
105 static NTSTATUS
106 UsbhubPdoQueryId(
107 IN PDEVICE_OBJECT DeviceObject,
108 IN PIRP Irp,
109 OUT ULONG_PTR* Information)
110 {
111 PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
112 ULONG IdType;
113 PWCHAR SourceString = NULL;
114 NTSTATUS Status = STATUS_SUCCESS;
115
116 IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
117 DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
118
119 switch (IdType)
120 {
121 case BusQueryDeviceID:
122 {
123 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
124 SourceString = DeviceExtension->DeviceId;
125 break;
126 }
127 /* FIXME: Implement */
128 case BusQueryHardwareIDs:
129 {
130 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
131 SourceString = DeviceExtension->HardwareIds;
132 Status = STATUS_NOT_SUPPORTED;
133 break;
134 }
135 /* FIXME: Implement */
136 case BusQueryCompatibleIDs:
137 {
138 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
139 SourceString = DeviceExtension->CompatibleIds;
140 Status = STATUS_NOT_SUPPORTED;
141 break;
142 }
143 case BusQueryInstanceID:
144 {
145 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
146 SourceString = DeviceExtension->InstanceId;
147 break;
148 }
149 default:
150 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
151 return STATUS_NOT_SUPPORTED;
152 }
153
154 *Information = (ULONG_PTR)SourceString;
155 return Status;
156 }
157
158 static NTSTATUS
159 UsbhubPdoQueryDeviceText(
160 IN PDEVICE_OBJECT DeviceObject,
161 IN PIRP Irp,
162 OUT ULONG_PTR* Information)
163 {
164 PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
165 DEVICE_TEXT_TYPE DeviceTextType;
166 LCID LocaleId;
167
168 DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
169 LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
170 DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
171
172 switch (DeviceTextType)
173 {
174 case DeviceTextDescription:
175 case DeviceTextLocationInformation:
176 {
177 if (DeviceTextType == DeviceTextDescription)
178 {
179 *Information = (ULONG_PTR)DeviceExtension->TextDescription;
180 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
181 }
182 else
183 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
184
185 /* if (!DeviceExtension->dev->descriptor.iProduct)
186 return STATUS_NOT_SUPPORTED;*/
187
188 return STATUS_SUCCESS;
189 }
190 default:
191 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
192 return STATUS_NOT_SUPPORTED;
193 }
194 }
195
196 NTSTATUS NTAPI
197 UsbhubPnpPdo(
198 IN PDEVICE_OBJECT DeviceObject,
199 IN PIRP Irp)
200 {
201 ULONG MinorFunction;
202 PIO_STACK_LOCATION Stack;
203 ULONG_PTR Information = 0;
204 NTSTATUS Status;
205
206 Stack = IoGetCurrentIrpStackLocation(Irp);
207 MinorFunction = Stack->MinorFunction;
208
209 switch (MinorFunction)
210 {
211 case IRP_MN_START_DEVICE: /* 0x0 */
212 {
213 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
214 Status = UsbhubPdoStartDevice(DeviceObject, Irp);
215 break;
216 }
217 case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
218 {
219 PDEVICE_CAPABILITIES DeviceCapabilities;
220 ULONG i;
221 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
222
223 DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
224 /* FIXME: capabilities can change with connected device */
225 DeviceCapabilities->LockSupported = TRUE;
226 DeviceCapabilities->EjectSupported = FALSE;
227 DeviceCapabilities->Removable = FALSE;
228 DeviceCapabilities->DockDevice = FALSE;
229 DeviceCapabilities->UniqueID = FALSE;
230 DeviceCapabilities->SilentInstall = TRUE;
231 DeviceCapabilities->RawDeviceOK = FALSE;
232 DeviceCapabilities->SurpriseRemovalOK = FALSE;
233 DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
234 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
235 DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
236 for (i = 0; i < PowerSystemMaximum; i++)
237 DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
238 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
239 DeviceCapabilities->D1Latency = 0; /* FIXME */
240 DeviceCapabilities->D2Latency = 0; /* FIXME */
241 DeviceCapabilities->D3Latency = 0; /* FIXME */
242 Status = STATUS_SUCCESS;
243 break;
244 }
245 case IRP_MN_QUERY_RESOURCES: /* 0x0a */
246 {
247 PCM_RESOURCE_LIST ResourceList;
248
249 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
250 ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
251 if (!ResourceList)
252 {
253 DPRINT1("Usbhub: ExAllocatePool() failed\n");
254 Status = STATUS_INSUFFICIENT_RESOURCES;
255 }
256 else
257 {
258 ResourceList->Count = 0;
259 Information = (ULONG_PTR)ResourceList;
260 Status = STATUS_SUCCESS;
261 }
262 break;
263 }
264 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
265 {
266 PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
267
268 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
269 ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
270 if (!ResourceList)
271 {
272 DPRINT1("Usbhub: ExAllocatePool() failed\n");
273 Status = STATUS_INSUFFICIENT_RESOURCES;
274 }
275 else
276 {
277 RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
278 ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
279 ResourceList->AlternativeLists = 1;
280 ResourceList->List->Version = 1;
281 ResourceList->List->Revision = 1;
282 ResourceList->List->Count = 0;
283 Information = (ULONG_PTR)ResourceList;
284 Status = STATUS_SUCCESS;
285 }
286 break;
287 }
288 case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
289 {
290 Status = UsbhubPdoQueryDeviceText(DeviceObject, Irp, &Information);
291 break;
292 }
293 case IRP_MN_QUERY_ID: /* 0x13 */
294 {
295 Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
296 break;
297 }
298 default:
299 {
300 /* We can't forward request to the lower driver, because
301 * we are a Pdo, so we don't have lower driver...
302 */
303 DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
304 Information = Irp->IoStatus.Information;
305 Status = Irp->IoStatus.Status;
306 }
307 }
308
309 Irp->IoStatus.Information = Information;
310 Irp->IoStatus.Status = Status;
311 IoCompleteRequest(Irp, IO_NO_INCREMENT);
312 return Status;
313 }
314