~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-m68k/ide.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.