Work on SCSI MMC layer. Some things may be broken.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: scsi_mmc.h,v 1.11 2004/07/21 11:07:27 rocky Exp $
|
$Id: scsi_mmc.h,v 1.12 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -20,14 +20,19 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file scsi_mmc.h
|
\file scsi_mmc.h
|
||||||
\brief Common definitions for SCSI MMC (Multimedia commands).
|
\brief Common definitions for SCSI MMC (Multi-Media Commands).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SCSI_MMC_H__
|
#ifndef __SCSI_MMC_H__
|
||||||
#define __SCSI_MMC_H__
|
#define __SCSI_MMC_H__
|
||||||
|
|
||||||
|
#include <cdio/cdio.h>
|
||||||
|
#include <cdio/types.h>
|
||||||
|
|
||||||
/*! The generic packet command opcodes for CD/DVD Logical Units. */
|
/*! The generic packet command opcodes for CD/DVD Logical Units. */
|
||||||
|
|
||||||
|
#define CDIO_MMC_GPCMD_INQUIRY 0x12
|
||||||
|
#define CDIO_MMC_GPCMD_MODE_SELECT_6 0x15
|
||||||
#define CDIO_MMC_GPCMD_MODE_SENSE 0x1a
|
#define CDIO_MMC_GPCMD_MODE_SENSE 0x1a
|
||||||
#define CDIO_MMC_GPCMD_START_STOP 0x1b
|
#define CDIO_MMC_GPCMD_START_STOP 0x1b
|
||||||
#define CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL 0x1e
|
#define CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL 0x1e
|
||||||
@@ -39,23 +44,22 @@
|
|||||||
#define CDIO_MMC_GPCMD_READ_SUBCHANNEL 0x42
|
#define CDIO_MMC_GPCMD_READ_SUBCHANNEL 0x42
|
||||||
#define CDIO_MMC_GPCMD_READ_TOC 0x43
|
#define CDIO_MMC_GPCMD_READ_TOC 0x43
|
||||||
#define CDIO_MMC_GPCMD_READ_HEADER 0x44
|
#define CDIO_MMC_GPCMD_READ_HEADER 0x44
|
||||||
#define CDIO_MMC_GPCMD_PLAYAUDIO10 0x45
|
#define CDIO_MMC_GPCMD_PLAY_AUDIO_10 0x45
|
||||||
#define CDIO_MMC_GPCMD_PLAYAUDIO_MSF 0x47
|
#define CDIO_MMC_GPCMD_PLAY_AUDIO_MSF 0x47
|
||||||
#define CDIO_MMC_GPCMD_PLAYAUDIO_TI 0x48
|
#define CDIO_MMC_GPCMD_PLAY_AUDIO_TI 0x48
|
||||||
#define CDIO_MMC_GPCMD_PLAYTRACK_REL10 0x49
|
#define CDIO_MMC_GPCMD_PLAY_TRACK_REL_10 0x49
|
||||||
#define CDIO_MMC_GPCMD_PAUSE_RESUME 0x4b
|
#define CDIO_MMC_GPCMD_PAUSE_RESUME 0x4b
|
||||||
|
|
||||||
#define CDIO_MMC_GPCMD_READ_DISC_INFO 0x51
|
#define CDIO_MMC_GPCMD_READ_DISC_INFO 0x51
|
||||||
#define CDIO_MMC_GPCMD_MODE_SELECT 0x55
|
#define CDIO_MMC_GPCMD_MODE_SELECT 0x55
|
||||||
#define CDIO_MMC_GPCMD_MODE_SELECT_6 0x15
|
|
||||||
#define CDIO_MMC_GPCMD_MODE_SENSE_10 0x5a
|
#define CDIO_MMC_GPCMD_MODE_SENSE_10 0x5a
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Group 5 Commands
|
Group 5 Commands
|
||||||
*/
|
*/
|
||||||
#define CDIO_MMC_GPCMD_PLAYAUDIO_12 0xa5
|
#define CDIO_MMC_GPCMD_PLAY_AUDIO_12 0xa5
|
||||||
#define CDIO_MMC_GPCMD_READ_12 0xa8
|
#define CDIO_MMC_GPCMD_READ_12 0xa8
|
||||||
#define CDIO_MMC_GPCMD_PLAYTRACK_REL12 0xa9
|
#define CDIO_MMC_GPCMD_PLAY_TRACK_REL_12 0xa9
|
||||||
#define CDIO_MMC_GPCMD_READ_CD 0xbe
|
#define CDIO_MMC_GPCMD_READ_CD 0xbe
|
||||||
#define CDIO_MMC_GPCMD_READ_MSF 0xb9
|
#define CDIO_MMC_GPCMD_READ_MSF 0xb9
|
||||||
|
|
||||||
@@ -106,38 +110,86 @@
|
|||||||
#define CDIO_MMC_GPCMD_SET_SPEED 0xbb
|
#define CDIO_MMC_GPCMD_SET_SPEED 0xbb
|
||||||
|
|
||||||
|
|
||||||
#define CDIO_MMC_SET_COMMAND(rec, command) \
|
/*! The largest Command Descriptor Buffer (CDB) size.
|
||||||
rec[0] = command
|
The possible sizes are 6, 10, and 12 bytes.
|
||||||
|
*/
|
||||||
|
#define MAX_CDB_LEN 12
|
||||||
|
|
||||||
#define CDIO_MMC_SET_READ_TYPE(rec, sector_type) \
|
/*! A Command Descriptor Buffer (CDB) used in sending SCSI MMC
|
||||||
rec[1] = (sector_type << 2)
|
commands.
|
||||||
|
*/
|
||||||
|
typedef struct scsi_mmc_cdb {
|
||||||
|
uint8_t field[MAX_CDB_LEN];
|
||||||
|
} scsi_mmc_cdb_t;
|
||||||
|
|
||||||
|
/*! An enumeration indicating whether a SCSI MMC command is sending
|
||||||
|
data or getting data.
|
||||||
|
*/
|
||||||
|
typedef enum scsi_mmc_direction {
|
||||||
|
SCSI_MMC_DATA_READ,
|
||||||
|
SCSI_MMC_DATA_WRITE
|
||||||
|
} scsi_mmc_direction_t;
|
||||||
|
|
||||||
|
#define CDIO_MMC_SET_COMMAND(cdb, command) \
|
||||||
|
cdb[0] = command
|
||||||
|
|
||||||
|
#define CDIO_MMC_SET_READ_TYPE(cdb, sector_type) \
|
||||||
|
cdb[1] = (sector_type << 2)
|
||||||
|
|
||||||
|
|
||||||
#define CDIO_MMC_SET_READ_LBA(rec, lba) \
|
#define CDIO_MMC_SET_READ_LBA(cdb, lba) \
|
||||||
rec[2] = (lba >> 24) & 0xff; \
|
cdb[2] = (lba >> 24) & 0xff; \
|
||||||
rec[3] = (lba >> 16) & 0xff; \
|
cdb[3] = (lba >> 16) & 0xff; \
|
||||||
rec[4] = (lba >> 8) & 0xff; \
|
cdb[4] = (lba >> 8) & 0xff; \
|
||||||
rec[5] = (lba ) & 0xff
|
cdb[5] = (lba ) & 0xff
|
||||||
|
|
||||||
#define CDIO_MMC_SET_START_TRACK(rec, command) \
|
#define CDIO_MMC_SET_START_TRACK(cdb, command) \
|
||||||
rec[6] = command
|
cdb[6] = command
|
||||||
|
|
||||||
#define CDIO_MMC_SET_READ_LENGTH(rec, len) \
|
#define CDIO_MMC_SET_READ_LENGTH(cdb, len) \
|
||||||
rec[6] = (len >> 16) & 0xff; \
|
cdb[6] = (len >> 16) & 0xff; \
|
||||||
rec[7] = (len >> 8) & 0xff; \
|
cdb[7] = (len >> 8) & 0xff; \
|
||||||
rec[8] = (len ) & 0xff
|
cdb[8] = (len ) & 0xff
|
||||||
|
|
||||||
#define CDIO_MMC_MCSB_ALL_HEADERS 0x78
|
#define CDIO_MMC_MCSB_ALL_HEADERS 0x78
|
||||||
|
|
||||||
#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(rec, val) \
|
#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \
|
||||||
rec[9] = val;
|
cdb[9] = val;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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.
|
||||||
|
p_buf Buffer for data, both sending and receiving.
|
||||||
|
i_buf 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.
|
||||||
|
|
||||||
|
Returns 0 if command completed successfully.
|
||||||
|
*/
|
||||||
|
int scsi_mmc_run_cmd( const CdIo *cdio, int t_timeout,
|
||||||
|
const scsi_mmc_cdb_t *p_cdb,
|
||||||
|
scsi_mmc_direction_t e_direction, unsigned int i_buf,
|
||||||
|
/*in/out*/ void *p_buf );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
On input a MODE_SENSE command was issued and we have the results
|
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
|
in p. We interpret this and return a bit mask set according to the
|
||||||
capabilities.
|
capabilities.
|
||||||
*/
|
*/
|
||||||
void cdio_get_drive_cap_mmc(const uint8_t *p,
|
void scsi_mmc_get_drive_cap(const uint8_t *p,
|
||||||
/*out*/ cdio_drive_read_cap_t *p_read_cap,
|
/*out*/ cdio_drive_read_cap_t *p_read_cap,
|
||||||
/*out*/ cdio_drive_write_cap_t *p_write_cap,
|
/*out*/ cdio_drive_write_cap_t *p_write_cap,
|
||||||
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
|
/*out*/ cdio_drive_misc_cap_t *p_misc_cap);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
$Id: sector.h,v 1.20 2004/07/21 10:29:00 rocky Exp $
|
$Id: sector.h,v 1.21 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
||||||
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
@@ -82,8 +82,8 @@ typedef enum {
|
|||||||
MODE2_RAW /**< 2352 byte block length */
|
MODE2_RAW /**< 2352 byte block length */
|
||||||
} trackmode_t;
|
} trackmode_t;
|
||||||
|
|
||||||
/*! disc modes. The first combined from MMC-3 5.29.2.8 and
|
/*! disc modes. The first combined from MMC-3 5.29.2.8 (Send CUESHEET)
|
||||||
GNU/Linux /usr/include/linux/cdrom.h and we've added DVD.
|
and GNU/Linux /usr/include/linux/cdrom.h and we've added DVD.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CDIO_DISC_MODE_CD_DA, /**< CD-DA */
|
CDIO_DISC_MODE_CD_DA, /**< CD-DA */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: freebsd_cam.c,v 1.20 2004/07/19 01:29:04 rocky Exp $
|
$Id: freebsd_cam.c,v 1.21 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.20 2004/07/19 01:29:04 rocky Exp $";
|
static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.21 2004/07/22 09:52:17 rocky Exp $";
|
||||||
|
|
||||||
#ifdef HAVE_FREEBSD_CDROM
|
#ifdef HAVE_FREEBSD_CDROM
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ get_drive_cap_freebsd_cam (img_private_t *env,
|
|||||||
*p_read_cap = 0;
|
*p_read_cap = 0;
|
||||||
*p_write_cap = 0;
|
*p_write_cap = 0;
|
||||||
*p_misc_cap = 0;
|
*p_misc_cap = 0;
|
||||||
cdio_get_drive_cap_mmc(&(buf[n], p_read_cap, p_write_cap, p_misc_cap));
|
scsi_mmc_get_drive_cap(&(buf[n], p_read_cap, p_write_cap, p_misc_cap));
|
||||||
} else {
|
} else {
|
||||||
*p_read_cap = CDIO_DRIVE_CAP_ERROR;
|
*p_read_cap = CDIO_DRIVE_CAP_ERROR;
|
||||||
*p_write_cap = CDIO_DRIVE_CAP_ERROR;
|
*p_write_cap = CDIO_DRIVE_CAP_ERROR;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: aspi32.c,v 1.30 2004/07/19 01:13:32 rocky Exp $
|
$Id: aspi32.c,v 1.31 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: aspi32.c,v 1.30 2004/07/19 01:13:32 rocky Exp $";
|
static const char _rcsid[] = "$Id: aspi32.c,v 1.31 2004/07/22 09:52:17 rocky Exp $";
|
||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/sector.h>
|
#include <cdio/sector.h>
|
||||||
@@ -773,7 +773,7 @@ get_drive_cap_aspi (const _img_private_t *env,
|
|||||||
/* Don't handle these yet. */
|
/* Don't handle these yet. */
|
||||||
break;
|
break;
|
||||||
case CDIO_MMC_CAPABILITIES_PAGE:
|
case CDIO_MMC_CAPABILITIES_PAGE:
|
||||||
cdio_get_drive_cap_mmc(p, p_read_cap, p_write_cap, p_misc_cap);
|
scsi_mmc_get_drive_cap(p, p_read_cap, p_write_cap, p_misc_cap);
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: win32_ioctl.c,v 1.19 2004/07/19 01:13:32 rocky Exp $
|
$Id: win32_ioctl.c,v 1.20 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.19 2004/07/19 01:13:32 rocky Exp $";
|
static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.20 2004/07/22 09:52:17 rocky Exp $";
|
||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/sector.h>
|
#include <cdio/sector.h>
|
||||||
@@ -569,7 +569,7 @@ get_drive_cap_win32ioctl (const _img_private_t *env,
|
|||||||
FALSE) ) {
|
FALSE) ) {
|
||||||
unsigned int n=sptwb.DataBuf[3]+4;
|
unsigned int n=sptwb.DataBuf[3]+4;
|
||||||
/* Reader? */
|
/* Reader? */
|
||||||
cdio_get_drive_cap_mmc(&(sptwb.DataBuf[n]), p_read_cap,
|
scsi_mmc_get_drive_cap(&(sptwb.DataBuf[n]), p_read_cap,
|
||||||
p_write_cap, p_misc_cap);
|
p_write_cap, p_misc_cap);
|
||||||
} else {
|
} else {
|
||||||
*p_read_cap = CDIO_DRIVE_CAP_UNKNOWN;
|
*p_read_cap = CDIO_DRIVE_CAP_UNKNOWN;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: _cdio_linux.c,v 1.71 2004/07/21 10:19:21 rocky Exp $
|
$Id: _cdio_linux.c,v 1.72 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||||
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
@@ -27,12 +27,13 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.71 2004/07/21 10:19:21 rocky Exp $";
|
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.72 2004/07/22 09:52:17 rocky Exp $";
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <cdio/sector.h>
|
#include <cdio/sector.h>
|
||||||
#include <cdio/util.h>
|
#include <cdio/util.h>
|
||||||
|
#include <cdio/types.h>
|
||||||
#include <cdio/scsi_mmc.h>
|
#include <cdio/scsi_mmc.h>
|
||||||
#include <cdio/cdtext.h>
|
#include <cdio/cdtext.h>
|
||||||
#include "cdtext_private.h"
|
#include "cdtext_private.h"
|
||||||
@@ -69,10 +70,12 @@ static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.71 2004/07/21 10:19:21 rock
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
typedef struct cdrom_generic_command cgc_t;
|
/* Default value in milliseconds we will wait for a command to
|
||||||
|
complete. */
|
||||||
|
#define DEFAULT_TIMEOUT 500
|
||||||
|
|
||||||
#define TOTAL_TRACKS (env->tochdr.cdth_trk1)
|
#define TOTAL_TRACKS (p_env->tochdr.cdth_trk1)
|
||||||
#define FIRST_TRACK_NUM (env->tochdr.cdth_trk0)
|
#define FIRST_TRACK_NUM (p_env->tochdr.cdth_trk0)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
_AM_NONE,
|
_AM_NONE,
|
||||||
@@ -93,6 +96,7 @@ typedef struct {
|
|||||||
|
|
||||||
access_mode_t access_mode;
|
access_mode_t access_mode;
|
||||||
bool b_cdtext_init;
|
bool b_cdtext_init;
|
||||||
|
bool b_cdtext_error;
|
||||||
|
|
||||||
/* Some of the more OS specific things. */
|
/* Some of the more OS specific things. */
|
||||||
cdtext_t cdtext_track[CDIO_CD_MAX_TRACKS+1]; /*CD-TEXT for each track*/
|
cdtext_t cdtext_track[CDIO_CD_MAX_TRACKS+1]; /*CD-TEXT for each track*/
|
||||||
@@ -159,12 +163,12 @@ cdio_is_cdrom(char *drive, char *mnttype)
|
|||||||
Get disc tyhpe associated with cd_obj.
|
Get disc tyhpe associated with cd_obj.
|
||||||
*/
|
*/
|
||||||
static discmode_t
|
static discmode_t
|
||||||
_get_discmode_linux (void *user_data)
|
_get_discmode_linux (void *p_user_data)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
int32_t i_discmode;
|
int32_t i_discmode;
|
||||||
i_discmode = ioctl (env->gen.fd, CDROM_DISC_STATUS);
|
i_discmode = ioctl (p_env->gen.fd, CDROM_DISC_STATUS);
|
||||||
|
|
||||||
if (i_discmode < 0) return CDIO_DISC_MODE_ERROR;
|
if (i_discmode < 0) return CDIO_DISC_MODE_ERROR;
|
||||||
|
|
||||||
@@ -255,10 +259,46 @@ cdio_check_mounts(const char *mtab)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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.
|
||||||
|
p_buf Buffer for data, both sending and receiving
|
||||||
|
i_buf 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.
|
||||||
|
|
||||||
|
We return true if command completed successfully and false if not.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
_set_bsize (int fd, unsigned int bsize)
|
scsi_mmc_run_cmd_linux( const _img_private_t *p_env, int i_timeout,
|
||||||
|
unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb,
|
||||||
|
scsi_mmc_direction_t e_direction,
|
||||||
|
unsigned int i_buf, /*out*/ void *p_buf )
|
||||||
{
|
{
|
||||||
struct cdrom_generic_command cgc;
|
struct cdrom_generic_command cgc;
|
||||||
|
memset (&cgc, 0, sizeof (struct cdrom_generic_command));
|
||||||
|
memcpy(&cgc.cmd, p_cdb, i_cdb);
|
||||||
|
cgc.buflen = i_buf;
|
||||||
|
cgc.buffer = p_buf;
|
||||||
|
cgc.data_direction = SCSI_MMC_DATA_READ ? CGC_DATA_READ : CGC_DATA_WRITE;
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_CDROM_TIMEOUT
|
||||||
|
if (i_timeout >= 0)
|
||||||
|
cgc.timeout = i_timeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ioctl (p_env->gen.fd, CDROM_SEND_PACKET, &cgc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_set_bsize (_img_private_t *p_env, unsigned int bsize)
|
||||||
|
{
|
||||||
|
scsi_mmc_cdb_t cdb;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -277,65 +317,57 @@ _set_bsize (int fd, unsigned int bsize)
|
|||||||
} mh;
|
} mh;
|
||||||
|
|
||||||
memset (&mh, 0, sizeof (mh));
|
memset (&mh, 0, sizeof (mh));
|
||||||
memset (&cgc, 0, sizeof (struct cdrom_generic_command));
|
|
||||||
|
|
||||||
CDIO_MMC_SET_COMMAND(cgc.cmd, CDIO_MMC_GPCMD_MODE_SELECT_6);
|
|
||||||
|
|
||||||
cgc.cmd[1] = 1 << 4;
|
|
||||||
cgc.cmd[4] = 12;
|
|
||||||
|
|
||||||
cgc.buflen = sizeof (mh);
|
|
||||||
cgc.buffer = (void *) &mh;
|
|
||||||
|
|
||||||
cgc.data_direction = CGC_DATA_WRITE;
|
|
||||||
|
|
||||||
mh.block_desc_length = 0x08;
|
mh.block_desc_length = 0x08;
|
||||||
mh.block_length_hi = (bsize >> 16) & 0xff;
|
mh.block_length_hi = (bsize >> 16) & 0xff;
|
||||||
mh.block_length_med = (bsize >> 8) & 0xff;
|
mh.block_length_med = (bsize >> 8) & 0xff;
|
||||||
mh.block_length_lo = (bsize >> 0) & 0xff;
|
mh.block_length_lo = (bsize >> 0) & 0xff;
|
||||||
|
|
||||||
return ioctl (fd, CDROM_SEND_PACKET, &cgc);
|
memset (&cdb, 0, sizeof (cdb));
|
||||||
|
|
||||||
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6);
|
||||||
|
|
||||||
|
cdb.field[1] = 1 << 4;
|
||||||
|
cdb.field[4] = 12;
|
||||||
|
|
||||||
|
return scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
|
SCSI_MMC_DATA_WRITE, sizeof(mh), &mh);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Packet driver to read mode2 sectors.
|
/* Packet driver to read mode2 sectors.
|
||||||
Can read only up to 25 blocks.
|
Can read only up to 25 blocks.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_sectors_mmc (int fd, void *buf, lba_t lba, int sector_type,
|
_read_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba,
|
||||||
unsigned int nblocks)
|
int sector_type, unsigned int nblocks)
|
||||||
{
|
{
|
||||||
cgc_t cgc;
|
scsi_mmc_cdb_t cdb;
|
||||||
|
|
||||||
memset (&cgc, 0, sizeof (cgc_t));
|
memset (&cdb, 0, sizeof (scsi_mmc_cdb_t));
|
||||||
|
|
||||||
cgc.cmd[0] = CDIO_MMC_GPCMD_READ_CD;
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);
|
||||||
CDIO_MMC_SET_READ_TYPE (cgc.cmd, sector_type);
|
CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type);
|
||||||
CDIO_MMC_SET_READ_LBA (cgc.cmd, lba);
|
CDIO_MMC_SET_READ_LBA (cdb.field, lba);
|
||||||
CDIO_MMC_SET_READ_LENGTH(cgc.cmd, nblocks);
|
CDIO_MMC_SET_READ_LENGTH(cdb.field, nblocks);
|
||||||
CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cgc.cmd, CDIO_MMC_MCSB_ALL_HEADERS);
|
CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field,
|
||||||
|
CDIO_MMC_MCSB_ALL_HEADERS);
|
||||||
|
|
||||||
cgc.buflen = CDIO_CD_FRAMESIZE_RAW * nblocks;
|
return scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
cgc.buffer = buf;
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
|
SCSI_MMC_DATA_READ,
|
||||||
#ifdef HAVE_LINUX_CDROM_TIMEOUT
|
CDIO_CD_FRAMESIZE_RAW * nblocks,
|
||||||
cgc.timeout = 500;
|
p_buf);
|
||||||
#endif
|
|
||||||
cgc.data_direction = CGC_DATA_READ;
|
|
||||||
|
|
||||||
return ioctl (fd, CDROM_SEND_PACKET, &cgc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MMC driver to read audio sectors.
|
/* MMC driver to read audio sectors.
|
||||||
Can read only up to 25 blocks.
|
Can read only up to 25 blocks.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_audio_sectors_linux (void *user_data, void *buf, lsn_t lsn,
|
_read_audio_sectors_linux (void *p_user_data, void *buf, lsn_t lsn,
|
||||||
unsigned int nblocks)
|
unsigned int nblocks)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
return _read_sectors_mmc( env->gen.fd, buf, lsn,
|
return _read_sectors_mmc( p_env, buf, lsn,
|
||||||
CDIO_MMC_READ_TYPE_CDDA, nblocks);
|
CDIO_MMC_READ_TYPE_CDDA, nblocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,56 +375,52 @@ _read_audio_sectors_linux (void *user_data, void *buf, lsn_t lsn,
|
|||||||
Can read only up to 25 blocks.
|
Can read only up to 25 blocks.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_mode2_sectors_mmc (int fd, void *buf, lba_t lba,
|
_read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba,
|
||||||
unsigned int nblocks, bool b_read_10)
|
unsigned int nblocks, bool b_read_10)
|
||||||
{
|
{
|
||||||
struct cdrom_generic_command cgc;
|
scsi_mmc_cdb_t cdb;
|
||||||
|
|
||||||
memset (&cgc, 0, sizeof (struct cdrom_generic_command));
|
memset (&cdb, 0, sizeof (scsi_mmc_cdb_t));
|
||||||
|
|
||||||
CDIO_MMC_SET_COMMAND(cgc.cmd, b_read_10
|
CDIO_MMC_SET_COMMAND(cdb.field, b_read_10
|
||||||
? CDIO_MMC_GPCMD_READ_10 : CDIO_MMC_GPCMD_READ_CD);
|
? CDIO_MMC_GPCMD_READ_10 : CDIO_MMC_GPCMD_READ_CD);
|
||||||
|
|
||||||
CDIO_MMC_SET_READ_LBA(cgc.cmd, lba);
|
CDIO_MMC_SET_READ_LBA(cdb.field, lba);
|
||||||
CDIO_MMC_SET_READ_LENGTH(cgc.cmd, nblocks);
|
CDIO_MMC_SET_READ_LENGTH(cdb.field, nblocks);
|
||||||
|
|
||||||
if (!b_read_10) {
|
if (!b_read_10) {
|
||||||
cgc.cmd[1] = 0; /* sector size mode2 */
|
cdb.field[1] = 0; /* sector size mode2 */
|
||||||
cgc.cmd[9] = 0x58; /* 2336 mode2 */
|
cdb.field[9] = 0x58; /* 2336 mode2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
cgc.buflen = M2RAW_SECTOR_SIZE * nblocks;
|
if (b_read_10) {
|
||||||
cgc.buffer = buf;
|
int retval;
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_CDROM_TIMEOUT
|
if ((retval = _set_bsize (p_env, M2RAW_SECTOR_SIZE)))
|
||||||
cgc.timeout = 500;
|
return retval;
|
||||||
#endif
|
|
||||||
cgc.data_direction = CGC_DATA_READ;
|
|
||||||
|
|
||||||
if (b_read_10)
|
if ((retval = scsi_mmc_run_cmd_linux (p_env, 0,
|
||||||
{
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
int retval;
|
SCSI_MMC_DATA_READ,
|
||||||
|
M2RAW_SECTOR_SIZE * nblocks, p_buf)))
|
||||||
if ((retval = _set_bsize (fd, M2RAW_SECTOR_SIZE)))
|
{
|
||||||
|
_set_bsize (p_env, CDIO_CD_FRAMESIZE);
|
||||||
return retval;
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
if ((retval = ioctl (fd, CDROM_SEND_PACKET, &cgc)))
|
if ((retval = _set_bsize (p_env, CDIO_CD_FRAMESIZE)))
|
||||||
{
|
return retval;
|
||||||
_set_bsize (fd, CDIO_CD_FRAMESIZE);
|
} else
|
||||||
return retval;
|
return scsi_mmc_run_cmd_linux (p_env, 0,
|
||||||
}
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
|
SCSI_MMC_DATA_READ,
|
||||||
if ((retval = _set_bsize (fd, CDIO_CD_FRAMESIZE)))
|
M2RAW_SECTOR_SIZE * nblocks, p_buf);
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return ioctl (fd, CDROM_SEND_PACKET, &cgc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_read_mode2_sectors (int fd, void *buf, lba_t lba,
|
_read_mode2_sectors (_img_private_t *p_env, void *p_buf, lba_t lba,
|
||||||
unsigned int nblocks, bool b_read_10)
|
unsigned int nblocks, bool b_read_10)
|
||||||
{
|
{
|
||||||
unsigned int l = 0;
|
unsigned int l = 0;
|
||||||
@@ -401,10 +429,10 @@ _read_mode2_sectors (int fd, void *buf, lba_t lba,
|
|||||||
while (nblocks > 0)
|
while (nblocks > 0)
|
||||||
{
|
{
|
||||||
const unsigned nblocks2 = (nblocks > 25) ? 25 : nblocks;
|
const unsigned nblocks2 = (nblocks > 25) ? 25 : nblocks;
|
||||||
void *buf2 = ((char *)buf ) + (l * M2RAW_SECTOR_SIZE);
|
void *p_buf2 = ((char *)p_buf ) + (l * M2RAW_SECTOR_SIZE);
|
||||||
|
|
||||||
retval |= _read_mode2_sectors_mmc (fd, buf2, lba + l, nblocks2,
|
retval |= _read_mode2_sectors_mmc (p_env, p_buf2, lba + l,
|
||||||
b_read_10);
|
nblocks2, b_read_10);
|
||||||
|
|
||||||
if (retval)
|
if (retval)
|
||||||
break;
|
break;
|
||||||
@@ -421,16 +449,16 @@ _read_mode2_sectors (int fd, void *buf, lba_t lba,
|
|||||||
from lsn. Returns 0 if no error.
|
from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_mode1_sector_linux (void *env, void *data, lsn_t lsn,
|
_read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
|
||||||
bool b_form2)
|
bool b_form2)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if FIXED
|
#if FIXED
|
||||||
char buf[M2RAW_SECTOR_SIZE] = { 0, };
|
char buf[M2RAW_SECTOR_SIZE] = { 0, };
|
||||||
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
|
struct cdrom_msf *p_msf = (struct cdrom_msf *) &buf;
|
||||||
msf_t _msf;
|
msf_t _msf;
|
||||||
|
|
||||||
_img_private_t *_obj = env;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
|
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
|
||||||
msf->cdmsf_min0 = from_bcd8(_msf.m);
|
msf->cdmsf_min0 = from_bcd8(_msf.m);
|
||||||
@@ -446,7 +474,7 @@ _read_mode1_sector_linux (void *env, void *data, lsn_t lsn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _AM_IOCTL:
|
case _AM_IOCTL:
|
||||||
if (ioctl (_obj->gen.fd, CDROMREADMODE1, &buf) == -1)
|
if (ioctl (p_env->gen.fd, CDROMREADMODE1, &buf) == -1)
|
||||||
{
|
{
|
||||||
perror ("ioctl()");
|
perror ("ioctl()");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -456,20 +484,20 @@ _read_mode1_sector_linux (void *env, void *data, lsn_t lsn,
|
|||||||
|
|
||||||
case _AM_READ_CD:
|
case _AM_READ_CD:
|
||||||
case _AM_READ_10:
|
case _AM_READ_10:
|
||||||
if (_read_mode2_sectors (_obj->gen.fd, buf, lsn, 1,
|
if (_read_mode2_sectors (p_env->gen.fd, buf, lsn, 1,
|
||||||
(_obj->access_mode == _AM_READ_10)))
|
(p_env->access_mode == _AM_READ_10)))
|
||||||
{
|
{
|
||||||
perror ("ioctl()");
|
perror ("ioctl()");
|
||||||
if (_obj->access_mode == _AM_READ_CD)
|
if (p_env->access_mode == _AM_READ_CD)
|
||||||
{
|
{
|
||||||
cdio_info ("READ_CD failed; switching to READ_10 mode...");
|
cdio_info ("READ_CD failed; switching to READ_10 mode...");
|
||||||
_obj->access_mode = _AM_READ_10;
|
p_env->access_mode = _AM_READ_10;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");
|
cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");
|
||||||
_obj->access_mode = _AM_IOCTL;
|
p_env->access_mode = _AM_IOCTL;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -481,7 +509,7 @@ _read_mode1_sector_linux (void *env, void *data, lsn_t lsn,
|
|||||||
b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE);
|
b_form2 ? M2RAW_SECTOR_SIZE: CDIO_CD_FRAMESIZE);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return cdio_generic_read_form1_sector(env, data, lsn);
|
return cdio_generic_read_form1_sector(p_user_data, p_data, lsn);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -492,17 +520,17 @@ _read_mode1_sector_linux (void *env, void *data, lsn_t lsn,
|
|||||||
Returns 0 if no error.
|
Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_mode1_sectors_linux (void *user_data, void *data, lsn_t lsn,
|
_read_mode1_sectors_linux (void *p_user_data, void *p_data, lsn_t lsn,
|
||||||
bool b_form2, unsigned int nblocks)
|
bool b_form2, unsigned int nblocks)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int retval;
|
int retval;
|
||||||
unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
|
unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
|
||||||
|
|
||||||
for (i = 0; i < nblocks; i++) {
|
for (i = 0; i < nblocks; i++) {
|
||||||
if ( (retval = _read_mode1_sector_linux (env,
|
if ( (retval = _read_mode1_sector_linux (p_env,
|
||||||
((char *)data) + (blocksize * i),
|
((char *)p_data) + (blocksize * i),
|
||||||
lsn + i, b_form2)) )
|
lsn + i, b_form2)) )
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -514,14 +542,14 @@ _read_mode1_sectors_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
from lsn. Returns 0 if no error.
|
from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
_read_mode2_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
|
||||||
bool b_form2)
|
bool b_form2)
|
||||||
{
|
{
|
||||||
char buf[M2RAW_SECTOR_SIZE] = { 0, };
|
char buf[M2RAW_SECTOR_SIZE] = { 0, };
|
||||||
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
|
struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
|
||||||
msf_t _msf;
|
msf_t _msf;
|
||||||
|
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
|
cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
|
||||||
msf->cdmsf_min0 = from_bcd8(_msf.m);
|
msf->cdmsf_min0 = from_bcd8(_msf.m);
|
||||||
@@ -529,7 +557,7 @@ _read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
msf->cdmsf_frame0 = from_bcd8(_msf.f);
|
msf->cdmsf_frame0 = from_bcd8(_msf.f);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
switch (env->access_mode)
|
switch (p_env->access_mode)
|
||||||
{
|
{
|
||||||
case _AM_NONE:
|
case _AM_NONE:
|
||||||
cdio_warn ("no way to read mode2");
|
cdio_warn ("no way to read mode2");
|
||||||
@@ -537,7 +565,7 @@ _read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case _AM_IOCTL:
|
case _AM_IOCTL:
|
||||||
if (ioctl (env->gen.fd, CDROMREADMODE2, &buf) == -1)
|
if (ioctl (p_env->gen.fd, CDROMREADMODE2, &buf) == -1)
|
||||||
{
|
{
|
||||||
perror ("ioctl()");
|
perror ("ioctl()");
|
||||||
return 1;
|
return 1;
|
||||||
@@ -547,20 +575,20 @@ _read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
|
|
||||||
case _AM_READ_CD:
|
case _AM_READ_CD:
|
||||||
case _AM_READ_10:
|
case _AM_READ_10:
|
||||||
if (_read_mode2_sectors (env->gen.fd, buf, lsn, 1,
|
if (_read_mode2_sectors (p_env, buf, lsn, 1,
|
||||||
(env->access_mode == _AM_READ_10)))
|
(p_env->access_mode == _AM_READ_10)))
|
||||||
{
|
{
|
||||||
perror ("ioctl()");
|
perror ("ioctl()");
|
||||||
if (env->access_mode == _AM_READ_CD)
|
if (p_env->access_mode == _AM_READ_CD)
|
||||||
{
|
{
|
||||||
cdio_info ("READ_CD failed; switching to READ_10 mode...");
|
cdio_info ("READ_CD failed; switching to READ_10 mode...");
|
||||||
env->access_mode = _AM_READ_10;
|
p_env->access_mode = _AM_READ_10;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");
|
cdio_info ("READ_10 failed; switching to ioctl(CDROMREADMODE2) mode...");
|
||||||
env->access_mode = _AM_IOCTL;
|
p_env->access_mode = _AM_IOCTL;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -569,9 +597,9 @@ _read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (b_form2)
|
if (b_form2)
|
||||||
memcpy (data, buf, M2RAW_SECTOR_SIZE);
|
memcpy (p_data, buf, M2RAW_SECTOR_SIZE);
|
||||||
else
|
else
|
||||||
memcpy (((char *)data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);
|
memcpy (((char *)p_data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -582,17 +610,17 @@ _read_mode2_sector_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
Returns 0 if no error.
|
Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_read_mode2_sectors_linux (void *user_data, void *data, lsn_t lsn,
|
_read_mode2_sectors_linux (void *p_user_data, void *data, lsn_t lsn,
|
||||||
bool b_form2, unsigned int nblocks)
|
bool b_form2, unsigned int nblocks)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
|
unsigned int i_blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
|
||||||
|
|
||||||
/* For each frame, pick out the data part we need */
|
/* For each frame, pick out the data part we need */
|
||||||
for (i = 0; i < nblocks; i++) {
|
for (i = 0; i < nblocks; i++) {
|
||||||
int retval;
|
int retval;
|
||||||
if ( (retval = _read_mode2_sector_linux (env,
|
if ( (retval = _read_mode2_sector_linux (p_env,
|
||||||
((char *)data) + (i_blocksize * i),
|
((char *)data) + (i_blocksize * i),
|
||||||
lsn + i, b_form2)) )
|
lsn + i, b_form2)) )
|
||||||
return retval;
|
return retval;
|
||||||
@@ -604,16 +632,16 @@ _read_mode2_sectors_linux (void *user_data, void *data, lsn_t lsn,
|
|||||||
Return the size of the CD in logical block address (LBA) units.
|
Return the size of the CD in logical block address (LBA) units.
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
static uint32_t
|
||||||
_stat_size_linux (void *user_data)
|
_stat_size_linux (void *p_user_data)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
struct cdrom_tocentry tocent;
|
struct cdrom_tocentry tocent;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
tocent.cdte_track = CDIO_CDROM_LEADOUT_TRACK;
|
tocent.cdte_track = CDIO_CDROM_LEADOUT_TRACK;
|
||||||
tocent.cdte_format = CDROM_LBA;
|
tocent.cdte_format = CDROM_LBA;
|
||||||
if (ioctl (env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
|
if (ioctl (p_env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
|
||||||
{
|
{
|
||||||
perror ("ioctl(CDROMREADTOCENTRY)");
|
perror ("ioctl(CDROMREADTOCENTRY)");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
@@ -633,18 +661,18 @@ _stat_size_linux (void *user_data)
|
|||||||
0 is returned if no error was found, and nonzero if there as an error.
|
0 is returned if no error was found, and nonzero if there as an error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_set_arg_linux (void *user_data, const char key[], const char value[])
|
_set_arg_linux (void *p_user_data, const char key[], const char value[])
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (!strcmp (key, "source"))
|
if (!strcmp (key, "source"))
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
free (env->gen.source_name);
|
free (p_env->gen.source_name);
|
||||||
|
|
||||||
env->gen.source_name = strdup (value);
|
p_env->gen.source_name = strdup (value);
|
||||||
}
|
}
|
||||||
else if (!strcmp (key, "access-mode"))
|
else if (!strcmp (key, "access-mode"))
|
||||||
{
|
{
|
||||||
@@ -661,12 +689,12 @@ _set_arg_linux (void *user_data, const char key[], const char value[])
|
|||||||
Return false if successful or true if an error.
|
Return false if successful or true if an error.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
_cdio_read_toc (_img_private_t *env)
|
_cdio_read_toc (_img_private_t *p_env)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* read TOC header */
|
/* read TOC header */
|
||||||
if ( ioctl(env->gen.fd, CDROMREADTOCHDR, &env->tochdr) == -1 ) {
|
if ( ioctl(p_env->gen.fd, CDROMREADTOCHDR, &p_env->tochdr) == -1 ) {
|
||||||
cdio_warn("%s: %s\n",
|
cdio_warn("%s: %s\n",
|
||||||
"error in ioctl CDROMREADTOCHDR", strerror(errno));
|
"error in ioctl CDROMREADTOCHDR", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
@@ -674,10 +702,10 @@ _cdio_read_toc (_img_private_t *env)
|
|||||||
|
|
||||||
/* read individual tracks */
|
/* read individual tracks */
|
||||||
for (i= FIRST_TRACK_NUM; i<=TOTAL_TRACKS; i++) {
|
for (i= FIRST_TRACK_NUM; i<=TOTAL_TRACKS; i++) {
|
||||||
env->tocent[i-FIRST_TRACK_NUM].cdte_track = i;
|
p_env->tocent[i-FIRST_TRACK_NUM].cdte_track = i;
|
||||||
env->tocent[i-FIRST_TRACK_NUM].cdte_format = CDROM_MSF;
|
p_env->tocent[i-FIRST_TRACK_NUM].cdte_format = CDROM_MSF;
|
||||||
if ( ioctl(env->gen.fd, CDROMREADTOCENTRY,
|
if ( ioctl(p_env->gen.fd, CDROMREADTOCENTRY,
|
||||||
&env->tocent[i-FIRST_TRACK_NUM]) == -1 ) {
|
&p_env->tocent[i-FIRST_TRACK_NUM]) == -1 ) {
|
||||||
cdio_warn("%s %d: %s\n",
|
cdio_warn("%s %d: %s\n",
|
||||||
"error in ioctl CDROMREADTOCENTRY for track",
|
"error in ioctl CDROMREADTOCENTRY for track",
|
||||||
i, strerror(errno));
|
i, strerror(errno));
|
||||||
@@ -693,11 +721,11 @@ _cdio_read_toc (_img_private_t *env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read the lead-out track */
|
/* read the lead-out track */
|
||||||
env->tocent[TOTAL_TRACKS].cdte_track = CDIO_CDROM_LEADOUT_TRACK;
|
p_env->tocent[TOTAL_TRACKS].cdte_track = CDIO_CDROM_LEADOUT_TRACK;
|
||||||
env->tocent[TOTAL_TRACKS].cdte_format = CDROM_MSF;
|
p_env->tocent[TOTAL_TRACKS].cdte_format = CDROM_MSF;
|
||||||
|
|
||||||
if (ioctl(env->gen.fd, CDROMREADTOCENTRY,
|
if (ioctl(p_env->gen.fd, CDROMREADTOCENTRY,
|
||||||
&env->tocent[TOTAL_TRACKS]) == -1 ) {
|
&p_env->tocent[TOTAL_TRACKS]) == -1 ) {
|
||||||
cdio_warn("%s: %s\n",
|
cdio_warn("%s: %s\n",
|
||||||
"error in ioctl CDROMREADTOCENTRY for lead-out",
|
"error in ioctl CDROMREADTOCENTRY for lead-out",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -711,7 +739,7 @@ _cdio_read_toc (_img_private_t *env)
|
|||||||
i, msf->minute, msf->second, msf->frame);
|
i, msf->minute, msf->second, msf->frame);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
env->gen.toc_init = true;
|
p_env->gen.toc_init = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,35 +767,31 @@ set_cdtext_field_linux(void *user_data, track_t i_track,
|
|||||||
not exist.
|
not exist.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
_init_cdtext_linux (_img_private_t *env)
|
_init_cdtext_linux (_img_private_t *p_env)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct cdrom_generic_command cdc;
|
scsi_mmc_cdb_t cdb;
|
||||||
struct request_sense sense;
|
|
||||||
unsigned char wdata[2000]= {0, }; /* Data read from device starts here */
|
unsigned char wdata[2000]= {0, }; /* Data read from device starts here */
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
memset(&cdc, 0, sizeof(struct cdrom_generic_command));
|
memset (&cdb, 0, sizeof (scsi_mmc_cdb_t));
|
||||||
memset(&sense, 0, sizeof(struct request_sense));
|
|
||||||
|
|
||||||
/* Operation code */
|
/* Operation code */
|
||||||
CDIO_MMC_SET_COMMAND(cdc.cmd, CDIO_MMC_GPCMD_READ_TOC);
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
|
||||||
|
|
||||||
/* Format */
|
/* Format */
|
||||||
cdc.cmd[2] = CDIO_MMC_READTOC_FMT_CDTEXT;
|
cdb.field[2] = CDIO_MMC_READTOC_FMT_CDTEXT;
|
||||||
|
|
||||||
cdc.buffer = wdata;
|
status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
cdc.buflen = sizeof(wdata);
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
cdc.stat = 0;
|
SCSI_MMC_DATA_READ, sizeof(wdata), &wdata);
|
||||||
cdc.sense = &sense;
|
|
||||||
cdc.data_direction = CGC_DATA_READ;
|
|
||||||
|
|
||||||
status = ioctl(env->gen.fd, CDROM_SEND_PACKET, (void *)&cdc);
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
cdio_info ("CDTEXT reading failed\n");
|
cdio_info ("CD-TEXT reading failed\n");
|
||||||
|
p_env->b_cdtext_error = true;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return cdtext_data_init(env, FIRST_TRACK_NUM, wdata,
|
return cdtext_data_init(p_env, FIRST_TRACK_NUM, wdata,
|
||||||
set_cdtext_field_linux);
|
set_cdtext_field_linux);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -780,78 +804,63 @@ _init_cdtext_linux (_img_private_t *env)
|
|||||||
or CD-TEXT information does not exist.
|
or CD-TEXT information does not exist.
|
||||||
*/
|
*/
|
||||||
static const cdtext_t *
|
static const cdtext_t *
|
||||||
_get_cdtext_linux (void *user_data, track_t i_track)
|
_get_cdtext_linux (void *p_user_data, track_t i_track)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if ( NULL == env ||
|
if ( NULL == p_env ||
|
||||||
(0 != i_track
|
(0 != i_track
|
||||||
&& i_track >= TOTAL_TRACKS+FIRST_TRACK_NUM ) )
|
&& i_track >= TOTAL_TRACKS+FIRST_TRACK_NUM ) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
env->b_cdtext_init = _init_cdtext_linux(env);
|
p_env->b_cdtext_init = _init_cdtext_linux(p_env);
|
||||||
if (!env->b_cdtext_init) return NULL;
|
if (!p_env->b_cdtext_init || p_env->b_cdtext_error) return NULL;
|
||||||
|
|
||||||
if (0 == i_track)
|
if (0 == i_track)
|
||||||
return &(env->cdtext);
|
return &(p_env->cdtext);
|
||||||
else
|
else
|
||||||
return &(env->cdtext_track[i_track-FIRST_TRACK_NUM]);
|
return &(p_env->cdtext_track[i_track-FIRST_TRACK_NUM]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Eject using SCSI commands. Return 1 if successful, 0 otherwise.
|
* Eject using SCSI MMC commands. Return 1 if successful, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_eject_media_mmc(int fd)
|
_eject_media_mmc(_img_private_t *p_env)
|
||||||
{
|
{
|
||||||
int status;
|
int i_status;
|
||||||
struct sdata {
|
scsi_mmc_cdb_t cdb;
|
||||||
unsigned int inlen; /* Length of data written to device */
|
uint8_t buf[1];
|
||||||
unsigned int outlen; /* Length of data read from device */
|
|
||||||
char cdb[10]; /* SCSI command bytes (6 <= x <= 16) */
|
|
||||||
} scsi_cmd;
|
|
||||||
|
|
||||||
CDIO_MMC_SET_COMMAND(scsi_cmd.cdb, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL);
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL);
|
||||||
|
|
||||||
scsi_cmd.inlen = 0;
|
i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
scsi_cmd.outlen = 0;
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
scsi_cmd.cdb[1] = 0;
|
SCSI_MMC_DATA_WRITE, 0, &buf);
|
||||||
scsi_cmd.cdb[2] = 0;
|
if (0 != i_status)
|
||||||
scsi_cmd.cdb[3] = 0;
|
return i_status;
|
||||||
scsi_cmd.cdb[4] = 0;
|
|
||||||
scsi_cmd.cdb[5] = 0;
|
|
||||||
status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);
|
|
||||||
if (status != 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
scsi_cmd.inlen = 0;
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
|
||||||
scsi_cmd.outlen = 0;
|
cdb.field[4] = 1;
|
||||||
CDIO_MMC_SET_COMMAND(scsi_cmd.cdb, CDIO_MMC_GPCMD_START_STOP);
|
i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
scsi_cmd.cdb[1] = 0;
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
scsi_cmd.cdb[2] = 0;
|
SCSI_MMC_DATA_WRITE, 0, &buf);
|
||||||
scsi_cmd.cdb[3] = 0;
|
if (0 != i_status)
|
||||||
scsi_cmd.cdb[4] = 1;
|
return i_status;
|
||||||
scsi_cmd.cdb[5] = 0;
|
|
||||||
status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);
|
|
||||||
if (status != 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
scsi_cmd.inlen = 0;
|
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
|
||||||
scsi_cmd.outlen = 0;
|
cdb.field[4] = 2; /* eject */
|
||||||
CDIO_MMC_SET_COMMAND(scsi_cmd.cdb, CDIO_MMC_GPCMD_START_STOP);
|
|
||||||
scsi_cmd.cdb[1] = 0;
|
i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT,
|
||||||
scsi_cmd.cdb[2] = 0;
|
scsi_mmc_get_cmd_len(cdb.field[0]), &cdb,
|
||||||
scsi_cmd.cdb[3] = 0;
|
SCSI_MMC_DATA_WRITE, 0, &buf);
|
||||||
scsi_cmd.cdb[4] = 2; /* eject */
|
if (0 != i_status)
|
||||||
scsi_cmd.cdb[5] = 0;
|
return i_status;
|
||||||
status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd);
|
|
||||||
if (status != 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
/* force kernel to reread partition table when new disc inserted */
|
/* force kernel to reread partition table when new disc inserted */
|
||||||
status = ioctl(fd, BLKRRPART);
|
i_status = ioctl(p_env->gen.fd, BLKRRPART);
|
||||||
return (status);
|
return (i_status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -860,16 +869,14 @@ _eject_media_mmc(int fd)
|
|||||||
Return 0 if success and 1 for failure, and 2 if no routine.
|
Return 0 if success and 1 for failure, and 2 if no routine.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_eject_media_linux (void *user_data) {
|
_eject_media_linux (void *p_user_data) {
|
||||||
|
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
int ret=2;
|
int ret=2;
|
||||||
int status;
|
int status;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
close(env->gen.fd);
|
if ((fd = open (p_env->gen.source_name, O_RDONLY|O_NONBLOCK)) > -1) {
|
||||||
env->gen.fd = -1;
|
|
||||||
if ((fd = open (env->gen.source_name, O_RDONLY|O_NONBLOCK)) > -1) {
|
|
||||||
if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {
|
if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case CDS_TRAY_OPEN:
|
case CDS_TRAY_OPEN:
|
||||||
@@ -882,7 +889,7 @@ _eject_media_linux (void *user_data) {
|
|||||||
if((ret = ioctl(fd, CDROMEJECT)) != 0) {
|
if((ret = ioctl(fd, CDROMEJECT)) != 0) {
|
||||||
int eject_error = errno;
|
int eject_error = errno;
|
||||||
/* Try ejecting the MMC way... */
|
/* Try ejecting the MMC way... */
|
||||||
ret = _eject_media_mmc(fd);
|
ret = _eject_media_mmc(p_env);
|
||||||
if (0 != ret) {
|
if (0 != ret) {
|
||||||
cdio_warn("ioctl CDROMEJECT failed: %s\n", strerror(eject_error));
|
cdio_warn("ioctl CDROMEJECT failed: %s\n", strerror(eject_error));
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@@ -898,9 +905,11 @@ _eject_media_linux (void *user_data) {
|
|||||||
ret=1;
|
ret=1;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
return ret;
|
} else
|
||||||
}
|
ret = 2;
|
||||||
return 2;
|
close(p_env->gen.fd);
|
||||||
|
p_env->gen.fd = -1;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -933,11 +942,11 @@ _get_arg_linux (void *env, const char key[])
|
|||||||
CDIO_INVALID_TRACK is returned on error.
|
CDIO_INVALID_TRACK is returned on error.
|
||||||
*/
|
*/
|
||||||
static track_t
|
static track_t
|
||||||
_get_first_track_num_linux(void *user_data)
|
_get_first_track_num_linux(void *p_user_data)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (!env->gen.toc_init) _cdio_read_toc (env) ;
|
if (!p_env->gen.toc_init) _cdio_read_toc (p_env) ;
|
||||||
|
|
||||||
return FIRST_TRACK_NUM;
|
return FIRST_TRACK_NUM;
|
||||||
}
|
}
|
||||||
@@ -1031,11 +1040,11 @@ _get_drive_cap_linux (const void *env,
|
|||||||
CDIO_INVALID_TRACK is returned on error.
|
CDIO_INVALID_TRACK is returned on error.
|
||||||
*/
|
*/
|
||||||
static track_t
|
static track_t
|
||||||
_get_num_tracks_linux(void *user_data)
|
_get_num_tracks_linux(void *p_user_data)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (!env->gen.toc_init) _cdio_read_toc (env) ;
|
if (!p_env->gen.toc_init) _cdio_read_toc (p_env) ;
|
||||||
|
|
||||||
return TOTAL_TRACKS;
|
return TOTAL_TRACKS;
|
||||||
}
|
}
|
||||||
@@ -1044,9 +1053,9 @@ _get_num_tracks_linux(void *user_data)
|
|||||||
Get format of track.
|
Get format of track.
|
||||||
*/
|
*/
|
||||||
static track_format_t
|
static track_format_t
|
||||||
_get_track_format_linux(void *user_data, track_t i_track)
|
_get_track_format_linux(void *p_user_data, track_t i_track)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (i_track > (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM)
|
if (i_track > (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM)
|
||||||
return TRACK_FORMAT_ERROR;
|
return TRACK_FORMAT_ERROR;
|
||||||
@@ -1056,10 +1065,10 @@ _get_track_format_linux(void *user_data, track_t i_track)
|
|||||||
/* This is pretty much copied from the "badly broken" cdrom_count_tracks
|
/* This is pretty much copied from the "badly broken" cdrom_count_tracks
|
||||||
in linux/cdrom.c.
|
in linux/cdrom.c.
|
||||||
*/
|
*/
|
||||||
if (env->tocent[i_track].cdte_ctrl & CDIO_CDROM_DATA_TRACK) {
|
if (p_env->tocent[i_track].cdte_ctrl & CDIO_CDROM_DATA_TRACK) {
|
||||||
if (env->tocent[i_track].cdte_format == CDIO_CDROM_CDI_TRACK)
|
if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_CDI_TRACK)
|
||||||
return TRACK_FORMAT_CDI;
|
return TRACK_FORMAT_CDI;
|
||||||
else if (env->tocent[i_track].cdte_format == CDIO_CDROM_XA_TRACK)
|
else if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_XA_TRACK)
|
||||||
return TRACK_FORMAT_XA;
|
return TRACK_FORMAT_XA;
|
||||||
else
|
else
|
||||||
return TRACK_FORMAT_DATA;
|
return TRACK_FORMAT_DATA;
|
||||||
@@ -1077,11 +1086,11 @@ _get_track_format_linux(void *user_data, track_t i_track)
|
|||||||
FIXME: there's gotta be a better design for this and get_track_format?
|
FIXME: there's gotta be a better design for this and get_track_format?
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
_get_track_green_linux(void *user_data, track_t i_track)
|
_get_track_green_linux(void *p_user_data, track_t i_track)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (!env->gen.toc_init) _cdio_read_toc (env) ;
|
if (!p_env->gen.toc_init) _cdio_read_toc (p_env) ;
|
||||||
|
|
||||||
if (i_track >= (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM)
|
if (i_track >= (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM)
|
||||||
return false;
|
return false;
|
||||||
@@ -1091,7 +1100,7 @@ _get_track_green_linux(void *user_data, track_t i_track)
|
|||||||
/* FIXME: Dunno if this is the right way, but it's what
|
/* FIXME: Dunno if this is the right way, but it's what
|
||||||
I was using in cd-info for a while.
|
I was using in cd-info for a while.
|
||||||
*/
|
*/
|
||||||
return ((env->tocent[i_track].cdte_ctrl & 2) != 0);
|
return ((p_env->tocent[i_track].cdte_ctrl & 2) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1104,13 +1113,13 @@ _get_track_green_linux(void *user_data, track_t i_track)
|
|||||||
False is returned if there is no track entry.
|
False is returned if there is no track entry.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
_get_track_msf_linux(void *user_data, track_t i_track, msf_t *msf)
|
_get_track_msf_linux(void *p_user_data, track_t i_track, msf_t *msf)
|
||||||
{
|
{
|
||||||
_img_private_t *env = user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
|
|
||||||
if (NULL == msf) return false;
|
if (NULL == msf) return false;
|
||||||
|
|
||||||
if (!env->gen.toc_init) _cdio_read_toc (env) ;
|
if (!p_env->gen.toc_init) _cdio_read_toc (p_env) ;
|
||||||
|
|
||||||
if (i_track == CDIO_CDROM_LEADOUT_TRACK)
|
if (i_track == CDIO_CDROM_LEADOUT_TRACK)
|
||||||
i_track = TOTAL_TRACKS + FIRST_TRACK_NUM;
|
i_track = TOTAL_TRACKS + FIRST_TRACK_NUM;
|
||||||
@@ -1118,7 +1127,8 @@ _get_track_msf_linux(void *user_data, track_t i_track, msf_t *msf)
|
|||||||
if (i_track > (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM) {
|
if (i_track > (TOTAL_TRACKS+FIRST_TRACK_NUM) || i_track < FIRST_TRACK_NUM) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
struct cdrom_msf0 *msf0= &env->tocent[i_track-FIRST_TRACK_NUM].cdte_addr.msf;
|
struct cdrom_msf0 *msf0=
|
||||||
|
&p_env->tocent[i_track-FIRST_TRACK_NUM].cdte_addr.msf;
|
||||||
msf->m = to_bcd8(msf0->minute);
|
msf->m = to_bcd8(msf0->minute);
|
||||||
msf->s = to_bcd8(msf0->second);
|
msf->s = to_bcd8(msf0->second);
|
||||||
msf->f = to_bcd8(msf0->frame);
|
msf->f = to_bcd8(msf0->frame);
|
||||||
@@ -1307,6 +1317,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
|
|||||||
_data->gen.init = false;
|
_data->gen.init = false;
|
||||||
_data->gen.fd = -1;
|
_data->gen.fd = -1;
|
||||||
_data->b_cdtext_init = false;
|
_data->b_cdtext_init = false;
|
||||||
|
_data->b_cdtext_error = false;
|
||||||
|
|
||||||
if (NULL == psz_orig_source) {
|
if (NULL == psz_orig_source) {
|
||||||
psz_source=cdio_get_default_device_linux();
|
psz_source=cdio_get_default_device_linux();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: _cdio_sunos.c,v 1.56 2004/07/19 01:29:04 rocky Exp $
|
$Id: _cdio_sunos.c,v 1.57 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||||
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_SOLARIS_CDROM
|
#ifdef HAVE_SOLARIS_CDROM
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.56 2004/07/19 01:29:04 rocky Exp $";
|
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.57 2004/07/22 09:52:17 rocky Exp $";
|
||||||
|
|
||||||
#ifdef HAVE_GLOB_H
|
#ifdef HAVE_GLOB_H
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
@@ -649,7 +649,7 @@ _get_drive_cap_solaris (const void *user_data,
|
|||||||
/* Don't handle these yet. */
|
/* Don't handle these yet. */
|
||||||
break;
|
break;
|
||||||
case CDIO_MMC_CAPABILITIES_PAGE:
|
case CDIO_MMC_CAPABILITIES_PAGE:
|
||||||
cdio_get_drive_cap_mmc(p, p_read_cap, p_write_cap, p_misc_cap);
|
scsi_mmc_get_drive_cap(p, p_read_cap, p_write_cap, p_misc_cap);
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: cdio_private.h,v 1.31 2004/07/21 10:19:21 rocky Exp $
|
$Id: cdio_private.h,v 1.32 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/cdtext.h>
|
#include <cdio/cdtext.h>
|
||||||
|
#include <cdio/scsi_mmc.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -198,6 +199,29 @@ extern "C" {
|
|||||||
int (*read_mode1_sectors) (void *env, void *buf, lsn_t lsn,
|
int (*read_mode1_sectors) (void *env, void *buf, lsn_t lsn,
|
||||||
bool mode1_form2, unsigned int nblocks);
|
bool mode1_form2, unsigned int nblocks);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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.
|
||||||
|
cdb_len number of bytes in cdb (6, 10, or 12).
|
||||||
|
cdb CDB bytes. All values that are needed should be set on
|
||||||
|
input.
|
||||||
|
b_return_data TRUE if the command expects data to be returned in
|
||||||
|
the buffer
|
||||||
|
len Size of buffer
|
||||||
|
buf Buffer for data, both sending and receiving
|
||||||
|
|
||||||
|
Returns 0 if command completed successfully.
|
||||||
|
*/
|
||||||
|
int (*run_scsi_mmc_cmd) ( const CdIo *cdio, unsigned int i_timeout,
|
||||||
|
unsigned int cdb_len,
|
||||||
|
const scsi_mmc_cdb_t *p_cdb,
|
||||||
|
scsi_mmc_direction_t e_direction,
|
||||||
|
unsigned int len, /*in/out*/ void *p_buf );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Set the arg "key" with "value" in the source device.
|
Set the arg "key" with "value" in the source device.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Common MMC routines.
|
/* Common MMC routines.
|
||||||
|
|
||||||
$Id: scsi_mmc.c,v 1.6 2004/07/19 01:13:32 rocky Exp $
|
$Id: scsi_mmc.c,v 1.7 2004/07/22 09:52:17 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2004 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/scsi_mmc.h>
|
#include <cdio/scsi_mmc.h>
|
||||||
|
#include "cdio_private.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
On input a MODE_SENSE command was issued and we have the results
|
On input a MODE_SENSE command was issued and we have the results
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
capabilities.
|
capabilities.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cdio_get_drive_cap_mmc(const uint8_t *p,
|
scsi_mmc_get_drive_cap(const uint8_t *p,
|
||||||
/*out*/ cdio_drive_read_cap_t *p_read_cap,
|
/*out*/ cdio_drive_read_cap_t *p_read_cap,
|
||||||
/*out*/ cdio_drive_write_cap_t *p_write_cap,
|
/*out*/ cdio_drive_write_cap_t *p_write_cap,
|
||||||
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
|
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
|
||||||
@@ -59,3 +60,43 @@ cdio_get_drive_cap_mmc(const uint8_t *p,
|
|||||||
if (p[6] >> 5 != 0)
|
if (p[6] >> 5 != 0)
|
||||||
*p_misc_cap |= CDIO_DRIVE_CAP_MISC_CLOSE_TRAY;
|
*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.
|
||||||
|
|
||||||
|
We return 0 if command completed successfully and 1 if not.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
scsi_mmc_run_cmd( const CdIo *cdio, int i_timeout, const scsi_mmc_cdb_t *p_cdb,
|
||||||
|
scsi_mmc_direction_t e_direction, unsigned int i_buf,
|
||||||
|
/*in/out*/ void *p_buf )
|
||||||
|
{
|
||||||
|
if (cdio && cdio->op.run_scsi_mmc_cmd) {
|
||||||
|
return cdio->op.run_scsi_mmc_cmd(cdio, i_timeout,
|
||||||
|
scsi_mmc_get_cmd_len(p_cdb->field[0]),
|
||||||
|
p_cdb, e_direction, i_buf, p_buf);
|
||||||
|
} else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user