Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d728824 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

libata: convert the remaining PATA drivers to new init model



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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 4447d351
Loading
Loading
Loading
Loading
+71 −59
Original line number Diff line number Diff line
@@ -186,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = {
	.qc_issue		= ata_qc_issue_prot,
	.data_xfer		= ata_data_xfer,

	.irq_handler		= ata_interrupt,
	.irq_clear		= ata_bmdma_irq_clear,
	.irq_on			= ata_irq_on,
	.irq_ack		= ata_irq_ack,
@@ -194,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = {
	.port_start		= ata_port_start,
};

static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct ata_port_info pi = {
		.flags		= ATA_FLAG_SLAVE_POSS,
		.pio_mask	= 0x1f,
		.port_ops	= &cs5520_port_ops,
	};
	const struct ata_port_info *ppi[2];
	u8 pcicfg;
	void __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);
}

/**
+23 −20
Original line number Diff line number Diff line
@@ -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,
@@ -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;
@@ -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);
}

/**
+17 −22
Original line number Diff line number Diff line
@@ -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,
@@ -174,12 +173,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,

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

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

	cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -187,6 +186,12 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
	if (!cs0 || !cs1)
		return -EINVAL;

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

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

	data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
@@ -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)
+19 −19
Original line number Diff line number Diff line
@@ -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;
@@ -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);
+21 −25
Original line number Diff line number Diff line
@@ -301,35 +301,33 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
	.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;

	struct ata_host *host;
	struct ata_port *ap;
	struct ata_ioports *aio;
	int rc;

	host = ata_host_alloc(dev, 1);
	if (!host)
		return -ENOMEM;

	ap = host->ports[0];
	ap->flags		|= ATA_FLAG_SLAVE_POSS;
	ap->pio_mask		= 0x1f;	/* Up to PIO4 */
	ap->mwdma_mask		= 0x00;	/* No MWDMA   */
	ap->udma_mask		= 0x00;	/* No UDMA    */
	ap->ops			= &mpc52xx_ata_port_ops;
	host->private_data	= priv;

	aio = &ap->ioaddr;
	aio->cmd_addr		= NULL;	/* Don't have a classic reg block */
	aio->altstatus_addr	= &priv->ata_regs->tf_control;
	aio->ctl_addr		= &priv->ata_regs->tf_control;
@@ -344,11 +342,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
	aio->status_addr	= &priv->ata_regs->tf_command;
	aio->command_addr	= &priv->ata_regs->tf_command;

	ae->private_data = priv;

	rv = ata_device_add(ae);

	return rv ? 0 : -EINVAL;
	/* activate host */
	return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
				 &mpc52xx_ata_sht);
}

static struct mpc52xx_ata_priv *
Loading