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
- Lines: 196
- Date:
Wed Feb 9 11:42:35 2000
- Orig file:
v2.3.42/linux/drivers/char/lp.c
- Orig date:
Tue Jan 4 13:57:16 2000
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)