aboutsummaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/Kconfig49
-rw-r--r--drivers/ata/Makefile3
-rw-r--r--drivers/ata/ahci.c347
-rw-r--r--drivers/ata/ata_generic.c14
-rw-r--r--drivers/ata/ata_piix.c76
-rw-r--r--drivers/ata/libata-core.c622
-rw-r--r--drivers/ata/libata-eh.c13
-rw-r--r--drivers/ata/libata-scsi.c400
-rw-r--r--drivers/ata/libata-sff.c666
-rw-r--r--drivers/ata/libata.h4
-rw-r--r--drivers/ata/pata_ali.c32
-rw-r--r--drivers/ata/pata_amd.c36
-rw-r--r--drivers/ata/pata_artop.c12
-rw-r--r--drivers/ata/pata_atiixp.c17
-rw-r--r--drivers/ata/pata_cmd64x.c41
-rw-r--r--drivers/ata/pata_cs5520.c41
-rw-r--r--drivers/ata/pata_cs5530.c44
-rw-r--r--drivers/ata/pata_cs5535.c6
-rw-r--r--drivers/ata/pata_cypress.c6
-rw-r--r--drivers/ata/pata_efar.c6
-rw-r--r--drivers/ata/pata_hpt366.c26
-rw-r--r--drivers/ata/pata_hpt37x.c67
-rw-r--r--drivers/ata/pata_hpt3x2n.c32
-rw-r--r--drivers/ata/pata_hpt3x3.c8
-rw-r--r--drivers/ata/pata_isapnp.c21
-rw-r--r--drivers/ata/pata_it8213.c354
-rw-r--r--drivers/ata/pata_it821x.c62
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c55
-rw-r--r--drivers/ata/pata_jmicron.c26
-rw-r--r--drivers/ata/pata_legacy.c168
-rw-r--r--drivers/ata/pata_marvell.c12
-rw-r--r--drivers/ata/pata_mpc52xx.c538
-rw-r--r--drivers/ata/pata_mpiix.c113
-rw-r--r--drivers/ata/pata_netcell.c6
-rw-r--r--drivers/ata/pata_ns87410.c6
-rw-r--r--drivers/ata/pata_oldpiix.c24
-rw-r--r--drivers/ata/pata_opti.c24
-rw-r--r--drivers/ata/pata_optidma.c40
-rw-r--r--drivers/ata/pata_pcmcia.c27
-rw-r--r--drivers/ata/pata_pdc2027x.c122
-rw-r--r--drivers/ata/pata_pdc202xx_old.c41
-rw-r--r--drivers/ata/pata_platform.c70
-rw-r--r--drivers/ata/pata_qdi.c54
-rw-r--r--drivers/ata/pata_radisys.c6
-rw-r--r--drivers/ata/pata_rz1000.c14
-rw-r--r--drivers/ata/pata_sc1200.c6
-rw-r--r--drivers/ata/pata_serverworks.c31
-rw-r--r--drivers/ata/pata_sil680.c10
-rw-r--r--drivers/ata/pata_sis.c70
-rw-r--r--drivers/ata/pata_sl82c105.c10
-rw-r--r--drivers/ata/pata_triflex.c6
-rw-r--r--drivers/ata/pata_via.c37
-rw-r--r--drivers/ata/pata_winbond.c51
-rw-r--r--drivers/ata/pdc_adma.c120
-rw-r--r--drivers/ata/sata_inic162x.c781
-rw-r--r--drivers/ata/sata_mv.c205
-rw-r--r--drivers/ata/sata_nv.c651
-rw-r--r--drivers/ata/sata_promise.c379
-rw-r--r--drivers/ata/sata_qstor.c138
-rw-r--r--drivers/ata/sata_sil.c99
-rw-r--r--drivers/ata/sata_sil24.c178
-rw-r--r--drivers/ata/sata_sis.c161
-rw-r--r--drivers/ata/sata_svw.c153
-rw-r--r--drivers/ata/sata_sx4.c207
-rw-r--r--drivers/ata/sata_uli.c69
-rw-r--r--drivers/ata/sata_via.c206
-rw-r--r--drivers/ata/sata_vsc.c111
67 files changed, 4676 insertions, 3354 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 984ab284382..3747457fee7 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -19,6 +19,10 @@ config ATA
if ATA
+config ATA_NONSTANDARD
+ bool
+ default n
+
config SATA_AHCI
tristate "AHCI SATA support"
depends on PCI
@@ -37,12 +41,12 @@ config SATA_SVW
If unsure, say N.
config ATA_PIIX
- tristate "Intel PIIX/ICH SATA support"
+ tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
depends on PCI
help
- This option enables support for ICH5/6/7/8 Serial ATA.
- If PATA support was enabled previously, this enables
- support for select Intel PIIX/ICH PATA host controllers.
+ This option enables support for ICH5/6/7/8 Serial ATA
+ and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
+ host controllers.
If unsure, say N.
@@ -112,11 +116,14 @@ config SATA_SIL24
If unsure, say N.
config SATA_SIS
- tristate "SiS 964/180 SATA support"
+ tristate "SiS 964/965/966/180 SATA support"
depends on PCI
+ select PATA_SIS
help
- This option enables support for SiS Serial ATA 964/180.
-
+ This option enables support for SiS Serial ATA on
+ SiS 964/965/966/180 and Parallel ATA on SiS 180.
+ The PATA support for SiS 180 requires additionally to
+ enable the PATA_SIS driver in the config.
If unsure, say N.
config SATA_ULI
@@ -143,6 +150,12 @@ config SATA_VITESSE
If unsure, say N.
+config SATA_INIC162X
+ tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for Initio 162x Serial ATA.
+
config SATA_INTEL_COMBINED
bool
depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
@@ -292,7 +305,7 @@ config PATA_ISAPNP
If unsure, say N.
config PATA_IT821X
- tristate "IT821x PATA support (Experimental)"
+ tristate "IT8211/2 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ITE 8211 and 8212
@@ -301,6 +314,15 @@ config PATA_IT821X
If unsure, say N.
+config PATA_IT8213
+ tristate "IT8213 PATA support (Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for the ITE 821 PATA
+ controllers via the new ATA layer.
+
+ If unsure, say N.
+
config PATA_JMICRON
tristate "JMicron PATA support"
depends on PCI
@@ -337,6 +359,15 @@ config PATA_MARVELL
If unsure, say N.
+config PATA_MPC52xx
+ tristate "Freescale MPC52xx SoC internal IDE"
+ depends on PPC_MPC52xx
+ help
+ This option enables support for integrated IDE controller
+ of the Freescale MPC52xx SoC.
+
+ If unsure, say N.
+
config PATA_MPIIX
tristate "Intel PATA MPIIX support"
depends on PCI
@@ -381,7 +412,7 @@ config PATA_OPTI
If unsure, say N.
config PATA_OPTIDMA
- tristate "OPTI FireStar PATA support (Veyr Experimental)"
+ tristate "OPTI FireStar PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables DMA/PIO support for the later OPTi
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index bc3d81ae757..cd096f0c78a 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SATA_SX4) += sata_sx4.o
obj-$(CONFIG_SATA_NV) += sata_nv.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_MV) += sata_mv.o
+obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
obj-$(CONFIG_PATA_ALI) += pata_ali.o
@@ -33,11 +34,13 @@ obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
+obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
+obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f36da488a2c..92cdb0c5171 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -45,7 +45,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "ahci"
#define DRV_VERSION "2.0"
@@ -75,6 +74,7 @@ enum {
AHCI_CMD_CLR_BUSY = (1 << 10),
RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
+ RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
board_ahci = 0,
@@ -165,9 +165,6 @@ enum {
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
- /* hpriv->flags bits */
- AHCI_FLAG_MSI = (1 << 0),
-
/* ap->flags bits */
AHCI_FLAG_NO_NCQ = (1 << 24),
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
@@ -190,7 +187,6 @@ struct ahci_sg {
};
struct ahci_host_priv {
- unsigned long flags;
u32 cap; /* cache of HOST_CAP register */
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
};
@@ -202,6 +198,10 @@ struct ahci_port_priv {
dma_addr_t cmd_tbl_dma;
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;
};
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
@@ -224,7 +224,6 @@ 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);
-static void ahci_remove_one (struct pci_dev *pdev);
static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
@@ -261,6 +260,8 @@ static const struct ata_port_operations ahci_ops = {
.irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = ahci_scr_read,
.scr_write = ahci_scr_write,
@@ -292,6 +293,8 @@ static const struct ata_port_operations ahci_vt8251_ops = {
.irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = ahci_scr_read,
.scr_write = ahci_scr_write,
@@ -361,7 +364,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
{ PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
{ PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
- { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */
+ { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */
{ PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
@@ -402,6 +405,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */
{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */
+ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
@@ -418,7 +429,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- 0x010601, 0xffffff, board_ahci },
+ PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
{ } /* terminate list */
};
@@ -428,9 +439,9 @@ static struct pci_driver ahci_pci_driver = {
.name = DRV_NAME,
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
+ .remove = ata_pci_remove_one,
.suspend = ahci_pci_device_suspend,
.resume = ahci_pci_device_resume,
- .remove = ahci_remove_one,
};
@@ -439,16 +450,12 @@ static inline int ahci_nr_ports(u32 cap)
return (cap & 0x1f) + 1;
}
-static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
+static inline void __iomem *ahci_port_base(void __iomem *base,
+ unsigned int port)
{
return base + 0x100 + (port * 0x80);
}
-static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int port)
-{
- return (void __iomem *) ahci_port_base_ul((unsigned long)base, port);
-}
-
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
{
unsigned int sc_reg;
@@ -462,7 +469,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
return 0xffffffffU;
}
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -480,7 +487,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
return;
}
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void ahci_start_engine(void __iomem *port_mmio)
@@ -578,35 +585,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
{
u32 cmd, scontrol;
- cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
-
- if (cap & HOST_CAP_SSC) {
- /* enable transitions to slumber mode */
- scontrol = readl(port_mmio + PORT_SCR_CTL);
- if ((scontrol & 0x0f00) > 0x100) {
- scontrol &= ~0xf00;
- writel(scontrol, port_mmio + PORT_SCR_CTL);
- }
-
- /* put device into slumber mode */
- writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD);
-
- /* wait for the transition to complete */
- ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER,
- PORT_CMD_ICC_SLUMBER, 1, 50);
- }
+ if (!(cap & HOST_CAP_SSS))
+ return;
- /* put device into listen mode */
- if (cap & HOST_CAP_SSS) {
- /* first set PxSCTL.DET to 0 */
- scontrol = readl(port_mmio + PORT_SCR_CTL);
- scontrol &= ~0xf;
- writel(scontrol, port_mmio + PORT_SCR_CTL);
+ /* put device into listen mode, first set PxSCTL.DET to 0 */
+ scontrol = readl(port_mmio + PORT_SCR_CTL);
+ scontrol &= ~0xf;
+ writel(scontrol, port_mmio + PORT_SCR_CTL);
- /* then set PxCMD.SUD to 0 */
- cmd &= ~PORT_CMD_SPIN_UP;
- writel(cmd, port_mmio + PORT_CMD);
- }
+ /* then set PxCMD.SUD to 0 */
+ cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
+ cmd &= ~PORT_CMD_SPIN_UP;
+ writel(cmd, port_mmio + PORT_CMD);
}
static void ahci_init_port(void __iomem *port_mmio, u32 cap,
@@ -645,8 +635,6 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
u32 cap_save, impl_save, tmp;
cap_save = readl(mmio + HOST_CAP);
- cap_save &= ( (1<<28) | (1<<17) );
- cap_save |= (1 << 27);
impl_save = readl(mmio + HOST_PORTS_IMPL);
/* global controller reset */
@@ -741,7 +729,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 = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ata_taskfile tf;
u32 tmp;
@@ -769,7 +757,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
static int ahci_clo(struct ata_port *ap)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ahci_host_priv *hpriv = ap->host->private_data;
u32 tmp;
@@ -791,7 +779,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->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
@@ -899,7 +887,7 @@ 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->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
@@ -909,7 +897,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
/* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(ap->device, &tf);
- tf.command = 0xff;
+ tf.command = 0x80;
ata_tf_to_fis(&tf, d2h_fis, 0);
rc = sata_std_hardreset(ap, class);
@@ -927,7 +915,7 @@ 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->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
@@ -952,7 +940,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 = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
u32 new_tmp, tmp;
ata_std_postreset(ap, class);
@@ -971,7 +959,7 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class)
static u8 ahci_check_status(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = ap->ioaddr.cmd_addr;
return readl(mmio + PORT_TFDATA) & 0xFF;
}
@@ -1117,11 +1105,12 @@ 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->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
struct ata_eh_info *ehi = &ap->eh_info;
+ struct ahci_port_priv *pp = ap->private_data;
u32 status, qc_active;
- int rc;
+ int rc, known_irq = 0;
status = readl(port_mmio + PORT_IRQ_STAT);
writel(status, port_mmio + PORT_IRQ_STAT);
@@ -1148,17 +1137,53 @@ static void ahci_host_intr(struct ata_port *ap)
/* hmmm... a spurious interupt */
- /* some devices send D2H reg with I bit set during NCQ command phase */
- if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
+ /* if !NCQ, ignore. No modern ATA device has broken HSM
+ * implementation for non-NCQ commands.
+ */
+ if (!ap->sactive)
return;
- /* ignore interim PIO setup fis interrupts */
- if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
- return;
+ if (status & PORT_IRQ_D2H_REG_FIS) {
+ if (!pp->ncq_saw_d2h)
+ ata_port_printk(ap, KERN_INFO,
+ "D2H reg with I during NCQ, "
+ "this message won't be printed again\n");
+ pp->ncq_saw_d2h = 1;
+ known_irq = 1;
+ }
+
+ if (status & PORT_IRQ_DMAS_FIS) {
+ if (!pp->ncq_saw_dmas)
+ ata_port_printk(ap, KERN_INFO,
+ "DMAS FIS during NCQ, "
+ "this message won't be printed again\n");
+ pp->ncq_saw_dmas = 1;
+ 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.
+ */
+ 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",
+ 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++;
+ known_irq = 1;
+ }
- if (ata_ratelimit())
+ if (!known_irq)
ata_port_printk(ap, KERN_INFO, "spurious interrupt "
- "(irq_stat 0x%x active_tag %d sactive 0x%x)\n",
+ "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n",
status, ap->active_tag, ap->sactive);
}
@@ -1178,7 +1203,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
VPRINTK("ENTER\n");
hpriv = host->private_data;
- mmio = host->mmio_base;
+ mmio = host->iomap[AHCI_PCI_BAR];
/* sigh. 0xffffffff is a valid return from h/w */
irq_stat = readl(mmio + HOST_IRQ_STAT);
@@ -1223,7 +1248,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 = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
if (qc->tf.protocol == ATA_PROT_NCQ)
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1235,7 +1260,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->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
/* turn IRQ off */
@@ -1244,14 +1269,14 @@ static void ahci_freeze(struct ata_port *ap)
static void ahci_thaw(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
u32 tmp;
/* clear IRQ */
tmp = readl(port_mmio + PORT_IRQ_STAT);
writel(tmp, port_mmio + PORT_IRQ_STAT);
- writel(1 << ap->id, mmio + HOST_IRQ_STAT);
+ writel(1 << ap->port_no, mmio + HOST_IRQ_STAT);
/* turn IRQ back on */
writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
@@ -1259,7 +1284,7 @@ static void ahci_thaw(struct ata_port *ap)
static void ahci_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ 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)) {
@@ -1275,7 +1300,7 @@ static void ahci_error_handler(struct ata_port *ap)
static void ahci_vt8251_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ 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)) {
@@ -1292,7 +1317,7 @@ 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->mmio_base;
+ 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)
@@ -1309,7 +1334,7 @@ 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->mmio_base;
+ 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;
@@ -1330,7 +1355,7 @@ 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->mmio_base;
+ 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);
@@ -1342,7 +1367,7 @@ static int ahci_port_resume(struct ata_port *ap)
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
u32 ctl;
if (mesg.event == PM_EVENT_SUSPEND) {
@@ -1363,10 +1388,12 @@ 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->mmio_base;
+ void __iomem *mmio = host->iomap[AHCI_PCI_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) {
rc = ahci_reset_controller(mmio, pdev);
@@ -1387,29 +1414,24 @@ 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->mmio_base;
+ 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;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
- memset(pp, 0, sizeof(*pp));
rc = ata_pad_alloc(ap, dev);
- if (rc) {
- kfree(pp);
+ if (rc)
return rc;
- }
- mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
- if (!mem) {
- ata_pad_free(ap, dev);
- kfree(pp);
+ mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
+ if (!mem)
return -ENOMEM;
- }
memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
/*
@@ -1451,10 +1473,8 @@ static int ahci_port_start(struct ata_port *ap)
static void ahci_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
struct ahci_host_priv *hpriv = ap->host->private_data;
- struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ 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;
@@ -1463,19 +1483,13 @@ static void ahci_port_stop(struct ata_port *ap)
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
if (rc)
ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
-
- ap->private_data = NULL;
- dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
- pp->cmd_slot, pp->cmd_slot_dma);
- ata_pad_free(ap, dev);
- kfree(pp);
}
-static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
+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_ul(base, port_idx);
+ base = ahci_port_base(base, port_idx);
VPRINTK("base now==0x%lx\n", base);
port->cmd_addr = base;
@@ -1488,7 +1502,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
{
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
unsigned int i, cap_n_ports, using_dac;
int rc;
@@ -1555,7 +1569,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
}
for (i = 0; i < probe_ent->n_ports; i++)
- ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
+ ahci_setup_port(&probe_ent->port[i], mmio, i);
ahci_init_controller(mmio, pdev, probe_ent->n_ports,
probe_ent->port_flags, hpriv);
@@ -1569,7 +1583,7 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
{
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
u32 vers, cap, impl, speed;
const char *speed_s;
u16 cc;
@@ -1588,11 +1602,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
speed_s = "?";
pci_read_config_word(pdev, 0x0a, &cc);
- if (cc == 0x0101)
+ if (cc == PCI_CLASS_STORAGE_IDE)
scc_s = "IDE";
- else if (cc == 0x0106)
+ else if (cc == PCI_CLASS_STORAGE_SATA)
scc_s = "SATA";
- else if (cc == 0x0104)
+ else if (cc == PCI_CLASS_STORAGE_RAID)
scc_s = "RAID";
else
scc_s = "unknown";
@@ -1636,15 +1650,13 @@ 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 ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- struct ahci_host_priv *hpriv;
- unsigned long base;
- void __iomem *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int have_msi, pci_dev_busy = 0;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
+ struct ahci_host_priv *hpriv;
int rc;
VPRINTK("ENTER\n");
@@ -1654,57 +1666,36 @@ 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");
- /* JMicron-specific fixup: make sure we're in AHCI mode */
- /* This is protected from races with ata_jmicron by the pci probe
- locking */
if (pdev->vendor == PCI_VENDOR_ID_JMICRON) {
- /* AHCI enable, AHCI on function 0 */
- pci_write_config_byte(pdev, 0x41, 0xa1);
- /* Function 1 is the PATA controller */
+ /* Function 1 is the PATA controller except on the 368, where
+ we are not AHCI anyway */
if (PCI_FUNC(pdev->devfn))
return -ENODEV;
}
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
- if (pci_enable_msi(pdev) == 0)
- have_msi = 1;
- else {
+ if (pci_enable_msi(pdev))
pci_intx(pdev, 1);
- have_msi = 0;
- }
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_msi;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, AHCI_PCI_BAR, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
+ 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;
@@ -1714,16 +1705,13 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
- if (have_msi)
- hpriv->flags |= AHCI_FLAG_MSI;
-
/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
- goto err_out_hpriv;
+ return rc;
if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
(hpriv->cap & HOST_CAP_NCQ))
@@ -1731,62 +1719,11 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
ahci_print_info(probe_ent);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_hpriv:
- kfree(hpriv);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_msi:
- if (have_msi)
- pci_disable_msi(pdev);
- else
- pci_intx(pdev, 0);
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-}
-
-static void ahci_remove_one (struct pci_dev *pdev)
-{
- struct device *dev = pci_dev_to_dev(pdev);
- struct ata_host *host = dev_get_drvdata(dev);
- struct ahci_host_priv *hpriv = host->private_data;
- unsigned int i;
- int have_msi;
-
- for (i = 0; i < host->n_ports; i++)
- ata_port_detach(host->ports[i]);
-
- have_msi = hpriv->flags & AHCI_FLAG_MSI;
- free_irq(host->irq, host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_scsi_release(ap->scsi_host);
- scsi_host_put(ap->scsi_host);
- }
-
- kfree(hpriv);
- pci_iounmap(pdev, host->mmio_base);
- kfree(host);
-
- if (have_msi)
- pci_disable_msi(pdev);
- else
- pci_intx(pdev, 0);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- dev_set_drvdata(dev, NULL);
}
static int __init ahci_init(void)
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 908751d27e7..be66ea08da5 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap)
/**
* generic_set_mode - mode setting
* @ap: interface to set up
+ * @unused: returned device on error
*
* Use a non standard set_mode function. We don't want to be tuned.
* The BIOS configured everything. Our job is not to fiddle. We
@@ -71,18 +72,18 @@ static void generic_error_handler(struct ata_port *ap)
* and respect them.
*/
-static void generic_set_mode(struct ata_port *ap)
+static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int dma_enabled = 0;
int i;
/* Bits 5 and 6 indicate if DMA is active on master/slave */
if (ap->ioaddr.bmdma_addr)
- dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_enabled(dev)) {
+ if (ata_dev_ready(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
@@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap)
}
}
}
+ return 0;
}
static struct scsi_host_template generic_sht = {
@@ -136,7 +138,7 @@ static struct ata_port_operations generic_port_ops = {
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -148,10 +150,10 @@ static struct ata_port_operations generic_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int all_generic_ide; /* Set to claim all devices */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c7de0bb1591..4d716c7347e 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -118,7 +118,7 @@ enum {
PIIX_80C_SEC = (1 << 7) | (1 << 6),
/* controller IDs */
- piix_pata_33 = 0, /* PIIX3 or 4 at 33Mhz */
+ piix_pata_33 = 0, /* PIIX4 at 33Mhz */
ich_pata_33 = 1, /* ICH up to UDMA 33 only */
ich_pata_66 = 2, /* ICH up to 66 Mhz */
ich_pata_100 = 3, /* ICH up to UDMA 100 */
@@ -128,6 +128,7 @@ enum {
ich6_sata_ahci = 7,
ich6m_sata_ahci = 8,
ich8_sata_ahci = 9,
+ piix_pata_mwdma = 10, /* PIIX3 MWDMA only */
/* constants for mapping table */
P0 = 0, /* port 0 */
@@ -153,7 +154,6 @@ struct piix_host_priv {
static int piix_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent);
-static void piix_host_stop(struct ata_host *host);
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);
@@ -164,7 +164,8 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static unsigned int in_module_init = 1;
static const struct pci_device_id piix_pci_tbl[] = {
-#ifdef ATA_ENABLE_PATA
+ /* Intel PIIX3 for the 430HX etc */
+ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_mwdma },
/* 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 },
@@ -202,7 +203,6 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH7/7-R (i945, i975) UDMA 100*/
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
-#endif
/* NOTE: The following PCI ids must be kept in sync with the
* list in drivers/pci/quirks.c.
@@ -226,14 +226,26 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
- /* Enterprise Southbridge 2 (where's the datasheet?) */
+ /* Enterprise Southbridge 2 (631xESB/632xESB) */
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
+ /* SATA Controller 1 IDE (ICH8) */
{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* SATA Controller 2 IDE (ICH8, ditto) */
+ /* SATA Controller 2 IDE (ICH8) */
{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
- /* Mobile SATA Controller IDE (ICH8M, ditto) */
+ /* Mobile SATA Controller IDE (ICH8M) */
{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9) */
+ { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ /* SATA Controller IDE (ICH9M) */
+ { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
{ } /* terminate list */
};
@@ -285,7 +297,7 @@ static const struct ata_port_operations piix_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -294,10 +306,10 @@ static const struct ata_port_operations piix_pata_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = piix_host_stop,
};
static const struct ata_port_operations ich_pata_ops = {
@@ -318,7 +330,7 @@ static const struct ata_port_operations ich_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -327,10 +339,10 @@ static const struct ata_port_operations ich_pata_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations piix_sata_ops = {
@@ -348,7 +360,7 @@ static const struct ata_port_operations piix_sata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -357,10 +369,10 @@ static const struct ata_port_operations piix_sata_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = piix_host_stop,
};
static const struct piix_map_db ich5_map_db = {
@@ -429,7 +441,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
};
static struct ata_port_info piix_port_info[] = {
- /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */
+ /* piix_pata_33: 0: PIIX4 at 33MHz */
{
.sht = &piix_sht,
.flags = PIIX_PATA_FLAGS,
@@ -531,6 +543,14 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
+ /* piix_pata_mwdma: 10: PIIX3 MWDMA only */
+ {
+ .sht = &piix_sht,
+ .flags = PIIX_PATA_FLAGS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .port_ops = &piix_pata_ops,
+ },
};
static struct pci_bits piix_enable_bits[] = {
@@ -557,6 +577,7 @@ struct ich_laptop {
static const struct ich_laptop ich_laptop[] = {
/* devid, subvendor, subdev */
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
+ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
/* end marker */
{ 0, }
};
@@ -620,7 +641,7 @@ 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);
}
@@ -764,7 +785,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
u16 master_data;
u8 speed = adev->dma_mode;
int devid = adev->devno + 2 * ap->port_no;
- u8 udma_enable;
+ u8 udma_enable = 0;
static const /* ISP RTC */
u8 timings[][2] = { { 0, 0 },
@@ -774,7 +795,8 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
{ 2, 3 }, };
pci_read_config_word(dev, master_port, &master_data);
- pci_read_config_byte(dev, 0x48, &udma_enable);
+ if (ap->udma_mask)
+ pci_read_config_byte(dev, 0x48, &udma_enable);
if (speed >= XFER_UDMA_0) {
unsigned int udma = adev->dma_mode - XFER_UDMA_0;
@@ -1047,6 +1069,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
+ struct device *dev = &pdev->dev;
struct ata_port_info port_info[2];
struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
struct piix_host_priv *hpriv;
@@ -1060,7 +1083,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!in_module_init)
return -ENODEV;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
@@ -1110,15 +1133,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return ata_pci_init_one(pdev, ppinfo, 2);
}
-static void piix_host_stop(struct ata_host *host)
-{
- struct piix_host_priv *hpriv = host->private_data;
-
- ata_host_stop(host);
-
- kfree(hpriv);
-}
-
static int __init piix_init(void)
{
int rc;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 011c0a8a2dc..25d8d3f778a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -59,6 +59,9 @@
#include "libata.h"
+#define DRV_VERSION "2.10" /* must be exactly four chars */
+
+
/* debounce timing parameters in msecs { interval, duration, timeout } */
const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
@@ -598,51 +601,7 @@ void ata_dev_disable(struct ata_device *dev)
}
/**
- * ata_pio_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
- * This technique was originally described in
- * Hale Landis's ATADRVR (www.ata-atapi.com), and
- * later found its way into the ATA/ATAPI spec.
- *
- * Write a pattern to the ATA shadow registers,
- * and if a device is present, it will respond by
- * correctly storing and echoing back the
- * ATA shadow register contents.
- *
- * LOCKING:
- * caller.
- */
-
-static unsigned int ata_pio_devchk(struct ata_port *ap,
- unsigned int device)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- u8 nsect, lbal;
-
- ap->ops->dev_select(ap, device);
-
- outb(0x55, ioaddr->nsect_addr);
- outb(0xaa, ioaddr->lbal_addr);
-
- outb(0xaa, ioaddr->nsect_addr);
- outb(0x55, ioaddr->lbal_addr);
-
- outb(0x55, ioaddr->nsect_addr);
- outb(0xaa, ioaddr->lbal_addr);
-
- nsect = inb(ioaddr->nsect_addr);
- lbal = inb(ioaddr->lbal_addr);
-
- if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
-
- return 0; /* nothing found */
-}
-
-/**
- * ata_mmio_devchk - PATA device presence detection
+ * ata_devchk - PATA device presence detection
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
@@ -659,25 +618,24 @@ static unsigned int ata_pio_devchk(struct ata_port *ap,
* caller.
*/
-static unsigned int ata_mmio_devchk(struct ata_port *ap,
- unsigned int device)
+static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
ap->ops->dev_select(ap, device);
- writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
- writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
- writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
- writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0xaa, ioaddr->nsect_addr);
+ iowrite8(0x55, ioaddr->lbal_addr);
- writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
- writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
- nsect = readb((void __iomem *) ioaddr->nsect_addr);
- lbal = readb((void __iomem *) ioaddr->lbal_addr);
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 0x55) && (lbal == 0xaa))
return 1; /* we found a device */
@@ -686,27 +644,6 @@ static unsigned int ata_mmio_devchk(struct ata_port *ap,
}
/**
- * ata_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
- * Dispatch ATA device presence detection, depending
- * on whether we are using PIO or MMIO to talk to the
- * ATA shadow registers.
- *
- * LOCKING:
- * caller.
- */
-
-static unsigned int ata_devchk(struct ata_port *ap,
- unsigned int device)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- return ata_mmio_devchk(ap, device);
- return ata_pio_devchk(ap, device);
-}
-
-/**
* ata_dev_classify - determine device type based on ATA-spec signature
* @tf: ATA taskfile register set for device to be identified
*
@@ -923,11 +860,7 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device)
else
tmp = ATA_DEVICE_OBS | ATA_DEV1;
- if (ap->flags & ATA_FLAG_MMIO) {
- writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
- } else {
- outb(tmp, ap->ioaddr.device_addr);
- }
+ iowrite8(tmp, ap->ioaddr.device_addr);
ata_pause(ap); /* needed; also flushes, for mmio */
}
@@ -1037,7 +970,7 @@ static unsigned int ata_id_xfermask(const u16 *id)
* the PIO timing number for the maximum. Turn it into
* a mask.
*/
- u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
+ u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF;
if (mode < 5) /* Valid PIO range */
pio_mask = (2 << mode) - 1;
else
@@ -1156,7 +1089,7 @@ void ata_port_flush_task(struct ata_port *ap)
ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
}
-void ata_qc_complete_internal(struct ata_queued_cmd *qc)
+static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
{
struct completion *waiting = qc->private_data;
@@ -1249,7 +1182,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
buflen += sg[i].length;
ata_sg_init(qc, sg, n_elem);
- qc->nsect = buflen / ATA_SECT_SIZE;
+ qc->nbytes = buflen;
}
qc->private_data = &wait;
@@ -1291,7 +1224,7 @@ 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 ((qc->flags & ATA_QCFLAG_FAILED) && !qc->err_mask) {
if (ata_msg_warn(ap))
ata_dev_printk(dev, KERN_WARNING,
"zero err_mask for failed "
@@ -1332,7 +1265,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
}
/**
- * ata_exec_internal_sg - execute libata internal command
+ * ata_exec_internal - execute libata internal command
* @dev: Device to which the command is sent
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
@@ -1353,11 +1286,17 @@ unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen)
{
- struct scatterlist sg;
+ struct scatterlist *psg = NULL, sg;
+ unsigned int n_elem = 0;
- sg_init_one(&sg, buf, buflen);
+ if (dma_dir != DMA_NONE) {
+ WARN_ON(!buf);
+ sg_init_one(&sg, buf, buflen);
+ psg = &sg;
+ n_elem++;
+ }
- return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
+ return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem);
}
/**
@@ -1601,6 +1540,8 @@ int ata_dev_configure(struct ata_device *dev)
const u16 *id = dev->id;
unsigned int xfer_mask;
char revbuf[7]; /* XYZ-99\0 */
+ char fwrevbuf[ATA_ID_FW_REV_LEN+1];
+ char modelbuf[ATA_ID_PROD_LEN+1];
int rc;
if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
@@ -1655,6 +1596,16 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
+ /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+ sizeof(fwrevbuf));
+
+ ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+ sizeof(modelbuf));
+
+ if (dev->id[59] & 0x100)
+ dev->multi_count = dev->id[59] & 0xff;
+
if (ata_id_has_lba(id)) {
const char *lba_desc;
char ncq_desc[20];
@@ -1674,13 +1625,16 @@ int ata_dev_configure(struct ata_device *dev)
ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
/* print device info to dmesg */
- if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "%s, "
- "max %s, %Lu sectors: %s %s\n",
- revbuf,
- ata_mode_string(xfer_mask),
+ if (ata_msg_drv(ap) && print_info) {
+ ata_dev_printk(dev, KERN_INFO,
+ "%s: %s, %s, max %s\n",
+ revbuf, modelbuf, fwrevbuf,
+ ata_mode_string(xfer_mask));
+ ata_dev_printk(dev, KERN_INFO,
+ "%Lu sectors, multi %u: %s %s\n",
(unsigned long long)dev->n_sectors,
- lba_desc, ncq_desc);
+ dev->multi_count, lba_desc, ncq_desc);
+ }
} else {
/* CHS */
@@ -1697,22 +1651,17 @@ int ata_dev_configure(struct ata_device *dev)
}
/* print device info to dmesg */
- if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "%s, "
- "max %s, %Lu sectors: CHS %u/%u/%u\n",
- revbuf,
- ata_mode_string(xfer_mask),
- (unsigned long long)dev->n_sectors,
- dev->cylinders, dev->heads,
- dev->sectors);
- }
-
- if (dev->id[59] & 0x100) {
- dev->multi_count = dev->id[59] & 0xff;
- if (ata_msg_drv(ap) && print_info)
+ if (ata_msg_drv(ap) && print_info) {
ata_dev_printk(dev, KERN_INFO,
- "ata%u: dev %u multi count %u\n",
- ap->id, dev->devno, dev->multi_count);
+ "%s: %s, %s, max %s\n",
+ revbuf, modelbuf, fwrevbuf,
+ ata_mode_string(xfer_mask));
+ 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,
+ dev->heads, dev->sectors);
+ }
}
dev->cdb_len = 16;
@@ -2384,6 +2333,10 @@ static int ata_dev_set_mode(struct ata_device *dev)
dev->flags |= ATA_DFLAG_PIO;
err_mask = ata_dev_set_xfermode(dev);
+ /* Old CFA may refuse this command, which is just fine */
+ if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
+ err_mask &= ~AC_ERR_DEV;
+
if (err_mask) {
ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
"(err_mask=0x%x)\n", err_mask);
@@ -2425,18 +2378,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
int i, rc = 0, used_dma = 0, found = 0;
/* has private set_mode? */
- if (ap->ops->set_mode) {
- /* FIXME: make ->set_mode handle no device case and
- * return error code and failing device on failure.
- */
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- if (ata_dev_ready(&ap->device[i])) {
- ap->ops->set_mode(ap);
- break;
- }
- }
- return 0;
- }
+ 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++) {
@@ -2496,7 +2439,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->device[i];
- /* don't udpate suspended devices' xfer mode */
+ /* don't update suspended devices' xfer mode */
if (!ata_dev_ready(dev))
continue;
@@ -2617,13 +2560,8 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
u8 nsect, lbal;
ap->ops->dev_select(ap, 1);
- if (ap->flags & ATA_FLAG_MMIO) {
- nsect = readb((void __iomem *) ioaddr->nsect_addr);
- lbal = readb((void __iomem *) ioaddr->lbal_addr);
- } else {
- nsect = inb(ioaddr->nsect_addr);
- lbal = inb(ioaddr->lbal_addr);
- }
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
if (time_after(jiffies, timeout)) {
@@ -2651,19 +2589,11 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
DPRINTK("ata%u: bus reset via SRST\n", ap->id);
/* software reset. causes dev0 to be selected */
- if (ap->flags & ATA_FLAG_MMIO) {
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- } else {
- outb(ap->ctl, ioaddr->ctl_addr);
- udelay(10);
- outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
- udelay(10);
- outb(ap->ctl, ioaddr->ctl_addr);
- }
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
/* spec mandates ">= 2ms" before checking status.
* We wait 150ms, because that was the magic delay used for
@@ -2748,8 +2678,7 @@ void ata_bus_reset(struct ata_port *ap)
ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
/* re-enable interrupts */
- if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
/* is double-select really necessary? */
if (ap->device[1].class != ATA_DEV_NONE)
@@ -2764,10 +2693,7 @@ void ata_bus_reset(struct ata_port *ap)
if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
/* set up device control for ATA_FLAG_SATA_RESET */
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
}
DPRINTK("EXIT\n");
@@ -3101,6 +3027,9 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
return 0;
}
+ /* wait a while before checking status, see SRST for more info */
+ msleep(150);
+
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
ata_port_printk(ap, KERN_ERR,
"COMRESET failed (device not ready)\n");
@@ -3141,11 +3070,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
sata_scr_write(ap, SCR_ERROR, serror);
/* re-enable interrupts */
- if (!ap->ops->error_handler) {
- /* FIXME: hack. create a hook instead */
- if (ap->ioaddr.ctl_addr)
- ata_irq_on(ap);
- }
+ if (!ap->ops->error_handler)
+ ap->ops->irq_on(ap);
/* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE)
@@ -3160,12 +3086,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
}
/* set up device control */
- if (ap->ioaddr.ctl_addr) {
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
- else
- outb(ap->ctl, ap->ioaddr.ctl_addr);
- }
+ if (ap->ioaddr.ctl_addr)
+ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
DPRINTK("EXIT\n");
}
@@ -3190,7 +3112,8 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
const u16 *new_id)
{
const u16 *old_id = dev->id;
- unsigned char model[2][41], serial[2][21];
+ unsigned char model[2][ATA_ID_PROD_LEN + 1];
+ unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
u64 new_n_sectors;
if (dev->class != new_class) {
@@ -3199,10 +3122,10 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
return 0;
}
- ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0]));
- ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1]));
- ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0]));
- ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1]));
+ ata_id_c_string(old_id, model[0], ATA_ID_PROD, sizeof(model[0]));
+ ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
+ ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
+ ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
new_n_sectors = ata_id_n_sectors(new_id);
if (strcmp(model[0], model[1])) {
@@ -3327,37 +3250,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ }
};
-static int ata_strim(char *s, size_t len)
-{
- len = strnlen(s, len);
-
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
- return len;
-}
-
unsigned long ata_device_blacklisted(const struct ata_device *dev)
{
- unsigned char model_num[40];
- unsigned char model_rev[16];
- unsigned int nlen, rlen;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+ unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
const struct ata_blacklist_entry *ad = ata_device_blacklist;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS,
- sizeof(model_rev));
- nlen = ata_strim(model_num, sizeof(model_num));
- rlen = ata_strim(model_rev, sizeof(model_rev));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+ ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
while (ad->model_num) {
- if (!strncmp(ad->model_num, model_num, nlen)) {
+ if (!strcmp(ad->model_num, model_num)) {
if (ad->model_rev == NULL)
return ad->horkage;
- if (!strncmp(ad->model_rev, model_rev, rlen))
+ if (!strcmp(ad->model_rev, model_rev))
return ad->horkage;
}
ad++;
@@ -3897,53 +3803,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
}
/**
- * ata_mmio_data_xfer - Transfer data by MMIO
- * @adev: device for this I/O
- * @buf: data buffer
- * @buflen: buffer length
- * @write_data: read/write
- *
- * Transfer data from/to the device data register by MMIO.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
-{
- struct ata_port *ap = adev->ap;
- unsigned int i;
- unsigned int words = buflen >> 1;
- u16 *buf16 = (u16 *) buf;
- void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
-
- /* Transfer multiple of 2 bytes */
- if (write_data) {
- for (i = 0; i < words; i++)
- writew(le16_to_cpu(buf16[i]), mmio);
- } else {
- for (i = 0; i < words; i++)
- buf16[i] = cpu_to_le16(readw(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);
- writew(le16_to_cpu(align_buf[0]), mmio);
- } else {
- align_buf[0] = cpu_to_le16(readw(mmio));
- memcpy(trailing_buf, align_buf, 1);
- }
- }
-}
-
-/**
- * ata_pio_data_xfer - Transfer data by PIO
+ * ata_data_xfer - Transfer data by PIO
* @adev: device to target
* @buf: data buffer
* @buflen: buffer length
@@ -3954,18 +3814,17 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
* LOCKING:
* Inherited from caller.
*/
-
-void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
+void ata_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;
/* Transfer multiple of 2 bytes */
if (write_data)
- outsw(ap->ioaddr.data_addr, buf, words);
+ iowrite16_rep(ap->ioaddr.data_addr, buf, words);
else
- insw(ap->ioaddr.data_addr, buf, words);
+ ioread16_rep(ap->ioaddr.data_addr, buf, words);
/* Transfer trailing 1 byte, if any. */
if (unlikely(buflen & 0x01)) {
@@ -3974,16 +3833,16 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
if (write_data) {
memcpy(align_buf, trailing_buf, 1);
- outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
+ iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
} else {
- align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr));
+ align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr));
memcpy(trailing_buf, align_buf, 1);
}
}
}
/**
- * ata_pio_data_xfer_noirq - Transfer data by PIO
+ * ata_data_xfer_noirq - Transfer data by PIO
* @adev: device to target
* @buf: data buffer
* @buflen: buffer length
@@ -3995,13 +3854,12 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
* LOCKING:
* Inherited from caller.
*/
-
-void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
+void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
+ unsigned int buflen, int write_data)
{
unsigned long flags;
local_irq_save(flags);
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
local_irq_restore(flags);
}
@@ -4025,11 +3883,11 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned int offset;
unsigned char *buf;
- if (qc->cursect == (qc->nsect - 1))
+ if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE)
ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
- offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
+ offset = sg[qc->cursg].offset + qc->cursg_ofs;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4054,10 +3912,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
}
- qc->cursect++;
- qc->cursg_ofs++;
+ qc->curbytes += ATA_SECT_SIZE;
+ qc->cursg_ofs += ATA_SECT_SIZE;
- if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
+ if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -4082,7 +3940,8 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
WARN_ON(qc->dev->multi_count == 0);
- nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count);
+ nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE,
+ qc->dev->multi_count);
while (nsect--)
ata_pio_sector(qc);
} else
@@ -4323,7 +4182,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
qc = ata_qc_from_tag(ap, qc->tag);
if (qc) {
if (likely(!(qc->err_mask & AC_ERR_HSM))) {
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
ata_qc_complete(qc);
} else
ata_port_freeze(ap);
@@ -4339,7 +4198,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
} else {
if (in_wq) {
spin_lock_irqsave(ap->lock, flags);
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
ata_qc_complete(qc);
spin_unlock_irqrestore(ap->lock, flags);
} else
@@ -5164,7 +5023,7 @@ idle_irq:
#ifdef ATA_IRQ_TRAP
if ((ap->stats.idle_irq % 1000) == 0) {
- ata_irq_ack(ap, 0); /* debug trap */
+ ap->ops->irq_ack(ap, 0); /* debug trap */
ata_port_printk(ap, KERN_WARNING, "irq trap\n");
return 1;
}
@@ -5505,54 +5364,25 @@ void ata_host_resume(struct ata_host *host)
* LOCKING:
* Inherited from caller.
*/
-
-int ata_port_start (struct ata_port *ap)
+int ata_port_start(struct ata_port *ap)
{
struct device *dev = ap->dev;
int rc;
- ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
+ ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
+ GFP_KERNEL);
if (!ap->prd)
return -ENOMEM;
rc = ata_pad_alloc(ap, dev);
- if (rc) {
- dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+ if (rc)
return rc;
- }
-
- DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
+ DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
+ (unsigned long long)ap->prd_dma);
return 0;
}
-
-/**
- * ata_port_stop - Undo ata_port_start()
- * @ap: Port to shut down
- *
- * Frees the PRD table.
- *
- * May be used as the port_stop() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-void ata_port_stop (struct ata_port *ap)
-{
- struct device *dev = ap->dev;
-
- dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
- ata_pad_free(ap, dev);
-}
-
-void ata_host_stop (struct ata_host *host)
-{
- if (host->mmio_base)
- iounmap(host->mmio_base);
-}
-
/**
* ata_dev_init - Initialize an ata_device structure
* @dev: Device structure to initialize
@@ -5726,6 +5556,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
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 (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+
+ scsi_host_put(ap->scsi_host);
+ }
+
+ if (host->ops->host_stop)
+ host->ops->host_stop(host);
+}
+
/**
* ata_sas_host_init - Initialize a host struct
* @host: host to initialize
@@ -5773,22 +5624,28 @@ int ata_device_add(const struct ata_probe_ent *ent)
int rc;
DPRINTK("ENTER\n");
-
+
if (ent->irq == 0) {
dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
return 0;
}
+
+ if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
+ return 0;
+
/* alloc a container for our list of ATA ports (buses) */
- host = kzalloc(sizeof(struct ata_host) +
- (ent->n_ports * sizeof(void *)), GFP_KERNEL);
+ host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
+ (ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host)
- return 0;
+ goto err_out;
+ devres_add(dev, host);
+ dev_set_drvdata(dev, host);
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->mmio_base = ent->mmio_base;
+ host->iomap = ent->iomap;
host->private_data = ent->private_data;
/* register each port bound to this device */
@@ -5826,8 +5683,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
(ap->pio_mask << ATA_SHIFT_PIO);
/* print per-port info to dmesg */
- ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
- "ctl 0x%lX bmdma 0x%lX irq %d\n",
+ 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,
@@ -5840,8 +5697,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
}
/* obtain irq, that may be shared between channels */
- rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
- DRV_NAME, host);
+ 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);
@@ -5854,15 +5711,19 @@ int ata_device_add(const struct ata_probe_ent *ent)
so trap it now */
BUG_ON(ent->irq == ent->irq2);
- rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
- DRV_NAME, host);
+ 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_free_irq;
+ goto err_out;
}
}
+ /* 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++) {
@@ -5931,24 +5792,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
ata_scsi_scan_host(ap);
}
- dev_set_drvdata(dev, host);
-
VPRINTK("EXIT, returning %u\n", ent->n_ports);
return ent->n_ports; /* success */
-err_out_free_irq:
- free_irq(ent->irq, host);
-err_out:
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- if (ap) {
- ap->ops->port_stop(ap);
- scsi_host_put(ap->scsi_host);
- }
- }
-
- kfree(host);
- VPRINTK("EXIT, returning 0\n");
+ err_out:
+ devres_release_group(dev, ata_device_add);
+ dev_set_drvdata(dev, NULL);
+ VPRINTK("EXIT, returning %d\n", rc);
return 0;
}
@@ -6011,76 +5861,20 @@ void ata_port_detach(struct ata_port *ap)
}
/**
- * ata_host_remove - PCI layer callback for device removal
- * @host: ATA host set that was removed
+ * ata_host_detach - Detach all ports of an ATA host
+ * @host: Host to detach
*
- * Unregister all objects associated with this host set. Free those
- * objects.
+ * Detach all ports of @host.
*
* LOCKING:
- * Inherited from calling layer (may sleep).
+ * Kernel thread context (may sleep).
*/
-
-void ata_host_remove(struct ata_host *host)
+void ata_host_detach(struct ata_host *host)
{
- unsigned int i;
+ int i;
for (i = 0; i < host->n_ports; i++)
ata_port_detach(host->ports[i]);
-
- free_irq(host->irq, host);
- if (host->irq2)
- free_irq(host->irq2, host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_scsi_release(ap->scsi_host);
-
- if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- /* FIXME: Add -ac IDE pci mods to remove these special cases */
- if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
- release_region(ATA_PRIMARY_CMD, 8);
- else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
- release_region(ATA_SECONDARY_CMD, 8);
- }
-
- scsi_host_put(ap->scsi_host);
- }
-
- if (host->ops->host_stop)
- host->ops->host_stop(host);
-
- kfree(host);
-}
-
-/**
- * ata_scsi_release - SCSI layer callback hook for host unload
- * @shost: libata host to be unloaded
- *
- * Performs all duties necessary to shut down a libata port...
- * Kill port kthread, disable port, and release resources.
- *
- * LOCKING:
- * Inherited from SCSI layer.
- *
- * RETURNS:
- * One.
- */
-
-int ata_scsi_release(struct Scsi_Host *shost)
-{
- struct ata_port *ap = ata_shost_to_port(shost);
-
- DPRINTK("ENTER\n");
-
- ap->ops->port_disable(ap);
- ap->ops->port_stop(ap);
-
- DPRINTK("EXIT\n");
- return 1;
}
struct ata_probe_ent *
@@ -6088,7 +5882,11 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+ /* 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)));
@@ -6138,37 +5936,23 @@ void ata_std_ports(struct ata_ioports *ioaddr)
#ifdef CONFIG_PCI
-void ata_pci_host_stop (struct ata_host *host)
-{
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- pci_iounmap(pdev, host->mmio_base);
-}
-
/**
* ata_pci_remove_one - PCI layer callback for device removal
* @pdev: PCI device that was removed
*
- * PCI layer indicates to libata via this hook that
- * hot-unplug or module unload event has occurred.
- * Handle this by unregistering all objects associated
- * with this PCI device. Free those objects. Then finally
- * release PCI resources and disable device.
+ * PCI layer indicates to libata via this hook that hot-unplug or
+ * module unload event has occurred. Detach all ports. Resource
+ * release is handled via devres.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*/
-
-void ata_pci_remove_one (struct pci_dev *pdev)
+void ata_pci_remove_one(struct pci_dev *pdev)
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
-
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- dev_set_drvdata(dev, NULL);
+ ata_host_detach(host);
}
/* move to PCI subsystem */
@@ -6215,12 +5999,22 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
}
}
-void ata_pci_device_do_resume(struct pci_dev *pdev)
+int ata_pci_device_do_resume(struct pci_dev *pdev)
{
+ int rc;
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- pci_enable_device(pdev);
+
+ rc = pcim_enable_device(pdev);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to enable device after resume (%d)\n", rc);
+ return rc;
+ }
+
pci_set_master(pdev);
+ return 0;
}
int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
@@ -6240,10 +6034,12 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
int ata_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
- ata_pci_device_do_resume(pdev);
- ata_host_resume(host);
- return 0;
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc == 0)
+ ata_host_resume(host);
+ return rc;
}
#endif /* CONFIG_PCI */
@@ -6389,8 +6185,7 @@ 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_port_detach);
-EXPORT_SYMBOL_GPL(ata_host_remove);
+EXPORT_SYMBOL_GPL(ata_host_detach);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
EXPORT_SYMBOL_GPL(ata_hsm_move);
@@ -6407,12 +6202,9 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
-EXPORT_SYMBOL_GPL(ata_port_stop);
-EXPORT_SYMBOL_GPL(ata_host_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
-EXPORT_SYMBOL_GPL(ata_mmio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq);
+EXPORT_SYMBOL_GPL(ata_data_xfer);
+EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
@@ -6449,7 +6241,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
-EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(sata_scr_valid);
EXPORT_SYMBOL_GPL(sata_scr_read);
@@ -6470,7 +6261,6 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_host_stop);
EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6494,3 +6284,7 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
EXPORT_SYMBOL_GPL(ata_do_eh);
+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);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 08ad44b3e48..52c85af7fe9 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1443,15 +1443,10 @@ static void ata_eh_report(struct ata_port *ap)
};
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
- unsigned int nbytes;
if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
continue;
- nbytes = qc->nbytes;
- if (!nbytes)
- nbytes = qc->nsect << 9;
-
ata_dev_printk(qc->dev, KERN_ERR,
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
"tag %d cdb 0x%x data %u %s\n "
@@ -1461,7 +1456,7 @@ static void ata_eh_report(struct ata_port *ap)
cmd->lbal, cmd->lbam, cmd->lbah,
cmd->hob_feature, cmd->hob_nsect,
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
- cmd->device, qc->tag, qc->cdb[0], nbytes,
+ cmd->device, qc->tag, qc->cdb[0], qc->nbytes,
dma_str[qc->dma_dir],
res->command, res->feature, res->nsect,
res->lbal, res->lbam, res->lbah,
@@ -1796,7 +1791,7 @@ static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
*r_failed_dev = dev;
DPRINTK("EXIT\n");
- return 0;
+ return rc;
}
/**
@@ -1979,6 +1974,10 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+ /* collect port action mask recorded in dev actions */
+ ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK;
+ ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK;
+
/* process hotplug request */
if (dev->flags & ATA_DFLAG_DETACH)
ata_eh_detach_dev(dev);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 664e1377b54..0009818a430 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -51,7 +51,7 @@
#define SECTOR_SIZE 512
-typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, const u8 *scsicmd);
+typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
static struct ata_device * __ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
@@ -149,6 +149,45 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
}
/**
+ * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+ * @sdev: SCSI device to get identify data for
+ * @arg: User buffer area for identify data
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+static int ata_get_identity(struct scsi_device *sdev, void __user *arg)
+{
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
+ u16 __user *dst = arg;
+ char buf[40];
+
+ if (!dev)
+ return -ENOMSG;
+
+ if (copy_to_user(dst, dev->id, ATA_ID_WORDS * sizeof(u16)))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_PROD, ATA_ID_PROD_LEN);
+ if (copy_to_user(dst + ATA_ID_PROD, buf, ATA_ID_PROD_LEN))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_FW_REV, ATA_ID_FW_REV_LEN);
+ if (copy_to_user(dst + ATA_ID_FW_REV, buf, ATA_ID_FW_REV_LEN))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ if (copy_to_user(dst + ATA_ID_SERNO, buf, ATA_ID_SERNO_LEN))
+ return -EFAULT;
+
+ return 0;
+}
+
+/**
* ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
* @scsidev: Device to which we are issuing command
* @arg: User provided data for issuing command
@@ -159,7 +198,6 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
* RETURNS:
* Zero on success, negative errno on error.
*/
-
int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
{
int rc = 0;
@@ -273,8 +311,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
{
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
- u8 args[7];
- struct scsi_sense_hdr sshdr;
+ u8 args[7], *sensebuf = NULL;
+ int cmd_result;
if (arg == NULL)
return -EINVAL;
@@ -282,10 +320,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT;
+ sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
+ if (!sensebuf)
+ return -ENOMEM;
+
memset(scsi_cmd, 0, sizeof(scsi_cmd));
scsi_cmd[0] = ATA_16;
scsi_cmd[1] = (3 << 1); /* Non-data */
- /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+ scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */
scsi_cmd[4] = args[1];
scsi_cmd[6] = args[2];
scsi_cmd[8] = args[3];
@@ -295,11 +337,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
- if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr,
- (10*HZ), 5))
+ cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
+ sensebuf, (10*HZ), 5, 0);
+
+ if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
+ u8 *desc = sensebuf + 8;
+ cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
+
+ /* If we set cc then ATA pass-through will cause a
+ * check condition even if no error. Filter that. */
+ if (cmd_result & SAM_STAT_CHECK_CONDITION) {
+ struct scsi_sense_hdr sshdr;
+ scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
+ &sshdr);
+ if (sshdr.sense_key==0 &&
+ sshdr.asc==0 && sshdr.ascq==0)
+ cmd_result &= ~SAM_STAT_CHECK_CONDITION;
+ }
+
+ /* Send userspace ATA registers */
+ if (sensebuf[0] == 0x72 && /* format is "descriptor" */
+ desc[0] == 0x09) {/* code is "ATA Descriptor" */
+ args[0] = desc[13]; /* status */
+ args[1] = desc[3]; /* error */
+ args[2] = desc[5]; /* sector count (0:7) */
+ args[3] = desc[7]; /* lbal */
+ args[4] = desc[9]; /* lbam */
+ args[5] = desc[11]; /* lbah */
+ args[6] = desc[12]; /* select */
+ if (copy_to_user(arg, args, sizeof(args)))
+ rc = -EFAULT;
+ }
+ }
+
+ if (cmd_result) {
rc = -EIO;
+ goto error;
+ }
- /* Need code to retrieve data from check condition? */
+ error:
+ kfree(sensebuf);
return rc;
}
@@ -320,6 +397,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return -EINVAL;
return 0;
+ case HDIO_GET_IDENTITY:
+ return ata_get_identity(scsidev, arg);
+
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
@@ -358,9 +438,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
* RETURNS:
* Command allocated, or %NULL if none available.
*/
-struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
- struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *))
+static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
+ struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
{
struct ata_queued_cmd *qc;
@@ -372,7 +452,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
if (cmd->use_sg) {
qc->__sg = (struct scatterlist *) cmd->request_buffer;
qc->n_elem = cmd->use_sg;
- } else {
+ } else if (cmd->request_bufflen) {
qc->__sg = &qc->sgent;
qc->n_elem = 1;
}
@@ -396,7 +476,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
* LOCKING:
* inherited from caller
*/
-void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
{
u8 stat = tf->command, err = tf->feature;
@@ -571,8 +651,8 @@ int ata_scsi_device_resume(struct scsi_device *sdev)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
- u8 *ascq, int verbose)
+static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
+ u8 *asc, u8 *ascq, int verbose)
{
int i;
@@ -935,7 +1015,6 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
/**
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY
* (to start). Perhaps these commands should be preceded by
@@ -948,22 +1027,25 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
- const u8 *scsicmd)
+static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
+ const u8 *cdb = scmd->cmnd;
+
+ if (scmd->cmd_len < 5)
+ goto invalid_fld;
tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf->protocol = ATA_PROT_NODATA;
- if (scsicmd[1] & 0x1) {
+ if (cdb[1] & 0x1) {
; /* ignore IMMED bit, violates sat-r05 */
}
- if (scsicmd[4] & 0x2)
+ if (cdb[4] & 0x2)
goto invalid_fld; /* LOEJ bit set not supported */
- if (((scsicmd[4] >> 4) & 0xf) != 0)
+ if (((cdb[4] >> 4) & 0xf) != 0)
goto invalid_fld; /* power conditions not supported */
- if (scsicmd[4] & 0x1) {
+ if (cdb[4] & 0x1) {
tf->nsect = 1; /* 1 sector, lba=0 */
if (qc->dev->flags & ATA_DFLAG_LBA) {
@@ -981,11 +1063,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else {
- tf->nsect = 0; /* time period value (0 implies now) */
- tf->command = ATA_CMD_STANDBY;
- /* Consider: ATA STANDBY IMMEDIATE command */
- }
+ } else
+ /* Issue ATA STANDBY IMMEDIATE command */
+ tf->command = ATA_CMD_STANDBYNOW1;
+
/*
* Standby and Idle condition timers could be implemented but that
* would require libata to implement the Power condition mode page
@@ -996,7 +1077,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc,
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
}
@@ -1005,7 +1086,6 @@ invalid_fld:
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate (ignored)
*
* Sets up an ATA taskfile to issue FLUSH CACHE or
* FLUSH CACHE EXT.
@@ -1016,8 +1096,7 @@ invalid_fld:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &qc->tf;
@@ -1034,7 +1113,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
/**
* scsi_6_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 6-byte commands.
*
@@ -1042,18 +1121,17 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("six-byte command\n");
- lba |= ((u64)scsicmd[2]) << 8;
- lba |= ((u64)scsicmd[3]);
+ lba |= ((u64)cdb[2]) << 8;
+ lba |= ((u64)cdb[3]);
- len |= ((u32)scsicmd[4]);
+ len |= ((u32)cdb[4]);
*plba = lba;
*plen = len;
@@ -1061,7 +1139,7 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_10_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 10-byte commands.
*
@@ -1069,21 +1147,20 @@ static void scsi_6_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("ten-byte command\n");
- lba |= ((u64)scsicmd[2]) << 24;
- lba |= ((u64)scsicmd[3]) << 16;
- lba |= ((u64)scsicmd[4]) << 8;
- lba |= ((u64)scsicmd[5]);
+ lba |= ((u64)cdb[2]) << 24;
+ lba |= ((u64)cdb[3]) << 16;
+ lba |= ((u64)cdb[4]) << 8;
+ lba |= ((u64)cdb[5]);
- len |= ((u32)scsicmd[7]) << 8;
- len |= ((u32)scsicmd[8]);
+ len |= ((u32)cdb[7]) << 8;
+ len |= ((u32)cdb[8]);
*plba = lba;
*plen = len;
@@ -1091,7 +1168,7 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* scsi_16_lba_len - Get LBA and transfer length
- * @scsicmd: SCSI command to translate
+ * @cdb: SCSI command to translate
*
* Calculate LBA and transfer length for 16-byte commands.
*
@@ -1099,27 +1176,26 @@ static void scsi_10_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* @plba: the LBA
* @plen: the transfer length
*/
-
-static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
+static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
u32 len = 0;
VPRINTK("sixteen-byte command\n");
- lba |= ((u64)scsicmd[2]) << 56;
- lba |= ((u64)scsicmd[3]) << 48;
- lba |= ((u64)scsicmd[4]) << 40;
- lba |= ((u64)scsicmd[5]) << 32;
- lba |= ((u64)scsicmd[6]) << 24;
- lba |= ((u64)scsicmd[7]) << 16;
- lba |= ((u64)scsicmd[8]) << 8;
- lba |= ((u64)scsicmd[9]);
+ lba |= ((u64)cdb[2]) << 56;
+ lba |= ((u64)cdb[3]) << 48;
+ lba |= ((u64)cdb[4]) << 40;
+ lba |= ((u64)cdb[5]) << 32;
+ lba |= ((u64)cdb[6]) << 24;
+ lba |= ((u64)cdb[7]) << 16;
+ lba |= ((u64)cdb[8]) << 8;
+ lba |= ((u64)cdb[9]);
- len |= ((u32)scsicmd[10]) << 24;
- len |= ((u32)scsicmd[11]) << 16;
- len |= ((u32)scsicmd[12]) << 8;
- len |= ((u32)scsicmd[13]);
+ len |= ((u32)cdb[10]) << 24;
+ len |= ((u32)cdb[11]) << 16;
+ len |= ((u32)cdb[12]) << 8;
+ len |= ((u32)cdb[13]);
*plba = lba;
*plen = len;
@@ -1128,7 +1204,6 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts SCSI VERIFY command to an ATA READ VERIFY command.
*
@@ -1138,23 +1213,28 @@ static void scsi_16_lba_len(const u8 *scsicmd, u64 *plba, u32 *plen)
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_taskfile *tf = &qc->tf;
struct ata_device *dev = qc->dev;
u64 dev_sectors = qc->dev->n_sectors;
+ const u8 *cdb = scmd->cmnd;
u64 block;
u32 n_block;
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->protocol = ATA_PROT_NODATA;
- if (scsicmd[0] == VERIFY)
- scsi_10_lba_len(scsicmd, &block, &n_block);
- else if (scsicmd[0] == VERIFY_16)
- scsi_16_lba_len(scsicmd, &block, &n_block);
- else
+ if (cdb[0] == VERIFY) {
+ if (scmd->cmd_len < 10)
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ } else if (cdb[0] == VERIFY_16) {
+ if (scmd->cmd_len < 16)
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ } else
goto invalid_fld;
if (!n_block)
@@ -1229,24 +1309,23 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, const u8 *sc
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
/**
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
- * @scsicmd: SCSI command to translate
*
* Converts any of six SCSI read/write commands into the
* ATA counterpart, including starting sector (LBA),
@@ -1262,29 +1341,33 @@ nothing_to_do:
* RETURNS:
* Zero on success, non-zero on error.
*/
-
-static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+ const u8 *cdb = scmd->cmnd;
unsigned int tf_flags = 0;
u64 block;
u32 n_block;
int rc;
- if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
- scsicmd[0] == WRITE_16)
+ if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
tf_flags |= ATA_TFLAG_WRITE;
/* Calculate the SCSI LBA, transfer length and FUA. */
- switch (scsicmd[0]) {
+ switch (cdb[0]) {
case READ_10:
case WRITE_10:
- scsi_10_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 10))
+ goto invalid_fld;
+ scsi_10_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
case READ_6:
case WRITE_6:
- scsi_6_lba_len(scsicmd, &block, &n_block);
+ if (unlikely(scmd->cmd_len < 6))
+ goto invalid_fld;
+ scsi_6_lba_len(cdb, &block, &n_block);
/* for 6-byte r/w commands, transfer length 0
* means 256 blocks of data, not 0 block.
@@ -1294,8 +1377,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
break;
case READ_16:
case WRITE_16:
- scsi_16_lba_len(scsicmd, &block, &n_block);
- if (unlikely(scsicmd[1] & (1 << 3)))
+ if (unlikely(scmd->cmd_len < 16))
+ goto invalid_fld;
+ scsi_16_lba_len(cdb, &block, &n_block);
+ if (unlikely(cdb[1] & (1 << 3)))
tf_flags |= ATA_TFLAG_FUA;
break;
default:
@@ -1315,7 +1400,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
goto nothing_to_do;
qc->flags |= ATA_QCFLAG_IO;
- qc->nsect = n_block;
+ qc->nbytes = n_block * ATA_SECT_SIZE;
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
qc->tag);
@@ -1326,17 +1411,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
goto out_of_range;
/* treat all other errors as -EINVAL, fall through */
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
out_of_range:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
/* "Logical Block Address out of range" */
return 1;
nothing_to_do:
- qc->scsicmd->result = SAM_STAT_GOOD;
+ scmd->result = SAM_STAT_GOOD;
return 1;
}
@@ -1456,7 +1541,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
ata_xlat_func_t xlat_func)
{
struct ata_queued_cmd *qc;
- u8 *scsicmd = cmd->cmnd;
int is_io = xlat_func == ata_scsi_rw_xlat;
VPRINTK("ENTER\n");
@@ -1488,7 +1572,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
qc->complete_fn = ata_scsi_qc_complete;
- if (xlat_func(qc, scsicmd))
+ if (xlat_func(qc))
goto early_finish;
/* select device, send command to hardware */
@@ -1539,7 +1623,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- buf = kmap_atomic(sg->page, KM_USER0) + sg->offset;
+ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
@@ -1567,7 +1651,7 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
- kunmap_atomic(buf - sg->offset, KM_USER0);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
@@ -1655,8 +1739,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
if (buflen > 35) {
memcpy(&rbuf[8], "ATA ", 8);
- ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
- ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
+ ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
+ ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
if (rbuf[32] == 0 || rbuf[32] == ' ')
memcpy(&rbuf[32], "n/a ", 4);
}
@@ -1725,13 +1809,13 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
0,
0x80, /* this page code */
0,
- ATA_SERNO_LEN, /* page len */
+ ATA_ID_SERNO_LEN, /* page len */
};
memcpy(rbuf, hdr, sizeof(hdr));
- if (buflen > (ATA_SERNO_LEN + 4 - 1))
+ if (buflen > (ATA_ID_SERNO_LEN + 4 - 1))
ata_id_string(args->id, (unsigned char *) &rbuf[4],
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
return 0;
}
@@ -1756,19 +1840,18 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
{
int num;
const int sat_model_serial_desc_len = 68;
- const int ata_model_byte_len = 40;
rbuf[1] = 0x83; /* this page code */
num = 4;
- if (buflen > (ATA_SERNO_LEN + num + 3)) {
+ if (buflen > (ATA_ID_SERNO_LEN + num + 3)) {
/* piv=0, assoc=lu, code_set=ACSII, designator=vendor */
rbuf[num + 0] = 2;
- rbuf[num + 3] = ATA_SERNO_LEN;
+ rbuf[num + 3] = ATA_ID_SERNO_LEN;
num += 4;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
- num += ATA_SERNO_LEN;
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ num += ATA_ID_SERNO_LEN;
}
if (buflen > (sat_model_serial_desc_len + num + 3)) {
/* SAT defined lu model and serial numbers descriptor */
@@ -1780,11 +1863,11 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
memcpy(rbuf + num, "ATA ", 8);
num += 8;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_PROD_OFS, ata_model_byte_len);
- num += ata_model_byte_len;
+ ATA_ID_PROD, ATA_ID_PROD_LEN);
+ num += ATA_ID_PROD_LEN;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
- num += ATA_SERNO_LEN;
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ num += ATA_ID_SERNO_LEN;
}
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
return 0;
@@ -1912,15 +1995,15 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
*/
static int ata_dev_supports_fua(u16 *id)
{
- unsigned char model[41], fw[9];
+ unsigned char model[ATA_ID_PROD_LEN + 1], fw[ATA_ID_FW_REV_LEN + 1];
if (!libata_fua)
return 0;
if (!ata_id_has_fua(id))
return 0;
- ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model));
- ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw));
+ ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
+ ata_id_c_string(id, fw, ATA_ID_FW_REV, sizeof(fw));
if (strcmp(model, "Maxtor"))
return 1;
@@ -2344,7 +2427,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
/**
* atapi_xlat - Initialize PACKET taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI CDB associated with this PACKET command
*
* LOCKING:
* spin_lock_irqsave(host lock)
@@ -2352,25 +2434,25 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
* RETURNS:
* Zero on success, non-zero on failure.
*/
-
-static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
{
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
int using_pio = (dev->flags & ATA_DFLAG_PIO);
- int nodata = (cmd->sc_data_direction == DMA_NONE);
+ int nodata = (scmd->sc_data_direction == DMA_NONE);
if (!using_pio)
/* Check whether ATAPI DMA is safe */
if (ata_check_atapi_dma(qc))
using_pio = 1;
- memcpy(&qc->cdb, scsicmd, dev->cdb_len);
+ memset(qc->cdb, 0, dev->cdb_len);
+ memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
qc->complete_fn = atapi_qc_complete;
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
- if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
qc->tf.flags |= ATA_TFLAG_WRITE;
DPRINTK("direction: write\n");
}
@@ -2392,12 +2474,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
qc->tf.protocol = ATA_PROT_ATAPI_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (cmd->sc_data_direction != DMA_TO_DEVICE))
+ if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
- qc->nbytes = cmd->request_bufflen;
+ qc->nbytes = scmd->request_bufflen;
return 0;
}
@@ -2517,28 +2599,27 @@ ata_scsi_map_proto(u8 byte1)
/**
* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
* @qc: command structure to be initialized
- * @scsicmd: SCSI command to convert
*
* Handles either 12 or 16-byte versions of the CDB.
*
* RETURNS:
* Zero on success, non-zero on failure.
*/
-static unsigned int
-ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
+static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &(qc->tf);
- struct scsi_cmnd *cmd = qc->scsicmd;
+ struct scsi_cmnd *scmd = qc->scsicmd;
struct ata_device *dev = qc->dev;
+ const u8 *cdb = scmd->cmnd;
- if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
+ if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
goto invalid_fld;
/* We may not issue DMA commands if no DMA mode is set */
if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld;
- if (scsicmd[1] & 0xe0)
+ if (cdb[1] & 0xe0)
/* PIO multi not supported yet */
goto invalid_fld;
@@ -2546,18 +2627,18 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
*/
- if (scsicmd[0] == ATA_16) {
+ if (cdb[0] == ATA_16) {
/*
* 16-byte CDB - may contain extended commands.
*
* If that is the case, copy the upper byte register values.
*/
- if (scsicmd[1] & 0x01) {
- tf->hob_feature = scsicmd[3];
- tf->hob_nsect = scsicmd[5];
- tf->hob_lbal = scsicmd[7];
- tf->hob_lbam = scsicmd[9];
- tf->hob_lbah = scsicmd[11];
+ if (cdb[1] & 0x01) {
+ tf->hob_feature = cdb[3];
+ tf->hob_nsect = cdb[5];
+ tf->hob_lbal = cdb[7];
+ tf->hob_lbam = cdb[9];
+ tf->hob_lbah = cdb[11];
tf->flags |= ATA_TFLAG_LBA48;
} else
tf->flags &= ~ATA_TFLAG_LBA48;
@@ -2565,26 +2646,26 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
/*
* Always copy low byte, device and command registers.
*/
- tf->feature = scsicmd[4];
- tf->nsect = scsicmd[6];
- tf->lbal = scsicmd[8];
- tf->lbam = scsicmd[10];
- tf->lbah = scsicmd[12];
- tf->device = scsicmd[13];
- tf->command = scsicmd[14];
+ tf->feature = cdb[4];
+ tf->nsect = cdb[6];
+ tf->lbal = cdb[8];
+ tf->lbam = cdb[10];
+ tf->lbah = cdb[12];
+ tf->device = cdb[13];
+ tf->command = cdb[14];
} else {
/*
* 12-byte CDB - incapable of extended commands.
*/
tf->flags &= ~ATA_TFLAG_LBA48;
- tf->feature = scsicmd[3];
- tf->nsect = scsicmd[4];
- tf->lbal = scsicmd[5];
- tf->lbam = scsicmd[6];
- tf->lbah = scsicmd[7];
- tf->device = scsicmd[8];
- tf->command = scsicmd[9];
+ tf->feature = cdb[3];
+ tf->nsect = cdb[4];
+ tf->lbal = cdb[5];
+ tf->lbam = cdb[6];
+ tf->lbah = cdb[7];
+ tf->device = cdb[8];
+ tf->command = cdb[9];
}
/*
* If slave is possible, enforce correct master/slave bit
@@ -2611,7 +2692,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
*/
tf->flags |= (ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE);
- if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ if (scmd->sc_data_direction == DMA_TO_DEVICE)
tf->flags |= ATA_TFLAG_WRITE;
/*
@@ -2620,7 +2701,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
+ qc->nbytes = scmd->request_bufflen;
/* request result TF */
qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -2628,7 +2709,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
return 0;
invalid_fld:
- ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+ ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
/* "Invalid field in cdb" */
return 1;
}
@@ -2701,22 +2782,29 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
#endif
}
-static inline int __ata_scsi_queuecmd(struct scsi_cmnd *cmd,
+static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
void (*done)(struct scsi_cmnd *),
struct ata_device *dev)
{
int rc = 0;
+ if (unlikely(!scmd->cmd_len)) {
+ ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+ scmd->result = DID_ERROR << 16;
+ done(scmd);
+ return 0;
+ }
+
if (dev->class == ATA_DEV_ATA) {
ata_xlat_func_t xlat_func = ata_get_xlat_func(dev,
- cmd->cmnd[0]);
+ scmd->cmnd[0]);
if (xlat_func)
- rc = ata_scsi_translate(dev, cmd, done, xlat_func);
+ rc = ata_scsi_translate(dev, scmd, done, xlat_func);
else
- ata_scsi_simulate(dev, cmd, done);
+ ata_scsi_simulate(dev, scmd, done);
} else
- rc = ata_scsi_translate(dev, cmd, done, atapi_xlat);
+ rc = ata_scsi_translate(dev, scmd, done, atapi_xlat);
return rc;
}
@@ -3011,7 +3099,8 @@ void ata_scsi_hotplug(struct work_struct *work)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
if (ata_dev_enabled(dev) && !dev->sdev) {
- queue_delayed_work(ata_aux_wq, &ap->hotplug_task, HZ);
+ queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
+ round_jiffies_relative(HZ));
break;
}
}
@@ -3216,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init);
void ata_sas_port_destroy(struct ata_port *ap)
{
- ap->ops->port_stop(ap);
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
kfree(ap);
}
EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 10ee22ae5c1..16bc3e35bdd 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -56,10 +56,7 @@ u8 ata_irq_on(struct ata_port *ap)
ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
tmp = ata_wait_idle(ap);
ap->ops->irq_clear(ap);
@@ -67,92 +64,74 @@ u8 ata_irq_on(struct ata_port *ap)
return tmp;
}
+u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
+
/**
- * ata_tf_load_pio - send taskfile registers to host controller
- * @ap: Port to which output is sent
- * @tf: ATA taskfile register set
+ * ata_irq_ack - Acknowledge a device interrupt.
+ * @ap: Port on which interrupts are enabled.
*
- * Outputs ATA taskfile to standard ATA host controller.
+ * Wait up to 10 ms for legacy IDE device to become idle (BUSY
+ * or BUSY+DRQ clear). Obtain dma status and port status from
+ * device. Clear the interrupt. Return port status.
*
* LOCKING:
- * Inherited from caller.
*/
-static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+ u8 host_stat, post_stat, status;
- if (tf->ctl != ap->last_ctl) {
- outb(tf->ctl, ioaddr->ctl_addr);
- ap->last_ctl = tf->ctl;
- ata_wait_idle(ap);
- }
+ status = ata_busy_wait(ap, bits, 1000);
+ if (status & bits)
+ if (ata_msg_err(ap))
+ printk(KERN_ERR "abnormal status 0x%X\n", status);
- if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- outb(tf->hob_feature, ioaddr->feature_addr);
- outb(tf->hob_nsect, ioaddr->nsect_addr);
- outb(tf->hob_lbal, ioaddr->lbal_addr);
- outb(tf->hob_lbam, ioaddr->lbam_addr);
- outb(tf->hob_lbah, ioaddr->lbah_addr);
- 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);
- }
+ /* get controller status; clear intr, err bits */
+ host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- if (is_addr) {
- outb(tf->feature, ioaddr->feature_addr);
- outb(tf->nsect, ioaddr->nsect_addr);
- outb(tf->lbal, ioaddr->lbal_addr);
- outb(tf->lbam, ioaddr->lbam_addr);
- outb(tf->lbah, ioaddr->lbah_addr);
- 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);
- }
+ post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- if (tf->flags & ATA_TFLAG_DEVICE) {
- outb(tf->device, ioaddr->device_addr);
- VPRINTK("device 0x%X\n", tf->device);
- }
+ 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);
- ata_wait_idle(ap);
+ return status;
}
+u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq) { return 0; }
+
/**
- * ata_tf_load_mmio - send taskfile registers to host controller
+ * ata_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
- * Outputs ATA taskfile to standard ATA host controller using MMIO.
+ * Outputs ATA taskfile to standard ATA host controller.
*
* LOCKING:
* Inherited from caller.
*/
-static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+void ata_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) {
- writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+ iowrite8(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
- writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
- writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
- writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
- writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
+ iowrite8(tf->hob_feature, ioaddr->feature_addr);
+ iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
+ iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
+ iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
+ iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
tf->hob_feature,
tf->hob_nsect,
@@ -162,11 +141,11 @@ static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
}
if (is_addr) {
- writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
- writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
- writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
- writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
- writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+ iowrite8(tf->feature, ioaddr->feature_addr);
+ iowrite8(tf->nsect, ioaddr->nsect_addr);
+ iowrite8(tf->lbal, ioaddr->lbal_addr);
+ iowrite8(tf->lbam, ioaddr->lbam_addr);
+ iowrite8(tf->lbah, ioaddr->lbah_addr);
VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
tf->feature,
tf->nsect,
@@ -176,108 +155,34 @@ static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
}
if (tf->flags & ATA_TFLAG_DEVICE) {
- writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+ iowrite8(tf->device, ioaddr->device_addr);
VPRINTK("device 0x%X\n", tf->device);
}
ata_wait_idle(ap);
}
-
-/**
- * ata_tf_load - send taskfile registers to host controller
- * @ap: Port to which output is sent
- * @tf: ATA taskfile register set
- *
- * 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.
- *
- * May be used as the tf_load() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_tf_load_mmio(ap, tf);
- else
- ata_tf_load_pio(ap, tf);
-}
-
-/**
- * ata_exec_command_pio - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues PIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
- outb(tf->command, ap->ioaddr.command_addr);
- ata_pause(ap);
-}
-
-
/**
- * ata_exec_command_mmio - issue ATA command to host controller
+ * ata_exec_command - issue ATA command to host controller
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
*
- * Issues MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * FIXME: missing write posting for 400nS delay enforcement
+ * Issues ATA command, with proper synchronization with interrupt
+ * handler / other threads.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_exec_command_mmio(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);
- writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
+ iowrite8(tf->command, ap->ioaddr.command_addr);
ata_pause(ap);
}
-
/**
- * ata_exec_command - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues PIO/MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_exec_command_mmio(ap, tf);
- else
- ata_exec_command_pio(ap, tf);
-}
-
-/**
- * ata_tf_read_pio - input device's ATA taskfile shadow registers
+ * ata_tf_read - input device's ATA taskfile shadow registers
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
@@ -287,121 +192,28 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
* LOCKING:
* Inherited from caller.
*/
-
-static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- tf->command = ata_check_status(ap);
- tf->feature = inb(ioaddr->error_addr);
- tf->nsect = inb(ioaddr->nsect_addr);
- tf->lbal = inb(ioaddr->lbal_addr);
- tf->lbam = inb(ioaddr->lbam_addr);
- tf->lbah = inb(ioaddr->lbah_addr);
- tf->device = inb(ioaddr->device_addr);
-
- if (tf->flags & ATA_TFLAG_LBA48) {
- outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
- tf->hob_feature = inb(ioaddr->error_addr);
- tf->hob_nsect = inb(ioaddr->nsect_addr);
- tf->hob_lbal = inb(ioaddr->lbal_addr);
- tf->hob_lbam = inb(ioaddr->lbam_addr);
- tf->hob_lbah = inb(ioaddr->lbah_addr);
- }
-}
-
-/**
- * ata_tf_read_mmio - input device's ATA taskfile shadow registers
- * @ap: Port from which input is read
- * @tf: ATA taskfile register set for storing input
- *
- * Reads ATA taskfile registers for currently-selected device
- * into @tf via MMIO.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
tf->command = ata_check_status(ap);
- tf->feature = readb((void __iomem *)ioaddr->error_addr);
- tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
- tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
- tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
- tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
- tf->device = readb((void __iomem *)ioaddr->device_addr);
+ tf->feature = ioread8(ioaddr->error_addr);
+ tf->nsect = ioread8(ioaddr->nsect_addr);
+ tf->lbal = ioread8(ioaddr->lbal_addr);
+ tf->lbam = ioread8(ioaddr->lbam_addr);
+ tf->lbah = ioread8(ioaddr->lbah_addr);
+ tf->device = ioread8(ioaddr->device_addr);
if (tf->flags & ATA_TFLAG_LBA48) {
- writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
- tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
- tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
- tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
- tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
- tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
+ iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
+ tf->hob_feature = ioread8(ioaddr->error_addr);
+ tf->hob_nsect = ioread8(ioaddr->nsect_addr);
+ tf->hob_lbal = ioread8(ioaddr->lbal_addr);
+ tf->hob_lbam = ioread8(ioaddr->lbam_addr);
+ tf->hob_lbah = ioread8(ioaddr->lbah_addr);
}
}
-
-/**
- * ata_tf_read - input device's ATA taskfile shadow registers
- * @ap: Port from which input is read
- * @tf: ATA taskfile register set for storing input
- *
- * Reads ATA taskfile registers for currently-selected device
- * into @tf.
- *
- * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
- * is set, also reads the hob registers.
- *
- * May be used as the tf_read() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_tf_read_mmio(ap, tf);
- else
- ata_tf_read_pio(ap, tf);
-}
-
-/**
- * ata_check_status_pio - Read device status reg & clear interrupt
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
- * and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
-static u8 ata_check_status_pio(struct ata_port *ap)
-{
- return inb(ap->ioaddr.status_addr);
-}
-
-/**
- * ata_check_status_mmio - Read device status reg & clear interrupt
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
- * via MMIO and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
-static u8 ata_check_status_mmio(struct ata_port *ap)
-{
- return readb((void __iomem *) ap->ioaddr.status_addr);
-}
-
-
/**
* ata_check_status - Read device status reg & clear interrupt
* @ap: port where the device is
@@ -410,19 +222,14 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
* and return its value. This also clears pending interrupts
* from this device
*
- * May be used as the check_status() entry in ata_port_operations.
- *
* LOCKING:
* Inherited from caller.
*/
u8 ata_check_status(struct ata_port *ap)
{
- if (ap->flags & ATA_FLAG_MMIO)
- return ata_check_status_mmio(ap);
- return ata_check_status_pio(ap);
+ return ioread8(ap->ioaddr.status_addr);
}
-
/**
* ata_altstatus - Read device alternate status reg
* @ap: port where the device is
@@ -441,58 +248,52 @@ u8 ata_altstatus(struct ata_port *ap)
if (ap->ops->check_altstatus)
return ap->ops->check_altstatus(ap);
- if (ap->flags & ATA_FLAG_MMIO)
- return readb((void __iomem *)ap->ioaddr.altstatus_addr);
- return inb(ap->ioaddr.altstatus_addr);
+ return ioread8(ap->ioaddr.altstatus_addr);
}
/**
- * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
+ * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
+void ata_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 = (void __iomem *) ap->ioaddr.bmdma_addr;
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
- writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
- dmactl = readb(mmio + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
if (!rw)
dmactl |= ATA_DMA_WR;
- writeb(dmactl, mmio + ATA_DMA_CMD);
+ iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
/**
- * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction
+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
+void ata_bmdma_start (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
u8 dmactl;
/* start host DMA transaction */
- dmactl = readb(mmio + ATA_DMA_CMD);
- writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* Strictly, one may wish to issue a readb() here, to
* flush the mmio write. However, control also passes
@@ -508,96 +309,6 @@ static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
}
/**
- * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO)
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 dmactl;
-
- /* load PRD table addr. */
- outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
- /* specify data direction, triple-check start bit is clear */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
- if (!rw)
- dmactl |= ATA_DMA_WR;
- outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
-}
-
-/**
- * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO)
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- u8 dmactl;
-
- /* start host DMA transaction */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- outb(dmactl | ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-}
-
-
-/**
- * ata_bmdma_start - Start a PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * Writes the ATA_DMA_START flag to the DMA command register.
- *
- * May be used as the bmdma_start() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_start(struct ata_queued_cmd *qc)
-{
- if (qc->ap->flags & ATA_FLAG_MMIO)
- ata_bmdma_start_mmio(qc);
- else
- ata_bmdma_start_pio(qc);
-}
-
-
-/**
- * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * Writes address of PRD table to device's PRD Table Address
- * register, sets the DMA control register, and calls
- * ops->exec_command() to start the transfer.
- *
- * May be used as the bmdma_setup() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_setup(struct ata_queued_cmd *qc)
-{
- if (qc->ap->flags & ATA_FLAG_MMIO)
- ata_bmdma_setup_mmio(qc);
- else
- ata_bmdma_setup_pio(qc);
-}
-
-
-/**
* ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
* @ap: Port associated with this ATA transaction.
*
@@ -608,23 +319,16 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
void ata_bmdma_irq_clear(struct ata_port *ap)
{
- if (!ap->ioaddr.bmdma_addr)
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ if (!mmio)
return;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio =
- ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
- writeb(readb(mmio), mmio);
- } else {
- unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
- outb(inb(addr), addr);
- }
+ iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
}
-
/**
* ata_bmdma_status - Read PCI IDE BMDMA status
* @ap: Port associated with this ATA transaction.
@@ -636,19 +340,11 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
u8 ata_bmdma_status(struct ata_port *ap)
{
- u8 host_stat;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
- host_stat = readb(mmio + ATA_DMA_STATUS);
- } else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- return host_stat;
+ return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
-
/**
* ata_bmdma_stop - Stop PCI IDE BMDMA transfer
* @qc: Command we are ending DMA for
@@ -660,21 +356,14 @@ u8 ata_bmdma_status(struct ata_port *ap)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
void ata_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
- /* clear start/stop bit */
- writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
- mmio + ATA_DMA_CMD);
- } else {
- /* clear start/stop bit */
- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- }
+ /* clear start/stop bit */
+ iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+ mmio + ATA_DMA_CMD);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
@@ -696,10 +385,7 @@ void ata_bmdma_freeze(struct ata_port *ap)
ap->ctl |= ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
/* Under certain circumstances, some controllers raise IRQ on
* ATA_NIEN manipulation. Also, many controllers fail to mask
@@ -724,8 +410,7 @@ void ata_bmdma_thaw(struct ata_port *ap)
/* clear & re-enable interrupts */
ata_chk_status(ap);
ap->ops->irq_clear(ap);
- if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
}
/**
@@ -775,7 +460,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
* really a timeout event, adjust error mask and
* cancel frozen state.
*/
- if (qc->err_mask == AC_ERR_TIMEOUT && host_stat & ATA_DMA_ERR) {
+ if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1;
}
@@ -827,10 +512,26 @@ void ata_bmdma_error_handler(struct ata_port *ap)
*/
void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
{
- ata_bmdma_stop(qc);
+ if (qc->ap->ioaddr.bmdma_addr)
+ ata_bmdma_stop(qc);
}
#ifdef CONFIG_PCI
+
+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;
+ }
+ return 1;
+}
+
/**
* ata_pci_init_native_mode - Initialize native-mode driver
* @pdev: pci device to be initialized
@@ -852,43 +553,62 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
{
- struct ata_probe_ent *probe_ent =
- ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
- int p = 0;
- unsigned long bmdma;
+ 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;
+ }
+ }
+
+ 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 = pci_resource_start(pdev, 0);
+ probe_ent->port[p].cmd_addr = iomap[0];
probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr =
- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
- bmdma = pci_resource_start(pdev, 4);
- if (bmdma) {
- if (inb(bmdma + 2) & 0x80)
+ 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 = bmdma;
+ probe_ent->port[p].bmdma_addr = iomap[4];
}
ata_std_ports(&probe_ent->port[p]);
p++;
}
if (ports & ATA_PORT_SECONDARY) {
- probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
+ probe_ent->port[p].cmd_addr = iomap[2];
probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr =
- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
- bmdma = pci_resource_start(pdev, 4);
- if (bmdma) {
- bmdma += 8;
- if(inb(bmdma + 2) & 0x80)
+ 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 = bmdma;
+ probe_ent->port[p].bmdma_addr = iomap[4] + 8;
}
ata_std_ports(&probe_ent->port[p]);
probe_ent->pinfo2 = port[1];
@@ -899,13 +619,29 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
return probe_ent;
}
-
static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
struct ata_port_info **port, int port_mask)
{
struct ata_probe_ent *probe_ent;
- unsigned long bmdma = pci_resource_start(pdev, 4);
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
@@ -914,13 +650,14 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
probe_ent->irq_flags = IRQF_SHARED;
if (port_mask & ATA_PORT_PRIMARY) {
- probe_ent->irq = ATA_PRIMARY_IRQ;
- probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD;
+ 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 = ATA_PRIMARY_CTL;
+ probe_ent->port[0].ctl_addr = iomap[1];
if (bmdma) {
probe_ent->port[0].bmdma_addr = bmdma;
- if (inb(bmdma + 2) & 0x80)
+ 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]);
@@ -929,15 +666,16 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
if (port_mask & ATA_PORT_SECONDARY) {
if (probe_ent->irq)
- probe_ent->irq2 = ATA_SECONDARY_IRQ;
+ probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
else
- probe_ent->irq = ATA_SECONDARY_IRQ;
- probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD;
+ 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 = ATA_SECONDARY_CTL;
+ probe_ent->port[1].ctl_addr = iomap[3];
if (bmdma) {
probe_ent->port[1].bmdma_addr = bmdma + 8;
- if (inb(bmdma + 10) & 0x80)
+ if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (ioread8(bmdma + 10) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
}
ata_std_ports(&probe_ent->port[1]);
@@ -979,15 +717,18 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
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];
u8 mask;
unsigned int legacy_mode = 0;
- int disable_dev_on_err = 1;
int rc;
DPRINTK("ENTER\n");
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
BUG_ON(n_ports < 1 || n_ports > 2);
port[0] = port_info[0];
@@ -1004,9 +745,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
boot for the primary video which is BIOS enabled
*/
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
- return rc;
+ goto err_out;
if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
u8 tmp8;
@@ -1022,19 +763,22 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
left a device in compatibility mode */
if (legacy_mode) {
printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
- return -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
+ goto err_out;
}
#endif
}
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- disable_dev_on_err = 0;
- goto err_out;
- }
-
- if (legacy_mode) {
- if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
+ if (!legacy_mode) {
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc) {
+ pcim_pin_device(pdev);
+ 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;
@@ -1044,7 +788,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_PRIMARY;
else {
- disable_dev_on_err = 0;
+ pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
"ata: conflict with %s\n",
ATA_PRIMARY_CMD,
@@ -1053,7 +797,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
} else
legacy_mode |= ATA_PORT_PRIMARY;
- if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
+ 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;
@@ -1063,7 +807,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_SECONDARY;
else {
- disable_dev_on_err = 0;
+ pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
"ata: conflict with %s\n",
ATA_SECONDARY_CMD,
@@ -1071,21 +815,28 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
} 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);
}
/* we have legacy mode, but all ports are unavailable */
if (legacy_mode == (1 << 3)) {
rc = -EBUSY;
- goto err_out_regions;
+ goto err_out;
}
/* 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_regions;
+ goto err_out;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ goto err_out;
if (legacy_mode) {
probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
@@ -1097,31 +848,22 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
if (!probe_ent) {
rc = -ENOMEM;
- goto err_out_regions;
+ goto err_out;
}
pci_set_master(pdev);
if (!ata_device_add(probe_ent)) {
rc = -ENODEV;
- goto err_out_ent;
+ goto err_out;
}
- kfree(probe_ent);
-
+ devm_kfree(dev, probe_ent);
+ devres_remove_group(dev, NULL);
return 0;
-err_out_ent:
- kfree(probe_ent);
-err_out_regions:
- if (legacy_mode & ATA_PORT_PRIMARY)
- release_region(ATA_PRIMARY_CMD, 8);
- if (legacy_mode & ATA_PORT_SECONDARY)
- release_region(ATA_SECONDARY_CMD, 8);
- pci_release_regions(pdev);
err_out:
- if (disable_dev_on_err)
- pci_disable_device(pdev);
+ devres_release_group(dev, NULL);
return rc;
}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 81ae41d5f23..06ccf230e3c 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -29,7 +29,6 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
-#define DRV_VERSION "2.00" /* must be exactly four chars */
struct ata_scsi_args {
struct ata_device *dev;
@@ -136,4 +135,7 @@ 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 c5d61d1911a..ab44d18850f 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -153,11 +153,11 @@ static void ali_early_error_handler(struct ata_port *ap)
static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
- char model_num[40];
+ char model_num[ATA_ID_PROD_LEN + 1];
/* No DMA on anything but a disk for now */
if (adev->class != ATA_DEV_ATA)
mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
+ 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);
@@ -370,14 +370,14 @@ static struct ata_port_operations ali_early_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -411,14 +411,14 @@ static struct ata_port_operations ali_20_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -449,14 +449,14 @@ static struct ata_port_operations ali_c2_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -486,14 +486,14 @@ static struct ata_port_operations ali_c5_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
@@ -504,7 +504,7 @@ static struct ata_port_operations ali_c5_port_ops = {
* Perform the setup on the device that must be done both at boot
* and at resume time.
*/
-
+
static void ali_init_chipset(struct pci_dev *pdev)
{
u8 rev, tmp;
@@ -655,7 +655,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
port_info[0] = port_info[1] = &info_c5;
ali_init_chipset(pdev);
-
+
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
/* Are we paired with a UDMA capable chip */
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index a6b330089f2..619e44b0403 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -362,14 +362,14 @@ static struct ata_port_operations amd33_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd66_port_ops = {
@@ -396,14 +396,14 @@ static struct ata_port_operations amd66_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd100_port_ops = {
@@ -430,14 +430,14 @@ static struct ata_port_operations amd100_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd133_port_ops = {
@@ -464,14 +464,14 @@ static struct ata_port_operations amd133_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations nv100_port_ops = {
@@ -498,14 +498,14 @@ static struct ata_port_operations nv100_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations nv133_port_ops = {
@@ -532,14 +532,14 @@ static struct ata_port_operations nv133_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 37bc1323bda..21c30282717 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -341,14 +341,14 @@ static const struct ata_port_operations artop6210_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations artop6260_ops = {
@@ -373,14 +373,14 @@ static const struct ata_port_operations artop6260_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 6f6672c5513..c3eb40c91c8 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -36,15 +36,22 @@ enum {
static int atiixp_pre_reset(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- static struct pci_bits atiixp_enable_bits[] = {
+ static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
{ 0x48, 1, 0x08, 0x00 }
};
+ u8 udma;
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
- ap->cbl = ATA_CBL_PATA80;
+ /* 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);
}
@@ -245,14 +252,14 @@ static struct ata_port_operations atiixp_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 15841a56369..da098282b5f 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
static const u8 udma_data[] = {
- 0x31, 0x21, 0x11, 0x25, 0x15, 0x05
+ 0x30, 0x20, 0x10, 0x20, 0x10, 0x00
};
static const u8 mwdma_data[] = {
0x30, 0x20, 0x10
@@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
pci_read_config_byte(pdev, pciD, &regD);
pci_read_config_byte(pdev, pciU, &regU);
- regD &= ~(0x20 << shift);
- regU &= ~(0x35 << shift);
+ /* DMA bits off */
+ regD &= ~(0x20 << adev->devno);
+ /* DMA control bits */
+ regU &= ~(0x30 << shift);
+ /* DMA timing bits */
+ regU &= ~(0x05 << adev->devno);
- if (adev->dma_mode >= XFER_UDMA_0)
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ /* Merge thge timing value */
regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
- else
+ /* Merge the control bits */
+ regU |= 1 << adev->devno; /* UDMA on */
+ if (adev->dma_mode > 2) /* 15nS timing */
+ regU |= 4 << adev->devno;
+ } else
regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift;
regD |= 0x20 << adev->devno;
@@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u8 dma_intr;
- int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
- int dma_mask = ap->port_no ? ARTTIM2 : CFR;
+ int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+ int dma_reg = ap->port_no ? ARTTIM2 : CFR;
ata_bmdma_stop(qc);
@@ -304,14 +313,14 @@ static struct ata_port_operations cmd64x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations cmd646r1_port_ops = {
@@ -338,14 +347,14 @@ static struct ata_port_operations cmd646r1_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations cmd648_port_ops = {
@@ -372,14 +381,14 @@ static struct ata_port_operations cmd648_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 9f165a8e032..1ce8fcfd782 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -99,9 +99,9 @@ static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int
static void cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev)
{
/* Set the DMA enable/disable flag */
- u8 reg = inb(ap->ioaddr.bmdma_addr + 0x02);
+ u8 reg = ioread8(ap->ioaddr.bmdma_addr + 0x02);
reg |= 1<<(adev->devno + 5);
- outb(reg, ap->ioaddr.bmdma_addr + 0x02);
+ iowrite8(reg, ap->ioaddr.bmdma_addr + 0x02);
}
/**
@@ -193,19 +193,20 @@ static struct ata_port_operations cs5520_port_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
u8 pcicfg;
+ void *iomap[5];
static struct ata_probe_ent probe[2];
int ports = 0;
@@ -236,6 +237,16 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
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);
+
+ 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 */
@@ -249,10 +260,10 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
probe[0].irq_flags = 0;
probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
probe[0].n_ports = 1;
- probe[0].port[0].cmd_addr = 0x1F0;
- probe[0].port[0].ctl_addr = 0x3F6;
- probe[0].port[0].altstatus_addr = 0x3F6;
- probe[0].port[0].bmdma_addr = pci_resource_start(dev, 2);
+ 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 */
@@ -260,10 +271,10 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
probe[1] = probe[0];
INIT_LIST_HEAD(&probe[1].node);
probe[1].irq = 15;
- probe[1].port[0].cmd_addr = 0x170;
- probe[1].port[0].ctl_addr = 0x376;
- probe[1].port[0].altstatus_addr = 0x376;
- probe[1].port[0].bmdma_addr = pci_resource_start(dev, 2) + 8;
+ 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]);
@@ -294,7 +305,7 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
@@ -305,7 +316,7 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
* Do any reconfiguration work needed by a resume from RAM. We need
* to restore DMA mode support on BIOSen which disabled it
*/
-
+
static int cs5520_reinit_one(struct pci_dev *pdev)
{
u8 pcicfg;
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 1c628014dae..3d7b7d87ec6 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -37,6 +37,13 @@
#define DRV_NAME "pata_cs5530"
#define DRV_VERSION "0.7.1"
+static void __iomem *cs5530_port_base(struct ata_port *ap)
+{
+ unsigned long bmdma = (unsigned long)ap->ioaddr.bmdma_addr;
+
+ return (void __iomem *)((bmdma & ~0x0F) + 0x20 + 0x10 * ap->port_no);
+}
+
/**
* cs5530_set_piomode - PIO setup
* @ap: ATA interface
@@ -52,19 +59,19 @@ static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev)
{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010},
{0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}
};
- unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
+ void __iomem *base = cs5530_port_base(ap);
u32 tuning;
int format;
/* Find out which table to use */
- tuning = inl(base + 0x04);
+ tuning = ioread32(base + 0x04);
format = (tuning & 0x80000000UL) ? 1 : 0;
/* Now load the right timing register */
if (adev->devno)
base += 0x08;
- outl(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base);
+ iowrite32(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base);
}
/**
@@ -79,12 +86,12 @@ static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
- unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
+ void __iomem *base = cs5530_port_base(ap);
u32 tuning, timing = 0;
u8 reg;
/* Find out which table to use */
- tuning = inl(base + 0x04);
+ tuning = ioread32(base + 0x04);
switch(adev->dma_mode) {
case XFER_UDMA_0:
@@ -105,20 +112,20 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
/* Merge in the PIO format bit */
timing |= (tuning & 0x80000000UL);
if (adev->devno == 0) /* Master */
- outl(timing, base + 0x04);
+ iowrite32(timing, base + 0x04);
else {
if (timing & 0x00100000)
tuning |= 0x00100000; /* UDMA for both */
else
tuning &= ~0x00100000; /* MWDMA for both */
- outl(tuning, base + 0x04);
- outl(timing, base + 0x0C);
+ iowrite32(tuning, base + 0x04);
+ iowrite32(timing, base + 0x0C);
}
/* Set the DMA capable bit in the BMDMA area */
- reg = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ reg = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
reg |= (1 << (5 + adev->devno));
- outb(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
/* Remember the last DMA setup we did */
@@ -210,14 +217,14 @@ static struct ata_port_operations cs5530_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = cs5530_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct dmi_system_id palmax_dmi_table[] = {
@@ -247,7 +254,7 @@ static int cs5530_is_palmax(void)
* Perform the chip initialisation work that is shared between both
* setup and resume paths
*/
-
+
static int cs5530_init_chip(void)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL;
@@ -357,11 +364,11 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cs5530_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
-
+
/* Chip initialisation */
if (cs5530_init_chip())
return -ENODEV;
-
+
if (cs5530_is_palmax())
port_info[1] = &info_palmax_secondary;
@@ -372,10 +379,11 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int cs5530_reinit_one(struct pci_dev *pdev)
{
/* If we fail on resume we are doomed */
- BUG_ON(cs5530_init_chip());
+ if (cs5530_init_chip())
+ BUG();
return ata_pci_device_resume(pdev);
}
-
+
static const struct pci_device_id cs5530[] = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index e3efec4ffc7..17bc693cc51 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -214,14 +214,14 @@ static struct ata_port_operations cs5535_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index e2a95699bae..63f48f08763 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -165,14 +165,14 @@ static struct ata_port_operations cy82c693_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index edf8a63f50a..c19b6a8a7dc 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -261,14 +261,14 @@ static const struct ata_port_operations efar_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 2663599a7c0..27d724b5eea 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -151,23 +151,13 @@ static const char *bad_ata66_3[] = {
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
-
- while(list[i] != NULL) {
- if (!strncmp(list[i], s, len)) {
+ while (list[i] != NULL) {
+ if (!strcmp(list[i], model_num)) {
printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
modestr, list[i]);
return 1;
@@ -232,7 +222,7 @@ static int hpt36x_pre_reset(struct ata_port *ap)
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;
@@ -371,14 +361,14 @@ static struct ata_port_operations hpt366_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 47082df7199..4ffc392052c 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.5.1"
+#define DRV_VERSION "0.5.2"
struct hpt_clock {
u8 xfer_speed;
@@ -349,24 +349,13 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
-
- while(list[i] != NULL) {
- if (!strncmp(list[i], s, len)) {
+ while (list[i] != NULL) {
+ if (!strcmp(list[i], model_num)) {
printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
modestr, list[i]);
return 1;
@@ -416,7 +405,7 @@ static const char *bad_ata100_5[] = {
static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
- if (adev->class != ATA_DEV_ATA) {
+ if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
@@ -459,7 +448,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
};
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
-
+
pci_read_config_byte(pdev, 0x5B, &scr2);
pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
/* Cable register now active */
@@ -504,7 +493,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
-
+
/* Do the extra channel work */
pci_read_config_word(pdev, 0x52, &mcr3);
pci_read_config_word(pdev, 0x56, &mcr6);
@@ -645,24 +634,24 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2);
+ u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2);
u8 dma_cmd;
- unsigned long bmdma = ap->ioaddr.bmdma_addr;
+ void __iomem *bmdma = ap->ioaddr.bmdma_addr;
if (dma_stat & 0x01) {
udelay(20);
- dma_stat = inb(bmdma + 2);
+ dma_stat = ioread8(bmdma + 2);
}
if (dma_stat & 0x01) {
/* Clear the engine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(10);
/* Stop DMA */
- dma_cmd = inb(bmdma );
- outb(dma_cmd & 0xFE, bmdma);
+ dma_cmd = ioread8(bmdma );
+ iowrite8(dma_cmd & 0xFE, bmdma);
/* Clear Error */
- dma_stat = inb(bmdma + 2);
- outb(dma_stat | 0x06 , bmdma + 2);
+ dma_stat = ioread8(bmdma + 2);
+ iowrite8(dma_stat | 0x06 , bmdma + 2);
/* Clear the engine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(10);
@@ -749,7 +738,7 @@ static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int mscreg = 0x50 + 2 * ap->port_no;
+ int mscreg = 0x50 + 4 * ap->port_no;
u8 bwsr_stat, msc_stat;
pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
@@ -807,14 +796,14 @@ static struct ata_port_operations hpt370_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -846,14 +835,14 @@ static struct ata_port_operations hpt370a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -886,14 +875,14 @@ static struct ata_port_operations hpt372_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -926,14 +915,14 @@ static struct ata_port_operations hpt374_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index f6817b4093a..65f2e180e7f 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n"
-#define DRV_VERSION "0.3"
+#define DRV_VERSION "0.3.2"
enum {
HPT_PCI_FAST = (1 << 31),
@@ -263,26 +263,26 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
static void hpt3x2n_set_clock(struct ata_port *ap, int source)
{
- unsigned long bmdma = ap->ioaddr.bmdma_addr;
+ void __iomem *bmdma = ap->ioaddr.bmdma_addr;
/* Tristate the bus */
- outb(0x80, bmdma+0x73);
- outb(0x80, bmdma+0x77);
+ iowrite8(0x80, bmdma+0x73);
+ iowrite8(0x80, bmdma+0x77);
/* Switch clock and reset channels */
- outb(source, bmdma+0x7B);
- outb(0xC0, bmdma+0x79);
+ iowrite8(source, bmdma+0x7B);
+ iowrite8(0xC0, bmdma+0x79);
/* Reset state machines */
- outb(0x37, bmdma+0x70);
- outb(0x37, bmdma+0x74);
+ iowrite8(0x37, bmdma+0x70);
+ iowrite8(0x37, bmdma+0x74);
/* Complete reset */
- outb(0x00, bmdma+0x79);
+ iowrite8(0x00, bmdma+0x79);
/* Reconnect channels to bus */
- outb(0x00, bmdma+0x73);
- outb(0x00, bmdma+0x77);
+ iowrite8(0x00, bmdma+0x73);
+ iowrite8(0x00, bmdma+0x77);
}
/* Check if our partner interface is busy */
@@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap)
return 0;
}
-static int hpt3x2n_use_dpll(struct ata_port *ap, int reading)
+static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
{
long flags = (long)ap->host->private_data;
/* See if we should use the DPLL */
- if (reading == 0)
+ if (writing)
return USE_DPLL; /* Needed for write */
if (flags & PCI66)
return USE_DPLL; /* Needed at 66Mhz */
@@ -373,14 +373,14 @@ static struct ata_port_operations hpt3x2n_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = hpt3x2n_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 5f1d385eb59..483ce7c12c9 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -148,14 +148,14 @@ static struct ata_port_operations hpt3x3_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -164,7 +164,7 @@ static struct ata_port_operations hpt3x3_port_ops = {
*
* Perform the setup required at boot and on resume.
*/
-
+
static void hpt3x3_init_chipset(struct pci_dev *dev)
{
u16 cmd;
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index a97d55ae95c..1bf5ec18b2e 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -53,14 +53,14 @@ static struct ata_port_operations isapnp_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -75,6 +75,7 @@ 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;
+ void __iomem *cmd_addr, *ctl_addr;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
@@ -83,6 +84,10 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
if (pnp_irq_valid(idev, 0) == 0)
return -ENODEV;
+ 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;
@@ -93,11 +98,13 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
ae.irq = pnp_irq(idev, 0);
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS;
- ae.port[0].cmd_addr = pnp_port_start(idev, 0);
+ ae.port[0].cmd_addr = cmd_addr;
if (pnp_port_valid(idev, 1) == 0) {
- ae.port[0].altstatus_addr = pnp_port_start(idev, 1);
- ae.port[0].ctl_addr = pnp_port_start(idev, 1);
+ 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;
}
ata_std_ports(&ae.port[0]);
@@ -120,7 +127,7 @@ static void isapnp_remove_one(struct pnp_dev *idev)
struct device *dev = &idev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
new file mode 100644
index 00000000000..7eac869dfcd
--- /dev/null
+++ b/drivers/ata/pata_it8213.c
@@ -0,0 +1,354 @@
+/*
+ * pata_it8213.c - iTE Tech. Inc. IT8213 PATA driver
+ *
+ * The IT8213 is a very Intel ICH like device for timing purposes, having
+ * a similar register layout and the same split clock arrangement. Cable
+ * detection is different, and it does not have slave channels or all the
+ * clutter of later ICH/SATA setups.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define DRV_NAME "pata_it8213"
+#define DRV_VERSION "0.0.2"
+
+/**
+ * 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
+ */
+
+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
+ * @ap: Port to probe
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_error_handler(struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, it8213_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+}
+
+/**
+ * it8213_set_piomode - Initialize host controller PATA PIO timings
+ * @ap: Port whose timings we are configuring
+ * @adev: um
+ *
+ * Set PIO mode for device, in host controller PCI config space.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
+{
+ unsigned int pio = adev->pio_mode - XFER_PIO_0;
+ struct pci_dev *dev = to_pci_dev(ap->host->dev);
+ unsigned int idetm_port= ap->port_no ? 0x42 : 0x40;
+ u16 idetm_data;
+ int control = 0;
+
+ /*
+ * See Intel Document 298600-004 for the timing programing rules
+ * for PIIX/ICH. The 8213 is a clone so very similar
+ */
+
+ static const /* ISP RTC */
+ u8 timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+ if (pio > 2)
+ control |= 1; /* TIME1 enable */
+ if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */
+ control |= 2; /* IORDY enable */
+ /* Bit 2 is set for ATAPI on the IT8213 - reverse of ICH/PIIX */
+ if (adev->class != ATA_DEV_ATA)
+ control |= 4;
+
+ pci_read_config_word(dev, idetm_port, &idetm_data);
+
+ /* Enable PPE, IE and TIME as appropriate */
+
+ if (adev->devno == 0) {
+ idetm_data &= 0xCCF0;
+ idetm_data |= control;
+ idetm_data |= (timings[pio][0] << 12) |
+ (timings[pio][1] << 8);
+ } else {
+ u8 slave_data;
+
+ idetm_data &= 0xCC0F;
+ idetm_data |= (control << 4);
+
+ /* Slave timing in seperate register */
+ pci_read_config_byte(dev, 0x44, &slave_data);
+ slave_data &= 0xF0;
+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << 4;
+ pci_write_config_byte(dev, 0x44, slave_data);
+ }
+
+ idetm_data |= 0x4000; /* Ensure SITRE is enabled */
+ pci_write_config_word(dev, idetm_port, idetm_data);
+}
+
+/**
+ * it8213_set_dmamode - Initialize host controller PATA DMA timings
+ * @ap: Port whose timings we are configuring
+ * @adev: Device to program
+ *
+ * Set UDMA/MWDMA mode for device, in host controller PCI config space.
+ * This device is basically an ICH alike.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *dev = to_pci_dev(ap->host->dev);
+ u16 master_data;
+ u8 speed = adev->dma_mode;
+ int devid = adev->devno;
+ u8 udma_enable;
+
+ static const /* ISP RTC */
+ u8 timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+ pci_read_config_word(dev, 0x40, &master_data);
+ pci_read_config_byte(dev, 0x48, &udma_enable);
+
+ if (speed >= XFER_UDMA_0) {
+ unsigned int udma = adev->dma_mode - XFER_UDMA_0;
+ u16 udma_timing;
+ u16 ideconf;
+ int u_clock, u_speed;
+
+ /* Clocks follow the PIIX style */
+ u_speed = min(2 - (udma & 1), udma);
+ if (udma == 5)
+ u_clock = 0x1000; /* 100Mhz */
+ else if (udma > 2)
+ u_clock = 1; /* 66Mhz */
+ else
+ u_clock = 0; /* 33Mhz */
+
+ udma_enable |= (1 << devid);
+
+ /* Load the UDMA mode number */
+ pci_read_config_word(dev, 0x4A, &udma_timing);
+ udma_timing &= ~(3 << (4 * devid));
+ udma_timing |= (udma & 3) << (4 * devid);
+ pci_write_config_word(dev, 0x4A, udma_timing);
+
+ /* Load the clock selection */
+ pci_read_config_word(dev, 0x54, &ideconf);
+ ideconf &= ~(0x1001 << devid);
+ ideconf |= u_clock << devid;
+ pci_write_config_word(dev, 0x54, ideconf);
+ } else {
+ /*
+ * MWDMA is driven by the PIO timings. We must also enable
+ * IORDY unconditionally along with TIME1. PPE has already
+ * been set when the PIO timing was set.
+ */
+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0;
+ unsigned int control;
+ u8 slave_data;
+ static const unsigned int needed_pio[3] = {
+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
+ };
+ int pio = needed_pio[mwdma] - XFER_PIO_0;
+
+ control = 3; /* IORDY|TIME1 */
+
+ /* If the drive MWDMA is faster than it can do PIO then
+ we must force PIO into PIO0 */
+
+ if (adev->pio_mode < needed_pio[mwdma])
+ /* Enable DMA timing only */
+ control |= 8; /* PIO cycles in PIO0 */
+
+ if (devid) { /* Slave */
+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */
+ master_data |= control << 4;
+ pci_read_config_byte(dev, 0x44, &slave_data);
+ slave_data &= (0x0F + 0xE1 * ap->port_no);
+ /* Load the matching timing */
+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
+ pci_write_config_byte(dev, 0x44, slave_data);
+ } else { /* Master */
+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY
+ and master timing bits */
+ master_data |= control;
+ master_data |=
+ (timings[pio][0] << 12) |
+ (timings[pio][1] << 8);
+ }
+ udma_enable &= ~(1 << devid);
+ pci_write_config_word(dev, 0x40, master_data);
+ }
+ pci_write_config_byte(dev, 0x48, udma_enable);
+}
+
+static struct scsi_host_template it8213_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
+};
+
+static const struct ata_port_operations it8213_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = it8213_set_piomode,
+ .set_dmamode = it8213_set_dmamode,
+ .mode_filter = ata_pci_default_filter,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = it8213_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_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,
+};
+
+
+/**
+ * it8213_init_one - Register 8213 ATA PCI device with kernel services
+ * @pdev: PCI device to register
+ * @ent: Entry in it8213_pci_tbl matching with @pdev
+ *
+ * Called from kernel PCI layer.
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, or -ERRNO value.
+ */
+
+static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ static struct ata_port_info info = {
+ .sht = &it8213_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x1f, /* UDMA 100 */
+ .port_ops = &it8213_ops,
+ };
+ static struct ata_port_info *port_info[2] = { &info, &info };
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "version " DRV_VERSION "\n");
+
+ /* Current IT8213 stuff is single port */
+ return ata_pci_init_one(pdev, port_info, 1);
+}
+
+static const struct pci_device_id it8213_pci_tbl[] = {
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8213), },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver it8213_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = it8213_pci_tbl,
+ .probe = it8213_init_one,
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+};
+
+static int __init it8213_init(void)
+{
+ return pci_register_driver(&it8213_pci_driver);
+}
+
+static void __exit it8213_exit(void)
+{
+ pci_unregister_driver(&it8213_pci_driver);
+}
+
+module_init(it8213_init);
+module_exit(it8213_exit);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("SCSI low-level driver for the ITE 8213");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, it8213_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 0b56ff3d1cf..73394c75be4 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
/**
* it821x_smart_set_mode - mode setting
* @ap: interface to set up
+ * @unused: device that failed (error only)
*
* Use a non standard set_mode function. We don't want to be tuned.
* The BIOS configured everything. Our job is not to fiddle. We
@@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
* and respect them.
*/
-static void it821x_smart_set_mode(struct ata_port *ap)
+static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int dma_enabled = 0;
int i;
@@ -491,7 +492,7 @@ static void it821x_smart_set_mode(struct ata_port *ap)
/* Bits 5 and 6 indicate if DMA is active on master/slave */
/* It is possible that BMDMA isn't allocated */
if (ap->ioaddr.bmdma_addr)
- dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
@@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap)
}
}
}
+ return 0;
}
/**
@@ -529,23 +531,9 @@ static void it821x_smart_set_mode(struct ata_port *ap)
static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev)
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
-
- /* This block ought to be a library routine as it is in several
- drivers now */
-
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
-
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+
+ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (adev->max_sectors > 255)
adev->max_sectors = 255;
@@ -606,14 +594,10 @@ static int it821x_port_start(struct ata_port *ap)
if (ret < 0)
return ret;
- ap->private_data = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
- if (ap->private_data == NULL) {
- ata_port_stop(ap);
+ itdev = devm_kzalloc(&pdev->dev, sizeof(struct it821x_dev), GFP_KERNEL);
+ if (itdev == NULL)
return -ENOMEM;
- }
-
- itdev = ap->private_data;
- memset(itdev, 0, sizeof(struct it821x_dev));
+ ap->private_data = itdev;
pci_read_config_byte(pdev, 0x50, &conf);
@@ -644,20 +628,6 @@ static int it821x_port_start(struct ata_port *ap)
return 0;
}
-/**
- * it821x_port_stop - port shutdown
- * @ap: ATA port being removed
- *
- * Release the private objects we added in it821x_port_start
- */
-
-static void it821x_port_stop(struct ata_port *ap) {
- kfree(ap->private_data);
- ap->private_data = NULL; /* We want an OOPS if we reuse this
- too late! */
- ata_port_stop(ap);
-}
-
static struct scsi_host_template it821x_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -704,14 +674,14 @@ static struct ata_port_operations it821x_smart_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = it821x_smart_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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 = it821x_port_start,
- .port_stop = it821x_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations it821x_passthru_port_ops = {
@@ -740,14 +710,14 @@ static struct ata_port_operations it821x_passthru_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = it821x_passthru_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_clear = ata_bmdma_irq_clear,
.irq_handler = ata_interrupt,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = it821x_port_start,
- .port_stop = it821x_port_stop,
- .host_stop = ata_host_stop
};
static void __devinit it821x_disable_raid(struct pci_dev *pdev)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index cb8924109f5..3222ac7b945 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -23,9 +23,9 @@
#include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf"
-#define DRV_VERSION "0.1.1"
+#define DRV_VERSION "0.1.1ac1"
-static void ixp4xx_set_mode(struct ata_port *ap)
+static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev)
{
int i;
@@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
static void ixp4xx_phy_reset(struct ata_port *ap)
@@ -94,14 +95,6 @@ static void ixp4xx_irq_clear(struct ata_port *ap)
{
}
-static void ixp4xx_host_stop (struct ata_host *host)
-{
- struct ixp4xx_pata_data *data = host->dev->platform_data;
-
- iounmap(data->cs0);
- iounmap(data->cs1);
-}
-
static struct scsi_host_template ixp4xx_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -138,10 +131,10 @@ static struct ata_port_operations ixp4xx_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ixp4xx_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ixp4xx_host_stop,
.phy_reset = ixp4xx_phy_reset,
};
@@ -149,9 +142,9 @@ static struct ata_port_operations ixp4xx_port_ops = {
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
struct ixp4xx_pata_data *data)
{
- ioaddr->cmd_addr = (unsigned long) data->cs0;
- ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
- ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
+ ioaddr->cmd_addr = data->cs0;
+ ioaddr->altstatus_addr = data->cs1 + 0x06;
+ ioaddr->ctl_addr = data->cs1 + 0x06;
ata_std_ports(ioaddr);
@@ -161,19 +154,19 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
* ixp4xx in little endian mode.
*/
- ioaddr->data_addr ^= 0x02;
- ioaddr->cmd_addr ^= 0x03;
- ioaddr->altstatus_addr ^= 0x03;
- ioaddr->ctl_addr ^= 0x03;
- ioaddr->error_addr ^= 0x03;
- ioaddr->feature_addr ^= 0x03;
- ioaddr->nsect_addr ^= 0x03;
- ioaddr->lbal_addr ^= 0x03;
- ioaddr->lbam_addr ^= 0x03;
- ioaddr->lbah_addr ^= 0x03;
- ioaddr->device_addr ^= 0x03;
- ioaddr->status_addr ^= 0x03;
- ioaddr->command_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->data_addr ^= 0x02;
+ *(unsigned long *)&ioaddr->cmd_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->altstatus_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->ctl_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->error_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->feature_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->nsect_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbal_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbam_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbah_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->device_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->status_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->command_addr ^= 0x03;
#endif
}
@@ -194,8 +187,8 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
- data->cs0 = ioremap(cs0->start, 0x1000);
- data->cs1 = ioremap(cs1->start, 0x1000);
+ data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
+ data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
irq = platform_get_irq(pdev, 0);
if (irq)
@@ -237,7 +230,7 @@ static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
{
struct ata_host *host = platform_get_drvdata(dev);
- ata_host_remove(host);
+ 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 2d661cb4df3..7a635dd326f 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -161,16 +161,16 @@ static const struct ata_port_operations jmicron_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* IRQ-related hooks */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
@@ -204,20 +204,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
u32 reg;
- if (id->driver_data != 368) {
- /* Put the controller into AHCI mode in case the AHCI driver
- has not yet been loaded. This can be done with either
- function present */
+ /* PATA controller is fn 1, AHCI is fn 0 */
+ if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1)
+ return -ENODEV;
- /* FIXME: We may want a way to override this in future */
- pci_write_config_byte(pdev, 0x41, 0xa1);
-
- /* PATA controller is fn 1, AHCI is fn 0 */
- if (PCI_FUNC(pdev->devfn) != 1)
- return -ENODEV;
- }
- if ( id->driver_data == 365 || id->driver_data == 366) {
- /* The 365/66 have two PATA channels, redirect the second */
+ /* 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);
@@ -229,7 +221,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static int jmicron_reinit_one(struct pci_dev *pdev)
{
u32 reg;
-
+
switch(pdev->device) {
case PCI_DEVICE_ID_JMICRON_JMB368:
break;
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index c7d1738e4e6..4223e10de6a 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */
/**
* legacy_set_mode - mode setting
* @ap: IDE interface
+ * @unused: Device that failed when error is returned
*
* Use a non standard set_mode function. We don't want to be tuned.
*
@@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */
* expand on this as per hdparm in the base kernel.
*/
-static void legacy_set_mode(struct ata_port *ap)
+static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int i;
@@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
static struct scsi_host_template legacy_sht = {
@@ -162,14 +164,14 @@ static struct ata_port_operations simple_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .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 = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations legacy_port_ops = {
@@ -187,14 +189,14 @@ static struct ata_port_operations legacy_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .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 = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -255,31 +257,33 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
local_irq_save(flags);
/* Perform the 32bit I/O synchronization sequence */
- inb(ap->ioaddr.nsect_addr);
- inb(ap->ioaddr.nsect_addr);
- inb(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
/* Now the data */
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le16(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
local_irq_restore(flags);
}
else
- ata_pio_data_xfer_noirq(adev, buf, buflen, write_data);
+ ata_data_xfer_noirq(adev, buf, buflen, write_data);
}
static struct ata_port_operations pdc20230_port_ops = {
@@ -301,10 +305,10 @@ static struct ata_port_operations pdc20230_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -330,8 +334,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
inb(0x3E6);
inb(0x3E6);
- outb(recover << 4 | active, ap->ioaddr.device_addr);
- inb(ap->ioaddr.status_addr);
+ iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
+ ioread8(ap->ioaddr.status_addr);
}
static struct ata_port_operations ht6560a_port_ops = {
@@ -349,14 +353,14 @@ static struct ata_port_operations ht6560a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer, /* Check vlb/noirq */
+ .data_xfer = ata_data_xfer, /* Check vlb/noirq */
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -385,7 +389,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
inb(0x3E6);
inb(0x3E6);
- outb(recover << 4 | active, ap->ioaddr.device_addr);
+ iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
if (adev->class != ATA_DEV_ATA) {
u8 rconf = inb(0x3E6);
@@ -394,7 +398,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
outb(rconf, 0x3E6);
}
}
- inb(ap->ioaddr.status_addr);
+ ioread8(ap->ioaddr.status_addr);
}
static struct ata_port_operations ht6560b_port_ops = {
@@ -412,14 +416,14 @@ static struct ata_port_operations ht6560b_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer, /* FIXME: Check 32bit and noirq */
+ .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -462,12 +466,12 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
u8 rc;
/* Enter configuration mode */
- inw(ap->ioaddr.error_addr);
- inw(ap->ioaddr.error_addr);
- outb(3, ap->ioaddr.nsect_addr);
+ ioread16(ap->ioaddr.error_addr);
+ ioread16(ap->ioaddr.error_addr);
+ iowrite8(3, ap->ioaddr.nsect_addr);
/* Read VLB clock strapping */
- clock = 1000000000 / khz[inb(ap->ioaddr.lbah_addr) & 0x03];
+ clock = 1000000000 / khz[ioread8(ap->ioaddr.lbah_addr) & 0x03];
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
@@ -485,33 +489,33 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
setup = FIT(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */
- rc = inb(ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x7F;
rc |= (adev->devno << 7);
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Write the timings */
- outb(active << 4 | recover, ap->ioaddr.error_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
/* Select the right bank for read timings, also
load the shared timings for address */
- rc = inb(ap->ioaddr.device_addr);
+ rc = ioread8(ap->ioaddr.device_addr);
rc &= 0xC0;
rc |= adev->devno; /* Index select */
rc |= (setup << 4) | 0x04;
- outb(rc, ap->ioaddr.device_addr);
+ iowrite8(rc, ap->ioaddr.device_addr);
/* Load the read timings */
- outb(active << 4 | recover, ap->ioaddr.data_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
/* Ensure the timing register mode is right */
- rc = inb (ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x73;
rc |= 0x84;
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Exit command mode */
- outb(0x83, ap->ioaddr.nsect_addr);
+ iowrite8(0x83, ap->ioaddr.nsect_addr);
}
@@ -530,14 +534,14 @@ static struct ata_port_operations opti82c611a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -561,9 +565,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
sysclk = opti_syscfg(0xAC) & 0xC0; /* BIOS set */
/* Enter configuration mode */
- inw(ap->ioaddr.error_addr);
- inw(ap->ioaddr.error_addr);
- outb(3, ap->ioaddr.nsect_addr);
+ ioread16(ap->ioaddr.error_addr);
+ ioread16(ap->ioaddr.error_addr);
+ iowrite8(3, ap->ioaddr.nsect_addr);
/* Read VLB clock strapping */
clock = 1000000000 / khz[sysclk];
@@ -584,33 +588,33 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
setup = FIT(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */
- rc = inb(ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x7F;
rc |= (adev->devno << 7);
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Write the timings */
- outb(active << 4 | recover, ap->ioaddr.error_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
/* Select the right bank for read timings, also
load the shared timings for address */
- rc = inb(ap->ioaddr.device_addr);
+ rc = ioread8(ap->ioaddr.device_addr);
rc &= 0xC0;
rc |= adev->devno; /* Index select */
rc |= (setup << 4) | 0x04;
- outb(rc, ap->ioaddr.device_addr);
+ iowrite8(rc, ap->ioaddr.device_addr);
/* Load the read timings */
- outb(active << 4 | recover, ap->ioaddr.data_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
/* Ensure the timing register mode is right */
- rc = inb (ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x73;
rc |= 0x84;
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Exit command mode */
- outb(0x83, ap->ioaddr.nsect_addr);
+ iowrite8(0x83, ap->ioaddr.nsect_addr);
/* We need to know this for quad device on the MVB */
ap->host->private_data = ap;
@@ -660,14 +664,14 @@ static struct ata_port_operations opti82c46x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = opti82c46x_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
@@ -687,19 +691,26 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
struct legacy_data *ld = &legacy_data[nr_legacy_host];
struct ata_probe_ent ae;
struct platform_device *pdev;
- int ret = -EBUSY;
struct ata_port_operations *ops = &legacy_port_ops;
+ void __iomem *io_addr, *ctrl_addr;
int pio_modes = pio_mask;
u32 mask = (1 << port);
-
- if (request_region(io, 8, "pata_legacy") == NULL)
- return -EBUSY;
- if (request_region(ctrl, 1, "pata_legacy") == NULL)
- goto fail_io;
+ int ret;
pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
- if (pdev == NULL)
- goto fail_dev;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ ret = -EBUSY;
+ if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL ||
+ devm_request_region(&pdev->dev, ctrl, 1, "pata_legacy") == NULL)
+ goto fail;
+
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io, 8);
+ ctrl_addr = devm_ioport_map(&pdev->dev, ctrl, 1);
+ if (!io_addr || !ctrl_addr)
+ goto fail;
if (ht6560a & mask) {
ops = &ht6560a_port_ops;
@@ -766,27 +777,22 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io;
- ae.port[0].altstatus_addr = ctrl;
- ae.port[0].ctl_addr = ctrl;
+ 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 = ata_device_add(&ae);
- if (ret == 0) {
- ret = -ENODEV;
+ ret = -ENODEV;
+ if (!ata_device_add(&ae))
goto fail;
- }
+
legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
ld->platform_dev = pdev;
return 0;
fail:
platform_device_unregister(pdev);
-fail_dev:
- release_region(ctrl, 1);
-fail_io:
- release_region(io, 8);
return ret;
}
@@ -919,15 +925,11 @@ static __exit void legacy_exit(void)
for (i = 0; i < nr_legacy_host; i++) {
struct legacy_data *ld = &legacy_data[i];
- struct ata_port *ap =legacy_host[i]->ports[0];
- unsigned long io = ap->ioaddr.cmd_addr;
- unsigned long ctrl = ap->ioaddr.ctl_addr;
- ata_host_remove(legacy_host[i]);
+
+ ata_host_detach(legacy_host[i]);
platform_device_unregister(ld->platform_dev);
if (ld->timing)
release_region(ld->timing, 2);
- release_region(io, 8);
- release_region(ctrl, 1);
}
}
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 1c810ea0025..13a70ac6f1d 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -45,10 +45,10 @@ static int marvell_pre_reset(struct ata_port *ap)
for(i = 0; i <= 0x0F; i++)
printk("%02X:%02X ", i, readb(barp + i));
printk("\n");
-
+
devices = readl(barp + 0x0C);
pci_iounmap(pdev, barp);
-
+
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
(!(devices & 0x10))) /* PATA enable ? */
return -ENOENT;
@@ -57,7 +57,7 @@ static int marvell_pre_reset(struct ata_port *ap)
switch(ap->port_no)
{
case 0:
- if (inb(ap->ioaddr.bmdma_addr + 1) & 1)
+ if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -129,16 +129,16 @@ static const struct ata_port_operations marvell_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* Timeout handling */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
new file mode 100644
index 00000000000..d7378df4497
--- /dev/null
+++ b/drivers/ata/pata_mpc52xx.c
@@ -0,0 +1,538 @@
+/*
+ * drivers/ata/pata_mpc52xx.c
+ *
+ * libata driver for the Freescale MPC52xx on-chip IDE interface
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/libata.h>
+
+#include <asm/types.h>
+#include <asm/prom.h>
+#include <asm/of_platform.h>
+#include <asm/mpc52xx.h>
+
+
+#define DRV_NAME "mpc52xx_ata"
+#define DRV_VERSION "0.1.0"
+
+
+/* Private structures used by the driver */
+struct mpc52xx_ata_timings {
+ u32 pio1;
+ u32 pio2;
+};
+
+struct mpc52xx_ata_priv {
+ unsigned int ipb_period;
+ struct mpc52xx_ata __iomem * ata_regs;
+ int ata_irq;
+ struct mpc52xx_ata_timings timings[2];
+ int csel;
+};
+
+
+/* ATAPI-4 PIO specs (in ns) */
+static const int ataspec_t0[5] = {600, 383, 240, 180, 120};
+static const int ataspec_t1[5] = { 70, 50, 30, 30, 25};
+static const int ataspec_t2_8[5] = {290, 290, 290, 80, 70};
+static const int ataspec_t2_16[5] = {165, 125, 100, 80, 70};
+static const int ataspec_t2i[5] = { 0, 0, 0, 70, 25};
+static const int ataspec_t4[5] = { 30, 20, 15, 10, 10};
+static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
+
+#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
+
+
+/* Bit definitions inside the registers */
+#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
+#define MPC52xx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */
+#define MPC52xx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt in PIO */
+#define MPC52xx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports IORDY protocol */
+
+#define MPC52xx_ATA_HOSTSTAT_TIP 0x80000000UL /* Transaction in progress */
+#define MPC52xx_ATA_HOSTSTAT_UREP 0x40000000UL /* UDMA Read Extended Pause */
+#define MPC52xx_ATA_HOSTSTAT_RERR 0x02000000UL /* Read Error */
+#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
+
+#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
+
+#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
+#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
+#define MPC52xx_ATA_DMAMODE_UDMA 0x04 /* UDMA enabled */
+#define MPC52xx_ATA_DMAMODE_IE 0x08 /* Enable drive interrupt to CPU in DMA mode */
+#define MPC52xx_ATA_DMAMODE_FE 0x10 /* FIFO Flush enable in Rx mode */
+#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
+#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
+
+
+/* Structure of the hardware registers */
+struct mpc52xx_ata {
+
+ /* Host interface registers */
+ u32 config; /* ATA + 0x00 Host configuration */
+ u32 host_status; /* ATA + 0x04 Host controller status */
+ u32 pio1; /* ATA + 0x08 PIO Timing 1 */
+ u32 pio2; /* ATA + 0x0c PIO Timing 2 */
+ u32 mdma1; /* ATA + 0x10 MDMA Timing 1 */
+ u32 mdma2; /* ATA + 0x14 MDMA Timing 2 */
+ u32 udma1; /* ATA + 0x18 UDMA Timing 1 */
+ u32 udma2; /* ATA + 0x1c UDMA Timing 2 */
+ u32 udma3; /* ATA + 0x20 UDMA Timing 3 */
+ u32 udma4; /* ATA + 0x24 UDMA Timing 4 */
+ u32 udma5; /* ATA + 0x28 UDMA Timing 5 */
+ u32 share_cnt; /* ATA + 0x2c ATA share counter */
+ u32 reserved0[3];
+
+ /* FIFO registers */
+ u32 fifo_data; /* ATA + 0x3c */
+ u8 fifo_status_frame; /* ATA + 0x40 */
+ u8 fifo_status; /* ATA + 0x41 */
+ u16 reserved7[1];
+ u8 fifo_control; /* ATA + 0x44 */
+ u8 reserved8[5];
+ u16 fifo_alarm; /* ATA + 0x4a */
+ u16 reserved9;
+ u16 fifo_rdp; /* ATA + 0x4e */
+ u16 reserved10;
+ u16 fifo_wrp; /* ATA + 0x52 */
+ u16 reserved11;
+ u16 fifo_lfrdp; /* ATA + 0x56 */
+ u16 reserved12;
+ u16 fifo_lfwrp; /* ATA + 0x5a */
+
+ /* Drive TaskFile registers */
+ u8 tf_control; /* ATA + 0x5c TASKFILE Control/Alt Status */
+ u8 reserved13[3];
+ u16 tf_data; /* ATA + 0x60 TASKFILE Data */
+ u16 reserved14;
+ u8 tf_features; /* ATA + 0x64 TASKFILE Features/Error */
+ u8 reserved15[3];
+ u8 tf_sec_count; /* ATA + 0x68 TASKFILE Sector Count */
+ u8 reserved16[3];
+ u8 tf_sec_num; /* ATA + 0x6c TASKFILE Sector Number */
+ u8 reserved17[3];
+ u8 tf_cyl_low; /* ATA + 0x70 TASKFILE Cylinder Low */
+ u8 reserved18[3];
+ u8 tf_cyl_high; /* ATA + 0x74 TASKFILE Cylinder High */
+ u8 reserved19[3];
+ u8 tf_dev_head; /* ATA + 0x78 TASKFILE Device/Head */
+ u8 reserved20[3];
+ u8 tf_command; /* ATA + 0x7c TASKFILE Command/Status */
+ u8 dma_mode; /* ATA + 0x7d ATA Host DMA Mode configuration */
+ u8 reserved21[2];
+};
+
+
+/* ======================================================================== */
+/* Aux fns */
+/* ======================================================================== */
+
+
+/* MPC52xx low level hw control */
+
+static int
+mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ unsigned int ipb_period = priv->ipb_period;
+ unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta;
+
+ if ((pio<0) || (pio>4))
+ return -EINVAL;
+
+ t0 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
+ t1 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t1[pio]);
+ t2_8 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_8[pio]);
+ t2_16 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_16[pio]);
+ t2i = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2i[pio]);
+ t4 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t4[pio]);
+ ta = CALC_CLKCYC(ipb_period, 1000 * ataspec_ta[pio]);
+
+ timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i);
+ timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8);
+
+ return 0;
+}
+
+static void
+mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
+{
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ struct mpc52xx_ata_timings *timing = &priv->timings[device];
+
+ out_be32(&regs->pio1, timing->pio1);
+ out_be32(&regs->pio2, timing->pio2);
+ out_be32(&regs->mdma1, 0);
+ out_be32(&regs->mdma2, 0);
+ out_be32(&regs->udma1, 0);
+ out_be32(&regs->udma2, 0);
+ out_be32(&regs->udma3, 0);
+ out_be32(&regs->udma4, 0);
+ out_be32(&regs->udma5, 0);
+
+ priv->csel = device;
+}
+
+static int
+mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
+{
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ int tslot;
+
+ /* Clear share_cnt (all sample code do this ...) */
+ out_be32(&regs->share_cnt, 0);
+
+ /* Configure and reset host */
+ out_be32(&regs->config,
+ MPC52xx_ATA_HOSTCONF_IE |
+ MPC52xx_ATA_HOSTCONF_IORDY |
+ MPC52xx_ATA_HOSTCONF_SMR |
+ MPC52xx_ATA_HOSTCONF_FR);
+
+ udelay(10);
+
+ out_be32(&regs->config,
+ MPC52xx_ATA_HOSTCONF_IE |
+ MPC52xx_ATA_HOSTCONF_IORDY);
+
+ /* Set the time slot to 1us */
+ tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
+ out_be32(&regs->share_cnt, tslot << 16 );
+
+ /* Init timings to PIO0 */
+ memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
+
+ mpc52xx_ata_compute_pio_timings(priv, 0, 0);
+ mpc52xx_ata_compute_pio_timings(priv, 1, 0);
+
+ mpc52xx_ata_apply_timings(priv, 0);
+
+ return 0;
+}
+
+
+/* ======================================================================== */
+/* libata driver */
+/* ======================================================================== */
+
+static void
+mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ int pio, rv;
+
+ pio = adev->pio_mode - XFER_PIO_0;
+
+ rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
+
+ if (rv) {
+ printk(KERN_ERR DRV_NAME
+ ": Trying to select invalid PIO mode %d\n", pio);
+ return;
+ }
+
+ mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
+mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ if (device != priv->csel)
+ mpc52xx_ata_apply_timings(priv, device);
+
+ ata_std_dev_select(ap,device);
+}
+
+static void
+mpc52xx_ata_error_handler(struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
+ ata_std_postreset);
+}
+
+
+
+static struct scsi_host_template mpc52xx_ata_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations mpc52xx_ata_port_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = mpc52xx_ata_set_piomode,
+ .dev_select = mpc52xx_ata_dev_select,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = mpc52xx_ata_error_handler,
+ .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 */
+ aio->altstatus_addr = &priv->ata_regs->tf_control;
+ aio->ctl_addr = &priv->ata_regs->tf_control;
+ aio->data_addr = &priv->ata_regs->tf_data;
+ aio->error_addr = &priv->ata_regs->tf_features;
+ aio->feature_addr = &priv->ata_regs->tf_features;
+ aio->nsect_addr = &priv->ata_regs->tf_sec_count;
+ aio->lbal_addr = &priv->ata_regs->tf_sec_num;
+ aio->lbam_addr = &priv->ata_regs->tf_cyl_low;
+ aio->lbah_addr = &priv->ata_regs->tf_cyl_high;
+ aio->device_addr = &priv->ata_regs->tf_dev_head;
+ 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;
+}
+
+static struct mpc52xx_ata_priv *
+mpc52xx_ata_remove_one(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct mpc52xx_ata_priv *priv = host->private_data;
+
+ ata_host_detach(host);
+
+ return priv;
+}
+
+
+/* ======================================================================== */
+/* OF Platform driver */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
+{
+ unsigned int ipb_freq;
+ struct resource res_mem;
+ int ata_irq = NO_IRQ;
+ struct mpc52xx_ata __iomem *ata_regs;
+ struct mpc52xx_ata_priv *priv;
+ int rv;
+
+ /* Get ipb frequency */
+ ipb_freq = mpc52xx_find_ipb_freq(op->node);
+ if (!ipb_freq) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Unable to find IPB Bus frequency\n" );
+ return -ENODEV;
+ }
+
+ /* Get IRQ and register */
+ rv = of_address_to_resource(op->node, 0, &res_mem);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while parsing device node resource\n" );
+ return rv;
+ }
+
+ ata_irq = irq_of_parse_and_map(op->node, 0);
+ if (ata_irq == NO_IRQ) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while mapping the irq\n");
+ return -EINVAL;
+ }
+
+ /* Request mem region */
+ if (!devm_request_mem_region(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata), DRV_NAME)) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while requesting mem region\n");
+ rv = -EBUSY;
+ goto err;
+ }
+
+ /* Remap registers */
+ ata_regs = devm_ioremap(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata));
+ if (!ata_regs) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while mapping register set\n");
+ rv = -ENOMEM;
+ goto err;
+ }
+
+ /* Prepare our private structure */
+ priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
+ GFP_ATOMIC);
+ if (!priv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while allocating private structure\n");
+ rv = -ENOMEM;
+ goto err;
+ }
+
+ priv->ipb_period = 1000000000 / (ipb_freq / 1000);
+ priv->ata_regs = ata_regs;
+ priv->ata_irq = ata_irq;
+ priv->csel = -1;
+
+ /* Init the hw */
+ rv = mpc52xx_ata_hw_init(priv);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+ goto err;
+ }
+
+ /* Register ourselves to libata */
+ rv = mpc52xx_ata_init_one(&op->dev, priv);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while registering to ATA layer\n");
+ return rv;
+ }
+
+ /* Done */
+ return 0;
+
+ /* Error path */
+err:
+ irq_dispose_mapping(ata_irq);
+ return rv;
+}
+
+static int
+mpc52xx_ata_remove(struct of_device *op)
+{
+ struct mpc52xx_ata_priv *priv;
+
+ priv = mpc52xx_ata_remove_one(&op->dev);
+ irq_dispose_mapping(priv->ata_irq);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_PM
+
+static int
+mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
+{
+ return 0; /* FIXME : What to do here ? */
+}
+
+static int
+mpc52xx_ata_resume(struct of_device *op)
+{
+ return 0; /* FIXME : What to do here ? */
+}
+
+#endif
+
+
+static struct of_device_id mpc52xx_ata_of_match[] = {
+ {
+ .compatible = "mpc5200-ata",
+ },
+ {
+ .compatible = "mpc52xx-ata",
+ },
+ {},
+};
+
+
+static struct of_platform_driver mpc52xx_ata_of_platform_driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .match_table = mpc52xx_ata_of_match,
+ .probe = mpc52xx_ata_probe,
+ .remove = mpc52xx_ata_remove,
+#ifdef CONFIG_PM
+ .suspend = mpc52xx_ata_suspend,
+ .resume = mpc52xx_ata_resume,
+#endif
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+
+/* ======================================================================== */
+/* Module */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_ata_init(void)
+{
+ printk(KERN_INFO "ata: MPC52xx IDE/ATA libata driver\n");
+ return of_register_platform_driver(&mpc52xx_ata_of_platform_driver);
+}
+
+static void __exit
+mpc52xx_ata_exit(void)
+{
+ of_unregister_platform_driver(&mpc52xx_ata_of_platform_driver);
+}
+
+module_init(mpc52xx_ata_init);
+module_exit(mpc52xx_ata_exit);
+
+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
+MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
+MODULE_VERSION(DRV_VERSION);
+
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 4ccca938675..ca8c965179b 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.3"
+#define DRV_VERSION "0.7.5"
enum {
IDETIM = 0x6C, /* IDE control register */
@@ -49,12 +49,9 @@ enum {
static int mpiix_pre_reset(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- static const struct pci_bits mpiix_enable_bits[] = {
- { 0x6D, 1, 0x80, 0x80 },
- { 0x6F, 1, 0x80, 0x80 }
- };
+ static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 };
- if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no]))
+ if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
return -ENOENT;
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
@@ -80,8 +77,8 @@ static void mpiix_error_handler(struct ata_port *ap)
* @adev: ATA device
*
* Called to do the PIO mode setup. The MPIIX allows us to program the
- * IORDY sample point (2-5 clocks), recovery 1-4 clocks and whether
- * prefetching or iordy are used.
+ * IORDY sample point (2-5 clocks), recovery (1-4 clocks) and whether
+ * prefetching or IORDY are used.
*
* This would get very ugly because we can only program timing for one
* device at a time, the other gets PIO0. Fortunately libata calls
@@ -103,18 +100,19 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ 2, 3 }, };
pci_read_config_word(pdev, IDETIM, &idetim);
- /* Mask the IORDY/TIME/PPE0 bank for this device */
+
+ /* Mask the IORDY/TIME/PPE for this device */
if (adev->class == ATA_DEV_ATA)
- control |= PPE; /* PPE enable for disk */
+ control |= PPE; /* Enable prefetch/posting for disk */
if (ata_pio_need_iordy(adev))
- control |= IORDY; /* IORDY */
- if (pio > 0)
+ control |= IORDY;
+ if (pio > 1)
control |= FTIM; /* This drive is on the fast timing bank */
/* Mask out timing and clear both TIME bank selects */
idetim &= 0xCCEE;
- idetim &= ~(0x07 << (2 * adev->devno));
- idetim |= (control << (2 * adev->devno));
+ idetim &= ~(0x07 << (4 * adev->devno));
+ idetim |= control << (4 * adev->devno);
idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8);
pci_write_config_word(pdev, IDETIM, idetim);
@@ -188,23 +186,24 @@ static struct ata_port_operations mpiix_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = mpiix_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
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[2];
+ static struct ata_probe_ent probe;
static int printed_version;
+ void __iomem *cmd_addr, *ctl_addr;
u16 idetim;
- int enabled;
+ int irq;
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
@@ -217,65 +216,49 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!(idetim & ENABLED))
return -ENODEV;
+ /* See if it's primary or secondary channel... */
+ if (!(idetim & SECONDARY)) {
+ irq = 14;
+ cmd_addr = devm_ioport_map(&dev->dev, 0x1F0, 8);
+ ctl_addr = devm_ioport_map(&dev->dev, 0x3F6, 1);
+ } else {
+ irq = 15;
+ cmd_addr = devm_ioport_map(&dev->dev, 0x170, 8);
+ ctl_addr = devm_ioport_map(&dev->dev, 0x376, 1);
+ }
+
+ if (!cmd_addr || !ctl_addr)
+ return -ENOMEM;
+
/* We do our own plumbing to avoid leaking special cases for whacko
ancient hardware into the core code. There are two issues to
worry about. #1 The chip is a bridge so if in legacy mode and
without BARs set fools the setup. #2 If you pci_disable_device
the MPIIX your box goes castors up */
- INIT_LIST_HEAD(&probe[0].node);
- probe[0].dev = pci_dev_to_dev(dev);
- probe[0].port_ops = &mpiix_port_ops;
- probe[0].sht = &mpiix_sht;
- probe[0].pio_mask = 0x1F;
- probe[0].irq = 14;
- probe[0].irq_flags = SA_SHIRQ;
- probe[0].port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- probe[0].n_ports = 1;
- probe[0].port[0].cmd_addr = 0x1F0;
- probe[0].port[0].ctl_addr = 0x3F6;
- probe[0].port[0].altstatus_addr = 0x3F6;
-
- /* The secondary lurks at different addresses but is otherwise
- the same beastie */
-
- INIT_LIST_HEAD(&probe[1].node);
- probe[1] = probe[0];
- probe[1].irq = 15;
- probe[1].port[0].cmd_addr = 0x170;
- probe[1].port[0].ctl_addr = 0x376;
- probe[1].port[0].altstatus_addr = 0x376;
+ 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 = SA_SHIRQ;
+ probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ probe.n_ports = 1;
+
+ probe.irq = irq;
+ probe.port[0].cmd_addr = cmd_addr;
+ probe.port[0].ctl_addr = ctl_addr;
+ probe.port[0].altstatus_addr = ctl_addr;
/* Let libata fill in the port details */
- ata_std_ports(&probe[0].port[0]);
- ata_std_ports(&probe[1].port[0]);
+ ata_std_ports(&probe.port[0]);
/* Now add the port that is active */
- enabled = (idetim & SECONDARY) ? 1 : 0;
-
- if (ata_device_add(&probe[enabled]))
+ if (ata_device_add(&probe))
return 0;
return -ENODEV;
}
-/**
- * mpiix_remove_one - device unload
- * @pdev: PCI device being removed
- *
- * Handle an unplug/unload event for a PCI device. Unload the
- * PCI driver but do not use the default handler as we *MUST NOT*
- * disable the device as it has other functions.
- */
-
-static void __devexit mpiix_remove_one(struct pci_dev *pdev)
-{
- struct device *dev = pci_dev_to_dev(pdev);
- struct ata_host *host = dev_get_drvdata(dev);
-
- ata_host_remove(host);
- dev_set_drvdata(dev, NULL);
-}
-
static const struct pci_device_id mpiix[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
@@ -286,7 +269,7 @@ static struct pci_driver mpiix_pci_driver = {
.name = DRV_NAME,
.id_table = mpiix,
.probe = mpiix_init_one,
- .remove = mpiix_remove_one,
+ .remove = ata_pci_remove_one,
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
};
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index cf7fe037471..e8393e19be4 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -89,16 +89,16 @@ static const struct ata_port_operations netcell_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* IRQ-related hooks */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index c3032eb9010..3d1fa487c48 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -179,14 +179,14 @@ static struct ata_port_operations ns87410_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ns87410_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 10ac3cc1018..45215aa05e7 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.2"
+#define DRV_VERSION "0.5.3"
/**
* oldpiix_pre_reset - probe begin
@@ -94,19 +94,21 @@ static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev)
{ 2, 1 },
{ 2, 3 }, };
- if (pio > 2)
- control |= 1; /* TIME1 enable */
+ if (pio > 1)
+ control |= 1; /* TIME */
if (ata_pio_need_iordy(adev))
- control |= 2; /* IE IORDY */
+ control |= 2; /* IE */
- /* Intel specifies that the PPE functionality is for disk only */
+ /* Intel specifies that the prefetch/posting is for disk only */
if (adev->class == ATA_DEV_ATA)
- control |= 4; /* PPE enable */
+ control |= 4; /* PPE */
pci_read_config_word(dev, idetm_port, &idetm_data);
- /* Enable PPE, IE and TIME as appropriate. Clear the other
- drive timing bits */
+ /*
+ * Set PPE, IE and TIME as appropriate.
+ * Clear the other drive's timing bits.
+ */
if (adev->devno == 0) {
idetm_data &= 0xCCE0;
idetm_data |= control;
@@ -259,14 +261,14 @@ static const struct ata_port_operations oldpiix_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = oldpiix_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index c2988b0aa8e..da1aa148b37 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -95,18 +95,18 @@ static void opti_error_handler(struct ata_port *ap)
static void opti_write_reg(struct ata_port *ap, u8 val, int reg)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* These 3 unlock the control register access */
- inw(regio + 1);
- inw(regio + 1);
- outb(3, regio + 2);
+ ioread16(regio + 1);
+ ioread16(regio + 1);
+ iowrite8(3, regio + 2);
/* Do the I/O */
- outb(val, regio + reg);
+ iowrite8(val, regio + reg);
/* Relock */
- outb(0x83, regio + 2);
+ iowrite8(0x83, regio + 2);
}
/**
@@ -124,7 +124,7 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev)
struct ata_device *pair = ata_dev_pair(adev);
int clock;
int pio = adev->pio_mode - XFER_PIO_0;
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
u8 addr;
/* Address table precomputed with prefetch off and a DCLK of 2 */
@@ -137,8 +137,8 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ 0x58, 0x44, 0x32, 0x22, 0x21 }
};
- outb(0xff, regio + 5);
- clock = inw(regio + 5) & 1;
+ iowrite8(0xff, regio + 5);
+ clock = ioread16(regio + 5) & 1;
/*
* As with many controllers the address setup time is shared
@@ -205,14 +205,14 @@ static struct ata_port_operations opti_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 80d111c569d..d80b36e209c 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -91,12 +91,12 @@ static void optidma_error_handler(struct ata_port *ap)
static void optidma_unlock(struct ata_port *ap)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* These 3 unlock the control register access */
- inw(regio + 1);
- inw(regio + 1);
- outb(3, regio + 2);
+ ioread16(regio + 1);
+ ioread16(regio + 1);
+ iowrite8(3, regio + 2);
}
/**
@@ -108,10 +108,10 @@ static void optidma_unlock(struct ata_port *ap)
static void optidma_lock(struct ata_port *ap)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* Relock */
- outb(0x83, regio + 2);
+ iowrite8(0x83, regio + 2);
}
/**
@@ -133,7 +133,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
struct ata_device *pair = ata_dev_pair(adev);
int pio = adev->pio_mode - XFER_PIO_0;
int dma = adev->dma_mode - XFER_MW_DMA_0;
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
u8 addr;
/* Address table precomputed with a DCLK of 2 */
@@ -178,20 +178,20 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
/* Commence primary programming sequence */
/* First we load the device number into the timing select */
- outb(adev->devno, regio + MISC_REG);
+ iowrite8(adev->devno, regio + MISC_REG);
/* Now we load the data timings into read data/write data */
if (mode < XFER_MW_DMA_0) {
- outb(data_rec_timing[pci_clock][pio], regio + READ_REG);
- outb(data_rec_timing[pci_clock][pio], regio + WRITE_REG);
+ iowrite8(data_rec_timing[pci_clock][pio], regio + READ_REG);
+ iowrite8(data_rec_timing[pci_clock][pio], regio + WRITE_REG);
} else if (mode < XFER_UDMA_0) {
- outb(dma_data_rec_timing[pci_clock][dma], regio + READ_REG);
- outb(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG);
+ iowrite8(dma_data_rec_timing[pci_clock][dma], regio + READ_REG);
+ iowrite8(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG);
}
/* Finally we load the address setup into the misc register */
- outb(addr | adev->devno, regio + MISC_REG);
+ iowrite8(addr | adev->devno, regio + MISC_REG);
/* Programming sequence complete, timing 0 dev 0, timing 1 dev 1 */
- outb(0x85, regio + CNTRL_REG);
+ iowrite8(0x85, regio + CNTRL_REG);
/* Switch back to IDE mode */
optidma_lock(ap);
@@ -389,14 +389,14 @@ static struct ata_port_operations optidma_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations optiplus_port_ops = {
@@ -424,14 +424,14 @@ static struct ata_port_operations optiplus_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 9ed7f58424a..acfc09f9abd 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -88,14 +88,14 @@ static struct ata_port_operations pcmcia_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .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 = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
#define CS_CHECK(fn, ret) \
@@ -123,6 +123,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
cistpl_cftable_entry_t *cfg;
int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM;
unsigned long io_base, ctl_base;
+ void __iomem *io_addr, *ctl_addr;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL)
@@ -233,10 +234,17 @@ next_entry:
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+ /* iomap */
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io_base, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, ctl_base, 1);
+ if (!io_addr || !ctl_addr)
+ goto failed;
+
/* Success. Disable the IRQ nIEN line, do quirks */
- outb(0x02, ctl_base);
+ iowrite8(0x02, ctl_addr);
if (is_kme)
- outb(0x81, ctl_base + 0x01);
+ iowrite8(0x81, ctl_addr + 0x01);
/* FIXME: Could be more ports at base + 0x10 but we only deal with
one right now */
@@ -258,11 +266,12 @@ next_entry:
ae.irq = pdev->irq.AssignedIRQ;
ae.irq_flags = SA_SHIRQ;
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io_base;
- ae.port[0].altstatus_addr = ctl_base;
- ae.port[0].ctl_addr = ctl_base;
+ 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)
goto failed;
@@ -298,7 +307,7 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev)
/* If we have attached the device to the ATA layer, detach it */
if (info->ndev) {
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
info->ndev = 0;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 76dd1c935db..ffa7f47fbb2 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -33,7 +33,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "pata_pdc2027x"
#define DRV_VERSION "0.74-ac5"
@@ -46,6 +45,8 @@
#endif
enum {
+ PDC_MMIO_BAR = 5,
+
PDC_UDMA_100 = 0,
PDC_UDMA_133 = 1,
@@ -62,7 +63,6 @@ enum {
};
static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void pdc2027x_remove_one(struct pci_dev *pdev);
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);
@@ -123,7 +123,7 @@ static struct pci_driver pdc2027x_pci_driver = {
.name = DRV_NAME,
.id_table = pdc2027x_pci_tbl,
.probe = pdc2027x_init_one,
- .remove = __devexit_p(pdc2027x_remove_one),
+ .remove = ata_pci_remove_one,
};
static struct scsi_host_template pdc2027x_sht = {
@@ -160,7 +160,7 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -169,10 +169,10 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static struct ata_port_operations pdc2027x_pata133_ops = {
@@ -194,7 +194,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -203,10 +203,10 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static struct ata_port_info pdc2027x_port_info[] = {
@@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);
*/
static inline void __iomem *port_mmio(struct ata_port *ap, unsigned int offset)
{
- return ap->host->mmio_base + ap->port_no * 0x100 + offset;
+ return ap->host->iomap[PDC_MMIO_BAR] + ap->port_no * 0x100 + offset;
}
/**
@@ -526,18 +526,19 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
static long pdc_read_counter(struct ata_probe_ent *probe_ent)
{
+ void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
long counter;
int retry = 1;
u32 bccrl, bccrh, bccrlv, bccrhv;
retry:
- bccrl = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrh = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
+ bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
rmb();
/* Read the counter values again for verification */
- bccrlv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrhv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
+ bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
rmb();
counter = (bccrh << 15) | bccrl;
@@ -568,7 +569,7 @@ retry:
*/
static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
{
-
+ void __iomem *mmio_base = probe_ent->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;
@@ -587,7 +588,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
/* Show the current clock value of PLL control register
* (maybe already configured by the firmware)
*/
- pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+ pll_ctl = readw(mmio_base + PDC_PLL_CTL);
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
#endif
@@ -627,8 +628,8 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl);
- writew(pll_ctl, probe_ent->mmio_base + PDC_PLL_CTL);
- readw(probe_ent->mmio_base + PDC_PLL_CTL); /* flush */
+ writew(pll_ctl, mmio_base + PDC_PLL_CTL);
+ readw(mmio_base + PDC_PLL_CTL); /* flush */
/* Wait the PLL circuit to be stable */
mdelay(30);
@@ -638,7 +639,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
* Show the current clock value of PLL control register
* (maybe configured by the firmware)
*/
- pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+ pll_ctl = readw(mmio_base + PDC_PLL_CTL);
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
#endif
@@ -654,6 +655,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
*/
static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
{
+ void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
u32 scr;
long start_count, end_count;
long pll_clock;
@@ -662,10 +664,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
start_count = pdc_read_counter(probe_ent);
/* Start the test mode */
- scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+ scr = readl(mmio_base + PDC_SYS_CTL);
PDPRINTK("scr[%X]\n", scr);
- writel(scr | (0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
- readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+ writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
+ readl(mmio_base + PDC_SYS_CTL); /* flush */
/* Let the counter run for 100 ms. */
mdelay(100);
@@ -674,10 +676,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
end_count = pdc_read_counter(probe_ent);
/* Stop the test mode */
- scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+ scr = readl(mmio_base + PDC_SYS_CTL);
PDPRINTK("scr[%X]\n", scr);
- writel(scr & ~(0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
- readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+ writel(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL);
+ readl(mmio_base + PDC_SYS_CTL); /* flush */
/* calculate the input clock in Hz */
pll_clock = (start_count - end_count) * 10;
@@ -722,7 +724,7 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
* @port: ata ioports to setup
* @base: base address
*/
-static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base;
@@ -755,48 +757,37 @@ 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 = NULL;
- unsigned long base;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
if (rc)
- goto err_out;
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
/* Prepare the probe entry */
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ 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);
- mmio_base = pci_iomap(pdev, 5, 0);
- if (!mmio_base) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- base = (unsigned long) mmio_base;
-
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;
@@ -806,12 +797,14 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- pdc_ata_setup_port(&probe_ent->port[0], base + 0x17c0);
- probe_ent->port[0].bmdma_addr = base + 0x1000;
- pdc_ata_setup_port(&probe_ent->port[1], base + 0x15c0);
- probe_ent->port[1].bmdma_addr = 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;
@@ -820,32 +813,13 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
/* initialize adapter */
if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
- goto err_out_free_ent;
+ return -EIO;
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
-}
-
-/**
- * pdc2027x_remove_one - Called to remove a single instance of the
- * adapter.
- *
- * @dev: The PCI device to remove.
- * FIXME: module load/unload not working yet
- */
-static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
-{
- ata_pci_remove_one(pdev);
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index ad691b9e774..6dd63413a52 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -170,17 +170,17 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
struct ata_taskfile *tf = &qc->tf;
int sel66 = ap->port_no ? 0x08: 0x02;
- unsigned long master = ap->host->ports[0]->ioaddr.bmdma_addr;
- unsigned long clock = master + 0x11;
- unsigned long atapi_reg = master + 0x20 + (4 * ap->port_no);
+ void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
+ void __iomem *clock = master + 0x11;
+ void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
u32 len;
/* Check we keep host level locking here */
if (adev->dma_mode >= XFER_UDMA_2)
- outb(inb(clock) | sel66, clock);
+ iowrite8(ioread8(clock) | sel66, clock);
else
- outb(inb(clock) & ~sel66, clock);
+ iowrite8(ioread8(clock) & ~sel66, clock);
/* The DMA clocks may have been trashed by a reset. FIXME: make conditional
and move to qc_issue ? */
@@ -189,17 +189,14 @@ 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)
{
- if (tf->flags & ATA_TFLAG_LBA48)
- len = qc->nsect * 512;
- else
- len = qc->nbytes;
+ len = qc->nbytes;
if (tf->flags & ATA_TFLAG_WRITE)
len |= 0x06000000;
else
len |= 0x05000000;
- outl(len, atapi_reg);
+ iowrite32(len, atapi_reg);
}
/* Activate DMA */
@@ -222,19 +219,19 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
int sel66 = ap->port_no ? 0x08: 0x02;
/* The clock bits are in the same register for both channels */
- unsigned long master = ap->host->ports[0]->ioaddr.bmdma_addr;
- unsigned long clock = master + 0x11;
- unsigned long atapi_reg = master + 0x20 + (4 * ap->port_no);
+ void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
+ void __iomem *clock = master + 0x11;
+ void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
/* Cases the state machine will not complete correctly */
if (tf->protocol == ATA_PROT_ATAPI_DMA || ( tf->flags & ATA_TFLAG_LBA48)) {
- outl(0, atapi_reg);
- outb(inb(clock) & ~sel66, clock);
+ iowrite32(0, atapi_reg);
+ iowrite8(ioread8(clock) & ~sel66, clock);
}
/* Check we keep host level locking here */
/* Flip back to 33Mhz for PIO */
if (adev->dma_mode >= XFER_UDMA_2)
- outb(inb(clock) & ~sel66, clock);
+ iowrite8(ioread8(clock) & ~sel66, clock);
ata_bmdma_stop(qc);
}
@@ -297,14 +294,14 @@ static struct ata_port_operations pdc2024x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations pdc2026x_port_ops = {
@@ -331,14 +328,14 @@ static struct ata_port_operations pdc2026x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 443b1d85c6c..479a326114e 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -30,7 +30,7 @@ static int pio_mask = 1;
* Provide our own set_mode() as we don't want to change anything that has
* already been configured..
*/
-static void pata_platform_set_mode(struct ata_port *ap)
+static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused)
{
int i;
@@ -44,23 +44,7 @@ static void pata_platform_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
-}
-
-static void pata_platform_host_stop(struct ata_host *host)
-{
- int i;
-
- /*
- * Unmap the bases for MMIO
- */
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (ap->flags & ATA_FLAG_MMIO) {
- iounmap((void __iomem *)ap->ioaddr.ctl_addr);
- iounmap((void __iomem *)ap->ioaddr.cmd_addr);
- }
- }
+ return 0;
}
static struct scsi_host_template pata_platform_sht = {
@@ -99,14 +83,14 @@ static struct ata_port_operations pata_platform_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .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 = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = pata_platform_host_stop
};
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
@@ -152,7 +136,6 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
struct resource *io_res, *ctl_res;
struct ata_probe_ent ae;
unsigned int mmio;
- int ret;
/*
* Simple resource validation ..
@@ -206,46 +189,29 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
* Handle the MMIO case
*/
if (mmio) {
- ae.port_flags |= ATA_FLAG_MMIO;
-
- ae.port[0].cmd_addr = (unsigned long)ioremap(io_res->start,
+ ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
- if (unlikely(!ae.port[0].cmd_addr)) {
- dev_err(&pdev->dev, "failed to remap IO base\n");
- return -ENXIO;
- }
-
- ae.port[0].ctl_addr = (unsigned long)ioremap(ctl_res->start,
+ ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
- if (unlikely(!ae.port[0].ctl_addr)) {
- dev_err(&pdev->dev, "failed to remap CTL base\n");
- ret = -ENXIO;
- goto bad_remap;
- }
} else {
- ae.port[0].cmd_addr = io_res->start;
- ae.port[0].ctl_addr = ctl_res->start;
+ ae.port[0].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,
+ ctl_res->end - ctl_res->start + 1);
+ }
+ if (!ae.port[0].cmd_addr || !ae.port[0].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;
pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
- if (unlikely(ata_device_add(&ae) == 0)) {
- ret = -ENODEV;
- goto add_failed;
- }
+ if (unlikely(ata_device_add(&ae) == 0))
+ return -ENODEV;
return 0;
-
-add_failed:
- if (ae.port[0].ctl_addr && mmio)
- iounmap((void __iomem *)ae.port[0].ctl_addr);
-bad_remap:
- if (ae.port[0].cmd_addr && mmio)
- iounmap((void __iomem *)ae.port[0].cmd_addr);
-
- return ret;
}
/**
@@ -260,7 +226,7 @@ static int __devexit pata_platform_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ 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 36f621abc39..1b3b4ed8eb1 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -131,22 +131,24 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
if (ata_id_has_dword_io(adev->id)) {
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le32(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le32(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
} else
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
}
static struct scsi_host_template qdi_sht = {
@@ -189,10 +191,10 @@ static struct ata_port_operations qdi6500_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations qdi6580_port_ops = {
@@ -217,10 +219,10 @@ static struct ata_port_operations qdi6580_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -238,17 +240,22 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
{
struct ata_probe_ent ae;
struct platform_device *pdev;
+ void __iomem *io_addr, *ctl_addr;
int ret;
- unsigned long ctrl = io + 0x206;
-
/*
* Fill in a probe structure first of all
*/
pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, io + 0x206, 1);
+ if (!io_addr || !ctl_addr)
+ goto fail;
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
@@ -267,9 +274,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io;
- ae.port[0].altstatus_addr = ctrl;
- ae.port[0].ctl_addr = ctrl;
+ 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]);
/*
@@ -282,14 +289,17 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
qdi_data[nr_qdi_host].platform_dev = pdev;
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
- ret = ata_device_add(&ae);
- if (ret == 0) {
- platform_device_unregister(pdev);
- return -ENODEV;
- }
+
+ ret = -ENODEV;
+ if (!ata_device_add(&ae))
+ goto fail;
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
return 0;
+
+ fail:
+ platform_device_unregister(pdev);
+ return ret;
}
/**
@@ -382,7 +392,7 @@ static __exit void qdi_exit(void)
int i;
for (i = 0; i < nr_qdi_host; i++) {
- ata_host_remove(qdi_host[i]);
+ ata_host_detach(qdi_host[i]);
/* Free the control resource. The 6580 dual channel has the resources
* claimed as a pair of 2 byte resources so we need no special cases...
*/
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 065541d034a..0d1e571ef63 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -255,14 +255,14 @@ static const struct ata_port_operations radisys_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = radisys_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 3677c642c9f..71a2bac09e0 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap)
/**
* rz1000_set_mode - mode setting function
* @ap: ATA interface
+ * @unused: returned device on set_mode failure
*
* Use a non standard set_mode function. We don't want to be tuned. We
* would prefer to be BIOS generic but for the fact our hardware is
* whacked out.
*/
-static void rz1000_set_mode(struct ata_port *ap)
+static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
{
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)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
@@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap)
dev->flags |= ATA_DFLAG_PIO;
}
}
+ return 0;
}
@@ -105,8 +107,6 @@ static struct ata_port_operations rz1000_port_ops = {
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .error_handler = rz1000_error_handler,
-
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
@@ -115,7 +115,7 @@ static struct ata_port_operations rz1000_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -124,10 +124,10 @@ static struct ata_port_operations rz1000_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int rz1000_fifo_disable(struct pci_dev *pdev)
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index a3b35bc5039..58e42fbd14f 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -220,14 +220,14 @@ static struct ata_port_operations sc1200_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = sc1200_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index f02b6a3b0f1..ad5b43fef3d 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -218,25 +218,18 @@ static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct a
static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
const char *p;
- char model_num[40];
- int len, i;
+ char model_num[ATA_ID_PROD_LEN + 1];
+ int i;
/* Disk, UDMA */
if (adev->class != ATA_DEV_ATA)
return ata_pci_default_filter(ap, adev, mask);
/* Actually do need to check */
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
- /* Precuationary - why not do this in the libata core ?? */
+ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- len = strlen(model_num);
- while ((len > 0) && (model_num[len - 1] == ' ')) {
- len--;
- model_num[len] = 0;
- }
-
- for(i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
- if (!strncmp(p, model_num, len))
+ for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
+ if (!strcmp(p, model_num))
mask &= ~(0x1F << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(ap, adev, mask);
@@ -355,14 +348,14 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations serverworks_csb_port_ops = {
@@ -390,14 +383,14 @@ static struct ata_port_operations serverworks_csb_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int serverworks_fixup_osb4(struct pci_dev *pdev)
@@ -559,7 +552,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
{
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
-
+
switch (pdev->device)
{
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 32cf0bfa892..ed79fabe025 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -135,7 +135,7 @@ static void sil680_error_handler(struct ata_port *ap)
static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
- static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 };
+ static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };
unsigned long tfaddr = sil680_selreg(ap, 0x02);
unsigned long addr = sil680_seldev(ap, adev, 0x04);
@@ -252,14 +252,14 @@ static struct ata_port_operations sil680_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -270,7 +270,7 @@ static struct ata_port_operations sil680_port_ops = {
* is powered up on boot and when we resume in case we resumed from RAM.
* Returns the final clock settings.
*/
-
+
static u8 sil680_init_chip(struct pci_dev *pdev)
{
u32 class_rev = 0;
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 916cedb3d75..560103d55b2 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -32,7 +32,9 @@
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/ata.h>
+#include "libata.h"
+#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "pata_sis"
#define DRV_VERSION "0.4.5"
@@ -43,6 +45,34 @@ struct sis_chipset {
up code later */
};
+struct sis_laptop {
+ u16 device;
+ u16 subvendor;
+ u16 subdevice;
+};
+
+static const struct sis_laptop sis_laptop[] = {
+ /* devid, subvendor, subdev */
+ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */
+ /* end marker */
+ { 0, }
+};
+
+static int sis_short_ata40(struct pci_dev *dev)
+{
+ const struct sis_laptop *lap = &sis_laptop[0];
+
+ while (lap->device) {
+ if (lap->device == dev->device &&
+ lap->subvendor == dev->subsystem_vendor &&
+ lap->subdevice == dev->subsystem_device)
+ return 1;
+ lap++;
+ }
+
+ return 0;
+}
+
/**
* sis_port_base - return PCI configuration base for dev
* @adev: device
@@ -79,7 +109,7 @@ static int sis_133_pre_reset(struct ata_port *ap)
/* 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)
+ if ((tmp & 0x8000) && !sis_short_ata40(pdev))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -127,7 +157,7 @@ static int sis_66_pre_reset(struct ata_port *ap)
/* 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)
+ if ((tmp & 0x10) && !sis_short_ata40(pdev))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -573,14 +603,14 @@ static const struct ata_port_operations sis_133_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_133_early_ops = {
@@ -606,14 +636,14 @@ static const struct ata_port_operations sis_133_early_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_100_ops = {
@@ -640,14 +670,14 @@ static const struct ata_port_operations sis_100_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_66_ops = {
@@ -673,14 +703,14 @@ static const struct ata_port_operations sis_66_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_old_ops = {
@@ -706,14 +736,14 @@ static const struct ata_port_operations sis_old_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info sis_info = {
@@ -753,7 +783,7 @@ static struct ata_port_info sis_info100_early = {
.pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
-static struct ata_port_info sis_info133 = {
+struct ata_port_info sis_info133 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -768,6 +798,8 @@ static struct ata_port_info sis_info133_early = {
.port_ops = &sis_133_early_ops,
};
+/* Privately shared with the SiS180 SATA driver, not for use elsewhere */
+EXPORT_SYMBOL_GPL(sis_info133);
static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
{
@@ -847,7 +879,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct sis_chipset *chipset = NULL;
static struct sis_chipset sis_chipsets[] = {
-
+
{ 0x0968, &sis_info133 },
{ 0x0966, &sis_info133 },
{ 0x0965, &sis_info133 },
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index e94f515ef54..f2fa158d07c 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -139,13 +139,13 @@ 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, 1);
+ 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, 3);
+ sl82c105_configure_piomode(ap, adev, 4);
break;
default:
BUG();
@@ -262,14 +262,14 @@ static struct ata_port_operations sl82c105_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index a142971f130..453ab90b721 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -221,14 +221,14 @@ static struct ata_port_operations triflex_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index cc09d47fb92..220fcd6c549 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -23,6 +23,7 @@
* VIA VT8233c - UDMA100
* VIA VT8235 - UDMA133
* VIA VT8237 - UDMA133
+ * VIA VT8237S - UDMA133
* VIA VT8251 - UDMA133
*
* Most registers remain compatible across chips. Others start reserved
@@ -61,7 +62,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_via"
-#define DRV_VERSION "0.2.0"
+#define DRV_VERSION "0.2.1"
/*
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -95,6 +96,7 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
@@ -161,10 +163,15 @@ static int via_pre_reset(struct ata_port *ap)
return -ENOENT;
}
- if ((config->flags & VIA_UDMA) >= VIA_UDMA_66)
+ if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
ap->cbl = via_cable_detect(ap);
- else
+ /* 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);
}
@@ -327,14 +334,14 @@ static struct ata_port_operations via_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations via_port_ops_noirq = {
@@ -362,14 +369,14 @@ static struct ata_port_operations via_port_ops_noirq = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .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 = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -384,13 +391,13 @@ static struct ata_port_operations via_port_ops_noirq = {
static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
{
u8 enable;
-
+
/* 0x40 low bits indicate enabled channels */
pci_read_config_byte(pdev, 0x40 , &enable);
enable &= 3;
-
+
if (flags & VIA_SET_FIFO) {
- u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
+ static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
u8 fifo;
pci_read_config_byte(pdev, 0x43, &fifo);
@@ -509,7 +516,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initialise the FIFO for the enabled channels. */
via_config_fifo(pdev, config->flags);
-
+
/* Clock set up */
switch(config->flags & VIA_UDMA) {
case VIA_UDMA_NONE:
@@ -568,7 +575,7 @@ static int via_reinit_one(struct pci_dev *pdev)
u32 timing;
struct ata_host *host = dev_get_drvdata(&pdev->dev);
const struct via_isa_bridge *config = host->private_data;
-
+
via_config_fifo(pdev, config->flags);
if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
@@ -583,7 +590,7 @@ static int via_reinit_one(struct pci_dev *pdev)
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
- return ata_pci_device_resume(pdev);
+ return ata_pci_device_resume(pdev);
}
static const struct pci_device_id via[] = {
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 3ea345cde52..0888b4f19f4 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -5,7 +5,7 @@
* Support for the Winbond 83759A when operating in advanced mode.
* Multichip mode is not currently supported.
*/
-
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -69,7 +69,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
reg = winbond_readcfg(winbond->config, 0x81);
-
+
/* Get the timing data in cycles */
if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
@@ -80,9 +80,9 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery;
winbond_writecfg(winbond->config, timing, reg);
-
+
/* Load the setup timing */
-
+
reg = 0x35;
if (adev->class != ATA_DEV_ATA)
reg |= 0x08; /* FIFO off */
@@ -100,22 +100,24 @@ static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsig
if (ata_id_has_dword_io(adev->id)) {
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le16(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
} else
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
}
static struct scsi_host_template winbond_sht = {
@@ -158,10 +160,10 @@ static struct ata_port_operations winbond_port_ops = {
.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,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -194,20 +196,29 @@ static __init int winbond_init_one(unsigned long port)
winbond_writecfg(port, 0x85, reg);
reg = winbond_readcfg(port, 0x81);
-
+
if (!(reg & 0x03)) /* Disabled */
return 0;
for (i = 0; i < 2 ; i ++) {
+ unsigned long cmd_port = 0x1F0 - (0x80 * i);
+ void __iomem *cmd_addr, *ctl_addr;
- if (reg & (1 << i)) {
+ 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 (pdev == NULL)
+ 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);
@@ -217,14 +228,14 @@ static __init int winbond_init_one(unsigned long port)
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 = 0x1F0 - (0x80 * i);
- ae.port[0].altstatus_addr = ae.port[0].cmd_addr + 0x0206;
- ae.port[0].ctl_addr = ae.port[0].altstatus_addr;
+ 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
@@ -257,7 +268,7 @@ static __init int winbond_init(void)
int ct = 0;
int i;
-
+
if (probe_winbond == 0)
return -ENODEV;
@@ -288,7 +299,7 @@ static __exit void winbond_exit(void)
int i;
for (i = 0; i < nr_winbond_host; i++) {
- ata_host_remove(winbond_host[i]);
+ ata_host_detach(winbond_host[i]);
release_region(winbond_data[i].config, 2);
platform_device_unregister(winbond_data[i].platform_dev);
}
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 9021e34d209..b4ed8ce553e 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -42,7 +42,6 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
-#include <asm/io.h>
#include <linux/libata.h>
#define DRV_NAME "pdc_adma"
@@ -52,9 +51,15 @@
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
/* macro to calculate base address for ADMA regs */
-#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
+#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)
enum {
+ ADMA_MMIO_BAR = 4,
+
ADMA_PORTS = 2,
ADMA_CPB_BYTES = 40,
ADMA_PRD_BYTES = LIBATA_MAX_PRD * 16,
@@ -167,9 +172,11 @@ static const struct ata_port_operations adma_ata_ops = {
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
.eng_timeout = adma_eng_timeout,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = adma_intr,
.irq_clear = adma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = adma_port_start,
.port_stop = adma_port_stop,
.host_stop = adma_host_stop,
@@ -235,11 +242,10 @@ 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 *mmio_base = ap->host->mmio_base;
- void __iomem *chan = ADMA_REGS(mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
/* mask/clear ATA interrupts */
- writeb(ATA_NIEN, (void __iomem *)ap->ioaddr.ctl_addr);
+ writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
ata_check_status(ap);
/* reset the ADMA engine */
@@ -263,7 +269,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_REGS(ap->host->mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
writew(aPIOMD4, chan + ADMA_CONTROL);
readb(chan + ADMA_STATUS); /* flush */
@@ -410,7 +416,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_REGS(ap->host->mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
VPRINTK("ENTER, ap %p\n", ap);
@@ -443,13 +449,12 @@ static unsigned int adma_qc_issue(struct ata_queued_cmd *qc)
static inline unsigned int adma_intr_pkt(struct ata_host *host)
{
unsigned int handled = 0, port_no;
- u8 __iomem *mmio_base = host->mmio_base;
for (port_no = 0; port_no < host->n_ports; ++port_no) {
struct ata_port *ap = host->ports[port_no];
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
- void __iomem *chan = ADMA_REGS(mmio_base, port_no);
+ void __iomem *chan = ADMA_HOST_REGS(host, port_no);
u8 status = readb(chan + ADMA_STATUS);
if (status == 0)
@@ -523,7 +528,7 @@ static irqreturn_t adma_intr(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-static void adma_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void adma_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base + 0x000;
@@ -550,48 +555,28 @@ static int adma_port_start(struct ata_port *ap)
if (rc)
return rc;
adma_enter_reg_mode(ap);
- rc = -ENOMEM;
- pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
- pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
- GFP_KERNEL);
+ return -ENOMEM;
+ pp->pkt = dmam_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
if (!pp->pkt)
- goto err_out_kfree;
+ return -ENOMEM;
/* paranoia? */
if ((pp->pkt_dma & 7) != 0) {
printk("bad alignment for pp->pkt_dma: %08x\n",
(u32)pp->pkt_dma);
- dma_free_coherent(dev, ADMA_PKT_BYTES,
- pp->pkt, pp->pkt_dma);
- goto err_out_kfree;
+ return -ENOMEM;
}
memset(pp->pkt, 0, ADMA_PKT_BYTES);
ap->private_data = pp;
adma_reinit_engine(ap);
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
static void adma_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
- struct adma_port_priv *pp = ap->private_data;
-
- adma_reset_engine(ADMA_REGS(ap->host->mmio_base, ap->port_no));
- if (pp != NULL) {
- ap->private_data = NULL;
- if (pp->pkt != NULL)
- dma_free_coherent(dev, ADMA_PKT_BYTES,
- pp->pkt, pp->pkt_dma);
- kfree(pp);
- }
- ata_port_stop(ap);
+ adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no));
}
static void adma_host_stop(struct ata_host *host)
@@ -599,16 +584,14 @@ 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_REGS(host->mmio_base, port_no));
-
- ata_pci_host_stop(host);
+ adma_reset_engine(ADMA_HOST_REGS(host, port_no));
}
static void adma_host_init(unsigned int chip_id,
struct ata_probe_ent *probe_ent)
{
unsigned int port_no;
- void __iomem *mmio_base = probe_ent->mmio_base;
+ void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR];
/* enable/lock aGO operation */
writeb(7, mmio_base + ADMA_MODE_LOCK);
@@ -638,7 +621,7 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
}
static int adma_ata_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
@@ -649,34 +632,25 @@ static int adma_ata_init_one(struct pci_dev *pdev,
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc)
- goto err_out;
-
- if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
- rc = -ENODEV;
- goto err_out_regions;
- }
+ if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0)
+ return -ENODEV;
- mmio_base = pci_iomap(pdev, 4, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME);
+ if (rc)
+ return rc;
+ mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR];
rc = adma_set_dma_masks(pdev, mmio_base);
if (rc)
- goto err_out_iounmap;
+ return rc;
- probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
+ 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);
@@ -690,12 +664,12 @@ static int adma_ata_init_one(struct pci_dev *pdev,
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
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],
- ADMA_ATA_REGS((unsigned long)mmio_base, port_no));
+ ADMA_ATA_REGS(mmio_base, port_no));
}
pci_set_master(pdev);
@@ -703,19 +677,11 @@ static int adma_ata_init_one(struct pci_dev *pdev,
/* initialize adapter */
adma_host_init(board_idx, probe_ent);
- rc = ata_device_add(probe_ent);
- kfree(probe_ent);
- if (rc != ADMA_PORTS)
- goto err_out_iounmap;
- return 0;
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
+ devm_kfree(&pdev->dev, probe_ent);
+ return 0;
}
static int __init adma_ata_init(void)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
new file mode 100644
index 00000000000..c5335f42280
--- /dev/null
+++ b/drivers/ata/sata_inic162x.c
@@ -0,0 +1,781 @@
+/*
+ * sata_inic162x.c - Driver for Initio 162x SATA controllers
+ *
+ * Copyright 2006 SUSE Linux Products GmbH
+ * Copyright 2006 Tejun Heo <teheo@novell.com>
+ *
+ * This file is released under GPL v2.
+ *
+ * This controller is eccentric and easily locks up if something isn't
+ * right. Documentation is available at initio's website but it only
+ * documents registers (not programming model).
+ *
+ * - ATA disks work.
+ * - Hotplug works.
+ * - ATAPI read works but burning doesn't. This thing is really
+ * peculiar about ATAPI and I couldn't figure out how ATAPI PIO and
+ * ATAPI DMA WRITE should be programmed. If you've got a clue, be
+ * my guest.
+ * - Both STR and STD work.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_device.h>
+
+#define DRV_NAME "sata_inic162x"
+#define DRV_VERSION "0.1"
+
+enum {
+ MMIO_BAR = 5,
+
+ NR_PORTS = 2,
+
+ HOST_CTL = 0x7c,
+ HOST_STAT = 0x7e,
+ HOST_IRQ_STAT = 0xbc,
+ HOST_IRQ_MASK = 0xbe,
+
+ PORT_SIZE = 0x40,
+
+ /* registers for ATA TF operation */
+ PORT_TF = 0x00,
+ PORT_ALT_STAT = 0x08,
+ PORT_IRQ_STAT = 0x09,
+ PORT_IRQ_MASK = 0x0a,
+ PORT_PRD_CTL = 0x0b,
+ PORT_PRD_ADDR = 0x0c,
+ PORT_PRD_XFERLEN = 0x10,
+
+ /* IDMA register */
+ PORT_IDMA_CTL = 0x14,
+
+ PORT_SCR = 0x20,
+
+ /* HOST_CTL bits */
+ HCTL_IRQOFF = (1 << 8), /* global IRQ off */
+ HCTL_PWRDWN = (1 << 13), /* power down PHYs */
+ HCTL_SOFTRST = (1 << 13), /* global reset (no phy reset) */
+ HCTL_RPGSEL = (1 << 15), /* register page select */
+
+ HCTL_KNOWN_BITS = HCTL_IRQOFF | HCTL_PWRDWN | HCTL_SOFTRST |
+ HCTL_RPGSEL,
+
+ /* HOST_IRQ_(STAT|MASK) bits */
+ HIRQ_PORT0 = (1 << 0),
+ HIRQ_PORT1 = (1 << 1),
+ HIRQ_SOFT = (1 << 14),
+ HIRQ_GLOBAL = (1 << 15), /* STAT only */
+
+ /* PORT_IRQ_(STAT|MASK) bits */
+ PIRQ_OFFLINE = (1 << 0), /* device unplugged */
+ PIRQ_ONLINE = (1 << 1), /* device plugged */
+ PIRQ_COMPLETE = (1 << 2), /* completion interrupt */
+ PIRQ_FATAL = (1 << 3), /* fatal error */
+ PIRQ_ATA = (1 << 4), /* ATA interrupt */
+ PIRQ_REPLY = (1 << 5), /* reply FIFO not empty */
+ PIRQ_PENDING = (1 << 7), /* port IRQ pending (STAT only) */
+
+ PIRQ_ERR = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL,
+
+ PIRQ_MASK_DMA_READ = PIRQ_REPLY | PIRQ_ATA,
+ PIRQ_MASK_OTHER = PIRQ_REPLY | PIRQ_COMPLETE,
+ PIRQ_MASK_FREEZE = 0xff,
+
+ /* PORT_PRD_CTL bits */
+ PRD_CTL_START = (1 << 0),
+ PRD_CTL_WR = (1 << 3),
+ PRD_CTL_DMAEN = (1 << 7), /* DMA enable */
+
+ /* PORT_IDMA_CTL bits */
+ IDMA_CTL_RST_ATA = (1 << 2), /* hardreset ATA bus */
+ IDMA_CTL_RST_IDMA = (1 << 5), /* reset IDMA machinary */
+ IDMA_CTL_GO = (1 << 7), /* IDMA mode go */
+ IDMA_CTL_ATA_NIEN = (1 << 8), /* ATA IRQ disable */
+};
+
+struct inic_host_priv {
+ u16 cached_hctl;
+};
+
+struct inic_port_priv {
+ u8 dfl_prdctl;
+ u8 cached_prdctl;
+ u8 cached_pirq_mask;
+};
+
+static int inic_slave_config(struct scsi_device *sdev)
+{
+ /* This controller is braindamaged. dma_boundary is 0xffff
+ * like others but it will lock up the whole machine HARD if
+ * 65536 byte PRD entry is fed. Reduce maximum segment size.
+ */
+ blk_queue_max_segment_size(sdev->request_queue, 65536 - 512);
+
+ return ata_scsi_slave_config(sdev);
+}
+
+static struct scsi_host_template inic_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 = inic_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+};
+
+static const int scr_map[] = {
+ [SCR_STATUS] = 0,
+ [SCR_ERROR] = 1,
+ [SCR_CONTROL] = 2,
+};
+
+static void __iomem * inic_port_base(struct ata_port *ap)
+{
+ return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE;
+}
+
+static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp = ap->private_data;
+
+ writeb(mask, port_base + PORT_IRQ_MASK);
+ pp->cached_pirq_mask = mask;
+}
+
+static void inic_set_pirq_mask(struct ata_port *ap, u8 mask)
+{
+ struct inic_port_priv *pp = ap->private_data;
+
+ if (pp->cached_pirq_mask != mask)
+ __inic_set_pirq_mask(ap, mask);
+}
+
+static void inic_reset_port(void __iomem *port_base)
+{
+ void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
+ u16 ctl;
+
+ ctl = readw(idma_ctl);
+ ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO);
+
+ /* mask IRQ and assert reset */
+ writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl);
+ readw(idma_ctl); /* flush */
+
+ /* give it some time */
+ msleep(1);
+
+ /* release reset */
+ writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl);
+
+ /* clear irq */
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ /* reenable ATA IRQ, turn off IDMA mode */
+ writew(ctl, idma_ctl);
+}
+
+static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *addr;
+ u32 val;
+
+ if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
+ return 0xffffffffU;
+
+ addr = scr_addr + scr_map[sc_reg] * 4;
+ val = readl(scr_addr + scr_map[sc_reg] * 4);
+
+ /* this controller has stuck DIAG.N, ignore it */
+ if (sc_reg == SCR_ERROR)
+ val &= ~SERR_PHYRDY_CHG;
+ return val;
+}
+
+static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *addr;
+
+ if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
+ return;
+
+ addr = scr_addr + scr_map[sc_reg] * 4;
+ writel(val, scr_addr + scr_map[sc_reg] * 4);
+}
+
+/*
+ * In TF mode, inic162x is very similar to SFF device. TF registers
+ * function the same. DMA engine behaves similary using the same PRD
+ * format as BMDMA but different command register, interrupt and event
+ * notification methods are used. The following inic_bmdma_*()
+ * functions do the impedance matching.
+ */
+static void inic_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+ int rw = qc->tf.flags & ATA_TFLAG_WRITE;
+
+ /* make sure device sees PRD table writes */
+ wmb();
+
+ /* load transfer length */
+ writel(qc->nbytes, port_base + PORT_PRD_XFERLEN);
+
+ /* turn on DMA and specify data direction */
+ pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN;
+ if (!rw)
+ pp->cached_prdctl |= PRD_CTL_WR;
+ writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
+
+ /* issue r/w command */
+ ap->ops->exec_command(ap, &qc->tf);
+}
+
+static void inic_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* start host DMA transaction */
+ pp->cached_prdctl |= PRD_CTL_START;
+ writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
+}
+
+static void inic_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* stop DMA engine */
+ writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
+}
+
+static u8 inic_bmdma_status(struct ata_port *ap)
+{
+ /* event is already verified by the interrupt handler */
+ return ATA_DMA_INTR;
+}
+
+static void inic_irq_clear(struct ata_port *ap)
+{
+ /* noop */
+}
+
+static void inic_host_intr(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct ata_eh_info *ehi = &ap->eh_info;
+ u8 irq_stat;
+
+ /* fetch and clear irq */
+ irq_stat = readb(port_base + PORT_IRQ_STAT);
+ writeb(irq_stat, port_base + PORT_IRQ_STAT);
+
+ if (likely(!(irq_stat & PIRQ_ERR))) {
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+
+ if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
+ ata_chk_status(ap); /* clear ATA interrupt */
+ return;
+ }
+
+ if (likely(ata_host_intr(ap, qc)))
+ return;
+
+ ata_chk_status(ap); /* clear ATA interrupt */
+ ata_port_printk(ap, KERN_WARNING, "unhandled "
+ "interrupt, irq_stat=%x\n", irq_stat);
+ return;
+ }
+
+ /* error */
+ ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat);
+
+ if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
+ } else
+ ata_port_abort(ap);
+}
+
+static irqreturn_t inic_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ void __iomem *mmio_base = host->iomap[MMIO_BAR];
+ u16 host_irq_stat;
+ int i, handled = 0;;
+
+ host_irq_stat = readw(mmio_base + HOST_IRQ_STAT);
+
+ if (unlikely(!(host_irq_stat & HIRQ_GLOBAL)))
+ goto out;
+
+ spin_lock(&host->lock);
+
+ for (i = 0; i < NR_PORTS; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!(host_irq_stat & (HIRQ_PORT0 << i)))
+ continue;
+
+ if (likely(ap && !(ap->flags & ATA_FLAG_DISABLED))) {
+ inic_host_intr(ap);
+ handled++;
+ } else {
+ if (ata_ratelimit())
+ dev_printk(KERN_ERR, host->dev, "interrupt "
+ "from disabled port %d (0x%x)\n",
+ i, host_irq_stat);
+ }
+ }
+
+ spin_unlock(&host->lock);
+
+ out:
+ return IRQ_RETVAL(handled);
+}
+
+static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ /* ATA IRQ doesn't wait for DMA transfer completion and vice
+ * versa. Mask IRQ selectively to detect command completion.
+ * Without it, ATA DMA read command can cause data corruption.
+ *
+ * Something similar might be needed for ATAPI writes. I
+ * tried a lot of combinations but couldn't find the solution.
+ */
+ if (qc->tf.protocol == ATA_PROT_DMA &&
+ !(qc->tf.flags & ATA_TFLAG_WRITE))
+ inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ);
+ else
+ inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+
+ /* Issuing a command to yet uninitialized port locks up the
+ * controller. Most of the time, this happens for the first
+ * command after reset which are ATA and ATAPI IDENTIFYs.
+ * Fast fail if stat is 0x7f or 0xff for those commands.
+ */
+ if (unlikely(qc->tf.command == ATA_CMD_ID_ATA ||
+ qc->tf.command == ATA_CMD_ID_ATAPI)) {
+ u8 stat = ata_chk_status(ap);
+ if (stat == 0x7f || stat == 0xff)
+ return AC_ERR_HSM;
+ }
+
+ return ata_qc_issue_prot(qc);
+}
+
+static void inic_freeze(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ __inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE);
+
+ ata_chk_status(ap);
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ readb(port_base + PORT_IRQ_STAT); /* flush */
+}
+
+static void inic_thaw(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ ata_chk_status(ap);
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+
+ readb(port_base + PORT_IRQ_STAT); /* flush */
+}
+
+/*
+ * SRST and SControl hardreset don't give valid signature on this
+ * controller. Only controller specific hardreset mechanism works.
+ */
+static int inic_hardreset(struct ata_port *ap, unsigned int *class)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
+ const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+ u16 val;
+ int rc;
+
+ /* hammer it into sane state */
+ inic_reset_port(port_base);
+
+ val = readw(idma_ctl);
+ writew(val | IDMA_CTL_RST_ATA, idma_ctl);
+ readw(idma_ctl); /* flush */
+ msleep(1);
+ writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
+
+ rc = sata_phy_resume(ap, timing);
+ if (rc) {
+ ata_port_printk(ap, KERN_WARNING, "failed to resume "
+ "link after reset (errno=%d)\n", rc);
+ return rc;
+ }
+
+ *class = ATA_DEV_NONE;
+ if (ata_port_online(ap)) {
+ struct ata_taskfile tf;
+
+ /* wait a while before checking status */
+ msleep(150);
+
+ if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "device busy after hardreset\n");
+ return -EIO;
+ }
+
+ ata_tf_read(ap, &tf);
+ *class = ata_dev_classify(&tf);
+ if (*class == ATA_DEV_UNKNOWN)
+ *class = ATA_DEV_NONE;
+ }
+
+ return 0;
+}
+
+static void inic_error_handler(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp = ap->private_data;
+ unsigned long flags;
+
+ /* reset PIO HSM and stop DMA engine */
+ inic_reset_port(port_base);
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->hsm_task_state = HSM_ST_IDLE;
+ writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* PIO and DMA engines have been stopped, perform recovery */
+ ata_do_eh(ap, ata_std_prereset, NULL, inic_hardreset,
+ ata_std_postreset);
+}
+
+static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+ /* make DMA engine forget about the failed command */
+ if (qc->err_mask)
+ inic_reset_port(inic_port_base(qc->ap));
+}
+
+static void inic_dev_config(struct ata_port *ap, struct ata_device *dev)
+{
+ /* inic can only handle upto LBA28 max sectors */
+ if (dev->max_sectors > ATA_MAX_SECTORS)
+ dev->max_sectors = ATA_MAX_SECTORS;
+}
+
+static void init_port(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* Setup PRD address */
+ writel(ap->prd_dma, port_base + PORT_PRD_ADDR);
+}
+
+static int inic_port_resume(struct ata_port *ap)
+{
+ init_port(ap);
+ return 0;
+}
+
+static int inic_port_start(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp;
+ u8 tmp;
+ int rc;
+
+ /* alloc and initialize private data */
+ pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+ ap->private_data = pp;
+
+ /* default PRD_CTL value, DMAEN, WR and START off */
+ tmp = readb(port_base + PORT_PRD_CTL);
+ tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START);
+ pp->dfl_prdctl = tmp;
+
+ /* Alloc resources */
+ rc = ata_port_start(ap);
+ if (rc) {
+ kfree(pp);
+ return rc;
+ }
+
+ init_port(ap);
+
+ return 0;
+}
+
+static struct ata_port_operations inic_port_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .scr_read = inic_scr_read,
+ .scr_write = inic_scr_write,
+
+ .bmdma_setup = inic_bmdma_setup,
+ .bmdma_start = inic_bmdma_start,
+ .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,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = inic_qc_issue,
+ .data_xfer = ata_data_xfer,
+
+ .freeze = inic_freeze,
+ .thaw = inic_thaw,
+ .error_handler = inic_error_handler,
+ .post_internal_cmd = inic_post_internal_cmd,
+ .dev_config = inic_dev_config,
+
+ .port_resume = inic_port_resume,
+
+ .port_start = inic_port_start,
+};
+
+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
+ * results in machine lock up. Tell libata to always prefer
+ * DMA.
+ */
+ .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &inic_port_ops
+};
+
+static int init_controller(void __iomem *mmio_base, u16 hctl)
+{
+ int i;
+ u16 val;
+
+ hctl &= ~HCTL_KNOWN_BITS;
+
+ /* Soft reset whole controller. Spec says reset duration is 3
+ * PCI clocks, be generous and give it 10ms.
+ */
+ writew(hctl | HCTL_SOFTRST, mmio_base + HOST_CTL);
+ readw(mmio_base + HOST_CTL); /* flush */
+
+ for (i = 0; i < 10; i++) {
+ msleep(1);
+ val = readw(mmio_base + HOST_CTL);
+ if (!(val & HCTL_SOFTRST))
+ break;
+ }
+
+ if (val & HCTL_SOFTRST)
+ return -EIO;
+
+ /* mask all interrupts and reset ports */
+ for (i = 0; i < NR_PORTS; i++) {
+ void __iomem *port_base = mmio_base + i * PORT_SIZE;
+
+ writeb(0xff, port_base + PORT_IRQ_MASK);
+ inic_reset_port(port_base);
+ }
+
+ /* port IRQ is masked now, unmask global IRQ */
+ writew(hctl & ~HCTL_IRQOFF, mmio_base + HOST_CTL);
+ val = readw(mmio_base + HOST_IRQ_MASK);
+ val &= ~(HIRQ_PORT0 | HIRQ_PORT1);
+ writew(val, mmio_base + HOST_IRQ_MASK);
+
+ return 0;
+}
+
+static int inic_pci_device_resume(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct inic_host_priv *hpriv = host->private_data;
+ void __iomem *mmio_base = host->iomap[MMIO_BAR];
+ int rc;
+
+ ata_pci_device_do_resume(pdev);
+
+ 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;
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+
+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;
+ struct inic_host_priv *hpriv;
+ void __iomem * const *iomap;
+ int i, rc;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ return rc;
+
+ rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
+ if (rc)
+ return rc;
+ iomap = pcim_iomap_table(pdev);
+
+ /* Set dma_mask. This devices doesn't support 64bit addressing. */
+ 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;
+ }
+
+ 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 = SA_SHIRQ;
+
+ 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,
+ "failed to initialize controller\n");
+ return rc;
+ }
+
+ pci_set_master(pdev);
+
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+
+ devm_kfree(&pdev->dev, probe_ent);
+
+ return 0;
+}
+
+static const struct pci_device_id inic_pci_tbl[] = {
+ { PCI_VDEVICE(INIT, 0x1622), },
+ { },
+};
+
+static struct pci_driver inic_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = inic_pci_tbl,
+ .suspend = ata_pci_device_suspend,
+ .resume = inic_pci_device_resume,
+ .probe = inic_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static int __init inic_init(void)
+{
+ return pci_register_driver(&inic_pci_driver);
+}
+
+static void __exit inic_exit(void)
+{
+ pci_unregister_driver(&inic_pci_driver);
+}
+
+MODULE_AUTHOR("Tejun Heo");
+MODULE_DESCRIPTION("low-level driver for Initio 162x SATA");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(pci, inic_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(inic_init);
+module_exit(inic_exit);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 1b8e0eb9e03..769eca52442 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -34,7 +34,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_mv"
#define DRV_VERSION "0.7"
@@ -342,7 +341,6 @@ static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static void mv_phy_reset(struct ata_port *ap);
static void __mv_phy_reset(struct ata_port *ap, int can_sleep);
-static void mv_host_stop(struct ata_host *host);
static int mv_port_start(struct ata_port *ap);
static void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc);
@@ -406,19 +404,20 @@ static const struct ata_port_operations mv5_ops = {
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv5_scr_read,
.scr_write = mv5_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_operations mv6_ops = {
@@ -434,19 +433,20 @@ static const struct ata_port_operations mv6_ops = {
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_operations mv_iie_ops = {
@@ -462,19 +462,20 @@ static const struct ata_port_operations mv_iie_ops = {
.qc_prep = mv_qc_prep_iie,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_info mv_port_info[] = {
@@ -523,8 +524,7 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_7042 */
.sht = &mv_sht,
- .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- MV_FLAG_DUAL_HC),
+ .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &mv_iie_ops,
@@ -545,6 +545,8 @@ static const struct pci_device_id mv_pci_tbl[] = {
{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+ { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+
{ } /* terminate list */
};
@@ -619,7 +621,7 @@ static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port)
static inline void __iomem *mv_ap_base(struct ata_port *ap)
{
- return mv_port_base(ap->host->mmio_base, ap->port_no);
+ return mv_port_base(ap->host->iomap[MV_PRIMARY_BAR], ap->port_no);
}
static inline int mv_get_hc_count(unsigned long port_flags)
@@ -808,35 +810,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
}
-/**
- * mv_host_stop - Host specific cleanup/stop routine.
- * @host: host data structure
- *
- * Disable ints, cleanup host memory, call general purpose
- * host_stop.
- *
- * LOCKING:
- * Inherited from caller.
- */
-static void mv_host_stop(struct ata_host *host)
-{
- struct mv_host_priv *hpriv = host->private_data;
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- if (hpriv->hp_flags & MV_HP_FLAG_MSI) {
- pci_disable_msi(pdev);
- } else {
- pci_intx(pdev, 0);
- }
- kfree(hpriv);
- ata_host_stop(host);
-}
-
-static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
-{
- dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
-}
-
static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
{
u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
@@ -882,22 +855,21 @@ static int mv_port_start(struct ata_port *ap)
void __iomem *port_mmio = mv_ap_base(ap);
void *mem;
dma_addr_t mem_dma;
- int rc = -ENOMEM;
+ int rc;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
- memset(pp, 0, sizeof(*pp));
+ return -ENOMEM;
- mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
- GFP_KERNEL);
+ mem = dmam_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
if (!mem)
- goto err_out_pp;
+ return -ENOMEM;
memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
rc = ata_pad_alloc(ap, dev);
if (rc)
- goto err_out_priv;
+ return rc;
/* First item in chunk of DMA memory:
* 32-slot command request table (CRQB), 32 bytes each in size
@@ -950,13 +922,6 @@ static int mv_port_start(struct ata_port *ap)
*/
ap->private_data = pp;
return 0;
-
-err_out_priv:
- mv_priv_free(pp, dev);
-err_out_pp:
- kfree(pp);
-err_out:
- return rc;
}
/**
@@ -970,18 +935,11 @@ err_out:
*/
static void mv_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
- struct mv_port_priv *pp = ap->private_data;
unsigned long flags;
spin_lock_irqsave(&ap->host->lock, flags);
mv_stop_dma(ap);
spin_unlock_irqrestore(&ap->host->lock, flags);
-
- ap->private_data = NULL;
- ata_pad_free(ap, dev);
- mv_priv_free(pp, dev);
- kfree(pp);
}
/**
@@ -1347,7 +1305,7 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed)
*/
static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
{
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
void __iomem *hc_mmio = mv_hc_base(mmio, hc);
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
@@ -1390,8 +1348,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
} else {
/* PIO: check for device (drive) interrupt */
if ((DEV_IRQ << hard_port) & hc_irq_cause) {
- ata_status = readb((void __iomem *)
- ap->ioaddr.status_addr);
+ ata_status = readb(ap->ioaddr.status_addr);
handled = 1;
/* ignore spurious intr if drive still BUSY */
if (ata_status & ATA_BUSY) {
@@ -1451,7 +1408,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
unsigned int hc, handled = 0, n_hcs;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
struct mv_host_priv *hpriv;
u32 irq_stat;
@@ -1527,22 +1484,24 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
{
- void __iomem *mmio = mv5_phy_base(ap->host->mmio_base, ap->port_no);
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+ void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU)
- return readl(mmio + ofs);
+ return readl(addr + ofs);
else
return (u32) ofs;
}
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{
- void __iomem *mmio = mv5_phy_base(ap->host->mmio_base, ap->port_no);
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+ void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU)
- writelfl(val, mmio + ofs);
+ writelfl(val, addr + ofs);
}
static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
@@ -1904,7 +1863,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
static void mv_stop_and_reset(struct ata_port *ap)
{
struct mv_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
mv_stop_dma(ap);
@@ -2002,10 +1961,10 @@ comreset_retry:
break;
}
- tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
- tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
- tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr);
- tf.nsect = readb((void __iomem *) ap->ioaddr.nsect_addr);
+ tf.lbah = readb(ap->ioaddr.lbah_addr);
+ tf.lbam = readb(ap->ioaddr.lbam_addr);
+ tf.lbal = readb(ap->ioaddr.lbal_addr);
+ tf.nsect = readb(ap->ioaddr.nsect_addr);
dev->class = ata_dev_classify(&tf);
if (!ata_dev_enabled(dev)) {
@@ -2037,17 +1996,17 @@ static void mv_phy_reset(struct ata_port *ap)
*/
static void mv_eng_timeout(struct ata_port *ap)
{
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
struct ata_queued_cmd *qc;
unsigned long flags;
ata_port_printk(ap, KERN_ERR, "Entering mv_eng_timeout\n");
DPRINTK("All regs @ start of eng_timeout\n");
- mv_dump_all_regs(ap->host->mmio_base, ap->port_no,
- to_pci_dev(ap->host->dev));
+ mv_dump_all_regs(mmio, ap->port_no, to_pci_dev(ap->host->dev));
qc = ata_qc_from_tag(ap, ap->active_tag);
printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
- ap->host->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
+ mmio, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
spin_lock_irqsave(&ap->host->lock, flags);
mv_err_intr(ap, 0);
@@ -2075,7 +2034,7 @@ static void mv_eng_timeout(struct ata_port *ap)
*/
static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
{
- unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
+ void __iomem *shd_base = port_mmio + SHD_BLK_OFS;
unsigned serr_ofs;
/* PIO related setup
@@ -2223,7 +2182,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
unsigned int board_idx)
{
int rc = 0, n_hc, port, hc;
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
struct mv_host_priv *hpriv = probe_ent->private_data;
/* global interrupt mask */
@@ -2341,49 +2300,36 @@ 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 ata_probe_ent *probe_ent = NULL;
+ 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;
- void __iomem *mmio_base;
- int pci_dev_busy = 0, rc;
+ int rc;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
- if (rc) {
+ rc = pcim_enable_device(pdev);
+ if (rc)
return rc;
- }
pci_set_master(pdev);
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, MV_PRIMARY_BAR, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
+ 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;
@@ -2393,53 +2339,26 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
/* initialize adapter */
rc = mv_init_host(pdev, probe_ent, board_idx);
- if (rc) {
- goto err_out_hpriv;
- }
+ if (rc)
+ return rc;
/* Enable interrupts */
- if (msi && pci_enable_msi(pdev) == 0) {
- hpriv->hp_flags |= MV_HP_FLAG_MSI;
- } else {
+ if (msi && !pci_enable_msi(pdev))
pci_intx(pdev, 1);
- }
mv_dump_pci_cfg(pdev, 0x68);
mv_print_info(probe_ent);
- if (ata_device_add(probe_ent) == 0) {
- rc = -ENODEV; /* No devices discovered */
- goto err_out_dev_add;
- }
+ if (ata_device_add(probe_ent) == 0)
+ return -ENODEV;
- kfree(probe_ent);
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_dev_add:
- if (MV_HP_FLAG_MSI & hpriv->hp_flags) {
- pci_disable_msi(pdev);
- } else {
- pci_intx(pdev, 0);
- }
-err_out_hpriv:
- kfree(hpriv);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy) {
- pci_disable_device(pdev);
- }
-
- return rc;
}
static int __init mv_init(void)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0d316eb3c21..095ef1b2cd0 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -49,11 +49,13 @@
#include <linux/libata.h>
#define DRV_NAME "sata_nv"
-#define DRV_VERSION "3.2"
+#define DRV_VERSION "3.3"
#define NV_ADMA_DMA_BOUNDARY 0xffffffffUL
enum {
+ NV_MMIO_BAR = 5,
+
NV_PORTS = 2,
NV_PIO_MASK = 0x1f,
NV_MWDMA_MASK = 0x07,
@@ -213,12 +215,21 @@ struct nv_adma_port_priv {
dma_addr_t cpb_dma;
struct nv_adma_prd *aprd;
dma_addr_t aprd_dma;
+ void __iomem * ctl_block;
+ void __iomem * gen_block;
+ void __iomem * notifier_clear_block;
u8 flags;
};
+struct nv_host_priv {
+ unsigned long type;
+};
+
#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static void nv_remove_one (struct pci_dev *pdev);
+static int nv_pci_device_resume(struct pci_dev *pdev);
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);
@@ -239,6 +250,8 @@ 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);
+static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg);
+static int nv_adma_port_resume(struct ata_port *ap);
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);
@@ -270,14 +283,6 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
- { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
- { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
- { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
@@ -292,7 +297,9 @@ static struct pci_driver nv_pci_driver = {
.name = DRV_NAME,
.id_table = nv_pci_tbl,
.probe = nv_init_one,
- .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = nv_pci_device_resume,
+ .remove = nv_remove_one,
};
static struct scsi_host_template nv_sht = {
@@ -311,6 +318,8 @@ 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,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
};
static struct scsi_host_template nv_adma_sht = {
@@ -329,6 +338,8 @@ 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,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
};
static const struct ata_port_operations nv_generic_ops = {
@@ -348,14 +359,14 @@ static const struct ata_port_operations nv_generic_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .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,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_operations nv_nf2_ops = {
@@ -375,14 +386,14 @@ static const struct ata_port_operations nv_nf2_ops = {
.thaw = nv_nf2_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .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,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_operations nv_ck804_ops = {
@@ -402,13 +413,14 @@ static const struct ata_port_operations nv_ck804_ops = {
.thaw = nv_ck804_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .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,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
.host_stop = nv_ck804_host_stop,
};
@@ -430,13 +442,17 @@ static const struct ata_port_operations nv_adma_ops = {
.thaw = nv_ck804_thaw,
.error_handler = nv_adma_error_handler,
.post_internal_cmd = nv_adma_bmdma_stop,
- .data_xfer = ata_mmio_data_xfer,
+ .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,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = nv_adma_port_start,
.port_stop = nv_adma_port_stop,
+ .port_suspend = nv_adma_port_suspend,
+ .port_resume = nv_adma_port_resume,
.host_stop = nv_adma_host_stop,
};
@@ -475,6 +491,7 @@ static struct ata_port_info nv_port_info[] = {
{
.sht = &nv_adma_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_HRST_TO_RESUME |
ATA_FLAG_MMIO | ATA_FLAG_NCQ,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
@@ -491,57 +508,72 @@ MODULE_VERSION(DRV_VERSION);
static int adma_enabled = 1;
-static inline void __iomem *__nv_adma_ctl_block(void __iomem *mmio,
- unsigned int port_no)
-{
- mmio += NV_ADMA_PORT + port_no * NV_ADMA_PORT_SIZE;
- return mmio;
-}
-
-static inline void __iomem *nv_adma_ctl_block(struct ata_port *ap)
-{
- return __nv_adma_ctl_block(ap->host->mmio_base, ap->port_no);
-}
-
-static inline void __iomem *nv_adma_gen_block(struct ata_port *ap)
-{
- return (ap->host->mmio_base + NV_ADMA_GEN);
-}
-
-static inline void __iomem *nv_adma_notifier_clear_block(struct ata_port *ap)
-{
- return (nv_adma_gen_block(ap) + NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no));
-}
-
static void nv_adma_register_mode(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
struct nv_adma_port_priv *pp = ap->private_data;
- u16 tmp;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp, status;
+ int count = 0;
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
return;
+ status = readw(mmio + NV_ADMA_STAT);
+ while(!(status & NV_ADMA_STAT_IDLE) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA IDLE, stat=0x%hx\n",
+ status);
+
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ count = 0;
+ status = readw(mmio + NV_ADMA_STAT);
+ while(!(status & NV_ADMA_STAT_LEGACY) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA LEGACY, stat=0x%hx\n",
+ status);
+
pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
}
static void nv_adma_mode(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
struct nv_adma_port_priv *pp = ap->private_data;
- u16 tmp;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp, status;
+ int count = 0;
if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
return;
-
+
WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ status = readw(mmio + NV_ADMA_STAT);
+ while(((status & NV_ADMA_STAT_LEGACY) ||
+ !(status & NV_ADMA_STAT_IDLE)) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA LEGACY clear and IDLE, stat=0x%hx\n",
+ status);
+
pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE;
}
@@ -576,7 +608,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
/* Subtract 1 since an extra entry may be needed for padding, see
libata-scsi.c */
sg_tablesize = LIBATA_MAX_PRD - 1;
-
+
/* Since the legacy DMA engine is in use, we need to disable ADMA
on the port. */
adma_enable = 0;
@@ -588,7 +620,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
adma_enable = 1;
}
-
+
pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &current_reg);
if(ap->port_no == 1)
@@ -597,7 +629,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
else
config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
-
+
if(adma_enable) {
new_reg = current_reg | config_mask;
pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
@@ -606,10 +638,10 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
new_reg = current_reg & ~config_mask;
pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE;
}
-
+
if(current_reg != new_reg)
pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg);
-
+
blk_queue_bounce_limit(sdev->request_queue, bounce_limit);
blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
@@ -656,59 +688,67 @@ static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
return idx;
}
-static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
+static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
{
struct nv_adma_port_priv *pp = ap->private_data;
- int complete = 0, have_err = 0;
u8 flags = pp->cpb[cpb_num].resp_flags;
VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags);
- if (flags & NV_CPB_RESP_DONE) {
- VPRINTK("CPB flags done, flags=0x%x\n", flags);
- complete = 1;
- }
- if (flags & NV_CPB_RESP_ATA_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags ATA err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
- }
- if (flags & NV_CPB_RESP_CMD_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags CMD err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
- }
- if (flags & NV_CPB_RESP_CPB_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags CPB err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
+ if (unlikely((force_err ||
+ flags & (NV_CPB_RESP_ATA_ERR |
+ NV_CPB_RESP_CMD_ERR |
+ NV_CPB_RESP_CPB_ERR)))) {
+ struct ata_eh_info *ehi = &ap->eh_info;
+ int freeze = 0;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags );
+ if (flags & NV_CPB_RESP_ATA_ERR) {
+ ata_ehi_push_desc(ehi, ": ATA error");
+ ehi->err_mask |= AC_ERR_DEV;
+ } else if (flags & NV_CPB_RESP_CMD_ERR) {
+ ata_ehi_push_desc(ehi, ": CMD error");
+ ehi->err_mask |= AC_ERR_DEV;
+ } else if (flags & NV_CPB_RESP_CPB_ERR) {
+ ata_ehi_push_desc(ehi, ": CPB error");
+ ehi->err_mask |= AC_ERR_SYSTEM;
+ freeze = 1;
+ } else {
+ /* notifier error, but no error in CPB flags? */
+ ehi->err_mask |= AC_ERR_OTHER;
+ freeze = 1;
+ }
+ /* Kill all commands. EH will determine what actually failed. */
+ if (freeze)
+ ata_port_freeze(ap);
+ else
+ ata_port_abort(ap);
+ return 1;
}
- if(complete || force_err)
- {
+
+ if (flags & NV_CPB_RESP_DONE) {
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
- if(likely(qc)) {
- u8 ata_status = 0;
- /* Only use the ATA port status for non-NCQ commands.
+ 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)
- ata_status = readb(nv_adma_ctl_block(ap) + (ATA_REG_STATUS * 4));
-
- if(have_err || force_err)
- ata_status |= ATA_ERR;
-
- qc->err_mask |= ac_err_mask(ata_status);
+ 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);
ata_qc_complete(qc);
}
}
+ return 0;
}
static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
{
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
- int handled;
/* freeze if hotplugged */
if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) {
@@ -727,13 +767,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
}
/* handle interrupt */
- handled = ata_host_intr(ap, qc);
- if (unlikely(!handled)) {
- /* spurious, clear it */
- ata_check_status(ap);
- }
-
- return 1;
+ return ata_host_intr(ap, qc);
}
static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -750,16 +784,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
struct nv_adma_port_priv *pp = ap->private_data;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
u16 status;
u32 gen_ctl;
- int have_global_err = 0;
u32 notifier, notifier_error;
/* if in ATA register mode, use standard ata interrupt handler */
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
- u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
+ u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
>> (NV_INT_PORT_SHIFT * i);
+ if(ata_tag_valid(ap->active_tag))
+ /** NV_INT_DEV indication seems unreliable at times
+ at least in ADMA mode. Force it on always when a
+ command is active, to prevent losing interrupts. */
+ irq_stat |= NV_INT_DEV;
handled += nv_host_intr(ap, irq_stat);
continue;
}
@@ -768,7 +806,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
notifier_clears[i] = notifier | notifier_error;
- gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
+ gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
!notifier_error)
@@ -784,52 +822,60 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
readw(mmio + NV_ADMA_STAT); /* flush posted write */
rmb();
- /* freeze if hotplugged */
- if (unlikely(status & (NV_ADMA_STAT_HOTPLUG | NV_ADMA_STAT_HOTUNPLUG))) {
- ata_port_printk(ap, KERN_NOTICE, "Hotplug event, freezing\n");
+ handled++; /* irq handled if we got here */
+
+ /* freeze if hotplugged or controller error */
+ if (unlikely(status & (NV_ADMA_STAT_HOTPLUG |
+ NV_ADMA_STAT_HOTUNPLUG |
+ NV_ADMA_STAT_TIMEOUT))) {
+ struct ata_eh_info *ehi = &ap->eh_info;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status );
+ if (status & NV_ADMA_STAT_TIMEOUT) {
+ ehi->err_mask |= AC_ERR_SYSTEM;
+ ata_ehi_push_desc(ehi, ": timeout");
+ } else if (status & NV_ADMA_STAT_HOTPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, ": hotplug");
+ } else if (status & NV_ADMA_STAT_HOTUNPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, ": hot unplug");
+ }
ata_port_freeze(ap);
- handled++;
continue;
}
- if (status & NV_ADMA_STAT_TIMEOUT) {
- ata_port_printk(ap, KERN_ERR, "timeout, stat=0x%x\n", status);
- have_global_err = 1;
- }
- if (status & NV_ADMA_STAT_CPBERR) {
- ata_port_printk(ap, KERN_ERR, "CPB error, stat=0x%x\n", status);
- have_global_err = 1;
- }
- if ((status & NV_ADMA_STAT_DONE) || have_global_err) {
+ if (status & (NV_ADMA_STAT_DONE |
+ NV_ADMA_STAT_CPBERR)) {
/** Check CPBs for completed commands */
- if(ata_tag_valid(ap->active_tag))
+ if (ata_tag_valid(ap->active_tag)) {
/* Non-NCQ command */
- nv_adma_check_cpb(ap, ap->active_tag, have_global_err ||
- (notifier_error & (1 << ap->active_tag)));
- else {
- int pos;
+ 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)) ) {
+
+ while ((pos = ffs(active)) && !error) {
pos--;
- nv_adma_check_cpb(ap, pos, have_global_err ||
- (notifier_error & (1 << pos)) );
+ error = nv_adma_check_cpb(ap, pos,
+ notifier_error & (1 << pos) );
active &= ~(1 << pos );
}
}
}
-
- handled++; /* irq handled if we got here */
}
}
-
+
if(notifier_clears[0] || notifier_clears[1]) {
/* Note: Both notifier clear registers must be written
if either is set, even if one is zero, according to NVIDIA. */
- writel(notifier_clears[0],
- nv_adma_notifier_clear_block(host->ports[0]));
- writel(notifier_clears[1],
- nv_adma_notifier_clear_block(host->ports[1]));
+ struct nv_adma_port_priv *pp = host->ports[0]->private_data;
+ writel(notifier_clears[0], pp->notifier_clear_block);
+ pp = host->ports[1]->private_data;
+ writel(notifier_clears[1], pp->notifier_clear_block);
}
spin_unlock(&host->lock);
@@ -839,19 +885,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
static void nv_adma_irq_clear(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
u16 status = readw(mmio + NV_ADMA_STAT);
u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
- unsigned long dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
+ void __iomem *dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
/* clear ADMA status */
writew(status, mmio + NV_ADMA_STAT);
writel(notifier | notifier_error,
- nv_adma_notifier_clear_block(ap));
+ pp->notifier_clear_block);
/** clear legacy status */
- outb(inb(dma_stat_addr), dma_stat_addr);
+ iowrite8(ioread8(dma_stat_addr), dma_stat_addr);
}
static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
@@ -867,15 +914,15 @@ static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
}
/* load PRD table addr. */
- outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
if (!rw)
dmactl |= ATA_DMA_WR;
- outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* issue r/w command */
ata_exec_command(ap, &qc->tf);
@@ -893,9 +940,9 @@ static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
}
/* start host DMA transaction */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- outb(dmactl | ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ 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)
@@ -907,8 +954,8 @@ static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
return;
/* clear start/stop bit */
- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ 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 */
@@ -920,7 +967,7 @@ static u8 nv_adma_bmdma_status(struct ata_port *ap)
WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
- return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
static int nv_adma_port_start(struct ata_port *ap)
@@ -930,7 +977,7 @@ static int nv_adma_port_start(struct ata_port *ap)
int rc;
void *mem;
dma_addr_t mem_dma;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio;
u16 tmp;
VPRINTK("ENTER\n");
@@ -939,19 +986,21 @@ static int nv_adma_port_start(struct ata_port *ap)
if (rc)
return rc;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
-
- mem = dma_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
- &mem_dma, GFP_KERNEL);
-
- if (!mem) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ mmio = ap->host->iomap[NV_MMIO_BAR] + NV_ADMA_PORT +
+ ap->port_no * NV_ADMA_PORT_SIZE;
+ pp->ctl_block = mmio;
+ pp->gen_block = ap->host->iomap[NV_MMIO_BAR] + NV_ADMA_GEN;
+ pp->notifier_clear_block = pp->gen_block +
+ NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no);
+
+ mem = dmam_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
+ &mem_dma, GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
memset(mem, 0, NV_ADMA_PORT_PRIV_DMA_SZ);
/*
@@ -985,9 +1034,9 @@ static int nv_adma_port_start(struct ata_port *ap)
/* clear CPB fetch count */
writew(0, mmio + NV_ADMA_CPB_COUNT);
- /* clear GO for register mode */
+ /* clear GO for register mode, enable interrupt */
tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
@@ -997,53 +1046,89 @@ static int nv_adma_port_start(struct ata_port *ap)
readl( mmio + NV_ADMA_CTL ); /* flush posted write */
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
static void nv_adma_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
struct nv_adma_port_priv *pp = ap->private_data;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
VPRINTK("ENTER\n");
+ writew(0, mmio + NV_ADMA_CTL);
+}
+static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
+
+ /* Go to register mode - clears GO */
+ nv_adma_register_mode(ap);
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* disable interrupt, shut down port */
writew(0, mmio + NV_ADMA_CTL);
- ap->private_data = NULL;
- dma_free_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, pp->cpb, pp->cpb_dma);
- kfree(pp);
- ata_port_stop(ap);
+ return 0;
}
+static int nv_adma_port_resume(struct ata_port *ap)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp;
+
+ /* set CPB block location */
+ writel(pp->cpb_dma & 0xFFFFFFFF, mmio + NV_ADMA_CPB_BASE_LOW);
+ writel((pp->cpb_dma >> 16 ) >> 16, mmio + NV_ADMA_CPB_BASE_HIGH);
+
+ /* clear any outstanding interrupt conditions */
+ writew(0xffff, mmio + NV_ADMA_STAT);
+
+ /* initialize port variables */
+ pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* 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);
+
+ 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 */
+ udelay(1);
+ writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+
+ return 0;
+}
static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
{
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR];
struct ata_ioports *ioport = &probe_ent->port[port];
VPRINTK("ENTER\n");
mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
- ioport->cmd_addr = (unsigned long) mmio;
- ioport->data_addr = (unsigned long) mmio + (ATA_REG_DATA * 4);
+ ioport->cmd_addr = mmio;
+ ioport->data_addr = mmio + (ATA_REG_DATA * 4);
ioport->error_addr =
- ioport->feature_addr = (unsigned long) mmio + (ATA_REG_ERR * 4);
- ioport->nsect_addr = (unsigned long) mmio + (ATA_REG_NSECT * 4);
- ioport->lbal_addr = (unsigned long) mmio + (ATA_REG_LBAL * 4);
- ioport->lbam_addr = (unsigned long) mmio + (ATA_REG_LBAM * 4);
- ioport->lbah_addr = (unsigned long) mmio + (ATA_REG_LBAH * 4);
- ioport->device_addr = (unsigned long) mmio + (ATA_REG_DEVICE * 4);
+ ioport->feature_addr = mmio + (ATA_REG_ERR * 4);
+ ioport->nsect_addr = mmio + (ATA_REG_NSECT * 4);
+ ioport->lbal_addr = mmio + (ATA_REG_LBAL * 4);
+ ioport->lbam_addr = mmio + (ATA_REG_LBAM * 4);
+ ioport->lbah_addr = mmio + (ATA_REG_LBAH * 4);
+ ioport->device_addr = mmio + (ATA_REG_DEVICE * 4);
ioport->status_addr =
- ioport->command_addr = (unsigned long) mmio + (ATA_REG_STATUS * 4);
+ ioport->command_addr = mmio + (ATA_REG_STATUS * 4);
ioport->altstatus_addr =
- ioport->ctl_addr = (unsigned long) mmio + 0x20;
+ ioport->ctl_addr = mmio + 0x20;
}
static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
@@ -1066,15 +1151,6 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
for (i = 0; i < probe_ent->n_ports; i++)
nv_adma_setup_port(probe_ent, i);
- for (i = 0; i < probe_ent->n_ports; i++) {
- void __iomem *mmio = __nv_adma_ctl_block(probe_ent->mmio_base, i);
- u16 tmp;
-
- /* enable interrupt, clear reset if not already clear */
- tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
- }
-
return 0;
}
@@ -1120,18 +1196,31 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
}
+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. */
+ if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
+ (qc->tf.flags & ATA_TFLAG_POLLING))
+ return 1;
+
+ if((qc->flags & ATA_QCFLAG_DMAMAP) ||
+ (qc->tf.protocol == ATA_PROT_NODATA))
+ return 0;
+
+ return 1;
+}
+
static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
{
struct nv_adma_port_priv *pp = qc->ap->private_data;
struct nv_adma_cpb *cpb = &pp->cpb[qc->tag];
u8 ctl_flags = NV_CPB_CTL_CPB_VALID |
- NV_CPB_CTL_APRD_VALID |
NV_CPB_CTL_IEN;
- VPRINTK("qc->flags = 0x%lx\n", qc->flags);
-
- if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
- (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ if (nv_adma_use_reg_mode(qc)) {
nv_adma_register_mode(qc->ap);
ata_qc_prep(qc);
return;
@@ -1147,9 +1236,15 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
if (qc->tf.protocol == ATA_PROT_NCQ)
ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA;
+ VPRINTK("qc->flags = 0x%lx\n", qc->flags);
+
nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
- nv_adma_fill_sg(qc, cpb);
+ if(qc->flags & ATA_QCFLAG_DMAMAP) {
+ nv_adma_fill_sg(qc, cpb);
+ ctl_flags |= NV_CPB_CTL_APRD_VALID;
+ } else
+ memset(&cpb->aprd[0], 0, sizeof(struct nv_adma_prd) * 5);
/* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
finished filling in all of the contents */
@@ -1160,14 +1255,13 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
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 = nv_adma_ctl_block(qc->ap);
+ void __iomem *mmio = pp->ctl_block;
VPRINTK("ENTER\n");
- if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
- (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ if (nv_adma_use_reg_mode(qc)) {
/* use ATA register mode */
- VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags);
+ VPRINTK("using ATA register mode: 0x%lx\n", qc->flags);
nv_adma_register_mode(qc->ap);
return ata_qc_issue_prot(qc);
} else
@@ -1239,7 +1333,7 @@ static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance)
irqreturn_t ret;
spin_lock(&host->lock);
- irq_stat = inb(host->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
+ irq_stat = ioread8(host->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
ret = nv_do_interrupt(host, irq_stat);
spin_unlock(&host->lock);
@@ -1253,7 +1347,7 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
irqreturn_t ret;
spin_lock(&host->lock);
- irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804);
+ irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804);
ret = nv_do_interrupt(host, irq_stat);
spin_unlock(&host->lock);
@@ -1265,7 +1359,7 @@ static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return ioread32((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -1273,36 +1367,36 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
if (sc_reg > SCR_CONTROL)
return;
- iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_nf2_freeze(struct ata_port *ap)
{
- unsigned long scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
- mask = inb(scr_addr + NV_INT_ENABLE);
+ mask = ioread8(scr_addr + NV_INT_ENABLE);
mask &= ~(NV_INT_ALL << shift);
- outb(mask, scr_addr + NV_INT_ENABLE);
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
static void nv_nf2_thaw(struct ata_port *ap)
{
- unsigned long scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
- outb(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
+ iowrite8(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
- mask = inb(scr_addr + NV_INT_ENABLE);
+ mask = ioread8(scr_addr + NV_INT_ENABLE);
mask |= (NV_INT_MASK << shift);
- outb(mask, scr_addr + NV_INT_ENABLE);
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
static void nv_ck804_freeze(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
@@ -1313,7 +1407,7 @@ static void nv_ck804_freeze(struct ata_port *ap)
static void nv_ck804_thaw(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
@@ -1345,32 +1439,13 @@ static void nv_adma_error_handler(struct ata_port *ap)
{
struct nv_adma_port_priv *pp = ap->private_data;
if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
int i;
u16 tmp;
- u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
- u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
- u32 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
- u32 status = readw(mmio + NV_ADMA_STAT);
-
- ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
- "notifier_error 0x%X gen_ctl 0x%X status 0x%X\n",
- notifier, notifier_error, gen_ctl, status);
-
- for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
- struct nv_adma_cpb *cpb = &pp->cpb[i];
- if( cpb->ctl_flags || cpb->resp_flags )
- 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);
- ata_port_printk(ap, KERN_ERR, "Resetting port\n");
-
/* Mark all of the CPBs as invalid to prevent them from being executed */
for( i=0;i<NV_ADMA_MAX_CPBS;i++)
pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID;
@@ -1396,10 +1471,10 @@ 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;
- int pci_dev_busy = 0;
+ struct nv_host_priv *hpriv;
int rc;
u32 bar;
- unsigned long base;
+ void __iomem *base;
unsigned long type = ent->driver_data;
int mask_set = 0;
@@ -1410,17 +1485,17 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_resource_start(pdev, bar) == 0)
return -ENODEV;
- if ( !printed_version++)
+ if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
- goto err_out;
+ return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out_disable;
+ pcim_pin_device(pdev);
+ return rc;
}
if(type >= CK804 && adma_enabled) {
@@ -1434,27 +1509,31 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if(!mask_set) {
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
}
rc = -ENOMEM;
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
+
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)
- goto err_out_regions;
+ return -ENOMEM;
- probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
- if (!probe_ent->mmio_base) {
- rc = -EIO;
- goto err_out_free_ent;
- }
+ if (!pcim_iomap(pdev, NV_MMIO_BAR, 0))
+ return -EIO;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- base = (unsigned long)probe_ent->mmio_base;
+ probe_ent->private_data = hpriv;
+ hpriv->type = type;
+ 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;
@@ -1472,28 +1551,72 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (type == ADMA) {
rc = nv_adma_host_init(probe_ent);
if (rc)
- goto err_out_iounmap;
+ return rc;
}
rc = ata_device_add(probe_ent);
if (rc != NV_PORTS)
- goto err_out_iounmap;
-
- kfree(probe_ent);
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
+}
-err_out_iounmap:
- pci_iounmap(pdev, probe_ent->mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out_disable:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
-err_out:
- return rc;
+static void nv_remove_one (struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct nv_host_priv *hpriv = host->private_data;
+
+ ata_pci_remove_one(pdev);
+ kfree(hpriv);
+}
+
+static int nv_pci_device_resume(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct nv_host_priv *hpriv = host->private_data;
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if(rc)
+ return rc;
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+ if(hpriv->type >= CK804) {
+ u8 regval;
+
+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
+ regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+ pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
+ }
+ if(hpriv->type == ADMA) {
+ u32 tmp32;
+ struct nv_adma_port_priv *pp;
+ /* enable/disable ADMA on the ports appropriately */
+ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
+
+ pp = host->ports[0]->private_data;
+ if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+ tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+ else
+ tmp32 |= (NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+ pp = host->ports[1]->private_data;
+ if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+ tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+ else
+ tmp32 |= (NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+
+ pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
+ }
+ }
+
+ ata_host_resume(host);
+
+ return 0;
}
static void nv_ck804_host_stop(struct ata_host *host)
@@ -1505,25 +1628,13 @@ static void nv_ck804_host_stop(struct ata_host *host)
pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
-
- ata_pci_host_stop(host);
}
static void nv_adma_host_stop(struct ata_host *host)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
- int i;
u32 tmp32;
- for (i = 0; i < host->n_ports; i++) {
- void __iomem *mmio = __nv_adma_ctl_block(host->mmio_base, i);
- u16 tmp;
-
- /* disable interrupt */
- tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp & ~NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
- }
-
/* disable ADMA on the ports */
pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index f055874a6ec..3be4cc338d7 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -39,10 +39,10 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/device.h>
+#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
@@ -50,6 +50,17 @@
enum {
+ PDC_MMIO_BAR = 3,
+
+ /* register offsets */
+ PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */
+ PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */
+ PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */
+ PDC_CYLINDER_LOW = 0x10, /* Cylinder low reg (per port) */
+ PDC_CYLINDER_HIGH = 0x14, /* Cylinder high reg (per port) */
+ PDC_DEVICE = 0x18, /* Device/Head reg (per port) */
+ PDC_COMMAND = 0x1C, /* Command/status reg (per port) */
+ PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_FLASH_CTL = 0x44, /* Flash control register */
@@ -71,13 +82,23 @@ enum {
PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
+ /* Sequence counter control registers bit definitions */
+ PDC_SEQCNTRL_INT_MASK = (1 << 5), /* Sequence Interrupt Mask */
+
+ /* Feature register values */
+ PDC_FEATURE_ATAPI_PIO = 0x00, /* ATAPI data xfer by PIO */
+ PDC_FEATURE_ATAPI_DMA = 0x01, /* ATAPI data xfer by DMA */
+
+ /* Device/Head register values */
+ PDC_DEVICE_SATA = 0xE0, /* Device/Head value for SATA devices */
+
/* PDC_CTLSTAT bit definitions */
PDC_DMA_ENABLE = (1 << 7),
PDC_IRQ_DISABLE = (1 << 10),
PDC_RESET = (1 << 11), /* HDMA reset */
PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
+ ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
/* hp->flags bits */
@@ -92,6 +113,7 @@ struct pdc_port_priv {
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);
@@ -100,14 +122,14 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
static void pdc_eng_timeout(struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
-static void pdc_port_stop(struct ata_port *ap);
static void pdc_pata_phy_reset(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 void pdc_irq_clear(struct ata_port *ap);
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
-static void pdc_host_stop(struct ata_host *host);
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);
@@ -139,6 +161,34 @@ static const struct ata_port_operations pdc_sata_ops = {
.check_status = ata_check_status,
.exec_command = pdc_exec_command_mmio,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = pdc_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,
+ .post_internal_cmd = pdc_post_internal_cmd,
+ .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,
+};
+
+/* First-generation chips need a more restrictive ->check_atapi_dma op */
+static const struct ata_port_operations pdc_old_sata_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = pdc_tf_load_mmio,
+ .tf_read = ata_tf_read,
+ .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,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
@@ -146,15 +196,15 @@ static const struct ata_port_operations pdc_sata_ops = {
.thaw = pdc_thaw,
.error_handler = pdc_error_handler,
.post_internal_cmd = pdc_post_internal_cmd,
- .data_xfer = ata_mmio_data_xfer,
+ .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_stop = pdc_port_stop,
- .host_stop = pdc_host_stop,
};
static const struct ata_port_operations pdc_pata_ops = {
@@ -164,30 +214,31 @@ static const struct ata_port_operations pdc_pata_ops = {
.check_status = ata_check_status,
.exec_command = pdc_exec_command_mmio,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = pdc_check_atapi_dma,
.phy_reset = pdc_pata_phy_reset,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = pdc_eng_timeout,
.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_stop = pdc_port_stop,
- .host_stop = pdc_host_stop,
};
static const struct ata_port_info pdc_port_info[] = {
/* board_2037x */
{
.sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &pdc_sata_ops,
+ .port_ops = &pdc_old_sata_ops,
},
/* board_20319 */
@@ -197,7 +248,7 @@ static const struct ata_port_info pdc_port_info[] = {
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &pdc_sata_ops,
+ .port_ops = &pdc_old_sata_ops,
},
/* board_20619 */
@@ -213,7 +264,7 @@ static const struct ata_port_info pdc_port_info[] = {
/* board_2057x */
{
.sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -271,21 +322,22 @@ static int pdc_port_start(struct ata_port *ap)
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;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
- pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
ap->private_data = pp;
@@ -300,40 +352,11 @@ static int pdc_port_start(struct ata_port *ap)
}
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-
-static void pdc_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
- dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
}
-
-static void pdc_host_stop(struct ata_host *host)
-{
- struct pdc_host_priv *hp = host->private_data;
-
- ata_pci_host_stop(host);
-
- kfree(hp);
-}
-
-
static void pdc_reset_port(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
+ void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
unsigned int i;
u32 tmp;
@@ -377,18 +400,102 @@ static void pdc_pata_phy_reset(struct ata_port *ap)
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- if (sc_reg > SCR_CONTROL)
+ if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
return 0xffffffffU;
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
u32 val)
{
- if (sc_reg > SCR_CONTROL)
+ if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
return;
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ dma_addr_t sg_table = ap->prd_dma;
+ unsigned int cdb_len = qc->dev->cdb_len;
+ u8 *cdb = qc->cdb;
+ struct pdc_port_priv *pp = ap->private_data;
+ u8 *buf = pp->pkt;
+ u32 *buf32 = (u32 *) buf;
+ unsigned int dev_sel, feature, nbytes;
+
+ /* set control bits (byte 0), zero delay seq id (byte 3),
+ * and seq id (byte 2)
+ */
+ switch (qc->tf.protocol) {
+ case ATA_PROT_ATAPI_DMA:
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+ buf32[0] = cpu_to_le32(PDC_PKT_READ);
+ else
+ buf32[0] = 0;
+ break;
+ case ATA_PROT_ATAPI_NODATA:
+ buf32[0] = cpu_to_le32(PDC_PKT_NODATA);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */
+ buf32[2] = 0; /* no next-packet */
+
+ /* select drive */
+ if (sata_scr_valid(ap)) {
+ dev_sel = PDC_DEVICE_SATA;
+ } else {
+ dev_sel = ATA_DEVICE_OBS;
+ if (qc->dev->devno != 0)
+ dev_sel |= ATA_DEV1;
+ }
+ buf[12] = (1 << 5) | ATA_REG_DEVICE;
+ buf[13] = dev_sel;
+ buf[14] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_CLEAR_BSY;
+ buf[15] = dev_sel; /* once more, waiting for BSY to clear */
+
+ buf[16] = (1 << 5) | ATA_REG_NSECT;
+ buf[17] = 0x00;
+ buf[18] = (1 << 5) | ATA_REG_LBAL;
+ buf[19] = 0x00;
+
+ /* set feature and byte counter registers */
+ if (qc->tf.protocol != ATA_PROT_ATAPI_DMA) {
+ feature = PDC_FEATURE_ATAPI_PIO;
+ /* set byte counter register to real transfer byte count */
+ nbytes = qc->nbytes;
+ if (nbytes > 0xffff)
+ nbytes = 0xffff;
+ } else {
+ feature = PDC_FEATURE_ATAPI_DMA;
+ /* set byte counter register to 0 */
+ nbytes = 0;
+ }
+ buf[20] = (1 << 5) | ATA_REG_FEATURE;
+ buf[21] = feature;
+ buf[22] = (1 << 5) | ATA_REG_BYTEL;
+ buf[23] = nbytes & 0xFF;
+ buf[24] = (1 << 5) | ATA_REG_BYTEH;
+ buf[25] = (nbytes >> 8) & 0xFF;
+
+ /* send ATAPI packet command 0xA0 */
+ buf[26] = (1 << 5) | ATA_REG_CMD;
+ buf[27] = ATA_CMD_PACKET;
+
+ /* select drive and check DRQ */
+ buf[28] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_WAIT_DRDY;
+ buf[29] = dev_sel;
+
+ /* we can represent cdb lengths 2/4/6/8/10/12/14/16 */
+ BUG_ON(cdb_len & ~0x1E);
+
+ /* append the CDB as the final part */
+ buf[30] = (((cdb_len >> 1) & 7) << 5) | ATA_REG_DATA | PDC_LAST_REG;
+ memcpy(buf+31, cdb, cdb_len);
}
static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -415,6 +522,17 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
pdc_pkt_footer(&qc->tf, pp->pkt, i);
break;
+ case ATA_PROT_ATAPI:
+ ata_qc_prep(qc);
+ break;
+
+ case ATA_PROT_ATAPI_DMA:
+ ata_qc_prep(qc);
+ /*FALLTHROUGH*/
+ case ATA_PROT_ATAPI_NODATA:
+ pdc_atapi_pkt(qc);
+ break;
+
default:
break;
}
@@ -517,7 +635,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
{
unsigned int handled = 0;
u32 tmp;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
+ void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
@@ -528,6 +646,8 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
+ case ATA_PROT_ATAPI_DMA:
+ case ATA_PROT_ATAPI_NODATA:
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
ata_qc_complete(qc);
handled = 1;
@@ -544,7 +664,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
static void pdc_irq_clear(struct ata_port *ap)
{
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
readl(mmio + PDC_INT_SEQMASK);
}
@@ -560,12 +680,12 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
VPRINTK("ENTER\n");
- if (!host || !host->mmio_base) {
+ if (!host || !host->iomap[PDC_MMIO_BAR]) {
VPRINTK("QUICK EXIT\n");
return IRQ_NONE;
}
- mmio_base = host->mmio_base;
+ mmio_base = host->iomap[PDC_MMIO_BAR];
/* reading should also clear interrupts */
mask = readl(mmio_base + PDC_INT_SEQMASK);
@@ -610,32 +730,34 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
unsigned int port_no = ap->port_no;
u8 seq = (u8) (port_no + 1);
VPRINTK("ENTER, ap %p\n", ap);
- writel(0x00000001, ap->host->mmio_base + (seq * 4));
- readl(ap->host->mmio_base + (seq * 4)); /* flush */
+ writel(0x00000001, mmio + (seq * 4));
+ readl(mmio + (seq * 4)); /* flush */
pp->pkt[2] = seq;
wmb(); /* flush PRD, pkt writes */
- writel(pp->pkt_dma, (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+ writel(pp->pkt_dma, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
}
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
{
switch (qc->tf.protocol) {
+ case ATA_PROT_ATAPI_NODATA:
+ if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
+ break;
+ /*FALLTHROUGH*/
+ case ATA_PROT_ATAPI_DMA:
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
pdc_packet_start(qc);
return 0;
- case ATA_PROT_ATAPI_DMA:
- BUG();
- break;
-
default:
break;
}
@@ -658,8 +780,44 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
ata_exec_command(ap, tf);
}
+static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ u8 *scsicmd = qc->scsicmd->cmnd;
+ int pio = 1; /* atapi dma off by default */
+
+ /* Whitelist commands that may use DMA. */
+ switch (scsicmd[0]) {
+ case WRITE_12:
+ case WRITE_10:
+ case WRITE_6:
+ case READ_12:
+ case READ_10:
+ case READ_6:
+ case 0xad: /* READ_DVD_STRUCTURE */
+ case 0xbe: /* READ_CD */
+ pio = 0;
+ }
+ /* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */
+ if (scsicmd[0] == WRITE_10) {
+ unsigned int lba;
+ lba = (scsicmd[2] << 24) | (scsicmd[3] << 16) | (scsicmd[4] << 8) | scsicmd[5];
+ if (lba >= 0xFFFF4FA2)
+ pio = 1;
+ }
+ return pio;
+}
-static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static int pdc_old_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);
+}
+
+static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base;
port->data_addr = base;
@@ -679,7 +837,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
{
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
struct pdc_host_priv *hp = pe->private_data;
int hotplug_offset;
u32 tmp;
@@ -733,55 +891,43 @@ 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 = NULL;
+ struct ata_probe_ent *probe_ent;
struct pdc_host_priv *hp;
- unsigned long base;
- void __iomem *mmio_base;
+ void __iomem *base;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
int rc;
+ u8 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ 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);
- mmio_base = pci_iomap(pdev, 3, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hp = kzalloc(sizeof(*hp), GFP_KERNEL);
- if (hp == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
+ hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL);
+ if (hp == NULL)
+ return -ENOMEM;
probe_ent->private_data = hp;
@@ -794,7 +940,9 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ 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);
@@ -820,7 +968,17 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
hp->flags |= PDC_FLAG_GEN_II;
/* Fall through */
case board_2037x:
- probe_ent->n_ports = 2;
+ /* TX2plus boards also have a PATA port */
+ 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;
@@ -841,22 +999,11 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* initialize adapter */
pdc_host_init(board_idx, probe_ent);
- /* FIXME: Need any other frees than hp? */
if (!ata_device_add(probe_ent))
- kfree(hp);
-
- kfree(probe_ent);
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 710909df4ea..bfa35ede655 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -37,13 +37,14 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
-#include <asm/io.h>
#include <linux/libata.h>
#define DRV_NAME "sata_qstor"
#define DRV_VERSION "0.06"
enum {
+ QS_MMIO_BAR = 4,
+
QS_PORTS = 4,
QS_MAX_PRD = LIBATA_MAX_PRD,
QS_CPB_ORDER = 6,
@@ -117,7 +118,6 @@ static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *en
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_port_stop(struct ata_port *ap);
static void qs_phy_reset(struct ata_port *ap);
static void qs_qc_prep(struct ata_queued_cmd *qc);
static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
@@ -157,14 +157,15 @@ static const struct ata_port_operations qs_ata_ops = {
.phy_reset = qs_phy_reset,
.qc_prep = qs_qc_prep,
.qc_issue = qs_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .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,
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
.port_start = qs_port_start,
- .port_stop = qs_port_stop,
.host_stop = qs_host_stop,
.bmdma_stop = qs_bmdma_stop,
.bmdma_status = qs_bmdma_status,
@@ -197,6 +198,11 @@ static struct pci_driver qs_ata_pci_driver = {
.remove = ata_pci_remove_one,
};
+static void __iomem *qs_mmio_base(struct ata_host *host)
+{
+ return host->iomap[QS_MMIO_BAR];
+}
+
static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
{
return 1; /* ATAPI DMA not supported */
@@ -219,7 +225,7 @@ static void qs_irq_clear(struct ata_port *ap)
static inline void qs_enter_reg_mode(struct ata_port *ap)
{
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
readb(chan + QS_CCT_CTR0); /* flush */
@@ -227,7 +233,7 @@ static inline void qs_enter_reg_mode(struct ata_port *ap)
static inline void qs_reset_channel_logic(struct ata_port *ap)
{
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1);
readb(chan + QS_CCT_CTR0); /* flush */
@@ -257,14 +263,14 @@ static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return ~0U;
- return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 8));
}
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 8));
}
static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
@@ -325,7 +331,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
/* host control block (HCB) */
buf[ 0] = QS_HCB_HDR;
buf[ 1] = hflags;
- *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE);
+ *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes);
*(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem);
addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
*(__le64 *)(&buf[16]) = cpu_to_le64(addr);
@@ -341,7 +347,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
static inline void qs_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
VPRINTK("ENTER, ap %p\n", ap);
@@ -378,7 +384,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
{
unsigned int handled = 0;
u8 sFFE;
- u8 __iomem *mmio_base = host->mmio_base;
+ u8 __iomem *mmio_base = qs_mmio_base(host);
do {
u32 sff0 = readl(mmio_base + QS_HST_SFF);
@@ -470,7 +476,7 @@ static irqreturn_t qs_intr(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base + 0x400;
@@ -492,7 +498,7 @@ static int qs_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
struct qs_port_priv *pp;
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = qs_mmio_base(ap->host);
void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
u64 addr;
int rc;
@@ -501,17 +507,13 @@ static int qs_port_start(struct ata_port *ap)
if (rc)
return rc;
qs_enter_reg_mode(ap);
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
- pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
- GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+ pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
memset(pp->pkt, 0, QS_PKT_BYTES);
ap->private_data = pp;
@@ -519,43 +521,19 @@ static int qs_port_start(struct ata_port *ap)
writel((u32) addr, chan + QS_CCF_CPBA);
writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-static void qs_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct qs_port_priv *pp = ap->private_data;
-
- if (pp != NULL) {
- ap->private_data = NULL;
- if (pp->pkt != NULL)
- dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt,
- pp->pkt_dma);
- kfree(pp);
- }
- ata_port_stop(ap);
}
static void qs_host_stop(struct ata_host *host)
{
- void __iomem *mmio_base = host->mmio_base;
- struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio_base = qs_mmio_base(host);
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
-
- pci_iounmap(pdev, mmio_base);
}
static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
{
- void __iomem *mmio_base = pe->mmio_base;
+ void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
unsigned int port_no;
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
@@ -630,44 +608,34 @@ 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 = NULL;
- void __iomem *mmio_base;
+ struct ata_probe_ent *probe_ent;
+ void __iomem * const *iomap;
unsigned int board_idx = (unsigned int) ent->driver_data;
int rc, port_no;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc)
- goto err_out;
-
- if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
- rc = -ENODEV;
- goto err_out_regions;
- }
+ if ((pci_resource_flags(pdev, QS_MMIO_BAR) & IORESOURCE_MEM) == 0)
+ return -ENODEV;
- mmio_base = pci_iomap(pdev, 4, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
+ if (rc)
+ return rc;
+ iomap = pcim_iomap_table(pdev);
- rc = qs_set_dma_masks(pdev, mmio_base);
+ rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
if (rc)
- goto err_out_iounmap;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
@@ -680,12 +648,12 @@ static int qs_ata_init_one(struct pci_dev *pdev,
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = iomap;
probe_ent->n_ports = QS_PORTS;
for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
- unsigned long chan = (unsigned long)mmio_base +
- (port_no * 0x4000);
+ void __iomem *chan =
+ probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
qs_ata_setup_port(&probe_ent->port[port_no], chan);
}
@@ -694,19 +662,11 @@ static int qs_ata_init_one(struct pci_dev *pdev,
/* initialize adapter */
qs_host_init(board_idx, probe_ent);
- rc = ata_device_add(probe_ent);
- kfree(probe_ent);
- if (rc != QS_PORTS)
- goto err_out_iounmap;
- return 0;
+ if (ata_device_add(probe_ent) != QS_PORTS)
+ return -EIO;
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
+ devm_kfree(&pdev->dev, probe_ent);
+ return 0;
}
static int __init qs_ata_init(void)
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 7808d0369d9..dca3d3749f0 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -49,6 +49,8 @@
#define DRV_VERSION "2.0"
enum {
+ SIL_MMIO_BAR = 5,
+
/*
* host flags
*/
@@ -200,18 +202,18 @@ static const struct ata_port_operations sil_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = sil_freeze,
.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,
.scr_read = sil_scr_read,
.scr_write = sil_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_info sil_port_info[] = {
@@ -297,7 +299,8 @@ static void sil_post_set_mode (struct ata_port *ap)
{
struct ata_host *host = ap->host;
struct ata_device *dev;
- void __iomem *addr = host->mmio_base + sil_port[ap->port_no].xfer_mode;
+ void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
+ void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
u32 tmp, dev_mode[2];
unsigned int i;
@@ -320,9 +323,9 @@ static void sil_post_set_mode (struct ata_port *ap)
readl(addr); /* flush */
}
-static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
+static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
{
- unsigned long offset = ap->ioaddr.scr_addr;
+ void __iomem *offset = ap->ioaddr.scr_addr;
switch (sc_reg) {
case SCR_STATUS:
@@ -341,7 +344,7 @@ static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_re
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
return readl(mmio);
return 0xffffffffU;
@@ -349,7 +352,7 @@ 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)
{
- void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
writel(val, mmio);
}
@@ -444,7 +447,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
static irqreturn_t sil_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
- void __iomem *mmio_base = host->mmio_base;
+ void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
int handled = 0;
int i;
@@ -476,7 +479,7 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance)
static void sil_freeze(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
u32 tmp;
/* global IRQ mask doesn't block SATA IRQ, turn off explicitly */
@@ -491,7 +494,7 @@ static void sil_freeze(struct ata_port *ap)
static void sil_thaw(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
u32 tmp;
/* clear IRQ */
@@ -541,9 +544,9 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
{
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
unsigned int n, quirks = 0;
- unsigned char model_num[41];
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
- ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++)
if (!strcmp(sil_blacklist[n].product, model_num)) {
@@ -621,38 +624,35 @@ 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 ata_probe_ent *probe_ent = NULL;
- unsigned long base;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
unsigned int i;
- int pci_dev_busy = 0;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << SIL_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = pci_dev_to_dev(pdev);
@@ -666,22 +666,16 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq_flags = IRQF_SHARED;
probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
- mmio_base = pci_iomap(pdev, 5, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- base = (unsigned long) mmio_base;
+ mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
for (i = 0; i < probe_ent->n_ports; i++) {
- probe_ent->port[i].cmd_addr = base + sil_port[i].tf;
+ probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
probe_ent->port[i].altstatus_addr =
- probe_ent->port[i].ctl_addr = base + sil_port[i].ctl;
- probe_ent->port[i].bmdma_addr = base + sil_port[i].bmdma;
- probe_ent->port[i].scr_addr = base + sil_port[i].scr;
+ 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]);
}
@@ -690,30 +684,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
#ifdef CONFIG_PM
static int sil_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
- ata_pci_device_do_resume(pdev);
sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- host->mmio_base);
+ host->iomap[SIL_MMIO_BAR]);
ata_host_resume(host);
return 0;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 5aa288d2fb8..e65e8d55da3 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -28,7 +28,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_sil24"
#define DRV_VERSION "0.3"
@@ -61,6 +60,9 @@ struct sil24_port_multiplier {
};
enum {
+ SIL24_HOST_BAR = 0,
+ SIL24_PORT_BAR = 2,
+
/*
* Global controller registers (128 bytes @ BAR0)
*/
@@ -321,12 +323,6 @@ struct sil24_port_priv {
struct ata_taskfile tf; /* Cached taskfile registers */
};
-/* ap->host->private_data */
-struct sil24_host_priv {
- void __iomem *host_base; /* global controller control (128 bytes @BAR0) */
- void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
-};
-
static void sil24_dev_config(struct ata_port *ap, 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);
@@ -341,8 +337,6 @@ static void sil24_thaw(struct ata_port *ap);
static void sil24_error_handler(struct ata_port *ap);
static void sil24_post_internal_cmd(struct ata_queued_cmd *qc);
static int sil24_port_start(struct ata_port *ap);
-static void sil24_port_stop(struct ata_port *ap);
-static void sil24_host_stop(struct ata_host *host);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM
static int sil24_pci_device_resume(struct pci_dev *pdev);
@@ -362,7 +356,7 @@ static struct pci_driver sil24_pci_driver = {
.name = DRV_NAME,
.id_table = sil24_pci_tbl,
.probe = sil24_init_one,
- .remove = ata_pci_remove_one, /* safe? */
+ .remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = sil24_pci_device_resume,
@@ -406,6 +400,8 @@ static const struct ata_port_operations sil24_ops = {
.irq_handler = sil24_interrupt,
.irq_clear = sil24_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = sil24_scr_read,
.scr_write = sil24_scr_write,
@@ -416,8 +412,6 @@ static const struct ata_port_operations sil24_ops = {
.post_internal_cmd = sil24_post_internal_cmd,
.port_start = sil24_port_start,
- .port_stop = sil24_port_stop,
- .host_stop = sil24_host_stop,
};
/*
@@ -467,7 +461,7 @@ static int sil24_tag(int tag)
static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
if (dev->cdb_len == 16)
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -478,7 +472,7 @@ static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct sil24_prb __iomem *prb = port;
u8 fis[6 * 4];
@@ -501,7 +495,7 @@ static int sil24_scr_map[] = {
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
@@ -512,7 +506,7 @@ 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)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
@@ -528,7 +522,7 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
static int sil24_init_port(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 tmp;
writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
@@ -544,7 +538,7 @@ static int sil24_init_port(struct ata_port *ap)
static int sil24_softreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
dma_addr_t paddr = pp->cmd_block_dma;
@@ -604,7 +598,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
const char *reason;
int tout_msec, rc;
u32 tmp;
@@ -721,7 +715,7 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
unsigned int tag = sil24_tag(qc->tag);
dma_addr_t paddr;
void __iomem *activate;
@@ -742,7 +736,7 @@ static void sil24_irq_clear(struct ata_port *ap)
static void sil24_freeze(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
/* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear
* PORT_IRQ_ENABLE instead.
@@ -752,7 +746,7 @@ static void sil24_freeze(struct ata_port *ap)
static void sil24_thaw(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 tmp;
/* clear IRQ */
@@ -765,7 +759,7 @@ static void sil24_thaw(struct ata_port *ap)
static void sil24_error_intr(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct ata_eh_info *ehi = &ap->eh_info;
int freeze = 0;
u32 irq_stat;
@@ -843,7 +837,7 @@ static void sil24_finish_qc(struct ata_queued_cmd *qc)
static inline void sil24_host_intr(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 slot_stat, qc_active;
int rc;
@@ -878,12 +872,12 @@ static inline void sil24_host_intr(struct ata_port *ap)
static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
- struct sil24_host_priv *hpriv = host->private_data;
+ void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
unsigned handled = 0;
u32 status;
int i;
- status = readl(hpriv->host_base + HOST_IRQ_STAT);
+ status = readl(host_base + HOST_IRQ_STAT);
if (status == 0xffffffff) {
printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
@@ -938,13 +932,6 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
sil24_init_port(ap);
}
-static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
-{
- const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS;
-
- dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
-}
-
static int sil24_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -952,22 +939,22 @@ static int sil24_port_start(struct ata_port *ap)
union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
dma_addr_t cb_dma;
- int rc = -ENOMEM;
+ int rc;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
+ return -ENOMEM;
pp->tf.command = ATA_DRDY;
- cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
+ cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb)
- goto err_out_pp;
+ return -ENOMEM;
memset(cb, 0, cb_size);
rc = ata_pad_alloc(ap, dev);
if (rc)
- goto err_out_pad;
+ return rc;
pp->cmd_block = cb;
pp->cmd_block_dma = cb_dma;
@@ -975,33 +962,6 @@ static int sil24_port_start(struct ata_port *ap)
ap->private_data = pp;
return 0;
-
-err_out_pad:
- sil24_cblk_free(pp, dev);
-err_out_pp:
- kfree(pp);
-err_out:
- return rc;
-}
-
-static void sil24_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct sil24_port_priv *pp = ap->private_data;
-
- sil24_cblk_free(pp, dev);
- ata_pad_free(ap, dev);
- kfree(pp);
-}
-
-static void sil24_host_stop(struct ata_host *host)
-{
- struct sil24_host_priv *hpriv = host->private_data;
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- pci_iounmap(pdev, hpriv->host_base);
- pci_iounmap(pdev, hpriv->port_base);
- kfree(hpriv);
}
static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
@@ -1066,43 +1026,32 @@ 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 = NULL;
- struct sil24_host_priv *hpriv = NULL;
- void __iomem *host_base = NULL;
- void __iomem *port_base = NULL;
+ struct ata_probe_ent *probe_ent;
+ void __iomem *host_base;
+ void __iomem *port_base;
int i, rc;
u32 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev,
+ (1 << SIL24_HOST_BAR) | (1 << SIL24_PORT_BAR),
+ DRV_NAME);
if (rc)
- goto out_disable;
-
- rc = -ENOMEM;
- /* map mmio registers */
- host_base = pci_iomap(pdev, 0, 0);
- if (!host_base)
- goto out_free;
- port_base = pci_iomap(pdev, 2, 0);
- if (!port_base)
- goto out_free;
-
- /* allocate & init probe_ent and hpriv */
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (!probe_ent)
- goto out_free;
+ return rc;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv)
- goto out_free;
+ /* allocate & init probe_ent */
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (!probe_ent)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
@@ -1117,10 +1066,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->private_data = hpriv;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- hpriv->host_base = host_base;
- hpriv->port_base = port_base;
+ host_base = probe_ent->iomap[SIL24_HOST_BAR];
+ port_base = probe_ent->iomap[SIL24_PORT_BAR];
/*
* Configure the device
@@ -1132,7 +1081,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
- goto out_free;
+ return rc;
}
}
} else {
@@ -1140,13 +1089,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
- goto out_free;
+ 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");
- goto out_free;
+ return rc;
}
}
@@ -1162,11 +1111,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
for (i = 0; i < probe_ent->n_ports; i++) {
- unsigned long portu =
- (unsigned long)port_base + i * PORT_REGS_SIZE;
+ void __iomem *port = port_base + i * PORT_REGS_SIZE;
- probe_ent->port[i].cmd_addr = portu;
- probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
+ probe_ent->port[i].cmd_addr = port;
+ probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
ata_std_ports(&probe_ent->port[i]);
}
@@ -1176,38 +1124,30 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
- kfree(probe_ent);
+ devm_kfree(dev, probe_ent);
return 0;
-
- out_free:
- if (host_base)
- pci_iounmap(pdev, host_base);
- if (port_base)
- pci_iounmap(pdev, port_base);
- kfree(probe_ent);
- kfree(hpriv);
- pci_release_regions(pdev);
- out_disable:
- pci_disable_device(pdev);
- return rc;
}
#ifdef CONFIG_PM
static int sil24_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
- struct sil24_host_priv *hpriv = host->private_data;
+ void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
+ void __iomem *port_base = host->iomap[SIL24_PORT_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)
- writel(HOST_CTRL_GLOBAL_RST, hpriv->host_base + HOST_CTRL);
+ writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- hpriv->host_base, hpriv->port_base);
+ host_base, port_base);
ata_host_resume(host);
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9c25a1e9173..49c9e2bd706 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -40,9 +40,11 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include "libata.h"
+#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "sata_sis"
-#define DRV_VERSION "0.6"
+#define DRV_VERSION "0.7"
enum {
sis_180 = 0,
@@ -67,9 +69,12 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static const struct pci_device_id sis_pci_tbl[] = {
- { PCI_VDEVICE(SI, 0x180), sis_180 },
- { PCI_VDEVICE(SI, 0x181), sis_180 },
- { PCI_VDEVICE(SI, 0x182), sis_180 },
+ { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */
+ { PCI_VDEVICE(SI, 0x0181), sis_180 }, /* SiS 964/180 */
+ { PCI_VDEVICE(SI, 0x0182), sis_180 }, /* SiS 965/965L */
+ { PCI_VDEVICE(SI, 0x0183), sis_180 }, /* SiS 965/965L */
+ { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/966L */
+ { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L */
{ } /* terminate list */
};
@@ -112,18 +117,18 @@ static const struct ata_port_operations sis_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.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,
.scr_read = sis_scr_read,
.scr_write = sis_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info sis_port_info = {
@@ -135,31 +140,42 @@ static struct ata_port_info sis_port_info = {
.port_ops = &sis_ops,
};
-
MODULE_AUTHOR("Uwe Koziolek");
MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+ u8 pmr;
- if (port_no) {
- if (device == 0x182)
- addr += SIS182_SATA1_OFS;
- else
- addr += SIS180_SATA1_OFS;
+ if (ap->port_no) {
+ switch (pdev->device) {
+ case 0x0180:
+ case 0x0181:
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+ if ((pmr & SIS_PMR_COMBINED) == 0)
+ addr += SIS180_SATA1_OFS;
+ break;
+
+ case 0x0182:
+ case 0x0183:
+ case 0x1182:
+ case 0x1183:
+ addr += SIS182_SATA1_OFS;
+ break;
+ }
}
-
return addr;
}
static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
u32 val, val2 = 0;
u8 pmr;
@@ -170,26 +186,28 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
pci_read_config_dword(pdev, cfg_addr, &val);
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
}
-static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
u8 pmr;
- if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
return;
pci_read_config_byte(pdev, SIS_PMR, &pmr);
pci_write_config_dword(pdev, cfg_addr, val);
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
pci_write_config_dword(pdev, cfg_addr+0x10, val);
}
@@ -207,10 +225,11 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
pci_read_config_byte(pdev, SIS_PMR, &pmr);
- val = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+ val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
- val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
+ val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
return (val | val2) & 0xfffffffb;
}
@@ -228,9 +247,10 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
if (ap->flags & SIS_FLAG_CFGSCR)
sis_scr_cfg_write(ap, sc_reg, val);
else {
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
}
}
@@ -241,29 +261,28 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
int rc;
u32 genctl, val;
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
- int pci_dev_busy = 0;
u8 pmr;
- u8 port2_start;
+ u8 port2_start = 0x20;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
/* check and see if the SCRs are in IO space or PCI cfg space */
pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
@@ -282,60 +301,79 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
pci_read_config_byte(pdev, SIS_PMR, &pmr);
- if (ent->device != 0x182) {
+ switch (ent->device) {
+ case 0x0180:
+ case 0x0181:
+
+ /* The PATA-handling is provided by pata_sis */
+ switch (pmr & 0x30) {
+ case 0x10:
+ ppi[1] = &sis_info133;
+ break;
+
+ case 0x30:
+ ppi[0] = &sis_info133;
+ break;
+ }
if ((pmr & SIS_PMR_COMBINED) == 0) {
dev_printk(KERN_INFO, &pdev->dev,
"Detected SiS 180/181/964 chipset in SATA mode\n");
port2_start = 64;
- }
- else {
+ } else {
dev_printk(KERN_INFO, &pdev->dev,
"Detected SiS 180/181 chipset in combined mode\n");
port2_start=0;
pi.flags |= ATA_FLAG_SLAVE_POSS;
}
- }
- else {
+ break;
+
+ case 0x0182:
+ case 0x0183:
pci_read_config_dword ( pdev, 0x6C, &val);
if (val & (1L << 31)) {
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
pi.flags |= ATA_FLAG_SLAVE_POSS;
- }
- else
+ } else {
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
- port2_start = 0x20;
+ }
+ break;
+
+ case 0x1182:
+ case 0x1183:
+ pci_read_config_dword(pdev, 0x64, &val);
+ if (val & 0x10000000) {
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966L SATA controller\n");
+ } else {
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966 SATA controller\n");
+ pi.flags |= ATA_FLAG_SLAVE_POSS;
+ }
+ break;
}
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ if (!probe_ent)
+ return -ENOMEM;
if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
- probe_ent->port[0].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR);
- probe_ent->port[1].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR) + port2_start;
+ void *mmio;
+
+ mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
+ if (!mmio)
+ return -ENOMEM;
+
+ probe_ent->port[0].scr_addr = mmio;
+ probe_ent->port[1].scr_addr = mmio + port2_start;
}
pci_set_master(pdev);
pci_intx(pdev, 1);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -EIO;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-err_out_regions:
- pci_release_regions(pdev);
-
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-
}
static int __init sis_init(void)
@@ -350,4 +388,3 @@ static void __exit sis_exit(void)
module_init(sis_init);
module_exit(sis_exit);
-
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index db32d15b7fa..4e428999420 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -56,6 +56,8 @@
#define DRV_VERSION "2.0"
enum {
+ K2_FLAG_NO_ATAPI_DMA = (1 << 29),
+
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
K2_SATA_TF_DATA_OFFSET = 0x00,
@@ -83,16 +85,38 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
+
+ board_svw4 = 0,
+ 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);
+static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
+ return -1; /* ATAPI DMA not supported */
+
+ return 0;
+}
+
static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -101,7 +125,7 @@ static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -116,11 +140,16 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ ioaddr->lbah_addr);
} else if (is_addr) {
writew(tf->feature, ioaddr->feature_addr);
writew(tf->nsect, ioaddr->nsect_addr);
@@ -233,7 +262,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
static u8 k2_stat_check_status(struct ata_port *ap)
{
- return readl((void *) ap->ioaddr.status_addr);
+ return readl((void __iomem *) ap->ioaddr.status_addr);
}
#ifdef CONFIG_PPC_OF
@@ -313,27 +342,28 @@ static const struct ata_port_operations k2_sata_ops = {
.check_status = k2_stat_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = k2_sata_check_atapi_dma,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.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,
.scr_read = k2_sata_scr_read,
.scr_write = k2_sata_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
-static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET;
port->data_addr = base + K2_SATA_TF_DATA_OFFSET;
@@ -356,10 +386,11 @@ static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
- int pci_dev_busy = 0;
+ const struct k2_board_info *board_info =
+ &k2_board_info[ent->driver_data];
int rc;
int i;
@@ -370,7 +401,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
* 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
*/
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
/*
@@ -380,56 +411,35 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
if (pci_resource_len(pdev, 5) == 0)
return -ENODEV;
- /* Request PCI regions */
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ /* Request and iomap PCI regions */
+ rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 5, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- /* 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)
- */
- writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
- mmio_base + K2_SATA_SICR1_OFFSET);
-
- /* Clear SATA error & interrupts we don't use */
- writel(0xffffffff, mmio_base + K2_SATA_SCR_ERROR_OFFSET);
- writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
-
probe_ent->sht = &k2_sata_sht;
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO;
+ 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->mmio_base = mmio_base;
+ 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
@@ -438,28 +448,33 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
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 < ent->driver_data; i++)
- k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
+ 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)
+ */
+ writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
+ mmio_base + K2_SATA_SICR1_OFFSET);
+
+ /* Clear SATA error & interrupts we don't use */
+ writel(0xffffffff, mmio_base + K2_SATA_SCR_ERROR_OFFSET);
+ writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
/* 0x240 is device ID for Apple K2 device
@@ -469,11 +484,11 @@ err_out:
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), 8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), 4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), 4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
{ }
};
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ae7992de4b0..06e87a37738 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -42,7 +42,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
@@ -50,6 +49,9 @@
enum {
+ PDC_MMIO_BAR = 3,
+ PDC_DIMM_BAR = 4,
+
PDC_PRD_TBL = 0x44, /* Direct command DMA table addr */
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
@@ -138,8 +140,6 @@ struct pdc_port_priv {
};
struct pdc_host_priv {
- void __iomem *dimm_mmio;
-
unsigned int doing_hdma;
unsigned int hdma_prod;
unsigned int hdma_cons;
@@ -156,11 +156,9 @@ 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 pdc_port_stop(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 void pdc20621_host_stop(struct ata_host *host);
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,
@@ -205,13 +203,13 @@ static const struct ata_port_operations pdc_20621_ops = {
.phy_reset = pdc_20621_phy_reset,
.qc_prep = pdc20621_qc_prep,
.qc_issue = pdc20621_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .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,
.port_start = pdc_port_start,
- .port_stop = pdc_port_stop,
- .host_stop = pdc20621_host_stop,
};
static const struct ata_port_info pdc_port_info[] = {
@@ -243,18 +241,6 @@ static struct pci_driver pdc_sata_pci_driver = {
};
-static void pdc20621_host_stop(struct ata_host *host)
-{
- struct pci_dev *pdev = to_pci_dev(host->dev);
- struct pdc_host_priv *hpriv = host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
-
- pci_iounmap(pdev, dimm_mmio);
- kfree(hpriv);
-
- pci_iounmap(pdev, host->mmio_base);
-}
-
static int pdc_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -265,43 +251,19 @@ static int pdc_port_start(struct ata_port *ap)
if (rc)
return rc;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
- memset(pp, 0, sizeof(*pp));
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
- pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
ap->private_data = pp;
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-
-static void pdc_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
- dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
}
-
static void pdc_20621_phy_reset (struct ata_port *ap)
{
VPRINTK("ENTER\n");
@@ -452,9 +414,8 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
struct scatterlist *sg;
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
unsigned int portno = ap->port_no;
unsigned int i, idx, total_len = 0, sgt_len;
u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
@@ -513,9 +474,8 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
unsigned int portno = ap->port_no;
unsigned int i;
@@ -565,7 +525,7 @@ static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
{
struct ata_port *ap = qc->ap;
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -619,8 +579,7 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int port_no = ap->port_no;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
dimm_mmio += (port_no * PDC_DIMM_WINDOW_STEP);
dimm_mmio += PDC_DIMM_HOST_PKT;
@@ -639,7 +598,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct ata_host *host = ap->host;
unsigned int port_no = ap->port_no;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 seq = (u8) (port_no + 1);
unsigned int port_ofs;
@@ -668,8 +627,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
readl(mmio + PDC_20621_SEQCTL + (seq * 4)); /* flush */
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
port_ofs + PDC_DIMM_ATA_PKT,
port_ofs + PDC_DIMM_ATA_PKT,
@@ -747,8 +706,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
readl(mmio + PDC_20621_SEQCTL + (seq * 4));
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
}
/* step two - execute ATA command */
@@ -781,7 +740,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
static void pdc20621_irq_clear(struct ata_port *ap)
{
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
mmio += PDC_CHIP0_OFS;
@@ -799,12 +758,12 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
VPRINTK("ENTER\n");
- if (!host || !host->mmio_base) {
+ if (!host || !host->iomap[PDC_MMIO_BAR]) {
VPRINTK("QUICK EXIT\n");
return IRQ_NONE;
}
- mmio_base = host->mmio_base;
+ mmio_base = host->iomap[PDC_MMIO_BAR];
/* reading should also clear interrupts */
mmio_base += PDC_CHIP0_OFS;
@@ -905,7 +864,7 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
}
-static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base;
port->data_addr = base;
@@ -931,9 +890,8 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->mmio_base;
- struct pdc_host_priv *hpriv = pe->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -987,9 +945,8 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->mmio_base;
- struct pdc_host_priv *hpriv = pe->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1034,7 +991,7 @@ 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,
u32 subaddr, u32 *pdata)
{
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
u32 i2creg = 0;
u32 status;
u32 count =0;
@@ -1093,7 +1050,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
u32 data = 0;
int size, i;
u8 bdimmsize;
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
static const struct {
unsigned int reg;
unsigned int ofs;
@@ -1155,8 +1112,8 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
{
u32 data, spd0;
- int error, i;
- void __iomem *mmio = pe->mmio_base;
+ int error, i;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1210,7 +1167,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->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1334,7 +1291,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
static void pdc_20621_init(struct ata_probe_ent *pe)
{
u32 tmp;
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1365,67 +1322,43 @@ 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 = NULL;
- unsigned long base;
- void __iomem *mmio_base;
- void __iomem *dimm_mmio = NULL;
- struct pdc_host_priv *hpriv = NULL;
+ struct ata_probe_ent *probe_ent;
+ void __iomem *base;
+ struct pdc_host_priv *hpriv;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, (1 << PDC_MMIO_BAR) | (1 << PDC_DIMM_BAR),
+ DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 3, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
-
- dimm_mmio = pci_iomap(pdev, 4, 0);
- if (!dimm_mmio) {
- kfree(hpriv);
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
-
- hpriv->dimm_mmio = dimm_mmio;
+ 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;
@@ -1436,10 +1369,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
- base += PDC_CHIP0_OFS;
+ 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);
@@ -1451,31 +1384,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
/* initialize adapter */
/* initialize local dimm */
- if (pdc20621_dimm_init(probe_ent)) {
- rc = -ENOMEM;
- goto err_out_iounmap_dimm;
- }
+ if (pdc20621_dimm_init(probe_ent))
+ return -ENOMEM;
pdc_20621_init(probe_ent);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_iounmap_dimm: /* only get to this label if 20621 */
- kfree(hpriv);
- pci_iounmap(pdev, dimm_mmio);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 5c603ca3a50..80131eec68f 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -108,7 +108,7 @@ static const struct ata_port_operations uli_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -117,18 +117,19 @@ static const struct ata_port_operations uli_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = uli_scr_read,
.scr_write = uli_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info uli_port_info = {
.sht = &uli_sht,
- .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_IGN_SIMPLEX,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 */
.port_ops = &uli_ops,
@@ -188,62 +189,60 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *ppi[2];
int rc;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
struct uli_priv *hpriv;
+ void __iomem * const *iomap;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ 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) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ if (!probe_ent)
+ return -ENOMEM;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_probe_ent;
- }
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
probe_ent->private_data = hpriv;
+ iomap = pcim_iomap_table(pdev);
+
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 = pci_resource_start(pdev, 0) + 8;
+ probe_ent->port[2].cmd_addr = iomap[0] + 8;
probe_ent->port[2].altstatus_addr =
- probe_ent->port[2].ctl_addr =
- (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
+ probe_ent->port[2].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
+ probe_ent->port[2].bmdma_addr = iomap[4] + 16;
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
- probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
+ probe_ent->port[3].cmd_addr = iomap[2] + 8;
probe_ent->port[3].altstatus_addr =
- probe_ent->port[3].ctl_addr =
- (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
+ probe_ent->port[3].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
+ probe_ent->port[3].bmdma_addr = iomap[4] + 24;
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
ata_std_ports(&probe_ent->port[2]);
@@ -268,21 +267,11 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_intx(pdev, 1);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_probe_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-
}
static int __init uli_init(void)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1c7f19aecc2..baca6d79bb0 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -44,7 +44,6 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_via"
#define DRV_VERSION "2.0"
@@ -59,11 +58,14 @@ enum {
SATA_INT_GATE = 0x41, /* SATA interrupt gating */
SATA_NATIVE_MODE = 0x42, /* Native mode enable */
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,
- N_PORTS = 2,
+ PATA_PORT = 2, /* PATA is port 2 */
+ N_PORTS = 3,
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
@@ -74,9 +76,16 @@ enum {
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
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 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 },
{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
@@ -125,24 +134,58 @@ static const struct ata_port_operations vt6420_sata_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
- .freeze = ata_bmdma_freeze,
+ .freeze = svia_noop_freeze,
.thaw = ata_bmdma_thaw,
.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,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
-static const struct ata_port_operations vt6421_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,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_data_xfer,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = vt6421_pata_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,
+
+ .port_start = vt6421_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,
@@ -156,22 +199,22 @@ static const struct ata_port_operations vt6421_sata_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
+ .error_handler = vt6421_sata_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,
.scr_read = svia_scr_read,
.scr_write = svia_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .port_start = vt6421_port_start,
};
static struct ata_port_info vt6420_port_info = {
@@ -193,14 +236,23 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return inl(ap->ioaddr.scr_addr + (4 * sc_reg));
+ return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg));
}
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
return;
- outl(val, ap->ioaddr.scr_addr + (4 * sc_reg));
+ iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg));
+}
+
+static void svia_noop_freeze(struct ata_port *ap)
+{
+ /* Some VIA controllers choke if ATA_NIEN is manipulated in
+ * certain way. Leave it alone and just clear pending IRQ.
+ */
+ ata_chk_status(ap);
+ ata_bmdma_irq_clear(ap);
}
/**
@@ -278,6 +330,61 @@ static void vt6420_error_handler(struct ata_port *ap)
NULL, ata_std_postreset);
}
+static int vt6421_pata_prereset(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);
+}
+
+static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 };
+ pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]);
+}
+
+static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 };
+ 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
};
@@ -286,31 +393,28 @@ static const unsigned int vt6421_bar_sizes[] = {
16, 16, 16, 16, 32, 128
};
-static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
+static void __iomem * svia_scr_addr(void __iomem *addr, unsigned int port)
{
return addr + (port * 128);
}
-static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
+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,
- struct pci_dev *pdev,
- unsigned int port)
+ void __iomem * const *iomap, unsigned int port)
{
- unsigned long reg_addr = pci_resource_start(pdev, port);
- unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8);
- unsigned long scr_addr;
+ 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 = (reg_addr + 8) | ATA_PCI_CTL_OFS;
+ probe_ent->port[port].ctl_addr = (void __iomem *)
+ ((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS);
probe_ent->port[port].bmdma_addr = bmdma_addr;
-
- scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
- probe_ent->port[port].scr_addr = scr_addr;
+ probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port);
ata_std_ports(&probe_ent->port[port]);
}
@@ -319,16 +423,16 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
{
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi[2];
-
+ void __iomem * const *iomap;
+
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;
- probe_ent->port[0].scr_addr =
- svia_scr_addr(pci_resource_start(pdev, 5), 0);
- probe_ent->port[1].scr_addr =
- svia_scr_addr(pci_resource_start(pdev, 5), 1);
+ 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);
return probe_ent;
}
@@ -338,7 +442,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
struct ata_probe_ent *probe_ent;
unsigned int i;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent)
return NULL;
@@ -357,7 +461,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
probe_ent->udma_mask = 0x7f;
for (i = 0; i < N_PORTS; i++)
- vt6421_init_addrs(probe_ent, pdev, i);
+ vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i);
return probe_ent;
}
@@ -409,20 +513,19 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_probe_ent *probe_ent;
int board_id = (int) ent->driver_data;
const int *bar_sizes;
- int pci_dev_busy = 0;
u8 tmp8;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
if (board_id == vt6420) {
@@ -431,8 +534,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev_printk(KERN_ERR, &pdev->dev,
"SATA master/slave not supported (0x%x)\n",
(int) tmp8);
- rc = -EIO;
- goto err_out_regions;
+ return -EIO;
}
bar_sizes = &svia_bar_sizes[0];
@@ -448,16 +550,15 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
i,
(unsigned long long)pci_resource_start(pdev, i),
(unsigned long long)pci_resource_len(pdev, i));
- rc = -ENODEV;
- goto err_out_regions;
+ return -ENODEV;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
if (board_id == vt6420)
probe_ent = vt6420_init_probe_ent(pdev);
@@ -466,26 +567,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!probe_ent) {
dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
- rc = -ENOMEM;
- goto err_out_regions;
+ return -ENOMEM;
}
svia_configure(pdev);
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
static int __init svia_init(void)
@@ -500,4 +593,3 @@ static void __exit svia_exit(void)
module_init(svia_init);
module_exit(svia_exit);
-
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index e654b990b90..3d9daf23111 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -50,6 +50,8 @@
#define DRV_VERSION "2.0"
enum {
+ VSC_MMIO_BAR = 0,
+
/* Interrupt register offsets (from chip base address) */
VSC_SATA_INT_STAT_OFFSET = 0x00,
VSC_SATA_INT_MASK_OFFSET = 0x04,
@@ -96,7 +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)))
@@ -105,7 +106,7 @@ static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -114,7 +115,7 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -123,7 +124,7 @@ static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
void __iomem *mask_addr;
u8 mask;
- mask_addr = ap->host->mmio_base +
+ mask_addr = ap->host->iomap[VSC_MMIO_BAR] +
VSC_SATA_INT_MASK_OFFSET + ap->port_no;
mask = readb(mask_addr);
if (ctl & ATA_NIEN)
@@ -149,11 +150,16 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
vsc_intr_mask_update(ap, tf->ctl & ATA_NIEN);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writew(tf->feature | (((u16)tf->hob_feature) << 8), ioaddr->feature_addr);
- writew(tf->nsect | (((u16)tf->hob_nsect) << 8), ioaddr->nsect_addr);
- writew(tf->lbal | (((u16)tf->hob_lbal) << 8), ioaddr->lbal_addr);
- writew(tf->lbam | (((u16)tf->hob_lbam) << 8), ioaddr->lbam_addr);
- writew(tf->lbah | (((u16)tf->hob_lbah) << 8), ioaddr->lbah_addr);
+ writew(tf->feature | (((u16)tf->hob_feature) << 8),
+ ioaddr->feature_addr);
+ writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
+ ioaddr->nsect_addr);
+ writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
+ ioaddr->lbal_addr);
+ writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
+ ioaddr->lbam_addr);
+ writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
+ ioaddr->lbah_addr);
} else if (is_addr) {
writew(tf->feature, ioaddr->feature_addr);
writew(tf->nsect, ioaddr->nsect_addr);
@@ -212,7 +218,8 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
spin_lock(&host->lock);
- int_status = readl(host->mmio_base + VSC_SATA_INT_STAT_OFFSET);
+ int_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))) {
@@ -296,21 +303,22 @@ static const struct ata_port_operations vsc_sata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_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,
.scr_read = vsc_sata_scr_read,
.scr_write = vsc_sata_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
-static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
+ void __iomem *base)
{
port->cmd_addr = base + VSC_SATA_TF_CMD_OFFSET;
port->data_addr = base + VSC_SATA_TF_DATA_OFFSET;
@@ -335,72 +343,62 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned lon
static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
- int pci_dev_busy = 0;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
/*
* Check if we have needed resource mapped.
*/
- if (pci_resource_len(pdev, 0) == 0) {
- rc = -ENODEV;
- goto err_out;
- }
+ if (pci_resource_len(pdev, 0) == 0)
+ return -ENODEV;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
*/
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
- memset(probe_ent, 0, sizeof(*probe_ent));
+ 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);
- mmio_base = pci_iomap(pdev, 0, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
/*
* Due to a bug in the chip, the default cache line size can't be used
*/
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80);
+ 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->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ 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
@@ -409,11 +407,13 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
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], base + 1 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[1], base + 2 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[2], base + 3 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[3], base + 4 * VSC_SATA_PORT_OFFSET);
+ 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);
@@ -425,20 +425,11 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
*/
pci_write_config_dword(pdev, 0x98, 0);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
static const struct pci_device_id vsc_sata_pci_tbl[] = {