| /* | |
| * This file is subject to the terms and conditions of the GNU General Public | |
| * License. See the file "COPYING" in the main directory of this archive | |
| * for more details. | |
| * | |
| * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. | |
| */ | |
| #ifndef _ASM_SN_IO_H | |
| #define _ASM_SN_IO_H | |
| #include <linux/compiler.h> | |
| #include <asm/intrinsics.h> | |
| extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */ | |
| extern void __sn_mmiowb(void); /* Forward definition */ | |
| extern int num_cnodes; | |
| #define __sn_mf_a() ia64_mfa() | |
| extern void sn_dma_flush(unsigned long); | |
| #define __sn_inb ___sn_inb | |
| #define __sn_inw ___sn_inw | |
| #define __sn_inl ___sn_inl | |
| #define __sn_outb ___sn_outb | |
| #define __sn_outw ___sn_outw | |
| #define __sn_outl ___sn_outl | |
| #define __sn_readb ___sn_readb | |
| #define __sn_readw ___sn_readw | |
| #define __sn_readl ___sn_readl | |
| #define __sn_readq ___sn_readq | |
| #define __sn_readb_relaxed ___sn_readb_relaxed | |
| #define __sn_readw_relaxed ___sn_readw_relaxed | |
| #define __sn_readl_relaxed ___sn_readl_relaxed | |
| #define __sn_readq_relaxed ___sn_readq_relaxed | |
| /* | |
| * Convenience macros for setting/clearing bits using the above accessors | |
| */ | |
| #define __sn_setq_relaxed(addr, val) \ | |
| writeq((__sn_readq_relaxed(addr) | (val)), (addr)) | |
| #define __sn_clrq_relaxed(addr, val) \ | |
| writeq((__sn_readq_relaxed(addr) & ~(val)), (addr)) | |
| /* | |
| * The following routines are SN Platform specific, called when | |
| * a reference is made to inX/outX set macros. SN Platform | |
| * inX set of macros ensures that Posted DMA writes on the | |
| * Bridge is flushed. | |
| * | |
| * The routines should be self explainatory. | |
| */ | |
| static inline unsigned int | |
| ___sn_inb (unsigned long port) | |
| { | |
| volatile unsigned char *addr; | |
| unsigned char ret = -1; | |
| if ((addr = sn_io_addr(port))) { | |
| ret = *addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| } | |
| return ret; | |
| } | |
| static inline unsigned int | |
| ___sn_inw (unsigned long port) | |
| { | |
| volatile unsigned short *addr; | |
| unsigned short ret = -1; | |
| if ((addr = sn_io_addr(port))) { | |
| ret = *addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| } | |
| return ret; | |
| } | |
| static inline unsigned int | |
| ___sn_inl (unsigned long port) | |
| { | |
| volatile unsigned int *addr; | |
| unsigned int ret = -1; | |
| if ((addr = sn_io_addr(port))) { | |
| ret = *addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| } | |
| return ret; | |
| } | |
| static inline void | |
| ___sn_outb (unsigned char val, unsigned long port) | |
| { | |
| volatile unsigned char *addr; | |
| if ((addr = sn_io_addr(port))) { | |
| *addr = val; | |
| __sn_mmiowb(); | |
| } | |
| } | |
| static inline void | |
| ___sn_outw (unsigned short val, unsigned long port) | |
| { | |
| volatile unsigned short *addr; | |
| if ((addr = sn_io_addr(port))) { | |
| *addr = val; | |
| __sn_mmiowb(); | |
| } | |
| } | |
| static inline void | |
| ___sn_outl (unsigned int val, unsigned long port) | |
| { | |
| volatile unsigned int *addr; | |
| if ((addr = sn_io_addr(port))) { | |
| *addr = val; | |
| __sn_mmiowb(); | |
| } | |
| } | |
| /* | |
| * The following routines are SN Platform specific, called when | |
| * a reference is made to readX/writeX set macros. SN Platform | |
| * readX set of macros ensures that Posted DMA writes on the | |
| * Bridge is flushed. | |
| * | |
| * The routines should be self explainatory. | |
| */ | |
| static inline unsigned char | |
| ___sn_readb (const volatile void __iomem *addr) | |
| { | |
| unsigned char val; | |
| val = *(volatile unsigned char __force *)addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| return val; | |
| } | |
| static inline unsigned short | |
| ___sn_readw (const volatile void __iomem *addr) | |
| { | |
| unsigned short val; | |
| val = *(volatile unsigned short __force *)addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| return val; | |
| } | |
| static inline unsigned int | |
| ___sn_readl (const volatile void __iomem *addr) | |
| { | |
| unsigned int val; | |
| val = *(volatile unsigned int __force *)addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| return val; | |
| } | |
| static inline unsigned long | |
| ___sn_readq (const volatile void __iomem *addr) | |
| { | |
| unsigned long val; | |
| val = *(volatile unsigned long __force *)addr; | |
| __sn_mf_a(); | |
| sn_dma_flush((unsigned long)addr); | |
| return val; | |
| } | |
| /* | |
| * For generic and SN2 kernels, we have a set of fast access | |
| * PIO macros. These macros are provided on SN Platform | |
| * because the normal inX and readX macros perform an | |
| * additional task of flushing Post DMA request on the Bridge. | |
| * | |
| * These routines should be self explainatory. | |
| */ | |
| static inline unsigned int | |
| sn_inb_fast (unsigned long port) | |
| { | |
| volatile unsigned char *addr = (unsigned char *)port; | |
| unsigned char ret; | |
| ret = *addr; | |
| __sn_mf_a(); | |
| return ret; | |
| } | |
| static inline unsigned int | |
| sn_inw_fast (unsigned long port) | |
| { | |
| volatile unsigned short *addr = (unsigned short *)port; | |
| unsigned short ret; | |
| ret = *addr; | |
| __sn_mf_a(); | |
| return ret; | |
| } | |
| static inline unsigned int | |
| sn_inl_fast (unsigned long port) | |
| { | |
| volatile unsigned int *addr = (unsigned int *)port; | |
| unsigned int ret; | |
| ret = *addr; | |
| __sn_mf_a(); | |
| return ret; | |
| } | |
| static inline unsigned char | |
| ___sn_readb_relaxed (const volatile void __iomem *addr) | |
| { | |
| return *(volatile unsigned char __force *)addr; | |
| } | |
| static inline unsigned short | |
| ___sn_readw_relaxed (const volatile void __iomem *addr) | |
| { | |
| return *(volatile unsigned short __force *)addr; | |
| } | |
| static inline unsigned int | |
| ___sn_readl_relaxed (const volatile void __iomem *addr) | |
| { | |
| return *(volatile unsigned int __force *) addr; | |
| } | |
| static inline unsigned long | |
| ___sn_readq_relaxed (const volatile void __iomem *addr) | |
| { | |
| return *(volatile unsigned long __force *) addr; | |
| } | |
| struct pci_dev; | |
| static inline int | |
| sn_pci_set_vchan(struct pci_dev *pci_dev, unsigned long *addr, int vchan) | |
| { | |
| if (vchan > 1) { | |
| return -1; | |
| } | |
| if (!(*addr >> 32)) /* Using a mask here would be cleaner */ | |
| return 0; /* but this generates better code */ | |
| if (vchan == 1) { | |
| /* Set Bit 57 */ | |
| *addr |= (1UL << 57); | |
| } else { | |
| /* Clear Bit 57 */ | |
| *addr &= ~(1UL << 57); | |
| } | |
| return 0; | |
| } | |
| #endif /* _ASM_SN_IO_H */ |