X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fppdev.c;h=4abd1eff61d667c79297e59235437405b3f6b451;hb=refs%2Fheads%2Fvserver;hp=525905c07435c9f2041bc27b91dc5c35fcbac0cb;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 525905c07..4abd1eff6 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -59,15 +59,16 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include #include +#include #define PP_VERSION "ppdev: user-space parallel port driver" #define CHRDEV "ppdev" @@ -102,10 +103,10 @@ static inline void pp_enable_irq (struct pp_struct *pp) port->ops->enable_irq (port); } -static ssize_t pp_read (struct file * file, char * buf, size_t count, +static ssize_t pp_read (struct file * file, char __user * buf, size_t count, loff_t * ppos) { - unsigned int minor = iminor(file->f_dentry->d_inode); + unsigned int minor = iminor(file->f_path.dentry->d_inode); struct pp_struct *pp = file->private_data; char * kbuffer; ssize_t bytes_read = 0; @@ -185,10 +186,10 @@ static ssize_t pp_read (struct file * file, char * buf, size_t count, return bytes_read; } -static ssize_t pp_write (struct file * file, const char * buf, size_t count, - loff_t * ppos) +static ssize_t pp_write (struct file * file, const char __user * buf, + size_t count, loff_t * ppos) { - unsigned int minor = iminor(file->f_dentry->d_inode); + unsigned int minor = iminor(file->f_path.dentry->d_inode); struct pp_struct *pp = file->private_data; char * kbuffer; ssize_t bytes_written = 0; @@ -268,7 +269,7 @@ static ssize_t pp_write (struct file * file, const char * buf, size_t count, return bytes_written; } -static void pp_irq (int irq, void * private, struct pt_regs * unused) +static void pp_irq (int irq, void * private) { struct pp_struct * pp = (struct pp_struct *) private; @@ -334,6 +335,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, unsigned int minor = iminor(inode); struct pp_struct *pp = file->private_data; struct parport * port; + void __user *argp = (void __user *)arg; /* First handle the cases that don't take arguments. */ switch (cmd) { @@ -395,7 +397,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, case PPSETMODE: { int mode; - if (copy_from_user (&mode, (int *) arg, sizeof (mode))) + if (copy_from_user (&mode, argp, sizeof (mode))) return -EFAULT; /* FIXME: validate mode */ pp->state.mode = mode; @@ -417,7 +419,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, } else { mode = pp->state.mode; } - if (copy_to_user ((int *)arg, &mode, sizeof (mode))) { + if (copy_to_user (argp, &mode, sizeof (mode))) { return -EFAULT; } return 0; @@ -425,7 +427,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, case PPSETPHASE: { int phase; - if (copy_from_user (&phase, (int *) arg, sizeof (phase))) { + if (copy_from_user (&phase, argp, sizeof (phase))) { return -EFAULT; } /* FIXME: validate phase */ @@ -446,7 +448,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, } else { phase = pp->state.phase; } - if (copy_to_user ((int *)arg, &phase, sizeof (phase))) { + if (copy_to_user (argp, &phase, sizeof (phase))) { return -EFAULT; } return 0; @@ -460,7 +462,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, return -ENODEV; modes = port->modes; - if (copy_to_user ((unsigned int *)arg, &modes, sizeof (modes))) { + if (copy_to_user (argp, &modes, sizeof (modes))) { return -EFAULT; } return 0; @@ -469,7 +471,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, { int uflags; - if (copy_from_user (&uflags, (int *)arg, sizeof (uflags))) { + if (copy_from_user (&uflags, argp, sizeof (uflags))) { return -EFAULT; } pp->flags &= ~PP_FLAGMASK; @@ -481,7 +483,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, int uflags; uflags = pp->flags & PP_FLAGMASK; - if (copy_to_user ((int *)arg, &uflags, sizeof (uflags))) { + if (copy_to_user (argp, &uflags, sizeof (uflags))) { return -EFAULT; } return 0; @@ -508,17 +510,17 @@ static int pp_ioctl(struct inode *inode, struct file *file, case PPRSTATUS: reg = parport_read_status (port); - if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg))) + if (copy_to_user (argp, ®, sizeof (reg))) return -EFAULT; return 0; case PPRDATA: reg = parport_read_data (port); - if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg))) + if (copy_to_user (argp, ®, sizeof (reg))) return -EFAULT; return 0; case PPRCONTROL: reg = parport_read_control (port); - if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg))) + if (copy_to_user (argp, ®, sizeof (reg))) return -EFAULT; return 0; case PPYIELD: @@ -537,29 +539,29 @@ static int pp_ioctl(struct inode *inode, struct file *file, return 0; case PPWCONTROL: - if (copy_from_user (®, (unsigned char *) arg, sizeof (reg))) + if (copy_from_user (®, argp, sizeof (reg))) return -EFAULT; parport_write_control (port, reg); return 0; case PPWDATA: - if (copy_from_user (®, (unsigned char *) arg, sizeof (reg))) + if (copy_from_user (®, argp, sizeof (reg))) return -EFAULT; parport_write_data (port, reg); return 0; case PPFCONTROL: - if (copy_from_user (&mask, (unsigned char *) arg, + if (copy_from_user (&mask, argp, sizeof (mask))) return -EFAULT; - if (copy_from_user (®, 1 + (unsigned char *) arg, + if (copy_from_user (®, 1 + (unsigned char __user *) arg, sizeof (reg))) return -EFAULT; parport_frob_control (port, mask, reg); return 0; case PPDATADIR: - if (copy_from_user (&mode, (int *) arg, sizeof (mode))) + if (copy_from_user (&mode, argp, sizeof (mode))) return -EFAULT; if (mode) port->ops->data_reverse (port); @@ -568,7 +570,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, return 0; case PPNEGOT: - if (copy_from_user (&mode, (int *) arg, sizeof (mode))) + if (copy_from_user (&mode, argp, sizeof (mode))) return -EFAULT; switch ((ret = parport_negotiate (port, mode))) { case 0: break; @@ -583,8 +585,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, return ret; case PPWCTLONIRQ: - if (copy_from_user (®, (unsigned char *) arg, - sizeof (reg))) + if (copy_from_user (®, argp, sizeof (reg))) return -EFAULT; /* Remember what to set the control lines to, for next @@ -595,14 +596,13 @@ static int pp_ioctl(struct inode *inode, struct file *file, case PPCLRIRQ: ret = atomic_read (&pp->irqc); - if (copy_to_user ((int *) arg, &ret, sizeof (ret))) + if (copy_to_user (argp, &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))) { + if (copy_from_user (&par_timeout, argp, sizeof(struct timeval))) { return -EFAULT; } /* Convert to jiffies, place in pp->pdev->timeout */ @@ -621,10 +621,8 @@ static int pp_ioctl(struct inode *inode, struct file *file, 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))) { + if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) return -EFAULT; - } return 0; default: @@ -739,7 +737,9 @@ static unsigned int pp_poll (struct file * file, poll_table * wait) return mask; } -static struct file_operations pp_fops = { +static struct class *ppdev_class; + +static const struct file_operations pp_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = pp_read, @@ -750,32 +750,58 @@ static struct file_operations pp_fops = { .release = pp_release, }; +static void pp_attach(struct parport *port) +{ + device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), + "parport%d", port->number); +} + +static void pp_detach(struct parport *port) +{ + device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); +} + +static struct parport_driver pp_driver = { + .name = CHRDEV, + .attach = pp_attach, + .detach = pp_detach, +}; + static int __init ppdev_init (void) { - int i; + int err = 0; if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) { printk (KERN_WARNING CHRDEV ": unable to get major %d\n", PP_MAJOR); return -EIO; } - devfs_mk_dir("parports"); - for (i = 0; i < PARPORT_MAX; i++) { - devfs_mk_cdev(MKDEV(PP_MAJOR, i), - S_IFCHR | S_IRUGO | S_IWUGO, "parports/%d", i); + ppdev_class = class_create(THIS_MODULE, CHRDEV); + if (IS_ERR(ppdev_class)) { + err = PTR_ERR(ppdev_class); + goto out_chrdev; + } + if (parport_register_driver(&pp_driver)) { + printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); + goto out_class; } printk (KERN_INFO PP_VERSION "\n"); - return 0; + goto out; + +out_class: + class_destroy(ppdev_class); +out_chrdev: + unregister_chrdev(PP_MAJOR, CHRDEV); +out: + return err; } static void __exit ppdev_cleanup (void) { - int i; /* Clean up all parport stuff */ - for (i = 0; i < PARPORT_MAX; i++) - devfs_remove("parports/%d", i); - devfs_remove("parports"); + parport_unregister_driver(&pp_driver); + class_destroy(ppdev_class); unregister_chrdev (PP_MAJOR, CHRDEV); }