亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? dma

?? 是關于linux2.5.1的完全源碼
??
字號:
Support functions for the SA11x0 internal DMA channels======================================================Nicolas Pitre <nico@cam.org>Last updated: 2001/07/15The DMA controller consists of six independent DMA channels. Each channelcan be configured to service any of the serial controllers. Two channelsare required to service a full-duplex serial controller. The DMAcontroller is intended to relieve the processor of the interrupt overheadin servicing these ports with programmed I/ O.If desired, any or all peripherals (except the UDC) may be serviced withprogrammed I/ O instead of DMA. Each peripheral is capable of requestingprocessor service through its own interrupt lines or through a DMArequest.A set of functions is provided to support drivers working with DMA buffersthrough a generic interface for (wishfully) all DMA usages.  Thosefunctions will take care of buffer queueing and splitting, DMA registermanagement, interrupt handling, etc.SA11x0 DMA API--------------Here is the description for the DMA API.int sa1100_request_dma( dmach_t *channel, const char *device_id,			dma_device_t device );This function will search for a free DMA channel and returns the channelnumber in '*channel'.  'device_id' should point to a string identifyingthe DMA usage or device (mainly for /proc).  'device' is the SA11x0peripheral's ports.  Note that reading from a port and writing to thesame port are actually considered as two different streams requiringtwo DMA channels with their own device type.  All possible dma_device_tare defined in include/asm-arm/arch-sa1100/dma.h.  If no channel isavailable, or if the desired device is already in use by another DMAchannel, then an error code is returned.  This function must be calledbefore any other DMA calls.int sa1100_dma_queue_buffer( dmach_t channel, void *buf_id,                             dma_addr_t data, int size );This function enqueue the specified buffer for DMA processing.  The bufferwill be transmitted or filled with incoming data depending on the channelconfiguration made through sa1100_dma_set_device().  If the queue isempty, DMA starts immediately on the given buffer.Arguments are:dmach_t channel:	the channel number.void *buf_id:		a buffer identification known by the caller.dma_addr_t data:	the buffer's physical address.int size:		the buffer size in bytes.Note here the dma_addr_t which is not the same as the virtual address asreturned by kmalloc() and friends.  The DMA controller must be given aphysical address to a buffer which is not cached bye the CPU data cache.To get such address, the DMA mapping functions (seeDocumentation/DMA-mapping.txt) are recommended.  The only relevantfunctions are pci_alloc_consistent(), pci_map_single() and their unmapcounterparts.  The PCI dev argument is NULL of course.There is no restriction on the buffer size.  The DMA code will split it upinternally to acommodate the DMA controller as needed.  If the buffercan't be enqueued the appropriate error code is returned.int sa1100_dma_set_callback( dmach_t channel, dma_callback_t cb );As soon as the DMa completes with a buffer, a callback function is used tonotify the driver which would have registered one.  The callback functionis prototyped as:void dma_callback( void *buf_id, int size );The 'buf_id' argument is the buffer identifier as passed tosa1100_dma_queue_buffer().  The 'size' argument is the number of bytes theDMA processed (should be the same as the buffer size).Note that this callback function is called while in interrupt context.So it has to be small and efficient while posponing more complexprocessing to a bottom-half function or similar.  Allrestrictions for interrupt handlers still apply.int sa1100_dma_get_current( dmach_t channel, void **buf_id,                            dma_addr_t *addr );This returns the buffer ID and the DMA address pointer within the buffercurrently being processed.  If no such buffer is currently processed, anerror code is returned.  This is useful for mmap()'ed buffers like inaudio drivers.int sa1100_dma_stop( dmach_t channel );This call stops any DMA transfer on the given channel.int sa1100_dma_resume( dmach_t channel );This call resumes a DMA transfer which would have been stopped throughsa1100_dma_stop().int sa1100_dma_flush_all( dmach_t channel );This completely flushes all queued buffers and on-going DMA transfers on agiven channel.  The next enqueued buffer following this call will beprocessed right away.int sa1100_dma_set_spin( dmach_t channel, dma_addr_t addr, int size );Because there is at least one device out there that uses its receivesignal for its transmit clock reference, we need a mecanism to make theDMA "spin" on a certain buffer for when there is no more actual buffer toprocess.  The 'addr' argument is the physical memory address to use, andthe 'size' argument determines the spin DMA chunk.  This size can't belarger than 8191 (if so, it is clamped to 4096).  When the size is 0,the spin function is turned off.When activated, DMA will "spin" until there is any buffer in the queue.The current DMA chunk will terminate before a newly queued buffer isprocessed.  The spin buffer will only be reused when there is no moreacctual buffer to process.It is important not to choose a too small 'size' value since it willgreatly increase the interrupt load required to restart the spin.  Sincethis feature will typically be used on transmit DMAs, and because a bufferfull of zeros is probably the best thing to spin out, the 'addr' argumentmay well be used with FLUSH_BASE_PHYS for which no allocation nor memorybus request are needed.The spinning DMA is affected by sa1100_dma_stop() and sa1100_dma_resume()but not bu sa1100_dma_flush_all().void sa1100_free_dma( dmach_t channel );This clears all activities on a given DMA channel and releases it forfuture requests.Buffer allocation-----------------Like mentionned above, it is the driver's responsibility to allocate, freeand keep track of buffer space with dma_addr_t type addresses. However thedriver must not change the state of any buffer after it has been sent tosa1100-dma_queue_buffer().  When that function has been called, the bufferbecomes the DMA's ownership until one of these events occur:- The callback function is called by the DMA code with a buffer ID to  indicate that DMA processing terminated on that buffer.  Then the  driver owns the buffer again.- The sa1100-dma_flush_all() function is called by the driver at which  point *all* queued buffers are owned by the driver again.- The sa1100-free_dma() does the same as sa1100-dma_flush_all().This doesn't mean that you can't change the content of a queued buffer inconjonction with the usage of pci_map_consistent() andsa1100_dma_get_current()... but then you must be sure you know what you'redoing (this doesn't work with pci_map_single()).Examples--------A real example of audio ring buffers is implemented in thedrivers/sound/sa1100-audio.c driver.  The SA1110 USB client and theSA11x0 FIR drivers are also using this interface to implement packetizedDMA.A transmit DMA for network packets could look like this (largely simplified):struct sk_buff *tx_ring_skb[RING_SIZE];dma_addr_t      tx_ring_dma[RING_SIZE];int cur_tx;...transmit function:	tx_ring_skb[cur_tx] = skb;	tx_ring_dma[cur_tx] = pci_map_single(NULL, skb->data, skb->len,	                                     PCI_DMA_TODEVICE);	sa1100_dma_queue_buffer(channel, (void*)cur_tx,	                        tx_ring_dma[cur_tx], skb->len);	cur_tx++; cur_tx %= RING_SIZE;	...and the callback function:void tx_done_callback( void *buf_id, int size ) {	int done_tx = (int) buf_id;	struct sk_buff *skb = tx_ring_skb[done_tx];	pci_unmap_single(NULL, tx_ring_dma[done_tx], skb->len,	                 PCI_DMA_TODEVICE);	stats.tx_packets++;	stats.tx_bytes += size;	dev_kfree_skb_irq(skb);	tx_ring_skb[done_tx] = NULL;}For drivers expecting variable length packets i.e. USB client, it isnecessary to register the appropriate IRQ to be notified when the receiveris idle, the packet is complete, etc.  We could use one buffer at a timewith its ID being the virtual address of the buffer.Then the sequence:	/* be sure DMA won't continue under our feet */	sa1100_dma_stop(channel);	/* get the actual DMA length */	sa1100_get_current(channel, &data, &dma_ptr);	/* acquire ownership for the buffer */	sa1100_dma_flush_all(channel);	/* unmap the DMA buffer (actually doing cache coherency on ARM) */	pci_unmap_single (NULL, dma_addr, MAX_PKT_SIZE, PCI_DMA_FROMDEVICE);	/* get remaining bytes from the fifo */	ptr = data + dma_ptr - dma_addr;	while (fifo_not_empty)		*ptr++ = get_byte_from_fifo;	/* feed another free buffer for the next packet */	dma_addr2 = pci_map_single(NULL, data2, MAX_PKT_SIZE,					PCI_DMA_FROMDEVICE);	sa1100_dma_queue_buffer(channel, data2, dma_addr2, MAX_PKT_SIZE);	/* process the current packet */	...might do the trick.  This looks a bit ugly but that's a starting point forimprovements.TODO----- Create kernel-doc comments in the source to document the API and  let the documentation be generated automatically.

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲精品国久久99热| 欧美日韩一区二区三区四区| 91精品国产综合久久香蕉的特点 | 99精品视频在线观看免费| 91精品国产综合久久精品麻豆| 国产精品免费丝袜| 美女一区二区三区| 色婷婷av一区二区三区大白胸| 久久久精品国产免大香伊 | 国产无人区一区二区三区| 日韩在线观看一区二区| 91网页版在线| 欧美国产视频在线| 精品一区二区三区蜜桃| 91麻豆精品国产91久久久久久 | www国产成人| 午夜精品久久久久久久99水蜜桃 | 国产91在线观看| 欧美一区二区三区性视频| 亚洲一区在线视频| 色婷婷精品久久二区二区蜜臀av| 久久这里都是精品| 经典三级一区二区| 日韩一级片在线观看| 亚洲国产cao| 欧美在线观看一区| 中文字幕一区在线观看| 风间由美一区二区三区在线观看| 精品av久久707| 久久99日本精品| 日韩一区二区在线看| 日产国产高清一区二区三区 | 国产乱码精品一区二区三| 欧美一区二区视频在线观看2022| 亚洲国产精品一区二区久久恐怖片| 91麻豆精品一区二区三区| 国产精品久久久久精k8| 波多野结衣在线aⅴ中文字幕不卡| 久久精品人人做人人综合| 国内精品久久久久影院一蜜桃| 日韩精品综合一本久道在线视频| 蜜臀av性久久久久蜜臀aⅴ| 91精品一区二区三区久久久久久| 视频在线观看一区| 欧美一区二区三区四区久久| 日韩精品电影一区亚洲| 欧美一区二区三区的| 日本女人一区二区三区| 欧美一区二区三区四区在线观看| 日韩不卡一区二区三区| 日韩亚洲欧美在线| 蜜臂av日日欢夜夜爽一区| 日韩免费在线观看| 国产精品一区二区黑丝| 久久精品欧美日韩精品 | 天天av天天翘天天综合网| 欧美日韩视频一区二区| 日韩中文字幕91| 精品少妇一区二区三区| 国产成人在线网站| 最新高清无码专区| 欧美在线制服丝袜| 日韩成人精品在线观看| 久久综合成人精品亚洲另类欧美| 国产成人精品影院| 一区二区三区四区乱视频| 欧美色综合网站| 久久99久久久欧美国产| 欧美激情在线一区二区| 91麻豆精品一区二区三区| 亚洲成av人片一区二区三区 | 91久久久免费一区二区| 日韩电影在线观看网站| 久久久天堂av| 色嗨嗨av一区二区三区| 日韩av中文字幕一区二区 | 欧美人与禽zozo性伦| 麻豆精品视频在线观看视频| 国产女人aaa级久久久级 | 91在线一区二区三区| 亚洲国产aⅴ成人精品无吗| 91麻豆精品国产无毒不卡在线观看| 国产在线观看一区二区| 亚洲天堂福利av| 91精品国产综合久久香蕉的特点 | 日韩电影在线观看网站| 国产日产欧美一区二区视频| 91久久精品一区二区二区| 秋霞午夜鲁丝一区二区老狼| 国产亚洲欧美色| 欧美又粗又大又爽| 国内成人精品2018免费看| 自拍偷拍欧美激情| 日韩欧美一区二区久久婷婷| 9色porny自拍视频一区二区| 日韩国产一区二| 一区在线观看免费| 日韩三级视频在线看| 99视频精品全部免费在线| 日韩av电影天堂| 亚洲少妇30p| 精品久久久久久久人人人人传媒| 97se亚洲国产综合自在线不卡| 免费观看在线综合| 亚洲精品一二三四区| 精品国产乱码久久久久久牛牛| 色悠久久久久综合欧美99| 激情av综合网| 亚洲地区一二三色| 国产精品视频一二| 欧美xxxxx牲另类人与| 色婷婷久久久亚洲一区二区三区| 国产精品主播直播| 日韩成人一区二区| 亚洲精品国产a久久久久久| 久久久精品国产免大香伊| 欧美男生操女生| 91视频在线看| 国产aⅴ综合色| 麻豆精品一区二区三区| 亚洲成人激情综合网| 亚洲人成影院在线观看| 久久久久久久精| 日韩天堂在线观看| 欧美影院一区二区三区| 99精品一区二区| 高清beeg欧美| 国产一区二区三区免费播放| 天天操天天干天天综合网| 伊人婷婷欧美激情| 国产精品久久久一区麻豆最新章节| 日韩欧美中文字幕精品| 欧美精品tushy高清| 欧洲一区二区av| 97精品国产露脸对白| 成人国产精品免费观看动漫| 国产一区二区h| 狠狠色狠狠色合久久伊人| 麻豆久久久久久| 日本aⅴ精品一区二区三区 | 国产偷国产偷精品高清尤物 | 91麻豆精东视频| 99re热这里只有精品视频| 成人午夜电影小说| 国产一区二区美女| 国内精品免费**视频| 激情深爱一区二区| 精品亚洲欧美一区| 九九热在线视频观看这里只有精品| 日韩 欧美一区二区三区| 婷婷六月综合亚洲| 婷婷国产在线综合| 天堂一区二区在线| 五月天亚洲婷婷| 三级久久三级久久久| 婷婷中文字幕综合| 欧美aⅴ一区二区三区视频| 日本一区中文字幕| 日本女人一区二区三区| 免费人成精品欧美精品| 美女脱光内衣内裤视频久久影院| 琪琪一区二区三区| 九九热在线视频观看这里只有精品| 久久国产精品99久久久久久老狼| 久久不见久久见免费视频1| 韩国精品免费视频| 高清不卡一二三区| 99久久精品国产网站| 91在线免费播放| 欧美综合色免费| 欧美日韩亚洲综合一区二区三区| 欧美日韩精品综合在线| 欧美一区二区三区人| 精品久久五月天| 国产欧美中文在线| 亚洲品质自拍视频| 午夜私人影院久久久久| 蜜臀精品久久久久久蜜臀| 国产主播一区二区| www.色精品| 欧美亚洲一区二区三区四区| 欧美一区二区在线观看| 久久久精品国产免大香伊 | 精品免费视频一区二区| 国产日韩亚洲欧美综合| 亚洲欧美在线高清| 亚洲在线视频网站| 久久精品国产在热久久| 国产麻豆精品视频| 色综合久久天天| 3d成人h动漫网站入口| 久久综合久久鬼色| 国产精品乱码一区二区三区软件 | 依依成人精品视频| 美女脱光内衣内裤视频久久网站 | 麻豆一区二区99久久久久| 国产99久久久久久免费看农村| 在线观看区一区二| 精品国产91亚洲一区二区三区婷婷| 国产精品久久久久久久久动漫 |