public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Higdon <jeremy@sgi.com>
To: linux-ia64@vger.kernel.org
Subject: [PATCH] Fix 64 bit DMA mapping problem with PCI cards on SN2
Date: Sat, 21 Feb 2004 01:08:41 +0000	[thread overview]
Message-ID: <20040221010841.GC530871@sgi.com> (raw)

PCI cards were forced to 32 bit addresses.  There is significant
extra overhead to DMA setup with 32 bit, and it is fairly easy to
run out of mapping resources.

This patch reenables 64 bit DMA mapping for PCI cards.

thanks

jeremy

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1584  -> 1.1585 
#	arch/ia64/sn/io/machvec/pci_dma.c	1.25    -> 1.26   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 04/02/20	jeremy@tomahawk.engr.sgi.com	1.1585
# pci_dma.c:
#   Add 64 bit direct translations back in for PCI devices.
# --------------------------------------------
#
diff -Nru a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c
--- a/arch/ia64/sn/io/machvec/pci_dma.c	Fri Feb 20 16:35:57 2004
+++ b/arch/ia64/sn/io/machvec/pci_dma.c	Fri Feb 20 16:35:57 2004
@@ -225,13 +225,13 @@
 int
 sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
-
 	int i;
 	vertex_hdl_t vhdl;
 	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pcibr_dmamap_t dma_map;
 	struct scatterlist *saved_sg = sg;
+	unsigned dma_flag;
 
 	/* can't go anywhere w/o a direction in life */
 	if (direction = PCI_DMA_NONE)
@@ -244,33 +244,32 @@
 	vhdl = device_sysdata->vhdl;
 
 	/*
+	 * 64 bit DMA mask can use direct translations
+	 * PCI only
+	 *   32 bit DMA mask might be able to use direct, otherwise use dma map
+	 * PCI-X
+	 *   only 64 bit DMA mask supported; both direct and dma map will fail
+	 */
+	if (hwdev->dma_mask = ~0UL)
+		dma_flag = PCIIO_DMA_DATA | PCIIO_DMA_A64;
+	else
+		dma_flag = PCIIO_DMA_DATA;
+
+	/*
 	 * Setup a DMA address for each entry in the
 	 * scatterlist.
 	 */
 	for (i = 0; i < nents; i++, sg++) {
 		phys_addr = __pa((unsigned long)page_address(sg->page) + sg->offset);
-
-		/*
-		 * Handle 32-63 bit cards via direct mapping
-		 */
-		if (IS_PCI32G(hwdev)) {
-			sg->dma_address = pcibr_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length, PCIIO_DMA_DATA);
+		sg->dma_address = pcibr_dmatrans_addr(vhdl, NULL, phys_addr,
+					       sg->length, dma_flag);
+		if (sg->dma_address) {
 			sg->dma_length = sg->length;
-			/*
-			 * See if we got a direct map entry
-			 */
-			if (sg->dma_address) {
-				continue;
-			}
-
+			continue;
 		}
 
-		/*
-		 * It is a 32 bit card and we cannot do direct mapping,
-		 * so we use an ATE.
-		 */
-		dma_map = pcibr_dmamap_alloc(vhdl, NULL, sg->length, PCIIO_DMA_DATA);
+		dma_map = pcibr_dmamap_alloc(vhdl, NULL, sg->length,
+			PCIIO_DMA_DATA|MINIMAL_ATE_FLAG(phys_addr, sg->length));
 		if (!dma_map) {
 			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
 			       "anymore 32 bit page map entries.\n");
@@ -356,38 +355,33 @@
 	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pcibr_dmamap_t dma_map = NULL;
+	unsigned dma_flag;
 
 	if (direction = PCI_DMA_NONE)
 		BUG();
 
-	/* SN cannot support DMA addresses smaller than 32 bits. */
-	if (IS_PCI32L(hwdev))
-		return 0;
-
 	/*
 	 * find vertex for the device
 	 */
 	device_sysdata = SN_DEVICE_SYSDATA(hwdev);
 	vhdl = device_sysdata->vhdl;
 
-	/*
-	 * Call our dmamap interface
-	 */
-	dma_addr = 0;
 	phys_addr = __pa(ptr);
-
 	/*
-	 * Devices that support 32 bit to 63 bit DMA addresses get
-	 * 32 bit DMA addresses.
-	 *
-	 * First try to get a 32 bit direct map register.
+	 * 64 bit DMA mask can use direct translations
+	 * PCI only
+	 *   32 bit DMA mask might be able to use direct, otherwise use dma map
+	 * PCI-X
+	 *   only 64 bit DMA mask supported; both direct and dma map will fail
 	 */
-	if (IS_PCI32G(hwdev)) {
-		dma_addr = pcibr_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					       PCIIO_DMA_DATA);
-		if (dma_addr)
-			return dma_addr;
-	}
+	if (hwdev->dma_mask = ~0UL)
+		dma_flag = PCIIO_DMA_DATA | PCIIO_DMA_A64;
+	else
+		dma_flag = PCIIO_DMA_DATA;
+
+	dma_addr = pcibr_dmatrans_addr(vhdl, NULL, phys_addr, size, dma_flag);
+	if (dma_addr)
+		return dma_addr;
 
 	/*
 	 * It's a 32 bit card and we cannot do direct mapping so

             reply	other threads:[~2004-02-21  1:08 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-21  1:08 Jeremy Higdon [this message]
2004-02-21  4:42 ` [PATCH] Fix 64 bit DMA mapping problem with PCI cards on SN2 Jesse Barnes

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=20040221010841.GC530871@sgi.com \
    --to=jeremy@sgi.com \
    --cc=linux-ia64@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox