X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Flp.c;h=e572605252935c8562b64dbfcb6ed483fbd10756;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=c1437fb248ecee34b53d306fb4fa0da5ea515e1b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/lp.c b/drivers/char/lp.c index c1437fb24..e57260525 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -12,7 +12,7 @@ * "lp=" command line parameters added by Grant Guenther, grant@torque.net * lp_read (Status readback) support added by Carsten Gross, * carsten@sol.wohnheim.uni-ulm.de - * Support for parport by Philip Blundell + * Support for parport by Philip Blundell * Parport sharing hacking by Andrea Arcangeli * Fixed kernel_(to/from)_user memory copy to check for errors * by Riccardo Facchetti @@ -127,6 +127,8 @@ #include #include #include +#include +#include #include #undef LP_STATS @@ -142,10 +144,10 @@ /* ROUND_UP macro from fs/select.c */ #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) -struct lp_struct lp_table[LP_NO]; +static struct lp_struct lp_table[LP_NO]; static unsigned int lp_count = 0; -static struct class_simple *lp_class; +static struct class *lp_class; #ifdef CONFIG_LP_CONSOLE static struct parport *console_registered; // initially NULL @@ -218,6 +220,7 @@ static int lp_reset(int minor) static void lp_error (int minor) { + DEFINE_WAIT(wait); int polling; if (LP_F(minor) & LP_ABORT) @@ -225,8 +228,9 @@ static void lp_error (int minor) polling = lp_table[minor].dev->port->irq == PARPORT_IRQ_NONE; if (polling) lp_release_parport (&lp_table[minor]); - interruptible_sleep_on_timeout (&lp_table[minor].waitq, - LP_TIMEOUT_POLLED); + prepare_to_wait(&lp_table[minor].waitq, &wait, TASK_INTERRUPTIBLE); + schedule_timeout(LP_TIMEOUT_POLLED); + finish_wait(&lp_table[minor].waitq, &wait); if (polling) lp_claim_parport_or_block (&lp_table[minor]); else parport_yield_blocking (lp_table[minor].dev); } @@ -291,7 +295,7 @@ static int lp_wait_ready(int minor, int nonblock) return error; } -static ssize_t lp_write(struct file * file, const char * buf, +static ssize_t lp_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { unsigned int minor = iminor(file->f_dentry->d_inode); @@ -304,7 +308,7 @@ static ssize_t lp_write(struct file * file, const char * buf, (LP_F(minor) & LP_ABORT)); #ifdef LP_STATS - if (jiffies-lp_table[minor].lastcall > LP_TIME(minor)) + if (time_after(jiffies, lp_table[minor].lastcall + LP_TIME(minor))) lp_table[minor].runchars = 0; lp_table[minor].lastcall = jiffies; @@ -314,12 +318,14 @@ static ssize_t lp_write(struct file * file, const char * buf, if (copy_size > LP_BUFFER_SIZE) copy_size = LP_BUFFER_SIZE; - if (copy_from_user (kbuf, buf, copy_size)) - return -EFAULT; - if (down_interruptible (&lp_table[minor].port_mutex)) return -EINTR; + if (copy_from_user (kbuf, buf, copy_size)) { + retv = -EFAULT; + goto out_unlock; + } + /* Claim Parport or sleep until it becomes available */ lp_claim_parport_or_block (&lp_table[minor]); @@ -398,7 +404,7 @@ static ssize_t lp_write(struct file * file, const char * buf, lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; lp_release_parport (&lp_table[minor]); } - +out_unlock: up (&lp_table[minor].port_mutex); return retv; @@ -407,9 +413,10 @@ static ssize_t lp_write(struct file * file, const char * buf, #ifdef CONFIG_PARPORT_1284 /* Status readback conforming to ieee1284 */ -static ssize_t lp_read(struct file * file, char * buf, +static ssize_t lp_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { + DEFINE_WAIT(wait); unsigned int minor=iminor(file->f_dentry->d_inode); struct parport *port = lp_table[minor].dev->port; ssize_t retval = 0; @@ -458,9 +465,11 @@ static ssize_t lp_read(struct file * file, char * buf, retval = -EIO; goto out; } - } else - interruptible_sleep_on_timeout (&lp_table[minor].waitq, - LP_TIMEOUT_POLLED); + } else { + prepare_to_wait(&lp_table[minor].waitq, &wait, TASK_INTERRUPTIBLE); + schedule_timeout(LP_TIMEOUT_POLLED); + finish_wait(&lp_table[minor].waitq, &wait); + } if (signal_pending (current)) { retval = -ERESTARTSYS; @@ -560,6 +569,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, unsigned int minor = iminor(inode); int status; int retval = 0; + void __user *argp = (void __user *)arg; #ifdef LP_DEBUG printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); @@ -603,7 +613,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, return -EINVAL; break; case LPGETIRQ: - if (copy_to_user((int *) arg, &LP_IRQ(minor), + if (copy_to_user(argp, &LP_IRQ(minor), sizeof(int))) return -EFAULT; break; @@ -612,7 +622,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, status = r_str(minor); lp_release_parport (&lp_table[minor]); - if (copy_to_user((int *) arg, &status, sizeof(int))) + if (copy_to_user(argp, &status, sizeof(int))) return -EFAULT; break; case LPRESET: @@ -620,7 +630,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, break; #ifdef LP_STATS case LPGETSTATS: - if (copy_to_user((int *) arg, &LP_STAT(minor), + if (copy_to_user(argp, &LP_STAT(minor), sizeof(struct lp_stats))) return -EFAULT; if (capable(CAP_SYS_ADMIN)) @@ -630,13 +640,12 @@ static int lp_ioctl(struct inode *inode, struct file *file, #endif case LPGETFLAGS: status = LP_F(minor); - if (copy_to_user((int *) arg, &status, sizeof(int))) + if (copy_to_user(argp, &status, sizeof(int))) return -EFAULT; break; case LPSETTIMEOUT: - if (copy_from_user (&par_timeout, - (struct timeval *) arg, + if (copy_from_user (&par_timeout, argp, sizeof (struct timeval))) { return -EFAULT; } @@ -749,8 +758,8 @@ static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC }; static char *parport[LP_NO] = { NULL, }; static int reset = 0; -MODULE_PARM(parport, "1-" __MODULE_STRING(LP_NO) "s"); -MODULE_PARM(reset, "i"); +module_param_array(parport, charp, NULL, 0); +module_param(reset, bool, 0); #ifndef MODULE static int __init lp_setup (char *str) @@ -796,7 +805,7 @@ static int lp_register(int nr, struct parport *port) if (reset) lp_reset(nr); - class_simple_device_add(lp_class, MKDEV(LP_MAJOR, nr), NULL, + class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, "lp%d", nr); devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO, "printers/%d", nr); @@ -867,7 +876,7 @@ static struct parport_driver lp_driver = { .detach = lp_detach, }; -int __init lp_init (void) +static int __init lp_init (void) { int i, err = 0; @@ -899,7 +908,7 @@ int __init lp_init (void) } devfs_mk_dir("printers"); - lp_class = class_simple_create(THIS_MODULE, "printer"); + lp_class = class_create(THIS_MODULE, "printer"); if (IS_ERR(lp_class)) { err = PTR_ERR(lp_class); goto out_devfs; @@ -922,7 +931,7 @@ int __init lp_init (void) return 0; out_class: - class_simple_destroy(lp_class); + class_destroy(lp_class); out_devfs: devfs_remove("printers"); unregister_chrdev(LP_MAJOR, "lp"); @@ -973,10 +982,10 @@ static void lp_cleanup_module (void) continue; parport_unregister_device(lp_table[offset].dev); devfs_remove("printers/%d", offset); - class_simple_device_remove(MKDEV(LP_MAJOR, offset)); + class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); } devfs_remove("printers"); - class_simple_destroy(lp_class); + class_destroy(lp_class); } __setup("lp=", lp_setup);