Tim Waugh (tim@cyberelk.demon.co.uk)
Fri, 6 Nov 1998 00:19:19 +0000 (GMT)
Hi guys,
Please can anyone who uses lp_read test this out and let me know if it
still works? The idea is that it irons out some bugs in the old lp_read
code.
Does anyone use lp_read? Let me know.
Tim.
*/
--- /big/linux-2.1.126/drivers/char/lp.c Sat Oct 24 11:39:41 1998
+++ linux/drivers/char/lp.c Fri Nov 6 00:11:10 1998
@@ -456,102 +456,72 @@
return (i & 0x0f);
}
-static inline void lp_select_in_high(int minor)
-{
- parport_frob_control(lp_table[minor].dev->port, 8, 8);
+static void lp_read_terminate(struct parport *port) {
+ parport_write_control(port, (parport_read_control(port) & ~2) | 8);
+ /* SelectIN high, AutoFeed low */
+ if (parport_wait_peripheral(port, 0x80, 0))
+ /* timeout, SelectIN high, Autofeed low */
+ return;
+ parport_write_control(port, parport_read_control(port) | 2);
+ /* AutoFeed high */
+ parport_wait_peripheral(port, 0x80, 0x80);
+ /* no timeout possible, Autofeed low, SelectIN high */
+ parport_write_control(port, (parport_read_control(port) & ~2) | 8);
}
-
+
/* Status readback confirming to ieee1284 */
static ssize_t lp_read(struct file * file, char * buf,
- size_t count, loff_t *ppos)
+ size_t length, loff_t *ppos)
{
- unsigned char z=0, Byte=0, status;
- char *temp;
- ssize_t retval;
- unsigned int counter=0;
- unsigned int i;
+ int i;
unsigned int minor=MINOR(file->f_dentry->d_inode->i_rdev);
-
- /* Claim Parport or sleep until it becomes available
- */
- lp_parport_claim (minor);
-
- temp=buf;
-#ifdef LP_READ_DEBUG
- printk(KERN_INFO "lp%d: read mode\n", minor);
-#endif
+ char *temp = buf;
+ ssize_t count = 0;
+ unsigned char z = 0;
+ unsigned char Byte = 0;
+ struct parport *port = lp_table[minor].dev->port;
- retval = verify_area(VERIFY_WRITE, buf, count);
- if (retval)
- return retval;
- if (parport_ieee1284_nibble_mode_ok(lp_table[minor].dev->port, 0)==0) {
-#ifdef LP_READ_DEBUG
- printk(KERN_INFO "lp%d: rejected IEEE1284 negotiation.\n",
- minor);
-#endif
- lp_select_in_high(minor);
- parport_release(lp_table[minor].dev);
- return temp-buf; /* End of file */
- }
- for (i=0; i<=(count*2); i++) {
- parport_frob_control(lp_table[minor].dev->port, 2, 2); /* AutoFeed high */
- do {
- status = (r_str(minor) & 0x40);
- udelay(50);
- counter++;
- if (current->need_resched)
- schedule ();
- } while ((status == 0x40) && (counter < 20));
- if (counter == 20) {
- /* Timeout */
+ for (i=0; ; i++) {
+ parport_frob_control(port, 2, 2); /* AutoFeed high */
+ if (parport_wait_peripheral(port, 0x40, 0)) {
#ifdef LP_READ_DEBUG
- printk(KERN_DEBUG "lp_read: (Autofeed high) timeout\n");
+ /* Some peripherals just time out when they've sent
+ all their data. */
+ printk("%s: read1 timeout.\n", port->name);
#endif
- parport_frob_control(lp_table[minor].dev->port, 2, 0);
- lp_select_in_high(minor);
- parport_release(lp_table[minor].dev);
- return temp-buf; /* end the read at timeout */
+ parport_frob_control(port, 2, 0); /* AutoFeed low */
+ break;
}
- counter=0;
z = lp_read_nibble(minor);
- parport_frob_control(lp_table[minor].dev->port, 2, 0); /* AutoFeed low */
- do {
- status=(r_str(minor) & 0x40);
- udelay(20);
- counter++;
- if (current->need_resched)
- schedule ();
- } while ( (status == 0) && (counter < 20) );
- if (counter == 20) { /* Timeout */
-#ifdef LP_READ_DEBUG
- printk(KERN_DEBUG "lp_read: (Autofeed low) timeout\n");
-#endif
- if (signal_pending(current)) {
- lp_select_in_high(minor);
- parport_release(lp_table[minor].dev);
- if (temp !=buf)
- return temp-buf;
- else
- return -EINTR;
- }
- current->state=TASK_INTERRUPTIBLE;
- current->timeout=jiffies + LP_TIME(minor);
- schedule ();
+ parport_frob_control(port, 2, 0); /* AutoFeed low */
+ if (parport_wait_peripheral(port, 0x40, 0x40)) {
+ printk("%s: read2 timeout.\n", port->name);
+ break;
}
+ if ((i & 1) != 0) {
+ Byte |= (z<<4);
+ if (temp) {
+ if (__put_user (Byte, temp))
+ {
+ count = -EFAULT;
+ temp = NULL;
+ } else {
+ temp++;
- counter=0;
-
- if (( i & 1) != 0) {
- Byte= (Byte | z<<4);
- if (__put_user(Byte, (char *)temp))
- return -EFAULT;
- temp++;
- } else Byte=z;
+ if (++count == length)
+ temp = NULL;
+ }
+ }
+ /* Does the error line indicate end of data? */
+ if ((parport_read_status(port) & LP_PERRORP) ==
+ LP_PERRORP)
+ break;
+ } else
+ Byte=z;
}
- lp_select_in_high(minor);
- lp_parport_release(minor);
- return temp-buf;
+ lp_read_terminate(port);
+ return count;
}
#endif
-- To unsubscribe, send mail to: linux-parport-request@torque.net --
-- with the single word "unsubscribe" in the body of the message. --
This archive was generated by hypermail 2.0b3 on Wed 30 Dec 1998 - 10:18:44 EST