On Mon, 10 Sep 2001 22:37:32 +0100, Philip Blundell <philb@gnu.org> wrote:
>
> >I think at least for now I think I'm just going to turn DMA off. I'm
> >still open to trying other experiments, though, if anybody wants to
> >suggest something.
>
> I guess it would be instructive to know how the corruptions
> correspond to invocations of parport_pc_fifo_write_block_dma. If
> you feel like hacking that function around a bit, how about adding
> a flag that gets set when the "DMA write timed out" condition
> happens; if the flag is set on entry to the function, dump out the
> first few bytes in `buf' to the console and clear the flag again.
>
> I'm slightly suspicious that there might be a hardware flaw in
> either your DMA controller or your parallel port. If you have
> another computer with a different chipset available, it would be
> interesting to know whether you can make the same thing happen.
>
> p.
>
For those of you just joining us, here's a recap:
I've been trying to get ECP mode writes working on my machine running
a 2.4.2 kernel. To do this, parport_pc must be built with
CONFIG_PARPORT_PC_FIFO, some changes must be made to lp.o to tell
parport to use ECP mode, and the irq option for parport_pc must be set
to "auto" in /etc/modules.conf. If the dma option is set to "auto",
DMA will be used for loading up the FIFO; otherwise if the dma option
is set tup "none" PIO will be used for loading the FIFO.
In the course of doing these changes and testing them out, I
discovered problems when the FIFO/DMA combination is used to send data
to a printer in compatibility mode if there is a long pause in the
data stream; i.e. if the transfer to the printer looks like:
swallow lots of bytes
pause 30 seconds or so
swallow lots more bytes
In this case the printer receives garbage data. I spent a of time
trying to pinpoint where the problem was, and could only conclude that
it happened when the code timed out in parport_pc_fifo_write_block_dma().
There didn't seem to be any problem, though, if I set things up to
use PIO instead of DMA, so ultimately I decided to do that.
Since then I've done some further testing and have discovered that, at
least with the hardware I have, there are problems in ECP mode as well
-- except that for ECP mode the problems exist whether I use DMA or
whether I use PIO to send data to the FIFO. The problems appear to be
related to the process used to recover from the timeouts -- putting
the port into test mode and trying to determine how many bytes are
left in the FIFO. I'm beginning to think, in fact, that the hardware
is broken in such a way that whenever the FIFO is used, you'd better
not mess with the port's mode until that byte has been received by
the peripheral.
So here's what I've got:
Mode PIO/DMA status
----- -------- ------
compat. PIO OK
compat. DMA broken after timeout
ECP PIO broken after timeout
ECP DMA broken after timeout
I've got a workaround (listed below) , but I don't really like it,
because the effect is to change parport_pc_fifo_write_block_pio() and
parport_pc_fifo_write_block_dma() from non-blocking to blocking calls.
Suggestions for better solutions would be appreciated. For example,
could/should we add an option for parport_pc to do non-blocking
vs. blocking writes for dealing with such apparently broken hardware?
I see this as analogous to the the DOS mode command for setting
"retries=infinite".
As an aside, I've changed from using a specialized test program in
the printer to using a Postscript program which causes a pause
in the download. See below.
-- Dave Strauss
Changes to parport_pc.c:
===================================================================
RCS file: RCS/parport_pc.c,v
retrieving revision 1.3
diff -up -r1.3 parport_pc.c
--- parport_pc.c 2001/09/13 21:34:52 1.3
+++ parport_pc.c 2001/09/14 21:28:57
@@ -531,7 +531,7 @@ static size_t parport_pc_fifo_write_bloc
if (!time_before (jiffies, expire)) {
/* Timed out. */
printk (KERN_DEBUG "FIFO write timed out\n");
- break;
+ expire = jiffies + port->cad->timeout;
}
ecrval = inb (ECONTROL (port));
if (!(ecrval & (1<<2))) {
@@ -652,7 +652,7 @@ static size_t parport_pc_fifo_write_bloc
if (!time_before (jiffies, expire)) {
/* Timed out. */
printk (KERN_DEBUG "DMA write timed out\n");
- break;
+ expire = jiffies + port->cad->timeout;
}
/* Is serviceIntr set? */
if (!(inb (ECONTROL (port)) & (1<<2))) {
Postscript test file, fill in the blanks:
----------------------- CUT HERE -------------------------
%!PS
1 2 add 3 add 4 add 5 add 6 add 7 add 8 add 9 add 10 add pop
[ repeat for 7000 lines or so ]
(waiting\n) print flush
/start realtime def
{ realtime start sub 40000 gt { exit } if} loop
(continuing\n) print flush
1 2 add 3 add 4 add 5 add 6 add 7 add 8 add 9 add 10 add pop
[ repeat for another 7000 lines or so ]
----------------------- CUT HERE -------------------------
To see problems with the download, you will have to download an error
handler that will print out errors when they happen. Some Postscript
printers have a front panel setting to do this.
-- 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 : Sat Sep 15 2001 - 04:14:50 EDT