bug-vcdimager
[Top][All Lists]
Advanced

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

Re: [VCDImager Bugs/Devel] vcdxrip rip errors


From: Steven M. Schultz
Subject: Re: [VCDImager Bugs/Devel] vcdxrip rip errors
Date: Sat, 13 Oct 2001 12:13:22 -0700 (PDT)

Hi!

> well the workaround is there, in case the CMD_READ_CD ioctl doesn't work
> (usually because the command is not implemented...), then the fall back
> to work with CMD_READ_10 is used instead...

> actually I wanted to get rid of the regular read(), since it's not that
> flexible;

        And I know it works because I tested it when you first wrote it ;)

> well, maybe the workaround mechanism doesn't work anymore...

        Possible.

> maybe one should check the return values...
        
        I mention that below and have provided an updated module that does
        report more information.

> btw, have you changed hardware? cause vcd_image_bsdicd.c hasn't changed
> since 2001/08/31 in cvs... and you told me that version worked... :-/

        Yes.   I am no a different system and the CDrom drive is a different
        brand.  When I tested earlier I was using either an ATAPI DVDrom drive
        or a Yamaha 8824S CDRW drive.   Last night and today I am using
        a system that has a Plextor CDrom drive and a Yamaha 8424S.

        And now for the news you've been waiting for :)

        I have narrowed down the problem.

        It turns out I was indeed offbase before - the _workaround flag
        can work (and has worked - I remember testing it before).

        IF I use a Plextor Ultraplex CDrom drive I get failures.  However
        if a Yamaha 8424S CD/RW drive is used the 'vcdxrip' works correctly!

        Enclosed is an updated vcd_image_bsdicd.c module that adds some
        debugging output.  It is necessary to check both the 'ioctl' status
        (which says the kernel accepted the request) _and_ the SCSI status
        suc.suc_sus.sus_status because that is how devices pass back
        success/failure.   I also print out the first 8 bytes of the sense
        data returned.

        Then there was a duplicated ioctl (fd, SCSIRAWCDB, &suc) call.    It
        did not seem logical to do this:

              ioctl (fd, SCSIRAWCDB, &suc);
              if (_workaround)
                 {
                 ioctl (fd, SCSIRAWCDB, &suc);
                 }
              else
                 ioctl (fd, SCSIRAWCDB, &suc);

        The fix is to simply remove the first 'ioctl (fd, SCSIRAWCDB, &suc)' and
        rely on the 'if ... else ...' to issue the ioctl.

        Included also is the output from the plextor drive - I will have to
        find a SCSI error code listing somewhere to decode what:

                INFO: _read_mode2 sense: 70 0 5 0 0 0 0 a

        means - obviously Plextor drives do not like the SCSI commands being
        presented.   If those bits make sense to you then perhaps a fix
        for SCSI Plextor drives can be created.

        Steven Schultz
-----------------------------cut here-----------------------
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2001-10-13 12:02 PDT by <address@hidden>.
# Source directory was `/tmp'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    240 -rw-r--r-- vcdxrip.script
#   7597 -rw-r--r-- vcd_image_bsdicd.c
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh02113; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= vcdxrip.script ==============
if test -f 'vcdxrip.script' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'vcdxrip.script' '(file already exists)'
else
  $echo 'x -' extracting 'vcdxrip.script' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'vcdxrip.script' &&
Script started on Sat Oct 13 11:51:01 2001
moe.2685-> ./vcdxrip --cdrom-device=/dev/rsr1c
INFO: _read_mode2 sus_status 2
INFO: _read_mode2 sense: 70 0 5 0 0 0 0 a
**ERROR: unexcected descriptor type
X
Script done on Sat Oct 13 11:51:29 2001
SHAR_EOF
  $shar_touch -am 1013120101 'vcdxrip.script' &&
  chmod 0644 'vcdxrip.script' ||
  $echo 'restore of' 'vcdxrip.script' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'vcdxrip.script:' 'MD5 check failed'
743b9faa0636e5ecbe528ba3ba576f2f  vcdxrip.script
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'vcdxrip.script'`"
    test 240 -eq "$shar_count" ||
    $echo 'vcdxrip.script:' 'original size' '240,' 'current size' "$shar_count!"
  fi
fi
# ============= vcd_image_bsdicd.c ==============
if test -f 'vcd_image_bsdicd.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'vcd_image_bsdicd.c' '(file already exists)'
else
  $echo 'x -' extracting 'vcd_image_bsdicd.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'vcd_image_bsdicd.c' &&
/*
X    $Id: vcd_image_bsdicd.c,v 1.2 2001/08/31 09:04:53 hvr Exp $
X
X    Copyright (C) 2001 Herbert Valerio Riedel <address@hidden>
X
X    This program is free software; you can redistribute it and/or modify
X    it under the terms of the GNU General Public License as published by
X    the Free Software Foundation; either version 2 of the License, or
X    (at your option) any later version.
X
X    This program is distributed in the hope that it will be useful,
X    but WITHOUT ANY WARRANTY; without even the implied warranty of
X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X    GNU General Public License for more details.
X
X    You should have received a copy of the GNU General Public License
X    along with this program; if not, write to the Free Software
X    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
X
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
X
#include <libvcd/vcd_assert.h>
#include <libvcd/vcd_bytesex.h>
#include <libvcd/vcd_cd_sector.h>
#include <libvcd/vcd_image_bsdicd.h>
#include <libvcd/vcd_iso9660.h>
#include <libvcd/vcd_logging.h>
#include <libvcd/vcd_util.h>
X
static const char _rcsid[] = "$Id: vcd_image_bsdicd.c,v 1.2 2001/08/31 09:04:53 
hvr Exp $";
X
#if defined(__bsdi__)
/* && defined(SCSIRAWCDB) */
X
#include </sys/dev/scsi/scsi.h>
#include </sys/dev/scsi/scsi_ioctl.h>
X
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
X
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
X
/* reader */
X
typedef struct {
X  int fd;
X
X  enum {
X    _AM_NONE,
X    _AM_READ_CD,
X    _AM_READ_10
X  } access_mode;
X
X  char *device;
X  
X  bool init;
} _img_bsdicd_src_t;
X
static void
_source_init (_img_bsdicd_src_t *_obj)
{
X  if (_obj->init)
X    return;
X
X  _obj->fd = open (_obj->device, O_RDONLY, 0);
X  _obj->access_mode = _AM_READ_CD;
X
X  if (_obj->fd < 0)
X    {
X      vcd_error ("open (%s): %s", _obj->device, strerror (errno));
X      return;
X    }
X
X  _obj->init = true;
}
X
X
static void
_source_free (void *user_data)
{
X  _img_bsdicd_src_t *_obj = user_data;
X
X  free (_obj->device);
X
X  if (_obj->fd)
X    close (_obj->fd);
X
X  free (_obj);
}
X
static int 
_set_bsize (int fd, unsigned bsize)
{
X  struct
X  {
X    uint8_t reserved1;
X    uint8_t medium;
X    uint8_t reserved2;
X    uint8_t block_desc_length;
X    uint8_t density;
X    uint8_t number_of_blocks_hi;
X    uint8_t number_of_blocks_med;
X    uint8_t number_of_blocks_lo;
X    uint8_t reserved3;
X    uint8_t block_length_hi;
X    uint8_t block_length_med;
X    uint8_t block_length_lo;
X  } mh;
X
X  struct scsi_user_cdb suc; 
X
X  memset (&mh, 0, sizeof (mh));
X  memset (&suc, 0, sizeof (struct scsi_user_cdb));
X  
X  suc.suc_cdb[0] = 0x15;
X  suc.suc_cdb[1] = 1 << 4;
X  suc.suc_cdb[4] = 12;
X  suc.suc_cdblen = 6;;
X
X  suc.suc_data = (u_char *)&mh;
X  suc.suc_datalen = sizeof (mh);
X
X  suc.suc_timeout = 500;
X  suc.suc_flags = SUC_WRITE;
X
X  mh.block_desc_length = 0x08;
X  mh.block_length_hi = (bsize >> 16) & 0xff;
X  mh.block_length_med = (bsize >> 8) & 0xff;
X  mh.block_length_lo = (bsize >> 0) & 0xff;
X
X  return ioctl (fd, SCSIRAWCDB, &suc);
}
X
static int
_read_mode2 (int fd, void *buf, uint32_t lba, unsigned nblocks, 
X            bool _workaround)
{
X  struct scsi_user_cdb suc; 
X  u_char *cp;
X
X  memset (&suc, 0, sizeof (struct scsi_user_cdb));
X
X  suc.suc_cdb[0] = (_workaround 
X                   ? 0x28 /* CMD_READ_10 */
X                   : 0xbe /* CMD_READ_CD */);
X
X  if (!_workaround)
X    suc.suc_cdb[1] = 0; /* sector size mode2 */
X  
X  suc.suc_cdb[2] = (lba >> 24) & 0xff;
X  suc.suc_cdb[3] = (lba >> 16) & 0xff;
X  suc.suc_cdb[4] = (lba >> 8) & 0xff;
X  suc.suc_cdb[5] = (lba >> 0) & 0xff;
X
X  suc.suc_cdb[6] = (nblocks >> 16) & 0xff;
X  suc.suc_cdb[7] = (nblocks >> 8) & 0xff;
X  suc.suc_cdb[8] = (nblocks >> 0) & 0xff;
X
X  if (!_workaround)
X    suc.suc_cdb[9] = 0x58; /* 2336 mode2 mixed form */
X
X  suc.suc_cdblen = _workaround ? 10 : 12;
X
X  suc.suc_data = buf;
X  suc.suc_datalen = 2336 * nblocks;
X
X  suc.suc_timeout = 500;
X  suc.suc_flags = SUC_READ;
X
X  if (_workaround)
X    {
X      int retval;
X
X      if ((retval = _set_bsize (fd, 2336)))
X       return retval;
X
X      if ((retval = ioctl (fd, SCSIRAWCDB, &suc)))
X       {
X         _set_bsize (fd, 2048);
X         return retval;
X       }
X
X      if ((retval = _set_bsize (fd, 2048)))
X       return retval;
X    }
X  else
X    {
X    if (ioctl (fd, SCSIRAWCDB, &suc))
X       vcd_error ("ioctl (SCSIRAWCDB): %s", strerror (errno));
X    if (suc.suc_sus.sus_status)
X       {
X       vcd_info("_read_mode2 sus_status %d\n", suc.suc_sus.sus_status);
X       cp = suc.suc_sus.sus_sense;
X       vcd_info("_read_mode2 sense: %x %x %x %x %x %x %x %x\n", 
X               cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
X       }
X    }
X  return 0;
}
X
static int
_read_mode2_sector (void *user_data, void *data, uint32_t lsn, bool form2)
{
X  _img_bsdicd_src_t *_obj = user_data;
X
X  _source_init (_obj);
X
X  if (form2)
X    {
X    retry:
X       switch (_obj->access_mode)
X         {
X         case _AM_NONE:
X           vcd_error ("no way to read mode2");
X           return 1;
X           break;
X
X         case _AM_READ_CD:
X         case _AM_READ_10:
X           if (_read_mode2 (_obj->fd, data, lsn, 1, 
X                            (_obj->access_mode == _AM_READ_10)))
X             {
X               perror ("ioctl()");
X               if (_obj->access_mode == _AM_READ_CD)
X                 {
X                   vcd_info ("READ_CD failed; switching to READ_10 mode...");
X                   _obj->access_mode = _AM_READ_10;
X                   goto retry;
X                 }
X               else
X                 {
X                   vcd_info ("READ_10 failed; no way to read mode2 left.");
X                   _obj->access_mode = _AM_NONE;
X                   goto retry;
X                 }
X               return 1;
X             }
X           break;
X         }
X    }
X  else
X    {
X      char buf[M2RAW_SIZE] = { 0, };
X      int retval;
X
X      if ((retval = _read_mode2_sector (_obj, buf, lsn, true)))
X       return retval;
X
X      memcpy (data, buf + 8, ISO_BLOCKSIZE);
X    }
X
X  return 0;
}
X
static const u_char scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
X
static uint32_t 
_stat_size (void *user_data)
{
X  _img_bsdicd_src_t *_obj = user_data;
X
X  struct scsi_user_cdb suc; 
X  uint8_t buf[12] = { 0, };
X
X  uint32_t retval;
X
X  _source_init(_obj);
X
X  memset (&suc, 0, sizeof (struct scsi_user_cdb));
X
X  suc.suc_cdb[0] = 0x43; /* CMD_READ_TOC_PMA_ATIP */
X  suc.suc_cdb[1] = 0; /* lba; msf: 0x2 */
X  suc.suc_cdb[6] = 0xaa; /* CDROM_LEADOUT */
X  suc.suc_cdb[8] = 12; /* ? */
X  suc.suc_cdblen = 10;
X
X  suc.suc_data = buf;
X  suc.suc_datalen = sizeof (buf);
X
X  suc.suc_timeout = 500;
X  suc.suc_flags = SUC_READ;
X
X  if (ioctl (_obj->fd, SCSIRAWCDB, &suc))
X    {
X      vcd_error ("ioctl (SCSIRAWCDB): %s", strerror (errno));
X      return 0;
X    }
X
X  if (suc.suc_sus.sus_status)
X    {
X      vcd_error ("scsistatus = %d", suc.suc_sus.sus_status);
X      return 0;
X    }
X
X  {
X    int i;
X
X    retval = 0;
X    for (i = 8; i < 12; i++)
X      {
X        retval <<= 8;
X        retval += buf[i];
X      }
X  }
X
X  return retval;
}
X
static int
_source_set_arg (void *user_data, const char key[], const char value[])
{
X  _img_bsdicd_src_t *_obj = user_data;
X  
X  if (!strcmp (key, "device"))
X    {
X      if (!value)
X       return -2;
X
X      free (_obj->device);
X      
X      _obj->device = strdup (value);
X    }
X  else 
X    return -1;
X
X  return 0;
}
X
#endif /* defined(__bsdi__) */
X
VcdImageSource *
vcd_image_source_new_bsdicd (void)
{
#if defined(__bsdi__)
X  _img_bsdicd_src_t *_data;
X
X  vcd_image_source_funcs _funcs = {
X    read_mode2_sector: _read_mode2_sector,
X    stat_size: _stat_size,
X    free: _source_free,
X    setarg: _source_set_arg
X  };
X
X  _data = _vcd_malloc (sizeof (_img_bsdicd_src_t));
X  _data->device = strdup ("/dev/cdrom");
X
X  return vcd_image_source_new (_data, &_funcs);
#else 
X  vcd_error ("bsdi cd image source only supported under BSDI");
X  return NULL;
#endif
}
X
X
SHAR_EOF
  $shar_touch -am 1013120201 'vcd_image_bsdicd.c' &&
  chmod 0644 'vcd_image_bsdicd.c' ||
  $echo 'restore of' 'vcd_image_bsdicd.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'vcd_image_bsdicd.c:' 'MD5 check failed'
e16de4a466501aba60b5ce598c3b0ee5  vcd_image_bsdicd.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'vcd_image_bsdicd.c'`"
    test 7597 -eq "$shar_count" ||
    $echo 'vcd_image_bsdicd.c:' 'original size' '7597,' 'current size' 
"$shar_count!"
  fi
fi
rm -fr _sh02113
exit 0



reply via email to

[Prev in Thread] Current Thread [Next in Thread]