1/*
2 * linux/include/asm-m68k/raw_io.h
3 *
4 * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
5 *
6 */
7
8#ifndef _RAW_IO_H
9#define _RAW_IO_H
10
11#ifdef __KERNEL__
12
13
14/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
15 * two accesses to memory, which may be undesirable for some devices.
16 */
17#define in_8(addr) \
18    ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; })
19#define in_be16(addr) \
20    ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; })
21#define in_be32(addr) \
22    ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; })
23#define in_le16(addr) \
24    ({ unsigned short __v = le16_to_cpu(*(volatile unsigned short *) (addr)); __v; })
25#define in_le32(addr) \
26    ({ unsigned int __v = le32_to_cpu(*(volatile unsigned int *) (addr)); __v; })
27
28#define out_8(addr,b) (void)((*(volatile unsigned char *) (addr)) = (b))
29#define out_be16(addr,w) (void)((*(volatile unsigned short *) (addr)) = (w))
30#define out_be32(addr,l) (void)((*(volatile unsigned int *) (addr)) = (l))
31#define out_le16(addr,w) (void)((*(volatile unsigned short *) (addr)) = cpu_to_le16(w))
32#define out_le32(addr,l) (void)((*(volatile unsigned int *) (addr)) = cpu_to_le32(l))
33
34#define raw_inb in_8
35#define raw_inw in_be16
36#define raw_inl in_be32
37
38#define raw_outb(val,port) out_8((port),(val))
39#define raw_outw(val,port) out_be16((port),(val))
40#define raw_outl(val,port) out_be32((port),(val))
41
42#define raw_insb(port, buf, len) ({	   \
43	volatile unsigned char *_port = (volatile unsigned char *) (port);   \
44        unsigned char *_buf =(unsigned char *)(buf);	   \
45        unsigned int  _i,_len=(unsigned int)(len);	   \
46        for(_i=0; _i< _len; _i++)  \
47           *_buf++=in_8(_port);      \
48  })
49
50#define raw_outsb(port, buf, len) ({	   \
51	volatile unsigned char *_port = (volatile unsigned char *) (port);   \
52        unsigned char *_buf =(unsigned char *)(buf);	   \
53        unsigned int  _i,_len=(unsigned int)(len);	   \
54        for( _i=0; _i< _len; _i++)  \
55           out_8(_port,*_buf++);      \
56  })
57
58
59#define raw_insw(port, buf, nr) ({				\
60	volatile unsigned char *_port = (volatile unsigned char *) (port);	\
61	unsigned char *_buf = (unsigned char *)(buf);			\
62	unsigned int _nr = (unsigned int)(nr);					\
63	unsigned long _tmp;				\
64							\
65	if (_nr & 15) {					\
66		_tmp = (_nr & 15) - 1;			\
67		asm volatile (				\
68			"1: movew %2@,%0@+; dbra %1,1b"	\
69			: "=a" (_buf), "=d" (_tmp)	\
70			: "a" (_port), "0" (_buf),	\
71			  "1" (_tmp));			\
72	}						\
73	if (_nr >> 4) {					\
74		_tmp = (_nr >> 4) - 1;			\
75		asm volatile (				\
76			"1: "				\
77			"movew %2@,%0@+; "		\
78			"movew %2@,%0@+; "		\
79			"movew %2@,%0@+; "		\
80			"movew %2@,%0@+; "		\
81			"movew %2@,%0@+; "		\
82			"movew %2@,%0@+; "		\
83			"movew %2@,%0@+; "		\
84			"movew %2@,%0@+; "		\
85			"movew %2@,%0@+; "		\
86			"movew %2@,%0@+; "		\
87			"movew %2@,%0@+; "		\
88			"movew %2@,%0@+; "		\
89			"movew %2@,%0@+; "		\
90			"movew %2@,%0@+; "		\
91			"movew %2@,%0@+; "		\
92			"movew %2@,%0@+; "		\
93			"dbra %1,1b"			\
94			: "=a" (_buf), "=d" (_tmp)	\
95			: "a" (_port), "0" (_buf),	\
96			  "1" (_tmp));			\
97	}						\
98})
99
100#define raw_outsw(port, buf, nr) ({				\
101	volatile unsigned char *_port = (volatile unsigned char *) (port);	\
102	unsigned char *_buf = (unsigned char *)(buf);			\
103	unsigned int _nr = (unsigned int)(nr);					\
104	unsigned long _tmp;				\
105							\
106	if (_nr & 15) {					\
107		_tmp = (_nr & 15) - 1;			\
108		asm volatile (				\
109			"1: movew %0@+,%2@; dbra %1,1b"	\
110			: "=a" (_buf), "=d" (_tmp)	\
111			: "a" (_port), "0" (_buf),	\
112			  "1" (_tmp));			\
113	}						\
114	if (_nr >> 4) {					\
115		_tmp = (_nr >> 4) - 1;			\
116		asm volatile (				\
117			"1: "				\
118			"movew %0@+,%2@; "		\
119			"movew %0@+,%2@; "		\
120			"movew %0@+,%2@; "		\
121			"movew %0@+,%2@; "		\
122			"movew %0@+,%2@; "		\
123			"movew %0@+,%2@; "		\
124			"movew %0@+,%2@; "		\
125			"movew %0@+,%2@; "		\
126			"movew %0@+,%2@; "		\
127			"movew %0@+,%2@; "		\
128			"movew %0@+,%2@; "		\
129			"movew %0@+,%2@; "		\
130			"movew %0@+,%2@; "		\
131			"movew %0@+,%2@; "		\
132			"movew %0@+,%2@; "		\
133			"movew %0@+,%2@; "		\
134			"dbra %1,1b"	   		\
135			: "=a" (_buf), "=d" (_tmp)	\
136			: "a" (_port), "0" (_buf),	\
137			  "1" (_tmp));			\
138	}						\
139})
140
141
142#define raw_insw_swapw(port, buf, nr) \
143({  if ((nr) % 8) \
144	__asm__ __volatile__ \
145	       ("movel %0,%/a0; \
146		 movel %1,%/a1; \
147		 movel %2,%/d6; \
148		 subql #1,%/d6; \
149	       1:movew %/a0@,%/d0; \
150		 rolw  #8,%/d0; \
151		 movew %/d0,%/a1@+; \
152		 dbra %/d6,1b"  \
153		:               \
154		: "g" (port), "g" (buf), "g" (nr) \
155		: "d0", "a0", "a1", "d6"); \
156    else \
157	__asm__ __volatile__ \
158	       ("movel %0,%/a0; \
159		 movel %1,%/a1; \
160		 movel %2,%/d6; \
161		 lsrl  #3,%/d6; \
162		 subql #1,%/d6; \
163	       1:movew %/a0@,%/d0; \
164		 rolw  #8,%/d0; \
165		 movew %/d0,%/a1@+; \
166		 movew %/a0@,%/d0; \
167		 rolw  #8,%/d0; \
168		 movew %/d0,%/a1@+; \
169		 movew %/a0@,%/d0; \
170		 rolw  #8,%/d0; \
171		 movew %/d0,%/a1@+; \
172		 movew %/a0@,%/d0; \
173		 rolw  #8,%/d0; \
174		 movew %/d0,%/a1@+; \
175		 movew %/a0@,%/d0; \
176		 rolw  #8,%/d0; \
177		 movew %/d0,%/a1@+; \
178		 movew %/a0@,%/d0; \
179		 rolw  #8,%/d0; \
180		 movew %/d0,%/a1@+; \
181		 movew %/a0@,%/d0; \
182		 rolw  #8,%/d0; \
183		 movew %/d0,%/a1@+; \
184		 movew %/a0@,%/d0; \
185		 rolw  #8,%/d0; \
186		 movew %/d0,%/a1@+; \
187		 dbra %/d6,1b"  \
188                :               \
189		: "g" (port), "g" (buf), "g" (nr) \
190		: "d0", "a0", "a1", "d6"); \
191})
192
193
194#define raw_outsw_swapw(port, buf, nr) \
195({  if ((nr) % 8) \
196	__asm__ __volatile__ \
197	       ("movel %0,%/a0; \
198		 movel %1,%/a1; \
199		 movel %2,%/d6; \
200		 subql #1,%/d6; \
201	       1:movew %/a1@+,%/d0; \
202		 rolw  #8,%/d0; \
203		 movew %/d0,%/a0@; \
204		 dbra %/d6,1b"  \
205                :               \
206		: "g" (port), "g" (buf), "g" (nr) \
207		: "d0", "a0", "a1", "d6"); \
208    else \
209	__asm__ __volatile__ \
210	       ("movel %0,%/a0; \
211		 movel %1,%/a1; \
212		 movel %2,%/d6; \
213		 lsrl  #3,%/d6; \
214		 subql #1,%/d6; \
215	       1:movew %/a1@+,%/d0; \
216		 rolw  #8,%/d0; \
217		 movew %/d0,%/a0@; \
218		 movew %/a1@+,%/d0; \
219		 rolw  #8,%/d0; \
220		 movew %/d0,%/a0@; \
221		 movew %/a1@+,%/d0; \
222		 rolw  #8,%/d0; \
223		 movew %/d0,%/a0@; \
224		 movew %/a1@+,%/d0; \
225		 rolw  #8,%/d0; \
226		 movew %/d0,%/a0@; \
227		 movew %/a1@+,%/d0; \
228		 rolw  #8,%/d0; \
229		 movew %/d0,%/a0@; \
230		 movew %/a1@+,%/d0; \
231		 rolw  #8,%/d0; \
232		 movew %/d0,%/a0@; \
233		 movew %/a1@+,%/d0; \
234		 rolw  #8,%/d0; \
235		 movew %/d0,%/a0@; \
236		 movew %/a1@+,%/d0; \
237		 rolw  #8,%/d0; \
238		 movew %/d0,%/a0@; \
239		 dbra %/d6,1b"  \
240                :               \
241		: "g" (port), "g" (buf), "g" (nr) \
242		: "d0", "a0", "a1", "d6"); \
243})
244
245
246#endif /* __KERNEL__ */
247
248#endif /* _RAW_IO_H */
249