ReactOS 0.4.17-dev-1190-g4c812f4
acpi.c File Reference
#include "pciidex.h"
#include <acpiioct.h>
Include dependency graph for acpi.c:

Go to the source code of this file.

Functions

 _IRQL_requires_max_ (DISPATCH_LEVEL)
 
BOOLEAN AtaAcpiGetTimingMode (_In_ PDEVICE_OBJECT DeviceObject, _Out_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode)
 
NTSTATUS AtaAcpiSetTimingMode (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode, _In_opt_ PIDENTIFY_DEVICE_DATA IdBlock1, _In_opt_ PIDENTIFY_DEVICE_DATA IdBlock2)
 
PVOID AtaAcpiGetTaskFile (_In_ PDEVICE_OBJECT DeviceObject)
 
VOID AtaAcpiSetDeviceData (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIDENTIFY_DEVICE_DATA IdBlock)
 

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 16 of file acpi.c.

25{
26 PIRP Irp;
27 PIO_STACK_LOCATION IoStack;
30 PDEVICE_OBJECT TopDeviceObject;
31 PVOID SystemBuffer;
32 ULONG SystemBufferLength;
33
34 /* Get the ACPI bus filter device for this DO */
36
37 /* METHOD_BUFFERED returns the result in place, so the buffer must fit both directions */
38 SystemBufferLength = InputBufferLength;
39 if (OutputBuffer != NULL)
40 SystemBufferLength = max(SystemBufferLength, OutputBufferLength);
41
42 SystemBuffer = ExAllocatePoolZero(NonPagedPool, SystemBufferLength, TAG_PCIIDEX);
43 if (!SystemBuffer)
44 {
46 goto Exit;
47 }
49
50 /*
51 * We could be called at DISPATCH_LEVEL,
52 * so use IoAllocateIrp() rather going through IoBuildDeviceIoControlRequest().
53 */
54 Irp = IoAllocateIrp(TopDeviceObject->StackSize, 0);
55 if (!Irp)
56 {
58 goto Exit;
59 }
60 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
61 Irp->UserBuffer = OutputBuffer;
63 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
64
65 /*
66 * Submit an asynchronous evaluation request.
67 * Note that _STM should be evaluated while the device queue has been paused,
68 * so we must not cause *any* page faults and use IOCTL_ACPI_EVAL_METHOD.
69 * AtaAcpiEvaluateObject() also has to be non-pageable.
70 */
74 IoStack->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
75 IoStack->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
76
80 &Event,
81 TRUE,
82 TRUE,
83 TRUE);
84
85 Status = IoCallDriver(TopDeviceObject, Irp);
87 {
89 Status = Irp->IoStatus.Status;
90 }
91
92 if (OutputBuffer)
93 RtlCopyMemory(OutputBuffer, SystemBuffer, min(Irp->IoStatus.Information, OutputBufferLength));
94
96
98 {
100
102 (OutputBuffer->Count == 0))
103 {
104 ERR("Invalid ACPI output buffer\n");
105
107 }
108 }
109
110Exit:
111 if (SystemBuffer)
112 ExFreePoolWithTag(SystemBuffer, TAG_PCIIDEX);
113
114 ObDereferenceObject(TopDeviceObject);
115 return Status;
116}
#define IOCTL_ACPI_ASYNC_EVAL_METHOD
Definition: acpiioct.h:193
#define ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:16
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: precomp.h:57
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:24
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
_In_ PIRP Irp
Definition: kse.h:79
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define min(a, b)
Definition: monoChain.cc:55
#define KernelMode
Definition: asm.h:38
@ NotificationEvent
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1416
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:647
#define IoCallDriver
Definition: irp.c:1257
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1698
#define STATUS_ACPI_INVALID_DATA
Definition: ntstatus.h:1662
IO_COMPLETION_ROUTINE PciIdeXPdoCompletionRoutine
Definition: pciidex.h:528
#define TAG_PCIIDEX
Definition: pciidex.h:32
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
static void Exit(void)
Definition: sock.c:1330
union _IO_STACK_LOCATION::@1814 Parameters
struct _IO_STACK_LOCATION::@1814::@1815 DeviceIoControl
#define max(a, b)
Definition: svc.c:63
#define STATUS_PENDING
Definition: telnetd.h:14
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
_In_ PGUID _In_ ULONG OutputBufferLength
Definition: ucxcontroller.h:81
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2702
#define IRP_INPUT_OPERATION
#define IRP_BUFFERED_IO
@ Executive
Definition: ketypes.h:467
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ AtaAcpiGetTaskFile()

PVOID AtaAcpiGetTaskFile ( _In_ PDEVICE_OBJECT  DeviceObject)

Definition at line 233 of file acpi.c.

235{
238 ULONG RetryCount, OutputSize;
240
241 PAGED_CODE();
242 /*
243 * We invoke this routine within the PnP START handler only,
244 * and thus specify that the code is in a pageable section.
245 */
247
248 InputBuffer.MethodNameAsUlong = 'FTG_'; // _GTF
250
251 /*
252 * The output buffer must be large enough to hold the list of ATA commands to the drive.
253 * We assume that 10 commands is the common case.
254 */
257
258 for (RetryCount = 0; RetryCount < 2; ++RetryCount)
259 {
261 if (!OutputBuffer)
262 {
263 ERR("Failed to allocate memory of size %lu\n", OutputSize);
264 return NULL;
265 }
266
267 /* Evaluate the _GTF method */
268 Status = AtaAcpiEvaluateObject(DeviceObject,
270 sizeof(InputBuffer),
272 OutputSize);
273
274 /* Increase the allocation size if it's too small */
276 {
277 OutputSize = OutputBuffer->Length;
278
280 continue;
281 }
282
283 break;
284 }
285
286 if (!NT_SUCCESS(Status))
287 goto Cleanup;
288
289 if (OutputBuffer->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER)
290 {
291 ERR("Unexpected method type %u\n", OutputBuffer->Argument[0].Type);
292 goto Cleanup;
293 }
294
295 if (OutputBuffer->Argument[0].DataLength % sizeof(ATA_ACPI_TASK_FILE))
296 {
297 ERR("Incorrect command stream length %u\n", OutputBuffer->Argument[0].DataLength);
298 goto Cleanup;
299 }
300
301 if (OutputBuffer->Argument[0].DataLength == 0)
302 {
303 WARN("Empty command list\n");
304 goto Cleanup;
305 }
306
307 return OutputBuffer;
308
309Cleanup:
311
312 return NULL;
313}
#define PAGED_CODE()
#define ACPI_METHOD_ARGUMENT_LENGTH(DataLength)
Definition: acpiioct.h:153
#define ACPI_EVAL_INPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:12
#define ACPI_METHOD_ARGUMENT_BUFFER
Definition: acpiioct.h:32
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:99
#define WARN(fmt,...)
Definition: precomp.h:61
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG _In_ PVOID Argument
Definition: dispmprt.h:1288
static const WCHAR Cleanup[]
Definition: register.c:80
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by AtaCtrlGetInitTaskFile().

◆ AtaAcpiGetTimingMode()

BOOLEAN AtaAcpiGetTimingMode ( _In_ PDEVICE_OBJECT  DeviceObject,
_Out_ PIDE_ACPI_TIMING_MODE_BLOCK  TimingMode 
)

Definition at line 119 of file acpi.c.

122{
124 ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*TimingMode))];
128
129 RtlZeroMemory(Buffer, sizeof(Buffer));
130
131 InputBuffer.MethodNameAsUlong = 'MTG_'; // _GTM
133
134 /* Evaluate the _GTM method */
135 Status = AtaAcpiEvaluateObject(DeviceObject,
137 sizeof(InputBuffer),
139 sizeof(Buffer));
140
141 if (!NT_SUCCESS(Status))
142 {
144
145 TRACE("Failed to evaluate the _GTM method, status 0x%lx\n", Status);
146 return FALSE;
147 }
148
149 if (OutputBuffer->Argument[0].DataLength < sizeof(*TimingMode))
150 {
151 ERR("Buffer too small, size %u/%u\n",
152 OutputBuffer->Argument[0].DataLength, sizeof(*TimingMode));
153 return FALSE;
154 }
155
156 if (OutputBuffer->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER)
157 {
158 ERR("Unexpected method type %u\n", OutputBuffer->Argument[0].Type);
159 return FALSE;
160 }
161
162 RtlCopyMemory(TimingMode, OutputBuffer->Argument[0].Data, sizeof(*TimingMode));
163
164 return TRUE;
165}
Definition: bufpool.h:45
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by PciIdeAcpiSetTransferMode(), and PciIdeXPdoStartDevice().

◆ AtaAcpiSetDeviceData()

VOID AtaAcpiSetDeviceData ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIDENTIFY_DEVICE_DATA  IdBlock 
)

Definition at line 317 of file acpi.c.

320{
324 ULONG InputSize;
325
326 PAGED_CODE();
328
330 ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*IdBlock));
331
333 if (!InputBuffer)
334 {
335 ERR("Failed to allocate memory\n");
336 return;
337 }
338 InputBuffer->MethodNameAsUlong = 'DDS_'; // _SDD
340 InputBuffer->ArgumentCount = 1;
341 InputBuffer->Size = InputSize;
342
343 /* Argument 1: The ATA drive ID block */
344 Argument = InputBuffer->Argument;
345 ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, IdBlock, sizeof(*IdBlock));
346
347 /* Evaluate the _SDD method */
348 Status = AtaAcpiEvaluateObject(DeviceObject, InputBuffer, InputSize, NULL, 0);
349 if (!NT_SUCCESS(Status))
350 {
352 TRACE("Failed to set device data, status 0x%lx\n", Status);
353 else
354 WARN("Failed to set device data, status 0x%lx\n", Status);
355 }
356
358}
#define ExAllocatePoolUninitialized
#define ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE
Definition: acpiioct.h:15
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:80
#define ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, BuffData, BuffLength)
Definition: acpiioct.h:174
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by AtaCtrlSetDeviceData().

◆ AtaAcpiSetTimingMode()

NTSTATUS AtaAcpiSetTimingMode ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIDE_ACPI_TIMING_MODE_BLOCK  TimingMode,
_In_opt_ PIDENTIFY_DEVICE_DATA  IdBlock1,
_In_opt_ PIDENTIFY_DEVICE_DATA  IdBlock2 
)

Definition at line 168 of file acpi.c.

173{
177 ULONG InputSize;
178
180 ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*TimingMode)) +
181 ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*IdBlock1)) +
182 ACPI_METHOD_ARGUMENT_LENGTH(sizeof(*IdBlock2));
183
185 if (!InputBuffer)
186 {
187 ERR("Failed to allocate memory\n");
189 }
190 InputBuffer->MethodNameAsUlong = 'MTS_'; // _STM
192 InputBuffer->ArgumentCount = 3;
193 InputBuffer->Size = InputSize;
194
195 /* Argument 1: The channel timing information block */
196 Argument = InputBuffer->Argument;
197 ACPI_METHOD_SET_ARGUMENT_BUFFER(Argument, TimingMode, sizeof(*TimingMode));
198
199 /* Argument 2: The ATA drive ID block */
202 Argument->DataLength = sizeof(*IdBlock1);
203 if (IdBlock1)
204 RtlCopyMemory(Argument->Data, IdBlock1, sizeof(*IdBlock1));
205 else
206 RtlZeroMemory(Argument->Data, sizeof(*IdBlock1));
207
208 /* Argument 3: The ATA drive ID block */
211 Argument->DataLength = sizeof(*IdBlock2);
212 if (IdBlock2)
213 RtlCopyMemory(Argument->Data, IdBlock2, sizeof(*IdBlock2));
214 else
215 RtlZeroMemory(Argument->Data, sizeof(*IdBlock2));
216
217 /* Evaluate the _STM method */
218 Status = AtaAcpiEvaluateObject(DeviceObject, InputBuffer, InputSize, NULL, 0);
219 if (!NT_SUCCESS(Status))
220 {
222 INFO("Failed to set transfer timings, status 0x%lx\n", Status);
223 else
224 ERR("Failed to set transfer timings, status 0x%lx\n", Status);
225 }
226
228 return Status;
229}
#define ACPI_METHOD_NEXT_ARGUMENT(Argument)
Definition: acpiioct.h:159
#define INFO
Definition: debug.h:89

Referenced by AtaCtrlSetTransferMode(), and PciIdeAcpiSetTransferMode().