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

Go to the source code of this file.

Functions

static BOOLEAN PataIsDevicePresent (_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG DeviceNumber)
 
static VOID PataIssueSoftwareReset (_In_ PCHANNEL_DATA_PATA ChanData)
 
static VOID PataDrainDeviceBuffer (_In_ PCHANNEL_DATA_PATA ChanData)
 
ULONG PataChannelGetMaximumDeviceCount (_In_ PVOID ChannelContext)
 
VOID PataResetChannel (_In_ PVOID ChannelContext)
 
ATA_CONNECTION_STATUS PataIdentifyDevice (_In_ PVOID ChannelContext, _In_ ULONG DeviceNumber)
 
ULONG PataEnumerateChannel (_In_ PVOID ChannelContext)
 

Function Documentation

◆ PataChannelGetMaximumDeviceCount()

ULONG PataChannelGetMaximumDeviceCount ( _In_ PVOID  ChannelContext)

Definition at line 87 of file pata_hw.c.

89{
90 PCHANNEL_DATA_PATA ChanData = ChannelContext;
91
92#if defined(_M_IX86)
93 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
94 return 4;
95#endif
96
97 return (ChanData->ChanInfo & CHANNEL_FLAG_NO_SLAVE) ? 1 : 2;
98}
#define CHANNEL_FLAG_NO_SLAVE
Definition: pciidex.h:270
#define CHANNEL_FLAG_CBUS
Definition: pciidex.h:283

Referenced by PataEnumerateChannel(), PataResetChannel(), and PciIdeXQueryPciIdeInterface().

◆ PataDrainDeviceBuffer()

static VOID PataDrainDeviceBuffer ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 61 of file pata_hw.c.

63{
64 ULONG i;
65 USHORT LocalBuffer;
66
67 /* Try to clear the DRQ indication */
68 for (i = 0; i < ATA_MAX_TRANSFER_LENGTH / sizeof(USHORT); ++i)
69 {
70 UCHAR IdeStatus = ChanData->ReadStatus(ChanData);
71
72 if (!(IdeStatus & IDE_STATUS_DRQ))
73 break;
74
75 ATA_READ_BLOCK_16((PUSHORT)ChanData->Regs.Data,
76 &LocalBuffer,
77 1,
78 ChanData,
79 MRES_TF);
80 }
81
82 if (i > 0)
83 INFO("CH %lu: Total drained %lu bytes\n", ChanData->Channel, i * sizeof(USHORT));
84}
#define ATA_MAX_TRANSFER_LENGTH
Definition: ata_shared.h:26
#define IDE_STATUS_DRQ
Definition: atapi.h:128
#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 ATA_READ_BLOCK_16(Port, Buffer, Count)
Definition: hwidep.h:92
unsigned short USHORT
Definition: pedump.c:61
unsigned char UCHAR
Definition: typedefs.h:53
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PataResetChannel().

◆ PataEnumerateChannel()

ULONG PataEnumerateChannel ( _In_ PVOID  ChannelContext)

Definition at line 246 of file pata_hw.c.

248{
249 PCHANNEL_DATA_PATA ChanData = ChannelContext;
250
251 /*
252 * By default, we do not issue the software reset to detect the device signature,
253 * since attached devices may reset their current transfer mode.
254 * We need to know what transfer mode is actually set by BIOS in order to
255 * select any transfer mode correctly by our generic PATA chipset driver
256 * (PciIdeAcpiSetTransferMode() or PciIdeBiosSetTransferMode()).
257 */
258 return PataChannelGetMaximumDeviceCount(ChanData);
259}
ULONG PataChannelGetMaximumDeviceCount(_In_ PVOID ChannelContext)
Definition: pata_hw.c:87

◆ PataIdentifyDevice()

ATA_CONNECTION_STATUS PataIdentifyDevice ( _In_ PVOID  ChannelContext,
_In_ ULONG  DeviceNumber 
)

Definition at line 214 of file pata_hw.c.

217{
218 PCHANNEL_DATA_PATA ChanData = ChannelContext;
219 UCHAR IdeStatus;
220
221 if (!PataIsDevicePresent(ChanData, DeviceNumber))
223
224 /* Wait for busy to clear */
225 IdeStatus = ATA_WAIT(ChanData, ATA_TIME_BUSY_SELECT, IDE_STATUS_BUSY, 0);
226 if (IdeStatus & (IDE_STATUS_BUSY | IDE_STATUS_DRQ))
227 {
228 /*
229 * This status indicates that the previous command hasn't been completed
230 * and the device is left in an unexpected state.
231 * A device reset is required to recover.
232 */
233 WARN("CH %lu: Device %lu is busy %02x\n", ChanData->Channel, DeviceNumber, IdeStatus);
234 return CONN_STATUS_FAILURE;
235 }
236
237 /*
238 * Also we do not check the device signature,
239 * because early ATAPI drives (NEC CDR-260, and some other devices)
240 * report an ATA signature.
241 */
243}
@ CONN_STATUS_FAILURE
Definition: ata_shared.h:83
@ CONN_STATUS_DEV_UNKNOWN
Definition: ata_shared.h:85
@ CONN_STATUS_NO_DEVICE
Definition: ata_shared.h:84
#define IDE_STATUS_BUSY
Definition: atapi.h:132
#define WARN(fmt,...)
Definition: precomp.h:61
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
#define ATA_TIME_BUSY_SELECT
20 ms
Definition: hwidep.h:69
FORCEINLINE UCHAR ATA_WAIT(_In_ PCHANNEL_DATA_PATA ChanData, _In_range_(>, 0) ULONG Timeout, _In_ UCHAR Mask, _In_ UCHAR Value)
Definition: pata.h:301
static BOOLEAN PataIsDevicePresent(_In_ PCHANNEL_DATA_PATA ChanData, _In_ ULONG DeviceNumber)
Definition: pata_hw.c:16

◆ PataIsDevicePresent()

static BOOLEAN PataIsDevicePresent ( _In_ PCHANNEL_DATA_PATA  ChanData,
_In_ ULONG  DeviceNumber 
)
static

Definition at line 16 of file pata_hw.c.

19{
20 UCHAR IdeStatus;
21
22 /* Select the device */
24
25 /* Do a quick check first */
26 IdeStatus = ChanData->ReadStatus(ChanData);
27 INFO("CH %lu: Device %lu status %02x\n", ChanData->Channel, DeviceNumber, IdeStatus);
28 if (IdeStatus == 0xFF || IdeStatus == 0x7F)
29 return FALSE;
30
31 /* Look at controller */
32 ATA_WRITE(ChanData->Regs.ByteCountLow, 0x55, ChanData, MRES_TF);
33 ATA_WRITE(ChanData->Regs.ByteCountLow, 0xAA, ChanData, MRES_TF);
34 ATA_WRITE(ChanData->Regs.ByteCountLow, 0x55, ChanData, MRES_TF);
35 if (ATA_READ(ChanData->Regs.ByteCountLow, ChanData, MRES_TF) != 0x55)
36 return FALSE;
37 ATA_WRITE(ChanData->Regs.ByteCountHigh, 0xAA, ChanData, MRES_TF);
38 ATA_WRITE(ChanData->Regs.ByteCountHigh, 0x55, ChanData, MRES_TF);
39 ATA_WRITE(ChanData->Regs.ByteCountHigh, 0xAA, ChanData, MRES_TF);
40 if (ATA_READ(ChanData->Regs.ByteCountHigh, ChanData, MRES_TF) != 0xAA)
41 return FALSE;
42
43 return TRUE;
44}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ATA_WRITE(Port, Value)
Definition: hwidep.h:80
#define ATA_READ(Port)
Definition: hwidep.h:89
#define IDE_DRIVE_SELECT
Definition: hwidep.h:56
FORCEINLINE VOID ATA_SELECT_DEVICE(_In_ PCHANNEL_DATA_PATA ChanData, _In_ UCHAR DeviceNumber, _In_ UCHAR DeviceSelect)
Definition: pata.h:271

Referenced by PataIdentifyDevice(), and PataResetChannel().

◆ PataIssueSoftwareReset()

static VOID PataIssueSoftwareReset ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 48 of file pata_hw.c.

50{
51 ATA_WRITE(ChanData->Regs.Control, IDE_DC_RESET_CONTROLLER | IDE_DC_ALWAYS,
52 ChanData, MRES_CTRL);
54 ATA_WRITE(ChanData->Regs.Control, IDE_DC_DISABLE_INTERRUPTS | IDE_DC_ALWAYS,
55 ChanData, MRES_CTRL);
57}
#define IDE_DC_RESET_CONTROLLER
Definition: atapi.h:146
#define IDE_DC_DISABLE_INTERRUPTS
Definition: atapi.h:145
#define IDE_DC_ALWAYS
Definition: hwidep.h:54
#define KeStallExecutionProcessor(MicroSeconds)
Definition: precomp.h:27

Referenced by PataResetChannel().

◆ PataResetChannel()

VOID PataResetChannel ( _In_ PVOID  ChannelContext)

Definition at line 101 of file pata_hw.c.

103{
104 PCHANNEL_DATA_PATA ChanData = ChannelContext;
105 ULONG i, DeviceNumber, DeviceCount, DeviceBitmap = 0;
106
107 ChanData->IsPollingActive = FALSE;
108
109#if defined(_M_IX86)
110 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
111 ChanData->LastAtaBankId = 0xFF;
112#endif
113
114 /*
115 * Reset the start/stop bus master bit, also needed on some chips to recover,
116 * see for example Intel 82371AB/EB/MB Specification Update 297738-017 #10.
117 */
118 if (ChanData->Regs.Dma != NULL)
119 PciIdeDmaStop(ChanData);
120
121 PataDrainDeviceBuffer(ChanData);
122
125 {
126 if (PataIsDevicePresent(ChanData, DeviceNumber))
127 DeviceBitmap |= 1 << DeviceNumber;
128 }
129 /* Restore the device selection */
131
132 WARN("CH %lu: Resetting IDE channel, devices map 0x%lx\n", ChanData->Channel, DeviceBitmap);
133
134#if defined(_M_IX86)
135 if (ChanData->ChanInfo & CHANNEL_FLAG_CBUS)
136 {
137 /* Reset the secondary IDE channel if present */
138 if (DeviceBitmap & ((1 << 2) | (1 << 3)))
139 {
141 PataIssueSoftwareReset(ChanData);
142 }
143
145 ChanData->LastAtaBankId = 0xFF;
146 }
147#endif
148 PataIssueSoftwareReset(ChanData);
149
151 {
152 UCHAR IdeStatus;
153
154 /* The reset will cause the master device to be selected */
155 if ((DeviceNumber % 2) != 0)
156 {
157 /* Always check BSY for the master device regardless of its presence */
158 if (!(DeviceBitmap & (1 << DeviceNumber)))
159 continue;
160
161 for (i = ATA_TIME_RESET_SELECT; i > 0; i--)
162 {
163 /* Select the device again */
164 ATA_SELECT_DEVICE(ChanData,
166 IDE_DRIVE_SELECT | ((DeviceNumber & 1) << 4));
167
168 /* Check whether the selection was successful */
169 ATA_WRITE(ChanData->Regs.ByteCountLow, 0xAA, ChanData, MRES_TF);
170 ATA_WRITE(ChanData->Regs.ByteCountLow, 0x55, ChanData, MRES_TF);
171 ATA_WRITE(ChanData->Regs.ByteCountLow, 0xAA, ChanData, MRES_TF);
172 if (ATA_READ(ChanData->Regs.ByteCountLow, ChanData, MRES_TF) == 0xAA)
173 break;
174
175 AtaSleep();
176 }
177 if (i == 0)
178 {
179 ERR("CH %lu: Device %lu selection timeout %02x\n",
180 ChanData->Channel, DeviceNumber, ChanData->ReadStatus(ChanData));
181 continue;
182 }
183 }
184
185 /* Now wait for busy to clear */
186 for (i = 0; i < ATA_TIME_BUSY_RESET; ++i)
187 {
188 IdeStatus = ChanData->ReadStatus(ChanData);
189 if (IdeStatus == 0xFF)
190 break;
191
192 if (!(IdeStatus & IDE_STATUS_BUSY))
193 break;
194
195 AtaSleep();
196 }
197
198 if (IdeStatus & IDE_STATUS_BUSY)
199 {
200 ERR("CH %lu: Failed to reset device %lu, status %02x\n",
201 ChanData->Channel, DeviceNumber, IdeStatus);
202 }
203 else
204 {
205 INFO("CH %lu: Device %lu online with status %02x\n",
206 ChanData->Channel, DeviceNumber, IdeStatus);
207 }
208 }
209
211}
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
#define ATA_TIME_BUSY_RESET
10 s
Definition: hwidep.h:72
#define ATA_TIME_RESET_SELECT
2 s
Definition: hwidep.h:73
ULONG DeviceCount
Definition: mpu401.c:26
#define PC98_ATA_BANK
Definition: pata.h:28
static VOID PataDrainDeviceBuffer(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_hw.c:61
static VOID PataIssueSoftwareReset(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_hw.c:48
VOID PciIdeDmaStop(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: pata_io.c:247
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
VOID AtaSleep(VOID)
Definition: pciidex.c:100
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaChanEnableInterruptsSync(_In_ PVOID ChannelContext, _In_ BOOLEAN Enable)
Definition: fdo.c:62
PCHANNEL_READ_STATUS ReadStatus
Definition: pciidex.h:299
BOOLEAN IsPollingActive
Definition: pciidex.h:311
IDE_REGISTERS Regs
Definition: pciidex.h:302
IDE_REG ByteCountLow
Definition: hwidep.h:122
unsigned char * PUCHAR
Definition: typedefs.h:53