diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/s390/cio/ccwgroup.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5aeb68e732b0..e5ccda63e883 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
| @@ -75,8 +75,10 @@ static void ccwgroup_ungroup_callback(struct device *dev) | |||
| 75 | { | 75 | { |
| 76 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | 76 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
| 77 | 77 | ||
| 78 | mutex_lock(&gdev->reg_mutex); | ||
| 78 | __ccwgroup_remove_symlinks(gdev); | 79 | __ccwgroup_remove_symlinks(gdev); |
| 79 | device_unregister(dev); | 80 | device_unregister(dev); |
| 81 | mutex_unlock(&gdev->reg_mutex); | ||
| 80 | } | 82 | } |
| 81 | 83 | ||
| 82 | static ssize_t | 84 | static ssize_t |
| @@ -173,7 +175,8 @@ ccwgroup_create(struct device *root, | |||
| 173 | return -ENOMEM; | 175 | return -ENOMEM; |
| 174 | 176 | ||
| 175 | atomic_set(&gdev->onoff, 0); | 177 | atomic_set(&gdev->onoff, 0); |
| 176 | 178 | mutex_init(&gdev->reg_mutex); | |
| 179 | mutex_lock(&gdev->reg_mutex); | ||
| 177 | for (i = 0; i < argc; i++) { | 180 | for (i = 0; i < argc; i++) { |
| 178 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); | 181 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); |
| 179 | 182 | ||
| @@ -183,12 +186,12 @@ ccwgroup_create(struct device *root, | |||
| 183 | || gdev->cdev[i]->id.driver_info != | 186 | || gdev->cdev[i]->id.driver_info != |
| 184 | gdev->cdev[0]->id.driver_info) { | 187 | gdev->cdev[0]->id.driver_info) { |
| 185 | rc = -EINVAL; | 188 | rc = -EINVAL; |
| 186 | goto free_dev; | 189 | goto error; |
| 187 | } | 190 | } |
| 188 | /* Don't allow a device to belong to more than one group. */ | 191 | /* Don't allow a device to belong to more than one group. */ |
| 189 | if (gdev->cdev[i]->dev.driver_data) { | 192 | if (gdev->cdev[i]->dev.driver_data) { |
| 190 | rc = -EINVAL; | 193 | rc = -EINVAL; |
| 191 | goto free_dev; | 194 | goto error; |
| 192 | } | 195 | } |
| 193 | gdev->cdev[i]->dev.driver_data = gdev; | 196 | gdev->cdev[i]->dev.driver_data = gdev; |
| 194 | } | 197 | } |
| @@ -203,9 +206,8 @@ ccwgroup_create(struct device *root, | |||
| 203 | gdev->cdev[0]->dev.bus_id); | 206 | gdev->cdev[0]->dev.bus_id); |
| 204 | 207 | ||
| 205 | rc = device_register(&gdev->dev); | 208 | rc = device_register(&gdev->dev); |
| 206 | |||
| 207 | if (rc) | 209 | if (rc) |
| 208 | goto free_dev; | 210 | goto error; |
| 209 | get_device(&gdev->dev); | 211 | get_device(&gdev->dev); |
| 210 | rc = device_create_file(&gdev->dev, &dev_attr_ungroup); | 212 | rc = device_create_file(&gdev->dev, &dev_attr_ungroup); |
| 211 | 213 | ||
| @@ -216,6 +218,7 @@ ccwgroup_create(struct device *root, | |||
| 216 | 218 | ||
| 217 | rc = __ccwgroup_create_symlinks(gdev); | 219 | rc = __ccwgroup_create_symlinks(gdev); |
| 218 | if (!rc) { | 220 | if (!rc) { |
| 221 | mutex_unlock(&gdev->reg_mutex); | ||
| 219 | put_device(&gdev->dev); | 222 | put_device(&gdev->dev); |
| 220 | return 0; | 223 | return 0; |
| 221 | } | 224 | } |
| @@ -224,19 +227,12 @@ ccwgroup_create(struct device *root, | |||
| 224 | error: | 227 | error: |
| 225 | for (i = 0; i < argc; i++) | 228 | for (i = 0; i < argc; i++) |
| 226 | if (gdev->cdev[i]) { | 229 | if (gdev->cdev[i]) { |
| 227 | put_device(&gdev->cdev[i]->dev); | ||
| 228 | gdev->cdev[i]->dev.driver_data = NULL; | ||
| 229 | } | ||
| 230 | put_device(&gdev->dev); | ||
| 231 | return rc; | ||
| 232 | free_dev: | ||
| 233 | for (i = 0; i < argc; i++) | ||
| 234 | if (gdev->cdev[i]) { | ||
| 235 | if (gdev->cdev[i]->dev.driver_data == gdev) | 230 | if (gdev->cdev[i]->dev.driver_data == gdev) |
| 236 | gdev->cdev[i]->dev.driver_data = NULL; | 231 | gdev->cdev[i]->dev.driver_data = NULL; |
| 237 | put_device(&gdev->cdev[i]->dev); | 232 | put_device(&gdev->cdev[i]->dev); |
| 238 | } | 233 | } |
| 239 | kfree(gdev); | 234 | mutex_unlock(&gdev->reg_mutex); |
| 235 | put_device(&gdev->dev); | ||
| 240 | return rc; | 236 | return rc; |
| 241 | } | 237 | } |
| 242 | 238 | ||
| @@ -422,8 +418,12 @@ ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) | |||
| 422 | get_driver(&cdriver->driver); | 418 | get_driver(&cdriver->driver); |
| 423 | while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, | 419 | while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, |
| 424 | __ccwgroup_match_all))) { | 420 | __ccwgroup_match_all))) { |
| 425 | __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); | 421 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
| 422 | |||
| 423 | mutex_lock(&gdev->reg_mutex); | ||
| 424 | __ccwgroup_remove_symlinks(gdev); | ||
| 426 | device_unregister(dev); | 425 | device_unregister(dev); |
| 426 | mutex_unlock(&gdev->reg_mutex); | ||
| 427 | put_device(dev); | 427 | put_device(dev); |
| 428 | } | 428 | } |
| 429 | put_driver(&cdriver->driver); | 429 | put_driver(&cdriver->driver); |
| @@ -444,8 +444,10 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev) | |||
| 444 | if (cdev->dev.driver_data) { | 444 | if (cdev->dev.driver_data) { |
| 445 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; | 445 | gdev = (struct ccwgroup_device *)cdev->dev.driver_data; |
| 446 | if (get_device(&gdev->dev)) { | 446 | if (get_device(&gdev->dev)) { |
| 447 | mutex_lock(&gdev->reg_mutex); | ||
| 447 | if (device_is_registered(&gdev->dev)) | 448 | if (device_is_registered(&gdev->dev)) |
| 448 | return gdev; | 449 | return gdev; |
| 450 | mutex_unlock(&gdev->reg_mutex); | ||
| 449 | put_device(&gdev->dev); | 451 | put_device(&gdev->dev); |
| 450 | } | 452 | } |
| 451 | return NULL; | 453 | return NULL; |
| @@ -465,6 +467,7 @@ ccwgroup_remove_ccwdev(struct ccw_device *cdev) | |||
| 465 | if (gdev) { | 467 | if (gdev) { |
| 466 | __ccwgroup_remove_symlinks(gdev); | 468 | __ccwgroup_remove_symlinks(gdev); |
| 467 | device_unregister(&gdev->dev); | 469 | device_unregister(&gdev->dev); |
| 470 | mutex_unlock(&gdev->reg_mutex); | ||
| 468 | put_device(&gdev->dev); | 471 | put_device(&gdev->dev); |
| 469 | } | 472 | } |
| 470 | } | 473 | } |
