Fix 64 bit DMA mapping problem with PCI cards on SN2
PATCH 1/1 Fix 64 bit DMA mapping problem with PCI cards on SN2
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 [email protected] 1.1585
# pci_dma.c:
# Add 64 bit direct translations back in for PCI devices.
# --------------------------------------------
#
arch/ia64/sn/io/machvec/pci_dma.c +33 -39
@@ -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
David, it looks like we accidentally dropped a hunk in the DMA mapping code. Can you please push this patch to Linus soon?
Thanks,
Jesse
Quoted 5 lines · Jeremy Higdon
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.