LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Hardware (https://www.linuxquestions.org/questions/linux-hardware-18/)
-   -   Setting the read speed of a dvd drive (https://www.linuxquestions.org/questions/linux-hardware-18/setting-the-read-speed-of-a-dvd-drive-630987/)

tex2us 03-27-2008 06:48 AM

Setting the read speed of a dvd drive
 
As everyone knows, the speed of the cdrom drive can be set using hdparm. However, this is not working for dvd drives reading dvd discs.
I found a solution, after a lot of useless searching, and since I didn't see any reference of the problem here (or a complete description of it anywhere), for easy reach, in case anyone else needs it/
This might not be the right board, so I ask the mods to move it, if necessary.
The thing goes like this:
First compile the code below (thanks go to Thomas Fritzsche for it)
Code:

/*
 * SpeedControl - use SET STREAMING command to set the speed of DVD-drives
 *     
 *
 * Copyright (c) 2004        Thomas Fritzsche <tf@noto.de>
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h>

 
void dump_sense(unsigned char *cdb, struct request_sense *sense)
{
  int i;
 
  printf("Command failed: ");
   
  for (i=0; i<12; i++)
    printf("%02x ", cdb[i]);
         
    if (sense) {
      printf(" - sense: %02x.%02x.%02x\n", sense->sense_key, sense->asc,
              sense->ascq);
    } else {
      printf(", no sense\n");
    }
}

int main(int argc, char *argv[])
{
  char *device = "/dev/cdrom";
  int c,fd;
  int speed = 0;
  unsigned long rw_size;
 
  unsigned char buffer[28];
 
  struct cdrom_generic_command cgc;
  struct request_sense sense;
  extern char * optarg;

  while((c=getopt(argc,argv,"x:"))!=EOF) {
    switch(c) {
      case 'x': speed = atoi(optarg); break;
      default:
        printf("Usage: speedcontrol [-x speed] [device]");
        return -1;
    }
  }

  if (argc > optind) device = argv[optind];
 
  fd = open(device, O_RDONLY | O_NONBLOCK);
  if (fd < 0) {
    printf("Can't open device %s\n", device);
    return -1;
  }


  memset(&cgc, 0, sizeof(cgc));
  memset(&sense, 0, sizeof(sense));
  memset(&buffer, 0, sizeof(buffer));

 /* SET STREAMING command */
  cgc.cmd[0] = 0xb6;
 /* 28 byte parameter list length */
  cgc.cmd[10] = 28;

  cgc.sense = &sense;
  cgc.buffer = buffer;
  cgc.buflen = sizeof(buffer);
  cgc.data_direction = CGC_DATA_WRITE;
  cgc.quiet = 1;
 
  if(speed == 0) {
/* set Restore Drive Defaults */ 
    buffer[0] = 4;
  }

  buffer[8] = 0xff;
  buffer[9] = 0xff;
  buffer[10] = 0xff;
  buffer[11] = 0xff;

  rw_size = 177 * speed;

/* read size */ 
  buffer[12] = (rw_size >> 24) & 0xff;
  buffer[13] = (rw_size >> 16) & 0xff;
  buffer[14] = (rw_size >>  8) & 0xff;
  buffer[15] = rw_size & 0xff;

/* read time 1 sec. */
  buffer[18] = 0x03;
  buffer[19] = 0xE8;

/* write size */
  buffer[20] = (rw_size >> 24) & 0xff;
  buffer[21] = (rw_size >> 16) & 0xff;
  buffer[22] = (rw_size >>  8) & 0xff;
  buffer[23] = rw_size & 0xff;

/* write time 1 sec. */
  buffer[26] = 0x03;
  buffer[27] = 0xE8;
 
  if (ioctl(fd, CDROM_SEND_PACKET, &cgc) != 0)     
    if (ioctl(fd, CDROM_SELECT_SPEED, speed) != 0) {
      dump_sense(cgc.cmd, cgc.sense);   
      printf("ERROR.\n");
      return -1;
    }
  printf("OK...\n");
  return 0;
}

The read/write size is the number of kb per time (which is 1 sec), so to set the read speed to 4X (or about 5.5MB/sec), the x parameter would be 32

Junior Hacker 03-28-2008 01:23 AM

Before I actually read your post I opened another tab and Googled these key words, "setting optical drive speed in Linux" and found this page.

Junior Hacker 03-28-2008 01:37 AM

The nerve of some people eh!
Here you are being the educator and they go and make a web site with your material already!!!

tex2us 03-28-2008 06:14 AM

Yes, I was expecting this kind of reply, not from a senior member, though
The problem is that yes, this code is available with a web search, and I found the c file 6 months ago, but what is the speed parameter? Without reading the code, one would guess it's the video disc speed multiplier, reading the code isn't much helpful either. To properly use the speed value, one would need to know what parameters the SET STREAMING command needs, and the docs for that command (or at least Fuji4r10.pdf that I found) is not really in the first results page.
Since nobody bothers to mention what the x parameter means, I believed I should, so at least others won't lose time searching for the x parameter
And btw, the speed is reset after the disc is ejected, not after reboot

gilbertt 04-22-2008 07:06 PM

Hi all,

So in conclusion there is as yet no straightforward way of playing DVD's in Linux without the drive sounding like its about to take off? I've been Googling and posting everywhere for days and there doesn't appear to be a solution..

I tried hdparm. I tried the eject command. I tried finding the devices menu in K3b, but when I tried to apt get install to the latest version of k3b it told me I already had it, even though I clearly didn't.

Seems the only thing to do is go back to Windows and use Nero drive speed. It's a shame there isn't something as simple available in Linux. Surely someone out there is watching DVD's in Linux?

Sometimes its fun trying to figure stuff out and sometimes it just seems like a pointless battle. Can anyone please help on this?


All times are GMT -5. The time now is 09:37 PM.