aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/paride/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/paride/pf.c')
-rw-r--r--drivers/block/paride/pf.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index c059aab3006b..4457b494882a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -152,6 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
152#include <linux/spinlock.h> 152#include <linux/spinlock.h>
153#include <linux/blkdev.h> 153#include <linux/blkdev.h>
154#include <linux/blkpg.h> 154#include <linux/blkpg.h>
155#include <linux/smp_lock.h>
155#include <asm/uaccess.h> 156#include <asm/uaccess.h>
156 157
157static DEFINE_SPINLOCK(pf_spin_lock); 158static DEFINE_SPINLOCK(pf_spin_lock);
@@ -266,7 +267,7 @@ static const struct block_device_operations pf_fops = {
266 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
267 .open = pf_open, 268 .open = pf_open,
268 .release = pf_release, 269 .release = pf_release,
269 .locked_ioctl = pf_ioctl, 270 .ioctl = pf_ioctl,
270 .getgeo = pf_getgeo, 271 .getgeo = pf_getgeo,
271 .media_changed = pf_check_media, 272 .media_changed = pf_check_media,
272}; 273};
@@ -299,20 +300,26 @@ static void __init pf_init_units(void)
299static int pf_open(struct block_device *bdev, fmode_t mode) 300static int pf_open(struct block_device *bdev, fmode_t mode)
300{ 301{
301 struct pf_unit *pf = bdev->bd_disk->private_data; 302 struct pf_unit *pf = bdev->bd_disk->private_data;
303 int ret;
302 304
305 lock_kernel();
303 pf_identify(pf); 306 pf_identify(pf);
304 307
308 ret = -ENODEV;
305 if (pf->media_status == PF_NM) 309 if (pf->media_status == PF_NM)
306 return -ENODEV; 310 goto out;
307 311
312 ret = -EROFS;
308 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) 313 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE))
309 return -EROFS; 314 goto out;
310 315
316 ret = 0;
311 pf->access++; 317 pf->access++;
312 if (pf->removable) 318 if (pf->removable)
313 pf_lock(pf, 1); 319 pf_lock(pf, 1);
314 320out:
315 return 0; 321 unlock_kernel();
322 return ret;
316} 323}
317 324
318static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) 325static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -342,7 +349,10 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
342 349
343 if (pf->access != 1) 350 if (pf->access != 1)
344 return -EBUSY; 351 return -EBUSY;
352 lock_kernel();
345 pf_eject(pf); 353 pf_eject(pf);
354 unlock_kernel();
355
346 return 0; 356 return 0;
347} 357}
348 358
@@ -350,14 +360,18 @@ static int pf_release(struct gendisk *disk, fmode_t mode)
350{ 360{
351 struct pf_unit *pf = disk->private_data; 361 struct pf_unit *pf = disk->private_data;
352 362
353 if (pf->access <= 0) 363 lock_kernel();
364 if (pf->access <= 0) {
365 unlock_kernel();
354 return -EINVAL; 366 return -EINVAL;
367 }
355 368
356 pf->access--; 369 pf->access--;
357 370
358 if (!pf->access && pf->removable) 371 if (!pf->access && pf->removable)
359 pf_lock(pf, 0); 372 pf_lock(pf, 0);
360 373
374 unlock_kernel();
361 return 0; 375 return 0;
362 376
363} 377}