aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3325660f7248..c7671e188017 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -313,6 +313,7 @@
313#include <linux/cdrom.h> 313#include <linux/cdrom.h>
314#include <linux/ide.h> 314#include <linux/ide.h>
315#include <linux/completion.h> 315#include <linux/completion.h>
316#include <linux/mutex.h>
316 317
317#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */ 318#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
318 319
@@ -324,7 +325,7 @@
324 325
325#include "ide-cd.h" 326#include "ide-cd.h"
326 327
327static DECLARE_MUTEX(idecd_ref_sem); 328static DEFINE_MUTEX(idecd_ref_mutex);
328 329
329#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) 330#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
330 331
@@ -335,11 +336,11 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
335{ 336{
336 struct cdrom_info *cd = NULL; 337 struct cdrom_info *cd = NULL;
337 338
338 down(&idecd_ref_sem); 339 mutex_lock(&idecd_ref_mutex);
339 cd = ide_cd_g(disk); 340 cd = ide_cd_g(disk);
340 if (cd) 341 if (cd)
341 kref_get(&cd->kref); 342 kref_get(&cd->kref);
342 up(&idecd_ref_sem); 343 mutex_unlock(&idecd_ref_mutex);
343 return cd; 344 return cd;
344} 345}
345 346
@@ -347,9 +348,9 @@ static void ide_cd_release(struct kref *);
347 348
348static void ide_cd_put(struct cdrom_info *cd) 349static void ide_cd_put(struct cdrom_info *cd)
349{ 350{
350 down(&idecd_ref_sem); 351 mutex_lock(&idecd_ref_mutex);
351 kref_put(&cd->kref, ide_cd_release); 352 kref_put(&cd->kref, ide_cd_release);
352 up(&idecd_ref_sem); 353 mutex_unlock(&idecd_ref_mutex);
353} 354}
354 355
355/**************************************************************************** 356/****************************************************************************
@@ -2471,52 +2472,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2471} 2472}
2472 2473
2473static 2474static
2474int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
2475 unsigned int cmd, unsigned long arg)
2476{
2477 struct packet_command cgc;
2478 char buffer[16];
2479 int stat;
2480
2481 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
2482
2483 /* These will be moved into the Uniform layer shortly... */
2484 switch (cmd) {
2485 case CDROMSETSPINDOWN: {
2486 char spindown;
2487
2488 if (copy_from_user(&spindown, (void __user *) arg, sizeof(char)))
2489 return -EFAULT;
2490
2491 if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
2492 return stat;
2493
2494 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
2495
2496 return cdrom_mode_select(cdi, &cgc);
2497 }
2498
2499 case CDROMGETSPINDOWN: {
2500 char spindown;
2501
2502 if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
2503 return stat;
2504
2505 spindown = buffer[11] & 0x0f;
2506
2507 if (copy_to_user((void __user *) arg, &spindown, sizeof (char)))
2508 return -EFAULT;
2509
2510 return 0;
2511 }
2512
2513 default:
2514 return -EINVAL;
2515 }
2516
2517}
2518
2519static
2520int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, 2475int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
2521 unsigned int cmd, void *arg) 2476 unsigned int cmd, void *arg)
2522 2477
@@ -2852,12 +2807,11 @@ static struct cdrom_device_ops ide_cdrom_dops = {
2852 .get_mcn = ide_cdrom_get_mcn, 2807 .get_mcn = ide_cdrom_get_mcn,
2853 .reset = ide_cdrom_reset, 2808 .reset = ide_cdrom_reset,
2854 .audio_ioctl = ide_cdrom_audio_ioctl, 2809 .audio_ioctl = ide_cdrom_audio_ioctl,
2855 .dev_ioctl = ide_cdrom_dev_ioctl,
2856 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | 2810 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
2857 CDC_SELECT_SPEED | CDC_SELECT_DISC | 2811 CDC_SELECT_SPEED | CDC_SELECT_DISC |
2858 CDC_MULTI_SESSION | CDC_MCN | 2812 CDC_MULTI_SESSION | CDC_MCN |
2859 CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | 2813 CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
2860 CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R | 2814 CDC_DRIVE_STATUS | CDC_CD_R |
2861 CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM | 2815 CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
2862 CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW | 2816 CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
2863 CDC_MRW_W | CDC_RAM, 2817 CDC_MRW_W | CDC_RAM,
@@ -3367,6 +3321,45 @@ static int idecd_release(struct inode * inode, struct file * file)
3367 return 0; 3321 return 0;
3368} 3322}
3369 3323
3324static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3325{
3326 struct packet_command cgc;
3327 char buffer[16];
3328 int stat;
3329 char spindown;
3330
3331 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3332 return -EFAULT;
3333
3334 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3335
3336 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3337 if (stat)
3338 return stat;
3339
3340 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3341 return cdrom_mode_select(cdi, &cgc);
3342}
3343
3344static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3345{
3346 struct packet_command cgc;
3347 char buffer[16];
3348 int stat;
3349 char spindown;
3350
3351 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3352
3353 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3354 if (stat)
3355 return stat;
3356
3357 spindown = buffer[11] & 0x0f;
3358 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3359 return -EFAULT;
3360 return 0;
3361}
3362
3370static int idecd_ioctl (struct inode *inode, struct file *file, 3363static int idecd_ioctl (struct inode *inode, struct file *file,
3371 unsigned int cmd, unsigned long arg) 3364 unsigned int cmd, unsigned long arg)
3372{ 3365{
@@ -3374,7 +3367,16 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
3374 struct cdrom_info *info = ide_cd_g(bdev->bd_disk); 3367 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3375 int err; 3368 int err;
3376 3369
3377 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); 3370 switch (cmd) {
3371 case CDROMSETSPINDOWN:
3372 return idecd_set_spindown(&info->devinfo, arg);
3373 case CDROMGETSPINDOWN:
3374 return idecd_get_spindown(&info->devinfo, arg);
3375 default:
3376 break;
3377 }
3378
3379 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
3378 if (err == -EINVAL) 3380 if (err == -EINVAL)
3379 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); 3381 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3380 3382