home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-i386 / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.5 KB  |  286 lines

  1. /*
  2.  * Architecture specific parts of the Floppy driver
  3.  *
  4.  * This file is subject to the terms and conditions of the GNU General Public
  5.  * License.  See the file "COPYING" in the main directory of this archive
  6.  * for more details.
  7.  *
  8.  * Copyright (C) 1995
  9.  */
  10. #ifndef __ASM_I386_FLOPPY_H
  11. #define __ASM_I386_FLOPPY_H
  12.  
  13. #include <linux/vmalloc.h>
  14.  
  15.  
  16. /*
  17.  * The DMA channel used by the floppy controller cannot access data at
  18.  * addresses >= 16MB
  19.  *
  20.  * Went back to the 1MB limit, as some people had problems with the floppy
  21.  * driver otherwise. It doesn't matter much for performance anyway, as most
  22.  * floppy accesses go through the track buffer.
  23.  */
  24. #define _CROSS_64KB(a,s,vdma) \
  25. (!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
  26.  
  27. #define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
  28.  
  29.  
  30. #define SW fd_routine[use_virtual_dma&1]
  31. #define CSW fd_routine[can_use_virtual_dma & 1]
  32.  
  33.  
  34. #define fd_inb(port)            inb_p(port)
  35. #define fd_outb(value,port)        outb_p(value,port)
  36.  
  37. #define fd_request_dma()        CSW._request_dma(FLOPPY_DMA,"floppy")
  38. #define fd_free_dma()           CSW._free_dma(FLOPPY_DMA)
  39. #define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
  40. #define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
  41. #define fd_free_irq()        free_irq(FLOPPY_IRQ, NULL)
  42. #define fd_get_dma_residue()    SW._get_dma_residue(FLOPPY_DMA)
  43. #define fd_dma_mem_alloc(size)    SW._dma_mem_alloc(size)
  44. #define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
  45.  
  46. #define FLOPPY_CAN_FALLBACK_ON_NODMA
  47.  
  48. static int virtual_dma_count;
  49. static int virtual_dma_residue;
  50. static char *virtual_dma_addr;
  51. static int virtual_dma_mode;
  52. static int doing_pdma;
  53.  
  54. static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
  55. {
  56.     register unsigned char st;
  57.  
  58. #undef TRACE_FLPY_INT
  59.  
  60. #ifdef TRACE_FLPY_INT
  61.     static int calls=0;
  62.     static int bytes=0;
  63.     static int dma_wait=0;
  64. #endif
  65.     if (!doing_pdma)
  66.         return floppy_interrupt(irq, dev_id, regs);
  67.  
  68. #ifdef TRACE_FLPY_INT
  69.     if(!calls)
  70.         bytes = virtual_dma_count;
  71. #endif
  72.  
  73.     {
  74.         register int lcount;
  75.         register char *lptr;
  76.  
  77.         st = 1;
  78.         for(lcount=virtual_dma_count, lptr=virtual_dma_addr; 
  79.             lcount; lcount--, lptr++) {
  80.             st=inb(virtual_dma_port+4) & 0xa0 ;
  81.             if(st != 0xa0) 
  82.                 break;
  83.             if(virtual_dma_mode)
  84.                 outb_p(*lptr, virtual_dma_port+5);
  85.             else
  86.                 *lptr = inb_p(virtual_dma_port+5);
  87.         }
  88.         virtual_dma_count = lcount;
  89.         virtual_dma_addr = lptr;
  90.         st = inb(virtual_dma_port+4);
  91.     }
  92.  
  93. #ifdef TRACE_FLPY_INT
  94.     calls++;
  95. #endif
  96.     if(st == 0x20)
  97.         return IRQ_HANDLED;
  98.     if(!(st & 0x20)) {
  99.         virtual_dma_residue += virtual_dma_count;
  100.         virtual_dma_count=0;
  101. #ifdef TRACE_FLPY_INT
  102.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", 
  103.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  104.                dma_wait);
  105.         calls = 0;
  106.         dma_wait=0;
  107. #endif
  108.         doing_pdma = 0;
  109.         floppy_interrupt(irq, dev_id, regs);
  110.         return IRQ_HANDLED;
  111.     }
  112. #ifdef TRACE_FLPY_INT
  113.     if(!virtual_dma_count)
  114.         dma_wait++;
  115. #endif
  116.     return IRQ_HANDLED;
  117. }
  118.  
  119. static void fd_disable_dma(void)
  120. {
  121.     if(! (can_use_virtual_dma & 1))
  122.         disable_dma(FLOPPY_DMA);
  123.     doing_pdma = 0;
  124.     virtual_dma_residue += virtual_dma_count;
  125.     virtual_dma_count=0;
  126. }
  127.  
  128. static int vdma_request_dma(unsigned int dmanr, const char * device_id)
  129. {
  130.     return 0;
  131. }
  132.  
  133. static void vdma_nop(unsigned int dummy)
  134. {
  135. }
  136.  
  137.  
  138. static int vdma_get_dma_residue(unsigned int dummy)
  139. {
  140.     return virtual_dma_count + virtual_dma_residue;
  141. }
  142.  
  143.  
  144. static int fd_request_irq(void)
  145. {
  146.     if(can_use_virtual_dma)
  147.         return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
  148.                            "floppy", NULL);
  149.     else
  150.         return request_irq(FLOPPY_IRQ, floppy_interrupt,
  151.                            SA_INTERRUPT|SA_SAMPLE_RANDOM,
  152.                            "floppy", NULL);    
  153.  
  154. }
  155.  
  156. static unsigned long dma_mem_alloc(unsigned long size)
  157. {
  158.     return __get_dma_pages(GFP_KERNEL,get_order(size));
  159. }
  160.  
  161.  
  162. static unsigned long vdma_mem_alloc(unsigned long size)
  163. {
  164.     return (unsigned long) vmalloc(size);
  165.  
  166. }
  167.  
  168. #define nodma_mem_alloc(size) vdma_mem_alloc(size)
  169.  
  170. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  171. {
  172.     if((unsigned int) addr >= (unsigned int) high_memory)
  173.         vfree((void *)addr);
  174.     else
  175.         free_pages(addr, get_order(size));        
  176. }
  177.  
  178. #define fd_dma_mem_free(addr, size)  _fd_dma_mem_free(addr, size) 
  179.  
  180. static void _fd_chose_dma_mode(char *addr, unsigned long size)
  181. {
  182.     if(can_use_virtual_dma == 2) {
  183.         if((unsigned int) addr >= (unsigned int) high_memory ||
  184.            isa_virt_to_bus(addr) >= 0x1000000 ||
  185.            _CROSS_64KB(addr, size, 0))
  186.             use_virtual_dma = 1;
  187.         else
  188.             use_virtual_dma = 0;
  189.     } else {
  190.         use_virtual_dma = can_use_virtual_dma & 1;
  191.     }
  192. }
  193.  
  194. #define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
  195.  
  196.  
  197. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  198. {
  199.     doing_pdma = 1;
  200.     virtual_dma_port = io;
  201.     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  202.     virtual_dma_addr = addr;
  203.     virtual_dma_count = size;
  204.     virtual_dma_residue = 0;
  205.     return 0;
  206. }
  207.  
  208. static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
  209. {
  210. #ifdef FLOPPY_SANITY_CHECK
  211.     if (CROSS_64KB(addr, size)) {
  212.         printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
  213.         return -1;
  214.     }
  215. #endif
  216.     /* actual, physical DMA */
  217.     doing_pdma = 0;
  218.     clear_dma_ff(FLOPPY_DMA);
  219.     set_dma_mode(FLOPPY_DMA,mode);
  220.     set_dma_addr(FLOPPY_DMA,isa_virt_to_bus(addr));
  221.     set_dma_count(FLOPPY_DMA,size);
  222.     enable_dma(FLOPPY_DMA);
  223.     return 0;
  224. }
  225.  
  226. static struct fd_routine_l {
  227.     int (*_request_dma)(unsigned int dmanr, const char * device_id);
  228.     void (*_free_dma)(unsigned int dmanr);
  229.     int (*_get_dma_residue)(unsigned int dummy);
  230.     unsigned long (*_dma_mem_alloc) (unsigned long size);
  231.     int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
  232. } fd_routine[] = {
  233.     {
  234.         request_dma,
  235.         free_dma,
  236.         get_dma_residue,
  237.         dma_mem_alloc,
  238.         hard_dma_setup
  239.     },
  240.     {
  241.         vdma_request_dma,
  242.         vdma_nop,
  243.         vdma_get_dma_residue,
  244.         vdma_mem_alloc,
  245.         vdma_dma_setup
  246.     }
  247. };
  248.  
  249.  
  250. static int FDC1 = 0x3f0;
  251. static int FDC2 = -1;
  252.  
  253. /*
  254.  * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
  255.  * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
  256.  * coincides with another rtc CMOS user.        Paul G.
  257.  */
  258. #define FLOPPY0_TYPE    ({                \
  259.     unsigned long flags;                \
  260.     unsigned char val;                \
  261.     spin_lock_irqsave(&rtc_lock, flags);        \
  262.     val = (CMOS_READ(0x10) >> 4) & 15;        \
  263.     spin_unlock_irqrestore(&rtc_lock, flags);    \
  264.     val;                        \
  265. })
  266.  
  267. #define FLOPPY1_TYPE    ({                \
  268.     unsigned long flags;                \
  269.     unsigned char val;                \
  270.     spin_lock_irqsave(&rtc_lock, flags);        \
  271.     val = CMOS_READ(0x10) & 15;            \
  272.     spin_unlock_irqrestore(&rtc_lock, flags);    \
  273.     val;                        \
  274. })
  275.  
  276. #define N_FDC 2
  277. #define N_DRIVE 8
  278.  
  279. #define FLOPPY_MOTOR_MASK 0xf0
  280.  
  281. #define AUTO_DMA
  282.  
  283. #define EXTRA_FLOPPY_PARAMS
  284.  
  285. #endif /* __ASM_I386_FLOPPY_H */
  286.