ReactOS 0.4.16-dev-2633-g8dc9e50
dev_config.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS ATA Port Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Device initialization and configuration code
5 * COPYRIGHT: Copyright 2026 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "atapi.h"
11
12#include <acpiioct.h>
13
14/* FUNCTIONS ******************************************************************/
15
16static
19 _In_ PATAPORT_PORT_DATA PortData,
21{
22 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
24
25 if (IS_ATAPI(&DevExt->Device) || (DevExt->Device.DeviceFlags & DEVICE_LBA_MODE))
26 return STATUS_SUCCESS;
27
29 Request->TimeOut = 5;
30
31 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
32 Request->TaskFile.Command = IDE_COMMAND_SET_DRIVE_PARAMETERS;
33 Request->TaskFile.SectorCount = (UCHAR)DevExt->Device.SectorsPerTrack;
34 Request->TaskFile.DriveSelect = (UCHAR)(DevExt->Device.Heads - 1) |
35 DevExt->Device.DeviceSelect;
36
37 Status = AtaPortSendRequest(PortData, DevExt);
38 if (!NT_SUCCESS(Status))
39 {
40 WARN("CH %lu: Failed to set geometry for '%s'\n",
41 PortData->PortNumber,
42 DevExt->TransferModeSelectedBitmap,
43 DevExt->FriendlyName);
44 }
45
46 return Status;
47}
48
49static
50VOID
54{
55 Request->Flags = 0;
56 Request->TimeOut = 3;
57
58 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
59 Request->TaskFile.Command = IDE_COMMAND_SET_FEATURE;
60 Request->TaskFile.Feature = IDE_FEATURE_SET_TRANSFER_MODE;
61 Request->TaskFile.SectorCount = Mode;
62}
63
64static
67 _In_ PATAPORT_PORT_DATA PortData,
69{
70 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
72 ULONG Mode;
73
74 NT_VERIFY(_BitScanReverse(&Mode, DevExt->TransferModeSelectedBitmap & PIO_ALL) != 0);
75
78
79 Status = AtaPortSendRequest(PortData, DevExt);
80 if (!NT_SUCCESS(Status))
81 {
82 WARN("CH %lu: Failed to set %lu PIO settings for '%s'\n",
83 PortData->PortNumber,
84 Mode,
85 DevExt->FriendlyName);
86 }
87
88 return Status;
89}
90
91static
94 _In_ PATAPORT_PORT_DATA PortData,
96{
97 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
99 ULONG Mode;
100
101 if (!_BitScanReverse(&Mode, DevExt->TransferModeSelectedBitmap & ~PIO_ALL))
102 return STATUS_SUCCESS;
103
104 if (Mode >= UDMA_MODE(0))
106 else if (Mode >= MWDMA_MODE(0))
108 else
111
112 Status = AtaPortSendRequest(PortData, DevExt);
113 if (NT_SUCCESS(Status))
114 {
115 DevExt->Device.DeviceFlags &= ~DEVICE_PIO_ONLY;
116 }
117 else
118 {
119 WARN("CH %lu: Failed to set 0x%lx DMA settings for '%s'\n",
120 PortData->PortNumber,
121 Mode,
122 DevExt->FriendlyName);
123
124 DevExt->Device.DeviceFlags &= ~DEVICE_NCQ;
125 DevExt->TransferModeSelectedBitmap &= PIO_ALL;
126 }
127
128 return Status;
129}
130
131static
134 _In_ PATAPORT_PORT_DATA PortData,
136{
137 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
139
140 if (IS_ATAPI(&DevExt->Device))
141 return STATUS_SUCCESS;
142
143 DevExt->Device.MultiSectorCount = AtaDevMaximumSectorsPerDrq(&DevExt->IdentifyDeviceData);
144 if (DevExt->Device.MultiSectorCount == 0)
145 return STATUS_SUCCESS;
146
147 Request->Flags = 0;
148 Request->TimeOut = 3;
149
150 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
151 Request->TaskFile.Command = IDE_COMMAND_SET_MULTIPLE;
152 Request->TaskFile.SectorCount = DevExt->Device.MultiSectorCount;
153
154 Status = AtaPortSendRequest(PortData, DevExt);
155 if (!NT_SUCCESS(Status))
156 {
157 WARN("CH %lu: Failed to set %u multiple mode for '%s'\n",
158 PortData->PortNumber,
159 DevExt->Device.MultiSectorCount,
160 DevExt->FriendlyName);
161
162 DevExt->Device.MultiSectorCount = 0;
163 }
164
165 return Status;
166}
167
168static
171 _In_ PATA_ACPI_TASK_FILE AcpiTaskFile)
172{
173 switch (AcpiTaskFile->Command)
174 {
175 /* These features are managed by the driver */
177 {
178 if (AcpiTaskFile->Feature == IDE_FEATURE_SET_TRANSFER_MODE)
179 return FALSE;
180 break;
181 }
184 return FALSE;
185
186 // TODO: Anything else to check?
187 default:
188 break;
189 }
190
191 return TRUE;
192}
193
194static
195VOID
197 _In_ ATA_ACPI_TASK_FILE* __restrict AcpiTaskFile,
198 _Out_ ATA_DEVICE_REQUEST* __restrict Request)
199{
201 Request->TimeOut = 6;
202
203 Request->TaskFile.Feature = AcpiTaskFile->Feature;
204 Request->TaskFile.SectorCount = AcpiTaskFile->SectorCount;
205 Request->TaskFile.LowLba = AcpiTaskFile->LowLba;
206 Request->TaskFile.MidLba = AcpiTaskFile->MidLba;
207 Request->TaskFile.HighLba = AcpiTaskFile->HighLba;
208 Request->TaskFile.DriveSelect = AcpiTaskFile->DriveSelect;
209 Request->TaskFile.Command = AcpiTaskFile->Command;
210}
211
212static
215 _In_ PATAPORT_PORT_DATA PortData,
217{
218 PACPI_EVAL_OUTPUT_BUFFER GtfDataBuffer = DevExt->GtfDataBuffer;
219 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
220 PATA_ACPI_TASK_FILE AcpiTaskFile;
222 ULONG i;
223
224 if (!GtfDataBuffer)
225 return STATUS_SUCCESS;
226
227 ASSERT(GtfDataBuffer->Signature == ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE);
228
229 AcpiTaskFile = (PATA_ACPI_TASK_FILE)GtfDataBuffer->Argument[0].Data;
230
231 for (i = 0; i < GtfDataBuffer->Argument[0].DataLength / sizeof(*AcpiTaskFile); ++i)
232 {
234
235 if (!AtaDeviceFilterAcpiTaskFile(AcpiTaskFile))
236 {
237 Result = "filtered out";
238 }
239 else
240 {
242
243 Status = AtaPortSendRequest(PortData, DevExt);
245 return Status;
246 Result = NT_SUCCESS(Status) ? "completed" : "aborted";
247 }
248 INFO("CH %lu: GTF[%lu]: %02x:%02x:%02x:%02x:%02x:%02x:%02x -- %s\n",
249 PortData->PortNumber,
250 i,
251 AcpiTaskFile->Feature,
252 AcpiTaskFile->SectorCount,
253 AcpiTaskFile->LowLba,
254 AcpiTaskFile->MidLba,
255 AcpiTaskFile->HighLba,
256 AcpiTaskFile->DriveSelect,
257 AcpiTaskFile->Command,
258 Result);
259
260 ++AcpiTaskFile;
261 }
262
263 return STATUS_SUCCESS;
264}
265
266/*
267 * See MSDN note:
268 * https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/security-group-commands
269 */
270static
273 _In_ PATAPORT_PORT_DATA PortData,
275{
276 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
277
278 if (IS_ATAPI(&DevExt->Device) ||
279 AtapInPEMode ||
280 !AtaDevHasSecurityModeFeature(&DevExt->IdentifyDeviceData))
281 {
282 return STATUS_SUCCESS;
283 }
284
285 Request->Flags = 0;
286 Request->TimeOut = 3;
287
288 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
289 Request->TaskFile.Command = IDE_COMMAND_SECURITY_FREEZE_LOCK;
290
291 return AtaPortSendRequest(PortData, DevExt);
292}
293
294static
297 _In_ PATAPORT_PORT_DATA PortData,
299{
300 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
301
302 Request->Flags = 0;
303 Request->TimeOut = 3;
304
305 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
306 Request->TaskFile.Command = IDE_COMMAND_SET_FEATURE;
308
309 return AtaPortSendRequest(PortData, DevExt);
310}
311
312static
315 _In_ PATAPORT_PORT_DATA PortData,
317{
318 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
320
321 if (!AtaDevHasRemovableMediaStatusNotification(&DevExt->IdentifyDeviceData))
322 return STATUS_SUCCESS;
323
324 Request->Flags = 0;
325 Request->TimeOut = 3;
326
327 RtlZeroMemory(&Request->TaskFile, sizeof(Request->TaskFile));
328 Request->TaskFile.Command = IDE_COMMAND_SET_FEATURE;
329 Request->TaskFile.Feature = IDE_FEATURE_ENABLE_MSN;
330
331 Status = AtaPortSendRequest(PortData, DevExt);
332 if (NT_SUCCESS(Status))
333 {
334 DevExt->Device.DeviceFlags |= DEVICE_HAS_MEDIA_STATUS;
335 }
336
337 return Status;
338}
339
342 _In_ PATAPORT_PORT_DATA PortData,
344{
346
347 DevExt->Device.DeviceFlags |= DEVICE_PIO_ONLY;
348 DevExt->Device.DeviceFlags &= ~(DEVICE_HAS_MEDIA_STATUS | DEVICE_SENSE_DATA_REPORTING);
349 DevExt->Device.MultiSectorCount = 0;
350
351 Status = AtaDeviceSetGeometry(PortData, DevExt);
353 return Status;
354
355 Status = AtaDeviceSetPioTransferMode(PortData, DevExt);
357 return Status;
358
359 Status = AtaDeviceSetDmaTransferMode(PortData, DevExt);
361 return Status;
362
363 Status = AtaDeviceSetMultipleMode(PortData, DevExt);
365 return Status;
366
367 Status = AtaDeviceExecuteAcpiTaskFile(PortData, DevExt);
369 return Status;
370
373 return Status;
374
375 Status = AtaDeviceLockDeviceParameters(PortData, DevExt);
377 return Status;
378
379 Status = AtaDeviceEnableMsnFeature(PortData, DevExt);
381 return Status;
382
383 /* Identify data might have changed during the configuration, so update it here */
384 Status = AtaDeviceSendIdentify(PortData,
385 DevExt,
386 IS_ATAPI(&DevExt->Device) ?
388 if (NT_SUCCESS(Status))
389 {
390 RtlCopyMemory(&DevExt->IdentifyDeviceData,
391 DevExt->Device.LocalBuffer,
392 sizeof(DevExt->IdentifyDeviceData));
393 }
394
395 return Status;
396}
#define ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:16
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:99
unsigned char BOOLEAN
Definition: actypes.h:127
#define IDE_FEATURE_ENABLE_MSN
Definition: ata.h:727
#define IDE_SET_UDMA_MODE(mode)
Definition: ata.h:715
#define IDE_SET_MWDMA_MODE(mode)
Definition: ata.h:714
#define IDE_SET_SWDMA_MODE(mode)
Definition: ata.h:713
#define IDE_COMMAND_SECURITY_FREEZE_LOCK
Definition: ata.h:707
#define IDE_SET_ADVANCE_PIO_MODE(mode)
Definition: ata.h:712
#define IDE_FEATURE_DISABLE_REVERT_TO_POWER_ON
Definition: ata.h:723
#define IDE_FEATURE_SET_TRANSFER_MODE
Definition: ata.h:718
#define IDE_COMMAND_SET_FEATURE
Definition: ata.h:702
struct _ATA_ACPI_TASK_FILE * PATA_ACPI_TASK_FILE
#define MWDMA_MODE(n)
Definition: ata_user.h:38
#define SWDMA_MODE(n)
Definition: ata_user.h:37
#define PIO_ALL
Definition: ata_user.h:19
#define UDMA_MODE(n)
Definition: ata_user.h:39
BOOLEAN AtapInPEMode
Definition: atapi.c:15
#define DEVICE_PIO_ONLY
Definition: atapi.h:82
#define DEVICE_SENSE_DATA_REPORTING
Definition: atapi.h:88
NTSTATUS AtaPortSendRequest(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: portstate.c:831
#define DEVICE_LBA_MODE
Definition: atapi.h:83
#define DEVICE_HAS_MEDIA_STATUS
Definition: atapi.h:87
NTSTATUS AtaDeviceSendIdentify(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ UCHAR Command)
Definition: dev_identify.c:45
#define IS_ATAPI(Device)
Definition: atapi.h:176
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_SET_DRIVE_PARAMETERS
Definition: atapi.h:108
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
LONG NTSTATUS
Definition: precomp.h:26
#define WARN(fmt,...)
Definition: precomp.h:61
static NTSTATUS AtaDeviceLockSecurityModeFeatureCommands(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:272
static VOID AtaDeviceBuildSetTransferModeTaskFile(_In_ PATA_DEVICE_REQUEST Request, _In_ UCHAR Mode)
Definition: dev_config.c:51
static NTSTATUS AtaDeviceSetGeometry(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:18
static NTSTATUS AtaDeviceSetMultipleMode(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:133
static NTSTATUS AtaDeviceSetDmaTransferMode(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:93
static NTSTATUS AtaDeviceSetPioTransferMode(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:66
NTSTATUS AtaPortDeviceProcessConfig(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:341
static BOOLEAN AtaDeviceFilterAcpiTaskFile(_In_ PATA_ACPI_TASK_FILE AcpiTaskFile)
Definition: dev_config.c:170
static VOID AtaDeviceAcpiTaskFileToInternalTaskFile(_In_ ATA_ACPI_TASK_FILE *__restrict AcpiTaskFile, _Out_ ATA_DEVICE_REQUEST *__restrict Request)
Definition: dev_config.c:196
static NTSTATUS AtaDeviceEnableMsnFeature(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:314
static NTSTATUS AtaDeviceLockDeviceParameters(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:296
static NTSTATUS AtaDeviceExecuteAcpiTaskFile(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:214
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INFO
Definition: debug.h:89
for(i=0;i< ARRAY_SIZE(offsets);i++)
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ ULONG Mode
Definition: hubbusif.h:303
FORCEINLINE UCHAR AtaDevMaximumSectorsPerDrq(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:346
#define REQUEST_FLAG_SET_DEVICE_REGISTER
Definition: hwidep.h:170
FORCEINLINE BOOLEAN AtaDevHasRemovableMediaStatusNotification(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
FORCEINLINE BOOLEAN AtaDevHasSecurityModeFeature(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
#define ASSERT(a)
Definition: mode.c:44
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:524
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:180
#define STATUS_SUCCESS
Definition: shellext.h:65
unsigned char UCHAR
Definition: typedefs.h:53
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304