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

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

?? dma

?? 該文件是rt_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一区二区三区免费野_久草精品视频
高清在线成人网| 日韩欧美中文字幕精品| 欧美日韩精品电影| 国产欧美日产一区| 五月天亚洲精品| www.亚洲人| xvideos.蜜桃一区二区| 一区二区久久久| 国产激情一区二区三区桃花岛亚洲| 欧美亚洲另类激情小说| 中文一区一区三区高中清不卡| 午夜精品免费在线| 色婷婷综合久久久久中文| 久久久亚洲综合| 日韩电影在线一区| 在线观看成人小视频| 日本一区二区三区四区在线视频| 日本不卡一区二区| 欧美探花视频资源| 亚洲免费观看高清完整版在线观看熊| 国产乱码精品一区二区三| 欧美肥妇free| 五月天亚洲婷婷| 欧美另类久久久品| 午夜精品福利在线| 91精品国产综合久久精品性色 | 久久国产精品72免费观看| 在线欧美一区二区| 亚洲美女屁股眼交| 一本高清dvd不卡在线观看| 国产亚洲精品bt天堂精选| 久久精品免费看| 精品国产第一区二区三区观看体验| 午夜久久久影院| 欧美美女bb生活片| 日本不卡123| 日韩精品一区在线观看| 久久国产精品色婷婷| 337p粉嫩大胆色噜噜噜噜亚洲| 天天av天天翘天天综合网色鬼国产| 欧美吻胸吃奶大尺度电影| 一级中文字幕一区二区| 欧美四级电影在线观看| 亚洲国产成人porn| 3d动漫精品啪啪一区二区竹菊| 婷婷成人激情在线网| 欧美一区二区精美| 韩日欧美一区二区三区| 国产欧美日韩综合| 91麻豆免费看| 日韩电影在线观看电影| 精品入口麻豆88视频| 国产suv精品一区二区6| 亚洲欧美视频在线观看| 欧美性色aⅴ视频一区日韩精品| 亚洲成人一区二区在线观看| 欧美日韩aaa| 国产毛片精品视频| 成人欧美一区二区三区| 在线视频中文字幕一区二区| 日本网站在线观看一区二区三区 | 在线看国产一区二区| 午夜精品一区二区三区三上悠亚| 精品日本一线二线三线不卡| 国产999精品久久| 亚洲国产日韩a在线播放性色| 91精品国产福利在线观看| 国产精品一区二区不卡| 亚洲免费在线观看视频| 日韩一级免费一区| 色综合夜色一区| 激情都市一区二区| 亚洲国产一区二区三区青草影视| 欧美一级片在线看| 一本色道久久加勒比精品| 狂野欧美性猛交blacked| 国产日产精品1区| 欧美电影影音先锋| 成人午夜电影小说| 日本美女一区二区| 亚洲另类春色校园小说| 久久久国产精品不卡| 欧美色欧美亚洲另类二区| 国产宾馆实践打屁股91| 日本少妇一区二区| 一区二区在线观看不卡| 精品国产青草久久久久福利| 在线观看亚洲专区| 99久久精品一区| 久久国产福利国产秒拍| 亚洲国产一二三| 亚洲久草在线视频| 中文字幕免费不卡| 2021中文字幕一区亚洲| 欧美私人免费视频| 成人教育av在线| 国产精品888| 韩国av一区二区三区四区| 婷婷激情综合网| 午夜私人影院久久久久| 1024成人网色www| 欧美极品aⅴ影院| 久久影视一区二区| 日韩一级在线观看| 欧美一区二区三区不卡| 欧美伊人久久久久久久久影院| 99这里只有精品| 丁香天五香天堂综合| 国产精品自拍网站| 韩国一区二区在线观看| 蜜臀av性久久久久蜜臀aⅴ| 亚洲成av人影院| 亚洲国产成人tv| 亚洲成人动漫av| 亚洲成人一区二区| 天天色 色综合| 视频一区二区国产| 日韩成人精品在线| 日韩av一级片| 精品亚洲国内自在自线福利| 麻豆久久久久久久| 开心九九激情九九欧美日韩精美视频电影| 日韩福利视频网| 久久99久久99小草精品免视看| 精品影视av免费| 国产在线一区二区综合免费视频| 美女视频免费一区| 国产一区999| 成人av电影在线网| 91蝌蚪国产九色| 精品1区2区3区| 91精品国产欧美一区二区18| 日韩一区二区在线看片| 精品噜噜噜噜久久久久久久久试看| 日韩欧美亚洲国产精品字幕久久久| 日韩欧美成人一区二区| 精品剧情v国产在线观看在线| 337p粉嫩大胆色噜噜噜噜亚洲| 久久精品一区二区| 综合激情网...| 亚洲综合色在线| 美女性感视频久久| 福利一区二区在线观看| 99综合电影在线视频| 欧美人牲a欧美精品| 久久亚洲综合av| 一区二区成人在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎 | 国产精品视频一区二区三区不卡| 国产精品毛片高清在线完整版| 一区二区三区四区乱视频| 天堂一区二区在线| 丁香激情综合五月| 精品1区2区3区| 欧美韩日一区二区三区四区| 亚洲精品美国一| 久草这里只有精品视频| 91原创在线视频| 欧美本精品男人aⅴ天堂| 国产精品福利一区二区三区| 亚洲高清免费一级二级三级| 国产剧情一区二区| 欧美在线观看18| 国产欧美1区2区3区| 肉色丝袜一区二区| 9i在线看片成人免费| 精品免费一区二区三区| 亚洲国产一区二区三区| 国产成a人亚洲| 91麻豆精品91久久久久同性| 国产精品欧美精品| 久久国内精品自在自线400部| 色综合天天性综合| 久久久久久久久久久99999| 亚洲国产毛片aaaaa无费看| 懂色av一区二区三区免费观看| 7777精品伊人久久久大香线蕉经典版下载 | 欧美中文字幕一区二区三区| 久久免费国产精品| 亚洲成av人片一区二区梦乃| 成人av在线看| 欧美精品一区二区三区在线播放| 一区二区久久久| 色综合久久中文字幕| 国产欧美一区二区三区沐欲| 喷水一区二区三区| 欧美日韩免费一区二区三区| 中文字幕综合网| 国产精品自拍在线| 精品国产1区2区3区| 免播放器亚洲一区| 8x福利精品第一导航| 亚洲一区二区三区视频在线播放 | 国产精品久久久久久久久免费桃花 | 精品国产百合女同互慰| 另类成人小视频在线| 欧美一区二区在线免费观看| 天天操天天干天天综合网| 欧美日韩国产综合草草| 午夜av电影一区|