[libata] Add a bunch of PATA drivers.

The vast majority of drivers and changes are from Alan Cox.  Albert Lee
contributed and maintains pata_pdc2027x.  Adrian Bunk, Andrew Morton,
and Tejun Heo contributed various minor fixes and updates.

Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Jeff Garzik
2006-08-29 18:12:40 -04:00
parent b01e86fee6
commit 669a5db411
43 changed files with 18371 additions and 110 deletions

View File

@@ -145,6 +145,340 @@ config SATA_INTEL_COMBINED
depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
default y
config PATA_ALI
tristate "ALi PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ALi ATA interfaces
found on the many ALi chipsets.
If unsure, say N.
config PATA_AMD
tristate "AMD/NVidia PATA support (Experimental)"
depends on PCI
help
This option enables support for the AMD and NVidia PATA
interfaces found on the chipsets for Athlon/Athlon64.
If unsure, say N.
config PATA_ARTOP
tristate "ARTOP 6210/6260 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for ARTOP PATA controllers.
If unsure, say N.
config PATA_ATIIXP
tristate "ATI PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ATI ATA interfaces
found on the many ATI chipsets.
If unsure, say N.
config PATA_CMD64X
tristate "CMD64x PATA support (Very Experimental)"
depends on PCI&& EXPERIMENTAL
help
This option enables support for the CMD64x series chips
except for the CMD640.
If unsure, say N.
config PATA_CS5520
tristate "CS5510/5520 PATA support"
depends on PCI
help
This option enables support for the Cyrix 5510/5520
companion chip used with the MediaGX/Geode processor family.
If unsure, say N.
config PATA_CS5530
tristate "CS5530 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the Cyrix/NatSemi/AMD CS5530
companion chip used with the MediaGX/Geode processor family.
If unsure, say N.
config PATA_CS5535
tristate "CS5535 PATA support (Experimental)"
depends on PCI && X86 && !X86_64 && EXPERIMENTAL
help
This option enables support for the NatSemi/AMD CS5535
companion chip used with the Geode processor family.
If unsure, say N.
config PATA_CYPRESS
tristate "Cypress CY82C693 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the Cypress/Contaq CY82C693
chipset found in some Alpha systems
If unsure, say N.
config PATA_EFAR
tristate "EFAR SLC90E66 support"
depends on PCI
help
This option enables support for the EFAR SLC90E66
IDE controller found on some older machines.
If unsure, say N.
config ATA_GENERIC
tristate "Generic ATA support"
depends on PCI
help
This option enables support for generic BIOS configured
ATA controllers via the new ATA layer
If unsure, say N.
config PATA_HPT366
tristate "HPT 366/368 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the HPT 366 and 368
PATA controllers via the new ATA layer.
If unsure, say N.
config PATA_HPT37X
tristate "HPT 370/370A/371/372/374/302 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the majority of the later HPT
PATA controllers via the new ATA layer.
If unsure, say N.
config PATA_HPT3X2N
tristate "HPT 372N/302N PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the N variant HPT PATA
controllers via the new ATA layer
If unsure, say N.
config PATA_HPT3X3
tristate "HPT 343/363 PATA support (Experimental)"
depends on PCI
help
This option enables support for the HPT 343/363
PATA controllers via the new ATA layer
If unsure, say N.
config PATA_ISAPNP
tristate "ISA Plug and Play PATA support (Very Experimental)"
depends on EXPERIMENTAL && ISAPNP
help
This option enables support for ISA plug & play ATA
controllers such as those found on old soundcards.
If unsure, say N.
config PATA_IT8172
tristate "IT8172 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ITE 8172 PATA controller
via the new ATA layer.
If unsure, say N.
config PATA_IT821X
tristate "IT821x PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ITE 8211 and 8212
PATA controllers via the new ATA layer, including RAID
mode.
If unsure, say N.
config PATA_LEGACY
tristate "Legacy ISA PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for ISA/VLB bus legacy PATA
ports and allows them to be accessed via the new ATA layer.
If unsure, say N.
config PATA_TRIFLEX
tristate "Compaq Triflex PATA support"
depends on PCI
help
Enable support for the Compaq 'Triflex' IDE controller as found
on many Compaq Pentium-Pro systems, via the new ATA layer.
If unsure, say N.
config PATA_MPIIX
tristate "Intel PATA MPIIX support"
depends on PCI
help
This option enables support for MPIIX PATA support.
If unsure, say N.
config PATA_OLDPIIX
tristate "Intel PATA old PIIX support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for old(?) PIIX PATA support.
If unsure, say N.
config PATA_NETCELL
tristate "NETCELL Revolution RAID support"
depends on PCI
help
This option enables support for the Netcell Revolution RAID
PATA controller.
If unsure, say N.
config PATA_NS87410
tristate "Nat Semi NS87410 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the National Semiconductor
NS87410 PCI-IDE controller.
If unsure, say N.
config PATA_OPTI
tristate "OPTI621/6215 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables full PIO support for the early Opti ATA
controllers found on some old motherboards.
If unsure, say N.
config PATA_OPTIDMA
tristate "OPTI FireStar PATA support (Veyr Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables DMA/PIO support for the later OPTi
controllers found on some old motherboards and in some
latops
If unsure, say N.
config PATA_PCMCIA
tristate "PCMCIA PATA support"
depends on PCMCIA
help
This option enables support for PCMCIA ATA interfaces, including
compact flash card adapters via the new ATA layer.
If unsure, say N.
config PATA_PDC_OLD
tristate "Older Promise PATA controller support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the Promise 20246, 20262, 20263,
20265 and 20267 adapters.
If unsure, say N.
config PATA_QDI
tristate "QDI VLB PATA support"
help
Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
config PATA_RADISYS
tristate "RADISYS 82600 PATA support (Very experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the RADISYS 82600
PATA controllers via the new ATA layer
If unsure, say N.
config PATA_RZ1000
tristate "PC Tech RZ1000 PATA support"
depends on PCI
help
This option enables basic support for the PC Tech RZ1000/1
PATA controllers via the new ATA layer
If unsure, say N.
config PATA_SC1200
tristate "SC1200 PATA support (Raving Lunatic)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the NatSemi/AMD SC1200 SoC
companion chip used with the Geode processor family.
If unsure, say N.
config PATA_SERVERWORKS
tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the Serverworks OSB4/CSB5/CSB6 and
HT1000 PATA controllers, via the new ATA layer.
If unsure, say N.
config PATA_PDC2027X
tristate "Promise PATA 2027x support"
depends on PCI
help
This option enables support for Promise PATA pdc20268 to pdc20277 host adapters.
If unsure, say N.
config PATA_SIL680
tristate "CMD / Silicon Image 680 PATA support"
depends on PCI
help
This option enables support for CMD / Silicon Image 680 PATA.
If unsure, say N.
config PATA_SIS
tristate "SiS PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for SiS PATA controllers
If unsure, say N.
config PATA_VIA
tristate "VIA PATA support"
depends on PCI
help
This option enables support for the VIA PATA interfaces
found on the many VIA chipsets.
If unsure, say N.
config PATA_WINBOND
tristate "Winbond SL82C105 PATA support"
depends on PCI
help
This option enables support for SL82C105 PATA devices found in the
Netwinder and some other systems
If unsure, say N.
endif
endmenu

View File

@@ -17,5 +17,46 @@ obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_MV) += sata_mv.o
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
obj-$(CONFIG_PATA_ALI) += pata_ali.o
obj-$(CONFIG_PATA_AMD) += pata_amd.o
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o
obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
obj-$(CONFIG_PATA_EFAR) += pata_efar.o
obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
obj-$(CONFIG_PATA_IT8172) += pata_it8172.o
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o
obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o
obj-$(CONFIG_PATA_QDI) += pata_qdi.o
obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o
obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o
obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o
obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
obj-$(CONFIG_PATA_VIA) += pata_via.o
obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
obj-$(CONFIG_PATA_SIS) += pata_sis.o
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o

252
drivers/ata/ata_generic.c Normal file
View File

@@ -0,0 +1,252 @@
/*
* ata_generic.c - Generic PATA/SATA controller driver.
* Copyright 2005 Red Hat Inc <alan@redhat.com>, all rights reserved.
*
* Elements from ide/pci/generic.c
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com>
*
* May be copied or modified under the terms of the GNU General Public License
*
* Driver for PCI IDE interfaces implementing the standard bus mastering
* interface functionality. This assumes the BIOS did the drive set up and
* tuning for us. By default we do not grab all IDE class devices as they
* may have other drivers or need fixups to avoid problems. Instead we keep
* a default list of stuff without documentation/driver that appears to
* work.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "ata_generic"
#define DRV_VERSION "0.2.6"
/*
* A generic parallel ATA driver using libata
*/
/**
* generic_pre_reset - probe begin
* @ap: ATA port
*
* Set up cable type and use generic probe init
*/
static int generic_pre_reset(struct ata_port *ap)
{
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
/**
* generic_error_handler - Probe specified port on PATA host controller
* @ap: Port to probe
* @classes:
*
* LOCKING:
* None (inherited from caller).
*/
static void generic_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, generic_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* generic_set_mode - mode setting
* @ap: interface to set up
*
* Use a non standard set_mode function. We don't want to be tuned.
* The BIOS configured everything. Our job is not to fiddle. We
* read the dma enabled bits from the PCI configuration of the device
* and respect them.
*/
static void generic_set_mode(struct ata_port *ap)
{
int dma_enabled = 0;
int i;
/* Bits 5 and 6 indicate if DMA is active on master/slave */
if (ap->ioaddr.bmdma_addr)
dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
/* We do need the right mode information for DMA or PIO
and this comes from the current configuration flags */
if (dma_enabled & (1 << (5 + i))) {
dev->xfer_mode = XFER_MW_DMA_0;
dev->xfer_shift = ATA_SHIFT_MWDMA;
dev->flags &= ~ATA_DFLAG_PIO;
} else {
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
dev->flags |= ATA_DFLAG_PIO;
}
}
}
}
static struct scsi_host_template generic_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations generic_port_ops = {
.set_mode = generic_set_mode,
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.data_xfer = ata_pio_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = generic_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
static int all_generic_ide; /* Set to claim all devices */
/**
* ata_generic_init - attach generic IDE
* @dev: PCI device found
* @id: match entry
*
* Called each time a matching IDE interface is found. We check if the
* interface is one we wish to claim and if so we perform any chip
* specific hacks then let the ATA layer do the heavy lifting.
*/
static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
u16 command;
static struct ata_port_info info = {
.sht = &generic_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x3f,
.port_ops = &generic_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
/* Don't use the generic entry unless instructed to do so */
if (id->driver_data == 1 && all_generic_ide == 0)
return -ENODEV;
/* Devices that need care */
if (dev->vendor == PCI_VENDOR_ID_UMC &&
dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
(!(PCI_FUNC(dev->devfn) & 1)))
return -ENODEV;
if (dev->vendor == PCI_VENDOR_ID_OPTI &&
dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
(!(PCI_FUNC(dev->devfn) & 1)))
return -ENODEV;
/* Don't re-enable devices in generic mode or we will break some
motherboards with disabled and unused IDE controllers */
pci_read_config_word(dev, PCI_COMMAND, &command);
if (!(command & PCI_COMMAND_IO))
return -ENODEV;
if (dev->vendor == PCI_VENDOR_ID_AL)
ata_pci_clear_simplex(dev);
return ata_pci_init_one(dev, port_info, 2);
}
static struct pci_device_id ata_generic[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), },
{ PCI_DEVICE(PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), },
{ PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F), },
{ PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A), },
{ PCI_DEVICE(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF), },
{ PCI_DEVICE(PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561), },
{ PCI_DEVICE(PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558), },
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO), },
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), },
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), },
/* Must come last. If you add entries adjust this table appropriately */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
{ 0, },
};
static struct pci_driver ata_generic_pci_driver = {
.name = DRV_NAME,
.id_table = ata_generic,
.probe = ata_generic_init_one,
.remove = ata_pci_remove_one
};
static int __init ata_generic_init(void)
{
return pci_module_init(&ata_generic_pci_driver);
}
static void __exit ata_generic_exit(void)
{
pci_unregister_driver(&ata_generic_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for generic ATA");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, ata_generic);
MODULE_VERSION(DRV_VERSION);
module_init(ata_generic_init);
module_exit(ata_generic_exit);
module_param(all_generic_ide, int, 0);

File diff suppressed because it is too large Load Diff

679
drivers/ata/pata_ali.c Normal file

File diff suppressed because it is too large Load Diff

707
drivers/ata/pata_amd.c Normal file

File diff suppressed because it is too large Load Diff

518
drivers/ata/pata_artop.c Normal file

File diff suppressed because it is too large Load Diff

306
drivers/ata/pata_atiixp.c Normal file
View File

@@ -0,0 +1,306 @@
/*
* pata_atiixp.c - ATI PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
* Based on
*
* linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004
*
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
* Copyright (C) 2004 Bartlomiej Zolnierkiewicz
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_atiixp"
#define DRV_VERSION "0.4.2"
enum {
ATIIXP_IDE_PIO_TIMING = 0x40,
ATIIXP_IDE_MWDMA_TIMING = 0x44,
ATIIXP_IDE_PIO_CONTROL = 0x48,
ATIIXP_IDE_PIO_MODE = 0x4a,
ATIIXP_IDE_UDMA_CONTROL = 0x54,
ATIIXP_IDE_UDMA_MODE = 0x56
};
static int atiixp_pre_reset(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) {
ata_port_disable(ap);
printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
return 0;
}
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
static void atiixp_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* atiixp_set_pio_timing - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called by both the pio and dma setup functions to set the controller
* timings for PIO transfers. We must load both the mode number and
* timing values into the controller.
*/
static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio)
{
static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 };
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = 2 * ap->port_no + adev->devno;
/* Check this is correct - the order is odd in both drivers */
int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
u16 pio_mode_data, pio_timing_data;
pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
pio_mode_data &= ~(0x7 << (4 * dn));
pio_mode_data |= pio << (4 * dn);
pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
pio_mode_data &= ~(0xFF << timing_shift);
pio_mode_data |= (pio_timings[pio] << timing_shift);
pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
}
/**
* atiixp_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the PIO mode setup. We use a shared helper for this
* as the DMA setup must also adjust the PIO timing information.
*/
static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
atiixp_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0);
}
/**
* atiixp_set_dmamode - set initial DMA mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the DMA mode setup. We use timing tables for most
* modes but must tune an appropriate PIO mode to match.
*/
static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 };
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dma = adev->dma_mode;
int dn = 2 * ap->port_no + adev->devno;
int wanted_pio;
if (adev->dma_mode >= XFER_UDMA_0) {
u16 udma_mode_data;
dma -= XFER_UDMA_0;
pci_read_config_word(pdev, ATIIXP_IDE_UDMA_MODE, &udma_mode_data);
udma_mode_data &= ~(0x7 << (4 * dn));
udma_mode_data |= dma << (4 * dn);
pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data);
} else {
u16 mwdma_timing_data;
/* Check this is correct - the order is odd in both drivers */
int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
dma -= XFER_MW_DMA_0;
pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data);
mwdma_timing_data &= ~(0xFF << timing_shift);
mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data);
}
/*
* We must now look at the PIO mode situation. We may need to
* adjust the PIO mode to keep the timings acceptable
*/
if (adev->dma_mode >= XFER_MW_DMA_2)
wanted_pio = 4;
else if (adev->dma_mode == XFER_MW_DMA_1)
wanted_pio = 3;
else if (adev->dma_mode == XFER_MW_DMA_0)
wanted_pio = 0;
else BUG();
if (adev->pio_mode != wanted_pio)
atiixp_set_pio_timing(ap, adev, wanted_pio);
}
/**
* atiixp_bmdma_start - DMA start callback
* @qc: Command in progress
*
* When DMA begins we need to ensure that the UDMA control
* register for the channel is correctly set.
*/
static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = (2 * ap->port_no) + adev->devno;
u16 tmp16;
pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
if (adev->dma_mode >= XFER_UDMA_0)
tmp16 |= (1 << dn);
else
tmp16 &= ~(1 << dn);
pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
ata_bmdma_start(qc);
}
/**
* atiixp_dma_stop - DMA stop callback
* @qc: Command in progress
*
* DMA has completed. Clear the UDMA flag as the next operations will
* be PIO ones not UDMA data transfer.
*/
static void atiixp_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = (2 * ap->port_no) + qc->dev->devno;
u16 tmp16;
pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
tmp16 &= ~(1 << dn);
pci_write_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
ata_bmdma_stop(qc);
}
static struct scsi_host_template atiixp_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations atiixp_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = atiixp_set_piomode,
.set_dmamode = atiixp_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = atiixp_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = atiixp_bmdma_start,
.bmdma_stop = atiixp_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info = {
.sht = &atiixp_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x06, /* No MWDMA0 support */
.udma_mask = 0x3F,
.port_ops = &atiixp_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
return ata_pci_init_one(dev, port_info, 2);
}
static struct pci_device_id atiixp[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
{ 0, },
};
static struct pci_driver atiixp_pci_driver = {
.name = DRV_NAME,
.id_table = atiixp,
.probe = atiixp_init_one,
.remove = ata_pci_remove_one
};
static int __init atiixp_init(void)
{
return pci_register_driver(&atiixp_pci_driver);
}
static void __exit atiixp_exit(void)
{
pci_unregister_driver(&atiixp_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for ATI IXP200/300/400");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, atiixp);
MODULE_VERSION(DRV_VERSION);
module_init(atiixp_init);
module_exit(atiixp_exit);

505
drivers/ata/pata_cmd64x.c Normal file

File diff suppressed because it is too large Load Diff

336
drivers/ata/pata_cs5520.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* IDE tuning and bus mastering support for the CS5510/CS5520
* chipsets
*
* The CS5510/CS5520 are slightly unusual devices. Unlike the
* typical IDE controllers they do bus mastering with the drive in
* PIO mode and smarter silicon.
*
* The practical upshot of this is that we must always tune the
* drive for the right PIO mode. We must also ignore all the blacklists
* and the drive bus mastering DMA information. Also to confuse matters
* further we can do DMA on PIO only drives.
*
* DMA on the 5510 also requires we disable_hlt() during DMA on early
* revisions.
*
* *** This driver is strictly experimental ***
*
* (c) Copyright Red Hat Inc 2002
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Documentation:
* Not publically available.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_cs5520"
#define DRV_VERSION "0.6.2"
struct pio_clocks
{
int address;
int assert;
int recovery;
};
static const struct pio_clocks cs5520_pio_clocks[]={
{3, 6, 11},
{2, 5, 6},
{1, 4, 3},
{1, 3, 2},
{1, 2, 1}
};
/**
* cs5520_set_timings - program PIO timings
* @ap: ATA port
* @adev: ATA device
*
* Program the PIO mode timings for the controller according to the pio
* clocking table.
*/
static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int slave = adev->devno;
pio -= XFER_PIO_0;
/* Channel command timing */
pci_write_config_byte(pdev, 0x62 + ap->port_no,
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
/* FIXME: should these use address ? */
/* Read command timing */
pci_write_config_byte(pdev, 0x64 + 4*ap->port_no + slave,
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
/* Write command timing */
pci_write_config_byte(pdev, 0x66 + 4*ap->port_no + slave,
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
}
/**
* cs5520_enable_dma - turn on DMA bits
*
* Turn on the DMA bits for this disk. Needed because the BIOS probably
* has not done the work for us. Belongs in the core SATA code.
*/
static void cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev)
{
/* Set the DMA enable/disable flag */
u8 reg = inb(ap->ioaddr.bmdma_addr + 0x02);
reg |= 1<<(adev->devno + 5);
outb(reg, ap->ioaddr.bmdma_addr + 0x02);
}
/**
* cs5520_set_dmamode - program DMA timings
* @ap: ATA port
* @adev: ATA device
*
* Program the DMA mode timings for the controller according to the pio
* clocking table. Note that this device sets the DMA timings to PIO
* mode values. This may seem bizarre but the 5520 architecture talks
* PIO mode to the disk and DMA mode to the controller so the underlying
* transfers are PIO timed.
*/
static void cs5520_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
static const int dma_xlate[3] = { XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 };
cs5520_set_timings(ap, adev, dma_xlate[adev->dma_mode]);
cs5520_enable_dma(ap, adev);
}
/**
* cs5520_set_piomode - program PIO timings
* @ap: ATA port
* @adev: ATA device
*
* Program the PIO mode timings for the controller according to the pio
* clocking table. We know pio_mode will equal dma_mode because of the
* CS5520 architecture. At least once we turned DMA on and wrote a
* mode setter.
*/
static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
cs5520_set_timings(ap, adev, adev->pio_mode);
}
static int cs5520_pre_reset(struct ata_port *ap)
{
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
static void cs5520_error_handler(struct ata_port *ap)
{
return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
static struct scsi_host_template cs5520_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations cs5520_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = cs5520_set_piomode,
.set_dmamode = cs5520_set_dmamode,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = cs5520_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_pio_data_xfer,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop,
};
static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
u8 pcicfg;
static struct ata_probe_ent probe[2];
int ports = 0;
/* IDE port enable bits */
pci_read_config_byte(dev, 0x60, &pcicfg);
/* Check if the ATA ports are enabled */
if ((pcicfg & 3) == 0)
return -ENODEV;
if ((pcicfg & 0x40) == 0) {
printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
}
/* Perform set up for DMA */
if (pci_enable_device_bars(dev, 1<<2)) {
printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
return -ENODEV;
}
pci_set_master(dev);
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
return -ENODEV;
}
if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
return -ENODEV;
}
/* We have to do our own plumbing as the PCI setup for this
chipset is non-standard so we can't punt to the libata code */
INIT_LIST_HEAD(&probe[0].node);
probe[0].dev = pci_dev_to_dev(dev);
probe[0].port_ops = &cs5520_port_ops;
probe[0].sht = &cs5520_sht;
probe[0].pio_mask = 0x1F;
probe[0].mwdma_mask = id->driver_data;
probe[0].irq = 14;
probe[0].irq_flags = 0;
probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
probe[0].n_ports = 1;
probe[0].port[0].cmd_addr = 0x1F0;
probe[0].port[0].ctl_addr = 0x3F6;
probe[0].port[0].altstatus_addr = 0x3F6;
probe[0].port[0].bmdma_addr = pci_resource_start(dev, 2);
/* The secondary lurks at different addresses but is otherwise
the same beastie */
probe[1] = probe[0];
INIT_LIST_HEAD(&probe[1].node);
probe[1].irq = 15;
probe[1].port[0].cmd_addr = 0x170;
probe[1].port[0].ctl_addr = 0x376;
probe[1].port[0].altstatus_addr = 0x376;
probe[1].port[0].bmdma_addr = pci_resource_start(dev, 2) + 8;
/* Let libata fill in the port details */
ata_std_ports(&probe[0].port[0]);
ata_std_ports(&probe[1].port[0]);
/* Now add the ports that are active */
if (pcicfg & 1)
ports += ata_device_add(&probe[0]);
if (pcicfg & 2)
ports += ata_device_add(&probe[1]);
if (ports)
return 0;
return -ENODEV;
}
/**
* cs5520_remove_one - device unload
* @pdev: PCI device being removed
*
* Handle an unplug/unload event for a PCI device. Unload the
* PCI driver but do not use the default handler as we manage
* resources ourself and *MUST NOT* disable the device as it has
* other functions.
*/
static void __devexit cs5520_remove_one(struct pci_dev *pdev)
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev);
ata_host_remove(host);
dev_set_drvdata(dev, NULL);
}
/* For now keep DMA off. We can set it for all but A rev CS5510 once the
core ATA code can handle it */
static struct pci_device_id pata_cs5520[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
{ 0, },
};
static struct pci_driver cs5520_pci_driver = {
.name = DRV_NAME,
.id_table = pata_cs5520,
.probe = cs5520_init_one,
.remove = cs5520_remove_one
};
static int __init cs5520_init(void)
{
return pci_register_driver(&cs5520_pci_driver);
}
static void __exit cs5520_exit(void)
{
pci_unregister_driver(&cs5520_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, pata_cs5520);
MODULE_VERSION(DRV_VERSION);
module_init(cs5520_init);
module_exit(cs5520_exit);

387
drivers/ata/pata_cs5530.c Normal file
View File

@@ -0,0 +1,387 @@
/*
* pata-cs5530.c - CS5530 PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
* based upon cs5530.c by Mark Lord.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Loosely based on the piix & svwks drivers.
*
* Documentation:
* Available from AMD web site.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/dmi.h>
#define DRV_NAME "pata_cs5530"
#define DRV_VERSION "0.6"
/**
* cs5530_set_piomode - PIO setup
* @ap: ATA interface
* @adev: device on the interface
*
* Set our PIO requirements. This is fairly simple on the CS5530
* chips.
*/
static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
static const unsigned int cs5530_pio_timings[2][5] = {
{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010},
{0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}
};
unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
u32 tuning;
int format;
/* Find out which table to use */
tuning = inl(base + 0x04);
format = (tuning & 0x80000000UL) ? 1 : 0;
/* Now load the right timing register */
if (adev->devno)
base += 0x08;
outl(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base);
}
/**
* cs5530_set_dmamode - DMA timing setup
* @ap: ATA interface
* @adev: Device being configured
*
* We cannot mix MWDMA and UDMA without reloading timings each switch
* master to slave. We track the last DMA setup in order to minimise
* reloads.
*/
static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
u32 tuning, timing = 0;
u8 reg;
/* Find out which table to use */
tuning = inl(base + 0x04);
switch(adev->dma_mode) {
case XFER_UDMA_0:
timing = 0x00921250;break;
case XFER_UDMA_1:
timing = 0x00911140;break;
case XFER_UDMA_2:
timing = 0x00911030;break;
case XFER_MW_DMA_0:
timing = 0x00077771;break;
case XFER_MW_DMA_1:
timing = 0x00012121;break;
case XFER_MW_DMA_2:
timing = 0x00002020;break;
default:
BUG();
}
/* Merge in the PIO format bit */
timing |= (tuning & 0x80000000UL);
if (adev->devno == 0) /* Master */
outl(timing, base + 0x04);
else {
if (timing & 0x00100000)
tuning |= 0x00100000; /* UDMA for both */
else
tuning &= ~0x00100000; /* MWDMA for both */
outl(tuning, base + 0x04);
outl(timing, base + 0x0C);
}
/* Set the DMA capable bit in the BMDMA area */
reg = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
reg |= (1 << (5 + adev->devno));
outb(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
/* Remember the last DMA setup we did */
ap->private_data = adev;
}
/**
* cs5530_qc_issue_prot - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
* neccessary. Specifically we have a problem that there is only
* one MWDMA/UDMA bit.
*/
static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
struct ata_device *prev = ap->private_data;
/* See if the DMA settings could be wrong */
if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
/* Maybe, but do the channels match MWDMA/UDMA ? */
if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
(adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
/* Switch the mode bits */
cs5530_set_dmamode(ap, adev);
}
return ata_qc_issue_prot(qc);
}
static int cs5530_pre_reset(struct ata_port *ap)
{
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
static void cs5530_error_handler(struct ata_port *ap)
{
return ata_bmdma_drive_eh(ap, cs5530_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
static struct scsi_host_template cs5530_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations cs5530_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = cs5530_set_piomode,
.set_dmamode = cs5530_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = cs5530_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.qc_prep = ata_qc_prep,
.qc_issue = cs5530_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
static struct dmi_system_id palmax_dmi_table[] = {
{
.ident = "Palmax PD1100",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Cyrix"),
DMI_MATCH(DMI_PRODUCT_NAME, "Caddis"),
},
},
{ }
};
static int cs5530_is_palmax(void)
{
if (dmi_check_system(palmax_dmi_table)) {
printk(KERN_INFO "Palmax PD1100: Disabling DMA on docking port.\n");
return 1;
}
return 0;
}
/**
* cs5530_init_one - Initialise a CS5530
* @dev: PCI device
* @id: Entry in match table
*
* Install a driver for the newly found CS5530 companion chip. Most of
* this is just housekeeping. We have to set the chip up correctly and
* turn off various bits of emulation magic.
*/
static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
int compiler_warning_pointless_fix;
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
static struct ata_port_info info = {
.sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
.port_ops = &cs5530_port_ops
};
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
static struct ata_port_info info_palmax_secondary = {
.sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &cs5530_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
dev = NULL;
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
master_0 = pci_dev_get(dev);
break;
case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
cs5530_0 = pci_dev_get(dev);
break;
}
}
if (!master_0) {
printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER function\n");
goto fail_put;
}
if (!cs5530_0) {
printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY function\n");
goto fail_put;
}
pci_set_master(cs5530_0);
compiler_warning_pointless_fix = pci_set_mwi(cs5530_0);
/*
* Set PCI CacheLineSize to 16-bytes:
* --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530
*
* Note: This value is constant because the 5530 is only a Geode companion
*/
pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04);
/*
* Disable trapping of UDMA register accesses (Win98 hack):
* --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530
*/
pci_write_config_word(cs5530_0, 0xd0, 0x5006);
/*
* Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus:
* The other settings are what is necessary to get the register
* into a sane state for IDE DMA operation.
*/
pci_write_config_byte(master_0, 0x40, 0x1e);
/*
* Set max PCI burst size (16-bytes seems to work best):
* 16bytes: set bit-1 at 0x41 (reg value of 0x16)
* all others: clear bit-1 at 0x41, and do:
* 128bytes: OR 0x00 at 0x41
* 256bytes: OR 0x04 at 0x41
* 512bytes: OR 0x08 at 0x41
* 1024bytes: OR 0x0c at 0x41
*/
pci_write_config_byte(master_0, 0x41, 0x14);
/*
* These settings are necessary to get the chip
* into a sane state for IDE DMA operation.
*/
pci_write_config_byte(master_0, 0x42, 0x00);
pci_write_config_byte(master_0, 0x43, 0xc1);
pci_dev_put(master_0);
pci_dev_put(cs5530_0);
if (cs5530_is_palmax())
port_info[1] = &info_palmax_secondary;
/* Now kick off ATA set up */
return ata_pci_init_one(dev, port_info, 2);
fail_put:
if (master_0)
pci_dev_put(master_0);
if (cs5530_0)
pci_dev_put(cs5530_0);
return -ENODEV;
}
static struct pci_device_id cs5530[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
{ 0, },
};
static struct pci_driver cs5530_pci_driver = {
.name = DRV_NAME,
.id_table = cs5530,
.probe = cs5530_init_one,
.remove = ata_pci_remove_one
};
static int __init cs5530_init(void)
{
return pci_register_driver(&cs5530_pci_driver);
}
static void __exit cs5530_exit(void)
{
pci_unregister_driver(&cs5530_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5530);
MODULE_VERSION(DRV_VERSION);
module_init(cs5530_init);
module_exit(cs5530_exit);

291
drivers/ata/pata_cs5535.c Normal file
View File

@@ -0,0 +1,291 @@
/*
* pata-cs5535.c - CS5535 PATA for new ATA layer
* (C) 2005-2006 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
* based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and
* made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de
* and Alexander Kiausch <alex.kiausch@t-online.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Loosely based on the piix & svwks drivers.
*
* Documentation:
* Available from AMD web site.
* TODO
* Review errata to see if serializing is neccessary
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <asm/msr.h>
#define DRV_NAME "cs5535"
#define DRV_VERSION "0.2.10"
/*
* The Geode (Aka Athlon GX now) uses an internal MSR based
* bus system for control. Demented but there you go.
*/
#define MSR_ATAC_BASE 0x51300000
#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
#define ATAC_RESET (MSR_ATAC_BASE+0x10)
#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
#define ATAC_BM0_CMD_PRIM 0x00
#define ATAC_BM0_STS_PRIM 0x02
#define ATAC_BM0_PRD 0x04
#define CS5535_CABLE_DETECT 0x48
#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 )
/**
* cs5535_pre_reset - detect cable type
* @ap: Port to detect on
*
* Perform cable detection for ATA66 capable cable. Return a libata
* cable type.
*/
static int cs5535_pre_reset(struct ata_port *ap)
{
u8 cable;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
if (cable & 1)
ap->cbl = ATA_CBL_PATA80;
else
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
/**
* cs5535_error_handler - reset/probe
* @ap: Port to reset
*
* Reset and configure a port
*/
static void cs5535_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, cs5535_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* cs5535_set_piomode - PIO setup
* @ap: ATA interface
* @adev: device on the interface
*
* Set our PIO requirements. The CS5535 is pretty clean about all this
*/
static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
static const u16 pio_timings[5] = {
0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
};
static const u16 pio_cmd_timings[5] = {
0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
};
u32 reg, dummy;
struct ata_device *pair = ata_dev_pair(adev);
int mode = adev->pio_mode - XFER_PIO_0;
int cmdmode = mode;
/* Command timing has to be for the lowest of the pair of devices */
if (pair) {
int pairmode = pair->pio_mode - XFER_PIO_0;
cmdmode = min(mode, pairmode);
/* Write the other drive timing register if it changed */
if (cmdmode < pairmode)
wrmsr(ATAC_CH0D0_PIO + 2 * pair->devno,
pio_cmd_timings[cmdmode] << 16 | pio_timings[pairmode], 0);
}
/* Write the drive timing register */
wrmsr(ATAC_CH0D0_PIO + 2 * adev->devno,
pio_cmd_timings[cmdmode] << 16 | pio_timings[mode], 0);
/* Set the PIO "format 1" bit in the DMA timing register */
rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy);
wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg | 0x80000000UL, 0);
}
/**
* cs5535_set_dmamode - DMA timing setup
* @ap: ATA interface
* @adev: Device being configured
*
*/
static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
static const u32 udma_timings[5] = {
0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061
};
static const u32 mwdma_timings[3] = {
0x7F0FFFF3, 0x7F035352, 0x7F024241
};
u32 reg, dummy;
int mode = adev->dma_mode;
rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy);
reg &= 0x80000000UL;
if (mode >= XFER_UDMA_0)
reg |= udma_timings[mode - XFER_UDMA_0];
else
reg |= mwdma_timings[mode - XFER_MW_DMA_0];
wrmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, 0);
}
static struct scsi_host_template cs5535_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations cs5535_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = cs5535_set_piomode,
.set_dmamode = cs5535_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = cs5535_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
/**
* cs5535_init_one - Initialise a CS5530
* @dev: PCI device
* @id: Entry in match table
*
* Install a driver for the newly found CS5530 companion chip. Most of
* this is just housekeeping. We have to set the chip up correctly and
* turn off various bits of emulation magic.
*/
static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info = {
.sht = &cs5535_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x1f,
.port_ops = &cs5535_port_ops
};
struct ata_port_info *ports[1] = { &info };
u32 timings, dummy;
/* Check the BIOS set the initial timing clock. If not set the
timings for PIO0 */
rdmsr(ATAC_CH0D0_PIO, timings, dummy);
if (CS5535_BAD_PIO(timings))
wrmsr(ATAC_CH0D0_PIO, 0xF7F4F7F4UL, 0);
rdmsr(ATAC_CH0D1_PIO, timings, dummy);
if (CS5535_BAD_PIO(timings))
wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
return ata_pci_init_one(dev, ports, 1);
}
static struct pci_device_id cs5535[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, 0x002D), },
{ 0, },
};
static struct pci_driver cs5535_pci_driver = {
.name = DRV_NAME,
.id_table = cs5535,
.probe = cs5535_init_one,
.remove = ata_pci_remove_one
};
static int __init cs5535_init(void)
{
return pci_register_driver(&cs5535_pci_driver);
}
static void __exit cs5535_exit(void)
{
pci_unregister_driver(&cs5535_pci_driver);
}
MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch");
MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5535);
MODULE_VERSION(DRV_VERSION);
module_init(cs5535_init);
module_exit(cs5535_exit);

227
drivers/ata/pata_cypress.c Normal file
View File

@@ -0,0 +1,227 @@
/*
* pata_cypress.c - Cypress PATA for new ATA layer
* (C) 2006 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
* Based heavily on
* linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_cypress"
#define DRV_VERSION "0.1.2"
/* here are the offset definitions for the registers */
enum {
CY82_IDE_CMDREG = 0x04,
CY82_IDE_ADDRSETUP = 0x48,
CY82_IDE_MASTER_IOR = 0x4C,
CY82_IDE_MASTER_IOW = 0x4D,
CY82_IDE_SLAVE_IOR = 0x4E,
CY82_IDE_SLAVE_IOW = 0x4F,
CY82_IDE_MASTER_8BIT = 0x50,
CY82_IDE_SLAVE_8BIT = 0x51,
CY82_INDEX_PORT = 0x22,
CY82_DATA_PORT = 0x23,
CY82_INDEX_CTRLREG1 = 0x01,
CY82_INDEX_CHANNEL0 = 0x30,
CY82_INDEX_CHANNEL1 = 0x31,
CY82_INDEX_TIMEOUT = 0x32
};
static int cy82c693_pre_reset(struct ata_port *ap)
{
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
static void cy82c693_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, cy82c693_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* cy82c693_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the PIO mode setup.
*/
static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct ata_timing t;
const unsigned long T = 1000000 / 33;
short time_16, time_8;
u32 addr;
if (ata_timing_compute(adev, adev->pio_mode, &t, T, 1) < 0) {
printk(KERN_ERR DRV_NAME ": mome computation failed.\n");
return;
}
time_16 = FIT(t.recover, 0, 15) | (FIT(t.active, 0, 15) << 4);
time_8 = FIT(t.act8b, 0, 15) | (FIT(t.rec8b, 0, 15) << 4);
if (adev->devno == 0) {
pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
addr &= ~0x0F; /* Mask bits */
addr |= FIT(t.setup, 0, 15);
pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
pci_write_config_byte(pdev, CY82_IDE_MASTER_IOR, time_16);
pci_write_config_byte(pdev, CY82_IDE_MASTER_IOW, time_16);
pci_write_config_byte(pdev, CY82_IDE_MASTER_8BIT, time_8);
} else {
pci_read_config_dword(pdev, CY82_IDE_ADDRSETUP, &addr);
addr &= ~0xF0; /* Mask bits */
addr |= (FIT(t.setup, 0, 15) << 4);
pci_write_config_dword(pdev, CY82_IDE_ADDRSETUP, addr);
pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOR, time_16);
pci_write_config_byte(pdev, CY82_IDE_SLAVE_IOW, time_16);
pci_write_config_byte(pdev, CY82_IDE_SLAVE_8BIT, time_8);
}
}
/**
* cy82c693_set_dmamode - set initial DMA mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the DMA mode setup.
*/
static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
int reg = CY82_INDEX_CHANNEL0 + ap->port_no;
/* Be afraid, be very afraid. Magic registers in low I/O space */
outb(reg, 0x22);
outb(adev->dma_mode - XFER_MW_DMA_0, 0x23);
/* 0x50 gives the best behaviour on the Alpha's using this chip */
outb(CY82_INDEX_TIMEOUT, 0x22);
outb(0x50, 0x23);
}
static struct scsi_host_template cy82c693_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations cy82c693_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = cy82c693_set_piomode,
.set_dmamode = cy82c693_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = cy82c693_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static struct ata_port_info info = {
.sht = &cy82c693_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cy82c693_port_ops
};
static struct ata_port_info *port_info[1] = { &info };
/* Devfn 1 is the ATA primary. The secondary is magic and on devfn2. For the
moment we don't handle the secondary. FIXME */
if (PCI_FUNC(pdev->devfn) != 1)
return -ENODEV;
return ata_pci_init_one(pdev, port_info, 1);
}
static struct pci_device_id cy82c693[] = {
{ PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
};
static struct pci_driver cy82c693_pci_driver = {
.name = DRV_NAME,
.id_table = cy82c693,
.probe = cy82c693_init_one,
.remove = ata_pci_remove_one
};
static int __init cy82c693_init(void)
{
return pci_register_driver(&cy82c693_pci_driver);
}
static void __exit cy82c693_exit(void)
{
pci_unregister_driver(&cy82c693_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the CY82C693 PATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cy82c693);
MODULE_VERSION(DRV_VERSION);
module_init(cy82c693_init);
module_exit(cy82c693_exit);

342
drivers/ata/pata_efar.c Normal file
View File

@@ -0,0 +1,342 @@
/*
* pata_efar.c - EFAR PIIX clone controller driver
*
* (C) 2005 Red Hat <alan@redhat.com>
*
* Some parts based on ata_piix.c by Jeff Garzik and others.
*
* The EFAR is a PIIX4 clone with UDMA66 support. Unlike the later
* Intel ICH controllers the EFAR widened the UDMA mode register bits
* and doesn't require the funky clock selection.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/ata.h>
#define DRV_NAME "pata_efar"
#define DRV_VERSION "0.4.1"
/**
* efar_pre_reset - check for 40/80 pin
* @ap: Port
*
* Perform cable detection for the EFAR ATA interface. This is
* different to the PIIX arrangement
*/
static int efar_pre_reset(struct ata_port *ap)
{
static const struct pci_bits efar_enable_bits[] = {
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
{ 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */
};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 tmp;
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) {
ata_port_disable(ap);
printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
return 0;
}
pci_read_config_byte(pdev, 0x47, &tmp);
if (tmp & (2 >> ap->port_no))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
/**
* efar_probe_reset - Probe specified port on PATA host controller
* @ap: Port to probe
*
* LOCKING:
* None (inherited from caller).
*/
static void efar_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, efar_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* efar_set_piomode - 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 efar_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned int idetm_port= ap->port_no ? 0x42 : 0x40;
u16 idetm_data;
int control = 0;
/*
* See Intel Document 298600-004 for the timing programing rules
* for PIIX/ICH. The EFAR is a clone so very similar
*/
static const /* ISP RTC */
u8 timings[][2] = { { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
if (pio > 2)
control |= 1; /* TIME1 enable */
if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */
control |= 2; /* IE enable */
/* Intel specifies that the PPE functionality is for disk only */
if (adev->class == ATA_DEV_ATA)
control |= 4; /* PPE enable */
pci_read_config_word(dev, idetm_port, &idetm_data);
/* Enable PPE, IE and TIME as appropriate */
if (adev->devno == 0) {
idetm_data &= 0xCCF0;
idetm_data |= control;
idetm_data |= (timings[pio][0] << 12) |
(timings[pio][1] << 8);
} else {
int shift = 4 * ap->port_no;
u8 slave_data;
idetm_data &= 0xCC0F;
idetm_data |= (control << 4);
/* Slave timing in seperate register */
pci_read_config_byte(dev, 0x44, &slave_data);
slave_data &= 0x0F << shift;
slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << shift;
pci_write_config_byte(dev, 0x44, slave_data);
}
idetm_data |= 0x4000; /* Ensure SITRE is enabled */
pci_write_config_word(dev, idetm_port, idetm_data);
}
/**
* efar_set_dmamode - Initialize host controller PATA DMA timings
* @ap: Port whose timings we are configuring
* @adev: Device to program
*
* Set UDMA/MWDMA mode for device, in host controller PCI config space.
*
* LOCKING:
* None (inherited from caller).
*/
static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *dev = to_pci_dev(ap->host->dev);
u8 master_port = ap->port_no ? 0x42 : 0x40;
u16 master_data;
u8 speed = adev->dma_mode;
int devid = adev->devno + 2 * ap->port_no;
u8 udma_enable;
static const /* ISP RTC */
u8 timings[][2] = { { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
pci_read_config_word(dev, master_port, &master_data);
pci_read_config_byte(dev, 0x48, &udma_enable);
if (speed >= XFER_UDMA_0) {
unsigned int udma = adev->dma_mode - XFER_UDMA_0;
u16 udma_timing;
udma_enable |= (1 << devid);
/* Load the UDMA mode number */
pci_read_config_word(dev, 0x4A, &udma_timing);
udma_timing &= ~(7 << (4 * devid));
udma_timing |= udma << (4 * devid);
pci_write_config_word(dev, 0x4A, udma_timing);
} else {
/*
* MWDMA is driven by the PIO timings. We must also enable
* IORDY unconditionally along with TIME1. PPE has already
* been set when the PIO timing was set.
*/
unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0;
unsigned int control;
u8 slave_data;
const unsigned int needed_pio[3] = {
XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
};
int pio = needed_pio[mwdma] - XFER_PIO_0;
control = 3; /* IORDY|TIME1 */
/* If the drive MWDMA is faster than it can do PIO then
we must force PIO into PIO0 */
if (adev->pio_mode < needed_pio[mwdma])
/* Enable DMA timing only */
control |= 8; /* PIO cycles in PIO0 */
if (adev->devno) { /* Slave */
master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */
master_data |= control << 4;
pci_read_config_byte(dev, 0x44, &slave_data);
slave_data &= (0x0F + 0xE1 * ap->port_no);
/* Load the matching timing */
slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
pci_write_config_byte(dev, 0x44, slave_data);
} else { /* Master */
master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY
and master timing bits */
master_data |= control;
master_data |=
(timings[pio][0] << 12) |
(timings[pio][1] << 8);
}
udma_enable &= ~(1 << devid);
pci_write_config_word(dev, master_port, master_data);
}
pci_write_config_byte(dev, 0x48, udma_enable);
}
static struct scsi_host_template efar_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static const struct ata_port_operations efar_ops = {
.port_disable = ata_port_disable,
.set_piomode = efar_set_piomode,
.set_dmamode = efar_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = efar_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_pio_data_xfer,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop,
};
/**
* efar_init_one - Register EFAR ATA PCI device with kernel services
* @pdev: PCI device to register
* @ent: Entry in efar_pci_tbl matching with @pdev
*
* Called from kernel PCI layer.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*
* RETURNS:
* Zero on success, or -ERRNO value.
*/
static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
static struct ata_port_info info = {
.sht = &efar_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
.udma_mask = 0x0f, /* UDMA 66 */
.port_ops = &efar_ops,
};
static struct ata_port_info *port_info[2] = { &info, &info };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
return ata_pci_init_one(pdev, port_info, 2);
}
static const struct pci_device_id efar_pci_tbl[] = {
{ 0x1055, 0x9130, PCI_ANY_ID, PCI_ANY_ID, },
{ } /* terminate list */
};
static struct pci_driver efar_pci_driver = {
.name = DRV_NAME,
.id_table = efar_pci_tbl,
.probe = efar_init_one,
.remove = ata_pci_remove_one,
};
static int __init efar_init(void)
{
return pci_register_driver(&efar_pci_driver);
}
static void __exit efar_exit(void)
{
pci_unregister_driver(&efar_pci_driver);
}
module_init(efar_init);
module_exit(efar_exit);
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("SCSI low-level driver for EFAR PIIX clones");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, efar_pci_tbl);
MODULE_VERSION(DRV_VERSION);

478
drivers/ata/pata_hpt366.c Normal file
View File

@@ -0,0 +1,478 @@
/*
* Libata driver for the highpoint 366 and 368 UDMA66 ATA controllers.
*
* This driver is heavily based upon:
*
* linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
*
*
* TODO
* Maybe PLL mode
* Look into engine reset on timeout errors. Should not be
* required.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_hpt366"
#define DRV_VERSION "0.5"
struct hpt_clock {
u8 xfer_speed;
u32 timing;
};
/* key for bus clock timings
* bit
* 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
* DMA. cycles = value + 1
* 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW
* DMA. cycles = value + 1
* 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file
* register access.
* 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file
* register access.
* 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer.
* during task file register access.
* 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA
* xfer.
* 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task
* register access.
* 28 UDMA enable
* 29 DMA enable
* 30 PIO_MST enable. if set, the chip is in bus master mode during
* PIO.
* 31 FIFO enable.
*/
static const struct hpt_clock hpt366_40[] = {
{ XFER_UDMA_4, 0x900fd943 },
{ XFER_UDMA_3, 0x900ad943 },
{ XFER_UDMA_2, 0x900bd943 },
{ XFER_UDMA_1, 0x9008d943 },
{ XFER_UDMA_0, 0x9008d943 },
{ XFER_MW_DMA_2, 0xa008d943 },
{ XFER_MW_DMA_1, 0xa010d955 },
{ XFER_MW_DMA_0, 0xa010d9fc },
{ XFER_PIO_4, 0xc008d963 },
{ XFER_PIO_3, 0xc010d974 },
{ XFER_PIO_2, 0xc010d997 },
{ XFER_PIO_1, 0xc010d9c7 },
{ XFER_PIO_0, 0xc018d9d9 },
{ 0, 0x0120d9d9 }
};
static const struct hpt_clock hpt366_33[] = {
{ XFER_UDMA_4, 0x90c9a731 },
{ XFER_UDMA_3, 0x90cfa731 },
{ XFER_UDMA_2, 0x90caa731 },
{ XFER_UDMA_1, 0x90cba731 },
{ XFER_UDMA_0, 0x90c8a731 },
{ XFER_MW_DMA_2, 0xa0c8a731 },
{ XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */
{ XFER_MW_DMA_0, 0xa0c8a797 },
{ XFER_PIO_4, 0xc0c8a731 },
{ XFER_PIO_3, 0xc0c8a742 },
{ XFER_PIO_2, 0xc0d0a753 },
{ XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */
{ XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */
{ 0, 0x0120a7a7 }
};
static const struct hpt_clock hpt366_25[] = {
{ XFER_UDMA_4, 0x90c98521 },
{ XFER_UDMA_3, 0x90cf8521 },
{ XFER_UDMA_2, 0x90cf8521 },
{ XFER_UDMA_1, 0x90cb8521 },
{ XFER_UDMA_0, 0x90cb8521 },
{ XFER_MW_DMA_2, 0xa0ca8521 },
{ XFER_MW_DMA_1, 0xa0ca8532 },
{ XFER_MW_DMA_0, 0xa0ca8575 },
{ XFER_PIO_4, 0xc0ca8521 },
{ XFER_PIO_3, 0xc0ca8532 },
{ XFER_PIO_2, 0xc0ca8542 },
{ XFER_PIO_1, 0xc0d08572 },
{ XFER_PIO_0, 0xc0d08585 },
{ 0, 0x01208585 }
};
static const char *bad_ata33[] = {
"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
"Maxtor 90510D4",
"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
NULL
};
static const char *bad_ata66_4[] = {
"IBM-DTLA-307075",
"IBM-DTLA-307060",
"IBM-DTLA-307045",
"IBM-DTLA-307030",
"IBM-DTLA-307020",
"IBM-DTLA-307015",
"IBM-DTLA-305040",
"IBM-DTLA-305030",
"IBM-DTLA-305020",
"IC35L010AVER07-0",
"IC35L020AVER07-0",
"IC35L030AVER07-0",
"IC35L040AVER07-0",
"IC35L060AVER07-0",
"WDC AC310200R",
NULL
};
static const char *bad_ata66_3[] = {
"WDC AC310200R",
NULL
};
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
{
unsigned char model_num[40];
char *s;
unsigned int len;
int i = 0;
ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
s = &model_num[0];
len = strnlen(s, sizeof(model_num));
/* ATAPI specifies that empty space is blank-filled; remove blanks */
while ((len > 0) && (s[len - 1] == ' ')) {
len--;
s[len] = 0;
}
while(list[i] != NULL) {
if (!strncmp(list[i], s, len)) {
printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
modestr, list[i]);
return 1;
}
i++;
}
return 0;
}
/**
* hpt366_filter - mode selection filter
* @ap: ATA interface
* @adev: ATA device
*
* Block UDMA on devices that cause trouble with this controller.
*/
static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
mask &= ~(0x07 << ATA_SHIFT_UDMA);
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
mask &= ~(0x0F << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(ap, adev, mask);
}
/**
* hpt36x_find_mode - reset the hpt36x bus
* @ap: ATA port
* @speed: transfer mode
*
* Return the 32bit register programming information for this channel
* that matches the speed provided.
*/
static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
{
struct hpt_clock *clocks = ap->host->private_data;
while(clocks->xfer_speed) {
if (clocks->xfer_speed == speed)
return clocks->timing;
clocks++;
}
BUG();
return 0xffffffffU; /* silence compiler warning */
}
static int hpt36x_pre_reset(struct ata_port *ap)
{
u8 ata66;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
pci_read_config_byte(pdev, 0x5A, &ata66);
if (ata66 & (1 << ap->port_no))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
/**
* hpt36x_error_handler - reset the hpt36x bus
* @ap: ATA port to reset
*
* Perform the reset handling for the 366/368
*/
static void hpt36x_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, hpt36x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* hpt366_set_piomode - PIO setup
* @ap: ATA interface
* @adev: device on the interface
*
* Perform PIO mode setup.
*/
static void hpt366_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 addr1, addr2;
u32 reg;
u32 mode;
u8 fast;
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
addr2 = 0x51 + 4 * ap->port_no;
/* Fast interrupt prediction disable, hold off interrupt disable */
pci_read_config_byte(pdev, addr2, &fast);
if (fast & 0x80) {
fast &= ~0x80;
pci_write_config_byte(pdev, addr2, fast);
}
pci_read_config_dword(pdev, addr1, &reg);
mode = hpt36x_find_mode(ap, adev->pio_mode);
mode &= ~0x8000000; /* No FIFO in PIO */
mode &= ~0x30070000; /* Leave config bits alone */
reg &= 0x30070000; /* Strip timing bits */
pci_write_config_dword(pdev, addr1, reg | mode);
}
/**
* hpt366_set_dmamode - DMA timing setup
* @ap: ATA interface
* @adev: Device being configured
*
* Set up the channel for MWDMA or UDMA modes. Much the same as with
* PIO, load the mode number and then set MWDMA or UDMA flag.
*/
static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 addr1, addr2;
u32 reg;
u32 mode;
u8 fast;
addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
addr2 = 0x51 + 4 * ap->port_no;
/* Fast interrupt prediction disable, hold off interrupt disable */
pci_read_config_byte(pdev, addr2, &fast);
if (fast & 0x80) {
fast &= ~0x80;
pci_write_config_byte(pdev, addr2, fast);
}
pci_read_config_dword(pdev, addr1, &reg);
mode = hpt36x_find_mode(ap, adev->dma_mode);
mode |= 0x8000000; /* FIFO in MWDMA or UDMA */
mode &= ~0xC0000000; /* Leave config bits alone */
reg &= 0xC0000000; /* Strip timing bits */
pci_write_config_dword(pdev, addr1, reg | mode);
}
static struct scsi_host_template hpt36x_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
/*
* Configuration for HPT366/68
*/
static struct ata_port_operations hpt366_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = hpt366_set_piomode,
.set_dmamode = hpt366_set_dmamode,
.mode_filter = hpt366_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = hpt36x_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
/**
* hpt36x_init_one - Initialise an HPT366/368
* @dev: PCI device
* @id: Entry in match table
*
* Initialise an HPT36x device. There are some interesting complications
* here. Firstly the chip may report 366 and be one of several variants.
* Secondly all the timings depend on the clock for the chip which we must
* detect and look up
*
* This is the known chip mappings. It may be missing a couple of later
* releases.
*
* Chip version PCI Rev Notes
* HPT366 4 (HPT366) 0 UDMA66
* HPT366 4 (HPT366) 1 UDMA66
* HPT368 4 (HPT366) 2 UDMA66
* HPT37x/30x 4 (HPT366) 3+ Other driver
*
*/
static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info_hpt366 = {
.sht = &hpt36x_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x1f,
.port_ops = &hpt366_port_ops
};
struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366};
u32 class_rev;
u32 reg1;
u8 drive_fast;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
/* May be a later chip in disguise. Check */
/* Newer chips are not in the HPT36x driver. Ignore them */
if (class_rev > 2)
return -ENODEV;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
pci_read_config_byte(dev, 0x51, &drive_fast);
if (drive_fast & 0x80)
pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
pci_read_config_dword(dev, 0x40, &reg1);
/* PCI clocking determines the ATA timing values to use */
/* info_hpt366 is safe against re-entry so we can scribble on it */
switch(reg1 & 0x700) {
case 5:
info_hpt366.private_data = &hpt366_40;
break;
case 9:
info_hpt366.private_data = &hpt366_25;
break;
default:
info_hpt366.private_data = &hpt366_33;
break;
}
/* Now kick off ATA set up */
return ata_pci_init_one(dev, port_info, 2);
}
static struct pci_device_id hpt36x[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
{ 0, },
};
static struct pci_driver hpt36x_pci_driver = {
.name = DRV_NAME,
.id_table = hpt36x,
.probe = hpt36x_init_one,
.remove = ata_pci_remove_one
};
static int __init hpt36x_init(void)
{
return pci_register_driver(&hpt36x_pci_driver);
}
static void __exit hpt36x_exit(void)
{
pci_unregister_driver(&hpt36x_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, hpt36x);
MODULE_VERSION(DRV_VERSION);
module_init(hpt36x_init);
module_exit(hpt36x_exit);

1257
drivers/ata/pata_hpt37x.c Normal file

File diff suppressed because it is too large Load Diff

597
drivers/ata/pata_hpt3x2n.c Normal file

File diff suppressed because it is too large Load Diff

226
drivers/ata/pata_hpt3x3.c Normal file
View File

@@ -0,0 +1,226 @@
/*
* pata_hpt3x3 - HPT3x3 driver
* (c) Copyright 2005-2006 Red Hat
*
* Was pata_hpt34x but the naming was confusing as it supported the
* 343 and 363 so it has been renamed.
*
* Based on:
* linux/drivers/ide/pci/hpt34x.c Version 0.40 Sept 10, 2002
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
*
* May be copied or modified under the terms of the GNU General Public
* License
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x3"
#define DRV_VERSION "0.4.1"
static int hpt3x3_probe_init(struct ata_port *ap)
{
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
/**
* hpt3x3_probe_reset - reset the hpt3x3 bus
* @ap: ATA port to reset
*
* Perform the housekeeping when doing an ATA bus reeset. We just
* need to force the cable type.
*/
static void hpt3x3_error_handler(struct ata_port *ap)
{
return ata_bmdma_drive_eh(ap, hpt3x3_probe_init, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* hpt3x3_set_piomode - PIO setup
* @ap: ATA interface
* @adev: device on the interface
*
* Set our PIO requirements. This is fairly simple on the HPT3x3 as
* all we have to do is clear the MWDMA and UDMA bits then load the
* mode number.
*/
static void hpt3x3_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 r1, r2;
int dn = 2 * ap->port_no + adev->devno;
pci_read_config_dword(pdev, 0x44, &r1);
pci_read_config_dword(pdev, 0x48, &r2);
/* Load the PIO timing number */
r1 &= ~(7 << (3 * dn));
r1 |= (adev->pio_mode - XFER_PIO_0) << (3 * dn);
r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
pci_write_config_dword(pdev, 0x44, r1);
pci_write_config_dword(pdev, 0x48, r2);
}
/**
* hpt3x3_set_dmamode - DMA timing setup
* @ap: ATA interface
* @adev: Device being configured
*
* Set up the channel for MWDMA or UDMA modes. Much the same as with
* PIO, load the mode number and then set MWDMA or UDMA flag.
*/
static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 r1, r2;
int dn = 2 * ap->port_no + adev->devno;
int mode_num = adev->dma_mode & 0x0F;
pci_read_config_dword(pdev, 0x44, &r1);
pci_read_config_dword(pdev, 0x48, &r2);
/* Load the timing number */
r1 &= ~(7 << (3 * dn));
r1 |= (mode_num << (3 * dn));
r2 &= ~(0x11 << dn); /* Clear MWDMA and UDMA bits */
if (adev->dma_mode >= XFER_UDMA_0)
r2 |= 0x01 << dn; /* Ultra mode */
else
r2 |= 0x10 << dn; /* MWDMA */
pci_write_config_dword(pdev, 0x44, r1);
pci_write_config_dword(pdev, 0x48, r2);
}
static struct scsi_host_template hpt3x3_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations hpt3x3_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = hpt3x3_set_piomode,
.set_dmamode = hpt3x3_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = hpt3x3_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
/**
* hpt3x3_init_one - Initialise an HPT343/363
* @dev: PCI device
* @id: Entry in match table
*
* Perform basic initialisation. The chip has a quirk that it won't
* function unless it is at XX00. The old ATA driver touched this up
* but we leave it for pci quirks to do properly.
*/
static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info = {
.sht = &hpt3x3_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
.port_ops = &hpt3x3_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
u16 cmd;
/* Initialize the board */
pci_write_config_word(dev, 0x80, 0x00);
/* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (cmd & PCI_COMMAND_MEMORY)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
else
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
/* Now kick off ATA set up */
return ata_pci_init_one(dev, port_info, 2);
}
static struct pci_device_id hpt3x3[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343), },
{ 0, },
};
static struct pci_driver hpt3x3_pci_driver = {
.name = DRV_NAME,
.id_table = hpt3x3,
.probe = hpt3x3_init_one,
.remove = ata_pci_remove_one
};
static int __init hpt3x3_init(void)
{
return pci_register_driver(&hpt3x3_pci_driver);
}
static void __exit hpt3x3_exit(void)
{
pci_unregister_driver(&hpt3x3_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Highpoint HPT343/363");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, hpt3x3);
MODULE_VERSION(DRV_VERSION);
module_init(hpt3x3_init);
module_exit(hpt3x3_exit);

156
drivers/ata/pata_isapnp.c Normal file
View File

@@ -0,0 +1,156 @@
/*
* pata-isapnp.c - ISA PnP PATA controller driver.
* Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved.
*
* Based in part on ide-pnp.c by Andrey Panin <pazke@donpac.ru>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/isapnp.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/libata.h>
#define DRV_NAME "pata_isapnp"
#define DRV_VERSION "0.1.5"
static struct scsi_host_template isapnp_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations isapnp_port_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
/**
* isapnp_init_one - attach an isapnp interface
* @idev: PnP device
* @dev_id: matching detect line
*
* Register an ISA bus IDE interface. Such interfaces are PIO 0 and
* non shared IRQ.
*/
static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
{
struct ata_probe_ent ae;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
/* FIXME: Should selected polled PIO here not fail */
if (pnp_irq_valid(idev, 0) == 0)
return -ENODEV;
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &idev->dev;
ae.port_ops = &isapnp_port_ops;
ae.sht = &isapnp_sht;
ae.n_ports = 1;
ae.pio_mask = 1; /* ISA so PIO 0 cycles */
ae.irq = pnp_irq(idev, 0);
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS;
ae.port[0].cmd_addr = pnp_port_start(idev, 0);
if (pnp_port_valid(idev, 1) == 0) {
ae.port[0].altstatus_addr = pnp_port_start(idev, 1);
ae.port[0].ctl_addr = pnp_port_start(idev, 1);
ae.port_flags |= ATA_FLAG_SRST;
}
ata_std_ports(&ae.port[0]);
if (ata_device_add(&ae) == 0)
return -ENODEV;
return 0;
}
/**
* isapnp_remove_one - unplug an isapnp interface
* @idev: PnP device
*
* Remove a previously configured PnP ATA port. Called only on module
* unload events as the core does not currently deal with ISAPnP docking.
*/
static void isapnp_remove_one(struct pnp_dev *idev)
{
struct device *dev = &idev->dev;
struct ata_host *host = dev_get_drvdata(dev);
ata_host_remove(host);
dev_set_drvdata(dev, NULL);
}
static struct pnp_device_id isapnp_devices[] = {
/* Generic ESDI/IDE/ATA compatible hard disk controller */
{.id = "PNP0600", .driver_data = 0},
{.id = ""}
};
static struct pnp_driver isapnp_driver = {
.name = DRV_NAME,
.id_table = isapnp_devices,
.probe = isapnp_init_one,
.remove = isapnp_remove_one,
};
static int __init isapnp_init(void)
{
return pnp_register_driver(&isapnp_driver);
}
static void __exit isapnp_exit(void)
{
pnp_unregister_driver(&isapnp_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for ISA PnP ATA");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
module_init(isapnp_init);
module_exit(isapnp_exit);

288
drivers/ata/pata_it8172.c Normal file
View File

@@ -0,0 +1,288 @@
/*
* pata_it8172.c - IT8172 PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
* Based heavily on
*
* BRIEF MODULE DESCRIPTION
* IT8172 IDE controller support
*
* Copyright 2000 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
* stevel@mvista.com or source@mvista.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
* TODO
* Check for errata
* See if we really need to force native mode
* PIO timings (also lacking in original)
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#define DRV_NAME "pata_it8172"
#define DRV_VERSION "0.3.1"
static int it8172_pre_reset(struct ata_port *ap)
{
static const struct pci_bits it8172_enable_bits[] = {
{ 0x00, 0, 0x00, 0x00 },
{ 0x40, 1, 0x00, 0x01 }
};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (ap->port_no && !pci_test_config_bits(pdev, &it8172_enable_bits[ap->port_no])) {
ata_port_disable(ap);
printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
return 0;
}
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
static void it8172_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, it8172_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
* it8172_set_pio_timing - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called by both the pio and dma setup functions to set the controller
* timings for PIO transfers. We must load both the mode number and
* timing values into the controller.
*/
static void it8172_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u16 reg40;
pci_read_config_word(pdev, 0x40, &reg40);
/*
* FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
* are being left at the default values of 8 PCI clocks (242 nsec
* for a 33 MHz clock). These can be safely shortened at higher
* PIO modes. The DIOR/DIOW pulse width and recovery times only
* apply to PIO modes, not to the DMA modes.
*/
/*
* Enable port 0x44. The IT8172G spec is confused; it calls
* this register the "Slave IDE Timing Register", but in fact,
* it controls timing for both master and slave drives.
*/
reg40 |= 0x4000;
if (adev->devno) {
reg40 &= 0xC006;
if (pio > 1)
/* Enable prefetch and IORDY sample-point */
reg40 |= 0x0060;
} else {
reg40 &= 0xC060;
if (pio > 1)
/* Enable prefetch and IORDY sample-point */
reg40 |= 0x0006;
}
/* Write back the enables */
pci_write_config_word(pdev, 0x40, reg40);
}
/**
* it8172_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the PIO mode setup. We use a shared helper for this
* as the DMA setup must also adjust the PIO timing information.
*/
static void it8172_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
it8172_set_pio_timing(ap, adev, adev->pio_mode - XFER_PIO_0);
}
/**
* it8172_set_dmamode - set initial DMA mode data
* @ap: ATA interface
* @adev: ATA device
*
* Called to do the DMA mode setup. We must tune an appropriate PIO
* mode to match.
*/
static void it8172_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int dn = (2 * ap->port_no) + adev->devno;
u8 reg48, reg4a;
int pio;
static const int pio_map[] = { 1, 3, 4};
/*
* Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
* at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
* transfers on some drives, even though both numbers meet the minimum
* ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
* So the faster times are just commented out here. The good news is
* that the slower cycle time has very little affect on transfer
* performance.
*/
pci_read_config_byte(pdev, 0x48, &reg48);
pci_read_config_byte(pdev, 0x4A, &reg4a);
reg4a &= ~(3 << (4 * dn));
if (adev->dma_mode >= XFER_UDMA_0) {
reg48 |= 1 << dn;
#ifdef UDMA_TIMING_SET
reg4a |= ((adev->dma_mode - XFER_UDMA_0) << (4 * dn));
#endif
pio = 4;
} else {
pio = pio_map[adev->dma_mode - XFER_MW_DMA_0];
reg48 &= ~ (1 << dn);
}
pci_write_config_byte(pdev, 0x48, reg48);
pci_write_config_byte(pdev, 0x4A, reg4a);
it8172_set_pio_timing(ap, adev, pio);
}
static struct scsi_host_template it8172_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
.max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
};
static struct ata_port_operations it8172_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = it8172_set_piomode,
.set_dmamode = it8172_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = it8172_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ata_pio_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.port_start = ata_port_start,
.port_stop = ata_port_stop,
.host_stop = ata_host_stop
};
static int it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static struct ata_port_info info = {
.sht = &it8172_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x06, /* No MWDMA0 support */
.udma_mask = 0x7,
.port_ops = &it8172_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
if ((!(PCI_FUNC(dev->devfn) & 1) ||
(!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))))
return -ENODEV; /* IT8172 is more than an IDE controller */
return ata_pci_init_one(dev, port_info, 2);
}
static struct pci_device_id it8172[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G), },
{ 0, },
};
static struct pci_driver it8172_pci_driver = {
.name = DRV_NAME,
.id_table = it8172,
.probe = it8172_init_one,
.remove = ata_pci_remove_one
};
static int __init it8172_init(void)
{
return pci_register_driver(&it8172_pci_driver);
}
static void __exit it8172_exit(void)
{
pci_unregister_driver(&it8172_pci_driver);
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for ITE IT8172");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, it8172);
MODULE_VERSION(DRV_VERSION);
module_init(it8172_init);
module_exit(it8172_exit);

Some files were not shown because too many files have changed in this diff Show More