diff options
Diffstat (limited to 'drivers/ata/pata_icside.c')
-rw-r--r-- | drivers/ata/pata_icside.c | 59 |
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, |