⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kllad.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 5 页
字号:
				return -EFAULT;						rc = kdmapool_check_valid((struct llad *)NULL,param.dmapool_id);			if (rc == 0){				param.buffer_count = kdmapool_get_available_buffer_count((struct llad *) NULL, param.dmapool_id);				if (ctu((char *) arg, &param, sizeof(param)) != 0)					return -EFAULT;			}		}		break;	case DIRECT_IOCTL_DMAPOOL_GET_PHYSICAL_ADDRESS:		{			struct kdmapool_userbuffer param;						if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;						rc = kdmapool_check_valid((struct llad*)NULL,param.dmapool_id);			if (rc == 0) {				param.physical_address = kdmapool_get_bus_address((struct llad *) NULL, param.dmapool_id,  param.ptr, param.size);				if (ctu((char *) arg, &param, sizeof(param)) != 0)					return -EFAULT;			}		}		break;	case DIRECT_IOCTL_DMAPOOL_GET_VIRTUAL_ADDRESS:		{			struct kdmapool_userbuffer param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;						rc = kdmapool_check_valid((struct llad *)NULL,param.dmapool_id);			if (rc == 0) {				param.ptr = kdmapool_get_virt_address((struct llad *) NULL, param.dmapool_id,  param.physical_address, param.size);				if (ctu((char *) arg, &param, sizeof(param)) != 0)					return -EFAULT;			}		}		break;	case DIRECT_IOCTL_DMAPOOL_ACQUIRE:		{			struct kdmapool_physbuffer param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;						rc = kdmapool_check_valid((struct llad *)NULL,param.dmapool_id);			if (rc == 0)				rc = kdmapool_acquire((struct llad *) NULL, param.dmapool_id, param.physical_address);		}		break;	case DIRECT_IOCTL_DMAPOOL_RELEASE:		{			struct kdmapool_physbuffer param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;						rc = kdmapool_check_valid((struct llad *)NULL,param.dmapool_id);			if (rc == 0)				rc = kdmapool_release((struct llad *) NULL, param.dmapool_id, param.physical_address);		}		break;        case DIRECT_IOCTL_DMAPOOL_FLUSH_CACHE:		{			struct kdmapool_userbuffer param;						if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;						kc_flush_cache((void *)param.physical_address, param.size);			rc = 0;		}		break;			case DIRECT_IOCTL_DMAPOOL_INVALIDATE_CACHE:		{			struct kdmapool_userbuffer param;						if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			kc_invalidate_cache((void *)param.physical_address, param.size);			rc = 0;		}		break;		#if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2)	case DIRECT_IOCTL_GBUS_READ_UINT8:		{				struct gbus_uint8 param;						if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			param.data = gbus_read_uint8(pGBus, param.byte_address);			rc = ctu((char *) arg, &param, sizeof(param));			if (rc != 0) rc=-EFAULT;		}		break;	case DIRECT_IOCTL_GBUS_READ_UINT16:		{				struct gbus_uint16 param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			param.data = gbus_read_uint16(pGBus, param.byte_address);			rc = ctu((char *) arg, &param, sizeof(param));			if (rc != 0) rc=-EFAULT;		}		break;	case DIRECT_IOCTL_GBUS_READ_UINT32:		{				struct gbus_uint32 param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			param.data = gbus_read_uint32(pGBus, param.byte_address);			rc = ctu((char *) arg, &param, sizeof(param));			if (rc != 0) rc=-EFAULT;		}		break;	case DIRECT_IOCTL_GBUS_READ_DATA8:		{				struct gbus_data8 param;			RMuint32 xfer_size, xfer_offset;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint8));				gbus_read_data8(pGBus, 						param.byte_address + xfer_offset * sizeof(RMuint8), 						(RMuint8 *) gbus_buf, 						xfer_size * sizeof(RMuint8));				if (ctu(param.data + xfer_offset, gbus_buf, xfer_size * sizeof(RMuint8)) != 0) {					rc = -EFAULT;					break;				}				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_READ_DATA16:		{				struct gbus_data16 param;			RMuint32 xfer_size, xfer_offset;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint16));				gbus_read_data16(pGBus, 						 param.byte_address + xfer_offset * sizeof(RMuint16), 						 (RMuint16 *) gbus_buf, 						 xfer_size);				if (ctu(param.data + xfer_offset, gbus_buf, xfer_size * sizeof(RMuint16)) != 0) {					rc = -EFAULT;					break;				}				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_READ_DATA32:		{				struct gbus_data32 param;			RMuint32 xfer_size, xfer_offset;							if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint32));				gbus_read_data32(pGBus, 						 param.byte_address + xfer_offset * sizeof(RMuint32), 						 (RMuint32 *) gbus_buf, 						 xfer_size);				if (ctu(param.data + xfer_offset, gbus_buf, xfer_size * sizeof(RMuint32)) != 0) {					rc = -EFAULT;					break;				}				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_WRITE_UINT8:		{				struct gbus_uint8 param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0) 				return -EFAULT;			gbus_write_uint8(pGBus, param.byte_address, param.data);			rc = 0;		}		break;	case DIRECT_IOCTL_GBUS_WRITE_UINT16:		{				struct gbus_uint16 param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0) 				return -EFAULT;			gbus_write_uint16(pGBus, param.byte_address, param.data);			rc = 0;		}		break;	case DIRECT_IOCTL_GBUS_WRITE_UINT32:		{				struct gbus_uint32 param;			if (cfu(&param, (char *)arg, sizeof(param)) != 0) 				return -EFAULT;			gbus_write_uint32(pGBus, param.byte_address, param.data);			rc = 0;		}		break;	case DIRECT_IOCTL_GBUS_WRITE_DATA8:		{				struct gbus_data8 param;			RMuint32 xfer_size, xfer_offset;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint8));				if (cfu(gbus_buf, param.data + xfer_offset, sizeof(RMuint8) * xfer_size) != 0) {					rc = -EFAULT;					break;				}				gbus_write_data8(pGBus, 						 param.byte_address + xfer_offset * sizeof(RMuint8), 						 (RMuint8 *) gbus_buf, 						 xfer_size);				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_WRITE_DATA16:		{				struct gbus_data16 param;			RMuint32 xfer_size, xfer_offset;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint16));				if (cfu(gbus_buf, param.data + xfer_offset, sizeof(RMuint16) * xfer_size) != 0) {					rc = -EFAULT;					break;				}				gbus_write_data16(pGBus, 						  param.byte_address + xfer_offset * sizeof(RMuint16), 						  (RMuint16 *) gbus_buf, 						  xfer_size);				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_WRITE_DATA32:		{				struct gbus_data32 param;			RMuint32 xfer_size, xfer_offset;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			xfer_offset = 0;			rc = 0;			if (down_interruptible(&gbus_buf_sem)) {				rc = -ERESTARTSYS; 				goto done;			}			while (xfer_offset < param.count) {				xfer_size = RMmin(param.count - xfer_offset, GBUS_BUF_SIZE / sizeof(RMuint32));				if (cfu(gbus_buf, param.data + xfer_offset, sizeof(RMuint32) * xfer_size) != 0) {					rc = -EFAULT;					break;				}				gbus_write_data32(pGBus, 						  param.byte_address + xfer_offset * sizeof(RMuint32), 						  (RMuint32 *) gbus_buf, 						  xfer_size);				xfer_offset += xfer_size;			}			up(&gbus_buf_sem);		}		break;	case DIRECT_IOCTL_GBUS_GET_REGIONS_INFO:		{			struct gbus_regions_info param;			param.region_size = DIRECT_REGION_SIZE;			param.region_count = DIRECT_REGION_COUNT;			//			printk("DIRECT_IOCTL_GBUS_GET_REGION_INFO: param.region_size=%lu param.region_count=%lu\n", param.region_size, param.region_count);			if (ctu((char *) arg, &param, sizeof(param)) != 0) {				rc = -EFAULT;				break;			}			rc = 0;		}		break;	case DIRECT_IOCTL_GBUS_LOCK_AREA:		{			struct gbus_lock_area param, local_param;			int i, size, addr, do_map=1, region_count;			if (cfu(&param, (char *)arg, sizeof(param)) != 0)				return -EFAULT;			if (param.region_index >= DIRECT_REGION_COUNT)				return -EINVAL;						/* locking is done on multiple of KERNEL_PAGE_SIZE bytes */			//get address offset from page 			param.offset = param.byte_address & (KERNEL_PAGE_SIZE - 1);			//get page base address 			addr = param.byte_address & ~(KERNEL_PAGE_SIZE - 1);						//get the system pages region count			param.region_count = (param.size + param.offset+ KERNEL_PAGE_SIZE - 1) / KERNEL_PAGE_SIZE;			region_count=param.region_count; //number of kernel pages for this region			/* keep track of orignial parameters */			local_param = param;			if (param.region_index == 0) { //region_index is a parameter								/* try to get an already locked area */				param.region_index = get_locked_area(&param);				/* printk("lock_area: get_locked= %p %d %d %u\n", param.byte_address, param.offset, param.size, param.region_index); */								if (param.region_index<DIRECT_REGION_COUNT) {					do_map = 0; //add lock on this zone 					goto end_lock_area;				}								/* restore original parameters */				param = local_param;								//look for first available free region				for (i=0 ; i<DIRECT_REGION_COUNT ; i++) {					if (unlocked_regions(i, 1))						break;				}								if (i==DIRECT_REGION_COUNT) //no more available					return -EINVAL;								param.region_index = i;/* 				printk("lock_area: found unlocked region %i\n", i); */			}			else {				if (!unlocked_regions(param.region_index, 1))					return -EINVAL;			}					end_lock_area:		/* 	printk("end_lock_area:this area will take %i system pages (0x%x bytes)\n", param.region_count, param.region_count*KERNEL_PAGE_SIZE); */			i = param.region_index;			size = param.size +param.offset;					/* 	 printk("end_lock_area:R.region_info[%i].direct_map = 0x%x\n",i,addr);  */			if (do_map)				R.region_info[i].direct_map = addr;				R.region_info[i].map_refcount ++; 			R.region_info[i].region_count=region_count; 			R.region_info[i].area_byte_address=param.byte_address;			R.region_info[i].area_size=param.size;			R.region_info[i].area_offset=param.offset;		/* 	printk("end_lock_area: locked @%p off:%d size:%d index:%d sys pages count=%d\n", param.byte_address, param.offset, param.size, param.region_index, param.region_count);				 */			if (ctu((char *) arg, &param, sizeof(param)) != 0) 				return -EFAULT;			rc = 0;		}		break;	case DIRECT_IOCTL_GBUS_UNLOCK_REGION:		{			unsigned long region_index; 			if (cfu(&region_index, (char *)arg, sizeof(region_index)) != 0)				return -EFAULT;						if (region_index >= DIRECT_REGION_COUNT)				return -EINVAL;			if (R.region_info[region_index].region_count == 0)				return -EINVAL;	/* 		printk("unlock_region: R.region_info[%i].region_count=%i -> 0\n",region_index,R.region_info[region_index].region_count); */			R.region_info[region_index].map_refcount--;			if (R.region_info[region_index].map_refcount == 0) {				/* printk("unlock_region:area unlocked %d\n", region_index); */				R.region_info[region_index].direct_map = 0;				R.region_info[region_index].region_count=0;			}			rc = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -