[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 ACPIDispatchDeviceControl(
172 IN PDEVICE_OBJECT DeviceObject,
173 IN PIRP Irp)
174 {
175 PIO_STACK_LOCATION irpStack;
176 NTSTATUS status = STATUS_NOT_SUPPORTED;
177 PCOMMON_DEVICE_DATA commonData;
178
179 PAGED_CODE ();
180
181 irpStack = IoGetCurrentIrpStackLocation (Irp);
182 ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
183
184 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
185
186 Irp->IoStatus.Information = 0;
187
188 if (!commonData->IsFDO)
189 {
190 switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
191 {
192 case IOCTL_ACPI_EVAL_METHOD:
193 status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
194 Irp);
195 break;
196
197 /* TODO: Implement other IOCTLs */
198
199 default:
200 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
201 break;
202 }
203 }
204 else
205 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
206
207 if (status != STATUS_PENDING)
208 {
209 Irp->IoStatus.Status = status;
210 IoCompleteRequest(Irp, IO_NO_INCREMENT);
211 }
212
213 return status;
214 }
215
216 NTSTATUS
217 NTAPI
218 DriverEntry (
219 PDRIVER_OBJECT DriverObject,
220 PUNICODE_STRING RegistryPath
221 )
222 {
223 DPRINT("Driver Entry \n");
224
225 //
226 // Set entry points into the driver
227 //
228 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
229 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
230 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
231
232 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
233
234 return STATUS_SUCCESS;
235 }