[PARPORT] [PATCH] to drivers/parport/ieee1284_ops.c to fix timing dependent printer hang

From: Tim Josling (tej@melbpc.org.au)
Date: Thu Mar 20 2003 - 14:32:16 EST

  • Next message: Tim Josling: "[PARPORT] Re: [PATCH] to drivers/parport/ieee1284_ops.c to fix timing dependent hang"

    Hopefully I have at last foudn the right place to post this...

    I have an HP1100 printer and since I upgraded to a faster CPU the
    printer has started hanging. The problem persisteed across 2.0 2.2 and
    2.4 kernel versions. I am running Red Hat Linux 8.0 on a Compaq Armada E500.

    The problem occurs intermittently. The symptom is that the 'buffer
    contains data' light stays on on the printer, but data transfer stops.

    I traced the problem to drivers/parport/ieee1284_ops.c function
    parport_ieee1284_write_compat. The problem occurs when the parallel port
    is not using interrupts. If the printer takes a while to respond the
    routine parport_wait_event gets called, if count == 0. However this
    routine generally waits almost no time, as shown in my traces, if the
    port does not have interrupts enabled. Looking at that code, it seems
    that parport_wait_event is only meant to be called when interrupts are
    available on the port.

    Anyway, if 32 repeats of this occur e.g. for a complex document where
    the printer is slow, 'wait' ends up as a negative number from repeated
    doublings due to the way twos complement arithmetic works in C. In this
    case the routine never returns, or at least waits for a very long time
    i.e. hours. So no more data gets sent to the printer.

    Originally I fixed the problem by adding code to ensure that 'wait'
    never got set to anything above 10 seconds (10 * HZ). However the patch
    I have sent you does something different, it just ensures that
    parport_wait_event never gets called for printer without interrupt. I
    have tested this on documents which reproduce the problem and the hangs
    go away.

    Clearly I am not an expert on the parport code, so my patch may be
    incorrect. I have traces using extra printks I put in the code, showing
    the wait variable being doubled to negative value, available on request.

    Definitely my patch does fix a real problem on my system.

    As far as I can tell from browsing the patches since 2.4.18, there has
    not been any other fix for this problem to date.

    Tim Josling

    --- ChangeLog.original 2003-03-16 09:18:07.000000000 +1100
    +++ ChangeLog 2003-03-16 09:20:35.000000000 +1100
    @@ -1,3 +1,9 @@
    +2003-03-16 Tim Josling <tej@melbpc.org.au>
    + * ieee1284_ops.c (parport_ieee1284_write_compat): Avoid calling
    + parport_wait_event if interrupts are not enabled for device, avoid
    + output hang.
       2002-04-25 Tim Waugh <twaugh@redhat.com>

           * parport_serial.c, parport_pc.c: Move some SIIG cards around.

    --- ieee1284_ops.c.original 2003-03-16 08:27:33.000000000 +1100
    +++ ieee1284_ops.c 2003-03-16 09:17:23.000000000 +1100
    @@ -93,7 +93,7 @@
                                  first time around the loop, don't let go of
                                  the port. This way, we find out if we have
                                  our interrupt handler called. */
    - if (count && no_irq) {
    + if (count || no_irq) {
                       parport_release (dev);
                       __set_current_state (TASK_INTERRUPTIBLE);
                       schedule_timeout (wait);

    -- 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 Mar 20 2003 - 14:51:13 EST