mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 08:08:51 +01:00 
			
		
		
		
	Fixed MTP to work with TWRP
This commit is contained in:
		
						commit
						f6dfaef42e
					
				
					 50820 changed files with 20846062 additions and 0 deletions
				
			
		
							
								
								
									
										141
									
								
								arch/s390/hypfs/hypfs_sprp.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								arch/s390/hypfs/hypfs_sprp.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,141 @@ | |||
| /*
 | ||||
|  *    Hypervisor filesystem for Linux on s390. | ||||
|  *    Set Partition-Resource Parameter interface. | ||||
|  * | ||||
|  *    Copyright IBM Corp. 2013 | ||||
|  *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/compat.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/gfp.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/compat.h> | ||||
| #include <asm/sclp.h> | ||||
| #include "hypfs.h" | ||||
| 
 | ||||
| #define DIAG304_SET_WEIGHTS	0 | ||||
| #define DIAG304_QUERY_PRP	1 | ||||
| #define DIAG304_SET_CAPPING	2 | ||||
| 
 | ||||
| #define DIAG304_CMD_MAX		2 | ||||
| 
 | ||||
| static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd) | ||||
| { | ||||
| 	register unsigned long _data asm("2") = (unsigned long) data; | ||||
| 	register unsigned long _rc asm("3"); | ||||
| 	register unsigned long _cmd asm("4") = cmd; | ||||
| 
 | ||||
| 	asm volatile("diag %1,%2,0x304\n" | ||||
| 		     : "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory"); | ||||
| 
 | ||||
| 	return _rc; | ||||
| } | ||||
| 
 | ||||
| static void hypfs_sprp_free(const void *data) | ||||
| { | ||||
| 	free_page((unsigned long) data); | ||||
| } | ||||
| 
 | ||||
| static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size) | ||||
| { | ||||
| 	unsigned long rc; | ||||
| 	void *data; | ||||
| 
 | ||||
| 	data = (void *) get_zeroed_page(GFP_KERNEL); | ||||
| 	if (!data) | ||||
| 		return -ENOMEM; | ||||
| 	rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP); | ||||
| 	if (rc != 1) { | ||||
| 		*data_ptr = *free_ptr = NULL; | ||||
| 		*size = 0; | ||||
| 		free_page((unsigned long) data); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 	*data_ptr = *free_ptr = data; | ||||
| 	*size = PAGE_SIZE; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int __hypfs_sprp_ioctl(void __user *user_area) | ||||
| { | ||||
| 	struct hypfs_diag304 diag304; | ||||
| 	unsigned long cmd; | ||||
| 	void __user *udata; | ||||
| 	void *data; | ||||
| 	int rc; | ||||
| 
 | ||||
| 	if (copy_from_user(&diag304, user_area, sizeof(diag304))) | ||||
| 		return -EFAULT; | ||||
| 	if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||||
| 	if (!data) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	udata = (void __user *)(unsigned long) diag304.data; | ||||
| 	if (diag304.args[1] == DIAG304_SET_WEIGHTS || | ||||
| 	    diag304.args[1] == DIAG304_SET_CAPPING) | ||||
| 		if (copy_from_user(data, udata, PAGE_SIZE)) { | ||||
| 			rc = -EFAULT; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 	cmd = *(unsigned long *) &diag304.args[0]; | ||||
| 	diag304.rc = hypfs_sprp_diag304(data, cmd); | ||||
| 
 | ||||
| 	if (diag304.args[1] == DIAG304_QUERY_PRP) | ||||
| 		if (copy_to_user(udata, data, PAGE_SIZE)) { | ||||
| 			rc = -EFAULT; | ||||
| 			goto out; | ||||
| 		} | ||||
| 
 | ||||
| 	rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0; | ||||
| out: | ||||
| 	free_page((unsigned long) data); | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd, | ||||
| 			       unsigned long arg) | ||||
| { | ||||
| 	void __user *argp; | ||||
| 
 | ||||
| 	if (!capable(CAP_SYS_ADMIN)) | ||||
| 		return -EACCES; | ||||
| 	if (is_compat_task()) | ||||
| 		argp = compat_ptr(arg); | ||||
| 	else | ||||
| 		argp = (void __user *) arg; | ||||
| 	switch (cmd) { | ||||
| 	case HYPFS_DIAG304: | ||||
| 		return __hypfs_sprp_ioctl(argp); | ||||
| 	default: /* unknown ioctl number */ | ||||
| 		return -ENOTTY; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct hypfs_dbfs_file hypfs_sprp_file = { | ||||
| 	.name		= "diag_304", | ||||
| 	.data_create	= hypfs_sprp_create, | ||||
| 	.data_free	= hypfs_sprp_free, | ||||
| 	.unlocked_ioctl = hypfs_sprp_ioctl, | ||||
| }; | ||||
| 
 | ||||
| int hypfs_sprp_init(void) | ||||
| { | ||||
| 	if (!sclp_has_sprp()) | ||||
| 		return 0; | ||||
| 	return hypfs_dbfs_create_file(&hypfs_sprp_file); | ||||
| } | ||||
| 
 | ||||
| void hypfs_sprp_exit(void) | ||||
| { | ||||
| 	if (!sclp_has_sprp()) | ||||
| 		return; | ||||
| 	hypfs_dbfs_remove_file(&hypfs_sprp_file); | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228