[ACPI]
[reactos.git] / reactos / drivers / bus / acpi / main.c
1 #include <ntddk.h>
2
3 #include <acpi.h>
4 #include <acpisys.h>
5
6 #include <acpi_bus.h>
7 #include <acpi_drivers.h>
8
9 #include <acpiioct.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 #ifdef ALLOC_PRAGMA
15 #pragma alloc_text (INIT, DriverEntry)
16 #pragma alloc_text (PAGE, Bus_AddDevice)
17
18 #endif
19
20
21
22 NTSTATUS
23 NTAPI
24 Bus_AddDevice(
25 PDRIVER_OBJECT DriverObject,
26 PDEVICE_OBJECT PhysicalDeviceObject
27 )
28
29 {
30 NTSTATUS status;
31 PDEVICE_OBJECT deviceObject = NULL;
32 PFDO_DEVICE_DATA deviceData = NULL;
33 PWCHAR deviceName = NULL;
34 #ifndef NDEBUG
35 ULONG nameLength;
36 #endif
37
38 PAGED_CODE ();
39
40 DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject);
41
42 DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
43 status = IoCreateDevice(DriverObject,
44 sizeof(FDO_DEVICE_DATA),
45 NULL,
46 FILE_DEVICE_ACPI,
47 FILE_DEVICE_SECURE_OPEN,
48 TRUE,
49 &deviceObject);
50 if (!NT_SUCCESS(status))
51 {
52 DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
53 goto End;
54 }
55
56 deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
57 RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));
58
59 //
60 // Set the initial state of the FDO
61 //
62
63 INITIALIZE_PNP_STATE(deviceData->Common);
64
65 deviceData->Common.IsFDO = TRUE;
66
67 deviceData->Common.Self = deviceObject;
68
69 ExInitializeFastMutex (&deviceData->Mutex);
70
71 InitializeListHead (&deviceData->ListOfPDOs);
72
73 // Set the PDO for use with PlugPlay functions
74
75 deviceData->UnderlyingPDO = PhysicalDeviceObject;
76
77 //
78 // Set the initial powerstate of the FDO
79 //
80
81 deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
82 deviceData->Common.SystemPowerState = PowerSystemWorking;
83
84 deviceObject->Flags |= DO_POWER_PAGABLE;
85
86 //
87 // Attach our FDO to the device stack.
88 // The return value of IoAttachDeviceToDeviceStack is the top of the
89 // attachment chain. This is where all the IRPs should be routed.
90 //
91
92 deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
93 deviceObject,
94 PhysicalDeviceObject);
95
96 if (NULL == deviceData->NextLowerDriver) {
97
98 status = STATUS_NO_SUCH_DEVICE;
99 goto End;
100 }
101
102
103 #ifndef NDEBUG
104 //
105 // We will demonstrate here the step to retrieve the name of the PDO
106 //
107
108 status = IoGetDeviceProperty (PhysicalDeviceObject,
109 DevicePropertyPhysicalDeviceObjectName,
110 0,
111 NULL,
112 &nameLength);
113
114 if (status != STATUS_BUFFER_TOO_SMALL)
115 {
116 DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
117 goto End;
118 }
119
120 deviceName = ExAllocatePoolWithTag (NonPagedPool,
121 nameLength, 'IPCA');
122
123 if (NULL == deviceName) {
124 DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
125 status = STATUS_INSUFFICIENT_RESOURCES;
126 goto End;
127 }
128
129 status = IoGetDeviceProperty (PhysicalDeviceObject,
130 DevicePropertyPhysicalDeviceObjectName,
131 nameLength,
132 deviceName,
133 &nameLength);
134
135 if (!NT_SUCCESS (status)) {
136
137 DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
138 goto End;
139 }
140
141 DPRINT("AddDevice: %p to %p->%p (%ws) \n",
142 deviceObject,
143 deviceData->NextLowerDriver,
144 PhysicalDeviceObject,
145 deviceName);
146
147 #endif
148
149 //
150 // We are done with initializing, so let's indicate that and return.
151 // This should be the final step in the AddDevice process.
152 //
153 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
154
155 End:
156 if (deviceName){
157 ExFreePool(deviceName);
158 }
159 if (!NT_SUCCESS(status) && deviceObject){
160 if (deviceData && deviceData->NextLowerDriver){
161 IoDetachDevice (deviceData->NextLowerDriver);
162 }
163 IoDeleteDevice (deviceObject);
164 }
165 return status;
166
167 }
168
169 NTSTATUS
170 NTAPI
171 ACPIDispatchCreateClose(
172 IN PDEVICE_OBJECT DeviceObject,
173 IN PIRP Irp)
174 {
175 Irp->IoStatus.Status = STATUS_SUCCESS;
176 Irp->IoStatus.Information = 0;
177
178 IoCompleteRequest(Irp, IO_NO_INCREMENT);
179
180 return STATUS_SUCCESS;
181 }
182
183 NTSTATUS
184 NTAPI
185 ACPIDispatchDeviceControl(
186 IN PDEVICE_OBJECT DeviceObject,
187 IN PIRP Irp)
188 {
189 PIO_STACK_LOCATION irpStack;
190 NTSTATUS status = STATUS_NOT_SUPPORTED;
191 PCOMMON_DEVICE_DATA commonData;
192
193 PAGED_CODE ();
194
195 irpStack = IoGetCurrentIrpStackLocation (Irp);
196 ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
197
198 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
199
200 Irp->IoStatus.Information = 0;
201
202 if (!commonData->IsFDO)
203 {
204 switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
205 {
206 case IOCTL_ACPI_EVAL_METHOD:
207 status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
208 Irp);
209 break;
210
211 /* TODO: Implement other IOCTLs */
212
213 default:
214 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
215 break;
216 }
217 }
218 else
219 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
220
221 if (status != STATUS_PENDING)
222 {
223 Irp->IoStatus.Status = status;
224 IoCompleteRequest(Irp, IO_NO_INCREMENT);
225 }
226
227 return status;
228 }
229
230 NTSTATUS
231 NTAPI
232 DriverEntry (
233 PDRIVER_OBJECT DriverObject,
234 PUNICODE_STRING RegistryPath
235 )
236 {
237 DPRINT("Driver Entry \n");
238
239 //
240 // Set entry points into the driver
241 //
242 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
243 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
244 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
245 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
246 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
247
248 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
249
250 return STATUS_SUCCESS;
251 }