54 lines
		
	
	
	
		
			1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			54 lines
		
	
	
	
		
			1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | #include <linux/uaccess.h>
 | ||
|  | #include <linux/export.h>
 | ||
|  | #include <linux/uio.h>
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  *	Copy iovec to kernel. Returns -EFAULT on error. | ||
|  |  * | ||
|  |  *	Note: this modifies the original iovec. | ||
|  |  */ | ||
|  | 
 | ||
|  | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) | ||
|  | { | ||
|  | 	while (len > 0) { | ||
|  | 		if (iov->iov_len) { | ||
|  | 			int copy = min_t(unsigned int, len, iov->iov_len); | ||
|  | 			if (copy_from_user(kdata, iov->iov_base, copy)) | ||
|  | 				return -EFAULT; | ||
|  | 			len -= copy; | ||
|  | 			kdata += copy; | ||
|  | 			iov->iov_base += copy; | ||
|  | 			iov->iov_len -= copy; | ||
|  | 		} | ||
|  | 		iov++; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return 0; | ||
|  | } | ||
|  | EXPORT_SYMBOL(memcpy_fromiovec); | ||
|  | 
 | ||
|  | /*
 | ||
|  |  *	Copy kernel to iovec. Returns -EFAULT on error. | ||
|  |  * | ||
|  |  *	Note: this modifies the original iovec. | ||
|  |  */ | ||
|  | 
 | ||
|  | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) | ||
|  | { | ||
|  | 	while (len > 0) { | ||
|  | 		if (iov->iov_len) { | ||
|  | 			int copy = min_t(unsigned int, iov->iov_len, len); | ||
|  | 			if (copy_to_user(iov->iov_base, kdata, copy)) | ||
|  | 				return -EFAULT; | ||
|  | 			kdata += copy; | ||
|  | 			len -= copy; | ||
|  | 			iov->iov_len -= copy; | ||
|  | 			iov->iov_base += copy; | ||
|  | 		} | ||
|  | 		iov++; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return 0; | ||
|  | } | ||
|  | EXPORT_SYMBOL(memcpy_toiovec); |