1 /* $Id: ide.h,v 1.19 2000/05/27 00:49:37 davem 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/hdreg.h>
17
18 #undef MAX_HWIFS
19 #define MAX_HWIFS 2
20
21 #define ide__sti() __sti()
22
23 static __inline__ int ide_default_irq(ide_ioreg_t base)
24 {
25 return 0;
26 }
27
28 static __inline__ ide_ioreg_t ide_default_io_base(int index)
29 {
30 return 0;
31 }
32
33 static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
34 {
35 ide_ioreg_t reg = data_port;
36 int i;
37
38 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
39 hw->io_ports[i] = reg;
40 reg += 1;
41 }
42 if (ctrl_port) {
43 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
44 } else {
45 hw->io_ports[IDE_CONTROL_OFFSET] = 0;
46 }
47 if (irq != NULL)
48 *irq = 0;
49 hw->io_ports[IDE_IRQ_OFFSET] = 0;
50 }
51
52 /*
53 * This registers the standard ports for this architecture with the IDE
54 * driver.
55 */
56 static __inline__ void ide_init_default_hwifs(void)
57 {
58 #ifndef CONFIG_BLK_DEV_IDEPCI
59 hw_regs_t hw;
60 int index;
61
62 for (index = 0; index < MAX_HWIFS; index++) {
63 ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
64 hw.irq = ide_default_irq(ide_default_io_base(index));
65 ide_register_hw(&hw, NULL);
66 }
67 #endif /* CONFIG_BLK_DEV_IDEPCI */
68 }
69
70 typedef union {
71 unsigned int all : 8; /* all of the bits together */
72 struct {
73 unsigned int bit7 : 1;
74 unsigned int lba : 1;
75 unsigned int bit5 : 1;
76 unsigned int unit : 1;
77 unsigned int head : 4;
78 } b;
79 } select_t;
80
81 static __inline__ int ide_request_irq(unsigned int irq,
82 void (*handler)(int, void *, struct pt_regs *),
83 unsigned long flags, const char *name, void *devid)
84 {
85 return request_irq(irq, handler, SA_SHIRQ, name, devid);
86 }
87
88 static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
89 {
90 free_irq(irq, dev_id);
91 }
92
93 static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size)
94 {
95 return check_region(base, size);
96 }
97
98 static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size,
99 const char *name)
100 {
101 request_region(base, size, name);
102 }
103
104 static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size)
105 {
106 release_region(base, size);
107 }
108
109 #undef SUPPORT_SLOW_DATA_PORTS
110 #define SUPPORT_SLOW_DATA_PORTS 0
111
112 #undef SUPPORT_VLB_SYNC
113 #define SUPPORT_VLB_SYNC 0
114
115 #undef HD_DATA
116 #define HD_DATA ((ide_ioreg_t)0)
117
118 /* From m68k code... */
119
120 #ifdef insl
121 #undef insl
122 #endif
123 #ifdef outsl
124 #undef outsl
125 #endif
126 #ifdef insw
127 #undef insw
128 #endif
129 #ifdef outsw
130 #undef outsw
131 #endif
132
133 #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
134 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
135
136 #define insw(port, buf, nr) ide_insw((port), (buf), (nr))
137 #define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
138
139 static __inline__ unsigned int inw_be(unsigned long addr)
140 {
141 unsigned int ret;
142
143 __asm__ __volatile__("lduha [%1] %2, %0"
144 : "=r" (ret)
145 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
146
147 return ret;
148 }
149
150 static __inline__ void ide_insw(unsigned long port,
151 void *dst,
152 unsigned long count)
153 {
154 unsigned long end = (unsigned long)dst + (count << 1);
155 u16 *ps = dst;
156 u32 *pi;
157
158 if(((u64)ps) & 0x2) {
159 *ps++ = inw_be(port);
160 count--;
161 }
162 pi = (u32 *)ps;
163 while(count >= 2) {
164 u32 w;
165
166 w = inw_be(port) << 16;
167 w |= inw_be(port);
168 *pi++ = w;
169 count -= 2;
170 }
171 ps = (u16 *)pi;
172 if(count)
173 *ps++ = inw_be(port);
174
175 __flush_dcache_range((unsigned long)dst, end);
176 }
177
178 static __inline__ void outw_be(unsigned short w, unsigned long addr)
179 {
180 __asm__ __volatile__("stha %0, [%1] %2"
181 : /* no outputs */
182 : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
183 }
184
185 static __inline__ void ide_outsw(unsigned long port,
186 const void *src,
187 unsigned long count)
188 {
189 unsigned long end = (unsigned long)src + (count << 1);
190 const u16 *ps = src;
191 const u32 *pi;
192
193 if(((u64)src) & 0x2) {
194 outw_be(*ps++, port);
195 count--;
196 }
197 pi = (const u32 *)ps;
198 while(count >= 2) {
199 u32 w;
200
201 w = *pi++;
202 outw_be((w >> 16), port);
203 outw_be(w, port);
204 count -= 2;
205 }
206 ps = (const u16 *)pi;
207 if(count)
208 outw_be(*ps, port);
209
210 __flush_dcache_range((unsigned long)src, end);
211 }
212
213 #define T_CHAR (0x0000) /* char: don't touch */
214 #define T_SHORT (0x4000) /* short: 12 -> 21 */
215 #define T_INT (0x8000) /* int: 1234 -> 4321 */
216 #define T_TEXT (0xc000) /* text: 12 -> 21 */
217
218 #define T_MASK_TYPE (0xc000)
219 #define T_MASK_COUNT (0x3fff)
220
221 #define D_CHAR(cnt) (T_CHAR | (cnt))
222 #define D_SHORT(cnt) (T_SHORT | (cnt))
223 #define D_INT(cnt) (T_INT | (cnt))
224 #define D_TEXT(cnt) (T_TEXT | (cnt))
225
226 static u_short driveid_types[] = {
227 D_SHORT(10), /* config - vendor2 */
228 D_TEXT(20), /* serial_no */
229 D_SHORT(3), /* buf_type - ecc_bytes */
230 D_TEXT(48), /* fw_rev - model */
231 D_CHAR(2), /* max_multsect - vendor3 */
232 D_SHORT(1), /* dword_io */
233 D_CHAR(2), /* vendor4 - capability */
234 D_SHORT(1), /* reserved50 */
235 D_CHAR(4), /* vendor5 - tDMA */
236 D_SHORT(4), /* field_valid - cur_sectors */
237 D_INT(1), /* cur_capacity */
238 D_CHAR(2), /* multsect - multsect_valid */
239 D_INT(1), /* lba_capacity */
240 D_SHORT(194) /* dma_1word - reservedyy */
241 };
242
243 #define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types))
244
245 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
246 {
247 u_char *p = (u_char *)id;
248 int i, j, cnt;
249 u_char t;
250
251 for (i = 0; i < num_driveid_types; i++) {
252 cnt = driveid_types[i] & T_MASK_COUNT;
253 switch (driveid_types[i] & T_MASK_TYPE) {
254 case T_CHAR:
255 p += cnt;
256 break;
257 case T_SHORT:
258 for (j = 0; j < cnt; j++) {
259 t = p[0];
260 p[0] = p[1];
261 p[1] = t;
262 p += 2;
263 }
264 break;
265 case T_INT:
266 for (j = 0; j < cnt; j++) {
267 t = p[0];
268 p[0] = p[3];
269 p[3] = t;
270 t = p[1];
271 p[1] = p[2];
272 p[2] = t;
273 p += 4;
274 }
275 break;
276 case T_TEXT:
277 for (j = 0; j < cnt; j += 2) {
278 t = p[0];
279 p[0] = p[1];
280 p[1] = t;
281 p += 2;
282 }
283 break;
284 };
285 }
286 }
287
288 /*
289 * The following are not needed for the non-m68k ports
290 */
291 #define ide_ack_intr(hwif) (1)
292 #define ide_release_lock(lock) do {} while (0)
293 #define ide_get_lock(lock, hdlr, data) do {} while (0)
294
295 #endif /* __KERNEL__ */
296
297 #endif /* _SPARC64_IDE_H */
298
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.