Re: [PARPORT] ECP read - FIFO/DMA

From: Tim Waugh (twaugh@redhat.com)
Date: Tue Mar 14 2000 - 11:51:28 EST

  • Next message: Tim Waugh: "Re: [PARPORT] Clean IEEE1284 termination"

    On Fri, 10 Mar 2000, Richard Stover wrote:

    > Since I've been working on a device driver to handle a high speed
    > camera that will produce data at very high rates I've been looking at
    > issues like this. If you have a peripheral that does follow the ECP
    > standards you shouldn't have to loose any data. The way to stop data
    > is to negotiate from reverse to forward phase (from input to output).
    > When the host sets nReverseRequest (also called nInit high, the
    > pheripheral must tri-state its data bus. If the peripheral was in the
    > middle of a data transmission it must assume the data byte will be
    > discarded by the host and it stops all furthter transfers. You can
    > then read whatever is left in the fifo. nReverseRequest is bit 2 of
    > the device control register.

    Here's a patch to test out (I can't test it myself). Let me know if it's
    okay. It applies to 2.3.52pre3.

    Tim.
    */

    Index: drivers/parport/parport_pc.c
    ===================================================================
    RCS file: /usr/local/src/cvsroot/linux/drivers/parport/parport_pc.c,v
    retrieving revision 1.40
    diff -d -u -r1.40 parport_pc.c
    --- drivers/parport/parport_pc.c 2000/03/14 13:55:01 1.40
    +++ drivers/parport/parport_pc.c 2000/03/14 16:45:56
    @@ -178,9 +178,6 @@
             int cnfga;
             const struct parport_pc_private *priv = p->physport->private_data;
     
    - /* Prevent further data transfer. */
    - frob_econtrol (p, 0xe0, ECR_TST << 5);
    -
             /* Adjust for the contents of the FIFO. */
             for (residue = priv->fifo_depth; ; residue--) {
                     if (inb (ECONTROL (p)) & 0x2)
    @@ -862,7 +859,8 @@
                                                            length, flags);
     
             /* Switch to reverse mode if necessary. */
    - if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) {
    + if ((port->ieee1284.phase != IEEE1284_PH_REV_IDLE) &&
    + (port->ieee1284.phase != IEEE1284_PH_REV_DATA)) {
                     /* Event 38: Set nAutoFd low */
                     parport_frob_control (port,
                                           PARPORT_CONTROL_AUTOFD,
    @@ -879,7 +877,7 @@
                     parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0);
             }
     
    - /* Set up ECP parallel port mode.*/
    + /* Set up ECP FIFO mode.*/
             parport_pc_data_reverse (port); /* Must be in PS2 mode */
             parport_pc_frob_control (port,
                                      PARPORT_CONTROL_STROBE |
    @@ -951,14 +949,23 @@
                     left--;
             }
     
    + port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
    +
    + /* Go to forward idle mode to shut the peripheral up. */
    + parport_frob_control (port, PARPORT_CONTROL_INIT, 0);
    + parport_wait_peripheral (port,
    + PARPORT_STATUS_PAPEROUT,
    + PARPORT_STATUS_PAPEROUT);
    + port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
    +
             /* Finish up. */
    - if (change_mode (port, ECR_PS2) == -EBUSY) {
    + {
                     int lost = get_fifo_residue (port);
    - printk (KERN_DEBUG "%s: DATA LOSS (%d bytes)!\n", port->name,
    - lost);
    + if (lost)
    + /* Shouldn't happen with compliant peripherals. */
    + printk (KERN_DEBUG "%s: DATA LOSS (%d bytes)!\n",
    + port->name, lost);
             }
    -
    - port->ieee1284.phase = IEEE1284_PH_REV_IDLE;
     
             return length - left;
     }

    -- 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 : Tue Mar 14 2000 - 11:55:04 EST