Skip to content

Commit

Permalink
libata: convert the remaining PATA drivers to new init model
Browse files Browse the repository at this point in the history
Convert pdc_adma, pata_cs5520, pata_isapnp, pata_ixp4xx_cf,
pata_legacy, pata_mpc52xx, pata_mpiix, pata_pcmcia, pata_pdc2027x,
pata_platform, pata_qdi, pata_scc and pata_winbond to new init model.

* init_one()'s now follow more consistent init order

* cs5520 now registers one host with two ports, not two hosts.  If any
  of the two ports are disabled, it's made dummy as other drivers do.

Tested pdc_adma and pata_legacy.  Both are as broken as before.  The
rest are compile tested only.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Apr 28, 2007
1 parent 4447d35 commit 5d72882
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 429 deletions.
130 changes: 71 additions & 59 deletions drivers/ata/pata_cs5520.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,99 +186,111 @@ static struct ata_port_operations cs5520_port_ops = {
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,

.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,

.port_start = ata_port_start,
};

static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct ata_port_info pi = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &cs5520_port_ops,
};
const struct ata_port_info *ppi[2];
u8 pcicfg;
void __iomem *iomap[5];
static struct ata_probe_ent probe[2];
int ports = 0;
void *iomap[5];
struct ata_host *host;
struct ata_ioports *ioaddr;
int i, rc;

/* IDE port enable bits */
pci_read_config_byte(dev, 0x60, &pcicfg);
pci_read_config_byte(pdev, 0x60, &pcicfg);

/* Check if the ATA ports are enabled */
if ((pcicfg & 3) == 0)
return -ENODEV;

ppi[0] = ppi[1] = &ata_dummy_port_info;
if (pcicfg & 1)
ppi[0] = &pi;
if (pcicfg & 2)
ppi[1] = &pi;

if ((pcicfg & 0x40) == 0) {
printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
dev_printk(KERN_WARNING, &pdev->dev,
"DMA mode disabled. Enabling.\n");
pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
}

pi.mwdma_mask = id->driver_data;

host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
if (!host)
return -ENOMEM;

/* Perform set up for DMA */
if (pci_enable_device_bars(dev, 1<<2)) {
if (pci_enable_device_bars(pdev, 1<<2)) {
printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
return -ENODEV;
}
pci_set_master(dev);
if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {

if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
return -ENODEV;
}
if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
return -ENODEV;
}

/* Map IO ports */
iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8);
iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1);
iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8);
iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1);
iomap[4] = pcim_iomap(dev, 2, 0);
/* Map IO ports and initialize host accordingly */
iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
iomap[4] = pcim_iomap(pdev, 2, 0);

if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
return -ENOMEM;

/* We have to do our own plumbing as the PCI setup for this
chipset is non-standard so we can't punt to the libata code */

INIT_LIST_HEAD(&probe[0].node);
probe[0].dev = pci_dev_to_dev(dev);
probe[0].port_ops = &cs5520_port_ops;
probe[0].sht = &cs5520_sht;
probe[0].pio_mask = 0x1F;
probe[0].mwdma_mask = id->driver_data;
probe[0].irq = 14;
probe[0].irq_flags = 0;
probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
probe[0].n_ports = 1;
probe[0].port[0].cmd_addr = iomap[0];
probe[0].port[0].ctl_addr = iomap[1];
probe[0].port[0].altstatus_addr = iomap[1];
probe[0].port[0].bmdma_addr = iomap[4];

/* The secondary lurks at different addresses but is otherwise
the same beastie */

probe[1] = probe[0];
INIT_LIST_HEAD(&probe[1].node);
probe[1].irq = 15;
probe[1].port[0].cmd_addr = iomap[2];
probe[1].port[0].ctl_addr = iomap[3];
probe[1].port[0].altstatus_addr = iomap[3];
probe[1].port[0].bmdma_addr = iomap[4] + 8;

/* Let libata fill in the port details */
ata_std_ports(&probe[0].port[0]);
ata_std_ports(&probe[1].port[0]);

/* Now add the ports that are active */
if (pcicfg & 1)
ports += ata_device_add(&probe[0]);
if (pcicfg & 2)
ports += ata_device_add(&probe[1]);
if (ports)
return 0;
return -ENODEV;
ioaddr = &host->ports[0]->ioaddr;
ioaddr->cmd_addr = iomap[0];
ioaddr->ctl_addr = iomap[1];
ioaddr->altstatus_addr = iomap[1];
ioaddr->bmdma_addr = iomap[4];
ata_std_ports(ioaddr);

ioaddr = &host->ports[1]->ioaddr;
ioaddr->cmd_addr = iomap[2];
ioaddr->ctl_addr = iomap[3];
ioaddr->altstatus_addr = iomap[3];
ioaddr->bmdma_addr = iomap[4] + 8;
ata_std_ports(ioaddr);

/* activate the host */
pci_set_master(pdev);
rc = ata_host_start(host);
if (rc)
return rc;

for (i = 0; i < 2; i++) {
static const int irq[] = { 14, 15 };
struct ata_port *ap = host->ports[0];

if (ata_port_is_dummy(ap))
continue;

rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
ata_interrupt, 0, DRV_NAME, host);
if (rc)
return rc;
}

return ata_host_register(host, &cs5520_sht);
}

/**
Expand Down
43 changes: 23 additions & 20 deletions drivers/ata/pata_isapnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ static struct ata_port_operations isapnp_port_ops = {

.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,
Expand All @@ -75,8 +74,10 @@ static struct ata_port_operations isapnp_port_ops = {

static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
{
struct ata_probe_ent ae;
struct ata_host *host;
struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
int rc;

if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
Expand All @@ -85,34 +86,36 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
if (pnp_irq_valid(idev, 0) == 0)
return -ENODEV;

/* allocate host */
host = ata_host_alloc(&idev->dev, 1);
if (!host)
return -ENOMEM;

/* acquire resources and fill host */
cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
if (!cmd_addr)
return -ENOMEM;

memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &idev->dev;
ae.port_ops = &isapnp_port_ops;
ae.sht = &isapnp_sht;
ae.n_ports = 1;
ae.pio_mask = 1; /* ISA so PIO 0 cycles */
ae.irq = pnp_irq(idev, 0);
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS;
ae.port[0].cmd_addr = cmd_addr;
ap = host->ports[0];

ap->ops = &isapnp_port_ops;
ap->pio_mask = 1;
ap->flags |= ATA_FLAG_SLAVE_POSS;

ap->ioaddr.cmd_addr = cmd_addr;

if (pnp_port_valid(idev, 1) == 0) {
ctl_addr = devm_ioport_map(&idev->dev,
pnp_port_start(idev, 1), 1);
ae.port[0].altstatus_addr = ctl_addr;
ae.port[0].ctl_addr = ctl_addr;
ae.port_flags |= ATA_FLAG_SRST;
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
}
ata_std_ports(&ae.port[0]);

if (ata_device_add(&ae) == 0)
return -ENODEV;
return 0;
ata_std_ports(&ap->ioaddr);

/* activate */
return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
&isapnp_sht);
}

/**
Expand Down
39 changes: 17 additions & 22 deletions drivers/ata/pata_ixp4xx_cf.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ static struct ata_port_operations ixp4xx_port_ops = {
.data_xfer = ixp4xx_mmio_data_xfer,
.cable_detect = ata_cable_40wire,

.irq_handler = ata_interrupt,
.irq_clear = ixp4xx_irq_clear,
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
Expand Down Expand Up @@ -174,19 +173,25 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,

static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
{
int ret;
unsigned int irq;
struct resource *cs0, *cs1;
struct ata_probe_ent ae;

struct ata_host *host;
struct ata_port *ap;
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
int rc;

cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);

if (!cs0 || !cs1)
return -EINVAL;

/* allocate host */
host = ata_host_alloc(&pdev->dev, 1);
if (!host)
return -ENOMEM;

/* acquire resources and fill host */
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;

data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
Expand All @@ -200,32 +205,22 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
*data->cs0_cfg = data->cs0_bits;
*data->cs1_cfg = data->cs1_bits;

memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ap = host->ports[0];

ae.dev = &pdev->dev;
ae.port_ops = &ixp4xx_port_ops;
ae.sht = &ixp4xx_sht;
ae.n_ports = 1;
ae.pio_mask = 0x1f; /* PIO4 */
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
| ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
ap->ops = &ixp4xx_port_ops;
ap->pio_mask = 0x1f; /* PIO4 */
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;

/* run in polling mode if no irq has been assigned */
if (!irq)
ae.port_flags |= ATA_FLAG_PIO_POLLING;
ap->flags |= ATA_FLAG_PIO_POLLING;

ixp4xx_setup_port(&ae.port[0], data);
ixp4xx_setup_port(&ap->ioaddr, data);

dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");

ret = ata_device_add(&ae);
if (ret == 0)
return -ENODEV;

return 0;
/* activate host */
return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
}

static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
Expand Down
38 changes: 19 additions & 19 deletions drivers/ata/pata_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,8 @@ static struct ata_port_operations opti82c46x_port_ops = {
static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq)
{
struct legacy_data *ld = &legacy_data[nr_legacy_host];
struct ata_probe_ent ae;
struct ata_host *host;
struct ata_port *ap;
struct platform_device *pdev;
struct ata_port_operations *ops = &legacy_port_ops;
void __iomem *io_addr, *ctrl_addr;
Expand Down Expand Up @@ -798,24 +799,23 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
if (ops == &legacy_port_ops && (autospeed & mask))
ops = &simple_port_ops;

memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &pdev->dev;
ae.port_ops = ops;
ae.sht = &legacy_sht;
ae.n_ports = 1;
ae.pio_mask = pio_modes;
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
ae.port[0].cmd_addr = io_addr;
ae.port[0].altstatus_addr = ctrl_addr;
ae.port[0].ctl_addr = ctrl_addr;
ata_std_ports(&ae.port[0]);
ae.private_data = ld;

ret = -ENODEV;
if (!ata_device_add(&ae))
ret = -ENOMEM;
host = ata_host_alloc(&pdev->dev, 1);
if (!host)
goto fail;
ap = host->ports[0];

ap->ops = ops;
ap->pio_mask = pio_modes;
ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
ap->ioaddr.cmd_addr = io_addr;
ap->ioaddr.altstatus_addr = ctrl_addr;
ap->ioaddr.ctl_addr = ctrl_addr;
ata_std_ports(&ap->ioaddr);
ap->private_data = ld;

ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
if (ret)
goto fail;

legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
Expand Down
Loading

0 comments on commit 5d72882

Please sign in to comment.