Re: [PARPORT] parallel port programming

From: Tim Waugh (twaugh@redhat.com)
Date: Tue Apr 04 2000 - 14:36:13 EDT

  • Next message: Tim Waugh: "Re: [PARPORT] Parallel port user-space driver and interrupts"

    I'm going to assume that you are using 2.3.x, since you're talking about
    parport_register_driver.

    In that case, please take a look at Documentation/DocBook in the current
    tree (2.3.99-pre4-3). There is a DocBook guide to the Linux parallel port
    API.

    I'll make the formatted HTML available on my web page when I get time.

    Also, I'm hoping to get some of it auto-generated from the source files.
    See the attached patch, which is some of my pending stuff for Linus.

    Tim.
    */

    Index: linux/drivers/parport/daisy.c
    diff -u linux/drivers/parport/daisy.c:1.1.1.3 linux/drivers/parport/daisy.c:1.4
    --- linux/drivers/parport/daisy.c:1.1.1.3 Wed Mar 1 09:36:13 2000
    +++ linux/drivers/parport/daisy.c Tue Apr 4 14:43:15 2000
    @@ -174,7 +174,26 @@
             return;
     }
     
    -/* Find a device by canonical device number. */
    +/**
    + * parport_open - find a device by canonical device number
    + * @devnum: canonical device number
    + * @name: name to associate with the device
    + * @pf: preemption callback
    + * @kf: kick callback
    + * @irqf: interrupt handler
    + * @flags: registration flags
    + * @handle: driver data
    + *
    + * This function is similar to parport_register_device(), except
    + * that it locates a device by its number rather than by the port
    + * it is attached to. See parport_find_device() and
    + * parport_find_class().
    + *
    + * All parameters except for @devnum are the same as for
    + * parport_register_device(). The return value is the same as
    + * for parport_register_device().
    + **/
    +
     struct pardevice *parport_open (int devnum, const char *name,
                                     int (*pf) (void *), void (*kf) (void *),
                                     void (*irqf) (int, void *, struct pt_regs *),
    @@ -218,14 +237,33 @@
     
             return dev;
     }
    +
    +/**
    + * parport_close - close a device opened with parport_open()
    + * @dev: device to close
    + *
    + * This is to parport_open() as parport_unregister_device() is to
    + * parport_register_device().
    + **/
     
    -/* The converse of parport_open. */
     void parport_close (struct pardevice *dev)
     {
             parport_unregister_device (dev);
     }
     
    -/* Convert device coordinates into a canonical device number. */
    +/**
    + * parport_device_num - convert device coordinates into a
    + * canonical device number
    + * @parport: parallel port number
    + * @mux: multiplexor port number (-1 for no multiplexor)
    + * @daisy: daisy chain address (-1 for no daisy chain address)
    + *
    + * This tries to locate a device on the given parallel port,
    + * multiplexor port and daisy chain address, and returns its
    + * device number or -NXIO if no device with those coordinates
    + * exists.
    + **/
    +
     int parport_device_num (int parport, int mux, int daisy)
     {
             struct daisydev *dev = topology;
    @@ -239,8 +277,33 @@
     
             return dev->devnum;
     }
    +
    +/**
    + * parport_device_coords - convert a canonical device number into
    + * device coordinates
    + * @devnum: device number
    + * @parport: pointer to storage for parallel port number
    + * @mux: pointer to storage for multiplexor port number
    + * @daisy: pointer to storage for daisy chain address
    + *
    + * This function converts a device number into its coordinates in
    + * terms of which parallel port in the system it is attached to,
    + * which multiplexor port it is attached to if there is a
    + * multiplexor on that port, and which daisy chain address it has
    + * if it is in a daisy chain.
    + *
    + * The caller must allocate storage for @parport, @mux, and
    + * @daisy.
    + *
    + * If there is no device with the specified device number, -ENXIO
    + * is returned. Otherwise, the values pointed to by @parport,
    + * @mux, and @daisy are set to the coordinates of the device,
    + * with -1 for coordinates with no value.
    + *
    + * This function is not actually very useful, but this interface
    + * was suggested by IEEE 1284.3.
    + **/
     
    -/* Convert a canonical device number into device coordinates. */
     int parport_device_coords (int devnum, int *parport, int *mux, int *daisy)
     {
             struct daisydev *dev = topology;
    @@ -437,6 +500,28 @@
     /* Find a device with a particular manufacturer and model string,
        starting from a given device number. Like the PCI equivalent,
        'from' itself is skipped. */
    +
    +/**
    + * parport_find_device - find a device with a specified
    + * manufacturer and model string
    + * @mfg: required manufacturer string
    + * @mdl: required model string
    + * @from: previous device number found in search, or %NULL for
    + * new search
    + *
    + * This walks through the list of parallel port devices looking
    + * for a device whose 'MFG' string matches @mfg and whose 'MDL'
    + * string matches @mdl in their IEEE 1284 Device ID.
    + *
    + * When a device is found matching those requirements, its device
    + * number is returned; if there is no matching device, a negative
    + * value is returned.
    + *
    + * A new search it initiated by passing %NULL as the @from
    + * argument. If @from is not %NULL, the search continues from
    + * that device.
    + **/
    +
     int parport_find_device (const char *mfg, const char *mdl, int from)
     {
             struct daisydev *d = topology; /* sorted by devnum */
    @@ -462,8 +547,25 @@
             return -1;
     }
     
    -/* Find a device in a particular class. Like the PCI equivalent,
    - 'from' itself is skipped. */
    +/**
    + * parport_find_class - find a device in a specified class
    + * @cls: required class
    + * @from: previous device number found in search, or %NULL for
    + * new search
    + *
    + * This walks through the list of parallel port devices looking
    + * for a device whose 'CLS' string matches @cls in their IEEE
    + * 1284 Device ID.
    + *
    + * When a device is found matching those requirements, its device
    + * number is returned; if there is no matching device, a negative
    + * value is returned.
    + *
    + * A new search it initiated by passing %NULL as the @from
    + * argument. If @from is not %NULL, the search continues from
    + * that device.
    + **/
    +
     int parport_find_class (parport_device_class cls, int from)
     {
             struct daisydev *d = topology; /* sorted by devnum */
    Index: linux/drivers/parport/ieee1284.c
    diff -u linux/drivers/parport/ieee1284.c:1.1.1.6 linux/drivers/parport/ieee1284.c:1.9
    --- linux/drivers/parport/ieee1284.c:1.1.1.6 Wed Mar 1 09:36:13 2000
    +++ linux/drivers/parport/ieee1284.c Tue Apr 4 14:05:42 2000
    @@ -42,11 +42,22 @@
             parport_ieee1284_wakeup (port_from_cookie[cookie % PARPORT_MAX]);
     }
     
    -/* Wait for a parport_ieee1284_wakeup.
    - * 0: success
    - * <0: error (exit as soon as possible)
    - * >0: timed out
    +/**
    + * parport_wait_event - wait for an event on a parallel port
    + * @port: port to wait on
    + * @timeout: time to wait (in jiffies)
    + *
    + * This function waits for up to @timeout jiffies for an
    + * interrupt to occur on a parallel port. If the port timeout is
    + * set to zero, it returns immediately.
    + *
    + * If an interrupt occurs before the timeout period elapses, this
    + * function returns one immediately. If it times out, it returns
    + * a value greater than zero. An error code less than zero
    + * indicates an error (most likely a pending signal), and the
    + * calling code should finish what it's doing as soon as it can.
      */
    +
     int parport_wait_event (struct parport *port, signed long timeout)
     {
             int ret;
    @@ -72,13 +83,29 @@
             return ret;
     }
     
    -/* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to
    - * 25 for this. After this time we can create a timeout because the
    - * peripheral doesn't conform to IEEE1284. We want to save CPU time: we are
    - * waiting a maximum time of 500 us busy (this is for speed). If there is
    - * not the right answer in this time, we call schedule and other processes
    - * are able to eat the time up to 40ms.
    - */
    +/**
    + * parport_poll_peripheral - poll status lines
    + * @port: port to watch
    + * @mask: status lines to watch
    + * @result: desired values of chosen status lines
    + * @usec: timeout
    + *
    + * This function busy-waits until the masked status lines have
    + * the desired values, or until the timeout period elapses. The
    + * @mask and @result parameters are bitmasks, with the bits
    + * defined by the constants in parport.h: %PARPORT_STATUS_BUSY,
    + * and so on.
    + *
    + * This function does not call schedule(); instead it busy-waits
    + * using udelay(). It currently has a resolution of 5usec.
    + *
    + * If the status lines take on the desired values before the
    + * timeout period elapses, parport_poll_peripheral() returns zero
    + * immediately. A zero return value greater than zero indicates
    + * a timeout. An error code (less than zero) indicates an error,
    + * most likely a signal that arrived, and the caller should
    + * finish what it is doing as soon as possible.
    +*/
     
     int parport_poll_peripheral(struct parport *port,
                                 unsigned char mask,
    @@ -102,6 +129,31 @@
             return 1;
     }
     
    +/**
    + * parport_wait_peripheral - wait for status lines to change in 35ms
    + * @port: port to watch
    + * @mask: status lines to watch
    + * @result: desired values of chosen status lines
    + *
    + * This function waits until the masked status lines have the
    + * desired values, or until 35ms have elapsed (see IEEE 1284-1994
    + * page 24 to 25 for why this value in particular is hardcoded).
    + * The @mask and @result parameters are bitmasks, with the bits
    + * defined by the constants in parport.h: %PARPORT_STATUS_BUSY,
    + * and so on.
    + *
    + * The port is polled quickly to start off with, in anticipation
    + * of a fast response from the peripheral. This fast polling
    + * time is configurable (using /proc), and defaults to 500usec.
    + * If the timeout for this port (see parport_set_timeout()) is
    + * zero, the fast polling time is 35ms, and this function does
    + * not call schedule().
    + *
    + * If the timeout for this port is non-zero, after the fast
    + * polling fails it uses parport_wait_event() to wait for up to
    + * 10ms, waking up if an interrupt occurs.
    + */
    +
     int parport_wait_peripheral(struct parport *port,
                                 unsigned char mask,
                                 unsigned char result)
    @@ -255,12 +307,21 @@
     }
     #endif /* IEEE1284 support */
     
    -/* Negotiate an IEEE 1284 mode.
    - * return values are:
    - * 0 - handshake OK; IEEE1284 peripheral and mode available
    - * -1 - handshake failed; peripheral is not compliant (or none present)
    - * 1 - handshake OK; IEEE1284 peripheral present but mode not available
    +/**
    + * parport_negotiate - negotiate an IEEE 1284 mode
    + * @port: port to use
    + * @mode: mode to negotiate to
    + *
    + * Use this to negotiate to a particular IEEE 1284 transfer mode.
    + * The @mode parameter should be one of the constants in
    + * parport.h starting %IEEE1284_MODE_xxx.
    + *
    + * The return value is 0 if the peripheral has accepted the
    + * negotiation to the mode specified, -1 if the peripheral is not
    + * IEEE 1284 compliant (or not present), or 1 if the peripheral
    + * has rejected the negotiation.
      */
    +
     int parport_negotiate (struct parport *port, int mode)
     {
     #ifndef CONFIG_PARPORT_1284
    @@ -512,8 +573,25 @@
             }
     #endif /* IEEE1284 support */
     }
    +
    +/**
    + * parport_write - write a block of data to a parallel port
    + * @port: port to write to
    + * @buffer: data buffer (in kernel space)
    + * @len: number of bytes of data to transfer
    + *
    + * This will write up to @len bytes of @buffer to the port
    + * specified, using the IEEE 1284 transfer mode most recently
    + * negotiated to (using parport_negotiate()), as long as that
    + * mode supports forward transfers (host to peripheral).
    + *
    + * It is the caller's responsibility to ensure that the first
    + * @len bytes of @buffer are valid.
    + *
    + * This function returns the number of bytes transferred (if zero
    + * or positive), or else an error code.
    + */
     
    -/* Write a block of data. */
     ssize_t parport_write (struct parport *port, const void *buffer, size_t len)
     {
     #ifndef CONFIG_PARPORT_1284
    @@ -577,8 +655,25 @@
             return retval;
     #endif /* IEEE1284 support */
     }
    +
    +/**
    + * parport_read - read a block of data from a parallel port
    + * @port: port to read from
    + * @buffer: data buffer (in kernel space)
    + * @len: number of bytes of data to transfer
    + *
    + * This will read up to @len bytes of @buffer to the port
    + * specified, using the IEEE 1284 transfer mode most recently
    + * negotiated to (using parport_negotiate()), as long as that
    + * mode supports reverse transfers (peripheral to host).
    + *
    + * It is the caller's responsibility to ensure that the first
    + * @len bytes of @buffer are available to write to.
    + *
    + * This function returns the number of bytes transferred (if zero
    + * or positive), or else an error code.
    + */
     
    -/* Read a block of data. */
     ssize_t parport_read (struct parport *port, void *buffer, size_t len)
     {
     #ifndef CONFIG_PARPORT_1284
    @@ -636,8 +731,24 @@
             return (*fn) (port, buffer, len, 0);
     #endif /* IEEE1284 support */
     }
    +
    +/**
    + * parport_set_timeout - set the inactivity timeout for a device
    + * on a port
    + * @dev: device on a port
    + * @inactivity: inactivity timeout (in jiffies)
    + *
    + * This sets the inactivity timeout for a particular device on a
    + * port. This affects functions like parport_wait_peripheral().
    + * The special value 0 means not to call schedule() while dealing
    + * with this device.
    + *
    + * The return value is the previous inactivity timeout.
    + *
    + * Any callers of parport_wait_event() for this device are woken
    + * up.
    + */
     
    -/* Set the amount of time we wait while nothing's happening. */
     long parport_set_timeout (struct pardevice *dev, long inactivity)
     {
             long int old = dev->timeout;
    Index: linux/drivers/parport/parport_pc.c
    diff -u linux/drivers/parport/parport_pc.c:1.1.1.28 linux/drivers/parport/parport_pc.c:1.49
    --- linux/drivers/parport/parport_pc.c:1.1.1.28 Wed Mar 29 09:55:40 2000
    +++ linux/drivers/parport/parport_pc.c Wed Mar 29 12:23:57 2000
    @@ -2254,6 +2254,7 @@
             boca_ioppar,
             plx_9050,
             afavlab_tk9902,
    + timedia_1889,
     };
     
     
    @@ -2291,6 +2292,7 @@
             /* boca_ioppar */ { 1, { { 0, -1 }, } },
             /* plx_9050 */ { 2, { { 4, -1 }, { 5, -1 }, } },
             /* afavlab_tk9902 */ { 1, { { 0, 1 }, } },
    + /* timedia_1889 */ { 1, { { 2, -1 }, } },
     };
     
     static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
    @@ -2348,6 +2350,8 @@
               PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 0,0, plx_9050 },
             { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_TK9902,
               PCI_ANY_ID, PCI_ANY_ID, 0, 0, afavlab_tk9902 },
    + { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
    + PCI_ANY_ID, PCI_ANY_ID, 0, 0, timedia_1889 },
             { 0, }, /* terminate list */
     };
     MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
    Index: linux/drivers/parport/share.c
    diff -u linux/drivers/parport/share.c:1.1.1.7 linux/drivers/parport/share.c:1.9
    --- linux/drivers/parport/share.c:1.1.1.7 Mon Apr 3 09:24:13 2000
    +++ linux/drivers/parport/share.c Tue Apr 4 14:05:26 2000
    @@ -103,6 +103,20 @@
             request_module ("parport_lowlevel");
     }
     
    +/**
    + * parport_register_driver - register a parallel port device driver
    + * @drv: structure describing the driver
    + *
    + * This can be called by a parallel port device driver in order
    + * to receive notifications about ports being found in the
    + * system, as well as ports no longer available.
    + *
    + * The @drv structure is allocated by the caller and must not be
    + * deallocated until after calling parport_unregister_driver().
    + *
    + * Returns 0 on success. Currently it always succeeds.
    + **/
    +
     int parport_register_driver (struct parport_driver *drv)
     {
             struct parport *port;
    @@ -121,6 +135,24 @@
             return 0;
     }
     
    +/**
    + * parport_unregister_driver - deregister a parallel port device driver
    + * @arg: structure describing the driver that was given to
    + * parport_register_driver()
    + *
    + * This should be called by a parallel port device driver that
    + * has registered itself using parport_register_driver() when it
    + * is about to be unloaded.
    + *
    + * When it returns, the driver's attach() routine will no longer
    + * be called, and for each port that attach() was called for, the
    + * detach() routine will hae been called.
    + *
    + * If the caller's attach() function can block, it is their
    + * responsibility to make sure to wait for it to exit before
    + * unloading.
    + **/
    +
     void parport_unregister_driver (struct parport_driver *arg)
     {
             struct parport_driver *drv = driver_chain, *olddrv = NULL;
    @@ -148,9 +180,19 @@
                     drv = drv->next;
             }
     }
    +
    +/**
    + * parport_enumerate - return a list of the system's parallel ports
    + *
    + * This returns the head of the list of parallel ports in the
    + * system. The structure that is returned describes the first
    + * port in the list, and its 'next' member points to the next
    + * port, or %NULL if it's the last port.
    + *
    + * If there are no parallel ports in the system,
    + * parport_enumerate() will return %NULL.
    + **/
     
    -/* Return a list of all the ports we know about. This function shouldn't
    - * really be used -- use parport_register_driver instead. */
     struct parport *parport_enumerate(void)
     {
             if (!portlist)
    @@ -159,6 +201,35 @@
             return portlist;
     }
     
    +/**
    + * parport_register_port - register a parallel port
    + * @base: base I/O address
    + * @irq: IRQ line
    + * @dma: DMA channel
    + * @ops: pointer to the port driver's port operations structure
    + *
    + * When a parallel port (lowlevel) driver finds a port that
    + * should be made available to parallel port device drivers, it
    + * should call parport_register_port(). The @base, @irq, and
    + * @dma parameters are for the convenience of port drivers, and
    + * for ports where they aren't meaningful needn't be set to
    + * anything special. They can be altered afterwards by adjusting
    + * the relevant members of the parport structure that is returned
    + * and represents the port. They should not be tampered with
    + * after calling parport_announce_port, however.
    + *
    + * If there are parallel port device drivers in the system that
    + * have registered themselves using parport_register_driver(),
    + * they are not told about the port at this time; that is done by
    + * parport_announce_port().
    + *
    + * The @ops structure is allocated by the caller, and must not be
    + * deallocated before calling parport_unregister_port().
    + *
    + * If there is no memory to allocate a new parport structure,
    + * this function will return %NULL.
    + **/
    +
     struct parport *parport_register_port(unsigned long base, int irq, int dma,
                                           struct parport_operations *ops)
     {
    @@ -243,6 +314,18 @@
             return tmp;
     }
     
    +/**
    + * parport_announce_port - tell device drivers about a parallel port
    + * @port: parallel port to announce
    + *
    + * After a port driver has registered a parallel port with
    + * parport_register_port, and performed any necessary
    + * initialisation or adjustments, it should call
    + * parport_announce_port() in order to notify all device drivers
    + * that have called parport_register_driver(). Their attach()
    + * functions will be called, with @port as the parameter.
    + **/
    +
     void parport_announce_port (struct parport *port)
     {
     #ifdef CONFIG_PARPORT_1284
    @@ -286,6 +369,25 @@
             kfree(port);
     }
     
    +/**
    + * parport_unregister_port - deregister a parallel port
    + * @port: parallel port to deregister
    + *
    + * When a parallel port driver is forcibly unloaded, or a
    + * parallel port becomes inaccessible, the port driver must call
    + * this function in order to deal with device drivers that still
    + * want to use it.
    + *
    + * The parport structure associated with the port has its
    + * operations structure replaced with one containing 'null'
    + * operations that return errors or just don't do anything.
    + *
    + * Any drivers that have registered themselves using
    + * parport_register_driver() are notified that the port is no
    + * longer accessible by having their detach() routines called
    + * with @port as the parameter.
    + **/
    +
     void parport_unregister_port(struct parport *port)
     {
             struct parport *p;
    @@ -320,10 +422,80 @@
                     free_port (port);
     }
     
    -struct pardevice *parport_register_device(struct parport *port, const char *name,
    - int (*pf)(void *), void (*kf)(void *),
    - void (*irq_func)(int, void *, struct pt_regs *),
    - int flags, void *handle)
    +/**
    + * parport_register_device - register a device on a parallel port
    + * @port: port to which the device is attached
    + * @name: a name to refer to the device
    + * @pf: preemption callback
    + * @kf: kick callback (wake-up)
    + * @irq_func: interrupt handler
    + * @flags: registration flags
    + * @handle: data for callback functions
    + *
    + * This function, called by parallel port device drivers,
    + * declares that a device is connected to a port, and tells the
    + * system all it needs to know.
    + *
    + * The @name is allocated by the caller and must not be
    + * deallocated until the caller calls @parport_unregister_device
    + * for that device.
    + *
    + * The preemption callback function, @pf, is called when this
    + * device driver has claimed access to the port but another
    + * device driver wants to use it. It is given @handle as its
    + * parameter, and should return zero if it is willing for the
    + * system to release the port to another driver on its behalf.
    + * If it wants to keep control of the port it should return
    + * non-zero, and no action will be taken. It is good manners for
    + * the driver to try to release the port at the earliest
    + * opportunity after its preemption callback rejects a preemption
    + * attempt. Note that if a preemption callback is happy for
    + * preemption to go ahead, there is no need to release the port;
    + * it is done automatically. This function may not block, as it
    + * may be called from interrupt context. If the device driver
    + * does not support preemption, @pf can be %NULL.
    + *
    + * The wake-up ("kick") callback function, @kf, is called when
    + * the port is available to be claimed for exclusive access; that
    + * is, parport_claim() is guaranteed to succeed when called from
    + * inside the wake-up callback function. If the driver wants to
    + * claim the port it should do so; otherwise, it need not take
    + * any action. This function may not block, as it may be called
    + * from interrupt context. If the device driver does not want to
    + * be explicitly invited to claim the port in this way, @kf can
    + * be %NULL.
    + *
    + * The interrupt handler, @irq_func, is called when an interrupt
    + * arrives from the parallel port. Note that if a device driver
    + * wants to use interrupts it should use parport_enable_irq(),
    + * and can also check the irq member of the parport structure
    + * representing the port.
    + *
    + * The parallel port (lowlevel) driver is the one that has called
    + * request_irq() and whose interrupt handler is called first.
    + * This handler does whatever needs to be done to the hardware to
    + * acknowledge the interrupt (for PC-style ports there is nothing
    + * special to be done). It then tells the IEEE 1284 code about
    + * the interrupt, which may involve reacting to an IEEE 1284
    + * event depending on the current IEEE 1284 phase. After this,
    + * it calls @irq_func. Needless to say, @irq_func will be called
    + * from interrupt context, and may not block.
    + *
    + * The %PARPORT_DEV_EXCL flag is for preventing port sharing, and
    + * so should only be used when sharing the port with other device
    + * drivers is impossible and would lead to incorrect behaviour.
    + * Use it sparingly! Normally, @flags will be zero.
    + *
    + * This function returns a pointer to a structure that represents
    + * the device on the port, or %NULL if there is not enough memory
    + * to allocate space for that structure.
    + **/
    +
    +struct pardevice *
    +parport_register_device(struct parport *port, const char *name,
    + int (*pf)(void *), void (*kf)(void *),
    + void (*irq_func)(int, void *, struct pt_regs *),
    + int flags, void *handle)
     {
             struct pardevice *tmp;
     
    @@ -420,6 +592,13 @@
             return NULL;
     }
     
    +/**
    + * parport_unregister_device - deregister a device on a parallel port
    + * @dev: pointer to structure representing device
    + *
    + * This undoes the effect of parport_register_device().
    + **/
    +
     void parport_unregister_device(struct pardevice *dev)
     {
             struct parport *port;
    @@ -466,6 +645,18 @@
                     free_port (port);
     }
     
    +/**
    + * parport_claim - claim access to a parallel port device
    + * @dev: pointer to structure representing a device on the port
    + *
    + * This function will not block and so can be used from interrupt
    + * context. If parport_claim() succeeds in claiming access to
    + * the port it returns zero and the port is available to use. It
    + * may fail (returning non-zero) if the port is in use by another
    + * driver and that driver is not willing to relinquish control of
    + * the port.
    + **/
    +
     int parport_claim(struct pardevice *dev)
     {
             struct pardevice *oldcad;
    @@ -567,6 +758,16 @@
             return -EAGAIN;
     }
     
    +/**
    + * parport_claim_or_block - claim access to a parallel port device
    + * @dev: pointer to structure representing a device on the port
    + *
    + * This behaves like parport_claim(), but will block if necessary
    + * to wait for the port to be free. A return value of 1
    + * indicates that it slept; 0 means that it succeeded without
    + * needing to sleep. A negative error code indicates failure.
    + **/
    +
     int parport_claim_or_block(struct pardevice *dev)
     {
             int r;
    @@ -608,6 +809,15 @@
             dev->waiting = 0;
             return r;
     }
    +
    +/**
    + * parport_release - give up access to a parallel port device
    + * @dev: pointer to structure representing parallel port device
    + *
    + * This function cannot fail, but it should not be called without
    + * the port claimed. Similarly, if the port is already claimed
    + * you should not try claiming it again.
    + **/
     
     void parport_release(struct pardevice *dev)
     {
    Index: linux/include/linux/parport.h
    diff -u linux/include/linux/parport.h:1.1.1.5 linux/include/linux/parport.h:1.6
    --- linux/include/linux/parport.h:1.1.1.5 Wed Feb 16 09:53:13 2000
    +++ linux/include/linux/parport.h Mon Apr 3 17:04:01 2000
    @@ -380,8 +380,26 @@
     
     extern void parport_release(struct pardevice *dev);
     
    -/* parport_yield relinquishes the port if it would be helpful to other
    - drivers. The return value is the same as for parport_claim. */
    +/**
    + * parport_yield - relinquish a parallel port temporarily
    + * @dev: a device on the parallel port
    + *
    + * This function relinquishes the port if it would be helpful to other
    + * drivers to do so. Afterwards it tries to reclaim the port using
    + * parport_claim(), and the return value is the same as for
    + * parport_claim(). If it fails, the port is left unclaimed and it is
    + * the driver's responsibility to reclaim the port.
    + *
    + * The parport_yield() and parport_yield_blocking() functions are for
    + * marking points in the driver at which other drivers may claim the
    + * port and use their devices. Yielding the port is similar to
    + * releasing it and reclaiming it, but is more efficient because no
    + * action is taken if there are no other devices needing the port. In
    + * fact, nothing is done even if there are other devices waiting but
    + * the current device is still within its "timeslice". The default
    + * timeslice is half a second, but it can be adjusted via the /proc
    + * interface.
    + **/
     extern __inline__ int parport_yield(struct pardevice *dev)
     {
             unsigned long int timeslip = (jiffies - dev->time);
    @@ -391,8 +409,15 @@
             return parport_claim(dev);
     }
     
    -/* parport_yield_blocking is the same but uses parport_claim_or_block
    - instead of parport_claim. */
    +/**
    + * parport_yield - relinquish a parallel port temporarily
    + * @dev: a device on the parallel port
    + *
    + * This function relinquishes the port if it would be helpful to other
    + * drivers to do so. Afterwards it tries to reclaim the port using
    + * parport_claim_or_block(), and the return value is the same as for
    + * parport_claim_or_block().
    + **/
     extern __inline__ int parport_yield_blocking(struct pardevice *dev)
     {
             unsigned long int timeslip = (jiffies - dev->time);

    -- 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 Apr 04 2000 - 14:41:51 EDT