summaryrefslogtreecommitdiff
path: root/src/input/vcd/libcdio/_cdio_bsdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/vcd/libcdio/_cdio_bsdi.c')
-rw-r--r--src/input/vcd/libcdio/_cdio_bsdi.c475
1 files changed, 282 insertions, 193 deletions
diff --git a/src/input/vcd/libcdio/_cdio_bsdi.c b/src/input/vcd/libcdio/_cdio_bsdi.c
index 7fd60a9d9..aef535752 100644
--- a/src/input/vcd/libcdio/_cdio_bsdi.c
+++ b/src/input/vcd/libcdio/_cdio_bsdi.c
@@ -1,5 +1,5 @@
/*
- $Id: _cdio_bsdi.c,v 1.2 2004/04/11 12:20:31 miguelfreitas Exp $
+ $Id: _cdio_bsdi.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,8 +27,9 @@
# include "config.h"
#endif
-static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.2 2004/04/11 12:20:31 miguelfreitas Exp $";
+static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $";
+#include <cdio/logging.h>
#include <cdio/sector.h>
#include <cdio/util.h>
#include "cdio_assert.h"
@@ -54,31 +55,109 @@ static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.2 2004/04/11 12:20:31 miguel
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
+#include </sys/dev/scsi/scsi.h>
+#include </sys/dev/scsi/scsi_ioctl.h>
+#include "cdtext_private.h"
-#define TOTAL_TRACKS (_obj->tochdr.cdth_trk1)
-#define FIRST_TRACK_NUM (_obj->tochdr.cdth_trk0)
+typedef enum {
+ _AM_NONE,
+ _AM_IOCTL,
+} access_mode_t;
typedef struct {
/* Things common to all drivers like this.
This must be first. */
generic_img_private_t gen;
- enum {
- _AM_NONE,
- _AM_IOCTL,
- } access_mode;
-
- char *source_name;
-
- bool init;
+ access_mode_t access_mode;
+ /* Some of the more OS specific things. */
/* Track information */
- bool toc_init; /* if true, info below is valid. */
struct cdrom_tochdr tochdr;
- struct cdrom_tocentry tocent[100]; /* entry info for each track */
+ struct cdrom_tocentry tocent[CDIO_CD_MAX_TRACKS+1];
} _img_private_t;
+/* Define the Cdrom Generic Command structure */
+typedef struct cgc
+{
+ scsi_mmc_cdb_t cdb;
+ u_char *buf;
+ int buflen;
+ int rw;
+ unsigned int timeout;
+ scsi_user_sense_t *sus;
+} cgc_t;
+
+
+/*
+ This code adapted from Steven M. Schultz's libdvd
+*/
+static int
+run_scsi_cmd_bsdi(const void *p_user_data, unsigned int i_timeout_ms,
+ unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb,
+ scsi_mmc_direction_t e_direction,
+ unsigned int i_buf, /*in/out*/ void *p_buf )
+{
+ const _img_private_t *p_env = p_user_data;
+ int i_status, i_asc;
+ struct scsi_user_cdb suc;
+ struct scsi_sense *sp;
+
+ again:
+ suc.suc_flags = SCSI_MMC_DATA_READ == e_direction ?
+ SUC_READ : SUC_WRITE;
+ suc.suc_cdblen = i_cdb;
+ memcpy(suc.suc_cdb, p_cdb, i_cdb);
+ suc.suc_data = p_buf;
+ suc.suc_datalen = i_buf;
+ suc.suc_timeout = msecs2secs(i_timeout_ms);
+ if (ioctl(p_env->gen.fd, SCSIRAWCDB, &suc) == -1)
+ return(errno);
+ i_status = suc.suc_sus.sus_status;
+
+#if 0
+ /*
+ * If the device returns a scsi sense error and debugging is enabled print
+ * some hopefully useful information on stderr.
+ */
+ if (i_status && debug)
+ {
+ unsigned char *cp;
+ int i;
+ cp = suc.suc_sus.sus_sense;
+ fprintf(stderr,"i_status = %x cdb =",
+ i_status);
+ for (i = 0; i < cdblen; i++)
+ fprintf(stderr, " %x", cgc->cdb[i]);
+ fprintf(stderr, "\nsense =");
+ for (i = 0; i < 16; i++)
+ fprintf(stderr, " %x", cp[i]);
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ /*
+ * HACK! Some drives return a silly "medium changed" on the first
+ * command AND a non-zero i_status which gets turned into a fatal
+ * (EIO) error even though the operation was a success. Retrying
+ * the operation clears the media changed status and gets the
+ * answer. */
+
+ sp = (struct scsi_sense *)&suc.suc_sus.sus_sense;
+ i_asc = XSENSE_ASC(sp);
+ if (i_status == STS_CHECKCOND && i_asc == 0x28)
+ goto again;
+#if 0
+ if (cgc->sus)
+ memcpy(cgc->sus, &suc.suc_sus, sizeof (struct scsi_user_sense));
+#endif
+
+ return(i_status);
+}
+
+
+
/* Check a drive to see if it is a CD-ROM
Return 1 if a CD-ROM. 0 if it exists but isn't a CD-ROM drive
and -1 if no device exists .
@@ -119,68 +198,68 @@ cdio_is_cdrom(char *drive, char *mnttype)
Initialize CD device.
*/
static bool
-_cdio_init (_img_private_t *_obj)
+_cdio_init (_img_private_t *p_env)
{
- if (_obj->gen.init) {
- cdio_error ("init called more than once");
+ if (p_env->gen.init) {
+ cdio_warn ("init called more than once");
return false;
}
- _obj->gen.fd = open (_obj->source_name, O_RDONLY, 0);
+ p_env->gen.fd = open (p_env->gen.source_name, O_RDONLY, 0);
- if (_obj->gen.fd < 0)
+ if (p_env->gen.fd < 0)
{
- cdio_error ("open (%s): %s", _obj->source_name, strerror (errno));
+ cdio_warn ("open (%s): %s", p_env->gen.source_name, strerror (errno));
return false;
}
- _obj->gen.init = true;
- _obj->toc_init = false;
+ p_env->gen.init = true;
+ p_env->gen.toc_init = false;
return true;
}
/* Read audio sectors
*/
static int
-_read_audio_sectors (void *env, void *data, lsn_t lsn,
- unsigned int nblocks)
+_read_audio_sectors_bsdi (void *user_data, void *data, lsn_t lsn,
+ unsigned int nblocks)
{
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
msf_t _msf;
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
- msf->cdmsf_min0 = from_bcd8(_msf.m);
- msf->cdmsf_sec0 = from_bcd8(_msf.s);
- msf->cdmsf_frame0 = from_bcd8(_msf.f);
+ msf->cdmsf_min0 = cdio_from_bcd8(_msf.m);
+ msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s);
+ msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f);
- if (_obj->gen.ioctls_debugged == 75)
+ if (p_env->gen.ioctls_debugged == 75)
cdio_debug ("only displaying every 75th ioctl from now on");
- if (_obj->gen.ioctls_debugged == 30 * 75)
+ if (p_env->gen.ioctls_debugged == 30 * 75)
cdio_debug ("only displaying every 30*75th ioctl from now on");
- if (_obj->gen.ioctls_debugged < 75
- || (_obj->gen.ioctls_debugged < (30 * 75)
- && _obj->gen.ioctls_debugged % 75 == 0)
- || _obj->gen.ioctls_debugged % (30 * 75) == 0)
+ if (p_env->gen.ioctls_debugged < 75
+ || (p_env->gen.ioctls_debugged < (30 * 75)
+ && p_env->gen.ioctls_debugged % 75 == 0)
+ || p_env->gen.ioctls_debugged % (30 * 75) == 0)
cdio_debug ("reading %2.2d:%2.2d:%2.2d",
msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0);
- _obj->gen.ioctls_debugged++;
+ p_env->gen.ioctls_debugged++;
- switch (_obj->access_mode) {
+ switch (p_env->access_mode) {
case _AM_NONE:
- cdio_error ("no way to read audio");
+ cdio_warn ("no way to read audio");
return 1;
break;
case _AM_IOCTL: {
unsigned int i;
for (i=0; i < nblocks; i++) {
- if (ioctl (_obj->gen.fd, CDROMREADRAW, &buf) == -1) {
+ if (ioctl (p_env->gen.fd, CDROMREADRAW, &buf) == -1) {
perror ("ioctl()");
return 1;
/* exit (EXIT_FAILURE); */
@@ -200,19 +279,15 @@ _read_audio_sectors (void *env, void *data, lsn_t lsn,
from lsn. Returns 0 if no error.
*/
static int
-_cdio_read_mode1_sector (void *env, void *data, lsn_t lsn,
+_read_mode1_sector_bsdi (void *user_data, void *data, lsn_t lsn,
bool b_form2)
{
- char buf[M2RAW_SECTOR_SIZE] = { 0, };
#if FIXED
+ char buf[M2RAW_SECTOR_SIZE] = { 0, };
do something here.
#else
- if (0 > cdio_generic_lseek(env, CDIO_CD_FRAMESIZE*lsn, SEEK_SET))
- return -1;
- if (0 > cdio_generic_read(env, buf, CDIO_CD_FRAMESIZE))
- return -1;
- memcpy (data, buf, b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE);
+ return cdio_generic_read_form1_sector(user_data, data, lsn);
#endif
return 0;
}
@@ -223,16 +298,16 @@ _cdio_read_mode1_sector (void *env, void *data, lsn_t lsn,
Returns 0 if no error.
*/
static int
-_cdio_read_mode1_sectors (void *env, void *data, lsn_t lsn,
+_read_mode1_sectors_bsdi (void *user_data, void *data, lsn_t lsn,
bool b_form2, unsigned int nblocks)
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
unsigned int i;
int retval;
unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
for (i = 0; i < nblocks; i++) {
- if ( (retval = _cdio_read_mode1_sector (_obj,
+ if ( (retval = _read_mode1_sector_bsdi (p_env,
((char *)data) + (blocksize * i),
lsn + i, b_form2)) )
return retval;
@@ -245,44 +320,44 @@ _cdio_read_mode1_sectors (void *env, void *data, lsn_t lsn,
from lsn. Returns 0 if no error.
*/
static int
-_cdio_read_mode2_sector (void *env, void *data, lsn_t lsn,
+_read_mode2_sector_bsdi (void *user_data, void *data, lsn_t lsn,
bool b_form2)
{
char buf[M2RAW_SECTOR_SIZE] = { 0, };
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
msf_t _msf;
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
- msf->cdmsf_min0 = from_bcd8(_msf.m);
- msf->cdmsf_sec0 = from_bcd8(_msf.s);
- msf->cdmsf_frame0 = from_bcd8(_msf.f);
+ msf->cdmsf_min0 = cdio_from_bcd8(_msf.m);
+ msf->cdmsf_sec0 = cdio_from_bcd8(_msf.s);
+ msf->cdmsf_frame0 = cdio_from_bcd8(_msf.f);
- if (_obj->gen.ioctls_debugged == 75)
+ if (p_env->gen.ioctls_debugged == 75)
cdio_debug ("only displaying every 75th ioctl from now on");
- if (_obj->gen.ioctls_debugged == 30 * 75)
+ if (p_env->gen.ioctls_debugged == 30 * 75)
cdio_debug ("only displaying every 30*75th ioctl from now on");
- if (_obj->gen.ioctls_debugged < 75
- || (_obj->gen.ioctls_debugged < (30 * 75)
- && _obj->gen.ioctls_debugged % 75 == 0)
- || _obj->gen.ioctls_debugged % (30 * 75) == 0)
+ if (p_env->gen.ioctls_debugged < 75
+ || (p_env->gen.ioctls_debugged < (30 * 75)
+ && p_env->gen.ioctls_debugged % 75 == 0)
+ || p_env->gen.ioctls_debugged % (30 * 75) == 0)
cdio_debug ("reading %2.2d:%2.2d:%2.2d",
msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0);
- _obj->gen.ioctls_debugged++;
+ p_env->gen.ioctls_debugged++;
- switch (_obj->access_mode)
+ switch (p_env->access_mode)
{
case _AM_NONE:
- cdio_error ("no way to read mode2");
+ cdio_warn ("no way to read mode2");
return 1;
break;
case _AM_IOCTL:
- if (ioctl (_obj->gen.fd, CDROMREADMODE2, &buf) == -1)
+ if (ioctl (p_env->gen.fd, CDROMREADMODE2, &buf) == -1)
{
perror ("ioctl()");
return 1;
@@ -305,27 +380,20 @@ _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn,
Returns 0 if no error.
*/
static int
-_cdio_read_mode2_sectors (void *env, void *data, lsn_t lsn,
+_read_mode2_sectors_bsdi (void *user_data, void *data, lsn_t lsn,
bool b_form2, unsigned int nblocks)
{
- _img_private_t *_obj = env;
- int i;
- int retval;
+ _img_private_t *p_env = user_data;
+ unsigned int i;
+ unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
+ /* For each frame, pick out the data part we need */
for (i = 0; i < nblocks; i++) {
- if (b_form2) {
- if ( (retval = _cdio_read_mode2_sector (_obj,
- ((char *)data) + (M2RAW_SECTOR_SIZE * i),
- lsn + i, true)) )
- return retval;
- } else {
- char buf[M2RAW_SECTOR_SIZE] = { 0, };
- if ( (retval = _cdio_read_mode2_sector (_obj, buf, lsn + i, true)) )
- return retval;
-
- memcpy (((char *)data) + (CDIO_CD_FRAMESIZE * i),
- buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);
- }
+ int retval = _read_mode2_sector_bsdi(p_env,
+ ((char *)data) +
+ (i_blocksize * i),
+ lsn + i, b_form2);
+ if (retval) return retval;
}
return 0;
}
@@ -334,16 +402,16 @@ _cdio_read_mode2_sectors (void *env, void *data, lsn_t lsn,
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
-_cdio_stat_size (void *env)
+_stat_size_bsdi (void *user_data)
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
struct cdrom_tocentry tocent;
uint32_t size;
tocent.cdte_track = CDIO_CDROM_LEADOUT_TRACK;
tocent.cdte_format = CDROM_LBA;
- if (ioctl (_obj->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
+ if (ioctl (p_env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
{
perror ("ioctl(CDROMREADTOCENTRY)");
exit (EXIT_FAILURE);
@@ -358,25 +426,25 @@ _cdio_stat_size (void *env)
Set the key "arg" to "value" in source device.
*/
static int
-_cdio_set_arg (void *env, const char key[], const char value[])
+_set_arg_bsdi (void *user_data, const char key[], const char value[])
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
if (!strcmp (key, "source"))
{
if (!value)
return -2;
- free (_obj->source_name);
+ free (p_env->gen.source_name);
- _obj->source_name = strdup (value);
+ p_env->gen.source_name = strdup (value);
}
else if (!strcmp (key, "access-mode"))
{
if (!strcmp(value, "IOCTL"))
- _obj->access_mode = _AM_IOCTL;
+ p_env->access_mode = _AM_IOCTL;
else
- cdio_error ("unknown access type: %s. ignored.", value);
+ cdio_warn ("unknown access type: %s. ignored.", value);
}
else
return -1;
@@ -389,29 +457,33 @@ _cdio_set_arg (void *env, const char key[], const char value[])
Return false if successful or true if an error.
*/
static bool
-_cdio_read_toc (_img_private_t *_obj)
+read_toc_bsdi (void *p_user_data)
{
+ _img_private_t *p_env = p_user_data;
int i;
/* read TOC header */
- if ( ioctl(_obj->gen.fd, CDROMREADTOCHDR, &_obj->tochdr) == -1 ) {
- cdio_error("%s: %s\n",
+ if ( ioctl(p_env->gen.fd, CDROMREADTOCHDR, &p_env->tochdr) == -1 ) {
+ cdio_warn("%s: %s\n",
"error in ioctl CDROMREADTOCHDR", strerror(errno));
return false;
}
+ p_env->gen.i_first_track = p_env->tochdr.cdth_trk0;
+ p_env->gen.i_tracks = p_env->tochdr.cdth_trk1;
+
/* read individual tracks */
- for (i= FIRST_TRACK_NUM; i<=TOTAL_TRACKS; i++) {
- _obj->tocent[i-1].cdte_track = i;
- _obj->tocent[i-1].cdte_format = CDROM_MSF;
- if ( ioctl(_obj->gen.fd, CDROMREADTOCENTRY, &_obj->tocent[i-1]) == -1 ) {
- cdio_error("%s %d: %s\n",
+ for (i= p_env->gen.i_first_track; i<=p_env->gen.i_tracks; i++) {
+ p_env->tocent[i-1].cdte_track = i;
+ p_env->tocent[i-1].cdte_format = CDROM_MSF;
+ if (ioctl(p_env->gen.fd, CDROMREADTOCENTRY, &p_env->tocent[i-1]) == -1) {
+ cdio_warn("%s %d: %s\n",
"error in ioctl CDROMREADTOCENTRY for track",
i, strerror(errno));
return false;
}
/****
- struct cdrom_msf0 *msf= &_obj->tocent[i-1].cdte_addr.msf;
+ struct cdrom_msf0 *msf= &p_env->tocent[i-1].cdte_addr.msf;
fprintf (stdout, "--- track# %d (msf %2.2x:%2.2x:%2.2x)\n",
i, msf->minute, msf->second, msf->frame);
@@ -420,24 +492,25 @@ _cdio_read_toc (_img_private_t *_obj)
}
/* read the lead-out track */
- _obj->tocent[TOTAL_TRACKS].cdte_track = CDIO_CDROM_LEADOUT_TRACK;
- _obj->tocent[TOTAL_TRACKS].cdte_format = CDROM_MSF;
+ p_env->tocent[p_env->gen.i_tracks].cdte_track = CDIO_CDROM_LEADOUT_TRACK;
+ p_env->tocent[p_env->gen.i_tracks].cdte_format = CDROM_MSF;
- if (ioctl(_obj->gen.fd, CDROMREADTOCENTRY,
- &_obj->tocent[TOTAL_TRACKS]) == -1 ) {
- cdio_error("%s: %s\n",
+ if (ioctl(p_env->gen.fd, CDROMREADTOCENTRY,
+ &p_env->tocent[p_env->gen.i_tracks]) == -1 ) {
+ cdio_warn("%s: %s\n",
"error in ioctl CDROMREADTOCENTRY for lead-out",
strerror(errno));
return false;
}
/*
- struct cdrom_msf0 *msf= &_obj->tocent[TOTAL_TRACKS].cdte_addr.msf;
+ struct cdrom_msf0 *msf= &p_env->tocent[p_env->gen.i_tracks].cdte_addr.msf;
fprintf (stdout, "--- track# %d (msf %2.2x:%2.2x:%2.2x)\n",
i, msf->minute, msf->second, msf->frame);
*/
+ p_env->gen.toc_init = true;
return true;
}
@@ -446,32 +519,32 @@ _cdio_read_toc (_img_private_t *_obj)
also free obj.
*/
static int
-_cdio_eject_media (void *env) {
+_eject_media_bsdi (void *user_data) {
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
int ret=2;
int status;
int fd;
- close(_obj->gen.fd);
- _obj->gen.fd = -1;
- if ((fd = open (_obj->source_name, O_RDONLY|O_NONBLOCK)) > -1) {
+ close(p_env->gen.fd);
+ p_env->gen.fd = -1;
+ if ((fd = open (p_env->gen.source_name, O_RDONLY|O_NONBLOCK)) > -1) {
if((status = ioctl(fd, CDROM_DRIVE_STATUS, (void *) CDSL_CURRENT)) > 0) {
switch(status) {
case CDS_TRAY_OPEN:
if((ret = ioctl(fd, CDROMCLOSETRAY, 0)) != 0) {
- cdio_error ("ioctl CDROMCLOSETRAY failed: %s\n", strerror(errno));
+ cdio_warn ("ioctl CDROMCLOSETRAY failed: %s\n", strerror(errno));
}
break;
case CDS_DISC_OK:
if((ret = ioctl(fd, CDROMEJECT, 0)) != 0) {
- cdio_error("ioctl CDROMEJECT failed: %s\n", strerror(errno));
+ cdio_warn("ioctl CDROMEJECT failed: %s\n", strerror(errno));
}
break;
}
ret=0;
} else {
- cdio_error ("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno));
+ cdio_warn ("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno));
ret=1;
}
close(fd);
@@ -483,14 +556,14 @@ _cdio_eject_media (void *env) {
Return the value associated with the key "arg".
*/
static const char *
-_cdio_get_arg (void *env, const char key[])
+_get_arg_bsdi (void *user_data, const char key[])
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
if (!strcmp (key, "source")) {
- return _obj->source_name;
+ return p_env->gen.source_name;
} else if (!strcmp (key, "access-mode")) {
- switch (_obj->access_mode) {
+ switch (p_env->access_mode) {
case _AM_IOCTL:
return "ioctl";
case _AM_NONE:
@@ -501,68 +574,42 @@ _cdio_get_arg (void *env, const char key[])
}
/*!
- Return the number of of the first track.
- CDIO_INVALID_TRACK is returned on error.
-*/
-static track_t
-_cdio_get_first_track_num(void *env)
-{
- _img_private_t *_obj = env;
-
- if (!_obj->toc_init) _cdio_read_toc (_obj) ;
-
- return FIRST_TRACK_NUM;
-}
-
-/*!
Return the media catalog number MCN.
Note: string is malloc'd so caller should free() then returned
string when done with it.
*/
static char *
-_cdio_get_mcn (void *env) {
+_get_mcn_bsdi (const void *user_data) {
struct cdrom_mcn mcn;
- _img_private_t *_obj = env;
- if (ioctl(_obj->gen.fd, CDROM_GET_MCN, &mcn) != 0)
+ const _img_private_t *p_env = user_data;
+ if (ioctl(p_env->gen.fd, CDROM_GET_MCN, &mcn) != 0)
return NULL;
return strdup(mcn.medium_catalog_number);
}
-/*!
- Return the number of tracks in the current medium.
- CDIO_INVALID_TRACK is returned on error.
-*/
-static track_t
-_cdio_get_num_tracks(void *env)
-{
- _img_private_t *_obj = env;
-
- if (!_obj->toc_init) _cdio_read_toc (_obj) ;
-
- return TOTAL_TRACKS;
-}
-
/*!
Get format of track.
*/
static track_format_t
-_cdio_get_track_format(void *env, track_t track_num)
+get_track_format_bsdi(void *user_data, track_t i_track)
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
- if (!_obj->toc_init) _cdio_read_toc (_obj) ;
+ if (!p_env->gen.toc_init) read_toc_bsdi (p_env) ;
- if (track_num > TOTAL_TRACKS || track_num == 0)
+ if (i_track > p_env->gen.i_tracks || i_track == 0)
return TRACK_FORMAT_ERROR;
+ i_track -= p_env->gen.i_first_track;
+
/* This is pretty much copied from the "badly broken" cdrom_count_tracks
in linux/cdrom.c.
*/
- if (_obj->tocent[track_num-1].cdte_ctrl & CDROM_DATA_TRACK) {
- if (_obj->tocent[track_num-1].cdte_format == 0x10)
+ if (p_env->tocent[i_track].cdte_ctrl & CDROM_DATA_TRACK) {
+ if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_CDI_TRACK)
return TRACK_FORMAT_CDI;
- else if (_obj->tocent[track_num-1].cdte_format == 0x20)
+ else if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_XA_TRACK)
return TRACK_FORMAT_XA;
else
return TRACK_FORMAT_DATA;
@@ -580,48 +627,52 @@ _cdio_get_track_format(void *env, track_t track_num)
FIXME: there's gotta be a better design for this and get_track_format?
*/
static bool
-_cdio_get_track_green(void *env, track_t track_num)
+_get_track_green_bsdi(void *user_data, track_t i_track)
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
- if (!_obj->toc_init) _cdio_read_toc (_obj) ;
+ if (!p_env->gen.toc_init) read_toc_bsdi (p_env) ;
- if (track_num == CDIO_CDROM_LEADOUT_TRACK) track_num = TOTAL_TRACKS+1;
+ if (i_track == CDIO_CDROM_LEADOUT_TRACK) i_track = p_env->gen.i_tracks+1;
- if (track_num > TOTAL_TRACKS+1 || track_num == 0)
+ if (i_track > p_env->gen.i_tracks+1 || i_track == 0)
return false;
/* FIXME: Dunno if this is the right way, but it's what
I was using in cdinfo for a while.
*/
- return ((_obj->tocent[track_num-1].cdte_ctrl & 2) != 0);
+ return ((p_env->tocent[i_track-1].cdte_ctrl & 2) != 0);
}
/*!
Return the starting MSF (minutes/secs/frames) for track number
- track_num in obj. Track numbers start at 1.
+ i_track in obj. Track numbers start at 1.
The "leadout" track is specified either by
- using track_num LEADOUT_TRACK or the total tracks+1.
+ using i_track LEADOUT_TRACK or the total tracks+1.
False is returned if there is no track entry.
*/
static bool
-_cdio_get_track_msf(void *env, track_t track_num, msf_t *msf)
+_get_track_msf_bsdi(void *user_data, track_t i_track, msf_t *msf)
{
- _img_private_t *_obj = env;
+ _img_private_t *p_env = user_data;
if (NULL == msf) return false;
- if (!_obj->toc_init) _cdio_read_toc (_obj) ;
+ if (!p_env->gen.toc_init) read_toc_bsdi (p_env) ;
- if (track_num == CDIO_CDROM_LEADOUT_TRACK) track_num = TOTAL_TRACKS+1;
+ if (i_track == CDIO_CDROM_LEADOUT_TRACK) i_track = p_env->gen.i_tracks+1;
- if (track_num > TOTAL_TRACKS+1 || track_num == 0) {
+ if (i_track > p_env->gen.i_tracks+1 || i_track == 0) {
return false;
- } else {
- struct cdrom_msf0 *msf0= &_obj->tocent[track_num-1].cdte_addr.msf;
- msf->m = to_bcd8(msf0->minute);
- msf->s = to_bcd8(msf0->second);
- msf->f = to_bcd8(msf0->frame);
+ }
+
+ i_track -= p_env->gen.i_first_track;
+
+ {
+ struct cdrom_msf0 *msf0= &p_env->tocent[i_track].cdte_addr.msf;
+ msf->m = cdio_to_bcd8(msf0->minute);
+ msf->s = cdio_to_bcd8(msf0->second);
+ msf->f = cdio_to_bcd8(msf0->frame);
return true;
}
}
@@ -690,46 +741,85 @@ cdio_get_default_device_bsdi(void)
ones to set that up.
*/
CdIo *
-cdio_open_bsdi (const char *source_name)
+cdio_open_am_bsdi (const char *psz_source_name, const char *psz_access_mode)
+{
+ if (psz_access_mode != NULL)
+ cdio_warn ("there is only one access mode for bsdi. Arg %s ignored",
+ psz_access_mode);
+ return cdio_open_bsdi(psz_source_name);
+}
+
+
+/*!
+ Initialization routine. This is the only thing that doesn't
+ get called via a function pointer. In fact *we* are the
+ ones to set that up.
+ */
+CdIo *
+cdio_open_bsdi (const char *psz_orig_source)
{
#ifdef HAVE_BSDI_CDROM
CdIo *ret;
_img_private_t *_data;
+ char *psz_source;
cdio_funcs _funcs = {
- .eject_media = _cdio_eject_media,
+ .eject_media = _eject_media_bsdi,
.free = cdio_generic_free,
- .get_arg = _cdio_get_arg,
+ .get_arg = _get_arg_bsdi,
+ .get_cdtext = get_cdtext_generic,
.get_default_device = cdio_get_default_device_bsdi,
.get_devices = cdio_get_devices_bsdi,
- .get_first_track_num= _cdio_get_first_track_num,
- .get_mcn = _cdio_get_mcn,
- .get_num_tracks = _cdio_get_num_tracks,
- .get_track_format = _cdio_get_track_format,
- .get_track_green = _cdio_get_track_green,
+ .get_drive_cap = scsi_mmc_get_drive_cap_generic,
+ .get_discmode = get_discmode_generic,
+ .get_first_track_num= get_first_track_num_generic,
+ .get_hwinfo = NULL,
+ .get_mcn = _get_mcn_bsdi,
+ .get_num_tracks = get_num_tracks_generic,
+ .get_track_format = get_track_format_bsdi,
+ .get_track_green = _get_track_green_bsdi,
.get_track_lba = NULL, /* This could be implemented if need be. */
- .get_track_msf = _cdio_get_track_msf,
+ .get_track_msf = _get_track_msf_bsdi,
.lseek = cdio_generic_lseek,
.read = cdio_generic_read,
- .read_audio_sectors = _read_audio_sectors,
- .read_mode1_sector = _cdio_read_mode1_sector,
- .read_mode1_sectors = _cdio_read_mode1_sectors,
- .read_mode2_sector = _cdio_read_mode2_sector,
- .read_mode2_sectors = _cdio_read_mode2_sectors,
- .set_arg = _cdio_set_arg,
- .stat_size = _cdio_stat_size
+ .read_audio_sectors = _read_audio_sectors_bsdi,
+ .read_mode1_sector = _read_mode1_sector_bsdi,
+ .read_mode1_sectors = _read_mode1_sectors_bsdi,
+ .read_mode2_sector = _read_mode2_sector_bsdi,
+ .read_mode2_sectors = _read_mode2_sectors_bsdi,
+ .read_toc = &read_toc_bsdi,
+ .run_scsi_mmc_cmd = &run_scsi_cmd_bsdi,
+ .set_arg = _set_arg_bsdi,
+ .stat_size = _stat_size_bsdi
};
_data = _cdio_malloc (sizeof (_img_private_t));
_data->access_mode = _AM_IOCTL;
_data->gen.init = false;
_data->gen.fd = -1;
+ _data->gen.toc_init = false;
+ _data->gen.b_cdtext_init = false;
+ _data->gen.b_cdtext_error = false;
+
+ if (NULL == psz_orig_source) {
+ psz_source=cdio_get_default_device_linux();
+ if (NULL == psz_source) return NULL;
+ _set_arg_bsdi(_data, "source", psz_source);
+ free(psz_source);
+ } else {
+ if (cdio_is_device_generic(psz_orig_source))
+ _set_arg_bsdi(_data, "source", psz_orig_source);
+ else {
+ /* The below would be okay if all device drivers worked this way. */
+#if 0
+ cdio_info ("source %s is not a device", psz_orig_source);
+#endif
+ return NULL;
+ }
+ }
- _cdio_set_arg(_data, "source", (NULL == source_name)
- ? DEFAULT_CDIO_DEVICE: source_name);
-
- ret = cdio_new (_data, &_funcs);
+ ret = cdio_new ( (void *) _data, &_funcs);
if (ret == NULL) return NULL;
if (_cdio_init(_data))
@@ -754,4 +844,3 @@ cdio_have_bsdi (void)
return false;
#endif /* HAVE_BSDI_CDROM */
}
-