summaryrefslogtreecommitdiff
path: root/drivers/ata/pata_icside.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_icside.c')
-rw-r--r--drivers/ata/pata_icside.c59
1 files changed, 24 insertions, 35 deletions
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 321d98b0bed2..be30923566c5 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -70,6 +70,8 @@ struct pata_icside_info {
unsigned int mwdma_mask;
unsigned int nr_ports;
const struct portinfo *port[2];
+ unsigned long raw_base;
+ unsigned long raw_ioc_base;
};
#define ICS_TYPE_A3IN 0
@@ -330,17 +332,12 @@ static void ata_dummy_noret(struct ata_port *port)
{
}
-/*
- * We need to shut down unused ports to prevent spurious interrupts.
- * FIXME: the libata core doesn't call this function for PATA interfaces.
- */
-static void pata_icside_port_disable(struct ata_port *ap)
+static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes)
{
struct pata_icside_state *state = ap->host->private_data;
- ata_port_printk(ap, KERN_ERR, "disabling icside port\n");
-
- ata_port_disable(ap);
+ if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE)
+ return ata_std_postreset(ap, classes);
state->port[ap->port_no].disabled = 1;
@@ -356,26 +353,13 @@ static void pata_icside_port_disable(struct ata_port *ap)
}
}
-static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq)
+static void pata_icside_error_handler(struct ata_port *ap)
{
- unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
- u8 status;
-
- status = ata_busy_wait(ap, bits, 1000);
- if (status & bits)
- if (ata_msg_err(ap))
- printk(KERN_ERR "abnormal status 0x%X\n", status);
-
- if (ata_msg_intr(ap))
- printk(KERN_INFO "%s: irq ack: drv_stat 0x%X\n",
- __FUNCTION__, status);
-
- return status;
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
+ pata_icside_postreset);
}
static struct ata_port_operations pata_icside_port_ops = {
- .port_disable = pata_icside_port_disable,
-
.set_dmamode = pata_icside_set_dmamode,
.tf_load = ata_tf_load,
@@ -397,12 +381,11 @@ static struct ata_port_operations pata_icside_port_ops = {
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
+ .error_handler = pata_icside_error_handler,
.post_internal_cmd = pata_icside_bmdma_stop,
.irq_clear = ata_dummy_noret,
.irq_on = ata_irq_on,
- .irq_ack = pata_icside_irq_ack,
.port_start = pata_icside_port_start,
@@ -411,9 +394,10 @@ static struct ata_port_operations pata_icside_port_ops = {
};
static void __devinit
-pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,
+pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base,
const struct portinfo *info)
{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
void __iomem *cmd = base + info->dataoffset;
ioaddr->cmd_addr = cmd;
@@ -430,6 +414,13 @@ pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base,
ioaddr->ctl_addr = base + info->ctrloffset;
ioaddr->altstatus_addr = ioaddr->ctl_addr;
+
+ ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
+ info->raw_base + info->dataoffset,
+ info->raw_base + info->ctrloffset);
+
+ if (info->raw_ioc_base)
+ ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base);
}
static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
@@ -450,6 +441,8 @@ static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
info->nr_ports = 1;
info->port[0] = &pata_icside_portinfo_v5;
+ info->raw_base = ecard_resource_start(ec, ECARD_RES_MEMC);
+
return 0;
}
@@ -484,19 +477,15 @@ static int __devinit pata_icside_register_v6(struct pata_icside_info *info)
state->port[0].port_sel = sel;
state->port[1].port_sel = sel | 1;
- /*
- * FIXME: work around libata's aversion to calling port_disable.
- * This permanently disables interrupts on port 0 - bad luck if
- * you have a drive on that port.
- */
- state->port[0].disabled = 1;
-
info->base = easi_base;
info->irqops = &pata_icside_ops_arcin_v6;
info->nr_ports = 2;
info->port[0] = &pata_icside_portinfo_v6_1;
info->port[1] = &pata_icside_portinfo_v6_2;
+ info->raw_base = ecard_resource_start(ec, ECARD_RES_EASI);
+ info->raw_ioc_base = ecard_resource_start(ec, ECARD_RES_IOCFAST);
+
return icside_dma_init(info);
}
@@ -533,7 +522,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ops = &pata_icside_port_ops;
- pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]);
+ pata_icside_setup_ioaddr(ap, info->base, info->port[i]);
}
return ata_host_activate(host, ec->irq, ata_interrupt, 0,