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

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? dma

?? MIZI Research, Inc.發(fā)布的嵌入式Linux內(nèi)核源碼
??
字號(hào):
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.

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色综合视频一区二区三区高清| 日本中文在线一区| 精品理论电影在线观看 | 欧美优质美女网站| 天堂一区二区在线| 一区二区三区蜜桃网| 欧美日韩五月天| 国产一区二区三区国产| 国产精品毛片久久久久久| 欧美熟乱第一页| 国产99久久久国产精品潘金| 看电视剧不卡顿的网站| 国产精品久久久久久久久图文区 | 亚洲午夜视频在线观看| 欧美日韩国产另类一区| 色中色一区二区| 欧美精品精品一区| 国产片一区二区三区| 蜜臀久久99精品久久久久宅男| 一区二区三区波多野结衣在线观看| 乱一区二区av| 91看片淫黄大片一级| 亚洲图片欧美视频| 欧美巨大另类极品videosbest | 成人av网站大全| 久久精品夜色噜噜亚洲a∨| 精品福利一区二区三区| 麻豆视频一区二区| 亚洲男人的天堂av| 91片黄在线观看| 午夜欧美在线一二页| 国产午夜精品一区二区| 韩国一区二区视频| 亚洲欧美日韩成人高清在线一区| 香蕉加勒比综合久久| 国产精品传媒视频| 91精品国产综合久久久久| 青青草97国产精品免费观看无弹窗版| 成人免费黄色在线| 蜜桃av一区二区| 亚洲日本欧美天堂| 精品国产伦一区二区三区免费 | 精品久久久影院| 欧美精品在线一区二区三区| 久久久久久日产精品| 欧美一区二区三区婷婷月色| 波多野洁衣一区| 亚洲福利国产精品| 午夜婷婷国产麻豆精品| 美女一区二区视频| 国产精品亚洲视频| 91免费观看视频在线| 欧美午夜宅男影院| 精品成a人在线观看| 日韩美一区二区三区| 欧美体内she精高潮| 欧美一区二区视频在线观看2020| 欧美亚洲国产一区在线观看网站 | 久久先锋影音av鲁色资源网| 2023国产一二三区日本精品2022| 欧美日韩国产高清一区二区三区 | 欧美在线免费播放| 欧美成人在线直播| 国产精品久久久久久妇女6080| 国产亚洲欧洲一区高清在线观看| 日韩一卡二卡三卡四卡| 99精品在线免费| 91精品欧美综合在线观看最新| 成人av中文字幕| 3751色影院一区二区三区| 久久久久久久久久久电影| 亚洲综合精品自拍| 日本亚洲最大的色成网站www| 亚洲一区二区成人在线观看| 日本va欧美va瓶| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲精品视频在线观看网站| 免费高清成人在线| 色一情一伦一子一伦一区| 91麻豆视频网站| 色香色香欲天天天影视综合网| 成人自拍视频在线观看| 欧美一区二区啪啪| 亚洲人成网站精品片在线观看| 亚洲色图在线看| 综合激情成人伊人| 美国三级日本三级久久99| 午夜精品aaa| 9i在线看片成人免费| 国产成人av资源| 日韩欧美亚洲另类制服综合在线| 在线播放中文一区| 亚洲欧美另类在线| 在线观看三级视频欧美| 欧美精品一区二| 亚洲bt欧美bt精品777| 婷婷丁香激情综合| 国产一区二区三区国产| 91精品久久久久久久99蜜桃 | 精品理论电影在线| 亚洲成a天堂v人片| 91年精品国产| 91美女视频网站| 久久精品一区二区三区四区| 免费成人你懂的| 亚洲欧美日韩一区| 成人免费观看男女羞羞视频| 亚洲精品一区二区三区精华液 | 亚洲老司机在线| 国产一区二区在线影院| 欧美在线一二三四区| 麻豆精品久久久| 欧美在线制服丝袜| 欧美mv和日韩mv的网站| 中文字幕一区三区| 久国产精品韩国三级视频| 欧美xxxxx牲另类人与| 首页国产丝袜综合| 国产成人一区二区精品非洲| 色哟哟精品一区| 自拍偷拍亚洲综合| 成人av电影在线网| 欧洲一区二区av| 一区av在线播放| 欧美性生活影院| 亚洲国产乱码最新视频| 欧美亚洲国产一区二区三区va| 久久久久久久综合色一本| 久久99久久久久| 在线影视一区二区三区| 欧美国产在线观看| 99综合电影在线视频| 国产精品久久毛片| av在线一区二区| 亚洲女同ⅹxx女同tv| 久久99久久久久| 欧美成人video| 亚洲五码中文字幕| 日韩免费高清电影| 国产精品一区在线观看乱码 | 国产精品一卡二| 亚洲私人黄色宅男| 91久久精品一区二区| 麻豆91小视频| 欧美极品aⅴ影院| 欧美日韩一区二区三区免费看| 国产精品乱码人人做人人爱| 色妹子一区二区| 天天影视网天天综合色在线播放| 欧美日精品一区视频| 国产乱码精品一品二品| 国产精品传媒视频| 欧美日韩一本到| 成人午夜免费av| 亚洲国产一区视频| 欧美—级在线免费片| 欧美特级限制片免费在线观看| 亚洲午夜影视影院在线观看| 日韩亚洲欧美在线| 在线视频亚洲一区| 韩国女主播一区| 亚洲成人精品影院| 26uuuu精品一区二区| 欧美人动与zoxxxx乱| 成人av网站在线| 狠狠狠色丁香婷婷综合激情 | 三级欧美在线一区| 欧美高清dvd| 丁香网亚洲国际| 免费成人在线观看| 亚洲欧美日韩国产综合在线| 91麻豆国产精品久久| 中文在线一区二区| 日韩电影在线观看一区| 欧美高清性hdvideosex| 国产凹凸在线观看一区二区| 亚洲va欧美va人人爽| 欧美日韩亚洲国产综合| 北条麻妃国产九九精品视频| 天天色综合天天| 一区二区高清视频在线观看| 制服丝袜激情欧洲亚洲| 在线日韩av片| 国产麻豆成人精品| 国产精品久久免费看| 91亚洲国产成人精品一区二三| 一区二区三区在线看| 日韩一区二区精品| 欧美亚洲动漫另类| 久久疯狂做爰流白浆xx| 亚洲线精品一区二区三区| 中文字幕一区二区三区四区不卡| 99re成人精品视频| 精品国内二区三区| 日韩精品一区二区三区视频在线观看 | ww久久中文字幕| 欧美一级在线免费| 91精品国产欧美一区二区| 91丨九色丨黑人外教| 成人高清视频在线观看|