From: Kevin Huang Date: Mon, 1 Jun 2009 03:43:20 +0000 (+0800) Subject: Staging: add pata_rdc driver X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=ad41a8a58e15bf4dee13b78bb3b77f4e1f417506;p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git Staging: add pata_rdc driver This is our IDE Source code. This is base on kernel 2.6.28. pata_rdc.h and pata_rdc.c From: Kevin Huang Cc: Tomy Wang Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/pata_rdc/pata_rdc.c b/drivers/staging/pata_rdc/pata_rdc.c new file mode 100644 index 000000000000..657e9971f41c --- /dev/null +++ b/drivers/staging/pata_rdc/pata_rdc.c @@ -0,0 +1,1403 @@ +#include +#include +#include + +#include +#include + +#include +#include + +#include "pata_rdc.h" + +//#define DBGPRINTF + +#ifdef DBGPRINTF + + #define dbgprintf(format, arg...) printk(KERN_INFO format, ## arg) + +#else + + #define dbgprintf(...) + +#endif + +// Driver Info. + +#define DRIVER_NAME "pata_rdc" // sata_rdc for SATA +#define DRIVER_VERSION "2.6.28" // based on kernel version. + // because each kernel main version has its libata, we follow kernel to determine the last libata version. + + +static const struct pci_device_id rdc_pata_id_table[] = { + { 0x17F3, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RDC_17F31011}, + { 0x17F3, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RDC_17F31012}, + { } /* terminate list */ +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("this version author is RDC"); // replace "RDC" with the last maintainer. +MODULE_DESCRIPTION("RDC PCI IDE Driver"); +MODULE_DEVICE_TABLE(pci, rdc_pata_id_table); +MODULE_VERSION(DRIVER_VERSION); + +// a pci driver +static struct pci_driver rdc_pata_driver = { + .name = DRIVER_NAME, + .id_table = rdc_pata_id_table, + .probe = rdc_init_one, + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = ata_pci_device_resume, +#endif +}; + +static unsigned int in_module_init = 1; // hotplugging check??? +static int __init pata_rdc_init(void) +{ + int rc; + + dbgprintf("pata_rdc_init\n"); + rc = pci_register_driver(&rdc_pata_driver); + if (rc) + { + dbgprintf("pata_rdc_init faile\n"); + return rc; + } + + in_module_init = 0; + + return 0; +} + +static void __exit pata_rdc_exit(void) +{ + dbgprintf("pata_rdc_exit\n"); + pci_unregister_driver(&rdc_pata_driver); +} + +module_init(pata_rdc_init); +module_exit(pata_rdc_exit); + +// ata device data + +static struct pci_bits ATA_Decode_Enable_Bits[] = { // see ATA Host Adapters Standards. + { 0x41U, 1U, 0x80UL, 0x80UL }, /* port (Channel) 0 */ + { 0x43U, 1U, 0x80UL, 0x80UL }, /* port (Channel) 1 */ +}; + +static struct scsi_host_template rdc_pata_sht = { // pata host template + ATA_BMDMA_SHT(DRIVER_NAME), +}; + +static const struct ata_port_operations rdc_pata_ops = { + .inherits = &ata_bmdma_port_ops, + + .port_start = rdc_pata_port_start, + .port_stop = rdc_pata_port_stop, + .prereset = rdc_pata_prereset, + .cable_detect = rdc_pata_cable_detect, + .set_piomode = rdc_pata_set_piomode, + .set_dmamode = rdc_pata_set_dmamode, + +}; + +static struct ata_port_info rdc_pata_port_info[] = { + [RDC_17F31011] = + { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ + .port_ops = &rdc_pata_ops, + }, + + [RDC_17F31012] = + { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = ATA_UDMA5, /* udma0-5 */ + .port_ops = &rdc_pata_ops, + }, + + +}; + + + + +// callback function for pci_driver + +/** + * Register ATA PCI device with kernel services + * @pdev: PCI device to register + * @ent: Entry in sch_pci_tbl matching with @pdev + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, or -ERRNO value. + */ +static int __devinit rdc_init_one( + struct pci_dev *pdev, + const struct pci_device_id *ent + ) +{ + //struct device *dev = &pdev->dev; + struct ata_port_info port_info[2]; + struct ata_port_info *ppinfo[] = { &port_info[0], &port_info[1] }; + + int rc; + + dbgprintf("rdc_init_one\n"); + + /* no hotplugging support (FIXME) */ // why??? + if (!in_module_init) + { + dbgprintf("rdc_init_one in_module_init == 0 failed \n"); + return -ENODEV; + } + port_info[0] = rdc_pata_port_info[ent->driver_data]; + port_info[1] = rdc_pata_port_info[ent->driver_data]; + + /* enable device and prepare host */ + rc = pci_enable_device(pdev); + if (rc) + { + dbgprintf("rdc_init_one pci_enable_device failed \n"); + return rc; + } + /* initialize controller */ + + pci_intx(pdev, 1); // enable interrupt + + return ata_pci_init_one(pdev, ppinfo); +} + +// callback function for ata_port + +/** + * Set port up for dma. + * @ap: Port to initialize + * + * Called just after data structures for each port are + * initialized. Allocates space for PRD table if the device + * is DMA capable SFF. + + Some drivers also use this entry point as a chance to allocate driverprivate + memory for ap->private_data. + + * + * May be used as the port_start() entry in ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +static int rdc_pata_port_start( + struct ata_port *ap + ) +{ + uint Channel; + + Channel = ap->port_no; + dbgprintf("rdc_pata_port_start Channel: %u \n", Channel); + if (ap->ioaddr.bmdma_addr) + { + return ata_port_start(ap); + } + else + { + dbgprintf("rdc_pata_port_start return 0 !!!\n"); + return 0; + } +} + +static void rdc_pata_port_stop( + struct ata_port *ap + ) +{ + uint Channel; + + Channel = ap->port_no; + + dbgprintf("rdc_pata_port_stop Channel: %u \n", Channel); +} + +/** + * prereset for PATA host controller + * @link: Target link + * @deadline: deadline jiffies for the operation + * + * LOCKING: + * None (inherited from caller). + */ +static int rdc_pata_prereset( + struct ata_link *link, + unsigned long deadline + ) +{ + struct pci_dev *pdev; + struct ata_port *ap; + + uint Channel; + + dbgprintf("rdc_pata_prereset\n"); + + ap = link->ap; + pdev = to_pci_dev(ap->host->dev); + + Channel = ap->port_no; + + // test ATA Decode Enable Bits, should be enable. + if (!pci_test_config_bits(pdev, &ATA_Decode_Enable_Bits[Channel])) + { + dbgprintf("rdc_pata_prereset Channel: %u, Decode Disable\n", Channel); + return -ENOENT; + } + else + { + dbgprintf("rdc_pata_prereset Channel: %u, Decode Enable\n", Channel); + return ata_std_prereset(link, deadline); + } +} + +/** + * Probe host controller cable detect info + * @ap: Port for which cable detect info is desired + * + * Read cable indicator from ATA PCI device's PCI config + * register. This register is normally set by firmware (BIOS). + * + * LOCKING: + * None (inherited from caller). + */ + +static int rdc_pata_cable_detect( + struct ata_port *ap + ) +{ + struct pci_dev *pdev; + + uint Channel; + + uint Mask; + u32 u32Value; + + dbgprintf("rdc_pata_cable_detect\n"); + + pdev = to_pci_dev(ap->host->dev); + + Channel = ap->port_no; + + if (Channel == 0) + { + Mask = ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report; + } + else + { + Mask = ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report; + } + + /* check BIOS cable detect results */ + pci_read_config_dword(pdev, ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, &u32Value); + + if ((u32Value & Mask) == 0) + { + dbgprintf("rdc_pata_cable_detect Channel: %u, PATA40 \n", Channel); + return ATA_CBL_PATA40; + } + else + { + dbgprintf("rdc_pata_cable_detect Channel: %u, PATA80 \n", Channel); + return ATA_CBL_PATA80; + } +} + +/** + * Initialize host controller PATA PIO timings + * @ap: Port whose timings we are configuring + * @adev: um + * + * Set PIO mode for device, in host controller PCI config space. + * + * LOCKING: + * None (inherited from caller). + */ + +static void rdc_pata_set_piomode( + struct ata_port *ap, + struct ata_device *adev + ) +{ + struct pci_dev *pdev; + + uint Channel; + uint DeviceID; + + uint PIOTimingMode; + uint PrefetchPostingEnable; + + dbgprintf("rdc_pata_set_piomode\n"); + + pdev = to_pci_dev(ap->host->dev); + + Channel = ap->port_no; + DeviceID = adev->devno; + PIOTimingMode = adev->pio_mode - XFER_PIO_0; // piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3... + + if (adev->class == ATA_DEV_ATA) + { + PrefetchPostingEnable = TRUE; + } + else + { // ATAPI, CD DVD Rom + PrefetchPostingEnable = FALSE; + } + + /* PIO configuration clears DTE unconditionally. It will be + * programmed in set_dmamode which is guaranteed to be called + * after set_piomode if any DMA mode is available. + */ + + /* Ensure the UDMA bit is off - it will be turned back on if + UDMA is selected */ + + if (Channel == 0) + { + ATAHostAdapter_SetPrimaryPIO( + pdev, + DeviceID, + PIOTimingMode, + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetPrimaryUDMA( + pdev, + DeviceID, + FALSE,//UDMAEnable, + UDMA0 + ); + } + else + { + ATAHostAdapter_SetSecondaryPIO( + pdev, + DeviceID, + PIOTimingMode, + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetSecondaryUDMA( + pdev, + DeviceID, + FALSE,//UDMAEnable, + UDMA0 + ); + } + dbgprintf("rdc_pata_set_piomode Channel: %u, DeviceID: %u, PIO: %d \n", Channel, DeviceID, PIOTimingMode); +} + +/** + * Initialize host controller PATA DMA timings + * @ap: Port whose timings we are configuring + * @adev: um + * + * Set MW/UDMA mode for device, in host controller PCI config space. + * + * LOCKING: + * None (inherited from caller). + */ + +static void rdc_pata_set_dmamode( + struct ata_port *ap, + struct ata_device *adev + ) +{ + struct pci_dev *pdev; + + uint Channel; + uint DeviceID; + + uint PIOTimingMode; + uint PrefetchPostingEnable; + uint DMATimingMode; + uint UDMAEnable; + + dbgprintf("rdc_pata_set_dmamode\n"); + + pdev = to_pci_dev(ap->host->dev); + + Channel = ap->port_no; + DeviceID = adev->devno; + PIOTimingMode = adev->pio_mode - XFER_PIO_0; // piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3... + DMATimingMode = adev->dma_mode; // UDMA or MDMA + + if (adev->class == ATA_DEV_ATA) + { + PrefetchPostingEnable = TRUE; + } + else + { // ATAPI, CD DVD Rom + PrefetchPostingEnable = FALSE; + } + + if (ap->udma_mask == 0) + { // ata_port dont support udma. depend on hardware spec. + UDMAEnable = FALSE; + } + else + { + UDMAEnable = TRUE; + } + + /*if (ap->mdma_mask == 0) + { + }*/ + + if (Channel == 0) + { + if (DMATimingMode >= XFER_UDMA_0) + { // UDMA + ATAHostAdapter_SetPrimaryPIO( + pdev, + DeviceID, + PIOTimingMode, + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetPrimaryUDMA( + pdev, + DeviceID, + UDMAEnable, + DMATimingMode - XFER_UDMA_0 + ); + dbgprintf("rdc_pata_set_dmamode Channel: %u, DeviceID: %u, UDMA: %u \n", Channel, DeviceID, (uint)(DMATimingMode - XFER_UDMA_0)); + } + else + { // MDMA + ATAHostAdapter_SetPrimaryPIO( + pdev, + DeviceID, + (DMATimingMode - XFER_MW_DMA_0) + PIO2, // MDMA0 = PIO2 + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetPrimaryUDMA( + pdev, + DeviceID, + FALSE,//UDMAEnable, + UDMA0 + ); + dbgprintf("rdc_pata_set_dmamode Channel: %u, DeviceID: %u, MDMA: %u \n", Channel, DeviceID, (uint)(DMATimingMode - XFER_MW_DMA_0)); + } + } + else + { + if (DMATimingMode >= XFER_UDMA_0) + { // UDMA + ATAHostAdapter_SetSecondaryPIO( + pdev, + DeviceID, + PIOTimingMode, + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetSecondaryUDMA( + pdev, + DeviceID, + UDMAEnable, + DMATimingMode - XFER_UDMA_0 + ); + dbgprintf("rdc_pata_set_dmamode Channel: %u, DeviceID: %u, UDMA: %u \n", Channel, DeviceID, (uint)(DMATimingMode - XFER_UDMA_0)); + } + else + { // MDMA + ATAHostAdapter_SetSecondaryPIO( + pdev, + DeviceID, + (DMATimingMode - XFER_MW_DMA_0) + PIO2, // MDMA0 = PIO2 + TRUE,//DMAEnable, + PrefetchPostingEnable + ); + + ATAHostAdapter_SetSecondaryUDMA( + pdev, + DeviceID, + FALSE,//UDMAEnable, + UDMA0 + ); + dbgprintf("rdc_pata_set_dmamode Channel: %u, DeviceID: %u, MDMA: %u \n", Channel, DeviceID, (uint)(DMATimingMode - XFER_MW_DMA_0)); + } + } +} + +// modified PCIDeviceIO code. + +static uint +PCIDeviceIO_ReadPCIConfiguration( + struct pci_dev *pdev, + uint Offset, + uint Length, + void* pBuffer + ) +{ + uint funcresult; + + unchar* pchar; + + uint i; + + funcresult = TRUE; + + pchar = pBuffer; + + for (i = 0; i < Length; i++) + { + pci_read_config_byte(pdev, Offset, pchar); + Offset++; + pchar++; + } + + funcresult = TRUE; + + goto funcexit; +funcexit: + + return funcresult; +} + +static uint +PCIDeviceIO_WritePCIConfiguration( + struct pci_dev *pdev, + uint Offset, + uint Length, + void* pBuffer + ) +{ + uint funcresult; + + unchar* pchar; + + uint i; + + funcresult = TRUE; + + pchar = pBuffer; + + for (i = 0; i < Length; i++) + { + pci_write_config_byte(pdev, Offset, *pchar); + Offset++; + pchar++; + } + + funcresult = TRUE; + + goto funcexit; +funcexit: + + return funcresult; +} + + +// modified ATAHostAdapter code. + +static uint +ATAHostAdapter_SetPrimaryPIO( + struct pci_dev *pdev, + uint DeviceID, + uint PIOTimingMode, + uint DMAEnable, + uint PrefetchPostingEnable + ) +{ + uint funcresult; + + uint result; + + uint ATATimingRegister; + uint Device1TimingRegister; + + funcresult = TRUE; + + ATATimingRegister = 0; + Device1TimingRegister = 0; + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_PrimaryTiming_Size, + &ATATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_Device1Timing_Size, + &Device1TimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable; + + switch(DeviceID) + { + case 0: + { + // mask clear + ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable + | ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable + | ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable + | ATAConfiguration_PrimaryTiming_Device0DMATimingEnable + | ATAConfiguration_PrimaryTiming_Device0RecoveryMode + | ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode + ); + + if (PIOTimingMode > PIO0) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable; + } + + if (PIOTimingMode >= PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable; + } + + if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable; + } + + if (DMAEnable == TRUE + && PIOTimingMode >= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable; + } + + if (PIOTimingMode <= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0; + } + else if (PIOTimingMode == PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1; + } + else if (PIOTimingMode == PIO4) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3; + } + + if (PIOTimingMode <= PIO1) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0; + } + else if (PIOTimingMode == PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1; + } + else if (PIOTimingMode <= PIO4) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2; + } + } + break; + case 1: + { + ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable + | ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable + | ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable + | ATAConfiguration_PrimaryTiming_Device1DMATimingEnable + ); + + if (PIOTimingMode > PIO0) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable; + } + + if (PIOTimingMode >= PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable; + } + + if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable; + } + + if (DMAEnable == TRUE + && PIOTimingMode >= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable; + } + + Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_PrimaryRecoveryMode | ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode); + + if (PIOTimingMode <= PIO2) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0; + } + else if (PIOTimingMode == PIO3) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1; + } + else if (PIOTimingMode == PIO4) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3; + } + + if (PIOTimingMode <= PIO1) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0; + } + else if (PIOTimingMode == PIO2) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1; + } + else if (PIOTimingMode <= PIO4) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2; + } + } + break; + default: + { + funcresult = FALSE; + goto funcexit; + } + break; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_PrimaryTiming_Size, + &ATATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_Device1Timing_Size, + &Device1TimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + goto funcexit; +funcexit: + + return funcresult; +} + +static uint +ATAHostAdapter_SetSecondaryPIO( + struct pci_dev *pdev, + uint DeviceID, + uint PIOTimingMode, + uint DMAEnable, + uint PrefetchPostingEnable + ) +{ + uint funcresult; + + uint result; + + uint ATATimingRegister; + uint Device1TimingRegister; + + funcresult = TRUE; + + ATATimingRegister = 0; + Device1TimingRegister = 0; + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_SecondaryTiming_Size, + &ATATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_Device1Timing_Size, + &Device1TimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable; + + switch(DeviceID) + { + case 0: + { + // mask clear + ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable + | ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable + | ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable + | ATAConfiguration_PrimaryTiming_Device0DMATimingEnable + | ATAConfiguration_PrimaryTiming_Device0RecoveryMode + | ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode + ); + + if (PIOTimingMode > PIO0) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable; + } + + if (PIOTimingMode >= PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable; + } + + if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable; + } + + if (DMAEnable == TRUE + && PIOTimingMode >= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable; + } + + if (PIOTimingMode <= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0; + } + else if (PIOTimingMode == PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1; + } + else if (PIOTimingMode == PIO4) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3; + } + + if (PIOTimingMode <= PIO1) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0; + } + else if (PIOTimingMode == PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1; + } + else if (PIOTimingMode <= PIO4) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2; + } + } + break; + case 1: + { + ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable + | ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable + | ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable + | ATAConfiguration_PrimaryTiming_Device1DMATimingEnable + ); + + if (PIOTimingMode > PIO0) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable; + } + + if (PIOTimingMode >= PIO3) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable; + } + + if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable; + } + + if (DMAEnable == TRUE + && PIOTimingMode >= PIO2) + { + ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable; + } + + Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_SecondaryRecoveryMode | ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode); + + if (PIOTimingMode <= PIO2) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0; + } + else if (PIOTimingMode == PIO3) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1; + } + else if (PIOTimingMode == PIO4) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3; + } + + if (PIOTimingMode <= PIO1) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0; + } + else if (PIOTimingMode == PIO2) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1; + } + else if (PIOTimingMode <= PIO4) + { + Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2; + } + } + break; + default: + { + funcresult = FALSE; + goto funcexit; + } + break; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_SecondaryTiming_Size, + &ATATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_Device1Timing_Size, + &Device1TimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + goto funcexit; +funcexit: + + return funcresult; +} + +static uint +ATAHostAdapter_SetPrimaryUDMA( + struct pci_dev *pdev, + uint DeviceID, + uint UDMAEnable, + uint UDMATimingMode + ) +{ + uint funcresult; + + uint result; + + uint UDMAControlRegister; + uint UDMATimingRegister; + ulong IDEIOConfigurationRegister; + + funcresult = TRUE; + + UDMAControlRegister = 0; + UDMATimingRegister = 0; + IDEIOConfigurationRegister = 0; + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMAControl_Size, + &UDMAControlRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMATiming_Size, + &UDMATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_IDEIOConfiguration_Size, + &IDEIOConfigurationRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + //Rom Code will determine the device cable type and ATA 100. + //IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report; + //IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported; + + switch(DeviceID) + { + case 0: + { + UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable); + if (UDMAEnable == TRUE) + { + UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable; + } + + IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable + | ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable + ); + + if (UDMATimingMode >= UDMA5) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable; + } + else if (UDMATimingMode >= UDMA3) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable; + } + + // if 80 cable report + + UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime); + + if (UDMATimingMode == UDMA0) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0; + } + else if (UDMATimingMode == UDMA1 || UDMATimingMode == UDMA3 || UDMATimingMode == UDMA5) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1; + } + else if (UDMATimingMode == UDMA2 || UDMATimingMode == UDMA4) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2; + } + } + break; + case 1: + { + UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable); + if (UDMAEnable == TRUE) + { + UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable; + } + + IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable + | ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable + ); + + if (UDMATimingMode >= UDMA5) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable; + } + else if (UDMATimingMode >= UDMA3) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable; + } + + // if 80 cable report + + UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime); + + if (UDMATimingMode == UDMA0) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0; + } + else if (UDMATimingMode == UDMA1 || UDMATimingMode == UDMA3 || UDMATimingMode == UDMA5) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1; + } + else if (UDMATimingMode == UDMA2 || UDMATimingMode == UDMA4) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2; + } + } + break; + default: + { + funcresult = FALSE; + goto funcexit; + } + break; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMAControl_Size, + &UDMAControlRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMATiming_Size, + &UDMATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_IDEIOConfiguration_Size, + &IDEIOConfigurationRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + goto funcexit; +funcexit: + + return funcresult; +} + +static uint +ATAHostAdapter_SetSecondaryUDMA( + struct pci_dev *pdev, + uint DeviceID, + uint UDMAEnable, + uint UDMATimingMode + ) +{ + uint funcresult; + + uint result; + + uint UDMAControlRegister; + uint UDMATimingRegister; + ulong IDEIOConfigurationRegister; + + funcresult = TRUE; + + UDMAControlRegister = 0; + UDMATimingRegister = 0; + IDEIOConfigurationRegister = 0; + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMAControl_Size, + &UDMAControlRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMATiming_Size, + &UDMATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_ReadPCIConfiguration( + pdev, + ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_IDEIOConfiguration_Size, + &IDEIOConfigurationRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + //Rom Code will determine the device cable type and ATA 100. + //IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report; + //IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported; + + switch(DeviceID) + { + case 0: + { + UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable); + if (UDMAEnable == TRUE) + { + UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable; + } + + IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable + | ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable + ); + + if (UDMATimingMode >= UDMA5) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable; + } + else if (UDMATimingMode >= UDMA3) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable; + } + + // if 80 cable report + + UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime); + + if (UDMATimingMode == UDMA0) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0; + } + else if (UDMATimingMode == UDMA1 || UDMATimingMode == UDMA3 || UDMATimingMode == UDMA5) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1; + } + else if (UDMATimingMode == UDMA2 || UDMATimingMode == UDMA4) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2; + } + } + break; + case 1: + { + UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable); + if (UDMAEnable == TRUE) + { + UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable; + } + + IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable + | ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable + ); + + if (UDMATimingMode >= UDMA5) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable; + } + else if (UDMATimingMode >= UDMA3) + { + IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable; + } + + // if 80 cable report + + UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime); + + if (UDMATimingMode == UDMA0) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0; + } + else if (UDMATimingMode == UDMA1 || UDMATimingMode == UDMA3 || UDMATimingMode == UDMA5) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1; + } + else if (UDMATimingMode == UDMA2 || UDMATimingMode == UDMA4) + { + UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2; + } + } + break; + default: + { + funcresult = FALSE; + goto funcexit; + } + break; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMAControl_Size, + &UDMAControlRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_UDMATiming_Size, + &UDMATimingRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + result = PCIDeviceIO_WritePCIConfiguration( + pdev, + ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, + ATAConfiguration_ID_IDEIOConfiguration_Size, + &IDEIOConfigurationRegister + ); + if (result == FALSE) + { + funcresult = FALSE; + goto funcexit; + } + + goto funcexit; +funcexit: + + return funcresult; +} diff --git a/drivers/staging/pata_rdc/pata_rdc.h b/drivers/staging/pata_rdc/pata_rdc.h new file mode 100644 index 000000000000..af1d79e104d0 --- /dev/null +++ b/drivers/staging/pata_rdc/pata_rdc.h @@ -0,0 +1,237 @@ +#ifndef pata_rdc_H +#define pata_rdc_H + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +// ATA Configuration Register ID offset address size +#define ATAConfiguration_PCIOffset 0x40 +#define ATAConfiguration_ID_PrimaryTiming 0x00 +#define ATAConfiguration_ID_SecondaryTiming 0x02 +#define ATAConfiguration_ID_Device1Timing 0x04 +#define ATAConfiguration_ID_UDMAControl 0x08 +#define ATAConfiguration_ID_UDMATiming 0x0A +#define ATAConfiguration_ID_IDEIOConfiguration 0x14 + +#define ATAConfiguration_ID_PrimaryTiming_Size 2 +#define ATAConfiguration_ID_SecondaryTiming_Size 2 +#define ATAConfiguration_ID_Device1Timing_Size 1 +#define ATAConfiguration_ID_UDMAControl_Size 1 +#define ATAConfiguration_ID_UDMATiming_Size 2 +#define ATAConfiguration_ID_IDEIOConfiguration_Size 4 + +// ATA Configuration Register bit define +#define ATAConfiguration_PrimaryTiming_Device0FastTimingEnable 0x0001 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable 0x0002 // PIO 3 or greater +#define ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable 0x0004 // PIO 2 or greater +#define ATAConfiguration_PrimaryTiming_Device0DMATimingEnable 0x0008 +#define ATAConfiguration_PrimaryTiming_Device1FastTimingEnable 0x0010 +#define ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable 0x0020 // PIO 3 or greater +#define ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable 0x0040 // PIO 2 or greater +#define ATAConfiguration_PrimaryTiming_Device1DMATimingEnable 0x0080 +#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode 0x0300 +#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0 0x0000 // PIO 0, PIO 2, MDMA 0 +#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1 0x0100 // PIO 3, MDMA 1 +#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_2 0x0200 // X +#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3 0x0300 // PIO 4, MDMA 2 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode 0x3000 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0 0x0000 // PIO 0 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1 0x1000 // PIO 2, MDMA 0 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2 0x2000 // PIO 3, PIO 4, MDMA 1, MDMA 2 +#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_3 0x3000 // X +#define ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable 0x4000 +#define ATAConfiguration_PrimaryTiming_IDEDecodeEnable 0x8000 + +#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode 0x0003 +#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0 0x0000 +#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1 0x0001 +#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_2 0x0002 +#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3 0x0003 +#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode 0x000C +#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0 0x0000 +#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1 0x0004 +#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2 0x0008 +#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_3 0x000C +#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode 0x0030 +#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0 0x0000 +#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1 0x0010 +#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_2 0x0020 +#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3 0x0030 +#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode 0x00C0 +#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0 0x0000 +#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1 0x0040 +#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2 0x0080 +#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_3 0x00C0 + +#define ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable 0x0001 +#define ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable 0x0002 +#define ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable 0x0004 +#define ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable 0x0008 + +#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime 0x0003 +#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0 0x0000 // UDMA 0 +#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1 0x0001 // UDMA 1, UDMA 3, UDMA 5 +#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2 0x0002 // UDMA 2, UDMA 4 +#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_3 0x0003 // X +#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime 0x0030 +#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0 0x0000 // UDMA 0 +#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1 0x0010 // UDMA 1, UDMA 3, UDMA 5 +#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2 0x0020 // UDMA 2, UDMA 4 +#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_3 0x0030 // X +#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime 0x0300 +#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0 0x0000 // UDMA 0 +#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1 0x0100 // UDMA 1, UDMA 3, UDMA 5 +#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2 0x0200 // UDMA 2, UDMA 4 +#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_3 0x0300 // X +#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime 0x3000 +#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0 0x0000 // UDMA 0 +#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1 0x1000 // UDMA 1, UDMA 3, UDMA 5 +#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2 0x2000 // UDMA 2, UDMA 4 +#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_3 0x3000 // X + +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable 0x00000001 // UDMA 3, UDMA 4 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable 0x00000002 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable 0x00000004 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable 0x00000008 +#define ATAConfiguration_IDEIOConfiguration_DeviceCable80Report 0x000000F0 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report 0x00000030 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0Cable80Report 0x00000010 // UDMA 3, UDMA 4, UDMA 5 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1Cable80Report 0x00000020 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report 0x000000C0 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0Cable80Report 0x00000040 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1Cable80Report 0x00000080 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable 0x00001000 // UDMA 5 +#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable 0x00002000 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable 0x00004000 +#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable 0x00008000 +#define ATAConfiguration_IDEIOConfiguration_ATA100IsSupported 0x00F00000 + +enum _PIOTimingMode +{ + PIO0 = 0, + PIO1, + PIO2, // MDMA 0 + PIO3, // MDMA 1 + PIO4 // MDMA 2 +}; + +enum _DMATimingMode +{ + MDMA0 = 0, + MDMA1, + MDMA2 +}; + +enum _UDMATimingMode +{ + UDMA0 = 0, + UDMA1, + UDMA2, + UDMA3, + UDMA4, + UDMA5 +}; + + +enum rdc_controller_ids { + /* controller IDs */ + RDC_17F31011, + RDC_17F31012 +}; + +// callback function for driver + +static int __devinit rdc_init_one( + struct pci_dev *pdev, + const struct pci_device_id *ent + ); + +// callback function for ata_port + +static int rdc_pata_port_start( + struct ata_port *ap + ); + +static void rdc_pata_port_stop( + struct ata_port *ap + ); + +static int rdc_pata_prereset( + struct ata_link *link, + unsigned long deadline + ); + +static int rdc_pata_cable_detect( + struct ata_port *ap + ); + +static void rdc_pata_set_piomode( + struct ata_port *ap, + struct ata_device *adev + ); + +static void rdc_pata_set_dmamode( + struct ata_port *ap, + struct ata_device *adev + ); + +// modified PCIDeviceIO code. + +static uint +PCIDeviceIO_ReadPCIConfiguration( + struct pci_dev *pdev, + uint Offset, + uint Length, + void* pBuffer + ); + +static uint +PCIDeviceIO_WritePCIConfiguration( + struct pci_dev *pdev, + uint Offset, + uint Length, + void* pBuffer + ); + +// modify ATAHostAdapter code + +static uint +ATAHostAdapter_SetPrimaryPIO( + struct pci_dev *pdev, + uint DeviceID, + uint PIOTimingMode, + uint DMAEnable, + uint PrefetchPostingEnable + ); + +static uint +ATAHostAdapter_SetSecondaryPIO( + struct pci_dev *pdev, + uint DeviceID, + uint PIOTimingMode, + uint DMAEnable, + uint PrefetchPostingEnable + ); + +static uint +ATAHostAdapter_SetPrimaryUDMA( + struct pci_dev *pdev, + uint DeviceID, + uint UDMAEnable, + uint UDMATimingMode + ); + +static uint +ATAHostAdapter_SetSecondaryUDMA( + struct pci_dev *pdev, + uint DeviceID, + uint UDMAEnable, + uint UDMATimingMode + ); + +#endif