patch-2.3.43 linux/drivers/char/lp.c

Next file: linux/drivers/char/mem.c
Previous file: linux/drivers/char/keyboard.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.42/linux/drivers/char/lp.c linux/drivers/char/lp.c
@@ -106,6 +106,8 @@
  * month ago...
  *
  *                                     14 Dec 1998, Andrea Arcangeli
+ *
+ * Copyright (C) 2000 by Tim Waugh (added LPSETTIMEOUT ioctl)
  */
 
 #include <linux/module.h>
@@ -133,6 +135,9 @@
 /* if you have more than 3 printers, remember to increase LP_NO */
 #define LP_NO 3
 
+/* ROUND_UP macro from fs/select.c */
+#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+
 struct lp_struct lp_table[LP_NO];
 
 static unsigned int lp_count = 0;
@@ -321,6 +326,7 @@
 	ssize_t retv = 0;
 	ssize_t written;
 	size_t copy_size = count;
+	long old_to;
 
 #ifdef LP_STATS
 	if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
@@ -346,6 +352,9 @@
 	/* Go to compatibility mode. */
 	parport_negotiate (port, IEEE1284_MODE_COMPAT);
 
+	old_to = parport_set_timeout (lp_table[minor].dev,
+				      lp_table[minor].timeout);
+
 	do {
 		/* Write the data. */
 		written = parport_write (port, kbuf, copy_size);
@@ -390,6 +399,9 @@
 		}	
 	} while (count > 0);
 
+	/* Not really necessary, but polite. */
+	parport_set_timeout (lp_table[minor].dev, old_to);
+
  	lp_parport_release (minor);
 
 	up (&lp_table[minor].port_mutex);
@@ -527,6 +539,9 @@
 	if ((LP_F(minor) & LP_EXIST) == 0)
 		return -ENODEV;
 	switch ( cmd ) {
+		struct timeval par_timeout;
+		long to_jiffies;
+
 		case LPTIME:
 			LP_TIME(minor) = arg * HZ/100;
 			break;
@@ -588,6 +603,26 @@
 			if (copy_to_user((int *) arg, &status, sizeof(int)))
 				return -EFAULT;
 			break;
+
+		case LPSETTIMEOUT:
+			if (copy_from_user (&par_timeout,
+					    (struct timeval *) arg,
+					    sizeof (struct timeval))) {
+				return -EFAULT;
+			}
+			/* Convert to jiffies, place in lp_table */
+			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;
+			}
+			lp_table[minor].timeout = to_jiffies;
+			break;
+
 		default:
 			retval = -EINVAL;
 	}
@@ -610,24 +645,14 @@
 #endif /* IEEE 1284 support */
 
 static struct file_operations lp_fops = {
-	lp_lseek,
-#ifdef CONFIG_PARPORT_1284
-	lp_read,
-#else
-	NULL,
-#endif
-	lp_write,
-	NULL,		/* lp_readdir */
+	write:		lp_write,
+	ioctl:		lp_ioctl,
+	open:		lp_open,
+	release:	lp_release,
 #ifdef CONFIG_PARPORT_1284
-	lp_poll,
-#else
-	NULL,
+	read:		lp_read,
+	poll:		lp_poll,
 #endif
-	lp_ioctl,
-	NULL,		/* lp_mmap */
-	lp_open,
-	NULL,		/* flush */
-	lp_release
 };
 
 /* --- support for console on the line printer ----------------- */
@@ -664,28 +689,33 @@
 	do {
 		/* Write the data, converting LF->CRLF as we go. */
 		ssize_t canwrite = count;
-		char *line = strchr (s, '\n');
-		if (line)
-			canwrite = line - s;
-
-		written = parport_write (port, s, canwrite);
-		if (written <= 0)
-			continue;
-
-		s += written;
-		count -= written;
-		if (line) {
+		char *lf = strchr (s, '\n');
+		if (lf)
+			canwrite = lf - s;
+
+		if (canwrite > 0) {
+			written = parport_write (port, s, canwrite);
+
+			if (written <= 0)
+				continue;
+
+			s += written;
+			count -= written;
+			canwrite -= written;
+		}
+
+		if (lf && canwrite <= 0) {
 			const char *crlf = "\r\n";
 			int i = 2;
 
 			/* Dodge the original '\n', and put '\r\n' instead. */
 			s++;
 			count--;
-			while (i) {
+			do {
 				written = parport_write (port, crlf, i);
 				if (written > 0)
 					i -= written, crlf += written;
-			}
+			} while (i > 0 && (CONSOLE_LP_STRICT || written > 0));
 		}
 	} while (count > 0 && (CONSOLE_LP_STRICT || written > 0));
 
@@ -698,7 +728,7 @@
 }
 
 static struct console lpcons = {
-	"lp0",
+	"lp",
 	lp_console_write,
 	NULL,
 	lp_console_device,
@@ -706,7 +736,7 @@
 	NULL,
 	NULL,
 	CON_PRINTBUFFER,
-	-1,
+	0,
 	0,
 	NULL
 };
@@ -778,6 +808,7 @@
 #ifdef CONFIG_LP_CONSOLE
 	if (!nr) {
 		if (port->modes & PARPORT_MODE_SAFEININT) {
+			MOD_INC_USE_COUNT;
 			register_console (&lpcons);
 			printk (KERN_INFO "lp%d: console ready\n", CONSOLE_LP);
 		} else
@@ -854,6 +885,7 @@
 		init_waitqueue_head (&lp_table[i].waitq);
 		init_waitqueue_head (&lp_table[i].dataq);
 		init_MUTEX (&lp_table[i].port_mutex);
+		lp_table[i].timeout = 10 * HZ;
 	}
 
 	if (register_chrdev (LP_MAJOR, "lp", &lp_fops)) {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)