ports/62122: Port multimedia/vcdimager: atapicam support added

Heiner h.eichmann at gmx.de
Fri Jan 30 17:32:11 UTC 2004


>Number:         62122
>Category:       ports
>Synopsis:       Port multimedia/vcdimager: atapicam support added
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jan 30 09:30:23 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Heiner Eichmann <h.eichmann at gmx.de>
>Release:        FreeBSD 4.9-STABLE i386
>Organization:
Sirius Cybernetics Corp.
>Environment:
=46reeBSD 7of9.unimatrix-zero.borg 4.9-STABLE FreeBSD 4.9-STABLE #0: Tue De=
c 30 09:19:53 CET 2003 =A0 =A0=20
root at 7of9.unimatrix-zero.borg:/usr/obj/usr/src/sys/MYKERNEL =A0i386
>Description:
The applied fix adds atapicam support to vcdxrip
>How-To-Repeat:
>Fix:

--Boundary-00=_COpGAWrKEKXFiqU
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="diff"

diff -urN ../../multimedia/vcdimager/Makefile ./Makefile
--- ../../multimedia/vcdimager/Makefile	Fri Oct 31 11:06:24 2003
+++ ./Makefile	Fri Jan 30 18:14:47 2004
@@ -25,6 +25,17 @@
 CONFIGURE_TARGET=
 CONFIGURE_ARGS+=--build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
 
+.if defined(WITH_CAM_SUPPORT)
+EXTRA_PATCHES+=	${PATCHDIR}/diff-libvcd-vcd_image_cd-generic.c
+CONFIGURE_ENV=	CPPFLAGS="${CXXFLAGS} -I${LOCALBASE}/include" \
+		LDFLAGS="-L${LOCALBASE}/lib -lcam"
+.else
+pre-everything::
+	@${ECHO_MSG} "If you want to add atapicam support, press CTRL-C now and set the switch"
+	@${ECHO_MSG} "WITH_CAM_SUPPORT, e.g. type make install -DWITH_CAM_SUPPORT"
+	@sleep 5
+.endif
+
 MAN1=		cdxa2mpeg.1 vcdimager.1 vcdxminfo.1 vcdxrip.1 vcdxgen.1 \
 		vcdxbuild.1 vcddebug.1 vcddump.1
 INFO=		vcdimager vcddump vcdxrip
diff -urN ../../multimedia/vcdimager/files/diff-libvcd-vcd_image_cd-generic.c ./files/diff-libvcd-vcd_image_cd-generic.c
--- ../../multimedia/vcdimager/files/diff-libvcd-vcd_image_cd-generic.c	Thu Jan  1 01:00:00 1970
+++ ./files/diff-libvcd-vcd_image_cd-generic.c	Fri Jan 30 18:01:42 2004
@@ -0,0 +1,426 @@
+--- libvcd/vcd_image_cd-generic.c.orig	Sun Jan 19 20:17:21 2003
++++ libvcd/vcd_image_cd-generic.c	Fri Jan 30 18:01:29 2004
+@@ -25,12 +25,419 @@
+ #include <libvcd/vcd_image_cd.h>
+ #include <libvcd/vcd_logging.h>
+ 
+-static const char _rcsid[] = "$Id: vcd_image_cd-generic.c,v 1.1 2003/01/19 19:17:21 hvr Exp $";
++#include <sys/stat.h>
++#include <sys/ioctl.h>
++#include <sys/types.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <unistd.h>
++
++#include <camlib.h>
++
++#include <cam/scsi/scsi_message.h>
++#include <cam/scsi/scsi_pass.h>
++#include <errno.h>
++#define ERRCODE(s)	((((s)[2]&0x0F)<<16)|((s)[12]<<8)|((s)[13]))
++#define EMEDIUMTYPE	EINVAL
++#define	ENOMEDIUM	ENODEV
++#define CREAM_ON_ERRNO(s)	do {			\
++    switch ((s)[12])					\
++    {	case 0x04:	errno=EAGAIN;	break;		\
++	case 0x20:	errno=ENODEV;	break;		\
++	case 0x21:	if ((s)[13]==0)	errno=ENOSPC;	\
++			else		errno=EINVAL;	\
++			break;				\
++	case 0x30:	errno=EMEDIUMTYPE;  break;	\
++	case 0x3A:	errno=ENOMEDIUM;    break;	\
++    }							\
++} while(0)
++#include <unistd.h>
++#include <vcd_cd_sector.h>
++#define DEFAULT_VCD_DEVICE "/dev/cdrom"
++
++typedef struct {
++  int fd;
++
++  enum {
++    _AM_NONE,
++    _AM_READ_CD,
++    _AM_READ_10
++  } access_mode;
++
++  char *device;
++      struct cam_device  *cam;
++      union ccb		ccb;
++
++  bool init;
++} _img_cd_src_t;
++
++static const u_char scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
++
++static int
++_scsi_cmd (_img_cd_src_t * _obj)
++{
++   int retval;
++_obj->ccb.csio.cdb_len = scsi_cdblen[(_obj->ccb.csio.cdb_io.cdb_bytes[0] >> 5) & 7];
++   if ((retval = cam_send_ccb(_obj->cam, &_obj->ccb)) < 0)
++   {
++      vcd_error ("transport failed: ", retval);
++      return -1;
++  }
++   if ((_obj->ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
++   {
++    return 0;
++   }
++   errno = EIO;
++   retval = ERRCODE(((unsigned char *)&_obj->ccb.csio.sense_data));
++   if (retval == 0)
++      retval = -1;
++   else
++      CREAM_ON_ERRNO(((unsigned char *)&_obj->ccb.csio.sense_data));
++      vcd_error ("transport failed: ", retval);
++  return retval;
++}
++
++static void
++_vcd_source_init (_img_cd_src_t *_obj)
++{
++  char pass[100];
++  if (_obj->init)
++    return;
++
++   _obj->cam=NULL;
++   memset (&_obj->ccb,0,sizeof(_obj->ccb));
++   _obj->ccb.ccb_h.func_code = XPT_GDEVLIST;
++  _obj->fd = open (_obj->device, O_RDONLY, 0);
++
++  if (_obj->fd < 0)
++    {
++      vcd_error ("open (%s): %s", _obj->device, strerror (errno));
++      return;
++    }
++
++   if (ioctl (_obj->fd,CAMGETPASSTHRU,&_obj->ccb) < 0)
++   {
++         vcd_error ("open: %s", strerror (errno));
++         return;
++   }
++   sprintf (pass,"/dev/%.15s%u",_obj->ccb.cgdl.periph_name,_obj->ccb.cgdl.unit_number);
++   _obj->cam = cam_open_pass (pass,O_RDWR,NULL);
++   close(_obj->fd); _obj->fd = -1;
++  _obj->init = true;
++  _obj = _obj;
++}
++
++
++static void
++_source_free (void *user_data)
++{
++  _img_cd_src_t *_obj = user_data;
++
++  if (NULL == _obj) return;
++  free (_obj->device);
++
++  if (_obj->fd > 0)
++    close (_obj->fd);
++
++   if(_obj->cam)
++       cam_close_device(_obj->cam);
++
++  free (_obj);
++}
++
++static int
++_set_bsize (_img_cd_src_t *_obj, unsigned bsize)
++{
++  struct
++  {
++    uint8_t reserved1;
++    uint8_t medium;
++    uint8_t reserved2;
++    uint8_t block_desc_length;
++    uint8_t density;
++    uint8_t number_of_blocks_hi;
++    uint8_t number_of_blocks_med;
++    uint8_t number_of_blocks_lo;
++    uint8_t reserved3;
++    uint8_t block_length_hi;
++    uint8_t block_length_med;
++    uint8_t block_length_lo;
++  } mh;
++
++      memset(&_obj->ccb,0,sizeof(_obj->ccb));
++
++      memset (&mh, 0, sizeof (mh));
++
++      _obj->ccb.ccb_h.path_id    = _obj->cam->path_id;
++      _obj->ccb.ccb_h.target_id  = _obj->cam->target_id;
++      _obj->ccb.ccb_h.target_lun = _obj->cam->target_lun;
++      cam_fill_csio (&(_obj->ccb.csio), 1, NULL, CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, NULL, 0, sizeof(_obj->ccb.csio.sense_data), 0, 30*1000);
++   _obj->ccb.csio.cdb_len = 4+1;
++
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[0] = 0x15;
++  _obj->ccb.csio.cdb_io.cdb_bytes[1] = 1 << 4;
++  _obj->ccb.csio.cdb_io.cdb_bytes[4] = 12;
++
++  _obj->ccb.csio.data_ptr = (u_char *)&mh;
++  _obj->ccb.csio.dxfer_len = sizeof (mh);;
++
++  //suc.suc_timeout = 500;
++  _obj->ccb.csio.ccb_h.flags = CAM_DIR_OUT;
++
++  mh.block_desc_length = 0x08;
++  mh.block_length_hi = (bsize >> 16) & 0xff;
++  mh.block_length_med = (bsize >> 8) & 0xff;
++  mh.block_length_lo = (bsize >> 0) & 0xff;
++
++  return _scsi_cmd (_obj);
++}
++
++static int
++_read_mode2 (_img_cd_src_t *_obj, void *buf, uint32_t lba, unsigned nblocks,
++	     bool _workaround)
++{
++  int retval = 0;
++      memset(&_obj->ccb,0,sizeof(_obj->ccb));
++      _obj->ccb.ccb_h.path_id    = _obj->cam->path_id;
++      _obj->ccb.ccb_h.target_id  = _obj->cam->target_id;
++      _obj->ccb.ccb_h.target_lun = _obj->cam->target_lun;
++      cam_fill_csio (&(_obj->ccb.csio), 1, NULL, CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, NULL, 0, sizeof(_obj->ccb.csio.sense_data), 0, 30*1000);
++   _obj->ccb.csio.cdb_len = (_workaround?8:9)+1;
++
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[0] = (_workaround
++		    ? 0x28 /* CMD_READ_10 */
++		    : 0xbe /* CMD_READ_CD */);
++
++  if (!_workaround)
++    _obj->ccb.csio.cdb_io.cdb_bytes[1] = 0; /* sector size mode2 */
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[2] = (lba >> 24) & 0xff;
++  _obj->ccb.csio.cdb_io.cdb_bytes[3] = (lba >> 16) & 0xff;
++  _obj->ccb.csio.cdb_io.cdb_bytes[4] = (lba >> 8) & 0xff;
++  _obj->ccb.csio.cdb_io.cdb_bytes[5] = (lba >> 0) & 0xff;
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[6] = (nblocks >> 16) & 0xff;
++  _obj->ccb.csio.cdb_io.cdb_bytes[7] = (nblocks >> 8) & 0xff;
++  _obj->ccb.csio.cdb_io.cdb_bytes[8] = (nblocks >> 0) & 0xff;
++
++  if (!_workaround)
++    _obj->ccb.csio.cdb_io.cdb_bytes[9] = 0x58; /* 2336 mode2 mixed form */
++
++  _obj->ccb.csio.data_ptr = buf;
++  _obj->ccb.csio.dxfer_len = 2336 * nblocks;
++
++  //suc.suc_timeout = 500;
++  _obj->ccb.csio.ccb_h.flags = CAM_DIR_IN;
++
++  if (_workaround)
++    {
++      if ((retval = _set_bsize (_obj, 2336)))
++	goto out;
++
++      if ((retval = _scsi_cmd(_obj)))
++	{
++	  _set_bsize (_obj, 2048);
++	  goto out;
++	}
++      retval = _set_bsize (_obj, 2048);
++    }
++  else
++    retval = _scsi_cmd(_obj);
++
++ out:
++  return retval;
++}
++
++static int
++_read_mode2_sector (void *user_data, void *data, uint32_t lsn, bool form2)
++{
++  _img_cd_src_t *_obj = user_data;
++
++  _vcd_source_init (_obj);
++
++  if (form2)
++    {
++    retry:
++      switch (_obj->access_mode)
++	{
++	case _AM_NONE:
++	  vcd_error ("no way to read mode2");
++	  return 1;
++	  break;
++
++	case _AM_READ_CD:
++	case _AM_READ_10:
++	  if (_read_mode2 (_obj, data, lsn, 1,
++			   (_obj->access_mode == _AM_READ_10)))
++	    {
++	      if (_obj->access_mode == _AM_READ_CD)
++		{
++		  vcd_info ("READ_CD failed; switching to READ_10 mode...");
++		  _obj->access_mode = _AM_READ_10;
++		  goto retry;
++		}
++	      else
++		{
++		  vcd_info ("READ_10 failed; no way to read mode2 left.");
++		  _obj->access_mode = _AM_NONE;
++		  goto retry;
++		}
++	      return 1;
++	    }
++	  break;
++	}
++    }
++  else
++    {
++      char buf[M2RAW_SECTOR_SIZE] = { 0, };
++      int retval;
++      if ((retval = _read_mode2_sector (_obj, buf, lsn, true)))
++      {
++	return retval;
++	}
++
++      memcpy (data, buf + 8, M2F1_SECTOR_SIZE);
++    }
++
++  return 0;
++}
++
++static uint32_t
++_stat_size (void *user_data)
++{
++  _img_cd_src_t *_obj = user_data;
++
++  uint8_t buf[12] = { 0, };
++
++  uint32_t retval;
++  _vcd_source_init(_obj);
++
++      memset(&_obj->ccb,0,sizeof(_obj->ccb));
++      _obj->ccb.ccb_h.path_id    = _obj->cam->path_id;
++      _obj->ccb.ccb_h.target_id  = _obj->cam->target_id;
++      _obj->ccb.ccb_h.target_lun = _obj->cam->target_lun;
++      cam_fill_csio (&(_obj->ccb.csio), 1, NULL, CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, NULL, 0, sizeof(_obj->ccb.csio.sense_data), 0, 30*1000);
++   _obj->ccb.csio.cdb_len = 8+1;
++
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[0] = 0x43; /* CMD_READ_TOC_PMA_ATIP */
++  _obj->ccb.csio.cdb_io.cdb_bytes[1] = 0; /* lba; msf: 0x2 */
++  _obj->ccb.csio.cdb_io.cdb_bytes[6] = 0xaa; /* CDROM_LEADOUT */
++  _obj->ccb.csio.cdb_io.cdb_bytes[8] = 12; /* ? */
++
++  _obj->ccb.csio.data_ptr = buf;
++  _obj->ccb.csio.dxfer_len = sizeof (buf);
++
++  //suc.suc_timeout = 500;
++  _obj->ccb.csio.ccb_h.flags = CAM_DIR_IN;
++
++  if (_scsi_cmd(_obj))
++    return 0;
++
++  {
++    int i;
++
++    retval = 0;
++    for (i = 8; i < 12; i++)
++      {
++        retval <<= 8;
++        retval += buf[i];
++      }
++  }
++
++  return retval;
++}
++
++static int
++_source_set_arg (void *user_data, const char key[], const char value[])
++{
++  _img_cd_src_t *_obj = user_data;
++
++  if (!strcmp (key, "device"))
++    {
++      if (!value)
++	return -2;
++
++      free (_obj->device);
++
++      _obj->device = strdup (value);
++    }
++  else if (!strcmp (key, "access-mode"))
++    {
++      if (!strcmp(value, "READ_CD"))
++	_obj->access_mode = _AM_READ_CD;
++      else if (!strcmp(value, "READ_10"))
++	_obj->access_mode = _AM_READ_10;
++      else
++	vcd_error ("unknown access type: %s. ignored.", value);
++    }
++  else 
++    return -1;
++
++  return 0;
++}
++
++static int
++_vcd_eject_media (void *user_data) {
++    _img_cd_src_t *_obj = user_data;
++
++    if (!_obj->init) _vcd_source_init(_obj);
++
++    if (_obj->fd == -1)
++       return 2;
++
++      memset(&_obj->ccb,0,sizeof(_obj->ccb));
++      _obj->ccb.ccb_h.path_id    = _obj->cam->path_id;
++      _obj->ccb.ccb_h.target_id  = _obj->cam->target_id;
++      _obj->ccb.ccb_h.target_lun = _obj->cam->target_lun;
++      cam_fill_csio (&(_obj->ccb.csio), 1, NULL, CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, NULL, 0, sizeof(_obj->ccb.csio.sense_data), 0, 30*1000);
++   _obj->ccb.csio.cdb_len = 5+1;
++
++
++  _obj->ccb.csio.cdb_io.cdb_bytes[0] = 0x1b;	/* CMD_START_STOP_DEVICE */
++  _obj->ccb.csio.cdb_io.cdb_bytes[1] = 0x1;	/* immediate */
++  _obj->ccb.csio.cdb_io.cdb_bytes[4] = 0x2;	/* eject */
++
++  _obj->ccb.csio.data_ptr = 0;
++  _obj->ccb.csio.dxfer_len = 0;
++
++  //suc.suc_timeout = 500;
++  _obj->ccb.csio.ccb_h.flags = CAM_DIR_IN;
++    return(_scsi_cmd(_obj));
++}
++
++static char *
++_vcd_get_default_device()
++{
++  return strdup(DEFAULT_VCD_DEVICE);
++}
++
+ 
+ VcdImageSource *
+ vcd_image_source_new_cd (void)
+ {
+-  vcd_error ("no CD-ROM image driver available for this architecture (%s)",
+-	     HOST_ARCH);
+-  return NULL;
++  _img_cd_src_t *_data;
++
++  vcd_image_source_funcs _funcs = {
++    .eject_media       = _vcd_eject_media,
++    .free              = _source_free,
++    .get_default_device= _vcd_get_default_device,
++    .read_mode2_sector = _read_mode2_sector,
++    .set_arg           = _source_set_arg,
++    .stat_size         = _stat_size
++  };
++
++  _data = _vcd_malloc (sizeof (_img_cd_src_t));
++  _data->access_mode = _AM_READ_CD;
++  _data->init        = false;
++  _data->device      = _vcd_get_default_device();
++  _data->fd          = -1;
++
++  return vcd_image_source_new (_data, &_funcs);
+ }

--Boundary-00=_COpGAWrKEKXFiqU--

>Release-Note:
>Audit-Trail:
>Unformatted:
 --Boundary-00=_COpGAWrKEKXFiqU
 Content-Type: text/plain;
   charset="iso-8859-1"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline
 



More information about the freebsd-ports-bugs mailing list