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-m68k / floppy.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.2 KB  |  260 lines

  1. /*
  2.  * Implementation independent bits of the Floppy driver.
  3.  *
  4.  * much of this file is derived from what was originally the Q40 floppy driver.
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file "COPYING" in the main directory of this archive
  8.  * for more details.
  9.  *
  10.  * Copyright (C) 1999, 2000, 2001
  11.  *
  12.  * Sun3x support added 2/4/2000 Sam Creasey (sammy@sammy.net)
  13.  *
  14.  */
  15.  
  16. #include <asm/io.h>
  17.  
  18. #include <linux/vmalloc.h>
  19.  
  20. asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
  21.                       struct pt_regs *regs);
  22.  
  23. /* constants... */
  24.  
  25. #undef MAX_DMA_ADDRESS
  26. #define MAX_DMA_ADDRESS   0x00  /* nothing like that */
  27.  
  28.  
  29. /*
  30.  * Again, the CMOS information doesn't work on m68k..
  31.  */
  32. #define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4)
  33. #define FLOPPY1_TYPE 0
  34.  
  35. #define FLOPPY_MOTOR_MASK 0xf0
  36.  
  37.  
  38. /* basically PC init + set use_virtual_dma */
  39. #define  FDC1 m68k_floppy_init()
  40.  
  41. #define N_FDC 1
  42. #define N_DRIVE 8
  43.  
  44.  
  45. /* vdma globals adapted from asm-i386/floppy.h */
  46.  
  47. static int virtual_dma_count=0;
  48. static int virtual_dma_residue=0;
  49. static char *virtual_dma_addr=NULL;
  50. static int virtual_dma_mode=0;
  51. static int doing_pdma=0;
  52.  
  53. #include <asm/sun3xflop.h>
  54.  
  55. extern spinlock_t  dma_spin_lock;
  56.  
  57. static __inline__ unsigned long claim_dma_lock(void)
  58. {
  59.     unsigned long flags;
  60.     spin_lock_irqsave(&dma_spin_lock, flags);
  61.     return flags;
  62. }
  63.  
  64. static __inline__ void release_dma_lock(unsigned long flags)
  65. {
  66.     spin_unlock_irqrestore(&dma_spin_lock, flags);
  67. }
  68.  
  69.  
  70. static __inline__ unsigned char fd_inb(int port)
  71. {
  72.     if(MACH_IS_Q40)
  73.         return inb_p(port);
  74.     else if(MACH_IS_SUN3X)
  75.         return sun3x_82072_fd_inb(port);
  76.     return 0;
  77. }
  78.  
  79. static __inline__ void fd_outb(unsigned char value, int port)
  80. {
  81.     if(MACH_IS_Q40)
  82.         outb_p(value, port);
  83.     else if(MACH_IS_SUN3X)
  84.         sun3x_82072_fd_outb(value, port);
  85. }
  86.  
  87.  
  88. static int fd_request_irq(void)
  89. {
  90.     if(MACH_IS_Q40)
  91.         return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT,
  92.                            "floppy", floppy_hardint);
  93.     else if(MACH_IS_SUN3X)
  94.         return sun3xflop_request_irq();
  95.     return -ENXIO;
  96. }
  97.  
  98. static void fd_free_irq(void)
  99. {
  100.     if(MACH_IS_Q40)
  101.         free_irq(FLOPPY_IRQ, floppy_hardint);
  102. }
  103.  
  104. #define fd_request_dma()        vdma_request_dma(FLOPPY_DMA,"floppy")
  105. #define fd_get_dma_residue()    vdma_get_dma_residue(FLOPPY_DMA)
  106. #define fd_dma_mem_alloc(size)    vdma_mem_alloc(size)
  107. #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io)
  108.  
  109. #define fd_enable_irq()           /* nothing... */
  110. #define fd_disable_irq()          /* nothing... */
  111.  
  112. #define fd_free_dma()             /* nothing */
  113.  
  114. /* No 64k boundary crossing problems on Q40 - no DMA at all */
  115. #define CROSS_64KB(a,s) (0)
  116.  
  117. #define DMA_MODE_READ  0x44    /* i386 look-alike */
  118. #define DMA_MODE_WRITE 0x48
  119.  
  120.  
  121. static int m68k_floppy_init(void)
  122. {
  123.   use_virtual_dma =1;
  124.   can_use_virtual_dma = 1;
  125.  
  126.  
  127.   if (MACH_IS_Q40)
  128.       return 0x3f0;
  129.   else if(MACH_IS_SUN3X)
  130.       return sun3xflop_init();
  131.   else
  132.     return -1;
  133. }
  134.  
  135.  
  136. static int vdma_request_dma(unsigned int dmanr, const char * device_id)
  137. {
  138.     return 0;
  139. }
  140.  
  141.  
  142. static int vdma_get_dma_residue(unsigned int dummy)
  143. {
  144.     return virtual_dma_count + virtual_dma_residue;
  145. }
  146.  
  147.  
  148. static unsigned long vdma_mem_alloc(unsigned long size)
  149. {
  150.     return (unsigned long) vmalloc(size);
  151.  
  152. }
  153.  
  154. static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
  155. {
  156.         vfree((void *)addr);
  157. }
  158. #define fd_dma_mem_free(addr,size) _fd_dma_mem_free(addr, size)
  159.  
  160.  
  161. /* choose_dma_mode ???*/
  162.  
  163. static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
  164. {
  165.     doing_pdma = 1;
  166.     virtual_dma_port = (MACH_IS_Q40 ? io : 0);
  167.     virtual_dma_mode = (mode  == DMA_MODE_WRITE);
  168.     virtual_dma_addr = addr;
  169.     virtual_dma_count = size;
  170.     virtual_dma_residue = 0;
  171.     return 0;
  172. }
  173.  
  174.  
  175.  
  176. static void fd_disable_dma(void)
  177. {
  178.     doing_pdma = 0;
  179.     virtual_dma_residue += virtual_dma_count;
  180.     virtual_dma_count=0;
  181. }
  182.  
  183.  
  184.  
  185. /* this is the only truly Q40 specific function */
  186.  
  187. asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
  188.                       struct pt_regs *regs)
  189. {
  190.     register unsigned char st;
  191.  
  192. #undef TRACE_FLPY_INT
  193. #define NO_FLOPPY_ASSEMBLER
  194.  
  195. #ifdef TRACE_FLPY_INT
  196.     static int calls=0;
  197.     static int bytes=0;
  198.     static int dma_wait=0;
  199. #endif
  200.     if(!doing_pdma) {
  201.         floppy_interrupt(irq, dev_id, regs);
  202.         return IRQ_HANDLED;
  203.     }
  204.  
  205. #ifdef TRACE_FLPY_INT
  206.     if(!calls)
  207.         bytes = virtual_dma_count;
  208. #endif
  209.  
  210.     {
  211.         register int lcount;
  212.         register char *lptr;
  213.  
  214.         /* serve 1st byte fast: */
  215.  
  216.         st=1;
  217.         for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
  218.             lcount; lcount--, lptr++) {
  219.             st=inb(virtual_dma_port+4) & 0xa0 ;
  220.             if(st != 0xa0)
  221.                 break;
  222.             if(virtual_dma_mode)
  223.                 outb_p(*lptr, virtual_dma_port+5);
  224.             else
  225.                 *lptr = inb_p(virtual_dma_port+5);
  226.         }
  227.  
  228.         virtual_dma_count = lcount;
  229.         virtual_dma_addr = lptr;
  230.         st = inb(virtual_dma_port+4);
  231.     }
  232.  
  233. #ifdef TRACE_FLPY_INT
  234.     calls++;
  235. #endif
  236.     if(st == 0x20)
  237.         return IRQ_HANDLED;
  238.     if(!(st & 0x20)) {
  239.         virtual_dma_residue += virtual_dma_count;
  240.         virtual_dma_count=0;
  241. #ifdef TRACE_FLPY_INT
  242.         printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
  243.                virtual_dma_count, virtual_dma_residue, calls, bytes,
  244.                dma_wait);
  245.         calls = 0;
  246.         dma_wait=0;
  247. #endif
  248.         doing_pdma = 0;
  249.         floppy_interrupt(irq, dev_id, regs);
  250.         return IRQ_HANDLED;
  251.     }
  252. #ifdef TRACE_FLPY_INT
  253.     if(!virtual_dma_count)
  254.         dma_wait++;
  255. #endif
  256.     return IRQ_HANDLED;
  257. }
  258.  
  259. #define EXTRA_FLOPPY_PARAMS
  260.