Boszormenyi Zoltan (zboszor@mol.hu)
Fri, 10 Jul 1998 14:39:11 +0100
Hi all!
My name is Zoltan Boszormenyi and I would like to report an error
in the lp driver. I have a parallel port ZIP drive and sometimes I
can use an other parallel port IDE type disk device, a so called
PHd (Pocket Harddisk) made by KT Technologies. (Grant R. Guenther
was so kind and smart to implement a driver for it. Thanks, again!)
I decided to stress-test the Linux parport scheme a week ago
and tried to use these two devices and printing at the same time.
In every tests I tried all the devices were connected this way:
computer <-> ZIP <-> PHd <-> printer
and were switched on. The printer is an old 9-pin Epson compatible one.
I used 2.1.108 and all the relevant kernel parts were modules:
parport, parport_pc, parport_probe, ppa, paride, ktti, pd
I made the following tests:
Single tests:
- printing
- copying to/from ZIP
- copying to/from PHd
Two-device tests:
- copying to/from ZIP and to/from PHd
- printing and copying to/from ZIP
- printing and copying to/from PHd
Three-device tests:
- printing and copying to/from ZIP and to/from PHd
The single and two-device tests went OK.
I had problems with the three-device tests: in every test the printer
stopped and the printer job was in D wait. (I printed the tiger.ps from
the Ghostscript examples.) The copying carried on and the files were OK
on both the ZIP and the PHd.
Then I changed all this #undefs into #defines in lp.c:
#undef LP_STATS
#undef LP_NEED_CAREFUL
#undef LP_DEBUG
#undef LP_READ_DEBUG
After recompiling lp.c I got the following messages on reboot:
Jul 8 23:20:27 boszi kernel: lp0: using parport0 (polling).
Jul 8 23:20:27 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbfffdb98
Jul 8 23:20:32 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffff214
And these are the messages during printing:
Jul 8 23:23:47 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffffba4
Jul 8 23:23:49 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffff214
Jul 8 23:23:49 boszi kernel: lp0 success after 234 counts.
Jul 8 23:23:49 boszi kernel: lp0 sleeping at 0 characters for 2 jiffies
Jul 8 23:23:49 boszi kernel: lp0 success after 684 counts.
Jul 8 23:23:49 boszi kernel: lp0 success after 904 counts.
***The rows below show a "hiccup" when I started copying to the ZIP
Jul 8 23:23:49 boszi kernel: lp0 sleeping at 0 characters for 2 jiffies
Jul 8 23:24:02 boszi last message repeated 554 times
Jul 8 23:24:03 boszi kernel: lp0 success after 965 counts.
Jul 8 23:24:03 boszi kernel: lp0 success after 968 counts.
***The rows below show another "hiccup" when I started copying to the PHd.
***Now both parallel device were copying.
Jul 8 23:24:03 boszi kernel: lp0 sleeping at 0 characters for 2 jiffies
Jul 8 23:24:34 boszi last message repeated 1032 times
Jul 8 23:24:54 boszi last message repeated 665 times
And the printer stopped at this point. In every five minutes I checked
the logs for half an hour and they did not change.
The lp driver actually locked!!
I tried again with interrupts:
Jul 8 23:59:18 boszi kernel: lp0: using parport0 (interrupt-driven).
Jul 8 23:59:18 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbfffdb98
Jul 8 23:59:24 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffff214
....
Jul 9 00:00:54 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffffba4
Jul 9 00:00:56 boszi kernel: lp0 ioctl, cmd: 0x5401, arg: 0xbffff214
Jul 9 00:00:56 boszi kernel: lp0 success after 86 counts.
Jul 9 00:00:56 boszi kernel: lp0 success after 307 counts.
Jul 9 00:00:56 boszi kernel: lp0 success after 952 counts.
Jul 9 00:01:26 boszi kernel: lp0 success after 959 counts.
***The rows below show the same message when I started copying to the ZIP
***and the PHd.
Jul 9 00:01:29 boszi kernel: lp0 sleeping at 0 characters for 2 jiffies
Jul 9 00:01:40 boszi last message repeated 320 times
And again it stopped, I checked it for more than fifteen minutes and
it did not change.
Somehow the lp driver does not handle the case when it has to wait too much
because other devices access the parallel port.
I saw a huge "do {} while" cycle in the function lp_write_buf() where this
"lp%d sleeping for %d jiffies" message is. In the middle there is an
if-then-else structure:
if (LP_POLLED(minor) ||
lp_table[minor].irq_missed)
{
lp_polling:
#if defined(LP_DEBUG) && defined(LP_STATS)
printk(KERN_DEBUG
"lp%d sleeping at %d characters for %d jiffies\n",
minor, lp->runchars, LP_TIME(minor));
#endif
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + LP_TIME(minor);
lp_schedule (minor);
} else {
cli();
if (LP_PREEMPTED(minor))
{
sti();
goto lp_polling;
}
if (!lp_table[minor].irq_detected)
{
current->timeout = jiffies + LP_TIMEOUT_INTERRUPT;
interruptible_sleep_on(&lp->wait_q);
}
sti();
}
I think there lies the problem. This loop is where it goes into an
infinite loop somehow. I changed the "cli();" to "save_flags(flags); cli();"
and the "sti();" to "restore_flags(flags);" and added an
"unsigned long flags;" at the beginning of the function as I saw
elsewhere in the kernel source but that did not help.
In the lp_schedule() function there is a condition I cannot
see through. I will try an explicit
"lp_parport_release(minor); schedule(); lp_parport_claim(minor);"
instead of "lp_schedule(minor);" and will report if that helps.
Maybe the lp maintainer can suggest some other patches. :)
Sincerely,
Zoltan Boszormenyi
-- 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:17:56 EST