ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-sparc64 / ide.h
1 /* $Id: ide.h,v 1.21 2001/09/25 20:21:48 kanoj Exp $
2  * ide.h: Ultra/PCI specific IDE glue.
3  *
4  * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
5  * Copyright (C) 1998  Eddie C. Dost   (ecd@skynet.be)
6  */
7
8 #ifndef _SPARC64_IDE_H
9 #define _SPARC64_IDE_H
10
11 #ifdef __KERNEL__
12
13 #include <linux/config.h>
14 #include <asm/pgalloc.h>
15 #include <asm/io.h>
16 #include <asm/page.h>
17 #include <asm/spitfire.h>
18
19 #ifndef MAX_HWIFS
20 # ifdef CONFIG_BLK_DEV_IDEPCI
21 #define MAX_HWIFS       10
22 # else
23 #define MAX_HWIFS       2
24 # endif
25 #endif
26
27 static __inline__ int ide_default_irq(unsigned long base)
28 {
29         return 0;
30 }
31
32 static __inline__ unsigned long ide_default_io_base(int index)
33 {
34         return 0;
35 }
36
37 #define ide_init_default_irq(base)      (0)
38
39 #define __ide_insl(data_reg, buffer, wcount) \
40         __ide_insw(data_reg, buffer, (wcount)<<1)
41 #define __ide_outsl(data_reg, buffer, wcount) \
42         __ide_outsw(data_reg, buffer, (wcount)<<1)
43
44 /* On sparc64, I/O ports and MMIO registers are accessed identically.  */
45 #define __ide_mm_insw   __ide_insw
46 #define __ide_mm_insl   __ide_insl
47 #define __ide_mm_outsw  __ide_outsw
48 #define __ide_mm_outsl  __ide_outsl
49
50 static __inline__ unsigned int inw_be(unsigned long addr)
51 {
52         unsigned int ret;
53
54         __asm__ __volatile__("lduha [%1] %2, %0"
55                              : "=r" (ret)
56                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
57
58         return ret;
59 }
60
61 static __inline__ void __ide_insw(unsigned long port,
62                                   void *dst,
63                                   u32 count)
64 {
65 #if (L1DCACHE_SIZE > PAGE_SIZE)         /* is there D$ aliasing problem */
66         unsigned long end = (unsigned long)dst + (count << 1);
67 #endif
68         u16 *ps = dst;
69         u32 *pi;
70
71         if(((u64)ps) & 0x2) {
72                 *ps++ = inw_be(port);
73                 count--;
74         }
75         pi = (u32 *)ps;
76         while(count >= 2) {
77                 u32 w;
78
79                 w  = inw_be(port) << 16;
80                 w |= inw_be(port);
81                 *pi++ = w;
82                 count -= 2;
83         }
84         ps = (u16 *)pi;
85         if(count)
86                 *ps++ = inw_be(port);
87
88 #if (L1DCACHE_SIZE > PAGE_SIZE)         /* is there D$ aliasing problem */
89         __flush_dcache_range((unsigned long)dst, end);
90 #endif
91 }
92
93 static __inline__ void outw_be(unsigned short w, unsigned long addr)
94 {
95         __asm__ __volatile__("stha %0, [%1] %2"
96                              : /* no outputs */
97                              : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
98 }
99
100 static __inline__ void __ide_outsw(unsigned long port,
101                                    void *src,
102                                    u32 count)
103 {
104 #if (L1DCACHE_SIZE > PAGE_SIZE)         /* is there D$ aliasing problem */
105         unsigned long end = (unsigned long)src + (count << 1);
106 #endif
107         const u16 *ps = src;
108         const u32 *pi;
109
110         if(((u64)src) & 0x2) {
111                 outw_be(*ps++, port);
112                 count--;
113         }
114         pi = (const u32 *)ps;
115         while(count >= 2) {
116                 u32 w;
117
118                 w = *pi++;
119                 outw_be((w >> 16), port);
120                 outw_be(w, port);
121                 count -= 2;
122         }
123         ps = (const u16 *)pi;
124         if(count)
125                 outw_be(*ps, port);
126
127 #if (L1DCACHE_SIZE > PAGE_SIZE)         /* is there D$ aliasing problem */
128         __flush_dcache_range((unsigned long)src, end);
129 #endif
130 }
131
132 #endif /* __KERNEL__ */
133
134 #endif /* _SPARC64_IDE_H */