* PATCH for changing of DVD speed via ioctl() call
@ 2005-08-21 15:55 cHitman
2005-08-22 9:09 ` Bartlomiej Zolnierkiewicz
0 siblings, 1 reply; 5+ messages in thread
From: cHitman @ 2005-08-21 15:55 UTC (permalink / raw)
To: linux-kernel
Hello, folks!
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@gmail.com>
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@gmail.com>
*
* 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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH for changing of DVD speed via ioctl() call
[not found] <4E0p1-3vc-23@gated-at.bofh.it>
@ 2005-08-21 19:56 ` Bodo Eggert
2005-08-22 2:37 ` Chris Wedgwood
0 siblings, 1 reply; 5+ messages in thread
From: Bodo Eggert @ 2005-08-21 19:56 UTC (permalink / raw)
To: cHitman, linux-kernel
cHitman <samartsev@gmail.com> wrote:
> 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.. :(
Introducing another device-specific IOCTL because the other device-specific
request turned out to be wrong is likely to be wrong, too.
> req.sense = sense;
> - if (speed == 0)
> + if (speed <= 0)
> speed = 0xffff; /* set to max */
> else
> speed *= 177; /* Nx to kbytes/s */
The parameter value should IMHO be a pointer to a struct {
unsigned long long maxspeed; // (with 0 being the magic max. value?)
int facility; /* 0=general speed, 2=general read, 4=read data,
6=read audio, 8=read raw ... whatever is supported
n+1 = s/read/write/ */
}
That will work for any device and speed you can expect in the near future.
> +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;
EINVAL?
--
Ich danke GMX dafür, die Verwendung meiner Adressen mittels per SPF
verbreiteten Lügen zu sabotieren.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH for changing of DVD speed via ioctl() call
2005-08-21 19:56 ` Bodo Eggert
@ 2005-08-22 2:37 ` Chris Wedgwood
2005-08-22 13:42 ` Bodo Eggert
0 siblings, 1 reply; 5+ messages in thread
From: Chris Wedgwood @ 2005-08-22 2:37 UTC (permalink / raw)
To: 7eggert; +Cc: cHitman, linux-kernel
On Sun, Aug 21, 2005 at 09:56:45PM +0200, Bodo Eggert wrote:
> The parameter value should IMHO be a pointer to a struct {
> unsigned long long maxspeed; // (with 0 being the magic max. value?)
> int facility; /* 0=general speed, 2=general read, 4=read data,
> 6=read audio, 8=read raw ... whatever is supported
> n+1 = s/read/write/ */
> }
Passing pointers inside ioctl's is horrible IMO and if we can avoid it
we should. It's just asking for problems.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH for changing of DVD speed via ioctl() call
2005-08-21 15:55 PATCH for changing of DVD speed via ioctl() call cHitman
@ 2005-08-22 9:09 ` Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 5+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2005-08-22 9:09 UTC (permalink / raw)
To: cHitman; +Cc: linux-kernel
On 8/21/05, cHitman <samartsev@gmail.com> 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@gmail.com>
>
> 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@gmail.com>
> *
> * 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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PATCH for changing of DVD speed via ioctl() call
2005-08-22 2:37 ` Chris Wedgwood
@ 2005-08-22 13:42 ` Bodo Eggert
0 siblings, 0 replies; 5+ messages in thread
From: Bodo Eggert @ 2005-08-22 13:42 UTC (permalink / raw)
To: Chris Wedgwood; +Cc: 7eggert, cHitman, linux-kernel
On Sun, 21 Aug 2005, Chris Wedgwood wrote:
> On Sun, Aug 21, 2005 at 09:56:45PM +0200, Bodo Eggert wrote:
> > The parameter value should IMHO be a pointer to a struct {
> > unsigned long long maxspeed; // (with 0 being the magic max. value?)
> > int facility; /* 0=general speed, 2=general read, 4=read data,
> > 6=read audio, 8=read raw ... whatever is supported
> > n+1 = s/read/write/ */
> > }
>
> Passing pointers inside ioctl's is horrible IMO and if we can avoid it
> we should. It's just asking for problems.
It's used in all ioctls not requiring a read-only int or a void. See man
ioctl_list (2).
--
Top 100 things you don't want the sysadmin to say:
26. What happens to a Hard Disk when you drop it?
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-08-22 23:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-21 15:55 PATCH for changing of DVD speed via ioctl() call cHitman
2005-08-22 9:09 ` Bartlomiej Zolnierkiewicz
[not found] <4E0p1-3vc-23@gated-at.bofh.it>
2005-08-21 19:56 ` Bodo Eggert
2005-08-22 2:37 ` Chris Wedgwood
2005-08-22 13:42 ` Bodo Eggert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox