Re: [PARPORT] ppdev hangs on read

From: stef (svoltz@wanadoo.fr)
Date: Mon Oct 28 2002 - 03:05:25 EST

  • Next message: int01h: "[PARPORT] Reading the state of the input in pareller port programing."

    On Thu, Oct 24, 2002 at 10:12:48AM +0100, Tim Waugh wrote:
    > On Thu, Oct 24, 2002 at 07:45:16AM +0200, stef wrote:
    >
    > > Here's the log with DEBUG defined in parport modules:
    >
    > I think you'll need to add more printks than just what you get with
    > DEBUG. We want to know, for both O_NONBLOCK and !O_NONBLOCK, what is
    > going on in the ppdev loop and what is going on in the parport_pc read
    > call.
    >
    > Tim.
    > */

            After putting some debug messages, I get:
            Oct 28 08:44:51 xxxx kernel: parport_pc_epp_read_data(1) called
            Oct 28 08:44:51 xxxx kernel: parport_pc_epp_read_data timeout
            Oct 28 08:44:51 xxxx kernel: parport_pc_epp_read_data return 0 bytes
            Oct 28 08:44:51 xxxx kernel: ppdev: pp_read (fct=2) data got 0 bytes

            Here are the code fragments:

            ppdev.c:

            while (bytes_read == 0) {
                    ssize_t need = min_t(unsigned long, count, PP_BUFFER_SIZE);

                    if (mode == IEEE1284_MODE_EPP) {
                            /* various specials for EPP mode */
                            int flags = 0;
                            size_t (*fn)(struct parport *, void *, size_t, int);

                            if (pp->flags & PP_W91284PIC) {
                                    flags |= PARPORT_W91284PIC;
                            }
                            if (pp->flags & PP_FASTREAD) {
                                    flags |= PARPORT_EPP_FAST;
                            }
                            if (pport->ieee1284.mode & IEEE1284_ADDR) {
                                    fct=1;
                                    fn = pport->ops->epp_read_addr;
                            } else {
                                    fct=2;
                                    fn = pport->ops->epp_read_data;
                            }
                            bytes_read = (*fn)(pport, kbuffer, need, flags);
                    } else {
                            fct=3;
                            bytes_read = parport_read (pport, kbuffer, need);
                    }

                    if (bytes_read != 0)
                            break;

                    if (file->f_flags & O_NONBLOCK) {
                            bytes_read = -EAGAIN;
                            break;
                    }

                    if (signal_pending (current)) {
                            bytes_read = -ERESTARTSYS;
                            break;
                    }

                    if (current->need_resched)
                            schedule ();
                    if(bytes_read == 0) {
                            if (pport->ieee1284.mode & IEEE1284_ADDR) {
                                    printk (KERN_DEBUG CHRDEV ": pp_read (fct=%d) addr got 0 bytes\n",fct);
                            } else {
                                    printk (KERN_DEBUG CHRDEV ": pp_read (fct=%d) data got 0 bytes\n",fct);
                            }
                    }
            }

            then parport_pc.c:

            
    #ifdef CONFIG_PARPORT_1284
    static size_t parport_pc_epp_read_data (struct parport *port, void *buf,
                                            size_t length, int flags)
    {
            size_t got = 0;
            printk (KERN_DEBUG "parport_pc_epp_read_data(%d) called\n",length);

            if (flags & PARPORT_W91284PIC) {
                    unsigned char status;
                    size_t left = length;

                    /* use knowledge about data lines..:
                     * nFault is 0 if there is at least 1 byte in the Warp's FIFO
                     * pError is 1 if there are 16 bytes in the Warp's FIFO
                     */
                    status = inb (STATUS (port));

                    while (!(status & 0x08) && (got < length)) {
                            if ((left >= 16) && (status & 0x20) && !(status & 0x08)) {
                                    /* can grab 16 bytes from warp fifo */
                                    if (!((long)buf & 0x03)) {
                                            insl (EPPDATA (port), buf, 4);
                                    } else {
                                            insb (EPPDATA (port), buf, 16);
                                    }
                                    buf += 16;
                                    got += 16;
                                    left -= 16;
                            } else {
                                    /* grab single byte from the warp fifo */
                                    *((char *)buf)++ = inb (EPPDATA (port));
                                    got++;
                                    left--;
                            }
                            status = inb (STATUS (port));
                            if (status & 0x01) {
                                    /* EPP timeout should never occur... */
                                    printk (KERN_DEBUG "%s: EPP timeout occured while talking to "
                                            "w91284pic (should not have done)\n", port->name);
                                    clear_epp_timeout (port);
                            }
                    }
                    printk (KERN_DEBUG "parport_pc_epp_read_data return %d bytes\n",got);
                    return got;
            }
            if ((flags & PARPORT_EPP_FAST) && (length > 1)) {
                    if (!(((long)buf | length) & 0x03)) {
                            insl (EPPDATA (port), buf, (length >> 2));
                    } else {
                            insb (EPPDATA (port), buf, length);
                    }
                    if (inb (STATUS (port)) & 0x01) {
                            clear_epp_timeout (port);
                            return -EIO;
                    }
                    printk (KERN_DEBUG "parport_pc_epp_read_data return %d bytes\n",length);
                    return length;
            }
            for (; got < length; got++) {
                    *((char*)buf)++ = inb (EPPDATA(port));
                    if (inb (STATUS (port)) & 0x01) {
                            /* EPP timeout */
                            clear_epp_timeout (port);
                            printk (KERN_DEBUG "parport_pc_epp_read_data timeout\n");
                            break;
                    }
            }
            printk (KERN_DEBUG "parport_pc_epp_read_data return %d bytes\n",got);
            return got;
    }

    Regards,
            Stef

    -- 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 : Mon Oct 28 2002 - 02:12:40 EST