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

📄 joystick.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		struct JS_DATA_TYPE data;		data.buttons = jd->new.buttons[0];		data.x = jd->num_axes < 1 ? 0 :			((js_correct(jd->new.axes[0], &jd->corr[0]) / 256) + 128) >> js_comp_glue.JS_CORR.x;		data.y = jd->num_axes < 2 ? 0 :			((js_correct(jd->new.axes[1], &jd->corr[1]) / 256) + 128) >> js_comp_glue.JS_CORR.y;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)		retval = copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;#else		if (!(retval = verify_area(VERIFY_WRITE, buf, sizeof(struct JS_DATA_TYPE)))) {			memcpy_tofs(buf, &data, sizeof(struct JS_DATA_TYPE));		}#endif		curl->startup = 0;		curl->tail = GOB(jd->bhead);		if (!retval) retval = sizeof(struct JS_DATA_TYPE);	}/* * Check main tail and move it. */	if (orig_tail == jd->tail) {		new_tail = curl->tail;		curl = jd->list;		while (curl != NULL && curl->tail != jd->tail) {			if (ROT(jd->bhead, new_tail, curl->tail) ||				(jd->bhead == curl->tail)) new_tail = curl->tail;			curl = curl->next;		}		if (curl == NULL) jd->tail = new_tail;	}	spin_unlock_irqrestore(&js_lock, flags);	return retval ? retval : written * sizeof(struct js_event);}/* * js_poll() does select() support. */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)static unsigned int js_poll(struct file *file, poll_table *wait){	struct js_list *curl = file->private_data;	unsigned long flags;	int retval = 0;	poll_wait(file, &curl->dev->wait, wait);	spin_lock_irqsave(&js_lock, flags);		if (GOF(curl->tail) != curl->dev->bhead ||		curl->startup < curl->dev->num_axes + curl->dev->num_buttons) retval = POLLIN | POLLRDNORM;	spin_unlock_irqrestore(&js_lock, flags);	return retval;}#elsestatic int js_select(struct inode *inode, struct file *file, int sel_type, select_table *wait){	struct js_list *curl = file->private_data;	if (sel_type == SEL_IN) {		if (GOF(curl->tail) != curl->dev->bhead) return 1;		select_wait(&curl->dev->wait, wait);	}	return 0;}#endif/* * js_ioctl handles misc ioctl calls. */static int js_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct js_list *curl;	struct js_dev *jd;	int len;	curl = file->private_data;	jd = curl->dev;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)	switch (cmd) {/* * 0.x compatibility */		case JS_SET_CAL:			return copy_from_user(&js_comp_glue.JS_CORR, (struct JS_DATA_TYPE *) arg,				sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;		case JS_GET_CAL:			return copy_to_user((struct JS_DATA_TYPE *) arg, &js_comp_glue.JS_CORR,				sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;		case JS_SET_TIMEOUT:			return get_user(js_comp_glue.JS_TIMEOUT, (int *) arg);		case JS_GET_TIMEOUT:			return put_user(js_comp_glue.JS_TIMEOUT, (int *) arg);		case JS_SET_TIMELIMIT:			return get_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);		case JS_GET_TIMELIMIT:			return put_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);		case JS_SET_ALL:			return copy_from_user(&js_comp_glue, (struct JS_DATA_SAVE_TYPE *) arg,						sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;		case JS_GET_ALL:			return copy_to_user((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue,						sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;/* * 1.x ioctl calls */		case JSIOCGVERSION:			return put_user(JS_VERSION, (__u32 *) arg);		case JSIOCGAXES:			return put_user(jd->num_axes, (__u8 *) arg);		case JSIOCGBUTTONS:			return put_user(jd->num_buttons, (__u8 *) arg);		case JSIOCSCORR:			return copy_from_user(jd->corr, (struct js_corr *) arg,						sizeof(struct js_corr) * jd->num_axes) ? -EFAULT : 0;		case JSIOCGCORR:			return copy_to_user((struct js_corr *) arg, jd->corr,						sizeof(struct js_corr) * jd->num_axes) ? -EFAULT : 0;		default:			if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {				len = strlen(jd->name) + 1;				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);				if (copy_to_user((char *) arg, jd->name, len)) return -EFAULT;				return len;			}	}#else	switch (cmd) {/* * 0.x compatibility */		case JS_SET_CAL:			if (verify_area(VERIFY_READ, (struct JS_DATA_TYPE *) arg,				sizeof(struct JS_DATA_TYPE))) return -EFAULT;			memcpy_fromfs(&js_comp_glue.JS_CORR, (struct JS_DATA_SAVE_TYPE *) arg,				sizeof(struct JS_DATA_TYPE));			return 0;		case JS_GET_CAL:			if (verify_area(VERIFY_WRITE, (struct JS_DATA_TYPE *) arg,				sizeof(struct JS_DATA_TYPE))) return -EFAULT;			memcpy_tofs((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue.JS_CORR,				sizeof(struct JS_DATA_TYPE));			return 0;		case JS_SET_TIMEOUT:			if (verify_area(VERIFY_READ, (int *) arg, sizeof(int))) return -EFAULT;			js_comp_glue.JS_TIMEOUT = get_user((int *) arg);			return 0;		case JS_GET_TIMEOUT:			if (verify_area(VERIFY_WRITE, (int *) arg, sizeof(int))) return -EFAULT;			put_user(js_comp_glue.JS_TIMEOUT, (int *) arg);			return 0;		case JS_SET_TIMELIMIT:			if (verify_area(VERIFY_READ, (long *) arg, sizeof(long))) return -EFAULT;			js_comp_glue.JS_TIMELIMIT = get_user((long *) arg);			return 0;		case JS_GET_TIMELIMIT:			if (verify_area(VERIFY_WRITE, (long *) arg, sizeof(long))) return -EFAULT;			put_user(js_comp_glue.JS_TIMELIMIT, (long *) arg);			return 0;		case JS_SET_ALL:			if (verify_area(VERIFY_READ, (struct JS_DATA_SAVE_TYPE *) arg,				sizeof(struct JS_DATA_SAVE_TYPE))) return -EFAULT;			memcpy_fromfs(&js_comp_glue, (struct JS_DATA_SAVE_TYPE *) arg,				sizeof(struct JS_DATA_SAVE_TYPE));			return 0;		case JS_GET_ALL:			if (verify_area(VERIFY_WRITE, (struct JS_DATA_SAVE_TYPE *) arg,				sizeof(struct JS_DATA_SAVE_TYPE))) return -EFAULT;			memcpy_tofs((struct JS_DATA_SAVE_TYPE *) arg, &js_comp_glue,				sizeof(struct JS_DATA_SAVE_TYPE));			return 0;/* * 1.x ioctl calls */		case JSIOCGVERSION:			if (verify_area(VERIFY_WRITE, (__u32 *) arg, sizeof(__u32))) return -EFAULT;			put_user(JS_VERSION, (__u32 *) arg);			return 0;		case JSIOCGAXES:			if (verify_area(VERIFY_WRITE, (__u8 *) arg, sizeof(__u8))) return -EFAULT;			put_user(jd->num_axes, (__u8 *) arg);			return 0;		case JSIOCGBUTTONS:			if (verify_area(VERIFY_WRITE, (__u8 *) arg, sizeof(__u8))) return -EFAULT;			put_user(jd->num_buttons, (__u8 *) arg);			return 0;		case JSIOCSCORR:			if (verify_area(VERIFY_READ, (struct js_corr *) arg,				sizeof(struct js_corr) * jd->num_axes)) return -EFAULT;			memcpy_fromfs(jd->corr, (struct js_corr *) arg,				sizeof(struct js_corr) * jd->num_axes);			return 0;		case JSIOCGCORR:			if (verify_area(VERIFY_WRITE, (struct js_corr *) arg,				sizeof(struct js_corr) * jd->num_axes)) return -EFAULT;			memcpy_tofs((struct js_corr *) arg,				jd->corr, sizeof(struct js_corr) * jd->num_axes);			return 0;		default:			if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {				len = strlen(jd->name) + 1;				if (verify_area(VERIFY_WRITE, (char *) arg, len)) return -EFAULT;				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);				memcpy_tofs((char *) arg, jd->name, len);				return len;			}	}#endif	return -EINVAL;}/* * js_open() performs necessary initialization and adds * an entry to the linked list. */static int js_open(struct inode *inode, struct file *file){	struct js_list *curl, *new;	struct js_dev *jd = js_dev;	int i = MINOR(inode->i_rdev);	unsigned long flags;	int result; 	if (MAJOR(inode->i_rdev) != JOYSTICK_MAJOR)		return -EINVAL;	spin_lock_irqsave(&js_lock, flags);	while (i > 0 && jd != NULL) {		jd = jd->next;		i--;	}	spin_unlock_irqrestore(&js_lock, flags);	if (jd == NULL) return -ENODEV;	if ((result = jd->open(jd))) return result;	MOD_INC_USE_COUNT;	if (!js_use_count++) js_do_timer(0);	if ((new = kmalloc(sizeof(struct js_list), GFP_KERNEL)) != NULL) {		spin_lock_irqsave(&js_lock, flags);		curl = jd->list;		jd->list = new;		jd->list->next = curl;		jd->list->dev = jd;		jd->list->startup = 0;		jd->list->tail = GOB(jd->bhead);		file->private_data = jd->list;		spin_unlock_irqrestore(&js_lock, flags);	} else {		result = -ENOMEM;	}	return result;}/* * js_release() removes an entry from list and deallocates memory * used by it. */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)static int js_release(struct inode *inode, struct file *file)#elsestatic void js_release(struct inode *inode, struct file *file)#endif{	struct js_list *curl = file->private_data;	struct js_dev *jd = curl->dev;	struct js_list **curp = &jd->list;	int new_tail;	unsigned long flags;	spin_lock_irqsave(&js_lock, flags);	while (*curp && (*curp != curl)) curp = &((*curp)->next);	*curp = (*curp)->next;	if (jd->list != NULL)	if (curl->tail == jd->tail) {		curl = jd->list;		new_tail = curl->tail;		while (curl != NULL && curl->tail != jd->tail) {			if (ROT(jd->bhead, new_tail, curl->tail) ||			       (jd->bhead == curl->tail)) new_tail = curl->tail;			curl = curl->next;		}		if (!curl) jd->tail = new_tail;	}	spin_unlock_irqrestore(&js_lock, flags);	kfree(file->private_data);	if (!--js_use_count) del_timer(&js_timer);	MOD_DEC_USE_COUNT;	jd->close(jd);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)	return 0;#endif}/* * js_dump_mem() dumps all data structures in memory. * It's used for debugging only. */#if 0static void js_dump_mem(void){	struct js_port *curp = js_port;	struct js_dev *curd = js_dev;	int i;	printk(",--- Dumping Devices:\n");	printk("| js_dev = %x\n", (int) js_dev);	while (curd != NULL) {		printk("|  %s-device %x, next %x axes %d, buttons %d, port %x - %#x\n",			curd->next ? "|":"`",			(int) curd, (int) curd->next, curd->num_axes, curd->num_buttons, (int) curd->port, curd->port->io);		curd = curd->next;	}	printk(">--- Dumping ports:\n");	printk("| js_port = %x\n", (int) js_port);	while (curp != NULL) {		printk("|  %s-port %x, next %x, io %#x, devices %d\n",			curp->next ? "|":"`",			(int) curp, (int) curp->next, curp->io, curp->ndevs);		for (i = 0; i < curp->ndevs; i++) {			curd = curp->devs[i];			if (curd)			printk("|  %s %s-device %x, next %x axes %d, buttons %d, port %x\n",				curp->next ? "|":" ", (i < curp->ndevs-1) ? "|":"`",				(int) curd, (int) curd->next, curd->num_axes, curd->num_buttons, (int) curd->port);			else			printk("|  %s %s-device %x, not there\n",				curp->next ? "|":" ", (i < curp->ndevs-1) ? "|":"`", (int) curd);		}		curp = curp->next;	}	printk("`--- Done\n");}#endifstruct js_port *js_register_port(struct js_port *port,				void *info, int devs, int infos, js_read_func read){	struct js_port **ptrp = &js_port;	struct js_port *curp;	void *all;	int i;	unsigned long flags;	if ((all = kmalloc(sizeof(struct js_port) + 4 * devs * sizeof(void*) + infos, GFP_KERNEL)) == NULL)		return NULL;	curp = all;	curp->next = NULL;	curp->prev = port;	curp->read = read;	curp->ndevs = devs;	curp->devs = all += sizeof(struct js_port);	for (i = 0; i < devs; i++) curp->devs[i] = NULL;	curp->axes = all += devs * sizeof(void*);	curp->buttons = (void*) all += devs * sizeof(void*);	curp->corr = all += devs * sizeof(void*);	if (infos) {		curp->info = all += devs * sizeof(void*); 		memcpy(curp->info, info, infos);	} else {		curp->info = NULL;	}	spin_lock_irqsave(&js_lock, flags);	while (*ptrp != NULL) ptrp=&((*ptrp)->next);	*ptrp = curp;	spin_unlock_irqrestore(&js_lock, flags);	return curp;}struct js_port *js_unregister_port(struct js_port *port){	struct js_port **curp = &js_port;	struct js_port *prev;	unsigned long flags;	spin_lock_irqsave(&js_lock, flags);	while (*curp != NULL && (*curp != port)) curp = &((*curp)->next);	*curp = (*curp)->next;	spin_unlock_irqrestore(&js_lock, flags);	prev = port->prev;	kfree(port);	return prev;}int js_register_device(struct js_port *port, int number, int axes, int buttons, char *name,					js_ops_func open, js_ops_func close){	struct js_dev **ptrd = &js_dev;	struct js_dev *curd;	void *all;	int i = 0;	unsigned long flags;	if ((all = kmalloc(sizeof(struct js_dev) + 2 * axes * sizeof(int) +			2 * (((buttons - 1) >> 5) + 1) * sizeof(int) +			axes * sizeof(struct js_corr) + strlen(name) + 1, GFP_KERNEL)) == NULL)		return -1;	curd = all;	curd->next = NULL;	curd->list = NULL;	curd->port = port;	curd->wait = NULL;	curd->open = open;	curd->close = close;	curd->ahead = 0;	curd->bhead = 0;	curd->tail = JS_BUFF_SIZE - 1;	curd->num_axes = axes;	curd->num_buttons = buttons;	curd->cur.axes = all += sizeof(struct js_dev);	curd->cur.buttons = all += axes * sizeof(int);	curd->new.axes = all += (((buttons - 1) >> 5) + 1) * sizeof(int);	curd->new.buttons = all += axes * sizeof(int);	curd->corr = all += (((buttons -1 ) >> 5) + 1) * sizeof(int);	curd->name = all += axes * sizeof(struct js_corr);	strcpy(curd->name, name);	port->devs[number] = curd;	port->axes[number] = curd->new.axes;	port->buttons[number] = curd->new.buttons;	port->corr[number] = curd->corr;	spin_lock_irqsave(&js_lock, flags);	while (*ptrd != NULL) { ptrd=&(*ptrd)->next; i++; }	*ptrd = curd;	spin_unlock_irqrestore(&js_lock, flags);		return i;}void js_unregister_device(struct js_dev *dev){	struct js_dev **curd = &js_dev;	unsigned long flags;	spin_lock_irqsave(&js_lock, flags);	while (*curd != NULL && (*curd != dev)) curd = &((*curd)->next);	*curd = (*curd)->next;	spin_unlock_irqrestore(&js_lock, flags);		kfree(dev);}/* * The operations structure. */static struct file_operations js_fops ={	read:		js_read,#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)	poll:		js_poll,#else	select:		js_select,#endif	ioctl:		js_ioctl,	open:		js_open,	release:	js_release,};/* * js_init() registers the driver and calls the probe function. * also initializes some crucial variables. */#ifdef MODULEint init_module(void)#elseint __init js_init(void)#endif{	int result;	js_setup_time();	if (register_chrdev(JOYSTICK_MAJOR, "js", &js_fops)) {		printk(KERN_ERR "js: unable to get major %d for joystick\n", JOYSTICK_MAJOR);		return -EBUSY;	}	spin_lock_init(&js_lock);	init_timer(&js_timer);	js_timer.function = js_do_timer;	js_timer.data = 1;	memset(&js_comp_glue, 0, sizeof(struct JS_DATA_SAVE_TYPE));	js_comp_glue.JS_TIMEOUT = JS_DEF_TIMEOUT;	js_comp_glue.JS_TIMELIMIT = JS_DEF_TIMELIMIT;#ifdef MODULE	result = 0;#else	result = -ENODEV;#ifdef CONFIG_JOY_LIGHTNING	if (!js_l4_init()) result = 0;#endif#ifdef CONFIG_JOY_SIDEWINDER	if (!js_sw_init()) result = 0;#endif#ifdef CONFIG_JOY_ASSASIN	if (!js_as_init()) result = 0;#endif#ifdef CONFIG_JOY_LOGITECH	if (!js_lt_init()) result = 0;#endif#ifdef CONFIG_JOY_THRUSTMASTER	if (!js_tm_init()) result = 0;#endif#ifdef CONFIG_JOY_GRAVIS	if (!js_gr_init()) result = 0;#endif#ifdef CONFIG_JOY_ANALOG	if (!js_an_init()) result = 0;#endif#ifdef CONFIG_JOY_CONSOLE	if (!js_console_init()) result = 0;#endif#ifdef CONFIG_JOY_DB9	if (!js_db9_init()) result = 0;#endif#ifdef CONFIG_JOY_AMIGA	if (!js_am_init()) result = 0;#endif	if (result) printk(KERN_ERR "js: no joysticks found\n");#endif	return result;}/* * cleanup_module() handles module removal. */#ifdef MODULEvoid cleanup_module(void){	del_timer(&js_timer);	if (unregister_chrdev(JOYSTICK_MAJOR, "js"))		printk(KERN_ERR "js: can't unregister device\n");}#endif

⌨️ 快捷键说明

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