[PATCH 17/20] libata: make ata_pci_acquire_resources() handle iomap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make ata_pci_acquire_resources() handle iomap.  @bar_mask is added and
for each set bit respective PCI BAR is iomapped and stored in
host->iomap[BAR#].  All iomaps stored in host->iomap[] are freed by
ata_pci_release_resources().

Also, acquire_resources() also map legacy IO areas and store them in
host->legacy_iomap[p][a] where @p is port number
(0=PRIMARY/1=SECONDARY) and @a indicates CMD or CTL.

This function only implements the feature.

Took hints from iomap patch by Jeff Garzik <jgarzik@xxxxxxxxx>.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>
---
 drivers/ata/ahci.c          |    2 +-
 drivers/ata/libata-legacy.c |   34 ++++++++++++++++++++++++++++++----
 drivers/ata/libata-pci.c    |   38 +++++++++++++++++++++++++++++++++++---
 drivers/ata/pdc_adma.c      |    2 +-
 drivers/ata/sata_mv.c       |    2 +-
 drivers/ata/sata_nv.c       |    2 +-
 drivers/ata/sata_promise.c  |    2 +-
 drivers/ata/sata_qstor.c    |    2 +-
 drivers/ata/sata_sil.c      |    2 +-
 drivers/ata/sata_sil24.c    |    2 +-
 drivers/ata/sata_sis.c      |    2 +-
 drivers/ata/sata_svw.c      |    2 +-
 drivers/ata/sata_sx4.c      |    2 +-
 drivers/ata/sata_uli.c      |    2 +-
 drivers/ata/sata_via.c      |    2 +-
 drivers/ata/sata_vsc.c      |    2 +-
 include/linux/libata.h      |    4 ++++
 17 files changed, 83 insertions(+), 21 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 1ad49fe..92d0394 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1488,7 +1488,7 @@ static int ahci_init_one(struct pci_dev 
 	hpriv = host->private_data;
 
 	/* acquire ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, 0, &reason);
+	rc = ata_pci_acquire_resources(host, 0, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/libata-legacy.c b/drivers/ata/libata-legacy.c
index c519602..eac4d06 100644
--- a/drivers/ata/libata-legacy.c
+++ b/drivers/ata/libata-legacy.c
@@ -52,10 +52,12 @@ static unsigned long ata_legacy_addr(int
 	}
 }
 
-static int ata_legacy_acquire_port(struct ata_port *ap)
+static int ata_legacy_acquire_port(struct ata_port *ap, const char **p_reason)
 {
 	struct ata_host *host = ap->host;
+	void __iomem **legacy_iomap = host->legacy_iomap[ap->port_no];
 	unsigned long cmd_addr = ata_legacy_addr(ap->port_no, 0);
+	unsigned long ctl_addr = ata_legacy_addr(ap->port_no, 1);
 
 	if (request_region(cmd_addr, 8, ata_drv_name(host)) != NULL)
 		host->legacy_flags |= ATA_LEGACY_RES_PRI << ap->port_no;
@@ -75,6 +77,13 @@ static int ata_legacy_acquire_port(struc
 		printk("ata: 0x%0lX IDE port preallocated\n", cmd_addr);
 	}
 
+	legacy_iomap[0] = ioport_map(cmd_addr, 8);
+	legacy_iomap[1] = ioport_map(ctl_addr, 4);
+	if (!legacy_iomap[0] || (ctl_addr && !legacy_iomap[1])) {
+		*p_reason = "failed to iomap legacy TF";
+		return -ENOMEM;
+	}
+
 	return 0;
 }
 
@@ -97,18 +106,28 @@ static int ata_legacy_acquire_port(struc
  */
 int ata_legacy_acquire_resources(struct ata_host *host, const char **p_reason)
 {
-	int i;
+	const char *reason;
+	int i, rc;
 
 	for (i = 0; i < 2; i++) {
 		if (!(host->legacy_flags & (ATA_PORT_PRIMARY << i)))
 			continue;
 		BUG_ON(i >= host->n_ports);
 
-		if (ata_legacy_acquire_port(host->ports[i]))
+		rc = ata_legacy_acquire_port(host->ports[i], &reason);
+		if (rc == -EBUSY)
 			host->ports[i]->ops = &ata_dummy_port_ops;
+		else if (rc)
+			goto err;
 	}
 
 	return 0;
+
+ err:
+	if (p_reason)
+		*p_reason = reason;
+	ata_legacy_release_resources(host);
+	return rc;
 }
 
 /**
@@ -122,9 +141,16 @@ int ata_legacy_acquire_resources(struct 
  */
 void ata_legacy_release_resources(struct ata_host *host)
 {
-	int i;
+	void __iomem *(*legacy_iomap)[2] = host->legacy_iomap;
+	int i, j;
 
 	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 2; j++)
+			if (legacy_iomap[i][j]) {
+				ioport_unmap(legacy_iomap[i][j]);
+				legacy_iomap[i][j] = NULL;
+			}
+
 		if (host->legacy_flags & (ATA_LEGACY_RES_PRI << i)) {
 			release_region(ata_legacy_addr(i, 0), 8);
 			host->legacy_flags &= ~(ATA_LEGACY_RES_PRI << i);
diff --git a/drivers/ata/libata-pci.c b/drivers/ata/libata-pci.c
index 7fee3c0..18a1952 100644
--- a/drivers/ata/libata-pci.c
+++ b/drivers/ata/libata-pci.c
@@ -133,6 +133,7 @@ int ata_pci_set_dma_mask(struct pci_dev 
  *	ata_pci_acquire_resources - acquire default PCI resources
  *	@host: target ATA host to acquire PCI resources for
  *	@dma_mask: DMA mask
+ *	@bar_mask: mask of PCI bars to iomap
  *	@p_reason: out arg for error message (can be NULL)
  *
  *	Acquire default ATA PCI resources.
@@ -144,11 +145,12 @@ int ata_pci_set_dma_mask(struct pci_dev 
  *	0 on success, -errno otherwise.
  */
 int ata_pci_acquire_resources(struct ata_host *host, u64 dma_mask,
-			      const char **p_reason)
+			      unsigned int bar_mask, const char **p_reason)
 {
 	struct pci_dev *pdev = to_pci_dev(host->dev);
+	void __iomem **iomap = host->iomap;
 	const char *reason;
-	int rc;
+	int i, rc;
 
 	/* acquire generic resources */
 
@@ -181,6 +183,28 @@ int ata_pci_acquire_resources(struct ata
 	if (rc)
 		goto err;
 
+	/* iomap PCI BARs */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		if (!(bar_mask & (1 << i)))
+			continue;
+
+		WARN_ON(iomap[i]);
+
+		if (!pci_resource_start(pdev, i) ||
+		    !pci_resource_len(pdev, i)) {
+			reason = "iomap requested for null PCI BAR";
+			rc = -EIO;
+			goto err;
+		}
+
+		iomap[i] = pci_iomap(pdev, i, 0);
+		if (!iomap[i]) {
+			rc = -ENOMEM;
+			reason = "failed to iomap PCI BAR";
+			goto err;
+		}
+	}
+
 	return 0;
 
  err:
@@ -202,6 +226,14 @@ int ata_pci_acquire_resources(struct ata
 void ata_pci_release_resources(struct ata_host *host)
 {
 	struct pci_dev *pdev = to_pci_dev(host->dev);
+	void __iomem **iomap = host->iomap;
+	int i;
+
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+		if (iomap[i]) {
+			pci_iounmap(pdev, iomap[i]);
+			iomap[i] = NULL;
+		}
 
 	if (host->pci_flags & ATA_PCI_RES_GEN) {
 		pci_release_regions(pdev);
@@ -470,7 +502,7 @@ int ata_pci_host_prepare(struct pci_dev 
 	/* acquire PCI and legacy resources and init host accordingly */
 	host->legacy_flags |= legacy_mask & ATA_LEGACY_MASK;
 
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index f21e0db..7f0c104 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -629,7 +629,7 @@ static int adma_ata_init_one(struct pci_
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, DMA_32BIT_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, DMA_32BIT_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 865cfd8..ea09e7e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2327,7 +2327,7 @@ static int mv_init_one(struct pci_dev *p
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, DMA_64BIT_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, DMA_64BIT_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 00894a0..f9b3602 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -507,7 +507,7 @@ static int nv_init_one (struct pci_dev *
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 6e33abb..e384d80 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -713,7 +713,7 @@ static int pdc_ata_init_one(struct pci_d
 	hp = host->private_data;
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 420eb58..dc8d88c 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -617,7 +617,7 @@ static int qs_ata_init_one(struct pci_de
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, 0, &reason);
+	rc = ata_pci_acquire_resources(host, 0, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 9cabbb5..dec3c91 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -626,7 +626,7 @@ static int sil_init_one (struct pci_dev 
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 9f1ad0f..269dee0 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1069,7 +1069,7 @@ static int sil24_init_one(struct pci_dev
 	hpriv = host->private_data;
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, DMA_64BIT_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, DMA_64BIT_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index a696693..0869501 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev 
 	}
 
 	/* acquire generic ATA PCI resources and init PCI host */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index d51e860..e16d1c7 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -394,7 +394,7 @@ static int k2_sata_init_one (struct pci_
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 4a235ab..3a0257d 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -1376,7 +1376,7 @@ static int pdc_sata_init_one(struct pci_
 	hpriv = host->private_data;
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 5ffdc2b..3a9723e 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -204,7 +204,7 @@ static int uli_init_one(struct pci_dev *
 	hpriv = host->private_data;
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index f0bc20e..2a7513d 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -262,7 +262,7 @@ static int svia_init_one(struct pci_dev 
 	}
 
 	/* acquire generic ATA PCI resources */
-	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, ATA_DMA_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 71ea8d9..153403f 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -368,7 +368,7 @@ static int __devinit vsc_sata_init_one (
 	/* Acquire generic ATA PCI resources.  Use 32 bit DMA mask,
 	 * because 64 bit address support is poor.
 	 */
-	rc = ata_pci_acquire_resources(host, DMA_32BIT_MASK, &reason);
+	rc = ata_pci_acquire_resources(host, DMA_32BIT_MASK, 0, &reason);
 	if (rc)
 		goto err;
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index f72cc73..ed02ae9 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -407,6 +407,9 @@ struct ata_host {
 	unsigned int		legacy_flags;
 	unsigned int		pci_flags;
 
+	void __iomem		*legacy_iomap[2][2];
+	void __iomem		*iomap[DEVICE_COUNT_RESOURCE];
+
 	struct list_head	irq_list;	/* list of acquired irqs */
 	struct ata_port		*ports[0];
 };
@@ -714,6 +717,7 @@ extern unsigned int ata_pci_legacy_mask(
 extern int ata_pci_set_dma_mask(struct pci_dev *pdev, u64 dma_mask,
 				const char **p_reason);
 extern int ata_pci_acquire_resources(struct ata_host *host, u64 dma_mask,
+				     unsigned int bar_mask,
 				     const char **p_reason);
 extern void ata_pci_release_resources(struct ata_host *host);
 extern void ata_pci_init_ports(struct ata_host *host);
-- 
1.4.1.1


-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux