Re: [PARPORT] ECP mode transfers in 2.4.x kernels

From: Dave Strauss (dstrauss@mail.wm.sps.mot.com)
Date: Fri Aug 24 2001 - 14:40:33 EDT

  • Next message: Tim Waugh: "Re: [PARPORT] ECP mode transfers in 2.4.x kernels"

    On Thu, 23 Aug 2001 17:07:08 +0100, Tim Waugh <twaugh@redhat.com> wrote:
    >
    > On Thu, Aug 23, 2001 at 12:01:00PM -0400, Dave Strauss wrote:
    >
    > > On Thu, 23 Aug 2001 16:36:49 +0100, Tim Waugh <twaugh@redhat.com> wrote:
    > > >
    > > > On Thu, Aug 23, 2001 at 11:31:50AM -0400, Dave Strauss wrote:
    > > > =20
    > > > > if (check_release_me_flag()) {
    > > > =20
    > > > You can clear it here, since you are already going to release the
    > > > port. Otherwise:
    > > > =20
    > > > > parport_release();
    > > > ... it could get set here...
    > > > > lock_access();
    > > > > clear_release_me_flag();
    > > > ... and never noticed.
    > > > > unlock_access();
    > > > > clear_ownership_flag();
    > > > > }
    > > > > }
    > > > =20
    > > > Tim.
    > > > */
    > > > =20
    > > Not necessarily. I probably don't care if it gets set after I
    > > check for it, because I will sooner or later come back into an
    > > entrypoint and check for it again.=20
    >
    > No, but you do care if it gets set after you check it but before you
    > set it, which is why you want to do both at the set time.
    >
    > > I'm assuming that "lock_access()" exists and that it holds off
    > > the preempt function from getting at the "release_me" flag until
    > > "unlock_access()" is called. What would these functions consist
    > > of?
    >
    > Just use test_and_set_bit.
    >
    > Tim.
    > */
    >

    OK. This works.

    Here's what I'm doing now:

    static int lp_preempt(void *handle)
    {
        struct lp_struct *this_lp = (struct lp_struct *)handle;
        set_bit(LP_PREEMPT_REQUEST, &this_lp->preempt_bits);
        return (1);
    }

    ...

    entrypoint()
    {
        parport_claim_or_block ();

        do_stuff();

        if (test_and_clear_bit(LP_PREEMPT_REQUEST, &preempt_bits)) {
            printk(KERN_INFO "lp%d releasing parport\n", minor);
            parport_negotiate (lp_table[minor].dev->port,
                                       IEEE1284_MODE_COMPAT);
            parport_release (lp_table[minor].dev);
        }

    }

    where LP_PREEMPT_REQUEST is 1 and "preempt_bits"
    is an unsigned long in struct lp_struct.

    I've only implemented this for the lp_read() entrypoint so far.

    Note the following:

       (1) I claim the parport driver every time I enter the entrypoint.
            I only release it if the "preempt" function was called.

       (2) I'm relying on the lp_release() call to release the parport
            driver for the final time.

       (3) I'm calling parport_claim_or_block every time entrypoint()
            gets called and relying on the parport driver to notice
            if/when I already own it.

    Are (2) and (3) safe things to do? Also, doing (3) causes the dmesg
    buffer to fill up with "parport0: lp already owner" messages from
    parport/share.c. Can we zap this message? Or should I burden lp.c
    with another flag so that it knows when it already owns parport?

    -- Dave Strauss

    -- 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 : Fri Aug 24 2001 - 15:49:27 EDT