19bcd8350SThomas Faber #ifndef UNIT_TEST
2c2c66affSColin Finck #include "precomp.h"
3c2c66affSColin Finck
4c2c66affSColin Finck #include <initguid.h>
5c2c66affSColin Finck #include <poclass.h>
6c2c66affSColin Finck
7c2c66affSColin Finck #define NDEBUG
8c2c66affSColin Finck #include <debug.h>
9c2c66affSColin Finck
10c2c66affSColin Finck #ifdef ALLOC_PRAGMA
11c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_PnP)
12c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceCaps)
13c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceId)
14c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceText)
15c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryResources)
16c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryResourceRequirements)
17c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryDeviceRelations)
18c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_PDO_QueryBusInformation)
19c2c66affSColin Finck #pragma alloc_text (PAGE, Bus_GetDeviceCapabilities)
20c2c66affSColin Finck #endif
21c2c66affSColin Finck
22c2c66affSColin Finck NTSTATUS
Bus_PDO_PnP(PDEVICE_OBJECT DeviceObject,PIRP Irp,PIO_STACK_LOCATION IrpStack,PPDO_DEVICE_DATA DeviceData)23c2c66affSColin Finck Bus_PDO_PnP (
24c2c66affSColin Finck PDEVICE_OBJECT DeviceObject,
25c2c66affSColin Finck PIRP Irp,
26c2c66affSColin Finck PIO_STACK_LOCATION IrpStack,
27c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData
28c2c66affSColin Finck )
29c2c66affSColin Finck {
30c2c66affSColin Finck NTSTATUS status;
31c2c66affSColin Finck POWER_STATE state;
32c2c66affSColin Finck struct acpi_device *device = NULL;
33c2c66affSColin Finck
34c2c66affSColin Finck PAGED_CODE ();
35c2c66affSColin Finck
36c2c66affSColin Finck if (DeviceData->AcpiHandle)
37c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &device);
38c2c66affSColin Finck
39c2c66affSColin Finck //
40c2c66affSColin Finck // NB: Because we are a bus enumerator, we have no one to whom we could
41c2c66affSColin Finck // defer these irps. Therefore we do not pass them down but merely
42c2c66affSColin Finck // return them.
43c2c66affSColin Finck //
44c2c66affSColin Finck
45c2c66affSColin Finck switch (IrpStack->MinorFunction) {
46c2c66affSColin Finck
47c2c66affSColin Finck case IRP_MN_START_DEVICE:
48c2c66affSColin Finck //
49c2c66affSColin Finck // Here we do what ever initialization and ``turning on'' that is
50c2c66affSColin Finck // required to allow others to access this device.
51c2c66affSColin Finck // Power up the device.
52c2c66affSColin Finck //
53c2c66affSColin Finck if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) &&
54c2c66affSColin Finck !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D0)))
55c2c66affSColin Finck {
56c2c66affSColin Finck DPRINT1("Device %x failed to start!\n", DeviceData->AcpiHandle);
57c2c66affSColin Finck status = STATUS_UNSUCCESSFUL;
58c2c66affSColin Finck break;
59c2c66affSColin Finck }
60c2c66affSColin Finck
61c2c66affSColin Finck DeviceData->InterfaceName.Length = 0;
62c2c66affSColin Finck status = STATUS_SUCCESS;
63c2c66affSColin Finck
64c2c66affSColin Finck if (!device)
65c2c66affSColin Finck {
66c2c66affSColin Finck status = IoRegisterDeviceInterface(DeviceData->Common.Self,
67c2c66affSColin Finck &GUID_DEVICE_SYS_BUTTON,
68c2c66affSColin Finck NULL,
69c2c66affSColin Finck &DeviceData->InterfaceName);
70c2c66affSColin Finck }
71c2c66affSColin Finck else if (device->flags.hardware_id &&
72c2c66affSColin Finck strstr(device->pnp.hardware_id, ACPI_THERMAL_HID))
73c2c66affSColin Finck {
74c2c66affSColin Finck status = IoRegisterDeviceInterface(DeviceData->Common.Self,
75c2c66affSColin Finck &GUID_DEVICE_THERMAL_ZONE,
76c2c66affSColin Finck NULL,
77c2c66affSColin Finck &DeviceData->InterfaceName);
78c2c66affSColin Finck }
79c2c66affSColin Finck else if (device->flags.hardware_id &&
80*f69e2563SGeorge Bișoc strstr(device->pnp.hardware_id, ACPI_FAN_HID))
81*f69e2563SGeorge Bișoc {
82*f69e2563SGeorge Bișoc status = IoRegisterDeviceInterface(DeviceData->Common.Self,
83*f69e2563SGeorge Bișoc &GUID_DEVICE_FAN,
84*f69e2563SGeorge Bișoc NULL,
85*f69e2563SGeorge Bișoc &DeviceData->InterfaceName);
86*f69e2563SGeorge Bișoc }
87*f69e2563SGeorge Bișoc else if (device->flags.hardware_id &&
88c2c66affSColin Finck strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID))
89c2c66affSColin Finck {
90c2c66affSColin Finck status = IoRegisterDeviceInterface(DeviceData->Common.Self,
91c2c66affSColin Finck &GUID_DEVICE_LID,
92c2c66affSColin Finck NULL,
93c2c66affSColin Finck &DeviceData->InterfaceName);
94c2c66affSColin Finck }
95c2c66affSColin Finck else if (device->flags.hardware_id &&
96c2c66affSColin Finck strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID))
97c2c66affSColin Finck {
98c2c66affSColin Finck status = IoRegisterDeviceInterface(DeviceData->Common.Self,
99c2c66affSColin Finck &GUID_DEVICE_PROCESSOR,
100c2c66affSColin Finck NULL,
101c2c66affSColin Finck &DeviceData->InterfaceName);
102c2c66affSColin Finck }
103c2c66affSColin Finck
104c2c66affSColin Finck /* Failure to register an interface is not a fatal failure so don't return a failure status */
105c2c66affSColin Finck if (NT_SUCCESS(status) && DeviceData->InterfaceName.Length != 0)
106c2c66affSColin Finck IoSetDeviceInterfaceState(&DeviceData->InterfaceName, TRUE);
107c2c66affSColin Finck
108c2c66affSColin Finck state.DeviceState = PowerDeviceD0;
109c2c66affSColin Finck PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state);
110c2c66affSColin Finck DeviceData->Common.DevicePowerState = PowerDeviceD0;
111c2c66affSColin Finck SET_NEW_PNP_STATE(DeviceData->Common, Started);
112c2c66affSColin Finck status = STATUS_SUCCESS;
113c2c66affSColin Finck break;
114c2c66affSColin Finck
115c2c66affSColin Finck case IRP_MN_STOP_DEVICE:
116c2c66affSColin Finck
117c2c66affSColin Finck if (DeviceData->InterfaceName.Length != 0)
118c2c66affSColin Finck IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE);
119c2c66affSColin Finck
120c2c66affSColin Finck //
121c2c66affSColin Finck // Here we shut down the device and give up and unmap any resources
122c2c66affSColin Finck // we acquired for the device.
123c2c66affSColin Finck //
124c2c66affSColin Finck if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) &&
125c2c66affSColin Finck !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3)))
126c2c66affSColin Finck {
127c2c66affSColin Finck DPRINT1("Device %x failed to stop!\n", DeviceData->AcpiHandle);
128c2c66affSColin Finck status = STATUS_UNSUCCESSFUL;
129c2c66affSColin Finck break;
130c2c66affSColin Finck }
131c2c66affSColin Finck
132c2c66affSColin Finck state.DeviceState = PowerDeviceD3;
133c2c66affSColin Finck PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state);
134c2c66affSColin Finck DeviceData->Common.DevicePowerState = PowerDeviceD3;
135c2c66affSColin Finck SET_NEW_PNP_STATE(DeviceData->Common, Stopped);
136c2c66affSColin Finck status = STATUS_SUCCESS;
137c2c66affSColin Finck break;
138c2c66affSColin Finck
139c2c66affSColin Finck
140c2c66affSColin Finck case IRP_MN_QUERY_STOP_DEVICE:
141c2c66affSColin Finck
142c2c66affSColin Finck //
143c2c66affSColin Finck // No reason here why we can't stop the device.
144c2c66affSColin Finck // If there were a reason we should speak now, because answering success
145c2c66affSColin Finck // here may result in a stop device irp.
146c2c66affSColin Finck //
147c2c66affSColin Finck
148c2c66affSColin Finck SET_NEW_PNP_STATE(DeviceData->Common, StopPending);
149c2c66affSColin Finck status = STATUS_SUCCESS;
150c2c66affSColin Finck break;
151c2c66affSColin Finck
152c2c66affSColin Finck case IRP_MN_CANCEL_STOP_DEVICE:
153c2c66affSColin Finck
154c2c66affSColin Finck //
155c2c66affSColin Finck // The stop was canceled. Whatever state we set, or resources we put
156c2c66affSColin Finck // on hold in anticipation of the forthcoming STOP device IRP should be
157c2c66affSColin Finck // put back to normal. Someone, in the long list of concerned parties,
158c2c66affSColin Finck // has failed the stop device query.
159c2c66affSColin Finck //
160c2c66affSColin Finck
161c2c66affSColin Finck //
162c2c66affSColin Finck // First check to see whether you have received cancel-stop
163c2c66affSColin Finck // without first receiving a query-stop. This could happen if someone
164c2c66affSColin Finck // above us fails a query-stop and passes down the subsequent
165c2c66affSColin Finck // cancel-stop.
166c2c66affSColin Finck //
167c2c66affSColin Finck
168c2c66affSColin Finck if (StopPending == DeviceData->Common.DevicePnPState)
169c2c66affSColin Finck {
170c2c66affSColin Finck //
171c2c66affSColin Finck // We did receive a query-stop, so restore.
172c2c66affSColin Finck //
173c2c66affSColin Finck RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common);
174c2c66affSColin Finck }
175c2c66affSColin Finck status = STATUS_SUCCESS;// We must not fail this IRP.
176c2c66affSColin Finck break;
177c2c66affSColin Finck
178c2c66affSColin Finck case IRP_MN_REMOVE_DEVICE:
179c2c66affSColin Finck //
180c2c66affSColin Finck // We handle REMOVE_DEVICE just like STOP_DEVICE. This is because
181c2c66affSColin Finck // the device is still physically present (or at least we don't know any better)
182c2c66affSColin Finck // so we have to retain the PDO after stopping and removing power from it.
183c2c66affSColin Finck //
184c2c66affSColin Finck if (DeviceData->InterfaceName.Length != 0)
185c2c66affSColin Finck IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE);
186c2c66affSColin Finck
187c2c66affSColin Finck if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) &&
188c2c66affSColin Finck !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3)))
189c2c66affSColin Finck {
190c2c66affSColin Finck DPRINT1("Device %x failed to enter D3!\n", DeviceData->AcpiHandle);
191c2c66affSColin Finck state.DeviceState = PowerDeviceD3;
192c2c66affSColin Finck PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state);
193c2c66affSColin Finck DeviceData->Common.DevicePowerState = PowerDeviceD3;
194c2c66affSColin Finck }
195c2c66affSColin Finck
196c2c66affSColin Finck SET_NEW_PNP_STATE(DeviceData->Common, Stopped);
197c2c66affSColin Finck status = STATUS_SUCCESS;
198c2c66affSColin Finck break;
199c2c66affSColin Finck
200c2c66affSColin Finck case IRP_MN_QUERY_REMOVE_DEVICE:
201c2c66affSColin Finck SET_NEW_PNP_STATE(DeviceData->Common, RemovalPending);
202c2c66affSColin Finck status = STATUS_SUCCESS;
203c2c66affSColin Finck break;
204c2c66affSColin Finck
205c2c66affSColin Finck case IRP_MN_CANCEL_REMOVE_DEVICE:
206c2c66affSColin Finck if (RemovalPending == DeviceData->Common.DevicePnPState)
207c2c66affSColin Finck {
208c2c66affSColin Finck RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common);
209c2c66affSColin Finck }
210c2c66affSColin Finck status = STATUS_SUCCESS;
211c2c66affSColin Finck break;
212c2c66affSColin Finck
213c2c66affSColin Finck case IRP_MN_QUERY_CAPABILITIES:
214c2c66affSColin Finck
215c2c66affSColin Finck //
216c2c66affSColin Finck // Return the capabilities of a device, such as whether the device
217c2c66affSColin Finck // can be locked or ejected..etc
218c2c66affSColin Finck //
219c2c66affSColin Finck
220c2c66affSColin Finck status = Bus_PDO_QueryDeviceCaps(DeviceData, Irp);
221c2c66affSColin Finck
222c2c66affSColin Finck break;
223c2c66affSColin Finck
224c2c66affSColin Finck case IRP_MN_QUERY_ID:
225c2c66affSColin Finck
226c2c66affSColin Finck // Query the IDs of the device
227c2c66affSColin Finck status = Bus_PDO_QueryDeviceId(DeviceData, Irp);
228c2c66affSColin Finck
229c2c66affSColin Finck break;
230c2c66affSColin Finck
231c2c66affSColin Finck case IRP_MN_QUERY_DEVICE_RELATIONS:
232c2c66affSColin Finck
233c2c66affSColin Finck DPRINT("\tQueryDeviceRelation Type: %s\n",DbgDeviceRelationString(\
234c2c66affSColin Finck IrpStack->Parameters.QueryDeviceRelations.Type));
235c2c66affSColin Finck
236c2c66affSColin Finck status = Bus_PDO_QueryDeviceRelations(DeviceData, Irp);
237c2c66affSColin Finck
238c2c66affSColin Finck break;
239c2c66affSColin Finck
240c2c66affSColin Finck case IRP_MN_QUERY_DEVICE_TEXT:
241c2c66affSColin Finck
242c2c66affSColin Finck status = Bus_PDO_QueryDeviceText(DeviceData, Irp);
243c2c66affSColin Finck
244c2c66affSColin Finck break;
245c2c66affSColin Finck
246c2c66affSColin Finck case IRP_MN_QUERY_RESOURCES:
247c2c66affSColin Finck
248c2c66affSColin Finck status = Bus_PDO_QueryResources(DeviceData, Irp);
249c2c66affSColin Finck
250c2c66affSColin Finck break;
251c2c66affSColin Finck
252c2c66affSColin Finck case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
253c2c66affSColin Finck
254c2c66affSColin Finck status = Bus_PDO_QueryResourceRequirements(DeviceData, Irp);
255c2c66affSColin Finck
256c2c66affSColin Finck break;
257c2c66affSColin Finck
258c2c66affSColin Finck case IRP_MN_QUERY_BUS_INFORMATION:
259c2c66affSColin Finck
260c2c66affSColin Finck status = Bus_PDO_QueryBusInformation(DeviceData, Irp);
261c2c66affSColin Finck
262c2c66affSColin Finck break;
263c2c66affSColin Finck
264c2c66affSColin Finck case IRP_MN_QUERY_INTERFACE:
265c2c66affSColin Finck
266c2c66affSColin Finck status = Bus_PDO_QueryInterface(DeviceData, Irp);
267c2c66affSColin Finck
268c2c66affSColin Finck break;
269c2c66affSColin Finck
270c2c66affSColin Finck
271c2c66affSColin Finck case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
272c2c66affSColin Finck
273c2c66affSColin Finck //
274c2c66affSColin Finck // OPTIONAL for bus drivers.
275c2c66affSColin Finck // The PnP Manager sends this IRP to a device
276c2c66affSColin Finck // stack so filter and function drivers can adjust the
277c2c66affSColin Finck // resources required by the device, if appropriate.
278c2c66affSColin Finck //
279c2c66affSColin Finck
280c2c66affSColin Finck //break;
281c2c66affSColin Finck
282c2c66affSColin Finck //case IRP_MN_QUERY_PNP_DEVICE_STATE:
283c2c66affSColin Finck
284c2c66affSColin Finck //
285c2c66affSColin Finck // OPTIONAL for bus drivers.
286c2c66affSColin Finck // The PnP Manager sends this IRP after the drivers for
287c2c66affSColin Finck // a device return success from the IRP_MN_START_DEVICE
288c2c66affSColin Finck // request. The PnP Manager also sends this IRP when a
289c2c66affSColin Finck // driver for the device calls IoInvalidateDeviceState.
290c2c66affSColin Finck //
291c2c66affSColin Finck
292c2c66affSColin Finck // break;
293c2c66affSColin Finck
294c2c66affSColin Finck //case IRP_MN_READ_CONFIG:
295c2c66affSColin Finck //case IRP_MN_WRITE_CONFIG:
296c2c66affSColin Finck
297c2c66affSColin Finck //
298c2c66affSColin Finck // Bus drivers for buses with configuration space must handle
299c2c66affSColin Finck // this request for their child devices. Our devices don't
300c2c66affSColin Finck // have a config space.
301c2c66affSColin Finck //
302c2c66affSColin Finck
303c2c66affSColin Finck // break;
304c2c66affSColin Finck
305c2c66affSColin Finck //case IRP_MN_SET_LOCK:
306c2c66affSColin Finck
307c2c66affSColin Finck // break;
308c2c66affSColin Finck
309c2c66affSColin Finck default:
310c2c66affSColin Finck
311c2c66affSColin Finck //
312c2c66affSColin Finck // For PnP requests to the PDO that we do not understand we should
313c2c66affSColin Finck // return the IRP WITHOUT setting the status or information fields.
314c2c66affSColin Finck // These fields may have already been set by a filter (eg acpi).
315c2c66affSColin Finck status = Irp->IoStatus.Status;
316c2c66affSColin Finck
317c2c66affSColin Finck break;
318c2c66affSColin Finck }
319c2c66affSColin Finck
320c2c66affSColin Finck Irp->IoStatus.Status = status;
321c2c66affSColin Finck IoCompleteRequest (Irp, IO_NO_INCREMENT);
322c2c66affSColin Finck
323c2c66affSColin Finck return status;
324c2c66affSColin Finck }
325c2c66affSColin Finck
326c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryDeviceCaps(PPDO_DEVICE_DATA DeviceData,PIRP Irp)327c2c66affSColin Finck Bus_PDO_QueryDeviceCaps(
328c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
329c2c66affSColin Finck PIRP Irp )
330c2c66affSColin Finck {
331c2c66affSColin Finck
332c2c66affSColin Finck PIO_STACK_LOCATION stack;
333c2c66affSColin Finck PDEVICE_CAPABILITIES deviceCapabilities;
334c2c66affSColin Finck struct acpi_device *device = NULL;
335c2c66affSColin Finck ULONG i;
336c2c66affSColin Finck
337c2c66affSColin Finck PAGED_CODE ();
338c2c66affSColin Finck
339c2c66affSColin Finck if (DeviceData->AcpiHandle)
340c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &device);
341c2c66affSColin Finck
342c2c66affSColin Finck stack = IoGetCurrentIrpStackLocation (Irp);
343c2c66affSColin Finck
344c2c66affSColin Finck //
345c2c66affSColin Finck // Get the packet.
346c2c66affSColin Finck //
347c2c66affSColin Finck deviceCapabilities=stack->Parameters.DeviceCapabilities.Capabilities;
348c2c66affSColin Finck
349c2c66affSColin Finck //
350c2c66affSColin Finck // Set the capabilities.
351c2c66affSColin Finck //
352c2c66affSColin Finck
353c2c66affSColin Finck if (deviceCapabilities->Version != 1 ||
354c2c66affSColin Finck deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
355c2c66affSColin Finck {
356c2c66affSColin Finck return STATUS_UNSUCCESSFUL;
357c2c66affSColin Finck }
358c2c66affSColin Finck
359c2c66affSColin Finck deviceCapabilities->D1Latency = 0;
360c2c66affSColin Finck deviceCapabilities->D2Latency = 0;
361c2c66affSColin Finck deviceCapabilities->D3Latency = 0;
362c2c66affSColin Finck
363c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
364c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
365c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
366c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
367c2c66affSColin Finck
368c2c66affSColin Finck for (i = 0; i < ACPI_D_STATE_COUNT && device; i++)
369c2c66affSColin Finck {
370c2c66affSColin Finck if (!device->power.states[i].flags.valid)
371c2c66affSColin Finck continue;
372c2c66affSColin Finck
373c2c66affSColin Finck switch (i)
374c2c66affSColin Finck {
375c2c66affSColin Finck case ACPI_STATE_D0:
376c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
377c2c66affSColin Finck break;
378c2c66affSColin Finck
379c2c66affSColin Finck case ACPI_STATE_D1:
380c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
381c2c66affSColin Finck deviceCapabilities->D1Latency = device->power.states[i].latency;
382c2c66affSColin Finck break;
383c2c66affSColin Finck
384c2c66affSColin Finck case ACPI_STATE_D2:
385c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
386c2c66affSColin Finck deviceCapabilities->D2Latency = device->power.states[i].latency;
387c2c66affSColin Finck break;
388c2c66affSColin Finck
389c2c66affSColin Finck case ACPI_STATE_D3:
390c2c66affSColin Finck deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
391c2c66affSColin Finck deviceCapabilities->D3Latency = device->power.states[i].latency;
392c2c66affSColin Finck break;
393c2c66affSColin Finck }
394c2c66affSColin Finck }
395c2c66affSColin Finck
396c2c66affSColin Finck // We can wake the system from D1
397c2c66affSColin Finck deviceCapabilities->DeviceWake = PowerDeviceD1;
398c2c66affSColin Finck
399c2c66affSColin Finck
400c2c66affSColin Finck deviceCapabilities->DeviceD1 =
401c2c66affSColin Finck (deviceCapabilities->DeviceState[PowerSystemSleeping1] == PowerDeviceD1) ? TRUE : FALSE;
402c2c66affSColin Finck deviceCapabilities->DeviceD2 =
403c2c66affSColin Finck (deviceCapabilities->DeviceState[PowerSystemSleeping2] == PowerDeviceD2) ? TRUE : FALSE;
404c2c66affSColin Finck
405c2c66affSColin Finck deviceCapabilities->WakeFromD0 = FALSE;
406c2c66affSColin Finck deviceCapabilities->WakeFromD1 = TRUE; //Yes we can
407c2c66affSColin Finck deviceCapabilities->WakeFromD2 = FALSE;
408c2c66affSColin Finck deviceCapabilities->WakeFromD3 = FALSE;
409c2c66affSColin Finck
410c2c66affSColin Finck if (device)
411c2c66affSColin Finck {
412c2c66affSColin Finck deviceCapabilities->LockSupported = device->flags.lockable;
413c2c66affSColin Finck deviceCapabilities->EjectSupported = device->flags.ejectable;
414c2c66affSColin Finck deviceCapabilities->HardwareDisabled = !device->status.enabled && !device->status.functional;
415c2c66affSColin Finck deviceCapabilities->Removable = device->flags.removable;
416c2c66affSColin Finck deviceCapabilities->SurpriseRemovalOK = device->flags.surprise_removal_ok;
417c2c66affSColin Finck deviceCapabilities->UniqueID = device->flags.unique_id;
418c2c66affSColin Finck deviceCapabilities->NoDisplayInUI = !device->status.show_in_ui;
419c2c66affSColin Finck deviceCapabilities->Address = device->pnp.bus_address;
420c2c66affSColin Finck }
421c2c66affSColin Finck
422c2c66affSColin Finck if (!device ||
423c2c66affSColin Finck (device->flags.hardware_id &&
424c2c66affSColin Finck (strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID) ||
425c2c66affSColin Finck strstr(device->pnp.hardware_id, ACPI_THERMAL_HID) ||
426c2c66affSColin Finck strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID))))
427c2c66affSColin Finck {
428c2c66affSColin Finck /* Allow ACPI to control the device if it is a lid button,
429c2c66affSColin Finck * a thermal zone, a processor, or a fixed feature button */
430c2c66affSColin Finck deviceCapabilities->RawDeviceOK = TRUE;
431c2c66affSColin Finck }
432c2c66affSColin Finck
433c2c66affSColin Finck deviceCapabilities->SilentInstall = FALSE;
434c2c66affSColin Finck deviceCapabilities->UINumber = (ULONG)-1;
435c2c66affSColin Finck
436c2c66affSColin Finck return STATUS_SUCCESS;
437c2c66affSColin Finck
438c2c66affSColin Finck }
439c2c66affSColin Finck
440c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryDeviceId(PPDO_DEVICE_DATA DeviceData,PIRP Irp)441c2c66affSColin Finck Bus_PDO_QueryDeviceId(
442c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
443c2c66affSColin Finck PIRP Irp )
444c2c66affSColin Finck {
445c2c66affSColin Finck PIO_STACK_LOCATION stack;
446c2c66affSColin Finck PWCHAR buffer, src;
447c2c66affSColin Finck WCHAR temp[256];
448c2c66affSColin Finck ULONG length, i;
449c2c66affSColin Finck NTSTATUS status = STATUS_SUCCESS;
450c2c66affSColin Finck struct acpi_device *Device;
451c2c66affSColin Finck
452c2c66affSColin Finck PAGED_CODE ();
453c2c66affSColin Finck
454c2c66affSColin Finck stack = IoGetCurrentIrpStackLocation (Irp);
455c2c66affSColin Finck
456c2c66affSColin Finck switch (stack->Parameters.QueryId.IdType) {
457c2c66affSColin Finck
458c2c66affSColin Finck case BusQueryDeviceID:
459c2c66affSColin Finck
460c2c66affSColin Finck /* This is a REG_SZ value */
461c2c66affSColin Finck
462c2c66affSColin Finck if (DeviceData->AcpiHandle)
463c2c66affSColin Finck {
464c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &Device);
465c2c66affSColin Finck
466c2c66affSColin Finck if (strcmp(Device->pnp.hardware_id, "Processor") == 0)
467c2c66affSColin Finck {
468c2c66affSColin Finck length = wcslen(ProcessorIdString);
469c2c66affSColin Finck wcscpy(temp, ProcessorIdString);
470c2c66affSColin Finck }
471c2c66affSColin Finck else
472c2c66affSColin Finck {
473c2c66affSColin Finck length = swprintf(temp,
474c2c66affSColin Finck L"ACPI\\%hs",
475c2c66affSColin Finck Device->pnp.hardware_id);
476c2c66affSColin Finck }
477c2c66affSColin Finck }
478c2c66affSColin Finck else
479c2c66affSColin Finck {
480c2c66affSColin Finck /* We know it's a fixed feature button because
481c2c66affSColin Finck * these are direct children of the ACPI root device
482c2c66affSColin Finck * and therefore have no handle
483c2c66affSColin Finck */
484c2c66affSColin Finck length = swprintf(temp,
485c2c66affSColin Finck L"ACPI\\FixedButton");
486c2c66affSColin Finck }
487c2c66affSColin Finck
488c2c66affSColin Finck temp[length++] = UNICODE_NULL;
489c2c66affSColin Finck
490c2c66affSColin Finck NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp));
491c2c66affSColin Finck
492c2c66affSColin Finck buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA');
493c2c66affSColin Finck
494c2c66affSColin Finck if (!buffer) {
495c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
496c2c66affSColin Finck break;
497c2c66affSColin Finck }
498c2c66affSColin Finck
499c2c66affSColin Finck RtlCopyMemory (buffer, temp, length * sizeof(WCHAR));
500c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) buffer;
501c2c66affSColin Finck DPRINT("BusQueryDeviceID: %ls\n",buffer);
502c2c66affSColin Finck break;
503c2c66affSColin Finck
504c2c66affSColin Finck case BusQueryInstanceID:
505c2c66affSColin Finck
506c2c66affSColin Finck /* This is a REG_SZ value */
507c2c66affSColin Finck
508c2c66affSColin Finck /* See comment in BusQueryDeviceID case */
509c2c66affSColin Finck if(DeviceData->AcpiHandle)
510c2c66affSColin Finck {
511c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &Device);
512c2c66affSColin Finck
513c2c66affSColin Finck if (Device->flags.unique_id)
514c2c66affSColin Finck length = swprintf(temp,
515c2c66affSColin Finck L"%hs",
516c2c66affSColin Finck Device->pnp.unique_id);
517c2c66affSColin Finck else
518c2c66affSColin Finck /* FIXME: Generate unique id! */
5192183e65cSHermès Bélusca-Maïto length = swprintf(temp, L"%ls", L"0");
520c2c66affSColin Finck }
521c2c66affSColin Finck else
522c2c66affSColin Finck {
523c2c66affSColin Finck /* FIXME: Generate unique id! */
5242183e65cSHermès Bélusca-Maïto length = swprintf(temp, L"%ls", L"0");
525c2c66affSColin Finck }
526c2c66affSColin Finck
527c2c66affSColin Finck temp[length++] = UNICODE_NULL;
528c2c66affSColin Finck
529c2c66affSColin Finck NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp));
530c2c66affSColin Finck
531c2c66affSColin Finck buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA');
532c2c66affSColin Finck if (!buffer) {
533c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
534c2c66affSColin Finck break;
535c2c66affSColin Finck }
536c2c66affSColin Finck
537c2c66affSColin Finck RtlCopyMemory (buffer, temp, length * sizeof (WCHAR));
538c2c66affSColin Finck DPRINT("BusQueryInstanceID: %ls\n",buffer);
539c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) buffer;
540c2c66affSColin Finck break;
541c2c66affSColin Finck
542c2c66affSColin Finck case BusQueryHardwareIDs:
543c2c66affSColin Finck
544c2c66affSColin Finck /* This is a REG_MULTI_SZ value */
545c2c66affSColin Finck length = 0;
546c2c66affSColin Finck status = STATUS_NOT_SUPPORTED;
547c2c66affSColin Finck
548c2c66affSColin Finck /* See comment in BusQueryDeviceID case */
549c2c66affSColin Finck if (DeviceData->AcpiHandle)
550c2c66affSColin Finck {
551c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &Device);
552c2c66affSColin Finck
553c2c66affSColin Finck if (!Device->flags.hardware_id)
554c2c66affSColin Finck {
555c2c66affSColin Finck /* We don't have the ID to satisfy this request */
556c2c66affSColin Finck break;
557c2c66affSColin Finck }
558c2c66affSColin Finck
559c2c66affSColin Finck DPRINT("Device name: %s\n", Device->pnp.device_name);
560c2c66affSColin Finck DPRINT("Hardware ID: %s\n", Device->pnp.hardware_id);
561c2c66affSColin Finck
562c2c66affSColin Finck if (strcmp(Device->pnp.hardware_id, "Processor") == 0)
563c2c66affSColin Finck {
564c2c66affSColin Finck length = ProcessorHardwareIds.Length / sizeof(WCHAR);
565c2c66affSColin Finck src = ProcessorHardwareIds.Buffer;
566c2c66affSColin Finck }
567c2c66affSColin Finck else
568c2c66affSColin Finck {
569c2c66affSColin Finck length += swprintf(&temp[length],
570c2c66affSColin Finck L"ACPI\\%hs",
571c2c66affSColin Finck Device->pnp.hardware_id);
572c2c66affSColin Finck temp[length++] = UNICODE_NULL;
573c2c66affSColin Finck
574c2c66affSColin Finck length += swprintf(&temp[length],
575c2c66affSColin Finck L"*%hs",
576c2c66affSColin Finck Device->pnp.hardware_id);
577c2c66affSColin Finck temp[length++] = UNICODE_NULL;
578c2c66affSColin Finck temp[length++] = UNICODE_NULL;
579c2c66affSColin Finck src = temp;
580c2c66affSColin Finck }
581c2c66affSColin Finck }
582c2c66affSColin Finck else
583c2c66affSColin Finck {
584c2c66affSColin Finck length += swprintf(&temp[length],
585c2c66affSColin Finck L"ACPI\\FixedButton");
586c2c66affSColin Finck temp[length++] = UNICODE_NULL;
587c2c66affSColin Finck
588c2c66affSColin Finck length += swprintf(&temp[length],
589c2c66affSColin Finck L"*FixedButton");
590c2c66affSColin Finck temp[length++] = UNICODE_NULL;
591c2c66affSColin Finck temp[length++] = UNICODE_NULL;
592c2c66affSColin Finck src = temp;
593c2c66affSColin Finck }
594c2c66affSColin Finck
595c2c66affSColin Finck NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp));
596c2c66affSColin Finck
597c2c66affSColin Finck buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA');
598c2c66affSColin Finck
599c2c66affSColin Finck if (!buffer) {
600c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
601c2c66affSColin Finck break;
602c2c66affSColin Finck }
603c2c66affSColin Finck
604c2c66affSColin Finck RtlCopyMemory (buffer, src, length * sizeof(WCHAR));
605c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) buffer;
606c2c66affSColin Finck DPRINT("BusQueryHardwareIDs: %ls\n",buffer);
607c2c66affSColin Finck status = STATUS_SUCCESS;
608c2c66affSColin Finck break;
609c2c66affSColin Finck
610c2c66affSColin Finck case BusQueryCompatibleIDs:
611c2c66affSColin Finck
612c2c66affSColin Finck /* This is a REG_MULTI_SZ value */
613c2c66affSColin Finck length = 0;
614c2c66affSColin Finck status = STATUS_NOT_SUPPORTED;
615c2c66affSColin Finck
616c2c66affSColin Finck /* See comment in BusQueryDeviceID case */
617c2c66affSColin Finck if (DeviceData->AcpiHandle)
618c2c66affSColin Finck {
619c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &Device);
620c2c66affSColin Finck
621c2c66affSColin Finck if (!Device->flags.hardware_id)
622c2c66affSColin Finck {
623c2c66affSColin Finck /* We don't have the ID to satisfy this request */
624c2c66affSColin Finck break;
625c2c66affSColin Finck }
626c2c66affSColin Finck
627c2c66affSColin Finck DPRINT("Device name: %s\n", Device->pnp.device_name);
628c2c66affSColin Finck DPRINT("Hardware ID: %s\n", Device->pnp.hardware_id);
629c2c66affSColin Finck
630c2c66affSColin Finck if (strcmp(Device->pnp.hardware_id, "Processor") == 0)
631c2c66affSColin Finck {
632c2c66affSColin Finck length += swprintf(&temp[length],
633c2c66affSColin Finck L"ACPI\\%hs",
634c2c66affSColin Finck Device->pnp.hardware_id);
635c2c66affSColin Finck temp[length++] = UNICODE_NULL;
636c2c66affSColin Finck
637c2c66affSColin Finck length += swprintf(&temp[length],
638c2c66affSColin Finck L"*%hs",
639c2c66affSColin Finck Device->pnp.hardware_id);
640c2c66affSColin Finck temp[length++] = UNICODE_NULL;
641c2c66affSColin Finck temp[length++] = UNICODE_NULL;
642c2c66affSColin Finck }
643c2c66affSColin Finck else if (Device->flags.compatible_ids)
644c2c66affSColin Finck {
645c2c66affSColin Finck for (i = 0; i < Device->pnp.cid_list->Count; i++)
646c2c66affSColin Finck {
647c2c66affSColin Finck length += swprintf(&temp[length],
648c2c66affSColin Finck L"ACPI\\%hs",
649c2c66affSColin Finck Device->pnp.cid_list->Ids[i].String);
650c2c66affSColin Finck temp[length++] = UNICODE_NULL;
651c2c66affSColin Finck
652c2c66affSColin Finck length += swprintf(&temp[length],
653c2c66affSColin Finck L"*%hs",
654c2c66affSColin Finck Device->pnp.cid_list->Ids[i].String);
655c2c66affSColin Finck temp[length++] = UNICODE_NULL;
656c2c66affSColin Finck }
657c2c66affSColin Finck
658c2c66affSColin Finck temp[length++] = UNICODE_NULL;
659c2c66affSColin Finck }
660c2c66affSColin Finck else
661c2c66affSColin Finck {
662c2c66affSColin Finck /* No compatible IDs */
663c2c66affSColin Finck break;
664c2c66affSColin Finck }
665c2c66affSColin Finck
666c2c66affSColin Finck NT_ASSERT(length * sizeof(WCHAR) <= sizeof(temp));
667c2c66affSColin Finck
668c2c66affSColin Finck buffer = ExAllocatePoolWithTag(PagedPool, length * sizeof(WCHAR), 'IpcA');
669c2c66affSColin Finck if (!buffer)
670c2c66affSColin Finck {
671c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
672c2c66affSColin Finck break;
673c2c66affSColin Finck }
674c2c66affSColin Finck
675c2c66affSColin Finck RtlCopyMemory (buffer, temp, length * sizeof(WCHAR));
676c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) buffer;
677c2c66affSColin Finck DPRINT("BusQueryCompatibleIDs: %ls\n",buffer);
678c2c66affSColin Finck status = STATUS_SUCCESS;
679c2c66affSColin Finck }
680c2c66affSColin Finck break;
681c2c66affSColin Finck
682c2c66affSColin Finck default:
683c2c66affSColin Finck status = Irp->IoStatus.Status;
684c2c66affSColin Finck }
685c2c66affSColin Finck return status;
686c2c66affSColin Finck }
687c2c66affSColin Finck
688c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryDeviceText(PPDO_DEVICE_DATA DeviceData,PIRP Irp)689c2c66affSColin Finck Bus_PDO_QueryDeviceText(
690c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
691c2c66affSColin Finck PIRP Irp )
692c2c66affSColin Finck {
693c2c66affSColin Finck PWCHAR Buffer, Temp;
694c2c66affSColin Finck PIO_STACK_LOCATION stack;
695c2c66affSColin Finck NTSTATUS status = Irp->IoStatus.Status;
696c2c66affSColin Finck PAGED_CODE ();
697c2c66affSColin Finck
698c2c66affSColin Finck stack = IoGetCurrentIrpStackLocation (Irp);
699c2c66affSColin Finck
700c2c66affSColin Finck switch (stack->Parameters.QueryDeviceText.DeviceTextType) {
701c2c66affSColin Finck
702c2c66affSColin Finck case DeviceTextDescription:
703c2c66affSColin Finck
704c2c66affSColin Finck if (!Irp->IoStatus.Information) {
705c2c66affSColin Finck if (wcsstr (DeviceData->HardwareIDs, L"PNP000") != 0)
706c2c66affSColin Finck Temp = L"Programmable interrupt controller";
707c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP010") != 0)
708c2c66affSColin Finck Temp = L"System timer";
709c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP020") != 0)
710c2c66affSColin Finck Temp = L"DMA controller";
711c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP03") != 0)
712c2c66affSColin Finck Temp = L"Keyboard";
713c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP040") != 0)
714c2c66affSColin Finck Temp = L"Parallel port";
715c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP05") != 0)
716c2c66affSColin Finck Temp = L"Serial port";
717c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP06") != 0)
718c2c66affSColin Finck Temp = L"Disk controller";
719c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP07") != 0)
720c2c66affSColin Finck Temp = L"Disk controller";
721c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP09") != 0)
722c2c66affSColin Finck Temp = L"Display adapter";
723c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A0") != 0)
724c2c66affSColin Finck Temp = L"Bus controller";
725c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0E0") != 0)
726c2c66affSColin Finck Temp = L"PCMCIA controller";
727c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0F") != 0)
728c2c66affSColin Finck Temp = L"Mouse device";
729c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP8") != 0)
730c2c66affSColin Finck Temp = L"Network adapter";
731c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNPA0") != 0)
732c2c66affSColin Finck Temp = L"SCSI controller";
733c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNPB0") != 0)
734c2c66affSColin Finck Temp = L"Multimedia device";
735c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNPC00") != 0)
736c2c66affSColin Finck Temp = L"Modem";
737c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0C") != 0)
738c2c66affSColin Finck Temp = L"Power Button";
739c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0E") != 0)
740c2c66affSColin Finck Temp = L"Sleep Button";
741c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0D") != 0)
742c2c66affSColin Finck Temp = L"Lid Switch";
743c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C09") != 0)
744c2c66affSColin Finck Temp = L"ACPI Embedded Controller";
745c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0B") != 0)
746c2c66affSColin Finck Temp = L"ACPI Fan";
747c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
748c2c66affSColin Finck wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0)
749c2c66affSColin Finck Temp = L"PCI Root Bridge";
750c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0A") != 0)
751c2c66affSColin Finck Temp = L"ACPI Battery";
752c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0F") != 0)
753c2c66affSColin Finck Temp = L"PCI Interrupt Link";
754c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"ACPI_PWR") != 0)
755c2c66affSColin Finck Temp = L"ACPI Power Resource";
756c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"Processor") != 0)
757c2c66affSColin Finck {
758c2c66affSColin Finck if (ProcessorNameString != NULL)
759c2c66affSColin Finck Temp = ProcessorNameString;
760c2c66affSColin Finck else
761c2c66affSColin Finck Temp = L"Processor";
762c2c66affSColin Finck }
763c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"ThermalZone") != 0)
764c2c66affSColin Finck Temp = L"ACPI Thermal Zone";
765c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0002") != 0)
766c2c66affSColin Finck Temp = L"Smart Battery";
767c2c66affSColin Finck else if (wcsstr(DeviceData->HardwareIDs, L"ACPI0003") != 0)
768c2c66affSColin Finck Temp = L"AC Adapter";
769c2c66affSColin Finck /* Simply checking if AcpiHandle is NULL eliminates the need to check
770c2c66affSColin Finck * for the 4 different names that ACPI knows the fixed feature button as internally
771c2c66affSColin Finck */
772c2c66affSColin Finck else if (!DeviceData->AcpiHandle)
773c2c66affSColin Finck Temp = L"ACPI Fixed Feature Button";
774c2c66affSColin Finck else
775c2c66affSColin Finck Temp = L"Other ACPI device";
776c2c66affSColin Finck
777c2c66affSColin Finck Buffer = ExAllocatePoolWithTag(PagedPool, (wcslen(Temp) + 1) * sizeof(WCHAR), 'IpcA');
778c2c66affSColin Finck
779c2c66affSColin Finck if (!Buffer) {
780c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
781c2c66affSColin Finck break;
782c2c66affSColin Finck }
783c2c66affSColin Finck
784c2c66affSColin Finck RtlCopyMemory (Buffer, Temp, (wcslen(Temp) + 1) * sizeof(WCHAR));
785c2c66affSColin Finck
786c2c66affSColin Finck DPRINT("\tDeviceTextDescription :%ws\n", Buffer);
787c2c66affSColin Finck
788c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) Buffer;
789c2c66affSColin Finck status = STATUS_SUCCESS;
790c2c66affSColin Finck }
791c2c66affSColin Finck break;
792c2c66affSColin Finck
793c2c66affSColin Finck default:
794c2c66affSColin Finck break;
795c2c66affSColin Finck }
796c2c66affSColin Finck
797c2c66affSColin Finck return status;
798c2c66affSColin Finck
799c2c66affSColin Finck }
800c2c66affSColin Finck
801c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryResources(PPDO_DEVICE_DATA DeviceData,PIRP Irp)802c2c66affSColin Finck Bus_PDO_QueryResources(
803c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
804c2c66affSColin Finck PIRP Irp )
805c2c66affSColin Finck {
806c2c66affSColin Finck ULONG NumberOfResources = 0;
807c2c66affSColin Finck PCM_RESOURCE_LIST ResourceList;
808c2c66affSColin Finck PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
809c2c66affSColin Finck ACPI_STATUS AcpiStatus;
810c2c66affSColin Finck ACPI_BUFFER Buffer;
811c2c66affSColin Finck ACPI_RESOURCE* resource;
812c2c66affSColin Finck ULONG ResourceListSize;
813c2c66affSColin Finck ULONG i;
814c2c66affSColin Finck ULONGLONG BusNumber;
815c2c66affSColin Finck struct acpi_device *device;
816c2c66affSColin Finck
817c2c66affSColin Finck if (!DeviceData->AcpiHandle)
818c2c66affSColin Finck {
819c2c66affSColin Finck return Irp->IoStatus.Status;
820c2c66affSColin Finck }
821c2c66affSColin Finck
822c2c66affSColin Finck /* A bus number resource is not included in the list of current resources
823c2c66affSColin Finck * for the root PCI bus so we manually query one here and if we find it
824c2c66affSColin Finck * we create a resource list and add a bus number descriptor to it */
825c2c66affSColin Finck if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
826c2c66affSColin Finck wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0)
827c2c66affSColin Finck {
828c2c66affSColin Finck acpi_bus_get_device(DeviceData->AcpiHandle, &device);
829c2c66affSColin Finck
830c2c66affSColin Finck AcpiStatus = acpi_evaluate_integer(DeviceData->AcpiHandle, "_BBN", NULL, &BusNumber);
831c2c66affSColin Finck if (AcpiStatus != AE_OK)
832c2c66affSColin Finck {
833c2c66affSColin Finck #if 0
834c2c66affSColin Finck if (device->flags.unique_id)
835c2c66affSColin Finck {
836c2c66affSColin Finck /* FIXME: Try the unique ID */
837c2c66affSColin Finck }
838c2c66affSColin Finck else
839c2c66affSColin Finck #endif
840c2c66affSColin Finck {
841c2c66affSColin Finck BusNumber = 0;
842c2c66affSColin Finck DPRINT1("Failed to find a bus number\n");
843c2c66affSColin Finck }
844c2c66affSColin Finck }
845c2c66affSColin Finck else
846c2c66affSColin Finck {
847c2c66affSColin Finck DPRINT("Using _BBN for bus number\n");
848c2c66affSColin Finck }
849c2c66affSColin Finck
850c2c66affSColin Finck DPRINT("Found PCI root hub: %d\n", BusNumber);
851c2c66affSColin Finck
852c2c66affSColin Finck ResourceListSize = sizeof(CM_RESOURCE_LIST);
853c2c66affSColin Finck ResourceList = ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'RpcA');
854c2c66affSColin Finck if (!ResourceList)
855c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
856c2c66affSColin Finck
857c2c66affSColin Finck ResourceList->Count = 1;
858c2c66affSColin Finck ResourceList->List[0].InterfaceType = Internal;
859c2c66affSColin Finck ResourceList->List[0].BusNumber = 0;
860c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Version = 1;
861c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Revision = 1;
862c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Count = 1;
863c2c66affSColin Finck ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
864c2c66affSColin Finck
865c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeBusNumber;
866c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
867c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Start = BusNumber;
868c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Length = 1;
869c2c66affSColin Finck
870c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
871c2c66affSColin Finck return STATUS_SUCCESS;
872c2c66affSColin Finck }
873c2c66affSColin Finck
874c2c66affSColin Finck /* Get current resources */
875c2c66affSColin Finck Buffer.Length = 0;
876c2c66affSColin Finck AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer);
877c2c66affSColin Finck if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) ||
878c2c66affSColin Finck Buffer.Length == 0)
879c2c66affSColin Finck {
880c2c66affSColin Finck return Irp->IoStatus.Status;
881c2c66affSColin Finck }
882c2c66affSColin Finck
883c2c66affSColin Finck Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'BpcA');
884c2c66affSColin Finck if (!Buffer.Pointer)
885c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
886c2c66affSColin Finck
887c2c66affSColin Finck AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer);
888c2c66affSColin Finck if (!ACPI_SUCCESS(AcpiStatus))
889c2c66affSColin Finck {
890c2c66affSColin Finck DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus);
891c2c66affSColin Finck ASSERT(FALSE);
892c2c66affSColin Finck return STATUS_UNSUCCESSFUL;
893c2c66affSColin Finck }
894c2c66affSColin Finck
895c2c66affSColin Finck resource= Buffer.Pointer;
896c2c66affSColin Finck /* Count number of resources */
897c2c66affSColin Finck while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG)
898c2c66affSColin Finck {
899c2c66affSColin Finck switch (resource->Type)
900c2c66affSColin Finck {
901c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
902c2c66affSColin Finck {
903c2c66affSColin Finck ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data;
904c2c66affSColin Finck if (irq_data->ProducerConsumer == ACPI_PRODUCER)
905c2c66affSColin Finck break;
906c2c66affSColin Finck NumberOfResources += irq_data->InterruptCount;
907c2c66affSColin Finck break;
908c2c66affSColin Finck }
909c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IRQ:
910c2c66affSColin Finck {
911c2c66affSColin Finck ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data;
912c2c66affSColin Finck NumberOfResources += irq_data->InterruptCount;
913c2c66affSColin Finck break;
914c2c66affSColin Finck }
915c2c66affSColin Finck case ACPI_RESOURCE_TYPE_DMA:
916c2c66affSColin Finck {
917c2c66affSColin Finck ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data;
918c2c66affSColin Finck NumberOfResources += dma_data->ChannelCount;
919c2c66affSColin Finck break;
920c2c66affSColin Finck }
921c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS16:
922c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS32:
923c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS64:
924c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
925c2c66affSColin Finck {
926c2c66affSColin Finck ACPI_RESOURCE_ADDRESS *addr_res = (ACPI_RESOURCE_ADDRESS*) &resource->Data;
927c2c66affSColin Finck if (addr_res->ProducerConsumer == ACPI_PRODUCER)
928c2c66affSColin Finck break;
929c2c66affSColin Finck NumberOfResources++;
930c2c66affSColin Finck break;
931c2c66affSColin Finck }
932c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY24:
933c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY32:
934c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
935c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_IO:
936c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IO:
937c2c66affSColin Finck {
938c2c66affSColin Finck NumberOfResources++;
939c2c66affSColin Finck break;
940c2c66affSColin Finck }
941c2c66affSColin Finck default:
942c2c66affSColin Finck {
943c2c66affSColin Finck DPRINT1("Unknown resource type: %d\n", resource->Type);
944c2c66affSColin Finck break;
945c2c66affSColin Finck }
946c2c66affSColin Finck }
947c2c66affSColin Finck resource = ACPI_NEXT_RESOURCE(resource);
948c2c66affSColin Finck }
949c2c66affSColin Finck
950c2c66affSColin Finck /* Allocate memory */
951c2c66affSColin Finck ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
952c2c66affSColin Finck ResourceList = ExAllocatePoolWithTag(PagedPool, ResourceListSize, 'RpcA');
953c2c66affSColin Finck
954c2c66affSColin Finck if (!ResourceList)
955c2c66affSColin Finck {
956c2c66affSColin Finck ExFreePoolWithTag(Buffer.Pointer, 'BpcA');
957c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
958c2c66affSColin Finck }
959c2c66affSColin Finck ResourceList->Count = 1;
960c2c66affSColin Finck ResourceList->List[0].InterfaceType = Internal; /* FIXME */
961c2c66affSColin Finck ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */
962c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Version = 1;
963c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Revision = 1;
964c2c66affSColin Finck ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
965c2c66affSColin Finck ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
966c2c66affSColin Finck
967c2c66affSColin Finck /* Fill resources list structure */
968c2c66affSColin Finck resource = Buffer.Pointer;
969c2c66affSColin Finck while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG)
970c2c66affSColin Finck {
971c2c66affSColin Finck switch (resource->Type)
972c2c66affSColin Finck {
973c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
974c2c66affSColin Finck {
975c2c66affSColin Finck ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data;
976c2c66affSColin Finck if (irq_data->ProducerConsumer == ACPI_PRODUCER)
977c2c66affSColin Finck break;
978c2c66affSColin Finck for (i = 0; i < irq_data->InterruptCount; i++)
979c2c66affSColin Finck {
980c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeInterrupt;
981c2c66affSColin Finck
982c2c66affSColin Finck ResourceDescriptor->ShareDisposition =
9839d53c935SThomas Faber (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive);
984c2c66affSColin Finck ResourceDescriptor->Flags =
985c2c66affSColin Finck (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED);
986c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Level =
987c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i];
988c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1);
989c2c66affSColin Finck
990c2c66affSColin Finck ResourceDescriptor++;
991c2c66affSColin Finck }
992c2c66affSColin Finck break;
993c2c66affSColin Finck }
994c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IRQ:
995c2c66affSColin Finck {
996c2c66affSColin Finck ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data;
997c2c66affSColin Finck for (i = 0; i < irq_data->InterruptCount; i++)
998c2c66affSColin Finck {
999c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeInterrupt;
1000c2c66affSColin Finck
1001c2c66affSColin Finck ResourceDescriptor->ShareDisposition =
10029d53c935SThomas Faber (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive);
1003c2c66affSColin Finck ResourceDescriptor->Flags =
1004c2c66affSColin Finck (irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED);
1005c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Level =
1006c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Vector = irq_data->Interrupts[i];
1007c2c66affSColin Finck ResourceDescriptor->u.Interrupt.Affinity = (KAFFINITY)(-1);
1008c2c66affSColin Finck
1009c2c66affSColin Finck ResourceDescriptor++;
1010c2c66affSColin Finck }
1011c2c66affSColin Finck break;
1012c2c66affSColin Finck }
1013c2c66affSColin Finck case ACPI_RESOURCE_TYPE_DMA:
1014c2c66affSColin Finck {
1015c2c66affSColin Finck ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data;
1016c2c66affSColin Finck for (i = 0; i < dma_data->ChannelCount; i++)
1017c2c66affSColin Finck {
1018c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeDma;
1019c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1020c2c66affSColin Finck switch (dma_data->Type)
1021c2c66affSColin Finck {
1022c2c66affSColin Finck case ACPI_TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break;
1023c2c66affSColin Finck case ACPI_TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break;
1024c2c66affSColin Finck case ACPI_TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break;
1025c2c66affSColin Finck }
1026c2c66affSColin Finck if (dma_data->BusMaster == ACPI_BUS_MASTER)
1027c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER;
1028c2c66affSColin Finck switch (dma_data->Transfer)
1029c2c66affSColin Finck {
1030c2c66affSColin Finck case ACPI_TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break;
1031c2c66affSColin Finck case ACPI_TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break;
1032c2c66affSColin Finck case ACPI_TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break;
1033c2c66affSColin Finck }
1034c2c66affSColin Finck ResourceDescriptor->u.Dma.Channel = dma_data->Channels[i];
1035c2c66affSColin Finck
1036c2c66affSColin Finck ResourceDescriptor++;
1037c2c66affSColin Finck }
1038c2c66affSColin Finck break;
1039c2c66affSColin Finck }
1040c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IO:
1041c2c66affSColin Finck {
1042c2c66affSColin Finck ACPI_RESOURCE_IO *io_data = (ACPI_RESOURCE_IO*) &resource->Data;
1043c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1044c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
1045c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1046c2c66affSColin Finck if (io_data->IoDecode == ACPI_DECODE_16)
1047c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
1048c2c66affSColin Finck else
1049c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
1050c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = io_data->Minimum;
1051c2c66affSColin Finck ResourceDescriptor->u.Port.Length = io_data->AddressLength;
1052c2c66affSColin Finck
1053c2c66affSColin Finck ResourceDescriptor++;
1054c2c66affSColin Finck break;
1055c2c66affSColin Finck }
1056c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_IO:
1057c2c66affSColin Finck {
1058c2c66affSColin Finck ACPI_RESOURCE_FIXED_IO *io_data = (ACPI_RESOURCE_FIXED_IO*) &resource->Data;
1059c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1060c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
1061c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1062c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = io_data->Address;
1063c2c66affSColin Finck ResourceDescriptor->u.Port.Length = io_data->AddressLength;
1064c2c66affSColin Finck
1065c2c66affSColin Finck ResourceDescriptor++;
1066c2c66affSColin Finck break;
1067c2c66affSColin Finck }
1068c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS16:
1069c2c66affSColin Finck {
1070c2c66affSColin Finck ACPI_RESOURCE_ADDRESS16 *addr16_data = (ACPI_RESOURCE_ADDRESS16*) &resource->Data;
1071c2c66affSColin Finck if (addr16_data->ProducerConsumer == ACPI_PRODUCER)
1072c2c66affSColin Finck break;
1073c2c66affSColin Finck if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1074c2c66affSColin Finck {
1075c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeBusNumber;
1076c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1077c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1078c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Start = addr16_data->Address.Minimum;
1079c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Length = addr16_data->Address.AddressLength;
1080c2c66affSColin Finck }
1081c2c66affSColin Finck else if (addr16_data->ResourceType == ACPI_IO_RANGE)
1082c2c66affSColin Finck {
1083c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1084c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1085c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1086c2c66affSColin Finck if (addr16_data->Decode == ACPI_POS_DECODE)
1087c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1088c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = addr16_data->Address.Minimum;
1089c2c66affSColin Finck ResourceDescriptor->u.Port.Length = addr16_data->Address.AddressLength;
1090c2c66affSColin Finck }
1091c2c66affSColin Finck else
1092c2c66affSColin Finck {
1093c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1094c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1095c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1096c2c66affSColin Finck if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1097c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1098c2c66affSColin Finck else
1099c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1100c2c66affSColin Finck switch (addr16_data->Info.Mem.Caching)
1101c2c66affSColin Finck {
1102c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1103c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1104c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1105c2c66affSColin Finck }
1106c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = addr16_data->Address.Minimum;
1107c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = addr16_data->Address.AddressLength;
1108c2c66affSColin Finck }
1109c2c66affSColin Finck ResourceDescriptor++;
1110c2c66affSColin Finck break;
1111c2c66affSColin Finck }
1112c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS32:
1113c2c66affSColin Finck {
1114c2c66affSColin Finck ACPI_RESOURCE_ADDRESS32 *addr32_data = (ACPI_RESOURCE_ADDRESS32*) &resource->Data;
1115c2c66affSColin Finck if (addr32_data->ProducerConsumer == ACPI_PRODUCER)
1116c2c66affSColin Finck break;
1117c2c66affSColin Finck if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1118c2c66affSColin Finck {
1119c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeBusNumber;
1120c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1121c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1122c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Start = addr32_data->Address.Minimum;
1123c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Length = addr32_data->Address.AddressLength;
1124c2c66affSColin Finck }
1125c2c66affSColin Finck else if (addr32_data->ResourceType == ACPI_IO_RANGE)
1126c2c66affSColin Finck {
1127c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1128c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1129c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1130c2c66affSColin Finck if (addr32_data->Decode == ACPI_POS_DECODE)
1131c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1132c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = addr32_data->Address.Minimum;
1133c2c66affSColin Finck ResourceDescriptor->u.Port.Length = addr32_data->Address.AddressLength;
1134c2c66affSColin Finck }
1135c2c66affSColin Finck else
1136c2c66affSColin Finck {
1137c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1138c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1139c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1140c2c66affSColin Finck if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1141c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1142c2c66affSColin Finck else
1143c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1144c2c66affSColin Finck switch (addr32_data->Info.Mem.Caching)
1145c2c66affSColin Finck {
1146c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1147c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1148c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1149c2c66affSColin Finck }
1150c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = addr32_data->Address.Minimum;
1151c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = addr32_data->Address.AddressLength;
1152c2c66affSColin Finck }
1153c2c66affSColin Finck ResourceDescriptor++;
1154c2c66affSColin Finck break;
1155c2c66affSColin Finck }
1156c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS64:
1157c2c66affSColin Finck {
1158c2c66affSColin Finck ACPI_RESOURCE_ADDRESS64 *addr64_data = (ACPI_RESOURCE_ADDRESS64*) &resource->Data;
1159c2c66affSColin Finck if (addr64_data->ProducerConsumer == ACPI_PRODUCER)
1160c2c66affSColin Finck break;
1161c2c66affSColin Finck if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1162c2c66affSColin Finck {
1163c2c66affSColin Finck DPRINT1("64-bit bus address is not supported!\n");
1164c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeBusNumber;
1165c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1166c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1167c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Address.Minimum;
1168c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength;
1169c2c66affSColin Finck }
1170c2c66affSColin Finck else if (addr64_data->ResourceType == ACPI_IO_RANGE)
1171c2c66affSColin Finck {
1172c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1173c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1174c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1175c2c66affSColin Finck if (addr64_data->Decode == ACPI_POS_DECODE)
1176c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1177c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Address.Minimum;
1178c2c66affSColin Finck ResourceDescriptor->u.Port.Length = addr64_data->Address.AddressLength;
1179c2c66affSColin Finck }
1180c2c66affSColin Finck else
1181c2c66affSColin Finck {
1182c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1183c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1184c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1185c2c66affSColin Finck if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1186c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1187c2c66affSColin Finck else
1188c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1189c2c66affSColin Finck switch (addr64_data->Info.Mem.Caching)
1190c2c66affSColin Finck {
1191c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1192c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1193c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1194c2c66affSColin Finck }
1195c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Address.Minimum;
1196c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = addr64_data->Address.AddressLength;
1197c2c66affSColin Finck }
1198c2c66affSColin Finck ResourceDescriptor++;
1199c2c66affSColin Finck break;
1200c2c66affSColin Finck }
1201c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
1202c2c66affSColin Finck {
1203c2c66affSColin Finck ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = (ACPI_RESOURCE_EXTENDED_ADDRESS64*) &resource->Data;
1204c2c66affSColin Finck if (addr64_data->ProducerConsumer == ACPI_PRODUCER)
1205c2c66affSColin Finck break;
1206c2c66affSColin Finck if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1207c2c66affSColin Finck {
1208c2c66affSColin Finck DPRINT1("64-bit bus address is not supported!\n");
1209c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeBusNumber;
1210c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1211c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1212c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Start = (ULONG)addr64_data->Address.Minimum;
1213c2c66affSColin Finck ResourceDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength;
1214c2c66affSColin Finck }
1215c2c66affSColin Finck else if (addr64_data->ResourceType == ACPI_IO_RANGE)
1216c2c66affSColin Finck {
1217c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypePort;
1218c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1219c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1220c2c66affSColin Finck if (addr64_data->Decode == ACPI_POS_DECODE)
1221c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1222c2c66affSColin Finck ResourceDescriptor->u.Port.Start.QuadPart = addr64_data->Address.Minimum;
1223c2c66affSColin Finck ResourceDescriptor->u.Port.Length = addr64_data->Address.AddressLength;
1224c2c66affSColin Finck }
1225c2c66affSColin Finck else
1226c2c66affSColin Finck {
1227c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1228c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1229c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1230c2c66affSColin Finck if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1231c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1232c2c66affSColin Finck else
1233c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1234c2c66affSColin Finck switch (addr64_data->Info.Mem.Caching)
1235c2c66affSColin Finck {
1236c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1237c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1238c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1239c2c66affSColin Finck }
1240c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = addr64_data->Address.Minimum;
1241c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = addr64_data->Address.AddressLength;
1242c2c66affSColin Finck }
1243c2c66affSColin Finck ResourceDescriptor++;
1244c2c66affSColin Finck break;
1245c2c66affSColin Finck }
1246c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY24:
1247c2c66affSColin Finck {
1248c2c66affSColin Finck ACPI_RESOURCE_MEMORY24 *mem24_data = (ACPI_RESOURCE_MEMORY24*) &resource->Data;
1249c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1250c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1251c2c66affSColin Finck ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_24;
1252c2c66affSColin Finck if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1253c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1254c2c66affSColin Finck else
1255c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1256c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = mem24_data->Minimum;
1257c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = mem24_data->AddressLength;
1258c2c66affSColin Finck
1259c2c66affSColin Finck ResourceDescriptor++;
1260c2c66affSColin Finck break;
1261c2c66affSColin Finck }
1262c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY32:
1263c2c66affSColin Finck {
1264c2c66affSColin Finck ACPI_RESOURCE_MEMORY32 *mem32_data = (ACPI_RESOURCE_MEMORY32*) &resource->Data;
1265c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1266c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1267c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1268c2c66affSColin Finck if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1269c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1270c2c66affSColin Finck else
1271c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1272c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = mem32_data->Minimum;
1273c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = mem32_data->AddressLength;
1274c2c66affSColin Finck
1275c2c66affSColin Finck ResourceDescriptor++;
1276c2c66affSColin Finck break;
1277c2c66affSColin Finck }
1278c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1279c2c66affSColin Finck {
1280c2c66affSColin Finck ACPI_RESOURCE_FIXED_MEMORY32 *memfixed32_data = (ACPI_RESOURCE_FIXED_MEMORY32*) &resource->Data;
1281c2c66affSColin Finck ResourceDescriptor->Type = CmResourceTypeMemory;
1282c2c66affSColin Finck ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1283c2c66affSColin Finck ResourceDescriptor->Flags = 0;
1284c2c66affSColin Finck if (memfixed32_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1285c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1286c2c66affSColin Finck else
1287c2c66affSColin Finck ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1288c2c66affSColin Finck ResourceDescriptor->u.Memory.Start.QuadPart = memfixed32_data->Address;
1289c2c66affSColin Finck ResourceDescriptor->u.Memory.Length = memfixed32_data->AddressLength;
1290c2c66affSColin Finck
1291c2c66affSColin Finck ResourceDescriptor++;
1292c2c66affSColin Finck break;
1293c2c66affSColin Finck }
1294c2c66affSColin Finck default:
1295c2c66affSColin Finck {
1296c2c66affSColin Finck break;
1297c2c66affSColin Finck }
1298c2c66affSColin Finck }
1299c2c66affSColin Finck resource = ACPI_NEXT_RESOURCE(resource);
1300c2c66affSColin Finck }
1301c2c66affSColin Finck
1302c2c66affSColin Finck ExFreePoolWithTag(Buffer.Pointer, 'BpcA');
1303c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
1304c2c66affSColin Finck return STATUS_SUCCESS;
1305c2c66affSColin Finck }
13069bcd8350SThomas Faber #endif /* UNIT_TEST */
1307c2c66affSColin Finck
1308c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryResourceRequirements(PPDO_DEVICE_DATA DeviceData,PIRP Irp)1309c2c66affSColin Finck Bus_PDO_QueryResourceRequirements(
1310c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
1311c2c66affSColin Finck PIRP Irp )
1312c2c66affSColin Finck {
1313c2c66affSColin Finck ULONG NumberOfResources = 0;
1314c2c66affSColin Finck ACPI_STATUS AcpiStatus;
1315c2c66affSColin Finck ACPI_BUFFER Buffer;
1316c2c66affSColin Finck ACPI_RESOURCE* resource;
1317c2c66affSColin Finck ULONG i, RequirementsListSize;
1318c2c66affSColin Finck PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
1319c2c66affSColin Finck PIO_RESOURCE_DESCRIPTOR RequirementDescriptor;
1320c2c66affSColin Finck BOOLEAN CurrentRes = FALSE;
132115226572SThomas Faber BOOLEAN SeenStartDependent;
1322c2c66affSColin Finck
1323c2c66affSColin Finck PAGED_CODE ();
1324c2c66affSColin Finck
1325c2c66affSColin Finck if (!DeviceData->AcpiHandle)
1326c2c66affSColin Finck {
1327c2c66affSColin Finck return Irp->IoStatus.Status;
1328c2c66affSColin Finck }
1329c2c66affSColin Finck
1330c2c66affSColin Finck /* Handle the PCI root manually */
1331c2c66affSColin Finck if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
1332c2c66affSColin Finck wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0)
1333c2c66affSColin Finck {
1334c2c66affSColin Finck return Irp->IoStatus.Status;
1335c2c66affSColin Finck }
1336c2c66affSColin Finck
1337c2c66affSColin Finck /* Get current resources */
1338c2c66affSColin Finck while (TRUE)
1339c2c66affSColin Finck {
1340c2c66affSColin Finck Buffer.Length = 0;
1341c2c66affSColin Finck if (CurrentRes)
1342c2c66affSColin Finck AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer);
1343c2c66affSColin Finck else
1344c2c66affSColin Finck AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer);
1345c2c66affSColin Finck if ((!ACPI_SUCCESS(AcpiStatus) && AcpiStatus != AE_BUFFER_OVERFLOW) ||
1346c2c66affSColin Finck Buffer.Length == 0)
1347c2c66affSColin Finck {
1348c2c66affSColin Finck if (!CurrentRes)
1349c2c66affSColin Finck CurrentRes = TRUE;
1350c2c66affSColin Finck else
1351c2c66affSColin Finck return Irp->IoStatus.Status;
1352c2c66affSColin Finck }
1353c2c66affSColin Finck else
1354c2c66affSColin Finck break;
1355c2c66affSColin Finck }
1356c2c66affSColin Finck
1357c2c66affSColin Finck Buffer.Pointer = ExAllocatePoolWithTag(PagedPool, Buffer.Length, 'BpcA');
1358c2c66affSColin Finck if (!Buffer.Pointer)
1359c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
1360c2c66affSColin Finck
1361c2c66affSColin Finck if (CurrentRes)
1362c2c66affSColin Finck AcpiStatus = AcpiGetCurrentResources(DeviceData->AcpiHandle, &Buffer);
1363c2c66affSColin Finck else
1364c2c66affSColin Finck AcpiStatus = AcpiGetPossibleResources(DeviceData->AcpiHandle, &Buffer);
1365c2c66affSColin Finck if (!ACPI_SUCCESS(AcpiStatus))
1366c2c66affSColin Finck {
1367c2c66affSColin Finck DPRINT1("AcpiGetCurrentResources #2 failed (0x%x)\n", AcpiStatus);
1368c2c66affSColin Finck ASSERT(FALSE);
1369c2c66affSColin Finck return STATUS_UNSUCCESSFUL;
1370c2c66affSColin Finck }
1371c2c66affSColin Finck
137215226572SThomas Faber SeenStartDependent = FALSE;
1373c2c66affSColin Finck resource = Buffer.Pointer;
1374c2c66affSColin Finck /* Count number of resources */
137515226572SThomas Faber while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG && resource->Type != ACPI_RESOURCE_TYPE_END_DEPENDENT)
1376c2c66affSColin Finck {
137715226572SThomas Faber if (resource->Type == ACPI_RESOURCE_TYPE_START_DEPENDENT)
137815226572SThomas Faber {
137915226572SThomas Faber if (SeenStartDependent)
138015226572SThomas Faber {
138115226572SThomas Faber break;
138215226572SThomas Faber }
138315226572SThomas Faber SeenStartDependent = TRUE;
138415226572SThomas Faber }
1385c2c66affSColin Finck switch (resource->Type)
1386c2c66affSColin Finck {
1387c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1388c2c66affSColin Finck {
1389c2c66affSColin Finck ACPI_RESOURCE_EXTENDED_IRQ *irq_data = (ACPI_RESOURCE_EXTENDED_IRQ*) &resource->Data;
1390c2c66affSColin Finck if (irq_data->ProducerConsumer == ACPI_PRODUCER)
1391c2c66affSColin Finck break;
1392c2c66affSColin Finck NumberOfResources += irq_data->InterruptCount;
1393c2c66affSColin Finck break;
1394c2c66affSColin Finck }
1395c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IRQ:
1396c2c66affSColin Finck {
1397c2c66affSColin Finck ACPI_RESOURCE_IRQ *irq_data = (ACPI_RESOURCE_IRQ*) &resource->Data;
1398c2c66affSColin Finck NumberOfResources += irq_data->InterruptCount;
1399c2c66affSColin Finck break;
1400c2c66affSColin Finck }
1401c2c66affSColin Finck case ACPI_RESOURCE_TYPE_DMA:
1402c2c66affSColin Finck {
1403c2c66affSColin Finck ACPI_RESOURCE_DMA *dma_data = (ACPI_RESOURCE_DMA*) &resource->Data;
1404c2c66affSColin Finck NumberOfResources += dma_data->ChannelCount;
1405c2c66affSColin Finck break;
1406c2c66affSColin Finck }
1407c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS16:
1408c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS32:
1409c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS64:
1410c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
1411c2c66affSColin Finck {
1412c2c66affSColin Finck ACPI_RESOURCE_ADDRESS *res_addr = (ACPI_RESOURCE_ADDRESS*) &resource->Data;
1413c2c66affSColin Finck if (res_addr->ProducerConsumer == ACPI_PRODUCER)
1414c2c66affSColin Finck break;
1415c2c66affSColin Finck NumberOfResources++;
1416c2c66affSColin Finck break;
1417c2c66affSColin Finck }
1418c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY24:
1419c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY32:
1420c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1421c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_IO:
1422c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IO:
1423c2c66affSColin Finck {
1424c2c66affSColin Finck NumberOfResources++;
1425c2c66affSColin Finck break;
1426c2c66affSColin Finck }
1427c2c66affSColin Finck default:
1428c2c66affSColin Finck {
1429c2c66affSColin Finck break;
1430c2c66affSColin Finck }
1431c2c66affSColin Finck }
1432c2c66affSColin Finck resource = ACPI_NEXT_RESOURCE(resource);
1433c2c66affSColin Finck }
1434c2c66affSColin Finck
1435c2c66affSColin Finck RequirementsListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
1436c2c66affSColin Finck RequirementsList = ExAllocatePoolWithTag(PagedPool, RequirementsListSize, 'RpcA');
1437c2c66affSColin Finck
1438c2c66affSColin Finck if (!RequirementsList)
1439c2c66affSColin Finck {
1440c2c66affSColin Finck ExFreePoolWithTag(Buffer.Pointer, 'BpcA');
1441c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
1442c2c66affSColin Finck }
1443c2c66affSColin Finck RequirementsList->ListSize = RequirementsListSize;
1444c2c66affSColin Finck RequirementsList->InterfaceType = Internal;
1445c2c66affSColin Finck RequirementsList->BusNumber = 0;
1446c2c66affSColin Finck RequirementsList->SlotNumber = 0; /* Not used by WDM drivers */
1447c2c66affSColin Finck RequirementsList->AlternativeLists = 1;
1448c2c66affSColin Finck RequirementsList->List[0].Version = 1;
1449c2c66affSColin Finck RequirementsList->List[0].Revision = 1;
1450c2c66affSColin Finck RequirementsList->List[0].Count = NumberOfResources;
1451c2c66affSColin Finck RequirementDescriptor = RequirementsList->List[0].Descriptors;
1452c2c66affSColin Finck
1453c2c66affSColin Finck /* Fill resources list structure */
145415226572SThomas Faber SeenStartDependent = FALSE;
1455c2c66affSColin Finck resource = Buffer.Pointer;
1456c2c66affSColin Finck while (resource->Type != ACPI_RESOURCE_TYPE_END_TAG && resource->Type != ACPI_RESOURCE_TYPE_END_DEPENDENT)
1457c2c66affSColin Finck {
145815226572SThomas Faber if (resource->Type == ACPI_RESOURCE_TYPE_START_DEPENDENT)
145915226572SThomas Faber {
146015226572SThomas Faber if (SeenStartDependent)
146115226572SThomas Faber {
146215226572SThomas Faber break;
146315226572SThomas Faber }
146415226572SThomas Faber SeenStartDependent = TRUE;
146515226572SThomas Faber }
1466c2c66affSColin Finck switch (resource->Type)
1467c2c66affSColin Finck {
1468c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1469c2c66affSColin Finck {
147028be285dSThomas Faber ACPI_RESOURCE_EXTENDED_IRQ *irq_data = &resource->Data.ExtendedIrq;
1471c2c66affSColin Finck if (irq_data->ProducerConsumer == ACPI_PRODUCER)
1472c2c66affSColin Finck break;
1473c2c66affSColin Finck for (i = 0; i < irq_data->InterruptCount; i++)
1474c2c66affSColin Finck {
1475c2c66affSColin Finck RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE;
1476c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeInterrupt;
14779d53c935SThomas Faber RequirementDescriptor->ShareDisposition = (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive);
1478c2c66affSColin Finck RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED);
1479c2c66affSColin Finck RequirementDescriptor->u.Interrupt.MinimumVector =
1480c2c66affSColin Finck RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i];
1481c2c66affSColin Finck
1482c2c66affSColin Finck RequirementDescriptor++;
1483c2c66affSColin Finck }
1484c2c66affSColin Finck break;
1485c2c66affSColin Finck }
1486c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IRQ:
1487c2c66affSColin Finck {
148828be285dSThomas Faber ACPI_RESOURCE_IRQ *irq_data = &resource->Data.Irq;
1489c2c66affSColin Finck for (i = 0; i < irq_data->InterruptCount; i++)
1490c2c66affSColin Finck {
1491c2c66affSColin Finck RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE;
1492c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeInterrupt;
14939d53c935SThomas Faber RequirementDescriptor->ShareDisposition = (irq_data->Shareable == ACPI_SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive);
1494c2c66affSColin Finck RequirementDescriptor->Flags =(irq_data->Triggering == ACPI_LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED);
1495c2c66affSColin Finck RequirementDescriptor->u.Interrupt.MinimumVector =
1496c2c66affSColin Finck RequirementDescriptor->u.Interrupt.MaximumVector = irq_data->Interrupts[i];
1497c2c66affSColin Finck
1498c2c66affSColin Finck RequirementDescriptor++;
1499c2c66affSColin Finck }
1500c2c66affSColin Finck break;
1501c2c66affSColin Finck }
1502c2c66affSColin Finck case ACPI_RESOURCE_TYPE_DMA:
1503c2c66affSColin Finck {
150428be285dSThomas Faber ACPI_RESOURCE_DMA *dma_data = &resource->Data.Dma;
1505c2c66affSColin Finck for (i = 0; i < dma_data->ChannelCount; i++)
1506c2c66affSColin Finck {
1507c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeDma;
1508c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1509c2c66affSColin Finck switch (dma_data->Type)
1510c2c66affSColin Finck {
1511c2c66affSColin Finck case ACPI_TYPE_A: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break;
1512c2c66affSColin Finck case ACPI_TYPE_B: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break;
1513c2c66affSColin Finck case ACPI_TYPE_F: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break;
1514c2c66affSColin Finck }
1515c2c66affSColin Finck if (dma_data->BusMaster == ACPI_BUS_MASTER)
1516c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER;
1517c2c66affSColin Finck switch (dma_data->Transfer)
1518c2c66affSColin Finck {
1519c2c66affSColin Finck case ACPI_TRANSFER_8: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8; break;
1520c2c66affSColin Finck case ACPI_TRANSFER_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_16; break;
1521c2c66affSColin Finck case ACPI_TRANSFER_8_16: RequirementDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break;
1522c2c66affSColin Finck }
1523c2c66affSColin Finck
1524c2c66affSColin Finck RequirementDescriptor->Option = (i == 0) ? IO_RESOURCE_PREFERRED : IO_RESOURCE_ALTERNATIVE;
1525c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
1526c2c66affSColin Finck RequirementDescriptor->u.Dma.MinimumChannel =
1527c2c66affSColin Finck RequirementDescriptor->u.Dma.MaximumChannel = dma_data->Channels[i];
1528c2c66affSColin Finck RequirementDescriptor++;
1529c2c66affSColin Finck }
1530c2c66affSColin Finck break;
1531c2c66affSColin Finck }
1532c2c66affSColin Finck case ACPI_RESOURCE_TYPE_IO:
1533c2c66affSColin Finck {
153428be285dSThomas Faber ACPI_RESOURCE_IO *io_data = &resource->Data.Io;
1535c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1536c2c66affSColin Finck if (io_data->IoDecode == ACPI_DECODE_16)
1537c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
1538c2c66affSColin Finck else
1539c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
1540c2c66affSColin Finck RequirementDescriptor->u.Port.Length = io_data->AddressLength;
1541c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1542c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1543c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
1544c2c66affSColin Finck RequirementDescriptor->u.Port.Alignment = io_data->Alignment;
1545c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Minimum;
1546c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Maximum + io_data->AddressLength - 1;
1547c2c66affSColin Finck
1548c2c66affSColin Finck RequirementDescriptor++;
1549c2c66affSColin Finck break;
1550c2c66affSColin Finck }
1551c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_IO:
1552c2c66affSColin Finck {
155328be285dSThomas Faber ACPI_RESOURCE_FIXED_IO *io_data = &resource->Data.FixedIo;
1554c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1555c2c66affSColin Finck RequirementDescriptor->u.Port.Length = io_data->AddressLength;
1556c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1557c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1558c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
1559c2c66affSColin Finck RequirementDescriptor->u.Port.Alignment = 1;
1560c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = io_data->Address;
1561c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = io_data->Address + io_data->AddressLength - 1;
1562c2c66affSColin Finck
1563c2c66affSColin Finck RequirementDescriptor++;
1564c2c66affSColin Finck break;
1565c2c66affSColin Finck }
1566c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS16:
1567c2c66affSColin Finck {
156828be285dSThomas Faber ACPI_RESOURCE_ADDRESS16 *addr16_data = &resource->Data.Address16;
1569c2c66affSColin Finck if (addr16_data->ProducerConsumer == ACPI_PRODUCER)
1570c2c66affSColin Finck break;
1571c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1572c2c66affSColin Finck if (addr16_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1573c2c66affSColin Finck {
1574c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeBusNumber;
1575c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareShared;
1576c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1577c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MinBusNumber = addr16_data->Address.Minimum;
1578c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MaxBusNumber = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1;
1579c2c66affSColin Finck RequirementDescriptor->u.BusNumber.Length = addr16_data->Address.AddressLength;
1580c2c66affSColin Finck }
1581c2c66affSColin Finck else if (addr16_data->ResourceType == ACPI_IO_RANGE)
1582c2c66affSColin Finck {
1583c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1584c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1585c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1586c2c66affSColin Finck if (addr16_data->Decode == ACPI_POS_DECODE)
1587c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1588c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr16_data->Address.Minimum;
1589c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1;
1590c2c66affSColin Finck RequirementDescriptor->u.Port.Length = addr16_data->Address.AddressLength;
1591c2c66affSColin Finck }
1592c2c66affSColin Finck else
1593c2c66affSColin Finck {
1594c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1595c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1596c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1597c2c66affSColin Finck if (addr16_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1598c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1599c2c66affSColin Finck else
1600c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1601c2c66affSColin Finck switch (addr16_data->Info.Mem.Caching)
1602c2c66affSColin Finck {
1603c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1604c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1605c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1606c2c66affSColin Finck }
1607c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr16_data->Address.Minimum;
1608c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr16_data->Address.Maximum + addr16_data->Address.AddressLength - 1;
1609c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = addr16_data->Address.AddressLength;
1610c2c66affSColin Finck }
1611c2c66affSColin Finck RequirementDescriptor++;
1612c2c66affSColin Finck break;
1613c2c66affSColin Finck }
1614c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS32:
1615c2c66affSColin Finck {
161628be285dSThomas Faber ACPI_RESOURCE_ADDRESS32 *addr32_data = &resource->Data.Address32;
1617c2c66affSColin Finck if (addr32_data->ProducerConsumer == ACPI_PRODUCER)
1618c2c66affSColin Finck break;
1619c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1620c2c66affSColin Finck if (addr32_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1621c2c66affSColin Finck {
1622c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeBusNumber;
1623c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareShared;
1624c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1625c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MinBusNumber = addr32_data->Address.Minimum;
1626c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MaxBusNumber = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1;
1627c2c66affSColin Finck RequirementDescriptor->u.BusNumber.Length = addr32_data->Address.AddressLength;
1628c2c66affSColin Finck }
1629c2c66affSColin Finck else if (addr32_data->ResourceType == ACPI_IO_RANGE)
1630c2c66affSColin Finck {
1631c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1632c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1633c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1634c2c66affSColin Finck if (addr32_data->Decode == ACPI_POS_DECODE)
1635c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1636c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr32_data->Address.Minimum;
1637c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1;
1638c2c66affSColin Finck RequirementDescriptor->u.Port.Length = addr32_data->Address.AddressLength;
1639c2c66affSColin Finck }
1640c2c66affSColin Finck else
1641c2c66affSColin Finck {
1642c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1643c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1644c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1645c2c66affSColin Finck if (addr32_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1646c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1647c2c66affSColin Finck else
1648c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1649c2c66affSColin Finck switch (addr32_data->Info.Mem.Caching)
1650c2c66affSColin Finck {
1651c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1652c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1653c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1654c2c66affSColin Finck }
1655c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr32_data->Address.Minimum;
1656c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr32_data->Address.Maximum + addr32_data->Address.AddressLength - 1;
1657c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = addr32_data->Address.AddressLength;
1658c2c66affSColin Finck }
1659c2c66affSColin Finck RequirementDescriptor++;
1660c2c66affSColin Finck break;
1661c2c66affSColin Finck }
1662c2c66affSColin Finck case ACPI_RESOURCE_TYPE_ADDRESS64:
1663c2c66affSColin Finck {
166428be285dSThomas Faber ACPI_RESOURCE_ADDRESS64 *addr64_data = &resource->Data.Address64;
1665c2c66affSColin Finck if (addr64_data->ProducerConsumer == ACPI_PRODUCER)
1666c2c66affSColin Finck break;
1667c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1668c2c66affSColin Finck if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1669c2c66affSColin Finck {
1670c2c66affSColin Finck DPRINT1("64-bit bus address is not supported!\n");
1671c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeBusNumber;
1672c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareShared;
1673c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1674c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Address.Minimum;
1675c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1676c2c66affSColin Finck RequirementDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength;
1677c2c66affSColin Finck }
1678c2c66affSColin Finck else if (addr64_data->ResourceType == ACPI_IO_RANGE)
1679c2c66affSColin Finck {
1680c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1681c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1682c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1683c2c66affSColin Finck if (addr64_data->Decode == ACPI_POS_DECODE)
1684c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1685c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Address.Minimum;
1686c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1687c2c66affSColin Finck RequirementDescriptor->u.Port.Length = addr64_data->Address.AddressLength;
1688c2c66affSColin Finck }
1689c2c66affSColin Finck else
1690c2c66affSColin Finck {
1691c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1692c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1693c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1694c2c66affSColin Finck if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1695c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1696c2c66affSColin Finck else
1697c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1698c2c66affSColin Finck switch (addr64_data->Info.Mem.Caching)
1699c2c66affSColin Finck {
1700c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1701c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1702c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1703c2c66affSColin Finck }
1704c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Address.Minimum;
1705c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1706c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = addr64_data->Address.AddressLength;
1707c2c66affSColin Finck }
1708c2c66affSColin Finck RequirementDescriptor++;
1709c2c66affSColin Finck break;
1710c2c66affSColin Finck }
1711c2c66affSColin Finck case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
1712c2c66affSColin Finck {
171328be285dSThomas Faber ACPI_RESOURCE_EXTENDED_ADDRESS64 *addr64_data = &resource->Data.ExtAddress64;
1714c2c66affSColin Finck if (addr64_data->ProducerConsumer == ACPI_PRODUCER)
1715c2c66affSColin Finck break;
1716c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1717c2c66affSColin Finck if (addr64_data->ResourceType == ACPI_BUS_NUMBER_RANGE)
1718c2c66affSColin Finck {
1719c2c66affSColin Finck DPRINT1("64-bit bus address is not supported!\n");
1720c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeBusNumber;
1721c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareShared;
1722c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1723c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MinBusNumber = (ULONG)addr64_data->Address.Minimum;
1724c2c66affSColin Finck RequirementDescriptor->u.BusNumber.MaxBusNumber = (ULONG)addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1725c2c66affSColin Finck RequirementDescriptor->u.BusNumber.Length = addr64_data->Address.AddressLength;
1726c2c66affSColin Finck }
1727c2c66affSColin Finck else if (addr64_data->ResourceType == ACPI_IO_RANGE)
1728c2c66affSColin Finck {
1729c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypePort;
1730c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1731c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_PORT_IO;
1732c2c66affSColin Finck if (addr64_data->Decode == ACPI_POS_DECODE)
1733c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_PORT_POSITIVE_DECODE;
1734c2c66affSColin Finck RequirementDescriptor->u.Port.MinimumAddress.QuadPart = addr64_data->Address.Minimum;
1735c2c66affSColin Finck RequirementDescriptor->u.Port.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1736c2c66affSColin Finck RequirementDescriptor->u.Port.Length = addr64_data->Address.AddressLength;
1737c2c66affSColin Finck }
1738c2c66affSColin Finck else
1739c2c66affSColin Finck {
1740c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1741c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1742c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1743c2c66affSColin Finck if (addr64_data->Info.Mem.WriteProtect == ACPI_READ_ONLY_MEMORY)
1744c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1745c2c66affSColin Finck else
1746c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1747c2c66affSColin Finck switch (addr64_data->Info.Mem.Caching)
1748c2c66affSColin Finck {
1749c2c66affSColin Finck case ACPI_CACHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_CACHEABLE; break;
1750c2c66affSColin Finck case ACPI_WRITE_COMBINING_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_COMBINEDWRITE; break;
1751c2c66affSColin Finck case ACPI_PREFETCHABLE_MEMORY: RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE; break;
1752c2c66affSColin Finck }
1753c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = addr64_data->Address.Minimum;
1754c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = addr64_data->Address.Maximum + addr64_data->Address.AddressLength - 1;
1755c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = addr64_data->Address.AddressLength;
1756c2c66affSColin Finck }
1757c2c66affSColin Finck RequirementDescriptor++;
1758c2c66affSColin Finck break;
1759c2c66affSColin Finck }
1760c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY24:
1761c2c66affSColin Finck {
176228be285dSThomas Faber ACPI_RESOURCE_MEMORY24 *mem24_data = &resource->Data.Memory24;
1763c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1764c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1765c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1766c2c66affSColin Finck RequirementDescriptor->Flags = CM_RESOURCE_MEMORY_24;
1767c2c66affSColin Finck if (mem24_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1768c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1769c2c66affSColin Finck else
1770c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1771c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem24_data->Minimum;
1772c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem24_data->Maximum + mem24_data->AddressLength - 1;
1773c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = mem24_data->AddressLength;
1774c2c66affSColin Finck
1775c2c66affSColin Finck RequirementDescriptor++;
1776c2c66affSColin Finck break;
1777c2c66affSColin Finck }
1778c2c66affSColin Finck case ACPI_RESOURCE_TYPE_MEMORY32:
1779c2c66affSColin Finck {
178028be285dSThomas Faber ACPI_RESOURCE_MEMORY32 *mem32_data = &resource->Data.Memory32;
1781c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1782c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1783c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1784c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1785c2c66affSColin Finck if (mem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1786c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1787c2c66affSColin Finck else
1788c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1789c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = mem32_data->Minimum;
1790c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = mem32_data->Maximum + mem32_data->AddressLength - 1;
1791c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = mem32_data->AddressLength;
1792c2c66affSColin Finck
1793c2c66affSColin Finck RequirementDescriptor++;
1794c2c66affSColin Finck break;
1795c2c66affSColin Finck }
1796c2c66affSColin Finck case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1797c2c66affSColin Finck {
179828be285dSThomas Faber ACPI_RESOURCE_FIXED_MEMORY32 *fixedmem32_data = &resource->Data.FixedMemory32;
1799c2c66affSColin Finck RequirementDescriptor->Option = CurrentRes ? 0 : IO_RESOURCE_PREFERRED;
1800c2c66affSColin Finck RequirementDescriptor->Type = CmResourceTypeMemory;
1801c2c66affSColin Finck RequirementDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1802c2c66affSColin Finck RequirementDescriptor->Flags = 0;
1803c2c66affSColin Finck if (fixedmem32_data->WriteProtect == ACPI_READ_ONLY_MEMORY)
1804c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY;
1805c2c66affSColin Finck else
1806c2c66affSColin Finck RequirementDescriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE;
1807c2c66affSColin Finck RequirementDescriptor->u.Memory.MinimumAddress.QuadPart = fixedmem32_data->Address;
1808c2c66affSColin Finck RequirementDescriptor->u.Memory.MaximumAddress.QuadPart = fixedmem32_data->Address + fixedmem32_data->AddressLength - 1;
1809c2c66affSColin Finck RequirementDescriptor->u.Memory.Length = fixedmem32_data->AddressLength;
1810c2c66affSColin Finck
1811c2c66affSColin Finck RequirementDescriptor++;
1812c2c66affSColin Finck break;
1813c2c66affSColin Finck }
1814c2c66affSColin Finck default:
1815c2c66affSColin Finck {
1816c2c66affSColin Finck break;
1817c2c66affSColin Finck }
1818c2c66affSColin Finck }
1819c2c66affSColin Finck resource = ACPI_NEXT_RESOURCE(resource);
1820c2c66affSColin Finck }
1821c2c66affSColin Finck ExFreePoolWithTag(Buffer.Pointer, 'BpcA');
1822c2c66affSColin Finck
1823c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR)RequirementsList;
1824c2c66affSColin Finck
1825c2c66affSColin Finck return STATUS_SUCCESS;
1826c2c66affSColin Finck }
1827c2c66affSColin Finck
18289bcd8350SThomas Faber #ifndef UNIT_TEST
1829c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryDeviceRelations(PPDO_DEVICE_DATA DeviceData,PIRP Irp)1830c2c66affSColin Finck Bus_PDO_QueryDeviceRelations(
1831c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
1832c2c66affSColin Finck PIRP Irp )
1833c2c66affSColin Finck /*++
1834c2c66affSColin Finck
1835c2c66affSColin Finck Routine Description:
1836c2c66affSColin Finck
1837c2c66affSColin Finck The PnP Manager sends this IRP to gather information about
1838c2c66affSColin Finck devices with a relationship to the specified device.
1839c2c66affSColin Finck Bus drivers must handle this request for TargetDeviceRelation
1840c2c66affSColin Finck for their child devices (child PDOs).
1841c2c66affSColin Finck
1842c2c66affSColin Finck If a driver returns relations in response to this IRP,
1843c2c66affSColin Finck it allocates a DEVICE_RELATIONS structure from paged
1844c2c66affSColin Finck memory containing a count and the appropriate number of
1845c2c66affSColin Finck device object pointers. The PnP Manager frees the structure
1846c2c66affSColin Finck when it is no longer needed. If a driver replaces a
1847c2c66affSColin Finck DEVICE_RELATIONS structure allocated by another driver,
1848c2c66affSColin Finck it must free the previous structure.
1849c2c66affSColin Finck
1850c2c66affSColin Finck A driver must reference the PDO of any device that it
1851c2c66affSColin Finck reports in this IRP (ObReferenceObject). The PnP Manager
1852c2c66affSColin Finck removes the reference when appropriate.
1853c2c66affSColin Finck
1854c2c66affSColin Finck Arguments:
1855c2c66affSColin Finck
1856c2c66affSColin Finck DeviceData - Pointer to the PDO's device extension.
1857c2c66affSColin Finck Irp - Pointer to the irp.
1858c2c66affSColin Finck
1859c2c66affSColin Finck Return Value:
1860c2c66affSColin Finck
1861c2c66affSColin Finck NT STATUS
1862c2c66affSColin Finck
1863c2c66affSColin Finck --*/
1864c2c66affSColin Finck {
1865c2c66affSColin Finck
1866c2c66affSColin Finck PIO_STACK_LOCATION stack;
1867c2c66affSColin Finck PDEVICE_RELATIONS deviceRelations;
1868c2c66affSColin Finck NTSTATUS status;
1869c2c66affSColin Finck
1870c2c66affSColin Finck PAGED_CODE ();
1871c2c66affSColin Finck
1872c2c66affSColin Finck stack = IoGetCurrentIrpStackLocation (Irp);
1873c2c66affSColin Finck
1874c2c66affSColin Finck switch (stack->Parameters.QueryDeviceRelations.Type) {
1875c2c66affSColin Finck
1876c2c66affSColin Finck case TargetDeviceRelation:
1877c2c66affSColin Finck
1878c2c66affSColin Finck deviceRelations = (PDEVICE_RELATIONS) Irp->IoStatus.Information;
1879c2c66affSColin Finck if (deviceRelations) {
1880c2c66affSColin Finck //
1881c2c66affSColin Finck // Only PDO can handle this request. Somebody above
1882c2c66affSColin Finck // is not playing by rule.
1883c2c66affSColin Finck //
18847d6bda16SSerge Gautherie ASSERTMSG("Someone above is handling TargetDeviceRelation\n", !deviceRelations);
1885c2c66affSColin Finck }
1886c2c66affSColin Finck
1887c2c66affSColin Finck deviceRelations = ExAllocatePoolWithTag(PagedPool,
1888c2c66affSColin Finck sizeof(DEVICE_RELATIONS),
1889c2c66affSColin Finck 'IpcA');
1890c2c66affSColin Finck if (!deviceRelations) {
1891c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
1892c2c66affSColin Finck break;
1893c2c66affSColin Finck }
1894c2c66affSColin Finck
1895c2c66affSColin Finck //
1896c2c66affSColin Finck // There is only one PDO pointer in the structure
1897c2c66affSColin Finck // for this relation type. The PnP Manager removes
1898c2c66affSColin Finck // the reference to the PDO when the driver or application
1899c2c66affSColin Finck // un-registers for notification on the device.
1900c2c66affSColin Finck //
1901c2c66affSColin Finck
1902c2c66affSColin Finck deviceRelations->Count = 1;
1903c2c66affSColin Finck deviceRelations->Objects[0] = DeviceData->Common.Self;
1904c2c66affSColin Finck ObReferenceObject(DeviceData->Common.Self);
1905c2c66affSColin Finck
1906c2c66affSColin Finck status = STATUS_SUCCESS;
1907c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
1908c2c66affSColin Finck break;
1909c2c66affSColin Finck
1910c2c66affSColin Finck case BusRelations: // Not handled by PDO
1911c2c66affSColin Finck case EjectionRelations: // optional for PDO
1912c2c66affSColin Finck case RemovalRelations: // // optional for PDO
1913c2c66affSColin Finck default:
1914c2c66affSColin Finck status = Irp->IoStatus.Status;
1915c2c66affSColin Finck }
1916c2c66affSColin Finck
1917c2c66affSColin Finck return status;
1918c2c66affSColin Finck }
1919c2c66affSColin Finck
1920c2c66affSColin Finck NTSTATUS
Bus_PDO_QueryBusInformation(PPDO_DEVICE_DATA DeviceData,PIRP Irp)1921c2c66affSColin Finck Bus_PDO_QueryBusInformation(
1922c2c66affSColin Finck PPDO_DEVICE_DATA DeviceData,
1923c2c66affSColin Finck PIRP Irp )
1924c2c66affSColin Finck /*++
1925c2c66affSColin Finck
1926c2c66affSColin Finck Routine Description:
1927c2c66affSColin Finck
1928c2c66affSColin Finck The PnP Manager uses this IRP to request the type and
1929c2c66affSColin Finck instance number of a device's parent bus. Bus drivers
1930c2c66affSColin Finck should handle this request for their child devices (PDOs).
1931c2c66affSColin Finck
1932c2c66affSColin Finck Arguments:
1933c2c66affSColin Finck
1934c2c66affSColin Finck DeviceData - Pointer to the PDO's device extension.
1935c2c66affSColin Finck Irp - Pointer to the irp.
1936c2c66affSColin Finck
1937c2c66affSColin Finck Return Value:
1938c2c66affSColin Finck
1939c2c66affSColin Finck NT STATUS
1940c2c66affSColin Finck
1941c2c66affSColin Finck --*/
1942c2c66affSColin Finck {
1943c2c66affSColin Finck
1944c2c66affSColin Finck PPNP_BUS_INFORMATION busInfo;
1945c2c66affSColin Finck
1946c2c66affSColin Finck PAGED_CODE ();
1947c2c66affSColin Finck
1948c2c66affSColin Finck busInfo = ExAllocatePoolWithTag(PagedPool,
1949c2c66affSColin Finck sizeof(PNP_BUS_INFORMATION),
1950c2c66affSColin Finck 'IpcA');
1951c2c66affSColin Finck
1952c2c66affSColin Finck if (busInfo == NULL) {
1953c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
1954c2c66affSColin Finck }
1955c2c66affSColin Finck
1956c2c66affSColin Finck busInfo->BusTypeGuid = GUID_ACPI_INTERFACE_STANDARD;
1957c2c66affSColin Finck
1958c2c66affSColin Finck busInfo->LegacyBusType = InternalPowerBus;
1959c2c66affSColin Finck
1960c2c66affSColin Finck busInfo->BusNumber = 0; //fixme
1961c2c66affSColin Finck
1962c2c66affSColin Finck Irp->IoStatus.Information = (ULONG_PTR)busInfo;
1963c2c66affSColin Finck
1964c2c66affSColin Finck return STATUS_SUCCESS;
1965c2c66affSColin Finck }
1966c2c66affSColin Finck
1967c2c66affSColin Finck
1968c2c66affSColin Finck NTSTATUS
Bus_GetDeviceCapabilities(PDEVICE_OBJECT DeviceObject,PDEVICE_CAPABILITIES DeviceCapabilities)1969c2c66affSColin Finck Bus_GetDeviceCapabilities(
1970c2c66affSColin Finck PDEVICE_OBJECT DeviceObject,
1971c2c66affSColin Finck PDEVICE_CAPABILITIES DeviceCapabilities
1972c2c66affSColin Finck )
1973c2c66affSColin Finck {
1974c2c66affSColin Finck IO_STATUS_BLOCK ioStatus;
1975c2c66affSColin Finck KEVENT pnpEvent;
1976c2c66affSColin Finck NTSTATUS status;
1977c2c66affSColin Finck PDEVICE_OBJECT targetObject;
1978c2c66affSColin Finck PIO_STACK_LOCATION irpStack;
1979c2c66affSColin Finck PIRP pnpIrp;
1980c2c66affSColin Finck
1981c2c66affSColin Finck PAGED_CODE();
1982c2c66affSColin Finck
1983c2c66affSColin Finck //
1984c2c66affSColin Finck // Initialize the capabilities that we will send down
1985c2c66affSColin Finck //
1986c2c66affSColin Finck RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) );
1987c2c66affSColin Finck DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES);
1988c2c66affSColin Finck DeviceCapabilities->Version = 1;
1989c2c66affSColin Finck DeviceCapabilities->Address = -1;
1990c2c66affSColin Finck DeviceCapabilities->UINumber = -1;
1991c2c66affSColin Finck
1992c2c66affSColin Finck //
1993c2c66affSColin Finck // Initialize the event
1994c2c66affSColin Finck //
1995c2c66affSColin Finck KeInitializeEvent( &pnpEvent, NotificationEvent, FALSE );
1996c2c66affSColin Finck
1997c2c66affSColin Finck targetObject = IoGetAttachedDeviceReference( DeviceObject );
1998c2c66affSColin Finck
1999c2c66affSColin Finck //
2000c2c66affSColin Finck // Build an Irp
2001c2c66affSColin Finck //
2002c2c66affSColin Finck pnpIrp = IoBuildSynchronousFsdRequest(
2003c2c66affSColin Finck IRP_MJ_PNP,
2004c2c66affSColin Finck targetObject,
2005c2c66affSColin Finck NULL,
2006c2c66affSColin Finck 0,
2007c2c66affSColin Finck NULL,
2008c2c66affSColin Finck &pnpEvent,
2009c2c66affSColin Finck &ioStatus
2010c2c66affSColin Finck );
2011c2c66affSColin Finck if (pnpIrp == NULL) {
2012c2c66affSColin Finck
2013c2c66affSColin Finck status = STATUS_INSUFFICIENT_RESOURCES;
2014c2c66affSColin Finck goto GetDeviceCapabilitiesExit;
2015c2c66affSColin Finck
2016c2c66affSColin Finck }
2017c2c66affSColin Finck
2018c2c66affSColin Finck //
2019c2c66affSColin Finck // Pnp Irps all begin life as STATUS_NOT_SUPPORTED;
2020c2c66affSColin Finck //
2021c2c66affSColin Finck pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
2022c2c66affSColin Finck
2023c2c66affSColin Finck //
2024c2c66affSColin Finck // Get the top of stack
2025c2c66affSColin Finck //
2026c2c66affSColin Finck irpStack = IoGetNextIrpStackLocation( pnpIrp );
2027c2c66affSColin Finck
2028c2c66affSColin Finck //
2029c2c66affSColin Finck // Set the top of stack
2030c2c66affSColin Finck //
2031c2c66affSColin Finck RtlZeroMemory( irpStack, sizeof(IO_STACK_LOCATION ) );
2032c2c66affSColin Finck irpStack->MajorFunction = IRP_MJ_PNP;
2033c2c66affSColin Finck irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
2034c2c66affSColin Finck irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;
2035c2c66affSColin Finck
2036c2c66affSColin Finck //
2037c2c66affSColin Finck // Call the driver
2038c2c66affSColin Finck //
2039c2c66affSColin Finck status = IoCallDriver( targetObject, pnpIrp );
2040c2c66affSColin Finck if (status == STATUS_PENDING) {
2041c2c66affSColin Finck
2042c2c66affSColin Finck //
2043c2c66affSColin Finck // Block until the irp comes back.
2044c2c66affSColin Finck // Important thing to note here is when you allocate
2045c2c66affSColin Finck // the memory for an event in the stack you must do a
2046c2c66affSColin Finck // KernelMode wait instead of UserMode to prevent
2047c2c66affSColin Finck // the stack from getting paged out.
2048c2c66affSColin Finck //
2049c2c66affSColin Finck
2050c2c66affSColin Finck KeWaitForSingleObject(
2051c2c66affSColin Finck &pnpEvent,
2052c2c66affSColin Finck Executive,
2053c2c66affSColin Finck KernelMode,
2054c2c66affSColin Finck FALSE,
2055c2c66affSColin Finck NULL
2056c2c66affSColin Finck );
2057c2c66affSColin Finck status = ioStatus.Status;
2058c2c66affSColin Finck
2059c2c66affSColin Finck }
2060c2c66affSColin Finck
2061c2c66affSColin Finck GetDeviceCapabilitiesExit:
2062c2c66affSColin Finck //
2063c2c66affSColin Finck // Done with reference
2064c2c66affSColin Finck //
2065c2c66affSColin Finck ObDereferenceObject( targetObject );
2066c2c66affSColin Finck
2067c2c66affSColin Finck //
2068c2c66affSColin Finck // Done
2069c2c66affSColin Finck //
2070c2c66affSColin Finck return status;
2071c2c66affSColin Finck
2072c2c66affSColin Finck }
20739bcd8350SThomas Faber #endif /* UNIT_TEST */
2074