Merge branch 'for-linus' of git://git.alsa-project.org/alsa-kernel
[pandora-kernel.git] / drivers / s390 / char / vmur.c
index 7689b50..49cba9e 100644 (file)
@@ -100,7 +100,8 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev)
        urd->reclen = cdev->id.driver_info;
        ccw_device_get_id(cdev, &urd->dev_id);
        mutex_init(&urd->io_mutex);
-       mutex_init(&urd->open_mutex);
+       init_waitqueue_head(&urd->wait);
+       spin_lock_init(&urd->open_lock);
        atomic_set(&urd->ref_count,  1);
        urd->cdev = cdev;
        get_device(&cdev->dev);
@@ -276,7 +277,8 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
        struct urdev *urd;
 
        TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
-             intparm, irb->scsw.cstat, irb->scsw.dstat, irb->scsw.count);
+             intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
+             irb->scsw.cmd.count);
 
        if (!intparm) {
                TRACE("ur_int_handler: unsolicited interrupt\n");
@@ -287,7 +289,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
        /* On special conditions irb is an error pointer */
        if (IS_ERR(irb))
                urd->io_request_rc = PTR_ERR(irb);
-       else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+       else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
                urd->io_request_rc = 0;
        else
                urd->io_request_rc = -EIO;
@@ -678,17 +680,21 @@ static int ur_open(struct inode *inode, struct file *file)
        if (!urd)
                return -ENXIO;
 
-       if (file->f_flags & O_NONBLOCK) {
-               if (!mutex_trylock(&urd->open_mutex)) {
+       spin_lock(&urd->open_lock);
+       while (urd->open_flag) {
+               spin_unlock(&urd->open_lock);
+               if (file->f_flags & O_NONBLOCK) {
                        rc = -EBUSY;
                        goto fail_put;
                }
-       } else {
-               if (mutex_lock_interruptible(&urd->open_mutex)) {
+               if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) {
                        rc = -ERESTARTSYS;
                        goto fail_put;
                }
+               spin_lock(&urd->open_lock);
        }
+       urd->open_flag++;
+       spin_unlock(&urd->open_lock);
 
        TRACE("ur_open\n");
 
@@ -720,7 +726,9 @@ static int ur_open(struct inode *inode, struct file *file)
 fail_urfile_free:
        urfile_free(urf);
 fail_unlock:
-       mutex_unlock(&urd->open_mutex);
+       spin_lock(&urd->open_lock);
+       urd->open_flag--;
+       spin_unlock(&urd->open_lock);
 fail_put:
        urdev_put(urd);
        return rc;
@@ -731,7 +739,10 @@ static int ur_release(struct inode *inode, struct file *file)
        struct urfile *urf = file->private_data;
 
        TRACE("ur_release\n");
-       mutex_unlock(&urf->urd->open_mutex);
+       spin_lock(&urf->urd->open_lock);
+       urf->urd->open_flag--;
+       spin_unlock(&urf->urd->open_lock);
+       wake_up_interruptible(&urf->urd->wait);
        urdev_put(urf->urd);
        urfile_free(urf);
        return 0;