aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/Kconfig59
-rw-r--r--drivers/ata/Makefile4
-rw-r--r--drivers/ata/ahci.c552
-rw-r--r--drivers/ata/ata_generic.c42
-rw-r--r--drivers/ata/ata_piix.c67
-rw-r--r--drivers/ata/libata-acpi.c709
-rw-r--r--drivers/ata/libata-core.c1343
-rw-r--r--drivers/ata/libata-eh.c360
-rw-r--r--drivers/ata/libata-scsi.c129
-rw-r--r--drivers/ata/libata-sff.c642
-rw-r--r--drivers/ata/libata.h38
-rw-r--r--drivers/ata/pata_ali.c80
-rw-r--r--drivers/ata/pata_amd.c95
-rw-r--r--drivers/ata/pata_artop.c26
-rw-r--r--drivers/ata/pata_atiixp.c30
-rw-r--r--drivers/ata/pata_cmd640.c312
-rw-r--r--drivers/ata/pata_cmd64x.c42
-rw-r--r--drivers/ata/pata_cs5520.c178
-rw-r--r--drivers/ata/pata_cs5530.c23
-rw-r--r--drivers/ata/pata_cs5535.c28
-rw-r--r--drivers/ata/pata_cypress.c18
-rw-r--r--drivers/ata/pata_efar.c35
-rw-r--r--drivers/ata/pata_hpt366.c33
-rw-r--r--drivers/ata/pata_hpt37x.c381
-rw-r--r--drivers/ata/pata_hpt3x2n.c74
-rw-r--r--drivers/ata/pata_hpt3x3.c28
-rw-r--r--drivers/ata/pata_isapnp.c47
-rw-r--r--drivers/ata/pata_it8213.c40
-rw-r--r--drivers/ata/pata_it821x.c44
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c50
-rw-r--r--drivers/ata/pata_jmicron.c57
-rw-r--r--drivers/ata/pata_legacy.c67
-rw-r--r--drivers/ata/pata_marvell.c24
-rw-r--r--drivers/ata/pata_mpc52xx.c55
-rw-r--r--drivers/ata/pata_mpiix.c44
-rw-r--r--drivers/ata/pata_netcell.c35
-rw-r--r--drivers/ata/pata_ns87410.c10
-rw-r--r--drivers/ata/pata_oldpiix.c13
-rw-r--r--drivers/ata/pata_opti.c9
-rw-r--r--drivers/ata/pata_optidma.c58
-rw-r--r--drivers/ata/pata_pcmcia.c85
-rw-r--r--drivers/ata/pata_pdc2027x.c158
-rw-r--r--drivers/ata/pata_pdc202xx_old.c71
-rw-r--r--drivers/ata/pata_platform.c46
-rw-r--r--drivers/ata/pata_qdi.c61
-rw-r--r--drivers/ata/pata_radisys.c41
-rw-r--r--drivers/ata/pata_rz1000.c35
-rw-r--r--drivers/ata/pata_sc1200.c8
-rw-r--r--drivers/ata/pata_scc.c1211
-rw-r--r--drivers/ata/pata_serverworks.c42
-rw-r--r--drivers/ata/pata_sil680.c31
-rw-r--r--drivers/ata/pata_sis.c126
-rw-r--r--drivers/ata/pata_sl82c105.c44
-rw-r--r--drivers/ata/pata_triflex.c8
-rw-r--r--drivers/ata/pata_via.c33
-rw-r--r--drivers/ata/pata_winbond.c103
-rw-r--r--drivers/ata/pdc_adma.c89
-rw-r--r--drivers/ata/sata_inic162x.c97
-rw-r--r--drivers/ata/sata_mv.c252
-rw-r--r--drivers/ata/sata_nv.c378
-rw-r--r--drivers/ata/sata_promise.c408
-rw-r--r--drivers/ata/sata_qstor.c66
-rw-r--r--drivers/ata/sata_sil.c130
-rw-r--r--drivers/ata/sata_sil24.c130
-rw-r--r--drivers/ata/sata_sis.c57
-rw-r--r--drivers/ata/sata_svw.c109
-rw-r--r--drivers/ata/sata_sx4.c166
-rw-r--r--drivers/ata/sata_uli.c67
-rw-r--r--drivers/ata/sata_via.c217
-rw-r--r--drivers/ata/sata_vsc.c197
-rw-r--r--drivers/ata/sis.h5
71 files changed, 6661 insertions, 3691 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 3747457fee7a..365c306c7cf8 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -156,10 +156,18 @@ config SATA_INIC162X
help
This option enables support for Initio 162x Serial ATA.
-config SATA_INTEL_COMBINED
+config SATA_ACPI
bool
- depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
+ depends on ACPI && PCI
default y
+ help
+ This option adds support for SATA-related ACPI objects.
+ These ACPI objects add the ability to retrieve taskfiles
+ from the ACPI BIOS and write them to the disk controller.
+ These objects may be related to performance, security,
+ power management, or other areas.
+ You can disable this at kernel boot time by using the
+ option libata.noacpi=1
config PATA_ALI
tristate "ALi PATA support (Experimental)"
@@ -171,7 +179,7 @@ config PATA_ALI
If unsure, say N.
config PATA_AMD
- tristate "AMD/NVidia PATA support (Experimental)"
+ tristate "AMD/NVidia PATA support"
depends on PCI
help
This option enables support for the AMD and NVidia PATA
@@ -196,6 +204,16 @@ config PATA_ATIIXP
If unsure, say N.
+config PATA_CMD640_PCI
+ tristate "CMD640 PCI PATA support (Very Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for the CMD640 PCI IDE
+ interface chip. Only the primary channel is currently
+ supported.
+
+ If unsure, say N.
+
config PATA_CMD64X
tristate "CMD64x PATA support (Very Experimental)"
depends on PCI&& EXPERIMENTAL
@@ -260,7 +278,7 @@ config ATA_GENERIC
If unsure, say N.
config PATA_HPT366
- tristate "HPT 366/368 PATA support (Very Experimental)"
+ tristate "HPT 366/368 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the HPT 366 and 368
@@ -269,7 +287,7 @@ config PATA_HPT366
If unsure, say N.
config PATA_HPT37X
- tristate "HPT 370/370A/371/372/374/302 PATA support (Very Experimental)"
+ tristate "HPT 370/370A/371/372/374/302 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the majority of the later HPT
@@ -296,7 +314,7 @@ config PATA_HPT3X3
If unsure, say N.
config PATA_ISAPNP
- tristate "ISA Plug and Play PATA support (Very Experimental)"
+ tristate "ISA Plug and Play PATA support (Experimental)"
depends on EXPERIMENTAL && ISAPNP
help
This option enables support for ISA plug & play ATA
@@ -305,8 +323,8 @@ config PATA_ISAPNP
If unsure, say N.
config PATA_IT821X
- tristate "IT8211/2 PATA support (Experimental)"
- depends on PCI && EXPERIMENTAL
+ tristate "IT8211/2 PATA support"
+ depends on PCI
help
This option enables support for the ITE 8211 and 8212
PATA controllers via the new ATA layer, including RAID
@@ -377,10 +395,10 @@ config PATA_MPIIX
If unsure, say N.
config PATA_OLDPIIX
- tristate "Intel PATA old PIIX support (Experimental)"
- depends on PCI && EXPERIMENTAL
+ tristate "Intel PATA old PIIX support"
+ depends on PCI
help
- This option enables support for old(?) PIIX PATA support.
+ This option enables support for early PIIX PATA support.
If unsure, say N.
@@ -431,7 +449,7 @@ config PATA_PCMCIA
If unsure, say N.
config PATA_PDC_OLD
- tristate "Older Promise PATA controller support (Very Experimental)"
+ tristate "Older Promise PATA controller support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the Promise 20246, 20262, 20263,
@@ -446,7 +464,7 @@ config PATA_QDI
Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
config PATA_RADISYS
- tristate "RADISYS 82600 PATA support (Very experimental)"
+ tristate "RADISYS 82600 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the RADISYS 82600
@@ -464,7 +482,7 @@ config PATA_RZ1000
If unsure, say N.
config PATA_SC1200
- tristate "SC1200 PATA support (Raving Lunatic)"
+ tristate "SC1200 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the NatSemi/AMD SC1200 SoC
@@ -473,8 +491,8 @@ config PATA_SC1200
If unsure, say N.
config PATA_SERVERWORKS
- tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support (Experimental)"
- depends on PCI && EXPERIMENTAL
+ tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support"
+ depends on PCI
help
This option enables support for the Serverworks OSB4/CSB5/CSB6 and
HT1000 PATA controllers, via the new ATA layer.
@@ -549,6 +567,15 @@ config PATA_IXP4XX_CF
If unsure, say N.
+config PATA_SCC
+ tristate "Toshiba's Cell Reference Set IDE support"
+ depends on PCI && PPC_CELLEB
+ help
+ This option enables support for the built-in IDE controller on
+ Toshiba Cell Reference Board.
+
+ If unsure, say N.
+
endif
endmenu
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index cd096f0c78a1..b7055e302650 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_PATA_ALI) += pata_ali.o
obj-$(CONFIG_PATA_AMD) += pata_amd.o
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
+obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
@@ -59,6 +60,7 @@ obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
obj-$(CONFIG_PATA_SIS) += pata_sis.o
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
+obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
@@ -66,4 +68,4 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o
-
+libata-$(CONFIG_SATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6a3543e06241..34c5534ed64c 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>
#define DRV_NAME "ahci"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.1"
enum {
@@ -80,6 +80,7 @@ enum {
board_ahci_pi = 1,
board_ahci_vt8251 = 2,
board_ahci_ign_iferr = 3,
+ board_ahci_sb600 = 4,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -168,6 +169,11 @@ enum {
AHCI_FLAG_NO_NCQ = (1 << 24),
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
+ AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
+
+ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_SKIP_D2H_BSY,
};
struct ahci_cmd_hdr {
@@ -186,8 +192,10 @@ struct ahci_sg {
};
struct ahci_host_priv {
- u32 cap; /* cache of HOST_CAP register */
- u32 port_map; /* cache of HOST_PORTS_IMPL reg */
+ u32 cap; /* cap to use */
+ u32 port_map; /* port map to use */
+ u32 saved_cap; /* saved initial cap */
+ u32 saved_port_map; /* saved initial port_map */
};
struct ahci_port_priv {
@@ -198,16 +206,15 @@ struct ahci_port_priv {
void *rx_fis;
dma_addr_t rx_fis_dma;
/* for NCQ spurious interrupt analysis */
- int ncq_saw_spurious_sdb_cnt;
unsigned int ncq_saw_d2h:1;
unsigned int ncq_saw_dmas:1;
+ unsigned int ncq_saw_sdb:1;
};
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t ahci_interrupt (int irq, void *dev_instance);
static void ahci_irq_clear(struct ata_port *ap);
static int ahci_port_start(struct ata_port *ap);
static void ahci_port_stop(struct ata_port *ap);
@@ -219,10 +226,12 @@ static void ahci_thaw(struct ata_port *ap);
static void ahci_error_handler(struct ata_port *ap);
static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
+#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
static int ahci_port_resume(struct ata_port *ap);
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int ahci_pci_device_resume(struct pci_dev *pdev);
+#endif
static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
@@ -241,8 +250,10 @@ static struct scsi_host_template ahci_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations ahci_ops = {
@@ -257,7 +268,6 @@ static const struct ata_port_operations ahci_ops = {
.qc_prep = ahci_qc_prep,
.qc_issue = ahci_qc_issue,
- .irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
.irq_on = ata_dummy_irq_on,
.irq_ack = ata_dummy_irq_ack,
@@ -271,8 +281,10 @@ static const struct ata_port_operations ahci_ops = {
.error_handler = ahci_error_handler,
.post_internal_cmd = ahci_post_internal_cmd,
+#ifdef CONFIG_PM
.port_suspend = ahci_port_suspend,
.port_resume = ahci_port_resume,
+#endif
.port_start = ahci_port_start,
.port_stop = ahci_port_stop,
@@ -290,7 +302,6 @@ static const struct ata_port_operations ahci_vt8251_ops = {
.qc_prep = ahci_qc_prep,
.qc_issue = ahci_qc_issue,
- .irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
.irq_on = ata_dummy_irq_on,
.irq_ack = ata_dummy_irq_ack,
@@ -304,8 +315,10 @@ static const struct ata_port_operations ahci_vt8251_ops = {
.error_handler = ahci_vt8251_error_handler,
.post_internal_cmd = ahci_post_internal_cmd,
+#ifdef CONFIG_PM
.port_suspend = ahci_port_suspend,
.port_resume = ahci_port_resume,
+#endif
.port_start = ahci_port_start,
.port_stop = ahci_port_stop,
@@ -314,42 +327,37 @@ static const struct ata_port_operations ahci_vt8251_ops = {
static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
{
- .sht = &ahci_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- ATA_FLAG_SKIP_D2H_BSY,
+ .flags = AHCI_FLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
/* board_ahci_pi */
{
- .sht = &ahci_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
+ .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
/* board_ahci_vt8251 */
{
- .sht = &ahci_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- ATA_FLAG_SKIP_D2H_BSY |
- ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
+ .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
+ AHCI_FLAG_NO_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_vt8251_ops,
},
/* board_ahci_ign_iferr */
{
- .sht = &ahci_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
- ATA_FLAG_SKIP_D2H_BSY |
- AHCI_FLAG_IGN_IRQ_IF_ERR,
+ .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &ahci_ops,
+ },
+ /* board_ahci_sb600 */
+ {
+ .flags = AHCI_FLAG_COMMON |
+ AHCI_FLAG_IGN_SERR_INTERNAL,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
@@ -381,23 +389,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
+ { PCI_VDEVICE(INTEL, 0x292c), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
- /* JMicron */
- { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
- { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */
- { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */
- { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */
- { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */
+ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
/* ATI */
- { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
- { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
+ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
/* VIA */
{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
+ { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */
/* NVIDIA */
{ PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */
@@ -439,8 +445,10 @@ static struct pci_driver ahci_pci_driver = {
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ahci_pci_device_suspend,
.resume = ahci_pci_device_resume,
+#endif
};
@@ -449,10 +457,100 @@ static inline int ahci_nr_ports(u32 cap)
return (cap & 0x1f) + 1;
}
-static inline void __iomem *ahci_port_base(void __iomem *base,
- unsigned int port)
+static inline void __iomem *ahci_port_base(struct ata_port *ap)
{
- return base + 0x100 + (port * 0x80);
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+
+ return mmio + 0x100 + (ap->port_no * 0x80);
+}
+
+/**
+ * ahci_save_initial_config - Save and fixup initial config values
+ * @pdev: target PCI device
+ * @pi: associated ATA port info
+ * @hpriv: host private area to store config values
+ *
+ * Some registers containing configuration info might be setup by
+ * BIOS and might be cleared on reset. This function saves the
+ * initial values of those registers into @hpriv such that they
+ * can be restored after controller reset.
+ *
+ * If inconsistent, config values are fixed up by this function.
+ *
+ * LOCKING:
+ * None.
+ */
+static void ahci_save_initial_config(struct pci_dev *pdev,
+ const struct ata_port_info *pi,
+ struct ahci_host_priv *hpriv)
+{
+ void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
+ u32 cap, port_map;
+ int i;
+
+ /* Values prefixed with saved_ are written back to host after
+ * reset. Values without are used for driver operation.
+ */
+ hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
+ hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
+
+ /* fixup zero port_map */
+ if (!port_map) {
+ port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "PORTS_IMPL is zero, forcing 0x%x\n", port_map);
+
+ /* write the fixed up value to the PI register */
+ hpriv->saved_port_map = port_map;
+ }
+
+ /* cross check port_map and cap.n_ports */
+ if (pi->flags & AHCI_FLAG_HONOR_PI) {
+ u32 tmp_port_map = port_map;
+ int n_ports = ahci_nr_ports(cap);
+
+ for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
+ if (tmp_port_map & (1 << i)) {
+ n_ports--;
+ tmp_port_map &= ~(1 << i);
+ }
+ }
+
+ /* Whine if inconsistent. No need to update cap.
+ * port_map is used to determine number of ports.
+ */
+ if (n_ports || tmp_port_map)
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "nr_ports (%u) and implemented port map "
+ "(0x%x) don't match\n",
+ ahci_nr_ports(cap), port_map);
+ } else {
+ /* fabricate port_map from cap.nr_ports */
+ port_map = (1 << ahci_nr_ports(cap)) - 1;
+ }
+
+ /* record values to use during operation */
+ hpriv->cap = cap;
+ hpriv->port_map = port_map;
+}
+
+/**
+ * ahci_restore_initial_config - Restore initial config
+ * @host: target ATA host
+ *
+ * Restore initial config stored by ahci_save_initial_config().
+ *
+ * LOCKING:
+ * None.
+ */
+static void ahci_restore_initial_config(struct ata_host *host)
+{
+ struct ahci_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+
+ writel(hpriv->saved_cap, mmio + HOST_CAP);
+ writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
+ (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
}
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
@@ -489,8 +587,9 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
-static void ahci_start_engine(void __iomem *port_mmio)
+static void ahci_start_engine(struct ata_port *ap)
{
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
/* start DMA */
@@ -500,8 +599,9 @@ static void ahci_start_engine(void __iomem *port_mmio)
readl(port_mmio + PORT_CMD); /* flush */
}
-static int ahci_stop_engine(void __iomem *port_mmio)
+static int ahci_stop_engine(struct ata_port *ap)
{
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
tmp = readl(port_mmio + PORT_CMD);
@@ -523,19 +623,23 @@ static int ahci_stop_engine(void __iomem *port_mmio)
return 0;
}
-static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
- dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_start_fis_rx(struct ata_port *ap)
{
+ void __iomem *port_mmio = ahci_port_base(ap);
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+ struct ahci_port_priv *pp = ap->private_data;
u32 tmp;
/* set FIS registers */
- if (cap & HOST_CAP_64)
- writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
- writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+ if (hpriv->cap & HOST_CAP_64)
+ writel((pp->cmd_slot_dma >> 16) >> 16,
+ port_mmio + PORT_LST_ADDR_HI);
+ writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
- if (cap & HOST_CAP_64)
- writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
- writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+ if (hpriv->cap & HOST_CAP_64)
+ writel((pp->rx_fis_dma >> 16) >> 16,
+ port_mmio + PORT_FIS_ADDR_HI);
+ writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
/* enable FIS reception */
tmp = readl(port_mmio + PORT_CMD);
@@ -546,8 +650,9 @@ static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
readl(port_mmio + PORT_CMD);
}
-static int ahci_stop_fis_rx(void __iomem *port_mmio)
+static int ahci_stop_fis_rx(struct ata_port *ap)
{
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
/* disable FIS reception */
@@ -564,14 +669,16 @@ static int ahci_stop_fis_rx(void __iomem *port_mmio)
return 0;
}
-static void ahci_power_up(void __iomem *port_mmio, u32 cap)
+static void ahci_power_up(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 cmd;
cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
/* spin up device */
- if (cap & HOST_CAP_SSS) {
+ if (hpriv->cap & HOST_CAP_SSS) {
cmd |= PORT_CMD_SPIN_UP;
writel(cmd, port_mmio + PORT_CMD);
}
@@ -580,11 +687,14 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap)
writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
}
-static void ahci_power_down(void __iomem *port_mmio, u32 cap)
+#ifdef CONFIG_PM
+static void ahci_power_down(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 cmd, scontrol;
- if (!(cap & HOST_CAP_SSS))
+ if (!(hpriv->cap & HOST_CAP_SSS))
return;
/* put device into listen mode, first set PxSCTL.DET to 0 */
@@ -597,30 +707,30 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
cmd &= ~PORT_CMD_SPIN_UP;
writel(cmd, port_mmio + PORT_CMD);
}
+#endif
-static void ahci_init_port(void __iomem *port_mmio, u32 cap,
- dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_init_port(struct ata_port *ap)
{
/* enable FIS reception */
- ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
+ ahci_start_fis_rx(ap);
/* enable DMA */
- ahci_start_engine(port_mmio);
+ ahci_start_engine(ap);
}
-static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
+static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
{
int rc;
/* disable DMA */
- rc = ahci_stop_engine(port_mmio);
+ rc = ahci_stop_engine(ap);
if (rc) {
*emsg = "failed to stop engine";
return rc;
}
/* disable FIS reception */
- rc = ahci_stop_fis_rx(port_mmio);
+ rc = ahci_stop_fis_rx(ap);
if (rc) {
*emsg = "failed stop FIS RX";
return rc;
@@ -629,12 +739,11 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
return 0;
}
-static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
+static int ahci_reset_controller(struct ata_host *host)
{
- u32 cap_save, impl_save, tmp;
-
- cap_save = readl(mmio + HOST_CAP);
- impl_save = readl(mmio + HOST_PORTS_IMPL);
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+ u32 tmp;
/* global controller reset */
tmp = readl(mmio + HOST_CTL);
@@ -650,7 +759,7 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
tmp = readl(mmio + HOST_CTL);
if (tmp & HOST_RESET) {
- dev_printk(KERN_ERR, &pdev->dev,
+ dev_printk(KERN_ERR, host->dev,
"controller reset failed (0x%x)\n", tmp);
return -EIO;
}
@@ -659,18 +768,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
writel(HOST_AHCI_EN, mmio + HOST_CTL);
(void) readl(mmio + HOST_CTL); /* flush */
- /* These write-once registers are normally cleared on reset.
- * Restore BIOS values... which we HOPE were present before
- * reset.
- */
- if (!impl_save) {
- impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
- dev_printk(KERN_WARNING, &pdev->dev,
- "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
- }
- writel(cap_save, mmio + HOST_CAP);
- writel(impl_save, mmio + HOST_PORTS_IMPL);
- (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
+ /* some registers might be cleared on reset. restore initial values */
+ ahci_restore_initial_config(host);
if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
u16 tmp16;
@@ -684,23 +783,23 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
return 0;
}
-static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
- int n_ports, unsigned int port_flags,
- struct ahci_host_priv *hpriv)
+static void ahci_init_controller(struct ata_host *host)
{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
int i, rc;
u32 tmp;
- for (i = 0; i < n_ports; i++) {
- void __iomem *port_mmio = ahci_port_base(mmio, i);
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ void __iomem *port_mmio = ahci_port_base(ap);
const char *emsg = NULL;
- if ((port_flags & AHCI_FLAG_HONOR_PI) &&
- !(hpriv->port_map & (1 << i)))
+ if (ata_port_is_dummy(ap))
continue;
/* make sure port is not active */
- rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+ rc = ahci_deinit_port(ap, &emsg);
if (rc)
dev_printk(KERN_WARNING, &pdev->dev,
"%s (%d)\n", emsg, rc);
@@ -728,7 +827,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
static unsigned int ahci_dev_classify(struct ata_port *ap)
{
- void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ahci_port_base(ap);
struct ata_taskfile tf;
u32 tmp;
@@ -778,8 +877,7 @@ static int ahci_clo(struct ata_port *ap)
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = ahci_port_base(ap);
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
struct ata_taskfile tf;
@@ -796,7 +894,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
}
/* prepare for SRST (AHCI-1.1 10.4.1) */
- rc = ahci_stop_engine(port_mmio);
+ rc = ahci_stop_engine(ap);
if (rc) {
reason = "failed to stop engine";
goto fail_restart;
@@ -816,7 +914,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
}
/* restart engine */
- ahci_start_engine(port_mmio);
+ ahci_start_engine(ap);
ata_tf_init(ap->device, &tf);
fis = pp->cmd_tbl;
@@ -875,7 +973,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
return 0;
fail_restart:
- ahci_start_engine(port_mmio);
+ ahci_start_engine(ap);
fail:
ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
return rc;
@@ -886,13 +984,11 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
struct ahci_port_priv *pp = ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
DPRINTK("ENTER\n");
- ahci_stop_engine(port_mmio);
+ ahci_stop_engine(ap);
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(ap->device, &tf);
@@ -901,7 +997,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
rc = sata_std_hardreset(ap, class);
- ahci_start_engine(port_mmio);
+ ahci_start_engine(ap);
if (rc == 0 && ata_port_online(ap))
*class = ahci_dev_classify(ap);
@@ -914,20 +1010,18 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
DPRINTK("ENTER\n");
- ahci_stop_engine(port_mmio);
+ ahci_stop_engine(ap);
rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
/* vt8251 needs SError cleared for the port to operate */
ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
- ahci_start_engine(port_mmio);
+ ahci_start_engine(ap);
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
@@ -939,7 +1033,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 new_tmp, tmp;
ata_std_postreset(ap, class);
@@ -1057,8 +1151,11 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
irq_stat &= ~PORT_IRQ_IF_ERR;
- if (irq_stat & PORT_IRQ_TF_ERR)
+ if (irq_stat & PORT_IRQ_TF_ERR) {
err_mask |= AC_ERR_DEV;
+ if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
+ serror &= ~SERR_INTERNAL;
+ }
if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
err_mask |= AC_ERR_HOST_BUS;
@@ -1104,8 +1201,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
static void ahci_host_intr(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ata_eh_info *ehi = &ap->eh_info;
struct ahci_port_priv *pp = ap->private_data;
u32 status, qc_active;
@@ -1160,23 +1256,32 @@ static void ahci_host_intr(struct ata_port *ap)
known_irq = 1;
}
- if (status & PORT_IRQ_SDB_FIS &&
- pp->ncq_saw_spurious_sdb_cnt < 10) {
- /* SDB FIS containing spurious completions might be
- * dangerous, we need to know more about them. Print
- * more of it.
- */
+ if (status & PORT_IRQ_SDB_FIS) {
const __le32 *f = pp->rx_fis + RX_FIS_SDB;
- ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ "
- "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n",
+ if (le32_to_cpu(f[1])) {
+ /* SDB FIS containing spurious completions
+ * might be dangerous, whine and fail commands
+ * with HSM violation. EH will turn off NCQ
+ * after several such failures.
+ */
+ ata_ehi_push_desc(ehi,
+ "spurious completions during NCQ "
+ "issue=0x%x SAct=0x%x FIS=%08x:%08x",
readl(port_mmio + PORT_CMD_ISSUE),
readl(port_mmio + PORT_SCR_ACT),
- le32_to_cpu(f[0]), le32_to_cpu(f[1]),
- pp->ncq_saw_spurious_sdb_cnt < 10 ?
- "" : ", shutting up");
-
- pp->ncq_saw_spurious_sdb_cnt++;
+ le32_to_cpu(f[0]), le32_to_cpu(f[1]));
+ ehi->err_mask |= AC_ERR_HSM;
+ ehi->action |= ATA_EH_SOFTRESET;
+ ata_port_freeze(ap);
+ } else {
+ if (!pp->ncq_saw_sdb)
+ ata_port_printk(ap, KERN_INFO,
+ "spurious SDB FIS %08x:%08x during NCQ, "
+ "this message won't be printed again\n",
+ le32_to_cpu(f[0]), le32_to_cpu(f[1]));
+ pp->ncq_saw_sdb = 1;
+ }
known_irq = 1;
}
@@ -1247,7 +1352,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ahci_port_base(ap);
if (qc->tf.protocol == ATA_PROT_NCQ)
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1259,8 +1364,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
static void ahci_freeze(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = ahci_port_base(ap);
/* turn IRQ off */
writel(0, port_mmio + PORT_IRQ_MASK);
@@ -1269,7 +1373,7 @@ static void ahci_freeze(struct ata_port *ap)
static void ahci_thaw(struct ata_port *ap)
{
void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+ void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
/* clear IRQ */
@@ -1283,13 +1387,10 @@ static void ahci_thaw(struct ata_port *ap)
static void ahci_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
/* restart engine */
- ahci_stop_engine(port_mmio);
- ahci_start_engine(port_mmio);
+ ahci_stop_engine(ap);
+ ahci_start_engine(ap);
}
/* perform recovery */
@@ -1299,13 +1400,10 @@ static void ahci_error_handler(struct ata_port *ap)
static void ahci_vt8251_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
/* restart engine */
- ahci_stop_engine(port_mmio);
- ahci_start_engine(port_mmio);
+ ahci_stop_engine(ap);
+ ahci_start_engine(ap);
}
/* perform recovery */
@@ -1316,35 +1414,26 @@ static void ahci_vt8251_error_handler(struct ata_port *ap)
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
- if (qc->flags & ATA_QCFLAG_FAILED)
- qc->err_mask |= AC_ERR_OTHER;
-
- if (qc->err_mask) {
+ if (qc->flags & ATA_QCFLAG_FAILED) {
/* make DMA engine forget about the failed command */
- ahci_stop_engine(port_mmio);
- ahci_start_engine(port_mmio);
+ ahci_stop_engine(ap);
+ ahci_start_engine(ap);
}
}
+#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
{
- struct ahci_host_priv *hpriv = ap->host->private_data;
- struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const char *emsg = NULL;
int rc;
- rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+ rc = ahci_deinit_port(ap, &emsg);
if (rc == 0)
- ahci_power_down(port_mmio, hpriv->cap);
+ ahci_power_down(ap);
else {
ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
- ahci_init_port(port_mmio, hpriv->cap,
- pp->cmd_slot_dma, pp->rx_fis_dma);
+ ahci_init_port(ap);
}
return rc;
@@ -1352,13 +1441,8 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
static int ahci_port_resume(struct ata_port *ap)
{
- struct ahci_port_priv *pp = ap->private_data;
- struct ahci_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
- ahci_power_up(port_mmio, hpriv->cap);
- ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+ ahci_power_up(ap);
+ ahci_init_port(ap);
return 0;
}
@@ -1386,8 +1470,6 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
static int ahci_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
- struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
int rc;
rc = ata_pci_device_do_resume(pdev);
@@ -1395,26 +1477,23 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
return rc;
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
- rc = ahci_reset_controller(mmio, pdev);
+ rc = ahci_reset_controller(host);
if (rc)
return rc;
- ahci_init_controller(mmio, pdev, host->n_ports,
- host->ports[0]->flags, hpriv);
+ ahci_init_controller(host);
}
ata_host_resume(host);
return 0;
}
+#endif
static int ahci_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
- struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
void *mem;
dma_addr_t mem_dma;
int rc;
@@ -1462,85 +1541,29 @@ static int ahci_port_start(struct ata_port *ap)
ap->private_data = pp;
/* power up port */
- ahci_power_up(port_mmio, hpriv->cap);
+ ahci_power_up(ap);
/* initialize port */
- ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+ ahci_init_port(ap);
return 0;
}
static void ahci_port_stop(struct ata_port *ap)
{
- struct ahci_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
- void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const char *emsg = NULL;
int rc;
/* de-initialize port */
- rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+ rc = ahci_deinit_port(ap, &emsg);
if (rc)
ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
}
-static void ahci_setup_port(struct ata_ioports *port, void __iomem *base,
- unsigned int port_idx)
-{
- VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
- base = ahci_port_base(base, port_idx);
- VPRINTK("base now==0x%lx\n", base);
-
- port->cmd_addr = base;
- port->scr_addr = base + PORT_SCR;
-
- VPRINTK("EXIT\n");
-}
-
-static int ahci_host_init(struct ata_probe_ent *probe_ent)
+static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
{
- struct ahci_host_priv *hpriv = probe_ent->private_data;
- struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
- unsigned int i, cap_n_ports, using_dac;
int rc;
- rc = ahci_reset_controller(mmio, pdev);
- if (rc)
- return rc;
-
- hpriv->cap = readl(mmio + HOST_CAP);
- hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
- cap_n_ports = ahci_nr_ports(hpriv->cap);
-
- VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
- hpriv->cap, hpriv->port_map, cap_n_ports);
-
- if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
- unsigned int n_ports = cap_n_ports;
- u32 port_map = hpriv->port_map;
- int max_port = 0;
-
- for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
- if (port_map & (1 << i)) {
- n_ports--;
- port_map &= ~(1 << i);
- max_port = i;
- } else
- probe_ent->dummy_port_mask |= 1 << i;
- }
-
- if (n_ports || port_map)
- dev_printk(KERN_WARNING, &pdev->dev,
- "nr_ports (%u) and implemented port map "
- "(0x%x) don't match\n",
- cap_n_ports, hpriv->port_map);
-
- probe_ent->n_ports = max_port + 1;
- } else
- probe_ent->n_ports = cap_n_ports;
-
- using_dac = hpriv->cap & HOST_CAP_64;
if (using_dac &&
!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
@@ -1566,23 +1589,14 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
return rc;
}
}
-
- for (i = 0; i < probe_ent->n_ports; i++)
- ahci_setup_port(&probe_ent->port[i], mmio, i);
-
- ahci_init_controller(mmio, pdev, probe_ent->n_ports,
- probe_ent->port_flags, hpriv);
-
- pci_set_master(pdev);
-
return 0;
}
-static void ahci_print_info(struct ata_probe_ent *probe_ent)
+static void ahci_print_info(struct ata_host *host)
{
- struct ahci_host_priv *hpriv = probe_ent->private_data;
- struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
+ struct ahci_host_priv *hpriv = host->private_data;
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
u32 vers, cap, impl, speed;
const char *speed_s;
u16 cc;
@@ -1652,11 +1666,12 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- unsigned int board_idx = (unsigned int) ent->driver_data;
+ struct ata_port_info pi = ahci_port_info[ent->driver_data];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
struct device *dev = &pdev->dev;
- struct ata_probe_ent *probe_ent;
struct ahci_host_priv *hpriv;
- int rc;
+ struct ata_host *host;
+ int i, rc;
VPRINTK("ENTER\n");
@@ -1665,13 +1680,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- if (pdev->vendor == PCI_VENDOR_ID_JMICRON) {
- /* Function 1 is the PATA controller except on the 368, where
- we are not AHCI anyway */
- if (PCI_FUNC(pdev->devfn))
- return -ENODEV;
- }
-
+ /* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -1685,44 +1694,49 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_enable_msi(pdev))
pci_intx(pdev, 1);
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
- probe_ent->sht = ahci_port_info[board_idx].sht;
- probe_ent->port_flags = ahci_port_info[board_idx].flags;
- probe_ent->pio_mask = ahci_port_info[board_idx].pio_mask;
- probe_ent->udma_mask = ahci_port_info[board_idx].udma_mask;
- probe_ent->port_ops = ahci_port_info[board_idx].port_ops;
+ /* save initial config */
+ ahci_save_initial_config(pdev, &pi, hpriv);
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
- probe_ent->private_data = hpriv;
+ /* prepare host */
+ if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ))
+ pi.flags |= ATA_FLAG_NCQ;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
+ if (!host)
+ return -ENOMEM;
+ host->iomap = pcim_iomap_table(pdev);
+ host->private_data = hpriv;
+
+ for (i = 0; i < host->n_ports; i++) {
+ if (hpriv->port_map & (1 << i)) {
+ struct ata_port *ap = host->ports[i];
+ void __iomem *port_mmio = ahci_port_base(ap);
+
+ ap->ioaddr.cmd_addr = port_mmio;
+ ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
+ } else
+ host->ports[i]->ops = &ata_dummy_port_ops;
+ }
/* initialize adapter */
- rc = ahci_host_init(probe_ent);
+ rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
if (rc)
return rc;
- if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
- (hpriv->cap & HOST_CAP_NCQ))
- probe_ent->port_flags |= ATA_FLAG_NCQ;
-
- ahci_print_info(probe_ent);
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
- if (!ata_device_add(probe_ent))
- return -ENODEV;
+ ahci_init_controller(host);
+ ahci_print_info(host);
- devm_kfree(dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
+ &ahci_sht);
}
static int __init ahci_init(void)
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index be66ea08da55..92a491ddd030 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -26,42 +26,13 @@
#include <linux/libata.h>
#define DRV_NAME "ata_generic"
-#define DRV_VERSION "0.2.10"
+#define DRV_VERSION "0.2.11"
/*
* A generic parallel ATA driver using libata
*/
/**
- * generic_pre_reset - probe begin
- * @ap: ATA port
- *
- * Set up cable type and use generic probe init
- */
-
-static int generic_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
-}
-
-
-/**
- * generic_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- * @classes:
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-
-static void generic_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, generic_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-/**
* generic_set_mode - mode setting
* @ap: interface to set up
* @unused: returned device on error
@@ -90,10 +61,10 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
/* We do need the right mode information for DMA or PIO
and this comes from the current configuration flags */
if (dma_enabled & (1 << (5 + i))) {
- dev->xfer_mode = XFER_MW_DMA_0;
- dev->xfer_shift = ATA_SHIFT_MWDMA;
+ ata_id_to_dma_mode(dev, XFER_MW_DMA_0);
dev->flags &= ~ATA_DFLAG_PIO;
} else {
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
dev->flags |= ATA_DFLAG_PIO;
@@ -119,8 +90,10 @@ static struct scsi_host_template generic_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations generic_port_ops = {
@@ -142,8 +115,9 @@ static struct ata_port_operations generic_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = generic_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -230,8 +204,10 @@ static struct pci_driver ata_generic_pci_driver = {
.id_table = ata_generic,
.probe = ata_generic_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init ata_generic_init(void)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 4d716c7347e7..55d306a3e538 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -93,7 +93,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "2.00ac7"
+#define DRV_VERSION "2.11"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -155,11 +155,11 @@ struct piix_host_priv {
static int piix_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent);
static void piix_pata_error_handler(struct ata_port *ap);
-static void ich_pata_error_handler(struct ata_port *ap);
static void piix_sata_error_handler(struct ata_port *ap);
static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
+static int ich_pata_cable_detect(struct ata_port *ap);
static unsigned int in_module_init = 1;
@@ -169,8 +169,6 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */
/* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */
{ 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 },
- { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
- { 0x8086, 0x25a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* Intel PIIX4 */
{ 0x8086, 0x7199, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 },
/* Intel PIIX4 */
@@ -255,8 +253,10 @@ static struct pci_driver piix_pci_driver = {
.id_table = piix_pci_tbl,
.probe = piix_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static struct scsi_host_template piix_sht = {
@@ -275,8 +275,10 @@ static struct scsi_host_template piix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations piix_pata_ops = {
@@ -303,6 +305,7 @@ static const struct ata_port_operations piix_pata_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = piix_pata_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
@@ -334,8 +337,9 @@ static const struct ata_port_operations ich_pata_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ich_pata_error_handler,
+ .error_handler = piix_pata_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ich_pata_cable_detect,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
@@ -578,12 +582,13 @@ static const struct ich_laptop ich_laptop[] = {
/* devid, subvendor, subdev */
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
+ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
/* end marker */
{ 0, }
};
/**
- * piix_pata_cbl_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
*
* Read 80c cable indicator from ATA PCI device's PCI config
@@ -593,23 +598,18 @@ static const struct ich_laptop ich_laptop[] = {
* None (inherited from caller).
*/
-static void ich_pata_cbl_detect(struct ata_port *ap)
+static int ich_pata_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
const struct ich_laptop *lap = &ich_laptop[0];
u8 tmp, mask;
- /* no 80c support in host controller? */
- if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
- goto cbl40;
-
/* Check for specials - Acer Aspire 5602WLMi */
while (lap->device) {
if (lap->device == pdev->device &&
lap->subvendor == pdev->subsystem_vendor &&
lap->subdevice == pdev->subsystem_device) {
- ap->cbl = ATA_CBL_PATA40_SHORT;
- return;
+ return ATA_CBL_PATA40_SHORT;
}
lap++;
}
@@ -618,20 +618,14 @@ static void ich_pata_cbl_detect(struct ata_port *ap)
mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
if ((tmp & mask) == 0)
- goto cbl40;
-
- ap->cbl = ATA_CBL_PATA80;
- return;
-
-cbl40:
- ap->cbl = ATA_CBL_PATA40;
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
}
/**
* piix_pata_prereset - prereset for PATA host controller
* @ap: Target port
*
- *
* LOCKING:
* None (inherited from caller).
*/
@@ -641,8 +635,6 @@ static int piix_pata_prereset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
return -ENOENT;
-
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -653,35 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap)
}
-/**
- * ich_pata_prereset - prereset for PATA host controller
- * @ap: Target port
- *
- *
- * LOCKING:
- * None (inherited from caller).
- */
-static int ich_pata_prereset(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
- if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
- ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
- ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
- return 0;
- }
-
- ich_pata_cbl_detect(ap);
-
- return ata_std_prereset(ap);
-}
-
-static void ich_pata_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ich_pata_prereset, ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
static void piix_sata_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
new file mode 100644
index 000000000000..03a0acff6cfa
--- /dev/null
+++ b/drivers/ata/libata-acpi.c
@@ -0,0 +1,709 @@
+/*
+ * libata-acpi.c
+ * Provides ACPI support for PATA/SATA.
+ *
+ * Copyright (C) 2006 Intel Corp.
+ * Copyright (C) 2006 Randy Dunlap
+ */
+
+#include <linux/ata.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/libata.h>
+#include <linux/pci.h>
+#include "libata.h"
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acnames.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acexcep.h>
+#include <acpi/acmacros.h>
+#include <acpi/actypes.h>
+
+#define SATA_ROOT_PORT(x) (((x) >> 16) & 0xffff)
+#define SATA_PORT_NUMBER(x) ((x) & 0xffff) /* or NO_PORT_MULT */
+#define NO_PORT_MULT 0xffff
+#define SATA_ADR_RSVD 0xffffffff
+
+#define REGS_PER_GTF 7
+struct taskfile_array {
+ u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
+};
+
+/*
+ * Helper - belongs in the PCI layer somewhere eventually
+ */
+static int is_pci_dev(struct device *dev)
+{
+ return (dev->bus == &pci_bus_type);
+}
+
+/**
+ * sata_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * This function is somewhat SATA-specific. Or at least the
+ * PATA & SATA versions of this function are different,
+ * so it's not entirely generic code.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
+ acpi_integer *pcidevfn)
+{
+ struct pci_dev *pci_dev;
+ acpi_integer addr;
+
+ if (!is_pci_dev(dev))
+ return -ENODEV;
+
+ pci_dev = to_pci_dev(dev); /* NOTE: PCI-specific */
+ /* Please refer to the ACPI spec for the syntax of _ADR. */
+ addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+ *pcidevfn = addr;
+ *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+ if (!*handle)
+ return -ENODEV;
+ return 0;
+}
+
+/**
+ * pata_get_dev_handle - finds acpi_handle and PCI device.function
+ * @dev: device to locate
+ * @handle: returned acpi_handle for @dev
+ * @pcidevfn: return PCI device.func for @dev
+ *
+ * The PATA and SATA versions of this function are different.
+ *
+ * Returns 0 on success, <0 on error.
+ */
+static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
+ acpi_integer *pcidevfn)
+{
+ unsigned int bus, devnum, func;
+ acpi_integer addr;
+ acpi_handle dev_handle, parent_handle;
+ struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
+ .pointer = NULL};
+ acpi_status status;
+ struct acpi_device_info *dinfo = NULL;
+ int ret = -ENODEV;
+ struct pci_dev *pdev;
+
+ if (!is_pci_dev(dev))
+ return -ENODEV;
+
+ pdev = to_pci_dev(dev);
+
+ bus = pdev->bus->number;
+ devnum = PCI_SLOT(pdev->devfn);
+ func = PCI_FUNC(pdev->devfn);
+
+ dev_handle = DEVICE_ACPI_HANDLE(dev);
+ parent_handle = DEVICE_ACPI_HANDLE(dev->parent);
+
+ status = acpi_get_object_info(parent_handle, &buffer);
+ if (ACPI_FAILURE(status))
+ goto err;
+
+ dinfo = buffer.pointer;
+ if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+ dinfo->address == bus) {
+ /* ACPI spec for _ADR for PCI bus: */
+ addr = (acpi_integer)(devnum << 16 | func);
+ *pcidevfn = addr;
+ *handle = dev_handle;
+ } else {
+ goto err;
+ }
+
+ if (!*handle)
+ goto err;
+ ret = 0;
+err:
+ kfree(dinfo);
+ return ret;
+}
+
+struct walk_info { /* can be trimmed some */
+ struct device *dev;
+ struct acpi_device *adev;
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ unsigned int drivenum;
+ acpi_handle obj_handle;
+ struct ata_port *ataport;
+ struct ata_device *atadev;
+ u32 sata_adr;
+ int status;
+ char basepath[ACPI_PATHNAME_MAX];
+ int basepath_len;
+};
+
+static acpi_status get_devices(acpi_handle handle,
+ u32 level, void *context, void **return_value)
+{
+ acpi_status status;
+ struct walk_info *winfo = context;
+ struct acpi_buffer namebuf = {ACPI_ALLOCATE_BUFFER, NULL};
+ char *pathname;
+ struct acpi_buffer buffer;
+ struct acpi_device_info *dinfo;
+
+ status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &namebuf);
+ if (status)
+ goto ret;
+ pathname = namebuf.pointer;
+
+ buffer.length = ACPI_ALLOCATE_BUFFER;
+ buffer.pointer = NULL;
+ status = acpi_get_object_info(handle, &buffer);
+ if (ACPI_FAILURE(status))
+ goto out2;
+
+ dinfo = buffer.pointer;
+
+ /* find full device path name for pcidevfn */
+ if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
+ dinfo->address == winfo->pcidevfn) {
+ if (ata_msg_probe(winfo->ataport))
+ ata_dev_printk(winfo->atadev, KERN_DEBUG,
+ ":%s: matches pcidevfn (0x%llx)\n",
+ pathname, winfo->pcidevfn);
+ strlcpy(winfo->basepath, pathname,
+ sizeof(winfo->basepath));
+ winfo->basepath_len = strlen(pathname);
+ goto out;
+ }
+
+ /* if basepath is not yet known, ignore this object */
+ if (!winfo->basepath_len)
+ goto out;
+
+ /* if this object is in scope of basepath, maybe use it */
+ if (strncmp(pathname, winfo->basepath,
+ winfo->basepath_len) == 0) {
+ if (!(dinfo->valid & ACPI_VALID_ADR))
+ goto out;
+ if (ata_msg_probe(winfo->ataport))
+ ata_dev_printk(winfo->atadev, KERN_DEBUG,
+ "GOT ONE: (%s) root_port = 0x%llx,"
+ " port_num = 0x%llx\n", pathname,
+ SATA_ROOT_PORT(dinfo->address),
+ SATA_PORT_NUMBER(dinfo->address));
+ /* heuristics: */
+ if (SATA_PORT_NUMBER(dinfo->address) != NO_PORT_MULT)
+ if (ata_msg_probe(winfo->ataport))
+ ata_dev_printk(winfo->atadev,
+ KERN_DEBUG, "warning: don't"
+ " know how to handle SATA port"
+ " multiplier\n");
+ if (SATA_ROOT_PORT(dinfo->address) ==
+ winfo->ataport->port_no &&
+ SATA_PORT_NUMBER(dinfo->address) == NO_PORT_MULT) {
+ if (ata_msg_probe(winfo->ataport))
+ ata_dev_printk(winfo->atadev,
+ KERN_DEBUG,
+ "THIS ^^^^^ is the requested"
+ " SATA drive (handle = 0x%p)\n",
+ handle);
+ winfo->sata_adr = dinfo->address;
+ winfo->obj_handle = handle;
+ }
+ }
+out:
+ kfree(dinfo);
+out2:
+ kfree(pathname);
+
+ret:
+ return status;
+}
+
+/* Get the SATA drive _ADR object. */
+static int get_sata_adr(struct device *dev, acpi_handle handle,
+ acpi_integer pcidevfn, unsigned int drive,
+ struct ata_port *ap,
+ struct ata_device *atadev, u32 *dev_adr)
+{
+ acpi_status status;
+ struct walk_info *winfo;
+ int err = -ENOMEM;
+
+ winfo = kzalloc(sizeof(struct walk_info), GFP_KERNEL);
+ if (!winfo)
+ goto out;
+
+ winfo->dev = dev;
+ winfo->atadev = atadev;
+ winfo->ataport = ap;
+ if (acpi_bus_get_device(handle, &winfo->adev) < 0)
+ if (ata_msg_probe(ap))
+ ata_dev_printk(winfo->atadev, KERN_DEBUG,
+ "acpi_bus_get_device failed\n");
+ winfo->handle = handle;
+ winfo->pcidevfn = pcidevfn;
+ winfo->drivenum = drive;
+
+ status = acpi_get_devices(NULL, get_devices, winfo, NULL);
+ if (ACPI_FAILURE(status)) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(winfo->atadev, KERN_DEBUG,
+ "%s: acpi_get_devices failed\n",
+ __FUNCTION__);
+ err = -ENODEV;
+ } else {
+ *dev_adr = winfo->sata_adr;
+ atadev->obj_handle = winfo->obj_handle;
+ err = 0;
+ }
+ kfree(winfo);
+out:
+ return err;
+}
+
+/**
+ * do_drive_get_GTF - get the drive bootup default taskfile settings
+ * @ap: the ata_port for the drive
+ * @ix: target ata_device (drive) index
+ * @gtf_length: number of bytes of _GTF data returned at @gtf_address
+ * @gtf_address: buffer containing _GTF taskfile arrays
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * The _GTF method has no input parameters.
+ * It returns a variable number of register set values (registers
+ * hex 1F1..1F7, taskfiles).
+ * The <variable number> is not known in advance, so have ACPI-CA
+ * allocate the buffer as needed and return it, then free it later.
+ *
+ * The returned @gtf_length and @gtf_address are only valid if the
+ * function return value is 0.
+ */
+static int do_drive_get_GTF(struct ata_port *ap, int ix,
+ unsigned int *gtf_length, unsigned long *gtf_address,
+ unsigned long *obj_loc)
+{
+ acpi_status status;
+ acpi_handle dev_handle = NULL;
+ acpi_handle chan_handle, drive_handle;
+ acpi_integer pcidevfn = 0;
+ u32 dev_adr;
+ struct acpi_buffer output;
+ union acpi_object *out_obj;
+ struct device *dev = ap->host->dev;
+ struct ata_device *atadev = &ap->device[ix];
+ int err = -ENODEV;
+
+ *gtf_length = 0;
+ *gtf_address = 0UL;
+ *obj_loc = 0UL;
+
+ if (libata_noacpi)
+ return 0;
+
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+ __FUNCTION__, ap->port_no);
+
+ if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: "
+ "ata_dev_present: %d, PORT_DISABLED: %lu\n",
+ __FUNCTION__, ata_dev_enabled(atadev),
+ ap->flags & ATA_FLAG_DISABLED);
+ goto out;
+ }
+
+ /* Don't continue if device has no _ADR method.
+ * _GTF is intended for known motherboard devices. */
+ if (!(ap->cbl == ATA_CBL_SATA)) {
+ err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+ if (err < 0) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: pata_get_dev_handle failed (%d)\n",
+ __FUNCTION__, err);
+ goto out;
+ }
+ } else {
+ err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+ if (err < 0) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: sata_get_dev_handle failed (%d\n",
+ __FUNCTION__, err);
+ goto out;
+ }
+ }
+
+ /* Get this drive's _ADR info. if not already known. */
+ if (!atadev->obj_handle) {
+ if (!(ap->cbl == ATA_CBL_SATA)) {
+ /* get child objects of dev_handle == channel objects,
+ * + _their_ children == drive objects */
+ /* channel is ap->port_no */
+ chan_handle = acpi_get_child(dev_handle,
+ ap->port_no);
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: chan adr=%d: chan_handle=0x%p\n",
+ __FUNCTION__, ap->port_no,
+ chan_handle);
+ if (!chan_handle) {
+ err = -ENODEV;
+ goto out;
+ }
+ /* TBD: could also check ACPI object VALID bits */
+ drive_handle = acpi_get_child(chan_handle, ix);
+ if (!drive_handle) {
+ err = -ENODEV;
+ goto out;
+ }
+ dev_adr = ix;
+ atadev->obj_handle = drive_handle;
+ } else { /* for SATA mode */
+ dev_adr = SATA_ADR_RSVD;
+ err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
+ ap, atadev, &dev_adr);
+ }
+ if (err < 0 || dev_adr == SATA_ADR_RSVD ||
+ !atadev->obj_handle) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: get_sata/pata_adr failed: "
+ "err=%d, dev_adr=%u, obj_handle=0x%p\n",
+ __FUNCTION__, err, dev_adr,
+ atadev->obj_handle);
+ goto out;
+ }
+ }
+
+ /* Setting up output buffer */
+ output.length = ACPI_ALLOCATE_BUFFER;
+ output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
+
+ /* _GTF has no input parameters */
+ err = -EIO;
+ status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
+ NULL, &output);
+ if (ACPI_FAILURE(status)) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: Run _GTF error: status = 0x%x\n",
+ __FUNCTION__, status);
+ goto out;
+ }
+
+ if (!output.length || !output.pointer) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+ "length or ptr is NULL (0x%llx, 0x%p)\n",
+ __FUNCTION__,
+ (unsigned long long)output.length,
+ output.pointer);
+ kfree(output.pointer);
+ goto out;
+ }
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ kfree(output.pointer);
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+ "error: expected object type of "
+ " ACPI_TYPE_BUFFER, got 0x%x\n",
+ __FUNCTION__, out_obj->type);
+ err = -ENOENT;
+ goto out;
+ }
+
+ if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
+ out_obj->buffer.length % REGS_PER_GTF) {
+ if (ata_msg_drv(ap))
+ ata_dev_printk(atadev, KERN_ERR,
+ "%s: unexpected GTF length (%d) or addr (0x%p)\n",
+ __FUNCTION__, out_obj->buffer.length,
+ out_obj->buffer.pointer);
+ err = -ENOENT;
+ goto out;
+ }
+
+ *gtf_length = out_obj->buffer.length;
+ *gtf_address = (unsigned long)out_obj->buffer.pointer;
+ *obj_loc = (unsigned long)out_obj;
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: returning "
+ "gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
+ __FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
+ err = 0;
+out:
+ return err;
+}
+
+/**
+ * taskfile_load_raw - send taskfile registers to host controller
+ * @ap: Port to which output is sent
+ * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
+ *
+ * Outputs ATA taskfile to standard ATA host controller using MMIO
+ * or PIO as indicated by the ATA_FLAG_MMIO flag.
+ * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
+ * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
+ * hob_lbal, hob_lbam, and hob_lbah.
+ *
+ * This function waits for idle (!BUSY and !DRQ) after writing
+ * registers. If the control register has a new value, this
+ * function also waits for idle after writing control and before
+ * writing the remaining registers.
+ *
+ * LOCKING: TBD:
+ * Inherited from caller.
+ */
+static void taskfile_load_raw(struct ata_port *ap,
+ struct ata_device *atadev,
+ const struct taskfile_array *gtf)
+{
+ struct ata_taskfile tf;
+ unsigned int err;
+
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
+ "%02x %02x %02x %02x %02x %02x %02x\n",
+ __FUNCTION__,
+ gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
+ gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
+
+ if ((gtf->tfa[0] == 0) && (gtf->tfa[1] == 0) && (gtf->tfa[2] == 0)
+ && (gtf->tfa[3] == 0) && (gtf->tfa[4] == 0) && (gtf->tfa[5] == 0)
+ && (gtf->tfa[6] == 0))
+ return;
+
+ ata_tf_init(atadev, &tf);
+
+ /* convert gtf to tf */
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
+ tf.protocol = atadev->class == ATA_DEV_ATAPI ?
+ ATA_PROT_ATAPI_NODATA : ATA_PROT_NODATA;
+ tf.feature = gtf->tfa[0]; /* 0x1f1 */
+ tf.nsect = gtf->tfa[1]; /* 0x1f2 */
+ tf.lbal = gtf->tfa[2]; /* 0x1f3 */
+ tf.lbam = gtf->tfa[3]; /* 0x1f4 */
+ tf.lbah = gtf->tfa[4]; /* 0x1f5 */
+ tf.device = gtf->tfa[5]; /* 0x1f6 */
+ tf.command = gtf->tfa[6]; /* 0x1f7 */
+
+ err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err && ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_ERR,
+ "%s: ata_exec_internal failed: %u\n",
+ __FUNCTION__, err);
+}
+
+/**
+ * do_drive_set_taskfiles - write the drive taskfile settings from _GTF
+ * @ap: the ata_port for the drive
+ * @atadev: target ata_device
+ * @gtf_length: total number of bytes of _GTF taskfiles
+ * @gtf_address: location of _GTF taskfile arrays
+ *
+ * This applies to both PATA and SATA drives.
+ *
+ * Write {gtf_address, length gtf_length} in groups of
+ * REGS_PER_GTF bytes.
+ */
+static int do_drive_set_taskfiles(struct ata_port *ap,
+ struct ata_device *atadev, unsigned int gtf_length,
+ unsigned long gtf_address)
+{
+ int err = -ENODEV;
+ int gtf_count = gtf_length / REGS_PER_GTF;
+ int ix;
+ struct taskfile_array *gtf;
+
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+ __FUNCTION__, ap->port_no);
+
+ if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
+ return 0;
+
+ if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
+ goto out;
+ if (!gtf_count) /* shouldn't be here */
+ goto out;
+
+ if (gtf_length % REGS_PER_GTF) {
+ if (ata_msg_drv(ap))
+ ata_dev_printk(atadev, KERN_ERR,
+ "%s: unexpected GTF length (%d)\n",
+ __FUNCTION__, gtf_length);
+ goto out;
+ }
+
+ for (ix = 0; ix < gtf_count; ix++) {
+ gtf = (struct taskfile_array *)
+ (gtf_address + ix * REGS_PER_GTF);
+
+ /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
+ taskfile_load_raw(ap, atadev, gtf);
+ }
+
+ err = 0;
+out:
+ return err;
+}
+
+/**
+ * ata_acpi_exec_tfs - get then write drive taskfile settings
+ * @ap: the ata_port for the drive
+ *
+ * This applies to both PATA and SATA drives.
+ */
+int ata_acpi_exec_tfs(struct ata_port *ap)
+{
+ int ix;
+ int ret =0;
+ unsigned int gtf_length;
+ unsigned long gtf_address;
+ unsigned long obj_loc;
+
+ if (libata_noacpi)
+ return 0;
+ /*
+ * TBD - implement PATA support. For now,
+ * we should not run GTF on PATA devices since some
+ * PATA require execution of GTM/STM before GTF.
+ */
+ if (!(ap->cbl == ATA_CBL_SATA))
+ return 0;
+
+ for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
+ if (!ata_dev_enabled(&ap->device[ix]))
+ continue;
+
+ ret = do_drive_get_GTF(ap, ix,
+ &gtf_length, &gtf_address, &obj_loc);
+ if (ret < 0) {
+ if (ata_msg_probe(ap))
+ ata_port_printk(ap, KERN_DEBUG,
+ "%s: get_GTF error (%d)\n",
+ __FUNCTION__, ret);
+ break;
+ }
+
+ ret = do_drive_set_taskfiles(ap, &ap->device[ix],
+ gtf_length, gtf_address);
+ kfree((void *)obj_loc);
+ if (ret < 0) {
+ if (ata_msg_probe(ap))
+ ata_port_printk(ap, KERN_DEBUG,
+ "%s: set_taskfiles error (%d)\n",
+ __FUNCTION__, ret);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * ata_acpi_push_id - send Identify data to drive
+ * @ap: the ata_port for the drive
+ * @ix: drive index
+ *
+ * _SDD ACPI object: for SATA mode only
+ * Must be after Identify (Packet) Device -- uses its data
+ * ATM this function never returns a failure. It is an optional
+ * method and if it fails for whatever reason, we should still
+ * just keep going.
+ */
+int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ int err;
+ struct device *dev = ap->host->dev;
+ struct ata_device *atadev = &ap->device[ix];
+ u32 dev_adr;
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[1];
+
+ if (libata_noacpi)
+ return 0;
+
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
+ __FUNCTION__, ix, ap->port_no);
+
+ /* Don't continue if not a SATA device. */
+ if (!(ap->cbl == ATA_CBL_SATA)) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: Not a SATA device\n", __FUNCTION__);
+ goto out;
+ }
+
+ /* Don't continue if device has no _ADR method.
+ * _SDD is intended for known motherboard devices. */
+ err = sata_get_dev_handle(dev, &handle, &pcidevfn);
+ if (err < 0) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: sata_get_dev_handle failed (%d\n",
+ __FUNCTION__, err);
+ goto out;
+ }
+
+ /* Get this drive's _ADR info, if not already known */
+ if (!atadev->obj_handle) {
+ dev_adr = SATA_ADR_RSVD;
+ err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
+ &dev_adr);
+ if (err < 0 || dev_adr == SATA_ADR_RSVD ||
+ !atadev->obj_handle) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s: get_sata_adr failed: "
+ "err=%d, dev_adr=%u, obj_handle=0x%p\n",
+ __FUNCTION__, err, dev_adr,
+ atadev->obj_handle);
+ goto out;
+ }
+ }
+
+ /* Give the drive Identify data to the drive via the _SDD method */
+ /* _SDD: set up input parameters */
+ input.count = 1;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
+ in_params[0].buffer.pointer = (u8 *)atadev->id;
+ /* Output buffer: _SDD has no output */
+
+ /* It's OK for _SDD to be missing too. */
+ swap_buf_le16(atadev->id, ATA_ID_WORDS);
+ status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
+ swap_buf_le16(atadev->id, ATA_ID_WORDS);
+
+ err = ACPI_FAILURE(status) ? -EIO : 0;
+ if (err < 0) {
+ if (ata_msg_probe(ap))
+ ata_dev_printk(atadev, KERN_DEBUG,
+ "%s _SDD error: status = 0x%x\n",
+ __FUNCTION__, status);
+ }
+
+ /* always return success */
+out:
+ return 0;
+}
+
+
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2cf8251728d2..ca67484af1eb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -59,7 +59,7 @@
#include "libata.h"
-#define DRV_VERSION "2.10" /* must be exactly four chars */
+#define DRV_VERSION "2.20" /* must be exactly four chars */
/* debounce timing parameters in msecs { interval, duration, timeout } */
@@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
static void ata_dev_xfermask(struct ata_device *dev);
-static unsigned int ata_unique_id = 1;
+unsigned int ata_print_id = 1;
static struct workqueue_struct *ata_wq;
struct workqueue_struct *ata_aux_wq;
@@ -89,10 +89,18 @@ int libata_fua = 0;
module_param_named(fua, libata_fua, int, 0444);
MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
+static int ata_ignore_hpa = 0;
+module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
+MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
+
static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
module_param(ata_probe_timeout, int, 0444);
MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
+int libata_noacpi = 1;
+module_param_named(noacpi, libata_noacpi, int, 0444);
+MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
@@ -311,9 +319,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->flags |= tf_flags;
- if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
- ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ &&
- likely(tag != ATA_TAG_INTERNAL)) {
+ if (ata_ncq_enabled(dev) && likely(tag != ATA_TAG_INTERNAL)) {
/* yay, NCQ */
if (!lba_48_ok(block, n_block))
return -ERANGE;
@@ -596,6 +602,8 @@ void ata_dev_disable(struct ata_device *dev)
{
if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) {
ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+ ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
+ ATA_DNXFER_QUIET);
dev->class++;
}
}
@@ -704,7 +712,7 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
* Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
*/
-static unsigned int
+unsigned int
ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err)
{
struct ata_taskfile tf;
@@ -804,6 +812,205 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
*p = '\0';
}
+static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
+{
+ u64 sectors = 0;
+
+ sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
+ sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
+ sectors |= (tf->hob_lbal & 0xff) << 24;
+ sectors |= (tf->lbah & 0xff) << 16;
+ sectors |= (tf->lbam & 0xff) << 8;
+ sectors |= (tf->lbal & 0xff);
+
+ return ++sectors;
+}
+
+static u64 ata_tf_to_lba(struct ata_taskfile *tf)
+{
+ u64 sectors = 0;
+
+ sectors |= (tf->device & 0x0f) << 24;
+ sectors |= (tf->lbah & 0xff) << 16;
+ sectors |= (tf->lbam & 0xff) << 8;
+ sectors |= (tf->lbal & 0xff);
+
+ return ++sectors;
+}
+
+/**
+ * ata_read_native_max_address_ext - LBA48 native max query
+ * @dev: Device to query
+ *
+ * Perform an LBA48 size query upon the device in question. Return the
+ * actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address_ext(struct ata_device *dev)
+{
+ unsigned int err;
+ struct ata_taskfile tf;
+
+ ata_tf_init(dev, &tf);
+
+ tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+ tf.protocol |= ATA_PROT_NODATA;
+ tf.device |= 0x40;
+
+ err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err)
+ return 0;
+
+ return ata_tf_to_lba48(&tf);
+}
+
+/**
+ * ata_read_native_max_address - LBA28 native max query
+ * @dev: Device to query
+ *
+ * Performa an LBA28 size query upon the device in question. Return the
+ * actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address(struct ata_device *dev)
+{
+ unsigned int err;
+ struct ata_taskfile tf;
+
+ ata_tf_init(dev, &tf);
+
+ tf.command = ATA_CMD_READ_NATIVE_MAX;
+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+ tf.protocol |= ATA_PROT_NODATA;
+ tf.device |= 0x40;
+
+ err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err)
+ return 0;
+
+ return ata_tf_to_lba(&tf);
+}
+
+/**
+ * ata_set_native_max_address_ext - LBA48 native max set
+ * @dev: Device to query
+ *
+ * Perform an LBA48 size set max upon the device in question. Return the
+ * actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
+{
+ unsigned int err;
+ struct ata_taskfile tf;
+
+ new_sectors--;
+
+ ata_tf_init(dev, &tf);
+
+ tf.command = ATA_CMD_SET_MAX_EXT;
+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+ tf.protocol |= ATA_PROT_NODATA;
+ tf.device |= 0x40;
+
+ tf.lbal = (new_sectors >> 0) & 0xff;
+ tf.lbam = (new_sectors >> 8) & 0xff;
+ tf.lbah = (new_sectors >> 16) & 0xff;
+
+ tf.hob_lbal = (new_sectors >> 24) & 0xff;
+ tf.hob_lbam = (new_sectors >> 32) & 0xff;
+ tf.hob_lbah = (new_sectors >> 40) & 0xff;
+
+ err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err)
+ return 0;
+
+ return ata_tf_to_lba48(&tf);
+}
+
+/**
+ * ata_set_native_max_address - LBA28 native max set
+ * @dev: Device to query
+ *
+ * Perform an LBA28 size set max upon the device in question. Return the
+ * actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
+{
+ unsigned int err;
+ struct ata_taskfile tf;
+
+ new_sectors--;
+
+ ata_tf_init(dev, &tf);
+
+ tf.command = ATA_CMD_SET_MAX;
+ tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+ tf.protocol |= ATA_PROT_NODATA;
+
+ tf.lbal = (new_sectors >> 0) & 0xff;
+ tf.lbam = (new_sectors >> 8) & 0xff;
+ tf.lbah = (new_sectors >> 16) & 0xff;
+ tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;
+
+ err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err)
+ return 0;
+
+ return ata_tf_to_lba(&tf);
+}
+
+/**
+ * ata_hpa_resize - Resize a device with an HPA set
+ * @dev: Device to resize
+ *
+ * Read the size of an LBA28 or LBA48 disk with HPA features and resize
+ * it if required to the full size of the media. The caller must check
+ * the drive has the HPA feature set enabled.
+ */
+
+static u64 ata_hpa_resize(struct ata_device *dev)
+{
+ u64 sectors = dev->n_sectors;
+ u64 hpa_sectors;
+
+ if (ata_id_has_lba48(dev->id))
+ hpa_sectors = ata_read_native_max_address_ext(dev);
+ else
+ hpa_sectors = ata_read_native_max_address(dev);
+
+ /* if no hpa, both should be equal */
+ ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, "
+ "hpa_sectors = %lld\n",
+ __FUNCTION__, (long long)sectors, (long long)hpa_sectors);
+
+ if (hpa_sectors > sectors) {
+ ata_dev_printk(dev, KERN_INFO,
+ "Host Protected Area detected:\n"
+ "\tcurrent size: %lld sectors\n"
+ "\tnative size: %lld sectors\n",
+ (long long)sectors, (long long)hpa_sectors);
+
+ if (ata_ignore_hpa) {
+ if (ata_id_has_lba48(dev->id))
+ hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
+ else
+ hpa_sectors = ata_set_native_max_address(dev,
+ hpa_sectors);
+
+ if (hpa_sectors) {
+ ata_dev_printk(dev, KERN_INFO, "native size "
+ "increased to %lld sectors\n",
+ (long long)hpa_sectors);
+ return hpa_sectors;
+ }
+ }
+ }
+ return sectors;
+}
+
static u64 ata_id_n_sectors(const u16 *id)
{
if (ata_id_has_lba(id)) {
@@ -820,6 +1027,48 @@ static u64 ata_id_n_sectors(const u16 *id)
}
/**
+ * ata_id_to_dma_mode - Identify DMA mode from id block
+ * @dev: device to identify
+ * @unknown: mode to assume if we cannot tell
+ *
+ * Set up the timing values for the device based upon the identify
+ * reported values for the DMA mode. This function is used by drivers
+ * which rely upon firmware configured modes, but wish to report the
+ * mode correctly when possible.
+ *
+ * In addition we emit similarly formatted messages to the default
+ * ata_dev_set_mode handler, in order to provide consistency of
+ * presentation.
+ */
+
+void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown)
+{
+ unsigned int mask;
+ u8 mode;
+
+ /* Pack the DMA modes */
+ mask = ((dev->id[63] >> 8) << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA;
+ if (dev->id[53] & 0x04)
+ mask |= ((dev->id[88] >> 8) << ATA_SHIFT_UDMA) & ATA_MASK_UDMA;
+
+ /* Select the mode in use */
+ mode = ata_xfer_mask2mode(mask);
+
+ if (mode != 0) {
+ ata_dev_printk(dev, KERN_INFO, "configured for %s\n",
+ ata_mode_string(mask));
+ } else {
+ /* SWDMA perhaps ? */
+ mode = unknown;
+ ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
+ }
+
+ /* Configure the device reporting */
+ dev->xfer_mode = mode;
+ dev->xfer_shift = ata_xfer_mode2shift(mode);
+}
+
+/**
* ata_noop_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
* @device: ATA device (numbered from zero) to select
@@ -887,8 +1136,8 @@ void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep)
{
if (ata_msg_probe(ap))
- ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: "
- "device %u, wait %u\n", ap->id, device, wait);
+ ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
+ "device %u, wait %u\n", device, wait);
if (wait)
ata_wait_idle(ap);
@@ -1224,12 +1473,16 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
if (ap->ops->post_internal_cmd)
ap->ops->post_internal_cmd(qc);
- if ((qc->flags & ATA_QCFLAG_FAILED) && !qc->err_mask) {
- if (ata_msg_warn(ap))
- ata_dev_printk(dev, KERN_WARNING,
- "zero err_mask for failed "
- "internal command, assuming AC_ERR_OTHER\n");
- qc->err_mask |= AC_ERR_OTHER;
+ /* perform minimal error analysis */
+ if (qc->flags & ATA_QCFLAG_FAILED) {
+ if (qc->result_tf.command & (ATA_ERR | ATA_DF))
+ qc->err_mask |= AC_ERR_DEV;
+
+ if (!qc->err_mask)
+ qc->err_mask |= AC_ERR_OTHER;
+
+ if (qc->err_mask & ~AC_ERR_OTHER)
+ qc->err_mask &= ~AC_ERR_OTHER;
}
/* finish up */
@@ -1333,30 +1586,44 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
* Check if the current speed of the device requires IORDY. Used
* by various controllers for chip configuration.
*/
-
+
unsigned int ata_pio_need_iordy(const struct ata_device *adev)
{
- int pio;
- int speed = adev->pio_mode - XFER_PIO_0;
-
- if (speed < 2)
+ /* Controller doesn't support IORDY. Probably a pointless check
+ as the caller should know this */
+ if (adev->ap->flags & ATA_FLAG_NO_IORDY)
return 0;
- if (speed > 2)
+ /* PIO3 and higher it is mandatory */
+ if (adev->pio_mode > XFER_PIO_2)
+ return 1;
+ /* We turn it on when possible */
+ if (ata_id_has_iordy(adev->id))
return 1;
+ return 0;
+}
+/**
+ * ata_pio_mask_no_iordy - Return the non IORDY mask
+ * @adev: ATA device
+ *
+ * Compute the highest mode possible if we are not using iordy. Return
+ * -1 if no iordy mode is available.
+ */
+
+static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
+{
/* If we have no drive specific rule, then PIO 2 is non IORDY */
-
if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */
- pio = adev->id[ATA_ID_EIDE_PIO];
+ u16 pio = adev->id[ATA_ID_EIDE_PIO];
/* Is the speed faster than the drive allows non IORDY ? */
if (pio) {
/* This is cycle times not frequency - watch the logic! */
if (pio > 240) /* PIO2 is 240nS per cycle */
- return 1;
- return 0;
+ return 3 << ATA_SHIFT_PIO;
+ return 7 << ATA_SHIFT_PIO;
}
}
- return 0;
+ return 3 << ATA_SHIFT_PIO;
}
/**
@@ -1385,14 +1652,13 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
struct ata_taskfile tf;
unsigned int err_mask = 0;
const char *reason;
+ int tried_spinup = 0;
int rc;
if (ata_msg_ctl(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n",
- __FUNCTION__, ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
-
retry:
ata_tf_init(dev, &tf);
@@ -1426,7 +1692,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) {
DPRINTK("ata%u.%d: NODEV after polling detection\n",
- ap->id, dev->devno);
+ ap->print_id, dev->devno);
return -ENOENT;
}
@@ -1449,6 +1715,32 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
goto err_out;
}
+ if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
+ tried_spinup = 1;
+ /*
+ * Drive powered-up in standby mode, and requires a specific
+ * SET_FEATURES spin-up subcommand before it will accept
+ * anything other than the original IDENTIFY command.
+ */
+ ata_tf_init(dev, &tf);
+ tf.command = ATA_CMD_SET_FEATURES;
+ tf.feature = SETFEATURES_SPINUP;
+ tf.protocol = ATA_PROT_NODATA;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+ if (err_mask) {
+ rc = -EIO;
+ reason = "SPINUP failed";
+ goto err_out;
+ }
+ /*
+ * If the drive initially returned incomplete IDENTIFY info,
+ * we now must reissue the IDENTIFY command.
+ */
+ if (id[2] == 0x37c8)
+ goto retry;
+ }
+
if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
/*
* The exact sequence expected by certain pre-ATA4 drives is:
@@ -1515,20 +1807,6 @@ static void ata_dev_config_ncq(struct ata_device *dev,
snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth);
}
-static void ata_set_port_max_cmd_len(struct ata_port *ap)
-{
- int i;
-
- if (ap->scsi_host) {
- unsigned int len = 0;
-
- for (i = 0; i < ATA_MAX_DEVICES; i++)
- len = max(len, ap->device[i].cdb_len);
-
- ap->scsi_host->max_cmd_len = len;
- }
-}
-
/**
* ata_dev_configure - Configure the specified ATA/ATAPI device
* @dev: Target device to configure
@@ -1554,15 +1832,23 @@ int ata_dev_configure(struct ata_device *dev)
int rc;
if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
- ata_dev_printk(dev, KERN_INFO,
- "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n",
- __FUNCTION__, ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n",
+ __FUNCTION__);
return 0;
}
if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n",
- __FUNCTION__, ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
+
+ /* set _SDD */
+ rc = ata_acpi_push_id(ap, dev->devno);
+ if (rc) {
+ ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
+ rc);
+ }
+
+ /* retrieve and execute the ATA task file of _GTF */
+ ata_acpi_exec_tfs(ap);
/* print device capabilities */
if (ata_msg_probe(ap))
@@ -1596,14 +1882,16 @@ int ata_dev_configure(struct ata_device *dev)
if (dev->class == ATA_DEV_ATA) {
if (ata_id_is_cfa(id)) {
if (id[162] & 1) /* CPRM may make this media unusable */
- ata_dev_printk(dev, KERN_WARNING, "ata%u: device %u supports DRM functions and may not be fully accessable.\n",
- ap->id, dev->devno);
+ ata_dev_printk(dev, KERN_WARNING,
+ "supports DRM functions and may "
+ "not be fully accessable.\n");
snprintf(revbuf, 7, "CFA");
}
else
snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));
dev->n_sectors = ata_id_n_sectors(id);
+ dev->n_sectors_boot = dev->n_sectors;
/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -1630,6 +1918,9 @@ int ata_dev_configure(struct ata_device *dev)
dev->flags |= ATA_DFLAG_FLUSH_EXT;
}
+ if (ata_id_hpa_enabled(dev->id))
+ dev->n_sectors = ata_hpa_resize(dev);
+
/* config NCQ */
ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
@@ -1665,7 +1956,7 @@ int ata_dev_configure(struct ata_device *dev)
"%s: %s, %s, max %s\n",
revbuf, modelbuf, fwrevbuf,
ata_mode_string(xfer_mask));
- ata_dev_printk(dev, KERN_INFO,
+ ata_dev_printk(dev, KERN_INFO,
"%Lu sectors, multi %u, CHS %u/%u/%u\n",
(unsigned long long)dev->n_sectors,
dev->multi_count, dev->cylinders,
@@ -1719,8 +2010,6 @@ int ata_dev_configure(struct ata_device *dev)
}
}
- ata_set_port_max_cmd_len(ap);
-
/* limit bridge transfers to udma5, 200 sectors */
if (ata_dev_knobble(dev)) {
if (ata_msg_drv(ap) && print_info)
@@ -1730,8 +2019,16 @@ int ata_dev_configure(struct ata_device *dev)
dev->max_sectors = ATA_MAX_SECTORS;
}
+ if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
+ dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
+ dev->max_sectors);
+
+ /* limit ATAPI DMA to R/W commands only */
+ if (ata_device_blacklisted(dev) & ATA_HORKAGE_DMA_RW_ONLY)
+ dev->horkage |= ATA_HORKAGE_DMA_RW_ONLY;
+
if (ap->ops->dev_config)
- ap->ops->dev_config(ap, dev);
+ ap->ops->dev_config(dev);
if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
@@ -1746,6 +2043,56 @@ err_out_nosup:
}
/**
+ * ata_cable_40wire - return 40 wire cable type
+ * @ap: port
+ *
+ * Helper method for drivers which want to hardwire 40 wire cable
+ * detection.
+ */
+
+int ata_cable_40wire(struct ata_port *ap)
+{
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * ata_cable_80wire - return 80 wire cable type
+ * @ap: port
+ *
+ * Helper method for drivers which want to hardwire 80 wire cable
+ * detection.
+ */
+
+int ata_cable_80wire(struct ata_port *ap)
+{
+ return ATA_CBL_PATA80;
+}
+
+/**
+ * ata_cable_unknown - return unknown PATA cable.
+ * @ap: port
+ *
+ * Helper method for drivers which have no PATA cable detection.
+ */
+
+int ata_cable_unknown(struct ata_port *ap)
+{
+ return ATA_CBL_PATA_UNK;
+}
+
+/**
+ * ata_cable_sata - return SATA cable type
+ * @ap: port
+ *
+ * Helper method for drivers which have SATA cables
+ */
+
+int ata_cable_sata(struct ata_port *ap)
+{
+ return ATA_CBL_SATA;
+}
+
+/**
* ata_bus_probe - Reset and probe ATA bus
* @ap: Bus to probe
*
@@ -1764,7 +2111,7 @@ int ata_bus_probe(struct ata_port *ap)
{
unsigned int classes[ATA_MAX_DEVICES];
int tries[ATA_MAX_DEVICES];
- int i, rc, down_xfermask;
+ int i, rc;
struct ata_device *dev;
ata_port_probe(ap);
@@ -1773,8 +2120,6 @@ int ata_bus_probe(struct ata_port *ap)
tries[i] = ATA_PROBE_MAX_TRIES;
retry:
- down_xfermask = 0;
-
/* reset and determine device classes */
ap->ops->phy_reset(ap);
@@ -1798,8 +2143,11 @@ int ata_bus_probe(struct ata_port *ap)
for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->device[i].pio_mode = XFER_PIO_0;
- /* read IDENTIFY page and configure devices */
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ /* read IDENTIFY page and configure devices. We have to do the identify
+ specific sequence bass-ackwards so that PDIAG- is released by
+ the slave device */
+
+ for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
dev = &ap->device[i];
if (tries[i])
@@ -1812,6 +2160,19 @@ int ata_bus_probe(struct ata_port *ap)
dev->id);
if (rc)
goto fail;
+ }
+
+ /* Now ask for the cable type as PDIAG- should have been released */
+ if (ap->ops->cable_detect)
+ ap->cbl = ap->ops->cable_detect(ap);
+
+ /* After the identify sequence we can now set up the devices. We do
+ this in the normal order so that the user doesn't get confused */
+
+ for(i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
+ if (!ata_dev_enabled(dev))
+ continue;
ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);
@@ -1822,10 +2183,8 @@ int ata_bus_probe(struct ata_port *ap)
/* configure transfer mode */
rc = ata_set_mode(ap, &dev);
- if (rc) {
- down_xfermask = 1;
+ if (rc)
goto fail;
- }
for (i = 0; i < ATA_MAX_DEVICES; i++)
if (ata_dev_enabled(&ap->device[i]))
@@ -1837,25 +2196,29 @@ int ata_bus_probe(struct ata_port *ap)
return -ENODEV;
fail:
+ tries[dev->devno]--;
+
switch (rc) {
case -EINVAL:
- case -ENODEV:
+ /* eeek, something went very wrong, give up */
tries[dev->devno] = 0;
break;
+
+ case -ENODEV:
+ /* give it just one more chance */
+ tries[dev->devno] = min(tries[dev->devno], 1);
case -EIO:
- sata_down_spd_limit(ap);
- /* fall through */
- default:
- tries[dev->devno]--;
- if (down_xfermask &&
- ata_down_xfermask_limit(dev, tries[dev->devno] == 1))
- tries[dev->devno] = 0;
+ if (tries[dev->devno] == 1) {
+ /* This is the last chance, better to slow
+ * down than lose it.
+ */
+ sata_down_spd_limit(ap);
+ ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+ }
}
- if (!tries[dev->devno]) {
- ata_down_xfermask_limit(dev, 1);
+ if (!tries[dev->devno])
ata_dev_disable(dev);
- }
goto retry;
}
@@ -1885,7 +2248,7 @@ void ata_port_probe(struct ata_port *ap)
* LOCKING:
* None.
*/
-static void sata_print_link_status(struct ata_port *ap)
+void sata_print_link_status(struct ata_port *ap)
{
u32 sstatus, scontrol, tmp;
@@ -2279,6 +2642,12 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
t->active += (t->cycle - (t->active + t->recover)) / 2;
t->recover = t->cycle - t->active;
}
+
+ /* In a few cases quantisation may produce enough errors to
+ leave t->cycle too low for the sum of active and recovery
+ if so we must correct this */
+ if (t->active + t->recover > t->cycle)
+ t->cycle = t->active + t->recover;
return 0;
}
@@ -2286,7 +2655,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
/**
* ata_down_xfermask_limit - adjust dev xfer masks downward
* @dev: Device to adjust xfer masks
- * @force_pio0: Force PIO0
+ * @sel: ATA_DNXFER_* selector
*
* Adjust xfer masks of @dev downward. Note that this function
* does not apply the change. Invoking ata_set_mode() afterwards
@@ -2298,37 +2667,78 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
* RETURNS:
* 0 on success, negative errno on failure
*/
-int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
+int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel)
{
- unsigned long xfer_mask;
- int highbit;
+ char buf[32];
+ unsigned int orig_mask, xfer_mask;
+ unsigned int pio_mask, mwdma_mask, udma_mask;
+ int quiet, highbit;
- xfer_mask = ata_pack_xfermask(dev->pio_mask, dev->mwdma_mask,
- dev->udma_mask);
+ quiet = !!(sel & ATA_DNXFER_QUIET);
+ sel &= ~ATA_DNXFER_QUIET;
- if (!xfer_mask)
- goto fail;
- /* don't gear down to MWDMA from UDMA, go directly to PIO */
- if (xfer_mask & ATA_MASK_UDMA)
- xfer_mask &= ~ATA_MASK_MWDMA;
+ xfer_mask = orig_mask = ata_pack_xfermask(dev->pio_mask,
+ dev->mwdma_mask,
+ dev->udma_mask);
+ ata_unpack_xfermask(xfer_mask, &pio_mask, &mwdma_mask, &udma_mask);
- highbit = fls(xfer_mask) - 1;
- xfer_mask &= ~(1 << highbit);
- if (force_pio0)
- xfer_mask &= 1 << ATA_SHIFT_PIO;
- if (!xfer_mask)
- goto fail;
+ switch (sel) {
+ case ATA_DNXFER_PIO:
+ highbit = fls(pio_mask) - 1;
+ pio_mask &= ~(1 << highbit);
+ break;
+
+ case ATA_DNXFER_DMA:
+ if (udma_mask) {
+ highbit = fls(udma_mask) - 1;
+ udma_mask &= ~(1 << highbit);
+ if (!udma_mask)
+ return -ENOENT;
+ } else if (mwdma_mask) {
+ highbit = fls(mwdma_mask) - 1;
+ mwdma_mask &= ~(1 << highbit);
+ if (!mwdma_mask)
+ return -ENOENT;
+ }
+ break;
+
+ case ATA_DNXFER_40C:
+ udma_mask &= ATA_UDMA_MASK_40C;
+ break;
+
+ case ATA_DNXFER_FORCE_PIO0:
+ pio_mask &= 1;
+ case ATA_DNXFER_FORCE_PIO:
+ mwdma_mask = 0;
+ udma_mask = 0;
+ break;
+
+ default:
+ BUG();
+ }
+
+ xfer_mask &= ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
+
+ if (!(xfer_mask & ATA_MASK_PIO) || xfer_mask == orig_mask)
+ return -ENOENT;
+
+ if (!quiet) {
+ if (xfer_mask & (ATA_MASK_MWDMA | ATA_MASK_UDMA))
+ snprintf(buf, sizeof(buf), "%s:%s",
+ ata_mode_string(xfer_mask),
+ ata_mode_string(xfer_mask & ATA_MASK_PIO));
+ else
+ snprintf(buf, sizeof(buf), "%s",
+ ata_mode_string(xfer_mask));
+
+ ata_dev_printk(dev, KERN_WARNING,
+ "limiting speed to %s\n", buf);
+ }
ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
&dev->udma_mask);
- ata_dev_printk(dev, KERN_WARNING, "limiting speed to %s\n",
- ata_mode_string(xfer_mask));
-
return 0;
-
- fail:
- return -EINVAL;
}
static int ata_dev_set_mode(struct ata_device *dev)
@@ -2367,12 +2777,13 @@ static int ata_dev_set_mode(struct ata_device *dev)
}
/**
- * ata_set_mode - Program timings and issue SET FEATURES - XFER
+ * ata_do_set_mode - Program timings and issue SET FEATURES - XFER
* @ap: port on which timings will be programmed
* @r_failed_dev: out paramter for failed device
*
- * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If
- * ata_set_mode() fails, pointer to the failing device is
+ * Standard implementation of the function used to tune and set
+ * ATA device disk transfer mode (PIO3, UDMA6, etc.). If
+ * ata_dev_set_mode() fails, pointer to the failing device is
* returned in @r_failed_dev.
*
* LOCKING:
@@ -2381,14 +2792,12 @@ static int ata_dev_set_mode(struct ata_device *dev)
* RETURNS:
* 0 on success, negative errno otherwise
*/
-int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+
+int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
{
struct ata_device *dev;
int i, rc = 0, used_dma = 0, found = 0;
- /* has private set_mode? */
- if (ap->ops->set_mode)
- return ap->ops->set_mode(ap, r_failed_dev);
/* step 1: calculate xfer_mask */
for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -2461,12 +2870,11 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
* host channels are not permitted to do so.
*/
if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX))
- ap->host->simplex_claimed = 1;
+ ap->host->simplex_claimed = ap;
/* step5: chip specific finalisation */
if (ap->ops->post_set_mode)
ap->ops->post_set_mode(ap);
-
out:
if (rc)
*r_failed_dev = dev;
@@ -2474,6 +2882,29 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
}
/**
+ * ata_set_mode - Program timings and issue SET FEATURES - XFER
+ * @ap: port on which timings will be programmed
+ * @r_failed_dev: out paramter for failed device
+ *
+ * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If
+ * ata_set_mode() fails, pointer to the failing device is
+ * returned in @r_failed_dev.
+ *
+ * LOCKING:
+ * PCI/etc. bus probe sem.
+ *
+ * RETURNS:
+ * 0 on success, negative errno otherwise
+ */
+int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+ /* has private set_mode? */
+ if (ap->ops->set_mode)
+ return ap->ops->set_mode(ap, r_failed_dev);
+ return ata_do_set_mode(ap, r_failed_dev);
+}
+
+/**
* ata_tf_to_host - issue ATA taskfile to host controller
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
@@ -2595,7 +3026,7 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- DPRINTK("ata%u: bus reset via SRST\n", ap->id);
+ DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
/* software reset. causes dev0 to be selected */
iowrite8(ap->ctl, ioaddr->ctl_addr);
@@ -2655,7 +3086,7 @@ void ata_bus_reset(struct ata_port *ap)
u8 err;
unsigned int dev0, dev1 = 0, devmask = 0;
- DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
+ DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
/* determine if device 0/1 are present */
if (ap->flags & ATA_FLAG_SATA_RESET)
@@ -3154,6 +3585,11 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
"%llu != %llu\n",
(unsigned long long)dev->n_sectors,
(unsigned long long)new_n_sectors);
+ /* Are we the boot time size - if so we appear to be the
+ same disk at this point and our HPA got reapplied */
+ if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors
+ && ata_id_hpa_enabled(new_id))
+ return 1;
return 0;
}
@@ -3242,16 +3678,30 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "WPI CDD-820", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA },
- { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
+ /* Weird ATAPI devices */
+ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 |
+ ATA_HORKAGE_DMA_RW_ONLY },
+
/* Devices we expect to fail diagnostics */
/* Devices where NCQ should be avoided */
/* NCQ is slow */
{ "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
+ /* http://thread.gmane.org/gmane.linux.ide/14907 */
+ { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
+ /* NCQ is broken */
+ { "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
+ /* NCQ hard hangs device under heavier load, needs hard power cycle */
+ { "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
+ /* Blacklist entries taken from Silicon Image 3124/3132
+ Windows driver .inf file - also several Linux problem reports */
+ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
+ { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
+ { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */
@@ -3314,19 +3764,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
xfer_mask = ata_pack_xfermask(ap->pio_mask,
ap->mwdma_mask, ap->udma_mask);
- /* Apply cable rule here. Don't apply it early because when
- * we handle hot plug the cable type can itself change.
- */
- if (ap->cbl == ATA_CBL_PATA40)
- xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
- /* Apply drive side cable rule. Unknown or 80 pin cables reported
- * host side are checked drive side as well. Cases where we know a
- * 40wire cable is used safely for 80 are not checked here.
- */
- if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
- xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
-
-
+ /* drive modes available */
xfer_mask &= ata_pack_xfermask(dev->pio_mask,
dev->mwdma_mask, dev->udma_mask);
xfer_mask &= ata_id_xfermask(dev->id);
@@ -3348,14 +3786,37 @@ static void ata_dev_xfermask(struct ata_device *dev)
"device is on DMA blacklist, disabling DMA\n");
}
- if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) {
+ if ((host->flags & ATA_HOST_SIMPLEX) &&
+ host->simplex_claimed && host->simplex_claimed != ap) {
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
"other device, disabling DMA\n");
}
+ if (ap->flags & ATA_FLAG_NO_IORDY)
+ xfer_mask &= ata_pio_mask_no_iordy(dev);
+
if (ap->ops->mode_filter)
- xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
+ xfer_mask = ap->ops->mode_filter(dev, xfer_mask);
+
+ /* Apply cable rule here. Don't apply it early because when
+ * we handle hot plug the cable type can itself change.
+ * Check this last so that we know if the transfer rate was
+ * solely limited by the cable.
+ * Unknown or 80 wire cables reported host side are checked
+ * drive side as well. Cases where we know a 40wire cable
+ * is used safely for 80 are not checked here.
+ */
+ if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
+ /* UDMA/44 or higher would be available */
+ if((ap->cbl == ATA_CBL_PATA40) ||
+ (ata_drive_40wire(dev->id) &&
+ (ap->cbl == ATA_CBL_PATA_UNK ||
+ ap->cbl == ATA_CBL_PATA80))) {
+ ata_dev_printk(dev, KERN_WARNING,
+ "limited to UDMA/33 due to 40-wire cable\n");
+ xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+ }
ata_unpack_xfermask(xfer_mask, &dev->pio_mask,
&dev->mwdma_mask, &dev->udma_mask);
@@ -3562,6 +4023,26 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
int rc = 0; /* Assume ATAPI DMA is OK by default */
+ /* some drives can only do ATAPI DMA on read/write */
+ if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) {
+ struct scsi_cmnd *cmd = qc->scsicmd;
+ u8 *scsicmd = cmd->cmnd;
+
+ switch (scsicmd[0]) {
+ case READ_10:
+ case WRITE_10:
+ case READ_12:
+ case WRITE_12:
+ case READ_6:
+ case WRITE_6:
+ /* atapi dma maybe ok */
+ break;
+ default:
+ /* turn off atapi dma */
+ return 1;
+ }
+ }
+
if (ap->ops->check_atapi_dma)
rc = ap->ops->check_atapi_dma(qc);
@@ -3725,7 +4206,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
struct scatterlist *lsg = &sg[qc->n_elem - 1];
int n_elem, pre_n_elem, dir, trim_sg = 0;
- VPRINTK("ENTER, ata%u\n", ap->id);
+ VPRINTK("ENTER, ata%u\n", ap->print_id);
WARN_ON(!(qc->flags & ATA_QCFLAG_SG));
/* we must lengthen transfers to end on a 32-bit boundary */
@@ -3874,10 +4355,10 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
/**
- * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data.
+ * ata_pio_sector - Transfer a sector of data.
* @qc: Command on going
*
- * Transfer ATA_SECT_SIZE of data from/to the ATA device.
+ * Transfer qc->sect_size bytes of data from/to the ATA device.
*
* LOCKING:
* Inherited from caller.
@@ -3892,7 +4373,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned int offset;
unsigned char *buf;
- if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE)
+ if (qc->curbytes == qc->nbytes - qc->sect_size)
ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
@@ -3912,17 +4393,17 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
buf = kmap_atomic(page, KM_IRQ0);
/* do the actual data transfer */
- ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+ ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
kunmap_atomic(buf, KM_IRQ0);
local_irq_restore(flags);
} else {
buf = page_address(page);
- ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+ ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
}
- qc->curbytes += ATA_SECT_SIZE;
- qc->cursg_ofs += ATA_SECT_SIZE;
+ qc->curbytes += qc->sect_size;
+ qc->cursg_ofs += qc->sect_size;
if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
qc->cursg++;
@@ -3931,10 +4412,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
}
/**
- * ata_pio_sectors - Transfer one or many 512-byte sectors.
+ * ata_pio_sectors - Transfer one or many sectors.
* @qc: Command on going
*
- * Transfer one or many ATA_SECT_SIZE of data from/to the
+ * Transfer one or many sectors of data from/to the
* ATA device for the DRQ request.
*
* LOCKING:
@@ -3949,7 +4430,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
WARN_ON(qc->dev->multi_count == 0);
- nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE,
+ nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
qc->dev->multi_count);
while (nsect--)
ata_pio_sector(qc);
@@ -4126,7 +4607,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc)
if (do_write != i_write)
goto err_out;
- VPRINTK("ata%u: xfering %d bytes\n", ap->id, bytes);
+ VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
__atapi_pio_bytes(qc, bytes);
@@ -4243,7 +4724,7 @@ int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
fsm_start:
DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
- ap->id, qc->tf.protocol, ap->hsm_task_state, status);
+ ap->print_id, qc->tf.protocol, ap->hsm_task_state, status);
switch (ap->hsm_task_state) {
case HSM_ST_FIRST:
@@ -4276,8 +4757,8 @@ fsm_start:
* let the EH abort the command or reset the device.
*/
if (unlikely(status & (ATA_ERR | ATA_DF))) {
- printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
- ap->id, status);
+ ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device "
+ "error, dev_stat 0x%X\n", status);
qc->err_mask |= AC_ERR_HSM;
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
@@ -4334,8 +4815,9 @@ fsm_start:
* let the EH abort the command or reset the device.
*/
if (unlikely(status & (ATA_ERR | ATA_DF))) {
- printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
- ap->id, status);
+ ata_port_printk(ap, KERN_WARNING, "DRQ=1 with "
+ "device error, dev_stat 0x%X\n",
+ status);
qc->err_mask |= AC_ERR_HSM;
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
@@ -4421,7 +4903,7 @@ fsm_start:
/* no more data to transfer */
DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
- ap->id, qc->dev->devno, status);
+ ap->print_id, qc->dev->devno, status);
WARN_ON(qc->err_mask);
@@ -4604,8 +5086,8 @@ static void fill_result_tf(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- ap->ops->tf_read(ap, &qc->result_tf);
qc->result_tf.flags = qc->tf.flags;
+ ap->ops->tf_read(ap, &qc->result_tf);
}
/**
@@ -4963,7 +5445,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
u8 status, host_stat = 0;
VPRINTK("ata%u: protocol %d task_state %d\n",
- ap->id, qc->tf.protocol, ap->hsm_task_state);
+ ap->print_id, qc->tf.protocol, ap->hsm_task_state);
/* Check whether we are expecting interrupt in this state */
switch (ap->hsm_task_state) {
@@ -4984,7 +5466,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
/* check status of DMA engine */
host_stat = ap->ops->bmdma_status(ap);
- VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
+ VPRINTK("ata%u: host_stat 0x%X\n",
+ ap->print_id, host_stat);
/* if it's not our irq... */
if (!(host_stat & ATA_DMA_INTR))
@@ -5245,6 +5728,7 @@ int ata_flush_cache(struct ata_device *dev)
return 0;
}
+#ifdef CONFIG_PM
static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
unsigned int action, unsigned int ehi_flags,
int wait)
@@ -5360,6 +5844,7 @@ void ata_host_resume(struct ata_host *host)
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
host->dev->power.power_state = PMSG_ON;
}
+#endif
/**
* ata_port_start - Set port up for dma.
@@ -5425,42 +5910,35 @@ void ata_dev_init(struct ata_device *dev)
}
/**
- * ata_port_init - Initialize an ata_port structure
- * @ap: Structure to initialize
- * @host: Collection of hosts to which @ap belongs
- * @ent: Probe information provided by low-level driver
- * @port_no: Port number associated with this ata_port
+ * ata_port_alloc - allocate and initialize basic ATA port resources
+ * @host: ATA host this allocated port belongs to
+ *
+ * Allocate and initialize basic ATA port resources.
*
- * Initialize a new ata_port structure.
+ * RETURNS:
+ * Allocate ATA port on success, NULL on failure.
*
* LOCKING:
- * Inherited from caller.
+ * Inherited from calling layer (may sleep).
*/
-void ata_port_init(struct ata_port *ap, struct ata_host *host,
- const struct ata_probe_ent *ent, unsigned int port_no)
+struct ata_port *ata_port_alloc(struct ata_host *host)
{
+ struct ata_port *ap;
unsigned int i;
+ DPRINTK("ENTER\n");
+
+ ap = kzalloc(sizeof(*ap), GFP_KERNEL);
+ if (!ap)
+ return NULL;
+
ap->lock = &host->lock;
ap->flags = ATA_FLAG_DISABLED;
- ap->id = ata_unique_id++;
+ ap->print_id = -1;
ap->ctl = ATA_DEVCTL_OBS;
ap->host = host;
- ap->dev = ent->dev;
- ap->port_no = port_no;
- if (port_no == 1 && ent->pinfo2) {
- ap->pio_mask = ent->pinfo2->pio_mask;
- ap->mwdma_mask = ent->pinfo2->mwdma_mask;
- ap->udma_mask = ent->pinfo2->udma_mask;
- ap->flags |= ent->pinfo2->flags;
- ap->ops = ent->pinfo2->port_ops;
- } else {
- ap->pio_mask = ent->pio_mask;
- ap->mwdma_mask = ent->mwdma_mask;
- ap->udma_mask = ent->udma_mask;
- ap->flags |= ent->port_flags;
- ap->ops = ent->port_ops;
- }
+ ap->dev = host->dev;
+
ap->hw_sata_spd_limit = UINT_MAX;
ap->active_tag = ATA_TAG_POISON;
ap->last_ctl = 0xFF;
@@ -5480,10 +5958,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
INIT_LIST_HEAD(&ap->eh_done_q);
init_waitqueue_head(&ap->eh_wait_q);
- /* set cable type */
ap->cbl = ATA_CBL_NONE;
- if (ap->flags & ATA_FLAG_SATA)
- ap->cbl = ATA_CBL_SATA;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
@@ -5496,94 +5971,209 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
#endif
+ return ap;
+}
+
+static void ata_host_release(struct device *gendev, void *res)
+{
+ struct ata_host *host = dev_get_drvdata(gendev);
+ int i;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!ap)
+ continue;
+
+ if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+ }
+
+ if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
+ host->ops->host_stop(host);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!ap)
+ continue;
+
+ if (ap->scsi_host)
+ scsi_host_put(ap->scsi_host);
- memcpy(&ap->ioaddr, &ent->port[port_no], sizeof(struct ata_ioports));
+ kfree(ap);
+ host->ports[i] = NULL;
+ }
+
+ dev_set_drvdata(gendev, NULL);
}
/**
- * ata_port_init_shost - Initialize SCSI host associated with ATA port
- * @ap: ATA port to initialize SCSI host for
- * @shost: SCSI host associated with @ap
+ * ata_host_alloc - allocate and init basic ATA host resources
+ * @dev: generic device this host is associated with
+ * @max_ports: maximum number of ATA ports associated with this host
+ *
+ * Allocate and initialize basic ATA host resources. LLD calls
+ * this function to allocate a host, initializes it fully and
+ * attaches it using ata_host_register().
+ *
+ * @max_ports ports are allocated and host->n_ports is
+ * initialized to @max_ports. The caller is allowed to decrease
+ * host->n_ports before calling ata_host_register(). The unused
+ * ports will be automatically freed on registration.
*
- * Initialize SCSI host @shost associated with ATA port @ap.
+ * RETURNS:
+ * Allocate ATA host on success, NULL on failure.
*
* LOCKING:
- * Inherited from caller.
+ * Inherited from calling layer (may sleep).
*/
-static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
+struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
{
- ap->scsi_host = shost;
+ struct ata_host *host;
+ size_t sz;
+ int i;
+
+ DPRINTK("ENTER\n");
+
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return NULL;
+
+ /* alloc a container for our list of ATA ports (buses) */
+ sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *);
+ /* alloc a container for our list of ATA ports (buses) */
+ host = devres_alloc(ata_host_release, sz, GFP_KERNEL);
+ if (!host)
+ goto err_out;
+
+ devres_add(dev, host);
+ dev_set_drvdata(dev, host);
+
+ spin_lock_init(&host->lock);
+ host->dev = dev;
+ host->n_ports = max_ports;
+
+ /* allocate ports bound to this host */
+ for (i = 0; i < max_ports; i++) {
+ struct ata_port *ap;
+
+ ap = ata_port_alloc(host);
+ if (!ap)
+ goto err_out;
+
+ ap->port_no = i;
+ host->ports[i] = ap;
+ }
- shost->unique_id = ap->id;
- shost->max_id = 16;
- shost->max_lun = 1;
- shost->max_channel = 1;
- shost->max_cmd_len = 12;
+ devres_remove_group(dev, NULL);
+ return host;
+
+ err_out:
+ devres_release_group(dev, NULL);
+ return NULL;
}
/**
- * ata_port_add - Attach low-level ATA driver to system
- * @ent: Information provided by low-level driver
- * @host: Collections of ports to which we add
- * @port_no: Port number associated with this host
+ * ata_host_alloc_pinfo - alloc host and init with port_info array
+ * @dev: generic device this host is associated with
+ * @ppi: array of ATA port_info to initialize host with
+ * @n_ports: number of ATA ports attached to this host
*
- * Attach low-level ATA driver to system.
- *
- * LOCKING:
- * PCI/etc. bus probe sem.
+ * Allocate ATA host and initialize with info from @ppi. If NULL
+ * terminated, @ppi may contain fewer entries than @n_ports. The
+ * last entry will be used for the remaining ports.
*
* RETURNS:
- * New ata_port on success, for NULL on error.
+ * Allocate ATA host on success, NULL on failure.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
*/
-static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
- struct ata_host *host,
- unsigned int port_no)
+struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+ const struct ata_port_info * const * ppi,
+ int n_ports)
{
- struct Scsi_Host *shost;
- struct ata_port *ap;
-
- DPRINTK("ENTER\n");
+ const struct ata_port_info *pi;
+ struct ata_host *host;
+ int i, j;
- if (!ent->port_ops->error_handler &&
- !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
- printk(KERN_ERR "ata%u: no reset mechanism available\n",
- port_no);
+ host = ata_host_alloc(dev, n_ports);
+ if (!host)
return NULL;
- }
- shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
- if (!shost)
- return NULL;
+ for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
- shost->transportt = &ata_scsi_transport_template;
+ if (ppi[j])
+ pi = ppi[j++];
- ap = ata_shost_to_port(shost);
+ ap->pio_mask = pi->pio_mask;
+ ap->mwdma_mask = pi->mwdma_mask;
+ ap->udma_mask = pi->udma_mask;
+ ap->flags |= pi->flags;
+ ap->ops = pi->port_ops;
- ata_port_init(ap, host, ent, port_no);
- ata_port_init_shost(ap, shost);
+ if (!host->ops && (pi->port_ops != &ata_dummy_port_ops))
+ host->ops = pi->port_ops;
+ if (!host->private_data && pi->private_data)
+ host->private_data = pi->private_data;
+ }
- return ap;
+ return host;
}
-static void ata_host_release(struct device *gendev, void *res)
+/**
+ * ata_host_start - start and freeze ports of an ATA host
+ * @host: ATA host to start ports for
+ *
+ * Start and then freeze ports of @host. Started status is
+ * recorded in host->flags, so this function can be called
+ * multiple times. Ports are guaranteed to get started only
+ * once. If host->ops isn't initialized yet, its set to the
+ * first non-dummy port ops.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 if all ports are started successfully, -errno otherwise.
+ */
+int ata_host_start(struct ata_host *host)
{
- struct ata_host *host = dev_get_drvdata(gendev);
- int i;
+ int i, rc;
+
+ if (host->flags & ATA_HOST_STARTED)
+ return 0;
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- if (!ap)
- continue;
+ if (!host->ops && !ata_port_is_dummy(ap))
+ host->ops = ap->ops;
- if (ap->ops->port_stop)
- ap->ops->port_stop(ap);
+ if (ap->ops->port_start) {
+ rc = ap->ops->port_start(ap);
+ if (rc) {
+ ata_port_printk(ap, KERN_ERR, "failed to "
+ "start port (errno=%d)\n", rc);
+ goto err_out;
+ }
+ }
- scsi_host_put(ap->scsi_host);
+ ata_eh_freeze_port(ap);
}
- if (host->ops->host_stop)
- host->ops->host_stop(host);
+ host->flags |= ATA_HOST_STARTED;
+ return 0;
+
+ err_out:
+ while (--i >= 0) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+ }
+ return rc;
}
/**
@@ -5597,7 +6187,7 @@ static void ata_host_release(struct device *gendev, void *res)
* PCI/etc. bus probe sem.
*
*/
-
+/* KILLME - the only user left is ipr */
void ata_host_init(struct ata_host *host, struct device *dev,
unsigned long flags, const struct ata_port_operations *ops)
{
@@ -5608,155 +6198,95 @@ void ata_host_init(struct ata_host *host, struct device *dev,
}
/**
- * ata_device_add - Register hardware device with ATA and SCSI layers
- * @ent: Probe information describing hardware device to be registered
- *
- * This function processes the information provided in the probe
- * information struct @ent, allocates the necessary ATA and SCSI
- * host information structures, initializes them, and registers
- * everything with requisite kernel subsystems.
+ * ata_host_register - register initialized ATA host
+ * @host: ATA host to register
+ * @sht: template for SCSI host
*
- * This function requests irqs, probes the ATA bus, and probes
- * the SCSI bus.
+ * Register initialized ATA host. @host is allocated using
+ * ata_host_alloc() and fully initialized by LLD. This function
+ * starts ports, registers @host with ATA and SCSI layers and
+ * probe registered devices.
*
* LOCKING:
- * PCI/etc. bus probe sem.
+ * Inherited from calling layer (may sleep).
*
* RETURNS:
- * Number of ports registered. Zero on error (no ports registered).
+ * 0 on success, -errno otherwise.
*/
-int ata_device_add(const struct ata_probe_ent *ent)
+int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
{
- unsigned int i;
- struct device *dev = ent->dev;
- struct ata_host *host;
- int rc;
-
- DPRINTK("ENTER\n");
+ int i, rc;
- if (ent->irq == 0) {
- dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
- return 0;
+ /* host must have been started */
+ if (!(host->flags & ATA_HOST_STARTED)) {
+ dev_printk(KERN_ERR, host->dev,
+ "BUG: trying to register unstarted host\n");
+ WARN_ON(1);
+ return -EINVAL;
}
- if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
- return 0;
+ /* Blow away unused ports. This happens when LLD can't
+ * determine the exact number of ports to allocate at
+ * allocation time.
+ */
+ for (i = host->n_ports; host->ports[i]; i++)
+ kfree(host->ports[i]);
- /* alloc a container for our list of ATA ports (buses) */
- host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
- (ent->n_ports * sizeof(void *)), GFP_KERNEL);
- if (!host)
- goto err_out;
- devres_add(dev, host);
- dev_set_drvdata(dev, host);
+ /* give ports names and add SCSI hosts */
+ for (i = 0; i < host->n_ports; i++)
+ host->ports[i]->print_id = ata_print_id++;
- ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
- host->n_ports = ent->n_ports;
- host->irq = ent->irq;
- host->irq2 = ent->irq2;
- host->iomap = ent->iomap;
- host->private_data = ent->private_data;
+ rc = ata_scsi_add_hosts(host, sht);
+ if (rc)
+ return rc;
- /* register each port bound to this device */
+ /* set cable, sata_spd_limit and report */
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
- unsigned long xfer_mode_mask;
- int irq_line = ent->irq;
-
- ap = ata_port_add(ent, host, i);
- host->ports[i] = ap;
- if (!ap)
- goto err_out;
+ struct ata_port *ap = host->ports[i];
+ int irq_line;
+ u32 scontrol;
+ unsigned long xfer_mask;
- /* dummy? */
- if (ent->dummy_port_mask & (1 << i)) {
- ata_port_printk(ap, KERN_INFO, "DUMMY\n");
- ap->ops = &ata_dummy_port_ops;
- continue;
- }
+ /* set SATA cable type if still unset */
+ if (ap->cbl == ATA_CBL_NONE && (ap->flags & ATA_FLAG_SATA))
+ ap->cbl = ATA_CBL_SATA;
- /* start port */
- rc = ap->ops->port_start(ap);
- if (rc) {
- host->ports[i] = NULL;
- scsi_host_put(ap->scsi_host);
- goto err_out;
+ /* init sata_spd_limit to the current value */
+ if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
+ int spd = (scontrol >> 4) & 0xf;
+ ap->hw_sata_spd_limit &= (1 << spd) - 1;
}
+ ap->sata_spd_limit = ap->hw_sata_spd_limit;
- /* Report the secondary IRQ for second channel legacy */
- if (i == 1 && ent->irq2)
- irq_line = ent->irq2;
+ /* report the secondary IRQ for second channel legacy */
+ irq_line = host->irq;
+ if (i == 1 && host->irq2)
+ irq_line = host->irq2;
- xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
- (ap->mwdma_mask << ATA_SHIFT_MWDMA) |
- (ap->pio_mask << ATA_SHIFT_PIO);
+ xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
+ ap->udma_mask);
/* print per-port info to dmesg */
- ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
- "ctl 0x%p bmdma 0x%p irq %d\n",
- ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
- ata_mode_string(xfer_mode_mask),
- ap->ioaddr.cmd_addr,
- ap->ioaddr.ctl_addr,
- ap->ioaddr.bmdma_addr,
- irq_line);
-
- /* freeze port before requesting IRQ */
- ata_eh_freeze_port(ap);
- }
-
- /* obtain irq, that may be shared between channels */
- rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
- ent->irq_flags, DRV_NAME, host);
- if (rc) {
- dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
- ent->irq, rc);
- goto err_out;
- }
-
- /* do we have a second IRQ for the other channel, eg legacy mode */
- if (ent->irq2) {
- /* We will get weird core code crashes later if this is true
- so trap it now */
- BUG_ON(ent->irq == ent->irq2);
-
- rc = devm_request_irq(dev, ent->irq2,
- ent->port_ops->irq_handler, ent->irq_flags,
- DRV_NAME, host);
- if (rc) {
- dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
- ent->irq2, rc);
- goto err_out;
- }
+ if (!ata_port_is_dummy(ap))
+ ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
+ "ctl 0x%p bmdma 0x%p irq %d\n",
+ ap->cbl == ATA_CBL_SATA ? 'S' : 'P',
+ ata_mode_string(xfer_mask),
+ ap->ioaddr.cmd_addr,
+ ap->ioaddr.ctl_addr,
+ ap->ioaddr.bmdma_addr,
+ irq_line);
+ else
+ ata_port_printk(ap, KERN_INFO, "DUMMY\n");
}
- /* resource acquisition complete */
- devres_remove_group(dev, ata_device_add);
-
/* perform each probe synchronously */
DPRINTK("probe begin\n");
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- u32 scontrol;
int rc;
- /* init sata_spd_limit to the current value */
- if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
- int spd = (scontrol >> 4) & 0xf;
- ap->hw_sata_spd_limit &= (1 << spd) - 1;
- }
- ap->sata_spd_limit = ap->hw_sata_spd_limit;
-
- rc = scsi_add_host(ap->scsi_host, dev);
- if (rc) {
- ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
- /* FIXME: do something useful here */
- /* FIXME: handle unconditional calls to
- * scsi_scan_host and ata_host_remove, below,
- * at the very least
- */
- }
-
+ /* probe */
if (ap->ops->error_handler) {
struct ata_eh_info *ehi = &ap->eh_info;
unsigned long flags;
@@ -5778,9 +6308,9 @@ int ata_device_add(const struct ata_probe_ent *ent)
/* wait for EH to finish */
ata_port_wait_eh(ap);
} else {
- DPRINTK("ata%u: bus probe begin\n", ap->id);
+ DPRINTK("ata%u: bus probe begin\n", ap->print_id);
rc = ata_bus_probe(ap);
- DPRINTK("ata%u: bus probe end\n", ap->id);
+ DPRINTK("ata%u: bus probe end\n", ap->print_id);
if (rc) {
/* FIXME: do something useful here?
@@ -5801,17 +6331,52 @@ int ata_device_add(const struct ata_probe_ent *ent)
ata_scsi_scan_host(ap);
}
- VPRINTK("EXIT, returning %u\n", ent->n_ports);
- return ent->n_ports; /* success */
-
- err_out:
- devres_release_group(dev, ata_device_add);
- dev_set_drvdata(dev, NULL);
- VPRINTK("EXIT, returning %d\n", rc);
return 0;
}
/**
+ * ata_host_activate - start host, request IRQ and register it
+ * @host: target ATA host
+ * @irq: IRQ to request
+ * @irq_handler: irq_handler used when requesting IRQ
+ * @irq_flags: irq_flags used when requesting IRQ
+ * @sht: scsi_host_template to use when registering the host
+ *
+ * After allocating an ATA host and initializing it, most libata
+ * LLDs perform three steps to activate the host - start host,
+ * request IRQ and register it. This helper takes necessasry
+ * arguments and performs the three steps in one go.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_host_activate(struct ata_host *host, int irq,
+ irq_handler_t irq_handler, unsigned long irq_flags,
+ struct scsi_host_template *sht)
+{
+ int rc;
+
+ rc = ata_host_start(host);
+ if (rc)
+ return rc;
+
+ rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
+ dev_driver_string(host->dev), host);
+ if (rc)
+ return rc;
+
+ rc = ata_host_register(host, sht);
+ /* if failed, just free the IRQ and leave ports alone */
+ if (rc)
+ devm_free_irq(host->dev, irq, host);
+
+ return rc;
+}
+
+/**
* ata_port_detach - Detach ATA port in prepration of device removal
* @ap: ATA port to be detached
*
@@ -5886,36 +6451,6 @@ void ata_host_detach(struct ata_host *host)
ata_port_detach(host->ports[i]);
}
-struct ata_probe_ent *
-ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
-{
- struct ata_probe_ent *probe_ent;
-
- /* XXX - the following if can go away once all LLDs are managed */
- if (!list_empty(&dev->devres_head))
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- else
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (!probe_ent) {
- printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
- kobject_name(&(dev->kobj)));
- return NULL;
- }
-
- INIT_LIST_HEAD(&probe_ent->node);
- probe_ent->dev = dev;
-
- probe_ent->sht = port->sht;
- probe_ent->port_flags = port->flags;
- probe_ent->pio_mask = port->pio_mask;
- probe_ent->mwdma_mask = port->mwdma_mask;
- probe_ent->udma_mask = port->udma_mask;
- probe_ent->port_ops = port->port_ops;
- probe_ent->private_data = port->private_data;
-
- return probe_ent;
-}
-
/**
* ata_std_ports - initialize ioaddr with standard port offsets.
* @ioaddr: IO address structure to be initialized
@@ -5998,14 +6533,14 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
return (tmp == bits->val) ? 1 : 0;
}
+#ifdef CONFIG_PM
void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
pci_save_state(pdev);
+ pci_disable_device(pdev);
- if (mesg.event == PM_EVENT_SUSPEND) {
- pci_disable_device(pdev);
+ if (mesg.event == PM_EVENT_SUSPEND)
pci_set_power_state(pdev, PCI_D3hot);
- }
}
int ata_pci_device_do_resume(struct pci_dev *pdev)
@@ -6050,6 +6585,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
ata_host_resume(host);
return rc;
}
+#endif /* CONFIG_PM */
+
#endif /* CONFIG_PCI */
@@ -6179,6 +6716,10 @@ const struct ata_port_operations ata_dummy_port_ops = {
.port_stop = ata_dummy_noret,
};
+const struct ata_port_info ata_dummy_port_info = {
+ .port_ops = &ata_dummy_port_ops,
+};
+
/*
* libata is essentially a library of internal helper functions for
* low-level ATA host controller drivers. As such, the API/ABI is
@@ -6190,10 +6731,15 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
EXPORT_SYMBOL_GPL(sata_deb_timing_long);
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
+EXPORT_SYMBOL_GPL(ata_dummy_port_info);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_host_init);
-EXPORT_SYMBOL_GPL(ata_device_add);
+EXPORT_SYMBOL_GPL(ata_host_alloc);
+EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
+EXPORT_SYMBOL_GPL(ata_host_start);
+EXPORT_SYMBOL_GPL(ata_host_register);
+EXPORT_SYMBOL_GPL(ata_host_activate);
EXPORT_SYMBOL_GPL(ata_host_detach);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
@@ -6205,6 +6751,7 @@ EXPORT_SYMBOL_GPL(ata_tf_load);
EXPORT_SYMBOL_GPL(ata_tf_read);
EXPORT_SYMBOL_GPL(ata_noop_dev_select);
EXPORT_SYMBOL_GPL(ata_std_dev_select);
+EXPORT_SYMBOL_GPL(sata_print_link_status);
EXPORT_SYMBOL_GPL(ata_tf_to_fis);
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
EXPORT_SYMBOL_GPL(ata_check_status);
@@ -6212,6 +6759,7 @@ EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt);
+EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_qc_prep);
@@ -6227,6 +6775,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_drive_eh);
EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_port_probe);
+EXPORT_SYMBOL_GPL(ata_dev_disable);
EXPORT_SYMBOL_GPL(sata_set_spd);
EXPORT_SYMBOL_GPL(sata_phy_debounce);
EXPORT_SYMBOL_GPL(sata_phy_resume);
@@ -6257,10 +6806,13 @@ EXPORT_SYMBOL_GPL(sata_scr_write);
EXPORT_SYMBOL_GPL(sata_scr_write_flush);
EXPORT_SYMBOL_GPL(ata_port_online);
EXPORT_SYMBOL_GPL(ata_port_offline);
+#ifdef CONFIG_PM
EXPORT_SYMBOL_GPL(ata_host_suspend);
EXPORT_SYMBOL_GPL(ata_host_resume);
+#endif /* CONFIG_PM */
EXPORT_SYMBOL_GPL(ata_id_string);
EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
EXPORT_SYMBOL_GPL(ata_device_blacklisted);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
@@ -6270,19 +6822,24 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
+EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+#ifdef CONFIG_PM
EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+#endif /* CONFIG_PM */
EXPORT_SYMBOL_GPL(ata_pci_default_filter);
EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
#endif /* CONFIG_PCI */
+#ifdef CONFIG_PM
EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
+#endif /* CONFIG_PM */
EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
@@ -6297,3 +6854,9 @@ EXPORT_SYMBOL_GPL(ata_irq_on);
EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
EXPORT_SYMBOL_GPL(ata_irq_ack);
EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
+EXPORT_SYMBOL_GPL(ata_dev_try_classify);
+
+EXPORT_SYMBOL_GPL(ata_cable_40wire);
+EXPORT_SYMBOL_GPL(ata_cable_80wire);
+EXPORT_SYMBOL_GPL(ata_cable_unknown);
+EXPORT_SYMBOL_GPL(ata_cable_sata);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 52c85af7fe99..2bff9adcacf1 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -44,10 +44,41 @@
#include "libata.h"
+enum {
+ ATA_EH_SPDN_NCQ_OFF = (1 << 0),
+ ATA_EH_SPDN_SPEED_DOWN = (1 << 1),
+ ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2),
+};
+
static void __ata_port_freeze(struct ata_port *ap);
static void ata_eh_finish(struct ata_port *ap);
+#ifdef CONFIG_PM
static void ata_eh_handle_port_suspend(struct ata_port *ap);
static void ata_eh_handle_port_resume(struct ata_port *ap);
+static int ata_eh_suspend(struct ata_port *ap,
+ struct ata_device **r_failed_dev);
+static void ata_eh_prep_resume(struct ata_port *ap);
+static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
+#else /* CONFIG_PM */
+static void ata_eh_handle_port_suspend(struct ata_port *ap)
+{ }
+
+static void ata_eh_handle_port_resume(struct ata_port *ap)
+{ }
+
+static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+ return 0;
+}
+
+static void ata_eh_prep_resume(struct ata_port *ap)
+{ }
+
+static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
static void ata_ering_record(struct ata_ering *ering, int is_io,
unsigned int err_mask)
@@ -65,12 +96,9 @@ static void ata_ering_record(struct ata_ering *ering, int is_io,
ent->timestamp = get_jiffies_64();
}
-static struct ata_ering_entry * ata_ering_top(struct ata_ering *ering)
+static void ata_ering_clear(struct ata_ering *ering)
{
- struct ata_ering_entry *ent = &ering->ring[ering->cursor];
- if (!ent->err_mask)
- return NULL;
- return ent;
+ memset(ering, 0, sizeof(*ering));
}
static int ata_ering_map(struct ata_ering *ering,
@@ -585,7 +613,7 @@ static void __ata_port_freeze(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_FROZEN;
- DPRINTK("ata%u port frozen\n", ap->id);
+ DPRINTK("ata%u port frozen\n", ap->print_id);
}
/**
@@ -658,7 +686,7 @@ void ata_eh_thaw_port(struct ata_port *ap)
spin_unlock_irqrestore(ap->lock, flags);
- DPRINTK("ata%u port thawed\n", ap->id);
+ DPRINTK("ata%u port thawed\n", ap->print_id);
}
static void ata_eh_scsidone(struct scsi_cmnd *scmd)
@@ -954,26 +982,27 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
* RETURNS:
* 0 on success, AC_ERR_* mask on failure
*/
-static unsigned int atapi_eh_request_sense(struct ata_device *dev,
- unsigned char *sense_buf)
+static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
{
+ struct ata_device *dev = qc->dev;
+ unsigned char *sense_buf = qc->scsicmd->sense_buffer;
struct ata_port *ap = dev->ap;
struct ata_taskfile tf;
u8 cdb[ATAPI_CDB_LEN];
DPRINTK("ATAPI request sense\n");
- ata_tf_init(dev, &tf);
-
/* FIXME: is this needed? */
memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
- /* XXX: why tf_read here? */
- ap->ops->tf_read(ap, &tf);
-
- /* fill these in, for the case where they are -not- overwritten */
+ /* initialize sense_buf with the error register,
+ * for the case where they are -not- overwritten
+ */
sense_buf[0] = 0x70;
- sense_buf[2] = tf.feature >> 4;
+ sense_buf[2] = qc->result_tf.feature >> 4;
+
+ /* some devices time out if garbage left in tf */
+ ata_tf_init(dev, &tf);
memset(cdb, 0, ATAPI_CDB_LEN);
cdb[0] = REQUEST_SENSE;
@@ -1027,7 +1056,7 @@ static void ata_eh_analyze_serror(struct ata_port *ap)
}
if (serror & SERR_INTERNAL) {
err_mask |= AC_ERR_SYSTEM;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_HARDRESET;
}
if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG))
ata_ehi_hotplugged(&ehc->i);
@@ -1122,7 +1151,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
return ATA_EH_SOFTRESET;
}
- if (!(qc->err_mask & AC_ERR_DEV))
+ if (stat & (ATA_ERR | ATA_DF))
+ qc->err_mask |= AC_ERR_DEV;
+ else
return 0;
switch (qc->dev->class) {
@@ -1137,8 +1168,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
case ATA_DEV_ATAPI:
if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
- tmp = atapi_eh_request_sense(qc->dev,
- qc->scsicmd->sense_buffer);
+ tmp = atapi_eh_request_sense(qc);
if (!tmp) {
/* ATA_QCFLAG_SENSE_VALID is used to
* tell atapi_qc_complete() that sense
@@ -1159,87 +1189,99 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
return action;
}
-static int ata_eh_categorize_ering_entry(struct ata_ering_entry *ent)
+static int ata_eh_categorize_error(int is_io, unsigned int err_mask)
{
- if (ent->err_mask & (AC_ERR_ATA_BUS | AC_ERR_TIMEOUT))
+ if (err_mask & AC_ERR_ATA_BUS)
return 1;
- if (ent->is_io) {
- if (ent->err_mask & AC_ERR_HSM)
- return 1;
- if ((ent->err_mask &
- (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV)
+ if (err_mask & AC_ERR_TIMEOUT)
+ return 2;
+
+ if (is_io) {
+ if (err_mask & AC_ERR_HSM)
return 2;
+ if ((err_mask &
+ (AC_ERR_DEV|AC_ERR_MEDIA|AC_ERR_INVALID)) == AC_ERR_DEV)
+ return 3;
}
return 0;
}
-struct speed_down_needed_arg {
+struct speed_down_verdict_arg {
u64 since;
- int nr_errors[3];
+ int nr_errors[4];
};
-static int speed_down_needed_cb(struct ata_ering_entry *ent, void *void_arg)
+static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
{
- struct speed_down_needed_arg *arg = void_arg;
+ struct speed_down_verdict_arg *arg = void_arg;
+ int cat = ata_eh_categorize_error(ent->is_io, ent->err_mask);
if (ent->timestamp < arg->since)
return -1;
- arg->nr_errors[ata_eh_categorize_ering_entry(ent)]++;
+ arg->nr_errors[cat]++;
return 0;
}
/**
- * ata_eh_speed_down_needed - Determine wheter speed down is necessary
+ * ata_eh_speed_down_verdict - Determine speed down verdict
* @dev: Device of interest
*
* This function examines error ring of @dev and determines
- * whether speed down is necessary. Speed down is necessary if
- * there have been more than 3 of Cat-1 errors or 10 of Cat-2
- * errors during last 15 minutes.
+ * whether NCQ needs to be turned off, transfer speed should be
+ * stepped down, or falling back to PIO is necessary.
+ *
+ * Cat-1 is ATA_BUS error for any command.
*
- * Cat-1 errors are ATA_BUS, TIMEOUT for any command and HSM
- * violation for known supported commands.
+ * Cat-2 is TIMEOUT for any command or HSM violation for known
+ * supported commands.
*
- * Cat-2 errors are unclassified DEV error for known supported
+ * Cat-3 is is unclassified DEV error for known supported
* command.
*
+ * NCQ needs to be turned off if there have been more than 3
+ * Cat-2 + Cat-3 errors during last 10 minutes.
+ *
+ * Speed down is necessary if there have been more than 3 Cat-1 +
+ * Cat-2 errors or 10 Cat-3 errors during last 10 minutes.
+ *
+ * Falling back to PIO mode is necessary if there have been more
+ * than 10 Cat-1 + Cat-2 + Cat-3 errors during last 5 minutes.
+ *
* LOCKING:
* Inherited from caller.
*
* RETURNS:
- * 1 if speed down is necessary, 0 otherwise
+ * OR of ATA_EH_SPDN_* flags.
*/
-static int ata_eh_speed_down_needed(struct ata_device *dev)
+static unsigned int ata_eh_speed_down_verdict(struct ata_device *dev)
{
- const u64 interval = 15LLU * 60 * HZ;
- static const int err_limits[3] = { -1, 3, 10 };
- struct speed_down_needed_arg arg;
- struct ata_ering_entry *ent;
- int err_cat;
- u64 j64;
+ const u64 j5mins = 5LLU * 60 * HZ, j10mins = 10LLU * 60 * HZ;
+ u64 j64 = get_jiffies_64();
+ struct speed_down_verdict_arg arg;
+ unsigned int verdict = 0;
- ent = ata_ering_top(&dev->ering);
- if (!ent)
- return 0;
+ /* scan past 10 mins of error history */
+ memset(&arg, 0, sizeof(arg));
+ arg.since = j64 - min(j64, j10mins);
+ ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg);
- err_cat = ata_eh_categorize_ering_entry(ent);
- if (err_cat == 0)
- return 0;
+ if (arg.nr_errors[2] + arg.nr_errors[3] > 3)
+ verdict |= ATA_EH_SPDN_NCQ_OFF;
+ if (arg.nr_errors[1] + arg.nr_errors[2] > 3 || arg.nr_errors[3] > 10)
+ verdict |= ATA_EH_SPDN_SPEED_DOWN;
+ /* scan past 3 mins of error history */
memset(&arg, 0, sizeof(arg));
+ arg.since = j64 - min(j64, j5mins);
+ ata_ering_map(&dev->ering, speed_down_verdict_cb, &arg);
- j64 = get_jiffies_64();
- if (j64 >= interval)
- arg.since = j64 - interval;
- else
- arg.since = 0;
-
- ata_ering_map(&dev->ering, speed_down_needed_cb, &arg);
+ if (arg.nr_errors[1] + arg.nr_errors[2] + arg.nr_errors[3] > 10)
+ verdict |= ATA_EH_SPDN_FALLBACK_TO_PIO;
- return arg.nr_errors[err_cat] > err_limits[err_cat];
+ return verdict;
}
/**
@@ -1257,31 +1299,80 @@ static int ata_eh_speed_down_needed(struct ata_device *dev)
* Kernel thread context (may sleep).
*
* RETURNS:
- * 0 on success, -errno otherwise
+ * Determined recovery action.
*/
-static int ata_eh_speed_down(struct ata_device *dev, int is_io,
- unsigned int err_mask)
+static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io,
+ unsigned int err_mask)
{
- if (!err_mask)
+ unsigned int verdict;
+ unsigned int action = 0;
+
+ /* don't bother if Cat-0 error */
+ if (ata_eh_categorize_error(is_io, err_mask) == 0)
return 0;
/* record error and determine whether speed down is necessary */
ata_ering_record(&dev->ering, is_io, err_mask);
+ verdict = ata_eh_speed_down_verdict(dev);
- if (!ata_eh_speed_down_needed(dev))
- return 0;
+ /* turn off NCQ? */
+ if ((verdict & ATA_EH_SPDN_NCQ_OFF) &&
+ (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ |
+ ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) {
+ dev->flags |= ATA_DFLAG_NCQ_OFF;
+ ata_dev_printk(dev, KERN_WARNING,
+ "NCQ disabled due to excessive errors\n");
+ goto done;
+ }
+
+ /* speed down? */
+ if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
+ /* speed down SATA link speed if possible */
+ if (sata_down_spd_limit(dev->ap) == 0) {
+ action |= ATA_EH_HARDRESET;
+ goto done;
+ }
- /* speed down SATA link speed if possible */
- if (sata_down_spd_limit(dev->ap) == 0)
- return ATA_EH_HARDRESET;
+ /* lower transfer mode */
+ if (dev->spdn_cnt < 2) {
+ static const int dma_dnxfer_sel[] =
+ { ATA_DNXFER_DMA, ATA_DNXFER_40C };
+ static const int pio_dnxfer_sel[] =
+ { ATA_DNXFER_PIO, ATA_DNXFER_FORCE_PIO0 };
+ int sel;
- /* lower transfer mode */
- if (ata_down_xfermask_limit(dev, 0) == 0)
- return ATA_EH_SOFTRESET;
+ if (dev->xfer_shift != ATA_SHIFT_PIO)
+ sel = dma_dnxfer_sel[dev->spdn_cnt];
+ else
+ sel = pio_dnxfer_sel[dev->spdn_cnt];
+
+ dev->spdn_cnt++;
+
+ if (ata_down_xfermask_limit(dev, sel) == 0) {
+ action |= ATA_EH_SOFTRESET;
+ goto done;
+ }
+ }
+ }
+
+ /* Fall back to PIO? Slowing down to PIO is meaningless for
+ * SATA. Consider it only for PATA.
+ */
+ if ((verdict & ATA_EH_SPDN_FALLBACK_TO_PIO) && (dev->spdn_cnt >= 2) &&
+ (dev->ap->cbl != ATA_CBL_SATA) &&
+ (dev->xfer_shift != ATA_SHIFT_PIO)) {
+ if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) {
+ dev->spdn_cnt = 0;
+ action |= ATA_EH_SOFTRESET;
+ goto done;
+ }
+ }
- ata_dev_printk(dev, KERN_ERR,
- "speed down requested but no transfer mode left\n");
return 0;
+ done:
+ /* device has been slowed down, blow error history */
+ ata_ering_clear(&dev->ering);
+ return action;
}
/**
@@ -1536,8 +1627,14 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
rc = prereset(ap);
if (rc) {
if (rc == -ENOENT) {
- ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n");
+ ata_port_printk(ap, KERN_DEBUG,
+ "port disabled. ignoring.\n");
ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++)
+ classes[i] = ATA_DEV_NONE;
+
+ rc = 0;
} else
ata_port_printk(ap, KERN_ERR,
"prereset failed (errno=%d)\n", rc);
@@ -1574,7 +1671,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
reset == softreset ? "soft" : "hard");
/* mark that this EH session started with reset */
- ehc->i.flags |= ATA_EHI_DID_RESET;
+ if (reset == hardreset)
+ ehc->i.flags |= ATA_EHI_DID_HARDRESET;
+ else
+ ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
rc = ata_do_reset(ap, reset, classes);
@@ -1648,12 +1748,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
{
struct ata_eh_context *ehc = &ap->eh_context;
struct ata_device *dev;
+ unsigned int new_mask = 0;
unsigned long flags;
int i, rc = 0;
DPRINTK("ENTER\n");
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ /* For PATA drive side cable detection to work, IDENTIFY must
+ * be done backwards such that PDIAG- is released by the slave
+ * device before the master device is identified.
+ */
+ for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
unsigned int action, readid_flags = 0;
dev = &ap->device[i];
@@ -1665,13 +1770,13 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
if (ata_port_offline(ap)) {
rc = -EIO;
- break;
+ goto err;
}
ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
rc = ata_dev_revalidate(dev, readid_flags);
if (rc)
- break;
+ goto err;
ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
@@ -1689,43 +1794,61 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
rc = ata_dev_read_id(dev, &dev->class, readid_flags,
dev->id);
- if (rc == 0) {
- ehc->i.flags |= ATA_EHI_PRINTINFO;
- rc = ata_dev_configure(dev);
- ehc->i.flags &= ~ATA_EHI_PRINTINFO;
- } else if (rc == -ENOENT) {
+ switch (rc) {
+ case 0:
+ new_mask |= 1 << i;
+ break;
+ case -ENOENT:
/* IDENTIFY was issued to non-existent
* device. No need to reset. Just
* thaw and kill the device.
*/
ata_eh_thaw_port(ap);
dev->class = ATA_DEV_UNKNOWN;
- rc = 0;
- }
-
- if (rc) {
- dev->class = ATA_DEV_UNKNOWN;
break;
+ default:
+ dev->class = ATA_DEV_UNKNOWN;
+ goto err;
}
+ }
+ }
- if (ata_dev_enabled(dev)) {
- spin_lock_irqsave(ap->lock, flags);
- ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
- spin_unlock_irqrestore(ap->lock, flags);
+ /* PDIAG- should have been released, ask cable type if post-reset */
+ if ((ehc->i.flags & ATA_EHI_DID_RESET) && ap->ops->cable_detect)
+ ap->cbl = ap->ops->cable_detect(ap);
- /* new device discovered, configure xfermode */
- ehc->i.flags |= ATA_EHI_SETMODE;
- }
- }
+ /* Configure new devices forward such that user doesn't see
+ * device detection messages backwards.
+ */
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
+
+ if (!(new_mask & (1 << i)))
+ continue;
+
+ ehc->i.flags |= ATA_EHI_PRINTINFO;
+ rc = ata_dev_configure(dev);
+ ehc->i.flags &= ~ATA_EHI_PRINTINFO;
+ if (rc)
+ goto err;
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* new device discovered, configure xfermode */
+ ehc->i.flags |= ATA_EHI_SETMODE;
}
- if (rc)
- *r_failed_dev = dev;
+ return 0;
- DPRINTK("EXIT\n");
+ err:
+ *r_failed_dev = dev;
+ DPRINTK("EXIT rc=%d\n", rc);
return rc;
}
+#ifdef CONFIG_PM
/**
* ata_eh_suspend - handle suspend EH action
* @ap: target host port
@@ -1883,6 +2006,7 @@ static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
DPRINTK("EXIT\n");
return 0;
}
+#endif /* CONFIG_PM */
static int ata_port_nr_enabled(struct ata_port *ap)
{
@@ -1964,7 +2088,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
{
struct ata_eh_context *ehc = &ap->eh_context;
struct ata_device *dev;
- int down_xfermask, i, rc;
+ int i, rc;
DPRINTK("ENTER\n");
@@ -1993,7 +2117,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
}
retry:
- down_xfermask = 0;
rc = 0;
/* if UNLOADING, finish immediately */
@@ -2038,10 +2161,8 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
/* configure transfer mode if necessary */
if (ehc->i.flags & ATA_EHI_SETMODE) {
rc = ata_set_mode(ap, &dev);
- if (rc) {
- down_xfermask = 1;
+ if (rc)
goto dev_fail;
- }
ehc->i.flags &= ~ATA_EHI_SETMODE;
}
@@ -2053,20 +2174,27 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
goto out;
dev_fail:
+ ehc->tries[dev->devno]--;
+
switch (rc) {
- case -ENODEV:
- /* device missing, schedule probing */
- ehc->i.probe_mask |= (1 << dev->devno);
case -EINVAL:
+ /* eeek, something went very wrong, give up */
ehc->tries[dev->devno] = 0;
break;
+
+ case -ENODEV:
+ /* device missing or wrong IDENTIFY data, schedule probing */
+ ehc->i.probe_mask |= (1 << dev->devno);
+ /* give it just one more chance */
+ ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
case -EIO:
- sata_down_spd_limit(ap);
- default:
- ehc->tries[dev->devno]--;
- if (down_xfermask &&
- ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1))
- ehc->tries[dev->devno] = 0;
+ if (ehc->tries[dev->devno] == 1) {
+ /* This is the last chance, better to slow
+ * down than lose it.
+ */
+ sata_down_spd_limit(ap);
+ ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+ }
}
if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
@@ -2181,6 +2309,7 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_eh_finish(ap);
}
+#ifdef CONFIG_PM
/**
* ata_eh_handle_port_suspend - perform port suspend operation
* @ap: port to suspend
@@ -2296,3 +2425,4 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
}
spin_unlock_irqrestore(ap->lock, flags);
}
+#endif /* CONFIG_PM */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 0009818a4306..9afba2ba489e 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
* libata transport template. libata doesn't do real transport stuff.
* It just needs the eh_timed_out hook.
*/
-struct scsi_transport_template ata_scsi_transport_template = {
+static struct scsi_transport_template ata_scsi_transport_template = {
.eh_strategy_handler = ata_scsi_error,
.eh_timed_out = ata_scsi_timed_out,
.user_scan = ata_scsi_user_scan,
@@ -333,6 +333,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
scsi_cmd[8] = args[3];
scsi_cmd[10] = args[4];
scsi_cmd[12] = args[5];
+ scsi_cmd[13] = args[6] & 0x4f;
scsi_cmd[14] = args[0];
/* Good values for timeout and retries? Values below
@@ -509,6 +510,7 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
}
}
+#ifdef CONFIG_PM
/**
* ata_scsi_device_suspend - suspend ATA device associated with sdev
* @sdev: the SCSI device to suspend
@@ -633,6 +635,7 @@ int ata_scsi_device_resume(struct scsi_device *sdev)
sdev->sdev_gendev.power.power_state = PMSG_ON;
return 0;
}
+#endif /* CONFIG_PM */
/**
* ata_to_sense_error - convert ATA error to SCSI error
@@ -781,7 +784,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
*/
if (qc->err_mask ||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
- ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
&sb[1], &sb[2], &sb[3], verbose);
sb[1] &= 0x0f;
}
@@ -854,7 +857,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
*/
if (qc->err_mask ||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
- ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
+ ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
&sb[1], &sb[2], &sb[3], verbose);
sb[1] &= 0x0f;
}
@@ -986,29 +989,32 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev;
unsigned long flags;
- int max_depth;
- if (queue_depth < 1)
+ if (queue_depth < 1 || queue_depth == sdev->queue_depth)
return sdev->queue_depth;
dev = ata_scsi_find_dev(ap, sdev);
if (!dev || !ata_dev_enabled(dev))
return sdev->queue_depth;
- max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id));
- max_depth = min(ATA_MAX_QUEUE - 1, max_depth);
- if (queue_depth > max_depth)
- queue_depth = max_depth;
-
- scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
-
+ /* NCQ enabled? */
spin_lock_irqsave(ap->lock, flags);
- if (queue_depth > 1)
- dev->flags &= ~ATA_DFLAG_NCQ_OFF;
- else
+ dev->flags &= ~ATA_DFLAG_NCQ_OFF;
+ if (queue_depth == 1 || !ata_ncq_enabled(dev)) {
dev->flags |= ATA_DFLAG_NCQ_OFF;
+ queue_depth = 1;
+ }
spin_unlock_irqrestore(ap->lock, flags);
+ /* limit and apply queue depth */
+ queue_depth = min(queue_depth, sdev->host->can_queue);
+ queue_depth = min(queue_depth, ata_id_queue_depth(dev->id));
+ queue_depth = min(queue_depth, ATA_MAX_QUEUE - 1);
+
+ if (sdev->queue_depth == queue_depth)
+ return -EINVAL;
+
+ scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth);
return queue_depth;
}
@@ -1469,7 +1475,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
}
if (need_sense && !ap->ops->error_handler)
- ata_dump_status(ap->id, &qc->result_tf);
+ ata_dump_status(ap->print_id, &qc->result_tf);
qc->scsidone(cmd);
@@ -1495,11 +1501,9 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
static int ata_scmd_need_defer(struct ata_device *dev, int is_io)
{
struct ata_port *ap = dev->ap;
+ int is_ncq = is_io && ata_ncq_enabled(dev);
- if (!(dev->flags & ATA_DFLAG_NCQ))
- return 0;
-
- if (is_io) {
+ if (is_ncq) {
if (!ata_tag_valid(ap->active_tag))
return 0;
} else {
@@ -2674,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = qc->dev->devno ?
tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+ /* READ/WRITE LONG use a non-standard sect_size */
+ qc->sect_size = ATA_SECT_SIZE;
+ switch (tf->command) {
+ case ATA_CMD_READ_LONG:
+ case ATA_CMD_READ_LONG_ONCE:
+ case ATA_CMD_WRITE_LONG:
+ case ATA_CMD_WRITE_LONG_ONCE:
+ if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
+ goto invalid_fld;
+ qc->sect_size = scmd->request_bufflen;
+ }
+
/*
* Filter SET_FEATURES - XFER MODE command -- otherwise,
* SET_FEATURES - XFER MODE must be preceded/succeeded
@@ -2774,7 +2790,7 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
u8 *scsicmd = cmd->cmnd;
DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ap->id,
+ ap->print_id,
scsidev->channel, scsidev->id, scsidev->lun,
scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
@@ -2788,8 +2804,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
{
int rc = 0;
- if (unlikely(!scmd->cmd_len)) {
- ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+ if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) {
+ DPRINTK("bad CDB len=%u, max=%u\n",
+ scmd->cmd_len, dev->cdb_len);
scmd->result = DID_ERROR << 16;
done(scmd);
return 0;
@@ -2944,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
}
}
+int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
+{
+ int i, rc;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ struct Scsi_Host *shost;
+
+ rc = -ENOMEM;
+ shost = scsi_host_alloc(sht, sizeof(struct ata_port *));
+ if (!shost)
+ goto err_alloc;
+
+ *(struct ata_port **)&shost->hostdata[0] = ap;
+ ap->scsi_host = shost;
+
+ shost->transportt = &ata_scsi_transport_template;
+ shost->unique_id = ap->print_id;
+ shost->max_id = 16;
+ shost->max_lun = 1;
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+
+ rc = scsi_add_host(ap->scsi_host, ap->host->dev);
+ if (rc)
+ goto err_add;
+ }
+
+ return 0;
+
+ err_add:
+ scsi_host_put(host->ports[i]->scsi_host);
+ err_alloc:
+ while (--i >= 0) {
+ struct Scsi_Host *shost = host->ports[i]->scsi_host;
+
+ scsi_remove_host(shost);
+ scsi_host_put(shost);
+ }
+ return rc;
+}
+
void ata_scsi_scan_host(struct ata_port *ap)
{
unsigned int i;
@@ -3220,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host,
struct ata_port_info *port_info,
struct Scsi_Host *shost)
{
- struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
- struct ata_probe_ent *ent;
+ struct ata_port *ap;
+ ap = ata_port_alloc(host);
if (!ap)
return NULL;
- ent = ata_probe_ent_alloc(host->dev, port_info);
- if (!ent) {
- kfree(ap);
- return NULL;
- }
-
- ata_port_init(ap, host, ent, 0);
+ ap->port_no = 0;
ap->lock = shost->host_lock;
- kfree(ent);
+ ap->pio_mask = port_info->pio_mask;
+ ap->mwdma_mask = port_info->mwdma_mask;
+ ap->udma_mask = port_info->udma_mask;
+ ap->flags |= port_info->flags;
+ ap->ops = port_info->port_ops;
+ ap->cbl = ATA_CBL_SATA;
+
return ap;
}
EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
@@ -3290,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap)
{
int rc = ap->ops->port_start(ap);
- if (!rc)
+ if (!rc) {
+ ap->print_id = ata_print_id++;
rc = ata_bus_probe(ap);
+ }
return rc;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 16bc3e35bdd4..d211db6b35a2 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -175,7 +175,7 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
*/
void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
{
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+ DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
iowrite8(tf->command, ap->ioaddr.command_addr);
ata_pause(ap);
@@ -521,173 +521,404 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
static int ata_resources_present(struct pci_dev *pdev, int port)
{
int i;
-
+
/* Check the PCI resources for this channel are enabled */
port = port * 2;
for (i = 0; i < 2; i ++) {
if (pci_resource_start(pdev, port + i) == 0 ||
- pci_resource_len(pdev, port + i) == 0)
- return 0;
+ pci_resource_len(pdev, port + i) == 0)
+ return 0;
}
return 1;
}
-
+
/**
- * ata_pci_init_native_mode - Initialize native-mode driver
- * @pdev: pci device to be initialized
- * @port: array[2] of pointers to port info structures.
- * @ports: bitmap of ports present
- *
- * Utility function which allocates and initializes an
- * ata_probe_ent structure for a standard dual-port
- * PIO-based IDE controller. The returned ata_probe_ent
- * structure can be passed to ata_device_add(). The returned
- * ata_probe_ent structure should then be freed with kfree().
- *
- * The caller need only pass the address of the primary port, the
- * secondary will be deduced automatically. If the device has non
- * standard secondary port mappings this function can be called twice,
- * once for each interface.
+ * ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host
+ * @host: target ATA host
+ *
+ * Acquire PCI BMDMA resources and initialize @host accordingly.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
*/
+static int ata_pci_init_bmdma(struct ata_host *host)
+{
+ struct device *gdev = host->dev;
+ struct pci_dev *pdev = to_pci_dev(gdev);
+ int i, rc;
+
+ /* TODO: If we get no DMA mask we should fall back to PIO */
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+
+ /* request and iomap DMA region */
+ rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
+ if (rc) {
+ dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
+ return -ENOMEM;
+ }
+ host->iomap = pcim_iomap_table(pdev);
-struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ void __iomem *bmdma = host->iomap[4] + 8 * i;
+
+ if (ata_port_is_dummy(ap))
+ continue;
+
+ ap->ioaddr.bmdma_addr = bmdma;
+ if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (ioread8(bmdma + 2) & 0x80))
+ host->flags |= ATA_HOST_SIMPLEX;
+ }
+
+ return 0;
+}
+
+/**
+ * ata_pci_init_native_host - acquire native ATA resources and init host
+ * @host: target ATA host
+ * @port_mask: ports to consider
+ *
+ * Acquire native PCI ATA resources for @host and initialize
+ * @host accordoingly.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
{
- struct ata_probe_ent *probe_ent;
- int i, p = 0;
- void __iomem * const *iomap;
-
- /* iomap BARs */
- for (i = 0; i < 4; i++) {
- if (pcim_iomap(pdev, i, 0) == NULL) {
- dev_printk(KERN_ERR, &pdev->dev,
- "failed to iomap PCI BAR %d\n", i);
- return NULL;
+ struct device *gdev = host->dev;
+ struct pci_dev *pdev = to_pci_dev(gdev);
+ int i, rc;
+
+ /* Discard disabled ports. Some controllers show their unused
+ * channels this way. Disabled ports are made dummy.
+ */
+ for (i = 0; i < 2; i++) {
+ if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
+ host->ports[i]->ops = &ata_dummy_port_ops;
+ port_mask &= ~(1 << i);
}
}
- pcim_iomap(pdev, 4, 0); /* may fail */
- iomap = pcim_iomap_table(pdev);
-
- /* alloc and init probe_ent */
- probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
- if (!probe_ent)
- return NULL;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
-
- /* Discard disabled ports. Some controllers show their
- unused channels this way */
- if (ata_resources_present(pdev, 0) == 0)
- ports &= ~ATA_PORT_PRIMARY;
- if (ata_resources_present(pdev, 1) == 0)
- ports &= ~ATA_PORT_SECONDARY;
-
- if (ports & ATA_PORT_PRIMARY) {
- probe_ent->port[p].cmd_addr = iomap[0];
- probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr = (void __iomem *)
- ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS);
- if (iomap[4]) {
- if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (ioread8(iomap[4] + 2) & 0x80))
- probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
- probe_ent->port[p].bmdma_addr = iomap[4];
- }
- ata_std_ports(&probe_ent->port[p]);
- p++;
+ if (!port_mask) {
+ dev_printk(KERN_ERR, gdev, "no available port\n");
+ return -ENODEV;
}
- if (ports & ATA_PORT_SECONDARY) {
- probe_ent->port[p].cmd_addr = iomap[2];
- probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr = (void __iomem *)
- ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS);
- if (iomap[4]) {
- if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (ioread8(iomap[4] + 10) & 0x80))
- probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
- probe_ent->port[p].bmdma_addr = iomap[4] + 8;
+ /* request, iomap BARs and init port addresses accordingly */
+ for (i = 0; i < 2; i++) {
+ struct ata_port *ap = host->ports[i];
+ int base = i * 2;
+ void __iomem * const *iomap;
+
+ if (!(port_mask & (1 << i)))
+ continue;
+
+ rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
+ if (rc) {
+ dev_printk(KERN_ERR, gdev, "failed to request/iomap "
+ "BARs for port %d (errno=%d)\n", i, rc);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ return rc;
}
- ata_std_ports(&probe_ent->port[p]);
- probe_ent->pinfo2 = port[1];
- p++;
+ host->iomap = iomap = pcim_iomap_table(pdev);
+
+ ap->ioaddr.cmd_addr = iomap[base];
+ ap->ioaddr.altstatus_addr =
+ ap->ioaddr.ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
+ ata_std_ports(&ap->ioaddr);
+ }
+
+ return 0;
+}
+
+/**
+ * ata_pci_prepare_native_host - helper to prepare native PCI ATA host
+ * @pdev: target PCI device
+ * @ppi: array of port_info
+ * @n_ports: number of ports to allocate
+ * @r_host: out argument for the initialized ATA host
+ *
+ * Helper to allocate ATA host for @pdev, acquire all native PCI
+ * resources and initialize it accordingly in one go.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_pci_prepare_native_host(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ int n_ports, struct ata_host **r_host)
+{
+ struct ata_host *host;
+ unsigned int port_mask;
+ int rc;
+
+ if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+ if (!host) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to allocate ATA host\n");
+ rc = -ENOMEM;
+ goto err_out;
}
- probe_ent->n_ports = p;
- return probe_ent;
+ port_mask = ATA_PORT_PRIMARY;
+ if (n_ports > 1)
+ port_mask |= ATA_PORT_SECONDARY;
+
+ rc = ata_pci_init_native_host(host, port_mask);
+ if (rc)
+ goto err_out;
+
+ /* init DMA related stuff */
+ rc = ata_pci_init_bmdma(host);
+ if (rc)
+ goto err_bmdma;
+
+ devres_remove_group(&pdev->dev, NULL);
+ *r_host = host;
+ return 0;
+
+ err_bmdma:
+ /* This is necessary because PCI and iomap resources are
+ * merged and releasing the top group won't release the
+ * acquired resources if some of those have been acquired
+ * before entering this function.
+ */
+ pcim_iounmap_regions(pdev, 0xf);
+ err_out:
+ devres_release_group(&pdev->dev, NULL);
+ return rc;
}
-static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
- struct ata_port_info **port, int port_mask)
+struct ata_legacy_devres {
+ unsigned int mask;
+ unsigned long cmd_port[2];
+ void __iomem * cmd_addr[2];
+ void __iomem * ctl_addr[2];
+ unsigned int irq[2];
+ void * irq_dev_id[2];
+};
+
+static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
{
- struct ata_probe_ent *probe_ent;
- void __iomem *iomap[5] = { }, *bmdma;
-
- if (port_mask & ATA_PORT_PRIMARY) {
- iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8);
- iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1);
- if (!iomap[0] || !iomap[1])
- return NULL;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (!legacy_dr->irq[i])
+ continue;
+
+ free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
+ legacy_dr->irq[i] = 0;
+ legacy_dr->irq_dev_id[i] = NULL;
}
+}
- if (port_mask & ATA_PORT_SECONDARY) {
- iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8);
- iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1);
- if (!iomap[2] || !iomap[3])
- return NULL;
+static void ata_legacy_release(struct device *gdev, void *res)
+{
+ struct ata_legacy_devres *this = res;
+ int i;
+
+ ata_legacy_free_irqs(this);
+
+ for (i = 0; i < 2; i++) {
+ if (this->cmd_addr[i])
+ ioport_unmap(this->cmd_addr[i]);
+ if (this->ctl_addr[i])
+ ioport_unmap(this->ctl_addr[i]);
+ if (this->cmd_port[i])
+ release_region(this->cmd_port[i], 8);
}
+}
- bmdma = pcim_iomap(pdev, 4, 16); /* may fail */
-
- /* alloc and init probe_ent */
- probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
- if (!probe_ent)
- return NULL;
-
- probe_ent->n_ports = 2;
- probe_ent->irq_flags = IRQF_SHARED;
-
- if (port_mask & ATA_PORT_PRIMARY) {
- probe_ent->irq = ATA_PRIMARY_IRQ(pdev);
- probe_ent->port[0].cmd_addr = iomap[0];
- probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = iomap[1];
- if (bmdma) {
- probe_ent->port[0].bmdma_addr = bmdma;
- if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (ioread8(bmdma + 2) & 0x80))
- probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
- }
- ata_std_ports(&probe_ent->port[0]);
- } else
- probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY;
+static int ata_init_legacy_port(struct ata_port *ap,
+ struct ata_legacy_devres *legacy_dr)
+{
+ struct ata_host *host = ap->host;
+ int port_no = ap->port_no;
+ unsigned long cmd_port, ctl_port;
+
+ if (port_no == 0) {
+ cmd_port = ATA_PRIMARY_CMD;
+ ctl_port = ATA_PRIMARY_CTL;
+ } else {
+ cmd_port = ATA_SECONDARY_CMD;
+ ctl_port = ATA_SECONDARY_CTL;
+ }
+
+ /* request cmd_port */
+ if (request_region(cmd_port, 8, "libata"))
+ legacy_dr->cmd_port[port_no] = cmd_port;
+ else {
+ dev_printk(KERN_WARNING, host->dev,
+ "0x%0lX IDE port busy\n", cmd_port);
+ return -EBUSY;
+ }
- if (port_mask & ATA_PORT_SECONDARY) {
- if (probe_ent->irq)
- probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
+ /* iomap cmd and ctl ports */
+ legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
+ legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
+ if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
+ return -ENOMEM;
+
+ /* init IO addresses */
+ ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
+ ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
+ ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
+ ata_std_ports(&ap->ioaddr);
+
+ return 0;
+}
+
+/**
+ * ata_init_legacy_host - acquire legacy ATA resources and init ATA host
+ * @host: target ATA host
+ * @legacy_mask: out parameter, mask indicating ports is in legacy mode
+ * @was_busy: out parameter, indicates whether any port was busy
+ *
+ * Acquire legacy ATA resources for ports.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+static int ata_init_legacy_host(struct ata_host *host,
+ unsigned int *legacy_mask, int *was_busy)
+{
+ struct device *gdev = host->dev;
+ struct ata_legacy_devres *legacy_dr;
+ int i, rc;
+
+ if (!devres_open_group(gdev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ rc = -ENOMEM;
+ legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
+ GFP_KERNEL);
+ if (!legacy_dr)
+ goto err_out;
+ devres_add(gdev, legacy_dr);
+
+ for (i = 0; i < 2; i++) {
+ *legacy_mask &= ~(1 << i);
+ rc = ata_init_legacy_port(host->ports[i], legacy_dr);
+ if (rc == 0)
+ legacy_dr->mask |= 1 << i;
+ else if (rc == -EBUSY)
+ (*was_busy)++;
+ }
+
+ if (!legacy_dr->mask)
+ return -EBUSY;
+
+ for (i = 0; i < 2; i++)
+ if (!(legacy_dr->mask & (1 << i)))
+ host->ports[i]->ops = &ata_dummy_port_ops;
+
+ *legacy_mask |= legacy_dr->mask;
+
+ devres_remove_group(gdev, NULL);
+ return 0;
+
+ err_out:
+ devres_release_group(gdev, NULL);
+ return rc;
+}
+
+/**
+ * ata_request_legacy_irqs - request legacy ATA IRQs
+ * @host: target ATA host
+ * @handler: array of IRQ handlers
+ * @irq_flags: array of IRQ flags
+ * @dev_id: array of IRQ dev_ids
+ *
+ * Request legacy IRQs for non-dummy legacy ports in @host. All
+ * IRQ parameters are passed as array to allow ports to have
+ * separate IRQ handlers.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+static int ata_request_legacy_irqs(struct ata_host *host,
+ irq_handler_t const *handler,
+ const unsigned int *irq_flags,
+ void * const *dev_id)
+{
+ struct device *gdev = host->dev;
+ struct ata_legacy_devres *legacy_dr;
+ int i, rc;
+
+ legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
+ BUG_ON(!legacy_dr);
+
+ for (i = 0; i < host->n_ports; i++) {
+ unsigned int irq;
+
+ /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
+ if (i == 0)
+ irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
else
- probe_ent->irq = ATA_SECONDARY_IRQ(pdev);
- probe_ent->port[1].cmd_addr = iomap[2];
- probe_ent->port[1].altstatus_addr =
- probe_ent->port[1].ctl_addr = iomap[3];
- if (bmdma) {
- probe_ent->port[1].bmdma_addr = bmdma + 8;
- if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (ioread8(bmdma + 10) & 0x80))
- probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
+ irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
+
+ if (!(legacy_dr->mask & (1 << i)))
+ continue;
+
+ if (!handler[i]) {
+ dev_printk(KERN_ERR, gdev,
+ "NULL handler specified for port %d\n", i);
+ rc = -EINVAL;
+ goto err_out;
+ }
+
+ rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
+ dev_id[i]);
+ if (rc) {
+ dev_printk(KERN_ERR, gdev,
+ "irq %u request failed (errno=%d)\n", irq, rc);
+ goto err_out;
}
- ata_std_ports(&probe_ent->port[1]);
- /* FIXME: could be pointing to stack area; must copy */
- probe_ent->pinfo2 = port[1];
- } else
- probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
+ /* record irq allocation in legacy_dr */
+ legacy_dr->irq[i] = irq;
+ legacy_dr->irq_dev_id[i] = dev_id[i];
- return probe_ent;
-}
+ /* only used to print info */
+ if (i == 0)
+ host->irq = irq;
+ else
+ host->irq2 = irq;
+ }
+ return 0;
+
+ err_out:
+ ata_legacy_free_irqs(legacy_dr);
+ return rc;
+}
/**
* ata_pci_init_one - Initialize/register PCI IDE host controller
@@ -718,8 +949,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
struct device *dev = &pdev->dev;
- struct ata_probe_ent *probe_ent = NULL;
- struct ata_port_info *port[2];
+ struct ata_host *host = NULL;
+ const struct ata_port_info *port[2];
u8 mask;
unsigned int legacy_mode = 0;
int rc;
@@ -732,10 +963,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
BUG_ON(n_ports < 1 || n_ports > 2);
port[0] = port_info[0];
- if (n_ports > 1)
- port[1] = port_info[1];
- else
- port[1] = port[0];
+ port[1] = (n_ports > 1) ? port_info[1] : NULL;
/* FIXME: Really for ATA it isn't safe because the device may be
multi-purpose and we want to leave it alone if it was already
@@ -743,7 +971,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
Checking dev->is_enabled is insufficient as this is not set at
boot for the primary video which is BIOS enabled
- */
+ */
rc = pcim_enable_device(pdev);
if (rc)
@@ -769,96 +997,68 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
#endif
}
+ /* alloc and init host */
+ host = ata_host_alloc_pinfo(dev, port, n_ports);
+ if (!host) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to allocate ATA host\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
if (!legacy_mode) {
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pcim_pin_device(pdev);
+ unsigned int port_mask;
+
+ port_mask = ATA_PORT_PRIMARY;
+ if (n_ports > 1)
+ port_mask |= ATA_PORT_SECONDARY;
+
+ rc = ata_pci_init_native_host(host, port_mask);
+ if (rc)
goto err_out;
- }
} else {
- /* Deal with combined mode hack. This side of the logic all
- goes away once the combined mode hack is killed in 2.6.21 */
- if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) {
- struct resource *conflict, res;
- res.start = ATA_PRIMARY_CMD;
- res.end = ATA_PRIMARY_CMD + 8 - 1;
- conflict = ____request_resource(&ioport_resource, &res);
- while (conflict->child)
- conflict = ____request_resource(conflict, &res);
- if (!strcmp(conflict->name, "libata"))
- legacy_mode |= ATA_PORT_PRIMARY;
- else {
- pcim_pin_device(pdev);
- printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
- "ata: conflict with %s\n",
- ATA_PRIMARY_CMD,
- conflict->name);
- }
- } else
- legacy_mode |= ATA_PORT_PRIMARY;
-
- if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) {
- struct resource *conflict, res;
- res.start = ATA_SECONDARY_CMD;
- res.end = ATA_SECONDARY_CMD + 8 - 1;
- conflict = ____request_resource(&ioport_resource, &res);
- while (conflict->child)
- conflict = ____request_resource(conflict, &res);
- if (!strcmp(conflict->name, "libata"))
- legacy_mode |= ATA_PORT_SECONDARY;
- else {
- pcim_pin_device(pdev);
- printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
- "ata: conflict with %s\n",
- ATA_SECONDARY_CMD,
- conflict->name);
- }
- } else
- legacy_mode |= ATA_PORT_SECONDARY;
-
- if (legacy_mode & ATA_PORT_PRIMARY)
- pci_request_region(pdev, 1, DRV_NAME);
- if (legacy_mode & ATA_PORT_SECONDARY)
- pci_request_region(pdev, 3, DRV_NAME);
- /* If there is a DMA resource, allocate it */
- pci_request_region(pdev, 4, DRV_NAME);
- }
+ int was_busy = 0;
- /* we have legacy mode, but all ports are unavailable */
- if (legacy_mode == (1 << 3)) {
- rc = -EBUSY;
- goto err_out;
+ rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
+ if (was_busy)
+ pcim_pin_device(pdev);
+ if (rc)
+ goto err_out;
+
+ /* request respective PCI regions, may fail */
+ rc = pci_request_region(pdev, 1, DRV_NAME);
+ rc = pci_request_region(pdev, 3, DRV_NAME);
}
- /* TODO: If we get no DMA mask we should fall back to PIO */
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- goto err_out;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ /* init BMDMA, may fail */
+ ata_pci_init_bmdma(host);
+ pci_set_master(pdev);
+
+ /* start host and request IRQ */
+ rc = ata_host_start(host);
if (rc)
goto err_out;
- if (legacy_mode) {
- probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
- } else {
- if (n_ports == 2)
- probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- else
- probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
+ if (!legacy_mode)
+ rc = devm_request_irq(dev, pdev->irq,
+ port_info[0]->port_ops->irq_handler,
+ IRQF_SHARED, DRV_NAME, host);
+ else {
+ irq_handler_t handler[2] = { host->ops->irq_handler,
+ host->ops->irq_handler };
+ unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
+ void *dev_id[2] = { host, host };
+
+ rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
}
- if (!probe_ent) {
- rc = -ENOMEM;
+ if (rc)
goto err_out;
- }
-
- pci_set_master(pdev);
- if (!ata_device_add(probe_ent)) {
- rc = -ENODEV;
+ /* register */
+ rc = ata_host_register(host, port_info[0]->sht);
+ if (rc)
goto err_out;
- }
- devm_kfree(dev, probe_ent);
devres_remove_group(dev, NULL);
return 0;
@@ -893,12 +1093,12 @@ int ata_pci_clear_simplex(struct pci_dev *pdev)
return 0;
}
-unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask)
+unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer_mask)
{
/* Filter out DMA modes if the device has been configured by
the BIOS as PIO only */
- if (ap->ioaddr.bmdma_addr == 0)
+ if (adev->ap->ioaddr.bmdma_addr == 0)
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
return xfer_mask;
}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 06ccf230e3c2..5f4d40cd3288 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -41,12 +41,23 @@ struct ata_scsi_args {
enum {
/* flags for ata_dev_read_id() */
ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */
+
+ /* selector for ata_down_xfermask_limit() */
+ ATA_DNXFER_PIO = 0, /* speed down PIO */
+ ATA_DNXFER_DMA = 1, /* speed down DMA */
+ ATA_DNXFER_40C = 2, /* apply 40c cable limit */
+ ATA_DNXFER_FORCE_PIO = 3, /* force PIO */
+ ATA_DNXFER_FORCE_PIO0 = 4, /* force PIO0 */
+
+ ATA_DNXFER_QUIET = (1 << 31),
};
+extern unsigned int ata_print_id;
extern struct workqueue_struct *ata_aux_wq;
extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
+extern int libata_noacpi;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
@@ -68,7 +79,7 @@ extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
extern int ata_dev_configure(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_port *ap);
extern int sata_set_spd_needed(struct ata_port *ap);
-extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
+extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
@@ -82,15 +93,26 @@ extern int ata_flush_cache(struct ata_device *dev);
extern void ata_dev_init(struct ata_device *dev);
extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
-extern void ata_port_init(struct ata_port *ap, struct ata_host *host,
- const struct ata_probe_ent *ent, unsigned int port_no);
-extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
- const struct ata_port_info *port);
+extern struct ata_port *ata_port_alloc(struct ata_host *host);
+/* libata-acpi.c */
+#ifdef CONFIG_SATA_ACPI
+extern int ata_acpi_exec_tfs(struct ata_port *ap);
+extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
+#else
+static inline int ata_acpi_exec_tfs(struct ata_port *ap)
+{
+ return 0;
+}
+static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+{
+ return 0;
+}
+#endif
/* libata-scsi.c */
-extern struct scsi_transport_template ata_scsi_transport_template;
-
+extern int ata_scsi_add_hosts(struct ata_host *host,
+ struct scsi_host_template *sht);
extern void ata_scsi_scan_host(struct ata_port *ap);
extern int ata_scsi_offline_dev(struct ata_device *dev);
extern void ata_scsi_hotplug(struct work_struct *work);
@@ -135,7 +157,5 @@ extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
/* libata-sff.c */
extern u8 ata_irq_on(struct ata_port *ap);
-/* pata_sis.c */
-extern struct ata_port_info sis_info133;
#endif /* __LIBATA_H__ */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index ab44d18850f6..d40edebb510a 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -34,7 +34,7 @@
#include <linux/dmi.h>
#define DRV_NAME "pata_ali"
-#define DRV_VERSION "0.7.2"
+#define DRV_VERSION "0.7.4"
/*
* Cable special cases
@@ -90,59 +90,6 @@ static int ali_c2_cable_detect(struct ata_port *ap)
}
/**
- * ali_early_error_handler - reset for eary chip
- * @ap: ATA port
- *
- * Handle the reset callback for the later chips with cable detect
- */
-
-static int ali_c2_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ali_c2_cable_detect(ap);
- return ata_std_prereset(ap);
-}
-
-static void ali_c2_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ali_c2_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
-/**
- * ali_early_cable_detect - cable detection
- * @ap: ATA port
- *
- * Perform cable detection for older chipsets. This turns out to be
- * rather easy to implement
- */
-
-static int ali_early_cable_detect(struct ata_port *ap)
-{
- return ATA_CBL_PATA40;
-}
-
-/**
- * ali_early_probe_init - reset for early chip
- * @ap: ATA port
- *
- * Handle the reset callback for the early (pre cable detect) chips.
- */
-
-static int ali_early_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ali_early_cable_detect(ap);
- return ata_std_prereset(ap);
-}
-
-static void ali_early_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, ali_early_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
-/**
* ali_20_filter - filter for earlier ALI DMA
* @ap: ALi ATA port
* @adev: attached device
@@ -151,7 +98,7 @@ static void ali_early_error_handler(struct ata_port *ap)
* fix that later on. Also ensure we do not do UDMA on WDC drives
*/
-static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask)
{
char model_num[ATA_ID_PROD_LEN + 1];
/* No DMA on anything but a disk for now */
@@ -160,7 +107,7 @@ static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (strstr(model_num, "WDC"))
return mask &= ~ATA_MASK_UDMA;
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
/**
@@ -314,7 +261,6 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
/**
* ali_lock_sectors - Keep older devices to 255 sector mode
- * @ap: ATA port
* @adev: Device
*
* Called during the bus probe for each device that is found. We use
@@ -324,7 +270,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* slower PIO methods
*/
-static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev)
+static void ali_lock_sectors(struct ata_device *adev)
{
adev->max_sectors = 255;
}
@@ -345,8 +291,10 @@ static struct scsi_host_template ali_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
/*
@@ -364,8 +312,9 @@ static struct ata_port_operations ali_early_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ali_early_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -400,8 +349,9 @@ static struct ata_port_operations ali_20_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ali_early_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -438,8 +388,9 @@ static struct ata_port_operations ali_c2_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ali_c2_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ali_c2_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -475,8 +426,9 @@ static struct ata_port_operations ali_c5_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ali_c2_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ali_c2_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -667,11 +619,13 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int ali_reinit_one(struct pci_dev *pdev)
{
ali_init_chipset(pdev);
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id ali[] = {
{ PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
@@ -685,8 +639,10 @@ static struct pci_driver ali_pci_driver = {
.id_table = ali,
.probe = ali_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ali_reinit_one,
+#endif
};
static int __init ali_init(void)
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 619e44b04032..536ee892ab72 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_amd"
-#define DRV_VERSION "0.2.7"
+#define DRV_VERSION "0.3.8"
/**
* timing_setup - shared timing computation and load
@@ -119,32 +119,25 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
}
/**
- * amd_probe_init - cable detection
+ * amd_probe_init - perform reset handling
* @ap: ATA port
*
- * Perform cable detection. The BIOS stores this in PCI config
- * space for us.
+ * Reset sequence checking enable bits to see which ports are
+ * active.
*/
static int amd_pre_reset(struct ata_port *ap)
{
- static const u32 bitmask[2] = {0x03, 0xC0};
static const struct pci_bits amd_enable_bits[] = {
{ 0x40, 1, 0x02, 0x02 },
{ 0x40, 1, 0x01, 0x01 }
};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 ata66;
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
return -ENOENT;
- pci_read_config_byte(pdev, 0x42, &ata66);
- if (ata66 & bitmask[ap->port_no])
- ap->cbl = ATA_CBL_PATA80;
- else
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -156,28 +149,16 @@ static void amd_error_handler(struct ata_port *ap)
ata_std_postreset);
}
-static int amd_early_pre_reset(struct ata_port *ap)
+static int amd_cable_detect(struct ata_port *ap)
{
+ static const u32 bitmask[2] = {0x03, 0x0C};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- static struct pci_bits amd_enable_bits[] = {
- { 0x40, 1, 0x02, 0x02 },
- { 0x40, 1, 0x01, 0x01 }
- };
-
- if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
- return -ENOENT;
-
- /* No host side cable detection */
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
-
-}
+ u8 ata66;
-static void amd_early_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, amd_early_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
+ pci_read_config_byte(pdev, 0x42, &ata66);
+ if (ata66 & bitmask[ap->port_no])
+ return ATA_CBL_PATA80;
+ return ATA_CBL_PATA40;
}
/**
@@ -247,31 +228,16 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
*/
static int nv_pre_reset(struct ata_port *ap) {
- static const u8 bitmask[2] = {0x03, 0xC0};
static const struct pci_bits nv_enable_bits[] = {
{ 0x50, 1, 0x02, 0x02 },
{ 0x50, 1, 0x01, 0x01 }
};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 ata66;
- u16 udma;
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
return -ENOENT;
- pci_read_config_byte(pdev, 0x52, &ata66);
- if (ata66 & bitmask[ap->port_no])
- ap->cbl = ATA_CBL_PATA80;
- else
- ap->cbl = ATA_CBL_PATA40;
-
- /* We now have to double check because the Nvidia boxes BIOS
- doesn't always set the cable bits but does set mode bits */
-
- pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
- if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
- ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
@@ -281,6 +247,29 @@ static void nv_error_handler(struct ata_port *ap)
ata_std_softreset, NULL,
ata_std_postreset);
}
+
+static int nv_cable_detect(struct ata_port *ap)
+{
+ static const u8 bitmask[2] = {0x03, 0x0C};
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 ata66;
+ u16 udma;
+ int cbl;
+
+ pci_read_config_byte(pdev, 0x52, &ata66);
+ if (ata66 & bitmask[ap->port_no])
+ cbl = ATA_CBL_PATA80;
+ else
+ cbl = ATA_CBL_PATA40;
+
+ /* We now have to double check because the Nvidia boxes BIOS
+ doesn't always set the cable bits but does set mode bits */
+ pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
+ if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
+ cbl = ATA_CBL_PATA80;
+ return cbl;
+}
+
/**
* nv100_set_piomode - set initial PIO mode data
* @ap: ATA interface
@@ -334,8 +323,10 @@ static struct scsi_host_template amd_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations amd33_port_ops = {
@@ -351,8 +342,9 @@ static struct ata_port_operations amd33_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = amd_early_error_handler,
+ .error_handler = amd_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -385,8 +377,9 @@ static struct ata_port_operations amd66_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = amd_early_error_handler,
+ .error_handler = amd_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -421,6 +414,7 @@ static struct ata_port_operations amd100_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = amd_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -455,6 +449,7 @@ static struct ata_port_operations amd133_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = amd_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = amd_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -489,6 +484,7 @@ static struct ata_port_operations nv100_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = nv_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -523,6 +519,7 @@ static struct ata_port_operations nv133_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = nv_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -663,6 +660,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int amd_reinit_one(struct pci_dev *pdev)
{
if (pdev->vendor == PCI_VENDOR_ID_AMD) {
@@ -679,6 +677,7 @@ static int amd_reinit_one(struct pci_dev *pdev)
}
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id amd[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 },
@@ -708,8 +707,10 @@ static struct pci_driver amd_pci_driver = {
.id_table = amd,
.probe = amd_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = amd_reinit_one,
+#endif
};
static int __init amd_init(void)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 21c30282717c..00e9ec342db0 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -49,8 +49,6 @@ static int artop6210_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
-
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -85,18 +83,28 @@ static int artop6260_pre_reset(struct ata_port *ap)
};
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 tmp;
/* Odd numbered device ids are the units with enable bits (the -R cards) */
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
+ return ata_std_prereset(ap);
+}
+/**
+ * artop6260_cable_detect - identify cable type
+ * @ap: Port
+ *
+ * Identify the cable type for the ARTOp interface in question
+ */
+
+static int artop6260_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 tmp;
pci_read_config_byte(pdev, 0x49, &tmp);
if (tmp & (1 << ap->port_no))
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
}
/**
@@ -225,7 +233,7 @@ static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev)
/**
* artop6210_set_dmamode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
- * @adev: um
+ * @adev: Device whose timings we are configuring
*
* Set DMA mode for device, in host controller PCI config space.
*
@@ -333,6 +341,7 @@ static const struct ata_port_operations artop6210_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = artop6210_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -366,6 +375,7 @@ static const struct ata_port_operations artop6260_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = artop6260_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = artop6260_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index c3eb40c91c80..39c871a3ddac 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -22,7 +22,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_atiixp"
-#define DRV_VERSION "0.4.4"
+#define DRV_VERSION "0.4.5"
enum {
ATIIXP_IDE_PIO_TIMING = 0x40,
@@ -35,23 +35,15 @@ enum {
static int atiixp_pre_reset(struct ata_port *ap)
{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
- u8 udma;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
- /* Hack from drivers/ide/pci. Really we want to know how to do the
- raw detection not play follow the bios mode guess */
- pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
- if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
- ap->cbl = ATA_CBL_PATA80;
- else
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -60,6 +52,19 @@ static void atiixp_error_handler(struct ata_port *ap)
ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
+static int atiixp_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 udma;
+
+ /* Hack from drivers/ide/pci. Really we want to know how to do the
+ raw detection not play follow the bios mode guess */
+ pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
+ if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
+ return ATA_CBL_PATA80;
+ return ATA_CBL_PATA40;
+}
+
/**
* atiixp_set_pio_timing - set initial PIO mode data
* @ap: ATA interface
@@ -224,8 +229,10 @@ static struct scsi_host_template atiixp_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations atiixp_port_ops = {
@@ -243,6 +250,7 @@ static struct ata_port_operations atiixp_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = atiixp_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = atiixp_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = atiixp_bmdma_start,
@@ -290,8 +298,10 @@ static struct pci_driver atiixp_pci_driver = {
.id_table = atiixp,
.probe = atiixp_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.resume = ata_pci_device_resume,
.suspend = ata_pci_device_suspend,
+#endif
};
static int __init atiixp_init(void)
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
new file mode 100644
index 000000000000..2105985a8013
--- /dev/null
+++ b/drivers/ata/pata_cmd640.c
@@ -0,0 +1,312 @@
+/*
+ * pata_cmd640.c - CMD640 PCI PATA for new ATA layer
+ * (C) 2007 Red Hat Inc
+ * Alan Cox <alan@redhat.com>
+ *
+ * Based upon
+ * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996
+ *
+ * Copyright (C) 1995-1996 Linus Torvalds & authors (see driver)
+ *
+ * This drives only the PCI version of the controller. If you have a
+ * VLB one then we have enough docs to support it but you can write
+ * your own code.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pata_cmd640"
+#define DRV_VERSION "0.0.5"
+
+struct cmd640_reg {
+ int last;
+ u8 reg58[ATA_MAX_DEVICES];
+};
+
+enum {
+ CFR = 0x50,
+ CNTRL = 0x51,
+ CMDTIM = 0x52,
+ ARTIM0 = 0x53,
+ DRWTIM0 = 0x54,
+ ARTIM23 = 0x57,
+ DRWTIM23 = 0x58,
+ BRST = 0x59
+};
+
+/**
+ * cmd640_set_piomode - set initial PIO mode data
+ * @ap: ATA port
+ * @adev: ATA device
+ *
+ * Called to do the PIO mode setup.
+ */
+
+static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct cmd640_reg *timing = ap->private_data;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct ata_timing t;
+ const unsigned long T = 1000000 / 33;
+ const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
+ u8 reg;
+ int arttim = ARTIM0 + 2 * adev->devno;
+ struct ata_device *pair = ata_dev_pair(adev);
+
+ if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
+ printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
+ return;
+ }
+
+ /* The second channel has shared timings and the setup timing is
+ messy to switch to merge it for worst case */
+ if (ap->port_no && pair) {
+ struct ata_timing p;
+ ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
+ ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
+ }
+
+ /* Make the timings fit */
+ if (t.recover > 16) {
+ t.active += t.recover - 16;
+ t.recover = 16;
+ }
+ if (t.active > 16)
+ t.active = 16;
+
+ /* Now convert the clocks into values we can actually stuff into
+ the chip */
+
+ if (t.recover > 1)
+ t.recover--; /* 640B only */
+ else
+ t.recover = 15;
+
+ if (t.setup > 4)
+ t.setup = 0xC0;
+ else
+ t.setup = setup_data[t.setup];
+
+ if (ap->port_no == 0) {
+ t.active &= 0x0F; /* 0 = 16 */
+
+ /* Load setup timing */
+ pci_read_config_byte(pdev, arttim, &reg);
+ reg &= 0x3F;
+ reg |= t.setup;
+ pci_write_config_byte(pdev, arttim, reg);
+
+ /* Load active/recovery */
+ pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
+ } else {
+ /* Save the shared timings for channel, they will be loaded
+ by qc_issue_prot. Reloading the setup time is expensive
+ so we keep a merged one loaded */
+ pci_read_config_byte(pdev, ARTIM23, &reg);
+ reg &= 0x3F;
+ reg |= t.setup;
+ pci_write_config_byte(pdev, ARTIM23, reg);
+ timing->reg58[adev->devno] = (t.active << 4) | t.recover;
+ }
+}
+
+
+/**
+ * cmd640_qc_issue_prot - command preparation hook
+ * @qc: Command to be issued
+ *
+ * Channel 1 has shared timings. We must reprogram the
+ * clock each drive 2/3 switch we do.
+ */
+
+static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct ata_device *adev = qc->dev;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct cmd640_reg *timing = ap->private_data;
+
+ if (ap->port_no != 0 && adev->devno != timing->last) {
+ pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
+ timing->last = adev->devno;
+ }
+ return ata_qc_issue_prot(qc);
+}
+
+/**
+ * cmd640_port_start - port setup
+ * @ap: ATA port being set up
+ *
+ * The CMD640 needs to maintain private data structures so we
+ * allocate space here.
+ */
+
+static int cmd640_port_start(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct cmd640_reg *timing;
+
+ int ret = ata_port_start(ap);
+ if (ret < 0)
+ return ret;
+
+ timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
+ if (timing == NULL)
+ return -ENOMEM;
+ timing->last = -1; /* Force a load */
+ ap->private_data = timing;
+ return ret;
+}
+
+static struct scsi_host_template cmd640_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
+#endif
+};
+
+static struct ata_port_operations cmd640_port_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = cmd640_set_piomode,
+ .mode_filter = ata_pci_default_filter,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = cmd640_qc_issue_prot,
+
+ /* In theory this is not needed once we kill the prefetcher */
+ .data_xfer = ata_data_xfer_noirq,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
+ .port_start = cmd640_port_start,
+};
+
+static void cmd640_hardware_init(struct pci_dev *pdev)
+{
+ u8 r;
+ u8 ctrl;
+
+ /* CMD640 detected, commiserations */
+ pci_write_config_byte(pdev, 0x5B, 0x00);
+ /* Get version info */
+ pci_read_config_byte(pdev, CFR, &r);
+ /* PIO0 command cycles */
+ pci_write_config_byte(pdev, CMDTIM, 0);
+ /* 512 byte bursts (sector) */
+ pci_write_config_byte(pdev, BRST, 0x40);
+ /*
+ * A reporter a long time ago
+ * Had problems with the data fifo
+ * So don't run the risk
+ * Of putting crap on the disk
+ * For its better just to go slow
+ */
+ /* Do channel 0 */
+ pci_read_config_byte(pdev, CNTRL, &ctrl);
+ pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
+ /* Ditto for channel 1 */
+ pci_read_config_byte(pdev, ARTIM23, &ctrl);
+ ctrl |= 0x0C;
+ pci_write_config_byte(pdev, ARTIM23, ctrl);
+}
+
+static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ static struct ata_port_info info = {
+ .sht = &cmd640_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .port_ops = &cmd640_port_ops
+ };
+
+ static struct ata_port_info *port_info[2] = { &info, &info };
+
+ cmd640_hardware_init(pdev);
+ return ata_pci_init_one(pdev, port_info, 2);
+}
+
+static int cmd640_reinit_one(struct pci_dev *pdev)
+{
+ cmd640_hardware_init(pdev);
+#ifdef CONFIG_PM
+ return ata_pci_device_resume(pdev);
+#else
+ return 0;
+#endif
+}
+
+static const struct pci_device_id cmd640[] = {
+ { PCI_VDEVICE(CMD, 0x640), 0 },
+ { },
+};
+
+static struct pci_driver cmd640_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = cmd640,
+ .probe = cmd640_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
+ .suspend = ata_pci_device_suspend,
+#endif
+ .resume = cmd640_reinit_one,
+};
+
+static int __init cmd640_init(void)
+{
+ return pci_register_driver(&cmd640_pci_driver);
+}
+
+static void __exit cmd640_exit(void)
+{
+ pci_unregister_driver(&cmd640_pci_driver);
+}
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cmd640);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(cmd640_init);
+module_exit(cmd640_exit);
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index da098282b5f6..3989cc577fcd 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -1,5 +1,5 @@
/*
- * pata_cmd64x.c - ATI PATA for new ATA layer
+ * pata_cmd64x.c - CMD64x PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
@@ -75,13 +75,7 @@ enum {
DTPR1 = 0x7C
};
-static int cmd64x_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-static int cmd648_pre_reset(struct ata_port *ap)
+static int cmd648_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 r;
@@ -89,21 +83,8 @@ static int cmd648_pre_reset(struct ata_port *ap)
/* Check cable detect bits */
pci_read_config_byte(pdev, BMIDECSR, &r);
if (r & (1 << ap->port_no))
- ap->cbl = ATA_CBL_PATA80;
- else
- ap->cbl = ATA_CBL_PATA40;
-
- return ata_std_prereset(ap);
-}
-
-static void cmd64x_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, cmd64x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-static void cmd648_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, cmd648_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ATA_CBL_PATA80;
+ return ATA_CBL_PATA40;
}
/**
@@ -285,8 +266,10 @@ static struct scsi_host_template cmd64x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations cmd64x_port_ops = {
@@ -302,8 +285,9 @@ static struct ata_port_operations cmd64x_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cmd64x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -336,8 +320,9 @@ static struct ata_port_operations cmd646r1_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cmd64x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -370,8 +355,9 @@ static struct ata_port_operations cmd648_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cmd648_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = cmd648_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -479,6 +465,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int cmd64x_reinit_one(struct pci_dev *pdev)
{
u8 mrdmode;
@@ -492,6 +479,7 @@ static int cmd64x_reinit_one(struct pci_dev *pdev)
#endif
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id cmd64x[] = {
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
@@ -507,8 +495,10 @@ static struct pci_driver cmd64x_pci_driver = {
.id_table = cmd64x,
.probe = cmd64x_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = cmd64x_reinit_one,
+#endif
};
static int __init cmd64x_init(void)
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 1ce8fcfd7826..79bef0d1fad3 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_cs5520"
-#define DRV_VERSION "0.6.3"
+#define DRV_VERSION "0.6.4"
struct pio_clocks
{
@@ -139,18 +139,6 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
cs5520_set_timings(ap, adev, adev->pio_mode);
}
-
-static int cs5520_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-static void cs5520_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
static struct scsi_host_template cs5520_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -167,8 +155,10 @@ static struct scsi_host_template cs5520_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations cs5520_port_ops = {
@@ -184,8 +174,9 @@ static struct ata_port_operations cs5520_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cs5520_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -195,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = {
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -203,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = {
.port_start = ata_port_start,
};
-static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct ata_port_info pi = {
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f,
+ .port_ops = &cs5520_port_ops,
+ };
+ const struct ata_port_info *ppi[2];
u8 pcicfg;
void *iomap[5];
- static struct ata_probe_ent probe[2];
- int ports = 0;
+ struct ata_host *host;
+ struct ata_ioports *ioaddr;
+ int i, rc;
/* IDE port enable bits */
- pci_read_config_byte(dev, 0x60, &pcicfg);
+ pci_read_config_byte(pdev, 0x60, &pcicfg);
/* Check if the ATA ports are enabled */
if ((pcicfg & 3) == 0)
return -ENODEV;
+ ppi[0] = ppi[1] = &ata_dummy_port_info;
+ if (pcicfg & 1)
+ ppi[0] = &pi;
+ if (pcicfg & 2)
+ ppi[1] = &pi;
+
if ((pcicfg & 0x40) == 0) {
- printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
- pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
+ dev_printk(KERN_WARNING, &pdev->dev,
+ "DMA mode disabled. Enabling.\n");
+ pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
}
+ pi.mwdma_mask = id->driver_data;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+ if (!host)
+ return -ENOMEM;
+
/* Perform set up for DMA */
- if (pci_enable_device_bars(dev, 1<<2)) {
+ if (pci_enable_device_bars(pdev, 1<<2)) {
printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
return -ENODEV;
}
- pci_set_master(dev);
- if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
return -ENODEV;
}
- if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
+ if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
return -ENODEV;
}
- /* Map IO ports */
- iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8);
- iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1);
- iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8);
- iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1);
- iomap[4] = pcim_iomap(dev, 2, 0);
+ /* Map IO ports and initialize host accordingly */
+ iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
+ iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
+ iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
+ iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
+ iomap[4] = pcim_iomap(pdev, 2, 0);
if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
return -ENOMEM;
- /* We have to do our own plumbing as the PCI setup for this
- chipset is non-standard so we can't punt to the libata code */
-
- INIT_LIST_HEAD(&probe[0].node);
- probe[0].dev = pci_dev_to_dev(dev);
- probe[0].port_ops = &cs5520_port_ops;
- probe[0].sht = &cs5520_sht;
- probe[0].pio_mask = 0x1F;
- probe[0].mwdma_mask = id->driver_data;
- probe[0].irq = 14;
- probe[0].irq_flags = 0;
- probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
- probe[0].n_ports = 1;
- probe[0].port[0].cmd_addr = iomap[0];
- probe[0].port[0].ctl_addr = iomap[1];
- probe[0].port[0].altstatus_addr = iomap[1];
- probe[0].port[0].bmdma_addr = iomap[4];
-
- /* The secondary lurks at different addresses but is otherwise
- the same beastie */
-
- probe[1] = probe[0];
- INIT_LIST_HEAD(&probe[1].node);
- probe[1].irq = 15;
- probe[1].port[0].cmd_addr = iomap[2];
- probe[1].port[0].ctl_addr = iomap[3];
- probe[1].port[0].altstatus_addr = iomap[3];
- probe[1].port[0].bmdma_addr = iomap[4] + 8;
-
- /* Let libata fill in the port details */
- ata_std_ports(&probe[0].port[0]);
- ata_std_ports(&probe[1].port[0]);
-
- /* Now add the ports that are active */
- if (pcicfg & 1)
- ports += ata_device_add(&probe[0]);
- if (pcicfg & 2)
- ports += ata_device_add(&probe[1]);
- if (ports)
- return 0;
- return -ENODEV;
+ ioaddr = &host->ports[0]->ioaddr;
+ ioaddr->cmd_addr = iomap[0];
+ ioaddr->ctl_addr = iomap[1];
+ ioaddr->altstatus_addr = iomap[1];
+ ioaddr->bmdma_addr = iomap[4];
+ ata_std_ports(ioaddr);
+
+ ioaddr = &host->ports[1]->ioaddr;
+ ioaddr->cmd_addr = iomap[2];
+ ioaddr->ctl_addr = iomap[3];
+ ioaddr->altstatus_addr = iomap[3];
+ ioaddr->bmdma_addr = iomap[4] + 8;
+ ata_std_ports(ioaddr);
+
+ /* activate the host */
+ pci_set_master(pdev);
+ rc = ata_host_start(host);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < 2; i++) {
+ static const int irq[] = { 14, 15 };
+ struct ata_port *ap = host->ports[0];
+
+ if (ata_port_is_dummy(ap))
+ continue;
+
+ rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
+ ata_interrupt, 0, DRV_NAME, host);
+ if (rc)
+ return rc;
+ }
+
+ return ata_host_register(host, &cs5520_sht);
}
/**
@@ -306,9 +309,9 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
- dev_set_drvdata(dev, NULL);
}
+#ifdef CONFIG_PM
/**
* cs5520_reinit_one - device resume
* @pdev: PCI device
@@ -325,6 +328,31 @@ static int cs5520_reinit_one(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
return ata_pci_device_resume(pdev);
}
+
+/**
+ * cs5520_pci_device_suspend - device suspend
+ * @pdev: PCI device
+ *
+ * We have to cut and waste bits from the standard method because
+ * the 5520 is a bit odd and not just a pure ATA device. As a result
+ * we must not disable it. The needed code is short and this avoids
+ * chip specific mess in the core code.
+ */
+
+static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc = 0;
+
+ rc = ata_host_suspend(host, mesg);
+ if (rc)
+ return rc;
+
+ pci_save_state(pdev);
+ return 0;
+}
+#endif /* CONFIG_PM */
+
/* For now keep DMA off. We can set it for all but A rev CS5510 once the
core ATA code can handle it */
@@ -340,8 +368,10 @@ static struct pci_driver cs5520_pci_driver = {
.id_table = pata_cs5520,
.probe = cs5520_init_one,
.remove = cs5520_remove_one,
- .suspend = ata_pci_device_suspend,
+#ifdef CONFIG_PM
+ .suspend = cs5520_pci_device_suspend,
.resume = cs5520_reinit_one,
+#endif
};
static int __init cs5520_init(void)
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 3d7b7d87ec6f..29642d5ee189 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -35,7 +35,7 @@
#include <linux/dmi.h>
#define DRV_NAME "pata_cs5530"
-#define DRV_VERSION "0.7.1"
+#define DRV_VERSION "0.7.2"
static void __iomem *cs5530_port_base(struct ata_port *ap)
{
@@ -160,18 +160,6 @@ static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
return ata_qc_issue_prot(qc);
}
-static int cs5530_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-static void cs5530_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, cs5530_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-
static struct scsi_host_template cs5530_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -188,8 +176,10 @@ static struct scsi_host_template cs5530_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations cs5530_port_ops = {
@@ -211,8 +201,9 @@ static struct ata_port_operations cs5530_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cs5530_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = cs5530_qc_issue_prot,
@@ -376,6 +367,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int cs5530_reinit_one(struct pci_dev *pdev)
{
/* If we fail on resume we are doomed */
@@ -383,6 +375,7 @@ static int cs5530_reinit_one(struct pci_dev *pdev)
BUG();
return ata_pci_device_resume(pdev);
}
+#endif /* CONFIG_PM */
static const struct pci_device_id cs5530[] = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
@@ -395,8 +388,10 @@ static struct pci_driver cs5530_pci_driver = {
.id_table = cs5530,
.probe = cs5530_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = cs5530_reinit_one,
+#endif
};
static int __init cs5530_init(void)
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 17bc693cc514..08cccc9c659b 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -70,36 +70,23 @@
#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 )
/**
- * cs5535_pre_reset - detect cable type
+ * cs5535_cable_detect - detect cable type
* @ap: Port to detect on
*
* Perform cable detection for ATA66 capable cable. Return a libata
* cable type.
*/
-static int cs5535_pre_reset(struct ata_port *ap)
+static int cs5535_cable_detect(struct ata_port *ap)
{
u8 cable;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
if (cable & 1)
- ap->cbl = ATA_CBL_PATA80;
+ return ATA_CBL_PATA80;
else
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-/**
- * cs5535_error_handler - reset/probe
- * @ap: Port to reset
- *
- * Reset and configure a port
- */
-
-static void cs5535_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, cs5535_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ATA_CBL_PATA40;
}
/**
@@ -185,8 +172,10 @@ static struct scsi_host_template cs5535_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations cs5535_port_ops = {
@@ -203,8 +192,9 @@ static struct ata_port_operations cs5535_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cs5535_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = cs5535_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -270,8 +260,10 @@ static struct pci_driver cs5535_pci_driver = {
.id_table = cs5535,
.probe = cs5535_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init cs5535_init(void)
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 63f48f08763d..6ec049c3b1dc 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -41,17 +41,6 @@ enum {
CY82_INDEX_TIMEOUT = 0x32
};
-static int cy82c693_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-static void cy82c693_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, cy82c693_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
/**
* cy82c693_set_piomode - set initial PIO mode data
* @ap: ATA interface
@@ -136,8 +125,10 @@ static struct scsi_host_template cy82c693_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations cy82c693_port_ops = {
@@ -154,8 +145,9 @@ static struct ata_port_operations cy82c693_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = cy82c693_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -206,8 +198,10 @@ static struct pci_driver cy82c693_pci_driver = {
.id_table = cy82c693,
.probe = cy82c693_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init cy82c693_init(void)
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index c19b6a8a7dc6..a3216850bba1 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -22,10 +22,10 @@
#include <linux/ata.h>
#define DRV_NAME "pata_efar"
-#define DRV_VERSION "0.4.3"
+#define DRV_VERSION "0.4.4"
/**
- * efar_pre_reset - check for 40/80 pin
+ * efar_pre_reset - Enable bits
* @ap: Port
*
* Perform cable detection for the EFAR ATA interface. This is
@@ -38,18 +38,11 @@ static int efar_pre_reset(struct ata_port *ap)
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
{ 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */
};
-
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 tmp;
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
return -ENOENT;
- pci_read_config_byte(pdev, 0x47, &tmp);
- if (tmp & (2 >> ap->port_no))
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
@@ -67,6 +60,25 @@ static void efar_error_handler(struct ata_port *ap)
}
/**
+ * efar_cable_detect - check for 40/80 pin
+ * @ap: Port
+ *
+ * Perform cable detection for the EFAR ATA interface. This is
+ * different to the PIIX arrangement
+ */
+
+static int efar_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 tmp;
+
+ pci_read_config_byte(pdev, 0x47, &tmp);
+ if (tmp & (2 >> ap->port_no))
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
+}
+
+/**
* efar_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
* @adev: um
@@ -234,8 +246,10 @@ static struct scsi_host_template efar_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations efar_ops = {
@@ -254,6 +268,7 @@ static const struct ata_port_operations efar_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = efar_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = efar_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -317,8 +332,10 @@ static struct pci_driver efar_pci_driver = {
.id_table = efar_pci_tbl,
.probe = efar_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init efar_init(void)
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 27d724b5eea2..93cfa6d300a5 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -27,7 +27,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt366"
-#define DRV_VERSION "0.5.3"
+#define DRV_VERSION "0.6.1"
struct hpt_clock {
u8 xfer_speed;
@@ -169,13 +169,12 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
/**
* hpt366_filter - mode selection filter
- * @ap: ATA interface
* @adev: ATA device
*
* Block UDMA on devices that cause trouble with this controller.
*/
-static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
@@ -185,7 +184,7 @@ static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
mask &= ~(0x0F << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
/**
@@ -210,24 +209,28 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
return 0xffffffffU; /* silence compiler warning */
}
+static int hpt36x_cable_detect(struct ata_port *ap)
+{
+ u8 ata66;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+ pci_read_config_byte(pdev, 0x5A, &ata66);
+ if (ata66 & (1 << ap->port_no))
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
+}
+
static int hpt36x_pre_reset(struct ata_port *ap)
{
static const struct pci_bits hpt36x_enable_bits[] = {
{ 0x50, 1, 0x04, 0x04 },
{ 0x54, 1, 0x04, 0x04 }
};
-
- u8 ata66;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
return -ENOENT;
- pci_read_config_byte(pdev, 0x5A, &ata66);
- if (ata66 & (1 << ap->port_no))
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
@@ -328,8 +331,10 @@ static struct scsi_host_template hpt36x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
/*
@@ -352,6 +357,7 @@ static struct ata_port_operations hpt366_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = hpt36x_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = hpt36x_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -457,12 +463,13 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return ata_pci_init_one(dev, port_info, 2);
}
+#ifdef CONFIG_PM
static int hpt36x_reinit_one(struct pci_dev *dev)
{
hpt36x_init_chipset(dev);
return ata_pci_device_resume(dev);
}
-
+#endif
static const struct pci_device_id hpt36x[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
@@ -474,8 +481,10 @@ static struct pci_driver hpt36x_pci_driver = {
.id_table = hpt36x,
.probe = hpt36x_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = hpt36x_reinit_one,
+#endif
};
static int __init hpt36x_init(void)
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 4ffc392052c0..41d831296347 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -8,6 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
+ * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
*
* TODO
* PLL mode
@@ -25,7 +26,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.5.2"
+#define DRV_VERSION "0.6.5"
struct hpt_clock {
u8 xfer_speed;
@@ -61,201 +62,75 @@ struct hpt_chip {
* 31 FIFO enable.
*/
-/* from highpoint documentation. these are old values */
-static const struct hpt_clock hpt370_timings_33[] = {
-/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */
- { XFER_UDMA_5, 0x16454e31 },
- { XFER_UDMA_4, 0x16454e31 },
- { XFER_UDMA_3, 0x166d4e31 },
- { XFER_UDMA_2, 0x16494e31 },
- { XFER_UDMA_1, 0x164d4e31 },
- { XFER_UDMA_0, 0x16514e31 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
+static struct hpt_clock hpt37x_timings_33[] = {
+ { XFER_UDMA_6, 0x12446231 }, /* 0x12646231 ?? */
+ { XFER_UDMA_5, 0x12446231 },
+ { XFER_UDMA_4, 0x12446231 },
+ { XFER_UDMA_3, 0x126c6231 },
+ { XFER_UDMA_2, 0x12486231 },
+ { XFER_UDMA_1, 0x124c6233 },
+ { XFER_UDMA_0, 0x12506297 },
+
+ { XFER_MW_DMA_2, 0x22406c31 },
+ { XFER_MW_DMA_1, 0x22406c33 },
+ { XFER_MW_DMA_0, 0x22406c97 },
+
+ { XFER_PIO_4, 0x06414e31 },
+ { XFER_PIO_3, 0x06414e42 },
+ { XFER_PIO_2, 0x06414e53 },
+ { XFER_PIO_1, 0x06814e93 },
+ { XFER_PIO_0, 0x06814ea7 }
};
-static const struct hpt_clock hpt370_timings_66[] = {
- { XFER_UDMA_5, 0x14846231 },
- { XFER_UDMA_4, 0x14886231 },
- { XFER_UDMA_3, 0x148c6231 },
- { XFER_UDMA_2, 0x148c6231 },
- { XFER_UDMA_1, 0x14906231 },
- { XFER_UDMA_0, 0x14986231 },
-
- { XFER_MW_DMA_2, 0x26514e21 },
- { XFER_MW_DMA_1, 0x26514e33 },
- { XFER_MW_DMA_0, 0x26514e97 },
-
- { XFER_PIO_4, 0x06514e21 },
- { XFER_PIO_3, 0x06514e22 },
- { XFER_PIO_2, 0x06514e33 },
- { XFER_PIO_1, 0x06914e43 },
- { XFER_PIO_0, 0x06914e57 },
- { 0, 0x06514e57 }
+static struct hpt_clock hpt37x_timings_50[] = {
+ { XFER_UDMA_6, 0x12848242 },
+ { XFER_UDMA_5, 0x12848242 },
+ { XFER_UDMA_4, 0x12ac8242 },
+ { XFER_UDMA_3, 0x128c8242 },
+ { XFER_UDMA_2, 0x120c8242 },
+ { XFER_UDMA_1, 0x12148254 },
+ { XFER_UDMA_0, 0x121882ea },
+
+ { XFER_MW_DMA_2, 0x22808242 },
+ { XFER_MW_DMA_1, 0x22808254 },
+ { XFER_MW_DMA_0, 0x228082ea },
+
+ { XFER_PIO_4, 0x0a81f442 },
+ { XFER_PIO_3, 0x0a81f443 },
+ { XFER_PIO_2, 0x0a81f454 },
+ { XFER_PIO_1, 0x0ac1f465 },
+ { XFER_PIO_0, 0x0ac1f48a }
};
-/* these are the current (4 sep 2001) timings from highpoint */
-static const struct hpt_clock hpt370a_timings_33[] = {
- { XFER_UDMA_5, 0x12446231 },
- { XFER_UDMA_4, 0x12446231 },
- { XFER_UDMA_3, 0x126c6231 },
- { XFER_UDMA_2, 0x12486231 },
- { XFER_UDMA_1, 0x124c6233 },
- { XFER_UDMA_0, 0x12506297 },
-
- { XFER_MW_DMA_2, 0x22406c31 },
- { XFER_MW_DMA_1, 0x22406c33 },
- { XFER_MW_DMA_0, 0x22406c97 },
-
- { XFER_PIO_4, 0x06414e31 },
- { XFER_PIO_3, 0x06414e42 },
- { XFER_PIO_2, 0x06414e53 },
- { XFER_PIO_1, 0x06814e93 },
- { XFER_PIO_0, 0x06814ea7 },
- { 0, 0x06814ea7 }
+static struct hpt_clock hpt37x_timings_66[] = {
+ { XFER_UDMA_6, 0x1c869c62 },
+ { XFER_UDMA_5, 0x1cae9c62 }, /* 0x1c8a9c62 */
+ { XFER_UDMA_4, 0x1c8a9c62 },
+ { XFER_UDMA_3, 0x1c8e9c62 },
+ { XFER_UDMA_2, 0x1c929c62 },
+ { XFER_UDMA_1, 0x1c9a9c62 },
+ { XFER_UDMA_0, 0x1c829c62 },
+
+ { XFER_MW_DMA_2, 0x2c829c62 },
+ { XFER_MW_DMA_1, 0x2c829c66 },
+ { XFER_MW_DMA_0, 0x2c829d2e },
+
+ { XFER_PIO_4, 0x0c829c62 },
+ { XFER_PIO_3, 0x0c829c84 },
+ { XFER_PIO_2, 0x0c829ca6 },
+ { XFER_PIO_1, 0x0d029d26 },
+ { XFER_PIO_0, 0x0d029d5e }
};
-/* 2x 33MHz timings */
-static const struct hpt_clock hpt370a_timings_66[] = {
- { XFER_UDMA_5, 0x1488e673 },
- { XFER_UDMA_4, 0x1488e673 },
- { XFER_UDMA_3, 0x1498e673 },
- { XFER_UDMA_2, 0x1490e673 },
- { XFER_UDMA_1, 0x1498e677 },
- { XFER_UDMA_0, 0x14a0e73f },
-
- { XFER_MW_DMA_2, 0x2480fa73 },
- { XFER_MW_DMA_1, 0x2480fa77 },
- { XFER_MW_DMA_0, 0x2480fb3f },
-
- { XFER_PIO_4, 0x0c82be73 },
- { XFER_PIO_3, 0x0c82be95 },
- { XFER_PIO_2, 0x0c82beb7 },
- { XFER_PIO_1, 0x0d02bf37 },
- { XFER_PIO_0, 0x0d02bf5f },
- { 0, 0x0d02bf5f }
-};
-
-static const struct hpt_clock hpt370a_timings_50[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0ac1f48a }
-};
-
-static const struct hpt_clock hpt372_timings_33[] = {
- { XFER_UDMA_6, 0x1c81dc62 },
- { XFER_UDMA_5, 0x1c6ddc62 },
- { XFER_UDMA_4, 0x1c8ddc62 },
- { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */
- { XFER_UDMA_2, 0x1c91dc62 },
- { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */
- { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */
-
- { XFER_MW_DMA_2, 0x2c829262 },
- { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */
- { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d5e }
-};
-
-static const struct hpt_clock hpt372_timings_50[] = {
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x0a81f443 }
-};
-
-static const struct hpt_clock hpt372_timings_66[] = {
- { XFER_UDMA_6, 0x1c869c62 },
- { XFER_UDMA_5, 0x1cae9c62 },
- { XFER_UDMA_4, 0x1c8a9c62 },
- { XFER_UDMA_3, 0x1c8e9c62 },
- { XFER_UDMA_2, 0x1c929c62 },
- { XFER_UDMA_1, 0x1c9a9c62 },
- { XFER_UDMA_0, 0x1c829c62 },
-
- { XFER_MW_DMA_2, 0x2c829c62 },
- { XFER_MW_DMA_1, 0x2c829c66 },
- { XFER_MW_DMA_0, 0x2c829d2e },
-
- { XFER_PIO_4, 0x0c829c62 },
- { XFER_PIO_3, 0x0c829c84 },
- { XFER_PIO_2, 0x0c829ca6 },
- { XFER_PIO_1, 0x0d029d26 },
- { XFER_PIO_0, 0x0d029d5e },
- { 0, 0x0d029d26 }
-};
-
-static const struct hpt_clock hpt374_timings_33[] = {
- { XFER_UDMA_6, 0x12808242 },
- { XFER_UDMA_5, 0x12848242 },
- { XFER_UDMA_4, 0x12ac8242 },
- { XFER_UDMA_3, 0x128c8242 },
- { XFER_UDMA_2, 0x120c8242 },
- { XFER_UDMA_1, 0x12148254 },
- { XFER_UDMA_0, 0x121882ea },
-
- { XFER_MW_DMA_2, 0x22808242 },
- { XFER_MW_DMA_1, 0x22808254 },
- { XFER_MW_DMA_0, 0x228082ea },
-
- { XFER_PIO_4, 0x0a81f442 },
- { XFER_PIO_3, 0x0a81f443 },
- { XFER_PIO_2, 0x0a81f454 },
- { XFER_PIO_1, 0x0ac1f465 },
- { XFER_PIO_0, 0x0ac1f48a },
- { 0, 0x06814e93 }
-};
static const struct hpt_chip hpt370 = {
"HPT370",
48,
{
- hpt370_timings_33,
+ hpt37x_timings_33,
NULL,
NULL,
- hpt370_timings_66
+ NULL
}
};
@@ -263,10 +138,10 @@ static const struct hpt_chip hpt370a = {
"HPT370A",
48,
{
- hpt370a_timings_33,
+ hpt37x_timings_33,
NULL,
- hpt370a_timings_50,
- hpt370a_timings_66
+ hpt37x_timings_50,
+ NULL
}
};
@@ -274,10 +149,10 @@ static const struct hpt_chip hpt372 = {
"HPT372",
55,
{
- hpt372_timings_33,
+ hpt37x_timings_33,
NULL,
- hpt372_timings_50,
- hpt372_timings_66
+ hpt37x_timings_50,
+ hpt37x_timings_66
}
};
@@ -285,10 +160,10 @@ static const struct hpt_chip hpt302 = {
"HPT302",
66,
{
- hpt372_timings_33,
+ hpt37x_timings_33,
NULL,
- hpt372_timings_50,
- hpt372_timings_66
+ hpt37x_timings_50,
+ hpt37x_timings_66
}
};
@@ -296,10 +171,10 @@ static const struct hpt_chip hpt371 = {
"HPT371",
66,
{
- hpt372_timings_33,
+ hpt37x_timings_33,
NULL,
- hpt372_timings_50,
- hpt372_timings_66
+ hpt37x_timings_50,
+ hpt37x_timings_66
}
};
@@ -307,10 +182,10 @@ static const struct hpt_chip hpt372a = {
"HPT372A",
66,
{
- hpt372_timings_33,
+ hpt37x_timings_33,
NULL,
- hpt372_timings_50,
- hpt372_timings_66
+ hpt37x_timings_50,
+ hpt37x_timings_66
}
};
@@ -318,7 +193,7 @@ static const struct hpt_chip hpt374 = {
"HPT374",
48,
{
- hpt374_timings_33,
+ hpt37x_timings_33,
NULL,
NULL,
NULL
@@ -397,13 +272,12 @@ static const char *bad_ata100_5[] = {
/**
* hpt370_filter - mode selection filter
- * @ap: ATA interface
* @adev: ATA device
*
* Block UDMA on devices that cause trouble with this controller.
*/
-static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
@@ -411,24 +285,23 @@ static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
mask &= ~(0x1F << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
/**
* hpt370a_filter - mode selection filter
- * @ap: ATA interface
* @adev: ATA device
*
* Block UDMA on devices that cause trouble with this controller.
*/
-static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class != ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
mask &= ~ (0x1F << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
/**
@@ -462,8 +335,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
ap->cbl = ATA_CBL_PATA80;
/* Reset the state machine */
- pci_write_config_byte(pdev, 0x50, 0x37);
- pci_write_config_byte(pdev, 0x54, 0x37);
+ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
return ata_std_prereset(ap);
@@ -513,8 +385,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
ap->cbl = ATA_CBL_PATA80;
/* Reset the state machine */
- pci_write_config_byte(pdev, 0x50, 0x37);
- pci_write_config_byte(pdev, 0x54, 0x37);
+ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
return ata_std_prereset(ap);
@@ -1032,6 +903,24 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x3f,
.port_ops = &hpt370a_port_ops
};
+ /* HPT370 - UDMA100 */
+ static struct ata_port_info info_hpt370_33 = {
+ .sht = &hpt37x_sht,
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x0f,
+ .port_ops = &hpt370_port_ops
+ };
+ /* HPT370A - UDMA100 */
+ static struct ata_port_info info_hpt370a_33 = {
+ .sht = &hpt37x_sht,
+ .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x0f,
+ .port_ops = &hpt370a_port_ops
+ };
/* HPT371, 372 and friends - UDMA133 */
static struct ata_port_info info_hpt372 = {
.sht = &hpt37x_sht,
@@ -1067,7 +956,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
u8 irqmask;
u32 class_rev;
+ u8 mcr1;
u32 freq;
+ int prefer_dpll = 1;
+
+ unsigned long iobase = pci_resource_start(dev, 4);
const struct hpt_chip *chip_table;
int clock_slot;
@@ -1088,10 +981,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
case 3:
port = &info_hpt370;
chip_table = &hpt370;
+ prefer_dpll = 0;
break;
case 4:
port = &info_hpt370a;
chip_table = &hpt370a;
+ prefer_dpll = 0;
break;
case 5:
port = &info_hpt372;
@@ -1119,8 +1014,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
chip_table = &hpt302;
break;
case PCI_DEVICE_ID_TTI_HPT371:
+ if (class_rev > 1)
+ return -ENODEV;
port = &info_hpt372;
chip_table = &hpt371;
+ /* Single channel device, master is not present
+ but the BIOS (or us for non x86) must mark it
+ absent */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ mcr1 &= ~0x04;
+ pci_write_config_byte(dev, 0x50, mcr1);
break;
case PCI_DEVICE_ID_TTI_HPT374:
chip_table = &hpt374;
@@ -1150,8 +1053,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
*/
pci_write_config_byte(dev, 0x5b, 0x23);
+
+ /*
+ * HighPoint does this for HPT372A.
+ * NOTE: This register is only writeable via I/O space.
+ */
+ if (chip_table == &hpt372a)
+ outb(0x0e, iobase + 0x9c);
- pci_read_config_dword(dev, 0x70, &freq);
+ /* Some devices do not let this value be accessed via PCI space
+ according to the old driver */
+
+ freq = inl(iobase + 0x90);
if ((freq >> 12) != 0xABCDE) {
int i;
u8 sr;
@@ -1162,7 +1075,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* This is the process the HPT371 BIOS is reported to use */
for(i = 0; i < 128; i++) {
pci_read_config_byte(dev, 0x78, &sr);
- total += sr;
+ total += sr & 0x1FF;
udelay(15);
}
freq = total / 128;
@@ -1173,15 +1086,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
* Turn the frequency check into a band and then find a timing
* table to match it.
*/
-
+
clock_slot = hpt37x_clock_slot(freq, chip_table->base);
- if (chip_table->clocks[clock_slot] == NULL) {
+ if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
/*
* We need to try PLL mode instead
+ *
+ * For non UDMA133 capable devices we should
+ * use a 50MHz DPLL by choice
*/
- unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192;
- unsigned int f_high = f_low + 2;
+ unsigned int f_low, f_high;
int adjust;
+
+ clock_slot = 2;
+ if (port->udma_mask & 0xE0)
+ clock_slot = 3;
+
+ f_low = (MHz[clock_slot] * chip_table->base) / 192;
+ f_high = f_low + 2;
+
+ /* Select the DPLL clock. */
+ pci_write_config_byte(dev, 0x5b, 0x21);
for(adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev))
@@ -1197,25 +1122,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
return -ENODEV;
}
- /* Check if this works for all cases */
- port->private_data = (void *)hpt370_timings_66;
+ if (clock_slot == 3)
+ port->private_data = (void *)hpt37x_timings_66;
+ else
+ port->private_data = (void *)hpt37x_timings_50;
printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
} else {
port->private_data = (void *)chip_table->clocks[clock_slot];
/*
- * Perform a final fixup. The 371 and 372 clock determines
- * if UDMA133 is available.
- */
-
- if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */
- printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n");
- if (port == &info_hpt372)
- port = &info_hpt372_50;
- else BUG();
- }
+ * Perform a final fixup. Note that we will have used the
+ * DPLL on the HPT372 which means we don't have to worry
+ * about lack of UDMA133 support on lower clocks
+ */
+
+ if (clock_slot < 2 && port == &info_hpt370)
+ port = &info_hpt370_33;
+ if (clock_slot < 2 && port == &info_hpt370a)
+ port = &info_hpt370a_33;
printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
}
+
port_info[0] = port_info[1] = port;
/* Now kick off ATA set up */
return ata_pci_init_one(dev, port_info, 2);
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 65f2e180e7fa..6a34521b9e01 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -8,10 +8,10 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
+ * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
*
*
* TODO
- * 371N
* Work out best PLL policy
*/
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n"
-#define DRV_VERSION "0.3.2"
+#define DRV_VERSION "0.3.3"
enum {
HPT_PCI_FAST = (1 << 31),
@@ -115,14 +115,13 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed)
}
/**
- * hpt3x2n_pre_reset - reset the hpt3x2n bus
- * @ap: ATA port to reset
+ * hpt3x2n_cable_detect - Detect the cable type
+ * @ap: ATA port to detect on
*
- * Perform the initial reset handling for the 3x2n series controllers.
- * Reset the hardware and state machine, obtain the cable type.
+ * Return the cable type attached to this port
*/
-static int hpt3xn_pre_reset(struct ata_port *ap)
+static int hpt3x2n_cable_detect(struct ata_port *ap)
{
u8 scr2, ata66;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -135,15 +134,26 @@ static int hpt3xn_pre_reset(struct ata_port *ap)
pci_write_config_byte(pdev, 0x5B, scr2);
if (ata66 & (1 << ap->port_no))
- ap->cbl = ATA_CBL_PATA40;
+ return ATA_CBL_PATA40;
else
- ap->cbl = ATA_CBL_PATA80;
+ return ATA_CBL_PATA80;
+}
+
+/**
+ * hpt3x2n_pre_reset - reset the hpt3x2n bus
+ * @ap: ATA port to reset
+ * @deadline: deadline jiffies for the operation
+ *
+ * Perform the initial reset handling for the 3x2n series controllers.
+ * Reset the hardware and state machine,
+ */
+static int hpt3xn_pre_reset(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
/* Reset the state machine */
- pci_write_config_byte(pdev, 0x50, 0x37);
- pci_write_config_byte(pdev, 0x54, 0x37);
+ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
-
return ata_std_prereset(ap);
}
@@ -364,6 +374,7 @@ static struct ata_port_operations hpt3x2n_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = hpt3x2n_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = hpt3x2n_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -422,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
{
unsigned long freq;
u32 fcnt;
+ unsigned long iobase = pci_resource_start(pdev, 4);
- pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt);
+ fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */
if ((fcnt >> 12) != 0xABCDE) {
printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n");
return 33; /* Not BIOS set */
@@ -492,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
unsigned int pci_mhz;
unsigned int f_low, f_high;
int adjust;
+ unsigned long iobase = pci_resource_start(dev, 4);
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -501,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (class_rev < 6)
return -ENODEV;
break;
+ case PCI_DEVICE_ID_TTI_HPT371:
+ if (class_rev < 2)
+ return -ENODEV;
+ /* 371N if rev > 1 */
+ break;
case PCI_DEVICE_ID_TTI_HPT372:
/* 372N if rev >= 1*/
if (class_rev == 0)
@@ -528,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
irqmask &= ~0x10;
pci_write_config_byte(dev, 0x5a, irqmask);
+ /*
+ * HPT371 chips physically have only one channel, the secondary one,
+ * but the primary channel registers do exist! Go figure...
+ * So, we manually disable the non-existing channel here
+ * (if the BIOS hasn't done this already).
+ */
+ if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
+ u8 mcr1;
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ mcr1 &= ~0x04;
+ pci_write_config_byte(dev, 0x50, mcr1);
+ }
+
/* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
50 for UDMA100. Right now we always use 66 */
@@ -546,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
break;
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
}
- if (adjust == 8)
- printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n");
+ if (adjust == 8) {
+ printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
+ return -ENODEV;
+ }
/* Set our private data up. We only need a few flags so we use
it directly */
port->private_data = NULL;
- if (pci_mhz > 60)
+ if (pci_mhz > 60) {
port->private_data = (void *)PCI66;
+ /*
+ * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+ * the MISC. register to stretch the UltraDMA Tss timing.
+ * NOTE: This register is only writeable via I/O space.
+ */
+ if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
+ outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
+ }
/* Now kick off ATA set up */
port_info[0] = port_info[1] = port;
@@ -562,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
static const struct pci_device_id hpt3x2n[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 483ce7c12c9a..ac28ec8c50aa 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -25,25 +25,6 @@
#define DRV_NAME "pata_hpt3x3"
#define DRV_VERSION "0.4.2"
-static int hpt3x3_probe_init(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-/**
- * hpt3x3_probe_reset - reset the hpt3x3 bus
- * @ap: ATA port to reset
- *
- * Perform the housekeeping when doing an ATA bus reeset. We just
- * need to force the cable type.
- */
-
-static void hpt3x3_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, hpt3x3_probe_init, ata_std_softreset, NULL, ata_std_postreset);
-}
-
/**
* hpt3x3_set_piomode - PIO setup
* @ap: ATA interface
@@ -119,8 +100,10 @@ static struct scsi_host_template hpt3x3_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations hpt3x3_port_ops = {
@@ -137,8 +120,9 @@ static struct ata_port_operations hpt3x3_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = hpt3x3_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -206,11 +190,13 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return ata_pci_init_one(dev, port_info, 2);
}
+#ifdef CONFIG_PM
static int hpt3x3_reinit_one(struct pci_dev *dev)
{
hpt3x3_init_chipset(dev);
return ata_pci_device_resume(dev);
}
+#endif
static const struct pci_device_id hpt3x3[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
@@ -223,8 +209,10 @@ static struct pci_driver hpt3x3_pci_driver = {
.id_table = hpt3x3,
.probe = hpt3x3_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = hpt3x3_reinit_one,
+#endif
};
static int __init hpt3x3_init(void)
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 1bf5ec18b2e3..d042efdfbac4 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -17,7 +17,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_isapnp"
-#define DRV_VERSION "0.1.5"
+#define DRV_VERSION "0.2.0"
static struct scsi_host_template isapnp_sht = {
.module = THIS_MODULE,
@@ -49,13 +49,13 @@ static struct ata_port_operations isapnp_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -74,8 +74,10 @@ static struct ata_port_operations isapnp_port_ops = {
static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
{
- struct ata_probe_ent ae;
+ struct ata_host *host;
+ struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
+ int rc;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
@@ -84,34 +86,36 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
if (pnp_irq_valid(idev, 0) == 0)
return -ENODEV;
+ /* allocate host */
+ host = ata_host_alloc(&idev->dev, 1);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
if (!cmd_addr)
return -ENOMEM;
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &idev->dev;
- ae.port_ops = &isapnp_port_ops;
- ae.sht = &isapnp_sht;
- ae.n_ports = 1;
- ae.pio_mask = 1; /* ISA so PIO 0 cycles */
- ae.irq = pnp_irq(idev, 0);
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_SLAVE_POSS;
- ae.port[0].cmd_addr = cmd_addr;
+ ap = host->ports[0];
+
+ ap->ops = &isapnp_port_ops;
+ ap->pio_mask = 1;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
+
+ ap->ioaddr.cmd_addr = cmd_addr;
if (pnp_port_valid(idev, 1) == 0) {
ctl_addr = devm_ioport_map(&idev->dev,
pnp_port_start(idev, 1), 1);
- ae.port[0].altstatus_addr = ctl_addr;
- ae.port[0].ctl_addr = ctl_addr;
- ae.port_flags |= ATA_FLAG_SRST;
+ ap->ioaddr.altstatus_addr = ctl_addr;
+ ap->ioaddr.ctl_addr = ctl_addr;
}
- ata_std_ports(&ae.port[0]);
- if (ata_device_add(&ae) == 0)
- return -ENODEV;
- return 0;
+ ata_std_ports(&ap->ioaddr);
+
+ /* activate */
+ return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
+ &isapnp_sht);
}
/**
@@ -128,7 +132,6 @@ static void isapnp_remove_one(struct pnp_dev *idev)
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
- dev_set_drvdata(dev, NULL);
}
static struct pnp_device_id isapnp_devices[] = {
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 7eac869dfcd3..011306ef8334 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -25,8 +25,8 @@
* it8213_pre_reset - check for 40/80 pin
* @ap: Port
*
- * Perform cable detection for the 8213 ATA interface. This is
- * different to the PIIX arrangement
+ * Filter out ports by the enable bits before doing the normal reset
+ * and probe.
*/
static int it8213_pre_reset(struct ata_port *ap)
@@ -34,23 +34,14 @@ static int it8213_pre_reset(struct ata_port *ap)
static const struct pci_bits it8213_enable_bits[] = {
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
};
-
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 tmp;
-
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
return -ENOENT;
-
- pci_read_config_byte(pdev, 0x42, &tmp);
- if (tmp & 2) /* The initial docs are incorrect */
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap);
}
/**
- * it8213_probe_reset - Probe specified port on PATA host controller
+ * it8213_error_handler - Probe specified port on PATA host controller
* @ap: Port to probe
*
* LOCKING:
@@ -63,9 +54,27 @@ static void it8213_error_handler(struct ata_port *ap)
}
/**
+ * it8213_cable_detect - check for 40/80 pin
+ * @ap: Port
+ *
+ * Perform cable detection for the 8213 ATA interface. This is
+ * different to the PIIX arrangement
+ */
+
+static int it8213_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 tmp;
+ pci_read_config_byte(pdev, 0x42, &tmp);
+ if (tmp & 2) /* The initial docs are incorrect */
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
+}
+
+/**
* it8213_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
- * @adev: um
+ * @adev: Device whose timings we are configuring
*
* Set PIO mode for device, in host controller PCI config space.
*
@@ -246,8 +255,10 @@ static struct scsi_host_template it8213_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations it8213_ops = {
@@ -266,6 +277,7 @@ static const struct ata_port_operations it8213_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = it8213_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = it8213_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -330,8 +342,10 @@ static struct pci_driver it8213_pci_driver = {
.id_table = it8213_pci_tbl,
.probe = it8213_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init it8213_init(void)
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 73394c75be42..f1f8cec8c224 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -80,7 +80,7 @@
#define DRV_NAME "pata_it821x"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.6"
struct it821x_dev
{
@@ -113,31 +113,6 @@ struct it821x_dev
static int it8212_noraid;
/**
- * it821x_pre_reset - probe
- * @ap: ATA port
- *
- * Set the cable type
- */
-
-static int it821x_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
-}
-
-/**
- * it821x_error_handler - probe/reset
- * @ap: ATA port
- *
- * Set the cable type and trigger a probe
- */
-
-static void it821x_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, it821x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-/**
* it821x_program - program the PIO/MWDMA registers
* @ap: ATA port
* @adev: Device to program
@@ -503,10 +478,12 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
/* We do need the right mode information for DMA or PIO
and this comes from the current configuration flags */
if (dma_enabled & (1 << (5 + i))) {
+ ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
dev->xfer_mode = XFER_MW_DMA_0;
dev->xfer_shift = ATA_SHIFT_MWDMA;
dev->flags &= ~ATA_DFLAG_PIO;
} else {
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
dev->flags |= ATA_DFLAG_PIO;
@@ -518,7 +495,6 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
/**
* it821x_dev_config - Called each device identify
- * @ap: ATA port
* @adev: Device that has just been identified
*
* Perform the initial setup needed for each device that is chip
@@ -529,7 +505,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
* basically we need to filter commands for this chip.
*/
-static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev)
+static void it821x_dev_config(struct ata_device *adev)
{
unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -644,8 +620,10 @@ static struct scsi_host_template it821x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations it821x_smart_port_ops = {
@@ -663,8 +641,9 @@ static struct ata_port_operations it821x_smart_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = it821x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -699,8 +678,9 @@ static struct ata_port_operations it821x_passthru_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = it821x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = it821x_passthru_bmdma_start,
@@ -778,6 +758,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int it821x_reinit_one(struct pci_dev *pdev)
{
/* Resume - turn raid back off if need be */
@@ -785,6 +766,7 @@ static int it821x_reinit_one(struct pci_dev *pdev)
it821x_disable_raid(pdev);
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id it821x[] = {
{ PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
@@ -798,8 +780,10 @@ static struct pci_driver it821x_pci_driver = {
.id_table = it821x,
.probe = it821x_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = it821x_reinit_one,
+#endif
};
static int __init it821x_init(void)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 3222ac7b945d..420c343e5711 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -23,15 +23,16 @@
#include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf"
-#define DRV_VERSION "0.1.1ac1"
+#define DRV_VERSION "0.1.2"
-static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev)
+static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
{
int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_enabled(dev)) {
+ if (ata_dev_ready(dev)) {
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
@@ -128,8 +129,8 @@ static struct ata_port_operations ixp4xx_port_ops = {
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ixp4xx_mmio_data_xfer,
+ .cable_detect = ata_cable_40wire,
- .irq_handler = ata_interrupt,
.irq_clear = ixp4xx_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -172,12 +173,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
{
- int ret;
unsigned int irq;
struct resource *cs0, *cs1;
- struct ata_probe_ent ae;
-
+ struct ata_host *host;
+ struct ata_port *ap;
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
+ int rc;
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -185,6 +186,12 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
if (!cs0 || !cs1)
return -EINVAL;
+ /* allocate host */
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
@@ -192,38 +199,28 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq)
- set_irq_type(irq, IRQT_HIGH);
+ set_irq_type(irq, IRQT_RISING);
/* Setup expansion bus chip selects */
*data->cs0_cfg = data->cs0_bits;
*data->cs1_cfg = data->cs1_bits;
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
+ ap = host->ports[0];
- ae.dev = &pdev->dev;
- ae.port_ops = &ixp4xx_port_ops;
- ae.sht = &ixp4xx_sht;
- ae.n_ports = 1;
- ae.pio_mask = 0x1f; /* PIO4 */
- ae.irq = irq;
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
- | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
+ ap->ops = &ixp4xx_port_ops;
+ ap->pio_mask = 0x1f; /* PIO4 */
+ ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
/* run in polling mode if no irq has been assigned */
if (!irq)
- ae.port_flags |= ATA_FLAG_PIO_POLLING;
+ ap->flags |= ATA_FLAG_PIO_POLLING;
- ixp4xx_setup_port(&ae.port[0], data);
+ ixp4xx_setup_port(&ap->ioaddr, data);
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- ret = ata_device_add(&ae);
- if (ret == 0)
- return -ENODEV;
-
- return 0;
+ /* activate host */
+ return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
}
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
@@ -231,7 +228,6 @@ static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
struct ata_host *host = platform_get_drvdata(dev);
ata_host_detach(host);
- platform_set_drvdata(dev, NULL);
return 0;
}
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 7a635dd326f8..43763c99ea02 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -137,6 +137,10 @@ static struct scsi_host_template jmicron_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations jmicron_ops = {
@@ -202,49 +206,20 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
};
struct ata_port_info *port_info[2] = { &info, &info };
- u32 reg;
-
- /* PATA controller is fn 1, AHCI is fn 0 */
- if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1)
- return -ENODEV;
-
- /* The 365/66 have two PATA channels, redirect the second */
- if (id->driver_data == 365 || id->driver_data == 366) {
- pci_read_config_dword(pdev, 0x80, &reg);
- reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
- pci_write_config_dword(pdev, 0x80, reg);
- }
-
return ata_pci_init_one(pdev, port_info, 2);
}
-static int jmicron_reinit_one(struct pci_dev *pdev)
-{
- u32 reg;
-
- switch(pdev->device) {
- case PCI_DEVICE_ID_JMICRON_JMB368:
- break;
- case PCI_DEVICE_ID_JMICRON_JMB365:
- case PCI_DEVICE_ID_JMICRON_JMB366:
- /* Restore mapping or disks swap and boy does it get ugly */
- pci_read_config_dword(pdev, 0x80, &reg);
- reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
- pci_write_config_dword(pdev, 0x80, reg);
- /* Fall through */
- default:
- /* Make sure AHCI is turned back on */
- pci_write_config_byte(pdev, 0x41, 0xa1);
- }
- return ata_pci_device_resume(pdev);
-}
-
static const struct pci_device_id jmicron_pci_tbl[] = {
- { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
- { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
- { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 365},
- { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 366},
- { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 368},
+ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 361 },
+ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 363 },
+ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 365 },
+ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 366 },
+ { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 368 },
{ } /* terminate list */
};
@@ -254,8 +229,10 @@ static struct pci_driver jmicron_pci_driver = {
.id_table = jmicron_pci_tbl,
.probe = jmicron_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
- .resume = jmicron_reinit_one,
+ .resume = ata_pci_device_resume,
+#endif
};
static int __init jmicron_init(void)
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 98c1fee4b305..707099291e01 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -64,12 +64,12 @@
#include <linux/platform_device.h>
#define DRV_NAME "pata_legacy"
-#define DRV_VERSION "0.5.3"
+#define DRV_VERSION "0.5.4"
#define NR_HOST 6
static int legacy_port[NR_HOST] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 };
-static int legacy_irq[NR_HOST] = { 15, 14, 11, 10, 8, 12 };
+static int legacy_irq[NR_HOST] = { 14, 15, 11, 10, 8, 12 };
struct legacy_data {
unsigned long timing;
@@ -162,6 +162,7 @@ static struct ata_port_operations simple_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -185,8 +186,12 @@ static struct ata_port_operations legacy_port_ops = {
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .cable_detect = ata_cable_40wire,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -298,7 +303,11 @@ static struct ata_port_operations pdc20230_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -350,7 +359,11 @@ static struct ata_port_operations ht6560a_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -413,7 +426,11 @@ static struct ata_port_operations ht6560b_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -531,7 +548,11 @@ static struct ata_port_operations opti82c611a_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
@@ -661,7 +682,11 @@ static struct ata_port_operations opti82c46x_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = opti82c46x_qc_issue_prot,
@@ -691,7 +716,8 @@ static struct ata_port_operations opti82c46x_port_ops = {
static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq)
{
struct legacy_data *ld = &legacy_data[nr_legacy_host];
- struct ata_probe_ent ae;
+ struct ata_host *host;
+ struct ata_port *ap;
struct platform_device *pdev;
struct ata_port_operations *ops = &legacy_port_ops;
void __iomem *io_addr, *ctrl_addr;
@@ -773,24 +799,23 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
if (ops == &legacy_port_ops && (autospeed & mask))
ops = &simple_port_ops;
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &pdev->dev;
- ae.port_ops = ops;
- ae.sht = &legacy_sht;
- ae.n_ports = 1;
- ae.pio_mask = pio_modes;
- ae.irq = irq;
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
- ae.port[0].cmd_addr = io_addr;
- ae.port[0].altstatus_addr = ctrl_addr;
- ae.port[0].ctl_addr = ctrl_addr;
- ata_std_ports(&ae.port[0]);
- ae.private_data = ld;
-
- ret = -ENODEV;
- if (!ata_device_add(&ae))
+ ret = -ENOMEM;
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ goto fail;
+ ap = host->ports[0];
+
+ ap->ops = ops;
+ ap->pio_mask = pio_modes;
+ ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
+ ap->ioaddr.cmd_addr = io_addr;
+ ap->ioaddr.altstatus_addr = ctrl_addr;
+ ap->ioaddr.ctl_addr = ctrl_addr;
+ ata_std_ports(&ap->ioaddr);
+ ap->private_data = ld;
+
+ ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
+ if (ret)
goto fail;
legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 13a70ac6f1dc..d9b94a1b6954 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -20,7 +20,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_marvell"
-#define DRV_VERSION "0.1.1"
+#define DRV_VERSION "0.1.4"
/**
* marvell_pre_reset - check for 40/80 pin
@@ -52,22 +52,23 @@ static int marvell_pre_reset(struct ata_port *ap)
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
(!(devices & 0x10))) /* PATA enable ? */
return -ENOENT;
+ return ata_std_prereset(ap);
+}
+static int marvell_cable_detect(struct ata_port *ap)
+{
/* Cable type */
switch(ap->port_no)
{
case 0:
if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
- break;
-
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
case 1: /* Legacy SATA port */
- ap->cbl = ATA_CBL_SATA;
- break;
+ return ATA_CBL_SATA;
}
- return ata_std_prereset(ap);
+ BUG();
+ return 0; /* Our BUG macro needs the right markup */
}
/**
@@ -103,8 +104,10 @@ static struct scsi_host_template marvell_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations marvell_ops = {
@@ -121,6 +124,7 @@ static const struct ata_port_operations marvell_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = marvell_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = marvell_cable_detect,
/* BMDMA handling is PCI ATA format, use helpers */
.bmdma_setup = ata_bmdma_setup,
@@ -199,8 +203,10 @@ static struct pci_driver marvell_pci_driver = {
.id_table = marvell_pci_tbl,
.probe = marvell_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init marvell_init(void)
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 29e1809e5ecf..9587a89f9683 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -24,7 +24,7 @@
#define DRV_NAME "mpc52xx_ata"
-#define DRV_VERSION "0.1.0"
+#define DRV_VERSION "0.1.0ac2"
/* Private structures used by the driver */
@@ -280,6 +280,10 @@ static struct scsi_host_template mpc52xx_ata_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+#endif
};
static struct ata_port_operations mpc52xx_ata_port_ops = {
@@ -293,39 +297,38 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = mpc52xx_ata_error_handler,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
.port_start = ata_port_start,
};
-static struct ata_probe_ent mpc52xx_ata_probe_ent = {
- .port_ops = &mpc52xx_ata_port_ops,
- .sht = &mpc52xx_ata_sht,
- .n_ports = 1,
- .pio_mask = 0x1f, /* Up to PIO4 */
- .mwdma_mask = 0x00, /* No MWDMA */
- .udma_mask = 0x00, /* No UDMA */
- .port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .irq_flags = 0,
-};
-
static int __devinit
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
{
- struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
- struct ata_ioports *aio = &ae->port[0];
- int rv;
-
- INIT_LIST_HEAD(&ae->node);
- ae->dev = dev;
- ae->irq = priv->ata_irq;
-
- aio->cmd_addr = 0; /* Don't have a classic reg block */
+ struct ata_host *host;
+ struct ata_port *ap;
+ struct ata_ioports *aio;
+ int rc;
+
+ host = ata_host_alloc(dev, 1);
+ if (!host)
+ return -ENOMEM;
+
+ ap = host->ports[0];
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
+ ap->pio_mask = 0x1f; /* Up to PIO4 */
+ ap->mwdma_mask = 0x00; /* No MWDMA */
+ ap->udma_mask = 0x00; /* No UDMA */
+ ap->ops = &mpc52xx_ata_port_ops;
+ host->private_data = priv;
+
+ aio = &ap->ioaddr;
+ aio->cmd_addr = NULL; /* Don't have a classic reg block */
aio->altstatus_addr = &priv->ata_regs->tf_control;
aio->ctl_addr = &priv->ata_regs->tf_control;
aio->data_addr = &priv->ata_regs->tf_data;
@@ -339,11 +342,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
aio->status_addr = &priv->ata_regs->tf_command;
aio->command_addr = &priv->ata_regs->tf_command;
- ae->private_data = priv;
-
- rv = ata_device_add(ae);
-
- return rv ? 0 : -EINVAL;
+ /* activate host */
+ return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
+ &mpc52xx_ata_sht);
}
static struct mpc52xx_ata_priv *
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index f2e7115f7ab9..987c5fafab08 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_mpiix"
-#define DRV_VERSION "0.7.5"
+#define DRV_VERSION "0.7.6"
enum {
IDETIM = 0x6C, /* IDE control register */
@@ -53,7 +53,6 @@ static int mpiix_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -165,8 +164,10 @@ static struct scsi_host_template mpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations mpiix_port_ops = {
@@ -183,12 +184,12 @@ static struct ata_port_operations mpiix_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = mpiix_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = mpiix_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -199,8 +200,9 @@ static struct ata_port_operations mpiix_port_ops = {
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* Single threaded by the PCI probe logic */
- static struct ata_probe_ent probe;
static int printed_version;
+ struct ata_host *host;
+ struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
u16 idetim;
int irq;
@@ -208,6 +210,10 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
+ host = ata_host_alloc(&dev->dev, 1);
+ if (!host)
+ return -ENOMEM;
+
/* MPIIX has many functions which can be turned on or off according
to other devices present. Make sure IDE is enabled before we try
and use it */
@@ -236,27 +242,21 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
without BARs set fools the setup. #2 If you pci_disable_device
the MPIIX your box goes castors up */
- INIT_LIST_HEAD(&probe.node);
- probe.dev = pci_dev_to_dev(dev);
- probe.port_ops = &mpiix_port_ops;
- probe.sht = &mpiix_sht;
- probe.pio_mask = 0x1F;
- probe.irq_flags = IRQF_SHARED;
- probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- probe.n_ports = 1;
+ ap = host->ports[0];
+ ap->ops = &mpiix_port_ops;
+ ap->pio_mask = 0x1F;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
- probe.irq = irq;
- probe.port[0].cmd_addr = cmd_addr;
- probe.port[0].ctl_addr = ctl_addr;
- probe.port[0].altstatus_addr = ctl_addr;
+ ap->ioaddr.cmd_addr = cmd_addr;
+ ap->ioaddr.ctl_addr = ctl_addr;
+ ap->ioaddr.altstatus_addr = ctl_addr;
/* Let libata fill in the port details */
- ata_std_ports(&probe.port[0]);
+ ata_std_ports(&ap->ioaddr);
- /* Now add the port that is active */
- if (ata_device_add(&probe))
- return 0;
- return -ENODEV;
+ /* activate host */
+ return ata_host_activate(host, irq, ata_interrupt, IRQF_SHARED,
+ &mpiix_sht);
}
static const struct pci_device_id mpiix[] = {
@@ -270,8 +270,10 @@ static struct pci_driver mpiix_pci_driver = {
.id_table = mpiix,
.probe = mpiix_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init mpiix_init(void)
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index e8393e19be47..dbba5b77d79c 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -16,33 +16,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_netcell"
-#define DRV_VERSION "0.1.6"
-
-/**
- * netcell_probe_init - check for 40/80 pin
- * @ap: Port
- *
- * Cables are handled by the RAID controller. Report 80 pin.
- */
-
-static int netcell_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
-}
-
-/**
- * netcell_probe_reset - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void netcell_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, netcell_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
+#define DRV_VERSION "0.1.7"
/* No PIO or DMA methods needed for this device */
@@ -63,8 +37,10 @@ static struct scsi_host_template netcell_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations netcell_ops = {
@@ -79,8 +55,9 @@ static const struct ata_port_operations netcell_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = netcell_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_80wire,
/* BMDMA handling is PCI ATA format, use helpers */
.bmdma_setup = ata_bmdma_setup,
@@ -153,8 +130,10 @@ static struct pci_driver netcell_pci_driver = {
.id_table = netcell_pci_tbl,
.probe = netcell_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init netcell_init(void)
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 3d1fa487c486..078aeda9cf8d 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -28,13 +28,13 @@
#include <linux/libata.h>
#define DRV_NAME "pata_ns87410"
-#define DRV_VERSION "0.4.3"
+#define DRV_VERSION "0.4.6"
/**
* ns87410_pre_reset - probe begin
* @ap: ATA port
*
- * Set up cable type and use generic probe init
+ * Check enabled ports
*/
static int ns87410_pre_reset(struct ata_port *ap)
@@ -47,7 +47,6 @@ static int ns87410_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -157,8 +156,10 @@ static struct scsi_host_template ns87410_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations ns87410_port_ops = {
@@ -175,6 +176,7 @@ static struct ata_port_operations ns87410_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ns87410_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ns87410_qc_issue_prot,
@@ -212,8 +214,10 @@ static struct pci_driver ns87410_pci_driver = {
.id_table = ns87410,
.probe = ns87410_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init ns87410_init(void)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 45215aa05e72..dea4690340d1 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -25,7 +25,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_oldpiix"
-#define DRV_VERSION "0.5.3"
+#define DRV_VERSION "0.5.5"
/**
* oldpiix_pre_reset - probe begin
@@ -44,7 +44,6 @@ static int oldpiix_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -65,7 +64,7 @@ static void oldpiix_pata_error_handler(struct ata_port *ap)
/**
* oldpiix_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port whose timings we are configuring
- * @adev: um
+ * @adev: Device whose timings we are configuring
*
* Set PIO mode for device, in host controller PCI config space.
*
@@ -209,10 +208,9 @@ static unsigned int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc)
struct ata_device *adev = qc->dev;
if (adev != ap->private_data) {
+ oldpiix_set_piomode(ap, adev);
if (adev->dma_mode)
oldpiix_set_dmamode(ap, adev);
- else if (adev->pio_mode)
- oldpiix_set_piomode(ap, adev);
}
return ata_qc_issue_prot(qc);
}
@@ -234,8 +232,10 @@ static struct scsi_host_template oldpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations oldpiix_pata_ops = {
@@ -254,6 +254,7 @@ static const struct ata_port_operations oldpiix_pata_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = oldpiix_pata_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -317,8 +318,10 @@ static struct pci_driver oldpiix_pci_driver = {
.id_table = oldpiix_pci_tbl,
.probe = oldpiix_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init oldpiix_init(void)
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index da1aa148b37d..13b63e21838d 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -34,7 +34,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_opti"
-#define DRV_VERSION "0.2.7"
+#define DRV_VERSION "0.2.9"
enum {
READ_REG = 0, /* index of Read cycle timing register */
@@ -61,8 +61,6 @@ static int opti_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
return -ENOENT;
-
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -179,8 +177,10 @@ static struct scsi_host_template opti_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations opti_port_ops = {
@@ -196,6 +196,7 @@ static struct ata_port_operations opti_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = opti_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -244,8 +245,10 @@ static struct pci_driver opti_pci_driver = {
.id_table = opti,
.probe = opti_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init opti_init(void)
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index d80b36e209cc..b70e04c144df 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -33,7 +33,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_optidma"
-#define DRV_VERSION "0.2.3"
+#define DRV_VERSION "0.3.2"
enum {
READ_REG = 0, /* index of Read cycle timing register */
@@ -62,7 +62,6 @@ static int optidma_pre_reset(struct ata_port *ap)
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -115,7 +114,7 @@ static void optidma_lock(struct ata_port *ap)
}
/**
- * optidma_set_mode - set mode data
+ * optidma_mode_setup - set mode data
* @ap: ATA interface
* @adev: ATA device
* @mode: Mode to set
@@ -128,7 +127,7 @@ static void optidma_lock(struct ata_port *ap)
* IRQ here we depend on the host set locking to avoid catastrophe.
*/
-static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
+static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
{
struct ata_device *pair = ata_dev_pair(adev);
int pio = adev->pio_mode - XFER_PIO_0;
@@ -202,7 +201,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
}
/**
- * optiplus_set_mode - DMA setup for Firestar Plus
+ * optiplus_mode_setup - DMA setup for Firestar Plus
* @ap: ATA port
* @adev: device
* @mode: desired mode
@@ -213,7 +212,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
* one
*/
-static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
+static void optiplus_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 udcfg;
@@ -225,7 +224,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
pci_read_config_byte(pdev, 0x44, &udcfg);
if (mode <= XFER_UDMA_0) {
udcfg &= ~(1 << unit);
- optidma_set_mode(ap, adev, adev->dma_mode);
+ optidma_mode_setup(ap, adev, adev->dma_mode);
} else {
udcfg |= (1 << unit);
if (ap->port_no) {
@@ -253,7 +252,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
{
- optidma_set_mode(ap, adev, adev->pio_mode);
+ optidma_mode_setup(ap, adev, adev->pio_mode);
}
/**
@@ -268,7 +267,7 @@ static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
{
- optidma_set_mode(ap, adev, adev->dma_mode);
+ optidma_mode_setup(ap, adev, adev->dma_mode);
}
/**
@@ -283,7 +282,7 @@ static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
{
- optiplus_set_mode(ap, adev, adev->pio_mode);
+ optiplus_mode_setup(ap, adev, adev->pio_mode);
}
/**
@@ -298,7 +297,7 @@ static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
static void optiplus_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
{
- optiplus_set_mode(ap, adev, adev->dma_mode);
+ optiplus_mode_setup(ap, adev, adev->dma_mode);
}
/**
@@ -322,26 +321,29 @@ static u8 optidma_make_bits43(struct ata_device *adev)
}
/**
- * optidma_post_set_mode - finalize PCI setup
+ * optidma_set_mode - mode setup
* @ap: port to set up
*
- * Finalise the configuration by writing the nibble of extra bits
- * of data into the chip.
+ * Use the standard setup to tune the chipset and then finalise the
+ * configuration by writing the nibble of extra bits of data into
+ * the chip.
*/
-static void optidma_post_set_mode(struct ata_port *ap)
+static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed)
{
u8 r;
int nybble = 4 * ap->port_no;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
- pci_read_config_byte(pdev, 0x43, &r);
-
- r &= (0x0F << nybble);
- r |= (optidma_make_bits43(&ap->device[0]) +
- (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
-
- pci_write_config_byte(pdev, 0x43, r);
+ int rc = ata_do_set_mode(ap, r_failed);
+ if (rc == 0) {
+ pci_read_config_byte(pdev, 0x43, &r);
+
+ r &= (0x0F << nybble);
+ r |= (optidma_make_bits43(&ap->device[0]) +
+ (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
+ pci_write_config_byte(pdev, 0x43, r);
+ }
+ return rc;
}
static struct scsi_host_template optidma_sht = {
@@ -360,8 +362,10 @@ static struct scsi_host_template optidma_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations optidma_port_ops = {
@@ -379,7 +383,8 @@ static struct ata_port_operations optidma_port_ops = {
.thaw = ata_bmdma_thaw,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.error_handler = optidma_error_handler,
- .post_set_mode = optidma_post_set_mode,
+ .set_mode = optidma_set_mode,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -414,7 +419,8 @@ static struct ata_port_operations optiplus_port_ops = {
.thaw = ata_bmdma_thaw,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.error_handler = optidma_error_handler,
- .post_set_mode = optidma_post_set_mode,
+ .set_mode = optidma_set_mode,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -524,8 +530,10 @@ static struct pci_driver optidma_pci_driver = {
.id_table = optidma,
.probe = optidma_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init optidma_init(void)
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 36468ec6454c..75dc84797ff3 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -42,7 +42,7 @@
#define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.2.11"
+#define DRV_VERSION "0.3.1"
/*
* Private data structure to glue stuff together
@@ -54,6 +54,39 @@ struct ata_pcmcia_info {
dev_node_t node;
};
+/**
+ * pcmcia_set_mode - PCMCIA specific mode setup
+ * @ap: Port
+ * @r_failed_dev: Return pointer for failed device
+ *
+ * Perform the tuning and setup of the devices and timings, which
+ * for PCMCIA is the same as any other controller. We wrap it however
+ * as we need to spot hardware with incorrect or missing master/slave
+ * decode, which alas is embarrassingly common in the PC world
+ */
+
+static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+ struct ata_device *master = &ap->device[0];
+ struct ata_device *slave = &ap->device[1];
+
+ if (!ata_dev_enabled(master) || !ata_dev_enabled(slave))
+ return ata_do_set_mode(ap, r_failed_dev);
+
+ if (memcmp(master->id + ATA_ID_FW_REV, slave->id + ATA_ID_FW_REV,
+ ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0)
+ {
+ /* Suspicious match, but could be two cards from
+ the same vendor - check serial */
+ if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO,
+ ATA_ID_SERNO_LEN) == 0 && master->id[ATA_ID_SERNO] >> 8) {
+ ata_dev_printk(slave, KERN_WARNING, "is a ghost device, ignoring.\n");
+ ata_dev_disable(slave);
+ }
+ }
+ return ata_do_set_mode(ap, r_failed_dev);
+}
+
static struct scsi_host_template pcmcia_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -73,6 +106,7 @@ static struct scsi_host_template pcmcia_sht = {
};
static struct ata_port_operations pcmcia_port_ops = {
+ .set_mode = pcmcia_set_mode,
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -84,13 +118,13 @@ static struct ata_port_operations pcmcia_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer_noirq,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -111,7 +145,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int pcmcia_init_one(struct pcmcia_device *pdev)
{
- struct ata_probe_ent ae;
+ struct ata_host *host;
+ struct ata_port *ap;
struct ata_pcmcia_info *info;
tuple_t tuple;
struct {
@@ -255,24 +290,24 @@ next_entry:
* Having done the PCMCIA plumbing the ATA side is relatively
* sane.
*/
-
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &pdev->dev;
- ae.port_ops = &pcmcia_port_ops;
- ae.sht = &pcmcia_sht;
- ae.n_ports = 1;
- ae.pio_mask = 1; /* ISA so PIO 0 cycles */
- ae.irq = pdev->irq.AssignedIRQ;
- ae.irq_flags = IRQF_SHARED;
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io_addr;
- ae.port[0].altstatus_addr = ctl_addr;
- ae.port[0].ctl_addr = ctl_addr;
- ata_std_ports(&ae.port[0]);
-
- ret = -ENODEV;
- if (ata_device_add(&ae) == 0)
+ ret = -ENOMEM;
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ goto failed;
+ ap = host->ports[0];
+
+ ap->ops = &pcmcia_port_ops;
+ ap->pio_mask = 1; /* ISA so PIO 0 cycles */
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
+ ap->ioaddr.cmd_addr = io_addr;
+ ap->ioaddr.altstatus_addr = ctl_addr;
+ ap->ioaddr.ctl_addr = ctl_addr;
+ ata_std_ports(&ap->ioaddr);
+
+ /* activate */
+ ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt,
+ IRQF_SHARED, &pcmcia_sht);
+ if (ret)
goto failed;
info->ndev = 1;
@@ -308,7 +343,6 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev)
if (info->ndev) {
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
- dev_set_drvdata(dev, NULL);
}
info->ndev = 0;
pdev->priv = NULL;
@@ -320,14 +354,17 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev)
static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_FUNC_ID(4),
PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
+ PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
+ PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
- PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
+ PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401), /* SanDisk CFA */
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
- PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar */
+ PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100), /* Viking CFA */
+ PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar, Viking CFA */
PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 61537873d28e..a61cbc110688 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_pdc2027x"
-#define DRV_VERSION "0.74-ac5"
+#define DRV_VERSION "0.9"
#undef PDC_DEBUG
#ifdef PDC_DEBUG
@@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e
static void pdc2027x_error_handler(struct ata_port *ap);
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_post_set_mode(struct ata_port *ap);
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
+static int pdc2027x_cable_detect(struct ata_port *ap);
+static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed);
/*
* ATA Timing Tables based on 133MHz controller clock.
@@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = {
static struct ata_port_operations pdc2027x_pata100_ops = {
.port_disable = ata_port_disable,
+ .mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -166,8 +169,8 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = pdc2027x_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = pdc2027x_cable_detect,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -179,7 +182,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.port_disable = ata_port_disable,
.set_piomode = pdc2027x_set_piomode,
.set_dmamode = pdc2027x_set_dmamode,
- .post_set_mode = pdc2027x_post_set_mode,
+ .set_mode = pdc2027x_set_mode,
+ .mode_filter = pdc2027x_mode_filter,
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -200,8 +204,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = pdc2027x_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = pdc2027x_cable_detect,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -212,7 +216,6 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
static struct ata_port_info pdc2027x_port_info[] = {
/* PDC_UDMA_100 */
{
- .sht = &pdc2027x_sht,
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
.pio_mask = 0x1f, /* pio0-4 */
@@ -222,7 +225,6 @@ static struct ata_port_info pdc2027x_port_info[] = {
},
/* PDC_UDMA_133 */
{
- .sht = &pdc2027x_sht,
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
.pio_mask = 0x1f, /* pio0-4 */
@@ -261,7 +263,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
}
/**
- * pdc2027x_pata_cbl_detect - Probe host controller cable detect info
+ * pdc2027x_pata_cable_detect - Probe host controller cable detect info
* @ap: Port for which cable detect info is desired
*
* Read 80c cable indicator from Promise extended register.
@@ -270,7 +272,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
* LOCKING:
* None (inherited from caller).
*/
-static void pdc2027x_cbl_detect(struct ata_port *ap)
+static int pdc2027x_cable_detect(struct ata_port *ap)
{
u32 cgcr;
@@ -281,13 +283,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap)
PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
- ap->cbl = ATA_CBL_PATA80;
- return;
-
+ return ATA_CBL_PATA80;
cbl40:
printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
- ap->cbl = ATA_CBL_PATA40;
- ap->udma_mask &= ATA_UDMA_MASK_40C;
+ return ATA_CBL_PATA40;
}
/**
@@ -314,7 +313,6 @@ static int pdc2027x_prereset(struct ata_port *ap)
/* Check whether port enabled */
if (!pdc2027x_port_enabled(ap))
return -ENOENT;
- pdc2027x_cbl_detect(ap);
return ata_std_prereset(ap);
}
@@ -334,6 +332,32 @@ static void pdc2027x_error_handler(struct ata_port *ap)
}
/**
+ * pdc2720x_mode_filter - mode selection filter
+ * @adev: ATA device
+ * @mask: list of modes proposed
+ *
+ * Block UDMA on devices that cause trouble with this controller.
+ */
+
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask)
+{
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+ struct ata_device *pair = ata_dev_pair(adev);
+
+ if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
+ return ata_pci_default_filter(adev, mask);
+
+ /* Check for slave of a Maxtor at UDMA6 */
+ ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
+ ATA_ID_PROD_LEN + 1);
+ /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
+ if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
+ mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
+
+ return ata_pci_default_filter(adev, mask);
+}
+
+/**
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
* @ap: Port to configure
* @adev: um
@@ -444,17 +468,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * pdc2027x_post_set_mode - Set the timing registers back to correct values.
+ * pdc2027x_set_mode - Set the timing registers back to correct values.
* @ap: Port to configure
+ * @r_failed: Returned device for failure
*
* The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
* automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
* This function overwrites the possibly incorrect values set by the hardware to be correct.
*/
-static void pdc2027x_post_set_mode(struct ata_port *ap)
+static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
{
int i;
+ i = ata_do_set_mode(ap, r_failed);
+ if (i < 0)
+ return i;
+
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
@@ -476,6 +505,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap)
}
}
}
+ return 0;
}
/**
@@ -521,12 +551,12 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
/**
* pdc_read_counter - Read the ctr counter
- * @probe_ent: for the port address
+ * @host: target ATA host
*/
-static long pdc_read_counter(struct ata_probe_ent *probe_ent)
+static long pdc_read_counter(struct ata_host *host)
{
- void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
long counter;
int retry = 1;
u32 bccrl, bccrh, bccrlv, bccrhv;
@@ -564,12 +594,12 @@ retry:
* adjust_pll - Adjust the PLL input clock in Hz.
*
* @pdc_controller: controller specific information
- * @probe_ent: For the port address
+ * @host: target ATA host
* @pll_clock: The input of PLL in HZ
*/
-static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
+static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx)
{
- void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u16 pll_ctl;
long pll_clock_khz = pll_clock / 1000;
long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
@@ -649,19 +679,19 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
/**
* detect_pll_input_clock - Detect the PLL input clock in Hz.
- * @probe_ent: for the port address
+ * @host: target ATA host
* Ex. 16949000 on 33MHz PCI bus for pdc20275.
* Half of the PCI clock.
*/
-static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
+static long pdc_detect_pll_input_clock(struct ata_host *host)
{
- void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
u32 scr;
long start_count, end_count;
long pll_clock;
/* Read current counter value */
- start_count = pdc_read_counter(probe_ent);
+ start_count = pdc_read_counter(host);
/* Start the test mode */
scr = readl(mmio_base + PDC_SYS_CTL);
@@ -673,7 +703,7 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
mdelay(100);
/* Read the counter values again */
- end_count = pdc_read_counter(probe_ent);
+ end_count = pdc_read_counter(host);
/* Stop the test mode */
scr = readl(mmio_base + PDC_SYS_CTL);
@@ -692,11 +722,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
/**
* pdc_hardware_init - Initialize the hardware.
- * @pdev: instance of pci_dev found
- * @pdc_controller: controller specific information
- * @pe: for the port address
+ * @host: target ATA host
+ * @board_idx: board identifier
*/
-static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx)
+static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
{
long pll_clock;
@@ -706,15 +735,15 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
* Ex. 25MHz or 40MHz, we have to adjust the cycle_time.
* The pdc20275 controller employs PLL circuit to help correct timing registers setting.
*/
- pll_clock = pdc_detect_pll_input_clock(pe);
+ pll_clock = pdc_detect_pll_input_clock(host);
if (pll_clock < 0) /* counter overflow? Try again. */
- pll_clock = pdc_detect_pll_input_clock(pe);
+ pll_clock = pdc_detect_pll_input_clock(host);
- dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
+ dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
/* Adjust PLL control register */
- pdc_adjust_pll(pe, pll_clock, board_idx);
+ pdc_adjust_pll(host, pll_clock, board_idx);
return 0;
}
@@ -746,8 +775,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
* Called when an instance of PCI adapter is inserted.
* This function checks whether the hardware is supported,
* initialize hardware and register an instance of ata_host to
- * libata by providing struct ata_probe_ent and ata_device_add().
- * (implements struct pci_driver.probe() )
+ * libata. (implements struct pci_driver.probe() )
*
* @pdev: instance of pci_dev found
* @ent: matching entry in the id_tbl[]
@@ -756,14 +784,21 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
{
static int printed_version;
unsigned int board_idx = (unsigned int) ent->driver_data;
-
- struct ata_probe_ent *probe_ent;
+ const struct ata_port_info *ppi[] =
+ { &pdc2027x_port_info[board_idx], NULL };
+ struct ata_host *host;
void __iomem *mmio_base;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* alloc host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -771,6 +806,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
@@ -780,46 +816,22 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
if (rc)
return rc;
- /* Prepare the probe entry */
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- probe_ent->sht = pdc2027x_port_info[board_idx].sht;
- probe_ent->port_flags = pdc2027x_port_info[board_idx].flags;
- probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask;
- probe_ent->mwdma_mask = pdc2027x_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = pdc2027x_port_info[board_idx].udma_mask;
- probe_ent->port_ops = pdc2027x_port_info[board_idx].port_ops;
+ mmio_base = host->iomap[PDC_MMIO_BAR];
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
+ pdc_ata_setup_port(&host->ports[0]->ioaddr, mmio_base + 0x17c0);
+ host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x1000;
+ pdc_ata_setup_port(&host->ports[1]->ioaddr, mmio_base + 0x15c0);
+ host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x1008;
- mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
-
- pdc_ata_setup_port(&probe_ent->port[0], mmio_base + 0x17c0);
- probe_ent->port[0].bmdma_addr = mmio_base + 0x1000;
- pdc_ata_setup_port(&probe_ent->port[1], mmio_base + 0x15c0);
- probe_ent->port[1].bmdma_addr = mmio_base + 0x1008;
-
- probe_ent->n_ports = 2;
-
- pci_set_master(pdev);
//pci_enable_intx(pdev);
/* initialize adapter */
- if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
+ if (pdc_hardware_init(host, board_idx) != 0)
return -EIO;
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &pdc2027x_sht);
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 6dd63413a523..ee636beb05e1 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -2,13 +2,14 @@
* pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
+ * (C) 2007 Bartlomiej Zolnierkiewicz
*
* Based in part on linux/drivers/ide/pci/pdc202xx_old.c
*
* First cut with LBA48/ATAPI
*
* TODO:
- * Channel interlock/reset on both required ?
+ * Channel interlock/reset on both required
*/
#include <linux/kernel.h>
@@ -21,45 +22,17 @@
#include <linux/libata.h>
#define DRV_NAME "pata_pdc202xx_old"
-#define DRV_VERSION "0.2.3"
+#define DRV_VERSION "0.4.2"
-/**
- * pdc2024x_pre_reset - probe begin
- * @ap: ATA port
- *
- * Set up cable type and use generic probe init
- */
-
-static int pdc2024x_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-
-static void pdc2024x_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, pdc2024x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-
-static int pdc2026x_pre_reset(struct ata_port *ap)
+static int pdc2026x_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u16 cis;
pci_read_config_word(pdev, 0x50, &cis);
if (cis & (1 << (10 + ap->port_no)))
- ap->cbl = ATA_CBL_PATA80;
- else
- ap->cbl = ATA_CBL_PATA40;
-
- return ata_std_prereset(ap);
-}
-
-static void pdc2026x_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, pdc2026x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ATA_CBL_PATA80;
+ return ATA_CBL_PATA40;
}
/**
@@ -76,7 +49,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
+ int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
static u16 pio_timing[5] = {
0x0913, 0x050C , 0x0308, 0x0206, 0x0104
};
@@ -85,7 +58,7 @@ static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *a
pci_read_config_byte(pdev, port, &r_ap);
pci_read_config_byte(pdev, port + 1, &r_bp);
r_ap &= ~0x3F; /* Preserve ERRDY_EN, SYNC_IN */
- r_bp &= ~0x07;
+ r_bp &= ~0x1F;
r_ap |= (pio_timing[pio] >> 8);
r_bp |= (pio_timing[pio] & 0xFF);
@@ -123,7 +96,7 @@ static void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
+ int port = 0x60 + 8 * ap->port_no + 4 * adev->devno;
static u8 udma_timing[6][2] = {
{ 0x60, 0x03 }, /* 33 Mhz Clock */
{ 0x40, 0x02 },
@@ -132,12 +105,17 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{ 0x20, 0x01 },
{ 0x20, 0x01 }
};
+ static u8 mdma_timing[3][2] = {
+ { 0x60, 0x03 },
+ { 0x60, 0x04 },
+ { 0xe0, 0x0f },
+ };
u8 r_bp, r_cp;
pci_read_config_byte(pdev, port + 1, &r_bp);
pci_read_config_byte(pdev, port + 2, &r_cp);
- r_bp &= ~0xF0;
+ r_bp &= ~0xE0;
r_cp &= ~0x0F;
if (adev->dma_mode >= XFER_UDMA_0) {
@@ -147,8 +125,8 @@ static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
} else {
int speed = adev->dma_mode - XFER_MW_DMA_0;
- r_bp |= 0x60;
- r_cp |= (5 - speed);
+ r_bp |= mdma_timing[speed][0];
+ r_cp |= mdma_timing[speed][1];
}
pci_write_config_byte(pdev, port + 1, r_bp);
pci_write_config_byte(pdev, port + 2, r_cp);
@@ -189,7 +167,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
/* Cases the state machine will not complete correctly without help */
if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
{
- len = qc->nbytes;
+ len = qc->nbytes / 2;
if (tf->flags & ATA_TFLAG_WRITE)
len |= 0x06000000;
@@ -238,7 +216,6 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
/**
* pdc2026x_dev_config - device setup hook
- * @ap: ATA port
* @adev: newly found device
*
* Perform chip specific early setup. We need to lock the transfer
@@ -246,7 +223,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
* barf.
*/
-static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
+static void pdc2026x_dev_config(struct ata_device *adev)
{
adev->max_sectors = 256;
}
@@ -267,8 +244,10 @@ static struct scsi_host_template pdc202xx_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations pdc2024x_port_ops = {
@@ -284,8 +263,9 @@ static struct ata_port_operations pdc2024x_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = pdc2024x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -318,8 +298,9 @@ static struct ata_port_operations pdc2026x_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = pdc2026x_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = pdc2026x_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = pdc2026x_bmdma_start,
@@ -399,8 +380,10 @@ static struct pci_driver pdc202xx_pci_driver = {
.id_table = pdc202xx,
.probe = pdc202xx_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init pdc202xx_init(void)
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 479a326114e0..a0a650c7f272 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -42,6 +42,7 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse
dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
dev->flags |= ATA_DFLAG_PIO;
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
}
}
return 0;
@@ -79,13 +80,13 @@ static struct ata_port_operations pata_platform_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer_noirq,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -134,7 +135,8 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
static int __devinit pata_platform_probe(struct platform_device *pdev)
{
struct resource *io_res, *ctl_res;
- struct ata_probe_ent ae;
+ struct ata_host *host;
+ struct ata_port *ap;
unsigned int mmio;
/*
@@ -174,44 +176,41 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
/*
* Now that that's out of the way, wire up the port..
*/
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &pdev->dev;
- ae.port_ops = &pata_platform_port_ops;
- ae.sht = &pata_platform_sht;
- ae.n_ports = 1;
- ae.pio_mask = pio_mask;
- ae.irq = platform_get_irq(pdev, 0);
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ return -ENOMEM;
+ ap = host->ports[0];
+
+ ap->ops = &pata_platform_port_ops;
+ ap->pio_mask = pio_mask;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
/*
* Handle the MMIO case
*/
if (mmio) {
- ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
+ ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
- ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
+ ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
} else {
- ae.port[0].cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
+ ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
- ae.port[0].ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
+ ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
}
- if (!ae.port[0].cmd_addr || !ae.port[0].ctl_addr) {
+ if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
dev_err(&pdev->dev, "failed to map IO/CTL base\n");
return -ENOMEM;
}
- ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
+ ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
- pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
+ pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
- if (unlikely(ata_device_add(&ae) == 0))
- return -ENODEV;
-
- return 0;
+ /* activate */
+ return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
+ 0, &pata_platform_sht);
}
/**
@@ -227,7 +226,6 @@ static int __devexit pata_platform_remove(struct platform_device *pdev)
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
- dev_set_drvdata(dev, NULL);
return 0;
}
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 4362141976ad..27685ce63ceb 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -26,7 +26,7 @@
#include <linux/platform_device.h>
#define DRV_NAME "pata_qdi"
-#define DRV_VERSION "0.2.4"
+#define DRV_VERSION "0.3.0"
#define NR_HOST 4 /* Two 6580s */
@@ -183,13 +183,13 @@ static struct ata_port_operations qdi6500_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = qdi_qc_issue_prot,
.data_xfer = qdi_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -211,13 +211,13 @@ static struct ata_port_operations qdi6580_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = qdi_qc_issue_prot,
.data_xfer = qdi_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -238,8 +238,9 @@ static struct ata_port_operations qdi6580_port_ops = {
static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
{
- struct ata_probe_ent ae;
struct platform_device *pdev;
+ struct ata_host *host;
+ struct ata_port *ap;
void __iomem *io_addr, *ctl_addr;
int ret;
@@ -257,34 +258,31 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
if (!io_addr || !ctl_addr)
goto fail;
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &pdev->dev;
+ ret = -ENOMEM;
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ goto fail;
+ ap = host->ports[0];
if (type == 6580) {
- ae.port_ops = &qdi6580_port_ops;
- ae.pio_mask = 0x1F;
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ ap->ops = &qdi6580_port_ops;
+ ap->pio_mask = 0x1F;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
} else {
- ae.port_ops = &qdi6500_port_ops;
- ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
- ATA_FLAG_NO_IORDY;
+ ap->ops = &qdi6500_port_ops;
+ ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
+ ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
}
- ae.sht = &qdi_sht;
- ae.n_ports = 1;
- ae.irq = irq;
- ae.irq_flags = 0;
- ae.port[0].cmd_addr = io_addr;
- ae.port[0].altstatus_addr = ctl_addr;
- ae.port[0].ctl_addr = ctl_addr;
- ata_std_ports(&ae.port[0]);
+ ap->ioaddr.cmd_addr = io_addr;
+ ap->ioaddr.altstatus_addr = ctl_addr;
+ ap->ioaddr.ctl_addr = ctl_addr;
+ ata_std_ports(&ap->ioaddr);
/*
* Hook in a private data structure per channel
*/
- ae.private_data = &qdi_data[nr_qdi_host];
+ ap->private_data = &qdi_data[nr_qdi_host];
qdi_data[nr_qdi_host].timing = port;
qdi_data[nr_qdi_host].fast = fast;
@@ -292,8 +290,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
- ret = -ENODEV;
- if (!ata_device_add(&ae))
+ /* activate */
+ ret = ata_host_activate(host, irq, ata_interrupt, 0, &qdi_sht);
+ if (ret)
goto fail;
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
@@ -363,7 +362,8 @@ static __init int qdi_init(void)
release_region(port, 2);
continue;
}
- ct += qdi_init_one(port, 6500, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04);
+ 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 */
@@ -375,11 +375,14 @@ static __init int qdi_init(void)
res = inb(port + 3);
if (res & 1) {
/* Single channel mode */
- ct += qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04);
+ if (qdi_init_one(port, 6580, ide_port[r & 0x01], ide_irq[r & 0x01], r & 0x04))
+ ct++;
} else {
/* Dual channel mode */
- ct += qdi_init_one(port, 6580, 0x1F0, 14, r & 0x04);
- ct += qdi_init_one(port + 2, 6580, 0x170, 15, r & 0x04);
+ 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++;
}
}
}
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 0d1e571ef633..1c54673e008d 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -24,40 +24,12 @@
#include <linux/ata.h>
#define DRV_NAME "pata_radisys"
-#define DRV_VERSION "0.4.1"
-
-/**
- * radisys_probe_init - probe begin
- * @ap: ATA port
- *
- * Set up cable type and use generic probe init
- */
-
-static int radisys_pre_reset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(ap);
-}
-
-
-/**
- * radisys_pata_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- * @classes:
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void radisys_pata_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, radisys_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
+#define DRV_VERSION "0.4.4"
/**
* radisys_set_piomode - Initialize host controller PATA PIO timings
- * @ap: Port whose timings we are configuring
- * @adev: um
+ * @ap: ATA port
+ * @adev: Device whose timings we are configuring
*
* Set PIO mode for device, in host controller PCI config space.
*
@@ -228,8 +200,10 @@ static struct scsi_host_template radisys_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations radisys_pata_ops = {
@@ -246,8 +220,9 @@ static const struct ata_port_operations radisys_pata_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = radisys_pata_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_unknown,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -312,8 +287,10 @@ static struct pci_driver radisys_pci_driver = {
.id_table = radisys_pci_tbl,
.probe = radisys_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init radisys_init(void)
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 71a2bac09e0d..85c45290eeee 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -25,31 +25,6 @@
/**
- * rz1000_prereset - probe begin
- * @ap: ATA port
- *
- * Set up cable type and use generics
- */
-
-static int rz1000_prereset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_PATA40;
- return ata_std_prereset(ap);
-}
-
-/**
- * rz1000_error_handler - probe reset
- * @ap: ATA port
- *
- * Perform the ATA standard reset sequence
- */
-
-static void rz1000_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, rz1000_prereset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-/**
* rz1000_set_mode - mode setting function
* @ap: ATA interface
* @unused: returned device on set_mode failure
@@ -71,6 +46,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
dev->flags |= ATA_DFLAG_PIO;
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO\n");
}
}
return 0;
@@ -93,8 +69,10 @@ static struct scsi_host_template rz1000_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations rz1000_port_ops = {
@@ -119,8 +97,9 @@ static struct ata_port_operations rz1000_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = rz1000_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
@@ -177,6 +156,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
return -ENODEV;
}
+#ifdef CONFIG_PM
static int rz1000_reinit_one(struct pci_dev *pdev)
{
/* If this fails on resume (which is a "cant happen" case), we
@@ -185,6 +165,7 @@ static int rz1000_reinit_one(struct pci_dev *pdev)
panic("rz1000 fifo");
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id pata_rz1000[] = {
{ PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
@@ -198,8 +179,10 @@ static struct pci_driver rz1000_pci_driver = {
.id_table = pata_rz1000,
.probe = rz1000_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = rz1000_reinit_one,
+#endif
};
static int __init rz1000_init(void)
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 58e42fbd14f9..66e8ff467c8d 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -194,8 +194,10 @@ static struct scsi_host_template sc1200_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations sc1200_port_ops = {
@@ -210,7 +212,11 @@ static struct ata_port_operations sc1200_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -266,8 +272,10 @@ static struct pci_driver sc1200_pci_driver = {
.id_table = sc1200,
.probe = sc1200_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init sc1200_init(void)
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
new file mode 100644
index 000000000000..5df354d573e8
--- /dev/null
+++ b/drivers/ata/pata_scc.c
@@ -0,0 +1,1211 @@
+/*
+ * Support for IDE interfaces on Celleb platform
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on drivers/ata/ata_piix.c:
+ * Copyright 2003-2005 Red Hat Inc
+ * Copyright 2003-2005 Jeff Garzik
+ * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
+ *
+ * and drivers/ata/ahci.c:
+ * Copyright 2004-2005 Red Hat, Inc.
+ *
+ * and drivers/ata/libata-core.c:
+ * Copyright 2003-2004 Red Hat, Inc. All rights reserved.
+ * Copyright 2003-2004 Jeff Garzik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pata_scc"
+#define DRV_VERSION "0.1"
+
+#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4
+
+/* PCI BARs */
+#define SCC_CTRL_BAR 0
+#define SCC_BMID_BAR 1
+
+/* offset of CTRL registers */
+#define SCC_CTL_PIOSHT 0x000
+#define SCC_CTL_PIOCT 0x004
+#define SCC_CTL_MDMACT 0x008
+#define SCC_CTL_MCRCST 0x00C
+#define SCC_CTL_SDMACT 0x010
+#define SCC_CTL_SCRCST 0x014
+#define SCC_CTL_UDENVT 0x018
+#define SCC_CTL_TDVHSEL 0x020
+#define SCC_CTL_MODEREG 0x024
+#define SCC_CTL_ECMODE 0xF00
+#define SCC_CTL_MAEA0 0xF50
+#define SCC_CTL_MAEC0 0xF54
+#define SCC_CTL_CCKCTRL 0xFF0
+
+/* offset of BMID registers */
+#define SCC_DMA_CMD 0x000
+#define SCC_DMA_STATUS 0x004
+#define SCC_DMA_TABLE_OFS 0x008
+#define SCC_DMA_INTMASK 0x010
+#define SCC_DMA_INTST 0x014
+#define SCC_DMA_PTERADD 0x018
+#define SCC_REG_CMD_ADDR 0x020
+#define SCC_REG_DATA 0x000
+#define SCC_REG_ERR 0x004
+#define SCC_REG_FEATURE 0x004
+#define SCC_REG_NSECT 0x008
+#define SCC_REG_LBAL 0x00C
+#define SCC_REG_LBAM 0x010
+#define SCC_REG_LBAH 0x014
+#define SCC_REG_DEVICE 0x018
+#define SCC_REG_STATUS 0x01C
+#define SCC_REG_CMD 0x01C
+#define SCC_REG_ALTSTATUS 0x020
+
+/* register value */
+#define TDVHSEL_MASTER 0x00000001
+#define TDVHSEL_SLAVE 0x00000004
+
+#define MODE_JCUSFEN 0x00000080
+
+#define ECMODE_VALUE 0x01
+
+#define CCKCTRL_ATARESET 0x00040000
+#define CCKCTRL_BUFCNT 0x00020000
+#define CCKCTRL_CRST 0x00010000
+#define CCKCTRL_OCLKEN 0x00000100
+#define CCKCTRL_ATACLKOEN 0x00000002
+#define CCKCTRL_LCLKEN 0x00000001
+
+#define QCHCD_IOS_SS 0x00000001
+
+#define QCHSD_STPDIAG 0x00020000
+
+#define INTMASK_MSK 0xD1000012
+#define INTSTS_SERROR 0x80000000
+#define INTSTS_PRERR 0x40000000
+#define INTSTS_RERR 0x10000000
+#define INTSTS_ICERR 0x01000000
+#define INTSTS_BMSINT 0x00000010
+#define INTSTS_BMHE 0x00000008
+#define INTSTS_IOIRQS 0x00000004
+#define INTSTS_INTRQ 0x00000002
+#define INTSTS_ACTEINT 0x00000001
+
+
+/* PIO transfer mode table */
+/* JCHST */
+static const unsigned long JCHSTtbl[2][7] = {
+ {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */
+ {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */
+};
+
+/* JCHHT */
+static const unsigned long JCHHTtbl[2][7] = {
+ {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */
+ {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */
+};
+
+/* JCHCT */
+static const unsigned long JCHCTtbl[2][7] = {
+ {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */
+ {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */
+};
+
+/* DMA transfer mode table */
+/* JCHDCTM/JCHDCTS */
+static const unsigned long JCHDCTxtbl[2][7] = {
+ {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */
+ {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */
+};
+
+/* JCSTWTM/JCSTWTS */
+static const unsigned long JCSTWTxtbl[2][7] = {
+ {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */
+ {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
+};
+
+/* JCTSS */
+static const unsigned long JCTSStbl[2][7] = {
+ {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */
+ {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */
+};
+
+/* JCENVT */
+static const unsigned long JCENVTtbl[2][7] = {
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */
+ {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
+};
+
+/* JCACTSELS/JCACTSELM */
+static const unsigned long JCACTSELtbl[2][7] = {
+ {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */
+};
+
+static const struct pci_device_id scc_pci_tbl[] = {
+ {PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { } /* terminate list */
+};
+
+/**
+ * scc_set_piomode - Initialize host controller PATA PIO timings
+ * @ap: Port whose timings we are configuring
+ * @adev: um
+ *
+ * Set PIO mode for device.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
+{
+ unsigned int pio = adev->pio_mode - XFER_PIO_0;
+ void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
+ void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
+ void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT;
+ void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT;
+ unsigned long reg;
+ int offset;
+
+ reg = in_be32(cckctrl_port);
+ if (reg & CCKCTRL_ATACLKOEN)
+ offset = 1; /* 133MHz */
+ else
+ offset = 0; /* 100MHz */
+
+ reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
+ out_be32(piosht_port, reg);
+ reg = JCHCTtbl[offset][pio];
+ out_be32(pioct_port, reg);
+}
+
+/**
+ * scc_set_dmamode - Initialize host controller PATA DMA timings
+ * @ap: Port whose timings we are configuring
+ * @adev: um
+ * @udma: udma mode, 0 - 6
+ *
+ * Set UDMA mode for device.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+{
+ unsigned int udma = adev->dma_mode;
+ unsigned int is_slave = (adev->devno != 0);
+ u8 speed = udma;
+ void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
+ void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
+ void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT;
+ void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST;
+ void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT;
+ void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST;
+ void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT;
+ void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL;
+ int offset, idx;
+
+ if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN)
+ offset = 1; /* 133MHz */
+ else
+ offset = 0; /* 100MHz */
+
+ if (speed >= XFER_UDMA_0)
+ idx = speed - XFER_UDMA_0;
+ else
+ return;
+
+ if (is_slave) {
+ out_be32(sdmact_port, JCHDCTxtbl[offset][idx]);
+ out_be32(scrcst_port, JCSTWTxtbl[offset][idx]);
+ out_be32(tdvhsel_port,
+ (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2));
+ } else {
+ out_be32(mdmact_port, JCHDCTxtbl[offset][idx]);
+ out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]);
+ out_be32(tdvhsel_port,
+ (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]);
+ }
+ out_be32(udenvt_port,
+ JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]);
+}
+
+/**
+ * scc_tf_load - send taskfile registers to host controller
+ * @ap: Port to which output is sent
+ * @tf: ATA taskfile register set
+ *
+ * Note: Original code is ata_tf_load().
+ */
+
+static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+ if (tf->ctl != ap->last_ctl) {
+ out_be32(ioaddr->ctl_addr, tf->ctl);
+ ap->last_ctl = tf->ctl;
+ ata_wait_idle(ap);
+ }
+
+ if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+ out_be32(ioaddr->feature_addr, tf->hob_feature);
+ out_be32(ioaddr->nsect_addr, tf->hob_nsect);
+ out_be32(ioaddr->lbal_addr, tf->hob_lbal);
+ out_be32(ioaddr->lbam_addr, tf->hob_lbam);
+ out_be32(ioaddr->lbah_addr, tf->hob_lbah);
+ VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+ tf->hob_feature,
+ tf->hob_nsect,
+ tf->hob_lbal,
+ tf->hob_lbam,
+ tf->hob_lbah);
+ }
+
+ if (is_addr) {
+ out_be32(ioaddr->feature_addr, tf->feature);
+ out_be32(ioaddr->nsect_addr, tf->nsect);
+ out_be32(ioaddr->lbal_addr, tf->lbal);
+ out_be32(ioaddr->lbam_addr, tf->lbam);
+ out_be32(ioaddr->lbah_addr, tf->lbah);
+ VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+ tf->feature,
+ tf->nsect,
+ tf->lbal,
+ tf->lbam,
+ tf->lbah);
+ }
+
+ if (tf->flags & ATA_TFLAG_DEVICE) {
+ out_be32(ioaddr->device_addr, tf->device);
+ VPRINTK("device 0x%X\n", tf->device);
+ }
+
+ ata_wait_idle(ap);
+}
+
+/**
+ * scc_check_status - Read device status reg & clear interrupt
+ * @ap: port where the device is
+ *
+ * Note: Original code is ata_check_status().
+ */
+
+static u8 scc_check_status (struct ata_port *ap)
+{
+ return in_be32(ap->ioaddr.status_addr);
+}
+
+/**
+ * scc_tf_read - input device's ATA taskfile shadow registers
+ * @ap: Port from which input is read
+ * @tf: ATA taskfile register set for storing input
+ *
+ * Note: Original code is ata_tf_read().
+ */
+
+static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ tf->command = scc_check_status(ap);
+ tf->feature = in_be32(ioaddr->error_addr);
+ tf->nsect = in_be32(ioaddr->nsect_addr);
+ tf->lbal = in_be32(ioaddr->lbal_addr);
+ tf->lbam = in_be32(ioaddr->lbam_addr);
+ tf->lbah = in_be32(ioaddr->lbah_addr);
+ tf->device = in_be32(ioaddr->device_addr);
+
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB);
+ tf->hob_feature = in_be32(ioaddr->error_addr);
+ tf->hob_nsect = in_be32(ioaddr->nsect_addr);
+ tf->hob_lbal = in_be32(ioaddr->lbal_addr);
+ tf->hob_lbam = in_be32(ioaddr->lbam_addr);
+ tf->hob_lbah = in_be32(ioaddr->lbah_addr);
+ }
+}
+
+/**
+ * scc_exec_command - issue ATA command to host controller
+ * @ap: port to which command is being issued
+ * @tf: ATA taskfile register set
+ *
+ * Note: Original code is ata_exec_command().
+ */
+
+static void scc_exec_command (struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
+
+ out_be32(ap->ioaddr.command_addr, tf->command);
+ ata_pause(ap);
+}
+
+/**
+ * scc_check_altstatus - Read device alternate status reg
+ * @ap: port where the device is
+ */
+
+static u8 scc_check_altstatus (struct ata_port *ap)
+{
+ return in_be32(ap->ioaddr.altstatus_addr);
+}
+
+/**
+ * scc_std_dev_select - Select device 0/1 on ATA bus
+ * @ap: ATA channel to manipulate
+ * @device: ATA device (numbered from zero) to select
+ *
+ * Note: Original code is ata_std_dev_select().
+ */
+
+static void scc_std_dev_select (struct ata_port *ap, unsigned int device)
+{
+ u8 tmp;
+
+ if (device == 0)
+ tmp = ATA_DEVICE_OBS;
+ else
+ tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+ out_be32(ap->ioaddr.device_addr, tmp);
+ ata_pause(ap);
+}
+
+/**
+ * scc_bmdma_setup - Set up PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * Note: Original code is ata_bmdma_setup().
+ */
+
+static void scc_bmdma_setup (struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ u8 dmactl;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ /* load PRD table addr */
+ out_be32(mmio + SCC_DMA_TABLE_OFS, ap->prd_dma);
+
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = in_be32(mmio + SCC_DMA_CMD);
+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+ out_be32(mmio + SCC_DMA_CMD, dmactl);
+
+ /* issue r/w command */
+ ap->ops->exec_command(ap, &qc->tf);
+}
+
+/**
+ * scc_bmdma_start - Start a PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * Note: Original code is ata_bmdma_start().
+ */
+
+static void scc_bmdma_start (struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ u8 dmactl;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ /* start host DMA transaction */
+ dmactl = in_be32(mmio + SCC_DMA_CMD);
+ out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START);
+}
+
+/**
+ * scc_devchk - PATA device presence detection
+ * @ap: ATA channel to examine
+ * @device: Device to examine (starting at zero)
+ *
+ * Note: Original code is ata_devchk().
+ */
+
+static unsigned int scc_devchk (struct ata_port *ap,
+ unsigned int device)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ u8 nsect, lbal;
+
+ ap->ops->dev_select(ap, device);
+
+ out_be32(ioaddr->nsect_addr, 0x55);
+ out_be32(ioaddr->lbal_addr, 0xaa);
+
+ out_be32(ioaddr->nsect_addr, 0xaa);
+ out_be32(ioaddr->lbal_addr, 0x55);
+
+ out_be32(ioaddr->nsect_addr, 0x55);
+ out_be32(ioaddr->lbal_addr, 0xaa);
+
+ nsect = in_be32(ioaddr->nsect_addr);
+ lbal = in_be32(ioaddr->lbal_addr);
+
+ if ((nsect == 0x55) && (lbal == 0xaa))
+ return 1; /* we found a device */
+
+ return 0; /* nothing found */
+}
+
+/**
+ * scc_bus_post_reset - PATA device post reset
+ *
+ * Note: Original code is ata_bus_post_reset().
+ */
+
+static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ unsigned int dev0 = devmask & (1 << 0);
+ unsigned int dev1 = devmask & (1 << 1);
+ unsigned long timeout;
+
+ /* if device 0 was found in ata_devchk, wait for its
+ * BSY bit to clear
+ */
+ if (dev0)
+ ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+
+ /* if device 1 was found in ata_devchk, wait for
+ * register access, then wait for BSY to clear
+ */
+ timeout = jiffies + ATA_TMOUT_BOOT;
+ while (dev1) {
+ u8 nsect, lbal;
+
+ ap->ops->dev_select(ap, 1);
+ nsect = in_be32(ioaddr->nsect_addr);
+ lbal = in_be32(ioaddr->lbal_addr);
+ if ((nsect == 1) && (lbal == 1))
+ break;
+ if (time_after(jiffies, timeout)) {
+ dev1 = 0;
+ break;
+ }
+ msleep(50); /* give drive a breather */
+ }
+ if (dev1)
+ ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+
+ /* is all this really necessary? */
+ ap->ops->dev_select(ap, 0);
+ if (dev1)
+ ap->ops->dev_select(ap, 1);
+ if (dev0)
+ ap->ops->dev_select(ap, 0);
+}
+
+/**
+ * scc_bus_softreset - PATA device software reset
+ *
+ * Note: Original code is ata_bus_softreset().
+ */
+
+static unsigned int scc_bus_softreset (struct ata_port *ap,
+ unsigned int devmask)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
+
+ /* software reset. causes dev0 to be selected */
+ out_be32(ioaddr->ctl_addr, ap->ctl);
+ udelay(20);
+ out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST);
+ udelay(20);
+ out_be32(ioaddr->ctl_addr, ap->ctl);
+
+ /* spec mandates ">= 2ms" before checking status.
+ * We wait 150ms, because that was the magic delay used for
+ * ATAPI devices in Hale Landis's ATADRVR, for the period of time
+ * between when the ATA command register is written, and then
+ * status is checked. Because waiting for "a while" before
+ * checking status is fine, post SRST, we perform this magic
+ * delay here as well.
+ *
+ * Old drivers/ide uses the 2mS rule and then waits for ready
+ */
+ msleep(150);
+
+ /* Before we perform post reset processing we want to see if
+ * the bus shows 0xFF because the odd clown forgets the D7
+ * pulldown resistor.
+ */
+ if (scc_check_status(ap) == 0xFF)
+ return 0;
+
+ scc_bus_post_reset(ap, devmask);
+
+ return 0;
+}
+
+/**
+ * scc_std_softreset - reset host port via ATA SRST
+ * @ap: port to reset
+ * @classes: resulting classes of attached devices
+ *
+ * Note: Original code is ata_std_softreset().
+ */
+
+static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
+{
+ unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+ unsigned int devmask = 0, err_mask;
+ u8 err;
+
+ DPRINTK("ENTER\n");
+
+ if (ata_port_offline(ap)) {
+ classes[0] = ATA_DEV_NONE;
+ goto out;
+ }
+
+ /* determine if device 0/1 are present */
+ if (scc_devchk(ap, 0))
+ devmask |= (1 << 0);
+ if (slave_possible && scc_devchk(ap, 1))
+ devmask |= (1 << 1);
+
+ /* select device 0 again */
+ ap->ops->dev_select(ap, 0);
+
+ /* issue bus reset */
+ DPRINTK("about to softreset, devmask=%x\n", devmask);
+ err_mask = scc_bus_softreset(ap, devmask);
+ if (err_mask) {
+ ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
+ err_mask);
+ return -EIO;
+ }
+
+ /* determine by signature whether we have ATA or ATAPI devices */
+ classes[0] = ata_dev_try_classify(ap, 0, &err);
+ if (slave_possible && err != 0x81)
+ classes[1] = ata_dev_try_classify(ap, 1, &err);
+
+ out:
+ DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+ return 0;
+}
+
+/**
+ * scc_bmdma_stop - Stop PCI IDE BMDMA transfer
+ * @qc: Command we are ending DMA for
+ */
+
+static void scc_bmdma_stop (struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
+ void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR];
+ u32 reg;
+
+ while (1) {
+ reg = in_be32(bmid_base + SCC_DMA_INTST);
+
+ if (reg & INTSTS_SERROR) {
+ printk(KERN_WARNING "%s: SERROR\n", DRV_NAME);
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT);
+ out_be32(bmid_base + SCC_DMA_CMD,
+ in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
+ continue;
+ }
+
+ if (reg & INTSTS_PRERR) {
+ u32 maea0, maec0;
+ maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0);
+ maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0);
+ printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0);
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT);
+ out_be32(bmid_base + SCC_DMA_CMD,
+ in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
+ continue;
+ }
+
+ if (reg & INTSTS_RERR) {
+ printk(KERN_WARNING "%s: Response Error\n", DRV_NAME);
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT);
+ out_be32(bmid_base + SCC_DMA_CMD,
+ in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
+ continue;
+ }
+
+ if (reg & INTSTS_ICERR) {
+ out_be32(bmid_base + SCC_DMA_CMD,
+ in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
+ printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME);
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT);
+ continue;
+ }
+
+ if (reg & INTSTS_BMSINT) {
+ unsigned int classes;
+ printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
+ /* TBD: SW reset */
+ scc_std_softreset(ap, &classes);
+ continue;
+ }
+
+ if (reg & INTSTS_BMHE) {
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE);
+ continue;
+ }
+
+ if (reg & INTSTS_ACTEINT) {
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT);
+ continue;
+ }
+
+ if (reg & INTSTS_IOIRQS) {
+ out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS);
+ continue;
+ }
+ break;
+ }
+
+ /* clear start/stop bit */
+ out_be32(bmid_base + SCC_DMA_CMD,
+ in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_altstatus(ap); /* dummy read */
+}
+
+/**
+ * scc_bmdma_status - Read PCI IDE BMDMA status
+ * @ap: Port associated with this ATA transaction.
+ */
+
+static u8 scc_bmdma_status (struct ata_port *ap)
+{
+ u8 host_stat;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ host_stat = in_be32(mmio + SCC_DMA_STATUS);
+
+ /* Workaround for PTERADD: emulate DMA_INTR when
+ * - IDE_STATUS[ERR] = 1
+ * - INT_STATUS[INTRQ] = 1
+ * - DMA_STATUS[IORACTA] = 1
+ */
+ if (!(host_stat & ATA_DMA_INTR)) {
+ u32 int_status = in_be32(mmio + SCC_DMA_INTST);
+ if (ata_altstatus(ap) & ATA_ERR &&
+ int_status & INTSTS_INTRQ &&
+ host_stat & ATA_DMA_ACTIVE)
+ host_stat |= ATA_DMA_INTR;
+ }
+
+ return host_stat;
+}
+
+/**
+ * scc_data_xfer - Transfer data by PIO
+ * @adev: device for this I/O
+ * @buf: data buffer
+ * @buflen: buffer length
+ * @write_data: read/write
+ *
+ * Note: Original code is ata_data_xfer().
+ */
+
+static void scc_data_xfer (struct ata_device *adev, unsigned char *buf,
+ unsigned int buflen, int write_data)
+{
+ struct ata_port *ap = adev->ap;
+ unsigned int words = buflen >> 1;
+ unsigned int i;
+ u16 *buf16 = (u16 *) buf;
+ void __iomem *mmio = ap->ioaddr.data_addr;
+
+ /* Transfer multiple of 2 bytes */
+ if (write_data) {
+ for (i = 0; i < words; i++)
+ out_be32(mmio, cpu_to_le16(buf16[i]));
+ } else {
+ for (i = 0; i < words; i++)
+ buf16[i] = le16_to_cpu(in_be32(mmio));
+ }
+
+ /* Transfer trailing 1 byte, if any. */
+ if (unlikely(buflen & 0x01)) {
+ u16 align_buf[1] = { 0 };
+ unsigned char *trailing_buf = buf + buflen - 1;
+
+ if (write_data) {
+ memcpy(align_buf, trailing_buf, 1);
+ out_be32(mmio, cpu_to_le16(align_buf[0]));
+ } else {
+ align_buf[0] = le16_to_cpu(in_be32(mmio));
+ memcpy(trailing_buf, align_buf, 1);
+ }
+ }
+}
+
+/**
+ * scc_irq_on - Enable interrupts on a port.
+ * @ap: Port on which interrupts are enabled.
+ *
+ * Note: Original code is ata_irq_on().
+ */
+
+static u8 scc_irq_on (struct ata_port *ap)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ u8 tmp;
+
+ ap->ctl &= ~ATA_NIEN;
+ ap->last_ctl = ap->ctl;
+
+ out_be32(ioaddr->ctl_addr, ap->ctl);
+ tmp = ata_wait_idle(ap);
+
+ ap->ops->irq_clear(ap);
+
+ return tmp;
+}
+
+/**
+ * scc_irq_ack - Acknowledge a device interrupt.
+ * @ap: Port on which interrupts are enabled.
+ *
+ * Note: Original code is ata_irq_ack().
+ */
+
+static u8 scc_irq_ack (struct ata_port *ap, unsigned int chk_drq)
+{
+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+ u8 host_stat, post_stat, status;
+
+ status = ata_busy_wait(ap, bits, 1000);
+ if (status & bits)
+ if (ata_msg_err(ap))
+ printk(KERN_ERR "abnormal status 0x%X\n", status);
+
+ /* get controller status; clear intr, err bits */
+ host_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);
+ out_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS,
+ host_stat | ATA_DMA_INTR | ATA_DMA_ERR);
+
+ post_stat = in_be32(ap->ioaddr.bmdma_addr + SCC_DMA_STATUS);
+
+ if (ata_msg_intr(ap))
+ printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
+ __FUNCTION__,
+ host_stat, post_stat, status);
+
+ return status;
+}
+
+/**
+ * scc_bmdma_freeze - Freeze BMDMA controller port
+ * @ap: port to freeze
+ *
+ * Note: Original code is ata_bmdma_freeze().
+ */
+
+static void scc_bmdma_freeze (struct ata_port *ap)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ ap->ctl |= ATA_NIEN;
+ ap->last_ctl = ap->ctl;
+
+ out_be32(ioaddr->ctl_addr, ap->ctl);
+
+ /* Under certain circumstances, some controllers raise IRQ on
+ * ATA_NIEN manipulation. Also, many controllers fail to mask
+ * previously pending IRQ on ATA_NIEN assertion. Clear it.
+ */
+ ata_chk_status(ap);
+
+ ap->ops->irq_clear(ap);
+}
+
+/**
+ * scc_pata_prereset - prepare for reset
+ * @ap: ATA port to be reset
+ */
+
+static int scc_pata_prereset (struct ata_port *ap)
+{
+ ap->cbl = ATA_CBL_PATA80;
+ return ata_std_prereset(ap);
+}
+
+/**
+ * scc_std_postreset - standard postreset callback
+ * @ap: the target ata_port
+ * @classes: classes of attached devices
+ *
+ * Note: Original code is ata_std_postreset().
+ */
+
+static void scc_std_postreset (struct ata_port *ap, unsigned int *classes)
+{
+ DPRINTK("ENTER\n");
+
+ /* re-enable interrupts */
+ if (!ap->ops->error_handler)
+ ap->ops->irq_on(ap);
+
+ /* is double-select really necessary? */
+ if (classes[0] != ATA_DEV_NONE)
+ ap->ops->dev_select(ap, 1);
+ if (classes[1] != ATA_DEV_NONE)
+ ap->ops->dev_select(ap, 0);
+
+ /* bail out if no device is present */
+ if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+ DPRINTK("EXIT, no device\n");
+ return;
+ }
+
+ /* set up device control */
+ if (ap->ioaddr.ctl_addr)
+ out_be32(ap->ioaddr.ctl_addr, ap->ctl);
+
+ DPRINTK("EXIT\n");
+}
+
+/**
+ * scc_error_handler - Stock error handler for BMDMA controller
+ * @ap: port to handle error for
+ */
+
+static void scc_error_handler (struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, scc_pata_prereset, scc_std_softreset, NULL,
+ scc_std_postreset);
+}
+
+/**
+ * scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Note: Original code is ata_bmdma_irq_clear().
+ */
+
+static void scc_bmdma_irq_clear (struct ata_port *ap)
+{
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ if (!mmio)
+ return;
+
+ out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS));
+}
+
+/**
+ * scc_port_start - Set port up for dma.
+ * @ap: Port to initialize
+ *
+ * Allocate space for PRD table using ata_port_start().
+ * Set PRD table address for PTERADD. (PRD Transfer End Read)
+ */
+
+static int scc_port_start (struct ata_port *ap)
+{
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+ int rc;
+
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+
+ out_be32(mmio + SCC_DMA_PTERADD, ap->prd_dma);
+ return 0;
+}
+
+/**
+ * scc_port_stop - Undo scc_port_start()
+ * @ap: Port to shut down
+ *
+ * Reset PTERADD.
+ */
+
+static void scc_port_stop (struct ata_port *ap)
+{
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ out_be32(mmio + SCC_DMA_PTERADD, 0);
+}
+
+static struct scsi_host_template scc_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
+#endif
+};
+
+static const struct ata_port_operations scc_pata_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = scc_set_piomode,
+ .set_dmamode = scc_set_dmamode,
+ .mode_filter = ata_pci_default_filter,
+
+ .tf_load = scc_tf_load,
+ .tf_read = scc_tf_read,
+ .exec_command = scc_exec_command,
+ .check_status = scc_check_status,
+ .check_altstatus = scc_check_altstatus,
+ .dev_select = scc_std_dev_select,
+
+ .bmdma_setup = scc_bmdma_setup,
+ .bmdma_start = scc_bmdma_start,
+ .bmdma_stop = scc_bmdma_stop,
+ .bmdma_status = scc_bmdma_status,
+ .data_xfer = scc_data_xfer,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+
+ .freeze = scc_bmdma_freeze,
+ .error_handler = scc_error_handler,
+ .post_internal_cmd = scc_bmdma_stop,
+
+ .irq_clear = scc_bmdma_irq_clear,
+ .irq_on = scc_irq_on,
+ .irq_ack = scc_irq_ack,
+
+ .port_start = scc_port_start,
+ .port_stop = scc_port_stop,
+};
+
+static struct ata_port_info scc_port_info[] = {
+ {
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x00,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &scc_pata_ops,
+ },
+};
+
+/**
+ * scc_reset_controller - initialize SCC PATA controller.
+ */
+
+static int scc_reset_controller(struct ata_host *host)
+{
+ void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
+ void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
+ void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
+ void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
+ void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
+ void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK;
+ void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS;
+ u32 reg = 0;
+
+ out_be32(cckctrl_port, reg);
+ reg |= CCKCTRL_ATACLKOEN;
+ out_be32(cckctrl_port, reg);
+ reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
+ out_be32(cckctrl_port, reg);
+ reg |= CCKCTRL_CRST;
+ out_be32(cckctrl_port, reg);
+
+ for (;;) {
+ reg = in_be32(cckctrl_port);
+ if (reg & CCKCTRL_CRST)
+ break;
+ udelay(5000);
+ }
+
+ reg |= CCKCTRL_ATARESET;
+ out_be32(cckctrl_port, reg);
+ out_be32(ecmode_port, ECMODE_VALUE);
+ out_be32(mode_port, MODE_JCUSFEN);
+ out_be32(intmask_port, INTMASK_MSK);
+
+ if (in_be32(dmastatus_port) & QCHSD_STPDIAG) {
+ printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * scc_setup_ports - initialize ioaddr with SCC PATA port offsets.
+ * @ioaddr: IO address structure to be initialized
+ * @base: base address of BMID region
+ */
+
+static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
+{
+ ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR;
+ ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
+ ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
+ ioaddr->bmdma_addr = base;
+ ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA;
+ ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR;
+ ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE;
+ ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT;
+ ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL;
+ ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM;
+ ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH;
+ ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE;
+ ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS;
+ ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
+}
+
+static int scc_host_init(struct ata_host *host)
+{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ int rc;
+
+ rc = scc_reset_controller(host);
+ if (rc)
+ return rc;
+
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+
+ scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);
+
+ pci_set_master(pdev);
+
+ return 0;
+}
+
+/**
+ * scc_init_one - Register SCC PATA device with kernel services
+ * @pdev: PCI device to register
+ * @ent: Entry in scc_pci_tbl matching with @pdev
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, or -ERRNO value.
+ */
+
+static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ unsigned int board_idx = (unsigned int) ent->driver_data;
+ const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
+ struct device *dev = &pdev->dev;
+ int rc;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "version " DRV_VERSION "\n");
+
+ host = ata_port_alloc_pinfo(&pdev->dev, ppi, 1);
+ if (!host)
+ return -ENOMEM;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
+ host->iomap = pcim_iomap_table(pdev);
+
+ rc = scc_host_init(host);
+ if (rc)
+ return rc;
+
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &scc_sht);
+}
+
+static struct pci_driver scc_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = scc_pci_tbl,
+ .probe = scc_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+#endif
+};
+
+static int __init scc_init (void)
+{
+ int rc;
+
+ DPRINTK("pci_register_driver\n");
+ rc = pci_register_driver(&scc_pci_driver);
+ if (rc)
+ return rc;
+
+ DPRINTK("done\n");
+ return 0;
+}
+
+static void __exit scc_exit (void)
+{
+ pci_unregister_driver(&scc_pci_driver);
+}
+
+module_init(scc_init);
+module_exit(scc_exit);
+
+MODULE_AUTHOR("Toshiba corp");
+MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index ad5b43fef3d1..3956ef26936d 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -1,5 +1,5 @@
/*
- * ata-serverworks.c - Serverworks PATA for new ATA layer
+ * pata_serverworks.c - Serverworks PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_serverworks"
-#define DRV_VERSION "0.3.9"
+#define DRV_VERSION "0.4.0"
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
@@ -137,14 +137,14 @@ static struct sv_cable_table cable_detect[] = {
};
/**
- * serverworks_pre_reset - cable detection
+ * serverworks_cable_detect - cable detection
* @ap: ATA port
*
* Perform cable detection according to the device and subvendor
* identifications
*/
-static int serverworks_pre_reset(struct ata_port *ap) {
+static int serverworks_cable_detect(struct ata_port *ap) {
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct sv_cable_table *cb = cable_detect;
@@ -152,8 +152,7 @@ static int serverworks_pre_reset(struct ata_port *ap) {
if (cb->device == pdev->device &&
(cb->subvendor == pdev->subsystem_vendor ||
cb->subvendor == PCI_ANY_ID)) {
- ap->cbl = cb->cable_detect(ap);
- return ata_std_prereset(ap);
+ return cb->cable_detect(ap);
}
cb++;
}
@@ -162,11 +161,6 @@ static int serverworks_pre_reset(struct ata_port *ap) {
return -1; /* kill compiler warning */
}
-static void serverworks_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, serverworks_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
/**
* serverworks_is_csb - Check for CSB or OSB
* @pdev: PCI device to check
@@ -191,31 +185,31 @@ static u8 serverworks_is_csb(struct pci_dev *pdev)
/**
* serverworks_osb4_filter - mode selection filter
- * @ap: ATA interface
* @adev: ATA device
+ * @mask: Mask of proposed modes
*
* Filter the offered modes for the device to apply controller
* specific rules. OSB4 requires no UDMA for disks due to a FIFO
* bug we hit.
*/
-static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA)
mask &= ~ATA_MASK_UDMA;
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
/**
* serverworks_csb_filter - mode selection filter
- * @ap: ATA interface
* @adev: ATA device
+ * @mask: Mask of proposed modes
*
* Check the blacklist and disable UDMA5 if matched
*/
-static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
{
const char *p;
char model_num[ATA_ID_PROD_LEN + 1];
@@ -223,7 +217,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
/* Disk, UDMA */
if (adev->class != ATA_DEV_ATA)
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
/* Actually do need to check */
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
@@ -232,7 +226,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
if (!strcmp(p, model_num))
mask &= ~(0x1F << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(ap, adev, mask);
+ return ata_pci_default_filter(adev, mask);
}
@@ -319,8 +313,10 @@ static struct scsi_host_template serverworks_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations serverworks_osb4_port_ops = {
@@ -337,8 +333,9 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = serverworks_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = serverworks_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -372,8 +369,9 @@ static struct ata_port_operations serverworks_csb_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = serverworks_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = serverworks_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -548,6 +546,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
return ata_pci_init_one(pdev, port_info, ports);
}
+#ifdef CONFIG_PM
static int serverworks_reinit_one(struct pci_dev *pdev)
{
/* Force master latency timer to 64 PCI clocks */
@@ -571,6 +570,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
}
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id serverworks[] = {
{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
@@ -587,8 +587,10 @@ static struct pci_driver serverworks_pci_driver = {
.id_table = serverworks,
.probe = serverworks_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = serverworks_reinit_one,
+#endif
};
static int __init serverworks_init(void)
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index ed79fabe025c..6770820cfca9 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -33,7 +33,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_sil680"
-#define DRV_VERSION "0.4.1"
+#define DRV_VERSION "0.4.6"
/**
* sil680_selreg - return register base
@@ -91,12 +91,6 @@ static int sil680_cable_detect(struct ata_port *ap) {
return ATA_CBL_PATA40;
}
-static int sil680_pre_reset(struct ata_port *ap)
-{
- ap->cbl = sil680_cable_detect(ap);
- return ata_std_prereset(ap);
-}
-
/**
* sil680_bus_reset - reset the SIL680 bus
* @ap: ATA port to reset
@@ -119,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
static void sil680_error_handler(struct ata_port *ap)
{
- ata_bmdma_drive_eh(ap, sil680_pre_reset, sil680_bus_reset, NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, ata_std_prereset, sil680_bus_reset, NULL, ata_std_postreset);
}
/**
@@ -139,10 +133,13 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
unsigned long tfaddr = sil680_selreg(ap, 0x02);
unsigned long addr = sil680_seldev(ap, adev, 0x04);
+ unsigned long addr_mask = 0x80 + 4 * ap->port_no;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int pio = adev->pio_mode - XFER_PIO_0;
int lowest_pio = pio;
+ int port_shift = 4 * adev->devno;
u16 reg;
+ u8 mode;
struct ata_device *pair = ata_dev_pair(adev);
@@ -153,10 +150,17 @@ static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);
pci_read_config_word(pdev, tfaddr-2, &reg);
+ pci_read_config_byte(pdev, addr_mask, &mode);
+
reg &= ~0x0200; /* Clear IORDY */
- if (ata_pio_need_iordy(adev))
+ mode &= ~(3 << port_shift); /* Clear IORDY and DMA bits */
+
+ if (ata_pio_need_iordy(adev)) {
reg |= 0x0200; /* Enable IORDY */
+ mode |= 1 << port_shift;
+ }
pci_write_config_word(pdev, tfaddr-2, reg);
+ pci_write_config_byte(pdev, addr_mask, mode);
}
/**
@@ -226,6 +230,10 @@ static struct scsi_host_template sil680_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+#endif
};
static struct ata_port_operations sil680_port_ops = {
@@ -243,6 +251,7 @@ static struct ata_port_operations sil680_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = sil680_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = sil680_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -367,11 +376,13 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
static int sil680_reinit_one(struct pci_dev *pdev)
{
sil680_init_chip(pdev);
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id sil680[] = {
{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
@@ -384,8 +395,10 @@ static struct pci_driver sil680_pci_driver = {
.id_table = sil680,
.probe = sil680_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = sil680_reinit_one,
+#endif
};
static int __init sil680_init(void)
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 560103d55b2e..a3fbcee6fb33 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -32,11 +32,10 @@
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/ata.h>
-#include "libata.h"
+#include "sis.h"
-#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "pata_sis"
-#define DRV_VERSION "0.4.5"
+#define DRV_VERSION "0.5.1"
struct sis_chipset {
u16 device; /* PCI host ID */
@@ -87,106 +86,55 @@ static int sis_port_base(struct ata_device *adev)
}
/**
- * sis_133_pre_reset - check for 40/80 pin
+ * sis_133_cable_detect - check for 40/80 pin
* @ap: Port
*
* Perform cable detection for the later UDMA133 capable
* SiS chipset.
*/
-static int sis_133_pre_reset(struct ata_port *ap)
+static int sis_133_cable_detect(struct ata_port *ap)
{
- static const struct pci_bits sis_enable_bits[] = {
- { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
- { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */
- };
-
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u16 tmp;
- if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
- return -ENOENT;
-
/* The top bit of this register is the cable detect bit */
pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp);
if ((tmp & 0x8000) && !sis_short_ata40(pdev))
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
-
- return ata_std_prereset(ap);
-}
-
-/**
- * sis_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void sis_133_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, sis_133_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
}
-
/**
- * sis_66_pre_reset - check for 40/80 pin
+ * sis_66_cable_detect - check for 40/80 pin
* @ap: Port
*
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
* SiS IDE controllers.
*/
-static int sis_66_pre_reset(struct ata_port *ap)
+static int sis_66_cable_detect(struct ata_port *ap)
{
- static const struct pci_bits sis_enable_bits[] = {
- { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
- { 0x4aU, 1U, 0x04UL, 0x04UL }, /* port 1 */
- };
-
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 tmp;
- if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
- ata_port_disable(ap);
- printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
- return 0;
- }
/* Older chips keep cable detect in bits 4/5 of reg 0x48 */
pci_read_config_byte(pdev, 0x48, &tmp);
tmp >>= ap->port_no;
if ((tmp & 0x10) && !sis_short_ata40(pdev))
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
-
- return ata_std_prereset(ap);
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
}
-/**
- * sis_66_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- * @classes:
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void sis_66_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, sis_66_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
/**
- * sis_old_pre_reset - probe begin
+ * sis_pre_reset - probe begin
* @ap: ATA port
*
* Set up cable type and use generic probe init
*/
-static int sis_old_pre_reset(struct ata_port *ap)
+static int sis_pre_reset(struct ata_port *ap)
{
static const struct pci_bits sis_enable_bits[] = {
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
@@ -195,27 +143,23 @@ static int sis_old_pre_reset(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
- ata_port_disable(ap);
- printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
- return 0;
- }
- ap->cbl = ATA_CBL_PATA40;
+ if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
+ return -ENOENT;
return ata_std_prereset(ap);
}
/**
- * sis_old_error_handler - Probe specified port on PATA host controller
+ * sis_error_handler - Probe specified port on PATA host controller
* @ap: Port to probe
*
* LOCKING:
* None (inherited from caller).
*/
-static void sis_old_error_handler(struct ata_port *ap)
+static void sis_error_handler(struct ata_port *ap)
{
- ata_bmdma_drive_eh(ap, sis_old_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ ata_bmdma_drive_eh(ap, sis_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
/**
@@ -495,7 +439,7 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
int drive_pci = sis_port_base(adev);
u16 timing;
- const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+ static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
pci_read_config_word(pdev, drive_pci, &timing);
@@ -532,8 +476,8 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev)
u32 reg54;
/* bits 4- cycle time 8 - cvs time */
- const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
- const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
+ static const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
+ static const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
/* If bit 14 is set then the registers are mapped at 0x70 not 0x40 */
pci_read_config_dword(pdev, 0x54, &reg54);
@@ -576,8 +520,10 @@ static struct scsi_host_template sis_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static const struct ata_port_operations sis_133_ops = {
@@ -594,8 +540,9 @@ static const struct ata_port_operations sis_133_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = sis_133_error_handler,
+ .error_handler = sis_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = sis_133_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -627,8 +574,9 @@ static const struct ata_port_operations sis_133_early_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = sis_66_error_handler,
+ .error_handler = sis_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = sis_66_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -660,9 +608,9 @@ static const struct ata_port_operations sis_100_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = sis_66_error_handler,
+ .error_handler = sis_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
-
+ .cable_detect = sis_66_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -691,10 +639,11 @@ static const struct ata_port_operations sis_66_ops = {
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .cable_detect = sis_66_cable_detect,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = sis_66_error_handler,
+ .error_handler = sis_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.bmdma_setup = ata_bmdma_setup,
@@ -727,8 +676,9 @@ static const struct ata_port_operations sis_old_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = sis_old_error_handler,
+ .error_handler = sis_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -877,6 +827,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *port;
struct pci_dev *host = NULL;
struct sis_chipset *chipset = NULL;
+ struct sis_chipset *sets;
static struct sis_chipset sis_chipsets[] = {
@@ -931,10 +882,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
/* We have to find the bridge first */
- for (chipset = &sis_chipsets[0]; chipset->device; chipset++) {
- host = pci_get_device(PCI_VENDOR_ID_SI, chipset->device, NULL);
+ for (sets = &sis_chipsets[0]; sets->device; sets++) {
+ host = pci_get_device(PCI_VENDOR_ID_SI, sets->device, NULL);
if (host != NULL) {
- if (chipset->device == 0x630) { /* SIS630 */
+ chipset = sets; /* Match found */
+ if (sets->device == 0x630) { /* SIS630 */
u8 host_rev;
pci_read_config_byte(host, PCI_REVISION_ID, &host_rev);
if (host_rev >= 0x30) /* 630 ET */
@@ -945,7 +897,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Look for concealed bridges */
- if (host == NULL) {
+ if (chipset == NULL) {
/* Second check */
u32 idemisc;
u16 trueid;
@@ -1033,8 +985,10 @@ static struct pci_driver sis_pci_driver = {
.id_table = sis_pci_tbl,
.probe = sis_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init sis_init(void)
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 96e890fd645b..da9e22b25753 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -7,6 +7,13 @@
* SL82C105/Winbond 553 IDE driver
*
* and in part on the documentation and errata sheet
+ *
+ *
+ * Note: The controller like many controllers has shared timings for
+ * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back
+ * in the dma_stop function. Thus we actually don't need a set_dmamode
+ * method as the PIO method is always called and will set the right PIO
+ * timing parameters.
*/
#include <linux/kernel.h>
@@ -19,7 +26,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_sl82c105"
-#define DRV_VERSION "0.2.3"
+#define DRV_VERSION "0.3.0"
enum {
/*
@@ -51,7 +58,6 @@ static int sl82c105_pre_reset(struct ata_port *ap)
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -126,33 +132,6 @@ static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *a
}
/**
- * sl82c105_set_dmamode - set initial DMA mode data
- * @ap: ATA interface
- * @adev: ATA device
- *
- * Called to do the DMA mode setup. This replaces the PIO timings
- * for the device in question. Set appropriate PIO timings not DMA
- * timings at this point.
- */
-
-static void sl82c105_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
- switch(adev->dma_mode) {
- case XFER_MW_DMA_0:
- sl82c105_configure_piomode(ap, adev, 0);
- break;
- case XFER_MW_DMA_1:
- sl82c105_configure_piomode(ap, adev, 3);
- break;
- case XFER_MW_DMA_2:
- sl82c105_configure_piomode(ap, adev, 4);
- break;
- default:
- BUG();
- }
-}
-
-/**
* sl82c105_reset_engine - Reset the DMA engine
* @ap: ATA interface
*
@@ -222,7 +201,7 @@ static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc)
/* This will redo the initial setup of the DMA device to matching
PIO timings */
- sl82c105_set_dmamode(ap, qc->dev);
+ sl82c105_set_piomode(ap, qc->dev);
}
static struct scsi_host_template sl82c105_sht = {
@@ -246,7 +225,6 @@ static struct scsi_host_template sl82c105_sht = {
static struct ata_port_operations sl82c105_port_ops = {
.port_disable = ata_port_disable,
.set_piomode = sl82c105_set_piomode,
- .set_dmamode = sl82c105_set_dmamode,
.mode_filter = ata_pci_default_filter,
.tf_load = ata_tf_load,
@@ -255,7 +233,11 @@ static struct ata_port_operations sl82c105_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
.error_handler = sl82c105_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = sl82c105_bmdma_start,
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index 453ab90b721e..e618ffd6e944 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -43,7 +43,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_triflex"
-#define DRV_VERSION "0.2.7"
+#define DRV_VERSION "0.2.8"
/**
* triflex_prereset - probe begin
@@ -63,7 +63,6 @@ static int triflex_prereset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -193,8 +192,10 @@ static struct scsi_host_template triflex_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations triflex_port_ops = {
@@ -212,6 +213,7 @@ static struct ata_port_operations triflex_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = triflex_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = triflex_bmdma_start,
@@ -260,8 +262,10 @@ static struct pci_driver triflex_pci_driver = {
.id_table = triflex,
.probe = triflex_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init triflex_init(void)
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 220fcd6c5492..96b71791d2f4 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -62,7 +62,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_via"
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.3.1"
/*
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -135,16 +135,23 @@ static const struct via_isa_bridge {
*/
static int via_cable_detect(struct ata_port *ap) {
+ const struct via_isa_bridge *config = ap->host->private_data;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 ata66;
+ /* Early chips are 40 wire */
+ if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
+ return ATA_CBL_PATA40;
+ /* UDMA 66 chips have only drive side logic */
+ else if((config->flags & VIA_UDMA) < VIA_UDMA_100)
+ return ATA_CBL_PATA_UNK;
+ /* UDMA 100 or later */
pci_read_config_dword(pdev, 0x50, &ata66);
/* Check both the drive cable reporting bits, we might not have
two drives */
if (ata66 & (0x10100000 >> (16 * ap->port_no)))
return ATA_CBL_PATA80;
- else
- return ATA_CBL_PATA40;
+ return ATA_CBL_PATA40;
}
static int via_pre_reset(struct ata_port *ap)
@@ -156,22 +163,10 @@ static int via_pre_reset(struct ata_port *ap)
{ 0x40, 1, 0x02, 0x02 },
{ 0x40, 1, 0x01, 0x01 }
};
-
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
return -ENOENT;
}
-
- if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
- ap->cbl = via_cable_detect(ap);
- /* The UDMA66 series has no cable detect so do drive side detect */
- else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA_UNK;
-
-
return ata_std_prereset(ap);
}
@@ -305,8 +300,10 @@ static struct scsi_host_template via_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.resume = ata_scsi_device_resume,
.suspend = ata_scsi_device_suspend,
+#endif
};
static struct ata_port_operations via_port_ops = {
@@ -325,6 +322,7 @@ static struct ata_port_operations via_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = via_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = via_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -360,6 +358,7 @@ static struct ata_port_operations via_port_ops_noirq = {
.thaw = ata_bmdma_thaw,
.error_handler = via_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = via_cable_detect,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -560,6 +559,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return ata_pci_init_one(pdev, port_info, 2);
}
+#ifdef CONFIG_PM
/**
* via_reinit_one - reinit after resume
* @pdev; PCI device
@@ -592,6 +592,7 @@ static int via_reinit_one(struct pci_dev *pdev)
}
return ata_pci_device_resume(pdev);
}
+#endif
static const struct pci_device_id via[] = {
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
@@ -607,8 +608,10 @@ static struct pci_driver via_pci_driver = {
.id_table = via,
.probe = via_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = via_reinit_one,
+#endif
};
static int __init via_init(void)
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 0888b4f19f4c..cc4ad271afb5 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -8,7 +8,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
@@ -17,7 +16,7 @@
#include <linux/platform_device.h>
#define DRV_NAME "pata_winbond"
-#define DRV_VERSION "0.0.1"
+#define DRV_VERSION "0.0.2"
#define NR_HOST 4 /* Two winbond controllers, two channels each */
@@ -36,7 +35,7 @@ static int probe_winbond = 1;
static int probe_winbond;
#endif
-static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(winbond_lock);
static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
{
@@ -152,13 +151,13 @@ static struct ata_port_operations winbond_port_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_40wire,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = winbond_data_xfer,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -179,11 +178,9 @@ static struct ata_port_operations winbond_port_ops = {
static __init int winbond_init_one(unsigned long port)
{
- struct ata_probe_ent ae;
struct platform_device *pdev;
- int ret;
u8 reg;
- int i;
+ int i, rc;
reg = winbond_readcfg(port, 0x81);
reg |= 0x80; /* jumpered mode off */
@@ -202,58 +199,56 @@ static __init int winbond_init_one(unsigned long port)
for (i = 0; i < 2 ; i ++) {
unsigned long cmd_port = 0x1F0 - (0x80 * i);
+ struct ata_host *host;
+ struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
- if (reg & (1 << i)) {
- /*
- * Fill in a probe structure first of all
- */
-
- pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
- ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
- if (!cmd_addr || !ctl_addr) {
- platform_device_unregister(pdev);
- return -ENOMEM;
- }
-
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
- ae.dev = &pdev->dev;
-
- ae.port_ops = &winbond_port_ops;
- ae.pio_mask = 0x1F;
-
- ae.sht = &winbond_sht;
-
- ae.n_ports = 1;
- ae.irq = 14 + i;
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = cmd_addr;
- ae.port[0].altstatus_addr = ctl_addr;
- ae.port[0].ctl_addr = ctl_addr;
- ata_std_ports(&ae.port[0]);
- /*
- * Hook in a private data structure per channel
- */
- ae.private_data = &winbond_data[nr_winbond_host];
- winbond_data[nr_winbond_host].config = port;
- winbond_data[nr_winbond_host].platform_dev = pdev;
-
- ret = ata_device_add(&ae);
- if (ret == 0) {
- platform_device_unregister(pdev);
- return -ENODEV;
- }
- winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
- }
+ if (!(reg & (1 << i)))
+ continue;
+
+ pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ rc = -ENOMEM;
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ goto err_unregister;
+
+ rc = -ENOMEM;
+ cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
+ if (!cmd_addr || !ctl_addr)
+ goto err_unregister;
+
+ ap = host->ports[0];
+ ap->ops = &winbond_port_ops;
+ ap->pio_mask = 0x1F;
+ ap->flags |= ATA_FLAG_SLAVE_POSS;
+ ap->ioaddr.cmd_addr = cmd_addr;
+ ap->ioaddr.altstatus_addr = ctl_addr;
+ ap->ioaddr.ctl_addr = ctl_addr;
+ ata_std_ports(&ap->ioaddr);
+
+ /* hook in a private data structure per channel */
+ host->private_data = &winbond_data[nr_winbond_host];
+ winbond_data[nr_winbond_host].config = port;
+ winbond_data[nr_winbond_host].platform_dev = pdev;
+
+ /* activate */
+ rc = ata_host_activate(host, 14 + i, ata_interrupt, 0,
+ &winbond_sht);
+ if (rc)
+ goto err_unregister;
+
+ winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
}
return 0;
+
+ err_unregister:
+ platform_device_unregister(pdev);
+ return rc;
}
/**
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 857ac23217ab..52b69530ab29 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -44,7 +44,7 @@
#include <linux/libata.h>
#define DRV_NAME "pdc_adma"
-#define DRV_VERSION "0.04"
+#define DRV_VERSION "0.05"
/* macro to calculate base address for ATA regs */
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
@@ -52,9 +52,9 @@
/* macro to calculate base address for ADMA regs */
#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
-/* macro to obtain addresses from ata_host */
-#define ADMA_HOST_REGS(host,port_no) \
- ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no)
+/* macro to obtain addresses from ata_port */
+#define ADMA_PORT_REGS(ap) \
+ ADMA_REGS((ap)->host->iomap[ADMA_MMIO_BAR], ap->port_no)
enum {
ADMA_MMIO_BAR = 4,
@@ -128,7 +128,6 @@ struct adma_port_priv {
static int adma_ata_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent);
-static irqreturn_t adma_intr (int irq, void *dev_instance);
static int adma_port_start(struct ata_port *ap);
static void adma_host_stop(struct ata_host *host);
static void adma_port_stop(struct ata_port *ap);
@@ -172,7 +171,6 @@ static const struct ata_port_operations adma_ata_ops = {
.qc_issue = adma_qc_issue,
.eng_timeout = adma_eng_timeout,
.data_xfer = ata_data_xfer,
- .irq_handler = adma_intr,
.irq_clear = adma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -186,7 +184,6 @@ static const struct ata_port_operations adma_ata_ops = {
static struct ata_port_info adma_port_info[] = {
/* board_1841_idx */
{
- .sht = &adma_ata_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
@@ -229,8 +226,10 @@ static void adma_irq_clear(struct ata_port *ap)
/* nothing */
}
-static void adma_reset_engine(void __iomem *chan)
+static void adma_reset_engine(struct ata_port *ap)
{
+ void __iomem *chan = ADMA_PORT_REGS(ap);
+
/* reset ADMA to idle state */
writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
udelay(2);
@@ -241,14 +240,14 @@ static void adma_reset_engine(void __iomem *chan)
static void adma_reinit_engine(struct ata_port *ap)
{
struct adma_port_priv *pp = ap->private_data;
- void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+ void __iomem *chan = ADMA_PORT_REGS(ap);
/* mask/clear ATA interrupts */
writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
ata_check_status(ap);
/* reset the ADMA engine */
- adma_reset_engine(chan);
+ adma_reset_engine(ap);
/* set in-FIFO threshold to 0x100 */
writew(0x100, chan + ADMA_FIFO_IN);
@@ -268,7 +267,7 @@ static void adma_reinit_engine(struct ata_port *ap)
static inline void adma_enter_reg_mode(struct ata_port *ap)
{
- void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+ void __iomem *chan = ADMA_PORT_REGS(ap);
writew(aPIOMD4, chan + ADMA_CONTROL);
readb(chan + ADMA_STATUS); /* flush */
@@ -415,7 +414,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
static inline void adma_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+ void __iomem *chan = ADMA_PORT_REGS(ap);
VPRINTK("ENTER, ap %p\n", ap);
@@ -453,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host)
struct ata_port *ap = host->ports[port_no];
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
- void __iomem *chan = ADMA_HOST_REGS(host, port_no);
+ void __iomem *chan = ADMA_PORT_REGS(ap);
u8 status = readb(chan + ADMA_STATUS);
if (status == 0)
@@ -498,7 +497,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
- ap->id, qc->tf.protocol, status);
+ ap->print_id, qc->tf.protocol, status);
/* complete taskfile transaction */
pp->state = adma_state_idle;
@@ -575,7 +574,7 @@ static int adma_port_start(struct ata_port *ap)
static void adma_port_stop(struct ata_port *ap)
{
- adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no));
+ adma_reset_engine(ap);
}
static void adma_host_stop(struct ata_host *host)
@@ -583,21 +582,19 @@ static void adma_host_stop(struct ata_host *host)
unsigned int port_no;
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
- adma_reset_engine(ADMA_HOST_REGS(host, port_no));
+ adma_reset_engine(host->ports[port_no]);
}
-static void adma_host_init(unsigned int chip_id,
- struct ata_probe_ent *probe_ent)
+static void adma_host_init(struct ata_host *host, unsigned int chip_id)
{
unsigned int port_no;
- void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR];
/* enable/lock aGO operation */
- writeb(7, mmio_base + ADMA_MODE_LOCK);
+ writeb(7, host->iomap[ADMA_MMIO_BAR] + ADMA_MODE_LOCK);
/* reset the ADMA logic */
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
- adma_reset_engine(ADMA_REGS(mmio_base, port_no));
+ adma_reset_engine(host->ports[port_no]);
}
static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
@@ -623,14 +620,21 @@ static int adma_ata_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- void __iomem *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
+ const struct ata_port_info *ppi[] = { &adma_port_info[board_idx], NULL };
+ struct ata_host *host;
+ void __iomem *mmio_base;
int rc, port_no;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* alloc host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, ADMA_PORTS);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -641,46 +645,23 @@ static int adma_ata_init_one(struct pci_dev *pdev,
rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME);
if (rc)
return rc;
- mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR];
+ host->iomap = pcim_iomap_table(pdev);
+ mmio_base = host->iomap[ADMA_MMIO_BAR];
rc = adma_set_dma_masks(pdev, mmio_base);
if (rc)
return rc;
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- probe_ent->sht = adma_port_info[board_idx].sht;
- probe_ent->port_flags = adma_port_info[board_idx].flags;
- probe_ent->pio_mask = adma_port_info[board_idx].pio_mask;
- probe_ent->mwdma_mask = adma_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = adma_port_info[board_idx].udma_mask;
- probe_ent->port_ops = adma_port_info[board_idx].port_ops;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->n_ports = ADMA_PORTS;
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
- adma_ata_setup_port(&probe_ent->port[port_no],
+ for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+ adma_ata_setup_port(&host->ports[port_no]->ioaddr,
ADMA_ATA_REGS(mmio_base, port_no));
- }
-
- pci_set_master(pdev);
/* initialize adapter */
- adma_host_init(board_idx, probe_ent);
+ adma_host_init(host, board_idx);
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, adma_intr, IRQF_SHARED,
+ &adma_ata_sht);
}
static int __init adma_ata_init(void)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 31b636fac98e..f099a1d83a00 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -135,8 +135,10 @@ static struct scsi_host_template inic_sht = {
.slave_configure = inic_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const int scr_map[] = {
@@ -486,11 +488,11 @@ static void inic_error_handler(struct ata_port *ap)
static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
{
/* make DMA engine forget about the failed command */
- if (qc->err_mask)
+ if (qc->flags & ATA_QCFLAG_FAILED)
inic_reset_port(inic_port_base(qc->ap));
}
-static void inic_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void inic_dev_config(struct ata_device *dev)
{
/* inic can only handle upto LBA28 max sectors */
if (dev->max_sectors > ATA_MAX_SECTORS)
@@ -557,7 +559,6 @@ static struct ata_port_operations inic_port_ops = {
.bmdma_stop = inic_bmdma_stop,
.bmdma_status = inic_bmdma_status,
- .irq_handler = inic_interrupt,
.irq_clear = inic_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -578,7 +579,6 @@ static struct ata_port_operations inic_port_ops = {
};
static struct ata_port_info inic_port_info = {
- .sht = &inic_sht,
/* For some reason, ATA_PROT_ATAPI is broken on this
* controller, and no, PIO_POLLING does't fix it. It somehow
* manages to report the wrong ireason and ignoring ireason
@@ -632,6 +632,7 @@ static int init_controller(void __iomem *mmio_base, u16 hctl)
return 0;
}
+#ifdef CONFIG_PM
static int inic_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
@@ -639,10 +640,11 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
void __iomem *mmio_base = host->iomap[MMIO_BAR];
int rc;
- ata_pci_device_do_resume(pdev);
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
- printk("XXX\n");
rc = init_controller(mmio_base, hpriv->cached_hctl);
if (rc)
return rc;
@@ -652,12 +654,13 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
return 0;
}
+#endif
static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_port_info *pinfo = &inic_port_info;
- struct ata_probe_ent *probe_ent;
+ const struct ata_port_info *ppi[] = { &inic_port_info, NULL };
+ struct ata_host *host;
struct inic_host_priv *hpriv;
void __iomem * const *iomap;
int i, rc;
@@ -665,18 +668,38 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pcim_enable_device(pdev);
- if (rc)
- return rc;
+ /* alloc host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!host || !hpriv)
+ return -ENOMEM;
+
+ host->private_data = hpriv;
- rc = pci_request_regions(pdev, DRV_NAME);
+ /* acquire resources and fill host */
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
if (rc)
return rc;
- iomap = pcim_iomap_table(pdev);
+ host->iomap = iomap = pcim_iomap_table(pdev);
+
+ for (i = 0; i < NR_PORTS; i++) {
+ struct ata_ioports *port = &host->ports[i]->ioaddr;
+ void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
+
+ port->cmd_addr = iomap[2 * i];
+ port->altstatus_addr =
+ port->ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
+ port->scr_addr = port_base + PORT_SCR;
+
+ ata_std_ports(port);
+ }
+
+ hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
/* Set dma_mask. This devices doesn't support 64bit addressing. */
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
@@ -693,43 +716,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
- if (!probe_ent || !hpriv)
- return -ENOMEM;
-
- probe_ent->dev = &pdev->dev;
- INIT_LIST_HEAD(&probe_ent->node);
-
- probe_ent->sht = pinfo->sht;
- probe_ent->port_flags = pinfo->flags;
- probe_ent->pio_mask = pinfo->pio_mask;
- probe_ent->mwdma_mask = pinfo->mwdma_mask;
- probe_ent->udma_mask = pinfo->udma_mask;
- probe_ent->port_ops = pinfo->port_ops;
- probe_ent->n_ports = NR_PORTS;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
-
- probe_ent->iomap = iomap;
-
- for (i = 0; i < NR_PORTS; i++) {
- struct ata_ioports *port = &probe_ent->port[i];
- void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
-
- port->cmd_addr = iomap[2 * i];
- port->altstatus_addr =
- port->ctl_addr = (void __iomem *)
- ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
- port->scr_addr = port_base + PORT_SCR;
-
- ata_std_ports(port);
- }
-
- probe_ent->private_data = hpriv;
- hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
-
rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
@@ -738,13 +724,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
pci_set_master(pdev);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
-
- return 0;
+ return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED,
+ &inic_sht);
}
static const struct pci_device_id inic_pci_tbl[] = {
@@ -755,8 +736,10 @@ static const struct pci_device_id inic_pci_tbl[] = {
static struct pci_driver inic_pci_driver = {
.name = DRV_NAME,
.id_table = inic_pci_tbl,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = inic_pci_device_resume,
+#endif
.probe = inic_init_one,
.remove = ata_pci_remove_one,
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index d689df52eae3..cb9b9ac12b4c 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "0.7"
+#define DRV_VERSION "0.8"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -137,14 +137,19 @@ enum {
PCI_ERR = (1 << 18),
TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */
TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */
+ PORTS_0_3_COAL_DONE = (1 << 8),
+ PORTS_4_7_COAL_DONE = (1 << 17),
PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */
GPIO_INT = (1 << 22),
SELF_INT = (1 << 23),
TWSI_INT = (1 << 24),
HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
+ HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */
HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT |
HC_MAIN_RSVD),
+ HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
+ HC_MAIN_RSVD_5),
/* SATAHC registers */
HC_CFG_OFS = 0,
@@ -248,10 +253,7 @@ enum {
#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
enum {
- /* Our DMA boundary is determined by an ePRD being unable to handle
- * anything larger than 64KB
- */
- MV_DMA_BOUNDARY = 0xffffU,
+ MV_DMA_BOUNDARY = 0xffffffffU,
EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
@@ -345,7 +347,6 @@ static void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc);
static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t mv_interrupt(int irq, void *dev_instance);
static void mv_eng_timeout(struct ata_port *ap);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -379,10 +380,10 @@ static struct scsi_host_template mv_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = MV_USE_Q_DEPTH,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = MV_MAX_SG_CT / 2,
+ .sg_tablesize = MV_MAX_SG_CT,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .use_clustering = 1,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
@@ -400,6 +401,7 @@ static const struct ata_port_operations mv5_ops = {
.dev_select = ata_std_dev_select,
.phy_reset = mv_phy_reset,
+ .cable_detect = ata_cable_sata,
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
@@ -407,7 +409,6 @@ static const struct ata_port_operations mv5_ops = {
.eng_timeout = mv_eng_timeout,
- .irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -429,6 +430,7 @@ static const struct ata_port_operations mv6_ops = {
.dev_select = ata_std_dev_select,
.phy_reset = mv_phy_reset,
+ .cable_detect = ata_cable_sata,
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
@@ -436,7 +438,6 @@ static const struct ata_port_operations mv6_ops = {
.eng_timeout = mv_eng_timeout,
- .irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -458,6 +459,7 @@ static const struct ata_port_operations mv_iie_ops = {
.dev_select = ata_std_dev_select,
.phy_reset = mv_phy_reset,
+ .cable_detect = ata_cable_sata,
.qc_prep = mv_qc_prep_iie,
.qc_issue = mv_qc_issue,
@@ -465,7 +467,6 @@ static const struct ata_port_operations mv_iie_ops = {
.eng_timeout = mv_eng_timeout,
- .irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -479,35 +480,30 @@ static const struct ata_port_operations mv_iie_ops = {
static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
- .sht = &mv_sht,
.flags = MV_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv5_ops,
},
{ /* chip_508x */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv5_ops,
},
{ /* chip_604x */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv6_ops,
},
{ /* chip_608x */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
MV_FLAG_DUAL_HC),
.pio_mask = 0x1f, /* pio0-4 */
@@ -515,14 +511,12 @@ static const struct ata_port_info mv_port_info[] = {
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
- .sht = &mv_sht,
.flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
@@ -546,6 +540,9 @@ static const struct pci_device_id mv_pci_tbl[] = {
{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+ /* add Marvell 7042 support */
+ { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
+
{ } /* terminate list */
};
@@ -580,6 +577,39 @@ static const struct mv_hw_ops mv6xxx_ops = {
static int msi; /* Use PCI msi; either zero (off, default) or non-zero */
+/* move to PCI layer or libata core? */
+static int pci_go_64(struct pci_dev *pdev)
+{
+ int rc;
+
+ if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (rc) {
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "64-bit DMA enable failed\n");
+ return rc;
+ }
+ }
+ } else {
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ return rc;
+ }
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
/*
* Functions
*/
@@ -793,20 +823,18 @@ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
{
unsigned int ofs = mv_scr_offset(sc_reg_in);
- if (0xffffffffU != ofs) {
+ if (0xffffffffU != ofs)
return readl(mv_ap_base(ap) + ofs);
- } else {
+ else
return (u32) ofs;
- }
}
static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{
unsigned int ofs = mv_scr_offset(sc_reg_in);
- if (0xffffffffU != ofs) {
+ if (0xffffffffU != ofs)
writelfl(val, mv_ap_base(ap) + ofs);
- }
}
static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
@@ -814,23 +842,27 @@ static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
/* set up non-NCQ EDMA configuration */
- cfg &= ~0x1f; /* clear queue depth */
- cfg &= ~EDMA_CFG_NCQ; /* clear NCQ mode */
cfg &= ~(1 << 9); /* disable equeue */
- if (IS_GEN_I(hpriv))
+ if (IS_GEN_I(hpriv)) {
+ cfg &= ~0x1f; /* clear queue depth */
cfg |= (1 << 8); /* enab config burst size mask */
+ }
- else if (IS_GEN_II(hpriv))
+ else if (IS_GEN_II(hpriv)) {
+ cfg &= ~0x1f; /* clear queue depth */
cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN;
+ cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */
+ }
else if (IS_GEN_IIE(hpriv)) {
- cfg |= (1 << 23); /* dis RX PM port mask */
- cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */
+ cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
+ cfg |= (1 << 22); /* enab 4-entry host queue cache */
cfg &= ~(1 << 19); /* dis 128-entry queue (for now?) */
cfg |= (1 << 18); /* enab early completion */
- cfg |= (1 << 17); /* enab host q cache */
- cfg |= (1 << 22); /* enab cutthrough */
+ cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */
+ cfg &= ~(1 << 16); /* dis FIS-based switching (for now) */
+ cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */
}
writelfl(cfg, port_mmio + EDMA_CFG_OFS);
@@ -950,38 +982,30 @@ static void mv_port_stop(struct ata_port *ap)
* LOCKING:
* Inherited from caller.
*/
-static void mv_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
{
struct mv_port_priv *pp = qc->ap->private_data;
- unsigned int i = 0;
+ unsigned int n_sg = 0;
struct scatterlist *sg;
+ struct mv_sg *mv_sg;
+ mv_sg = pp->sg_tbl;
ata_for_each_sg(sg, qc) {
- dma_addr_t addr;
- u32 sg_len, len, offset;
-
- addr = sg_dma_address(sg);
- sg_len = sg_dma_len(sg);
-
- while (sg_len) {
- offset = addr & MV_DMA_BOUNDARY;
- len = sg_len;
- if ((offset + sg_len) > 0x10000)
- len = 0x10000 - offset;
+ dma_addr_t addr = sg_dma_address(sg);
+ u32 sg_len = sg_dma_len(sg);
- pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
- pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
- pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff);
+ mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
+ mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
+ mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff);
- sg_len -= len;
- addr += len;
+ if (ata_sg_is_last(sg, qc))
+ mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
- if (!sg_len && ata_sg_is_last(sg, qc))
- pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
- i++;
- }
+ mv_sg++;
+ n_sg++;
}
+
+ return n_sg;
}
static inline unsigned mv_inc_q_index(unsigned index)
@@ -1276,7 +1300,7 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed)
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
}
DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
- "SERR: 0x%08x\n", ap->id, edma_err_cause, serr);
+ "SERR: 0x%08x\n", ap->print_id, edma_err_cause, serr);
/* Clear EDMA now that SERR cleanup done */
writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
@@ -1311,17 +1335,15 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
int shift, port, port0, hard_port, handled;
unsigned int err_mask;
- if (hc == 0) {
+ if (hc == 0)
port0 = 0;
- } else {
+ else
port0 = MV_PORTS_PER_HC;
- }
/* we'll need the HC success int register in most cases */
hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- if (hc_irq_cause) {
+ if (hc_irq_cause)
writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
- }
VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
hc,relevant,hc_irq_cause);
@@ -1416,9 +1438,8 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
/* check the cases where we either have nothing pending or have read
* a bogus register value which can indicate HW removal or PCI fault
*/
- if (!irq_stat || (0xffffffffU == irq_stat)) {
+ if (!irq_stat || (0xffffffffU == irq_stat))
return IRQ_NONE;
- }
n_hcs = mv_get_hc_count(host->ports[0]->flags);
spin_lock(&host->lock);
@@ -1943,7 +1964,6 @@ comreset_retry:
ata_port_disable(ap);
return;
}
- ap->cbl = ATA_CBL_SATA;
/* even after SStatus reflects that device is ready,
* it seems to take a while for link to be fully
@@ -2052,7 +2072,7 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
/* unused: */
- port->cmd_addr = port->bmdma_addr = port->scr_addr = 0;
+ port->cmd_addr = port->bmdma_addr = port->scr_addr = NULL;
/* Clear any currently outstanding port interrupt conditions */
serr_ofs = mv_scr_offset(SCR_ERROR);
@@ -2068,9 +2088,10 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
}
-static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
- unsigned int board_idx)
+static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ struct mv_host_priv *hpriv = host->private_data;
u8 rev_id;
u32 hp_flags = hpriv->hp_flags;
@@ -2168,8 +2189,8 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
/**
* mv_init_host - Perform some early initialization of the host.
- * @pdev: host PCI device
- * @probe_ent: early data struct representing the host
+ * @host: ATA host to initialize
+ * @board_idx: controller index
*
* If possible, do an early global reset of the host. Then do
* our port init and clear/unmask all/relevant host interrupts.
@@ -2177,24 +2198,23 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
* LOCKING:
* Inherited from caller.
*/
-static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
- unsigned int board_idx)
+static int mv_init_host(struct ata_host *host, unsigned int board_idx)
{
int rc = 0, n_hc, port, hc;
- void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
- struct mv_host_priv *hpriv = probe_ent->private_data;
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
+ struct mv_host_priv *hpriv = host->private_data;
/* global interrupt mask */
writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
- rc = mv_chip_id(pdev, hpriv, board_idx);
+ rc = mv_chip_id(host, board_idx);
if (rc)
goto done;
- n_hc = mv_get_hc_count(probe_ent->port_flags);
- probe_ent->n_ports = MV_PORTS_PER_HC * n_hc;
+ n_hc = mv_get_hc_count(host->ports[0]->flags);
- for (port = 0; port < probe_ent->n_ports; port++)
+ for (port = 0; port < host->n_ports; port++)
hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
@@ -2205,7 +2225,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
hpriv->ops->reset_bus(pdev, mmio);
hpriv->ops->enable_leds(hpriv, mmio);
- for (port = 0; port < probe_ent->n_ports; port++) {
+ for (port = 0; port < host->n_ports; port++) {
if (IS_60XX(hpriv)) {
void __iomem *port_mmio = mv_port_base(mmio, port);
@@ -2218,9 +2238,9 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
hpriv->ops->phy_errata(hpriv, mmio, port);
}
- for (port = 0; port < probe_ent->n_ports; port++) {
+ for (port = 0; port < host->n_ports; port++) {
void __iomem *port_mmio = mv_port_base(mmio, port);
- mv_port_init(&probe_ent->port[port], port_mmio);
+ mv_port_init(&host->ports[port]->ioaddr, port_mmio);
}
for (hc = 0; hc < n_hc; hc++) {
@@ -2240,7 +2260,11 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
/* and unmask interrupt generation for host regs */
writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
- writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
+
+ if (IS_50XX(hpriv))
+ writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS);
+ else
+ writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x "
"PCI int cause/mask=0x%08x/0x%08x\n",
@@ -2255,17 +2279,17 @@ done:
/**
* mv_print_info - Dump key info to kernel log for perusal.
- * @probe_ent: early data struct representing the host
+ * @host: ATA host to print info about
*
* FIXME: complete this.
*
* LOCKING:
* Inherited from caller.
*/
-static void mv_print_info(struct ata_probe_ent *probe_ent)
+static void mv_print_info(struct ata_host *host)
{
- struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- struct mv_host_priv *hpriv = probe_ent->private_data;
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ struct mv_host_priv *hpriv = host->private_data;
u8 rev_id, scc;
const char *scc_s;
@@ -2284,7 +2308,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
dev_printk(KERN_INFO, &pdev->dev,
"%u slots %u ports %s mode IRQ via %s\n",
- (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+ (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
}
@@ -2299,65 +2323,55 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
- struct device *dev = &pdev->dev;
- struct ata_probe_ent *probe_ent;
- struct mv_host_priv *hpriv;
unsigned int board_idx = (unsigned int)ent->driver_data;
- int rc;
+ const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
+ struct ata_host *host;
+ struct mv_host_priv *hpriv;
+ int n_ports, rc;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+ /* allocate host */
+ n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!host || !hpriv)
+ return -ENOMEM;
+ host->private_data = hpriv;
+
+ /* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
- pci_set_master(pdev);
rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv)
- return -ENOMEM;
-
- probe_ent->sht = mv_port_info[board_idx].sht;
- probe_ent->port_flags = mv_port_info[board_idx].flags;
- probe_ent->pio_mask = mv_port_info[board_idx].pio_mask;
- probe_ent->udma_mask = mv_port_info[board_idx].udma_mask;
- probe_ent->port_ops = mv_port_info[board_idx].port_ops;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
- probe_ent->private_data = hpriv;
+ rc = pci_go_64(pdev);
+ if (rc)
+ return rc;
/* initialize adapter */
- rc = mv_init_host(pdev, probe_ent, board_idx);
+ rc = mv_init_host(host, board_idx);
if (rc)
return rc;
/* Enable interrupts */
- if (msi && !pci_enable_msi(pdev))
+ if (msi && pci_enable_msi(pdev))
pci_intx(pdev, 1);
mv_dump_pci_cfg(pdev, 0x68);
- mv_print_info(probe_ent);
+ mv_print_info(host);
- if (ata_device_add(probe_ent) == 0)
- return -ENODEV;
-
- devm_kfree(dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
+ &mv_sht);
}
static int __init mv_init(void)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index ab92f208dae2..02169740ed24 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -219,6 +219,7 @@ struct nv_adma_port_priv {
void __iomem * gen_block;
void __iomem * notifier_clear_block;
u8 flags;
+ int last_issue_ncq;
};
struct nv_host_priv {
@@ -229,7 +230,9 @@ struct nv_host_priv {
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static void nv_remove_one (struct pci_dev *pdev);
+#ifdef CONFIG_PM
static int nv_pci_device_resume(struct pci_dev *pdev);
+#endif
static void nv_ck804_host_stop(struct ata_host *host);
static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
@@ -250,14 +253,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance);
static void nv_adma_irq_clear(struct ata_port *ap);
static int nv_adma_port_start(struct ata_port *ap);
static void nv_adma_port_stop(struct ata_port *ap);
+#ifdef CONFIG_PM
static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg);
static int nv_adma_port_resume(struct ata_port *ap);
+#endif
static void nv_adma_error_handler(struct ata_port *ap);
static void nv_adma_host_stop(struct ata_host *host);
-static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc);
-static void nv_adma_bmdma_start(struct ata_queued_cmd *qc);
-static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc);
-static u8 nv_adma_bmdma_status(struct ata_port *ap);
+static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
enum nv_host_type
{
@@ -297,8 +300,10 @@ static struct pci_driver nv_pci_driver = {
.name = DRV_NAME,
.id_table = nv_pci_tbl,
.probe = nv_init_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = nv_pci_device_resume,
+#endif
.remove = nv_remove_one,
};
@@ -318,8 +323,10 @@ static struct scsi_host_template nv_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static struct scsi_host_template nv_adma_sht = {
@@ -338,8 +345,10 @@ static struct scsi_host_template nv_adma_sht = {
.slave_configure = nv_adma_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations nv_generic_ops = {
@@ -360,7 +369,6 @@ static const struct ata_port_operations nv_generic_ops = {
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.data_xfer = ata_data_xfer,
- .irq_handler = nv_generic_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -387,7 +395,6 @@ static const struct ata_port_operations nv_nf2_ops = {
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.data_xfer = ata_data_xfer,
- .irq_handler = nv_nf2_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -414,7 +421,6 @@ static const struct ata_port_operations nv_ck804_ops = {
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.data_xfer = ata_data_xfer,
- .irq_handler = nv_ck804_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -427,23 +433,22 @@ static const struct ata_port_operations nv_ck804_ops = {
static const struct ata_port_operations nv_adma_ops = {
.port_disable = ata_port_disable,
.tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
+ .tf_read = nv_adma_tf_read,
.check_atapi_dma = nv_adma_check_atapi_dma,
.exec_command = ata_exec_command,
.check_status = ata_check_status,
.dev_select = ata_std_dev_select,
- .bmdma_setup = nv_adma_bmdma_setup,
- .bmdma_start = nv_adma_bmdma_start,
- .bmdma_stop = nv_adma_bmdma_stop,
- .bmdma_status = nv_adma_bmdma_status,
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
.qc_prep = nv_adma_qc_prep,
.qc_issue = nv_adma_qc_issue,
.freeze = nv_ck804_freeze,
.thaw = nv_ck804_thaw,
.error_handler = nv_adma_error_handler,
- .post_internal_cmd = nv_adma_bmdma_stop,
+ .post_internal_cmd = nv_adma_post_internal_cmd,
.data_xfer = ata_data_xfer,
- .irq_handler = nv_adma_interrupt,
.irq_clear = nv_adma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -451,8 +456,10 @@ static const struct ata_port_operations nv_adma_ops = {
.scr_write = nv_scr_write,
.port_start = nv_adma_port_start,
.port_stop = nv_adma_port_stop,
+#ifdef CONFIG_PM
.port_suspend = nv_adma_port_suspend,
.port_resume = nv_adma_port_resume,
+#endif
.host_stop = nv_adma_host_stop,
};
@@ -466,6 +473,7 @@ static struct ata_port_info nv_port_info[] = {
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_generic_ops,
+ .irq_handler = nv_generic_interrupt,
},
/* nforce2/3 */
{
@@ -476,6 +484,7 @@ static struct ata_port_info nv_port_info[] = {
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_nf2_ops,
+ .irq_handler = nv_nf2_interrupt,
},
/* ck804 */
{
@@ -486,6 +495,7 @@ static struct ata_port_info nv_port_info[] = {
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_ck804_ops,
+ .irq_handler = nv_ck804_interrupt,
},
/* ADMA */
{
@@ -497,6 +507,7 @@ static struct ata_port_info nv_port_info[] = {
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_adma_ops,
+ .irq_handler = nv_adma_interrupt,
},
};
@@ -657,34 +668,47 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
}
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ /* Since commands where a result TF is requested are not
+ executed in ADMA mode, the only time this function will be called
+ in ADMA mode will be if a command fails. In this case we
+ don't care about going into register mode with ADMA commands
+ pending, as the commands will all shortly be aborted anyway. */
+ nv_adma_register_mode(ap);
+
+ ata_tf_read(ap, tf);
+}
+
static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
{
unsigned int idx = 0;
- cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device | WNB);
-
- if ((tf->flags & ATA_TFLAG_LBA48) == 0) {
- cpb[idx++] = cpu_to_le16(IGN);
- cpb[idx++] = cpu_to_le16(IGN);
- cpb[idx++] = cpu_to_le16(IGN);
- cpb[idx++] = cpu_to_le16(IGN);
- cpb[idx++] = cpu_to_le16(IGN);
+ if(tf->flags & ATA_TFLAG_ISADDR) {
+ if (tf->flags & ATA_TFLAG_LBA48) {
+ cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature | WNB);
+ cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah);
+ cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature);
+ } else
+ cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature | WNB);
+
+ cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam);
+ cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah);
}
- else {
- cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature);
- cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah);
- }
- cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature);
- cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam);
- cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah);
+
+ if(tf->flags & ATA_TFLAG_DEVICE)
+ cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device);
cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND);
+ while(idx < 12)
+ cpb[idx++] = cpu_to_le16(IGN);
+
return idx;
}
@@ -727,20 +751,23 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
return 1;
}
- if (flags & NV_CPB_RESP_DONE) {
+ if (likely(flags & NV_CPB_RESP_DONE)) {
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
VPRINTK("CPB flags done, flags=0x%x\n", flags);
if (likely(qc)) {
- /* Grab the ATA port status for non-NCQ commands.
- For NCQ commands the current status may have nothing to do with
- the command just completed. */
- if (qc->tf.protocol != ATA_PROT_NCQ) {
- u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
- qc->err_mask |= ac_err_mask(ata_status);
- }
- DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
- qc->err_mask);
+ DPRINTK("Completing qc from tag %d\n",cpb_num);
ata_qc_complete(qc);
+ } else {
+ struct ata_eh_info *ehi = &ap->eh_info;
+ /* Notifier bits set without a command may indicate the drive
+ is misbehaving. Raise host state machine violation on this
+ condition. */
+ ata_port_printk(ap, KERN_ERR, "notifier for tag %d with no command?\n",
+ cpb_num);
+ ehi->err_mask |= AC_ERR_HSM;
+ ehi->action |= ATA_EH_SOFTRESET;
+ ata_port_freeze(ap);
+ return 1;
}
}
return 0;
@@ -852,22 +879,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
if (status & (NV_ADMA_STAT_DONE |
NV_ADMA_STAT_CPBERR)) {
- /** Check CPBs for completed commands */
+ u32 check_commands;
+ int pos, error = 0;
- if (ata_tag_valid(ap->active_tag)) {
- /* Non-NCQ command */
- nv_adma_check_cpb(ap, ap->active_tag,
- notifier_error & (1 << ap->active_tag));
- } else {
- int pos, error = 0;
- u32 active = ap->sactive;
-
- while ((pos = ffs(active)) && !error) {
- pos--;
- error = nv_adma_check_cpb(ap, pos,
- notifier_error & (1 << pos) );
- active &= ~(1 << pos );
- }
+ if(ata_tag_valid(ap->active_tag))
+ check_commands = 1 << ap->active_tag;
+ else
+ check_commands = ap->sactive;
+
+ /** Check CPBs for completed commands */
+ while ((pos = ffs(check_commands)) && !error) {
+ pos--;
+ error = nv_adma_check_cpb(ap, pos,
+ notifier_error & (1 << pos) );
+ check_commands &= ~(1 << pos );
}
}
}
@@ -905,73 +930,12 @@ static void nv_adma_irq_clear(struct ata_port *ap)
iowrite8(ioread8(dma_stat_addr), dma_stat_addr);
}
-static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
+static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- struct nv_adma_port_priv *pp = ap->private_data;
- u8 dmactl;
-
- if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
- WARN_ON(1);
- return;
- }
-
- /* load PRD table addr. */
- iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
- /* specify data direction, triple-check start bit is clear */
- dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
- if (!rw)
- dmactl |= ATA_DMA_WR;
-
- iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* issue r/w command */
- ata_exec_command(ap, &qc->tf);
-}
-
-static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct nv_adma_port_priv *pp = ap->private_data;
- u8 dmactl;
-
- if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
- WARN_ON(1);
- return;
- }
-
- /* start host DMA transaction */
- dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- iowrite8(dmactl | ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-}
-
-static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct nv_adma_port_priv *pp = ap->private_data;
-
- if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
- return;
-
- /* clear start/stop bit */
- iowrite8(ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
- ata_altstatus(ap); /* dummy read */
-}
-
-static u8 nv_adma_bmdma_status(struct ata_port *ap)
-{
- struct nv_adma_port_priv *pp = ap->private_data;
-
- WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
- return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ if(pp->flags & NV_ADMA_PORT_REGISTER_MODE)
+ ata_bmdma_post_internal_cmd(qc);
}
static int nv_adma_port_start(struct ata_port *ap)
@@ -1040,14 +1004,15 @@ static int nv_adma_port_start(struct ata_port *ap)
/* clear GO for register mode, enable interrupt */
tmp = readw(mmio + NV_ADMA_CTL);
- writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
+ writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
+ NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
udelay(1);
writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
return 0;
}
@@ -1061,6 +1026,7 @@ static void nv_adma_port_stop(struct ata_port *ap)
writew(0, mmio + NV_ADMA_CTL);
}
+#ifdef CONFIG_PM
static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg)
{
struct nv_adma_port_priv *pp = ap->private_data;
@@ -1099,26 +1065,28 @@ static int nv_adma_port_resume(struct ata_port *ap)
/* clear GO for register mode, enable interrupt */
tmp = readw(mmio + NV_ADMA_CTL);
- writew((tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
+ writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
+ NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
udelay(1);
writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
return 0;
}
+#endif
-static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
+static void nv_adma_setup_port(struct ata_port *ap)
{
- void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR];
- struct ata_ioports *ioport = &probe_ent->port[port];
+ void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
+ struct ata_ioports *ioport = &ap->ioaddr;
VPRINTK("ENTER\n");
- mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
+ mmio += NV_ADMA_PORT + ap->port_no * NV_ADMA_PORT_SIZE;
ioport->cmd_addr = mmio;
ioport->data_addr = mmio + (ATA_REG_DATA * 4);
@@ -1135,9 +1103,9 @@ static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int por
ioport->ctl_addr = mmio + 0x20;
}
-static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
+static int nv_adma_host_init(struct ata_host *host)
{
- struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+ struct pci_dev *pdev = to_pci_dev(host->dev);
unsigned int i;
u32 tmp32;
@@ -1152,8 +1120,8 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
- for (i = 0; i < probe_ent->n_ports; i++)
- nv_adma_setup_port(probe_ent, i);
+ for (i = 0; i < host->n_ports; i++)
+ nv_adma_setup_port(host->ports[i]);
return 0;
}
@@ -1163,11 +1131,7 @@ static void nv_adma_fill_aprd(struct ata_queued_cmd *qc,
int idx,
struct nv_adma_prd *aprd)
{
- u8 flags;
-
- memset(aprd, 0, sizeof(struct nv_adma_prd));
-
- flags = 0;
+ u8 flags = 0;
if (qc->tf.flags & ATA_TFLAG_WRITE)
flags |= NV_APRD_WRITE;
if (idx == qc->n_elem - 1)
@@ -1178,6 +1142,7 @@ static void nv_adma_fill_aprd(struct ata_queued_cmd *qc,
aprd->addr = cpu_to_le64(((u64)sg_dma_address(sg)));
aprd->len = cpu_to_le32(((u32)sg_dma_len(sg))); /* len in bytes */
aprd->flags = flags;
+ aprd->packet_len = 0;
}
static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
@@ -1198,6 +1163,8 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
}
if (idx > 5)
cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
+ else
+ cpb->next_aprd = cpu_to_le64(0);
}
static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
@@ -1205,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
struct nv_adma_port_priv *pp = qc->ap->private_data;
/* ADMA engine can only be used for non-ATAPI DMA commands,
- or interrupt-driven no-data commands. */
+ or interrupt-driven no-data commands, where a result taskfile
+ is not required. */
if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
- (qc->tf.flags & ATA_TFLAG_POLLING))
+ (qc->tf.flags & ATA_TFLAG_POLLING) ||
+ (qc->flags & ATA_QCFLAG_RESULT_TF))
return 1;
if((qc->flags & ATA_QCFLAG_DMAMAP) ||
@@ -1230,7 +1199,10 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
return;
}
- memset(cpb, 0, sizeof(struct nv_adma_cpb));
+ cpb->resp_flags = NV_CPB_RESP_DONE;
+ wmb();
+ cpb->ctl_flags = 0;
+ wmb();
cpb->len = 3;
cpb->tag = qc->tag;
@@ -1254,12 +1226,15 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
finished filling in all of the contents */
wmb();
cpb->ctl_flags = ctl_flags;
+ wmb();
+ cpb->resp_flags = 0;
}
static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
{
struct nv_adma_port_priv *pp = qc->ap->private_data;
void __iomem *mmio = pp->ctl_block;
+ int curr_ncq = (qc->tf.protocol == ATA_PROT_NCQ);
VPRINTK("ENTER\n");
@@ -1274,6 +1249,14 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
/* write append register, command tag in lower 8 bits
and (number of cpbs to append -1) in top 8 bits */
wmb();
+
+ if(curr_ncq != pp->last_issue_ncq) {
+ /* Seems to need some delay before switching between NCQ and non-NCQ
+ commands, else we get command timeouts and such. */
+ udelay(20);
+ pp->last_issue_ncq = curr_ncq;
+ }
+
writew(qc->tag, mmio + NV_ADMA_APPEND);
DPRINTK("Issued tag %u\n",qc->tag);
@@ -1447,6 +1430,30 @@ static void nv_adma_error_handler(struct ata_port *ap)
int i;
u16 tmp;
+ if(ata_tag_valid(ap->active_tag) || ap->sactive) {
+ u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
+ u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+ u32 gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
+ u32 status = readw(mmio + NV_ADMA_STAT);
+ u8 cpb_count = readb(mmio + NV_ADMA_CPB_COUNT);
+ u8 next_cpb_idx = readb(mmio + NV_ADMA_NEXT_CPB_IDX);
+
+ ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
+ "notifier_error 0x%X gen_ctl 0x%X status 0x%X "
+ "next cpb count 0x%X next cpb idx 0x%x\n",
+ notifier, notifier_error, gen_ctl, status,
+ cpb_count, next_cpb_idx);
+
+ for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
+ struct nv_adma_cpb *cpb = &pp->cpb[i];
+ if( (ata_tag_valid(ap->active_tag) && i == ap->active_tag) ||
+ ap->sactive & (1 << i) )
+ ata_port_printk(ap, KERN_ERR,
+ "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
+ i, cpb->ctl_flags, cpb->resp_flags);
+ }
+ }
+
/* Push us back into port register mode for error handling. */
nv_adma_register_mode(ap);
@@ -1460,10 +1467,10 @@ static void nv_adma_error_handler(struct ata_port *ap)
/* Reset channel */
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
udelay(1);
writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
- readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ readw( mmio + NV_ADMA_CTL ); /* flush posted write */
}
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
@@ -1473,14 +1480,13 @@ static void nv_adma_error_handler(struct ata_port *ap)
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
- struct ata_port_info *ppi[2];
- struct ata_probe_ent *probe_ent;
+ const struct ata_port_info *ppi[2];
+ struct ata_host *host;
struct nv_host_priv *hpriv;
int rc;
u32 bar;
void __iomem *base;
unsigned long type = ent->driver_data;
- int mask_set = 0;
// Make sure this is a SATA controller by counting the number of bars
// (NVIDIA SATA controllers will always have six bars). Otherwise,
@@ -1496,50 +1502,38 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pcim_pin_device(pdev);
- return rc;
- }
-
- if(type >= CK804 && adma_enabled) {
+ /* determine type and allocate host */
+ if (type >= CK804 && adma_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
type = ADMA;
- if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
- !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
- mask_set = 1;
- }
-
- if(!mask_set) {
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
}
- rc = -ENOMEM;
+ ppi[0] = ppi[1] = &nv_port_info[type];
+ rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ if (rc)
+ return rc;
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
+ hpriv->type = type;
+ host->private_data = hpriv;
- ppi[0] = ppi[1] = &nv_port_info[type];
- probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent)
- return -ENOMEM;
-
- if (!pcim_iomap(pdev, NV_MMIO_BAR, 0))
- return -EIO;
- probe_ent->iomap = pcim_iomap_table(pdev);
+ /* set 64bit dma masks, may fail */
+ if (type == ADMA) {
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0)
+ pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ }
- probe_ent->private_data = hpriv;
- hpriv->type = type;
+ /* request and iomap NV_MMIO_BAR */
+ rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME);
+ if (rc)
+ return rc;
- base = probe_ent->iomap[NV_MMIO_BAR];
- probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
- probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
+ /* configure SCR access */
+ base = host->iomap[NV_MMIO_BAR];
+ host->ports[0]->ioaddr.scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
+ host->ports[1]->ioaddr.scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
/* enable SATA space for CK804 */
if (type >= CK804) {
@@ -1550,20 +1544,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
}
- pci_set_master(pdev);
-
+ /* init ADMA */
if (type == ADMA) {
- rc = nv_adma_host_init(probe_ent);
+ rc = nv_adma_host_init(host);
if (rc)
return rc;
}
- rc = ata_device_add(probe_ent);
- if (rc != NV_PORTS)
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler,
+ IRQF_SHARED, ppi[0]->sht);
}
static void nv_remove_one (struct pci_dev *pdev)
@@ -1575,6 +1565,7 @@ static void nv_remove_one (struct pci_dev *pdev)
kfree(hpriv);
}
+#ifdef CONFIG_PM
static int nv_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
@@ -1622,6 +1613,7 @@ static int nv_pci_device_resume(struct pci_dev *pdev)
return 0;
}
+#endif
static void nv_ck804_host_stop(struct ata_host *host)
{
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index cf9ed8c39301..f56549b90aa6 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -45,10 +45,11 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
-#define DRV_VERSION "1.05"
+#define DRV_VERSION "2.05"
enum {
+ PDC_MAX_PORTS = 4,
PDC_MMIO_BAR = 3,
/* register offsets */
@@ -70,14 +71,31 @@ enum {
PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
- PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
- (1<<8) | (1<<9) | (1<<10),
+ /* PDC_GLOBAL_CTL bit definitions */
+ PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */
+ PDC_SH_ERR = (1 << 9), /* PCI error while loading S/G table */
+ PDC_DH_ERR = (1 << 10), /* PCI error while loading data */
+ PDC2_HTO_ERR = (1 << 12), /* host bus timeout */
+ PDC2_ATA_HBA_ERR = (1 << 13), /* error during SATA DATA FIS transmission */
+ PDC2_ATA_DMA_CNT_ERR = (1 << 14), /* DMA DATA FIS size differs from S/G count */
+ PDC_OVERRUN_ERR = (1 << 19), /* S/G byte count larger than HD requires */
+ PDC_UNDERRUN_ERR = (1 << 20), /* S/G byte count less than HD requires */
+ PDC_DRIVE_ERR = (1 << 21), /* drive error */
+ PDC_PCI_SYS_ERR = (1 << 22), /* PCI system error */
+ PDC1_PCI_PARITY_ERR = (1 << 23), /* PCI parity error (from SATA150 driver) */
+ PDC1_ERR_MASK = PDC1_PCI_PARITY_ERR,
+ PDC2_ERR_MASK = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR,
+ PDC_ERR_MASK = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR
+ | PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR
+ | PDC1_ERR_MASK | PDC2_ERR_MASK),
board_2037x = 0, /* FastTrak S150 TX2plus */
- board_20319 = 1, /* FastTrak S150 TX4 */
- board_20619 = 2, /* FastTrak TX4000 */
- board_2057x = 3, /* SATAII150 Tx2plus */
- board_40518 = 4, /* SATAII150 Tx4 */
+ board_2037x_pata = 1, /* FastTrak S150 TX2plus PATA port */
+ board_20319 = 2, /* FastTrak S150 TX4 */
+ board_20619 = 3, /* FastTrak TX4000 */
+ board_2057x = 4, /* SATAII150 Tx2plus */
+ board_2057x_pata = 5, /* SATAII150 Tx2plus */
+ board_40518 = 6, /* SATAII150 Tx4 */
PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
@@ -100,8 +118,10 @@ enum {
ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
- /* hp->flags bits */
- PDC_FLAG_GEN_II = (1 << 0),
+ /* ap->flags bits */
+ PDC_FLAG_GEN_II = (1 << 24),
+ PDC_FLAG_SATA_PATA = (1 << 25), /* supports SATA + PATA */
+ PDC_FLAG_4_PORTS = (1 << 26), /* 4 ports */
};
@@ -110,28 +130,25 @@ struct pdc_port_priv {
dma_addr_t pkt_dma;
};
-struct pdc_host_priv {
- unsigned long flags;
- unsigned long port_flags[ATA_MAX_PORTS];
-};
-
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
-static int pdc_port_start(struct ata_port *ap);
+static int pdc_common_port_start(struct ata_port *ap);
+static int pdc_sata_port_start(struct ata_port *ap);
static void pdc_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
-static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc);
+static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
static void pdc_irq_clear(struct ata_port *ap);
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
static void pdc_freeze(struct ata_port *ap);
static void pdc_thaw(struct ata_port *ap);
-static void pdc_error_handler(struct ata_port *ap);
+static void pdc_pata_error_handler(struct ata_port *ap);
+static void pdc_sata_error_handler(struct ata_port *ap);
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
-
+static int pdc_pata_cable_detect(struct ata_port *ap);
+static int pdc_sata_cable_detect(struct ata_port *ap);
static struct scsi_host_template pdc_ata_sht = {
.module = THIS_MODULE,
@@ -164,17 +181,17 @@ static const struct ata_port_operations pdc_sata_ops = {
.qc_issue = pdc_qc_issue_prot,
.freeze = pdc_freeze,
.thaw = pdc_thaw,
- .error_handler = pdc_error_handler,
+ .error_handler = pdc_sata_error_handler,
.post_internal_cmd = pdc_post_internal_cmd,
+ .cable_detect = pdc_sata_cable_detect,
.data_xfer = ata_data_xfer,
- .irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
.scr_read = pdc_sata_scr_read,
.scr_write = pdc_sata_scr_write,
- .port_start = pdc_port_start,
+ .port_start = pdc_sata_port_start,
};
/* First-generation chips need a more restrictive ->check_atapi_dma op */
@@ -185,23 +202,23 @@ static const struct ata_port_operations pdc_old_sata_ops = {
.check_status = ata_check_status,
.exec_command = pdc_exec_command_mmio,
.dev_select = ata_std_dev_select,
- .check_atapi_dma = pdc_old_check_atapi_dma,
+ .check_atapi_dma = pdc_old_sata_check_atapi_dma,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
.freeze = pdc_freeze,
.thaw = pdc_thaw,
- .error_handler = pdc_error_handler,
+ .error_handler = pdc_sata_error_handler,
.post_internal_cmd = pdc_post_internal_cmd,
+ .cable_detect = pdc_sata_cable_detect,
.data_xfer = ata_data_xfer,
- .irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
.scr_read = pdc_sata_scr_read,
.scr_write = pdc_sata_scr_write,
- .port_start = pdc_port_start,
+ .port_start = pdc_sata_port_start,
};
static const struct ata_port_operations pdc_pata_ops = {
@@ -217,31 +234,41 @@ static const struct ata_port_operations pdc_pata_ops = {
.qc_issue = pdc_qc_issue_prot,
.freeze = pdc_freeze,
.thaw = pdc_thaw,
- .error_handler = pdc_error_handler,
+ .error_handler = pdc_pata_error_handler,
+ .post_internal_cmd = pdc_post_internal_cmd,
+ .cable_detect = pdc_pata_cable_detect,
.data_xfer = ata_data_xfer,
- .irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
- .port_start = pdc_port_start,
+ .port_start = pdc_common_port_start,
};
static const struct ata_port_info pdc_port_info[] = {
/* board_2037x */
{
- .sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+ PDC_FLAG_SATA_PATA,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &pdc_old_sata_ops,
},
+ /* board_2037x_pata */
+ {
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &pdc_pata_ops,
+ },
+
/* board_20319 */
{
- .sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+ PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -250,8 +277,8 @@ static const struct ata_port_info pdc_port_info[] = {
/* board_20619 */
{
- .sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
+ PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -260,18 +287,28 @@ static const struct ata_port_info pdc_port_info[] = {
/* board_2057x */
{
- .sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+ PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &pdc_sata_ops,
},
+ /* board_2057x_pata */
+ {
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+ PDC_FLAG_GEN_II,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &pdc_pata_ops,
+ },
+
/* board_40518 */
{
- .sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+ PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -312,18 +349,12 @@ static struct pci_driver pdc_ata_pci_driver = {
};
-static int pdc_port_start(struct ata_port *ap)
+static int pdc_common_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
- struct pdc_host_priv *hp = ap->host->private_data;
struct pdc_port_priv *pp;
int rc;
- /* fix up port flags and cable type for SATA+PATA chips */
- ap->flags |= hp->port_flags[ap->port_no];
- if (ap->flags & ATA_FLAG_SATA)
- ap->cbl = ATA_CBL_SATA;
-
rc = ata_port_start(ap);
if (rc)
return rc;
@@ -338,8 +369,19 @@ static int pdc_port_start(struct ata_port *ap)
ap->private_data = pp;
+ return 0;
+}
+
+static int pdc_sata_port_start(struct ata_port *ap)
+{
+ int rc;
+
+ rc = pdc_common_port_start(ap);
+ if (rc)
+ return rc;
+
/* fix up PHYMODE4 align timing */
- if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
+ if (ap->flags & PDC_FLAG_GEN_II) {
void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
unsigned int tmp;
@@ -373,23 +415,25 @@ static void pdc_reset_port(struct ata_port *ap)
readl(mmio); /* flush */
}
-static void pdc_pata_cbl_detect(struct ata_port *ap)
+static int pdc_pata_cable_detect(struct ata_port *ap)
{
u8 tmp;
void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
tmp = readb(mmio);
+ if (tmp & 0x01)
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
+}
- if (tmp & 0x01) {
- ap->cbl = ATA_CBL_PATA40;
- ap->udma_mask &= ATA_UDMA_MASK_40C;
- } else
- ap->cbl = ATA_CBL_PATA80;
+static int pdc_sata_cable_detect(struct ata_port *ap)
+{
+ return ATA_CBL_SATA;
}
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
+ if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -398,7 +442,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
u32 val)
{
- if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
+ if (sc_reg > SCR_CONTROL)
return;
writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -554,52 +598,79 @@ static void pdc_thaw(struct ata_port *ap)
readl(mmio + PDC_CTLSTAT); /* flush */
}
-static int pdc_pre_reset(struct ata_port *ap)
+static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
{
- if (!sata_scr_valid(ap))
- pdc_pata_cbl_detect(ap);
- return ata_std_prereset(ap);
-}
-
-static void pdc_error_handler(struct ata_port *ap)
-{
- ata_reset_fn_t hardreset;
-
if (!(ap->pflags & ATA_PFLAG_FROZEN))
pdc_reset_port(ap);
- hardreset = NULL;
- if (sata_scr_valid(ap))
- hardreset = sata_std_hardreset;
-
/* perform recovery */
- ata_do_eh(ap, pdc_pre_reset, ata_std_softreset, hardreset,
+ ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
ata_std_postreset);
}
+static void pdc_pata_error_handler(struct ata_port *ap)
+{
+ pdc_common_error_handler(ap, NULL);
+}
+
+static void pdc_sata_error_handler(struct ata_port *ap)
+{
+ pdc_common_error_handler(ap, sata_std_hardreset);
+}
+
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- if (qc->flags & ATA_QCFLAG_FAILED)
- qc->err_mask |= AC_ERR_OTHER;
-
/* make DMA engine forget about the failed command */
- if (qc->err_mask)
+ if (qc->flags & ATA_QCFLAG_FAILED)
pdc_reset_port(ap);
}
+static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
+ u32 port_status, u32 err_mask)
+{
+ struct ata_eh_info *ehi = &ap->eh_info;
+ unsigned int ac_err_mask = 0;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "port_status 0x%08x", port_status);
+ port_status &= err_mask;
+
+ if (port_status & PDC_DRIVE_ERR)
+ ac_err_mask |= AC_ERR_DEV;
+ if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR))
+ ac_err_mask |= AC_ERR_HSM;
+ if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR))
+ ac_err_mask |= AC_ERR_ATA_BUS;
+ if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR
+ | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR))
+ ac_err_mask |= AC_ERR_HOST_BUS;
+
+ if (sata_scr_valid(ap))
+ ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR);
+
+ qc->err_mask |= ac_err_mask;
+
+ pdc_reset_port(ap);
+}
+
static inline unsigned int pdc_host_intr( struct ata_port *ap,
struct ata_queued_cmd *qc)
{
unsigned int handled = 0;
- u32 tmp;
- void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ u32 port_status, err_mask;
- tmp = readl(mmio);
- if (tmp & PDC_ERR_MASK) {
- qc->err_mask |= AC_ERR_DEV;
- pdc_reset_port(ap);
+ err_mask = PDC_ERR_MASK;
+ if (ap->flags & PDC_FLAG_GEN_II)
+ err_mask &= ~PDC1_ERR_MASK;
+ else
+ err_mask &= ~PDC2_ERR_MASK;
+ port_status = readl(port_mmio + PDC_GLOBAL_CTL);
+ if (unlikely(port_status & err_mask)) {
+ pdc_error_intr(ap, qc, port_status, err_mask);
+ return 1;
}
switch (qc->tf.protocol) {
@@ -766,42 +837,40 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
return pio;
}
-static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc)
+static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
-
/* First generation chips cannot use ATAPI DMA on SATA ports */
- if (sata_scr_valid(ap))
- return 1;
- return pdc_check_atapi_dma(qc);
+ return 1;
}
-static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
+static void pdc_ata_setup_port(struct ata_port *ap,
+ void __iomem *base, void __iomem *scr_addr)
{
- port->cmd_addr = base;
- port->data_addr = base;
- port->feature_addr =
- port->error_addr = base + 0x4;
- port->nsect_addr = base + 0x8;
- port->lbal_addr = base + 0xc;
- port->lbam_addr = base + 0x10;
- port->lbah_addr = base + 0x14;
- port->device_addr = base + 0x18;
- port->command_addr =
- port->status_addr = base + 0x1c;
- port->altstatus_addr =
- port->ctl_addr = base + 0x38;
+ ap->ioaddr.cmd_addr = base;
+ ap->ioaddr.data_addr = base;
+ ap->ioaddr.feature_addr =
+ ap->ioaddr.error_addr = base + 0x4;
+ ap->ioaddr.nsect_addr = base + 0x8;
+ ap->ioaddr.lbal_addr = base + 0xc;
+ ap->ioaddr.lbam_addr = base + 0x10;
+ ap->ioaddr.lbah_addr = base + 0x14;
+ ap->ioaddr.device_addr = base + 0x18;
+ ap->ioaddr.command_addr =
+ ap->ioaddr.status_addr = base + 0x1c;
+ ap->ioaddr.altstatus_addr =
+ ap->ioaddr.ctl_addr = base + 0x38;
+ ap->ioaddr.scr_addr = scr_addr;
}
-static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+static void pdc_host_init(struct ata_host *host)
{
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
- struct pdc_host_priv *hp = pe->private_data;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+ int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II;
int hotplug_offset;
u32 tmp;
- if (hp->flags & PDC_FLAG_GEN_II)
+ if (is_gen2)
hotplug_offset = PDC2_SATA_PLUG_CSR;
else
hotplug_offset = PDC_SATA_PLUG_CSR;
@@ -815,7 +884,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
/* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
tmp = readl(mmio + PDC_FLASH_CTL);
tmp |= 0x02000; /* bit 13 (enable bmr burst) */
- if (!(hp->flags & PDC_FLAG_GEN_II))
+ if (!is_gen2)
tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
writel(tmp, mmio + PDC_FLASH_CTL);
@@ -828,7 +897,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
writel(tmp | 0xff0000, mmio + hotplug_offset);
/* don't initialise TBG or SLEW on 2nd generation chips */
- if (hp->flags & PDC_FLAG_GEN_II)
+ if (is_gen2)
return;
/* reduce TBG clock to 133 Mhz. */
@@ -850,16 +919,16 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent;
- struct pdc_host_priv *hp;
+ const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
+ const struct ata_port_info *ppi[PDC_MAX_PORTS];
+ struct ata_host *host;
void __iomem *base;
- unsigned int board_idx = (unsigned int) ent->driver_data;
- int rc;
- u8 tmp;
+ int n_ports, i, rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* enable and acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -869,100 +938,49 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
pcim_pin_device(pdev);
if (rc)
return rc;
+ base = pcim_iomap_table(pdev)[PDC_MMIO_BAR];
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
-
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL);
- if (hp == NULL)
- return -ENOMEM;
-
- probe_ent->private_data = hp;
+ /* determine port configuration and setup host */
+ n_ports = 2;
+ if (pi->flags & PDC_FLAG_4_PORTS)
+ n_ports = 4;
+ for (i = 0; i < n_ports; i++)
+ ppi[i] = pi;
- probe_ent->sht = pdc_port_info[board_idx].sht;
- probe_ent->port_flags = pdc_port_info[board_idx].flags;
- probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
- probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
- probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- base = probe_ent->iomap[PDC_MMIO_BAR];
-
- pdc_ata_setup_port(&probe_ent->port[0], base + 0x200);
- pdc_ata_setup_port(&probe_ent->port[1], base + 0x280);
-
- probe_ent->port[0].scr_addr = base + 0x400;
- probe_ent->port[1].scr_addr = base + 0x500;
-
- /* notice 4-port boards */
- switch (board_idx) {
- case board_40518:
- hp->flags |= PDC_FLAG_GEN_II;
- /* Fall through */
- case board_20319:
- probe_ent->n_ports = 4;
-
- pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
- pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
-
- probe_ent->port[2].scr_addr = base + 0x600;
- probe_ent->port[3].scr_addr = base + 0x700;
- break;
- case board_2057x:
- hp->flags |= PDC_FLAG_GEN_II;
- /* Fall through */
- case board_2037x:
- /* TX2plus boards also have a PATA port */
- tmp = readb(base + PDC_FLASH_CTL+1);
+ if (pi->flags & PDC_FLAG_SATA_PATA) {
+ u8 tmp = readb(base + PDC_FLASH_CTL+1);
if (!(tmp & 0x80)) {
- probe_ent->n_ports = 3;
- pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
- hp->port_flags[2] = ATA_FLAG_SLAVE_POSS;
- printk(KERN_INFO DRV_NAME " PATA port found\n");
- } else
- probe_ent->n_ports = 2;
- hp->port_flags[0] = ATA_FLAG_SATA;
- hp->port_flags[1] = ATA_FLAG_SATA;
- break;
- case board_20619:
- probe_ent->n_ports = 4;
-
- pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
- pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
+ ppi[n_ports++] = pi + 1;
+ dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
+ }
+ }
- probe_ent->port[2].scr_addr = base + 0x600;
- probe_ent->port[3].scr_addr = base + 0x700;
- break;
- default:
- BUG();
- break;
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ if (!host) {
+ dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
+ return -ENOMEM;
}
+ host->iomap = pcim_iomap_table(pdev);
- pci_set_master(pdev);
+ for (i = 0; i < host->n_ports; i++)
+ pdc_ata_setup_port(host->ports[i],
+ base + 0x200 + i * 0x80,
+ base + 0x400 + i * 0x100);
/* initialize adapter */
- pdc_host_init(board_idx, probe_ent);
+ pdc_host_init(host);
- if (!ata_device_add(probe_ent))
- return -ENODEV;
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ /* start host, request IRQ and attach */
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, pdc_interrupt, IRQF_SHARED,
+ &pdc_ata_sht);
}
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 6097d8f2a0c0..f5a05de0093d 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -39,7 +39,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_qstor"
-#define DRV_VERSION "0.06"
+#define DRV_VERSION "0.07"
enum {
QS_MMIO_BAR = 4,
@@ -114,7 +114,6 @@ struct qs_port_priv {
static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t qs_intr (int irq, void *dev_instance);
static int qs_port_start(struct ata_port *ap);
static void qs_host_stop(struct ata_host *host);
static void qs_phy_reset(struct ata_port *ap);
@@ -158,7 +157,6 @@ static const struct ata_port_operations qs_ata_ops = {
.qc_issue = qs_qc_issue,
.data_xfer = ata_data_xfer,
.eng_timeout = qs_eng_timeout,
- .irq_handler = qs_intr,
.irq_clear = qs_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -173,7 +171,6 @@ static const struct ata_port_operations qs_ata_ops = {
static const struct ata_port_info qs_port_info[] = {
/* board_2068_idx */
{
- .sht = &qs_ata_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SATA_RESET |
//FIXME ATA_FLAG_SRST |
@@ -446,7 +443,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
- ap->id, qc->tf.protocol, status);
+ ap->print_id, qc->tf.protocol, status);
/* complete taskfile transaction */
pp->state = qs_state_idle;
@@ -530,16 +527,16 @@ static void qs_host_stop(struct ata_host *host)
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
}
-static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+static void qs_host_init(struct ata_host *host, unsigned int chip_id)
{
- void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
+ void __iomem *mmio_base = host->iomap[QS_MMIO_BAR];
unsigned int port_no;
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
/* reset each channel in turn */
- for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+ for (port_no = 0; port_no < host->n_ports; ++port_no) {
u8 __iomem *chan = mmio_base + (port_no * 0x4000);
writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
@@ -547,7 +544,7 @@ static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
}
writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
- for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+ for (port_no = 0; port_no < host->n_ports; ++port_no) {
u8 __iomem *chan = mmio_base + (port_no * 0x4000);
/* set FIFO depths to same settings as Windows driver */
writew(32, chan + QS_CFC_HUFT);
@@ -607,14 +604,20 @@ static int qs_ata_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent;
- void __iomem * const *iomap;
unsigned int board_idx = (unsigned int) ent->driver_data;
+ const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL };
+ struct ata_host *host;
int rc, port_no;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* alloc host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -625,47 +628,24 @@ static int qs_ata_init_one(struct pci_dev *pdev,
rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
if (rc)
return rc;
- iomap = pcim_iomap_table(pdev);
+ host->iomap = pcim_iomap_table(pdev);
- rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
+ rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]);
if (rc)
return rc;
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- probe_ent->sht = qs_port_info[board_idx].sht;
- probe_ent->port_flags = qs_port_info[board_idx].flags;
- probe_ent->pio_mask = qs_port_info[board_idx].pio_mask;
- probe_ent->mwdma_mask = qs_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = qs_port_info[board_idx].udma_mask;
- probe_ent->port_ops = qs_port_info[board_idx].port_ops;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = iomap;
- probe_ent->n_ports = QS_PORTS;
-
- for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+ for (port_no = 0; port_no < host->n_ports; ++port_no) {
void __iomem *chan =
- probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
- qs_ata_setup_port(&probe_ent->port[port_no], chan);
+ host->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
+ qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan);
}
- pci_set_master(pdev);
-
/* initialize adapter */
- qs_host_init(board_idx, probe_ent);
+ qs_host_init(host, board_idx);
- if (ata_device_add(probe_ent) != QS_PORTS)
- return -EIO;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED,
+ &qs_ata_sht);
}
static int __init qs_ata_init(void)
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index dca3d3749f06..0a1e417f309c 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_sil"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.2"
enum {
SIL_MMIO_BAR = 5,
@@ -114,11 +114,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM
static int sil_pci_device_resume(struct pci_dev *pdev);
#endif
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
+static void sil_dev_config(struct ata_device *dev);
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-static void sil_post_set_mode (struct ata_port *ap);
-static irqreturn_t sil_interrupt(int irq, void *dev_instance);
+static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
static void sil_freeze(struct ata_port *ap);
static void sil_thaw(struct ata_port *ap);
@@ -183,8 +182,10 @@ static struct scsi_host_template sil_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations sil_ops = {
@@ -195,7 +196,7 @@ static const struct ata_port_operations sil_ops = {
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .post_set_mode = sil_post_set_mode,
+ .set_mode = sil_set_mode,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
@@ -207,7 +208,6 @@ static const struct ata_port_operations sil_ops = {
.thaw = sil_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = sil_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -219,7 +219,6 @@ static const struct ata_port_operations sil_ops = {
static const struct ata_port_info sil_port_info[] = {
/* sil_3112 */
{
- .sht = &sil_sht,
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -228,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = {
},
/* sil_3112_no_sata_irq */
{
- .sht = &sil_sht,
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
SIL_FLAG_NO_SATA_IRQ,
.pio_mask = 0x1f, /* pio0-4 */
@@ -238,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = {
},
/* sil_3512 */
{
- .sht = &sil_sht,
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -247,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = {
},
/* sil_3114 */
{
- .sht = &sil_sht,
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -295,7 +291,16 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
return cache_line;
}
-static void sil_post_set_mode (struct ata_port *ap)
+/**
+ * sil_set_mode - wrap set_mode functions
+ * @ap: port to set up
+ * @r_failed: returned device when we fail
+ *
+ * Wrap the libata method for device setup as after the setup we need
+ * to inspect the results and do some configuration work
+ */
+
+static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)
{
struct ata_host *host = ap->host;
struct ata_device *dev;
@@ -303,6 +308,11 @@ static void sil_post_set_mode (struct ata_port *ap)
void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
u32 tmp, dev_mode[2];
unsigned int i;
+ int rc;
+
+ rc = ata_do_set_mode(ap, r_failed);
+ if (rc)
+ return rc;
for (i = 0; i < 2; i++) {
dev = &ap->device[i];
@@ -321,6 +331,7 @@ static void sil_post_set_mode (struct ata_port *ap)
tmp |= (dev_mode[1] << 4);
writel(tmp, addr);
readl(addr); /* flush */
+ return 0;
}
static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
@@ -339,7 +350,7 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re
break;
}
- return 0;
+ return NULL;
}
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
@@ -386,9 +397,15 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
goto freeze;
}
- if (unlikely(!qc || qc->tf.ctl & ATA_NIEN))
+ if (unlikely(!qc))
goto freeze;
+ if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) {
+ /* this sometimes happens, just clear IRQ */
+ ata_chk_status(ap);
+ return;
+ }
+
/* Check whether we are expecting interrupt in this state */
switch (ap->hsm_task_state) {
case HSM_ST_FIRST:
@@ -513,7 +530,6 @@ static void sil_thaw(struct ata_port *ap)
/**
* sil_dev_config - Apply device/host-specific errata fixups
- * @ap: Port containing device to be examined
* @dev: Device to be examined
*
* After the IDENTIFY [PACKET] DEVICE step is complete, and a
@@ -540,8 +556,9 @@ static void sil_thaw(struct ata_port *ap)
* appreciated.
* - But then again UDMA5 is hardly anything to complain about
*/
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void sil_dev_config(struct ata_device *dev)
{
+ struct ata_port *ap = dev->ap;
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
unsigned int n, quirks = 0;
unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -575,10 +592,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
}
}
-static void sil_init_controller(struct pci_dev *pdev,
- int n_ports, unsigned long port_flags,
- void __iomem *mmio_base)
+static void sil_init_controller(struct ata_host *host)
{
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
u8 cls;
u32 tmp;
int i;
@@ -588,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev,
if (cls) {
cls >>= 3;
cls++; /* cls = (line_size/8)+1 */
- for (i = 0; i < n_ports; i++)
+ for (i = 0; i < host->n_ports; i++)
writew(cls << 8 | cls,
mmio_base + sil_port[i].fifo_cfg);
} else
@@ -596,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev,
"cache line size not set. Driver may not function\n");
/* Apply R_ERR on DMA activate FIS errata workaround */
- if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
+ if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) {
int cnt;
- for (i = 0, cnt = 0; i < n_ports; i++) {
+ for (i = 0, cnt = 0; i < host->n_ports; i++) {
tmp = readl(mmio_base + sil_port[i].sfis_cfg);
if ((tmp & 0x3) != 0x01)
continue;
@@ -612,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev,
}
}
- if (n_ports == 4) {
+ if (host->n_ports == 4) {
/* flip the magic "make 4 ports work" bit */
tmp = readl(mmio_base + sil_port[2].bmdma);
if ((tmp & SIL_INTR_STEERING) == 0)
@@ -624,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev,
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct device *dev = &pdev->dev;
- struct ata_probe_ent *probe_ent;
+ int board_id = ent->driver_data;
+ const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+ struct ata_host *host;
void __iomem *mmio_base;
- int rc;
+ int n_ports, rc;
unsigned int i;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* allocate host */
+ n_ports = 2;
+ if (board_id == sil_3114)
+ n_ports = 4;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -642,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pcim_pin_device(pdev);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
@@ -650,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
+ mmio_base = host->iomap[SIL_MMIO_BAR];
- INIT_LIST_HEAD(&probe_ent->node);
- probe_ent->dev = pci_dev_to_dev(pdev);
- probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
- probe_ent->sht = sil_port_info[ent->driver_data].sht;
- probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
- probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
- probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
- probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
-
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
-
- for (i = 0; i < probe_ent->n_ports; i++) {
- probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
- probe_ent->port[i].altstatus_addr =
- probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl;
- probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma;
- probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr;
- ata_std_ports(&probe_ent->port[i]);
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+ ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
+ ioaddr->altstatus_addr =
+ ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
+ ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
+ ioaddr->scr_addr = mmio_base + sil_port[i].scr;
+ ata_std_ports(ioaddr);
}
- sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
- mmio_base);
+ /* initialize and activate */
+ sil_init_controller(host);
pci_set_master(pdev);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED,
+ &sil_sht);
}
#ifdef CONFIG_PM
@@ -701,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev)
if (rc)
return rc;
- sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- host->iomap[SIL_MMIO_BAR]);
+ sil_init_controller(host);
ata_host_resume(host);
return 0;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index e65e8d55da3e..e6223ba667da 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -30,7 +30,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_sil24"
-#define DRV_VERSION "0.3"
+#define DRV_VERSION "0.8"
/*
* Port request block (PRB) 32 bytes
@@ -323,7 +323,7 @@ struct sil24_port_priv {
struct ata_taskfile tf; /* Cached taskfile registers */
};
-static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
+static void sil24_dev_config(struct ata_device *dev);
static u8 sil24_check_status(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void sil24_qc_prep(struct ata_queued_cmd *qc);
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
static void sil24_irq_clear(struct ata_port *ap);
-static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
static void sil24_freeze(struct ata_port *ap);
static void sil24_thaw(struct ata_port *ap);
static void sil24_error_handler(struct ata_port *ap);
@@ -346,6 +345,7 @@ static const struct pci_device_id sil24_pci_tbl[] = {
{ PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 },
{ PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
{ PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
+ { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 },
{ PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
{ PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
@@ -380,8 +380,10 @@ static struct scsi_host_template sil24_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations sil24_ops = {
@@ -398,7 +400,6 @@ static const struct ata_port_operations sil24_ops = {
.qc_prep = sil24_qc_prep,
.qc_issue = sil24_qc_issue,
- .irq_handler = sil24_interrupt,
.irq_clear = sil24_irq_clear,
.irq_on = ata_dummy_irq_on,
.irq_ack = ata_dummy_irq_ack,
@@ -421,10 +422,9 @@ static const struct ata_port_operations sil24_ops = {
#define SIL24_NPORTS2FLAG(nports) ((((unsigned)(nports) - 1) & 0x3) << 30)
#define SIL24_FLAG2NPORTS(flag) ((((flag) >> 30) & 0x3) + 1)
-static struct ata_port_info sil24_port_info[] = {
+static const struct ata_port_info sil24_port_info[] = {
/* sil_3124 */
{
- .sht = &sil24_sht,
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
SIL24_FLAG_PCIX_IRQ_WOC,
.pio_mask = 0x1f, /* pio0-4 */
@@ -434,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = {
},
/* sil_3132 */
{
- .sht = &sil24_sht,
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -443,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = {
},
/* sil_3131/sil_3531 */
{
- .sht = &sil24_sht,
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -459,9 +457,9 @@ static int sil24_tag(int tag)
return tag;
}
-static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void sil24_dev_config(struct ata_device *dev)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = dev->ap->ioaddr.cmd_addr;
if (dev->cdb_len == 16)
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -647,7 +645,6 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
struct sil24_sge *sge)
{
struct scatterlist *sg;
- unsigned int idx = 0;
ata_for_each_sg(sg, qc) {
sge->addr = cpu_to_le64(sg_dma_address(sg));
@@ -656,9 +653,7 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
sge->flags = cpu_to_le32(SGE_TRM);
else
sge->flags = 0;
-
sge++;
- idx++;
}
}
@@ -924,11 +919,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- if (qc->flags & ATA_QCFLAG_FAILED)
- qc->err_mask |= AC_ERR_OTHER;
-
/* make DMA engine forget about the failed command */
- if (qc->err_mask)
+ if (qc->flags & ATA_QCFLAG_FAILED)
sil24_init_port(ap);
}
@@ -964,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap)
return 0;
}
-static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
- unsigned long port_flags,
- void __iomem *host_base,
- void __iomem *port_base)
+static void sil24_init_controller(struct ata_host *host)
{
+ void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
+ void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
u32 tmp;
int i;
@@ -979,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
writel(0, host_base + HOST_CTRL);
/* init ports */
- for (i = 0; i < n_ports; i++) {
+ for (i = 0; i < host->n_ports; i++) {
void __iomem *port = port_base + i * PORT_REGS_SIZE;
/* Initial PHY setting */
@@ -993,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
PORT_CS_PORT_RST,
PORT_CS_PORT_RST, 10, 100);
if (tmp & PORT_CS_PORT_RST)
- dev_printk(KERN_ERR, &pdev->dev,
+ dev_printk(KERN_ERR, host->dev,
"failed to clear port RST\n");
}
/* Configure IRQ WoC */
- if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC)
+ if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
else
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
@@ -1026,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
- struct device *dev = &pdev->dev;
- unsigned int board_id = (unsigned int)ent->driver_data;
- struct ata_port_info *pinfo = &sil24_port_info[board_id];
- struct ata_probe_ent *probe_ent;
- void __iomem *host_base;
- void __iomem *port_base;
+ struct ata_port_info pi = sil24_port_info[ent->driver_data];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+ void __iomem * const *iomap;
+ struct ata_host *host;
int i, rc;
u32 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -1047,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
DRV_NAME);
if (rc)
return rc;
+ iomap = pcim_iomap_table(pdev);
- /* allocate & init probe_ent */
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- if (!probe_ent)
- return -ENOMEM;
+ /* apply workaround for completion IRQ loss on PCI-X errata */
+ if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
+ tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
+ if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
+ dev_printk(KERN_INFO, &pdev->dev,
+ "Applying completion IRQ loss on PCI-X "
+ "errata fix\n");
+ else
+ pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
+ }
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
+ /* allocate and fill host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi,
+ SIL24_FLAG2NPORTS(ppi[0]->flags));
+ if (!host)
+ return -ENOMEM;
+ host->iomap = iomap;
- probe_ent->sht = pinfo->sht;
- probe_ent->port_flags = pinfo->flags;
- probe_ent->pio_mask = pinfo->pio_mask;
- probe_ent->mwdma_mask = pinfo->mwdma_mask;
- probe_ent->udma_mask = pinfo->udma_mask;
- probe_ent->port_ops = pinfo->port_ops;
- probe_ent->n_ports = SIL24_FLAG2NPORTS(pinfo->flags);
+ for (i = 0; i < host->n_ports; i++) {
+ void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
+ host->ports[i]->ioaddr.cmd_addr = port;
+ host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
- host_base = probe_ent->iomap[SIL24_HOST_BAR];
- port_base = probe_ent->iomap[SIL24_PORT_BAR];
+ ata_std_ports(&host->ports[i]->ioaddr);
+ }
- /*
- * Configure the device
- */
+ /* configure and activate the device */
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
if (rc) {
@@ -1099,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
- /* Apply workaround for completion IRQ loss on PCI-X errata */
- if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
- tmp = readl(host_base + HOST_CTRL);
- if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
- dev_printk(KERN_INFO, &pdev->dev,
- "Applying completion IRQ loss on PCI-X "
- "errata fix\n");
- else
- probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
- }
-
- for (i = 0; i < probe_ent->n_ports; i++) {
- void __iomem *port = port_base + i * PORT_REGS_SIZE;
-
- probe_ent->port[i].cmd_addr = port;
- probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
-
- ata_std_ports(&probe_ent->port[i]);
- }
-
- sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
- host_base, port_base);
+ sil24_init_controller(host);
pci_set_master(pdev);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
+ &sil24_sht);
}
#ifdef CONFIG_PM
@@ -1136,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
- void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
int rc;
rc = ata_pci_device_do_resume(pdev);
@@ -1146,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
- sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- host_base, port_base);
+ sil24_init_controller(host);
ata_host_resume(host);
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 49c9e2bd706f..d8ee062e82fc 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -40,9 +40,8 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
-#include "libata.h"
+#include "sis.h"
-#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "sata_sis"
#define DRV_VERSION "0.7"
@@ -122,7 +121,6 @@ static const struct ata_port_operations sis_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -132,7 +130,6 @@ static const struct ata_port_operations sis_ops = {
};
static struct ata_port_info sis_port_info = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x7,
@@ -257,12 +254,13 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- int rc;
+ struct ata_port_info pi = sis_port_info;
+ const struct ata_port_info *ppi[2] = { &pi, &pi };
+ struct ata_host *host;
u32 genctl, val;
- struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
u8 pmr;
u8 port2_start = 0x20;
+ int rc;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -271,19 +269,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pcim_pin_device(pdev);
- return rc;
- }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
-
/* check and see if the SCRs are in IO space or PCI cfg space */
pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
@@ -310,7 +295,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
case 0x10:
ppi[1] = &sis_info133;
break;
-
+
case 0x30:
ppi[0] = &sis_info133;
break;
@@ -350,30 +335,26 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent)
- return -ENOMEM;
+ rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ if (rc)
+ return rc;
- if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
- void *mmio;
+ if (!(pi.flags & SIS_FLAG_CFGSCR)) {
+ void __iomem *mmio;
- mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
- if (!mmio)
- return -ENOMEM;
+ rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME);
+ if (rc)
+ return rc;
+ mmio = host->iomap[SIS_SCR_PCI_BAR];
- probe_ent->port[0].scr_addr = mmio;
- probe_ent->port[1].scr_addr = mmio + port2_start;
+ host->ports[0]->ioaddr.scr_addr = mmio;
+ host->ports[1]->ioaddr.scr_addr = mmio + port2_start;
}
pci_set_master(pdev);
pci_intx(pdev, 1);
-
- if (!ata_device_add(probe_ent))
- return -EIO;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
-
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &sis_sht);
}
static int __init sis_init(void)
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 4e4289994204..cc07aac10e8c 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -53,10 +53,12 @@
#endif /* CONFIG_PPC_OF */
#define DRV_NAME "sata_svw"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.1"
enum {
- K2_FLAG_NO_ATAPI_DMA = (1 << 29),
+ /* ap->flags bits */
+ K2_FLAG_SATA_8_PORTS = (1 << 24),
+ K2_FLAG_NO_ATAPI_DMA = (1 << 25),
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
@@ -90,17 +92,6 @@ enum {
board_svw8 = 1,
};
-static const struct k2_board_info {
- unsigned int n_ports;
- unsigned long port_flags;
-} k2_board_info[] = {
- /* board_svw4 */
- { 4, K2_FLAG_NO_ATAPI_DMA },
-
- /* board_svw8 */
- { 8, K2_FLAG_NO_ATAPI_DMA },
-};
-
static u8 k2_stat_check_status(struct ata_port *ap);
@@ -354,7 +345,6 @@ static const struct ata_port_operations k2_sata_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -363,6 +353,28 @@ static const struct ata_port_operations k2_sata_ops = {
.port_start = ata_port_start,
};
+static const struct ata_port_info k2_port_info[] = {
+ /* board_svw4 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+ .port_ops = &k2_sata_ops,
+ },
+ /* board_svw8 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
+ K2_FLAG_SATA_8_PORTS,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+ .port_ops = &k2_sata_ops,
+ },
+};
+
static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET;
@@ -386,17 +398,24 @@ static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct device *dev = &pdev->dev;
- struct ata_probe_ent *probe_ent;
+ const struct ata_port_info *ppi[] =
+ { &k2_port_info[ent->driver_data], NULL };
+ struct ata_host *host;
void __iomem *mmio_base;
- const struct k2_board_info *board_info =
- &k2_board_info[ent->driver_data];
- int rc;
- int i;
+ int n_ports, i, rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* allocate host */
+ n_ports = 4;
+ if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS)
+ n_ports = 8;
+
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ if (!host)
+ return -ENOMEM;
+
/*
* If this driver happens to only be useful on Apple's K2, then
* we should check that here as it has a normal Serverworks ID
@@ -404,6 +423,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
rc = pcim_enable_device(pdev);
if (rc)
return rc;
+
/*
* Check if we have resources mapped at all (second function may
* have been disabled by firmware)
@@ -417,6 +437,15 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
pcim_pin_device(pdev);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
+ mmio_base = host->iomap[5];
+
+ /* different controllers have different number of ports - currently 4 or 8 */
+ /* All ports are on the same function. Multi-function device is no
+ * longer available. This should not be seen in any system. */
+ for (i = 0; i < host->n_ports; i++)
+ k2_sata_setup_port(&host->ports[i]->ioaddr,
+ mmio_base + i * K2_SATA_PORT_OFFSET);
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
@@ -425,38 +454,6 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
if (rc)
return rc;
- probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- probe_ent->sht = &k2_sata_sht;
- probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | board_info->port_flags;
- probe_ent->port_ops = &k2_sata_ops;
- probe_ent->n_ports = 4;
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- /* We don't care much about the PIO/UDMA masks, but the core won't like us
- * if we don't fill these
- */
- probe_ent->pio_mask = 0x1f;
- probe_ent->mwdma_mask = 0x7;
- probe_ent->udma_mask = 0x7f;
-
- mmio_base = probe_ent->iomap[5];
-
- /* different controllers have different number of ports - currently 4 or 8 */
- /* All ports are on the same function. Multi-function device is no
- * longer available. This should not be seen in any system. */
- for (i = 0; i < board_info->n_ports; i++)
- k2_sata_setup_port(&probe_ent->port[i],
- mmio_base + i * K2_SATA_PORT_OFFSET);
-
/* Clear a magic bit in SCR1 according to Darwin, those help
* some funky seagate drives (though so far, those were already
* set by the firmware on the machines I had access to)
@@ -469,12 +466,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &k2_sata_sht);
}
/* 0x240 is device ID for Apple K2 device
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 0ebd77b080d6..3a4f44559d0a 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -44,7 +44,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
-#define DRV_VERSION "0.9"
+#define DRV_VERSION "0.10"
enum {
@@ -151,24 +151,23 @@ struct pdc_host_priv {
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
static void pdc_eng_timeout(struct ata_port *ap);
static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
+static unsigned int pdc20621_dimm_init(struct ata_host *host);
+static int pdc20621_detect_dimm(struct ata_host *host);
+static unsigned int pdc20621_i2c_read(struct ata_host *host,
u32 device, u32 subaddr, u32 *pdata);
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe);
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe);
+static int pdc20621_prog_dimm0(struct ata_host *host);
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host);
#ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
+static void pdc20621_get_from_dimm(struct ata_host *host,
void *psource, u32 offset, u32 size);
#endif
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
+static void pdc20621_put_to_dimm(struct ata_host *host,
void *psource, u32 offset, u32 size);
static void pdc20621_irq_clear(struct ata_port *ap);
static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
@@ -204,7 +203,6 @@ static const struct ata_port_operations pdc_20621_ops = {
.qc_issue = pdc20621_qc_issue_prot,
.data_xfer = ata_data_xfer,
.eng_timeout = pdc_eng_timeout,
- .irq_handler = pdc20621_interrupt,
.irq_clear = pdc20621_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -214,7 +212,6 @@ static const struct ata_port_operations pdc_20621_ops = {
static const struct ata_port_info pdc_port_info[] = {
/* board_20621 */
{
- .sht = &pdc_sata_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
@@ -421,7 +418,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
- VPRINTK("ata%u: ENTER\n", ap->id);
+ VPRINTK("ata%u: ENTER\n", ap->print_id);
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -478,7 +475,7 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
unsigned int portno = ap->port_no;
unsigned int i;
- VPRINTK("ata%u: ENTER\n", ap->id);
+ VPRINTK("ata%u: ENTER\n", ap->print_id);
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -605,7 +602,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
- VPRINTK("ata%u: ENTER\n", ap->id);
+ VPRINTK("ata%u: ENTER\n", ap->print_id);
wmb(); /* flush PRD, pkt writes */
@@ -672,7 +669,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
/* step two - DMA from DIMM to host */
if (doing_hdma) {
- VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
+ VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->print_id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
@@ -683,7 +680,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
/* step one - exec ATA command */
else {
u8 seq = (u8) (port_no + 1 + 4);
- VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->id,
+ VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->print_id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* submit hdma pkt */
@@ -698,7 +695,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
/* step one - DMA from host to DIMM */
if (doing_hdma) {
u8 seq = (u8) (port_no + 1);
- VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->id,
+ VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->print_id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* submit ata pkt */
@@ -711,7 +708,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
/* step two - execute ATA command */
else {
- VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
+ VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->print_id,
readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
/* get drive status; clear intr; complete txn */
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
@@ -882,15 +879,15 @@ static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
#ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
u32 offset, u32 size)
{
u32 window_size;
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
- void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -937,15 +934,15 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
#endif
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
u32 offset, u32 size)
{
u32 window_size;
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
- void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -987,10 +984,10 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
}
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
+static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
u32 subaddr, u32 *pdata)
{
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
u32 i2creg = 0;
u32 status;
u32 count =0;
@@ -1023,17 +1020,17 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
}
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
+static int pdc20621_detect_dimm(struct ata_host *host)
{
u32 data=0 ;
- if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+ if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
PDC_DIMM_SPD_SYSTEM_FREQ, &data)) {
if (data == 100)
return 100;
} else
return 0;
- if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
+ if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
if(data <= 0x75)
return 133;
} else
@@ -1043,13 +1040,13 @@ static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
}
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
+static int pdc20621_prog_dimm0(struct ata_host *host)
{
u32 spd0[50];
u32 data = 0;
int size, i;
u8 bdimmsize;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
static const struct {
unsigned int reg;
unsigned int ofs;
@@ -1072,7 +1069,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
mmio += PDC_CHIP0_OFS;
for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++)
- pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+ pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
pdc_i2c_read_data[i].reg,
&spd0[pdc_i2c_read_data[i].ofs]);
@@ -1108,11 +1105,11 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
}
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
{
u32 data, spd0;
int error, i;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1129,7 +1126,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
/* Turn on for ECC */
- pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+ pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
PDC_DIMM_SPD_TYPE, &spd0);
if (spd0 == 0x02) {
data |= (0x01 << 16);
@@ -1156,7 +1153,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
}
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
+static unsigned int pdc20621_dimm_init(struct ata_host *host)
{
int speed, size, length;
u32 addr,spd0,pci_status;
@@ -1166,7 +1163,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
u32 ticks=0;
u32 clock=0;
u32 fparam=0;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1225,18 +1222,18 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
Read SPD of DIMM by I2C interface,
and program the DIMM Module Controller.
*/
- if (!(speed = pdc20621_detect_dimm(pe))) {
+ if (!(speed = pdc20621_detect_dimm(host))) {
printk(KERN_ERR "Detect Local DIMM Fail\n");
return 1; /* DIMM error */
}
VPRINTK("Local DIMM Speed = %d\n", speed);
/* Programming DIMM0 Module Control Register (index_CID0:80h) */
- size = pdc20621_prog_dimm0(pe);
+ size = pdc20621_prog_dimm0(host);
VPRINTK("Local DIMM Size = %dMB\n",size);
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
- if (pdc20621_prog_dimm_global(pe)) {
+ if (pdc20621_prog_dimm_global(host)) {
printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n");
return 1;
}
@@ -1249,20 +1246,20 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
'9','8','0','3','1','6','1','2',0,0};
u8 test_parttern2[40] = {0};
- pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x10040, 40);
- pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x40, 40);
+ pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40);
+ pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40);
- pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40);
- pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+ pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40);
+ pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
test_parttern2[1], &(test_parttern2[2]));
- pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040,
+ pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040,
40);
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
test_parttern2[1], &(test_parttern2[2]));
- pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40);
- pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+ pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40);
+ pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
test_parttern2[1], &(test_parttern2[2]));
}
@@ -1270,14 +1267,14 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
/* ECC initiliazation. */
- pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+ pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
PDC_DIMM_SPD_TYPE, &spd0);
if (spd0 == 0x02) {
VPRINTK("Start ECC initialization\n");
addr = 0;
length = size * 1024 * 1024;
while (addr < length) {
- pdc20621_put_to_dimm(pe, (void *) &tmp, addr,
+ pdc20621_put_to_dimm(host, (void *) &tmp, addr,
sizeof(u32));
addr += sizeof(u32);
}
@@ -1287,10 +1284,10 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
}
-static void pdc_20621_init(struct ata_probe_ent *pe)
+static void pdc_20621_init(struct ata_host *host)
{
u32 tmp;
- void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1321,15 +1318,25 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent;
+ const struct ata_port_info *ppi[] =
+ { &pdc_port_info[ent->driver_data], NULL };
+ struct ata_host *host;
void __iomem *base;
struct pdc_host_priv *hpriv;
- unsigned int board_idx = (unsigned int) ent->driver_data;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* allocate host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!host || !hpriv)
+ return -ENOMEM;
+
+ host->private_data = hpriv;
+
+ /* acquire resources and fill host */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
@@ -1340,7 +1347,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
pcim_pin_device(pdev);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
+
+ base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
+ pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200);
+ pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280);
+ pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300);
+ pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380);
+ /* configure and activate */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
return rc;
@@ -1348,50 +1363,13 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
if (rc)
return rc;
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
+ if (pdc20621_dimm_init(host))
return -ENOMEM;
-
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
- hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv)
- return -ENOMEM;
-
- probe_ent->sht = pdc_port_info[board_idx].sht;
- probe_ent->port_flags = pdc_port_info[board_idx].flags;
- probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
- probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
- probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
- probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
-
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- probe_ent->private_data = hpriv;
- base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
-
- probe_ent->n_ports = 4;
- pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
- pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
- pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
- pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+ pdc_20621_init(host);
pci_set_master(pdev);
-
- /* initialize adapter */
- /* initialize local dimm */
- if (pdc20621_dimm_init(probe_ent))
- return -ENOMEM;
- pdc_20621_init(probe_ent);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, pdc20621_interrupt,
+ IRQF_SHARED, &pdc_sata_sht);
}
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 80131eec68f4..f74e383de083 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -36,7 +36,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_uli"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.1"
enum {
uli_5289 = 0,
@@ -115,7 +115,6 @@ static const struct ata_port_operations uli_ops = {
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -127,7 +126,6 @@ static const struct ata_port_operations uli_ops = {
};
static struct ata_port_info uli_port_info = {
- .sht = &uli_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_IGN_SIMPLEX,
.pio_mask = 0x1f, /* pio0-4 */
@@ -185,12 +183,13 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent;
- struct ata_port_info *ppi[2];
- int rc;
+ const struct ata_port_info *ppi[] = { &uli_port_info, NULL };
unsigned int board_idx = (unsigned int) ent->driver_data;
+ struct ata_host *host;
struct uli_priv *hpriv;
void __iomem * const *iomap;
+ struct ata_ioports *ioaddr;
+ int n_ports, rc;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -199,54 +198,42 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pcim_pin_device(pdev);
- return rc;
- }
-
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ n_ports = 2;
+ if (board_idx == uli_5287)
+ n_ports = 4;
+ rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host);
if (rc)
return rc;
- ppi[0] = ppi[1] = &uli_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent)
- return -ENOMEM;
-
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
+ host->private_data = hpriv;
- probe_ent->private_data = hpriv;
-
- iomap = pcim_iomap_table(pdev);
+ iomap = host->iomap;
switch (board_idx) {
case uli_5287:
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
- probe_ent->n_ports = 4;
- probe_ent->port[2].cmd_addr = iomap[0] + 8;
- probe_ent->port[2].altstatus_addr =
- probe_ent->port[2].ctl_addr = (void __iomem *)
+ ioaddr = &host->ports[2]->ioaddr;
+ ioaddr->cmd_addr = iomap[0] + 8;
+ ioaddr->altstatus_addr =
+ ioaddr->ctl_addr = (void __iomem *)
((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[2].bmdma_addr = iomap[4] + 16;
+ ioaddr->bmdma_addr = iomap[4] + 16;
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
+ ata_std_ports(ioaddr);
- probe_ent->port[3].cmd_addr = iomap[2] + 8;
- probe_ent->port[3].altstatus_addr =
- probe_ent->port[3].ctl_addr = (void __iomem *)
+ ioaddr = &host->ports[3]->ioaddr;
+ ioaddr->cmd_addr = iomap[2] + 8;
+ ioaddr->altstatus_addr =
+ ioaddr->ctl_addr = (void __iomem *)
((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[3].bmdma_addr = iomap[4] + 24;
+ ioaddr->bmdma_addr = iomap[4] + 24;
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
-
- ata_std_ports(&probe_ent->port[2]);
- ata_std_ports(&probe_ent->port[3]);
+ ata_std_ports(ioaddr);
break;
case uli_5289:
@@ -266,12 +253,8 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_intx(pdev, 1);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &uli_sht);
}
static int __init uli_init(void)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index baca6d79bb0b..1d855f55f5f7 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -46,7 +46,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_via"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.1"
enum board_ids_enum {
vt6420,
@@ -60,12 +60,10 @@ enum {
SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */
PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */
PATA_PIO_TIMING = 0xAB, /* PATA timing register */
-
+
PORT0 = (1 << 1),
PORT1 = (1 << 0),
ALL_PORTS = PORT0 | PORT1,
- PATA_PORT = 2, /* PATA is port 2 */
- N_PORTS = 3,
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
@@ -78,11 +76,9 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void svia_noop_freeze(struct ata_port *ap);
static void vt6420_error_handler(struct ata_port *ap);
-static void vt6421_sata_error_handler(struct ata_port *ap);
-static void vt6421_pata_error_handler(struct ata_port *ap);
+static int vt6421_pata_cable_detect(struct ata_port *ap);
static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
-static int vt6421_port_start(struct ata_port *ap);
static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x5337), vt6420 },
@@ -141,7 +137,6 @@ static const struct ata_port_operations vt6420_sata_ops = {
.error_handler = vt6420_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -151,7 +146,7 @@ static const struct ata_port_operations vt6420_sata_ops = {
static const struct ata_port_operations vt6421_pata_ops = {
.port_disable = ata_port_disable,
-
+
.set_piomode = vt6421_set_pio_mode,
.set_dmamode = vt6421_set_dma_mode,
@@ -172,20 +167,20 @@ static const struct ata_port_operations vt6421_pata_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = vt6421_pata_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = vt6421_pata_cable_detect,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
- .port_start = vt6421_port_start,
+ .port_start = ata_port_start,
};
static const struct ata_port_operations vt6421_sata_ops = {
.port_disable = ata_port_disable,
-
+
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
@@ -203,10 +198,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = vt6421_sata_error_handler,
+ .error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = ata_cable_sata,
- .irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -214,11 +209,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
.scr_read = svia_scr_read,
.scr_write = svia_scr_write,
- .port_start = vt6421_port_start,
+ .port_start = ata_port_start,
};
-static struct ata_port_info vt6420_port_info = {
- .sht = &svia_sht,
+static const struct ata_port_info vt6420_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -226,6 +220,22 @@ static struct ata_port_info vt6420_port_info = {
.port_ops = &vt6420_sata_ops,
};
+static struct ata_port_info vt6421_sport_info = {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+ .port_ops = &vt6421_sata_ops,
+};
+
+static struct ata_port_info vt6421_pport_info = {
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0,
+ .udma_mask = 0x7f,
+ .port_ops = &vt6421_pata_ops,
+};
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
MODULE_LICENSE("GPL");
@@ -330,35 +340,15 @@ static void vt6420_error_handler(struct ata_port *ap)
NULL, ata_std_postreset);
}
-static int vt6421_pata_prereset(struct ata_port *ap)
+static int vt6421_pata_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 tmp;
pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
if (tmp & 0x10)
- ap->cbl = ATA_CBL_PATA40;
- else
- ap->cbl = ATA_CBL_PATA80;
- return 0;
-}
-
-static void vt6421_pata_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset,
- NULL, ata_std_postreset);
-}
-
-static int vt6421_sata_prereset(struct ata_port *ap)
-{
- ap->cbl = ATA_CBL_SATA;
- return 0;
-}
-
-static void vt6421_sata_error_handler(struct ata_port *ap)
-{
- return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset,
- NULL, ata_std_postreset);
+ return ATA_CBL_PATA40;
+ return ATA_CBL_PATA80;
}
static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
@@ -375,16 +365,6 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
}
-static int vt6421_port_start(struct ata_port *ap)
-{
- if (ap->port_no == PATA_PORT) {
- ap->ops = &vt6421_pata_ops;
- ap->mwdma_mask = 0;
- ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST;
- }
- return ata_port_start(ap);
-}
-
static const unsigned int svia_bar_sizes[] = {
8, 4, 8, 4, 16, 256
};
@@ -403,67 +383,78 @@ static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port)
return addr + (port * 64);
}
-static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
- void __iomem * const *iomap, unsigned int port)
+static void vt6421_init_addrs(struct ata_port *ap)
{
- void __iomem *reg_addr = iomap[port];
- void __iomem *bmdma_addr = iomap[4] + (port * 8);
-
- probe_ent->port[port].cmd_addr = reg_addr;
- probe_ent->port[port].altstatus_addr =
- probe_ent->port[port].ctl_addr = (void __iomem *)
+ void __iomem * const * iomap = ap->host->iomap;
+ void __iomem *reg_addr = iomap[ap->port_no];
+ void __iomem *bmdma_addr = iomap[4] + (ap->port_no * 8);
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ ioaddr->cmd_addr = reg_addr;
+ ioaddr->altstatus_addr =
+ ioaddr->ctl_addr = (void __iomem *)
((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS);
- probe_ent->port[port].bmdma_addr = bmdma_addr;
- probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port);
+ ioaddr->bmdma_addr = bmdma_addr;
+ ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no);
- ata_std_ports(&probe_ent->port[port]);
+ ata_std_ports(ioaddr);
}
-static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
+static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
{
- struct ata_probe_ent *probe_ent;
- struct ata_port_info *ppi[2];
- void __iomem * const *iomap;
+ const struct ata_port_info *ppi[] = { &vt6420_port_info, NULL };
+ struct ata_host *host;
+ int rc;
- ppi[0] = ppi[1] = &vt6420_port_info;
- probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent)
- return NULL;
+ rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ if (rc)
+ return rc;
+ *r_host = host;
- iomap = pcim_iomap_table(pdev);
- probe_ent->port[0].scr_addr = svia_scr_addr(iomap[5], 0);
- probe_ent->port[1].scr_addr = svia_scr_addr(iomap[5], 1);
+ rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n");
+ return rc;
+ }
+
+ host->ports[0]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 0);
+ host->ports[1]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 1);
- return probe_ent;
+ return 0;
}
-static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
+static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
{
- struct ata_probe_ent *probe_ent;
- unsigned int i;
-
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (!probe_ent)
- return NULL;
+ const struct ata_port_info *ppi[] =
+ { &vt6421_sport_info, &vt6421_sport_info, &vt6421_pport_info };
+ struct ata_host *host;
+ int i, rc;
+
+ *r_host = host = ata_host_alloc_pinfo(&pdev->dev, ppi, ARRAY_SIZE(ppi));
+ if (!host) {
+ dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
+ return -ENOMEM;
+ }
- memset(probe_ent, 0, sizeof(*probe_ent));
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
+ rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev, "failed to request/iomap "
+ "PCI BARs (errno=%d)\n", rc);
+ return rc;
+ }
+ host->iomap = pcim_iomap_table(pdev);
- probe_ent->sht = &svia_sht;
- probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
- probe_ent->port_ops = &vt6421_sata_ops;
- probe_ent->n_ports = N_PORTS;
- probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->pio_mask = 0x1f;
- probe_ent->mwdma_mask = 0x07;
- probe_ent->udma_mask = 0x7f;
+ for (i = 0; i < host->n_ports; i++)
+ vt6421_init_addrs(host->ports[i]);
- for (i = 0; i < N_PORTS; i++)
- vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i);
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
- return probe_ent;
+ return 0;
}
static void svia_configure(struct pci_dev *pdev)
@@ -510,7 +501,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
unsigned int i;
int rc;
- struct ata_probe_ent *probe_ent;
+ struct ata_host *host;
int board_id = (int) ent->driver_data;
const int *bar_sizes;
u8 tmp8;
@@ -522,12 +513,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
- if (rc) {
- pcim_pin_device(pdev);
- return rc;
- }
-
if (board_id == vt6420) {
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
if (tmp8 & SATA_2DEV) {
@@ -553,32 +538,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
}
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
-
if (board_id == vt6420)
- probe_ent = vt6420_init_probe_ent(pdev);
+ rc = vt6420_prepare_host(pdev, &host);
else
- probe_ent = vt6421_init_probe_ent(pdev);
-
- if (!probe_ent) {
- dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
- return -ENOMEM;
- }
+ rc = vt6421_prepare_host(pdev, &host);
+ if (rc)
+ return rc;
svia_configure(pdev);
pci_set_master(pdev);
-
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &svia_sht);
}
static int __init svia_init(void)
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 2fd037bde090..80126f835d32 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -47,7 +47,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_vsc"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.1"
enum {
VSC_MMIO_BAR = 0,
@@ -98,10 +98,6 @@ enum {
VSC_SATA_INT_PHY_CHANGE),
};
-#define is_vsc_sata_int_err(port_idx, int_status) \
- (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx)))
-
-
static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
@@ -119,6 +115,28 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
}
+static void vsc_freeze(struct ata_port *ap)
+{
+ void __iomem *mask_addr;
+
+ mask_addr = ap->host->iomap[VSC_MMIO_BAR] +
+ VSC_SATA_INT_MASK_OFFSET + ap->port_no;
+
+ writeb(0, mask_addr);
+}
+
+
+static void vsc_thaw(struct ata_port *ap)
+{
+ void __iomem *mask_addr;
+
+ mask_addr = ap->host->iomap[VSC_MMIO_BAR] +
+ VSC_SATA_INT_MASK_OFFSET + ap->port_no;
+
+ writeb(0xff, mask_addr);
+}
+
+
static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
{
void __iomem *mask_addr;
@@ -203,6 +221,36 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
}
}
+static inline void vsc_error_intr(u8 port_status, struct ata_port *ap)
+{
+ if (port_status & (VSC_SATA_INT_PHY_CHANGE | VSC_SATA_INT_ERROR_M))
+ ata_port_freeze(ap);
+ else
+ ata_port_abort(ap);
+}
+
+static void vsc_port_intr(u8 port_status, struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ int handled = 0;
+
+ if (unlikely(port_status & VSC_SATA_INT_ERROR)) {
+ vsc_error_intr(port_status, ap);
+ return;
+ }
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING)))
+ handled = ata_host_intr(ap, qc);
+
+ /* We received an interrupt during a polled command,
+ * or some other spurious condition. Interrupt reporting
+ * with this hardware is fairly reliable so it is safe to
+ * simply clear the interrupt
+ */
+ if (unlikely(!handled))
+ ata_chk_status(ap);
+}
/*
* vsc_sata_interrupt
@@ -214,59 +262,36 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
struct ata_host *host = dev_instance;
unsigned int i;
unsigned int handled = 0;
- u32 int_status;
-
- spin_lock(&host->lock);
+ u32 status;
- int_status = readl(host->iomap[VSC_MMIO_BAR] +
- VSC_SATA_INT_STAT_OFFSET);
+ status = readl(host->iomap[VSC_MMIO_BAR] + VSC_SATA_INT_STAT_OFFSET);
- for (i = 0; i < host->n_ports; i++) {
- if (int_status & ((u32) 0xFF << (8 * i))) {
- struct ata_port *ap;
+ if (unlikely(status == 0xffffffff || status == 0)) {
+ if (status)
+ dev_printk(KERN_ERR, host->dev,
+ ": IRQ status == 0xffffffff, "
+ "PCI fault or device removal?\n");
+ goto out;
+ }
- ap = host->ports[i];
+ spin_lock(&host->lock);
- if (is_vsc_sata_int_err(i, int_status)) {
- u32 err_status;
- printk(KERN_DEBUG "%s: ignoring interrupt(s)\n", __FUNCTION__);
- err_status = ap ? vsc_sata_scr_read(ap, SCR_ERROR) : 0;
- vsc_sata_scr_write(ap, SCR_ERROR, err_status);
- handled++;
- }
+ for (i = 0; i < host->n_ports; i++) {
+ u8 port_status = (status >> (8 * i)) & 0xff;
+ if (port_status) {
+ struct ata_port *ap = host->ports[i];
if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
-
- qc = ata_qc_from_tag(ap, ap->active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
- handled += ata_host_intr(ap, qc);
- else if (is_vsc_sata_int_err(i, int_status)) {
- /*
- * On some chips (i.e. Intel 31244), an error
- * interrupt will sneak in at initialization
- * time (phy state changes). Clearing the SCR
- * error register is not required, but it prevents
- * the phy state change interrupts from recurring
- * later.
- */
- u32 err_status;
- err_status = vsc_sata_scr_read(ap, SCR_ERROR);
- printk(KERN_DEBUG "%s: clearing interrupt, "
- "status %x; sata err status %x\n",
- __FUNCTION__,
- int_status, err_status);
- vsc_sata_scr_write(ap, SCR_ERROR, err_status);
- /* Clear interrupt status */
- ata_chk_status(ap);
- handled++;
- }
- }
+ vsc_port_intr(port_status, ap);
+ handled++;
+ } else
+ dev_printk(KERN_ERR, host->dev,
+ ": interrupt from disabled port %d\n", i);
}
}
spin_unlock(&host->lock);
-
+out:
return IRQ_RETVAL(handled);
}
@@ -304,11 +329,10 @@ static const struct ata_port_operations vsc_sata_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
+ .freeze = vsc_freeze,
+ .thaw = vsc_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_handler = vsc_sata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
@@ -342,30 +366,50 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ static const struct ata_port_info pi = {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = 0x7f,
+ .port_ops = &vsc_sata_ops,
+ };
+ const struct ata_port_info *ppi[] = { &pi, NULL };
static int printed_version;
- struct ata_probe_ent *probe_ent;
+ struct ata_host *host;
void __iomem *mmio_base;
- int rc;
+ int i, rc;
u8 cls;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ /* allocate host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+ if (!host)
+ return -ENOMEM;
+
rc = pcim_enable_device(pdev);
if (rc)
return rc;
- /*
- * Check if we have needed resource mapped.
- */
+ /* check if we have needed resource mapped */
if (pci_resource_len(pdev, 0) == 0)
return -ENODEV;
+ /* map IO regions and intialize host accordingly */
rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
+ host->iomap = pcim_iomap_table(pdev);
+
+ mmio_base = host->iomap[VSC_MMIO_BAR];
+
+ for (i = 0; i < host->n_ports; i++)
+ vsc_sata_setup_port(&host->ports[i]->ioaddr,
+ mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET);
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
@@ -377,12 +421,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
if (rc)
return rc;
- probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL)
- return -ENOMEM;
- probe_ent->dev = pci_dev_to_dev(pdev);
- INIT_LIST_HEAD(&probe_ent->node);
-
/*
* Due to a bug in the chip, the default cache line size can't be
* used (unless the default is non-zero).
@@ -393,33 +431,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
if (pci_enable_msi(pdev) == 0)
pci_intx(pdev, 0);
- else
- probe_ent->irq_flags = IRQF_SHARED;
-
- probe_ent->sht = &vsc_sata_sht;
- probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO;
- probe_ent->port_ops = &vsc_sata_ops;
- probe_ent->n_ports = 4;
- probe_ent->irq = pdev->irq;
- probe_ent->iomap = pcim_iomap_table(pdev);
-
- /* We don't care much about the PIO/UDMA masks, but the core won't like us
- * if we don't fill these
- */
- probe_ent->pio_mask = 0x1f;
- probe_ent->mwdma_mask = 0x07;
- probe_ent->udma_mask = 0x7f;
-
- mmio_base = probe_ent->iomap[VSC_MMIO_BAR];
-
- /* We have 4 ports per PCI function */
- vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET);
-
- pci_set_master(pdev);
/*
* Config offset 0x98 is "Extended Control and Status Register 0"
@@ -429,11 +440,9 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
*/
pci_write_config_dword(pdev, 0x98, 0);
- if (!ata_device_add(probe_ent))
- return -ENODEV;
-
- devm_kfree(&pdev->dev, probe_ent);
- return 0;
+ pci_set_master(pdev);
+ return ata_host_activate(host, pdev->irq, vsc_sata_interrupt,
+ IRQF_SHARED, &vsc_sata_sht);
}
static const struct pci_device_id vsc_sata_pci_tbl[] = {
diff --git a/drivers/ata/sis.h b/drivers/ata/sis.h
new file mode 100644
index 000000000000..231da8fc2200
--- /dev/null
+++ b/drivers/ata/sis.h
@@ -0,0 +1,5 @@
+
+struct ata_port_info;
+
+/* pata_sis.c */
+extern struct ata_port_info sis_info133;