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

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

?? dma

?? 一個2.4.21版本的嵌入式linux內核
??
字號:
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一区二区三区免费野_久草精品视频
蜜臀精品久久久久久蜜臀| 免费成人在线网站| 成人午夜视频网站| 日韩欧美一二三| 一区二区三国产精华液| 成人午夜又粗又硬又大| 久久亚洲综合色一区二区三区| 午夜视频一区二区| 在线看日韩精品电影| 国产精品欧美一级免费| 国产精品综合一区二区三区| 日韩精品在线看片z| 午夜精品一区二区三区免费视频 | 欧美激情一区二区三区| 久久精品国产77777蜜臀| 欧美三级蜜桃2在线观看| 亚洲人成网站在线| 成人av在线电影| 日本一区二区不卡视频| 国产一区二区在线看| 日韩欧美精品在线视频| 一区二区三区日韩精品视频| 成人av第一页| 亚洲国产精品精华液2区45| 久久精品噜噜噜成人88aⅴ| 91精品国产91久久久久久最新毛片 | 成人精品国产一区二区4080| 久久日韩粉嫩一区二区三区| 精久久久久久久久久久| 欧美大度的电影原声| 亚洲影院免费观看| 日本精品一区二区三区高清 | 久久综合色天天久久综合图片| 青椒成人免费视频| 欧美一区二区三区在线观看| 午夜伦理一区二区| 欧美年轻男男videosbes| 丝瓜av网站精品一区二区| 欧美老肥妇做.爰bbww视频| 无码av免费一区二区三区试看| 欧美怡红院视频| 亚洲国产精品麻豆| 欧美日韩不卡在线| 奇米在线7777在线精品| 欧美大黄免费观看| 日本在线不卡一区| 欧美电影免费观看高清完整版在线观看| 日韩中文欧美在线| 日韩一级片网址| 精品无人码麻豆乱码1区2区| 久久久久久免费网| k8久久久一区二区三区| 最新不卡av在线| 欧美三级午夜理伦三级中视频| 五月天一区二区| 日韩欧美区一区二| 国产高清精品久久久久| 国产精品久久看| 在线亚洲免费视频| 视频精品一区二区| 欧美成人猛片aaaaaaa| 毛片一区二区三区| 久久久久国产精品麻豆ai换脸| 懂色av噜噜一区二区三区av| 亚洲欧美aⅴ...| 欧美日韩国产色站一区二区三区| 麻豆精品国产91久久久久久| 欧美变态tickling挠脚心| 国产精品一区二区不卡| 日韩美女视频19| 欧美精品在线一区二区三区| 国产自产v一区二区三区c| 国产精品人成在线观看免费| 日本伦理一区二区| 亚洲成a人片综合在线| 精品国产一区二区三区忘忧草 | 国产精品自拍网站| 亚洲欧美激情视频在线观看一区二区三区| 欧美亚洲高清一区| 激情综合色播激情啊| 日韩一区欧美一区| 欧美丰满少妇xxxxx高潮对白| 久久福利资源站| 中文字幕一区在线观看| 久久精子c满五个校花| 日本乱人伦aⅴ精品| 九色综合国产一区二区三区| 日韩理论片中文av| 欧美一二三区在线观看| 国产成a人亚洲精| 午夜视黄欧洲亚洲| 中文字幕欧美国产| 在线不卡的av| 国产成人av资源| 婷婷综合另类小说色区| 日本一区免费视频| 在线播放91灌醉迷j高跟美女| 成人一区二区三区在线观看| 午夜精品久久久久久久久| 久久综合九色综合欧美就去吻 | 国产一二精品视频| 亚洲视频小说图片| 精品国精品国产| 欧美色综合久久| 国产不卡视频在线观看| 视频精品一区二区| 亚洲欧美日韩成人高清在线一区| 91精品免费观看| 福利视频网站一区二区三区| 日本美女一区二区三区| 亚洲色图欧美激情| 久久久久久久久99精品| 欧美猛男男办公室激情| 色综合天天综合给合国产| 美女网站色91| 亚洲午夜免费电影| 国产精品久久久久一区二区三区| 欧美成人午夜电影| 欧美日本免费一区二区三区| 国产麻豆一精品一av一免费 | 一区在线观看免费| 精品国产髙清在线看国产毛片| 色老综合老女人久久久| 国内精品免费在线观看| 樱花草国产18久久久久| 国产精品传媒视频| 久久久噜噜噜久噜久久综合| 欧美午夜精品一区二区三区| www.日本不卡| 国产成人综合亚洲网站| 美女视频黄a大片欧美| 午夜电影网一区| 午夜伊人狠狠久久| 亚洲成av人影院| 婷婷开心激情综合| 日韩专区中文字幕一区二区| 日韩国产高清影视| 日本欧美韩国一区三区| 青草国产精品久久久久久| 捆绑紧缚一区二区三区视频| 久久国内精品自在自线400部| 九九视频精品免费| 国产一区二区三区四| 国产高清无密码一区二区三区| 国产一区 二区 三区一级| 国产精品12区| 成人精品一区二区三区四区| 99国内精品久久| 91国偷自产一区二区开放时间| 欧美中文字幕一区二区三区亚洲| 欧美日韩在线播放三区四区| 制服视频三区第一页精品| 日韩欧美一区二区不卡| 久久久亚洲午夜电影| 国产精品―色哟哟| 亚洲精品高清视频在线观看| 亚洲第一主播视频| 青青草国产成人av片免费| 国产一区二区三区在线观看免费| 丁香婷婷综合色啪| 日本乱码高清不卡字幕| 欧美一区二区三区色| 久久久久久久久久久久久久久99 | 欧美丝袜第三区| 在线不卡a资源高清| 欧美mv日韩mv| 中文字幕av一区二区三区高| 亚洲综合无码一区二区| 免费人成网站在线观看欧美高清| 国内成人免费视频| 成人av在线影院| 国产精品高潮呻吟久久| 亚洲线精品一区二区三区| 日本视频在线一区| 国产高清不卡一区| 在线观看中文字幕不卡| 日韩一级黄色大片| 国产精品理论片在线观看| 亚洲综合视频在线观看| 精品一区二区三区免费毛片爱| jlzzjlzz亚洲日本少妇| 欧美丰满高潮xxxx喷水动漫| 国产夜色精品一区二区av| 亚洲黄色免费网站| 美脚の诱脚舐め脚责91| 99久久精品免费| 欧美一区二区三区视频| 国产精品视频线看| 午夜精品一区二区三区三上悠亚| 国产一区二三区好的| 欧美系列一区二区| 国产亚洲精品aa午夜观看| 亚洲国产精品自拍| 岛国一区二区三区| 欧美一区永久视频免费观看| 国产精品国产三级国产三级人妇| 男男gaygay亚洲| 色一情一伦一子一伦一区| 久久综合国产精品| 亚洲午夜精品网|