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

📄 agpgart_fe.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
static int agp_remove_client(pid_t id){	agp_client *client;	agp_client *prev_client;	agp_client *next_client;	agp_controller *controller;	controller = agp_find_controller_for_client(id);	if (controller == NULL) {		return -EINVAL;	}	client = agp_find_client_in_controller(controller, id);	if (client == NULL) {		return -EINVAL;	}	prev_client = client->prev;	next_client = client->next;	if (prev_client != NULL) {		prev_client->next = next_client;		if (next_client != NULL) {			next_client->prev = prev_client;		}	} else {		if (next_client != NULL) {			next_client->prev = NULL;		}		controller->clients = next_client;	}	controller->num_clients--;	agp_remove_seg_from_client(client);	kfree(client);	return 0;}/* End - Routines for managing client lists *//* File Operations */static int agp_mmap(struct file *file, struct vm_area_struct *vma){	int size;	int current_size;	unsigned long offset;	agp_client *client;	agp_file_private *priv = (agp_file_private *) file->private_data;	agp_kern_info kerninfo;	lock_kernel();	AGP_LOCK();	if (agp_fe.backend_acquired != TRUE) {		AGP_UNLOCK();		unlock_kernel();		return -EPERM;	}	if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) {		AGP_UNLOCK();		unlock_kernel();		return -EPERM;	}	agp_copy_info(&kerninfo);	size = vma->vm_end - vma->vm_start;	current_size = kerninfo.aper_size;	current_size = current_size * 0x100000;	offset = vma->vm_pgoff << PAGE_SHIFT;	if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {		if ((size + offset) > current_size) {			AGP_UNLOCK();			unlock_kernel();			return -EINVAL;		}		client = agp_find_client_by_pid(current->pid);		if (client == NULL) {			AGP_UNLOCK();			unlock_kernel();			return -EPERM;		}		if (!agp_find_seg_in_client(client, offset,					    size, vma->vm_page_prot)) {			AGP_UNLOCK();			unlock_kernel();			return -EINVAL;		}		if (remap_page_range(vma->vm_start,				     (kerninfo.aper_base + offset),				     size, vma->vm_page_prot)) {			AGP_UNLOCK();			unlock_kernel();			return -EAGAIN;		}		AGP_UNLOCK();		unlock_kernel();		return 0;	}	if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {		if (size != current_size) {			AGP_UNLOCK();			unlock_kernel();			return -EINVAL;		}		if (remap_page_range(vma->vm_start, kerninfo.aper_base,				     size, vma->vm_page_prot)) {			AGP_UNLOCK();			unlock_kernel();			return -EAGAIN;		}		AGP_UNLOCK();		unlock_kernel();		return 0;	}	AGP_UNLOCK();	unlock_kernel();	return -EPERM;}static int agp_release(struct inode *inode, struct file *file){	agp_file_private *priv = (agp_file_private *) file->private_data;	lock_kernel();	AGP_LOCK();	if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {		agp_controller *controller;		controller = agp_find_controller_by_pid(priv->my_pid);		if (controller != NULL) {			if (controller == agp_fe.current_controller) {				agp_controller_release_current(controller,							       priv);			}			agp_remove_controller(controller);		}	}	if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {		agp_remove_client(priv->my_pid);	}	agp_remove_file_private(priv);	kfree(priv);	AGP_UNLOCK();	unlock_kernel();	return 0;}static int agp_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	agp_file_private *priv;	agp_client *client;	int rc = -ENXIO;	AGP_LOCK();	if (minor != AGPGART_MINOR)		goto err_out;	priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL);	if (priv == NULL)		goto err_out_nomem;	memset(priv, 0, sizeof(agp_file_private));	set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);	priv->my_pid = current->pid;	if ((current->uid == 0) || (current->suid == 0)) {		/* Root priv, can be controller */		set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags);	}	client = agp_find_client_by_pid(current->pid);	if (client != NULL) {		set_bit(AGP_FF_IS_CLIENT, &priv->access_flags);		set_bit(AGP_FF_IS_VALID, &priv->access_flags);	}	file->private_data = (void *) priv;	agp_insert_file_private(priv);	AGP_UNLOCK();	return 0;err_out_nomem:	rc = -ENOMEM;err_out:	AGP_UNLOCK();	return rc;}static ssize_t agp_read(struct file *file, char *buf,			size_t count, loff_t * ppos){	return -EINVAL;}static ssize_t agp_write(struct file *file, const char *buf,			 size_t count, loff_t * ppos){	return -EINVAL;}static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg){	agp_info userinfo;	agp_kern_info kerninfo;	agp_copy_info(&kerninfo);	userinfo.version.major = kerninfo.version.major;	userinfo.version.minor = kerninfo.version.minor;	userinfo.bridge_id = kerninfo.device->vendor |	    (kerninfo.device->device << 16);	userinfo.agp_mode = kerninfo.mode;	userinfo.aper_base = kerninfo.aper_base;	userinfo.aper_size = kerninfo.aper_size;	userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;	userinfo.pg_used = kerninfo.current_memory;	if (copy_to_user((void *) arg, &userinfo, sizeof(agp_info))) {		return -EFAULT;	}	return 0;}static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg){	agp_controller *controller;	if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags))) {		return -EPERM;	}	if (agp_fe.current_controller != NULL) {		return -EBUSY;	}	if ((agp_backend_acquire()) == 0) {		agp_fe.backend_acquired = TRUE;	} else {		return -EBUSY;	}	controller = agp_find_controller_by_pid(priv->my_pid);	if (controller != NULL) {		agp_controller_make_current(controller);	} else {		controller = agp_create_controller(priv->my_pid);		if (controller == NULL) {			agp_fe.backend_acquired = FALSE;			agp_backend_release();			return -ENOMEM;		}		agp_insert_controller(controller);		agp_controller_make_current(controller);	}	set_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags);	set_bit(AGP_FF_IS_VALID, &priv->access_flags);	return 0;}static int agpioc_release_wrap(agp_file_private * priv, unsigned long arg){	agp_controller_release_current(agp_fe.current_controller, priv);	return 0;}static int agpioc_setup_wrap(agp_file_private * priv, unsigned long arg){	agp_setup mode;	if (copy_from_user(&mode, (void *) arg, sizeof(agp_setup))) {		return -EFAULT;	}	agp_enable(mode.agp_mode);	return 0;}static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg){	agp_region reserve;	agp_client *client;	agp_file_private *client_priv;	if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) {		return -EFAULT;	}	if ((unsigned) reserve.seg_count >= ~0U/sizeof(agp_segment))		return -EFAULT;	client = agp_find_client_by_pid(reserve.pid);	if (reserve.seg_count == 0) {		/* remove a client */		client_priv = agp_find_private(reserve.pid);		if (client_priv != NULL) {			set_bit(AGP_FF_IS_CLIENT,				&client_priv->access_flags);			set_bit(AGP_FF_IS_VALID,				&client_priv->access_flags);		}		if (client == NULL) {			/* client is already removed */			return 0;		}		return agp_remove_client(reserve.pid);	} else {		agp_segment *segment;		if (reserve.seg_count >= 16384)			return -EINVAL;					segment = kmalloc((sizeof(agp_segment) * reserve.seg_count),				  GFP_KERNEL);		if (segment == NULL) {			return -ENOMEM;		}		if (copy_from_user(segment, (void *) reserve.seg_list,				   sizeof(agp_segment) * reserve.seg_count)) {			kfree(segment);			return -EFAULT;		}		reserve.seg_list = segment;		if (client == NULL) {			/* Create the client and add the segment */			client = agp_create_client(reserve.pid);			if (client == NULL) {				kfree(segment);				return -ENOMEM;			}			client_priv = agp_find_private(reserve.pid);			if (client_priv != NULL) {				set_bit(AGP_FF_IS_CLIENT,					&client_priv->access_flags);				set_bit(AGP_FF_IS_VALID,					&client_priv->access_flags);			}			return agp_create_segment(client, &reserve);		} else {			return agp_create_segment(client, &reserve);		}	}	/* Will never really happen */	return -EINVAL;}static int agpioc_protect_wrap(agp_file_private * priv, unsigned long arg){	/* This function is not currently implemented */	return -EINVAL;}static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg){	agp_memory *memory;	agp_allocate alloc;	if (copy_from_user(&alloc, (void *) arg, sizeof(agp_allocate))) {		return -EFAULT;	}	memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);	if (memory == NULL) {		return -ENOMEM;	}	alloc.key = memory->key;	alloc.physical = memory->physical;	if (copy_to_user((void *) arg, &alloc, sizeof(agp_allocate))) {		agp_free_memory_wrap(memory);		return -EFAULT;	}	return 0;}static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg){	agp_memory *memory;	memory = agp_find_mem_by_key((int) arg);	if (memory == NULL) {		return -EINVAL;	}	agp_free_memory_wrap(memory);	return 0;}static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg){	agp_bind bind_info;	agp_memory *memory;	if (copy_from_user(&bind_info, (void *) arg, sizeof(agp_bind))) {		return -EFAULT;	}	memory = agp_find_mem_by_key(bind_info.key);	if (memory == NULL) {		return -EINVAL;	}	return agp_bind_memory(memory, bind_info.pg_start);}static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg){	agp_memory *memory;	agp_unbind unbind;	if (copy_from_user(&unbind, (void *) arg, sizeof(agp_unbind))) {		return -EFAULT;	}	memory = agp_find_mem_by_key(unbind.key);	if (memory == NULL) {		return -EINVAL;	}	return agp_unbind_memory(memory);}static int agp_ioctl(struct inode *inode, struct file *file,		     unsigned int cmd, unsigned long arg){	agp_file_private *curr_priv = (agp_file_private *) file->private_data;	int ret_val = -ENOTTY;	AGP_LOCK();	if ((agp_fe.current_controller == NULL) &&	    (cmd != AGPIOC_ACQUIRE)) {		ret_val = -EINVAL;	   	goto ioctl_out;	}	if ((agp_fe.backend_acquired != TRUE) &&	    (cmd != AGPIOC_ACQUIRE)) {		ret_val = -EBUSY;	   	goto ioctl_out;	}	if (cmd != AGPIOC_ACQUIRE) {		if (!(test_bit(AGP_FF_IS_CONTROLLER,			       &curr_priv->access_flags))) {			ret_val = -EPERM;		   	goto ioctl_out;		}		/* Use the original pid of the controller,		 * in case it's threaded */		if (agp_fe.current_controller->pid != curr_priv->my_pid) {			ret_val = -EBUSY;		   	goto ioctl_out;		}	}	switch (cmd) {	case AGPIOC_INFO:		{			ret_val = agpioc_info_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_ACQUIRE:		{			ret_val = agpioc_acquire_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_RELEASE:		{			ret_val = agpioc_release_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_SETUP:		{			ret_val = agpioc_setup_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_RESERVE:		{			ret_val = agpioc_reserve_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_PROTECT:		{			ret_val = agpioc_protect_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_ALLOCATE:		{			ret_val = agpioc_allocate_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_DEALLOCATE:		{			ret_val = agpioc_deallocate_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_BIND:		{			ret_val = agpioc_bind_wrap(curr_priv, arg);		   	goto ioctl_out;		}	case AGPIOC_UNBIND:		{			ret_val = agpioc_unbind_wrap(curr_priv, arg);		   	goto ioctl_out;		}	}   ioctl_out:	AGP_UNLOCK();	return ret_val;}static struct file_operations agp_fops ={	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		agp_read,	write:		agp_write,	ioctl:		agp_ioctl,	mmap:		agp_mmap,	open:		agp_open,	release:	agp_release,};static struct miscdevice agp_miscdev ={	AGPGART_MINOR,	AGPGART_MODULE_NAME,	&agp_fops};int __init agp_frontend_initialize(void){	memset(&agp_fe, 0, sizeof(struct agp_front_data));	AGP_LOCK_INIT();	if (misc_register(&agp_miscdev)) {		printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);		return -EIO;	}	return 0;}void __exit agp_frontend_cleanup(void){	misc_deregister(&agp_miscdev);}

⌨️ 快捷键说明

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