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

From: Bartlomiej Zolnierkiewicz
Date: Mon Aug 22 2005 - 17:25:28 EST


On 8/21/05, cHitman <samartsev@xxxxxxxxx> 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 <samartsev@xxxxxxxxx>
>
> 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 <samartsev@xxxxxxxxx>
> *
> * 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/