diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/con3215.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/con3270.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/fs3270.c | 10 | ||||
-rw-r--r-- | drivers/s390/char/monreader.c | 8 | ||||
-rw-r--r-- | drivers/s390/char/monwriter.c | 7 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/tape.h | 9 | ||||
-rw-r--r-- | drivers/s390/char/tape_34xx.c | 8 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/tape_block.c | 17 | ||||
-rw-r--r-- | drivers/s390/char/tape_char.c | 54 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 65 | ||||
-rw-r--r-- | drivers/s390/char/tape_proc.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/tty3270.c | 20 | ||||
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 8 | ||||
-rw-r--r-- | drivers/s390/char/vmur.c | 3 | ||||
-rw-r--r-- | drivers/s390/char/vmwatchdog.c | 29 |
17 files changed, 137 insertions, 108 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 21639d6c996f..9d61683b5633 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -857,7 +857,6 @@ static struct console con3215 = { | |||
857 | 857 | ||
858 | /* | 858 | /* |
859 | * 3215 console initialization code called from console_init(). | 859 | * 3215 console initialization code called from console_init(). |
860 | * NOTE: This is called before kmalloc is available. | ||
861 | */ | 860 | */ |
862 | static int __init con3215_init(void) | 861 | static int __init con3215_init(void) |
863 | { | 862 | { |
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index bb838bdf829d..6bca81aea396 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c | |||
@@ -572,7 +572,6 @@ static struct console con3270 = { | |||
572 | 572 | ||
573 | /* | 573 | /* |
574 | * 3270 console initialization code called from console_init(). | 574 | * 3270 console initialization code called from console_init(). |
575 | * NOTE: This is called before kmalloc is available. | ||
576 | */ | 575 | */ |
577 | static int __init | 576 | static int __init |
578 | con3270_init(void) | 577 | con3270_init(void) |
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 097d3846a828..d449063c30fe 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -38,6 +38,8 @@ struct fs3270 { | |||
38 | size_t rdbuf_size; /* size of data returned by RDBUF */ | 38 | size_t rdbuf_size; /* size of data returned by RDBUF */ |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static DEFINE_MUTEX(fs3270_mutex); | ||
42 | |||
41 | static void | 43 | static void |
42 | fs3270_wake_up(struct raw3270_request *rq, void *data) | 44 | fs3270_wake_up(struct raw3270_request *rq, void *data) |
43 | { | 45 | { |
@@ -328,7 +330,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
328 | if (!fp) | 330 | if (!fp) |
329 | return -ENODEV; | 331 | return -ENODEV; |
330 | rc = 0; | 332 | rc = 0; |
331 | lock_kernel(); | 333 | mutex_lock(&fs3270_mutex); |
332 | switch (cmd) { | 334 | switch (cmd) { |
333 | case TUBICMD: | 335 | case TUBICMD: |
334 | fp->read_command = arg; | 336 | fp->read_command = arg; |
@@ -354,7 +356,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
354 | rc = -EFAULT; | 356 | rc = -EFAULT; |
355 | break; | 357 | break; |
356 | } | 358 | } |
357 | unlock_kernel(); | 359 | mutex_unlock(&fs3270_mutex); |
358 | return rc; | 360 | return rc; |
359 | } | 361 | } |
360 | 362 | ||
@@ -437,7 +439,7 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
437 | minor = tty->index + RAW3270_FIRSTMINOR; | 439 | minor = tty->index + RAW3270_FIRSTMINOR; |
438 | tty_kref_put(tty); | 440 | tty_kref_put(tty); |
439 | } | 441 | } |
440 | lock_kernel(); | 442 | mutex_lock(&fs3270_mutex); |
441 | /* Check if some other program is already using fullscreen mode. */ | 443 | /* Check if some other program is already using fullscreen mode. */ |
442 | fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); | 444 | fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); |
443 | if (!IS_ERR(fp)) { | 445 | if (!IS_ERR(fp)) { |
@@ -478,7 +480,7 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
478 | } | 480 | } |
479 | filp->private_data = fp; | 481 | filp->private_data = fp; |
480 | out: | 482 | out: |
481 | unlock_kernel(); | 483 | mutex_unlock(&fs3270_mutex); |
482 | return rc; | 484 | return rc; |
483 | } | 485 | } |
484 | 486 | ||
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 66e21dd23154..60473f86e1f9 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
17 | #include <linux/types.h> | 16 | #include <linux/types.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
@@ -283,7 +282,6 @@ static int mon_open(struct inode *inode, struct file *filp) | |||
283 | /* | 282 | /* |
284 | * only one user allowed | 283 | * only one user allowed |
285 | */ | 284 | */ |
286 | lock_kernel(); | ||
287 | rc = -EBUSY; | 285 | rc = -EBUSY; |
288 | if (test_and_set_bit(MON_IN_USE, &mon_in_use)) | 286 | if (test_and_set_bit(MON_IN_USE, &mon_in_use)) |
289 | goto out; | 287 | goto out; |
@@ -321,7 +319,6 @@ static int mon_open(struct inode *inode, struct file *filp) | |||
321 | } | 319 | } |
322 | filp->private_data = monpriv; | 320 | filp->private_data = monpriv; |
323 | dev_set_drvdata(monreader_device, monpriv); | 321 | dev_set_drvdata(monreader_device, monpriv); |
324 | unlock_kernel(); | ||
325 | return nonseekable_open(inode, filp); | 322 | return nonseekable_open(inode, filp); |
326 | 323 | ||
327 | out_path: | 324 | out_path: |
@@ -331,7 +328,6 @@ out_priv: | |||
331 | out_use: | 328 | out_use: |
332 | clear_bit(MON_IN_USE, &mon_in_use); | 329 | clear_bit(MON_IN_USE, &mon_in_use); |
333 | out: | 330 | out: |
334 | unlock_kernel(); | ||
335 | return rc; | 331 | return rc; |
336 | } | 332 | } |
337 | 333 | ||
@@ -607,6 +603,10 @@ static int __init mon_init(void) | |||
607 | } | 603 | } |
608 | dcss_mkname(mon_dcss_name, &user_data_connect[8]); | 604 | dcss_mkname(mon_dcss_name, &user_data_connect[8]); |
609 | 605 | ||
606 | /* | ||
607 | * misc_register() has to be the last action in module_init(), because | ||
608 | * file operations will be available right after this. | ||
609 | */ | ||
610 | rc = misc_register(&mon_dev); | 610 | rc = misc_register(&mon_dev); |
611 | if (rc < 0 ) | 611 | if (rc < 0 ) |
612 | goto out; | 612 | goto out; |
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 66fb8eba93f4..6532ed8b4afa 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/types.h> | 16 | #include <linux/types.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
@@ -185,13 +184,11 @@ static int monwrite_open(struct inode *inode, struct file *filp) | |||
185 | monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); | 184 | monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); |
186 | if (!monpriv) | 185 | if (!monpriv) |
187 | return -ENOMEM; | 186 | return -ENOMEM; |
188 | lock_kernel(); | ||
189 | INIT_LIST_HEAD(&monpriv->list); | 187 | INIT_LIST_HEAD(&monpriv->list); |
190 | monpriv->hdr_to_read = sizeof(monpriv->hdr); | 188 | monpriv->hdr_to_read = sizeof(monpriv->hdr); |
191 | mutex_init(&monpriv->thread_mutex); | 189 | mutex_init(&monpriv->thread_mutex); |
192 | filp->private_data = monpriv; | 190 | filp->private_data = monpriv; |
193 | list_add_tail(&monpriv->priv_list, &mon_priv_list); | 191 | list_add_tail(&monpriv->priv_list, &mon_priv_list); |
194 | unlock_kernel(); | ||
195 | return nonseekable_open(inode, filp); | 192 | return nonseekable_open(inode, filp); |
196 | } | 193 | } |
197 | 194 | ||
@@ -364,6 +361,10 @@ static int __init mon_init(void) | |||
364 | goto out_driver; | 361 | goto out_driver; |
365 | } | 362 | } |
366 | 363 | ||
364 | /* | ||
365 | * misc_register() has to be the last action in module_init(), because | ||
366 | * file operations will be available right after this. | ||
367 | */ | ||
367 | rc = misc_register(&mon_dev); | 368 | rc = misc_register(&mon_dev); |
368 | if (rc) | 369 | if (rc) |
369 | goto out_device; | 370 | goto out_device; |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 5cc11c636d38..28b5afc129c3 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -84,6 +84,7 @@ static void __init sclp_read_info_early(void) | |||
84 | do { | 84 | do { |
85 | memset(sccb, 0, sizeof(*sccb)); | 85 | memset(sccb, 0, sizeof(*sccb)); |
86 | sccb->header.length = sizeof(*sccb); | 86 | sccb->header.length = sizeof(*sccb); |
87 | sccb->header.function_code = 0x80; | ||
87 | sccb->header.control_mask[2] = 0x80; | 88 | sccb->header.control_mask[2] = 0x80; |
88 | rc = sclp_cmd_sync_early(commands[i], sccb); | 89 | rc = sclp_cmd_sync_early(commands[i], sccb); |
89 | } while (rc == -EBUSY); | 90 | } while (rc == -EBUSY); |
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index a26333774701..7a242f073632 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -212,6 +212,9 @@ struct tape_device { | |||
212 | struct tape_class_device * nt; | 212 | struct tape_class_device * nt; |
213 | struct tape_class_device * rt; | 213 | struct tape_class_device * rt; |
214 | 214 | ||
215 | /* Device mutex to serialize tape commands. */ | ||
216 | struct mutex mutex; | ||
217 | |||
215 | /* Device discipline information. */ | 218 | /* Device discipline information. */ |
216 | struct tape_discipline * discipline; | 219 | struct tape_discipline * discipline; |
217 | void * discdata; | 220 | void * discdata; |
@@ -292,9 +295,9 @@ extern int tape_generic_pm_suspend(struct ccw_device *); | |||
292 | extern int tape_generic_probe(struct ccw_device *); | 295 | extern int tape_generic_probe(struct ccw_device *); |
293 | extern void tape_generic_remove(struct ccw_device *); | 296 | extern void tape_generic_remove(struct ccw_device *); |
294 | 297 | ||
295 | extern struct tape_device *tape_get_device(int devindex); | 298 | extern struct tape_device *tape_find_device(int devindex); |
296 | extern struct tape_device *tape_get_device_reference(struct tape_device *); | 299 | extern struct tape_device *tape_get_device(struct tape_device *); |
297 | extern struct tape_device *tape_put_device(struct tape_device *); | 300 | extern void tape_put_device(struct tape_device *); |
298 | 301 | ||
299 | /* Externals from tape_char.c */ | 302 | /* Externals from tape_char.c */ |
300 | extern int tapechar_init(void); | 303 | extern int tapechar_init(void); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 2fe45ff77b75..3657fe103c27 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -113,16 +113,16 @@ tape_34xx_work_handler(struct work_struct *work) | |||
113 | { | 113 | { |
114 | struct tape_34xx_work *p = | 114 | struct tape_34xx_work *p = |
115 | container_of(work, struct tape_34xx_work, work); | 115 | container_of(work, struct tape_34xx_work, work); |
116 | struct tape_device *device = p->device; | ||
116 | 117 | ||
117 | switch(p->op) { | 118 | switch(p->op) { |
118 | case TO_MSEN: | 119 | case TO_MSEN: |
119 | tape_34xx_medium_sense(p->device); | 120 | tape_34xx_medium_sense(device); |
120 | break; | 121 | break; |
121 | default: | 122 | default: |
122 | DBF_EVENT(3, "T34XX: internal error: unknown work\n"); | 123 | DBF_EVENT(3, "T34XX: internal error: unknown work\n"); |
123 | } | 124 | } |
124 | 125 | tape_put_device(device); | |
125 | p->device = tape_put_device(p->device); | ||
126 | kfree(p); | 126 | kfree(p); |
127 | } | 127 | } |
128 | 128 | ||
@@ -136,7 +136,7 @@ tape_34xx_schedule_work(struct tape_device *device, enum tape_op op) | |||
136 | 136 | ||
137 | INIT_WORK(&p->work, tape_34xx_work_handler); | 137 | INIT_WORK(&p->work, tape_34xx_work_handler); |
138 | 138 | ||
139 | p->device = tape_get_device_reference(device); | 139 | p->device = tape_get_device(device); |
140 | p->op = op; | 140 | p->op = op; |
141 | 141 | ||
142 | schedule_work(&p->work); | 142 | schedule_work(&p->work); |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index e4cc3aae9162..0c72aadb8391 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -608,7 +608,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) | |||
608 | 608 | ||
609 | INIT_WORK(&p->work, tape_3590_work_handler); | 609 | INIT_WORK(&p->work, tape_3590_work_handler); |
610 | 610 | ||
611 | p->device = tape_get_device_reference(device); | 611 | p->device = tape_get_device(device); |
612 | p->op = op; | 612 | p->op = op; |
613 | 613 | ||
614 | schedule_work(&p->work); | 614 | schedule_work(&p->work); |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 0c0705b91c28..4799cc2f73c3 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -54,7 +54,7 @@ static const struct block_device_operations tapeblock_fops = { | |||
54 | .owner = THIS_MODULE, | 54 | .owner = THIS_MODULE, |
55 | .open = tapeblock_open, | 55 | .open = tapeblock_open, |
56 | .release = tapeblock_release, | 56 | .release = tapeblock_release, |
57 | .locked_ioctl = tapeblock_ioctl, | 57 | .ioctl = tapeblock_ioctl, |
58 | .media_changed = tapeblock_medium_changed, | 58 | .media_changed = tapeblock_medium_changed, |
59 | .revalidate_disk = tapeblock_revalidate_disk, | 59 | .revalidate_disk = tapeblock_revalidate_disk, |
60 | }; | 60 | }; |
@@ -239,7 +239,7 @@ tapeblock_setup_device(struct tape_device * device) | |||
239 | disk->major = tapeblock_major; | 239 | disk->major = tapeblock_major; |
240 | disk->first_minor = device->first_minor; | 240 | disk->first_minor = device->first_minor; |
241 | disk->fops = &tapeblock_fops; | 241 | disk->fops = &tapeblock_fops; |
242 | disk->private_data = tape_get_device_reference(device); | 242 | disk->private_data = tape_get_device(device); |
243 | disk->queue = blkdat->request_queue; | 243 | disk->queue = blkdat->request_queue; |
244 | set_capacity(disk, 0); | 244 | set_capacity(disk, 0); |
245 | sprintf(disk->disk_name, "btibm%d", | 245 | sprintf(disk->disk_name, "btibm%d", |
@@ -247,11 +247,11 @@ tapeblock_setup_device(struct tape_device * device) | |||
247 | 247 | ||
248 | blkdat->disk = disk; | 248 | blkdat->disk = disk; |
249 | blkdat->medium_changed = 1; | 249 | blkdat->medium_changed = 1; |
250 | blkdat->request_queue->queuedata = tape_get_device_reference(device); | 250 | blkdat->request_queue->queuedata = tape_get_device(device); |
251 | 251 | ||
252 | add_disk(disk); | 252 | add_disk(disk); |
253 | 253 | ||
254 | tape_get_device_reference(device); | 254 | tape_get_device(device); |
255 | INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); | 255 | INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); |
256 | 256 | ||
257 | return 0; | 257 | return 0; |
@@ -274,13 +274,14 @@ tapeblock_cleanup_device(struct tape_device *device) | |||
274 | } | 274 | } |
275 | 275 | ||
276 | del_gendisk(device->blk_data.disk); | 276 | del_gendisk(device->blk_data.disk); |
277 | device->blk_data.disk->private_data = | 277 | device->blk_data.disk->private_data = NULL; |
278 | tape_put_device(device->blk_data.disk->private_data); | 278 | tape_put_device(device); |
279 | put_disk(device->blk_data.disk); | 279 | put_disk(device->blk_data.disk); |
280 | 280 | ||
281 | device->blk_data.disk = NULL; | 281 | device->blk_data.disk = NULL; |
282 | cleanup_queue: | 282 | cleanup_queue: |
283 | device->blk_data.request_queue->queuedata = tape_put_device(device); | 283 | device->blk_data.request_queue->queuedata = NULL; |
284 | tape_put_device(device); | ||
284 | 285 | ||
285 | blk_cleanup_queue(device->blk_data.request_queue); | 286 | blk_cleanup_queue(device->blk_data.request_queue); |
286 | device->blk_data.request_queue = NULL; | 287 | device->blk_data.request_queue = NULL; |
@@ -363,7 +364,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode) | |||
363 | struct tape_device * device; | 364 | struct tape_device * device; |
364 | int rc; | 365 | int rc; |
365 | 366 | ||
366 | device = tape_get_device_reference(disk->private_data); | 367 | device = tape_get_device(disk->private_data); |
367 | 368 | ||
368 | if (device->required_tapemarks) { | 369 | if (device->required_tapemarks) { |
369 | DBF_EVENT(2, "TBLOCK: missing tapemarks\n"); | 370 | DBF_EVENT(2, "TBLOCK: missing tapemarks\n"); |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 31566c55adfe..23d773a0d113 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -33,8 +33,7 @@ static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *); | |||
33 | static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); | 33 | static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); |
34 | static int tapechar_open(struct inode *,struct file *); | 34 | static int tapechar_open(struct inode *,struct file *); |
35 | static int tapechar_release(struct inode *,struct file *); | 35 | static int tapechar_release(struct inode *,struct file *); |
36 | static int tapechar_ioctl(struct inode *, struct file *, unsigned int, | 36 | static long tapechar_ioctl(struct file *, unsigned int, unsigned long); |
37 | unsigned long); | ||
38 | static long tapechar_compat_ioctl(struct file *, unsigned int, | 37 | static long tapechar_compat_ioctl(struct file *, unsigned int, |
39 | unsigned long); | 38 | unsigned long); |
40 | 39 | ||
@@ -43,7 +42,7 @@ static const struct file_operations tape_fops = | |||
43 | .owner = THIS_MODULE, | 42 | .owner = THIS_MODULE, |
44 | .read = tapechar_read, | 43 | .read = tapechar_read, |
45 | .write = tapechar_write, | 44 | .write = tapechar_write, |
46 | .ioctl = tapechar_ioctl, | 45 | .unlocked_ioctl = tapechar_ioctl, |
47 | .compat_ioctl = tapechar_compat_ioctl, | 46 | .compat_ioctl = tapechar_compat_ioctl, |
48 | .open = tapechar_open, | 47 | .open = tapechar_open, |
49 | .release = tapechar_release, | 48 | .release = tapechar_release, |
@@ -170,7 +169,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) | |||
170 | if (rc == 0) { | 169 | if (rc == 0) { |
171 | rc = block_size - request->rescnt; | 170 | rc = block_size - request->rescnt; |
172 | DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); | 171 | DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); |
173 | filp->f_pos += rc; | ||
174 | /* Copy data from idal buffer to user space. */ | 172 | /* Copy data from idal buffer to user space. */ |
175 | if (idal_buffer_to_user(device->char_data.idal_buf, | 173 | if (idal_buffer_to_user(device->char_data.idal_buf, |
176 | data, rc) != 0) | 174 | data, rc) != 0) |
@@ -238,7 +236,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t | |||
238 | break; | 236 | break; |
239 | DBF_EVENT(6, "TCHAR:wbytes: %lx\n", | 237 | DBF_EVENT(6, "TCHAR:wbytes: %lx\n", |
240 | block_size - request->rescnt); | 238 | block_size - request->rescnt); |
241 | filp->f_pos += block_size - request->rescnt; | ||
242 | written += block_size - request->rescnt; | 239 | written += block_size - request->rescnt; |
243 | if (request->rescnt != 0) | 240 | if (request->rescnt != 0) |
244 | break; | 241 | break; |
@@ -286,26 +283,20 @@ tapechar_open (struct inode *inode, struct file *filp) | |||
286 | if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) | 283 | if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) |
287 | return -ENODEV; | 284 | return -ENODEV; |
288 | 285 | ||
289 | lock_kernel(); | ||
290 | minor = iminor(filp->f_path.dentry->d_inode); | 286 | minor = iminor(filp->f_path.dentry->d_inode); |
291 | device = tape_get_device(minor / TAPE_MINORS_PER_DEV); | 287 | device = tape_find_device(minor / TAPE_MINORS_PER_DEV); |
292 | if (IS_ERR(device)) { | 288 | if (IS_ERR(device)) { |
293 | DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n"); | 289 | DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n"); |
294 | rc = PTR_ERR(device); | 290 | return PTR_ERR(device); |
295 | goto out; | ||
296 | } | 291 | } |
297 | 292 | ||
298 | |||
299 | rc = tape_open(device); | 293 | rc = tape_open(device); |
300 | if (rc == 0) { | 294 | if (rc == 0) { |
301 | filp->private_data = device; | 295 | filp->private_data = device; |
302 | rc = nonseekable_open(inode, filp); | 296 | nonseekable_open(inode, filp); |
303 | } | 297 | } else |
304 | else | ||
305 | tape_put_device(device); | 298 | tape_put_device(device); |
306 | 299 | ||
307 | out: | ||
308 | unlock_kernel(); | ||
309 | return rc; | 300 | return rc; |
310 | } | 301 | } |
311 | 302 | ||
@@ -342,7 +333,8 @@ tapechar_release(struct inode *inode, struct file *filp) | |||
342 | device->char_data.idal_buf = NULL; | 333 | device->char_data.idal_buf = NULL; |
343 | } | 334 | } |
344 | tape_release(device); | 335 | tape_release(device); |
345 | filp->private_data = tape_put_device(device); | 336 | filp->private_data = NULL; |
337 | tape_put_device(device); | ||
346 | 338 | ||
347 | return 0; | 339 | return 0; |
348 | } | 340 | } |
@@ -351,16 +343,11 @@ tapechar_release(struct inode *inode, struct file *filp) | |||
351 | * Tape device io controls. | 343 | * Tape device io controls. |
352 | */ | 344 | */ |
353 | static int | 345 | static int |
354 | tapechar_ioctl(struct inode *inp, struct file *filp, | 346 | __tapechar_ioctl(struct tape_device *device, |
355 | unsigned int no, unsigned long data) | 347 | unsigned int no, unsigned long data) |
356 | { | 348 | { |
357 | struct tape_device *device; | ||
358 | int rc; | 349 | int rc; |
359 | 350 | ||
360 | DBF_EVENT(6, "TCHAR:ioct\n"); | ||
361 | |||
362 | device = (struct tape_device *) filp->private_data; | ||
363 | |||
364 | if (no == MTIOCTOP) { | 351 | if (no == MTIOCTOP) { |
365 | struct mtop op; | 352 | struct mtop op; |
366 | 353 | ||
@@ -453,15 +440,30 @@ tapechar_ioctl(struct inode *inp, struct file *filp, | |||
453 | } | 440 | } |
454 | 441 | ||
455 | static long | 442 | static long |
443 | tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) | ||
444 | { | ||
445 | struct tape_device *device; | ||
446 | long rc; | ||
447 | |||
448 | DBF_EVENT(6, "TCHAR:ioct\n"); | ||
449 | |||
450 | device = (struct tape_device *) filp->private_data; | ||
451 | mutex_lock(&device->mutex); | ||
452 | rc = __tapechar_ioctl(device, no, data); | ||
453 | mutex_unlock(&device->mutex); | ||
454 | return rc; | ||
455 | } | ||
456 | |||
457 | static long | ||
456 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) | 458 | tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) |
457 | { | 459 | { |
458 | struct tape_device *device = filp->private_data; | 460 | struct tape_device *device = filp->private_data; |
459 | int rval = -ENOIOCTLCMD; | 461 | int rval = -ENOIOCTLCMD; |
460 | 462 | ||
461 | if (device->discipline->ioctl_fn) { | 463 | if (device->discipline->ioctl_fn) { |
462 | lock_kernel(); | 464 | mutex_lock(&device->mutex); |
463 | rval = device->discipline->ioctl_fn(device, no, data); | 465 | rval = device->discipline->ioctl_fn(device, no, data); |
464 | unlock_kernel(); | 466 | mutex_unlock(&device->mutex); |
465 | if (rval == -EINVAL) | 467 | if (rval == -EINVAL) |
466 | rval = -ENOIOCTLCMD; | 468 | rval = -ENOIOCTLCMD; |
467 | } | 469 | } |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 5cd31e071647..f5d6802dc5da 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -492,6 +492,7 @@ tape_alloc_device(void) | |||
492 | kfree(device); | 492 | kfree(device); |
493 | return ERR_PTR(-ENOMEM); | 493 | return ERR_PTR(-ENOMEM); |
494 | } | 494 | } |
495 | mutex_init(&device->mutex); | ||
495 | INIT_LIST_HEAD(&device->req_queue); | 496 | INIT_LIST_HEAD(&device->req_queue); |
496 | INIT_LIST_HEAD(&device->node); | 497 | INIT_LIST_HEAD(&device->node); |
497 | init_waitqueue_head(&device->state_change_wq); | 498 | init_waitqueue_head(&device->state_change_wq); |
@@ -511,11 +512,12 @@ tape_alloc_device(void) | |||
511 | * increment the reference count. | 512 | * increment the reference count. |
512 | */ | 513 | */ |
513 | struct tape_device * | 514 | struct tape_device * |
514 | tape_get_device_reference(struct tape_device *device) | 515 | tape_get_device(struct tape_device *device) |
515 | { | 516 | { |
516 | DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device, | 517 | int count; |
517 | atomic_inc_return(&device->ref_count)); | ||
518 | 518 | ||
519 | count = atomic_inc_return(&device->ref_count); | ||
520 | DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count); | ||
519 | return device; | 521 | return device; |
520 | } | 522 | } |
521 | 523 | ||
@@ -525,32 +527,25 @@ tape_get_device_reference(struct tape_device *device) | |||
525 | * The function returns a NULL pointer to be used by the caller | 527 | * The function returns a NULL pointer to be used by the caller |
526 | * for clearing reference pointers. | 528 | * for clearing reference pointers. |
527 | */ | 529 | */ |
528 | struct tape_device * | 530 | void |
529 | tape_put_device(struct tape_device *device) | 531 | tape_put_device(struct tape_device *device) |
530 | { | 532 | { |
531 | int remain; | 533 | int count; |
532 | 534 | ||
533 | remain = atomic_dec_return(&device->ref_count); | 535 | count = atomic_dec_return(&device->ref_count); |
534 | if (remain > 0) { | 536 | DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count); |
535 | DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain); | 537 | BUG_ON(count < 0); |
536 | } else { | 538 | if (count == 0) { |
537 | if (remain < 0) { | 539 | kfree(device->modeset_byte); |
538 | DBF_EVENT(4, "put device without reference\n"); | 540 | kfree(device); |
539 | } else { | ||
540 | DBF_EVENT(4, "tape_free_device(%p)\n", device); | ||
541 | kfree(device->modeset_byte); | ||
542 | kfree(device); | ||
543 | } | ||
544 | } | 541 | } |
545 | |||
546 | return NULL; | ||
547 | } | 542 | } |
548 | 543 | ||
549 | /* | 544 | /* |
550 | * Find tape device by a device index. | 545 | * Find tape device by a device index. |
551 | */ | 546 | */ |
552 | struct tape_device * | 547 | struct tape_device * |
553 | tape_get_device(int devindex) | 548 | tape_find_device(int devindex) |
554 | { | 549 | { |
555 | struct tape_device *device, *tmp; | 550 | struct tape_device *device, *tmp; |
556 | 551 | ||
@@ -558,7 +553,7 @@ tape_get_device(int devindex) | |||
558 | read_lock(&tape_device_lock); | 553 | read_lock(&tape_device_lock); |
559 | list_for_each_entry(tmp, &tape_device_list, node) { | 554 | list_for_each_entry(tmp, &tape_device_list, node) { |
560 | if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) { | 555 | if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) { |
561 | device = tape_get_device_reference(tmp); | 556 | device = tape_get_device(tmp); |
562 | break; | 557 | break; |
563 | } | 558 | } |
564 | } | 559 | } |
@@ -579,7 +574,8 @@ tape_generic_probe(struct ccw_device *cdev) | |||
579 | device = tape_alloc_device(); | 574 | device = tape_alloc_device(); |
580 | if (IS_ERR(device)) | 575 | if (IS_ERR(device)) |
581 | return -ENODEV; | 576 | return -ENODEV; |
582 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | 577 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | |
578 | CCWDEV_DO_MULTIPATH); | ||
583 | ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); | 579 | ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); |
584 | if (ret) { | 580 | if (ret) { |
585 | tape_put_device(device); | 581 | tape_put_device(device); |
@@ -606,7 +602,8 @@ __tape_discard_requests(struct tape_device *device) | |||
606 | list_del(&request->list); | 602 | list_del(&request->list); |
607 | 603 | ||
608 | /* Decrease ref_count for removed request. */ | 604 | /* Decrease ref_count for removed request. */ |
609 | request->device = tape_put_device(device); | 605 | request->device = NULL; |
606 | tape_put_device(device); | ||
610 | request->rc = -EIO; | 607 | request->rc = -EIO; |
611 | if (request->callback != NULL) | 608 | if (request->callback != NULL) |
612 | request->callback(request, request->callback_data); | 609 | request->callback(request, request->callback_data); |
@@ -664,9 +661,11 @@ tape_generic_remove(struct ccw_device *cdev) | |||
664 | tape_cleanup_device(device); | 661 | tape_cleanup_device(device); |
665 | } | 662 | } |
666 | 663 | ||
667 | if (!dev_get_drvdata(&cdev->dev)) { | 664 | device = dev_get_drvdata(&cdev->dev); |
665 | if (device) { | ||
668 | sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); | 666 | sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); |
669 | dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev))); | 667 | dev_set_drvdata(&cdev->dev, NULL); |
668 | tape_put_device(device); | ||
670 | } | 669 | } |
671 | } | 670 | } |
672 | 671 | ||
@@ -721,9 +720,8 @@ tape_free_request (struct tape_request * request) | |||
721 | { | 720 | { |
722 | DBF_LH(6, "Free request %p\n", request); | 721 | DBF_LH(6, "Free request %p\n", request); |
723 | 722 | ||
724 | if (request->device != NULL) { | 723 | if (request->device) |
725 | request->device = tape_put_device(request->device); | 724 | tape_put_device(request->device); |
726 | } | ||
727 | kfree(request->cpdata); | 725 | kfree(request->cpdata); |
728 | kfree(request->cpaddr); | 726 | kfree(request->cpaddr); |
729 | kfree(request); | 727 | kfree(request); |
@@ -838,7 +836,8 @@ static void tape_long_busy_timeout(unsigned long data) | |||
838 | BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY); | 836 | BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY); |
839 | DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id); | 837 | DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id); |
840 | __tape_start_next_request(device); | 838 | __tape_start_next_request(device); |
841 | device->lb_timeout.data = (unsigned long) tape_put_device(device); | 839 | device->lb_timeout.data = 0UL; |
840 | tape_put_device(device); | ||
842 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 841 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
843 | } | 842 | } |
844 | 843 | ||
@@ -918,7 +917,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request) | |||
918 | } | 917 | } |
919 | 918 | ||
920 | /* Increase use count of device for the added request. */ | 919 | /* Increase use count of device for the added request. */ |
921 | request->device = tape_get_device_reference(device); | 920 | request->device = tape_get_device(device); |
922 | 921 | ||
923 | if (list_empty(&device->req_queue)) { | 922 | if (list_empty(&device->req_queue)) { |
924 | /* No other requests are on the queue. Start this one. */ | 923 | /* No other requests are on the queue. Start this one. */ |
@@ -1117,8 +1116,8 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1117 | if (req->status == TAPE_REQUEST_LONG_BUSY) { | 1116 | if (req->status == TAPE_REQUEST_LONG_BUSY) { |
1118 | DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id); | 1117 | DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id); |
1119 | if (del_timer(&device->lb_timeout)) { | 1118 | if (del_timer(&device->lb_timeout)) { |
1120 | device->lb_timeout.data = (unsigned long) | 1119 | device->lb_timeout.data = 0UL; |
1121 | tape_put_device(device); | 1120 | tape_put_device(device); |
1122 | __tape_start_next_request(device); | 1121 | __tape_start_next_request(device); |
1123 | } | 1122 | } |
1124 | return; | 1123 | return; |
@@ -1173,7 +1172,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1173 | break; | 1172 | break; |
1174 | case TAPE_IO_LONG_BUSY: | 1173 | case TAPE_IO_LONG_BUSY: |
1175 | device->lb_timeout.data = | 1174 | device->lb_timeout.data = |
1176 | (unsigned long)tape_get_device_reference(device); | 1175 | (unsigned long) tape_get_device(device); |
1177 | device->lb_timeout.expires = jiffies + | 1176 | device->lb_timeout.expires = jiffies + |
1178 | LONG_BUSY_TIMEOUT * HZ; | 1177 | LONG_BUSY_TIMEOUT * HZ; |
1179 | DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id); | 1178 | DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id); |
@@ -1326,7 +1325,7 @@ EXPORT_SYMBOL(tape_generic_online); | |||
1326 | EXPORT_SYMBOL(tape_generic_offline); | 1325 | EXPORT_SYMBOL(tape_generic_offline); |
1327 | EXPORT_SYMBOL(tape_generic_pm_suspend); | 1326 | EXPORT_SYMBOL(tape_generic_pm_suspend); |
1328 | EXPORT_SYMBOL(tape_put_device); | 1327 | EXPORT_SYMBOL(tape_put_device); |
1329 | EXPORT_SYMBOL(tape_get_device_reference); | 1328 | EXPORT_SYMBOL(tape_get_device); |
1330 | EXPORT_SYMBOL(tape_state_verbose); | 1329 | EXPORT_SYMBOL(tape_state_verbose); |
1331 | EXPORT_SYMBOL(tape_op_verbose); | 1330 | EXPORT_SYMBOL(tape_op_verbose); |
1332 | EXPORT_SYMBOL(tape_state_set); | 1331 | EXPORT_SYMBOL(tape_state_set); |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index 202f42132939..ebd820ccfb24 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -45,7 +45,7 @@ static int tape_proc_show(struct seq_file *m, void *v) | |||
45 | seq_printf(m, "TapeNo\tBusID CuType/Model\t" | 45 | seq_printf(m, "TapeNo\tBusID CuType/Model\t" |
46 | "DevType/Model\tBlkSize\tState\tOp\tMedState\n"); | 46 | "DevType/Model\tBlkSize\tState\tOp\tMedState\n"); |
47 | } | 47 | } |
48 | device = tape_get_device(n); | 48 | device = tape_find_device(n); |
49 | if (IS_ERR(device)) | 49 | if (IS_ERR(device)) |
50 | return 0; | 50 | return 0; |
51 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 51 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 38385677c653..911822db614d 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/bootmem.h> | 21 | #include <linux/bootmem.h> |
22 | #include <linux/compat.h> | ||
22 | 23 | ||
23 | #include <asm/ccwdev.h> | 24 | #include <asm/ccwdev.h> |
24 | #include <asm/cio.h> | 25 | #include <asm/cio.h> |
@@ -1731,6 +1732,22 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file, | |||
1731 | return kbd_ioctl(tp->kbd, file, cmd, arg); | 1732 | return kbd_ioctl(tp->kbd, file, cmd, arg); |
1732 | } | 1733 | } |
1733 | 1734 | ||
1735 | #ifdef CONFIG_COMPAT | ||
1736 | static long | ||
1737 | tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, | ||
1738 | unsigned int cmd, unsigned long arg) | ||
1739 | { | ||
1740 | struct tty3270 *tp; | ||
1741 | |||
1742 | tp = tty->driver_data; | ||
1743 | if (!tp) | ||
1744 | return -ENODEV; | ||
1745 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1746 | return -EIO; | ||
1747 | return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg)); | ||
1748 | } | ||
1749 | #endif | ||
1750 | |||
1734 | static const struct tty_operations tty3270_ops = { | 1751 | static const struct tty_operations tty3270_ops = { |
1735 | .open = tty3270_open, | 1752 | .open = tty3270_open, |
1736 | .close = tty3270_close, | 1753 | .close = tty3270_close, |
@@ -1745,6 +1762,9 @@ static const struct tty_operations tty3270_ops = { | |||
1745 | .hangup = tty3270_hangup, | 1762 | .hangup = tty3270_hangup, |
1746 | .wait_until_sent = tty3270_wait_until_sent, | 1763 | .wait_until_sent = tty3270_wait_until_sent, |
1747 | .ioctl = tty3270_ioctl, | 1764 | .ioctl = tty3270_ioctl, |
1765 | #ifdef CONFIG_COMPAT | ||
1766 | .compat_ioctl = tty3270_compat_ioctl, | ||
1767 | #endif | ||
1748 | .set_termios = tty3270_set_termios | 1768 | .set_termios = tty3270_set_termios |
1749 | }; | 1769 | }; |
1750 | 1770 | ||
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index d1a142fa3eb4..899aa795bf38 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -312,11 +312,9 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) | |||
312 | return -ENOSYS; | 312 | return -ENOSYS; |
313 | 313 | ||
314 | /* Besure this device hasn't already been opened */ | 314 | /* Besure this device hasn't already been opened */ |
315 | lock_kernel(); | ||
316 | spin_lock_bh(&logptr->priv_lock); | 315 | spin_lock_bh(&logptr->priv_lock); |
317 | if (logptr->dev_in_use) { | 316 | if (logptr->dev_in_use) { |
318 | spin_unlock_bh(&logptr->priv_lock); | 317 | spin_unlock_bh(&logptr->priv_lock); |
319 | unlock_kernel(); | ||
320 | return -EBUSY; | 318 | return -EBUSY; |
321 | } | 319 | } |
322 | logptr->dev_in_use = 1; | 320 | logptr->dev_in_use = 1; |
@@ -360,9 +358,8 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) | |||
360 | || (logptr->iucv_path_severed)); | 358 | || (logptr->iucv_path_severed)); |
361 | if (logptr->iucv_path_severed) | 359 | if (logptr->iucv_path_severed) |
362 | goto out_record; | 360 | goto out_record; |
363 | ret = nonseekable_open(inode, filp); | 361 | nonseekable_open(inode, filp); |
364 | unlock_kernel(); | 362 | return 0; |
365 | return ret; | ||
366 | 363 | ||
367 | out_record: | 364 | out_record: |
368 | if (logptr->autorecording) | 365 | if (logptr->autorecording) |
@@ -372,7 +369,6 @@ out_path: | |||
372 | logptr->path = NULL; | 369 | logptr->path = NULL; |
373 | out_dev: | 370 | out_dev: |
374 | logptr->dev_in_use = 0; | 371 | logptr->dev_in_use = 0; |
375 | unlock_kernel(); | ||
376 | return -EIO; | 372 | return -EIO; |
377 | } | 373 | } |
378 | 374 | ||
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 77571b68539a..cc56fc708bae 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c | |||
@@ -695,7 +695,6 @@ static int ur_open(struct inode *inode, struct file *file) | |||
695 | 695 | ||
696 | if (accmode == O_RDWR) | 696 | if (accmode == O_RDWR) |
697 | return -EACCES; | 697 | return -EACCES; |
698 | lock_kernel(); | ||
699 | /* | 698 | /* |
700 | * We treat the minor number as the devno of the ur device | 699 | * We treat the minor number as the devno of the ur device |
701 | * to find in the driver tree. | 700 | * to find in the driver tree. |
@@ -749,7 +748,6 @@ static int ur_open(struct inode *inode, struct file *file) | |||
749 | goto fail_urfile_free; | 748 | goto fail_urfile_free; |
750 | urf->file_reclen = rc; | 749 | urf->file_reclen = rc; |
751 | file->private_data = urf; | 750 | file->private_data = urf; |
752 | unlock_kernel(); | ||
753 | return 0; | 751 | return 0; |
754 | 752 | ||
755 | fail_urfile_free: | 753 | fail_urfile_free: |
@@ -761,7 +759,6 @@ fail_unlock: | |||
761 | fail_put: | 759 | fail_put: |
762 | urdev_put(urd); | 760 | urdev_put(urd); |
763 | out: | 761 | out: |
764 | unlock_kernel(); | ||
765 | return rc; | 762 | return rc; |
766 | } | 763 | } |
767 | 764 | ||
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index f2bc287b69e4..c974058e48d2 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/suspend.h> | 20 | #include <linux/suspend.h> |
21 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
22 | #include <linux/smp_lock.h> | ||
23 | 22 | ||
24 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
25 | #include <asm/io.h> | 24 | #include <asm/io.h> |
@@ -49,6 +48,8 @@ static unsigned int vmwdt_interval = 60; | |||
49 | static unsigned long vmwdt_is_open; | 48 | static unsigned long vmwdt_is_open; |
50 | static int vmwdt_expect_close; | 49 | static int vmwdt_expect_close; |
51 | 50 | ||
51 | static DEFINE_MUTEX(vmwdt_mutex); | ||
52 | |||
52 | #define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ | 53 | #define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ |
53 | #define VMWDT_RUNNING 1 /* The watchdog is armed */ | 54 | #define VMWDT_RUNNING 1 /* The watchdog is armed */ |
54 | 55 | ||
@@ -133,15 +134,11 @@ static int __init vmwdt_probe(void) | |||
133 | static int vmwdt_open(struct inode *i, struct file *f) | 134 | static int vmwdt_open(struct inode *i, struct file *f) |
134 | { | 135 | { |
135 | int ret; | 136 | int ret; |
136 | lock_kernel(); | 137 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) |
137 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { | ||
138 | unlock_kernel(); | ||
139 | return -EBUSY; | 138 | return -EBUSY; |
140 | } | ||
141 | ret = vmwdt_keepalive(); | 139 | ret = vmwdt_keepalive(); |
142 | if (ret) | 140 | if (ret) |
143 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | 141 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); |
144 | unlock_kernel(); | ||
145 | return ret ? ret : nonseekable_open(i, f); | 142 | return ret ? ret : nonseekable_open(i, f); |
146 | } | 143 | } |
147 | 144 | ||
@@ -160,8 +157,7 @@ static struct watchdog_info vmwdt_info = { | |||
160 | .identity = "z/VM Watchdog Timer", | 157 | .identity = "z/VM Watchdog Timer", |
161 | }; | 158 | }; |
162 | 159 | ||
163 | static int vmwdt_ioctl(struct inode *i, struct file *f, | 160 | static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg) |
164 | unsigned int cmd, unsigned long arg) | ||
165 | { | 161 | { |
166 | switch (cmd) { | 162 | switch (cmd) { |
167 | case WDIOC_GETSUPPORT: | 163 | case WDIOC_GETSUPPORT: |
@@ -205,10 +201,19 @@ static int vmwdt_ioctl(struct inode *i, struct file *f, | |||
205 | case WDIOC_KEEPALIVE: | 201 | case WDIOC_KEEPALIVE: |
206 | return vmwdt_keepalive(); | 202 | return vmwdt_keepalive(); |
207 | } | 203 | } |
208 | |||
209 | return -EINVAL; | 204 | return -EINVAL; |
210 | } | 205 | } |
211 | 206 | ||
207 | static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
208 | { | ||
209 | int rc; | ||
210 | |||
211 | mutex_lock(&vmwdt_mutex); | ||
212 | rc = __vmwdt_ioctl(cmd, arg); | ||
213 | mutex_unlock(&vmwdt_mutex); | ||
214 | return (long) rc; | ||
215 | } | ||
216 | |||
212 | static ssize_t vmwdt_write(struct file *f, const char __user *buf, | 217 | static ssize_t vmwdt_write(struct file *f, const char __user *buf, |
213 | size_t count, loff_t *ppos) | 218 | size_t count, loff_t *ppos) |
214 | { | 219 | { |
@@ -288,7 +293,7 @@ static struct notifier_block vmwdt_power_notifier = { | |||
288 | static const struct file_operations vmwdt_fops = { | 293 | static const struct file_operations vmwdt_fops = { |
289 | .open = &vmwdt_open, | 294 | .open = &vmwdt_open, |
290 | .release = &vmwdt_close, | 295 | .release = &vmwdt_close, |
291 | .ioctl = &vmwdt_ioctl, | 296 | .unlocked_ioctl = &vmwdt_ioctl, |
292 | .write = &vmwdt_write, | 297 | .write = &vmwdt_write, |
293 | .owner = THIS_MODULE, | 298 | .owner = THIS_MODULE, |
294 | }; | 299 | }; |
@@ -309,6 +314,10 @@ static int __init vmwdt_init(void) | |||
309 | ret = register_pm_notifier(&vmwdt_power_notifier); | 314 | ret = register_pm_notifier(&vmwdt_power_notifier); |
310 | if (ret) | 315 | if (ret) |
311 | return ret; | 316 | return ret; |
317 | /* | ||
318 | * misc_register() has to be the last action in module_init(), because | ||
319 | * file operations will be available right after this. | ||
320 | */ | ||
312 | ret = misc_register(&vmwdt_dev); | 321 | ret = misc_register(&vmwdt_dev); |
313 | if (ret) { | 322 | if (ret) { |
314 | unregister_pm_notifier(&vmwdt_power_notifier); | 323 | unregister_pm_notifier(&vmwdt_power_notifier); |