diff options
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r-- | drivers/s390/cio/device.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 9e0cf44ff9d4..8eb089b99cde 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -80,7 +80,7 @@ ccw_bus_match (struct device * dev, struct device_driver * drv) * specified size. Return length of resulting string (excluding trailing '\0') * even if string doesn't fit buffer (snprintf semantics). */ static int snprint_alias(char *buf, size_t size, - struct ccw_device_id *id, const char *suffix) + const struct ccw_device_id *id, const char *suffix) { int len; @@ -101,10 +101,10 @@ static int snprint_alias(char *buf, size_t size, /* Set up environment variables for ccw device uevent. Return 0 on success, * non-zero otherwise. */ -static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) +static int ccw_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct ccw_device *cdev = to_ccwdev(dev); - struct ccw_device_id *id = &(cdev->id); + const struct ccw_device *cdev = to_ccwdev(dev); + const struct ccw_device_id *id = &(cdev->id); int ret; char modalias_buf[30]; @@ -244,10 +244,13 @@ int ccw_device_is_orphan(struct ccw_device *cdev) static void ccw_device_unregister(struct ccw_device *cdev) { + mutex_lock(&cdev->reg_mutex); if (device_is_registered(&cdev->dev)) { /* Undo device_add(). */ device_del(&cdev->dev); } + mutex_unlock(&cdev->reg_mutex); + if (cdev->private->flags.initialized) { cdev->private->flags.initialized = 0; /* Release reference from device_initialize(). */ @@ -653,11 +656,13 @@ static void ccw_device_do_unbind_bind(struct ccw_device *cdev) { int ret; + mutex_lock(&cdev->reg_mutex); if (device_is_registered(&cdev->dev)) { device_release_driver(&cdev->dev); ret = device_attach(&cdev->dev); WARN_ON(ret == -ENODEV); } + mutex_unlock(&cdev->reg_mutex); } static void @@ -740,6 +745,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch, INIT_LIST_HEAD(&priv->cmb_list); init_waitqueue_head(&priv->wait_q); timer_setup(&priv->timer, ccw_device_timeout, 0); + mutex_init(&cdev->reg_mutex); atomic_set(&priv->onoff, 0); cdev->ccwlock = sch->lock; @@ -825,6 +831,7 @@ static void io_subchannel_register(struct ccw_device *cdev) * be registered). We need to reprobe since we may now have sense id * information. */ + mutex_lock(&cdev->reg_mutex); if (device_is_registered(&cdev->dev)) { if (!cdev->drv) { ret = device_reprobe(&cdev->dev); @@ -847,12 +854,14 @@ static void io_subchannel_register(struct ccw_device *cdev) spin_lock_irqsave(sch->lock, flags); sch_set_cdev(sch, NULL); spin_unlock_irqrestore(sch->lock, flags); + mutex_unlock(&cdev->reg_mutex); /* Release initial device reference. */ put_device(&cdev->dev); goto out_err; } out: cdev->private->flags.recog_done = 1; + mutex_unlock(&cdev->reg_mutex); wake_up(&cdev->private->wait_q); out_err: if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count)) |