1 /*
2 * linux/include/asm-m68k/ide.h
3 *
4 * Copyright (C) 1994-1996 Linus Torvalds & authors
5 */
6
7 /* Copyright(c) 1996 Kars de Jong */
8 /* Based on the ide driver from 1.2.13pl8 */
9
10 /*
11 * Credits (alphabetical):
12 *
13 * - Bjoern Brauel
14 * - Kars de Jong
15 * - Torsten Ebeling
16 * - Dwight Engen
17 * - Thorsten Floeck
18 * - Roman Hodek
19 * - Guenther Kelleter
20 * - Chris Lawrence
21 * - Michael Rausch
22 * - Christian Sauer
23 * - Michael Schmitz
24 * - Jes Soerensen
25 * - Michael Thurm
26 * - Geert Uytterhoeven
27 */
28
29 #ifndef _M68K_IDE_H
30 #define _M68K_IDE_H
31
32 #ifdef __KERNEL__
33
34 #include <linux/config.h>
35
36 #include <asm/setup.h>
37 #include <asm/io.h>
38 #include <asm/irq.h>
39
40 #ifdef CONFIG_ATARI
41 #include <linux/interrupt.h>
42 #include <asm/atari_stdma.h>
43 #endif
44
45 #ifdef CONFIG_MAC
46 #include <asm/macints.h>
47 #endif
48
49 #ifndef MAX_HWIFS
50 #define MAX_HWIFS 4 /* same as the other archs */
51 #endif
52
53
54 static __inline__ int ide_default_irq(ide_ioreg_t base)
55 {
56 return 0;
57 }
58
59 static __inline__ ide_ioreg_t ide_default_io_base(int index)
60 {
61 return 0;
62 }
63
64 /*
65 * Can we do this in a generic manner??
66 */
67
68
69 /*
70 * Set up a hw structure for a specified data port, control port and IRQ.
71 * This should follow whatever the default interface uses.
72 */
73 static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
74 {
75 if (data_port || ctrl_port)
76 printk("ide_init_hwif_ports: must not be called\n");
77 }
78
79 /*
80 * This registers the standard ports for this architecture with the IDE
81 * driver.
82 */
83 static __inline__ void ide_init_default_hwifs(void)
84 {
85 }
86
87 typedef union {
88 unsigned all : 8; /* all of the bits together */
89 struct {
90 unsigned bit7 : 1; /* always 1 */
91 unsigned lba : 1; /* using LBA instead of CHS */
92 unsigned bit5 : 1; /* always 1 */
93 unsigned unit : 1; /* drive select number, 0 or 1 */
94 unsigned head : 4; /* always zeros here */
95 } b;
96 } select_t;
97
98 static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
99 unsigned long flags, const char *device, void *dev_id)
100 {
101 #ifdef CONFIG_AMIGA
102 if (MACH_IS_AMIGA)
103 return request_irq(irq, handler, 0, device, dev_id);
104 #endif /* CONFIG_AMIGA */
105 #ifdef CONFIG_Q40
106 if (MACH_IS_Q40)
107 return request_irq(irq, handler, 0, device, dev_id);
108 #endif /* CONFIG_Q40*/
109 #ifdef CONFIG_MAC
110 if (MACH_IS_MAC)
111 return request_irq(irq, handler, 0, device, dev_id);
112 #endif /* CONFIG_MAC */
113 return 0;
114 }
115
116 static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
117 {
118 #ifdef CONFIG_AMIGA
119 if (MACH_IS_AMIGA)
120 free_irq(irq, dev_id);
121 #endif /* CONFIG_AMIGA */
122 #ifdef CONFIG_Q40
123 if (MACH_IS_Q40)
124 free_irq(irq, dev_id);
125 #endif /* CONFIG_Q40*/
126 #ifdef CONFIG_MAC
127 if (MACH_IS_MAC)
128 free_irq(irq, dev_id);
129 #endif /* CONFIG_MAC */
130 }
131
132 /*
133 * We should really implement those some day.
134 */
135 static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
136 {
137 return 0;
138 }
139
140 static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
141 {
142 #ifdef CONFIG_Q40
143 if (MACH_IS_Q40)
144 request_region((q40ide_ioreg_t)from,extent,name);
145 #endif
146 }
147
148 static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
149 {
150 #ifdef CONFIG_Q40
151 if (MACH_IS_Q40)
152 release_region((q40ide_ioreg_t)from,extent);
153 #endif
154 }
155
156 #undef SUPPORT_SLOW_DATA_PORTS
157 #define SUPPORT_SLOW_DATA_PORTS 0
158
159 #undef SUPPORT_VLB_SYNC
160 #define SUPPORT_VLB_SYNC 0
161
162 /* this definition is used only on startup .. */
163 #ifndef CONFIG_Q40
164 #undef HD_DATA
165 #define HD_DATA NULL
166 #else
167 #ifdef MACH_Q40_ONLY
168 #undef HD_DATA
169 #define HD_DATA ((ide_ioreg_t)0x1f0)
170 #else
171 #undef HD_DATA
172 #define HD_DATA (MACH_IS_Q40 ? (ide_ioreg_t)0x1f0 : 0)
173 #endif
174 #endif
175
176
177 #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
178 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
179
180 #ifdef CONFIG_Q40
181 #ifdef MACH_Q40_ONLY
182 #define ADDR_TRANS(_addr_) (Q40_ISA_IO_W(_addr_))
183 #else
184 #define ADDR_TRANS(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
185 #endif
186 #else
187 #define ADDR_TRANS(_addr_) (_addr_)
188 #endif
189
190 #define insw(port, buf, nr) ({ \
191 unsigned char *_port = (unsigned char *) ADDR_TRANS(port); \
192 unsigned char *_buf = (buf); \
193 int _nr = (nr); \
194 unsigned long _tmp; \
195 \
196 if (_nr & 15) { \
197 _tmp = (_nr & 15) - 1; \
198 asm volatile ( \
199 "1: movew %2@,%0@+; dbra %1,1b" \
200 : "=a" (_buf), "=d" (_tmp) \
201 : "a" (_port), "" (_buf), \
202 "1" (_tmp)); \
203 } \
204 if (_nr >> 4) { \
205 _tmp = (_nr >> 4) - 1; \
206 asm volatile ( \
207 "1: " \
208 "movew %2@,%0@+; " \
209 "movew %2@,%0@+; " \
210 "movew %2@,%0@+; " \
211 "movew %2@,%0@+; " \
212 "movew %2@,%0@+; " \
213 "movew %2@,%0@+; " \
214 "movew %2@,%0@+; " \
215 "movew %2@,%0@+; " \
216 "movew %2@,%0@+; " \
217 "movew %2@,%0@+; " \
218 "movew %2@,%0@+; " \
219 "movew %2@,%0@+; " \
220 "movew %2@,%0@+; " \
221 "movew %2@,%0@+; " \
222 "movew %2@,%0@+; " \
223 "movew %2@,%0@+; " \
224 "dbra %1,1b" \
225 : "=a" (_buf), "=d" (_tmp) \
226 : "a" (_port), "" (_buf), \
227 "1" (_tmp)); \
228 } \
229 })
230
231 #define outsw(port, buf, nr) ({ \
232 unsigned char *_port = (unsigned char *) ADDR_TRANS(port); \
233 unsigned char *_buf = (buf); \
234 int _nr = (nr); \
235 unsigned long _tmp; \
236 \
237 if (_nr & 15) { \
238 _tmp = (_nr & 15) - 1; \
239 asm volatile ( \
240 "1: movew %0@+,%2@; dbra %1,1b" \
241 : "=a" (_buf), "=d" (_tmp) \
242 : "a" (_port), "" (_buf), \
243 "1" (_tmp)); \
244 } \
245 if (_nr >> 4) { \
246 _tmp = (_nr >> 4) - 1; \
247 asm volatile ( \
248 "1: " \
249 "movew %0@+,%2@; " \
250 "movew %0@+,%2@; " \
251 "movew %0@+,%2@; " \
252 "movew %0@+,%2@; " \
253 "movew %0@+,%2@; " \
254 "movew %0@+,%2@; " \
255 "movew %0@+,%2@; " \
256 "movew %0@+,%2@; " \
257 "movew %0@+,%2@; " \
258 "movew %0@+,%2@; " \
259 "movew %0@+,%2@; " \
260 "movew %0@+,%2@; " \
261 "movew %0@+,%2@; " \
262 "movew %0@+,%2@; " \
263 "movew %0@+,%2@; " \
264 "movew %0@+,%2@; " \
265 "dbra %1,1b" \
266 : "=a" (_buf), "=d" (_tmp) \
267 : "a" (_port), "" (_buf), \
268 "1" (_tmp)); \
269 } \
270 })
271
272 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
273 #define insl_swapw(data_reg, buffer, wcount) \
274 insw_swapw(data_reg, buffer, (wcount)<<1)
275 #define outsl_swapw(data_reg, buffer, wcount) \
276 outsw_swapw(data_reg, buffer, (wcount)<<1)
277
278 #define insw_swapw(port, buf, nr) \
279 if ((nr) % 8) \
280 __asm__ __volatile__ \
281 ("movel %0,%/a0; \
282 movel %1,%/a1; \
283 movel %2,%/d6; \
284 subql #1,%/d6; \
285 1:movew %/a0@,%/d0; \
286 rolw #8,%/d0; \
287 movew %/d0,%/a1@+; \
288 dbra %/d6,1b" : \
289 : "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
290 : "d0", "a0", "a1", "d6"); \
291 else \
292 __asm__ __volatile__ \
293 ("movel %0,%/a0; \
294 movel %1,%/a1; \
295 movel %2,%/d6; \
296 lsrl #3,%/d6; \
297 subql #1,%/d6; \
298 1:movew %/a0@,%/d0; \
299 rolw #8,%/d0; \
300 movew %/d0,%/a1@+; \
301 movew %/a0@,%/d0; \
302 rolw #8,%/d0; \
303 movew %/d0,%/a1@+; \
304 movew %/a0@,%/d0; \
305 rolw #8,%/d0; \
306 movew %/d0,%/a1@+; \
307 movew %/a0@,%/d0; \
308 rolw #8,%/d0; \
309 movew %/d0,%/a1@+; \
310 movew %/a0@,%/d0; \
311 rolw #8,%/d0; \
312 movew %/d0,%/a1@+; \
313 movew %/a0@,%/d0; \
314 rolw #8,%/d0; \
315 movew %/d0,%/a1@+; \
316 movew %/a0@,%/d0; \
317 rolw #8,%/d0; \
318 movew %/d0,%/a1@+; \
319 movew %/a0@,%/d0; \
320 rolw #8,%/d0; \
321 movew %/d0,%/a1@+; \
322 dbra %/d6,1b" : \
323 : "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
324 : "d0", "a0", "a1", "d6")
325
326
327 #define outsw_swapw(port, buf, nr) \
328 if ((nr) % 8) \
329 __asm__ __volatile__ \
330 ("movel %0,%/a0; \
331 movel %1,%/a1; \
332 movel %2,%/d6; \
333 subql #1,%/d6; \
334 1:movew %/a1@+,%/d0; \
335 rolw #8,%/d0; \
336 movew %/d0,%/a0@; \
337 dbra %/d6,1b" : \
338 : "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
339 : "d0", "a0", "a1", "d6"); \
340 else \
341 __asm__ __volatile__ \
342 ("movel %0,%/a0; \
343 movel %1,%/a1; \
344 movel %2,%/d6; \
345 lsrl #3,%/d6; \
346 subql #1,%/d6; \
347 1:movew %/a1@+,%/d0; \
348 rolw #8,%/d0; \
349 movew %/d0,%/a0@; \
350 movew %/a1@+,%/d0; \
351 rolw #8,%/d0; \
352 movew %/d0,%/a0@; \
353 movew %/a1@+,%/d0; \
354 rolw #8,%/d0; \
355 movew %/d0,%/a0@; \
356 movew %/a1@+,%/d0; \
357 rolw #8,%/d0; \
358 movew %/d0,%/a0@; \
359 movew %/a1@+,%/d0; \
360 rolw #8,%/d0; \
361 movew %/d0,%/a0@; \
362 movew %/a1@+,%/d0; \
363 rolw #8,%/d0; \
364 movew %/d0,%/a0@; \
365 movew %/a1@+,%/d0; \
366 rolw #8,%/d0; \
367 movew %/d0,%/a0@; \
368 movew %/a1@+,%/d0; \
369 rolw #8,%/d0; \
370 movew %/d0,%/a0@; \
371 dbra %/d6,1b" : \
372 : "g" (ADDR_TRANS(port)), "g" (buf), "g" (nr) \
373 : "d0", "a0", "a1", "d6")
374
375 #endif /* CONFIG_ATARI */
376
377 #define T_CHAR (0x0000) /* char: don't touch */
378 #define T_SHORT (0x4000) /* short: 12 -> 21 */
379 #define T_INT (0x8000) /* int: 1234 -> 4321 */
380 #define T_TEXT (0xc000) /* text: 12 -> 21 */
381
382 #define T_MASK_TYPE (0xc000)
383 #define T_MASK_COUNT (0x3fff)
384
385 #define D_CHAR(cnt) (T_CHAR | (cnt))
386 #define D_SHORT(cnt) (T_SHORT | (cnt))
387 #define D_INT(cnt) (T_INT | (cnt))
388 #define D_TEXT(cnt) (T_TEXT | (cnt))
389
390 #if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
391 static u_short driveid_types[] = {
392 D_SHORT(10), /* config - vendor2 */
393 D_TEXT(20), /* serial_no */
394 D_SHORT(3), /* buf_type, buf_size - ecc_bytes */
395 D_TEXT(48), /* fw_rev - model */
396 D_CHAR(2), /* max_multsect - vendor3 */
397 D_SHORT(1), /* dword_io */
398 D_CHAR(2), /* vendor4 - capability */
399 D_SHORT(1), /* reserved50 */
400 D_CHAR(4), /* vendor5 - tDMA */
401 D_SHORT(4), /* field_valid - cur_sectors */
402 D_INT(1), /* cur_capacity */
403 D_CHAR(2), /* multsect - multsect_valid */
404 D_INT(1), /* lba_capacity */
405 D_SHORT(194) /* dma_1word - reservedyy */
406 };
407
408 #define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types))
409 #endif /* CONFIG_AMIGA */
410
411 static __inline__ void ide_fix_driveid(struct hd_driveid *id)
412 {
413 #if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
414 u_char *p = (u_char *)id;
415 int i, j, cnt;
416 u_char t;
417
418 if (!MACH_IS_AMIGA && !MACH_IS_MAC)
419 return;
420 for (i = 0; i < num_driveid_types; i++) {
421 cnt = driveid_types[i] & T_MASK_COUNT;
422 switch (driveid_types[i] & T_MASK_TYPE) {
423 case T_CHAR:
424 p += cnt;
425 break;
426 case T_SHORT:
427 for (j = 0; j < cnt; j++) {
428 t = p[0];
429 p[0] = p[1];
430 p[1] = t;
431 p += 2;
432 }
433 break;
434 case T_INT:
435 for (j = 0; j < cnt; j++) {
436 t = p[0];
437 p[0] = p[3];
438 p[3] = t;
439 t = p[1];
440 p[1] = p[2];
441 p[2] = t;
442 p += 4;
443 }
444 break;
445 case T_TEXT:
446 for (j = 0; j < cnt; j += 2) {
447 t = p[0];
448 p[0] = p[1];
449 p[1] = t;
450 p += 2;
451 }
452 break;
453 }
454 }
455 #endif /* CONFIG_AMIGA */
456 }
457
458 static __inline__ void ide_release_lock (int *ide_lock)
459 {
460 #ifdef CONFIG_ATARI
461 if (MACH_IS_ATARI) {
462 if (*ide_lock == 0) {
463 printk("ide_release_lock: bug\n");
464 return;
465 }
466 *ide_lock = 0;
467 stdma_release();
468 }
469 #endif /* CONFIG_ATARI */
470 }
471
472 static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
473 {
474 #ifdef CONFIG_ATARI
475 if (MACH_IS_ATARI) {
476 if (*ide_lock == 0) {
477 if (in_interrupt() > 0)
478 panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
479 stdma_lock(handler, data);
480 *ide_lock = 1;
481 }
482 }
483 #endif /* CONFIG_ATARI */
484 }
485
486 #define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
487
488 /*
489 * On the Atari, we sometimes can't enable interrupts:
490 */
491
492 /* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def.
493 * to asm/ide.h
494 */
495 /* The Atari interrupt structure strictly requires that the IPL isn't lowered
496 * uncontrolled in an interrupt handler. In the concrete case, the IDE
497 * interrupt is already a slow int, so the irq is already disabled at the time
498 * the handler is called, and the IPL has been lowered to the minimum value
499 * possible. To avoid going below that, STI() checks for being called inside
500 * an interrupt, and in that case it does nothing. Hope that is reasonable and
501 * works. (Roman)
502 */
503 #ifdef MACH_ATARI_ONLY
504 #define ide__sti() \
505 do { \
506 if (!in_interrupt()) __sti(); \
507 } while(0)
508 #elif defined(CONFIG_ATARI)
509 #define ide__sti() \
510 do { \
511 if (!MACH_IS_ATARI || !in_interrupt()) sti(); \
512 } while(0)
513 #else /* !defined(CONFIG_ATARI) */
514 #define ide__sti() __sti()
515 #endif
516
517 #endif /* __KERNEL__ */
518
519 #endif /* _M68K_IDE_H */
520
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.