stdma.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/m68k/atari/stmda.c
  3.  *
  4.  *  Copyright (C) 1994 Roman Hodek
  5.  *
  6.  *
  7.  * This file is subject to the terms and conditions of the GNU General Public
  8.  * License.  See the file COPYING in the main directory of this archive
  9.  * for more details.
  10.  */
  11. /* This file contains some function for controlling the access to the  */
  12. /* ST-DMA chip that may be shared between devices. Currently we have:  */
  13. /*   TT:     Floppy and ACSI bus                                       */
  14. /*   Falcon: Floppy and SCSI                                           */
  15. /*                                                                     */
  16. /* The controlling functions set up a wait queue for access to the     */
  17. /* ST-DMA chip. Callers to stdma_lock() that cannot granted access are */
  18. /* put onto a queue and waked up later if the owner calls              */
  19. /* stdma_release(). Additionally, the caller gives his interrupt       */
  20. /* service routine to stdma_lock().                                    */
  21. /*                                                                     */
  22. /* On the Falcon, the IDE bus uses just the ACSI/Floppy interrupt, but */
  23. /* not the ST-DMA chip itself. So falhd.c needs not to lock the        */
  24. /* chip. The interrupt is routed to falhd.c if IDE is configured, the  */
  25. /* model is a Falcon and the interrupt was caused by the HD controller */
  26. /* (can be determined by looking at its status register).              */
  27. #include <linux/types.h>
  28. #include <linux/kdev_t.h>
  29. #include <linux/genhd.h>
  30. #include <linux/sched.h>
  31. #include <linux/init.h>
  32. #include <asm/atari_stdma.h>
  33. #include <asm/atariints.h>
  34. #include <asm/atarihw.h>
  35. #include <asm/io.h>
  36. #include <asm/irq.h>
  37. static int stdma_locked = 0; /* the semaphore */
  38. /* int func to be called */
  39. static void (*stdma_isr)(int, void *, struct pt_regs *) = NULL;
  40. static void *stdma_isr_data = NULL; /* data passed to isr */
  41. static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */
  42. /***************************** Prototypes *****************************/
  43. static void stdma_int (int irq, void *dummy, struct pt_regs *fp);
  44. /************************* End of Prototypes **************************/
  45. /*
  46.  * Function: void stdma_lock( isrfunc isr, void *data )
  47.  *
  48.  * Purpose: Tries to get a lock on the ST-DMA chip that is used by more
  49.  *   then one device driver. Waits on stdma_wait until lock is free.
  50.  *   stdma_lock() may not be called from an interrupt! You have to
  51.  *   get the lock in your main routine and release it when your
  52.  *   request is finished.
  53.  *
  54.  * Inputs: A interrupt function that is called until the lock is
  55.  *   released.
  56.  *
  57.  * Returns: nothing
  58.  *
  59.  */
  60. void stdma_lock(void (*handler)(int, void *, struct pt_regs *), void *data)
  61. {
  62. unsigned long oldflags;
  63. save_flags(oldflags);
  64. cli(); /* protect lock */
  65. while(stdma_locked)
  66. /* Since the DMA is used for file system purposes, we
  67.  have to sleep uninterruptible (there may be locked
  68.  buffers) */
  69. sleep_on(&stdma_wait);
  70. stdma_locked   = 1;
  71. stdma_isr      = handler;
  72. stdma_isr_data = data;
  73. restore_flags(oldflags);
  74. }
  75. /*
  76.  * Function: void stdma_release( void )
  77.  *
  78.  * Purpose: Releases the lock on the ST-DMA chip. 
  79.  *
  80.  * Inputs: none
  81.  *
  82.  * Returns: nothing
  83.  *
  84.  */
  85. void stdma_release(void)
  86. {
  87. unsigned long oldflags;
  88. save_flags(oldflags);
  89. cli();
  90. stdma_locked   = 0;
  91. stdma_isr      = NULL;
  92. stdma_isr_data = NULL;
  93. wake_up(&stdma_wait);
  94. restore_flags(oldflags);
  95. }
  96. /*
  97.  * Function: int stdma_others_waiting( void )
  98.  *
  99.  * Purpose: Check if someone waits for the ST-DMA lock.
  100.  *
  101.  * Inputs: none
  102.  *
  103.  * Returns: 0 if no one is waiting, != 0 otherwise
  104.  *
  105.  */
  106. int stdma_others_waiting(void)
  107. {
  108. return waitqueue_active(&stdma_wait);
  109. }
  110. /*
  111.  * Function: int stdma_islocked( void )
  112.  *
  113.  * Purpose: Check if the ST-DMA is currently locked.
  114.  * Note: Returned status is only valid if ints are disabled while calling and
  115.  *       as long as they remain disabled.
  116.  *       If called with ints enabled, status can change only from locked to
  117.  *       unlocked, because ints may not lock the ST-DMA.
  118.  *
  119.  * Inputs: none
  120.  *
  121.  * Returns: != 0 if locked, 0 otherwise
  122.  *
  123.  */
  124. int stdma_islocked(void)
  125. {
  126. return stdma_locked;
  127. }
  128. /*
  129.  * Function: void stdma_init( void )
  130.  *
  131.  * Purpose: Initialize the ST-DMA chip access controlling.
  132.  *   It sets up the interrupt and its service routine. The int is registered
  133.  *   as slow int, client devices have to live with that (no problem
  134.  *   currently).
  135.  *
  136.  * Inputs: none
  137.  *
  138.  * Return: nothing
  139.  *
  140.  */
  141. void __init stdma_init(void)
  142. {
  143. stdma_isr = NULL;
  144. request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW,
  145.             "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int);
  146. }
  147. /*
  148.  * Function: void stdma_int()
  149.  *
  150.  * Purpose: The interrupt routine for the ST-DMA. It calls the isr
  151.  *   registered by stdma_lock().
  152.  *
  153.  */
  154. static void stdma_int(int irq, void *dummy, struct pt_regs *fp)
  155. {
  156.   if (stdma_isr)
  157.       (*stdma_isr)(irq, stdma_isr_data, fp);
  158. }