4 * Copyright (c) Matthew Wilcox 2001 for Hewlett-Packard
5 * Copyright (c) Randolph Chung 2001 <tausq@debian.org>
7 * IO accessing functions which shouldn't be inlined because they're too big
10 #include <linux/kernel.h>
11 #include <linux/module.h>
14 /* Copies a block of memory to a device in an efficient manner.
15 * Assumes the device can cope with 32-bit transfers. If it can't,
16 * don't use this function.
18 void __memcpy_toio(unsigned long dest, unsigned long src, int count)
20 if ((dest & 3) != (src & 3))
23 writeb(*(char *)src, dest++);
28 __raw_writel(*(u32 *)src, dest);
35 writeb(*(char *)src, dest++);
41 ** Copies a block of memory from a device in an efficient manner.
42 ** Assumes the device can cope with 32-bit transfers. If it can't,
43 ** don't use this function.
45 ** CR16 counts on C3000 reading 256 bytes from Symbios 896 RAM:
46 ** 27341/64 = 427 cyc per int
47 ** 61311/128 = 478 cyc per short
48 ** 122637/256 = 479 cyc per byte
49 ** Ergo bus latencies dominant (not transfer size).
50 ** Minimize total number of transfers at cost of CPU cycles.
51 ** TODO: only look at src alignment and adjust the stores to dest.
53 void __memcpy_fromio(unsigned long dest, unsigned long src, int count)
55 /* first compare alignment of src/dst */
56 if ( ((dest ^ src) & 1) || (count < 2) )
59 if ( ((dest ^ src) & 2) || (count < 4) )
62 /* Then check for misaligned start address */
64 *(u8 *)dest = readb(src);
68 if (count < 2) goto bytecopy;
72 *(u16 *)dest = __raw_readw(src);
79 *(u32 *)dest = __raw_readl(src);
87 *(u16 *)dest = __raw_readw(src);
95 *(char *)dest = readb(src);
101 /* Sets a block of memory on a device to a given value.
102 * Assumes the device can cope with 32-bit transfers. If it can't,
103 * don't use this function.
105 void __memset_io(unsigned long dest, char fill, int count)
107 u32 fill32 = (fill << 24) | (fill << 16) | (fill << 8) | fill;
109 writeb(fill, dest++);
113 __raw_writel(fill32, dest);
118 writeb(fill, dest++);
123 * Read COUNT 8-bit bytes from port PORT into memory starting at
126 void insb (unsigned long port, void *dst, unsigned long count)
128 while (((unsigned long)dst) & 0x3) {
132 *(unsigned char *) dst = inb(port);
133 ((unsigned char *) dst)++;
140 w |= inb(port) << 16;
143 *(unsigned int *) dst = w;
144 ((unsigned int *) dst)++;
149 *(unsigned char *) dst = inb(port);
150 ((unsigned char *) dst)++;
156 * Read COUNT 16-bit words from port PORT into memory starting at
157 * SRC. SRC must be at least short aligned. This is used by the
158 * IDE driver to read disk sectors. Performance is important, but
159 * the interfaces seems to be slow: just using the inlined version
160 * of the inw() breaks things.
162 void insw (unsigned long port, void *dst, unsigned long count)
164 unsigned int l = 0, l2;
169 switch (((unsigned long) dst) & 0x3)
171 case 0x00: /* Buffer 32-bit aligned */
175 l = cpu_to_le16(inw(port)) << 16;
176 l |= cpu_to_le16(inw(port));
177 *(unsigned int *) dst = l;
178 ((unsigned int *) dst)++;
181 *(unsigned short *) dst = cpu_to_le16(inw(port));
185 case 0x02: /* Buffer 16-bit aligned */
186 *(unsigned short *) dst = cpu_to_le16(inw(port));
187 ((unsigned short *) dst)++;
192 l = cpu_to_le16(inw(port)) << 16;
193 l |= cpu_to_le16(inw(port));
194 *(unsigned int *) dst = l;
195 ((unsigned int *) dst)++;
198 *(unsigned short *) dst = cpu_to_le16(inw(port));
202 case 0x01: /* Buffer 8-bit aligned */
204 /* I don't bother with 32bit transfers
205 * in this case, 16bit will have to do -- DE */
208 l = cpu_to_le16(inw(port));
209 *(unsigned char *) dst = l >> 8;
210 ((unsigned char *) dst)++;
213 l2 = cpu_to_le16(inw(port));
214 *(unsigned short *) dst = (l & 0xff) << 8 | (l2 >> 8);
215 ((unsigned short *) dst)++;
218 *(unsigned char *) dst = l & 0xff;
226 * Read COUNT 32-bit words from port PORT into memory starting at
227 * SRC. Now works with any alignment in SRC. Performance is important,
228 * but the interfaces seems to be slow: just using the inlined version
229 * of the inl() breaks things.
231 void insl (unsigned long port, void *dst, unsigned long count)
233 unsigned int l = 0, l2;
238 switch (((unsigned long) dst) & 0x3)
240 case 0x00: /* Buffer 32-bit aligned */
243 *(unsigned int *) dst = cpu_to_le32(inl(port));
244 ((unsigned int *) dst)++;
248 case 0x02: /* Buffer 16-bit aligned */
251 l = cpu_to_le32(inl(port));
252 *(unsigned short *) dst = l >> 16;
253 ((unsigned short *) dst)++;
257 l2 = cpu_to_le32(inl(port));
258 *(unsigned int *) dst = (l & 0xffff) << 16 | (l2 >> 16);
259 ((unsigned int *) dst)++;
262 *(unsigned short *) dst = l & 0xffff;
264 case 0x01: /* Buffer 8-bit aligned */
267 l = cpu_to_le32(inl(port));
268 *(unsigned char *) dst = l >> 24;
269 ((unsigned char *) dst)++;
270 *(unsigned short *) dst = (l >> 8) & 0xffff;
271 ((unsigned short *) dst)++;
274 l2 = cpu_to_le32(inl(port));
275 *(unsigned int *) dst = (l & 0xff) << 24 | (l2 >> 8);
276 ((unsigned int *) dst)++;
279 *(unsigned char *) dst = l & 0xff;
281 case 0x03: /* Buffer 8-bit aligned */
284 l = cpu_to_le32(inl(port));
285 *(unsigned char *) dst = l >> 24;
286 ((unsigned char *) dst)++;
289 l2 = cpu_to_le32(inl(port));
290 *(unsigned int *) dst = (l & 0xffffff) << 8 | l2 >> 24;
291 ((unsigned int *) dst)++;
294 *(unsigned short *) dst = (l >> 8) & 0xffff;
295 ((unsigned short *) dst)++;
296 *(unsigned char *) dst = l & 0xff;
303 * Like insb but in the opposite direction.
304 * Don't worry as much about doing aligned memory transfers:
305 * doing byte reads the "slow" way isn't nearly as slow as
306 * doing byte writes the slow way (no r-m-w cycle).
308 void outsb(unsigned long port, const void * src, unsigned long count)
312 outb(*(char *)src, port);
318 * Like insw but in the opposite direction. This is used by the IDE
319 * driver to write disk sectors. Performance is important, but the
320 * interfaces seems to be slow: just using the inlined version of the
321 * outw() breaks things.
323 void outsw (unsigned long port, const void *src, unsigned long count)
325 unsigned int l = 0, l2;
330 switch (((unsigned long) src) & 0x3)
332 case 0x00: /* Buffer 32-bit aligned */
335 l = *(unsigned int *) src;
336 ((unsigned int *) src)++;
337 outw(le16_to_cpu(l >> 16), port);
338 outw(le16_to_cpu(l & 0xffff), port);
341 outw(le16_to_cpu(*(unsigned short*)src), port);
345 case 0x02: /* Buffer 16-bit aligned */
347 outw(le16_to_cpu(*(unsigned short*)src), port);
348 ((unsigned short *) src)++;
353 l = *(unsigned int *) src;
354 ((unsigned int *) src)++;
355 outw(le16_to_cpu(l >> 16), port);
356 outw(le16_to_cpu(l & 0xffff), port);
359 outw(le16_to_cpu(*(unsigned short*)src), port);
363 case 0x01: /* Buffer 8-bit aligned */
364 /* I don't bother with 32bit transfers
365 * in this case, 16bit will have to do -- DE */
367 l = *(unsigned char *) src << 8;
368 ((unsigned char *) src)++;
373 l2 = *(unsigned short *) src;
374 ((unsigned short *) src)++;
375 outw(le16_to_cpu(l | l2 >> 8), port);
378 l2 = *(unsigned char *) src;
379 outw (le16_to_cpu(l | l2>>8), port);
387 * Like insl but in the opposite direction. This is used by the IDE
388 * driver to write disk sectors. Works with any alignment in SRC.
389 * Performance is important, but the interfaces seems to be slow:
390 * just using the inlined version of the outl() breaks things.
392 void outsl (unsigned long port, const void *src, unsigned long count)
394 unsigned int l = 0, l2;
399 switch (((unsigned long) src) & 0x3)
401 case 0x00: /* Buffer 32-bit aligned */
404 outl(le32_to_cpu(*(unsigned int *) src), port);
405 ((unsigned int *) src)++;
409 case 0x02: /* Buffer 16-bit aligned */
412 l = *(unsigned short *) src;
413 ((unsigned short *) src)++;
417 l2 = *(unsigned int *) src;
418 ((unsigned int *) src)++;
419 outl (le32_to_cpu(l << 16 | l2 >> 16), port);
422 l2 = *(unsigned short *) src;
423 outl (le32_to_cpu(l << 16 | l2), port);
425 case 0x01: /* Buffer 8-bit aligned */
428 l = *(unsigned char *) src << 24;
429 ((unsigned char *) src)++;
430 l |= *(unsigned short *) src << 8;
431 ((unsigned short *) src)++;
434 l2 = *(unsigned int *) src;
435 ((unsigned int *) src)++;
436 outl (le32_to_cpu(l | l2 >> 24), port);
439 l2 = *(unsigned char *) src;
440 outl (le32_to_cpu(l | l2), port);
442 case 0x03: /* Buffer 8-bit aligned */
445 l = *(unsigned char *) src << 24;
446 ((unsigned char *) src)++;
449 l2 = *(unsigned int *) src;
450 ((unsigned int *) src)++;
451 outl (le32_to_cpu(l | l2 >> 8), port);
454 l2 = *(unsigned short *) src << 16;
455 ((unsigned short *) src)++;
456 l2 |= *(unsigned char *) src;
457 outl (le32_to_cpu(l | l2), port);
465 EXPORT_SYMBOL(outsb);
466 EXPORT_SYMBOL(outsw);
467 EXPORT_SYMBOL(outsl);