Commit b96d7157 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://github.com/jgarzik/libata-dev

* 'upstream-linus' of git://github.com/jgarzik/libata-dev: (50 commits)
  pata_efar: fix register naming used in efar_set_piomode()
  pata_rdc: add Power Management support
  ata_piix: unify code for programming PIO and MWDMA timings
  ata_piix: SITRE handling fix
  libata: make ata_sff_data_xfer_noirq() work with 32-bit PIO
  pata_artop: add Power Management support
  pata_sl82c105: add Power Management support
  pata_pdc2027x: add Power Management support
  pata_legacy: use PIO mask defines
  pata_legacy: unify QDI ->set_piomode methods
  libata: remove no longer needed pata_qdi driver
  pata_it8213: fix register naming used in it8213_set_piomode()
  pata_it8213: add UDMA100 and UDMA133 support
  pata_rdc: parallel scanning needs an extra locking
  pata_via: add via_fixup()
  libata: ata_timing_compute() fixup
  pata_scc: add proper cable detection method
  pata_arasan_cf: remove bogus to_platform_device() calls
  pata_atiixp: add proper ->prereset method
  pata_serverworks: add serverworks_fixup()
  ...
parents 138c4ae9 a0da1914
...@@ -820,7 +820,7 @@ config PATA_PLATFORM ...@@ -820,7 +820,7 @@ config PATA_PLATFORM
config PATA_OF_PLATFORM config PATA_OF_PLATFORM
tristate "OpenFirmware platform device PATA support" tristate "OpenFirmware platform device PATA support"
depends on PATA_PLATFORM && PPC_OF depends on PATA_PLATFORM && OF
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems with OpenFirmware devices commonly found on embedded systems with OpenFirmware
...@@ -831,6 +831,7 @@ config PATA_OF_PLATFORM ...@@ -831,6 +831,7 @@ config PATA_OF_PLATFORM
config PATA_QDI config PATA_QDI
tristate "QDI VLB PATA support" tristate "QDI VLB PATA support"
depends on ISA depends on ISA
select PATA_LEGACY
help help
Support for QDI 6500 and 6580 PATA controllers on VESA local bus. Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
......
...@@ -88,7 +88,6 @@ obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o ...@@ -88,7 +88,6 @@ obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
obj-$(CONFIG_PATA_QDI) += pata_qdi.o
obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o
obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o
obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o
......
...@@ -23,6 +23,41 @@ ...@@ -23,6 +23,41 @@
#include <linux/ahci_platform.h> #include <linux/ahci_platform.h>
#include "ahci.h" #include "ahci.h"
enum ahci_type {
AHCI, /* standard platform ahci */
IMX53_AHCI, /* ahci on i.mx53 */
};
static struct platform_device_id ahci_devtype[] = {
{
.name = "ahci",
.driver_data = AHCI,
}, {
.name = "imx53-ahci",
.driver_data = IMX53_AHCI,
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(platform, ahci_devtype);
static const struct ata_port_info ahci_port_info[] = {
/* by features */
[AHCI] = {
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
[IMX53_AHCI] = {
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_pmp_retry_srst_ops,
},
};
static struct scsi_host_template ahci_platform_sht = { static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT("ahci_platform"), AHCI_SHT("ahci_platform"),
}; };
...@@ -31,12 +66,8 @@ static int __init ahci_probe(struct platform_device *pdev) ...@@ -31,12 +66,8 @@ static int __init ahci_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct ahci_platform_data *pdata = dev->platform_data; struct ahci_platform_data *pdata = dev->platform_data;
struct ata_port_info pi = { const struct platform_device_id *id = platform_get_device_id(pdev);
.flags = AHCI_FLAG_COMMON, struct ata_port_info pi = ahci_port_info[id->driver_data];
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
};
const struct ata_port_info *ppi[] = { &pi, NULL }; const struct ata_port_info *ppi[] = { &pi, NULL };
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
struct ata_host *host; struct ata_host *host;
...@@ -177,6 +208,7 @@ static struct platform_driver ahci_driver = { ...@@ -177,6 +208,7 @@ static struct platform_driver ahci_driver = {
.name = "ahci", .name = "ahci",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.id_table = ahci_devtype,
}; };
static int __init ahci_init(void) static int __init ahci_init(void)
......
...@@ -113,6 +113,8 @@ enum { ...@@ -113,6 +113,8 @@ enum {
PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
PIIX_FLAG_PIO16 = (1 << 30), /*support 16bit PIO only*/
PIIX_80C_PRI = (1 << 5) | (1 << 4), PIIX_80C_PRI = (1 << 5) | (1 << 4),
PIIX_80C_SEC = (1 << 7) | (1 << 6), PIIX_80C_SEC = (1 << 7) | (1 << 6),
...@@ -147,6 +149,7 @@ enum piix_controller_ids { ...@@ -147,6 +149,7 @@ enum piix_controller_ids {
ich8m_apple_sata, /* locks up on second port enable */ ich8m_apple_sata, /* locks up on second port enable */
tolapai_sata, tolapai_sata,
piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
ich8_sata_snb,
}; };
struct piix_map_db { struct piix_map_db {
...@@ -177,6 +180,7 @@ static int piix_sidpr_scr_write(struct ata_link *link, ...@@ -177,6 +180,7 @@ static int piix_sidpr_scr_write(struct ata_link *link,
static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
unsigned hints); unsigned hints);
static bool piix_irq_check(struct ata_port *ap); static bool piix_irq_check(struct ata_port *ap);
static int piix_port_start(struct ata_port *ap);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev); static int piix_pci_device_resume(struct pci_dev *pdev);
...@@ -298,21 +302,21 @@ static const struct pci_device_id piix_pci_tbl[] = { ...@@ -298,21 +302,21 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller IDE (PCH) */ /* SATA Controller IDE (PCH) */
{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (CPT) */ /* SATA Controller IDE (CPT) */
{ 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x1c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (CPT) */ /* SATA Controller IDE (CPT) */
{ 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x1c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (CPT) */ /* SATA Controller IDE (CPT) */
{ 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (CPT) */ /* SATA Controller IDE (CPT) */
{ 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (PBG) */ /* SATA Controller IDE (PBG) */
{ 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (PBG) */ /* SATA Controller IDE (PBG) */
{ 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Panther Point) */ /* SATA Controller IDE (Panther Point) */
{ 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Panther Point) */ /* SATA Controller IDE (Panther Point) */
{ 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (Panther Point) */ /* SATA Controller IDE (Panther Point) */
{ 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (Panther Point) */ /* SATA Controller IDE (Panther Point) */
...@@ -338,6 +342,7 @@ static struct scsi_host_template piix_sht = { ...@@ -338,6 +342,7 @@ static struct scsi_host_template piix_sht = {
static struct ata_port_operations piix_sata_ops = { static struct ata_port_operations piix_sata_ops = {
.inherits = &ata_bmdma32_port_ops, .inherits = &ata_bmdma32_port_ops,
.sff_irq_check = piix_irq_check, .sff_irq_check = piix_irq_check,
.port_start = piix_port_start,
}; };
static struct ata_port_operations piix_pata_ops = { static struct ata_port_operations piix_pata_ops = {
...@@ -478,6 +483,7 @@ static const struct piix_map_db *piix_map_db_table[] = { ...@@ -478,6 +483,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
[ich8_2port_sata] = &ich8_2port_map_db, [ich8_2port_sata] = &ich8_2port_map_db,
[ich8m_apple_sata] = &ich8m_apple_map_db, [ich8m_apple_sata] = &ich8m_apple_map_db,
[tolapai_sata] = &tolapai_map_db, [tolapai_sata] = &tolapai_map_db,
[ich8_sata_snb] = &ich8_map_db,
}; };
static struct ata_port_info piix_port_info[] = { static struct ata_port_info piix_port_info[] = {
...@@ -606,6 +612,19 @@ static struct ata_port_info piix_port_info[] = { ...@@ -606,6 +612,19 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_vmw_ops, .port_ops = &piix_vmw_ops,
}, },
/*
* some Sandybridge chipsets have broken 32 mode up to now,
* see https://bugzilla.kernel.org/show_bug.cgi?id=40592
*/
[ich8_sata_snb] =
{
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR | PIIX_FLAG_PIO16,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
}; };
static struct pci_bits piix_enable_bits[] = { static struct pci_bits piix_enable_bits[] = {
...@@ -649,6 +668,14 @@ static const struct ich_laptop ich_laptop[] = { ...@@ -649,6 +668,14 @@ static const struct ich_laptop ich_laptop[] = {
{ 0, } { 0, }
}; };
static int piix_port_start(struct ata_port *ap)
{
if (!(ap->flags & PIIX_FLAG_PIO16))
ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
return ata_bmdma_port_start(ap);
}
/** /**
* ich_pata_cable_detect - Probe host controller cable detect info * ich_pata_cable_detect - Probe host controller cable detect info
* @ap: Port for which cable detect info is desired * @ap: Port for which cable detect info is desired
...@@ -704,22 +731,11 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline) ...@@ -704,22 +731,11 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
static DEFINE_SPINLOCK(piix_lock); static DEFINE_SPINLOCK(piix_lock);
/** static void piix_set_timings(struct ata_port *ap, struct ata_device *adev,
* piix_set_piomode - Initialize host controller PATA PIO timings u8 pio)
* @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 piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ {
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned long flags; unsigned long flags;
unsigned int pio = adev->pio_mode - XFER_PIO_0;
unsigned int is_slave = (adev->devno != 0); unsigned int is_slave = (adev->devno != 0);
unsigned int master_port= ap->port_no ? 0x42 : 0x40; unsigned int master_port= ap->port_no ? 0x42 : 0x40;
unsigned int slave_port = 0x44; unsigned int slave_port = 0x44;
...@@ -744,10 +760,16 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -744,10 +760,16 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
control |= 1; /* TIME1 enable */ control |= 1; /* TIME1 enable */
if (ata_pio_need_iordy(adev)) if (ata_pio_need_iordy(adev))
control |= 2; /* IE enable */ control |= 2; /* IE enable */
/* Intel specifies that the PPE functionality is for disk only */ /* Intel specifies that the PPE functionality is for disk only */
if (adev->class == ATA_DEV_ATA) if (adev->class == ATA_DEV_ATA)
control |= 4; /* PPE enable */ control |= 4; /* PPE enable */
/*
* If the drive MWDMA is faster than it can do PIO then
* we must force PIO into PIO0
*/
if (adev->pio_mode < XFER_PIO_0 + pio)
/* Enable DMA timing only */
control |= 8; /* PIO cycles in PIO0 */
spin_lock_irqsave(&piix_lock, flags); spin_lock_irqsave(&piix_lock, flags);
...@@ -759,8 +781,6 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -759,8 +781,6 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
if (is_slave) { if (is_slave) {
/* clear TIME1|IE1|PPE1|DTE1 */ /* clear TIME1|IE1|PPE1|DTE1 */
master_data &= 0xff0f; master_data &= 0xff0f;
/* Enable SITRE (separate slave timing register) */
master_data |= 0x4000;
/* enable PPE1, IE1 and TIME1 as needed */ /* enable PPE1, IE1 and TIME1 as needed */
master_data |= (control << 4); master_data |= (control << 4);
pci_read_config_byte(dev, slave_port, &slave_data); pci_read_config_byte(dev, slave_port, &slave_data);
...@@ -778,6 +798,9 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -778,6 +798,9 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
(timings[pio][0] << 12) | (timings[pio][0] << 12) |
(timings[pio][1] << 8); (timings[pio][1] << 8);
} }
/* Enable SITRE (separate slave timing register) */
master_data |= 0x4000;
pci_write_config_word(dev, master_port, master_data); pci_write_config_word(dev, master_port, master_data);
if (is_slave) if (is_slave)
pci_write_config_byte(dev, slave_port, slave_data); pci_write_config_byte(dev, slave_port, slave_data);
...@@ -794,6 +817,22 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -794,6 +817,22 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
spin_unlock_irqrestore(&piix_lock, flags); spin_unlock_irqrestore(&piix_lock, flags);
} }
/**
* piix_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
* @adev: Drive in question
*
* Set PIO mode for device, in host controller PCI config space.
*
* LOCKING:
* None (inherited from caller).
*/
static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
piix_set_timings(ap, adev, adev->pio_mode - XFER_PIO_0);
}
/** /**
* do_pata_set_dmamode - Initialize host controller PATA PIO timings * do_pata_set_dmamode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring * @ap: Port whose timings we are configuring
...@@ -810,31 +849,20 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in ...@@ -810,31 +849,20 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
{ {
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned long flags; unsigned long flags;
u8 master_port = ap->port_no ? 0x42 : 0x40;
u16 master_data;
u8 speed = adev->dma_mode; u8 speed = adev->dma_mode;
int devid = adev->devno + 2 * ap->port_no; int devid = adev->devno + 2 * ap->port_no;
u8 udma_enable = 0; u8 udma_enable = 0;
static const /* ISP RTC */
u8 timings[][2] = { { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
spin_lock_irqsave(&piix_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (ap->udma_mask)
pci_read_config_byte(dev, 0x48, &udma_enable);
if (speed >= XFER_UDMA_0) { if (speed >= XFER_UDMA_0) {
unsigned int udma = adev->dma_mode - XFER_UDMA_0; unsigned int udma = speed - XFER_UDMA_0;
u16 udma_timing; u16 udma_timing;
u16 ideconf; u16 ideconf;
int u_clock, u_speed; int u_clock, u_speed;
spin_lock_irqsave(&piix_lock, flags);
pci_read_config_byte(dev, 0x48, &udma_enable);
/* /*
* UDMA is handled by a combination of clock switching and * UDMA is handled by a combination of clock switching and
* selection of dividers * selection of dividers
...@@ -867,56 +895,21 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in ...@@ -867,56 +895,21 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
performance (WR_PingPong_En) */ performance (WR_PingPong_En) */
pci_write_config_word(dev, 0x54, ideconf); pci_write_config_word(dev, 0x54, ideconf);
} }
pci_write_config_byte(dev, 0x48, udma_enable);
spin_unlock_irqrestore(&piix_lock, flags);
} else { } else {
/* /* MWDMA is driven by the PIO timings. */
* MWDMA is driven by the PIO timings. We must also enable unsigned int mwdma = speed - XFER_MW_DMA_0;
* 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] = { const unsigned int needed_pio[3] = {
XFER_PIO_0, XFER_PIO_3, XFER_PIO_4 XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
}; };
int pio = needed_pio[mwdma] - XFER_PIO_0; int pio = needed_pio[mwdma] - XFER_PIO_0;
control = 3; /* IORDY|TIME1 */ /* XFER_PIO_0 is never used currently */
piix_set_timings(ap, adev, pio);
/* 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 &= (ap->port_no ? 0x0f : 0xf0);
/* 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);
}
if (ap->udma_mask)
udma_enable &= ~(1 << devid);
pci_write_config_word(dev, master_port, master_data);
} }
/* Don't scribble on 0x48 if the controller does not support UDMA */
if (ap->udma_mask)
pci_write_config_byte(dev, 0x48, udma_enable);
spin_unlock_irqrestore(&piix_lock, flags);
} }
/** /**
......
...@@ -2938,7 +2938,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, ...@@ -2938,7 +2938,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
if (speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) { if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) {
if (speed <= XFER_PIO_2) if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO]; p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
else if ((speed <= XFER_PIO_4) || else if ((speed <= XFER_PIO_4) ||
......
...@@ -2532,8 +2532,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset, ...@@ -2532,8 +2532,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
return reset(link, classes, deadline); return reset(link, classes, deadline);
} }
static int ata_eh_followup_srst_needed(struct ata_link *link, static int ata_eh_followup_srst_needed(struct ata_link *link, int rc)
int rc, const unsigned int *classes)
{ {
if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link)) if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
return 0; return 0;
...@@ -2726,7 +2725,7 @@ int ata_eh_reset(struct ata_link *link, int classify, ...@@ -2726,7 +2725,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
/* perform follow-up SRST if necessary */ /* perform follow-up SRST if necessary */
if (reset == hardreset && if (reset == hardreset &&
ata_eh_followup_srst_needed(link, rc, classes)) { ata_eh_followup_srst_needed(link, rc)) {
reset = softreset; reset = softreset;
if (!reset) { if (!reset) {
......
...@@ -569,7 +569,7 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, ...@@ -569,7 +569,7 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
/* Transfer trailing byte, if any. */ /* Transfer trailing byte, if any. */
if (unlikely(buflen & 0x01)) { if (unlikely(buflen & 0x01)) {
unsigned char pad[2]; unsigned char pad[2] = { };
/* Point buf to the tail of buffer */ /* Point buf to the tail of buffer */
buf += buflen - 1; buf += buflen - 1;
...@@ -628,7 +628,7 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, ...@@ -628,7 +628,7 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
/* Transfer trailing bytes, if any */ /* Transfer trailing bytes, if any */
if (unlikely(slop)) { if (unlikely(slop)) {
unsigned char pad[4]; unsigned char pad[4] = { };
/* Point buf to the tail of buffer */ /* Point buf to the tail of buffer */
buf += buflen - slop; buf += buflen - slop;
...@@ -678,7 +678,7 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, ...@@ -678,7 +678,7 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
unsigned int consumed; unsigned int consumed;
local_irq_save(flags); local_irq_save(flags);
consumed = ata_sff_data_xfer(dev, buf, buflen, rw); consumed = ata_sff_data_xfer32(dev, buf, buflen, rw);
local_irq_restore(flags); local_irq_restore(flags);
return consumed; return consumed;
...@@ -2507,31 +2507,10 @@ static const struct ata_port_info *ata_sff_find_valid_pi( ...@@ -2507,31 +2507,10 @@ static const struct ata_port_info *ata_sff_find_valid_pi(
return NULL; return NULL;
} }
/** static int ata_pci_init_one(struct pci_dev *pdev,
* ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller const struct ata_port_info * const *ppi,
* @pdev: Controller to be initialized struct scsi_host_template *sht, void *host_priv,
* @ppi: array of port_info, must be enough for two ports int hflags, bool bmdma)
* @sht: scsi_host_template to use when registering the host
* @host_priv: host private_data
* @hflag: host flags
*
* This is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
* IDE taskfile registers and is PIO only.
*
* ASSUMPTION:
* Nobody makes a single channel controller that appears solely as
* the secondary legacy port on PCI.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*
* RETURNS:
* Zero on success, negative on errno-based value on error.
*/
int ata_pci_sff_init_one(struct pci_dev *pdev,
const struct ata_port_info * const *ppi,
struct scsi_host_template *sht, void *host_priv, int hflag)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct ata_port_info *pi; const struct ata_port_info *pi;
...@@ -2553,14 +2532,22 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, ...@@ -2553,14 +2532,22 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
if (rc) if (rc)
goto out; goto out;
/* prepare and activate SFF host */ if (bmdma)
rc = ata_pci_sff_prepare_host(pdev, ppi, &host); /* prepare and activate BMDMA host */
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
else
/* prepare and activate SFF host */
rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc) if (rc)
goto out; goto out;
host->private_data = host_priv; host->private_data = host_priv;
host->flags |= hflag; host->flags |= hflags;
rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); if (bmdma) {
pci_set_master(pdev);
rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
} else
rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
out: out:
if (rc == 0) if (rc == 0)
devres_remove_group(&pdev->dev, NULL); devres_remove_group(&pdev->dev, NULL);
...@@ -2569,6 +2556,35 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, ...@@ -2569,6 +2556,35 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
return rc; return rc;
} }
/**
* ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller
* @pdev: Controller to be initialized
* @ppi: array of port_info, must be enough for two ports
* @sht: scsi_host_template to use when registering the host
* @host_priv: host private_data
* @hflag: host flags
*
* This is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
* IDE taskfile registers and is PIO only.
*
* ASSUMPTION:
* Nobody makes a single channel controller that appears solely as
* the secondary legacy port on PCI.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*
* RETURNS:
* Zero on success, negative on errno-based value on error.
*/
int ata_pci_sff_init_one(struct pci_dev *pdev,
const struct ata_port_info * const *ppi,
struct scsi_host_template *sht, void *host_priv, int hflag)
{
return ata_pci_init_one(pdev, ppi, sht, host_priv, hflag, 0);
}
EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
...@@ -3286,42 +3302,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev, ...@@ -3286,42 +3302,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev,
struct scsi_host_template *sht, void *host_priv, struct scsi_host_template *sht, void *host_priv,
int hflags) int hflags)
{ {
struct device *dev = &pdev->dev; return ata_pci_init_one(pdev, ppi, sht, host_priv, hflags, 1);
const struct ata_port_info *pi;
struct ata_host *host = NULL;
int rc;
DPRINTK("ENTER\n");
pi = ata_sff_find_valid_pi(ppi);
if (!pi) {
dev_err(&pdev->dev, "no valid port_info specified\n");
return -EINVAL;
}
if (!devres_open_group(dev, NULL, GFP_KERNEL))
return -ENOMEM;
rc = pcim_enable_device(pdev);
if (rc)
goto out;
/* prepare and activate BMDMA host */
rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
goto out;
host->private_data = host_priv;
host->flags |= hflags;
pci_set_master(pdev);
rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
out:
if (rc == 0)
devres_remove_group(&pdev->dev, NULL);
else
devres_release_group(&pdev->dev, NULL);
return rc;
} }
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
......
...@@ -56,7 +56,7 @@ static const struct dmi_system_id cable_dmi_table[] = { ...@@ -56,7 +56,7 @@ static const struct dmi_system_id cable_dmi_table[] = {
}, },
}, },
{ {
.ident = "Toshiba Satelite S1800-814", .ident = "Toshiba Satellite S1800-814",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"), DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"),
......
...@@ -922,8 +922,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) ...@@ -922,8 +922,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int arasan_cf_suspend(struct device *dev) static int arasan_cf_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ata_host *host = dev_get_drvdata(dev);
struct ata_host *host = dev_get_drvdata(&pdev->dev);
struct arasan_cf_dev *acdev = host->ports[0]->private_data; struct arasan_cf_dev *acdev = host->ports[0]->private_data;
if (acdev->dma_chan) { if (acdev->dma_chan) {
...@@ -937,8 +936,7 @@ static int arasan_cf_suspend(struct device *dev) ...@@ -937,8 +936,7 @@ static int arasan_cf_suspend(struct device *dev)
static int arasan_cf_resume(struct device *dev) static int arasan_cf_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct ata_host *host = dev_get_drvdata(dev);
struct ata_host *host = dev_get_drvdata(&pdev->dev);
struct arasan_cf_dev *acdev = host->ports[0]->private_data; struct arasan_cf_dev *acdev = host->ports[0]->private_data;
cf_init(acdev); cf_init(acdev);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* pata_artop.c - ARTOP ATA controller driver * pata_artop.c - ARTOP ATA controller driver
* *
* (C) 2006 Red Hat * (C) 2006 Red Hat
* (C) 2007 Bartlomiej Zolnierkiewicz * (C) 2007,2011 Bartlomiej Zolnierkiewicz
* *
* Based in part on drivers/ide/pci/aec62xx.c * Based in part on drivers/ide/pci/aec62xx.c
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <linux/ata.h> #include <linux/ata.h>
#define DRV_NAME "pata_artop" #define DRV_NAME "pata_artop"
#define DRV_VERSION "0.4.5" #define DRV_VERSION "0.4.6"
/* /*
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
...@@ -39,31 +39,15 @@ ...@@ -39,31 +39,15 @@
static int clock = 0; static int clock = 0;
static int artop6210_pre_reset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
const struct pci_bits artop_enable_bits[] = {
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
{ 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */
};
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
return ata_sff_prereset(link, deadline);
}
/** /**
* artop6260_pre_reset - check for 40/80 pin * artop62x0_pre_reset - probe begin
* @link: link * @link: link
* @deadline: deadline jiffies for the operation * @deadline: deadline jiffies for the operation
* *
* The ARTOP hardware reports the cable detect bits in register 0x49.
* Nothing complicated needed here. * Nothing complicated needed here.
*/ */
static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline) static int artop62x0_pre_reset(struct ata_link *link, unsigned long deadline)
{ {
static const struct pci_bits artop_enable_bits[] = { static const struct pci_bits artop_enable_bits[] = {
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
...@@ -73,7 +57,7 @@ static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline) ...@@ -73,7 +57,7 @@ static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline)
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
/* Odd numbered device ids are the units with enable bits (the -R cards) */ /* Odd numbered device ids are the units with enable bits. */
if ((pdev->device & 1) && if ((pdev->device & 1) &&
!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT; return -ENOENT;
...@@ -317,7 +301,7 @@ static struct ata_port_operations artop6210_ops = { ...@@ -317,7 +301,7 @@ static struct ata_port_operations artop6210_ops = {
.cable_detect = ata_cable_40wire, .cable_detect = ata_cable_40wire,
.set_piomode = artop6210_set_piomode, .set_piomode = artop6210_set_piomode,
.set_dmamode = artop6210_set_dmamode, .set_dmamode = artop6210_set_dmamode,
.prereset = artop6210_pre_reset, .prereset = artop62x0_pre_reset,
.qc_defer = artop6210_qc_defer, .qc_defer = artop6210_qc_defer,
}; };
...@@ -326,9 +310,36 @@ static struct ata_port_operations artop6260_ops = { ...@@ -326,9 +310,36 @@ static struct ata_port_operations artop6260_ops = {
.cable_detect = artop6260_cable_detect, .cable_detect = artop6260_cable_detect,
.set_piomode = artop6260_set_piomode, .set_piomode = artop6260_set_piomode,
.set_dmamode = artop6260_set_dmamode, .set_dmamode = artop6260_set_dmamode,
.prereset = artop6260_pre_reset, .prereset = artop62x0_pre_reset,
}; };
static void atp8xx_fixup(struct pci_dev *pdev)
{
if (pdev->device == 0x0005)
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
else if (pdev->device == 0x0008 || pdev->device == 0x0009) {
u8 reg;
/* Mac systems come up with some registers not set as we
will need them */
/* Clear reset & test bits */
pci_read_config_byte(pdev, 0x49, &reg);
pci_write_config_byte(pdev, 0x49, reg & ~0x30);
/* PCI latency must be > 0x80 for burst mode, tweak it
* if required.
*/
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &reg);
if (reg <= 0x80)
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90);
/* Enable IRQ output and burst mode */
pci_read_config_byte(pdev, 0x4a, &reg);
pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
}
}
/** /**
* artop_init_one - Register ARTOP ATA PCI device with kernel services * artop_init_one - Register ARTOP ATA PCI device with kernel services
...@@ -383,42 +394,22 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -383,42 +394,22 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
if (rc) if (rc)
return rc; return rc;
if (id->driver_data == 0) { /* 6210 variant */ if (id->driver_data == 0) /* 6210 variant */
ppi[0] = &info_6210; ppi[0] = &info_6210;
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
}
else if (id->driver_data == 1) /* 6260 */ else if (id->driver_data == 1) /* 6260 */
ppi[0] = &info_626x; ppi[0] = &info_626x;
else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ else if (id->driver_data == 2) { /* 6280 or 6280 + fast */
unsigned long io = pci_resource_start(pdev, 4); unsigned long io = pci_resource_start(pdev, 4);
u8 reg;
ppi[0] = &info_628x; ppi[0] = &info_628x;
if (inb(io) & 0x10) if (inb(io) & 0x10)
ppi[0] = &info_628x_fast; ppi[0] = &info_628x_fast;
/* Mac systems come up with some registers not set as we
will need them */
/* Clear reset & test bits */
pci_read_config_byte(pdev, 0x49, &reg);
pci_write_config_byte(pdev, 0x49, reg & ~ 0x30);
/* PCI latency must be > 0x80 for burst mode, tweak it
* if required.
*/
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &reg);
if (reg <= 0x80)
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90);
/* Enable IRQ output and burst mode */
pci_read_config_byte(pdev, 0x4a, &reg);
pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);
} }
BUG_ON(ppi[0] == NULL); BUG_ON(ppi[0] == NULL);
atp8xx_fixup(pdev);
return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0); return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0);
} }
...@@ -432,11 +423,32 @@ static const struct pci_device_id artop_pci_tbl[] = { ...@@ -432,11 +423,32 @@ static const struct pci_device_id artop_pci_tbl[] = {
{ } /* terminate list */ { } /* terminate list */
}; };
#ifdef CONFIG_PM
static int atp8xx_reinit_one(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
int rc;
rc = ata_pci_device_do_resume(pdev);
if (rc)
return rc;
atp8xx_fixup(pdev);
ata_host_resume(host);
return 0;
}
#endif
static struct pci_driver artop_pci_driver = { static struct pci_driver artop_pci_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = artop_pci_tbl, .id_table = artop_pci_tbl,
.probe = artop_init_one, .probe = artop_init_one,
.remove = ata_pci_remove_one, .remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = atp8xx_reinit_one,
#endif
}; };
static int __init artop_init(void) static int __init artop_init(void)
...@@ -452,9 +464,8 @@ static void __exit artop_exit(void) ...@@ -452,9 +464,8 @@ static void __exit artop_exit(void)
module_init(artop_init); module_init(artop_init);
module_exit(artop_exit); module_exit(artop_exit);
MODULE_AUTHOR("Alan Cox"); MODULE_AUTHOR("Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA"); MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, artop_pci_tbl); MODULE_DEVICE_TABLE(pci, artop_pci_tbl);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
...@@ -414,10 +414,13 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) ...@@ -414,10 +414,13 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
host->private_data = info; host->private_data = info;
return ata_host_activate(host, irq ? gpio_to_irq(irq) : 0, ret = ata_host_activate(host, irq ? gpio_to_irq(irq) : 0,
irq ? ata_sff_interrupt : NULL, irq ? ata_sff_interrupt : NULL,
irq_flags, &pata_at91_sht); irq_flags, &pata_at91_sht);
if (!ret)
return 0;
err_put: err_put:
clk_put(info->mck); clk_put(info->mck);
return ret; return ret;
......
...@@ -48,6 +48,31 @@ static int atiixp_cable_detect(struct ata_port *ap) ...@@ -48,6 +48,31 @@ static int atiixp_cable_detect(struct ata_port *ap)
static DEFINE_SPINLOCK(atiixp_lock); static DEFINE_SPINLOCK(atiixp_lock);
/**
* atiixp_prereset - perform reset handling
* @link: ATA link
* @deadline: deadline jiffies for the operation
*
* Reset sequence checking enable bits to see which ports are
* active.
*/
static int atiixp_prereset(struct ata_link *link, unsigned long deadline)
{
static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
return ata_sff_prereset(link, deadline);
}
/** /**
* atiixp_set_pio_timing - set initial PIO mode data * atiixp_set_pio_timing - set initial PIO mode data
* @ap: ATA interface * @ap: ATA interface
...@@ -221,6 +246,7 @@ static struct ata_port_operations atiixp_port_ops = { ...@@ -221,6 +246,7 @@ static struct ata_port_operations atiixp_port_ops = {
.bmdma_start = atiixp_bmdma_start, .bmdma_start = atiixp_bmdma_start,
.bmdma_stop = atiixp_bmdma_stop, .bmdma_stop = atiixp_bmdma_stop,
.prereset = atiixp_prereset,
.cable_detect = atiixp_cable_detect, .cable_detect = atiixp_cable_detect,
.set_piomode = atiixp_set_piomode, .set_piomode = atiixp_set_piomode,
.set_dmamode = atiixp_set_dmamode, .set_dmamode = atiixp_set_dmamode,
...@@ -235,16 +261,7 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -235,16 +261,7 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA5, .udma_mask = ATA_UDMA5,
.port_ops = &atiixp_port_ops .port_ops = &atiixp_port_ops
}; };
static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
const struct ata_port_info *ppi[] = { &info, &info }; const struct ata_port_info *ppi[] = { &info, &info };
int i;
for (i = 0; i < 2; i++)
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i]))
ppi[i] = &ata_dummy_port_info;
return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL,
ATA_HOST_PARALLEL_SCAN); ATA_HOST_PARALLEL_SCAN);
......
...@@ -82,7 +82,7 @@ static int cmd648_cable_detect(struct ata_port *ap) ...@@ -82,7 +82,7 @@ static int cmd648_cable_detect(struct ata_port *ap)
} }
/** /**
* cmd64x_set_piomode - set PIO and MWDMA timing * cmd64x_set_timing - set PIO and MWDMA timing
* @ap: ATA interface * @ap: ATA interface
* @adev: ATA device * @adev: ATA device
* @mode: mode * @mode: mode
...@@ -288,6 +288,22 @@ static struct ata_port_operations cmd648_port_ops = { ...@@ -288,6 +288,22 @@ static struct ata_port_operations cmd648_port_ops = {
.cable_detect = cmd648_cable_detect, .cable_detect = cmd648_cable_detect,
}; };
static void cmd64x_fixup(struct pci_dev *pdev)
{
u8 mrdmode;
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
mrdmode &= ~0x30; /* IRQ set up */
mrdmode |= 0x02; /* Memory read line enable */
pci_write_config_byte(pdev, MRDMODE, mrdmode);
/* PPC specific fixup copied from old driver */
#ifdef CONFIG_PPC
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
}
static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
static const struct ata_port_info cmd_info[6] = { static const struct ata_port_info cmd_info[6] = {
...@@ -336,7 +352,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -336,7 +352,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
&cmd_info[id->driver_data], &cmd_info[id->driver_data],
NULL NULL
}; };
u8 mrdmode, reg; u8 reg;
int rc; int rc;
struct pci_dev *bridge = pdev->bus->self; struct pci_dev *bridge = pdev->bus->self;
/* mobility split bridges don't report enabled ports correctly */ /* mobility split bridges don't report enabled ports correctly */
...@@ -368,11 +384,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -368,11 +384,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
cntrl_ch0_ok = 0; cntrl_ch0_ok = 0;
} }
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); cmd64x_fixup(pdev);
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
mrdmode &= ~ 0x30; /* IRQ set up */
mrdmode |= 0x02; /* Memory read line enable */
pci_write_config_byte(pdev, MRDMODE, mrdmode);
/* check for enabled ports */ /* check for enabled ports */
pci_read_config_byte(pdev, CNTRL, &reg); pci_read_config_byte(pdev, CNTRL, &reg);
...@@ -388,13 +400,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -388,13 +400,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ppi[1] = &ata_dummy_port_info; ppi[1] = &ata_dummy_port_info;
} }
/* Force PIO 0 here.. */
/* PPC specific fixup copied from old driver */
#ifdef CONFIG_PPC
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
} }
...@@ -402,21 +407,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -402,21 +407,14 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int cmd64x_reinit_one(struct pci_dev *pdev) static int cmd64x_reinit_one(struct pci_dev *pdev)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ata_host *host = dev_get_drvdata(&pdev->dev);
u8 mrdmode;
int rc; int rc;
rc = ata_pci_device_do_resume(pdev); rc = ata_pci_device_do_resume(pdev);
if (rc) if (rc)
return rc; return rc;
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); cmd64x_fixup(pdev);
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
mrdmode &= ~ 0x30; /* IRQ set up */
mrdmode |= 0x02; /* Memory read line enable */
pci_write_config_byte(pdev, MRDMODE, mrdmode);
#ifdef CONFIG_PPC
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
ata_host_resume(host); ata_host_resume(host);
return 0; return 0;
} }
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#include <asm/msr.h> #include <asm/msr.h>
#define DRV_NAME "cs5535" #define DRV_NAME "pata_cs5535"
#define DRV_VERSION "0.2.12" #define DRV_VERSION "0.2.12"
/* /*
...@@ -67,8 +67,6 @@ ...@@ -67,8 +67,6 @@
#define CS5535_CABLE_DETECT 0x48 #define CS5535_CABLE_DETECT 0x48
#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 )
/** /**
* cs5535_cable_detect - detect cable type * cs5535_cable_detect - detect cable type
* @ap: Port to detect on * @ap: Port to detect on
...@@ -188,16 +186,6 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -188,16 +186,6 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
}; };
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_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_bmdma_init_one(dev, ppi, &cs5535_sht, NULL, 0); return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL, 0);
} }
...@@ -230,7 +218,7 @@ static void __exit cs5535_exit(void) ...@@ -230,7 +218,7 @@ static void __exit cs5535_exit(void)
} }
MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch"); MODULE_AUTHOR("Alan Cox, Jens Altmann, Wolfgan Zuleger, Alexander Kiausch");
MODULE_DESCRIPTION("low-level driver for the NS/AMD 5530"); MODULE_DESCRIPTION("low-level driver for the NS/AMD 5535");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5535); MODULE_DEVICE_TABLE(pci, cs5535);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
......
...@@ -73,7 +73,7 @@ static DEFINE_SPINLOCK(efar_lock); ...@@ -73,7 +73,7 @@ static DEFINE_SPINLOCK(efar_lock);
/** /**
* efar_set_piomode - Initialize host controller PATA PIO timings * efar_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring * @ap: Port whose timings we are configuring
* @adev: um * @adev: Device to program
* *
* Set PIO mode for device, in host controller PCI config space. * Set PIO mode for device, in host controller PCI config space.
* *
...@@ -85,9 +85,9 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -85,9 +85,9 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev)
{ {
unsigned int pio = adev->pio_mode - XFER_PIO_0; unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned int idetm_port= ap->port_no ? 0x42 : 0x40; unsigned int master_port = ap->port_no ? 0x42 : 0x40;
unsigned long flags; unsigned long flags;
u16 idetm_data; u16 master_data;
u8 udma_enable; u8 udma_enable;
int control = 0; int control = 0;
...@@ -113,20 +113,20 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -113,20 +113,20 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev)
spin_lock_irqsave(&efar_lock, flags); spin_lock_irqsave(&efar_lock, flags);
pci_read_config_word(dev, idetm_port, &idetm_data); pci_read_config_word(dev, master_port, &master_data);
/* Set PPE, IE, and TIME as appropriate */ /* Set PPE, IE, and TIME as appropriate */
if (adev->devno == 0) { if (adev->devno == 0) {
idetm_data &= 0xCCF0; master_data &= 0xCCF0;
idetm_data |= control; master_data |= control;
idetm_data |= (timings[pio][0] << 12) | master_data |= (timings[pio][0] << 12) |
(timings[pio][1] << 8); (timings[pio][1] << 8);
} else { } else {
int shift = 4 * ap->port_no; int shift = 4 * ap->port_no;
u8 slave_data; u8 slave_data;
idetm_data &= 0xFF0F; master_data &= 0xFF0F;
idetm_data |= (control << 4); master_data |= (control << 4);
/* Slave timing in separate register */ /* Slave timing in separate register */
pci_read_config_byte(dev, 0x44, &slave_data); pci_read_config_byte(dev, 0x44, &slave_data);
...@@ -135,8 +135,8 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -135,8 +135,8 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(dev, 0x44, slave_data); pci_write_config_byte(dev, 0x44, slave_data);
} }
idetm_data |= 0x4000; /* Ensure SITRE is set */ master_data |= 0x4000; /* Ensure SITRE is set */
pci_write_config_word(dev, idetm_port, idetm_data); pci_write_config_word(dev, master_port, master_data);
pci_read_config_byte(dev, 0x48, &udma_enable); pci_read_config_byte(dev, 0x48, &udma_enable);
udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
......
...@@ -111,6 +111,28 @@ static const struct hpt_clock hpt366_25[] = { ...@@ -111,6 +111,28 @@ static const struct hpt_clock hpt366_25[] = {
{ 0, 0x01208585 } { 0, 0x01208585 }
}; };
/**
* hpt36x_find_mode - find the hpt36x timing
* @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_mode) {
if (clocks->xfer_mode == speed)
return clocks->timing;
clocks++;
}
BUG();
return 0xffffffffU; /* silence compiler warning */
}
static const char * const bad_ata33[] = { static const char * const bad_ata33[] = {
"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3",
"Maxtor 90845U3", "Maxtor 90650U2", "Maxtor 90845U3", "Maxtor 90650U2",
...@@ -210,10 +232,9 @@ static int hpt36x_cable_detect(struct ata_port *ap) ...@@ -210,10 +232,9 @@ static int hpt36x_cable_detect(struct ata_port *ap)
static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev,
u8 mode) u8 mode)
{ {
struct hpt_clock *clocks = ap->host->private_data;
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 addr = 0x40 + 4 * adev->devno; u32 addr = 0x40 + 4 * adev->devno;
u32 mask, reg; u32 mask, reg, t;
/* determine timing mask and find matching clock entry */ /* determine timing mask and find matching clock entry */
if (mode < XFER_MW_DMA_0) if (mode < XFER_MW_DMA_0)
...@@ -223,13 +244,7 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, ...@@ -223,13 +244,7 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev,
else else
mask = 0x30070000; mask = 0x30070000;
while (clocks->xfer_mode) { t = hpt36x_find_mode(ap, mode);
if (clocks->xfer_mode == mode)
break;
clocks++;
}
if (!clocks->xfer_mode)
BUG();
/* /*
* Combine new mode bits with old config bits and disable * Combine new mode bits with old config bits and disable
...@@ -237,7 +252,7 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev, ...@@ -237,7 +252,7 @@ static void hpt366_set_mode(struct ata_port *ap, struct ata_device *adev,
* problems handling I/O errors later. * problems handling I/O errors later.
*/ */
pci_read_config_dword(pdev, addr, &reg); pci_read_config_dword(pdev, addr, &reg);
reg = ((reg & ~mask) | (clocks->timing & mask)) & ~0xc0000000; reg = ((reg & ~mask) | (t & mask)) & ~0xc0000000;
pci_write_config_dword(pdev, addr, reg); pci_write_config_dword(pdev, addr, reg);
} }
......
...@@ -76,8 +76,8 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -76,8 +76,8 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
{ {
unsigned int pio = adev->pio_mode - XFER_PIO_0; unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned int idetm_port= ap->port_no ? 0x42 : 0x40; unsigned int master_port = ap->port_no ? 0x42 : 0x40;
u16 idetm_data; u16 master_data;
int control = 0; int control = 0;
/* /*
...@@ -100,19 +100,19 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -100,19 +100,19 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
if (adev->class != ATA_DEV_ATA) if (adev->class != ATA_DEV_ATA)
control |= 4; /* PPE */ control |= 4; /* PPE */
pci_read_config_word(dev, idetm_port, &idetm_data); pci_read_config_word(dev, master_port, &master_data);
/* Set PPE, IE, and TIME as appropriate */ /* Set PPE, IE, and TIME as appropriate */
if (adev->devno == 0) { if (adev->devno == 0) {
idetm_data &= 0xCCF0; master_data &= 0xCCF0;
idetm_data |= control; master_data |= control;
idetm_data |= (timings[pio][0] << 12) | master_data |= (timings[pio][0] << 12) |
(timings[pio][1] << 8); (timings[pio][1] << 8);
} else { } else {
u8 slave_data; u8 slave_data;
idetm_data &= 0xFF0F; master_data &= 0xFF0F;
idetm_data |= (control << 4); master_data |= (control << 4);
/* Slave timing in separate register */ /* Slave timing in separate register */
pci_read_config_byte(dev, 0x44, &slave_data); pci_read_config_byte(dev, 0x44, &slave_data);
...@@ -121,8 +121,8 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev) ...@@ -121,8 +121,8 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(dev, 0x44, slave_data); pci_write_config_byte(dev, 0x44, slave_data);
} }
idetm_data |= 0x4000; /* Ensure SITRE is set */ master_data |= 0x4000; /* Ensure SITRE is set */
pci_write_config_word(dev, idetm_port, idetm_data); pci_write_config_word(dev, master_port, master_data);
} }
/** /**
...@@ -163,7 +163,7 @@ static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev) ...@@ -163,7 +163,7 @@ static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev)
/* Clocks follow the PIIX style */ /* Clocks follow the PIIX style */
u_speed = min(2 - (udma & 1), udma); u_speed = min(2 - (udma & 1), udma);
if (udma == 5) if (udma > 4)
u_clock = 0x1000; /* 100Mhz */ u_clock = 0x1000; /* 100Mhz */
else if (udma > 2) else if (udma > 2)
u_clock = 1; /* 66Mhz */ u_clock = 1; /* 66Mhz */
...@@ -262,7 +262,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en ...@@ -262,7 +262,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA12_ONLY, .mwdma_mask = ATA_MWDMA12_ONLY,
.udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */ .udma_mask = ATA_UDMA6,
.port_ops = &it8213_ops, .port_ops = &it8213_ops,
}; };
/* Current IT8213 stuff is single port */ /* Current IT8213 stuff is single port */
......
...@@ -79,15 +79,6 @@ static int all; ...@@ -79,15 +79,6 @@ static int all;
module_param(all, int, 0444); module_param(all, int, 0444);
MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)"); MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)");
struct legacy_data {
unsigned long timing;
u8 clock[2];
u8 last;
int fast;
struct platform_device *platform_dev;
};
enum controller { enum controller {
BIOS = 0, BIOS = 0,
SNOOP = 1, SNOOP = 1,
...@@ -104,6 +95,14 @@ enum controller { ...@@ -104,6 +95,14 @@ enum controller {
UNKNOWN = -1 UNKNOWN = -1
}; };
struct legacy_data {
unsigned long timing;
u8 clock[2];
u8 last;
int fast;
enum controller type;
struct platform_device *platform_dev;
};
struct legacy_probe { struct legacy_probe {
unsigned char *name; unsigned char *name;
...@@ -137,11 +136,17 @@ static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ ...@@ -137,11 +136,17 @@ static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */
static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */
static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */
static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */
static int qdi; /* Set to probe QDI controllers */
static int autospeed; /* Chip present which snoops speed changes */ static int autospeed; /* Chip present which snoops speed changes */
static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */
static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
/* Set to probe QDI controllers */
#ifdef CONFIG_PATA_QDI_MODULE
static int qdi = 1;
#else
static int qdi;
#endif
#ifdef CONFIG_PATA_WINBOND_VLB_MODULE #ifdef CONFIG_PATA_WINBOND_VLB_MODULE
static int winbond = 1; /* Set to probe Winbond controllers, static int winbond = 1; /* Set to probe Winbond controllers,
give I/O port if non standard */ give I/O port if non standard */
...@@ -631,40 +636,20 @@ static struct ata_port_operations opti82c46x_port_ops = { ...@@ -631,40 +636,20 @@ static struct ata_port_operations opti82c46x_port_ops = {
.qc_issue = opti82c46x_qc_issue, .qc_issue = opti82c46x_qc_issue,
}; };
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing);
}
/** /**
* qdi6580dp_set_piomode - PIO setup for dual channel * qdi65x0_set_piomode - PIO setup for QDI65x0
* @ap: Port * @ap: Port
* @adev: Device * @adev: Device
* *
* In single channel mode the 6580 has one clock per device and we can
* avoid the requirement to clock switch. We also have to load the timing
* into the right clock according to whether we are master or slave.
*
* In dual channel mode the 6580 has one clock per channel and we have * In dual channel mode the 6580 has one clock per channel and we have
* to software clockswitch in qc_issue. * to software clockswitch in qc_issue.
*/ */
static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) static void qdi65x0_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ {
struct ata_timing t; struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data; struct legacy_data *ld_qdi = ap->host->private_data;
...@@ -682,47 +667,15 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -682,47 +667,15 @@ static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
recovery = 15 - clamp_val(t.recover, 0, 15); recovery = 15 - clamp_val(t.recover, 0, 15);
} }
timing = (recovery << 4) | active | 0x08; timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing; ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing + 2 * ap->port_no); if (ld_qdi->type == QDI6580)
/* Clear the FIFO */ outb(timing, ld_qdi->timing + 2 * adev->devno);
if (adev->class != ATA_DEV_ATA) else
outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3); outb(timing, ld_qdi->timing + 2 * ap->port_no);
}
/**
* qdi6580_set_piomode - PIO setup for single channel
* @ap: Port
* @adev: Device
*
* In single channel mode the 6580 has one clock per device and we can
* avoid the requirement to clock switch. We also have to load the timing
* into the right clock according to whether we are master or slave.
*/
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing + 2 * adev->devno);
/* Clear the FIFO */ /* Clear the FIFO */
if (adev->class != ATA_DEV_ATA) if (ld_qdi->type != QDI6500 && adev->class != ATA_DEV_ATA)
outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3); outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
} }
...@@ -789,20 +742,20 @@ static int qdi_port(struct platform_device *dev, ...@@ -789,20 +742,20 @@ static int qdi_port(struct platform_device *dev,
static struct ata_port_operations qdi6500_port_ops = { static struct ata_port_operations qdi6500_port_ops = {
.inherits = &legacy_base_port_ops, .inherits = &legacy_base_port_ops,
.set_piomode = qdi6500_set_piomode, .set_piomode = qdi65x0_set_piomode,
.qc_issue = qdi_qc_issue, .qc_issue = qdi_qc_issue,
.sff_data_xfer = vlb32_data_xfer, .sff_data_xfer = vlb32_data_xfer,
}; };
static struct ata_port_operations qdi6580_port_ops = { static struct ata_port_operations qdi6580_port_ops = {
.inherits = &legacy_base_port_ops, .inherits = &legacy_base_port_ops,
.set_piomode = qdi6580_set_piomode, .set_piomode = qdi65x0_set_piomode,
.sff_data_xfer = vlb32_data_xfer, .sff_data_xfer = vlb32_data_xfer,
}; };
static struct ata_port_operations qdi6580dp_port_ops = { static struct ata_port_operations qdi6580dp_port_ops = {
.inherits = &legacy_base_port_ops, .inherits = &legacy_base_port_ops,
.set_piomode = qdi6580dp_set_piomode, .set_piomode = qdi65x0_set_piomode,
.qc_issue = qdi_qc_issue, .qc_issue = qdi_qc_issue,
.sff_data_xfer = vlb32_data_xfer, .sff_data_xfer = vlb32_data_xfer,
}; };
...@@ -879,29 +832,29 @@ static struct ata_port_operations winbond_port_ops = { ...@@ -879,29 +832,29 @@ static struct ata_port_operations winbond_port_ops = {
}; };
static struct legacy_controller controllers[] = { static struct legacy_controller controllers[] = {
{"BIOS", &legacy_port_ops, 0x1F, {"BIOS", &legacy_port_ops, ATA_PIO4,
ATA_FLAG_NO_IORDY, 0, NULL }, ATA_FLAG_NO_IORDY, 0, NULL },
{"Snooping", &simple_port_ops, 0x1F, {"Snooping", &simple_port_ops, ATA_PIO4,
0, 0, NULL }, 0, 0, NULL },
{"PDC20230", &pdc20230_port_ops, 0x7, {"PDC20230", &pdc20230_port_ops, ATA_PIO2,
ATA_FLAG_NO_IORDY, ATA_FLAG_NO_IORDY,
ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL }, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL },
{"HT6560A", &ht6560a_port_ops, 0x07, {"HT6560A", &ht6560a_port_ops, ATA_PIO2,
ATA_FLAG_NO_IORDY, 0, NULL }, ATA_FLAG_NO_IORDY, 0, NULL },
{"HT6560B", &ht6560b_port_ops, 0x1F, {"HT6560B", &ht6560b_port_ops, ATA_PIO4,
ATA_FLAG_NO_IORDY, 0, NULL }, ATA_FLAG_NO_IORDY, 0, NULL },
{"OPTI82C611A", &opti82c611a_port_ops, 0x0F, {"OPTI82C611A", &opti82c611a_port_ops, ATA_PIO3,
0, 0, NULL }, 0, 0, NULL },
{"OPTI82C46X", &opti82c46x_port_ops, 0x0F, {"OPTI82C46X", &opti82c46x_port_ops, ATA_PIO3,
0, 0, NULL }, 0, 0, NULL },
{"QDI6500", &qdi6500_port_ops, 0x07, {"QDI6500", &qdi6500_port_ops, ATA_PIO2,
ATA_FLAG_NO_IORDY, ATA_FLAG_NO_IORDY,
ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
{"QDI6580", &qdi6580_port_ops, 0x1F, {"QDI6580", &qdi6580_port_ops, ATA_PIO4,
0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
{"QDI6580DP", &qdi6580dp_port_ops, 0x1F, {"QDI6580DP", &qdi6580dp_port_ops, ATA_PIO4,
0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
{"W83759A", &winbond_port_ops, 0x1F, {"W83759A", &winbond_port_ops, ATA_PIO4,
0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,
winbond_port } winbond_port }
}; };
...@@ -1022,6 +975,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) ...@@ -1022,6 +975,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1); ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1);
if (!io_addr || !ctrl_addr) if (!io_addr || !ctrl_addr)
goto fail; goto fail;
ld->type = probe->type;
if (controller->setup) if (controller->setup)
if (controller->setup(pdev, probe, ld) < 0) if (controller->setup(pdev, probe, ld) < 0)
goto fail; goto fail;
...@@ -1306,6 +1260,7 @@ MODULE_AUTHOR("Alan Cox"); ...@@ -1306,6 +1260,7 @@ MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for legacy ATA"); MODULE_DESCRIPTION("low-level driver for legacy ATA");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("pata_qdi");
MODULE_ALIAS("pata_winbond"); MODULE_ALIAS("pata_winbond");
module_param(probe_all, int, 0); module_param(probe_all, int, 0);
......
...@@ -780,7 +780,7 @@ mpc52xx_ata_probe(struct platform_device *op) ...@@ -780,7 +780,7 @@ mpc52xx_ata_probe(struct platform_device *op)
} }
task_irq = bcom_get_task_irq(dmatsk); task_irq = bcom_get_task_irq(dmatsk);
ret = request_irq(task_irq, &mpc52xx_ata_task_irq, IRQF_DISABLED, ret = request_irq(task_irq, &mpc52xx_ata_task_irq, 0,
"ATA task", priv); "ATA task", priv);
if (ret) { if (ret) {
dev_err(&op->dev, "error requesting DMA IRQ\n"); dev_err(&op->dev, "error requesting DMA IRQ\n");
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
...@@ -57,11 +59,11 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev) ...@@ -57,11 +59,11 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev)
prop = of_get_property(dn, "reg-shift", NULL); prop = of_get_property(dn, "reg-shift", NULL);
if (prop) if (prop)
reg_shift = *prop; reg_shift = be32_to_cpup(prop);
prop = of_get_property(dn, "pio-mode", NULL); prop = of_get_property(dn, "pio-mode", NULL);
if (prop) { if (prop) {
pio_mode = *prop; pio_mode = be32_to_cpup(prop);
if (pio_mode > 6) { if (pio_mode > 6) {
dev_err(&ofdev->dev, "invalid pio-mode\n"); dev_err(&ofdev->dev, "invalid pio-mode\n");
return -EINVAL; return -EINVAL;
......
...@@ -63,6 +63,7 @@ enum { ...@@ -63,6 +63,7 @@ enum {
}; };
static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int pdc2027x_reinit_one(struct pci_dev *pdev);
static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline); static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline);
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev); static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev); static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
...@@ -126,6 +127,10 @@ static struct pci_driver pdc2027x_pci_driver = { ...@@ -126,6 +127,10 @@ static struct pci_driver pdc2027x_pci_driver = {
.id_table = pdc2027x_pci_tbl, .id_table = pdc2027x_pci_tbl,
.probe = pdc2027x_init_one, .probe = pdc2027x_init_one,
.remove = ata_pci_remove_one, .remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = pdc2027x_reinit_one,
#endif
}; };
static struct scsi_host_template pdc2027x_sht = { static struct scsi_host_template pdc2027x_sht = {
...@@ -754,6 +759,31 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de ...@@ -754,6 +759,31 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
IRQF_SHARED, &pdc2027x_sht); IRQF_SHARED, &pdc2027x_sht);
} }
#ifdef CONFIG_PM
static int pdc2027x_reinit_one(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
unsigned int board_idx;
int rc;
rc = ata_pci_device_do_resume(pdev);
if (rc)
return rc;
if (pdev->device == PCI_DEVICE_ID_PROMISE_20268 ||
pdev->device == PCI_DEVICE_ID_PROMISE_20270)
board_idx = PDC_UDMA_100;
else
board_idx = PDC_UDMA_133;
if (pdc_hardware_init(host, board_idx))
return -EIO;
ata_host_resume(host);
return 0;
}
#endif
/** /**
* pdc2027x_init - Called after this module is loaded into the kernel. * pdc2027x_init - Called after this module is loaded into the kernel.
*/ */
......
/*
* pata_qdi.c - QDI VLB ATA controllers
* (C) 2006 Red Hat
*
* This driver mostly exists as a proof of concept for non PCI devices under
* libata. While the QDI6580 was 'neat' in 1993 it is no longer terribly
* useful.
*
* Tuning code written from the documentation at
* http://www.ryston.cz/petr/vlb/qd6500.html
* http://www.ryston.cz/petr/vlb/qd6580.html
*
* Probe code based on drivers/ide/legacy/qd65xx.c
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
* Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
#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/platform_device.h>
#define DRV_NAME "pata_qdi"
#define DRV_VERSION "0.3.1"
#define NR_HOST 4 /* Two 6580s */
struct qdi_data {
unsigned long timing;
u8 clock[2];
u8 last;
int fast;
struct platform_device *platform_dev;
};
static struct ata_host *qdi_host[NR_HOST];
static struct qdi_data qdi_data[NR_HOST];
static int nr_qdi_host;
#ifdef MODULE
static int probe_qdi = 1;
#else
static int probe_qdi;
#endif
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct qdi_data *qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
qdi->clock[adev->devno] = timing;
outb(timing, qdi->timing);
}
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct qdi_data *qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
qdi->clock[adev->devno] = timing;
outb(timing, qdi->timing);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
outb(0x5F, (qdi->timing & 0xFFF0) + 3);
}
/**
* qdi_qc_issue - 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.
*/
static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
struct qdi_data *qdi = ap->host->private_data;
if (qdi->clock[adev->devno] != qdi->last) {
if (adev->pio_mode) {
qdi->last = qdi->clock[adev->devno];
outb(qdi->clock[adev->devno], qdi->timing);
}
}
return ata_sff_qc_issue(qc);
}
static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
unsigned int buflen, int rw)
{
if (ata_id_has_dword_io(dev->id)) {
struct ata_port *ap = dev->link->ap;
int slop = buflen & 3;
if (rw == READ)
ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
__le32 pad;
if (rw == READ) {
pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
memcpy(buf + buflen - slop, &pad, slop);
} else {
memcpy(&pad, buf + buflen - slop, slop);
iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
}
buflen += 4 - slop;
}
} else
buflen = ata_sff_data_xfer(dev, buf, buflen, rw);
return buflen;
}
static struct scsi_host_template qdi_sht = {
ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations qdi6500_port_ops = {
.inherits = &ata_sff_port_ops,
.qc_issue = qdi_qc_issue,
.sff_data_xfer = qdi_data_xfer,
.cable_detect = ata_cable_40wire,
.set_piomode = qdi6500_set_piomode,
};
static struct ata_port_operations qdi6580_port_ops = {
.inherits = &qdi6500_port_ops,
.set_piomode = qdi6580_set_piomode,
};
/**
* qdi_init_one - attach a qdi interface
* @type: Type to display
* @io: I/O port start
* @irq: interrupt line
* @fast: True if on a > 33Mhz VLB
*
* Register an ISA bus IDE interface. Such interfaces are PIO and we
* assume do not support IRQ sharing.
*/
static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
{
unsigned long ctl = io + 0x206;
struct platform_device *pdev;
struct ata_host *host;
struct ata_port *ap;
void __iomem *io_addr, *ctl_addr;
int ret;
/*
* Fill in a probe structure first of all
*/
pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
ret = -ENOMEM;
io_addr = devm_ioport_map(&pdev->dev, io, 8);
ctl_addr = devm_ioport_map(&pdev->dev, ctl, 1);
if (!io_addr || !ctl_addr)
goto fail;
ret = -ENOMEM;
host = ata_host_alloc(&pdev->dev, 1);
if (!host)
goto fail;
ap = host->ports[0];
if (type == 6580) {
ap->ops = &qdi6580_port_ops;
ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
} else {
ap->ops = &qdi6500_port_ops;
ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */
ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
}
ap->ioaddr.cmd_addr = io_addr;
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
ata_sff_std_ports(&ap->ioaddr);
ata_port_desc(ap, "cmd %lx ctl %lx", io, ctl);
/*
* Hook in a private data structure per channel
*/
ap->private_data = &qdi_data[nr_qdi_host];
qdi_data[nr_qdi_host].timing = port;
qdi_data[nr_qdi_host].fast = fast;
qdi_data[nr_qdi_host].platform_dev = pdev;
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
/* activate */
ret = ata_host_activate(host, irq, ata_sff_interrupt, 0, &qdi_sht);
if (ret)
goto fail;
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
return 0;
fail:
platform_device_unregister(pdev);
return ret;
}
/**
* qdi_init - attach qdi interfaces
*
* Attach qdi IDE interfaces by scanning the ports it may occupy.
*/
static __init int qdi_init(void)
{
unsigned long flags;
static const unsigned long qd_port[2] = { 0x30, 0xB0 };
static const unsigned long ide_port[2] = { 0x170, 0x1F0 };
static const int ide_irq[2] = { 14, 15 };
int ct = 0;
int i;
if (probe_qdi == 0)
return -ENODEV;
/*
* Check each possible QD65xx base address
*/
for (i = 0; i < 2; i++) {
unsigned long port = qd_port[i];
u8 r, res;
if (request_region(port, 2, "pata_qdi")) {
/* Check for a card */
local_irq_save(flags);
r = inb_p(port);
outb_p(0x19, port);
res = inb_p(port);
outb_p(r, port);
local_irq_restore(flags);
/* Fail */
if (res == 0x19)
{
release_region(port, 2);
continue;
}
/* Passes the presence test */
r = inb_p(port + 1); /* Check port agrees with port set */
if ((r & 2) >> 1 != i) {
release_region(port, 2);
continue;
}
/* Check card type */
if ((r & 0xF0) == 0xC0) {
/* QD6500: single channel */
if (r & 8) {
/* Disabled ? */
release_region(port, 2);
continue;
}
if (qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04) == 0)
ct++;
}
if (((r & 0xF0) == 0xA0) || (r & 0xF0) == 0x50) {
/* QD6580: dual channel */
if (!request_region(port + 2 , 2, "pata_qdi"))
{
release_region(port, 2);
continue;
}
res = inb(port + 3);
if (res & 1) {
/* Single channel mode */
if (qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04) == 0)
ct++;
} else {
/* Dual channel mode */
if (qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04) == 0)
ct++;
if (qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04) == 0)
ct++;
}
}
}
}
if (ct != 0)
return 0;
return -ENODEV;
}
static __exit void qdi_exit(void)
{
int i;
for (i = 0; i < nr_qdi_host; i++) {
ata_host_detach(qdi_host[i]);
/* Free the control resource. The 6580 dual channel has the resources
* claimed as a pair of 2 byte resources so we need no special cases...
*/
release_region(qdi_data[i].timing, 2);
platform_device_unregister(qdi_data[i].platform_dev);
}
}
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for qdi ATA");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
module_init(qdi_init);
module_exit(qdi_exit);
module_param(probe_qdi, int, 0);
...@@ -86,6 +86,8 @@ static int rdc_pata_prereset(struct ata_link *link, unsigned long deadline) ...@@ -86,6 +86,8 @@ static int rdc_pata_prereset(struct ata_link *link, unsigned long deadline)
return ata_sff_prereset(link, deadline); return ata_sff_prereset(link, deadline);
} }
static DEFINE_SPINLOCK(rdc_lock);
/** /**
* rdc_set_piomode - Initialize host controller PATA PIO timings * rdc_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring * @ap: Port whose timings we are configuring
...@@ -101,6 +103,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -101,6 +103,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ {
unsigned int pio = adev->pio_mode - XFER_PIO_0; unsigned int pio = adev->pio_mode - XFER_PIO_0;
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned long flags;
unsigned int is_slave = (adev->devno != 0); unsigned int is_slave = (adev->devno != 0);
unsigned int master_port= ap->port_no ? 0x42 : 0x40; unsigned int master_port= ap->port_no ? 0x42 : 0x40;
unsigned int slave_port = 0x44; unsigned int slave_port = 0x44;
...@@ -124,6 +127,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -124,6 +127,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
if (adev->class == ATA_DEV_ATA) if (adev->class == ATA_DEV_ATA)
control |= 4; /* PPE enable */ control |= 4; /* PPE enable */
spin_lock_irqsave(&rdc_lock, flags);
/* PIO configuration clears DTE unconditionally. It will be /* PIO configuration clears DTE unconditionally. It will be
* programmed in set_dmamode which is guaranteed to be called * programmed in set_dmamode which is guaranteed to be called
* after set_piomode if any DMA mode is available. * after set_piomode if any DMA mode is available.
...@@ -161,6 +166,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -161,6 +166,8 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
pci_read_config_byte(dev, 0x48, &udma_enable); pci_read_config_byte(dev, 0x48, &udma_enable);
udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
pci_write_config_byte(dev, 0x48, udma_enable); pci_write_config_byte(dev, 0x48, udma_enable);
spin_unlock_irqrestore(&rdc_lock, flags);
} }
/** /**
...@@ -177,6 +184,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -177,6 +184,7 @@ static void rdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{ {
struct pci_dev *dev = to_pci_dev(ap->host->dev); struct pci_dev *dev = to_pci_dev(ap->host->dev);
unsigned long flags;
u8 master_port = ap->port_no ? 0x42 : 0x40; u8 master_port = ap->port_no ? 0x42 : 0x40;
u16 master_data; u16 master_data;
u8 speed = adev->dma_mode; u8 speed = adev->dma_mode;
...@@ -190,6 +198,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -190,6 +198,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{ 2, 1 }, { 2, 1 },
{ 2, 3 }, }; { 2, 3 }, };
spin_lock_irqsave(&rdc_lock, flags);
pci_read_config_word(dev, master_port, &master_data); pci_read_config_word(dev, master_port, &master_data);
pci_read_config_byte(dev, 0x48, &udma_enable); pci_read_config_byte(dev, 0x48, &udma_enable);
...@@ -271,6 +281,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -271,6 +281,8 @@ static void rdc_set_dmamode(struct ata_port *ap, struct ata_device *adev)
pci_write_config_word(dev, master_port, master_data); pci_write_config_word(dev, master_port, master_data);
} }
pci_write_config_byte(dev, 0x48, udma_enable); pci_write_config_byte(dev, 0x48, udma_enable);
spin_unlock_irqrestore(&rdc_lock, flags);
} }
static struct ata_port_operations rdc_pata_ops = { static struct ata_port_operations rdc_pata_ops = {
...@@ -375,6 +387,10 @@ static struct pci_driver rdc_pci_driver = { ...@@ -375,6 +387,10 @@ static struct pci_driver rdc_pci_driver = {
.id_table = rdc_pci_tbl, .id_table = rdc_pci_tbl,
.probe = rdc_init_one, .probe = rdc_init_one,
.remove = rdc_remove_one, .remove = rdc_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
#endif
}; };
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sc1200" #define DRV_NAME "pata_sc1200"
#define DRV_VERSION "0.2.6" #define DRV_VERSION "0.2.6"
#define SC1200_REV_A 0x00 #define SC1200_REV_A 0x00
...@@ -86,10 +86,14 @@ static int sc1200_clock(void) ...@@ -86,10 +86,14 @@ static int sc1200_clock(void)
static void sc1200_set_piomode(struct ata_port *ap, struct ata_device *adev) static void sc1200_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ {
static const u32 pio_timings[4][5] = { static const u32 pio_timings[4][5] = {
{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz /* format0, 33Mhz */
{0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 },
{0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz /* format1, 33Mhz */
{0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131} // format1, 66Mhz { 0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010 },
/* format1, 48Mhz */
{ 0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021 },
/* format1, 66Mhz */
{ 0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131 }
}; };
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
......
...@@ -825,18 +825,6 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf, ...@@ -825,18 +825,6 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
return words << 1; return words << 1;
} }
/**
* scc_pata_prereset - prepare for reset
* @ap: ATA port to be reset
* @deadline: deadline jiffies for the operation
*/
static int scc_pata_prereset(struct ata_link *link, unsigned long deadline)
{
link->ap->cbl = ATA_CBL_PATA80;
return ata_sff_prereset(link, deadline);
}
/** /**
* scc_postreset - standard postreset callback * scc_postreset - standard postreset callback
* @ap: the target ata_port * @ap: the target ata_port
...@@ -946,7 +934,7 @@ static struct ata_port_operations scc_pata_ops = { ...@@ -946,7 +934,7 @@ static struct ata_port_operations scc_pata_ops = {
.bmdma_status = scc_bmdma_status, .bmdma_status = scc_bmdma_status,
.sff_data_xfer = scc_data_xfer, .sff_data_xfer = scc_data_xfer,
.prereset = scc_pata_prereset, .cable_detect = ata_cable_80wire,
.softreset = scc_softreset, .softreset = scc_softreset,
.postreset = scc_postreset, .postreset = scc_postreset,
......
...@@ -58,31 +58,15 @@ static const char *csb_bad_ata100[] = { ...@@ -58,31 +58,15 @@ static const char *csb_bad_ata100[] = {
}; };
/** /**
* dell_cable - Dell serverworks cable detection * oem_cable - Dell/Sun serverworks cable detection
* @ap: ATA port to do cable detect * @ap: ATA port to do cable detect
* *
* Dell hide the 40/80 pin select for their interfaces in the top two * Dell PowerEdge and Sun Cobalt 'Alpine' hide the 40/80 pin select
* bits of the subsystem ID. * for their interfaces in the top two bits of the subsystem ID.
*/ */
static int dell_cable(struct ata_port *ap) { static int oem_cable(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev); {
if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
return ATA_CBL_PATA80;
return ATA_CBL_PATA40;
}
/**
* sun_cable - Sun Cobalt 'Alpine' cable detection
* @ap: ATA port to do cable select
*
* Cobalt CSB5 IDE hides the 40/80pin in the top two bits of the
* subsystem ID the same as dell. We could use one function but we may
* need to extend the Dell one in future
*/
static int sun_cable(struct ata_port *ap) {
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (pdev->subsystem_device & (1 << (ap->port_no + 14))) if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
...@@ -90,49 +74,21 @@ static int sun_cable(struct ata_port *ap) { ...@@ -90,49 +74,21 @@ static int sun_cable(struct ata_port *ap) {
return ATA_CBL_PATA40; return ATA_CBL_PATA40;
} }
/**
* osb4_cable - OSB4 cable detect
* @ap: ATA port to check
*
* The OSB4 isn't UDMA66 capable so this is easy
*/
static int osb4_cable(struct ata_port *ap) {
return ATA_CBL_PATA40;
}
/**
* csb_cable - CSB5/6 cable detect
* @ap: ATA port to check
*
* Serverworks default arrangement is to use the drive side detection
* only.
*/
static int csb_cable(struct ata_port *ap) {
return ATA_CBL_PATA_UNK;
}
struct sv_cable_table { struct sv_cable_table {
int device; int device;
int subvendor; int subvendor;
int (*cable_detect)(struct ata_port *ap); int (*cable_detect)(struct ata_port *ap);
}; };
/*
* Note that we don't copy the old serverworks code because the old
* code contains obvious mistakes
*/
static struct sv_cable_table cable_detect[] = { static struct sv_cable_table cable_detect[] = {
{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, oem_cable },
{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, oem_cable },
{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN, sun_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN, oem_cable },
{ PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, osb4_cable }, { PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, ata_cable_40wire },
{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, ata_cable_unknown },
{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, ata_cable_unknown },
{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, ata_cable_unknown },
{ PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, ata_cable_unknown },
{ } { }
}; };
...@@ -393,6 +349,31 @@ static void serverworks_fixup_ht1000(struct pci_dev *pdev) ...@@ -393,6 +349,31 @@ static void serverworks_fixup_ht1000(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x5A, btr); pci_write_config_byte(pdev, 0x5A, btr);
} }
static int serverworks_fixup(struct pci_dev *pdev)
{
int rc = 0;
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
rc = serverworks_fixup_osb4(pdev);
break;
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
ata_pci_bmdma_clear_simplex(pdev);
/* fall through */
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
rc = serverworks_fixup_csb(pdev);
break;
case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
serverworks_fixup_ht1000(pdev);
break;
}
return rc;
}
static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
...@@ -430,13 +411,12 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id ...@@ -430,13 +411,12 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
if (rc) if (rc)
return rc; return rc;
/* Force master latency timer to 64 PCI clocks */ rc = serverworks_fixup(pdev);
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
/* OSB4 : South Bridge and IDE */ /* OSB4 : South Bridge and IDE */
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
/* Select non UDMA capable OSB4 if we can't do fixups */ /* Select non UDMA capable OSB4 if we can't do fixups */
if ( serverworks_fixup_osb4(pdev) < 0) if (rc < 0)
ppi[0] = &info[1]; ppi[0] = &info[1];
} }
/* setup CSB5/CSB6 : South Bridge and IDE option RAID */ /* setup CSB5/CSB6 : South Bridge and IDE option RAID */
...@@ -446,19 +426,13 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id ...@@ -446,19 +426,13 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
/* If the returned btr is the newer revision then /* If the returned btr is the newer revision then
select the right info block */ select the right info block */
if (serverworks_fixup_csb(pdev) == 3) if (rc == 3)
ppi[0] = &info[3]; ppi[0] = &info[3];
/* Is this the 3rd channel CSB6 IDE ? */ /* Is this the 3rd channel CSB6 IDE ? */
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
ppi[1] = &ata_dummy_port_info; ppi[1] = &ata_dummy_port_info;
} }
/* setup HT1000E */
else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
serverworks_fixup_ht1000(pdev);
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
ata_pci_bmdma_clear_simplex(pdev);
return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0); return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0);
} }
...@@ -473,24 +447,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev) ...@@ -473,24 +447,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
if (rc) if (rc)
return rc; return rc;
/* Force master latency timer to 64 PCI clocks */ (void)serverworks_fixup(pdev);
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
serverworks_fixup_osb4(pdev);
break;
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
ata_pci_bmdma_clear_simplex(pdev);
/* fall through */
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
serverworks_fixup_csb(pdev);
break;
case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
serverworks_fixup_ht1000(pdev);
break;
}
ata_host_resume(host); ata_host_resume(host);
return 0; return 0;
......
...@@ -38,11 +38,12 @@ ...@@ -38,11 +38,12 @@
/** /**
* sil680_selreg - return register base * sil680_selreg - return register base
* @hwif: interface * @ap: ATA interface
* @r: config offset * @r: config offset
* *
* Turn a config register offset into the right address in either * Turn a config register offset into the right address in PCI space
* PCI space or MMIO space to access the control register in question * to access the control register in question.
*
* Thankfully this is a configuration operation so isn't performance * Thankfully this is a configuration operation so isn't performance
* criticial. * criticial.
*/ */
...@@ -56,12 +57,12 @@ static unsigned long sil680_selreg(struct ata_port *ap, int r) ...@@ -56,12 +57,12 @@ static unsigned long sil680_selreg(struct ata_port *ap, int r)
/** /**
* sil680_seldev - return register base * sil680_seldev - return register base
* @hwif: interface * @ap: ATA interface
* @r: config offset * @r: config offset
* *
* Turn a config register offset into the right address in either * Turn a config register offset into the right address in PCI space
* PCI space or MMIO space to access the control register in question * to access the control register in question including accounting for
* including accounting for the unit shift. * the unit shift.
*/ */
static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r) static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r)
...@@ -81,7 +82,8 @@ static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, ...@@ -81,7 +82,8 @@ static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev,
* space for us. * space for us.
*/ */
static int sil680_cable_detect(struct ata_port *ap) { static int sil680_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long addr = sil680_selreg(ap, 0); unsigned long addr = sil680_selreg(ap, 0);
u8 ata66; u8 ata66;
...@@ -93,7 +95,7 @@ static int sil680_cable_detect(struct ata_port *ap) { ...@@ -93,7 +95,7 @@ static int sil680_cable_detect(struct ata_port *ap) {
} }
/** /**
* sil680_set_piomode - set initial PIO mode data * sil680_set_piomode - set PIO mode data
* @ap: ATA interface * @ap: ATA interface
* @adev: ATA device * @adev: ATA device
* *
...@@ -104,8 +106,12 @@ static int sil680_cable_detect(struct ata_port *ap) { ...@@ -104,8 +106,12 @@ static int sil680_cable_detect(struct ata_port *ap) {
static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ {
static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; static const u16 speed_p[5] = {
static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 }; 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1
};
static const u16 speed_t[5] = {
0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1
};
unsigned long tfaddr = sil680_selreg(ap, 0x02); unsigned long tfaddr = sil680_selreg(ap, 0x02);
unsigned long addr = sil680_seldev(ap, adev, 0x04); unsigned long addr = sil680_seldev(ap, adev, 0x04);
...@@ -140,22 +146,23 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) ...@@ -140,22 +146,23 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
} }
/** /**
* sil680_set_dmamode - set initial DMA mode data * sil680_set_dmamode - set DMA mode data
* @ap: ATA interface * @ap: ATA interface
* @adev: ATA device * @adev: ATA device
* *
* Program the MWDMA/UDMA modes for the sil680 k * Program the MWDMA/UDMA modes for the sil680 chipset.
* chipset. The MWDMA mode values are pulled from a lookup table *
* The MWDMA mode values are pulled from a lookup table
* while the chipset uses mode number for UDMA. * while the chipset uses mode number for UDMA.
*/ */
static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev) static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{ {
static u8 ultra_table[2][7] = { static const u8 ultra_table[2][7] = {
{ 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */ { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */
{ 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */ { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */
}; };
static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 }; static const u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long ma = sil680_seldev(ap, adev, 0x08); unsigned long ma = sil680_seldev(ap, adev, 0x08);
...@@ -175,7 +182,7 @@ static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev) ...@@ -175,7 +182,7 @@ static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
mode &= ~(0x03 << port_shift); mode &= ~(0x03 << port_shift);
/* Extract scsc */ /* Extract scsc */
scsc = (scsc & 0x30) ? 1: 0; scsc = (scsc & 0x30) ? 1 : 0;
if (adev->dma_mode >= XFER_UDMA_0) { if (adev->dma_mode >= XFER_UDMA_0) {
multi = 0x10C1; multi = 0x10C1;
...@@ -248,7 +255,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) ...@@ -248,7 +255,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
{ {
u8 tmpbyte = 0; u8 tmpbyte = 0;
/* FIXME: double check */ /* FIXME: double check */
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
pdev->revision ? 1 : 255); pdev->revision ? 1 : 255);
...@@ -266,22 +273,22 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) ...@@ -266,22 +273,22 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5); *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
#endif #endif
switch(tmpbyte & 0x30) { switch (tmpbyte & 0x30) {
case 0x00: case 0x00:
/* 133 clock attempt to force it on */ /* 133 clock attempt to force it on */
pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10); pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
break; break;
case 0x30: case 0x30:
/* if clocking is disabled */ /* if clocking is disabled */
/* 133 clock attempt to force it on */ /* 133 clock attempt to force it on */
pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20); pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
break; break;
case 0x10: case 0x10:
/* 133 already */ /* 133 already */
break; break;
case 0x20: case 0x20:
/* BIOS set PCI x2 clocking */ /* BIOS set PCI x2 clocking */
break; break;
} }
pci_read_config_byte(pdev, 0x8A, &tmpbyte); pci_read_config_byte(pdev, 0x8A, &tmpbyte);
...@@ -299,12 +306,19 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) ...@@ -299,12 +306,19 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
pci_write_config_dword(pdev, 0xB8, 0x43924392); pci_write_config_dword(pdev, 0xB8, 0x43924392);
pci_write_config_dword(pdev, 0xBC, 0x40094009); pci_write_config_dword(pdev, 0xBC, 0x40094009);
switch(tmpbyte & 0x30) { switch (tmpbyte & 0x30) {
case 0x00: printk(KERN_INFO "sil680: 100MHz clock.\n");break; case 0x00:
case 0x10: printk(KERN_INFO "sil680: 133MHz clock.\n");break; printk(KERN_INFO "sil680: 100MHz clock.\n");
case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; break;
/* This last case is _NOT_ ok */ case 0x10:
case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); printk(KERN_INFO "sil680: 133MHz clock.\n");
break;
case 0x20:
printk(KERN_INFO "sil680: Using PCI clock.\n");
break;
/* This last case is _NOT_ ok */
case 0x30:
printk(KERN_ERR "sil680: Clock disabled ?\n");
} }
return tmpbyte & 0x30; return tmpbyte & 0x30;
} }
......
This diff is collapsed.
/* /*
* pata_sl82c105.c - SL82C105 PATA for new ATA layer * pata_sl82c105.c - SL82C105 PATA for new ATA layer
* (C) 2005 Red Hat Inc * (C) 2005 Red Hat Inc
* (C) 2011 Bartlomiej Zolnierkiewicz
* *
* Based in part on linux/drivers/ide/pci/sl82c105.c * Based in part on linux/drivers/ide/pci/sl82c105.c
* SL82C105/Winbond 553 IDE driver * SL82C105/Winbond 553 IDE driver
...@@ -289,6 +290,14 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev) ...@@ -289,6 +290,14 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev)
return bridge->revision; return bridge->revision;
} }
static void sl82c105_fixup(struct pci_dev *pdev)
{
u32 val;
pci_read_config_dword(pdev, 0x40, &val);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(pdev, 0x40, val);
}
static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{ {
...@@ -306,7 +315,6 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id ...@@ -306,7 +315,6 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
/* for now use only the first port */ /* for now use only the first port */
const struct ata_port_info *ppi[] = { &info_early, const struct ata_port_info *ppi[] = { &info_early,
NULL }; NULL };
u32 val;
int rev; int rev;
int rc; int rc;
...@@ -325,13 +333,28 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id ...@@ -325,13 +333,28 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
else else
ppi[0] = &info_dma; ppi[0] = &info_dma;
pci_read_config_dword(dev, 0x40, &val); sl82c105_fixup(dev);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
} }
#ifdef CONFIG_PM
static int sl82c105_reinit_one(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
int rc;
rc = ata_pci_device_do_resume(pdev);
if (rc)
return rc;
sl82c105_fixup(pdev);
ata_host_resume(host);
return 0;
}
#endif
static const struct pci_device_id sl82c105[] = { static const struct pci_device_id sl82c105[] = {
{ PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
...@@ -342,7 +365,11 @@ static struct pci_driver sl82c105_pci_driver = { ...@@ -342,7 +365,11 @@ static struct pci_driver sl82c105_pci_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = sl82c105, .id_table = sl82c105,
.probe = sl82c105_init_one, .probe = sl82c105_init_one,
.remove = ata_pci_remove_one .remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = sl82c105_reinit_one,
#endif
}; };
static int __init sl82c105_init(void) static int __init sl82c105_init(void)
......
...@@ -509,6 +509,27 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags) ...@@ -509,6 +509,27 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
} }
} }
static void via_fixup(struct pci_dev *pdev, const struct via_isa_bridge *config)
{
u32 timing;
/* Initialise the FIFO for the enabled channels. */
via_config_fifo(pdev, config->flags);
if (config->udma_mask == ATA_UDMA4) {
/* The 66 MHz devices require we enable the clock */
pci_read_config_dword(pdev, 0x50, &timing);
timing |= 0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
if (config->flags & VIA_BAD_CLK66) {
/* Disable the 66MHz clock on problem devices */
pci_read_config_dword(pdev, 0x50, &timing);
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
}
/** /**
* via_init_one - discovery callback * via_init_one - discovery callback
* @pdev: PCI device * @pdev: PCI device
...@@ -570,7 +591,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -570,7 +591,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct pci_dev *isa; struct pci_dev *isa;
const struct via_isa_bridge *config; const struct via_isa_bridge *config;
u8 enable; u8 enable;
u32 timing;
unsigned long flags = id->driver_data; unsigned long flags = id->driver_data;
int rc; int rc;
...@@ -609,9 +629,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -609,9 +629,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV; return -ENODEV;
} }
/* Initialise the FIFO for the enabled channels. */
via_config_fifo(pdev, config->flags);
/* Clock set up */ /* Clock set up */
switch (config->udma_mask) { switch (config->udma_mask) {
case 0x00: case 0x00:
...@@ -637,12 +654,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -637,12 +654,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV; return -ENODEV;
} }
if (config->flags & VIA_BAD_CLK66) { via_fixup(pdev, config);
/* Disable the 66MHz clock on problem devices */
pci_read_config_dword(pdev, 0x50, &timing);
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
/* We have established the device type, now fire it up */ /* We have established the device type, now fire it up */
return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0); return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0);
...@@ -661,29 +673,14 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -661,29 +673,14 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int via_reinit_one(struct pci_dev *pdev) static int via_reinit_one(struct pci_dev *pdev)
{ {
u32 timing;
struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ata_host *host = dev_get_drvdata(&pdev->dev);
const struct via_isa_bridge *config = host->private_data;
int rc; int rc;
rc = ata_pci_device_do_resume(pdev); rc = ata_pci_device_do_resume(pdev);
if (rc) if (rc)
return rc; return rc;
via_config_fifo(pdev, config->flags); via_fixup(pdev, host->private_data);
if (config->udma_mask == ATA_UDMA4) {
/* The 66 MHz devices require we enable the clock */
pci_read_config_dword(pdev, 0x50, &timing);
timing |= 0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
if (config->flags & VIA_BAD_CLK66) {
/* Disable the 66MHz clock on problem devices */
pci_read_config_dword(pdev, 0x50, &timing);
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
ata_host_resume(host); ata_host_resume(host);
return 0; return 0;
......
...@@ -4087,8 +4087,11 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4087,8 +4087,11 @@ static int mv_platform_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "slots %u ports %d\n", dev_info(&pdev->dev, "slots %u ports %d\n",
(unsigned)MV_MAX_Q_DEPTH, host->n_ports); (unsigned)MV_MAX_Q_DEPTH, host->n_ports);
return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, rc = ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
IRQF_SHARED, &mv6_sht); IRQF_SHARED, &mv6_sht);
if (!rc)
return 0;
err: err:
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
if (!IS_ERR(hpriv->clk)) { if (!IS_ERR(hpriv->clk)) {
...@@ -4110,8 +4113,7 @@ static int mv_platform_probe(struct platform_device *pdev) ...@@ -4110,8 +4113,7 @@ static int mv_platform_probe(struct platform_device *pdev)
*/ */
static int __devexit mv_platform_remove(struct platform_device *pdev) static int __devexit mv_platform_remove(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct ata_host *host = platform_get_drvdata(pdev);
struct ata_host *host = dev_get_drvdata(dev);
#if defined(CONFIG_HAVE_CLK) #if defined(CONFIG_HAVE_CLK)
struct mv_host_priv *hpriv = host->private_data; struct mv_host_priv *hpriv = host->private_data;
#endif #endif
...@@ -4129,7 +4131,7 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) ...@@ -4129,7 +4131,7 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ata_host *host = platform_get_drvdata(pdev);
if (host) if (host)
return ata_host_suspend(host, state); return ata_host_suspend(host, state);
else else
...@@ -4138,7 +4140,7 @@ static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) ...@@ -4138,7 +4140,7 @@ static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
static int mv_platform_resume(struct platform_device *pdev) static int mv_platform_resume(struct platform_device *pdev)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ata_host *host = platform_get_drvdata(pdev);
int ret; int ret;
if (host) { if (host) {
...@@ -4353,7 +4355,7 @@ static int mv_pci_init_one(struct pci_dev *pdev, ...@@ -4353,7 +4355,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int mv_pci_device_resume(struct pci_dev *pdev) static int mv_pci_device_resume(struct pci_dev *pdev)
{ {
struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ata_host *host = pci_get_drvdata(pdev);
int rc; int rc;
rc = ata_pci_device_do_resume(pdev); rc = ata_pci_device_do_resume(pdev);
......
...@@ -268,7 +268,7 @@ union sil24_cmd_block { ...@@ -268,7 +268,7 @@ union sil24_cmd_block {
struct sil24_atapi_block atapi; struct sil24_atapi_block atapi;
}; };
static struct sil24_cerr_info { static const struct sil24_cerr_info {
unsigned int err_mask, action; unsigned int err_mask, action;
const char *desc; const char *desc;
} sil24_cerr_db[] = { } sil24_cerr_db[] = {
...@@ -1019,7 +1019,7 @@ static void sil24_error_intr(struct ata_port *ap) ...@@ -1019,7 +1019,7 @@ static void sil24_error_intr(struct ata_port *ap)
/* deal with command error */ /* deal with command error */
if (irq_stat & PORT_IRQ_ERROR) { if (irq_stat & PORT_IRQ_ERROR) {
struct sil24_cerr_info *ci = NULL; const struct sil24_cerr_info *ci = NULL;
unsigned int err_mask = 0, action = 0; unsigned int err_mask = 0, action = 0;
u32 context, cerr; u32 context, cerr;
int pmp; int pmp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment