|  | /* | 
|  | * 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 */ |