Re: PATCH for changing of DVD speed via ioctl() call

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/21/05, cHitman <[email protected]> wrote:
> Hello, folks!

Hi,

Please use user-space solution instead:
http://www.ussg.iu.edu/hypermail/linux/kernel/0411.3/0812.html

Thanks,
Bartlomiej

> This patch implements changing of DVD speed via ioctl() call, like
> CDROM_SELECT_SPEED do. In CDROM_SELECT_SPEED its implementation isn't
> so good (diffirent values of 1x in KB/s, troubles with return value of
> cdrom_select_speed() and other). I defined CDROM_SELECT_DVDSPEED ioctl
> () call with value 0x5324. But some dvdroms (like Plexter) do not
> support this feature.. :(
> 
> I've successfully tested this patch on:s
> NEC ND-3500AG (fw 2.19)
> BENQ DVD-ROM 16X 1650T (fw: A.DD)
> HL-DT-ST DVD-RW GCA-4080N (fw: 0A31)
> 
> I've mailed this message to Jens Axboe but have not answer :(
> Please try it and say what you think about this..
> 
> patch for kernel 2.6.12
> 
> Signed-off-by: Ilja Samartsev <[email protected]>
> 
> PS: I'm not subscribed to LKML please CC me if you can.
> 
> =================== PATCH ====================
> --- linux/include/linux/cdrom.h 2005-08-13 12:54:06.000000000 +0600
> +++ my_linux/include/linux/cdrom.h      2005-08-14 15:06:06.000000000 +0600
> @@ -120,6 +120,7 @@
>  #define CDROM_CLEAR_OPTIONS    0x5321  /* Clear behavior options */
>  #define CDROM_SELECT_SPEED     0x5322  /* Set the CD-ROM speed */
>  #define CDROM_SELECT_DISC      0x5323  /* Select disc (for juke-boxes) */
> +#define CDROM_SELECT_DVDSPEED  0x5324  /* Set the DVD-ROM speed */
>  #define CDROM_MEDIA_CHANGED    0x5325  /* Check is media changed  */
>  #define CDROM_DRIVE_STATUS     0x5326  /* Get tray position, etc. */
>  #define CDROM_DISC_STATUS      0x5327  /* Get disc type, etc. */
> @@ -965,6 +966,7 @@ struct cdrom_device_ops {
>         int (*tray_move) (struct cdrom_device_info *, int);
>         int (*lock_door) (struct cdrom_device_info *, int);
>         int (*select_speed) (struct cdrom_device_info *, int);
> +       int (*select_dvd_speed) (struct cdrom_device_info *, int);
>         int (*select_disc) (struct cdrom_device_info *, int);
>         int (*get_last_session) (struct cdrom_device_info *,
>                                  struct cdrom_multisession *);
> --- linux/drivers/cdrom/cdrom.c 2005-08-13 12:54:06.000000000 +0600
> +++ my_linux/drivers/cdrom/cdrom.c      2005-08-12 17:11:20.000000000 +0600
> @@ -2327,6 +2327,11 @@ int cdrom_ioctl(struct file * file, stru
>                 return cdo->select_speed(cdi, arg);
>                 }
> 
> +       case CDROM_SELECT_DVDSPEED: {
> +               cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DVDSPEED\n");
> +               return cdo->select_dvd_speed(cdi, arg);
> +               }
> +
>         case CDROM_SELECT_DISC: {
>                 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
>                 if (!CDROM_CAN(CDC_SELECT_DISC))
> --- linux/drivers/ide/ide-cd.c  2005-08-13 12:54:06.000000000 +0600
> +++ my_linux/drivers/ide/ide-cd.c       2005-08-16 01:00:09.000000000 +0600
> @@ -2393,7 +2393,7 @@ static int cdrom_select_speed(ide_drive_
>         cdrom_prepare_request(drive, &req);
> 
>         req.sense = sense;
> -       if (speed == 0)
> +       if (speed <= 0)
>                 speed = 0xffff; /* set to max */
>         else
>                 speed *= 177;   /* Nx to kbytes/s */
> @@ -2415,6 +2415,63 @@ static int cdrom_select_speed(ide_drive_
>         return cdrom_queue_packet_command(drive, &req);
>  }
> 
> +static int cdrom_select_dvd_speed(ide_drive_t *drive, int speed,
> +               struct request_sense *sense)
> +{
> +       struct request req;
> +       struct request_sense cap_sense;
> +       unsigned char pd[28];
> +       unsigned long cap, spf;
> +
> +       if (!CDROM_CONFIG_FLAGS(drive)->dvd)
> +               return -ENOSYS;
> +
> +       cdrom_prepare_request(drive, &req);
> +
> +       req.sense = sense;
> +       req.data = pd;
> +       req.data_len = sizeof(pd);
> +
> +       memset(pd, 0, sizeof(pd));
> +
> +       req.cmd[0] = GPCMD_SET_STREAMING;
> +       req.cmd[10] = sizeof(pd); /* parameter list length */
> +
> +       if (speed <= 0) {
> +               pd[0] = 4;      /* restore drive defaults */
> +       } else {
> +
> +               speed *= 1385;  /* Nx to kbytes/s (FIXME: maybe not right value) */
> +
> +               if (!cdrom_read_capacity(drive, &cap, &spf, &cap_sense) && cap) {
> +                       /* good End LBA detected */
> +                       cap++;
> +                       pd[8] = (cap >> 24) & 0xff;
> +                       pd[9] = (cap >> 16) & 0xff;
> +                       pd[10] = (cap >> 8) & 0xff;
> +                       pd[11] = cap & 0xff;
> +               } else {
> +                       /* no good End LBA detected, using max */
> +                       pd[8] = 0xff;
> +                       pd[9] = 0xff;
> +                       pd[10] = 0xff;
> +                       pd[11] = 0xff;
> +               }
> +
> +               /* read and write size */
> +               pd[12] = pd[20] = (speed >> 24) & 0xff;
> +               pd[13] = pd[21] = (speed >> 16) & 0xff;
> +               pd[14] = pd[22] = (speed >> 8) & 0xff;
> +               pd[15] = pd[23] = speed & 0xff;
> +
> +               /* read and write time */
> +               pd[18] = pd[26] = 1000 >> 8;
> +               pd[19] = pd[27] = 1000 & 0xff;
> +       }
> +
> +       return cdrom_queue_packet_command(drive, &req);
> +}
> +
>  static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
>  {
>         struct request_sense sense;
> @@ -2670,6 +2727,19 @@ int ide_cdrom_select_speed (struct cdrom
>          return 0;
>  }
> 
> +static
> +int ide_cdrom_select_dvd_speed (struct cdrom_device_info *cdi, int speed)
> +{
> +       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
> +       struct request_sense sense;
> +       int stat;
> +
> +       if ((stat = cdrom_select_dvd_speed(drive, speed, &sense)) < 0)
> +               return stat;
> +
> +       return 0;
> +}
> +
>  /*
>   * add logic to try GET_EVENT command first to check for media and tray
>   * status. this should be supported by newer cd-r/w and all DVD etc
> @@ -2816,6 +2886,7 @@ static struct cdrom_device_ops ide_cdrom
>         .tray_move              = ide_cdrom_tray_move,
>         .lock_door              = ide_cdrom_lock_door,
>         .select_speed           = ide_cdrom_select_speed,
> +       .select_dvd_speed       = ide_cdrom_select_dvd_speed,
>         .get_last_session       = ide_cdrom_get_last_session,
>         .get_mcn                = ide_cdrom_get_mcn,
>         .reset                  = ide_cdrom_reset,
> 
> ====================== EOF ========================
> 
> =================== dvdspeed.c ====================
> /*
>  *  dvdspeed - small program for selecting speed of DVD drive
>  *    Copyright (C) 2005 Ilja Samartsev <[email protected]>
>  *
>  *  This program is free software; you can redistribute it and/or modify
>  *  it under the terms of the GNU General Public License as published by
>  *  the Free Software Foundation; either version 2 of the License, or
>  *  (at your option) any later version.
>  *
>  *  This program is distributed in the hope that it will be useful,
>  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  *  GNU General Public License for more details.
>  *
>  *  You should have received a copy of the GNU General Public License
>  *  along with this program; if not, write to the Free Software
>  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
>  */
> 
> #include <fcntl.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <linux/cdrom.h>
> 
> int main (int argc, char **argv)
> {
>         int fd, speed;
>         char *device;
> 
>         if (argc < 3) {
>                 printf("usage: %s device speed\n", argv[0]);
>                 return -1;
>         }
> 
>         device = argv[1];
>         speed = atoi(argv[2]);
> 
>         if ((fd = open(device, O_RDONLY|O_NONBLOCK)) >= 0) {
>                 if (ioctl(fd, CDROM_SELECT_DVDSPEED, speed) < 0) {
>                         perror("ioctl()");
>                         exit(-1);
>                 }
>         }
> 
>         return 0;
> }
> ====================== EOF ========================
> 
> --
> Samartsev Ilja
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux