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 Original line Diff line number Diff line
@@ -186,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = {
	.qc_issue		= ata_qc_issue_prot,
	.qc_issue		= ata_qc_issue_prot,
	.data_xfer		= ata_data_xfer,
	.data_xfer		= ata_data_xfer,


	.irq_handler		= ata_interrupt,
	.irq_clear		= ata_bmdma_irq_clear,
	.irq_clear		= ata_bmdma_irq_clear,
	.irq_on			= ata_irq_on,
	.irq_on			= ata_irq_on,
	.irq_ack		= ata_irq_ack,
	.irq_ack		= ata_irq_ack,
@@ -194,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = {
	.port_start		= ata_port_start,
	.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;
	u8 pcicfg;
	void __iomem *iomap[5];
	void *iomap[5];
	static struct ata_probe_ent probe[2];
	struct ata_host *host;
	int ports = 0;
	struct ata_ioports *ioaddr;
	int i, rc;


	/* IDE port enable bits */
	/* 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 */
	/* Check if the ATA ports are enabled */
	if ((pcicfg & 3) == 0)
	if ((pcicfg & 3) == 0)
		return -ENODEV;
		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) {
	if ((pcicfg & 0x40) == 0) {
		printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
		dev_printk(KERN_WARNING, &pdev->dev,
		pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
			   "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 */
	/* 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");
		printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
		return -ENODEV;
		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");
		printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
		return -ENODEV;
		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");
		printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
		return -ENODEV;
		return -ENODEV;
	}
	}


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


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


	/* We have to do our own plumbing as the PCI setup for this
	ioaddr = &host->ports[0]->ioaddr;
	   chipset is non-standard so we can't punt to the libata code */
	ioaddr->cmd_addr = iomap[0];

	ioaddr->ctl_addr = iomap[1];
	INIT_LIST_HEAD(&probe[0].node);
	ioaddr->altstatus_addr = iomap[1];
	probe[0].dev = pci_dev_to_dev(dev);
	ioaddr->bmdma_addr = iomap[4];
	probe[0].port_ops = &cs5520_port_ops;
	ata_std_ports(ioaddr);
	probe[0].sht = &cs5520_sht;

	probe[0].pio_mask = 0x1F;
	ioaddr = &host->ports[1]->ioaddr;
	probe[0].mwdma_mask = id->driver_data;
	ioaddr->cmd_addr = iomap[2];
	probe[0].irq = 14;
	ioaddr->ctl_addr = iomap[3];
	probe[0].irq_flags = 0;
	ioaddr->altstatus_addr = iomap[3];
	probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
	ioaddr->bmdma_addr = iomap[4] + 8;
	probe[0].n_ports = 1;
	ata_std_ports(ioaddr);
	probe[0].port[0].cmd_addr = iomap[0];

	probe[0].port[0].ctl_addr = iomap[1];
	/* activate the host */
	probe[0].port[0].altstatus_addr = iomap[1];
	pci_set_master(pdev);
	probe[0].port[0].bmdma_addr = iomap[4];
	rc = ata_host_start(host);

	if (rc)
	/* The secondary lurks at different addresses but is otherwise
		return rc;
	   the same beastie */


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

	probe[1].port[0].cmd_addr = iomap[2];
		if (ata_port_is_dummy(ap))
	probe[1].port[0].ctl_addr = iomap[3];
			continue;
	probe[1].port[0].altstatus_addr = iomap[3];

	probe[1].port[0].bmdma_addr = iomap[4] + 8;
		rc = devm_request_irq(&pdev->dev, irq[ap->port_no],

				      ata_interrupt, 0, DRV_NAME, host);
	/* Let libata fill in the port details */
		if (rc)
	ata_std_ports(&probe[0].port[0]);
			return rc;
	ata_std_ports(&probe[1].port[0]);
	}


	/* Now add the ports that are active */
	return ata_host_register(host, &cs5520_sht);
	if (pcicfg & 1)
		ports += ata_device_add(&probe[0]);
	if (pcicfg & 2)
		ports += ata_device_add(&probe[1]);
	if (ports)
		return 0;
	return -ENODEV;
}
}


/**
/**
+23 −20
Original line number Original line Diff line number Diff line
@@ -56,7 +56,6 @@ static struct ata_port_operations isapnp_port_ops = {


	.data_xfer	= ata_data_xfer,
	.data_xfer	= ata_data_xfer,


	.irq_handler	= ata_interrupt,
	.irq_clear	= ata_bmdma_irq_clear,
	.irq_clear	= ata_bmdma_irq_clear,
	.irq_on		= ata_irq_on,
	.irq_on		= ata_irq_on,
	.irq_ack	= ata_irq_ack,
	.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)
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;
	void __iomem *cmd_addr, *ctl_addr;
	int rc;


	if (pnp_port_valid(idev, 0) == 0)
	if (pnp_port_valid(idev, 0) == 0)
		return -ENODEV;
		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)
	if (pnp_irq_valid(idev, 0) == 0)
		return -ENODEV;
		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);
	cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
	if (!cmd_addr)
	if (!cmd_addr)
		return -ENOMEM;
		return -ENOMEM;


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

	ae.dev = &idev->dev;
	ap->ops = &isapnp_port_ops;
	ae.port_ops = &isapnp_port_ops;
	ap->pio_mask = 1;
	ae.sht = &isapnp_sht;
	ap->flags |= ATA_FLAG_SLAVE_POSS;
	ae.n_ports = 1;

	ae.pio_mask = 1;		/* ISA so PIO 0 cycles */
	ap->ioaddr.cmd_addr = cmd_addr;
	ae.irq = pnp_irq(idev, 0);
	ae.irq_flags = 0;
	ae.port_flags = ATA_FLAG_SLAVE_POSS;
	ae.port[0].cmd_addr = cmd_addr;


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


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

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


/**
/**
+17 −22
Original line number Original line Diff line number Diff line
@@ -131,7 +131,6 @@ static struct ata_port_operations ixp4xx_port_ops = {
	.data_xfer	= ixp4xx_mmio_data_xfer,
	.data_xfer	= ixp4xx_mmio_data_xfer,
	.cable_detect	= ata_cable_40wire,
	.cable_detect	= ata_cable_40wire,


	.irq_handler	= ata_interrupt,
	.irq_clear	= ixp4xx_irq_clear,
	.irq_clear	= ixp4xx_irq_clear,
	.irq_on		= ata_irq_on,
	.irq_on		= ata_irq_on,
	.irq_ack	= ata_irq_ack,
	.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)
static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
{
{
	int ret;
	unsigned int irq;
	unsigned int irq;
	struct resource *cs0, *cs1;
	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;
	struct ixp4xx_pata_data *data = pdev->dev.platform_data;
	int rc;


	cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	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)
	if (!cs0 || !cs1)
		return -EINVAL;
		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;
	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;


	data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
	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->cs0_cfg = data->cs0_bits;
	*data->cs1_cfg = data->cs1_bits;
	*data->cs1_cfg = data->cs1_bits;


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


	ae.dev		= &pdev->dev;
	ap->ops	= &ixp4xx_port_ops;
	ae.port_ops	= &ixp4xx_port_ops;
	ap->pio_mask = 0x1f; /* PIO4 */
	ae.sht		= &ixp4xx_sht;
	ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
	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;


	/* run in polling mode if no irq has been assigned */
	/* run in polling mode if no irq has been assigned */
	if (!irq)
	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");
	dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");


	ret = ata_device_add(&ae);
	/* activate host */
	if (ret == 0)
	return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
		return -ENODEV;

	return 0;
}
}


static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
+19 −19
Original line number Original line 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)
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 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 platform_device *pdev;
	struct ata_port_operations *ops = &legacy_port_ops;
	struct ata_port_operations *ops = &legacy_port_ops;
	void __iomem *io_addr, *ctrl_addr;
	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))
	if (ops == &legacy_port_ops && (autospeed & mask))
		ops = &simple_port_ops;
		ops = &simple_port_ops;


	memset(&ae, 0, sizeof(struct ata_probe_ent));
	ret = -ENOMEM;
	INIT_LIST_HEAD(&ae.node);
	host = ata_host_alloc(&pdev->dev, 1);
	ae.dev = &pdev->dev;
	if (!host)
	ae.port_ops = ops;
		goto fail;
	ae.sht = &legacy_sht;
	ap = host->ports[0];
	ae.n_ports = 1;

	ae.pio_mask = pio_modes;
	ap->ops = ops;
	ae.irq = irq;
	ap->pio_mask = pio_modes;
	ae.irq_flags = 0;
	ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
	ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
	ap->ioaddr.cmd_addr = io_addr;
	ae.port[0].cmd_addr = io_addr;
	ap->ioaddr.altstatus_addr = ctrl_addr;
	ae.port[0].altstatus_addr = ctrl_addr;
	ap->ioaddr.ctl_addr = ctrl_addr;
	ae.port[0].ctl_addr = ctrl_addr;
	ata_std_ports(&ap->ioaddr);
	ata_std_ports(&ae.port[0]);
	ap->private_data = ld;
	ae.private_data = ld;


	ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
	ret = -ENODEV;
	if (ret)
	if (!ata_device_add(&ae))
		goto fail;
		goto fail;


	legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
	legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
+21 −25
Original line number Original line Diff line number Diff line
@@ -301,35 +301,33 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
	.qc_prep		= ata_qc_prep,
	.qc_prep		= ata_qc_prep,
	.qc_issue		= ata_qc_issue_prot,
	.qc_issue		= ata_qc_issue_prot,
	.data_xfer		= ata_data_xfer,
	.data_xfer		= ata_data_xfer,
	.irq_handler		= ata_interrupt,
	.irq_clear		= ata_bmdma_irq_clear,
	.irq_clear		= ata_bmdma_irq_clear,
	.irq_on			= ata_irq_on,
	.irq_on			= ata_irq_on,
	.irq_ack		= ata_irq_ack,
	.irq_ack		= ata_irq_ack,
	.port_start		= ata_port_start,
	.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
static int __devinit
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
{
{
	struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
	struct ata_host *host;
	struct ata_ioports *aio = &ae->port[0];
	struct ata_port *ap;
	int rv;
	struct ata_ioports *aio;

	int rc;
	INIT_LIST_HEAD(&ae->node);

	ae->dev = dev;
	host = ata_host_alloc(dev, 1);
	ae->irq = priv->ata_irq;
	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->cmd_addr		= NULL;	/* Don't have a classic reg block */
	aio->altstatus_addr	= &priv->ata_regs->tf_control;
	aio->altstatus_addr	= &priv->ata_regs->tf_control;
	aio->ctl_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->status_addr	= &priv->ata_regs->tf_command;
	aio->command_addr	= &priv->ata_regs->tf_command;
	aio->command_addr	= &priv->ata_regs->tf_command;


	ae->private_data = priv;
	/* activate host */

	return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
	rv = ata_device_add(ae);
				 &mpc52xx_ata_sht);

	return rv ? 0 : -EINVAL;
}
}


static struct mpc52xx_ata_priv *
static struct mpc52xx_ata_priv *
Loading