stat_size -> get_disc_last_lsn. Now returns lsn_t and CDIO_INVALID_LSN

on error.

Add MMC version of get_disc_last_lsn.

More regularization of driver_return_code_t and get_disc_last_lsn

There's probably some small driver breakage which will be fixed soon.
This commit is contained in:
rocky
2005-01-24 00:06:31 +00:00
parent 19856a30da
commit 798929000d
20 changed files with 610 additions and 571 deletions

4
NEWS
View File

@@ -8,7 +8,7 @@
- cd-info now shows the total disc size.
- Filesystem reorganization to better support growth and paranoia inclusion
- FreeBSD 6 tolerated, CAM audio read mode works.
- improve Win32 driver
- improve Win32 driver, e.g. audio read mode works better for ioctl.
- mode detection fixes
- all read routines check and adjust the lsn so we don't try to access
beyond the end of the disc
@@ -171,4 +171,4 @@
0.1
Routines split off from VCDImager.
$Id: NEWS,v 1.62 2005/01/23 00:02:15 rocky Exp $
$Id: NEWS,v 1.63 2005/01/24 00:06:31 rocky Exp $

View File

@@ -1,5 +1,5 @@
/* -*- c -*-
$Id: disc.h,v 1.3 2005/01/09 16:07:46 rocky Exp $
$Id: disc.h,v 1.4 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -40,9 +40,9 @@ extern "C" {
/*!
Get the lsn of the end of the CD
@return the leadout LSN or CDIO_INVALID_LSN if there is an error.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
unsigned int cdio_get_disc_last_lsn(const CdIo_t *p_cdio);
lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio);
/*!
@@ -70,13 +70,8 @@ extern "C" {
*/
track_t cdio_get_num_tracks (const CdIo_t *p_cdio);
/*!
Get the size of the CD in logical block address (LBA) units.
@param p_cdio the CD object queried
@return the size or 0 if there was an error.
*/
uint32_t cdio_stat_size (const CdIo_t *p_cdio);
/*! cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn */
#define cdio_stat_size cdio_get_disc_last_lsn
#ifdef __cplusplus
}

View File

@@ -1,5 +1,5 @@
/*
$Id: scsi_mmc.h,v 1.40 2005/01/20 04:46:25 rocky Exp $
$Id: scsi_mmc.h,v 1.41 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -378,7 +378,14 @@ int scsi_mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
@return 0 if successful.
*/
int scsi_mmc_eject_media( const CdIo_t *p_cdio);
int scsi_mmc_eject_media( const CdIo_t *p_cdio );
/*!
Get the lsn of the end of the CD
@return the lsn. On error return CDIO_INVALID_LSN.
*/
lsn_t scsi_mmc_get_disc_last_lsn( const CdIo_t *p_cdio );
/*!
Return the discmode as reported by the SCSI-MMC Read (FULL) TOC

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd.c,v 1.11 2005/01/23 19:16:58 rocky Exp $
$Id: freebsd.c,v 1.12 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd.c,v 1.11 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd.c,v 1.12 2005/01/24 00:06:31 rocky Exp $";
#include "freebsd.h"
@@ -142,18 +142,19 @@ _read_mode2_sectors_freebsd (void *user_data, void *data, lsn_t lsn,
/*!
Return the size of the CD in logical block address (LBA) units.
@return the lsn. On error return CDIO_INVALID_LSN.
*/
static uint32_t
_stat_size_freebsd (void *p_obj)
static lsn_t
get_disc_last_lsn_freebsd (void *p_obj)
{
_img_private_t *p_env = p_obj;
if (NULL == p_env) return CDIO_INVALID_LBA;
if (!p_env) return CDIO_INVALID_LSN;
if (_AM_CAM == p_env->access_mode)
return stat_size_freebsd_cam(p_env);
return get_disc_last_lsn_mmc(p_env);
else
return stat_size_freebsd_ioctl(p_env);
return get_disc_last_lsn_freebsd_ioctl(p_env);
}
/*!
@@ -582,6 +583,7 @@ cdio_open_am_freebsd (const char *psz_orig_source_name,
.get_cdtext = get_cdtext_generic,
.get_default_device = cdio_get_default_device_freebsd,
.get_devices = cdio_get_devices_freebsd,
.get_disc_last_lsn = get_disc_last_lsn_freebsd
.get_discmode = get_discmode_generic,
.get_drive_cap = get_drive_cap_freebsd,
.get_first_track_num = get_first_track_num_generic,
@@ -604,7 +606,6 @@ cdio_open_am_freebsd (const char *psz_orig_source_name,
.set_arg = _set_arg_freebsd,
.set_blocksize = set_blocksize_mmc,
.set_speed = set_speed_freebsd,
.stat_size = _stat_size_freebsd
};
_data = _cdio_malloc (sizeof (_img_private_t));

View File

@@ -1,7 +1,7 @@
/*
$Id: freebsd_cam.c,v 1.2 2005/01/20 05:07:00 rocky Exp $
$Id: freebsd_cam.c,v 1.3 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.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
@@ -26,7 +26,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.2 2005/01/20 05:07:00 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.3 2005/01/24 00:06:31 rocky Exp $";
#ifdef HAVE_FREEBSD_CDROM
@@ -155,7 +155,7 @@ free_freebsd_cam (void *user_data)
free (p_env);
}
int
static driver_return_code_t
read_mode2_sector_freebsd_cam (_img_private_t *p_env, void *data, lsn_t lsn,
bool b_form2)
{
@@ -167,7 +167,7 @@ read_mode2_sector_freebsd_cam (_img_private_t *p_env, void *data, lsn_t lsn,
int retval = read_mode2_sectors_freebsd_cam(p_env, buf, lsn, 1);
if ( retval ) return retval;
memcpy (((char *)data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);
return 0;
return DRIVER_OP_SUCCESS;
}
}
@@ -195,19 +195,18 @@ read_mode2_sectors_freebsd_cam (_img_private_t *p_env, void *p_buf,
return retval;
if ((retval = run_scsi_cmd_freebsd_cam (p_env, 0,
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb,
SCSI_MMC_DATA_READ,
M2RAW_SECTOR_SIZE * nblocks,
p_buf)))
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb,
SCSI_MMC_DATA_READ,
M2RAW_SECTOR_SIZE * nblocks,
p_buf)))
{
scsi_mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE);
return retval;
}
if ((retval = scsi_mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE)))
return retval;
} else
return scsi_mmc_set_blocksize (p_env->gen.cdio, CDIO_CD_FRAMESIZE);
} else {
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);
CDIO_MMC_SET_READ_LENGTH24(cdb.field, nblocks);
cdb.field[1] = 0; /* sector size mode2 */
@@ -218,55 +217,7 @@ read_mode2_sectors_freebsd_cam (_img_private_t *p_env, void *p_buf,
SCSI_MMC_DATA_READ,
M2RAW_SECTOR_SIZE * nblocks, p_buf);
return 0;
}
/*!
Return the size of the CD in logical block address (LBA) units.
*/
uint32_t
stat_size_freebsd_cam (_img_private_t *p_env)
{
scsi_mmc_cdb_t cdb = {{0, }};
uint8_t buf[12] = { 0, };
uint32_t retval;
int i_status;
/* Operation code */
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
cdb.field[1] = 0; /* lba; msf: 0x2 */
/* Format */
cdb.field[2] = CDIO_MMC_READTOC_FMT_TOC;
CDIO_MMC_SET_START_TRACK(cdb.field, CDIO_CDROM_LEADOUT_TRACK);
CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(buf));
p_env->ccb.csio.data_ptr = buf;
p_env->ccb.csio.dxfer_len = sizeof (buf);
i_status = run_scsi_cmd_freebsd_cam(p_env, DEFAULT_TIMEOUT_MSECS,
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb, SCSI_MMC_DATA_READ,
sizeof(buf), buf);
if (0 != i_status)
return 0;
{
int i;
retval = 0;
for (i = 8; i < 12; i++)
{
retval <<= 8;
retval += buf[i];
}
}
return retval;
}
/*!
@@ -284,23 +235,21 @@ eject_media_freebsd_cam (_img_private_t *p_env)
i_status = run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS,
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb, SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
if (i_status) return i_status;
cdb.field[4] = 1;
i_status = run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
if (i_status) return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 2; /* eject */
return run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS,
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
scsi_mmc_get_cmd_len(cdb.field[0]),
&cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
}
#endif /* HAVE_FREEBSD_CDROM */

View File

@@ -1,5 +1,5 @@
/*
$Id: freebsd_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $
$Id: freebsd_ioctl.c,v 1.2 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: freebsd_ioctl.c,v 1.1 2004/12/18 17:29:32 rocky Exp $";
static const char _rcsid[] = "$Id: freebsd_ioctl.c,v 1.2 2005/01/24 00:06:31 rocky Exp $";
#ifdef HAVE_FREEBSD_CDROM
@@ -120,8 +120,8 @@ read_mode2_sector_freebsd_ioctl (_img_private_t *env, void *data, lsn_t lsn,
/*!
Return the size of the CD in logical block address (LBA) units.
*/
uint32_t
stat_size_freebsd_ioctl (_img_private_t *_obj)
lsn_t
get_disc_last_lsn_freebsd_ioctl (_img_private_t *_obj)
{
struct ioc_read_toc_single_entry tocent;
uint32_t size;

View File

@@ -1,5 +1,5 @@
/*
$Id: win32.c,v 1.11 2005/01/23 17:14:33 rocky Exp $
$Id: win32.c,v 1.12 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -26,7 +26,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: win32.c,v 1.11 2005/01/23 17:14:33 rocky Exp $";
static const char _rcsid[] = "$Id: win32.c,v 1.12 2005/01/24 00:06:31 rocky Exp $";
#include <cdio/cdio.h>
#include <cdio/sector.h>
@@ -381,7 +381,7 @@ _cdio_read_mode2_sectors (void *p_user_data, void *data, lsn_t lsn,
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
stat_size_win32 (void *p_user_data)
get_disc_last_lsn_win32 (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
@@ -741,6 +741,7 @@ cdio_open_am_win32 (const char *psz_orig_source, const char *psz_access_mode)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_default_device = cdio_get_default_device_win32;
_funcs.get_devices = cdio_get_devices_win32;
_funcs.get_disc_last_lsn = get_disc_last_lsn_win32;
_funcs.get_discmode = get_discmode_win32;
_funcs.get_drive_cap = get_drive_cap_mmc;
_funcs.get_first_track_num = get_first_track_num_generic;
@@ -766,7 +767,6 @@ cdio_open_am_win32 (const char *psz_orig_source, const char *psz_access_mode)
_funcs.set_arg = set_arg_win32;
_funcs.set_blocksize = set_blocksize_mmc;
_funcs.set_speed = set_speed_mmc;
_funcs.stat_size = stat_size_win32;
_data = _cdio_malloc (sizeof (_img_private_t));
_data->access_mode = str_to_access_mode_win32(psz_access_mode);

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_aix.c,v 1.6 2005/01/23 19:16:58 rocky Exp $
$Id: _cdio_aix.c,v 1.7 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
@@ -37,7 +37,7 @@
#ifdef HAVE_AIX_CDROM
static const char _rcsid[] = "$Id: _cdio_aix.c,v 1.6 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_aix.c,v 1.7 2005/01/24 00:06:31 rocky Exp $";
#ifdef HAVE_GLOB_H
#include <glob.h>
@@ -413,7 +413,7 @@ _read_mode2_sectors_aix (void *p_user_data, void *data, lsn_t lsn,
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_cdio_stat_size (void *p_user_data)
get_disc_last_lsn_aix (void *p_user_data)
{
uint32_t i_size=0;
#ifdef FINISHED
@@ -941,6 +941,7 @@ cdio_open_am_aix (const char *psz_orig_source, const char *access_mode)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_default_device = cdio_get_default_device_aix;
_funcs.get_devices = cdio_get_devices_aix;
_funcs.get_disc_last_lsn = get_disc_last_lsn_aix;
_funcs.get_discmode = get_discmode_aix;
_funcs.get_drive_cap = get_drive_cap_mmc;
_funcs.get_first_track_num= get_first_track_num_generic;
@@ -960,7 +961,6 @@ cdio_open_am_aix (const char *psz_orig_source, const char *access_mode)
_funcs.read_mode2_sectors = _read_mode2_sectors_aix;
_funcs.read_toc = read_toc_aix;
_funcs.run_scsi_mmc_cmd = run_scsi_cmd_aix;
_funcs.stat_size = _cdio_stat_size;
_funcs.set_arg = _set_arg_aix;
_data = _cdio_malloc (sizeof (_img_private_t));

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_bsdi.c,v 1.8 2005/01/23 19:16:58 rocky Exp $
$Id: _cdio_bsdi.c,v 1.9 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.8 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.9 2005/01/24 00:06:31 rocky Exp $";
#include <cdio/logging.h>
#include <cdio/sector.h>
@@ -271,7 +271,7 @@ _read_audio_sectors_bsdi (void *user_data, void *data, lsn_t lsn,
}
}
return 0;
return DRIVER_OP_SUCCESS;
}
/*!
@@ -289,7 +289,6 @@ _read_mode1_sector_bsdi (void *user_data, void *data, lsn_t lsn,
#else
return cdio_generic_read_form1_sector(user_data, data, lsn);
#endif
return 0;
}
/*!
@@ -312,7 +311,7 @@ _read_mode1_sectors_bsdi (void *p_user_data, void *p_data, lsn_t lsn,
lsn + i, b_form2)) )
return retval;
}
return 0;
return DRIVER_OP_SUCCESS;
}
/*!
@@ -371,7 +370,7 @@ _read_mode2_sector_bsdi (void *p_user_data, void *p_data, lsn_t lsn,
else
memcpy (((char *)p_data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);
return 0;
return DRIVER_OP_SUCCESS;
}
/*!
@@ -395,14 +394,14 @@ _read_mode2_sectors_bsdi (void *user_data, void *data, lsn_t lsn,
lsn + i, b_form2);
if (retval) return retval;
}
return 0;
return DRIVER_OP_SUCCESS;
}
/*!
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_stat_size_bsdi (void *user_data)
get_disc_last_lsn_bsdi (void *user_data)
{
_img_private_t *p_env = user_data;
@@ -767,6 +766,7 @@ cdio_open_bsdi (const char *psz_orig_source)
.get_default_device = cdio_get_default_device_bsdi,
.get_devices = cdio_get_devices_bsdi,
.get_drive_cap = get_drive_cap_mmc,
.get_disc_last_lsn = get_disc_last_lsn_bsdi
.get_discmode = get_discmode_generic,
.get_first_track_num= get_first_track_num_generic,
.get_hwinfo = NULL,
@@ -786,7 +786,6 @@ cdio_open_bsdi (const char *psz_orig_source)
.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));

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_linux.c,v 1.18 2005/01/23 19:16:58 rocky Exp $
$Id: _cdio_linux.c,v 1.19 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.18 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.19 2005/01/24 00:06:31 rocky Exp $";
#include <string.h>
@@ -921,9 +921,10 @@ run_scsi_cmd_linux( void *p_user_data,
/*!
Return the size of the CD in logical block address (LBA) units.
@return the lsn. On error return CDIO_INVALID_LSN.
*/
static uint32_t
stat_size_linux (void *p_user_data)
static lsn_t
get_disc_last_lsn_linux (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
@@ -935,7 +936,7 @@ stat_size_linux (void *p_user_data)
if (ioctl (p_env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
{
perror ("ioctl(CDROMREADTOCENTRY)");
exit (EXIT_FAILURE);
return CDIO_INVALID_LSN;
}
i_size = tocent.cdte_addr.lba;
@@ -1138,6 +1139,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
.get_cdtext = get_cdtext_generic,
.get_default_device = cdio_get_default_device_linux,
.get_devices = cdio_get_devices_linux,
.get_disc_last_lsn = get_disc_last_lsn_linux,
.get_discmode = get_discmode_linux,
#if USE_LINUX_CAP
.get_drive_cap = get_drive_cap_linux,
@@ -1167,7 +1169,6 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
.set_arg = set_arg_linux,
.set_blocksize = set_blocksize_mmc,
.set_speed = set_speed_linux,
.stat_size = stat_size_linux
};
_data = _cdio_malloc (sizeof (_img_private_t));

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_osx.c,v 1.10 2005/01/21 23:12:54 rocky Exp $
$Id: _cdio_osx.c,v 1.11 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
from vcdimager code:
@@ -34,7 +34,7 @@
#include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.10 2005/01/21 23:12:54 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.11 2005/01/24 00:06:31 rocky Exp $";
#include <cdio/logging.h>
#include <cdio/sector.h>
@@ -1321,7 +1321,7 @@ _eject_media_osx (void *user_data) {
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_stat_size_osx (void *user_data)
_get_disc_last_lsn_osx (void *user_data)
{
return get_track_lba_osx(user_data, CDIO_CDROM_LEADOUT_TRACK);
}
@@ -1667,6 +1667,7 @@ cdio_open_osx (const char *psz_orig_source)
.get_cdtext = get_cdtext_osx,
.get_default_device = cdio_get_default_device_osx,
.get_devices = cdio_get_devices_osx,
.get_disc_last_lsn = _get_disc_last_lsn_osx
.get_discmode = get_discmode_osx,
.get_drive_cap = get_drive_cap_osx,
.get_first_track_num = get_first_track_num_generic,
@@ -1691,7 +1692,6 @@ cdio_open_osx (const char *psz_orig_source)
.run_scsi_mmc_cmd = run_scsi_cmd_osx,
.set_arg = _set_arg_osx,
.set_speed = set_speed_osx,
.stat_size = _stat_size_osx
};
_data = _cdio_malloc (sizeof (_img_private_t));

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_sunos.c,v 1.15 2005/01/23 19:16:58 rocky Exp $
$Id: _cdio_sunos.c,v 1.16 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -38,7 +38,7 @@
#ifdef HAVE_SOLARIS_CDROM
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.15 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.16 2005/01/24 00:06:31 rocky Exp $";
#ifdef HAVE_GLOB_H
#include <glob.h>
@@ -346,7 +346,7 @@ _read_mode2_sectors_solaris (void *p_user_data, void *data, lsn_t lsn,
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_cdio_stat_size (void *p_user_data)
get_disc_last_lsn_sunos (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
@@ -865,6 +865,7 @@ cdio_open_am_solaris (const char *psz_orig_source, const char *access_mode)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_default_device = cdio_get_default_device_solaris;
_funcs.get_devices = cdio_get_devices_solaris;
_funcs.get_disc_last_lsn = get_disc_last_lsn_sunos;
_funcs.get_discmode = get_discmode_solaris;
_funcs.get_drive_cap = get_drive_cap_mmc;
_funcs.get_first_track_num = get_first_track_num_generic;
@@ -887,11 +888,9 @@ cdio_open_am_solaris (const char *psz_orig_source, const char *access_mode)
_funcs.read_mode2_sectors = _read_mode2_sectors_solaris;
_funcs.read_toc = read_toc_solaris;
_funcs.run_scsi_mmc_cmd = run_scsi_cmd_solaris;
_funcs.stat_size = _cdio_stat_size;
_funcs.set_arg = _set_arg_solaris;
_funcs.set_blocksize = set_blocksize_mmc;
_funcs.set_speed = set_speed_solaris;
_funcs.stat_size = _cdio_stat_size;
_data = _cdio_malloc (sizeof (_img_private_t));

View File

@@ -1,5 +1,5 @@
/*
$Id: cdio_private.h,v 1.9 2005/01/21 02:59:32 rocky Exp $
$Id: cdio_private.h,v 1.10 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -101,6 +101,12 @@ extern "C" {
*/
char * (*get_default_device)(void);
/*!
Return the size of the CD in logical block address (LBA) units.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t (*get_disc_last_lsn) (void *p_env);
/*!
Get disc mode associated with cd_obj.
*/
@@ -170,7 +176,7 @@ extern "C" {
Set the drive speed. -1 is returned if we had an error.
-2 is returned if this is not implemented for the current driver.
*/
int (*p_get_speed) (void *p_env);
int (*get_speed) (void *p_env);
/*!
Return true if we have XA data (green, mode2 form1) or
@@ -290,11 +296,6 @@ extern "C" {
*/
int (*set_speed) ( void *p_env, int i_speed );
/*!
Return the size of the CD in logical block address (LBA) units.
*/
uint32_t (*stat_size) (void *p_env);
} cdio_funcs_t;

View File

@@ -1,5 +1,5 @@
/*
$Id: disc.c,v 1.3 2005/01/09 16:07:46 rocky Exp $
$Id: disc.c,v 1.4 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -45,19 +45,26 @@ const char *discmode2str[] = {
"CD-i"
};
unsigned int
cdio_get_disc_last_lsn(const CdIo *p_cdio)
/*!
Get the size of the CD in logical block address (LBA) units.
@param p_cdio the CD object queried
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t
cdio_get_disc_last_lsn(const CdIo_t *p_cdio)
{
return cdio_get_track_lsn(p_cdio, CDIO_CDROM_LEADOUT_TRACK);
if (!p_cdio) return CDIO_INVALID_LSN;
return p_cdio->op.get_disc_last_lsn (p_cdio->env);
}
/*!
Get medium associated with cd_obj.
*/
discmode_t
cdio_get_discmode (CdIo *cd_obj)
cdio_get_discmode (CdIo_t *cd_obj)
{
if (cd_obj == NULL) return CDIO_DISC_MODE_ERROR;
if (!cd_obj) return CDIO_DISC_MODE_ERROR;
if (cd_obj->op.get_discmode) {
return cd_obj->op.get_discmode (cd_obj->env);
@@ -72,7 +79,7 @@ cdio_get_discmode (CdIo *cd_obj)
then return NULL.
*/
char *
cdio_get_mcn (const CdIo *p_cdio)
cdio_get_mcn (const CdIo_t *p_cdio)
{
if (p_cdio->op.get_mcn) {
return p_cdio->op.get_mcn (p_cdio->env);
@@ -80,17 +87,3 @@ cdio_get_mcn (const CdIo *p_cdio)
return NULL;
}
}
/*!
Get the size of the CD in logical block address (LBA) units.
@param p_cdio the CD object queried
@return the size or 0 if there was an error.
*/
uint32_t
cdio_stat_size (const CdIo_t *p_cdio)
{
if (!p_cdio) return 0;
return p_cdio->op.stat_size (p_cdio->env);
}

View File

@@ -1,5 +1,5 @@
/*
$Id: bincue.c,v 1.6 2005/01/23 19:16:58 rocky Exp $
$Id: bincue.c,v 1.7 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@@ -26,7 +26,7 @@
(*.cue).
*/
static const char _rcsid[] = "$Id: bincue.c,v 1.6 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: bincue.c,v 1.7 2005/01/24 00:06:31 rocky Exp $";
#include "image.h"
#include "cdio_assert.h"
@@ -63,7 +63,7 @@ static const char _rcsid[] = "$Id: bincue.c,v 1.6 2005/01/23 19:16:58 rocky Exp
#define DEFAULT_CDIO_DEVICE "videocd.bin"
#define DEFAULT_CDIO_CUE "videocd.cue"
static uint32_t _stat_size_bincue (void *user_data);
static lsn_t get_disc_last_lsn_bincue (void *user_data);
#include "image_common.h"
static bool parse_cuefile (_img_private_t *cd, const char *toc_name);
@@ -83,7 +83,7 @@ _init_bincue (_img_private_t *env)
return false;
}
/* Have to set init before calling _stat_size_bincue() or we will
/* Have to set init before calling get_disc_last_lsn_bincue() or we will
get into infinite recursion calling passing right here.
*/
env->gen.init = true;
@@ -93,7 +93,7 @@ _init_bincue (_img_private_t *env)
cdtext_init (&(env->gen.cdtext));
lead_lsn = _stat_size_bincue( (_img_private_t *) env);
lead_lsn = get_disc_last_lsn_bincue( (_img_private_t *) env);
if (-1 == lead_lsn) return false;
@@ -216,10 +216,10 @@ _read_bincue (void *user_data, void *data, size_t size)
/*!
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_stat_size_bincue (void *user_data)
static lsn_t
get_disc_last_lsn_bincue (void *p_user_data)
{
_img_private_t *env = user_data;
_img_private_t *env = p_user_data;
long size;
size = cdio_stream_stat (env->gen.data_source);
@@ -1140,6 +1140,7 @@ cdio_open_cue (const char *psz_cue_name)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_devices = cdio_get_devices_bincue;
_funcs.get_default_device = cdio_get_default_device_bincue;
_funcs.get_disc_last_lsn = get_disc_last_lsn_bincue;
_funcs.get_discmode = _get_discmode_image;
_funcs.get_drive_cap = _get_drive_cap_image;
_funcs.get_first_track_num = _get_first_track_num_image;
@@ -1161,7 +1162,6 @@ cdio_open_cue (const char *psz_cue_name)
_funcs.read_mode2_sector = _read_mode2_sector_bincue;
_funcs.read_mode2_sectors = _read_mode2_sectors_bincue;
_funcs.set_arg = _set_arg_image;
_funcs.stat_size = _stat_size_bincue;
if (NULL == psz_cue_name) return NULL;

View File

@@ -1,5 +1,5 @@
/*
$Id: cdrdao.c,v 1.10 2005/01/23 19:16:58 rocky Exp $
$Id: cdrdao.c,v 1.11 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
toc reading routine adapted from cuetools
@@ -25,7 +25,7 @@
(*.cue).
*/
static const char _rcsid[] = "$Id: cdrdao.c,v 1.10 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: cdrdao.c,v 1.11 2005/01/24 00:06:31 rocky Exp $";
#include "image.h"
#include "cdio_assert.h"
@@ -66,7 +66,7 @@ static const char _rcsid[] = "$Id: cdrdao.c,v 1.10 2005/01/23 19:16:58 rocky Exp
#include "image_common.h"
static uint32_t _stat_size_cdrdao (void *p_user_data);
static lsn_t get_disc_last_lsn_cdrdao (void *p_user_data);
static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name);
@@ -100,7 +100,7 @@ _init_cdrdao (_img_private_t *env)
if (env->gen.init)
return false;
/* Have to set init before calling _stat_size_cdrdao() or we will
/* Have to set init before calling get_disc_last_lsn_cdrdao() or we will
get into infinite recursion calling passing right here.
*/
env->gen.init = true;
@@ -113,7 +113,7 @@ _init_cdrdao (_img_private_t *env)
/* Read in TOC sheet. */
if ( !parse_tocfile(env, env->psz_cue_name) ) return false;
lead_lsn = _stat_size_cdrdao( (_img_private_t *) env);
lead_lsn = get_disc_last_lsn_cdrdao( (_img_private_t *) env);
if (-1 == lead_lsn)
return false;
@@ -231,8 +231,8 @@ _read_cdrdao (void *user_data, void *data, size_t size)
/*!
Return the size of the CD in logical block address (LBA) units.
*/
static uint32_t
_stat_size_cdrdao (void *p_user_data)
static lsn_t
get_disc_last_lsn_cdrdao (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
track_t i_leadout = p_env->gen.i_tracks;
@@ -1268,6 +1268,7 @@ cdio_open_cdrdao (const char *psz_cue_name)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_devices = cdio_get_devices_cdrdao;
_funcs.get_default_device = cdio_get_default_device_cdrdao;
_funcs.get_disc_last_lsn = get_disc_last_lsn_cdrdao;
_funcs.get_discmode = _get_discmode_image;
_funcs.get_drive_cap = _get_drive_cap_image;
_funcs.get_first_track_num = _get_first_track_num_image;
@@ -1291,7 +1292,6 @@ cdio_open_cdrdao (const char *psz_cue_name)
_funcs.set_arg = _set_arg_image;
_funcs.set_speed = cdio_generic_unimplemented_set_speed;
_funcs.set_blocksize = cdio_generic_unimplemented_set_blocksize;
_funcs.stat_size = _stat_size_cdrdao;
if (NULL == psz_cue_name) return NULL;

View File

@@ -1,5 +1,5 @@
/*
$Id: nrg.c,v 1.8 2005/01/23 19:16:58 rocky Exp $
$Id: nrg.c,v 1.9 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 2001, 2003 Herbert Valerio Riedel <hvr@gnu.org>
@@ -46,7 +46,7 @@
#include "_cdio_stdio.h"
#include "nrg.h"
static const char _rcsid[] = "$Id: nrg.c,v 1.8 2005/01/23 19:16:58 rocky Exp $";
static const char _rcsid[] = "$Id: nrg.c,v 1.9 2005/01/24 00:06:31 rocky Exp $";
/* reader */
@@ -68,8 +68,8 @@ typedef struct {
#define NEED_NERO_STRUCT
#include "image_common.h"
static bool parse_nrg (_img_private_t *env, const char *psz_cue_name);
static uint32_t _stat_size_nrg (void *p_user_data);
static bool parse_nrg (_img_private_t *env, const char *psz_cue_name);
static lsn_t get_disc_last_lsn_nrg (void *p_user_data);
/* Updates internal track TOC, so we can later
simulate ioctl(CDROMREADTOCENTRY).
@@ -730,7 +730,7 @@ parse_nrg (_img_private_t *p_env, const char *psz_nrg_name)
}
/* Fake out leadout track. */
/* Don't use _stat_size_nrg since that will lead to recursion since
/* Don't use get_disc_last_lsn_nrg since that will lead to recursion since
we haven't fully initialized things yet.
*/
cdio_lsn_to_msf (p_env->size, &p_env->tocent[p_env->gen.i_tracks].start_msf);
@@ -835,8 +835,14 @@ _read_nrg (void *p_user_data, void *buf, size_t size)
return cdio_stream_read(p_env->gen.data_source, buf, size, 1);
}
static uint32_t
_stat_size_nrg (void *p_user_data)
/*!
Get the size of the CD in logical block address (LBA) units.
@param p_cdio the CD object queried
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
static lsn_t
get_disc_last_lsn_nrg (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
@@ -1209,6 +1215,7 @@ cdio_open_nrg (const char *psz_source)
_funcs.get_cdtext = get_cdtext_generic;
_funcs.get_devices = cdio_get_devices_nrg;
_funcs.get_default_device = cdio_get_default_device_nrg;
_funcs.get_disc_last_lsn = get_disc_last_lsn_nrg;
_funcs.get_discmode = _get_discmode_image;
_funcs.get_drive_cap = _get_drive_cap_image;
_funcs.get_first_track_num = _get_first_track_num_image;
@@ -1230,7 +1237,6 @@ cdio_open_nrg (const char *psz_source)
_funcs.read_mode2_sector = _read_mode2_sector_nrg;
_funcs.read_mode2_sectors = _read_mode2_sectors_nrg;
_funcs.set_arg = _set_arg_image;
_funcs.stat_size = _stat_size_nrg;
_data = _cdio_malloc (sizeof (_img_private_t));
_data->gen.init = false;

View File

@@ -131,7 +131,6 @@ cdio_read_mode2_sectors
cdio_set_arg
cdio_set_blocksize
cdio_set_speed
cdio_stat_size
cdio_stdio_destroy
cdio_stdio_new
cdio_stream_read

View File

@@ -1,6 +1,6 @@
/* Common SCSI Multimedia Command (MMC) routines.
$Id: scsi_mmc.c,v 1.10 2005/01/23 19:16:58 rocky Exp $
$Id: scsi_mmc.c,v 1.11 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -40,151 +40,79 @@
#include <errno.h>
#endif
/*!
Return the discmode as reported by the SCSI-MMC Read (FULL) TOC
command.
Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
pages 56-62 from the SCSI MMC draft specification, revision 10a
at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
especially tables 72, 73 and 75.
*/
discmode_t
scsi_mmc_get_discmode( const CdIo_t *p_cdio )
{
uint8_t buf[14] = { 0, };
scsi_mmc_cdb_t cdb;
memset(&cdb, 0, sizeof(scsi_mmc_cdb_t));
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
cdb.field[1] = CDIO_CDROM_MSF; /* The MMC-5 spec may require this. */
cdb.field[2] = CDIO_MMC_READTOC_FMT_FULTOC;
CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
scsi_mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf);
if (buf[7] == 0xA0) {
if (buf[13] == 0x00) {
if (buf[5] & 0x04)
return CDIO_DISC_MODE_CD_DATA;
else
return CDIO_DISC_MODE_CD_DA;
}
else if (buf[13] == 0x10)
return CDIO_DISC_MODE_CD_I;
else if (buf[13] == 0x20)
return CDIO_DISC_MODE_CD_XA;
}
return CDIO_DISC_MODE_NO_INFO;
}
/*!
Set the drive speed.
@return the drive speed if greater than 0. -1 if we had an error. is -2
returned if this is not implemented for the current driver.
@see scsi_mmc_set_speed
*/
int
scsi_mmc_set_speed( const CdIo_t *p_cdio, int i_speed )
{
uint8_t buf[14] = { 0, };
scsi_mmc_cdb_t cdb;
/* If the requested speed is less than 1x 176 kb/s this command
will return an error - it's part of the ATAPI specs. Therefore,
test and stop early. */
if ( i_speed < 1 ) return -1;
memset(&cdb, 0, sizeof(scsi_mmc_cdb_t));
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_SET_SPEED);
CDIO_MMC_SET_LEN16(cdb.field, 2, i_speed);
/* Some drives like the Creative 24x CDRW require one to set a nonzero
write speed. So we set to the maximum value. */
CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff);
return scsi_mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ,
sizeof(buf), buf);
}
/*!
On input a MODE_SENSE command was issued and we have the results
in p. We interpret this and return a bit mask set according to the
capabilities.
*/
void
scsi_mmc_get_drive_cap_buf(const uint8_t *p,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
/* Reader */
if (p[2] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_R;
if (p[2] & 0x02) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_RW;
if (p[2] & 0x08) *p_read_cap |= CDIO_DRIVE_CAP_READ_DVD_ROM;
if (p[4] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_AUDIO;
if (p[4] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM1;
if (p[4] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM2;
if (p[5] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_DA;
if (p[5] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_C2_ERRS;
if (p[5] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_ISRC;
/* Writer */
if (p[3] & 0x01) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_R;
if (p[3] & 0x02) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_RW;
if (p[3] & 0x10) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_R;
if (p[3] & 0x20) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RAM;
if (p[4] & 0x80) *p_misc_cap |= CDIO_DRIVE_CAP_WRITE_BURN_PROOF;
/* Misc */
if (p[4] & 0x40) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_MULTI_SESSION;
if (p[6] & 0x01) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_LOCK;
if (p[6] & 0x08) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_EJECT;
if (p[6] >> 5 != 0)
*p_misc_cap |= CDIO_DRIVE_CAP_MISC_CLOSE_TRAY;
}
/*!
Return the number of length in bytes of the Command Descriptor
buffer (CDB) for a given SCSI MMC command. The length will be
either 6, 10, or 12.
*/
uint8_t
scsi_mmc_get_cmd_len(uint8_t scsi_cmd)
{
static const uint8_t scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
return scsi_cdblen[((scsi_cmd >> 5) & 7)];
}
/*!
Run a SCSI MMC command.
cdio CD structure set by cdio_open().
i_timeout time in milliseconds we will wait for the command
to complete. If this value is -1, use the default
time-out value.
buf Buffer for data, both sending and receiving
len Size of buffer
e_direction direction the transfer is to go
cdb CDB bytes. All values that are needed should be set on
input. We'll figure out what the right CDB length should be.
*/
driver_return_code_t
scsi_mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
const scsi_mmc_cdb_t *p_cdb,
scsi_mmc_direction_t e_direction, unsigned int i_buf,
/*in/out*/ void *p_buf )
{
if (!p_cdio) return DRIVER_OP_UNINIT;
if (!p_cdio->op.run_scsi_mmc_cmd) return DRIVER_OP_UNSUPPORTED;
return p_cdio->op.run_scsi_mmc_cmd(p_cdio->env, i_timeout_ms,
scsi_mmc_get_cmd_len(p_cdb->field[0]),
p_cdb, e_direction, i_buf, p_buf);
}
#define DEFAULT_TIMEOUT_MS 6000
/*************************************************************************
MMC CdIo Operations which a driver may use.
These are not accessible directly.
Most of these routines just pick out the cdio pointer and call the
corresponding publically-accessible routine.
*************************************************************************/
/* Set read blocksize (via MMC) */
driver_return_code_t
get_blocksize_mmc (void *p_user_data)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_get_blocksize(p_env->cdio);
}
/*!
Get the lsn of the end of the CD (via MMC).
@return the lsn. On error return CDIO_INVALID_LSN.
*/
lsn_t
get_disc_last_lsn_mmc (void *p_user_data)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return CDIO_INVALID_LSN;
return scsi_mmc_get_disc_last_lsn(p_env->cdio);
}
void
get_drive_cap_mmc (const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
const generic_img_private_t *p_env = p_user_data;
scsi_mmc_get_drive_cap( p_env->cdio,
p_read_cap, p_write_cap, p_misc_cap );
}
char *
get_mcn_mmc (const void *p_user_data)
{
const generic_img_private_t *p_env = p_user_data;
return scsi_mmc_get_mcn( p_env->cdio );
}
/* Set read blocksize (via MMC) */
driver_return_code_t
set_blocksize_mmc (void *p_user_data, int i_blocksize)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_set_blocksize(p_env->cdio, i_blocksize);
}
/* Set CD-ROM drive speed (via MMC) */
driver_return_code_t
set_speed_mmc (void *p_user_data, int i_speed)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_set_speed( p_env->cdio, i_speed );
}
/*************************************************************************
Miscellaenous other "private" routines. Probably need to better
classify these.
*************************************************************************/
int
scsi_mmc_get_blocksize_private ( void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd)
@@ -228,138 +156,43 @@ scsi_mmc_get_blocksize_private ( void *p_env,
return CDIO_MMC_GET_LEN16(p);
}
int
scsi_mmc_get_blocksize ( const CdIo_t *p_cdio)
{
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
return
scsi_mmc_get_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd);
}
/*!
* Eject using SCSI MMC commands. Return 0 if successful.
On input a MODE_SENSE command was issued and we have the results
in p. We interpret this and return a bit mask set according to the
capabilities.
*/
driver_return_code_t
scsi_mmc_eject_media( const CdIo_t *p_cdio )
void
scsi_mmc_get_drive_cap_buf(const uint8_t *p,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
int i_status = 0;
scsi_mmc_cdb_t cdb = {{0, }};
uint8_t buf[1];
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd;
/* Reader */
if (p[2] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_R;
if (p[2] & 0x02) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_RW;
if (p[2] & 0x08) *p_read_cap |= CDIO_DRIVE_CAP_READ_DVD_ROM;
if (p[4] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_AUDIO;
if (p[4] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM1;
if (p[4] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_MODE2_FORM2;
if (p[5] & 0x01) *p_read_cap |= CDIO_DRIVE_CAP_READ_CD_DA;
if (p[5] & 0x10) *p_read_cap |= CDIO_DRIVE_CAP_READ_C2_ERRS;
if (p[5] & 0x20) *p_read_cap |= CDIO_DRIVE_CAP_READ_ISRC;
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
if ( ! p_cdio->op.run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
run_scsi_mmc_cmd = p_cdio->op.run_scsi_mmc_cmd;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL);
i_status = run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status) return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 1;
i_status = run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 2; /* eject */
return run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
/* Writer */
if (p[3] & 0x01) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_R;
if (p[3] & 0x02) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_CD_RW;
if (p[3] & 0x10) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_R;
if (p[3] & 0x20) *p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RAM;
if (p[4] & 0x80) *p_misc_cap |= CDIO_DRIVE_CAP_WRITE_BURN_PROOF;
/* Misc */
if (p[4] & 0x40) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_MULTI_SESSION;
if (p[6] & 0x01) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_LOCK;
if (p[6] & 0x08) *p_misc_cap |= CDIO_DRIVE_CAP_MISC_EJECT;
if (p[6] >> 5 != 0)
*p_misc_cap |= CDIO_DRIVE_CAP_MISC_CLOSE_TRAY;
}
/*! Read sectors using SCSI-MMC GPCMD_READ_CD.
Can read only up to 25 blocks.
*/
driver_return_code_t
scsi_mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba,
int sector_type, unsigned int i_blocks )
{
scsi_mmc_cdb_t cdb = {{0, }};
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd;
if (!p_cdio) return DRIVER_OP_UNINIT;
if (!p_cdio->op.run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
run_scsi_mmc_cmd = p_cdio->op.run_scsi_mmc_cmd;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);
CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type);
CDIO_MMC_SET_READ_LBA (cdb.field, lba);
CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks);
CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field,
CDIO_MMC_MCSB_ALL_HEADERS);
return run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_READ,
CDIO_CD_FRAMESIZE_RAW * i_blocks,
p_buf);
}
driver_return_code_t
scsi_mmc_set_blocksize_private ( void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int i_bsize)
{
scsi_mmc_cdb_t cdb = {{0, }};
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;
if ( ! p_env ) return DRIVER_OP_UNINIT;
if ( ! run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
memset (&mh, 0, sizeof (mh));
mh.block_desc_length = 0x08;
mh.block_length_hi = (i_bsize >> 16) & 0xff;
mh.block_length_med = (i_bsize >> 8) & 0xff;
mh.block_length_lo = (i_bsize >> 0) & 0xff;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6);
cdb.field[1] = 1 << 4;
cdb.field[4] = 12;
return run_scsi_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, sizeof(mh), &mh);
}
driver_return_code_t
scsi_mmc_set_blocksize ( const CdIo_t *p_cdio, unsigned int i_blocksize)
{
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
return
scsi_mmc_set_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd,
i_blocksize);
}
/*!
Return the the kind of drive capabilities of device.
*/
@@ -451,18 +284,6 @@ scsi_mmc_get_drive_cap_private (void *p_env,
return;
}
void
scsi_mmc_get_drive_cap (const CdIo_t *p_cdio,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
if ( ! p_cdio ) return;
scsi_mmc_get_drive_cap_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd,
p_read_cap, p_write_cap, p_misc_cap);
}
/*!
Get the DVD type associated with cd object.
*/
@@ -521,59 +342,6 @@ scsi_mmc_get_dvd_struct_physical_private ( void *p_env, const
return DRIVER_OP_SUCCESS;
}
/*!
Get the DVD type associated with cd object.
*/
discmode_t
scsi_mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, cdio_dvd_struct_t *s)
{
if ( ! p_cdio ) return -2;
return
scsi_mmc_get_dvd_struct_physical_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd,
s);
}
/*!
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
False is returned if we had an error getting the information.
*/
bool
scsi_mmc_get_hwinfo ( const CdIo_t *p_cdio,
/*out*/ cdio_hwinfo_t *hw_info )
{
int i_status; /* Result of SCSI MMC command */
char buf[36] = { 0, }; /* Place to hold returned data */
scsi_mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_INQUIRY);
cdb.field[4] = sizeof(buf);
if (! p_cdio || ! hw_info ) return false;
i_status = scsi_mmc_run_cmd(p_cdio, DEFAULT_TIMEOUT_MS,
&cdb, SCSI_MMC_DATA_READ,
sizeof(buf), &buf);
if (i_status == 0) {
memcpy(hw_info->psz_vendor,
buf + 8,
sizeof(hw_info->psz_vendor)-1);
hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
memcpy(hw_info->psz_model,
buf + 8 + CDIO_MMC_HW_VENDOR_LEN,
sizeof(hw_info->psz_model)-1);
hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
memcpy(hw_info->psz_revision,
buf + 8 + CDIO_MMC_HW_VENDOR_LEN + CDIO_MMC_HW_MODEL_LEN,
sizeof(hw_info->psz_revision)-1);
hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
return true;
}
return false;
}
/*!
Return the media catalog number MCN.
@@ -609,14 +377,6 @@ scsi_mmc_get_mcn_private ( void *p_env,
return NULL;
}
char *
scsi_mmc_get_mcn ( const CdIo_t *p_cdio )
{
if ( ! p_cdio ) return NULL;
return scsi_mmc_get_mcn_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd );
}
/*
Read cdtext information for a CdIo_t object .
@@ -688,49 +448,362 @@ scsi_mmc_init_cdtext_private ( void *p_user_data,
}
}
/* Set read blocksize (via MMC) */
driver_return_code_t
get_blocksize_mmc (void *p_user_data)
scsi_mmc_set_blocksize_private ( void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int i_bsize)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_get_blocksize(p_env->cdio);
scsi_mmc_cdb_t cdb = {{0, }};
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;
if ( ! p_env ) return DRIVER_OP_UNINIT;
if ( ! run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
memset (&mh, 0, sizeof (mh));
mh.block_desc_length = 0x08;
mh.block_length_hi = (i_bsize >> 16) & 0xff;
mh.block_length_med = (i_bsize >> 8) & 0xff;
mh.block_length_lo = (i_bsize >> 0) & 0xff;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6);
cdb.field[1] = 1 << 4;
cdb.field[4] = 12;
return run_scsi_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, sizeof(mh), &mh);
}
/***********************************************************
User-accessible Operations.
************************************************************/
/*!
Return the number of length in bytes of the Command Descriptor
buffer (CDB) for a given SCSI MMC command. The length will be
either 6, 10, or 12.
*/
uint8_t
scsi_mmc_get_cmd_len(uint8_t scsi_cmd)
{
static const uint8_t scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
return scsi_cdblen[((scsi_cmd >> 5) & 7)];
}
/*!
Return the size of the CD in logical block address (LBA) units.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t
scsi_mmc_get_disc_last_lsn ( const CdIo_t *p_cdio )
{
scsi_mmc_cdb_t cdb = {{0, }};
uint8_t buf[12] = { 0, };
lsn_t retval = 0;
int i_status;
/* Operation code */
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
cdb.field[1] = 0; /* lba; msf: 0x2 */
/* Format */
cdb.field[2] = CDIO_MMC_READTOC_FMT_TOC;
CDIO_MMC_SET_START_TRACK(cdb.field, CDIO_CDROM_LEADOUT_TRACK);
CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(buf));
i_status = scsi_mmc_run_cmd(p_cdio, DEFAULT_TIMEOUT_MS, &cdb,
SCSI_MMC_DATA_READ,
sizeof(buf), buf);
if (i_status) return CDIO_INVALID_LSN;
{
int i;
for (i = 8; i < 12; i++) {
retval <<= 8;
retval += buf[i];
}
}
return retval;
}
/*!
Return the discmode as reported by the SCSI-MMC Read (FULL) TOC
command.
Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
pages 56-62 from the SCSI MMC draft specification, revision 10a
at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
especially tables 72, 73 and 75.
*/
discmode_t
scsi_mmc_get_discmode( const CdIo_t *p_cdio )
{
uint8_t buf[14] = { 0, };
scsi_mmc_cdb_t cdb;
memset(&cdb, 0, sizeof(scsi_mmc_cdb_t));
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
cdb.field[1] = CDIO_CDROM_MSF; /* The MMC-5 spec may require this. */
cdb.field[2] = CDIO_MMC_READTOC_FMT_FULTOC;
CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
scsi_mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf);
if (buf[7] == 0xA0) {
if (buf[13] == 0x00) {
if (buf[5] & 0x04)
return CDIO_DISC_MODE_CD_DATA;
else
return CDIO_DISC_MODE_CD_DA;
}
else if (buf[13] == 0x10)
return CDIO_DISC_MODE_CD_I;
else if (buf[13] == 0x20)
return CDIO_DISC_MODE_CD_XA;
}
return CDIO_DISC_MODE_NO_INFO;
}
void
get_drive_cap_mmc (const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
scsi_mmc_get_drive_cap (const CdIo_t *p_cdio,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
const generic_img_private_t *p_env = p_user_data;
scsi_mmc_get_drive_cap( p_env->cdio,
p_read_cap, p_write_cap, p_misc_cap );
if ( ! p_cdio ) return;
scsi_mmc_get_drive_cap_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd,
p_read_cap, p_write_cap, p_misc_cap);
}
/*!
Get the DVD type associated with cd object.
*/
discmode_t
scsi_mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, cdio_dvd_struct_t *s)
{
if ( ! p_cdio ) return -2;
return
scsi_mmc_get_dvd_struct_physical_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd,
s);
}
/*!
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command.
False is returned if we had an error getting the information.
*/
bool
scsi_mmc_get_hwinfo ( const CdIo_t *p_cdio,
/*out*/ cdio_hwinfo_t *hw_info )
{
int i_status; /* Result of SCSI MMC command */
char buf[36] = { 0, }; /* Place to hold returned data */
scsi_mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_INQUIRY);
cdb.field[4] = sizeof(buf);
if (! p_cdio || ! hw_info ) return false;
i_status = scsi_mmc_run_cmd(p_cdio, DEFAULT_TIMEOUT_MS,
&cdb, SCSI_MMC_DATA_READ,
sizeof(buf), &buf);
if (i_status == 0) {
memcpy(hw_info->psz_vendor,
buf + 8,
sizeof(hw_info->psz_vendor)-1);
hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
memcpy(hw_info->psz_model,
buf + 8 + CDIO_MMC_HW_VENDOR_LEN,
sizeof(hw_info->psz_model)-1);
hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
memcpy(hw_info->psz_revision,
buf + 8 + CDIO_MMC_HW_VENDOR_LEN + CDIO_MMC_HW_MODEL_LEN,
sizeof(hw_info->psz_revision)-1);
hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
return true;
}
return false;
}
char *
get_mcn_mmc (const void *p_user_data)
scsi_mmc_get_mcn ( const CdIo_t *p_cdio )
{
const generic_img_private_t *p_env = p_user_data;
return scsi_mmc_get_mcn( p_env->cdio );
if ( ! p_cdio ) return NULL;
return scsi_mmc_get_mcn_private (p_cdio->env,
p_cdio->op.run_scsi_mmc_cmd );
}
/* Set read blocksize (via MMC) */
/*!
Run a SCSI MMC command.
cdio CD structure set by cdio_open().
i_timeout time in milliseconds we will wait for the command
to complete. If this value is -1, use the default
time-out value.
buf Buffer for data, both sending and receiving
len Size of buffer
e_direction direction the transfer is to go
cdb CDB bytes. All values that are needed should be set on
input. We'll figure out what the right CDB length should be.
*/
driver_return_code_t
set_blocksize_mmc (void *p_user_data, int i_blocksize)
scsi_mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
const scsi_mmc_cdb_t *p_cdb,
scsi_mmc_direction_t e_direction, unsigned int i_buf,
/*in/out*/ void *p_buf )
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_set_blocksize(p_env->cdio, i_blocksize);
if (!p_cdio) return DRIVER_OP_UNINIT;
if (!p_cdio->op.run_scsi_mmc_cmd) return DRIVER_OP_UNSUPPORTED;
return p_cdio->op.run_scsi_mmc_cmd(p_cdio->env, i_timeout_ms,
scsi_mmc_get_cmd_len(p_cdb->field[0]),
p_cdb, e_direction, i_buf, p_buf);
}
/* Set CD-ROM drive speed (via MMC) */
driver_return_code_t
set_speed_mmc (void *p_user_data, int i_speed)
int
scsi_mmc_get_blocksize ( const CdIo_t *p_cdio)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return scsi_mmc_set_speed( p_env->cdio, i_speed );
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
return
scsi_mmc_get_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd);
}
/*!
* Eject using SCSI MMC commands. Return 0 if successful.
*/
driver_return_code_t
scsi_mmc_eject_media( const CdIo_t *p_cdio )
{
int i_status = 0;
scsi_mmc_cdb_t cdb = {{0, }};
uint8_t buf[1];
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd;
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
if ( ! p_cdio->op.run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
run_scsi_mmc_cmd = p_cdio->op.run_scsi_mmc_cmd;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL);
i_status = run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status) return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 1;
i_status = run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 2; /* eject */
return run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
}
/*! Read sectors using SCSI-MMC GPCMD_READ_CD.
Can read only up to 25 blocks.
*/
driver_return_code_t
scsi_mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lba_t lba,
int sector_type, unsigned int i_blocks )
{
scsi_mmc_cdb_t cdb = {{0, }};
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd;
if (!p_cdio) return DRIVER_OP_UNINIT;
if (!p_cdio->op.run_scsi_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
run_scsi_mmc_cmd = p_cdio->op.run_scsi_mmc_cmd;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);
CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type);
CDIO_MMC_SET_READ_LBA (cdb.field, lba);
CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks);
CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field,
CDIO_MMC_MCSB_ALL_HEADERS);
return run_scsi_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_READ,
CDIO_CD_FRAMESIZE_RAW * i_blocks,
p_buf);
}
driver_return_code_t
scsi_mmc_set_blocksize ( const CdIo_t *p_cdio, unsigned int i_blocksize)
{
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
return
scsi_mmc_set_blocksize_private (p_cdio->env, p_cdio->op.run_scsi_mmc_cmd,
i_blocksize);
}
/*!
Set the drive speed.
@return the drive speed if greater than 0. -1 if we had an error. is -2
returned if this is not implemented for the current driver.
@see scsi_mmc_set_speed
*/
int
scsi_mmc_set_speed( const CdIo_t *p_cdio, int i_speed )
{
uint8_t buf[14] = { 0, };
scsi_mmc_cdb_t cdb;
/* If the requested speed is less than 1x 176 kb/s this command
will return an error - it's part of the ATAPI specs. Therefore,
test and stop early. */
if ( i_speed < 1 ) return -1;
memset(&cdb, 0, sizeof(scsi_mmc_cdb_t));
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_SET_SPEED);
CDIO_MMC_SET_LEN16(cdb.field, 2, i_speed);
/* Some drives like the Creative 24x CDRW require one to set a
nonzero write speed or else one gets an error back. Some
specifications have setting the value 0xfffff indicate setting to
the maximum allowable speed.
*/
CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff);
return scsi_mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ,
sizeof(buf), buf);
}

View File

@@ -1,6 +1,6 @@
/* private MMC helper routines.
$Id: scsi_mmc_private.h,v 1.4 2005/01/23 19:16:58 rocky Exp $
$Id: scsi_mmc_private.h,v 1.5 2005/01/24 00:06:31 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -33,13 +33,48 @@ msecs2secs(unsigned int msecs)
}
#undef SECS2MSECS
typedef
int (*scsi_mmc_run_cmd_fn_t) ( 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 );
/***********************************************************
MMC CdIo Operations which a driver may use.
These are not directly user-accessible.
************************************************************/
/*!
Get the block size for subsequest read requests, via a SCSI MMC
MODE_SENSE 6 command.
*/
int get_blocksize_mmc (void *p_user_data);
/*!
Get the lsn of the end of the CD
@return the lsn. On error return CDIO_INVALID_LSN.
*/
lsn_t get_disc_last_lsn_mmc( void *p_user_data );
void get_drive_cap_mmc (const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
char *get_mcn_mmc (const void *p_user_data);
/* Set read blocksize (via MMC) */
driver_return_code_t set_blocksize_mmc (void *p_user_data, int i_blocksize);
/* Set CD-ROM drive speed (via MMC) */
driver_return_code_t set_speed_mmc (void *p_user_data, int i_speed);
/***********************************************************
Miscellaenous other "private" routines. Probably need
to better classify these.
************************************************************/
typedef driver_return_code_t (*scsi_mmc_run_cmd_fn_t)
( 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 );
int scsi_mmc_set_blocksize_mmc_private ( const void *p_env, const
scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
@@ -94,22 +129,3 @@ driver_return_code_t
scsi_mmc_set_blocksize_private ( void *p_env,
const scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd,
unsigned int i_bsize);
/*!
Get the block size for subsequest read requests, via a SCSI MMC
MODE_SENSE 6 command.
*/
int get_blocksize_mmc (void *p_user_data);
void get_drive_cap_mmc (const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
char *get_mcn_mmc (const void *p_user_data);
/* Set read blocksize (via MMC) */
driver_return_code_t set_blocksize_mmc (void *p_user_data, int i_blocksize);
/* Set CD-ROM drive speed (via MMC) */
driver_return_code_t set_speed_mmc (void *p_user_data, int i_speed);