ReactOS 0.4.16-dev-2633-g8dc9e50
pata_generic.c File Reference
#include "pciidex.h"
Include dependency graph for pata_generic.c:

Go to the source code of this file.

Functions

static ATATIM AtaGetClocks (_In_ ATATIM TimingValueNs, _In_ ULONG ClockPeriodPs)
 
static VOID AtaCalculateTimings (_In_ PCHANNEL_DEVICE_CONFIG Device, _Out_ PATA_TIMING Timing, _In_ ULONG Mode, _In_ ULONG ClockPeriodPs)
 
VOID AtaSelectTimings (_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList, _Out_writes_all_(MAX_IDE_DEVICE) PATA_TIMING Timings, _In_range_(>, 0) ULONG ClockPeriodPs, _In_ ULONG Flags)
 
VOID SataSetTransferMode (_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
 
static VOID AtaAcpiFindModeForCycleTime (_In_ ULONG GtmCycleTime, _In_ ULONG SupportedModesBitmap, _In_ ULONG CurrentModesBitmap, _In_ ULONG MinimumMode, _In_ ULONG MaximumMode, _Out_ PULONG BestCycleTime, _Out_ PULONG BestMode)
 
static VOID PciIdeAcpiSetTransferMode (_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
 
static VOID PciIdeBiosSetTransferMode (_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
 
static VOID PciIdeGenericSetTransferMode (_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
 
static VOID PataReleaseLegacyAddressRanges (_In_ PCHANNEL_DATA_PATA ChanData)
 
static VOID PataClaimLegacyAddressRanges (_In_ PCHANNEL_DATA_PATA ChanData)
 
static VOID PciIdeFreeMemory (_In_ PVOID ChannelContext)
 
static NTSTATUS PciIdeAllocateMemory (_In_ PVOID ChannelContext)
 
static BOOLEAN PciIdeIsDmaStatusValid (_In_ UCHAR DmaStatus)
 
static BOOLEAN PciIdeControllerInitDma (_In_ PATA_CONTROLLER Controller)
 
VOID PciIdeInitTaskFileIoResources (_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG_PTR CommandPortBase, _In_ ULONG_PTR ControlPortBase, _In_ ULONG CommandBlockSpare)
 
static NTSTATUS PciIdeAssignNativeResources (_In_ PATA_CONTROLLER Controller, _In_ PCHANNEL_DATA_PATA ChanData)
 
static NTSTATUS PciIdeAssignLegacyResources (_In_ PCHANNEL_DATA_PATA ChanData, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
 
NTSTATUS PciIdeParseResources (_In_ PCHANNEL_DATA_PATA ChanData, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
 
VOID PciIdeFreeResources (_In_ PVOID ChannelContext)
 
IDE_CHANNEL_STATE PciIdeGetChannelState (_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel)
 
static VOID PataEnableInterrupts (_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
 
NTSTATUS PciIdeConnectInterrupt (_In_ PVOID ChannelContext)
 
NTSTATUS PciIdeAttachChannel (_In_ PVOID ChannelContext, _In_ BOOLEAN Attach)
 
NTSTATUS PciIdeCreateChannelData (_In_ PATA_CONTROLLER Controller, _In_ ULONG HwExtensionSize)
 
NTSTATUS PciIdeGetControllerProperties (_Inout_ PATA_CONTROLLER Controller)
 

Variables

static const ULONG AtapModeToCycleTime []
 
static const ATA_TIMING AtapTimingTable []
 

Function Documentation

◆ AtaAcpiFindModeForCycleTime()

static VOID AtaAcpiFindModeForCycleTime ( _In_ ULONG  GtmCycleTime,
_In_ ULONG  SupportedModesBitmap,
_In_ ULONG  CurrentModesBitmap,
_In_ ULONG  MinimumMode,
_In_ ULONG  MaximumMode,
_Out_ PULONG  BestCycleTime,
_Out_ PULONG  BestMode 
)
static

Definition at line 202 of file pata_generic.c.

210{
211 LONG i;
212
213 if (GtmCycleTime == IDE_ACPI_TIMING_MODE_NOT_SUPPORTED)
214 {
215 *BestCycleTime = IDE_ACPI_TIMING_MODE_NOT_SUPPORTED;
216 *BestMode = PIO_MODE(0);
217 return;
218 }
219
220 for (i = MaximumMode; i >= MinimumMode; i--)
221 {
222 if ((SupportedModesBitmap & (1 << i)) && (AtapModeToCycleTime[i] >= GtmCycleTime))
223 {
224 *BestCycleTime = AtapModeToCycleTime[i];
225 *BestMode = i;
226 return;
227 }
228 }
229
230 /*
231 * This method can fail due to the first _GTM result
232 * may return compatible timings for a device,
233 * although the DMA mode is currently enabled by BIOS.
234 * For instance, this has been observed on a VPC 2007 ACPI firmware:
235 * Drive[0].PioSpeed 900 ns
236 * Drive[0].DmaSpeed 900 ns
237 * So we try to determine the transfer mode by other means below.
238 */
239 INFO("Failed to find mode for %ld ns cycle time from %lu in 0x%08lX\n",
240 (LONG)GtmCycleTime,
242 SupportedModesBitmap);
243
244 /* Search for the best enabled mode */
245 if (_BitScanReverse(BestMode, CurrentModesBitmap))
246 {
248 *BestCycleTime = AtapModeToCycleTime[*BestMode];
249 }
250 else
251 {
252 *BestCycleTime = IDE_ACPI_TIMING_MODE_NOT_SUPPORTED;
253 *BestMode = PIO_MODE(0);
254 }
255}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define IDE_ACPI_TIMING_MODE_NOT_SUPPORTED
Definition: ata_shared.h:42
#define PIO_MODE(n)
Definition: ata_user.h:36
#define INFO
Definition: debug.h:89
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
#define ASSERT(a)
Definition: mode.c:44
static const ULONG AtapModeToCycleTime[]
Definition: pata_generic.c:14
long LONG
Definition: pedump.c:60
unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:180
@ MaximumMode
Definition: ketypes.h:13

Referenced by PciIdeAcpiSetTransferMode().

◆ AtaCalculateTimings()

static VOID AtaCalculateTimings ( _In_ PCHANNEL_DEVICE_CONFIG  Device,
_Out_ PATA_TIMING  Timing,
_In_ ULONG  Mode,
_In_ ULONG  ClockPeriodPs 
)
static

Definition at line 62 of file pata_generic.c.

67{
68 ATATIM DataCycleTime, CmdCycleTime;
69
71
72 Timing->AddressSetup = AtaGetClocks(AtapTimingTable[Mode].AddressSetup, ClockPeriodPs);
73 Timing->CmdActive = AtaGetClocks(AtapTimingTable[Mode].CmdActive, ClockPeriodPs);
74 Timing->CmdRecovery = AtaGetClocks(AtapTimingTable[Mode].CmdRecovery, ClockPeriodPs);
75 Timing->DataActive = AtaGetClocks(AtapTimingTable[Mode].DataActive, ClockPeriodPs);
76 Timing->DataRecovery = AtaGetClocks(AtapTimingTable[Mode].DataRecovery, ClockPeriodPs);
77
78 if (Mode >= MWDMA_MODE(0))
79 DataCycleTime = Device->MinMwDmaCycleTime;
80 else if (Mode >= SWDMA_MODE(0))
81 DataCycleTime = Device->MinSwDmaCycleTime;
82 else
83 {
84 DataCycleTime = Device->MinPioCycleTime;
85
86 /* The t0 for register transfer is the same except for mode 2 */
87 if (Mode == PIO_MODE(2))
88 CmdCycleTime = max(DataCycleTime, 330);
89 else
90 CmdCycleTime = max(DataCycleTime, AtapModeToCycleTime[Mode]);
91 }
92 DataCycleTime = max(DataCycleTime, AtapModeToCycleTime[Mode]);
93
94 /*
95 * The minimum total cycle time requirement t0
96 * should be equal to or greater than the sum of t2 and t2i.
97 */
98 DataCycleTime = AtaGetClocks(DataCycleTime, ClockPeriodPs);
99 if ((Timing->DataActive + Timing->DataRecovery) < DataCycleTime)
100 {
101 Timing->DataActive += (DataCycleTime - (Timing->DataActive + Timing->DataRecovery)) / 2;
102 Timing->DataRecovery = DataCycleTime - Timing->DataActive;
103 }
104 if (Mode < SWDMA_MODE(0)) // PIO modes
105 {
106 CmdCycleTime = AtaGetClocks(CmdCycleTime, ClockPeriodPs);
107 if ((Timing->CmdActive + Timing->CmdRecovery) < CmdCycleTime)
108 {
109 Timing->CmdActive += (CmdCycleTime - (Timing->CmdActive + Timing->CmdRecovery)) / 2;
110 Timing->CmdRecovery = CmdCycleTime - Timing->CmdActive;
111 }
112 }
113}
#define MWDMA_MODE(n)
Definition: ata_user.h:38
#define SWDMA_MODE(n)
Definition: ata_user.h:37
_In_ ULONG Mode
Definition: hubbusif.h:303
USHORT ATATIM
Definition: pata.h:217
static ATATIM AtaGetClocks(_In_ ATATIM TimingValueNs, _In_ ULONG ClockPeriodPs)
Definition: pata_generic.c:53
static const ATA_TIMING AtapTimingTable[]
Definition: pata_generic.c:29
#define max(a, b)
Definition: svc.c:63
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474

Referenced by AtaSelectTimings().

◆ AtaGetClocks()

static ATATIM AtaGetClocks ( _In_ ATATIM  TimingValueNs,
_In_ ULONG  ClockPeriodPs 
)
static

Definition at line 53 of file pata_generic.c.

56{
57 return ((TimingValueNs * 1000) + ClockPeriodPs - 1) / ClockPeriodPs;
58}

Referenced by AtaCalculateTimings().

◆ AtaSelectTimings()

VOID AtaSelectTimings ( _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG DeviceList,
_Out_writes_all_(MAX_IDE_DEVICE) PATA_TIMING  Timings,
_In_range_(>, 0) ULONG  ClockPeriodPs,
_In_ ULONG  Flags 
)

Definition at line 116 of file pata_generic.c.

121{
122 ULONG i;
123
124 for (i = 0; i < MAX_IDE_DEVICE; ++i)
125 {
127 PATA_TIMING Timing = &Timings[i];
128 ATA_TIMING DmaTiming;
129
130 if (!Device)
131 {
132 RtlZeroMemory(Timing, sizeof(*Timing));
133 continue;
134 }
135
136 /* PIO mode */
137 AtaCalculateTimings(Device, Timing, Device->PioMode, ClockPeriodPs);
138
139 /* UDMA works independently of any PIO mode */
140 if (Device->DmaMode == PIO_MODE(0) || Device->DmaMode >= UDMA_MODE(0))
141 continue;
142
143 /* DMA mode */
144 AtaCalculateTimings(Device, &DmaTiming, Device->DmaMode, ClockPeriodPs);
145
146 /*
147 * Typically, the ATA port driver uses PIO commands along with DMA ones.
148 * Given that we program the chipset only once after device enumeration,
149 * we want to make sure the PIO commands would always work.
150 */
151 Timing->AddressSetup = max(Timing->AddressSetup, DmaTiming.AddressSetup);
152 Timing->CmdActive = max(Timing->CmdActive, DmaTiming.CmdActive);
153 Timing->CmdRecovery = max(Timing->CmdRecovery, DmaTiming.CmdRecovery);
154 Timing->DataActive = max(Timing->DataActive, DmaTiming.DataActive);
155 Timing->DataRecovery = max(Timing->DataRecovery, DmaTiming.DataRecovery);
156 }
157
158 /* Merge timings shared between both drives */
160 {
161 Timings[0].AddressSetup = max(Timings[0].AddressSetup, Timings[1].AddressSetup);
162
163 Timings[1].AddressSetup = Timings[0].AddressSetup;
164 }
166 {
167 Timings[0].CmdActive = max(Timings[0].CmdActive, Timings[1].CmdActive);
168 Timings[0].CmdRecovery = max(Timings[0].CmdRecovery, Timings[1].CmdRecovery);
169
170 Timings[1].CmdActive = Timings[0].CmdActive;
171 Timings[1].CmdRecovery = Timings[0].CmdRecovery;
172 }
174 {
175 Timings[0].DataActive = max(Timings[0].DataActive, Timings[1].DataActive);
176 Timings[0].DataRecovery = max(Timings[0].DataRecovery, Timings[1].DataRecovery);
177
178 Timings[1].DataActive = Timings[0].DataActive;
179 Timings[1].DataRecovery = Timings[0].DataRecovery;
180 }
181}
#define UDMA_MODE(n)
Definition: ata_user.h:39
PDEVICE_LIST DeviceList
Definition: utils.c:27
#define MAX_IDE_DEVICE
Definition: ide.h:32
#define SHARED_DATA_TIMINGS
Definition: pata.h:231
#define SHARED_CMD_TIMINGS
Definition: pata.h:230
#define SHARED_ADDR_TIMINGS
Definition: pata.h:232
static VOID AtaCalculateTimings(_In_ PCHANNEL_DEVICE_CONFIG Device, _Out_ PATA_TIMING Timing, _In_ ULONG Mode, _In_ ULONG ClockPeriodPs)
Definition: pata_generic.c:62
ATATIM CmdRecovery
Definition: pata.h:224
ATATIM CmdActive
Definition: pata.h:223
ATATIM DataRecovery
Definition: pata.h:227
ATATIM AddressSetup
Definition: pata.h:221
ATATIM DataActive
Definition: pata.h:226
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by AmdSetTransferMode(), CmdSetTransferMode(), Via6421SetTransferMode(), and ViaSetTransferMode().

◆ PataClaimLegacyAddressRanges()

static VOID PataClaimLegacyAddressRanges ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 452 of file pata_generic.c.

454{
456
457 PAGED_CODE();
458
459 if (IsNEC_98)
460 {
461 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
462 {
463 ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
465
466 ChanData->ChanInfo |= CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED |
468 }
469 }
470 else if (ChanData->Regs.Data == UlongToPtr(PCIIDE_LEGACY_PRIMARY_COMMAND_BASE))
471 {
472 ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
473 ChanData->ChanInfo |= CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED;
474 }
475 else if (ChanData->Regs.Data == UlongToPtr(PCIIDE_LEGACY_SECONDARY_COMMAND_BASE))
476 {
478 ChanData->ChanInfo |= CHANNEL_FLAG_SECONDARY_ADDRESS_CLAIMED;
479 }
480}
#define PAGED_CODE()
#define TRUE
Definition: types.h:120
#define UlongToPtr(u)
Definition: config.h:106
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
#define PCIIDE_LEGACY_SECONDARY_COMMAND_BASE
Definition: pata.h:77
#define PCIIDE_LEGACY_PRIMARY_COMMAND_BASE
Definition: pata.h:74
#define CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED
Definition: pciidex.h:267
#define CHANNEL_FLAG_SECONDARY_ADDRESS_CLAIMED
Definition: pciidex.h:268
#define CHANNEL_FLAG_CBUS
Definition: pciidex.h:283
BOOLEAN AtDiskPrimaryAddressClaimed
Definition: iotypes.h:4485
BOOLEAN AtDiskSecondaryAddressClaimed
Definition: iotypes.h:4486
#define IsNEC_98
Definition: ketypes.h:963

Referenced by PciIdeParseResources().

◆ PataEnableInterrupts()

static VOID PataEnableInterrupts ( _In_ PVOID  ChannelContext,
_In_ BOOLEAN  Enable 
)
static

Definition at line 965 of file pata_generic.c.

968{
969 PCHANNEL_DATA_PATA ChanData = ChannelContext;
971
972 INFO("CH %lu: %sable interrupts\n", ChanData->Channel, Enable ? "En" : "Dis");
973
975 if (Enable)
977 else
979
980#if defined(_M_IX86)
981 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
982 {
984 ATA_WRITE(ChanData->Regs.Control, Control, ChanData, MRES_CTRL);
985
986 /* Clear interrupts */
987 if (ChanData->CheckInterrupt)
988 ChanData->CheckInterrupt(ChanData);
989 ChanData->ReadStatus(ChanData);
990
992 ChanData->LastAtaBankId = 0xFF;
993 }
994#endif
995 ATA_WRITE(ChanData->Regs.Control, Control, ChanData, MRES_CTRL);
996
997 /* Clear interrupts */
998 if (ChanData->CheckInterrupt)
999 ChanData->CheckInterrupt(ChanData);
1000 ChanData->ReadStatus(ChanData);
1001
1002 if (ChanData->Regs.Dma != NULL)
1003 {
1004 UCHAR Status = ATA_READ(ChanData->Regs.Dma + PCIIDE_DMA_STATUS, ChanData, MRES_DMA);
1005
1006 ATA_WRITE(ChanData->Regs.Dma + PCIIDE_DMA_STATUS, Status, ChanData, MRES_DMA);
1007 }
1008}
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145
#define IDE_DC_REENABLE_CONTROLLER
Definition: atapi.h:147
#define NULL
Definition: types.h:112
Status
Definition: gdiplustypes.h:25
#define ATA_WRITE(Port, Value)
Definition: hwidep.h:80
#define IDE_DC_ALWAYS
Definition: hwidep.h:54
#define ATA_READ(Port)
Definition: hwidep.h:89
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define PCIIDE_DMA_STATUS
Definition: pata.h:107
#define PC98_ATA_BANK
Definition: pata.h:28
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
PCHANNEL_CHECK_INTERRUPT CheckInterrupt
Definition: pciidex.h:303
PCHANNEL_READ_STATUS ReadStatus
Definition: pciidex.h:299
IDE_REGISTERS Regs
Definition: pciidex.h:302
IDE_REG Control
Definition: hwidep.h:139
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PUCHAR
Definition: typedefs.h:53
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by PciIdeCreateChannelData().

◆ PataReleaseLegacyAddressRanges()

static VOID PataReleaseLegacyAddressRanges ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 433 of file pata_generic.c.

435{
437
438 PAGED_CODE();
439
440 if (ChanData->ChanInfo & CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED)
442 if (ChanData->ChanInfo & CHANNEL_FLAG_SECONDARY_ADDRESS_CLAIMED)
444
445 ChanData->ChanInfo &= ~(CHANNEL_FLAG_PRIMARY_ADDRESS_CLAIMED |
447}
#define FALSE
Definition: types.h:117

Referenced by PciIdeFreeResources().

◆ PciIdeAcpiSetTransferMode()

static VOID PciIdeAcpiSetTransferMode ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG DeviceList 
)
static

Definition at line 259 of file pata_generic.c.

262{
263 PIDE_ACPI_TIMING_MODE_BLOCK CurrentMode = &ChanData->CurrentTimingMode;
266 ULONG i;
267
268 ASSERT(ChanData->ChanInfo & CHANNEL_FLAG_HAS_ACPI_GTM);
269
270 NewMode.ModeFlags = CurrentMode->ModeFlags;
271
272 for (i = 0; i < MAX_IDE_DEVICE; ++i)
273 {
275 BOOLEAN HasUltraDMA;
276
277 if (!Device)
278 {
279 NewMode.Drive[i].PioSpeed = IDE_ACPI_TIMING_MODE_NOT_SUPPORTED;
280 NewMode.Drive[i].DmaSpeed = IDE_ACPI_TIMING_MODE_NOT_SUPPORTED;
281 continue;
282 }
283
284 /* PIO timing */
285 AtaAcpiFindModeForCycleTime(CurrentMode->Drive[i].PioSpeed,
286 Device->SupportedModes,
287 Device->CurrentModes & PIO_ALL,
288 PIO_MODE(0),
289 PIO_MODE(4),
290 &NewMode.Drive[i].PioSpeed,
291 &Device->PioMode);
292
293 /* DMA timing */
294 HasUltraDMA = !!(CurrentMode->ModeFlags & (IDE_ACPI_TIMING_MODE_FLAG_UDMA(i)));
295 AtaAcpiFindModeForCycleTime(CurrentMode->Drive[i].DmaSpeed,
296 Device->SupportedModes,
297 Device->CurrentModes & ~(PIO_ALL | SWDMA_ALL),
298 MWDMA_MODE(0),
299 HasUltraDMA ? UDMA_MODE(6) : MWDMA_MODE(2),
300 &NewMode.Drive[i].DmaSpeed,
301 &Device->DmaMode);
302
303 if (Device->DmaMode >= UDMA_MODE(0))
305 else
306 NewMode.ModeFlags &= ~IDE_ACPI_TIMING_MODE_FLAG_UDMA(i);
307 }
308
309 /*
310 * The underlying chipset might not allow the devices to be independently configured.
311 *
312 * For example, the Intel PIIX (0x8086:0x1230) cannot specify separate device timings.
313 * Please refer to PchSata.asi (PSIT bit)
314 * from the edk2-platforms repository for an example ASL implementation.
315 *
316 * It is possible to snoop an ATA command by software and run _STM each time
317 * the command being executed but an ACPI evaluation request can fail.
318 * For this reason, the timing setup only needs to be done once.
319 */
321 DeviceList[0] && DeviceList[1])
322 {
323 /* If we have a common timing mode for all devices use it, otherwise take the lower mode */
324 if (NewMode.Drive[0].DmaSpeed != IDE_ACPI_TIMING_MODE_NOT_SUPPORTED &&
325 NewMode.Drive[1].DmaSpeed != IDE_ACPI_TIMING_MODE_NOT_SUPPORTED)
326 {
327 NewMode.Drive[0].DmaSpeed = max(NewMode.Drive[0].DmaSpeed, NewMode.Drive[1].DmaSpeed);
328 DeviceList[0]->DmaMode = min(DeviceList[0]->DmaMode, DeviceList[1]->DmaMode);
329
330 NewMode.Drive[1].DmaSpeed = NewMode.Drive[0].DmaSpeed;
331 DeviceList[1]->DmaMode = DeviceList[0]->DmaMode;
332 }
333 NewMode.Drive[0].PioSpeed = max(NewMode.Drive[0].PioSpeed, NewMode.Drive[1].PioSpeed);
334 DeviceList[0]->PioMode = min(DeviceList[0]->PioMode, DeviceList[1]->PioMode);
335
336 NewMode.Drive[1].PioSpeed = NewMode.Drive[0].PioSpeed;
337 DeviceList[1]->PioMode = DeviceList[0]->PioMode;
338 }
339
340 INFO("CH %lu: Old timings %-2lX 0:%-3ld 0:%-3ld 1:%-3ld 1:%-3ld\n",
341 ChanData->Channel,
342 CurrentMode->ModeFlags,
343 (LONG)CurrentMode->Drive[0].PioSpeed,
344 (LONG)CurrentMode->Drive[0].DmaSpeed,
345 (LONG)CurrentMode->Drive[1].PioSpeed,
346 (LONG)CurrentMode->Drive[1].DmaSpeed);
347
348 INFO("CH %lu: New timings %-2lX 0:%-3ld 0:%-3ld 1:%-3ld 1:%-3ld\n",
349 ChanData->Channel,
350 NewMode.ModeFlags,
351 (LONG)NewMode.Drive[0].PioSpeed,
352 (LONG)NewMode.Drive[0].DmaSpeed,
353 (LONG)NewMode.Drive[1].PioSpeed,
354 (LONG)NewMode.Drive[1].DmaSpeed);
355
356 /* Evaluate _STM */
357 Status = AtaAcpiSetTimingMode(ChanData->PdoExt->Common.Self,
358 &NewMode,
359 DeviceList[0] ? DeviceList[0]->IdentifyDeviceData : NULL,
360 DeviceList[1] ? DeviceList[1]->IdentifyDeviceData : NULL);
361 if (!NT_SUCCESS(Status))
362 {
363 /* ACPI request failed, fall back to PIO */
364 for (i = 0; i < MAX_IDE_DEVICE; ++i)
365 {
367
368 if (!Device)
369 continue;
370
371 Device->DmaMode = PIO_MODE(0);
372 NT_VERIFY(_BitScanReverse(&Device->PioMode, Device->CurrentModes & PIO_ALL));
373 }
374 return;
375 }
376
377 /* Save the result */
378 AtaAcpiGetTimingMode(ChanData->PdoExt->Common.Self, CurrentMode);
379}
BOOLEAN AtaAcpiGetTimingMode(_In_ PDEVICE_OBJECT DeviceObject, _Out_ PIDE_ACPI_TIMING_MODE_BLOCK TimingMode)
Definition: acpi.c:98
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: acpi.c:147
unsigned char BOOLEAN
Definition: actypes.h:127
#define IDE_ACPI_TIMING_MODE_FLAG_UDMA(Drive)
Definition: ata_shared.h:47
#define IDE_ACPI_TIMING_MODE_FLAG_INDEPENDENT_TIMINGS
Definition: ata_shared.h:53
#define SWDMA_ALL
Definition: ata_user.h:23
#define PIO_ALL
Definition: ata_user.h:19
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define min(a, b)
Definition: monoChain.cc:55
static VOID AtaAcpiFindModeForCycleTime(_In_ ULONG GtmCycleTime, _In_ ULONG SupportedModesBitmap, _In_ ULONG CurrentModesBitmap, _In_ ULONG MinimumMode, _In_ ULONG MaximumMode, _Out_ PULONG BestCycleTime, _Out_ PULONG BestMode)
Definition: pata_generic.c:202
#define CHANNEL_FLAG_HAS_ACPI_GTM
Definition: pciidex.h:275
struct _IDE_ACPI_TIMING_MODE_BLOCK::@1699 Drive[2]
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304

Referenced by PciIdeGenericSetTransferMode().

◆ PciIdeAllocateMemory()

static NTSTATUS PciIdeAllocateMemory ( _In_ PVOID  ChannelContext)
static

Definition at line 511 of file pata_generic.c.

513{
514 PCHANNEL_DATA_PATA ChanData = ChannelContext;
515 PDMA_OPERATIONS DmaOperations = ChanData->DmaAdapter->DmaOperations;
516 PHYSICAL_ADDRESS LogicalAddress;
517 ULONG BlockSize;
518
519 PAGED_CODE();
520
521 BlockSize = sizeof(*ChanData->PrdTable) * ChanData->MaximumPhysicalPages;
522 ChanData->PrdTable = DmaOperations->AllocateCommonBuffer(ChanData->DmaAdapter,
523 BlockSize,
524 &LogicalAddress,
525 TRUE); // Cached
526 if (!ChanData->PrdTable)
528 RtlZeroMemory(ChanData->PrdTable, BlockSize);
529
530 ChanData->PrdTablePhysicalAddress = LogicalAddress.LowPart;
531
532 /* 32-bit DMA */
533 ASSERT(LogicalAddress.HighPart == 0);
534
535 /* The descriptor table must be 4 byte aligned */
536 ASSERT((LogicalAddress.LowPart % sizeof(ULONG)) == 0);
537
538 return STATUS_SUCCESS;
539}
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG PrdTablePhysicalAddress
Definition: pciidex.h:301
PPCIIDE_PRD_TABLE_ENTRY PrdTable
Definition: pciidex.h:300
PALLOCATE_COMMON_BUFFER AllocateCommonBuffer
Definition: iotypes.h:2637
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG LowPart
Definition: typedefs.h:106

Referenced by PciIdeCreateChannelData().

◆ PciIdeAssignLegacyResources()

static NTSTATUS PciIdeAssignLegacyResources ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_ PCM_RESOURCE_LIST  ResourcesTranslated 
)
static

Definition at line 723 of file pata_generic.c.

726{
727 PCM_PARTIAL_RESOURCE_DESCRIPTOR CommandPortDesc = NULL;
728 PCM_PARTIAL_RESOURCE_DESCRIPTOR ControlPortDesc = NULL;
730 ULONG i, Spare;
731
732 PAGED_CODE();
733
736
737 for (i = 0; i < ResourcesTranslated->List[0].PartialResourceList.Count; ++i)
738 {
740
741 Desc = &ResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
742 switch (Desc->Type)
743 {
746 {
747 if (IsNEC_98 && (ResourcesTranslated->List[0].PartialResourceList.Count >= 12))
748 {
749 if ((Desc->u.Port.Start.QuadPart == 0x640))
750 {
751 CommandPortDesc = Desc;
752 ChanData->ChanInfo |= CHANNEL_FLAG_CBUS;
753 }
754 else if ((Desc->u.Port.Start.QuadPart == 0x74C))
755 {
756 ControlPortDesc = Desc;
757 ChanData->ChanInfo |= CHANNEL_FLAG_CBUS;
758 }
759 }
760 else if (Desc->u.Port.Length == PCIIDE_LEGACY_CONTROL_IO_RANGE_LENGTH)
761 {
762 if (!ControlPortDesc)
763 ControlPortDesc = Desc;
764 }
765 else if (Desc->u.Port.Length == PCIIDE_LEGACY_COMMAND_IO_RANGE_LENGTH)
766 {
767 if (!CommandPortDesc)
768 CommandPortDesc = Desc;
769 }
770
771 break;
772 }
773
775 {
776 if (!InterruptDesc)
777 InterruptDesc = Desc;
778 break;
779 }
780
781 default:
782 break;
783 }
784 }
785
786 if (!CommandPortDesc || !ControlPortDesc || !InterruptDesc)
788
789 if (CommandPortDesc->Type == CmResourceTypeMemory)
790 ChanData->ChanInfo |= CHANNEL_FLAG_MRES_TF;
791
792 if (ControlPortDesc->Type == CmResourceTypeMemory)
793 ChanData->ChanInfo |= CHANNEL_FLAG_MRES_CTRL;
794
795 RtlCopyMemory(&ChanData->InterruptDesc, InterruptDesc, sizeof(*InterruptDesc));
796
797#if defined(_M_IX86)
798 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
799 {
800 Spare = 2;
801 }
802 else
803#endif
804 {
805 Spare = 1;
806 }
808 (ULONG_PTR)CommandPortDesc->u.Port.Start.QuadPart,
809 (ULONG_PTR)ControlPortDesc->u.Port.Start.QuadPart,
810 Spare);
811
812 return STATUS_SUCCESS;
813}
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:713
#define PCIIDE_LEGACY_COMMAND_IO_RANGE_LENGTH
Definition: pata.h:72
#define PCIIDE_LEGACY_CONTROL_IO_RANGE_LENGTH
Definition: pata.h:73
VOID PciIdeInitTaskFileIoResources(_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG_PTR CommandPortBase, _In_ ULONG_PTR ControlPortBase, _In_ ULONG CommandBlockSpare)
Definition: pata_generic.c:663
#define CHANNEL_FLAG_MRES_TF
Definition: pciidex.h:280
#define CHANNEL_FLAG_MRES_CTRL
Definition: pciidex.h:282
#define CmResourceTypeMemory
Definition: restypes.h:106
#define CmResourceTypePort
Definition: restypes.h:104
#define CmResourceTypeInterrupt
Definition: restypes.h:105
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@386 Port
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ WDFCMRESLIST _In_ WDFCMRESLIST ResourcesTranslated
Definition: wdfdevice.h:891

Referenced by PciIdeParseResources().

◆ PciIdeAssignNativeResources()

static NTSTATUS PciIdeAssignNativeResources ( _In_ PATA_CONTROLLER  Controller,
_In_ PCHANNEL_DATA_PATA  ChanData 
)
static

Definition at line 689 of file pata_generic.c.

692{
693 PVOID CommandPortBase, ControlPortBase;
694 const ULONG BarIndex = ChanData->Channel * 2;
695
696 PAGED_CODE();
697
698 CommandPortBase = AtaCtrlPciMapBar(Controller, BarIndex, PCIIDE_COMMAND_IO_RANGE_LENGTH);
699 if (!CommandPortBase)
701
702 ControlPortBase = AtaCtrlPciMapBar(Controller, BarIndex + 1, PCIIDE_CONTROL_IO_RANGE_LENGTH);
703 if (!ControlPortBase)
705
706 if (Controller->AccessRange[BarIndex].Flags & RANGE_IS_MAPPED)
707 ChanData->ChanInfo |= CHANNEL_FLAG_MRES_TF;
708
709 if (Controller->AccessRange[BarIndex + 1].Flags & RANGE_IS_MAPPED)
710 ChanData->ChanInfo |= CHANNEL_FLAG_MRES_CTRL;
711
713 (ULONG_PTR)CommandPortBase,
714 (ULONG_PTR)ControlPortBase + PCIIDE_CONTROL_IO_BAR_OFFSET,
715 1);
716
717 return STATUS_SUCCESS;
718}
#define PCIIDE_COMMAND_IO_RANGE_LENGTH
Definition: pata.h:82
#define PCIIDE_CONTROL_IO_RANGE_LENGTH
Definition: pata.h:83
#define PCIIDE_CONTROL_IO_BAR_OFFSET
Definition: pata.h:84
#define RANGE_IS_MAPPED
Definition: pciidex.h:192
PVOID AtaCtrlPciMapBar(_In_ PATA_CONTROLLER Controller, _In_range_(0, PCI_TYPE0_ADDRESSES) ULONG Index, _In_ ULONG MinimumIoLength)
Definition: fdo.c:249

Referenced by PciIdeParseResources().

◆ PciIdeAttachChannel()

NTSTATUS PciIdeAttachChannel ( _In_ PVOID  ChannelContext,
_In_ BOOLEAN  Attach 
)

Definition at line 1057 of file pata_generic.c.

1060{
1061 PCHANNEL_DATA_PATA ChanData = ChannelContext;
1062
1063 PAGED_CODE();
1064
1065 AtaChanEnableInterruptsSync(ChanData, Attach);
1066
1067 return STATUS_SUCCESS;
1068}
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaChanEnableInterruptsSync(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
Definition: fdo.c:62

◆ PciIdeBiosSetTransferMode()

static VOID PciIdeBiosSetTransferMode ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG DeviceList 
)
static

Definition at line 383 of file pata_generic.c.

386{
387 ULONG i;
388
389 /* Update manually using BIOS boot settings */
390 for (i = 0; i < MAX_IDE_DEVICE; ++i)
391 {
393 ULONG DmaFlags;
394
395 if (!Device)
396 continue;
397
398 /* Get the PIO and DMA modes set by BIOS */
399 if (!_BitScanReverse(&Device->DmaMode, Device->CurrentModes & ~PIO_ALL))
400 Device->DmaMode = PIO_MODE(0);
401 NT_VERIFY(_BitScanReverse(&Device->PioMode, Device->CurrentModes & PIO_ALL));
402
403 if (i == 0)
405 else
407
408 /* Disable DMA when when it is not supported */
409 if (!(ChanData->ChanInfo & DmaFlags))
410 Device->DmaMode = PIO_MODE(0);
411 }
412}
#define CHANNEL_FLAG_DRIVE0_DMA_CAPABLE
Definition: pciidex.h:261
#define CHANNEL_FLAG_DRIVE1_DMA_CAPABLE
Definition: pciidex.h:262

Referenced by PciIdeGenericSetTransferMode().

◆ PciIdeConnectInterrupt()

NTSTATUS PciIdeConnectInterrupt ( _In_ PVOID  ChannelContext)

Definition at line 1012 of file pata_generic.c.

1014{
1015 PCHANNEL_DATA_PATA ChanData = ChannelContext;
1016 PATA_CONTROLLER Controller = ChanData->Controller;
1017 PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDesc;
1018 PKSERVICE_ROUTINE IsrHandler;
1020
1021 PAGED_CODE();
1022
1023 if (Controller->Flags & CTRL_FLAG_NATIVE_PCI)
1024 InterruptDesc = &Controller->InterruptDesc;
1025 else
1026 InterruptDesc = &ChanData->InterruptDesc;
1027 ASSERT(InterruptDesc);
1028
1029 if (ChanData->Regs.Dma != NULL)
1030 IsrHandler = PciIdeChannelIsr;
1031 else
1032 IsrHandler = PataChannelIsr;
1033 Status = IoConnectInterrupt(&ChanData->InterruptObject,
1034 IsrHandler,
1035 ChanData,
1036 NULL,
1037 InterruptDesc->u.Interrupt.Vector,
1038 InterruptDesc->u.Interrupt.Level,
1039 InterruptDesc->u.Interrupt.Level,
1040 (InterruptDesc->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
1042 (InterruptDesc->ShareDisposition == CmResourceShareShared),
1043 InterruptDesc->u.Interrupt.Affinity,
1044 FALSE);
1045 if (!NT_SUCCESS(Status))
1046 {
1047 ERR("Could not connect to interrupt %lu, status 0x%lx\n",
1048 InterruptDesc->u.Interrupt.Vector, Status);
1049 return Status;
1050 }
1051
1052 return STATUS_SUCCESS;
1053}
#define ERR(fmt,...)
Definition: precomp.h:57
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:23
#define CTRL_FLAG_NATIVE_PCI
Definition: pciidex.h:223
KSERVICE_ROUTINE PciIdeChannelIsr
Definition: pciidex.h:703
KSERVICE_ROUTINE PataChannelIsr
Definition: pciidex.h:702
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: restypes.h:117
@ Latched
Definition: miniport.h:81
@ LevelSensitive
Definition: miniport.h:80
CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptDesc
Definition: pciidex.h:171
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@387 Interrupt
@ CmResourceShareShared
Definition: cmtypes.h:243
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:564

Referenced by PciIdeXPdoStartDevice().

◆ PciIdeControllerInitDma()

static BOOLEAN PciIdeControllerInitDma ( _In_ PATA_CONTROLLER  Controller)
static

Definition at line 565 of file pata_generic.c.

567{
568 ULONG i;
569
570 PAGED_CODE();
571
572 if (!(Controller->Pci.Command & PCI_ENABLE_BUS_MASTER))
573 {
574 INFO("PCI bus mastering disabled\n");
575 return FALSE;
576 }
577
578 if ((Controller->Pci.BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
579 !(Controller->Pci.ProgIf & PCIIDE_PROGIF_DMA_CAPABLE))
580 {
581 INFO("Non DMA capable controller detected\n");
582 return FALSE;
583 }
584
585 /* Assign DMA resources */
586 if (!(Controller->Flags & CTRL_FLAG_MANUAL_RES))
587 {
588 PUCHAR IoBase;
589
590 /* Check if BAR4 is available */
592 if (!IoBase)
593 {
594 if (Controller->AccessRange[PCIIDE_DMA_IO_BAR].Flags & RANGE_IS_VALID)
595 ERR("Failed to map bus master registers");
596 else
597 INFO("No bus master registers");
598 return FALSE;
599 }
600
601 for (i = 0; i < Controller->MaxChannels; ++i)
602 {
603 PCHANNEL_DATA_PATA ChanData = Controller->Channels[i];
604
605 if (Controller->AccessRange[PCIIDE_DMA_IO_BAR].Flags & RANGE_IS_MAPPED)
606 ChanData->ChanInfo |= CHANNEL_FLAG_MRES_DMA;
607
608 if (!IS_PRIMARY_CHANNEL(ChanData))
610
611 /*
612 * Save the DMA I/O address *in any case*. Some PATA controllers (Intel ICH)
613 * assert the DMA interrupt even if the current command is a PIO command,
614 * so we have to always clear the DMA interrupt.
615 */
616 ChanData->Regs.Dma = IoBase;
617
618 if (Controller->Flags & CTRL_FLAG_DMA_INTERRUPT)
620 }
621 }
622
623 for (i = 0; i < Controller->MaxChannels; ++i)
624 {
625 PCHANNEL_DATA_PATA ChanData = Controller->Channels[i];
626 UCHAR DmaStatus;
627
628 /* This channel does not support DMA */
629 if (!(ChanData->TransferModeSupported & ~PIO_ALL))
630 continue;
631
632 ASSERT(ChanData->Regs.Dma != NULL);
633
634 DmaStatus = ATA_READ(ChanData->Regs.Dma + PCIIDE_DMA_STATUS, ChanData, MRES_DMA);
635 if (!PciIdeIsDmaStatusValid(DmaStatus))
636 {
637 WARN("CH %lu: %p DMA 0x%02X\n", ChanData->Channel, ChanData->Regs.Dma, DmaStatus);
638 ChanData->TransferModeSupported &= PIO_ALL;
639 continue;
640 }
641
642 INFO("CH %lu: %p DMA 0x%02X\n", ChanData->Channel, ChanData->Regs.Dma, DmaStatus);
643
644 /* We look at the primary channel status register to determine the simplex mode */
645 if ((i == 0) && (Controller->MaxChannels > 1))
646 {
647 if (DmaStatus & PCIIDE_DMA_STATUS_SIMPLEX)
648 Controller->Flags |= CTRL_FLAG_IS_SIMPLEX;
649 }
650
651 /* The status bits 5:6 are set by the BIOS firmware at boot */
653 ChanData->ChanInfo |= CHANNEL_FLAG_DRIVE0_DMA_CAPABLE;
655 ChanData->ChanInfo |= CHANNEL_FLAG_DRIVE1_DMA_CAPABLE;
656 }
657
658 return TRUE;
659}
#define WARN(fmt,...)
Definition: precomp.h:61
#define PCIIDE_DMA_STATUS_DRIVE1_DMA_CAPABLE
Definition: pata.h:131
#define PCIIDE_PROGIF_DMA_CAPABLE
Definition: pata.h:99
#define PCIIDE_DMA_SECONDARY_CHANNEL_OFFSET
Definition: pata.h:89
#define PCIIDE_DMA_IO_BAR
Definition: pata.h:85
#define PCIIDE_DMA_STATUS_SIMPLEX
Definition: pata.h:132
#define PCIIDE_DMA_IO_RANGE_LENGTH
Definition: pata.h:86
#define PCIIDE_DMA_STATUS_DRIVE0_DMA_CAPABLE
Definition: pata.h:130
static BOOLEAN PciIdeIsDmaStatusValid(_In_ UCHAR DmaStatus)
Definition: pata_generic.c:544
#define CHANNEL_FLAG_MRES_DMA
Definition: pciidex.h:281
#define IS_PRIMARY_CHANNEL(PdoExtension)
Definition: pciidex.h:43
#define CTRL_FLAG_MANUAL_RES
Definition: pciidex.h:229
#define CTRL_FLAG_DMA_INTERRUPT
Definition: pciidex.h:230
CHANNEL_CHECK_INTERRUPT PciIdeCheckInterrupt
Definition: pciidex.h:704
#define RANGE_IS_VALID
Definition: pciidex.h:190
#define CTRL_FLAG_IS_SIMPLEX
Definition: pciidex.h:224
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3620
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:4106

Referenced by PciIdeGetControllerProperties().

◆ PciIdeCreateChannelData()

NTSTATUS PciIdeCreateChannelData ( _In_ PATA_CONTROLLER  Controller,
_In_ ULONG  HwExtensionSize 
)

Definition at line 1072 of file pata_generic.c.

1075{
1076 PCHANNEL_DATA_PATA ChanData;
1077 ULONG i, Size;
1078
1079 PAGED_CODE();
1080 ASSERT(Controller->MaxChannels != 0);
1081
1082 Size = FIELD_OFFSET(CHANNEL_DATA_PATA, HwExt) + HwExtensionSize;
1083 ChanData = ExAllocatePoolZero(NonPagedPool, Size * Controller->MaxChannels, TAG_PCIIDEX);
1084 if (!ChanData)
1086
1087 Controller->ChanDataBlock = ChanData;
1088 Controller->ChannelBitmap = NUM_TO_BITMAP(Controller->MaxChannels);
1089
1090 for (i = 0; i < Controller->MaxChannels; ++i)
1091 {
1092 Controller->Channels[i] = ChanData;
1093
1094 ChanData->Channel = i;
1095 ChanData->Controller = Controller;
1096
1097 /* Set default values */
1098 ChanData->ChanInfo = CHANNEL_FLAG_IO32;
1099 ChanData->AllocateMemory = PciIdeAllocateMemory;
1100 ChanData->FreeMemory = PciIdeFreeMemory;
1101 ChanData->EnableInterrupts = PataEnableInterrupts;
1102 ChanData->PreparePrdTable = PciIdePreparePrdTable;
1103 ChanData->PrepareIo = PataPrepareIo;
1104 ChanData->StartIo = PataStartIo;
1105 ChanData->LoadTaskFile = PataLoadTaskFile;
1106 ChanData->SaveTaskFile = PataSaveTaskFile;
1107 ChanData->ReadStatus = PataReadStatus;
1108 ChanData->SetTransferMode = PciIdeGenericSetTransferMode;
1109 ChanData->TransferModeSupported = PIO_ALL | SWDMA_ALL | MWDMA_ALL | UDMA_ALL;
1110
1112
1113 ChanData = (PVOID)((ULONG_PTR)ChanData + Size);
1114 }
1115
1116 return STATUS_SUCCESS;
1117}
#define UDMA_ALL
Definition: ata_user.h:31
#define MWDMA_ALL
Definition: ata_user.h:27
#define NUM_TO_BITMAP(num)
Definition: atapi.h:179
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define NonPagedPool
Definition: env_spec_w32.h:307
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
static VOID PciIdeGenericSetTransferMode(_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
Definition: pata_generic.c:416
static NTSTATUS PciIdeAllocateMemory(_In_ PVOID ChannelContext)
Definition: pata_generic.c:511
static VOID PciIdeFreeMemory(_In_ PVOID ChannelContext)
Definition: pata_generic.c:485
static VOID PataEnableInterrupts(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
Definition: pata_generic.c:965
CHANNEL_PREPARE_IO PataPrepareIo
Definition: pciidex.h:700
CHANNEL_LOAD_TASK_FILE PataLoadTaskFile
Definition: pciidex.h:705
KDEFERRED_ROUTINE PataPollingTimerDpc
Definition: pciidex.h:708
CHANNEL_START_IO PataStartIo
Definition: pciidex.h:701
#define CHANNEL_FLAG_IO32
Definition: pciidex.h:260
CHANNEL_SAVE_TASK_FILE PataSaveTaskFile
Definition: pciidex.h:706
CHANNEL_READ_STATUS PataReadStatus
Definition: pciidex.h:707
CHANNEL_PREPARE_PRD_TABLE PciIdePreparePrdTable
Definition: pciidex.h:699
#define TAG_PCIIDEX
Definition: pciidex.h:32
KDPC PollingTimerDpc
Definition: pciidex.h:312
PCHANNEL_SAVE_TASK_FILE SaveTaskFile
Definition: pciidex.h:298
PCHANNEL_LOAD_TASK_FILE LoadTaskFile
Definition: pciidex.h:297
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by AmdGetControllerProperties(), AtiGetControllerProperties(), CmdGetControllerProperties(), IntelGetControllerProperties(), PataGetControllerProperties(), PciIdeGetControllerProperties(), PcTechGetControllerProperties(), Sil680GetControllerProperties(), SvwPataGetControllerProperties(), SvwSataGetControllerProperties(), ToshibaGetControllerProperties(), Via6421GetControllerProperties(), ViaCx700GetControllerProperties(), and ViaGetControllerProperties().

◆ PciIdeFreeMemory()

static VOID PciIdeFreeMemory ( _In_ PVOID  ChannelContext)
static

Definition at line 485 of file pata_generic.c.

487{
488 PCHANNEL_DATA_PATA ChanData = ChannelContext;
489 PDMA_ADAPTER DmaAdapter = ChanData->DmaAdapter;
490 PDMA_OPERATIONS DmaOperations = ChanData->DmaAdapter->DmaOperations;
491 PHYSICAL_ADDRESS PrdTablePhysicalAddress;
492
493 PAGED_CODE();
494
495 if (!ChanData->PrdTable)
496 return;
497
498 PrdTablePhysicalAddress.QuadPart = ChanData->PrdTablePhysicalAddress;
499
500 DmaOperations->FreeCommonBuffer(DmaAdapter,
501 sizeof(*ChanData->PrdTable) * ChanData->MaximumPhysicalPages,
502 PrdTablePhysicalAddress,
503 ChanData->PrdTable,
504 TRUE); // Cached
505 ChanData->PrdTable = NULL;
506}
PFREE_COMMON_BUFFER FreeCommonBuffer
Definition: iotypes.h:2638
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by PciIdeCreateChannelData().

◆ PciIdeFreeResources()

VOID PciIdeFreeResources ( _In_ PVOID  ChannelContext)

Definition at line 877 of file pata_generic.c.

879{
880 PCHANNEL_DATA_PATA ChanData = ChannelContext;
881
882 PAGED_CODE();
883
884 if (ChanData->InterruptObject)
885 {
887
888 IoDisconnectInterrupt(ChanData->InterruptObject);
889 ChanData->InterruptObject = NULL;
890 }
891
892 ChanData->Regs.Dma = NULL;
893
894 ChanData->ChanInfo &= ~(CHANNEL_FLAG_DRIVE0_DMA_CAPABLE |
896
898}
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:142
static VOID PataReleaseLegacyAddressRanges(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_generic.c:433

Referenced by PciIdeXPdoStopDevice().

◆ PciIdeGenericSetTransferMode()

static VOID PciIdeGenericSetTransferMode ( _In_ PATA_CONTROLLER  Controller,
_In_ ULONG  Channel,
_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG DeviceList 
)
static

Definition at line 416 of file pata_generic.c.

420{
421 PCHANNEL_DATA_PATA ChanData = Controller->Channels[Channel];
422
423 /* Set the PATA transfer timings through ACPI if possible */
424 if (ChanData->ChanInfo & CHANNEL_FLAG_HAS_ACPI_GTM)
426 else
428}
static VOID PciIdeAcpiSetTransferMode(_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
Definition: pata_generic.c:259
static VOID PciIdeBiosSetTransferMode(_In_ PCHANNEL_DATA_PATA ChanData, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
Definition: pata_generic.c:383
_In_ ULONG Channel
Definition: pciidex.h:74

Referenced by PciIdeCreateChannelData().

◆ PciIdeGetChannelState()

IDE_CHANNEL_STATE PciIdeGetChannelState ( _In_ PATA_CONTROLLER  Controller,
_In_ ULONG  Channel 
)

Definition at line 902 of file pata_generic.c.

905{
906 PAGED_CODE();
907
908 /* SFF-8038i compliant hardware */
909 if (Controller->Flags & CTRL_FLAG_NATIVE_PCI)
910 {
911 /*
912 * If any native PCI IDE channel is enabled,
913 * its PCI I/O resources should be allocated as well:
914 *
915 * [BAR 0] I/O ports at FFC0 [size=8] Channel 0 task file registers
916 * [BAR 1] I/O ports at FF8C [size=4] Channel 0 device control
917 * [BAR 2] I/O ports at FF80 [size=8] Channel 1 task file registers
918 * [BAR 3] I/O ports at FF88 [size=4] Channel 1 device control
919 * [BAR 4] I/O ports at FFA0 [size=16] Bus Mastering registers
920 * [BAR 5] Memory at FE780000 Aux registers
921 */
922 if (!(Controller->Flags & CTRL_FLAG_MANUAL_RES))
923 {
924 const ULONG BarIndex = Channel * 2;
925
926 ASSERT(Channel < 2);
927
928 /* Check task file registers */
929 if (!(Controller->AccessRange[BarIndex].Flags & RANGE_IS_VALID))
930 return ChannelDisabled;
931
932 /* Check device control */
933 if (!(Controller->AccessRange[BarIndex + 1].Flags & RANGE_IS_VALID))
934 return ChannelDisabled;
935 }
936 }
937
938 if (Controller->ChannelEnableBits)
939 {
940 if (Controller->Flags & CTRL_FLAG_USE_TEST_FUNCTION)
941 {
942 /* Device-specific test */
943 return Controller->ChannelEnabledTest(Controller, Channel);
944 }
945 else
946 {
947 const ATA_PCI_ENABLE_BITS* EnableBits = &Controller->ChannelEnableBits[Channel];
948 UCHAR RegisterValue;
949
950 /* Test PCI bits */
951 RegisterValue = PciRead8(Controller, EnableBits->Register);
952 if ((RegisterValue & EnableBits->Mask) == EnableBits->ValueEnabled)
953 return ChannelEnabled;
954 else
955 return ChannelDisabled;
956 }
957 }
958
959 /* This channel is always enabled */
960 return ChannelStateUnknown;
961}
@ ChannelDisabled
Definition: ide.h:197
@ ChannelStateUnknown
Definition: ide.h:199
@ ChannelEnabled
Definition: ide.h:198
FORCEINLINE UCHAR PciRead8(_In_ PATA_CONTROLLER Controller, _In_ ULONG ConfigDataOffset)
Definition: pciidex.h:847
#define CTRL_FLAG_USE_TEST_FUNCTION
Definition: pciidex.h:226

Referenced by PciIdeXGetChannelState().

◆ PciIdeGetControllerProperties()

NTSTATUS PciIdeGetControllerProperties ( _Inout_ PATA_CONTROLLER  Controller)

Definition at line 1121 of file pata_generic.c.

1123{
1125 ULONG i;
1126
1127 PAGED_CODE();
1128
1129 Controller->MaxChannels = MAX_IDE_CHANNEL;
1130
1131 /* Match the controller through the PCI ID */
1132 switch (Controller->Pci.VendorID)
1133 {
1134 case PCI_VEN_ATI:
1135 Status = AtiGetControllerProperties(Controller);
1136 break;
1137 case PCI_VEN_AMD:
1138 case PCI_VEN_NVIDIA:
1139 Status = AmdGetControllerProperties(Controller);
1140 break;
1141 case PCI_VEN_CMD:
1142 Status = CmdGetControllerProperties(Controller);
1143 if (Status == STATUS_NO_MATCH)
1145 break;
1146 case PCI_VEN_INTEL:
1148 break;
1149 case PCI_VEN_PC_TECH:
1151 break;
1154 if (Status == STATUS_NO_MATCH)
1156 break;
1157 case PCI_VEN_TOSHIBA:
1159 break;
1160 case PCI_VEN_VIA:
1161 Status = ViaGetControllerProperties(Controller);
1162 break;
1163
1164 default:
1166 break;
1167 }
1168
1169 /* Try to use the generic PCI IDE minidriver */
1170 if (Status == STATUS_NO_MATCH)
1171 {
1172 if ((Controller->Pci.BaseClass != PCI_CLASS_MASS_STORAGE_CTLR) ||
1173 ((Controller->Pci.SubClass != PCI_SUBCLASS_MSC_IDE_CTLR) &&
1174 (Controller->Pci.SubClass != PCI_SUBCLASS_MSC_RAID_CTLR)))
1175 {
1176 ERR("Unsupported controller\n");
1177 return Status;
1178 }
1179
1180 WARN("%04X:%04X.%02X: Using generic PCI IDE minidriver\n",
1181 Controller->Pci.VendorID,
1182 Controller->Pci.DeviceID,
1183 Controller->Pci.RevisionID);
1184
1185 Status = PciIdeCreateChannelData(Controller, 0);
1186 if (!NT_SUCCESS(Status))
1187 return Status;
1188
1189 /* Disable 32-bit I/O for unknown controllers */
1190 for (i = 0; i < Controller->MaxChannels; ++i)
1191 {
1192 PCHANNEL_DATA_PATA ChanData = Controller->Channels[i];
1193
1194 ChanData->ChanInfo &= ~CHANNEL_FLAG_IO32;
1195 }
1196 }
1197
1198 if (!NT_SUCCESS(Status))
1199 return Status;
1200
1201 /*
1202 * Check for a legacy PCI IDE device.
1203 * NOTE: NT architecture does not support switching only one IDE channel to native mode.
1204 */
1205 if ((Controller->Pci.BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
1206 (Controller->Pci.SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
1207 {
1208 if (!(Controller->Pci.ProgIf & PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE) ||
1209 !(Controller->Pci.ProgIf & PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE))
1210 {
1211 Controller->Flags &= ~CTRL_FLAG_NATIVE_PCI;
1212 }
1213 }
1214
1215 if (Controller->Flags & CTRL_FLAG_NATIVE_PCI)
1216 {
1217 if (Controller->InterruptDesc.Type != CmResourceTypeInterrupt)
1218 {
1219 ERR("No interrupt resource\n");
1221 }
1222 }
1223
1224 if (!PciIdeControllerInitDma(Controller))
1225 {
1226 for (i = 0; i < Controller->MaxChannels; ++i)
1227 {
1228 PCHANNEL_DATA_PATA ChanData = Controller->Channels[i];
1229
1230 ChanData->TransferModeSupported &= PIO_ALL;
1231 }
1232 }
1233
1234 if (Controller->Flags & CTRL_FLAG_IS_SIMPLEX)
1235 {
1236 WARN("Sync access for hardware is required\n");
1237
1238 Controller->HwSyncObject = IoCreateController(0);
1239 if (!Controller->HwSyncObject)
1241 }
1242
1243 return STATUS_SUCCESS;
1244}
NTSTATUS AmdGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: amd.c:329
NTSTATUS AtiGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: ati.c:36
PCONTROLLER_OBJECT NTAPI IoCreateController(IN ULONG Size)
Definition: controller.c:57
NTSTATUS CmdGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: cmd.c:460
#define MAX_IDE_CHANNEL
Definition: ide.h:30
NTSTATUS IntelGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: intel.c:969
#define STATUS_NO_MATCH
Definition: ntstatus.h:873
#define PCI_VEN_CMD
Definition: pata.h:14
#define PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE
Definition: pata.h:97
#define PCI_VEN_INTEL
Definition: pata.h:19
#define PCI_VEN_ATI
Definition: pata.h:10
#define PCI_VEN_TOSHIBA
Definition: pata.h:17
#define PCI_VEN_NVIDIA
Definition: pata.h:12
#define PCI_VEN_AMD
Definition: pata.h:11
#define PCI_VEN_VIA
Definition: pata.h:15
#define PCI_VEN_PC_TECH
Definition: pata.h:13
#define PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE
Definition: pata.h:95
#define PCI_VEN_SERVERWORKS
Definition: pata.h:16
static BOOLEAN PciIdeControllerInitDma(_In_ PATA_CONTROLLER Controller)
Definition: pata_generic.c:565
NTSTATUS PciIdeCreateChannelData(_In_ PATA_CONTROLLER Controller, _In_ ULONG HwExtensionSize)
NTSTATUS PcTechGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: pctech.c:41
NTSTATUS Sil680GetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: sil680.c:214
NTSTATUS SvwPataGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: svw_pata.c:288
NTSTATUS SvwSataGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: svw_sata.c:215
NTSTATUS ToshibaGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: toshiba.c:102
NTSTATUS ViaGetControllerProperties(_Inout_ PATA_CONTROLLER Controller)
Definition: via.c:859
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:4131
#define PCI_SUBCLASS_MSC_RAID_CTLR
Definition: iotypes.h:4134

◆ PciIdeInitTaskFileIoResources()

VOID PciIdeInitTaskFileIoResources ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_ ULONG_PTR  CommandPortBase,
_In_ ULONG_PTR  ControlPortBase,
_In_ ULONG  CommandBlockSpare 
)

Definition at line 663 of file pata_generic.c.

668{
669 PIDE_REGISTERS Registers = &ChanData->Regs;
670
671 PAGED_CODE();
672
673 /* Standard PATA register layout */
674 Registers->Data = (PVOID)(CommandPortBase + 0 * CommandBlockSpare);
675 Registers->Error = (PVOID)(CommandPortBase + 1 * CommandBlockSpare);
676 Registers->SectorCount = (PVOID)(CommandPortBase + 2 * CommandBlockSpare);
677 Registers->LbaLow = (PVOID)(CommandPortBase + 3 * CommandBlockSpare);
678 Registers->LbaMid = (PVOID)(CommandPortBase + 4 * CommandBlockSpare);
679 Registers->LbaHigh = (PVOID)(CommandPortBase + 5 * CommandBlockSpare);
680 Registers->Device = (PVOID)(CommandPortBase + 6 * CommandBlockSpare);
681 Registers->Status = (PVOID)(CommandPortBase + 7 * CommandBlockSpare);
682
683 Registers->Control = (PVOID)ControlPortBase;
684}
IDE_REG Error
Definition: hwidep.h:111
IDE_REG LbaLow
LBA bits 0-7, 24-31.
Definition: hwidep.h:118
IDE_REG LbaMid
LBA bits 8-15, 32-39.
Definition: hwidep.h:121
IDE_REG Data
Definition: hwidep.h:107
IDE_REG Status
Definition: hwidep.h:135
IDE_REG LbaHigh
LBA bits 16-23, 40-47.
Definition: hwidep.h:127
IDE_REG Device
Definition: hwidep.h:131
IDE_REG SectorCount
Definition: hwidep.h:115

Referenced by PciIdeAssignLegacyResources(), PciIdeAssignNativeResources(), SvwSataParseResources(), and Via6421ParseResources().

◆ PciIdeIsDmaStatusValid()

static BOOLEAN PciIdeIsDmaStatusValid ( _In_ UCHAR  DmaStatus)
static

Definition at line 544 of file pata_generic.c.

546{
547 PAGED_CODE();
548
549 /* The status bits [3:4] must return 0 on reads */
551 {
552 /*
553 * Not a PCI IDE DMA device. This may happen when the channel is disabled
554 * (e.g. 8086:8C00 returns 0xFF for disabled SATA channels).
555 */
556 return FALSE;
557 }
558
559 return TRUE;
560}
#define PCIIDE_DMA_STATUS_RESERVED1
Definition: pata.h:128
#define PCIIDE_DMA_STATUS_RESERVED2
Definition: pata.h:129

Referenced by PciIdeControllerInitDma().

◆ PciIdeParseResources()

NTSTATUS PciIdeParseResources ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_ PCM_RESOURCE_LIST  ResourcesTranslated 
)

Definition at line 849 of file pata_generic.c.

852{
853 PATA_CONTROLLER Controller = ChanData->Controller;
855
856 PAGED_CODE();
857
858 ASSERT(ChanData->Channel < 2);
859
860 if (Controller->Flags & CTRL_FLAG_NATIVE_PCI)
861 Status = PciIdeAssignNativeResources(Controller, ChanData);
862 else
864 if (!NT_SUCCESS(Status))
865 {
866 ERR("CH %lu: Failed to assign I/O resources 0x%lx\n", ChanData->Channel, Status);
867 return Status;
868 }
869
871
872 return STATUS_SUCCESS;
873}
static VOID PataClaimLegacyAddressRanges(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_generic.c:452
static NTSTATUS PciIdeAssignNativeResources(_In_ PATA_CONTROLLER Controller, _In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_generic.c:689
static NTSTATUS PciIdeAssignLegacyResources(_In_ PCHANNEL_DATA_PATA ChanData, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
Definition: pata_generic.c:723

Referenced by PataGetControllerProperties(), and PciIdeXPdoStartDevice().

◆ SataSetTransferMode()

VOID SataSetTransferMode ( _In_ PATA_CONTROLLER  Controller,
_In_ ULONG  Channel,
_In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG DeviceList 
)

Definition at line 184 of file pata_generic.c.

188{
189 UNREFERENCED_PARAMETER(Controller);
192
193 /*
194 * Nothing to do here, just keep the selected Device->PioMode and Device->DmaMode
195 * because SATA hardware snoops the SET FEATURES command.
196 */
197 NOTHING;
198}
#define NOTHING
Definition: input_list.c:10
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329

Variable Documentation

◆ AtapModeToCycleTime

const ULONG AtapModeToCycleTime[]
static
Initial value:
=
{
600, 383, 240, 180, 120,
960, 480, 240,
480, 150, 120,
120, 80, 60, 45, 30, 20, 15
}

Definition at line 14 of file pata_generic.c.

Referenced by AtaAcpiFindModeForCycleTime(), and AtaCalculateTimings().

◆ AtapTimingTable

const ATA_TIMING AtapTimingTable[]
static
Initial value:
=
{
{ 70, 290, 240, 165, 150 },
{ 50, 290, 93, 125, 100 },
{ 30, 290, 40, 100, 90 },
{ 30, 80, 70, 80, 70 },
{ 25, 70, 25, 70, 25 },
{ 120, 0, 0, 480, 480 },
{ 90, 0, 0, 240, 240 },
{ 60, 0, 0, 120, 120 },
{ 60, 0, 0, 215, 215 },
{ 45, 0, 0, 80, 50 },
{ 25, 0, 0, 70, 25 },
}

Definition at line 29 of file pata_generic.c.

Referenced by AtaCalculateTimings().