root/include/asm/dma.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. enable_dma
  2. disable_dma
  3. clear_dma_ff
  4. set_dma_mode
  5. set_dma_page
  6. set_dma_addr
  7. set_dma_count
  8. get_dma_residue

   1 /* $Header: /sys/linux-0.97/include/asm/RCS/dma.h,v 1.4 1992/09/21 03:15:46 root Exp root $
   2  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
   3  * Written by Hennus Bergman, 1992.
   4  *
   5  * High DMA channel support by Hannu Savolainen
   6  */
   7 
   8 #ifndef _ASM_DMA_H
   9 #define _ASM_DMA_H
  10 
  11 #include <asm/io.h>             /* need byte IO */
  12 
  13 
  14 #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
  15 #define outb    outb_p
  16 #endif
  17 
  18 /*
  19  * The routines below should in most cases (with optimizing on) result
  20  * in equal or better code than similar code using macros.
  21  *
  22  * NOTE about DMA transfers: The DMA controller cannot handle transfers
  23  * that cross a 64k boundary. When the address reaches 0xNffff, it will wrap
  24  * around to 0xN0000, rather than increment to 0x(N+1)0000 !
  25  * Make sure you align your buffers properly! Runtime check recommended.
  26 
  27  ****** Correction!!!!!
  28  *      Channels 4-7 16 bit channels and capable to cross 64k boundaries
  29  *      but not 128k boundaries. Transfer count must be given as words.
  30  *      Maximum transfer size is 65k words = 128kb.
  31  *
  32  * NOTE2: DMA1..3 can only use the lower 1MB of physical memory. DMA4..7
  33  * can access the lower 16MB. There are people with >16MB, so beware!
  34  
  35  * **** Not correct!!! All channels are able to access the first 16MB *******
  36  */
  37 
  38 
  39 #define MAX_DMA_CHANNELS        8
  40 
  41 /* SOMEBODY should check the following:
  42  * Channels 0..3 are on the first DMA controller, channels 4..7 are
  43  * on the second. Channel 0 is for refresh, 4 is for cascading.
  44  * The first DMA controller uses bytes, the second words.
  45  *
  46  * Where are the page regs for the second DMA controller?????
  47  * (ch 5=0x8b, 6=0x89, 7=0x8a)
  48  */
  49 
  50 
  51 /* 8237 DMA controllers */
  52 #define IO_DMA1_BASE    0x00    /* 8 bit slave DMA, channels 0..3 */
  53 #define IO_DMA2_BASE    0xC0    /* 16 bit master DMA, ch 4(=slave input)..7 */
  54 
  55 /* DMA controller registers */
  56 #define DMA1_CMD_REG            0x08    /* DMA command register */
  57 #define DMA1_STAT_REG           0x08    /* DMA status register */
  58 #define DMA1_MASK_REG           0x0A    /* mask individual channels */
  59 #define DMA1_MODE_REG           0x0B    /* set modes for individual channels */
  60 #define DMA1_CLEAR_FF_REG       0x0C    /* Write 0 for LSB, 1 for MSB */
  61 #define DMA1_RESET_REG          0x0D    /* Write here to reset DMA controller */
  62 
  63 #define DMA2_CMD_REG            0xD0    /* DMA command register */
  64 #define DMA2_STAT_REG           0xD0    /* DMA status register */
  65 #define DMA2_MASK_REG           0xD4
  66 #define DMA2_MODE_REG           0xD6
  67 #define DMA2_CLEAR_FF_REG       0xD8
  68 #define DMA2_RESET_REG          0xDA    /* Write here to reset DMA controller */
  69 
  70 #define DMA_MODE_READ   0x44    /* I/O to memory, no autoinit, increment, single mode */
  71 #define DMA_MODE_WRITE  0x48    /* memory to I/O, no autoinit, increment, single mode */
  72 /* cascade mode (for DMA2 controller only) */
  73 #define DMA_MODE_CASCADE        0x40    /* 0xC0 */
  74 
  75 
  76 /* enable/disable a specific DMA channel */
  77 static __inline__ void enable_dma(unsigned int dmanr)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79         if (dmanr<=3)
  80                 outb(dmanr,  DMA1_MASK_REG);
  81         else
  82                 outb(dmanr & 3,  DMA2_MASK_REG);
  83 }
  84 
  85 static __inline__ void disable_dma(unsigned int dmanr)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87         if (dmanr<=3)
  88                 outb(dmanr | 4,  DMA1_MASK_REG);
  89         else
  90                 outb((dmanr & 3) | 4,  DMA2_MASK_REG);
  91 }
  92 
  93 /* Clear the 'DMA Pointer Flip Flop'.
  94  * Write 0 for LSB/MSB, 1 for MSB/LSB access.
  95  * Use this once to initialize the FF to a know state.
  96  * After that, keep track of it. :-) In order to do that,
  97  * dma_set_addr() and dma_set_count() should only be used wile
  98  * interrupts are disbled.
  99  */
 100 static __inline__ void clear_dma_ff(unsigned int dmanr)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         if (dmanr<=3)
 103                 outb(0,  DMA1_CLEAR_FF_REG);
 104         else
 105                 outb(0,  DMA2_CLEAR_FF_REG);
 106 }
 107 
 108 /* set mode (above) for a specific DMA channel */
 109 static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         if (dmanr<=3)
 112                 outb(mode | dmanr,  DMA1_MODE_REG);
 113         else
 114                 outb(DMA_MODE_CASCADE | mode | (dmanr&3),  DMA2_MODE_REG);
 115 }
 116 
 117 /* Set only the page register bits of the transfer address.
 118  * This is used for successive transfers when we know the contents of
 119  * the lower 16 bits of the DMA current address register, but a 64k boundary
 120  * may have been crossed.
 121  */
 122 static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         switch(dmanr) {
 125                 case 0:
 126                         outb(pagenr, 0x80);
 127                         break;
 128                 case 1:
 129                         outb(pagenr, 0x83);
 130                         break;
 131                 case 2:
 132                         outb(pagenr, 0x81);
 133                         break;
 134                 case 3:
 135                         outb(pagenr, 0x82);
 136                         break;
 137                 case 4:
 138                         outb(pagenr, 0x8f);
 139                         break;
 140                 case 5:
 141                         outb(pagenr, 0x8b);
 142                         break;
 143                 case 6:
 144                         outb(pagenr, 0x89);
 145                         break;
 146                 case 7:
 147                         outb(pagenr, 0x8a);
 148                         break;
 149         }
 150 }
 151 
 152 
 153 /* Set transfer address & page bits for specific DMA channel.
 154  * Assumes dma flipflop is clear.
 155  *
 156  * NOTE! A word address is assumed for the channels 4 to 7.
 157  */
 158 static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         unsigned int io_base = (dmanr<=3)? IO_DMA1_BASE : IO_DMA2_BASE;
 161         unsigned int page = a>>16;
 162 
 163         if (dmanr>3) page &= 0xfe;      /* The last bit is never used */
 164 
 165         set_dma_page(dmanr, page);
 166 
 167         if (dmanr>3) a >>= 1;
 168 
 169         outb(a & 0xff, ((dmanr&3)<<1) + io_base);
 170         outb((a>>8) & 0xff, ((dmanr&3)<<1) + io_base);
 171 }
 172 
 173 
 174 /* Set transfer size (max 64k) for a specific DMA channel.
 175  * You must ensure the parameters are valid.
 176  * NOTE: from a manual: "the number of transfers is one more 
 177  * than the initial word count"! This is taken into account.
 178  * Assumes dma flip-flop is clear.
 179  */
 180 static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 181 {
 182         unsigned int dc;
 183         unsigned int io_base = (dmanr<=3)? IO_DMA1_BASE : IO_DMA2_BASE;
 184 
 185         if (dmanr>3) count >>=1;
 186         dc = count - 1;
 187 
 188         outb(dc & 0xff, ((dmanr&3)<<1) + 1 + io_base);
 189         outb((dc>>8) & 0xff, ((dmanr&3)<<1) + 1 + io_base);
 190 }
 191 
 192 
 193 /* Get DMA residue count. After a DMA transfer, this
 194  * should return zero. Reading this while a DMA transfer is
 195  * still in progress will return unpredictable results.
 196  * If called before the channel has been used, it may return 1.
 197  * Otherwise, it returns the number of bytes left to transfer,
 198  * minus 1, modulo 64k.
 199  * Assumes DMA flip-flop is clear.
 200  */
 201 static __inline__ short int get_dma_residue(unsigned int dmanr)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203         unsigned int io_base = (dmanr<=3)? IO_DMA1_BASE : IO_DMA2_BASE;
 204 
 205         return 1 + inb( ((dmanr&3)<<1) + 1 + io_base ) +
 206                 ( inb( ((dmanr&3)<<1) + 1 + io_base ) << 8 );
 207 }
 208 
 209 /* These are in kernel/dma.c: */
 210 extern int request_dma(unsigned int dmanr);     /* reserve a DMA channel */
 211 extern void free_dma(unsigned int dmanr);       /* release it again */
 212 
 213 
 214 #endif /* _ASM_DMA_H */

/* [previous][next][first][last][top][bottom][index][help] */