Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!think.com!snorkelwacker.mit.edu!ira.uka.de!smurf!flatlin!tpki!oski!schlut From: schlut@oski.toppoint.de (Olaf Schlueter) Newsgroups: comp.os.minix Subject: Minix ST 1.5 printer driver problems Message-ID: <30@oski.toppoint.de> Date: 16 Apr 91 11:56:52 GMT Lines: 75 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