예제 #1
0
파일: op_dname.c 프로젝트: OPSF/uClinux
int oprof_init_hashmap(void)
{
	uint i;

	op_dname_stack = kmalloc(DNAME_STACK_MAX * sizeof(struct qstr *), GFP_KERNEL);
	if (!op_dname_stack)
		return -EFAULT;
	op_dname_top = 0;
	memset(op_dname_stack, 0, DNAME_STACK_MAX * sizeof(struct qstr *));

	hash_map = rvmalloc(PAGE_ALIGN(OP_HASH_MAP_SIZE));
	if (!hash_map)
		return -EFAULT;

	for (i = 0; i < OP_HASH_MAP_NR; ++i) {
		hash_map[i].name = 0;
		hash_map[i].parent = -1;
	}

	op_pool_start = (char *)(hash_map + OP_HASH_MAP_NR);
	op_pool_end = op_pool_start + POOL_SIZE;
	op_pool_pos = op_pool_start;

	/* Ensure that the zero hash map entry is never used, we use this
	 * value as end of path terminator */
	hash_map[0].name = alloc_in_pool("/", 1);
	hash_map[0].parent = 0;

	return 0;
}
예제 #2
0
파일: shm.c 프로젝트: Enextuse/RTAI
static inline void *_rt_shm_alloc(unsigned long name, int size, int suprt)
{
	void *adr;

//	suprt = USE_GFP_ATOMIC; // to force some testing
	if (!(adr = rt_get_adr_cnt(name)) && size > 0 && suprt >= 0 && RT_SHM_OP_PERM())
	{
		size = ((size - 1) & PAGE_MASK) + PAGE_SIZE;
		if ((adr = suprt ? rkmalloc(&size, SUPRT[suprt]) : rvmalloc(size)))
		{
			if (!rt_register(name, adr, suprt ? -size : size, 0))
			{
				if (suprt)
				{
					rkfree(adr, size);
				}
				else
				{
					rvfree(adr, size);
				}
				return 0;
			}
			memset(ALIGN2PAGE(adr), 0, size);
		}
	}
	return ALIGN2PAGE(adr);
}
예제 #3
0
static int dhahelper_alloc_pa(dhahelper_mem_t *arg)
{
	dhahelper_mem_t mem;
	if (copy_from_user(&mem, arg, sizeof(dhahelper_mem_t)))
	{
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");
		return -EFAULT;
	}
	mem.addr = rvmalloc(mem.length);
	if (copy_to_user(arg, &mem, sizeof(dhahelper_mem_t)))
	{
		if (dhahelper_verbosity > 0)
		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");
		return -EFAULT;
	}
	return 0;
}
예제 #4
0
static int vloopback_mmap(struct file *f, struct vm_area_struct *vma)
{
	struct video_device *loopdev=video_devdata(f);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	priv_ptr ptr=(priv_ptr)video_get_drvdata(loopdev);
#else
	priv_ptr ptr=(priv_ptr)loopdev->priv;
#endif	
	int nr=ptr->pipenr;
	unsigned long start = (unsigned long)vma->vm_start;
	long size = vma->vm_end - vma->vm_start;
	unsigned long page, pos;

	down(&loops[nr]->lock);
	if (ptr->in) {
		loops[nr]->zerocopy=1;
		if (loops[nr]->ropen) {
			info("Can't change size while opened for read");
			up(&loops[nr]->lock);
			return -EINVAL;
		}
		if (!size) {
			up(&loops[nr]->lock);
			return -EINVAL;
		}
		if (loops[nr]->buffer)
			rvfree(loops[nr]->buffer, loops[nr]->buflength*N_BUFFS);
		loops[nr]->buflength=size;
		loops[nr]->buffer=rvmalloc(loops[nr]->buflength*N_BUFFS);
	}
        if (loops[nr]->buffer == NULL) {
		up(&loops[nr]->lock);
                return -EINVAL;
	}

        if (size > (((N_BUFFS * loops[nr]->buflength) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
		up(&loops[nr]->lock);
                return -EINVAL;
	}

        pos = (unsigned long)loops[nr]->buffer;
        while (size > 0) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
                page = kvirt_to_pa(pos);
                if (remap_page_range(vma,start, page, PAGE_SIZE, PAGE_SHARED)) {
#else
		page = vmalloc_to_pfn((void *)pos);
		if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
#endif
			up(&loops[nr]->lock);
                        return -EAGAIN;
		}
                start += PAGE_SIZE;
                pos += PAGE_SIZE;
		size -= PAGE_SIZE;
        }
	up(&loops[nr]->lock);

	return 0;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
static long vloopback_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
#else
static int vloopback_ioctl(struct inode *inod, struct file *f, unsigned int cmd, unsigned long arg)
#endif
{
	struct video_device *loopdev=video_devdata(f);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	priv_ptr ptr=(priv_ptr)video_get_drvdata(loopdev);
#else
	priv_ptr ptr=(priv_ptr)loopdev->priv;
#endif	
	int nr=ptr->pipenr;
	int i;

	if (loops[nr]->zerocopy) {
		if (!ptr->in) {
			loops[nr]->ioctlnr=cmd;
			loops[nr]->ioctllength=_IOC_SIZE(cmd);
			/* info("DEBUG: vl_ioctl: !loop->in"); */
			/* info("DEBUG: vl_ioctl: cmd %lu", cmd); */
			/* info("DEBUG: vl_ioctl: len %lu", loops[nr]->ioctllength); */
			if(copy_from_user(loops[nr]->ioctldata, (void*)arg, _IOC_SIZE(cmd)))
				return -EFAULT;
			kill_proc(loops[nr]->pid, SIGIO, 1);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
			wait_event_interruptible(loops[nr]->wait, loops[nr]->ioctlnr==-1);
#else
			interruptible_sleep_on(&loops[nr]->wait);
#endif			
			
			if (loops[nr]->invalid_ioctl) {
				//info ("DEBUG: There was an invalid ioctl");
				loops[nr]->invalid_ioctl = 0;
				return -ENOTTY;
			}
			if (cmd & IOC_IN && !(cmd & IOC_OUT)) {
				//info("DEBUG: vl_ioctl: cmd & IOC_IN 1"); 
				if (memcmp(loops[nr]->ioctlretdata, loops[nr]->ioctldata, _IOC_SIZE(cmd))) {
					return -EINVAL;
				}
			 	//info("DEBUG: vl_ioctl: cmd & IOC_IN 2"); 
				return 0;
			} else {
				if (copy_to_user((void*)arg, loops[nr]->ioctlretdata, _IOC_SIZE(cmd)))
					return -EFAULT;
				//info("DEBUG: vl_ioctl: !(cmd & IOC_IN) 1");
				return 0;
			}
		} else {
			if ( (loops[nr]->ioctlnr!=cmd) && (cmd != (VIDIOCSINVALID))) {
				/* wrong ioctl */
				info("DEBUG: vo_ioctl: Wrong IOCTL");
				return 0;
			}
			if (cmd == VIDIOCSINVALID) {
				loops[nr]->invalid_ioctl = 1;
			} else {
				if (copy_from_user(loops[nr]->ioctlretdata, (void*)arg, loops[nr]->ioctllength))
					return -EFAULT;
			}
			loops[nr]->ioctlnr=-1;
			if (waitqueue_active(&loops[nr]->wait))
				wake_up(&loops[nr]->wait);
			return 0;
		}
	}
	switch(cmd)
	{
		/* Get capabilities */
		case VIDIOCGCAP:
		{
			struct video_capability b;
			if (ptr->in) {
				sprintf(b.name, "Video loopback %d input",
				    ptr->pipenr);
				b.type = 0;
			} else {
				sprintf(b.name, "Video loopback %d output",
				    ptr->pipenr);
				b.type = VID_TYPE_CAPTURE;
			}
			b.channels=1;
			b.audios=0;
			b.maxwidth=loops[nr]->width;
			b.maxheight=loops[nr]->height;
			b.minwidth=20;
			b.minheight=20;
			if(copy_to_user((void*)arg, &b, sizeof(b)))
				return -EFAULT;
			return 0;
		}
		/* Get channel info (sources) */
		case VIDIOCGCHAN:
		{
			struct video_channel v;
			if(copy_from_user(&v, (void*)arg, sizeof(v)))
				return -EFAULT;
			if(v.channel!=0) {
				info("VIDIOCGCHAN: Invalid Channel, was %d", v.channel);
				v.channel=0;
				//return -EINVAL;
			}
			v.flags=0;
			v.tuners=0;
			v.norm=0;
			v.type = VIDEO_TYPE_CAMERA;
			/*strcpy(v.name, "Loopback"); -- tibit */
			strcpy(v.name, "Composite1");
			if(copy_to_user((void*)arg, &v, sizeof(v)))
				return -EFAULT;
			return 0;
		}
		/* Set channel 	*/
		case VIDIOCSCHAN:
		{
			int v;
			if(copy_from_user(&v, (void*)arg, sizeof(v)))
				return -EFAULT;
			if(v!=0) {
				info("VIDIOCSCHAN: Invalid Channel, was %d", v);
				return -EINVAL;
			}
			return 0;
		}
		/* Get tuner abilities */
		case VIDIOCGTUNER:
		{
			struct video_tuner v;
			if(copy_from_user(&v, (void*)arg, sizeof(v))!=0)
				return -EFAULT;
			if(v.tuner) {
				info("VIDIOCGTUNER: Invalid Tuner, was %d", v.tuner);
				return -EINVAL;
			}
			strcpy(v.name, "Format");
			v.rangelow=0;
			v.rangehigh=0;
			v.flags=0;
			v.mode=VIDEO_MODE_AUTO;
			if(copy_to_user((void*)arg,&v, sizeof(v))!=0)
				return -EFAULT;
			return 0;
		}
		/* Get picture properties */
		case VIDIOCGPICT:
		{
			struct video_picture p;
			p.colour=0x8000;
			p.hue=0x8000;
			p.brightness=0x8000;
			p.contrast=0x8000;
			p.whiteness=0x8000;
			p.depth=0x8000;
			p.palette=loops[nr]->palette;
			if(copy_to_user((void*)arg, &p, sizeof(p)))
				return -EFAULT;
			return 0;

		}
		/* Set picture properties */
		case VIDIOCSPICT:
		{
			struct video_picture p;
			if(copy_from_user(&p, (void*)arg, sizeof(p)))
				return -EFAULT;
			if (!ptr->in) {
				if (p.palette!=loops[nr]->palette)
					return -EINVAL;
			} else
				loops[nr]->palette=p.palette;
			return 0;
		}
		/* Get the video overlay window */
		case VIDIOCGWIN:
		{
			struct video_window vw;
			vw.x=0;
			vw.y=0;
			vw.width=loops[nr]->width;
			vw.height=loops[nr]->height;
			vw.chromakey=0;
			vw.flags=0;
			vw.clipcount=0;
			if(copy_to_user((void*)arg, &vw, sizeof(vw)))
				return -EFAULT;
			return 0;
		}
		/* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
		case VIDIOCSWIN:
		{
			struct video_window vw;
			
			if(copy_from_user(&vw, (void*)arg, sizeof(vw)))
				return -EFAULT;
			if(vw.flags)
				return -EINVAL;
			if(vw.clipcount)
				return -EINVAL;
			if (loops[nr]->height==vw.height &&
			    loops[nr]->width==vw.width)
				return 0;
			if(!ptr->in) {
				return -EINVAL;
			} else {
				loops[nr]->height=vw.height;
				loops[nr]->width=vw.width;
				/* Make sure nobody is using the buffer while we
				   fool around with it.
				   We are also not allowing changes while
				   somebody using mmap has the output open.
				 */
				down(&loops[nr]->lock);
				if (loops[nr]->ropen) {
					info("Can't change size while opened for read");
					up(&loops[nr]->lock);
					return -EINVAL;
				}
				if (loops[nr]->buffer)
					rvfree(loops[nr]->buffer, loops[nr]->buflength*N_BUFFS);
				loops[nr]->buflength=vw.width*vw.height*4;
				loops[nr]->buffer=rvmalloc(loops[nr]->buflength*N_BUFFS);
				up(&loops[nr]->lock);
			}
			return 0;
		}
		/* Memory map buffer info */
		case VIDIOCGMBUF:
		{
			struct video_mbuf vm;
			
			vm.size=loops[nr]->buflength*N_BUFFS;
			vm.frames=N_BUFFS;
			for (i=0; i<vm.frames; i++)
				vm.offsets[i]=i*loops[nr]->buflength;
			if(copy_to_user((void*)arg, &vm, sizeof(vm)))
				return -EFAULT;
			return 0;
		}
		/* Grab frames */
		case VIDIOCMCAPTURE:
		{
			struct video_mmap vm;

			if (ptr->in)
				return -EINVAL;
			if (!loops[nr]->buffer)
				return -EINVAL;
			if (copy_from_user(&vm, (void*)arg, sizeof(vm)))
				return -EFAULT;
			if (vm.format!=loops[nr]->palette)
				return -EINVAL;
			if (vm.frame > N_BUFFS)
				return -EINVAL;
			return 0;
		}
		/* Sync with mmap grabbing */
		case VIDIOCSYNC:
		{
			int frame;
			unsigned long fw;

			if (copy_from_user((void *)&frame, (void*)arg, sizeof(int)))
				return -EFAULT;
			if (ptr->in)
				return -EINVAL;
			if (!loops[nr]->buffer)
				return -EINVAL;
			/* Ok, everything should be alright since the program
			   should have called VIDIOMCAPTURE and we are ready to
			   do the 'capturing' */
			if (frame > 1)
				return -EINVAL;
			loops[nr]->frame=frame;
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
			fw = loops[nr]->frameswrite;
			wait_event_interruptible(loops[nr]->wait, fw!=loops[nr]->frameswrite);
#else
			interruptible_sleep_on(&loops[nr]->wait);
#endif			
			if (!loops[nr]->buffer)		/* possibly released during sleep */
				return -EINVAL;
			loops[nr]->framesread++;
			return 0;
		}
		/* Get attached units */
		case VIDIOCGUNIT:
		{
			struct video_unit vu;
			
			if (ptr->in)
				vu.video=loops[nr]->vloopout->minor;
			else
				vu.video=loops[nr]->vloopin->minor;
			vu.vbi=VIDEO_NO_UNIT;
			vu.radio=VIDEO_NO_UNIT;
			vu.audio=VIDEO_NO_UNIT;
			vu.teletext=VIDEO_NO_UNIT;
			if (copy_to_user((void*)arg, &vu, sizeof(vu)))
				return -EFAULT;
			return 0;
		}
		/* Get frame buffer */
		case VIDIOCGFBUF:
		{
			struct video_buffer vb;

			memset(&vb, 0, sizeof(vb));
			vb.base=NULL;

			if(copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
				return -EFAULT;

			return 0;
		}
		/* Start, end capture */
		case VIDIOCCAPTURE:
		{
			int start;
			if (copy_from_user(&start, (void*)arg, sizeof(int)))
				return -EFAULT;
			/*
			if (start) info ("Capture started");
			else info ("Capture stopped");
			*/

			return 0;
		}

		case VIDIOCGFREQ:
		case VIDIOCSFREQ:
		case VIDIOCGAUDIO:
		case VIDIOCSAUDIO:
			return -EINVAL;
		case VIDIOCKEY:
			return 0;
		default:
			return -ENOTTY;
			//return -ENOIOCTLCMD;
	}
	return 0;
}

static unsigned int vloopback_poll(struct file *f, struct poll_table_struct *wait)
{
	struct video_device *loopdev=video_devdata(f);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	priv_ptr ptr=(priv_ptr)video_get_drvdata(loopdev);
#else
	priv_ptr ptr=(priv_ptr)loopdev->priv;
#endif	
	int nr=ptr->pipenr;

	if (loopdev==NULL)
		return -EFAULT;
	if (!ptr->in)
		return 0;

	if (loops[nr]->ioctlnr!=-1) {
		if (loops[nr]->zerocopy) {
			return (POLLIN | POLLPRI | POLLOUT | POLLRDNORM);
		} else {
			return (POLLOUT);
		}
	}
	return 0;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
static struct v4l2_file_operations fileops_template=
#else
static struct file_operations fileops_template=
#endif
{
	owner:		THIS_MODULE,
	open:		vloopback_open,
	release:	vloopback_release,
	read:		vloopback_read,
	write:		vloopback_write,
	poll:		vloopback_poll,
	ioctl:		vloopback_ioctl,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) && defined(CONFIG_COMPAT)
	compat_ioctl:	v4l_compat_ioctl32,
#endif
	mmap:		vloopback_mmap,
};
예제 #5
0
파일: qtft_fb.c 프로젝트: dujiepeng/module
static int qtft_fb_probe(struct platform_device * dev)
{
	struct fb_info *info;
	int retval = -ENOMEM;

	func_in();

	// 分配显存
	if (!(videomemory = rvmalloc(videomemorysize)))
		return retval;
	memset(videomemory, 0, videomemorysize);

	// 动态分配 fb_info
	info = framebuffer_alloc((sizeof(u32)*16), &dev->dev);
	if (!info)
		goto err0;

	// 虚拟地址
	info->screen_base = (char __iomem *)videomemory;
	info->screen_size = videomemorysize;
	
	// 文件操作符 qtft_fb_ops 在 ops.c 中定义
	info->fbops = &qtft_fb_ops;

	info->var = qtft_fb_var_default;

	qtft_fb_fix_default.smem_start = (unsigned long) videomemory;
	qtft_fb_fix_default.smem_len = videomemorysize;
	info->fix = qtft_fb_fix_default;
	
	// 16色伪调色板指针指向了 info->par 的私有空间
	info->pseudo_palette = info->par;
	info->par = NULL;
	info->flags = FBINFO_DEFAULT;

	// 为16色伪调色板分配内存
	retval = fb_alloc_cmap(&info->cmap, 16, 0);
	if (retval < 0)
		goto err1;

	retval = register_framebuffer(info);
	if (retval < 0)
		goto err2;

	// 初始化 LCD 模块
	retval = lcd_init();
	if (retval < 0)
		goto err3;

	retval = lcd_hard_reset();
	if (retval < 0)
		goto err3;

	retval = lcd_normal_config();
	if (retval < 0)
		goto err3;

	lcd_address_set(0,0,(info->var).xres,(info->var).yres);
	
	// 将 info 指针存入平台设备私有数据
	platform_set_drvdata(dev, info);

	printk(KERN_INFO "SPI QVGA TFT LCD driver: fb%d, %ldK video memory\n", info->node, videomemorysize >> 10);
	goto out;

err3:
	unregister_framebuffer(info);
err2:
	fb_dealloc_cmap(&info->cmap);
err1:
	framebuffer_release(info);
err0:
	rvfree(videomemory, videomemorysize);
out:
	func_out();
	return retval;
}