io.h
来自「linux 内核源代码」· C头文件 代码 · 共 749 行 · 第 1/2 页
H
749 行
#define __do_writeb(val, addr) out_8(PCI_FIX_ADDR(addr), val)#define __do_writew(val, addr) out_le16(PCI_FIX_ADDR(addr), val)#define __do_writel(val, addr) out_le32(PCI_FIX_ADDR(addr), val)#define __do_writeq(val, addr) out_le64(PCI_FIX_ADDR(addr), val)#define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val)#define __do_writel_be(val, addr) out_be32(PCI_FIX_ADDR(addr), val)#define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val)#ifdef CONFIG_EEH#define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr))#define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr))#define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr))#define __do_readq(addr) eeh_readq(PCI_FIX_ADDR(addr))#define __do_readw_be(addr) eeh_readw_be(PCI_FIX_ADDR(addr))#define __do_readl_be(addr) eeh_readl_be(PCI_FIX_ADDR(addr))#define __do_readq_be(addr) eeh_readq_be(PCI_FIX_ADDR(addr))#else /* CONFIG_EEH */#define __do_readb(addr) in_8(PCI_FIX_ADDR(addr))#define __do_readw(addr) in_le16(PCI_FIX_ADDR(addr))#define __do_readl(addr) in_le32(PCI_FIX_ADDR(addr))#define __do_readq(addr) in_le64(PCI_FIX_ADDR(addr))#define __do_readw_be(addr) in_be16(PCI_FIX_ADDR(addr))#define __do_readl_be(addr) in_be32(PCI_FIX_ADDR(addr))#define __do_readq_be(addr) in_be64(PCI_FIX_ADDR(addr))#endif /* !defined(CONFIG_EEH) */#ifdef CONFIG_PPC32#define __do_outb(val, port) _rec_outb(val, port)#define __do_outw(val, port) _rec_outw(val, port)#define __do_outl(val, port) _rec_outl(val, port)#define __do_inb(port) _rec_inb(port)#define __do_inw(port) _rec_inw(port)#define __do_inl(port) _rec_inl(port)#else /* CONFIG_PPC32 */#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port);#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port);#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port);#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port);#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port);#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port);#endif /* !CONFIG_PPC32 */#ifdef CONFIG_EEH#define __do_readsb(a, b, n) eeh_readsb(PCI_FIX_ADDR(a), (b), (n))#define __do_readsw(a, b, n) eeh_readsw(PCI_FIX_ADDR(a), (b), (n))#define __do_readsl(a, b, n) eeh_readsl(PCI_FIX_ADDR(a), (b), (n))#else /* CONFIG_EEH */#define __do_readsb(a, b, n) _insb(PCI_FIX_ADDR(a), (b), (n))#define __do_readsw(a, b, n) _insw(PCI_FIX_ADDR(a), (b), (n))#define __do_readsl(a, b, n) _insl(PCI_FIX_ADDR(a), (b), (n))#endif /* !CONFIG_EEH */#define __do_writesb(a, b, n) _outsb(PCI_FIX_ADDR(a),(b),(n))#define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))#define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))#define __do_memset_io(addr, c, n) \ _memset_io(PCI_FIX_ADDR(addr), c, n)#define __do_memcpy_toio(dst, src, n) \ _memcpy_toio(PCI_FIX_ADDR(dst), src, n)#ifdef CONFIG_EEH#define __do_memcpy_fromio(dst, src, n) \ eeh_memcpy_fromio(dst, PCI_FIX_ADDR(src), n)#else /* CONFIG_EEH */#define __do_memcpy_fromio(dst, src, n) \ _memcpy_fromio(dst,PCI_FIX_ADDR(src),n)#endif /* !CONFIG_EEH */#ifdef CONFIG_PPC_INDIRECT_IO#define DEF_PCI_HOOK(x) x#else#define DEF_PCI_HOOK(x) NULL#endif/* Structure containing all the hooks */extern struct ppc_pci_io {#define DEF_PCI_AC_RET(name, ret, at, al) ret (*name) at;#define DEF_PCI_AC_NORET(name, at, al) void (*name) at;#include <asm/io-defs.h>#undef DEF_PCI_AC_RET#undef DEF_PCI_AC_NORET} ppc_pci_io;/* The inline wrappers */#define DEF_PCI_AC_RET(name, ret, at, al) \static inline ret name at \{ \ if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \ return ppc_pci_io.name al; \ return __do_##name al; \}#define DEF_PCI_AC_NORET(name, at, al) \static inline void name at \{ \ if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \ ppc_pci_io.name al; \ else \ __do_##name al; \}#include <asm/io-defs.h>#undef DEF_PCI_AC_RET#undef DEF_PCI_AC_NORET/* Some drivers check for the presence of readq & writeq with * a #ifdef, so we make them happy here. */#ifdef __powerpc64__#define readq readq#define writeq writeq#endif/* * Convert a physical pointer to a virtual kernel pointer for /dev/mem * access */#define xlate_dev_mem_ptr(p) __va(p)/* * Convert a virtual cached pointer to an uncached pointer */#define xlate_dev_kmem_ptr(p) p/* * We don't do relaxed operations yet, at least not with this semantic */#define readb_relaxed(addr) readb(addr)#define readw_relaxed(addr) readw(addr)#define readl_relaxed(addr) readl(addr)#define readq_relaxed(addr) readq(addr)#ifdef CONFIG_PPC32#define mmiowb()#else/* * Enforce synchronisation of stores vs. spin_unlock * (this does it explicitly, though our implementation of spin_unlock * does it implicitely too) */static inline void mmiowb(void){ unsigned long tmp; __asm__ __volatile__("sync; li %0,0; stb %0,%1(13)" : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync)) : "memory");}#endif /* !CONFIG_PPC32 */static inline void iosync(void){ __asm__ __volatile__ ("sync" : : : "memory");}/* Enforce in-order execution of data I/O. * No distinction between read/write on PPC; use eieio for all three. * Those are fairly week though. They don't provide a barrier between * MMIO and cacheable storage nor do they provide a barrier vs. locks, * they only provide barriers between 2 __raw MMIO operations and * possibly break write combining. */#define iobarrier_rw() eieio()#define iobarrier_r() eieio()#define iobarrier_w() eieio()/* * output pause versions need a delay at least for the * w83c105 ide controller in a p610. */#define inb_p(port) inb(port)#define outb_p(val, port) (udelay(1), outb((val), (port)))#define inw_p(port) inw(port)#define outw_p(val, port) (udelay(1), outw((val), (port)))#define inl_p(port) inl(port)#define outl_p(val, port) (udelay(1), outl((val), (port)))#define IO_SPACE_LIMIT ~(0UL)/** * ioremap - map bus memory into CPU space * @address: bus address of the memory * @size: size of the resource to map * * ioremap performs a platform specific sequence of operations to * make bus memory CPU accessible via the readb/readw/readl/writeb/ * writew/writel functions and the other mmio helpers. The returned * address is not guaranteed to be usable directly as a virtual * address. * * We provide a few variations of it: * * * ioremap is the standard one and provides non-cacheable guarded mappings * and can be hooked by the platform via ppc_md * * * ioremap_flags allows to specify the page flags as an argument and can * also be hooked by the platform via ppc_md * * * ioremap_nocache is identical to ioremap * * * iounmap undoes such a mapping and can be hooked * * * __ioremap_at (and the pending __iounmap_at) are low level functions to * create hand-made mappings for use only by the PCI code and cannot * currently be hooked. Must be page aligned. * * * __ioremap is the low level implementation used by ioremap and * ioremap_flags and cannot be hooked (but can be used by a hook on one * of the previous ones) * * * __iounmap, is the low level implementation used by iounmap and cannot * be hooked (but can be used by a hook on iounmap) * */extern void __iomem *ioremap(phys_addr_t address, unsigned long size);extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size, unsigned long flags);#define ioremap_nocache(addr, size) ioremap((addr), (size))extern void iounmap(volatile void __iomem *addr);extern void __iomem *__ioremap(phys_addr_t, unsigned long size, unsigned long flags);extern void __iounmap(volatile void __iomem *addr);extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea, unsigned long size, unsigned long flags);extern void __iounmap_at(void *ea, unsigned long size);/* * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation * which needs some additional definitions here. They basically allow PIO * space overall to be 1GB. This will work as long as we never try to use * iomap to map MMIO below 1GB which should be fine on ppc64 */#define HAVE_ARCH_PIO_SIZE 1#define PIO_OFFSET 0x00000000UL#define PIO_MASK (FULL_IO_SIZE - 1)#define PIO_RESERVED (FULL_IO_SIZE)#define mmio_read16be(addr) readw_be(addr)#define mmio_read32be(addr) readl_be(addr)#define mmio_write16be(val, addr) writew_be(val, addr)#define mmio_write32be(val, addr) writel_be(val, addr)#define mmio_insb(addr, dst, count) readsb(addr, dst, count)#define mmio_insw(addr, dst, count) readsw(addr, dst, count)#define mmio_insl(addr, dst, count) readsl(addr, dst, count)#define mmio_outsb(addr, src, count) writesb(addr, src, count)#define mmio_outsw(addr, src, count) writesw(addr, src, count)#define mmio_outsl(addr, src, count) writesl(addr, src, count)/** * virt_to_phys - map virtual addresses to physical * @address: address to remap * * The returned physical address is the physical (CPU) mapping for * the memory address given. It is only valid to use this function on * addresses directly mapped or allocated via kmalloc. * * This function does not give bus mappings for DMA transfers. In * almost all conceivable cases a device driver should not be using * this function */static inline unsigned long virt_to_phys(volatile void * address){ return __pa((unsigned long)address);}/** * phys_to_virt - map physical address to virtual * @address: address to remap * * The returned virtual address is a current CPU mapping for * the memory address given. It is only valid to use this function on * addresses that have a kernel mapping * * This function does not handle bus mappings for DMA transfers. In * almost all conceivable cases a device driver should not be using * this function */static inline void * phys_to_virt(unsigned long address){ return (void *)__va(address);}/* * Change "struct page" to physical address. */#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)/* We do NOT want virtual merging, it would put too much pressure on * our iommu allocator. Instead, we want drivers to be smart enough * to coalesce sglists that happen to have been mapped in a contiguous * way by the iommu */#define BIO_VMERGE_BOUNDARY 0/* * 32 bits still uses virt_to_bus() for it's implementation of DMA * mappings se we have to keep it defined here. We also have some old * drivers (shame shame shame) that use bus_to_virt() and haven't been * fixed yet so I need to define it here. */#ifdef CONFIG_PPC32static inline unsigned long virt_to_bus(volatile void * address){ if (address == NULL) return 0; return __pa(address) + PCI_DRAM_OFFSET;}static inline void * bus_to_virt(unsigned long address){ if (address == 0) return NULL; return __va(address - PCI_DRAM_OFFSET);}#define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET)#endif /* CONFIG_PPC32 *//* access ports */#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v))#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v))#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))#define setbits8(_addr, _v) out_8((_addr), in_8(_addr) | (_v))#define clrbits8(_addr, _v) out_8((_addr), in_8(_addr) & ~(_v))/* Clear and set bits in one shot. These macros can be used to clear and * set multiple bits in a register using a single read-modify-write. These * macros can also be used to set a multiple-bit bit pattern using a mask, * by specifying the mask in the 'clear' parameter and the new bit pattern * in the 'set' parameter. */#define clrsetbits(type, addr, clear, set) \ out_##type((addr), (in_##type(addr) & ~(clear)) | (set))#ifdef __powerpc64__#define clrsetbits_be64(addr, clear, set) clrsetbits(be64, addr, clear, set)#define clrsetbits_le64(addr, clear, set) clrsetbits(le64, addr, clear, set)#endif#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)#define clrsetbits_le16(addr, clear, set) clrsetbits(le32, addr, clear, set)#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)#endif /* __KERNEL__ */#endif /* _ASM_POWERPC_IO_H */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?