1 /* 2 * PROJECT: ReactOS ACPI-Compliant Control Method Battery 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: boot/drivers/bus/acpi/cmbatt/cmexec.c 5 * PURPOSE: ACPI Method Execution/Evaluation Glue 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "cmbatt.h" 12 13 #include <acpiioct.h> 14 #include <debug.h> 15 16 /* FUNCTIONS ******************************************************************/ 17 18 NTSTATUS 19 NTAPI 20 GetDwordElement(IN PACPI_METHOD_ARGUMENT Argument, 21 OUT PULONG Value) 22 { 23 NTSTATUS Status; 24 25 /* Must have an integer */ 26 if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) 27 { 28 /* Not an integer, fail */ 29 Status = STATUS_ACPI_INVALID_DATA; 30 if (CmBattDebug & 0x4C) 31 DbgPrint("GetDwordElement: Object contained wrong data type - %d\n", 32 Argument->Type); 33 } 34 else 35 { 36 /* Read the integer value */ 37 *Value = Argument->Argument; 38 Status = STATUS_SUCCESS; 39 } 40 41 /* Return status */ 42 return Status; 43 } 44 45 NTSTATUS 46 NTAPI 47 GetStringElement(IN PACPI_METHOD_ARGUMENT Argument, 48 OUT PCHAR Value) 49 { 50 NTSTATUS Status; 51 52 /* Must have a string of buffer */ 53 if ((Argument->Type == ACPI_METHOD_ARGUMENT_STRING) || 54 (Argument->Type == ACPI_METHOD_ARGUMENT_BUFFER)) 55 { 56 /* String must be less than 256 characters */ 57 if (Argument->DataLength < 256) 58 { 59 /* Copy the buffer */ 60 RtlCopyMemory(Value, Argument->Data, Argument->DataLength); 61 Status = STATUS_SUCCESS; 62 } 63 else 64 { 65 /* The buffer is too small (the string is too large) */ 66 Status = STATUS_BUFFER_TOO_SMALL; 67 if (CmBattDebug & 0x4C) 68 DbgPrint("GetStringElement: return buffer not big enough - %d\n", Argument->DataLength); 69 } 70 } 71 else 72 { 73 /* Not valid string data */ 74 Status = STATUS_ACPI_INVALID_DATA; 75 if (CmBattDebug & 0x4C) 76 DbgPrint("GetStringElement: Object contained wrong data type - %d\n", Argument->Type); 77 } 78 79 /* Return the status */ 80 return Status; 81 } 82 83 NTSTATUS 84 NTAPI 85 CmBattSendDownStreamIrp(IN PDEVICE_OBJECT DeviceObject, 86 IN ULONG IoControlCode, 87 IN PVOID InputBuffer, 88 IN ULONG InputBufferLength, 89 IN PACPI_EVAL_OUTPUT_BUFFER OutputBuffer, 90 IN ULONG OutputBufferLength) 91 { 92 PIRP Irp; 93 NTSTATUS Status; 94 KEVENT Event; 95 IO_STATUS_BLOCK IoStatusBlock; 96 PAGED_CODE(); 97 98 /* Initialize our wait event */ 99 KeInitializeEvent(&Event, SynchronizationEvent, 0); 100 101 /* Allocate the IRP */ 102 Irp = IoBuildDeviceIoControlRequest(IoControlCode, 103 DeviceObject, 104 InputBuffer, 105 InputBufferLength, 106 OutputBuffer, 107 OutputBufferLength, 108 0, 109 &Event, 110 &IoStatusBlock); 111 if (!Irp) 112 { 113 /* No IRP, fail */ 114 if (CmBattDebug & 0x4C) 115 DbgPrint("CmBattSendDownStreamIrp: Failed to allocate Irp\n"); 116 return STATUS_INSUFFICIENT_RESOURCES; 117 } 118 119 /* Call ACPI */ 120 if (CmBattDebug & 0x40) 121 DbgPrint("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n", 122 Irp, KeGetCurrentThread()); 123 Status = IoCallDriver(DeviceObject, Irp); 124 if (Status == STATUS_PENDING) 125 { 126 /* Wait for completion */ 127 KeWaitForSingleObject(&Event, 128 Executive, 129 KernelMode, 130 FALSE, 131 NULL); 132 Status = Irp->IoStatus.Status; 133 } 134 135 /* Check if caller wanted output */ 136 if (OutputBuffer) 137 { 138 /* Make sure it's valid ACPI output buffer */ 139 if ((OutputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) || 140 !(OutputBuffer->Count)) 141 { 142 /* It isn't, so set failure code */ 143 Status = STATUS_ACPI_INVALID_DATA; 144 } 145 } 146 147 /* Return status */ 148 if (CmBattDebug & 0x40) 149 DbgPrint("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n", 150 Irp, Status, KeGetCurrentThread()); 151 return Status; 152 } 153 154 NTSTATUS 155 NTAPI 156 CmBattGetPsrData(IN PDEVICE_OBJECT DeviceObject, 157 OUT PULONG PsrData) 158 { 159 NTSTATUS Status; 160 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer; 161 ACPI_EVAL_INPUT_BUFFER InputBuffer; 162 PAGED_CODE(); 163 if (CmBattDebug & 0x40) 164 DbgPrint("CmBattGetPsrData: Entered with Pdo %x Tid %x\n", 165 DeviceObject, KeGetCurrentThread()); 166 167 /* Initialize to zero */ 168 ASSERT(PsrData != NULL); 169 *PsrData = 0; 170 171 /* Request the _PSR method */ 172 *(PULONG)InputBuffer.MethodName = 'RSP_'; 173 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE; 174 175 /* Send it to ACPI */ 176 Status = CmBattSendDownStreamIrp(DeviceObject, 177 IOCTL_ACPI_EVAL_METHOD, 178 &InputBuffer, 179 sizeof(InputBuffer), 180 &OutputBuffer, 181 sizeof(OutputBuffer)); 182 if (NT_SUCCESS(Status)) 183 { 184 /* Read the result */ 185 Status = GetDwordElement(OutputBuffer.Argument, PsrData); 186 if (CmBattDebug & 0x440) 187 DbgPrint("CmBattGetPsrData: _PSR method returned %x \n", *PsrData); 188 } 189 else if (CmBattDebug & 0x44C) 190 { 191 /* Failure */ 192 DbgPrint("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", Status); 193 } 194 195 /* Return status */ 196 return Status; 197 } 198 199 NTSTATUS 200 NTAPI 201 CmBattGetStaData(IN PDEVICE_OBJECT DeviceObject, 202 OUT PULONG StaData) 203 { 204 NTSTATUS Status; 205 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer; 206 ACPI_EVAL_INPUT_BUFFER InputBuffer; 207 PAGED_CODE(); 208 if (CmBattDebug & 0x40) 209 DbgPrint("CmBattGetStaData: Entered with Pdo %x Tid %x\n", 210 DeviceObject, KeGetCurrentThread()); 211 212 /* Initialize to zero */ 213 ASSERT(StaData != NULL); 214 *StaData = 0; 215 216 /* Request the _PSR method */ 217 *(PULONG)InputBuffer.MethodName = 'ATS_'; 218 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE; 219 220 /* Send it to ACPI */ 221 Status = CmBattSendDownStreamIrp(DeviceObject, 222 IOCTL_ACPI_EVAL_METHOD, 223 &InputBuffer, 224 sizeof(InputBuffer), 225 &OutputBuffer, 226 sizeof(OutputBuffer)); 227 if (NT_SUCCESS(Status)) 228 { 229 /* Read the result */ 230 Status = GetDwordElement(OutputBuffer.Argument, StaData); 231 if (CmBattDebug & 0x440) 232 DbgPrint("CmBattGetStaData: _STA method returned %x \n", *StaData); 233 } 234 else if (CmBattDebug & 0x44C) 235 { 236 /* Failure */ 237 DbgPrint("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", Status); 238 Status = STATUS_NO_SUCH_DEVICE; 239 } 240 241 /* Return status */ 242 return Status; 243 } 244 245 NTSTATUS 246 NTAPI 247 CmBattGetUniqueId(IN PDEVICE_OBJECT DeviceObject, 248 OUT PULONG UniqueId) 249 { 250 NTSTATUS Status; 251 ACPI_EVAL_OUTPUT_BUFFER OutputBuffer; 252 ACPI_EVAL_INPUT_BUFFER InputBuffer; 253 PAGED_CODE(); 254 if (CmBattDebug & 0x40) 255 DbgPrint("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n", 256 DeviceObject, KeGetCurrentThread()); 257 258 /* Initialize to zero */ 259 ASSERT(UniqueId != NULL); 260 *UniqueId = 0; 261 262 /* Request the _PSR method */ 263 *(PULONG)InputBuffer.MethodName = 'DIU_'; 264 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE; 265 266 /* Send it to ACPI */ 267 Status = CmBattSendDownStreamIrp(DeviceObject, 268 IOCTL_ACPI_EVAL_METHOD, 269 &InputBuffer, 270 sizeof(InputBuffer), 271 &OutputBuffer, 272 sizeof(OutputBuffer)); 273 if (NT_SUCCESS(Status)) 274 { 275 /* Read the result */ 276 Status = GetDwordElement(OutputBuffer.Argument, UniqueId); 277 if (CmBattDebug & 0x440) 278 DbgPrint("CmBattGetUniqueId: _UID method returned %x \n", *UniqueId); 279 } 280 else if (CmBattDebug & 0x44C) 281 { 282 /* Failure */ 283 DbgPrint("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", Status); 284 Status = STATUS_NO_SUCH_DEVICE; 285 } 286 287 /* Return status */ 288 return Status; 289 } 290 291 NTSTATUS 292 NTAPI 293 CmBattSetTripPpoint(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, 294 IN ULONG AlarmValue) 295 { 296 NTSTATUS Status; 297 ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER InputBuffer; 298 PAGED_CODE(); 299 if (CmBattDebug & 0x440) 300 DbgPrint("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n", 301 AlarmValue, DeviceExtension->DeviceId, KeGetCurrentThread); 302 303 /* Request the _BTP method */ 304 *(PULONG)InputBuffer.MethodName = 'PTB_'; 305 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE; 306 InputBuffer.IntegerArgument = AlarmValue; 307 308 /* Send it to ACPI */ 309 Status = CmBattSendDownStreamIrp(DeviceExtension->AttachedDevice, 310 IOCTL_ACPI_EVAL_METHOD, 311 &InputBuffer, 312 sizeof(InputBuffer), 313 NULL, 314 0); 315 if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0x440)) 316 DbgPrint("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n", 317 DeviceExtension->DeviceId, Status); 318 319 /* Return status */ 320 return Status; 321 } 322 323 NTSTATUS 324 NTAPI 325 CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension, 326 PACPI_BIF_DATA BifData) 327 { 328 UNIMPLEMENTED; 329 return STATUS_NOT_IMPLEMENTED; 330 } 331 332 NTSTATUS 333 NTAPI 334 CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension, 335 PACPI_BST_DATA BstData) 336 { 337 UNIMPLEMENTED; 338 return STATUS_NOT_IMPLEMENTED; 339 } 340 341 /* EOF */ 342