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

Go to the source code of this file.

Classes

struct  _CMD_HW_EXTENSION
 

Macros

#define PCI_DEV_PCI0640   0x0640
 
#define PCI_DEV_PCI0643   0x0643
 
#define PCI_DEV_PCI0646   0x0646
 
#define PCI_DEV_PCI0648   0x0648
 
#define PCI_DEV_CMD0649   0x0649
 
#define HW_FLAGS_PRIMARY_ENABLED   0x0001
 
#define HW_FLAGS_HAS_UDMA_REG   0x0002
 
#define HW_FLAGS_NEED_PIO_FIX   0x0004
 
#define HW_FLAGS_NO_PREFETCH   0x0008
 
#define CMD_PCI_CLOCK   30000
 
#define CMD_REG_CFR   0x50
 
#define CMD_REG_CNTRL   0x51
 
#define CMD_REG_CMDTIM   0x52
 
#define CMD_REG_ARTTIM0   0x53
 
#define CMD_REG_DRWTIM0   0x54
 
#define CMD_REG_ARTTIM1   0x55
 
#define CMD_REG_DRWTIM1   0x56
 
#define CMD_REG_ARTTIM23   0x57
 
#define CMD_REG_DRWTIM2   0x58
 
#define CMD_REG_DRWTIM23   0x58
 
#define CMD_REG_DRWTIM3   0x5B
 
#define CMD_REG_MRDMODE   0x71
 
#define CMD_REG_BMIDECSR   0x79
 
#define CMD_REG_UDIDETCR(Channel)   (((Channel) == 0) ? 0x73 : 0x7B)
 
#define CMD_CFR_INTR(Channel)   (((Channel) == 0) ? 0x04 : 0x10)
 
#define CMD_CNTRL_CHAN_EN(Channel)   (0x04 << (Channel))
 
#define CMD_ARTTIM_ART_MASK   0xC0
 
#define CMD_MRDMODE_READ_MULTIPLE   0x01
 
#define CMD_MRDMODE_INTR(Channel)   (0x04 << (Channel))
 
#define CMD_MRDMODE_INTR_CH0_BLOCK   0x10
 
#define CMD_MRDMODE_INTR_CH1_BLOCK   0x20
 
#define CMD_BMIDECSR_CR(Channel)   (0x01 << (Channel))
 
#define CMD_UDIDETCR_CLEAR(Drive)   (((Drive) == 0) ? 0x35 : 0xCA)
 
#define CMD_UDIDETCR_EN(Drive)   (0x01 << (Drive))
 

Typedefs

typedef struct _CMD_HW_EXTENSION CMD_HW_EXTENSION
 
typedef struct _CMD_HW_EXTENSIONPCMD_HW_EXTENSION
 

Functions

static VOID CmdFixRecoveryTiming (_In_ PCHANNEL_DEVICE_CONFIG Device, _Inout_ PATA_TIMING Timing, _In_ ATATIM CycleTimeClocks, _In_ ATATIM CmdActiveClocks, _In_ ATATIM CmdRecoveryClocks, _In_ ATATIM DataActiveClocks, _In_ ATATIM DataRecoveryClocks)
 
static VOID CmdDerateTimings (_In_ PCHANNEL_DEVICE_CONFIG Device, _Inout_ PATA_TIMING Timing)
 
static UCHAR CmdPackTimings (_In_ PATA_CONTROLLER Controller, _In_ ATATIM Active, _In_ ATATIM Recovery)
 
static VOID CmdSetTransferMode (_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
 
static IDE_CHANNEL_STATE CmdChannelEnabledTest (_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel)
 
static BOOLEAN CmdCheckInterruptMrdMode (_In_ PCHANNEL_DATA_PATA ChanData)
 
static BOOLEAN CmdCheckInterruptPci (_In_ PCHANNEL_DATA_PATA ChanData)
 
static VOID CmdControllerStart (_In_ PATA_CONTROLLER Controller)
 
NTSTATUS CmdGetControllerProperties (_Inout_ PATA_CONTROLLER Controller)
 

Variables

static const UCHAR CmdPrefetchDisable [MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
 
static const ULONG CmdPrefetchRegs [MAX_IDE_CHANNEL]
 
static const ULONG CmdDrwTimRegs [MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
 
static const ULONG CmdArtTimRegs [MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
 
static const UCHAR CmdArtTimings []
 
static const UCHAR CmdUdmaTimings [6][MAX_IDE_DEVICE]
 

Macro Definition Documentation

◆ CMD_ARTTIM_ART_MASK

#define CMD_ARTTIM_ART_MASK   0xC0

Definition at line 50 of file cmd.c.

◆ CMD_BMIDECSR_CR

#define CMD_BMIDECSR_CR (   Channel)    (0x01 << (Channel))

Definition at line 57 of file cmd.c.

◆ CMD_CFR_INTR

#define CMD_CFR_INTR (   Channel)    (((Channel) == 0) ? 0x04 : 0x10)

Definition at line 46 of file cmd.c.

◆ CMD_CNTRL_CHAN_EN

#define CMD_CNTRL_CHAN_EN (   Channel)    (0x04 << (Channel))

Definition at line 48 of file cmd.c.

◆ CMD_MRDMODE_INTR

#define CMD_MRDMODE_INTR (   Channel)    (0x04 << (Channel))

Definition at line 53 of file cmd.c.

◆ CMD_MRDMODE_INTR_CH0_BLOCK

#define CMD_MRDMODE_INTR_CH0_BLOCK   0x10

Definition at line 54 of file cmd.c.

◆ CMD_MRDMODE_INTR_CH1_BLOCK

#define CMD_MRDMODE_INTR_CH1_BLOCK   0x20

Definition at line 55 of file cmd.c.

◆ CMD_MRDMODE_READ_MULTIPLE

#define CMD_MRDMODE_READ_MULTIPLE   0x01

Definition at line 52 of file cmd.c.

◆ CMD_PCI_CLOCK

#define CMD_PCI_CLOCK   30000

Definition at line 29 of file cmd.c.

◆ CMD_REG_ARTTIM0

#define CMD_REG_ARTTIM0   0x53

Definition at line 34 of file cmd.c.

◆ CMD_REG_ARTTIM1

#define CMD_REG_ARTTIM1   0x55

Definition at line 36 of file cmd.c.

◆ CMD_REG_ARTTIM23

#define CMD_REG_ARTTIM23   0x57

Definition at line 38 of file cmd.c.

◆ CMD_REG_BMIDECSR

#define CMD_REG_BMIDECSR   0x79

Definition at line 43 of file cmd.c.

◆ CMD_REG_CFR

#define CMD_REG_CFR   0x50

Definition at line 31 of file cmd.c.

◆ CMD_REG_CMDTIM

#define CMD_REG_CMDTIM   0x52

Definition at line 33 of file cmd.c.

◆ CMD_REG_CNTRL

#define CMD_REG_CNTRL   0x51

Definition at line 32 of file cmd.c.

◆ CMD_REG_DRWTIM0

#define CMD_REG_DRWTIM0   0x54

Definition at line 35 of file cmd.c.

◆ CMD_REG_DRWTIM1

#define CMD_REG_DRWTIM1   0x56

Definition at line 37 of file cmd.c.

◆ CMD_REG_DRWTIM2

#define CMD_REG_DRWTIM2   0x58

Definition at line 39 of file cmd.c.

◆ CMD_REG_DRWTIM23

#define CMD_REG_DRWTIM23   0x58

Definition at line 40 of file cmd.c.

◆ CMD_REG_DRWTIM3

#define CMD_REG_DRWTIM3   0x5B

Definition at line 41 of file cmd.c.

◆ CMD_REG_MRDMODE

#define CMD_REG_MRDMODE   0x71

Definition at line 42 of file cmd.c.

◆ CMD_REG_UDIDETCR

#define CMD_REG_UDIDETCR (   Channel)    (((Channel) == 0) ? 0x73 : 0x7B)

Definition at line 44 of file cmd.c.

◆ CMD_UDIDETCR_CLEAR

#define CMD_UDIDETCR_CLEAR (   Drive)    (((Drive) == 0) ? 0x35 : 0xCA)

Definition at line 59 of file cmd.c.

◆ CMD_UDIDETCR_EN

#define CMD_UDIDETCR_EN (   Drive)    (0x01 << (Drive))

Definition at line 60 of file cmd.c.

◆ HW_FLAGS_HAS_UDMA_REG

#define HW_FLAGS_HAS_UDMA_REG   0x0002

Definition at line 25 of file cmd.c.

◆ HW_FLAGS_NEED_PIO_FIX

#define HW_FLAGS_NEED_PIO_FIX   0x0004

Definition at line 26 of file cmd.c.

◆ HW_FLAGS_NO_PREFETCH

#define HW_FLAGS_NO_PREFETCH   0x0008

Definition at line 27 of file cmd.c.

◆ HW_FLAGS_PRIMARY_ENABLED

#define HW_FLAGS_PRIMARY_ENABLED   0x0001

Definition at line 24 of file cmd.c.

◆ PCI_DEV_CMD0649

#define PCI_DEV_CMD0649   0x0649

Definition at line 22 of file cmd.c.

◆ PCI_DEV_PCI0640

#define PCI_DEV_PCI0640   0x0640

Definition at line 18 of file cmd.c.

◆ PCI_DEV_PCI0643

#define PCI_DEV_PCI0643   0x0643

Definition at line 19 of file cmd.c.

◆ PCI_DEV_PCI0646

#define PCI_DEV_PCI0646   0x0646

Definition at line 20 of file cmd.c.

◆ PCI_DEV_PCI0648

#define PCI_DEV_PCI0648   0x0648

Definition at line 21 of file cmd.c.

Typedef Documentation

◆ CMD_HW_EXTENSION

◆ PCMD_HW_EXTENSION

Function Documentation

◆ CmdChannelEnabledTest()

static IDE_CHANNEL_STATE CmdChannelEnabledTest ( _In_ PATA_CONTROLLER  Controller,
_In_ ULONG  Channel 
)
static

Definition at line 356 of file cmd.c.

359{
360 PCHANNEL_DATA_PATA ChanData = Controller->Channels[Channel];
362
363 /* Some controllers lack the primary channel enable bit */
364 if ((Channel == 0) && (ChanData->HwFlags & HW_FLAGS_PRIMARY_ENABLED))
365 return ChannelEnabled;
366
367 Control = PciRead8(Controller, CMD_REG_CNTRL);
369 return ChannelEnabled;
370
371 return ChannelDisabled;
372}
#define CMD_REG_CNTRL
Definition: cmd.c:32
#define CMD_CNTRL_CHAN_EN(Channel)
Definition: cmd.c:48
#define HW_FLAGS_PRIMARY_ENABLED
Definition: cmd.c:24
@ ChannelDisabled
Definition: ide.h:197
@ ChannelEnabled
Definition: ide.h:198
FORCEINLINE UCHAR PciRead8(_In_ PATA_CONTROLLER Controller, _In_ ULONG ConfigDataOffset)
Definition: pciidex.h:847
_In_ ULONG Channel
Definition: pciidex.h:74
unsigned char UCHAR
Definition: typedefs.h:53
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by CmdGetControllerProperties().

◆ CmdCheckInterruptMrdMode()

static BOOLEAN CmdCheckInterruptMrdMode ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 376 of file cmd.c.

378{
379 PATA_CONTROLLER Controller = ChanData->Controller;
380 UCHAR Control, InterruptMask;
381
382 if (ChanData->Regs.Dma)
383 Control = ATA_READ(ChanData->Regs.Dma + 1, ChanData, MRES_DMA);
384 else
385 Control = PciRead8(Controller, CMD_REG_MRDMODE);
386
387 InterruptMask = CMD_MRDMODE_INTR(ChanData->Channel);
388 if (!(Control & InterruptMask))
389 return FALSE;
390
392 Control |= InterruptMask;
393 /* Make sure we do not clear the write-only bits */
395
396 /* Clear the interrupt */
397 if (ChanData->Regs.Dma)
398 ATA_WRITE(ChanData->Regs.Dma + 1, Control, ChanData, MRES_DMA);
399 else
400 PciWrite8(Controller, CMD_REG_MRDMODE, Control);
401
402 return TRUE;
403}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CMD_REG_MRDMODE
Definition: cmd.c:42
#define CMD_MRDMODE_READ_MULTIPLE
Definition: cmd.c:52
#define CMD_MRDMODE_INTR(Channel)
Definition: cmd.c:53
#define ATA_WRITE(Port, Value)
Definition: hwidep.h:80
#define ATA_READ(Port)
Definition: hwidep.h:89
FORCEINLINE VOID PciWrite8(_In_ PATA_CONTROLLER Controller, _In_ ULONG ConfigDataOffset, _In_ UCHAR Value)
Definition: pciidex.h:883

Referenced by CmdGetControllerProperties().

◆ CmdCheckInterruptPci()

static BOOLEAN CmdCheckInterruptPci ( _In_ PCHANNEL_DATA_PATA  ChanData)
static

Definition at line 407 of file cmd.c.

409{
410 PATA_CONTROLLER Controller = ChanData->Controller;
411 UCHAR Status, InterruptMask;
413
414 InterruptMask = CMD_CFR_INTR(ChanData->Channel);
415 Register = (ChanData->Channel == 0) ? CMD_REG_CFR : CMD_REG_ARTTIM23;
416
417 /* Read CFR or REG_ARTTIM23 to clear the interrupt */
418 Status = PciRead8(Controller, Register);
419 return !!(Status & InterruptMask);
420}
#define CMD_REG_CFR
Definition: cmd.c:31
#define CMD_CFR_INTR(Channel)
Definition: cmd.c:46
#define CMD_REG_ARTTIM23
Definition: cmd.c:38
Status
Definition: gdiplustypes.h:25
uint32_t ULONG
Definition: typedefs.h:59

Referenced by CmdGetControllerProperties().

◆ CmdControllerStart()

static VOID CmdControllerStart ( _In_ PATA_CONTROLLER  Controller)
static

Definition at line 424 of file cmd.c.

426{
427 ULONG i;
429
430 /*
431 * Initialize the controller to compatible PIO timings.
432 * We dynamically adjust these timings depending on attached devices.
433 */
434 PciWrite8(Controller, CMD_REG_CMDTIM, 0);
435
436 if (Controller->Pci.DeviceID == PCI_DEV_PCI0640)
437 {
438 /*
439 * Errata: Disable the Read-Ahead Mode.
440 * https://www.mindprod.com/jgloss/eideflaw.html
441 */
442 for (i = 0; i < RTL_NUMBER_OF(CmdPrefetchRegs); ++i)
443 {
444 Control = PciRead8(Controller, CmdPrefetchRegs[i]);
446 PciWrite8(Controller, CmdPrefetchRegs[i], Control);
447 }
448 }
449 else
450 {
451 Control = PciRead8(Controller, CMD_REG_MRDMODE);
454 PciWrite8(Controller, CMD_REG_MRDMODE, Control);
455 }
456}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static const UCHAR CmdPrefetchDisable[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
Definition: cmd.c:68
#define CMD_MRDMODE_INTR_CH0_BLOCK
Definition: cmd.c:54
#define PCI_DEV_PCI0640
Definition: cmd.c:18
static const ULONG CmdPrefetchRegs[MAX_IDE_CHANNEL]
Definition: cmd.c:75
#define CMD_MRDMODE_INTR_CH1_BLOCK
Definition: cmd.c:55
#define CMD_REG_CMDTIM
Definition: cmd.c:33
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

Referenced by CmdGetControllerProperties().

◆ CmdDerateTimings()

static VOID CmdDerateTimings ( _In_ PCHANNEL_DEVICE_CONFIG  Device,
_Inout_ PATA_TIMING  Timing 
)
static

Definition at line 154 of file cmd.c.

157{
158 /* Make the timings run slower to address the PCI Bus Hang errata */
159 switch (Device->PioMode)
160 {
161 case PIO_MODE(0):
162 {
163 /*
164 * 600ns is minimum in PIO mode 0, but program the chip to 570ns.
165 * 480 + 90 = 570
166 */
167 CmdFixRecoveryTiming(Device, Timing, 20, 16, 3, 16, 3);
168 break;
169 }
170 case PIO_MODE(1):
171 {
172 /* 300 + 90 = 390 */
173 CmdFixRecoveryTiming(Device, Timing, 13, 10, 3, 10, 3);
174 break;
175 }
176 case PIO_MODE(2):
177 {
178 /*
179 * Cmd 300 + 90 = 390
180 * Data 150 + 90 = 240
181 */
182 CmdFixRecoveryTiming(Device, Timing, 8, 10, 3, 5, 3);
183 break;
184 }
185
186 /* PIO 3 & 4 unaffected by the errata */
187 default:
188 break;
189 }
190}
#define PIO_MODE(n)
Definition: ata_user.h:36
static VOID CmdFixRecoveryTiming(_In_ PCHANNEL_DEVICE_CONFIG Device, _Inout_ PATA_TIMING Timing, _In_ ATATIM CycleTimeClocks, _In_ ATATIM CmdActiveClocks, _In_ ATATIM CmdRecoveryClocks, _In_ ATATIM DataActiveClocks, _In_ ATATIM DataRecoveryClocks)
Definition: cmd.c:120
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474

Referenced by CmdSetTransferMode().

◆ CmdFixRecoveryTiming()

static VOID CmdFixRecoveryTiming ( _In_ PCHANNEL_DEVICE_CONFIG  Device,
_Inout_ PATA_TIMING  Timing,
_In_ ATATIM  CycleTimeClocks,
_In_ ATATIM  CmdActiveClocks,
_In_ ATATIM  CmdRecoveryClocks,
_In_ ATATIM  DataActiveClocks,
_In_ ATATIM  DataRecoveryClocks 
)
static

Definition at line 120 of file cmd.c.

128{
129 if (((Timing->DataActive + Timing->DataRecovery) > CycleTimeClocks) || // Cycle time not met
130 (Device->DmaMode == MWDMA_MODE(0))) // Data active time not met
131 {
132 if (Timing->CmdActive < CmdActiveClocks)
133 Timing->CmdActive = CmdActiveClocks;
134 if (Timing->CmdRecovery < CmdRecoveryClocks)
135 Timing->CmdRecovery = CmdRecoveryClocks;
136
137 if (Timing->DataActive < DataActiveClocks)
138 Timing->DataActive = DataActiveClocks;
139 if (Timing->DataRecovery < DataRecoveryClocks)
140 Timing->DataRecovery = DataRecoveryClocks;
141 }
142 else
143 {
144 /* Use recommended values */
145 Timing->CmdActive = CmdActiveClocks;
146 Timing->CmdRecovery = CmdRecoveryClocks;
147 Timing->DataActive = DataActiveClocks;
148 Timing->DataRecovery = DataRecoveryClocks;
149 }
150}
#define MWDMA_MODE(n)
Definition: ata_user.h:38

Referenced by CmdDerateTimings().

◆ CmdGetControllerProperties()

NTSTATUS CmdGetControllerProperties ( _Inout_ PATA_CONTROLLER  Controller)

Definition at line 460 of file cmd.c.

462{
464 ULONG i, SupportedMode, HwFlags = 0;
466
467 PAGED_CODE();
468 ASSERT(Controller->Pci.VendorID == PCI_VEN_CMD);
469
470 switch (Controller->Pci.DeviceID)
471 {
472 case PCI_DEV_PCI0640:
473 /*
474 * Errata: The CMD-640 has one set of task file registers per controller
475 * and thus the two channels cannot be used simultaneously.
476 * https://www.mindprod.com/jgloss/eideflaw.html
477 */
478 Controller->Flags |= CTRL_FLAG_IS_SIMPLEX;
479
480 SupportedMode = PIO_ALL;
482 break;
483
484 case PCI_DEV_PCI0643:
485 SupportedMode = PIO_ALL | SWDMA_ALL | MWDMA_ALL;
486
487 if (Controller->Pci.RevisionID < 6)
488 HwFlags |= HW_FLAGS_PRIMARY_ENABLED;
489 break;
490
491 case PCI_DEV_PCI0646:
492 SupportedMode = PIO_ALL | SWDMA_ALL | MWDMA_ALL;
493 HwFlags |= HW_FLAGS_HAS_UDMA_REG;
494
495 if (Controller->Pci.RevisionID < 3)
496 HwFlags |= HW_FLAGS_PRIMARY_ENABLED;
497 else
498 CheckInterrupt = CmdCheckInterruptMrdMode;
499
500 if (Controller->Pci.RevisionID == 5 || Controller->Pci.RevisionID == 6)
501 {
502 /*
503 * Early 646U2 revisions can support UDMA2 only at a PCI bus speed of 33MHz.
504 * When it runs at 25 MHz or 30 MHZ, the transfer speed must be limited to UDMA1.
505 */
506 SupportedMode |= UDMA_MODES(0, 1);
507 }
508 else if (Controller->Pci.RevisionID > 6)
509 {
510 SupportedMode |= UDMA_MODES(0, 2);
511 }
512 break;
513
514 case PCI_DEV_PCI0648:
515 SupportedMode = PIO_ALL | MWDMA_ALL | UDMA_MODES(0, 4);
516 /* Prefetch bits have different meaning on this controller */
518 CheckInterrupt = CmdCheckInterruptMrdMode;
519 break;
520
521 case PCI_DEV_CMD0649:
522 SupportedMode = PIO_ALL | MWDMA_ALL | UDMA_MODES(0, 5);
523 HwFlags |= HW_FLAGS_HAS_UDMA_REG;
524
525 if (Controller->Pci.RevisionID == 2)
526 HwFlags |= HW_FLAGS_NEED_PIO_FIX;
527
528 CheckInterrupt = CmdCheckInterruptMrdMode;
529 break;
530
531 default:
532 return STATUS_NO_MATCH;
533 }
534
535 Controller->Start = CmdControllerStart;
536
537 Controller->Flags |= CTRL_FLAG_USE_TEST_FUNCTION;
538 Controller->ChannelEnabledTest = CmdChannelEnabledTest;
539
540 Status = PciIdeCreateChannelData(Controller, 0);
541 if (!NT_SUCCESS(Status))
542 return Status;
543
544 Controller->HwExt = ExAllocatePoolZero(NonPagedPool, sizeof(CMD_HW_EXTENSION), TAG_PCIIDEX);
545 if (!Controller->HwExt)
547
548 for (i = 0; i < Controller->MaxChannels; ++i)
549 {
550 PCHANNEL_DATA_PATA ChanData = Controller->Channels[i];
551
552 ChanData->HwFlags = HwFlags;
553 ChanData->CheckInterrupt = CheckInterrupt;
554 ChanData->SetTransferMode = CmdSetTransferMode;
555 ChanData->TransferModeSupported = SupportedMode;
556
557 if (Controller->Pci.DeviceID == PCI_DEV_PCI0640)
558 {
559 ChanData->ChanInfo &= ~CHANNEL_FLAG_IO32;
560 }
561 else
562 {
563 /* Check for 80-conductor cable */
564 if (ChanData->TransferModeSupported & UDMA_80C_ALL)
565 {
566 UCHAR BmControl = PciRead8(Controller, CMD_REG_BMIDECSR);
567 if (!(BmControl & CMD_BMIDECSR_CR(i)))
568 {
569 INFO("CH %lu: BIOS detected 40-conductor cable\n", ChanData->Channel);
570 ChanData->TransferModeSupported &= ~UDMA_80C_ALL;
571 }
572 }
573 }
574 }
575
576 return STATUS_SUCCESS;
577}
#define PAGED_CODE()
#define MWDMA_ALL
Definition: ata_user.h:27
#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 INFO
Definition: debug.h:89
static VOID CmdSetTransferMode(_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel, _In_reads_(MAX_IDE_DEVICE) PCHANNEL_DEVICE_CONFIG *DeviceList)
Definition: cmd.c:243
static BOOLEAN CmdCheckInterruptPci(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: cmd.c:407
#define CMD_BMIDECSR_CR(Channel)
Definition: cmd.c:57
static IDE_CHANNEL_STATE CmdChannelEnabledTest(_In_ PATA_CONTROLLER Controller, _In_ ULONG Channel)
Definition: cmd.c:356
#define HW_FLAGS_HAS_UDMA_REG
Definition: cmd.c:25
#define PCI_DEV_PCI0643
Definition: cmd.c:19
#define HW_FLAGS_NEED_PIO_FIX
Definition: cmd.c:26
static BOOLEAN CmdCheckInterruptMrdMode(_In_ PCHANNEL_DATA_PATA ChanData)
Definition: cmd.c:376
#define CMD_REG_BMIDECSR
Definition: cmd.c:43
static VOID CmdControllerStart(_In_ PATA_CONTROLLER Controller)
Definition: cmd.c:424
#define PCI_DEV_PCI0648
Definition: cmd.c:21
#define PCI_DEV_CMD0649
Definition: cmd.c:22
#define PCI_DEV_PCI0646
Definition: cmd.c:20
#define HW_FLAGS_NO_PREFETCH
Definition: cmd.c:27
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ASSERT(a)
Definition: mode.c:44
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define STATUS_NO_MATCH
Definition: ntstatus.h:873
#define PCI_VEN_CMD
Definition: pata.h:14
#define UDMA_MODES(MinMode, MaxMode)
Definition: pata.h:49
#define UDMA_80C_ALL
Definition: pata.h:41
NTSTATUS PciIdeCreateChannelData(_In_ PATA_CONTROLLER Controller, _In_ ULONG HwExtensionSize)
#define CTRL_FLAG_USE_TEST_FUNCTION
Definition: pciidex.h:226
CHANNEL_CHECK_INTERRUPT * PCHANNEL_CHECK_INTERRUPT
Definition: pciidex.h:127
#define TAG_PCIIDEX
Definition: pciidex.h:32
#define CTRL_FLAG_IS_SIMPLEX
Definition: pciidex.h:224
#define STATUS_SUCCESS
Definition: shellext.h:65
PCHANNEL_CHECK_INTERRUPT CheckInterrupt
Definition: pciidex.h:303
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by PciIdeGetControllerProperties().

◆ CmdPackTimings()

static UCHAR CmdPackTimings ( _In_ PATA_CONTROLLER  Controller,
_In_ ATATIM  Active,
_In_ ATATIM  Recovery 
)
static

Definition at line 194 of file cmd.c.

198{
199 if (Controller->Pci.DeviceID == PCI_DEV_PCI0640)
200 {
201 if (Active >= 16)
202 Active = 0;
203 else if (Active < 2)
204 Active = 2;
205
206 if (Controller->Pci.RevisionID > 1)
207 {
208 /* 640B */
209 if (Recovery >= 17)
210 Recovery = 0;
211 else if (Recovery > 2)
212 --Recovery;
213 else
214 Recovery = 2;
215 }
216 else
217 {
218 /* 640A */
219 if (Recovery >= 16)
220 Recovery = 0;
221 else if (Recovery < 2)
222 Recovery = 2;
223 }
224 }
225 else
226 {
227 if (Active >= 16)
228 Active = 0;
229
230 if (Recovery >= 16)
231 Recovery = 0;
232 else if (Recovery > 1)
233 --Recovery;
234 else
235 Recovery = 15;
236 }
237
238 return (Active << 4) | Recovery;
239}
_In_ ULONG _In_ BOOLEAN Active
Definition: potypes.h:564

Referenced by CmdSetTransferMode().

◆ CmdSetTransferMode()

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

Definition at line 243 of file cmd.c.

247{
248 PCHANNEL_DATA_PATA ChanData = Controller->Channels[Channel];
249 PCMD_HW_EXTENSION HwExt = Controller->HwExt;
250 ATA_TIMING DeviceTimings[MAX_IDE_DEVICE];
251 ULONG i, TimingFlags;
252 UCHAR Value;
253
254 /* Some timings are shared between both drives drives on the secondary channel */
255 TimingFlags = 0;
256 if (Channel != 0)
257 {
258 TimingFlags |= SHARED_ADDR_TIMINGS;
259
260 if (Controller->Pci.DeviceID == PCI_DEV_PCI0640)
261 TimingFlags |= SHARED_DATA_TIMINGS;
262 }
263 AtaSelectTimings(DeviceList, DeviceTimings, CMD_PCI_CLOCK, TimingFlags);
264
265 /* Enable or disable prefetch mode */
266 Value = PciRead8(Controller, CmdPrefetchRegs[Channel]);
267 for (i = 0; i < MAX_IDE_DEVICE; ++i)
268 {
270
271 if (!Device)
272 continue;
273
274 if ((ChanData->HwFlags & HW_FLAGS_NO_PREFETCH) || !Device->IsFixedDisk)
276 else
277 Value &= ~CmdPrefetchDisable[Channel][i];
278 }
279 PciWrite8(Controller, CmdPrefetchRegs[Channel], Value);
280
281 /* Program timing settings */
282 for (i = 0; i < MAX_IDE_DEVICE; ++i)
283 {
285 PATA_TIMING Timing = &DeviceTimings[i];
286 UCHAR UdmaTimReg;
288
289 /* UDMA timings */
290 if (ChanData->HwFlags & HW_FLAGS_HAS_UDMA_REG)
291 {
292 UdmaTimReg = PciRead8(Controller, CMD_REG_UDIDETCR(Channel));
293 if (Device && (Device->DmaMode >= UDMA_MODE(0)))
294 {
295 UdmaTimReg &= ~CMD_UDIDETCR_CLEAR(i);
296 UdmaTimReg |= CmdUdmaTimings[Device->DmaMode - UDMA_MODE(0)][i];
297 }
298 else
299 {
300 UdmaTimReg &= ~CMD_UDIDETCR_EN(i);
301 }
302 PciWrite8(Controller, CMD_REG_UDIDETCR(Channel), UdmaTimReg);
303 }
304
305 if (!Device)
306 {
307 HwExt->CmdActive[i + Channel * MAX_IDE_DEVICE] = 0;
308 HwExt->CmdRecovery[i + Channel * MAX_IDE_DEVICE] = 0;
309 continue;
310 }
311
312 if (ChanData->HwFlags & HW_FLAGS_NEED_PIO_FIX)
313 CmdDerateTimings(Device, Timing);
314
315 /* 8-bit timings */
316 HwExt->CmdActive[i + Channel * MAX_IDE_DEVICE] = Timing->CmdActive;
317 HwExt->CmdRecovery[i + Channel * MAX_IDE_DEVICE] = Timing->CmdRecovery;
318
319 /* Address setup timing */
320 if (Timing->AddressSetup > RTL_NUMBER_OF(CmdArtTimings) - 1)
322 Value = PciRead8(Controller, CmdArtTimRegs[Channel][i]);
323 Value &= ~CMD_ARTTIM_ART_MASK;
324 Value |= CmdArtTimings[Timing->AddressSetup];
325 PciWrite8(Controller, CmdArtTimRegs[Channel][i], Value);
326
327 /* 16-bit timings */
328 Value = CmdPackTimings(Controller, Timing->DataActive, Timing->DataRecovery);
329 if ((Controller->Pci.DeviceID == PCI_DEV_PCI0640) && (Channel != 0))
331 else
333 PciWrite8(Controller, Register, Value);
334 }
335
336 /* 8-bit timings are shared between both the primary and secondary channels */
337 for (i = 0; i < MAX_IDE_CHANNEL * MAX_IDE_DEVICE; ++i)
338 {
339 if (HwExt->CmdActive[i] > DeviceTimings[0].CmdActive)
340 DeviceTimings[0].CmdActive = HwExt->CmdActive[i];
341
342 if (HwExt->CmdRecovery[i] > DeviceTimings[0].CmdRecovery)
343 DeviceTimings[0].CmdRecovery = HwExt->CmdRecovery[i];
344 }
345 if ((DeviceTimings[0].CmdActive != 0) || (DeviceTimings[0].CmdRecovery != 0))
346 {
347 Value = CmdPackTimings(Controller,
348 DeviceTimings[0].CmdActive,
349 DeviceTimings[0].CmdRecovery);
350 PciWrite8(Controller, CMD_REG_CMDTIM, Value);
351 }
352}
#define UDMA_MODE(n)
Definition: ata_user.h:39
PDEVICE_LIST DeviceList
Definition: utils.c:27
#define CMD_PCI_CLOCK
Definition: cmd.c:29
static const ULONG CmdDrwTimRegs[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
Definition: cmd.c:81
static UCHAR CmdPackTimings(_In_ PATA_CONTROLLER Controller, _In_ ATATIM Active, _In_ ATATIM Recovery)
Definition: cmd.c:194
#define CMD_REG_DRWTIM23
Definition: cmd.c:40
static VOID CmdDerateTimings(_In_ PCHANNEL_DEVICE_CONFIG Device, _Inout_ PATA_TIMING Timing)
Definition: cmd.c:154
static const UCHAR CmdArtTimings[]
Definition: cmd.c:95
static const UCHAR CmdUdmaTimings[6][MAX_IDE_DEVICE]
Definition: cmd.c:105
static const ULONG CmdArtTimRegs[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
Definition: cmd.c:88
#define CMD_REG_UDIDETCR(Channel)
Definition: cmd.c:44
#define MAX_IDE_DEVICE
Definition: ide.h:32
#define MAX_IDE_CHANNEL
Definition: ide.h:30
#define SHARED_DATA_TIMINGS
Definition: pata.h:231
#define SHARED_ADDR_TIMINGS
Definition: pata.h:232
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: pata_generic.c:116
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
ATATIM CmdActive[MAX_IDE_CHANNEL *MAX_IDE_DEVICE]
Definition: cmd.c:64
ATATIM CmdRecovery[MAX_IDE_CHANNEL *MAX_IDE_DEVICE]
Definition: cmd.c:65
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by CmdGetControllerProperties().

Variable Documentation

◆ CmdArtTimings

const UCHAR CmdArtTimings[]
static
Initial value:
=
{
0x40,
0x40,
0x40,
0x80,
0x00,
0xC0
}

Definition at line 95 of file cmd.c.

Referenced by CmdSetTransferMode().

◆ CmdArtTimRegs

const ULONG CmdArtTimRegs[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
static
Initial value:
=
{
}
#define CMD_REG_ARTTIM0
Definition: cmd.c:34
#define CMD_REG_ARTTIM1
Definition: cmd.c:36

Definition at line 88 of file cmd.c.

Referenced by CmdSetTransferMode().

◆ CmdDrwTimRegs

const ULONG CmdDrwTimRegs[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
static
Initial value:
=
{
}
#define CMD_REG_DRWTIM0
Definition: cmd.c:35
#define CMD_REG_DRWTIM3
Definition: cmd.c:41
#define CMD_REG_DRWTIM2
Definition: cmd.c:39
#define CMD_REG_DRWTIM1
Definition: cmd.c:37

Definition at line 81 of file cmd.c.

Referenced by CmdSetTransferMode().

◆ CmdPrefetchDisable

const UCHAR CmdPrefetchDisable[MAX_IDE_CHANNEL][MAX_IDE_DEVICE]
static
Initial value:
=
{
{ 0x40, 0x80 },
{ 0x04, 0x08 }
}

Definition at line 68 of file cmd.c.

Referenced by CmdControllerStart(), and CmdSetTransferMode().

◆ CmdPrefetchRegs

const ULONG CmdPrefetchRegs[MAX_IDE_CHANNEL]
static
Initial value:

Definition at line 75 of file cmd.c.

Referenced by CmdControllerStart(), and CmdSetTransferMode().

◆ CmdUdmaTimings

const UCHAR CmdUdmaTimings[6][MAX_IDE_DEVICE]
static
Initial value:
=
{
{ 0x31, 0xC2 },
{ 0x21, 0x82 },
{ 0x11, 0x42 },
{ 0x25, 0x8A },
{ 0x15, 0x4A },
{ 0x05, 0x0A }
}

Definition at line 105 of file cmd.c.

Referenced by CmdSetTransferMode().