--- zzzz-none-000/linux-2.4.17/include/asm-ppc/pci.h 2001-10-21 17:13:07.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/include/asm-ppc/pci.h 2004-11-24 13:21:50.000000000 +0000 @@ -1,10 +1,18 @@ /* - * BK Id: SCCS/s.pci.h 1.16 10/15/01 22:51:33 paulus + * BK Id: SCCS/s.pci.h 1.25 11/28/01 13:29:57 paulus */ #ifndef __PPC_PCI_H #define __PPC_PCI_H #ifdef __KERNEL__ +#include +#include +#include +#include +#include + +struct pci_dev; + /* Values for the `which' argument to sys_pciconfig_iobase syscall. */ #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 @@ -12,8 +20,13 @@ #define IOBASE_ISA_IO 3 #define IOBASE_ISA_MEM 4 +/* + * Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers + */ +extern int pci_assign_all_busses; -extern int pcibios_assign_all_busses(void); +#define pcibios_assign_all_busses() (pci_assign_all_busses) #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 @@ -40,22 +53,18 @@ extern unsigned long phys_to_bus(unsigned long pa); extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr); extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); + -/* Dynamic DMA Mapping stuff, stolen from i386 - * ++ajoshi +/* + * Dynamic DMA Mapping stuff + * Originally stolen from i386 by ajoshi and updated by paulus + * Non-consistent cache support by Dan Malek */ -#include -#include -#include -#include -#include - -struct pci_dev; - /* The PCI address space does equal the physical memory * address space. The networking and block device layers use * this boolean for bounce buffer decisions. + * XXX is this correct if CONFIG_NOT_COHERENT_CACHE? -- paulus */ #define PCI_DMA_BUS_IS_PHYS (1) @@ -91,6 +100,7 @@ { if (direction == PCI_DMA_NONE) BUG(); + consistent_sync(ptr, size, direction); return virt_to_bus(ptr); } @@ -102,16 +112,17 @@ /* nothing to do */ } - /* * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical * to pci_map_single, but takes a struct page instead of a virtual address */ static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, - unsigned long offset, size_t size, int direction) + unsigned long offset, size_t size, + int direction) { if (direction == PCI_DMA_NONE) BUG(); + consistent_sync_page(page, offset, size, direction); return (page - mem_map) * PAGE_SIZE + PCI_DRAM_OFFSET + offset; } @@ -127,7 +138,8 @@ * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). + * and length. They are obtained via sg_dma_{address,len}(SG), + * defined in . * * NOTE: An implementation may be able to use a smaller number of * DMA address/length pairs than there are SG table elements. @@ -155,10 +167,15 @@ else if (!sg[i].address && !sg[i].page) BUG(); - if (sg[i].address) + if (sg[i].address) { + consistent_sync(sg[i].address, sg[i].length, direction); sg[i].dma_address = virt_to_bus(sg[i].address); - else + } else { + consistent_sync_page(sg[i].page, sg[i].offset, + sg[i].length, direction); sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; + } + sg[i].dma_length = sg[i].length; } return nents; @@ -191,7 +208,20 @@ { if (direction == PCI_DMA_NONE) BUG(); - /* nothing to do */ +#ifdef CONFIG_NOT_COHERENT_CACHE + /* The bus_to_virt() can't be used here, in case dma_handle + * points to something that doesn't have the same cache attributes + * as the 1:1 mapped kernel memory. If we used it, we could + * get a cache line alias with the wrong attributes. + * Since there isn't any Linux way to get the real VA from a PA, + * it is just easier to flush the whole cache. The code to + * determine VA from PA would probably do the same :-). + * I don't know why these functions don't pass VA, since the + * cache operations use VA and the caller has this information. + * -- Dan + */ + flush_dcache_all(); +#endif } /* Make physical memory consistent for a set of streaming @@ -204,9 +234,13 @@ struct scatterlist *sg, int nelems, int direction) { + int i; + if (direction == PCI_DMA_NONE) BUG(); - /* nothing to do */ + + for (i = 0; i < nelems; i++, sg++) + consistent_sync(sg->address, sg->length, direction); } /* Return whether the given PCI device DMA address mask can @@ -249,14 +283,6 @@ /* Nothing to do. */ } -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - /* Return the index of the PCI controller for device PDEV. */ extern int pci_controller_num(struct pci_dev *pdev);