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

📄 ppdev.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (pp->flags & PP_CLAIMED) {			pp->pdev->port->ieee1284.mode = mode;			pp->pdev->port->ieee1284.phase = pp->state.phase;		}		return 0;	    }	case PPGETMODE:	    {		int mode;		if (pp->flags & PP_CLAIMED) {			mode = pp->pdev->port->ieee1284.mode;		} else {			mode = pp->state.mode;		}		if (copy_to_user ((int *)arg, &mode, sizeof (mode))) {			return -EFAULT;		}		return 0;	    }	case PPSETPHASE:	    {		int phase;		if (copy_from_user (&phase, (int *) arg, sizeof (phase))) {			return -EFAULT;		}		/* FIXME: validate phase */		pp->state.phase = phase;		if (pp->flags & PP_CLAIMED) {			pp->pdev->port->ieee1284.phase = phase;		}		return 0;	    }	case PPGETPHASE:	    {		int phase;		if (pp->flags & PP_CLAIMED) {			phase = pp->pdev->port->ieee1284.phase;		} else {			phase = pp->state.phase;		}		if (copy_to_user ((int *)arg, &phase, sizeof (phase))) {			return -EFAULT;		}		return 0;	    }	case PPGETMODES:	    {		unsigned int modes;		port = parport_find_number (minor);		if (!port)			return -ENODEV;		modes = port->modes;		if (copy_to_user ((unsigned int *)arg, &modes, sizeof (modes))) {			return -EFAULT;		}		return 0;	    }	case PPSETFLAGS:	    {		int uflags;		if (copy_from_user (&uflags, (int *)arg, sizeof (uflags))) {			return -EFAULT;		}		pp->flags &= ~PP_FLAGMASK;		pp->flags |= (uflags & PP_FLAGMASK);		return 0;	    }	case PPGETFLAGS:	    {		int uflags;		uflags = pp->flags & PP_FLAGMASK;		if (copy_to_user ((int *)arg, &uflags, sizeof (uflags))) {			return -EFAULT;		}		return 0;	    }	}	/* end switch() */	/* Everything else requires the port to be claimed, so check	 * that now. */	if ((pp->flags & PP_CLAIMED) == 0) {		printk (KERN_DEBUG CHRDEV "%x: claim the port first\n",			minor);		return -EINVAL;	}	port = pp->pdev->port;	switch (cmd) {		struct ieee1284_info *info;		unsigned char reg;		unsigned char mask;		int mode;		int ret;		struct timeval par_timeout;		long to_jiffies;	case PPRSTATUS:		reg = parport_read_status (port);		if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))			return -EFAULT;		return 0;	case PPRDATA:		reg = parport_read_data (port);		if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))			return -EFAULT;		return 0;	case PPRCONTROL:		reg = parport_read_control (port);		if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))			return -EFAULT;		return 0;	case PPYIELD:		parport_yield_blocking (pp->pdev);		return 0;	case PPRELEASE:		/* Save the state machine's state. */		info = &pp->pdev->port->ieee1284;		pp->state.mode = info->mode;		pp->state.phase = info->phase;		info->mode = pp->saved_state.mode;		info->phase = pp->saved_state.phase;		parport_release (pp->pdev);		pp->flags &= ~PP_CLAIMED;		return 0;	case PPWCONTROL:		if (copy_from_user (&reg, (unsigned char *) arg, sizeof (reg)))			return -EFAULT;		parport_write_control (port, reg);		return 0;	case PPWDATA:		if (copy_from_user (&reg, (unsigned char *) arg, sizeof (reg)))			return -EFAULT;		parport_write_data (port, reg);		return 0;	case PPFCONTROL:		if (copy_from_user (&mask, (unsigned char *) arg,				    sizeof (mask)))			return -EFAULT;		if (copy_from_user (&reg, 1 + (unsigned char *) arg,				    sizeof (reg)))			return -EFAULT;		parport_frob_control (port, mask, reg);		return 0;	case PPDATADIR:		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))			return -EFAULT;		if (mode)			port->ops->data_reverse (port);		else			port->ops->data_forward (port);		return 0;	case PPNEGOT:		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))			return -EFAULT;		switch ((ret = parport_negotiate (port, mode))) {		case 0: break;		case -1: /* handshake failed, peripheral not IEEE 1284 */			ret = -EIO;			break;		case 1:  /* handshake succeeded, peripheral rejected mode */			ret = -ENXIO;			break;		}		pp_enable_irq (pp);		return ret;	case PPWCTLONIRQ:		if (copy_from_user (&reg, (unsigned char *) arg,				    sizeof (reg)))			return -EFAULT;		/* Remember what to set the control lines to, for next		 * time we get an interrupt. */		pp->irqctl = reg;		pp->irqresponse = 1;		return 0;	case PPCLRIRQ:		ret = atomic_read (&pp->irqc);		if (copy_to_user ((int *) arg, &ret, sizeof (ret)))			return -EFAULT;		atomic_sub (ret, &pp->irqc);		return 0;	case PPSETTIME:		if (copy_from_user (&par_timeout, (struct timeval *)arg,				    sizeof(struct timeval))) {			return -EFAULT;		}		/* Convert to jiffies, place in pp->pdev->timeout */		if ((par_timeout.tv_sec < 0) || (par_timeout.tv_usec < 0)) {			return -EINVAL;		}		to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);		to_jiffies += par_timeout.tv_sec * (long)HZ;		if (to_jiffies <= 0) {			return -EINVAL;		}		pp->pdev->timeout = to_jiffies;		return 0;	case PPGETTIME:		to_jiffies = pp->pdev->timeout;		par_timeout.tv_sec = to_jiffies / HZ;		par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);		if (copy_to_user ((struct timeval *)arg, &par_timeout,				  sizeof(struct timeval))) {			return -EFAULT;		}		return 0;	default:		printk (KERN_DEBUG CHRDEV "%x: What? (cmd=0x%x)\n", minor,			cmd);		return -EINVAL;	}	/* Keep the compiler happy */	return 0;}static int pp_open (struct inode * inode, struct file * file){	unsigned int minor = MINOR (inode->i_rdev);	struct pp_struct *pp;	if (minor >= PARPORT_MAX)		return -ENXIO;	pp = kmalloc (sizeof (struct pp_struct), GFP_KERNEL);	if (!pp)		return -ENOMEM;	pp->state.mode = IEEE1284_MODE_COMPAT;	pp->state.phase = init_phase (pp->state.mode);	pp->flags = 0;	pp->irqresponse = 0;	atomic_set (&pp->irqc, 0);	init_waitqueue_head (&pp->irq_wait);	/* Defer the actual device registration until the first claim.	 * That way, we know whether or not the driver wants to have	 * exclusive access to the port (PPEXCL).	 */	pp->pdev = NULL;	file->private_data = pp;	return 0;}static int pp_release (struct inode * inode, struct file * file){	unsigned int minor = MINOR (inode->i_rdev);	struct pp_struct *pp = file->private_data;	int compat_negot;	lock_kernel();	compat_negot = 0;	if (!(pp->flags & PP_CLAIMED) && pp->pdev &&	    (pp->state.mode != IEEE1284_MODE_COMPAT)) {	    	struct ieee1284_info *info;		/* parport released, but not in compatability mode */		parport_claim_or_block (pp->pdev);		pp->flags |= PP_CLAIMED;		info = &pp->pdev->port->ieee1284;		pp->saved_state.mode = info->mode;		pp->saved_state.phase = info->phase;		info->mode = pp->state.mode;		info->phase = pp->state.phase;		compat_negot = 1;	} else if ((pp->flags & PP_CLAIMED) && pp->pdev &&	    (pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT)) {		compat_negot = 2;	}	if (compat_negot) {		parport_negotiate (pp->pdev->port, IEEE1284_MODE_COMPAT);		printk (KERN_DEBUG CHRDEV			"%x: negotiated back to compatibility mode because "			"user-space forgot\n", minor);	}	if (pp->flags & PP_CLAIMED) {		struct ieee1284_info *info;		info = &pp->pdev->port->ieee1284;		pp->state.mode = info->mode;		pp->state.phase = info->phase;		info->mode = pp->saved_state.mode;		info->phase = pp->saved_state.phase;		parport_release (pp->pdev);		if (compat_negot != 1) {			printk (KERN_DEBUG CHRDEV "%x: released pardevice "				"because user-space forgot\n", minor);		}	}	if (pp->pdev) {		const char *name = pp->pdev->name;		parport_unregister_device (pp->pdev);		kfree (name);		pp->pdev = NULL;		printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n",			minor);	}	unlock_kernel();	kfree (pp);	return 0;}/* No kernel lock held - fine */static unsigned int pp_poll (struct file * file, poll_table * wait){	struct pp_struct *pp = file->private_data;	unsigned int mask = 0;	poll_wait (file, &pp->irq_wait, wait);	if (atomic_read (&pp->irqc))		mask |= POLLIN | POLLRDNORM;	return mask;}static struct file_operations pp_fops = {	owner:		THIS_MODULE,	llseek:		no_llseek,	read:		pp_read,	write:		pp_write,	poll:		pp_poll,	ioctl:		pp_ioctl,	open:		pp_open,	release:	pp_release,};static devfs_handle_t devfs_handle;static int __init ppdev_init (void){	if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",			PP_MAJOR);		return -EIO;	}	devfs_handle = devfs_mk_dir (NULL, "parports", NULL);	devfs_register_series (devfs_handle, "%u", PARPORT_MAX,			       DEVFS_FL_DEFAULT, PP_MAJOR, 0,			       S_IFCHR | S_IRUGO | S_IWUGO,			       &pp_fops, NULL);	printk (KERN_INFO PP_VERSION "\n");	return 0;}static void __exit ppdev_cleanup (void){	/* Clean up all parport stuff */	devfs_unregister (devfs_handle);	devfs_unregister_chrdev (PP_MAJOR, CHRDEV);}module_init(ppdev_init);module_exit(ppdev_cleanup);MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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