All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <htejun@gmail.com>
To: jeff@garzik.org, alan@lxorguk.ukuu.org.uk,
	linux-ide@vger.kernel.org, brking@linux.vnet.ibm.com
Cc: Tejun Heo <htejun@gmail.com>
Subject: [PATCH 06/12] libata: convert native PCI host handling to new init model
Date: Wed, 11 Apr 2007 15:42:05 +0900	[thread overview]
Message-ID: <11762737253120-git-send-email-htejun@gmail.com> (raw)
In-Reply-To: <1176273724198-git-send-email-htejun@gmail.com>

Convert native PCI host handling to alloc-init-register model.  New
function ata_pci_init_native_host() follows the new init model and
replaces ata_pci_init_native_mode().  As there are remaining LLD
users, the old function isn't removed yet.

ata_pci_init_one() is reimplemented using the new function and now
fully converted to new init model.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
 drivers/ata/libata-core.c |    1 +
 drivers/ata/libata-sff.c  |  151 ++++++++++++++++++++++++++++++---------------
 include/linux/libata.h    |    2 +
 3 files changed, 104 insertions(+), 50 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 6d42550..5726ca6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6716,6 +6716,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
+EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 #ifdef CONFIG_PM
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d48e154..d551fa1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -678,6 +678,70 @@ static int ata_pci_init_bmdma(struct ata_host *host)
 	return 0;
 }
 
+/**
+ *	ata_pci_init_native_host - acquire native ATA resources and init host
+ *	@host: target ATA host
+ *	@port_mask: ports to consider
+ *
+ *	Acquire native PCI ATA resources for @host and initialize
+ *	@host accordoingly.
+ *
+ *	LOCKING:
+ *	Inherited from calling layer (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise.
+ */
+int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
+{
+	struct device *gdev = host->dev;
+	struct pci_dev *pdev = to_pci_dev(gdev);
+	int i, rc;
+
+	/* Discard disabled ports.  Some controllers show their unused
+	 * channels this way.  Disabled ports are made dummy.
+	 */
+	for (i = 0; i < 2; i++) {
+		if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
+			host->ports[i]->ops = &ata_dummy_port_ops;
+			port_mask &= ~(1 << i);
+		}
+	}
+
+	if (!port_mask) {
+		dev_printk(KERN_ERR, gdev, "no available port\n");
+		return -ENODEV;
+	}
+
+	/* request, iomap BARs and init port addresses accordingly */
+	for (i = 0; i < 2; i++) {
+		struct ata_port *ap = host->ports[i];
+		int base = i * 2;
+		void __iomem * const *iomap;
+
+		if (!(port_mask & (1 << i)))
+			continue;
+
+		rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
+		if (rc) {
+			dev_printk(KERN_ERR, gdev, "failed to request/iomap "
+				   "BARs for port %d (errno=%d)\n", i, rc);
+			if (rc == -EBUSY)
+				pcim_pin_device(pdev);
+			return rc;
+		}
+		host->iomap = iomap = pcim_iomap_table(pdev);
+
+		ap->ioaddr.cmd_addr = iomap[base];
+		ap->ioaddr.altstatus_addr =
+		ap->ioaddr.ctl_addr = (void __iomem *)
+			((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
+		ata_std_ports(&ap->ioaddr);
+	}
+
+	return 0;
+}
+
 struct ata_legacy_devres {
 	unsigned int	mask;
 	unsigned long	cmd_port[2];
@@ -917,7 +981,6 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 		      unsigned int n_ports)
 {
 	struct device *dev = &pdev->dev;
-	struct ata_probe_ent *probe_ent = NULL;
 	struct ata_host *host = NULL;
 	const struct ata_port_info *port[2];
 	u8 mask;
@@ -943,7 +1006,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 
 	   Checking dev->is_enabled is insufficient as this is not set at
 	   boot for the primary video which is BIOS enabled
-         */
+	  */
 
 	rc = pcim_enable_device(pdev);
 	if (rc)
@@ -969,30 +1032,28 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 #endif
 	}
 
+	/* alloc and init host */
+	host = ata_host_alloc_pinfo(dev, port, 2);
+	if (!host) {
+		dev_printk(KERN_ERR, &pdev->dev,
+			   "failed to allocate ATA host\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
 	if (!legacy_mode) {
-		rc = pci_request_regions(pdev, DRV_NAME);
-		if (rc) {
-			pcim_pin_device(pdev);
-			goto err_out;
-		}
+		unsigned int port_mask;
 
-		/* TODO: If we get no DMA mask we should fall back to PIO */
-		rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-		if (rc)
-			goto err_out;
-		rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+		port_mask = ATA_PORT_PRIMARY;
+		if (n_ports > 1)
+			port_mask |= ATA_PORT_SECONDARY;
+
+		rc = ata_pci_init_native_host(host, port_mask);
 		if (rc)
 			goto err_out;
-
-		pci_set_master(pdev);
 	} else {
 		int was_busy = 0;
 
-		rc = -ENOMEM;
-		host = ata_host_alloc_pinfo(dev, port, 2);
-		if (!host)
-			goto err_out;
-
 		rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
 		if (was_busy)
 			pcim_pin_device(pdev);
@@ -1002,47 +1063,37 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 		/* request respective PCI regions, may fail */
 		rc = pci_request_region(pdev, 1, DRV_NAME);
 		rc = pci_request_region(pdev, 3, DRV_NAME);
-
-		/* init bmdma */
-		ata_pci_init_bmdma(host);
-		pci_set_master(pdev);
 	}
 
-	if (legacy_mode) {
+	/* init BMDMA, may fail */
+	ata_pci_init_bmdma(host);
+	pci_set_master(pdev);
+
+	/* start host and request IRQ */
+	rc = ata_host_start(host);
+	if (rc)
+		goto err_out;
+
+	if (!legacy_mode)
+		rc = devm_request_irq(dev, pdev->irq,
+				      port_info[0]->port_ops->irq_handler,
+				      IRQF_SHARED, DRV_NAME, host);
+	else {
 		irq_handler_t handler[2] = { host->ops->irq_handler,
 					     host->ops->irq_handler };
 		unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
 		void *dev_id[2] = { host, host };
 
-		rc = ata_host_start(host);
-		if (rc)
-			goto err_out;
-
 		rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
-		if (rc)
-			goto err_out;
-
-		rc = ata_host_register(host, port_info[0]->sht);
-		if (rc)
-			goto err_out;
-	} else {
-		if (n_ports == 2)
-			probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-		else
-			probe_ent = ata_pci_init_native_mode(pdev, (struct ata_port_info **)port, ATA_PORT_PRIMARY);
-
-		if (!probe_ent) {
-			rc = -ENOMEM;
-			goto err_out;
-		}
+	}
+	if (rc)
+		goto err_out;
 
-		if (!ata_device_add(probe_ent)) {
-			rc = -ENODEV;
-			goto err_out;
-		}
+	/* register */
+	rc = ata_host_register(host, port_info[0]->sht);
+	if (rc)
+		goto err_out;
 
-		devm_kfree(dev, probe_ent);
-	}
 	devres_remove_group(dev, NULL);
 	return 0;
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 300daf6..400429f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -892,6 +892,8 @@ struct pci_bits {
 
 extern struct ata_probe_ent *
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
+extern int ata_pci_init_native_host(struct ata_host *host,
+				    unsigned int port_mask);
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
 extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
-- 
1.5.0.3



  parent reply	other threads:[~2007-04-11  6:42 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-11  6:42 [PATCHSET] libata: implement new initialization model, take #4 Tejun Heo
2007-04-11  6:42 ` [PATCH 02/12] libata: separate out ata_host_start() Tejun Heo
2007-04-11  6:42 ` [PATCH 03/12] libata: separate out ata_host_alloc() and ata_host_register() Tejun Heo
2007-04-11  6:42 ` [PATCH 01/12] libata: allocate ap separately from shost Tejun Heo
2007-04-11  6:42 ` [PATCH 04/12] libata: implement ata_host_alloc_pinfo() and ata_host_register() Tejun Heo
2007-04-11  6:42 ` [PATCH 09/12] libata: convert ata_pci_init_native_mode() users to new init model Tejun Heo
2007-04-11  6:42 ` [PATCH 11/12] libata: convert the remaining PATA drivers " Tejun Heo
2007-04-11  8:22   ` Alan Cox
2007-04-11  8:37     ` [PATCH 11/12 UPDATED] " Tejun Heo
2007-04-11  6:42 ` [PATCH 07/12] libata: add init helpers including ata_pci_prepare_native_host() Tejun Heo
2007-04-11  6:42 ` Tejun Heo [this message]
2007-04-11  6:42 ` [PATCH 12/12] libata: kill probe_ent and related helpers Tejun Heo
2007-04-11  6:42 ` [PATCH 05/12] libata: convert legacy PCI host handling to new init model Tejun Heo
2007-04-11  6:42 ` [PATCH 08/12] libata: convert drivers with combined SATA/PATA ports " Tejun Heo
2007-04-11  6:42 ` [PATCH 10/12] libata: convert the remaining SATA drivers " Tejun Heo
  -- strict thread matches above, loose matches on Subject: below --
2007-03-09 11:15 [PATCHSET] libata: implement new initialization model, take #3 Tejun Heo
2007-03-09 11:15 ` [PATCH 06/12] libata: convert native PCI host handling to new init model Tejun Heo
2007-03-09 15:45   ` Jeff Garzik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11762737253120-git-send-email-htejun@gmail.com \
    --to=htejun@gmail.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=brking@linux.vnet.ibm.com \
    --cc=jeff@garzik.org \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.