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

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

?? ccio-dma.c

?? 該文件是rt_linux
?? C
?? 第 1 頁 / 共 4 頁
字號:
			   (unsigned long)sg_dma_address(startsg), cnt,			   startsg->address, startsg->length		);		/*		** Look for the start of a new DMA stream		*/		if(sg_dma_address(startsg) & PIDE_FLAG) {			u32 pide = sg_dma_address(startsg) & ~PIDE_FLAG;			dma_offset = (unsigned long) pide & ~IOVP_MASK;			sg_dma_address(startsg) = 0;			dma_sg++;			sg_dma_address(dma_sg) = pide;			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);			n_mappings++;		}		/*		** Look for a VCONTIG chunk		*/		if (cnt) {			unsigned long vaddr = (unsigned long)startsg->address;			ASSERT(pdirp);			/* Since multiple Vcontig blocks could make up			** one DMA stream, *add* cnt to dma_len.			*/			sg_dma_len(dma_sg) += cnt;			cnt += dma_offset;			dma_offset=0;	/* only want offset on first chunk */			cnt = ROUNDUP(cnt, IOVP_SIZE);#ifdef CONFIG_PROC_FS			ioc->msg_pages += cnt >> IOVP_SHIFT;#endif			do {				ccio_io_pdir_entry(pdirp, KERNEL_SPACE, 						   (void *)vaddr, hint);				vaddr += IOVP_SIZE;				cnt -= IOVP_SIZE;				pdirp++;			} while (cnt > 0);		}		startsg++;	}	return(n_mappings);}/*** First pass is to walk the SG list and determine where the breaks are** in the DMA stream. Allocates PDIR entries but does not fill them.** Returns the number of DMA chunks.**** Doing the fill seperate from the coalescing/allocation keeps the** code simpler. Future enhancement could make one pass through** the sglist do both.*/static CCIO_INLINE intccio_coalesce_chunks(struct ioc *ioc, struct scatterlist *startsg, int nents){	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */	unsigned long vcontig_len;         /* len of VCONTIG chunk */	unsigned long vcontig_end;	struct scatterlist *dma_sg;        /* next DMA stream head */	unsigned long dma_offset, dma_len; /* start/len of DMA stream */	int n_mappings = 0;	while (nents > 0) {		/*		** Prepare for first/next DMA stream		*/		dma_sg = vcontig_sg = startsg;		dma_len = vcontig_len = vcontig_end = startsg->length;		vcontig_end += (unsigned long) startsg->address;		dma_offset = (unsigned long) startsg->address & ~IOVP_MASK;		/* PARANOID: clear entries */		sg_dma_address(startsg) = 0;		sg_dma_len(startsg) = 0;		/*		** This loop terminates one iteration "early" since		** it's always looking one "ahead".		*/		while(--nents > 0) {			unsigned long startsg_end;			startsg++;			startsg_end = (unsigned long)startsg->address + 				startsg->length;			/* PARANOID: clear entries */			sg_dma_address(startsg) = 0;			sg_dma_len(startsg) = 0;			/*			** First make sure current dma stream won't			** exceed DMA_CHUNK_SIZE if we coalesce the			** next entry.			*/   			if(ROUNDUP(dma_len + dma_offset + startsg->length,				   IOVP_SIZE) > DMA_CHUNK_SIZE)				break;			/*			** Append the next transaction?			*/			if(vcontig_end == (unsigned long) startsg->address) {				vcontig_len += startsg->length;				vcontig_end += startsg->length;				dma_len     += startsg->length;				continue;			}			/*			** Not virtually contigous.			** Terminate prev chunk.			** Start a new chunk.			**			** Once we start a new VCONTIG chunk, dma_offset			** can't change. And we need the offset from the first			** chunk - not the last one. Ergo Successive chunks			** must start on page boundaries and dove tail			** with it's predecessor.			*/			sg_dma_len(vcontig_sg) = vcontig_len;			vcontig_sg = startsg;			vcontig_len = startsg->length;			break;		}		/*		** End of DMA Stream		** Terminate last VCONTIG block.		** Allocate space for DMA stream.		*/		sg_dma_len(vcontig_sg) = vcontig_len;		dma_len = ROUNDUP(dma_len + dma_offset, IOVP_SIZE);		sg_dma_address(dma_sg) =			PIDE_FLAG 			| (ccio_alloc_range(ioc, (dma_len >> IOVP_SHIFT)) << IOVP_SHIFT)			| dma_offset;		n_mappings++;	}	return n_mappings;}/** * ccio_map_sg - Map the scatter/gather list into the IOMMU. * @dev: The PCI device. * @sglist: The scatter/gather list to be mapped in the IOMMU. * @nents: The number of entries in the scatter/gather list. * @direction: The direction of the DMA transaction (to/from device). * * This function implements the pci_map_sg function. */static intccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 	    int direction){	struct ioc *ioc;	int coalesced, filled = 0;	unsigned long flags;	unsigned long hint = hint_lookup[direction];		ASSERT(dev);	ASSERT(dev->sysdata);	ASSERT(HBA_DATA(dev->sysdata)->iommu);	ioc = GET_IOC(dev);		DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);	/* Fast path single entry scatterlists. */	if(nents == 1) {		sg_dma_address(sglist)= ccio_map_single(dev, sglist->address,							sglist->length, 							direction);		sg_dma_len(sglist)= sglist->length;		return 1;	}		spin_lock_irqsave(&ioc->res_lock, flags);#ifdef CONFIG_PROC_FS	ioc->msg_calls++;#endif	/*	** First coalesce the chunks and allocate I/O pdir space	**	** If this is one DMA stream, we can properly map using the	** correct virtual address associated with each DMA page.	** w/o this association, we wouldn't have coherent DMA!	** Access to the virtual address is what forces a two pass algorithm.	*/	coalesced = ccio_coalesce_chunks(ioc, sglist, nents);	/*	** Program the I/O Pdir	**	** map the virtual addresses to the I/O Pdir	** o dma_address will contain the pdir index	** o dma_len will contain the number of bytes to map 	** o address contains the virtual address.	*/	filled = ccio_fill_pdir(ioc, sglist, nents, hint);	spin_unlock_irqrestore(&ioc->res_lock, flags);	ASSERT(coalesced == filled);	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);	return filled;}/** * ccio_unmap_sg - Unmap the scatter/gather list from the IOMMU. * @dev: The PCI device. * @sglist: The scatter/gather list to be unmapped from the IOMMU. * @nents: The number of entries in the scatter/gather list. * @direction: The direction of the DMA transaction (to/from device). * * This function implements the pci_unmap_sg function. */static void ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 	      int direction){	struct ioc *ioc;	ASSERT(dev);	ASSERT(dev->sysdata);	ASSERT(HBA_DATA(dev->sysdata)->iommu);	ioc = GET_IOC(dev);	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",		__FUNCTION__, nents, sglist->address, sglist->length);#ifdef CONFIG_PROC_FS	ioc->usg_calls++;#endif	while(sg_dma_len(sglist) && nents--) {#ifdef CONFIG_PROC_FS		ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;#endif		ccio_unmap_single(dev, sg_dma_address(sglist),				  sg_dma_len(sglist), direction);		++sglist;	}	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);}static struct pci_dma_ops ccio_ops = {	ccio_dma_supported,	ccio_alloc_consistent,	ccio_free_consistent,	ccio_map_single,	ccio_unmap_single,	ccio_map_sg,	ccio_unmap_sg,	NULL,                   /* dma_sync_single : NOP for U2/Uturn */	NULL,                   /* dma_sync_sg     : ditto */};#ifdef CONFIG_PROC_FSstatic int proc_append(char *src, int len, char **dst, off_t *offset, int *max){	if (len < *offset) {		*offset -= len;		return 0;	}	if (*offset > 0) {		src += *offset;		len -= *offset;		*offset = 0;	}	if (len > *max) {		len = *max;	}	memcpy(*dst, src, len);	*dst += len;	*max -= len;	return (*max == 0);}static int ccio_proc_info(char *buf, char **start, off_t offset, int count,			  int *eof, void *data){	int max = count;	char tmp[80]; /* width of an ANSI-standard terminal */	struct ioc *ioc = ioc_list;	while (ioc != NULL) {		unsigned int total_pages = ioc->res_size << 3;		unsigned long avg = 0, min, max;		int j, len;		len = sprintf(tmp, "%s\n", ioc->name);		if (proc_append(tmp, len, &buf, &offset, &count))			break;				len = sprintf(tmp, "Cujo 2.0 bug    : %s\n",			      (ioc->cujo20_bug ? "yes" : "no"));		if (proc_append(tmp, len, &buf, &offset, &count))			break;				len = sprintf(tmp, "IO PDIR size    : %d bytes (%d entries)\n",			      total_pages * 8, total_pages);		if (proc_append(tmp, len, &buf, &offset, &count))			break;				len = sprintf(tmp, "IO PDIR entries : %ld free  %ld used (%d%%)\n",			      total_pages - ioc->used_pages, ioc->used_pages,			      (int)(ioc->used_pages * 100 / total_pages));		if (proc_append(tmp, len, &buf, &offset, &count))			break;				len = sprintf(tmp, "Resource bitmap : %d bytes (%d pages)\n", 			ioc->res_size, total_pages);		if (proc_append(tmp, len, &buf, &offset, &count))			break;				min = max = ioc->avg_search[0];		for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {			avg += ioc->avg_search[j];			if(ioc->avg_search[j] > max) 				max = ioc->avg_search[j];			if(ioc->avg_search[j] < min) 				min = ioc->avg_search[j];		}		avg /= CCIO_SEARCH_SAMPLE;		len = sprintf(tmp, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",			      min, avg, max);		if (proc_append(tmp, len, &buf, &offset, &count))			break;		len = sprintf(tmp, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",			      ioc->msingle_calls, ioc->msingle_pages,			      (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));		if (proc_append(tmp, len, &buf, &offset, &count))			break;				/* KLUGE - unmap_sg calls unmap_single for each mapped page */		min = ioc->usingle_calls - ioc->usg_calls;		max = ioc->usingle_pages - ioc->usg_pages;		len = sprintf(tmp, "pci_unmap_single: %8ld calls  %8ld pages (avg %d/1000)\n",			      min, max, (int)((max * 1000)/min));		if (proc_append(tmp, len, &buf, &offset, &count))			break; 		len = sprintf(tmp, "pci_map_sg()    : %8ld calls  %8ld pages (avg %d/1000)\n",			      ioc->msg_calls, ioc->msg_pages,			      (int)((ioc->msg_pages * 1000)/ioc->msg_calls));		if (proc_append(tmp, len, &buf, &offset, &count))			break;		len = sprintf(tmp, "pci_unmap_sg()  : %8ld calls  %8ld pages (avg %d/1000)\n\n\n",			      ioc->usg_calls, ioc->usg_pages,			      (int)((ioc->usg_pages * 1000)/ioc->usg_calls));		if (proc_append(tmp, len, &buf, &offset, &count))			break;		ioc = ioc->next;	}	if (count == 0) {		*eof = 1;	}	return (max - count);}static int ccio_resource_map(char *buf, char **start, off_t offset, int len,			     int *eof, void *data){	struct ioc *ioc = ioc_list;	buf[0] = '\0';	while (ioc != NULL) {		u32 *res_ptr = (u32 *)ioc->res_map;		int j;		for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {			if ((j & 7) == 0)				strcat(buf,"\n   ");			sprintf(buf, "%s %08x", buf, *res_ptr);			res_ptr++;		}		strcat(buf, "\n\n");		ioc = ioc->next;		break; /* XXX - remove me */	}	return strlen(buf);}#endif/** * ccio_find_ioc - Find the ioc in the ioc_list

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日本亚洲电影天堂| 激情图区综合网| 亚洲精品一区二区三区四区高清| 国产成人高清在线| 国产成人小视频| 欧美美女激情18p| 欧美日韩你懂得| 在线观看一区二区视频| 成人黄色一级视频| 国产成人av一区| 日韩一区二区三| 精品视频一区二区三区免费| 久久一二三国产| 欧美国产乱子伦| 国产日韩欧美高清在线| 中文字幕精品三区| 国内精品免费**视频| 欧美人与性动xxxx| 久久久亚洲精品一区二区三区| 精品欧美乱码久久久久久| 日韩精品中文字幕在线不卡尤物 | 久久国产精品99久久人人澡| 午夜欧美电影在线观看| 亚洲444eee在线观看| 日欧美一区二区| 国产一区二区福利视频| 国产成人综合亚洲91猫咪| 337p亚洲精品色噜噜噜| 精品久久国产老人久久综合| 日韩av在线发布| 欧美日韩成人综合天天影院 | 亚洲午夜免费视频| 日韩成人av影视| 欧美日韩的一区二区| 亚洲狠狠爱一区二区三区| 精品国产123| 麻豆久久一区二区| 成人aa视频在线观看| 国产精品私人影院| 五月激情综合婷婷| 7777精品伊人久久久大香线蕉超级流畅| 亚洲激情综合网| 视频在线观看91| 日韩一区二区在线观看视频| 欧美aⅴ一区二区三区视频| 成人免费黄色大片| 日韩欧美国产一二三区| 激情欧美一区二区三区在线观看| 久久综合999| 成人性生交大片免费看视频在线| 亚洲欧洲美洲综合色网| 久久国产视频网| 久久久91精品国产一区二区精品| 亚洲国产aⅴ成人精品无吗| 欧美日韩在线免费视频| 日韩精品一卡二卡三卡四卡无卡| 日韩精品一区二区三区视频播放| 黑人巨大精品欧美黑白配亚洲| 久久久久久毛片| 色先锋久久av资源部| 国产亚洲欧美在线| 色吧成人激情小说| 中文字幕av一区二区三区免费看 | 日韩精品高清不卡| 欧美成人艳星乳罩| 成人av在线电影| 亚洲午夜国产一区99re久久| 日韩欧美国产一二三区| 成人av动漫在线| 午夜精品一区在线观看| 久久精品欧美一区二区三区麻豆| 99re热视频这里只精品| 亚洲国产精品黑人久久久| 色婷婷国产精品久久包臀| 免费av成人在线| 国产精品二三区| 国产一区二区三区四区五区入口| 国产精品麻豆视频| 91精品国产欧美一区二区成人| 亚洲电影第三页| 久久夜色精品一区| 精品视频色一区| 99久久国产综合色|国产精品| 免费高清在线视频一区·| 亚洲色图欧美激情| 色综合久久88色综合天天6| 麻豆精品新av中文字幕| 亚洲人成亚洲人成在线观看图片| 99久久99久久精品国产片果冻| 视频一区中文字幕国产| 亚洲精品日韩一| 国产欧美一区视频| 日韩午夜激情av| 在线观看免费成人| 91小视频在线免费看| 日韩理论片在线| 久久香蕉国产线看观看99| 69堂成人精品免费视频| 91福利视频网站| 成人av免费在线播放| 免费不卡在线视频| 亚洲午夜羞羞片| 一区二区三区精密机械公司| 欧美精品免费视频| 91久久奴性调教| youjizz久久| 天天影视涩香欲综合网| 一区二区在线看| 国产精品久久久久aaaa樱花| 久久久国产午夜精品| 欧美成人vr18sexvr| 日韩亚洲欧美成人一区| 56国语精品自产拍在线观看| 欧美日本在线观看| 欧美视频第二页| 国产精品亚洲一区二区三区在线 | 亚洲另类一区二区| 国产日本一区二区| 久久久久久久综合狠狠综合| 精品国产青草久久久久福利| 制服丝袜成人动漫| 日韩视频国产视频| 91精品国产色综合久久久蜜香臀| 欧美日韩高清一区二区三区| 欧美一级免费大片| 日韩一区二区在线免费观看| 欧美一区二区三区在线视频| 91精品国产综合久久久久久| 日韩欧美你懂的| 精品99一区二区三区| 久久精品人人做人人综合| 久久婷婷久久一区二区三区| 国产日韩欧美电影| 亚洲图片你懂的| 亚洲国产精品影院| 青青草成人在线观看| 国产一区二区三区不卡在线观看| 国产东北露脸精品视频| av电影天堂一区二区在线观看| 色综合天天综合狠狠| 国产成都精品91一区二区三| 偷拍亚洲欧洲综合| 老司机精品视频线观看86| 国内精品在线播放| 99国产精品99久久久久久| 色欲综合视频天天天| 欧美精品日韩一本| 中文字幕精品—区二区四季| 一区二区三区四区在线| 免费人成黄页网站在线一区二区| 国产成人综合在线| 91免费观看在线| 日韩精品中文字幕在线不卡尤物 | 日韩精品一区二区三区在线 | 日韩亚洲欧美在线观看| 国产精品不卡一区| 午夜久久久久久久久| 国产不卡视频一区| 欧美日韩色一区| 国产亚洲自拍一区| 亚洲一区二区欧美日韩| 亚洲视频一二三区| 美女国产一区二区三区| av激情亚洲男人天堂| 日韩一级视频免费观看在线| 国产精品对白交换视频| 久久精品国产精品亚洲综合| 一本大道久久a久久精品综合| 日韩一区二区三| 亚洲一区二区三区美女| 成人av网站大全| 久久久影院官网| 青青草成人在线观看| 色婷婷亚洲综合| 亚洲国产高清不卡| 久久99热99| 欧美一区二视频| 亚洲一区二三区| 91在线一区二区| 中文字幕av不卡| 国产主播一区二区| 欧美一区永久视频免费观看| √…a在线天堂一区| 国产成人精品在线看| 精品国产一二三| 亚洲chinese男男1069| 一本一道波多野结衣一区二区| 国产亚洲欧美色| 精品亚洲国内自在自线福利| 国产成人精品www牛牛影视| 日韩免费看的电影| 日本不卡一二三| 欧美区一区二区三区| 亚洲影院在线观看| 色哟哟国产精品| 成人免费在线观看入口| 成a人片亚洲日本久久| 国产日韩成人精品| 豆国产96在线|亚洲| 国产无遮挡一区二区三区毛片日本|