io.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
- /* $Id: io.c,v 1.4 1999/08/18 23:37:46 ralf Exp $
- *
- * 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.
- *
- * Low level I/O functions for SNI.
- */
- #include <linux/string.h>
- #include <linux/spinlock.h>
- #include <asm/addrspace.h>
- #include <asm/system.h>
- #include <asm/sni.h>
- /*
- * Urgs... We only can see a 16mb window of the 4gb EISA address space
- * at PCIMT_EISA_BASE. Maladia segmentitis ...
- *
- * To avoid locking and all the related headacke we implement this such
- * that accessing the bus address space nests, so we're treating this
- * correctly even for interrupts. This is going to suck seriously for
- * the SMP members of the RM family.
- *
- * Making things worse the PCIMT_CSMAPISA register resides on the X bus with
- * it's unbeatable 1.4 mb/s transfer rate.
- */
- static inline void eisa_map(unsigned long address)
- {
- unsigned char upper;
- upper = address >> 24;
- *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
- }
- #define save_eisa_map()
- (*(volatile unsigned char *)PCIMT_CSMAPISA)
- #define restore_eisa_map(val)
- do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0)
- static unsigned char sni_readb(unsigned long addr)
- {
- unsigned char res;
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- restore_eisa_map(save_map);
- return res;
- }
- static unsigned short sni_readw(unsigned long addr)
- {
- unsigned short res;
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- restore_eisa_map(save_map);
- return res;
- }
- static unsigned int sni_readl(unsigned long addr)
- {
- unsigned int res;
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
- restore_eisa_map(save_map);
- return res;
- }
- static void sni_writeb(unsigned char val, unsigned long addr)
- {
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- restore_eisa_map(save_map);
- }
- static void sni_writew(unsigned short val, unsigned long addr)
- {
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- restore_eisa_map(save_map);
- }
- static void sni_writel(unsigned int val, unsigned long addr)
- {
- unsigned int save_map;
- save_map = save_eisa_map();
- eisa_map(addr);
- addr &= 0xffffff;
- *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
- restore_eisa_map(save_map);
- }
- static void sni_memset_io(unsigned long addr, int val, unsigned long len)
- {
- unsigned long waddr;
- unsigned int save_map;
- save_map = save_eisa_map();
- waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
- while(len) {
- unsigned long fraglen;
- fraglen = (~addr + 1) & 0xffffff;
- fraglen = (fraglen < len) ? fraglen : len;
- eisa_map(addr);
- memset((char *)waddr, val, fraglen);
- addr += fraglen;
- waddr = waddr + fraglen - 0x1000000;
- len -= fraglen;
- }
- restore_eisa_map(save_map);
- }
- static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
- {
- unsigned long waddr;
- unsigned int save_map;
- save_map = save_eisa_map();
- waddr = PCIMT_EISA_BASE | (from & 0xffffff);
- while(len) {
- unsigned long fraglen;
- fraglen = (~from + 1) & 0xffffff;
- fraglen = (fraglen < len) ? fraglen : len;
- eisa_map(from);
- memcpy((void *)to, (void *)waddr, fraglen);
- to += fraglen;
- from += fraglen;
- waddr = waddr + fraglen - 0x1000000;
- len -= fraglen;
- }
- restore_eisa_map(save_map);
- }
- static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
- {
- unsigned long waddr;
- unsigned int save_map;
- save_map = save_eisa_map();
- waddr = PCIMT_EISA_BASE | (to & 0xffffff);
- while(len) {
- unsigned long fraglen;
- fraglen = (~to + 1) & 0xffffff;
- fraglen = (fraglen < len) ? fraglen : len;
- eisa_map(to);
- memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
- to += fraglen;
- from += fraglen;
- waddr = waddr + fraglen - 0x1000000;
- len -= fraglen;
- }
- restore_eisa_map(save_map);
- }