/*
* Parallel-port resource manager code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
* Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
* Philip Blundell <philb@gnu.org>
* Andrea Arcangeli
*
* based on work by Grant Guenther <grant@torque.net>
* and Philip Blundell
*
* 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.
*/
#undef PARPORT_DEBUG_SHARING /* undef for production */
#include <linux/module.h>
#include <linux/string.h>
#include <linux/threads.h>
#include <linux/parport.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sched/signal.h>
#include <linux/kmod.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <asm/irq.h>
#undef PARPORT_PARANOID
#define PARPORT_DEFAULT_TIMESLICE (HZ/5)
unsigned long parport_default_timeslice = PARPORT_DEFAULT_TIMESLICE;
int parport_default_spintime = DEFAULT_SPIN_TIME;
static LIST_HEAD(portlist);
static DEFINE_SPINLOCK(parportlist_lock);
/* list of all allocated ports, sorted by ->number */
static LIST_HEAD(all_ports);
static DEFINE_SPINLOCK(full_list_lock);
static LIST_HEAD(drivers);
static DEFINE_MUTEX(registration_lock);
/* What you can do to a port that's gone away.. */
static void dead_write_lines(struct parport *p, unsigned char b){}
static unsigned char dead_read_lines(struct parport *p) { return 0; }
static unsigned char dead_frob_lines(struct parport *p, unsigned char b,
unsigned char c) { return 0; }
static void dead_onearg(struct parport *p){}
static void dead_initstate(struct pardevice *d, struct parport_state *s) { }
static void dead_state(struct parport *p, struct parport_state *s) { }
static size_t dead_write(struct parport *p, const void *b, size_t l, int f)
{ return 0; }
static size_t dead_read(struct parport *p, void *b, size_t l, int f)
{ return 0; }
static struct parport_operations dead_ops = {
.write_data = dead_write_lines, /* data */
.read_data = dead_read_lines,
.write_control = dead_write_lines, /* control */
.read_control = dead_read_lines,
.frob_control = dead_frob_lines,
.read_status = dead_read_lines, /* status */
.enable_irq = dead_onearg, /* enable_irq */
.disable_irq = dead_onearg, /* disable_irq */
.data_forward = dead_onearg, /* data_forward */
.data_reverse = dead_onearg, /* data_reverse */
.init_state = dead_initstate, /* init_state */
.save_state = dead_state,
.restore_state = dead_state,
.epp_write_data = dead_write, /* epp */
.epp_read_data = dead_read,
.epp_write_addr = dead_write,
.epp_read_addr = dead_read,
.ecp_write_data = dead_write, /* ecp */
.ecp_read_data = dead_read,
.ecp_write_addr = dead_write,
.compat_write_data = dead_write, /* compat */
.nibble_read_data = dead_read, /* nibble */
.byte_read_data = dead_read, /* byte */
.owner = NULL,
};
static struct device_type parport_device_type = {
.name = "parport",
};
static int is_parport(struct device *dev)
{
return dev->type == &parport_device_type;
}
static int parport_probe(struct device *dev)
{
struct parport_driver *drv;
if (is_parport(dev))
return -ENODEV;
drv = to_parport_driver(dev->driver);
if (!drv->probe)