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 | 12 | ||||
-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_async.c | 5 | ||||
-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 |
18 files changed, 140 insertions, 112 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 = { /* * 3215 console initialization code called from console_init(). - * NOTE: This is called before kmalloc is available. */ static int __init con3215_init(void) { 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 = { /* * 3270 console initialization code called from console_init(). - * NOTE: This is called before kmalloc is available. */ static int __init con3270_init(void) diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 097d3846a828..28e4649fa9e4 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -38,6 +38,8 @@ struct fs3270 { size_t rdbuf_size; /* size of data returned by RDBUF */ }; +static DEFINE_MUTEX(fs3270_mutex); + static void fs3270_wake_up(struct raw3270_request *rq, void *data) { @@ -74,7 +76,7 @@ fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq) } rc = raw3270_start(view, rq); if (rc == 0) { - /* Started sucessfully. Now wait for completion. */ + /* Started successfully. Now wait for completion. */ wait_event(fp->wait, raw3270_request_final(rq)); } } while (rc == -EACCES); @@ -328,7 +330,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!fp) return -ENODEV; rc = 0; - lock_kernel(); + mutex_lock(&fs3270_mutex); switch (cmd) { case TUBICMD: fp->read_command = arg; @@ -354,7 +356,7 @@ fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) rc = -EFAULT; break; } - unlock_kernel(); + mutex_unlock(&fs3270_mutex); return rc; } @@ -437,7 +439,7 @@ fs3270_open(struct inode *inode, struct file *filp) minor = tty->index + RAW3270_FIRSTMINOR; tty_kref_put(tty); } - lock_kernel(); + mutex_lock(&fs3270_mutex); /* Check if some other program is already using fullscreen mode. */ fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); if (!IS_ERR(fp)) { @@ -478,7 +480,7 @@ fs3270_open(struct inode *inode, struct file *filp) } filp->private_data = fp; out: - unlock_kernel(); + mutex_unlock(&fs3270_mutex); return rc; } 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 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/kernel.h> @@ -283,7 +282,6 @@ static int mon_open(struct inode *inode, struct file *filp) /* * only one user allowed */ - lock_kernel(); rc = -EBUSY; if (test_and_set_bit(MON_IN_USE, &mon_in_use)) goto out; @@ -321,7 +319,6 @@ static int mon_open(struct inode *inode, struct file *filp) } filp->private_data = monpriv; dev_set_drvdata(monreader_device, monpriv); - unlock_kernel(); return nonseekable_open(inode, filp); out_path: @@ -331,7 +328,6 @@ out_priv: out_use: clear_bit(MON_IN_USE, &mon_in_use); out: - unlock_kernel(); return rc; } @@ -607,6 +603,10 @@ static int __init mon_init(void) } dcss_mkname(mon_dcss_name, &user_data_connect[8]); + /* + * misc_register() has to be the last action in module_init(), because + * file operations will be available right after this. + */ rc = misc_register(&mon_dev); if (rc < 0 ) 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 @@ #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/errno.h> -#include <linux/smp_lock.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/miscdevice.h> @@ -185,13 +184,11 @@ static int monwrite_open(struct inode *inode, struct file *filp) monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); if (!monpriv) return -ENOMEM; - lock_kernel(); INIT_LIST_HEAD(&monpriv->list); monpriv->hdr_to_read = sizeof(monpriv->hdr); mutex_init(&monpriv->thread_mutex); filp->private_data = monpriv; list_add_tail(&monpriv->priv_list, &mon_priv_list); - unlock_kernel(); return nonseekable_open(inode, filp); } @@ -364,6 +361,10 @@ static int __init mon_init(void) goto out_driver; } + /* + * misc_register() has to be the last action in module_init(), because + * file operations will be available right after this. + */ rc = misc_register(&mon_dev); if (rc) goto out_device; diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index b44462a6c6d3..740fe405c395 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c @@ -101,18 +101,17 @@ static struct ctl_table callhome_table[] = { .mode = 0644, .proc_handler = proc_handler_callhome, }, - { .ctl_name = 0 } + {} }; static struct ctl_table kern_dir_table[] = { { - .ctl_name = CTL_KERN, .procname = "kernel", .maxlen = 0, .mode = 0555, .child = callhome_table, }, - { .ctl_name = 0 } + {} }; /* 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) do { memset(sccb, 0, sizeof(*sccb)); sccb->header.length = sizeof(*sccb); + sccb->header.function_code = 0x80; sccb->header.control_mask[2] = 0x80; rc = sclp_cmd_sync_early(commands[i], sccb); } 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 { struct tape_class_device * nt; struct tape_class_device * rt; + /* Device mutex to serialize tape commands. */ + struct mutex mutex; + /* Device discipline information. */ struct tape_discipline * discipline; void * discdata; @@ -292,9 +295,9 @@ extern int tape_generic_pm_suspend(struct ccw_device *); extern int tape_generic_probe(struct ccw_device *); extern void tape_generic_remove(struct ccw_device *); -extern struct tape_device *tape_get_device(int devindex); -extern struct tape_device *tape_get_device_reference(struct tape_device *); -extern struct tape_device *tape_put_device(struct tape_device *); +extern struct tape_device *tape_find_device(int devindex); +extern struct tape_device *tape_get_device(struct tape_device *); +extern void tape_put_device(struct tape_device *); /* Externals from tape_char.c */ 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) { struct tape_34xx_work *p = container_of(work, struct tape_34xx_work, work); + struct tape_device *device = p->device; switch(p->op) { case TO_MSEN: - tape_34xx_medium_sense(p->device); + tape_34xx_medium_sense(device); break; default: DBF_EVENT(3, "T34XX: internal error: unknown work\n"); } - - p->device = tape_put_device(p->device); + tape_put_device(device); kfree(p); } @@ -136,7 +136,7 @@ tape_34xx_schedule_work(struct tape_device *device, enum tape_op op) INIT_WORK(&p->work, tape_34xx_work_handler); - p->device = tape_get_device_reference(device); + p->device = tape_get_device(device); p->op = op; 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) INIT_WORK(&p->work, tape_3590_work_handler); - p->device = tape_get_device_reference(device); + p->device = tape_get_device(device); p->op = op; 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 = { .owner = THIS_MODULE, .open = tapeblock_open, .release = tapeblock_release, - .locked_ioctl = tapeblock_ioctl, + .ioctl = tapeblock_ioctl, .media_changed = tapeblock_medium_changed, .revalidate_disk = tapeblock_revalidate_disk, }; @@ -239,7 +239,7 @@ tapeblock_setup_device(struct tape_device * device) disk->major = tapeblock_major; disk->first_minor = device->first_minor; disk->fops = &tapeblock_fops; - disk->private_data = tape_get_device_reference(device); + disk->private_data = tape_get_device(device); disk->queue = blkdat->request_queue; set_capacity(disk, 0); sprintf(disk->disk_name, "btibm%d", @@ -247,11 +247,11 @@ tapeblock_setup_device(struct tape_device * device) blkdat->disk = disk; blkdat->medium_changed = 1; - blkdat->request_queue->queuedata = tape_get_device_reference(device); + blkdat->request_queue->queuedata = tape_get_device(device); add_disk(disk); - tape_get_device_reference(device); + tape_get_device(device); INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); return 0; @@ -274,13 +274,14 @@ tapeblock_cleanup_device(struct tape_device *device) } del_gendisk(device->blk_data.disk); - device->blk_data.disk->private_data = - tape_put_device(device->blk_data.disk->private_data); + device->blk_data.disk->private_data = NULL; + tape_put_device(device); put_disk(device->blk_data.disk); device->blk_data.disk = NULL; cleanup_queue: - device->blk_data.request_queue->queuedata = tape_put_device(device); + device->blk_data.request_queue->queuedata = NULL; + tape_put_device(device); blk_cleanup_queue(device->blk_data.request_queue); device->blk_data.request_queue = NULL; @@ -363,7 +364,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode) struct tape_device * device; int rc; - device = tape_get_device_reference(disk->private_data); + device = tape_get_device(disk->private_data); if (device->required_tapemarks) { 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 *); static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); -static int tapechar_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long tapechar_ioctl(struct file *, unsigned int, unsigned long); static long tapechar_compat_ioctl(struct file *, unsigned int, unsigned long); @@ -43,7 +42,7 @@ static const struct file_operations tape_fops = .owner = THIS_MODULE, .read = tapechar_read, .write = tapechar_write, - .ioctl = tapechar_ioctl, + .unlocked_ioctl = tapechar_ioctl, .compat_ioctl = tapechar_compat_ioctl, .open = tapechar_open, .release = tapechar_release, @@ -170,7 +169,6 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) if (rc == 0) { rc = block_size - request->rescnt; DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); - filp->f_pos += rc; /* Copy data from idal buffer to user space. */ if (idal_buffer_to_user(device->char_data.idal_buf, data, rc) != 0) @@ -238,7 +236,6 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t break; DBF_EVENT(6, "TCHAR:wbytes: %lx\n", block_size - request->rescnt); - filp->f_pos += block_size - request->rescnt; written += block_size - request->rescnt; if (request->rescnt != 0) break; @@ -286,26 +283,20 @@ tapechar_open (struct inode *inode, struct file *filp) if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) return -ENODEV; - lock_kernel(); minor = iminor(filp->f_path.dentry->d_inode); - device = tape_get_device(minor / TAPE_MINORS_PER_DEV); + device = tape_find_device(minor / TAPE_MINORS_PER_DEV); if (IS_ERR(device)) { - DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n"); - rc = PTR_ERR(device); - goto out; + DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n"); + return PTR_ERR(device); } - rc = tape_open(device); if (rc == 0) { filp->private_data = device; - rc = nonseekable_open(inode, filp); - } - else + nonseekable_open(inode, filp); + } else tape_put_device(device); -out: - unlock_kernel(); return rc; } @@ -342,7 +333,8 @@ tapechar_release(struct inode *inode, struct file *filp) device->char_data.idal_buf = NULL; } tape_release(device); - filp->private_data = tape_put_device(device); + filp->private_data = NULL; + tape_put_device(device); return 0; } @@ -351,16 +343,11 @@ tapechar_release(struct inode *inode, struct file *filp) * Tape device io controls. */ static int -tapechar_ioctl(struct inode *inp, struct file *filp, - unsigned int no, unsigned long data) +__tapechar_ioctl(struct tape_device *device, + unsigned int no, unsigned long data) { - struct tape_device *device; int rc; - DBF_EVENT(6, "TCHAR:ioct\n"); - - device = (struct tape_device *) filp->private_data; - if (no == MTIOCTOP) { struct mtop op; @@ -453,15 +440,30 @@ tapechar_ioctl(struct inode *inp, struct file *filp, } static long +tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) +{ + struct tape_device *device; + long rc; + + DBF_EVENT(6, "TCHAR:ioct\n"); + + device = (struct tape_device *) filp->private_data; + mutex_lock(&device->mutex); + rc = __tapechar_ioctl(device, no, data); + mutex_unlock(&device->mutex); + return rc; +} + +static long tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) { struct tape_device *device = filp->private_data; int rval = -ENOIOCTLCMD; if (device->discipline->ioctl_fn) { - lock_kernel(); + mutex_lock(&device->mutex); rval = device->discipline->ioctl_fn(device, no, data); - unlock_kernel(); + mutex_unlock(&device->mutex); if (rval == -EINVAL) rval = -ENOIOCTLCMD; } 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) kfree(device); return ERR_PTR(-ENOMEM); } + mutex_init(&device->mutex); INIT_LIST_HEAD(&device->req_queue); INIT_LIST_HEAD(&device->node); init_waitqueue_head(&device->state_change_wq); @@ -511,11 +512,12 @@ tape_alloc_device(void) * increment the reference count. */ struct tape_device * -tape_get_device_reference(struct tape_device *device) +tape_get_device(struct tape_device *device) { - DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device, - atomic_inc_return(&device->ref_count)); + int count; + count = atomic_inc_return(&device->ref_count); + DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count); return device; } @@ -525,32 +527,25 @@ tape_get_device_reference(struct tape_device *device) * The function returns a NULL pointer to be used by the caller * for clearing reference pointers. */ -struct tape_device * +void tape_put_device(struct tape_device *device) { - int remain; + int count; - remain = atomic_dec_return(&device->ref_count); - if (remain > 0) { - DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain); - } else { - if (remain < 0) { - DBF_EVENT(4, "put device without reference\n"); - } else { - DBF_EVENT(4, "tape_free_device(%p)\n", device); - kfree(device->modeset_byte); - kfree(device); - } + count = atomic_dec_return(&device->ref_count); + DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count); + BUG_ON(count < 0); + if (count == 0) { + kfree(device->modeset_byte); + kfree(device); } - - return NULL; } /* * Find tape device by a device index. */ struct tape_device * -tape_get_device(int devindex) +tape_find_device(int devindex) { struct tape_device *device, *tmp; @@ -558,7 +553,7 @@ tape_get_device(int devindex) read_lock(&tape_device_lock); list_for_each_entry(tmp, &tape_device_list, node) { if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) { - device = tape_get_device_reference(tmp); + device = tape_get_device(tmp); break; } } @@ -579,7 +574,8 @@ tape_generic_probe(struct ccw_device *cdev) device = tape_alloc_device(); if (IS_ERR(device)) return -ENODEV; - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | + CCWDEV_DO_MULTIPATH); ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); if (ret) { tape_put_device(device); @@ -606,7 +602,8 @@ __tape_discard_requests(struct tape_device *device) list_del(&request->list); /* Decrease ref_count for removed request. */ - request->device = tape_put_device(device); + request->device = NULL; + tape_put_device(device); request->rc = -EIO; if (request->callback != NULL) request->callback(request, request->callback_data); @@ -664,9 +661,11 @@ tape_generic_remove(struct ccw_device *cdev) tape_cleanup_device(device); } - if (!dev_get_drvdata(&cdev->dev)) { + device = dev_get_drvdata(&cdev->dev); + if (device) { sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); - dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev))); + dev_set_drvdata(&cdev->dev, NULL); + tape_put_device(device); } } @@ -721,9 +720,8 @@ tape_free_request (struct tape_request * request) { DBF_LH(6, "Free request %p\n", request); - if (request->device != NULL) { - request->device = tape_put_device(request->device); - } + if (request->device) + tape_put_device(request->device); kfree(request->cpdata); kfree(request->cpaddr); kfree(request); @@ -838,7 +836,8 @@ static void tape_long_busy_timeout(unsigned long data) BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY); DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id); __tape_start_next_request(device); - device->lb_timeout.data = (unsigned long) tape_put_device(device); + device->lb_timeout.data = 0UL; + tape_put_device(device); spin_unlock_irq(get_ccwdev_lock(device->cdev)); } @@ -918,7 +917,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request) } /* Increase use count of device for the added request. */ - request->device = tape_get_device_reference(device); + request->device = tape_get_device(device); if (list_empty(&device->req_queue)) { /* 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) if (req->status == TAPE_REQUEST_LONG_BUSY) { DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id); if (del_timer(&device->lb_timeout)) { - device->lb_timeout.data = (unsigned long) - tape_put_device(device); + device->lb_timeout.data = 0UL; + tape_put_device(device); __tape_start_next_request(device); } return; @@ -1173,7 +1172,7 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb) break; case TAPE_IO_LONG_BUSY: device->lb_timeout.data = - (unsigned long)tape_get_device_reference(device); + (unsigned long) tape_get_device(device); device->lb_timeout.expires = jiffies + LONG_BUSY_TIMEOUT * HZ; DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id); @@ -1326,7 +1325,7 @@ EXPORT_SYMBOL(tape_generic_online); EXPORT_SYMBOL(tape_generic_offline); EXPORT_SYMBOL(tape_generic_pm_suspend); EXPORT_SYMBOL(tape_put_device); -EXPORT_SYMBOL(tape_get_device_reference); +EXPORT_SYMBOL(tape_get_device); EXPORT_SYMBOL(tape_state_verbose); EXPORT_SYMBOL(tape_op_verbose); 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) seq_printf(m, "TapeNo\tBusID CuType/Model\t" "DevType/Model\tBlkSize\tState\tOp\tMedState\n"); } - device = tape_get_device(n); + device = tape_find_device(n); if (IS_ERR(device)) return 0; 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 @@ #include <linux/slab.h> #include <linux/bootmem.h> +#include <linux/compat.h> #include <asm/ccwdev.h> #include <asm/cio.h> @@ -1731,6 +1732,22 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file, return kbd_ioctl(tp->kbd, file, cmd, arg); } +#ifdef CONFIG_COMPAT +static long +tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct tty3270 *tp; + + tp = tty->driver_data; + if (!tp) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif + static const struct tty_operations tty3270_ops = { .open = tty3270_open, .close = tty3270_close, @@ -1745,6 +1762,9 @@ static const struct tty_operations tty3270_ops = { .hangup = tty3270_hangup, .wait_until_sent = tty3270_wait_until_sent, .ioctl = tty3270_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tty3270_compat_ioctl, +#endif .set_termios = tty3270_set_termios }; 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) return -ENOSYS; /* Besure this device hasn't already been opened */ - lock_kernel(); spin_lock_bh(&logptr->priv_lock); if (logptr->dev_in_use) { spin_unlock_bh(&logptr->priv_lock); - unlock_kernel(); return -EBUSY; } logptr->dev_in_use = 1; @@ -360,9 +358,8 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp) || (logptr->iucv_path_severed)); if (logptr->iucv_path_severed) goto out_record; - ret = nonseekable_open(inode, filp); - unlock_kernel(); - return ret; + nonseekable_open(inode, filp); + return 0; out_record: if (logptr->autorecording) @@ -372,7 +369,6 @@ out_path: logptr->path = NULL; out_dev: logptr->dev_in_use = 0; - unlock_kernel(); return -EIO; } 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) if (accmode == O_RDWR) return -EACCES; - lock_kernel(); /* * We treat the minor number as the devno of the ur device * to find in the driver tree. @@ -749,7 +748,6 @@ static int ur_open(struct inode *inode, struct file *file) goto fail_urfile_free; urf->file_reclen = rc; file->private_data = urf; - unlock_kernel(); return 0; fail_urfile_free: @@ -761,7 +759,6 @@ fail_unlock: fail_put: urdev_put(urd); out: - unlock_kernel(); return rc; } 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 @@ #include <linux/moduleparam.h> #include <linux/suspend.h> #include <linux/watchdog.h> -#include <linux/smp_lock.h> #include <asm/ebcdic.h> #include <asm/io.h> @@ -49,6 +48,8 @@ static unsigned int vmwdt_interval = 60; static unsigned long vmwdt_is_open; static int vmwdt_expect_close; +static DEFINE_MUTEX(vmwdt_mutex); + #define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ #define VMWDT_RUNNING 1 /* The watchdog is armed */ @@ -133,15 +134,11 @@ static int __init vmwdt_probe(void) static int vmwdt_open(struct inode *i, struct file *f) { int ret; - lock_kernel(); - if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { - unlock_kernel(); + if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) return -EBUSY; - } ret = vmwdt_keepalive(); if (ret) clear_bit(VMWDT_OPEN, &vmwdt_is_open); - unlock_kernel(); return ret ? ret : nonseekable_open(i, f); } @@ -160,8 +157,7 @@ static struct watchdog_info vmwdt_info = { .identity = "z/VM Watchdog Timer", }; -static int vmwdt_ioctl(struct inode *i, struct file *f, - unsigned int cmd, unsigned long arg) +static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg) { switch (cmd) { case WDIOC_GETSUPPORT: @@ -205,10 +201,19 @@ static int vmwdt_ioctl(struct inode *i, struct file *f, case WDIOC_KEEPALIVE: return vmwdt_keepalive(); } - return -EINVAL; } +static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + int rc; + + mutex_lock(&vmwdt_mutex); + rc = __vmwdt_ioctl(cmd, arg); + mutex_unlock(&vmwdt_mutex); + return (long) rc; +} + static ssize_t vmwdt_write(struct file *f, const char __user *buf, size_t count, loff_t *ppos) { @@ -288,7 +293,7 @@ static struct notifier_block vmwdt_power_notifier = { static const struct file_operations vmwdt_fops = { .open = &vmwdt_open, .release = &vmwdt_close, - .ioctl = &vmwdt_ioctl, + .unlocked_ioctl = &vmwdt_ioctl, .write = &vmwdt_write, .owner = THIS_MODULE, }; @@ -309,6 +314,10 @@ static int __init vmwdt_init(void) ret = register_pm_notifier(&vmwdt_power_notifier); if (ret) return ret; + /* + * misc_register() has to be the last action in module_init(), because + * file operations will be available right after this. + */ ret = misc_register(&vmwdt_dev); if (ret) { unregister_pm_notifier(&vmwdt_power_notifier); |