[comp.os.minix] Minix ST 1.5 printer driver problems

schlut@oski.toppoint.de (Olaf Schlueter) (04/16/91)

When I wrote a HP Deskjet + printer driver for mroff on Minix ST 1.5, I
got problems with the kernel printer driver. It looked like on the way from
the mroff driver to the printer somewhere bytes had been added or removed
so I got nasty bit shifts and misinterpreted graphics data on the
page occasionally. What had been most weird, it was only partially
reproducable, i.e. I could count on getting at least two destroyed lines
on the page, but could not predict where it would happen, even with
essantially the same output. The problem is definitely in the kernel:
I redirected the output of the printer driver into a file and sended
this file to the printer several times with the cat command. With
the original kernel printer driver (as distributed by PH) things
got even worse then (i. e. more bad lines).

Every once and again during the output the kernel reported "printer still
busy". To cite Mr. Spock "That's fascinating", since the place where this
message is produced, is entered on response to a printer not busy interrupt.

Looking at stprint.c, I found two places where I am in doubt whether the
code is correct. The first is the actual output of one character via the
sound chip: the manual of my printer states, that the strobe should
change state for at least 1 microsec. Currently with an 8 MHz CPU,
this condition is satisfied, but I decided to keep the strobe low
until the busy line changes state (kind of acknowledge by the printer).

Just a layer above in piaint() I guess a race condition: there is
a sequence of code looking like:

  while(left > 0) { outchar(*addr++); left--; ... }

outchar is the routine mentioned above which sends a byte to the printer.
left is a counter initialized on every user write request and counts
the remaining bytes to copy to the printer.

I think the race condition appears, if the printer handles the byte
send by outchar so fast (the hp deskjet has a 16K buffer), that the
printer not busy interrupt occurs just after returning from outchar.
Then piaint is reentered before left is decremented. If left had been
1 before sending the byte in *addr, it should now be 0 but isn't
(decrement is pending) so an additional excess byte is send to the printer.
The chance that this will happen is increased by the fact the
the printer not busy interrupt has the lowest priority of all MFP
interrupts, e.g. the chance that piaint itself is interrupted by
anything else is high, giving the printer additional time to handle
the byte.

I decided to enclose the sequence by a lock/restore pair. This indeed
improved the behaviour of the printer driver. If I used the cat
command to send the mroff printer driver output to the printer everything
worked ok then. A still unsolved riddle is if I send the output of
the printer driver directly to the printer the trouble starts again ?!
So (the printer driver is hpd150)

  hpd150 <body.out | cat >/dev/lp

works fine now, but

  hpd150 <body.out >/dev/lp

or (that's maybe important)

  hpd150 <body.out | cat -u >/dev/lp

doesn't. 

The misbehaviour of the kernel had been discoverd in the original kernel (PL 0),
since PL 1 and PL 2 did not change stprint.c (besides ansification) it should
be still there.

Any comments ?

Regards,

-- 
Olaf Schlueter, Sandkuhle 4-6, 2300 Kiel 1, Germany, Toppoint Mailbox e.V.
schlut@oski.toppoint.de, olaf@tpki.toppoint.de, (..!unido!tpki!olaf)

joerg@mwtech.UUCP (Joerg Werner) (04/22/91)

In article <30@oski.toppoint.de> schlut@oski.toppoint.de (Olaf Schlueter) writes:

>When I wrote a HP Deskjet + printer driver for mroff on Minix ST 1.5, I
>got problems with the kernel printer driver. It looked like on the way from
>the mroff driver to the printer somewhere bytes had been added or removed
>so I got nasty bit shifts and misinterpreted graphics data on the
>page occasionally. What had been most weird, it was only partially
>reproducable, i.e. I could count on getting at least two destroyed lines
>on the page, but could not predict where it would happen, even with
>essantially the same output. The problem is definitely in the kernel:

I've had the same problem with NEC P6+!

>Every once and again during the output the kernel reported "printer still
>busy". To cite Mr. Spock "That's fascinating", since the place where this
>message is produced, is entered on response to a printer not busy interrupt.

Delete the print statement :-)

>Just a layer above in piaint() I guess a race condition: there is
>a sequence of code looking like:
>
>  while(left > 0) { outchar(*addr++); left--; ... }
>

Yes, there is a race condition. But the solution is very simple.
The Problem is, that piaint() is reentered before left is decremented.
My solution (since MINIX ST 1.1) is:

  while(left > 0) { left--; outchar(*addr++); ... }

Decrement left _before_ outchar() is called!

Ciao Joerg
-- 
Joerg Werner, email: joerg@mwtech.UUCP, voice: 49-(0)6151-37 33 66

meulenbr@cst.prl.philips.nl (Frans Meulenbroeks) (04/22/91)

I've seen reports about bad printer problems before. 
Since I don't have a parallel printer, I cannot test these.
However someone reported that this is due to the fact that the
winchester task uses op to much stack.
Try to change the definition of WINCH_STACK to
#define WINCH_STACK     (3*SMALL_STACK/2)

Please let me know if that helps.

--
Frans Meulenbroeks        (meulenbr@prl.philips.nl)
	Centre for Software Technology

Christoph van Wuellen <HBO043%DJUKFA11.BITNET@cunyvm.cuny.edu> (04/22/91)

When processing graphics data, there might be a problem if
carriage return characters are inserted after 'newline' characters
which actually are only some graphics data.

C.v.W.

ralf@ptavv.ka.sub.org (Ralf Wenk) (04/24/91)

In article <meulenbr.672319161@cstw168>
meulenbr@cst.prl.philips.nl (Frans Meulenbroeks) writes:
> I've seen reports about bad printer problems before. 
> Since I don't have a parallel printer, I cannot test these.
> However someone reported that this is due to the fact that the
> winchester task uses op to much stack.
> Try to change the definition of WINCH_STACK to
> #define WINCH_STACK     (3*SMALL_STACK/2)
> 
> Please let me know if that helps.

If the winchester task uses up to much stack the system will crash
immediately when trying to print anything. But this bug was introduced
with patch 2 and fixed with patch 3.

I saw the problem mentioned in the original artikle too. I got a lot
of garbage and "printer still busy" messages when trying to print
graphic data on a 24 needle printer. After changing back to my old
9 needle printer I did not got any still-busy message and less often
the data was corrupted. When bypassing the printer driver and using
cat data >/dev/lp instead I got no data error any more. I can not
explain it, but it seems to have nothing to do with the stack of the
winchester task.

-- 
-- 
Ralf Wenk -- ralf@ptavv.ka.sub.org

schlut@oski.toppoint.de (Olaf Schlueter) (04/25/91)

meulenbr@cst.prl.philips.nl (Frans Meulenbroeks) writes:

>I've seen reports about bad printer problems before. 
>Since I don't have a parallel printer, I cannot test these.
>However someone reported that this is due to the fact that the
>winchester task uses op to much stack.
>Try to change the definition of WINCH_STACK to
>#define WINCH_STACK     (3*SMALL_STACK/2)

The winchester task indeed uses too much stack, that's true. It does
so since patch 1 to Minix 1.5 ST, when the winchester task learned
about extended partition schemes. During the initialization of
the winchester task, at least one, if a XGM partition is encountered,
two struct's with size 512 Bytes and auto storage class are used,
causing the winchester task to creep into the bottom of the 
printer's task stack. You won't notice it, until you try to print
something to /dev/lp. Since I got patch #1 out of the dump of old
minix articles, I thought that this had been reported earlier, but
obviously it wasn't. So if anyone has problems using his line printer
connected to the parallel port after applying patch #1 (which did
not touch stprint.c), have a look at st_wini.c, there are two
big struct's hi or so. Change their storage class to static.
(or increase the stacksize like frans suggests, that should work
either). On my system, the task stack overflow caused the system
to crash with a kernel trap panic.

But this is not the solution to my reported printer problem. 

-- 
-- 
Olaf Schlueter, Sandkuhle 4-6, 2300 Kiel 1, Germany, Toppoint Mailbox e.V.
schlut@oski.toppoint.de, olaf@tpki.toppoint.de, ...!unido!tpki!olaf

schlut@oski.toppoint.de (Olaf Schlueter) (04/25/91)

HBO043%DJUKFA11.BITNET@cunyvm.cuny.edu (Christoph van Wuellen) writes:

>When processing graphics data, there might be a problem if
>carriage return characters are inserted after 'newline' characters
>which actually are only some graphics data.

stprint.c does not append or delete any characters to the printer
output. at least I did not found anything like that in the code
and it is stated somewhere in the manual that output to /dev/lp
is not processed in any way. Indeed I have to use lpr for text
output since my printer needs CR-LF's for text, not just LF's.

lpr does process printer output, but I do not use lpr to output
the graphics data generated by the mroff printer driver.

-- 
-- 
Olaf Schlueter, Sandkuhle 4-6, 2300 Kiel 1, Germany, Toppoint Mailbox e.V.
schlut@oski.toppoint.de, olaf@tpki.toppoint.de, ...!unido!tpki!olaf