/* * Any part of this program may be used in documents licensed under * the GNU Free Documentation License, Version 1.1 or any later version * published by the Free Software Foundation.
*/ #ifndef _PARPORT_H_ #define _PARPORT_H_
/* Each device can have two callback functions: * 1) a preemption function, called by the resource manager to request * that the driver relinquish control of the port. The driver should * return zero if it agrees to release the port, and nonzero if it * refuses. Do not call parport_release() - the kernel will do this * implicitly. * * 2) a wake-up function, called by the resource manager to tell drivers * that the port is available to be claimed. If a driver wants to use * the port, it should call parport_claim() here.
*/
/* A parallel port device */ struct pardevice { constchar *name; struct parport *port; int daisy; int (*preempt)(void *); void (*wakeup)(void *); void *private; void (*irq_func)(void *); unsignedint flags; struct pardevice *next; struct pardevice *prev; struct device dev; bool devmodel; struct parport_state *state; /* saved status over preemption */
wait_queue_head_t wait_q; unsignedlongint time; unsignedlongint timeslice; volatilelongint timeout; unsignedlong waiting; /* long req'd for set_bit --RR */ struct pardevice *waitprev; struct pardevice *waitnext; void * sysctl_table;
};
/* IEEE1284 phases. These are exposed to userland through ppdev IOCTL
* PP[GS]ETPHASE, so do not change existing values. */ enum ieee1284_phase {
IEEE1284_PH_FWD_DATA,
IEEE1284_PH_FWD_IDLE,
IEEE1284_PH_TERMINATE,
IEEE1284_PH_NEGOTIATION,
IEEE1284_PH_HBUSY_DNA,
IEEE1284_PH_REV_IDLE,
IEEE1284_PH_HBUSY_DAVAIL,
IEEE1284_PH_REV_DATA,
IEEE1284_PH_ECP_SETUP,
IEEE1284_PH_ECP_FWD_TO_REV,
IEEE1284_PH_ECP_REV_TO_FWD,
IEEE1284_PH_ECP_DIR_UNKNOWN,
}; struct ieee1284_info { int mode; volatileenum ieee1284_phase phase; struct semaphore irq;
};
/* A parallel port */ struct parport { unsignedlong base; /* base address */ unsignedlong base_hi; /* base address (hi - ECR) */ unsignedint size; /* IO extent */ constchar *name; unsignedint modes; int irq; /* interrupt (or -1 for none) */ int dma; int muxport; /* which muxport (if any) this is */ int portnum; /* which physical parallel port (not mux) */ struct device *dev; /* Physical device associated with IO/DMA. * This may unfortulately be null if the * port has a legacy driver.
*/ struct device bus_dev; /* to link with the bus */ struct parport *physport; /* If this is a non-default mux parport, i.e. we're a clone of a real physical port, this is a pointer to that port. The locking is only done in the real port. For a clone port, the following structure members are meaningless: devices, cad, muxsel, waithead, waittail, flags, pdir, dev, ieee1284, *_lock.
It this is a default mux parport, or there is no mux involved, this points to
ourself. */
struct pardevice *devices; struct pardevice *cad; /* port owner */ int daisy; /* currently selected daisy addr */ int muxsel; /* currently selected mux port */
int parport_bus_init(void); void parport_bus_exit(void);
/* parport_register_port registers a new parallel port at the given address (if one does not already exist) and returns a pointer to it. This entails claiming the I/O region, IRQ and DMA. NULL is returned
if initialisation fails. */ struct parport *parport_register_port(unsignedlong base, int irq, int dma, struct parport_operations *ops);
/* Once a registered port is ready for high-level drivers to use, the low-level driver that registered it should announce it. This will call the high-level drivers' attach() functions (after things like determining the IEEE 1284.3 topology of the port and collecting
DeviceIDs). */ void parport_announce_port (struct parport *port);
/* Unregister a port. */ externvoid parport_remove_port(struct parport *port);
/* Register a new high-level driver. */
int __must_check __parport_register_driver(struct parport_driver *, struct module *, constchar *mod_name); /* * parport_register_driver must be a macro so that KBUILD_MODNAME can * be expanded
*/
/** * parport_register_driver - register a parallel port device driver * @driver: 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 @driver structure is allocated by the caller and must not be * deallocated until after calling parport_unregister_driver(). * * If using the non device model: * The driver's attach() function may block. The port that * attach() is given will be valid for the duration of the * callback, but if the driver wants to take a copy of the * pointer it must call parport_get_port() to do so. Calling * parport_register_device() on that port will do this for you. * * The driver's detach() function may block. The port that * detach() is given will be valid for the duration of the * callback, but if the driver wants to take a copy of the * pointer it must call parport_get_port() to do so. * * * Returns 0 on success. The non device model will always succeeds. * but the new device model can fail and will return the error code.
**/ #define parport_register_driver(driver) \
__parport_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
/* Unregister a high-level driver. */ void parport_unregister_driver(struct parport_driver *);
/** * module_parport_driver() - Helper macro for registering a modular parport driver * @__parport_driver: struct parport_driver to be used * * Helper macro for parport drivers which do not do anything special in module * init and exit. This eliminates a lot of boilerplate. Each module may only * use this macro once, and calling it replaces module_init() and module_exit().
*/ #define module_parport_driver(__parport_driver) \
module_driver(__parport_driver, parport_register_driver, parport_unregister_driver)
/* If parport_register_driver doesn't fit your needs, perhaps
* parport_find_xxx does. */ externstruct parport *parport_find_number (int); externstruct parport *parport_find_base (unsignedlong);
/* generic irq handler, if it suits your needs */ extern irqreturn_t parport_irq_handler(int irq, void *dev_id);
/* * parport_register_dev_model declares that a device is connected to a * port, and tells the kernel all it needs to know.
*/ struct pardevice *
parport_register_dev_model(struct parport *port, constchar *name, conststruct pardev_cb *par_dev_cb, int cnt);
/* parport_unregister unlinks a device from the chain. */ externvoid parport_unregister_device(struct pardevice *dev);
/* parport_claim tries to gain ownership of the port for a particular driver. This may fail (return non-zero) if another driver is busy. If this driver has registered an interrupt handler, it will be
enabled. */ externint parport_claim(struct pardevice *dev);
/* parport_claim_or_block is the same, but sleeps if the port cannot be claimed. Return value is 1 if it slept, 0 normally and -errno
on error. */ externint parport_claim_or_block(struct pardevice *dev);
/* parport_release reverses a previous parport_claim. This can never fail, though the effects are undefined (except that they are bad) if you didn't previously own the port. Once you have released the port you should make sure that neither your code nor the hardware on the port tries to initiate any communication without first re-claiming the port. If you mess with the port state (enabling
ECP for example) you should clean up before releasing the port. */
/** * 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.
**/ static __inline__ int parport_yield(struct pardevice *dev)
{ unsignedlongint timeslip = (jiffies - dev->time); if ((dev->port->waithead == NULL) || (timeslip < dev->timeslice)) return 0;
parport_release(dev); return parport_claim(dev);
}
/** * parport_yield_blocking - 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().
**/ static __inline__ int parport_yield_blocking(struct pardevice *dev)
{ unsignedlongint timeslip = (jiffies - dev->time); if ((dev->port->waithead == NULL) || (timeslip < dev->timeslice)) return 0;
parport_release(dev); return parport_claim_or_block(dev);
}
/* Flags used to identify what a device does. */ #define PARPORT_DEV_TRAN 0 /* WARNING !! DEPRECATED !! */ #define PARPORT_DEV_LURK (1<<0) /* WARNING !! DEPRECATED !! */ #define PARPORT_DEV_EXCL (1<<1) /* Need exclusive access. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.