summaryrefslogtreecommitdiff
path: root/drivers/parport/share.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parport/share.c')
-rw-r--r--drivers/parport/share.c342
1 files changed, 94 insertions, 248 deletions
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index 5dc53d420ca8..427abdf3c4c4 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -49,8 +49,6 @@ static DEFINE_SPINLOCK(parportlist_lock);
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.. */
@@ -130,7 +128,7 @@ static int parport_probe(struct device *dev)
return drv->probe(to_pardevice(dev));
}
-static struct bus_type parport_bus_type = {
+static const struct bus_type parport_bus_type = {
.name = "parport",
.probe = parport_probe,
};
@@ -165,10 +163,6 @@ static int driver_check(struct device_driver *dev_drv, void *_port)
static void attach_driver_chain(struct parport *port)
{
/* caller has exclusive registration_lock */
- struct parport_driver *drv;
-
- list_for_each_entry(drv, &drivers, list)
- drv->attach(port);
/*
* call the driver_check function of the drivers registered in
@@ -191,10 +185,7 @@ static int driver_detach(struct device_driver *_drv, void *_port)
/* Call detach(port) for each registered driver. */
static void detach_driver_chain(struct parport *port)
{
- struct parport_driver *drv;
/* caller has exclusive registration_lock */
- list_for_each_entry(drv, &drivers, list)
- drv->detach(port);
/*
* call the detach function of the drivers registered in
@@ -230,8 +221,20 @@ static int port_check(struct device *dev, void *dev_drv)
return 0;
}
+/*
+ * Iterates through all the devices connected to the bus and return 1
+ * if the device is a parallel port.
+ */
+
+static int port_detect(struct device *dev, void *dev_drv)
+{
+ if (is_parport(dev))
+ return 1;
+ return 0;
+}
+
/**
- * parport_register_driver - register a parallel port device driver
+ * __parport_register_driver - register a parallel port device driver
* @drv: structure describing the driver
* @owner: owner module of drv
* @mod_name: module name string
@@ -266,38 +269,32 @@ static int port_check(struct device *dev, void *dev_drv)
int __parport_register_driver(struct parport_driver *drv, struct module *owner,
const char *mod_name)
{
- if (list_empty(&portlist))
+ /* using device model */
+ int ret;
+
+ /* initialize common driver fields */
+ drv->driver.name = drv->name;
+ drv->driver.bus = &parport_bus_type;
+ drv->driver.owner = owner;
+ drv->driver.mod_name = mod_name;
+ ret = driver_register(&drv->driver);
+ if (ret)
+ return ret;
+
+ /*
+ * check if bus has any parallel port registered, if
+ * none is found then load the lowlevel driver.
+ */
+ ret = bus_for_each_dev(&parport_bus_type, NULL, NULL,
+ port_detect);
+ if (!ret)
get_lowlevel_driver();
- if (drv->devmodel) {
- /* using device model */
- int ret;
-
- /* initialize common driver fields */
- drv->driver.name = drv->name;
- drv->driver.bus = &parport_bus_type;
- drv->driver.owner = owner;
- drv->driver.mod_name = mod_name;
- ret = driver_register(&drv->driver);
- if (ret)
- return ret;
-
- mutex_lock(&registration_lock);
- if (drv->match_port)
- bus_for_each_dev(&parport_bus_type, NULL, drv,
- port_check);
- mutex_unlock(&registration_lock);
- } else {
- struct parport *port;
-
- drv->devmodel = false;
-
- mutex_lock(&registration_lock);
- list_for_each_entry(port, &portlist, list)
- drv->attach(port);
- list_add(&drv->list, &drivers);
- mutex_unlock(&registration_lock);
- }
+ mutex_lock(&registration_lock);
+ if (drv->match_port)
+ bus_for_each_dev(&parport_bus_type, NULL, drv,
+ port_check);
+ mutex_unlock(&registration_lock);
return 0;
}
@@ -332,17 +329,9 @@ static int port_detach(struct device *dev, void *_drv)
void parport_unregister_driver(struct parport_driver *drv)
{
- struct parport *port;
-
mutex_lock(&registration_lock);
- if (drv->devmodel) {
- bus_for_each_dev(&parport_bus_type, NULL, drv, port_detach);
- driver_unregister(&drv->driver);
- } else {
- list_del_init(&drv->list);
- list_for_each_entry(port, &portlist, list)
- drv->detach(port);
- }
+ bus_for_each_dev(&parport_bus_type, NULL, drv, port_detach);
+ driver_unregister(&drv->driver);
mutex_unlock(&registration_lock);
}
EXPORT_SYMBOL(parport_unregister_driver);
@@ -363,7 +352,6 @@ static void free_port(struct device *dev)
kfree(port->probe_info[d].description);
}
- kfree(port->name);
kfree(port);
}
@@ -440,7 +428,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
struct parport *tmp;
int num;
int device;
- char *name;
int ret;
tmp = kzalloc(sizeof(struct parport), GFP_KERNEL);
@@ -452,13 +439,9 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
tmp->irq = irq;
tmp->dma = dma;
tmp->muxport = tmp->daisy = tmp->muxsel = -1;
- tmp->modes = 0;
INIT_LIST_HEAD(&tmp->list);
- tmp->devices = tmp->cad = NULL;
- tmp->flags = 0;
tmp->ops = ops;
tmp->physport = tmp;
- memset(tmp->probe_info, 0, 5 * sizeof(struct parport_device_info));
rwlock_init(&tmp->cad_lock);
spin_lock_init(&tmp->waitlist_lock);
spin_lock_init(&tmp->pardevice_lock);
@@ -467,19 +450,15 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
sema_init(&tmp->ieee1284.irq, 0);
tmp->spintime = parport_default_spintime;
atomic_set(&tmp->ref_count, 1);
- INIT_LIST_HEAD(&tmp->full_list);
- name = kmalloc(15, GFP_KERNEL);
- if (!name) {
- kfree(tmp);
- return NULL;
- }
/* Search for the lowest free parport number. */
spin_lock(&full_list_lock);
- for (l = all_ports.next, num = 0; l != &all_ports; l = l->next, num++) {
+ num = 0;
+ list_for_each(l, &all_ports) {
struct parport *p = list_entry(l, struct parport, full_list);
- if (p->number != num)
+
+ if (p->number != num++)
break;
}
tmp->portnum = tmp->number = num;
@@ -489,19 +468,17 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
/*
* Now that the portnum is known finish doing the Init.
*/
- sprintf(name, "parport%d", tmp->portnum = tmp->number);
- tmp->name = name;
+ dev_set_name(&tmp->bus_dev, "parport%d", tmp->portnum);
tmp->bus_dev.bus = &parport_bus_type;
tmp->bus_dev.release = free_port;
- dev_set_name(&tmp->bus_dev, name);
tmp->bus_dev.type = &parport_device_type;
+ tmp->name = dev_name(&tmp->bus_dev);
+
for (device = 0; device < 5; device++)
/* assume the worst */
tmp->probe_info[device].class = PARPORT_CLASS_LEGACY;
- tmp->waithead = tmp->waittail = NULL;
-
ret = device_register(&tmp->bus_dev);
if (ret) {
put_device(&tmp->bus_dev);
@@ -534,8 +511,8 @@ void parport_announce_port(struct parport *port)
#endif
if (!port->dev)
- printk(KERN_WARNING "%s: fix this legacy no-device port driver!\n",
- port->name);
+ pr_warn("%s: fix this legacy no-device port driver!\n",
+ port->name);
parport_proc_register(port);
mutex_lock(&registration_lock);
@@ -621,47 +598,48 @@ void parport_remove_port(struct parport *port)
}
EXPORT_SYMBOL(parport_remove_port);
+static void free_pardevice(struct device *dev)
+{
+ struct pardevice *par_dev = to_pardevice(dev);
+
+ kfree_const(par_dev->name);
+ kfree(par_dev);
+}
+
/**
- * parport_register_device - register a device on a parallel port
+ * parport_register_dev_model - 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
+ * @par_dev_cb: struct containing callbacks
+ * @id: device number to be given to the device
*
* 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 struct pardev_cb contains pointer to callbacks. preemption
+ * callback function, @preempt, is called when this device driver
+ * has claimed access to the port but another device driver wants
+ * to use it. It is given, @private, 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, @preempt can be %NULL.
*
- * 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 wake-up ("kick") callback function, @wakeup, 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 explicitly invited to claim the port in this way, @wakeup can
* be %NULL.
*
* The interrupt handler, @irq_func, is called when an interrupt
@@ -691,144 +669,12 @@ EXPORT_SYMBOL(parport_remove_port);
**/
struct pardevice *
-parport_register_device(struct parport *port, const char *name,
- int (*pf)(void *), void (*kf)(void *),
- void (*irq_func)(void *),
- int flags, void *handle)
-{
- struct pardevice *tmp;
-
- if (port->physport->flags & PARPORT_FLAG_EXCL) {
- /* An exclusive device is registered. */
- printk(KERN_DEBUG "%s: no more devices allowed\n",
- port->name);
- return NULL;
- }
-
- if (flags & PARPORT_DEV_LURK) {
- if (!pf || !kf) {
- printk(KERN_INFO "%s: refused to register lurking device (%s) without callbacks\n", port->name, name);
- return NULL;
- }
- }
-
- if (flags & PARPORT_DEV_EXCL) {
- if (port->physport->devices) {
- /*
- * If a device is already registered and this new
- * device wants exclusive access, then no need to
- * continue as we can not grant exclusive access to
- * this device.
- */
- pr_err("%s: cannot grant exclusive access for device %s\n",
- port->name, name);
- return NULL;
- }
- }
-
- /*
- * We up our own module reference count, and that of the port
- * on which a device is to be registered, to ensure that
- * neither of us gets unloaded while we sleep in (e.g.)
- * kmalloc.
- */
- if (!try_module_get(port->ops->owner))
- return NULL;
-
- parport_get_port(port);
-
- tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL);
- if (!tmp)
- goto out;
-
- tmp->state = kmalloc(sizeof(struct parport_state), GFP_KERNEL);
- if (!tmp->state)
- goto out_free_pardevice;
-
- tmp->name = name;
- tmp->port = port;
- tmp->daisy = -1;
- tmp->preempt = pf;
- tmp->wakeup = kf;
- tmp->private = handle;
- tmp->flags = flags;
- tmp->irq_func = irq_func;
- tmp->waiting = 0;
- tmp->timeout = 5 * HZ;
- tmp->devmodel = false;
-
- /* Chain this onto the list */
- tmp->prev = NULL;
- /*
- * This function must not run from an irq handler so we don' t need
- * to clear irq on the local CPU. -arca
- */
- spin_lock(&port->physport->pardevice_lock);
-
- if (flags & PARPORT_DEV_EXCL) {
- if (port->physport->devices) {
- spin_unlock(&port->physport->pardevice_lock);
- printk(KERN_DEBUG
- "%s: cannot grant exclusive access for device %s\n",
- port->name, name);
- goto out_free_all;
- }
- port->flags |= PARPORT_FLAG_EXCL;
- }
-
- tmp->next = port->physport->devices;
- wmb(); /*
- * Make sure that tmp->next is written before it's
- * added to the list; see comments marked 'no locking
- * required'
- */
- if (port->physport->devices)
- port->physport->devices->prev = tmp;
- port->physport->devices = tmp;
- spin_unlock(&port->physport->pardevice_lock);
-
- init_waitqueue_head(&tmp->wait_q);
- tmp->timeslice = parport_default_timeslice;
- tmp->waitnext = tmp->waitprev = NULL;
-
- /*
- * This has to be run as last thing since init_state may need other
- * pardevice fields. -arca
- */
- port->ops->init_state(tmp, tmp->state);
- if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) {
- port->proc_device = tmp;
- parport_device_proc_register(tmp);
- }
- return tmp;
-
- out_free_all:
- kfree(tmp->state);
- out_free_pardevice:
- kfree(tmp);
- out:
- parport_put_port(port);
- module_put(port->ops->owner);
-
- return NULL;
-}
-EXPORT_SYMBOL(parport_register_device);
-
-static void free_pardevice(struct device *dev)
-{
- struct pardevice *par_dev = to_pardevice(dev);
-
- kfree(par_dev->name);
- kfree(par_dev);
-}
-
-struct pardevice *
parport_register_dev_model(struct parport *port, const char *name,
const struct pardev_cb *par_dev_cb, int id)
{
struct pardevice *par_dev;
+ const char *devname;
int ret;
- char *devname;
if (port->physport->flags & PARPORT_FLAG_EXCL) {
/* An exclusive device is registered. */
@@ -871,7 +717,7 @@ parport_register_dev_model(struct parport *port, const char *name,
if (!par_dev->state)
goto err_put_par_dev;
- devname = kstrdup(name, GFP_KERNEL);
+ devname = kstrdup_const(name, GFP_KERNEL);
if (!devname)
goto err_free_par_dev;
@@ -895,6 +741,7 @@ parport_register_dev_model(struct parport *port, const char *name,
par_dev->devmodel = true;
ret = device_register(&par_dev->dev);
if (ret) {
+ kfree(par_dev->state);
put_device(&par_dev->dev);
goto err_put_port;
}
@@ -912,6 +759,7 @@ parport_register_dev_model(struct parport *port, const char *name,
spin_unlock(&port->physport->pardevice_lock);
pr_debug("%s: cannot grant exclusive access for device %s\n",
port->name, name);
+ kfree(par_dev->state);
device_unregister(&par_dev->dev);
goto err_put_port;
}
@@ -947,7 +795,7 @@ parport_register_dev_model(struct parport *port, const char *name,
return par_dev;
err_free_devname:
- kfree(devname);
+ kfree_const(devname);
err_free_par_dev:
kfree(par_dev->state);
err_put_par_dev:
@@ -974,7 +822,7 @@ void parport_unregister_device(struct pardevice *dev)
#ifdef PARPORT_PARANOID
if (!dev) {
- printk(KERN_ERR "parport_unregister_device: passed NULL\n");
+ pr_err("%s: passed NULL\n", __func__);
return;
}
#endif
@@ -1024,10 +872,7 @@ void parport_unregister_device(struct pardevice *dev)
spin_unlock_irq(&port->waitlist_lock);
kfree(dev->state);
- if (dev->devmodel)
- device_unregister(&dev->dev);
- else
- kfree(dev);
+ device_unregister(&dev->dev);
module_put(port->ops->owner);
parport_put_port(port);
@@ -1115,8 +960,7 @@ int parport_claim(struct pardevice *dev)
unsigned long flags;
if (port->cad == dev) {
- printk(KERN_INFO "%s: %s already owner\n",
- dev->port->name,dev->name);
+ pr_info("%s: %s already owner\n", dev->port->name, dev->name);
return 0;
}
@@ -1136,9 +980,8 @@ int parport_claim(struct pardevice *dev)
* I think we'll actually deadlock rather than
* get here, but just in case..
*/
- printk(KERN_WARNING
- "%s: %s released port when preempted!\n",
- port->name, oldcad->name);
+ pr_warn("%s: %s released port when preempted!\n",
+ port->name, oldcad->name);
if (port->cad)
goto blocked;
}
@@ -1238,7 +1081,8 @@ int parport_claim_or_block(struct pardevice *dev)
r = parport_claim(dev);
if (r == -EAGAIN) {
#ifdef PARPORT_DEBUG_SHARING
- printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n", dev->name);
+ printk(KERN_DEBUG "%s: parport_claim() returned -EAGAIN\n",
+ dev->name);
#endif
/*
* FIXME!!! Use the proper locking for dev->waiting,
@@ -1271,7 +1115,7 @@ int parport_claim_or_block(struct pardevice *dev)
if (dev->port->physport->cad != dev)
printk(KERN_DEBUG "%s: exiting parport_claim_or_block but %s owns port!\n",
dev->name, dev->port->physport->cad ?
- dev->port->physport->cad->name:"nobody");
+ dev->port->physport->cad->name : "nobody");
#endif
}
dev->waiting = 0;
@@ -1298,8 +1142,8 @@ void parport_release(struct pardevice *dev)
write_lock_irqsave(&port->cad_lock, flags);
if (port->cad != dev) {
write_unlock_irqrestore(&port->cad_lock, flags);
- printk(KERN_WARNING "%s: %s tried to release parport when not owner\n",
- port->name, dev->name);
+ pr_warn("%s: %s tried to release parport when not owner\n",
+ port->name, dev->name);
return;
}
@@ -1339,7 +1183,8 @@ void parport_release(struct pardevice *dev)
if (dev->port->cad) /* racy but no matter */
return;
} else {
- printk(KERN_ERR "%s: don't know how to wake %s\n", port->name, pd->name);
+ pr_err("%s: don't know how to wake %s\n",
+ port->name, pd->name);
}
}
@@ -1365,4 +1210,5 @@ irqreturn_t parport_irq_handler(int irq, void *dev_id)
}
EXPORT_SYMBOL(parport_irq_handler);
+MODULE_DESCRIPTION("Parallel-port resource manager");
MODULE_LICENSE("GPL");