On Wed, 15 Aug 2001 22:59:37 +0100, Philip Blundell <philb@gnu.org> wrote:
>
>
> >What do I have to do to get a Linux box to do ECP mode transfers?
>
> I had a play with this a few months ago with inconclusive results. I think
> this was the patch, if you want to try it. It would certainly be interesting
> to hear what happens for you.
>
> p.
>
> [ ... ]
>
Philip,
Thanks for the patch!
So I guess it wasn't such a stupid question after all. Also I guess
there's no easy answer (at least for the unsophisticated user).
Regarding the patch, I've applied it and there is good news and bad
news. The good news is that data transfers do indeed happen in ECP
mode now. The bad news is that are a few problems. I've addressed at
least one of them but there are still others -- see my patch (which
includes yours) below (sorry but I don't know the version number of
the file I started with, and I don't have CVS access from where I'm
sitting now).
First problem: once the port is in ECP mode, any call to
lp_wait_ready() will fail because the call to lp_check_status() will
be wrong because the status lines mean different things in ECP mode.
I've gotten around it by getting out of lp_wait_ready() immediately
if the device is not in compatibility mode, but I'm not convinced this
is the correct thing to do. Perhaps lp_check_status() should be
changed instead.
Second problem: the original patch leaves the parallel port in ECP
mode permanently. My experience with working on printers of various
sorts is that this is in general a Bad Thing; the 1284 protocol is
easily broken if either side gets out of sync with the other, and the
longer the port is left in ECP mode the easier it is for this to
happen. Also, if other drivers want to use the port in other modes
(or in other ways) this could cause problems. I've gotten around this
in the patch below by always reverting to compatibility mode when the
write is completed, but again I'm not sure this is the correct thing.
Ideally we would like to leave the port in ECP mode if more data is
going to be sent, but of course we can't tell from the lp driver if
this is going to happen. Also there's the issue of error recovery.
One possibility I'm thinking of trying would be to force the port to
compatibility mode at the beginning, then into ECP mode (if the port
can handle it), then back to compatibility mode when the write is
completed; this doesn't address the meta-data issue but that probably
can't be helped.
Third problem: the data transfer rate is still very slow. I'm
expecting upwards or 400 Kbytes/sec but and getting only about 50
Kbytes/sec. I'm not why this is so.
Fourth problem: I'm getting garbage in the data stream. At this point
I haven't been able to characterize it very well beyong the fact that
the data reaching the printer is incorrect. I'm not sure if I'm
getting extra characters, dropped characters, garbled characters, or
all three.
-- Dave Strauss
===================================================================
diff -u -p lp.c.orig lp.c.new
--- lp.c.orig Thu Aug 16 12:06:15 2001
+++ lp.c.new Thu Aug 16 12:01:29 2001
@@ -224,7 +224,15 @@ static int lp_check_status(int minor)
static int lp_wait_ready(int minor)
{
+
+
int error = 0;
+
+ /* If we're not in compatibility mode, we're ready now! */
+ if (lp_table[minor].mode != IEEE1284_MODE_COMPAT) {
+ return (0);
+ }
+
do {
error = lp_check_status (minor);
if (error && (LP_F(minor) & LP_ABORT))
@@ -246,6 +254,7 @@ static ssize_t lp_write(struct file * fi
ssize_t retv = 0;
ssize_t written;
size_t copy_size = count;
+ int ret;
#ifdef LP_STATS
if (jiffies-lp_table[minor].lastcall > LP_TIME(minor))
@@ -269,7 +278,11 @@ static ssize_t lp_write(struct file * fi
parport_claim_or_block (lp_table[minor].dev);
/* Go to compatibility mode. */
- parport_negotiate (port, IEEE1284_MODE_COMPAT);
+ if ((ret = parport_negotiate (port, lp_table[minor].mode)) != 0) {
+ printk(KERN_DEBUG "lp%d: selecting compatibility mode (%d).\n",
+ minor, ret);
+ lp_table[minor].mode = IEEE1284_MODE_COMPAT;
+ }
parport_set_timeout (lp_table[minor].dev,
lp_table[minor].timeout);
@@ -319,6 +332,9 @@ static ssize_t lp_write(struct file * fi
}
} while (count > 0);
+ /* Always return to compatibility mode when we're done. */
+ parport_negotiate (port, IEEE1284_MODE_COMPAT);
+
parport_release (lp_table[minor].dev);
up (&lp_table[minor].port_mutex);
@@ -662,6 +678,12 @@ static int lp_register(int nr, struct pa
if (lp_table[nr].dev == NULL)
return 1;
lp_table[nr].flags |= LP_EXIST;
+
+ if (port->probe_info[0].class != PARPORT_CLASS_LEGACY
+ && (port->modes & PARPORT_MODE_ECP))
+ lp_table[nr].mode = IEEE1284_MODE_ECP;
+ else
+ lp_table[nr].mode = IEEE1284_MODE_COMPAT;
if (reset)
lp_reset(nr);
-- 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 2b29 : Thu Aug 16 2001 - 12:56:51 EDT