Ядро Linux в комментариях

       

Kernel/dma.c


22689 /* $Id: dma.c,v 1.7 1994/12/28 03:35:33 root Exp root $ 22690 * linux/kernel/dma.c: A DMA channel allocator. Inspired 22691 * by linux/kernel/irq.c. 22692 * 22693 * Written by Hennus Bergman, 1992. 22694 * 22695 * 1994/12/26: Changes by Alex Nash to fix a minor bug in 22696 * /proc/dma. In the previous version the reported 22697 * device could end up being wrong, if a device requested 22698 * a DMA channel that was already in use. [It also 22699 * happened to remove the sizeof(char *) == sizeof(int) 22700 * assumption introduced because of those /proc/dma 22701 * patches. -- Hennus] 22702 */ 22703 22704 #include <linux/kernel.h> 22705 #include <linux/errno.h> 22706 #include <asm/dma.h> 22707 #include <asm/system.h> 22708 #include <asm/spinlock.h> 22709 22710 /* A note on resource allocation: 22711 * 22712 * All drivers needing DMA channels, should allocate and 22713 * release them through the public routines 22714 * `request_dma()' and `free_dma()'. 22715 * 22716 * In order to avoid problems, all processes should 22717 * allocate resources in the same sequence and release 22718 * them in the reverse order. 22719 * 22720 * So, when allocating DMAs and IRQs, first allocate the 22721 * IRQ, then the DMA. When releasing them, first release 22722 * the DMA, then release the IRQ. If you don't, you may 22723 * cause allocation requests to fail unnecessarily. This 22724 * doesn't really matter now, but it will once we get 22725 * real semaphores in the kernel. */ 22726 22727 spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED; 22728 22729 /* Channel n is busy iff dma_chan_busy[n].lock != 0. 22730 * DMA0 used to be reserved for DRAM refresh, but 22731 * apparently not any more... DMA4 is reserved for 22732 * cascading. */ 22733 struct dma_chan { 22734 int lock; 22735 const char *device_id; 22736 }; 22737 22738 static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] ={ 22739 { 0, 0 }, 22740 { 0, 0 }, 22741 { 0, 0 }, 22742 { 0, 0 }, 22743 { 1, "cascade" }, 22744 { 0, 0 }, 22745 { 0, 0 }, 22746 { 0, 0 } 22747 }; 22748 22749 int get_dma_list(char *buf) 22750 { 22751 int i, len = 0; 22752 22753 for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { 22754 if (dma_chan_busy[i].lock) { 22755 len += sprintf(buf+len, "%2d: %s\n", 22756 i, 22757 dma_chan_busy[i].device_id); 22758 } 22759 } 22760 return len; 22761 } /* get_dma_list */ 22762 22763 22764 int request_dma(unsigned int dmanr, 22765 const char * device_id) 22766 { 22767 if (dmanr >= MAX_DMA_CHANNELS) 22768 return -EINVAL; 22769 22770 if (xchg(&dma_chan_busy[dmanr].lock, 1) != 0) 22771 return -EBUSY; 22772 22773 dma_chan_busy[dmanr].device_id = device_id; 22774 22775 /* old flag was 0, now contains 1 to indicate busy */ 22776 return 0; 22777 } /* request_dma */ 22778 22779 22780 void free_dma(unsigned int dmanr) 22781 { 22782 if (dmanr >= MAX_DMA_CHANNELS) { 22783 printk("Trying to free DMA%d\n", dmanr); 22784 return; 22785 } 22786 22787 if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) { 22788 printk("Trying to free free DMA%d\n", dmanr); 22789 return; 22790 } 22791 22792 } /* free_dma */



Содержание раздела