mmc: add mmc_close_tray().
mmc-tool: add option for close tray and to get mode-sense 2A data.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
$Id: mmc2a.c,v 1.2 2006/04/03 19:54:06 rocky Exp $
|
||||
$Id: mmc2a.c,v 1.3 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
/* Sample program to show use of the MMC interface.
|
||||
An optional drive name can be supplied as an argument.
|
||||
This basically the libdio mmc_get_hwinfo() routine.
|
||||
See also corresponding C++ programs.
|
||||
This basically calls to the libdio mmc_mode_sense_10() and mmc_mode_sense_6
|
||||
routines.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
$Id: cd_types.h,v 1.16 2006/03/28 03:26:16 rocky Exp $
|
||||
$Id: cd_types.h,v 1.17 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2003, 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2003, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
Copyright (C) 1996,1997,1998 Gerd Knorr <kraxel@bytesex.org>
|
||||
and Heiko Ei<45>feldt <heiko@hexco.de>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -*- c -*-
|
||||
$Id: device.h,v 1.35 2006/04/04 02:06:12 rocky Exp $
|
||||
$Id: device.h,v 1.36 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2005, 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (c) 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
$Id: mmc.h,v 1.26 2006/04/04 02:06:13 rocky Exp $
|
||||
$Id: mmc.h,v 1.27 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
@@ -18,7 +18,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*!
|
||||
/**
|
||||
* \file mmc.h
|
||||
*
|
||||
* \brief Common definitions for MMC (Multimedia Commands). Applications
|
||||
@@ -37,22 +37,22 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! Set this to the maximum value in milliseconds that we will
|
||||
/** Set this to the maximum value in milliseconds that we will
|
||||
wait on an MMC command. */
|
||||
extern uint32_t mmc_timeout_ms;
|
||||
|
||||
/*! The default timeout (non-read) is 6 seconds. */
|
||||
/** The default timeout (non-read) is 6 seconds. */
|
||||
#define MMC_TIMEOUT_DEFAULT 6000
|
||||
|
||||
/*! Set this to the maximum value in milliseconds that we will
|
||||
/** Set this to the maximum value in milliseconds that we will
|
||||
wait on an MMC read command. */
|
||||
extern uint32_t mmc_read_timeout_ms;
|
||||
|
||||
/*! The default read timeout is 3 minutes. */
|
||||
/** The default read timeout is 3 minutes. */
|
||||
#define MMC_READ_TIMEOUT_DEFAULT 3*60*1000
|
||||
|
||||
|
||||
/*! \brief The opcode-portion (generic packet commands) of an MMC command.
|
||||
/** \brief The opcode-portion (generic packet commands) of an MMC command.
|
||||
|
||||
In general, those opcodes that end in 6 take a 6-byte command
|
||||
descriptor, those that end in 10 take a 10-byte
|
||||
@@ -175,7 +175,7 @@ extern "C" {
|
||||
return */
|
||||
} cdio_mmc_read_sub_state_t;
|
||||
|
||||
/*! Level values that can go into READ_CD */
|
||||
/** Level values that can go into READ_CD */
|
||||
typedef enum {
|
||||
CDIO_MMC_READ_TYPE_ANY = 0, /**< All types */
|
||||
CDIO_MMC_READ_TYPE_CDDA = 1, /**< Only CD-DA sectors */
|
||||
@@ -185,7 +185,7 @@ extern "C" {
|
||||
CDIO_MMC_READ_TYPE_M2F2 = 5 /**< mode2 sectors form2 */
|
||||
} cdio_mmc_read_cd_type_t;
|
||||
|
||||
/*! Format values for READ_TOC */
|
||||
/** Format values for READ_TOC */
|
||||
typedef enum {
|
||||
CDIO_MMC_READTOC_FMT_TOC = 0,
|
||||
CDIO_MMC_READTOC_FMT_SESSION = 1,
|
||||
@@ -195,7 +195,7 @@ extern "C" {
|
||||
CDIO_MMC_READTOC_FMT_CDTEXT = 5 /**< CD-TEXT info */
|
||||
} cdio_mmc_readtoc_t;
|
||||
|
||||
/*! Page codes for MODE SENSE and MODE SET. */
|
||||
/** Page codes for MODE SENSE and MODE SET. */
|
||||
typedef enum {
|
||||
CDIO_MMC_R_W_ERROR_PAGE = 0x01,
|
||||
CDIO_MMC_WRITE_PARMS_PAGE = 0x05,
|
||||
@@ -218,7 +218,7 @@ PRAGMA_BEGIN_PACKED
|
||||
|
||||
typedef struct mmc_audio_volume_entry_s mmc_audio_volume_entry_t;
|
||||
|
||||
/*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
|
||||
/** This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */
|
||||
struct mmc_audio_volume_s
|
||||
{
|
||||
mmc_audio_volume_entry_t port[4];
|
||||
@@ -229,7 +229,7 @@ PRAGMA_BEGIN_PACKED
|
||||
PRAGMA_END_PACKED
|
||||
|
||||
|
||||
/*! Return type codes for GET_CONFIGURATION. */
|
||||
/** Return type codes for GET_CONFIGURATION. */
|
||||
typedef enum {
|
||||
CDIO_MMC_GET_CONF_ALL_FEATURES = 0, /**< all features without regard
|
||||
to currency. */
|
||||
@@ -241,7 +241,7 @@ typedef enum {
|
||||
} cdio_mmc_get_conf_t;
|
||||
|
||||
|
||||
/*! FEATURE codes used in GET CONFIGURATION. */
|
||||
/** FEATURE codes used in GET CONFIGURATION. */
|
||||
|
||||
typedef enum {
|
||||
CDIO_MMC_FEATURE_PROFILE_LIST = 0x000, /**< Profile List Feature */
|
||||
@@ -302,7 +302,7 @@ typedef enum {
|
||||
report */
|
||||
} cdio_mmc_feature_t;
|
||||
|
||||
/*! Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
|
||||
/** Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
|
||||
typedef enum {
|
||||
CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable
|
||||
of changing behavior */
|
||||
@@ -350,19 +350,19 @@ typedef enum {
|
||||
} cdio_mmc_feature_interface_t;
|
||||
|
||||
|
||||
/*! The largest Command Descriptor Block (CDB) size.
|
||||
/** The largest Command Descriptor Block (CDB) size.
|
||||
The possible sizes are 6, 10, and 12 bytes.
|
||||
*/
|
||||
#define MAX_CDB_LEN 12
|
||||
|
||||
/*! \brief A Command Descriptor Block (CDB) used in sending MMC
|
||||
/** \brief A Command Descriptor Block (CDB) used in sending MMC
|
||||
commands.
|
||||
*/
|
||||
typedef struct mmc_cdb_s {
|
||||
uint8_t field[MAX_CDB_LEN];
|
||||
} mmc_cdb_t;
|
||||
|
||||
/*! \brief Format of header block in data returned from an MMC
|
||||
/** \brief Format of header block in data returned from an MMC
|
||||
GET_CONFIGURATION command.
|
||||
*/
|
||||
typedef struct mmc_feature_list_header_s {
|
||||
@@ -376,7 +376,7 @@ typedef struct mmc_cdb_s {
|
||||
unsigned char profile_lsb;
|
||||
} cdio_mmc_feature_list_header_t;
|
||||
|
||||
/*! An enumeration indicating whether an MMC command is sending
|
||||
/** An enumeration indicating whether an MMC command is sending
|
||||
data or getting data.
|
||||
*/
|
||||
typedef enum mmc_direction_s {
|
||||
@@ -442,7 +442,7 @@ typedef struct mmc_cdb_s {
|
||||
#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \
|
||||
cdb[9] = val << 3;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Read Audio Subchannel information
|
||||
|
||||
@param p_cdio the CD object to be acted upon.
|
||||
@@ -452,58 +452,55 @@ driver_return_code_t
|
||||
mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
/*out*/ cdio_subchannel_t *p_subchannel);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return a string containing the name of the audio state as returned from
|
||||
the Q_SUBCHANNEL.
|
||||
*/
|
||||
const char *mmc_audio_state2str( uint8_t i_audio_state );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Eject using MMC commands. If CD-ROM is "locked" we'll unlock it.
|
||||
Command is not "immediate" -- we'll wait for the command to complete.
|
||||
For a more general (and lower-level) routine, @see mmc_start_stop_media.
|
||||
*/
|
||||
driver_return_code_t mmc_eject_media( const CdIo_t *p_cdio );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return a string containing the name of the given feature
|
||||
*/
|
||||
const char *mmc_feature2str( int i_feature );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return a string containing the name of the given feature
|
||||
*/
|
||||
const char *mmc_feature_profile2str( int i_feature_profile );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return the length in bytes of the Command Descriptor
|
||||
Buffer (CDB) for a given MMC command. The length will be
|
||||
either 6, 10, or 12.
|
||||
*/
|
||||
uint8_t mmc_get_cmd_len(uint8_t mmc_cmd);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the block size used in read requests, via MMC.
|
||||
@return the blocksize if > 0; error if <= 0
|
||||
*/
|
||||
int mmc_get_blocksize ( CdIo_t *p_cdio );
|
||||
|
||||
#if 0
|
||||
/*! Don't know how to implement yet. */
|
||||
/*!
|
||||
/**
|
||||
* Close tray using a MMC START STOP command.
|
||||
*/
|
||||
driver_return_code_t mmc_close_tray( const char *psz_device );
|
||||
#endif
|
||||
driver_return_code_t mmc_close_tray( CdIo_t *p_cdio );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the lsn of the end of the CD
|
||||
|
||||
@return the lsn. On error return CDIO_INVALID_LSN.
|
||||
*/
|
||||
lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Return the discmode as reported by the MMC Read (FULL) TOC
|
||||
command.
|
||||
|
||||
@@ -515,7 +512,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
discmode_t mmc_get_discmode( const CdIo_t *p_cdio );
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get drive capabilities for a device.
|
||||
@return the drive capabilities.
|
||||
*/
|
||||
@@ -532,13 +529,13 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
CDIO_MMC_LEVEL_NONE
|
||||
} cdio_mmc_level_t;
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the MMC level supported by the device.
|
||||
*/
|
||||
cdio_mmc_level_t mmc_get_drive_mmc_cap(CdIo_t *p_cdio);
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the DVD type associated with cd object.
|
||||
|
||||
@return the DVD discmode.
|
||||
@@ -546,7 +543,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
discmode_t mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio,
|
||||
cdio_dvd_struct_t *s);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the CD-ROM hardware info via an MMC INQUIRY command.
|
||||
|
||||
@return true if we were able to get hardware info, false if we had
|
||||
@@ -556,7 +553,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
/* out*/ cdio_hwinfo_t *p_hw_info );
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
Find out if media has changed since the last call.
|
||||
@param p_cdio the CD object to be acted upon.
|
||||
@return 1 if media has changed since last call, 0 if not. Error
|
||||
@@ -564,7 +561,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
*/
|
||||
int mmc_get_media_changed(const CdIo_t *p_cdio);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Get the media catalog number (MCN) from the CD via MMC.
|
||||
|
||||
@return the media catalog number r NULL if there is none or we
|
||||
@@ -583,7 +580,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/
|
||||
mmc_audio_volume_t *p_volume);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...)
|
||||
Is it possible for an interface to have serveral? If not this
|
||||
routine could probably return the single mmc_feature_interface_t.
|
||||
@@ -592,7 +589,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
bool_3way_t mmc_have_interface( CdIo_t *p_cdio,
|
||||
cdio_mmc_feature_interface_t e_interface );
|
||||
|
||||
/*! Run a MODE_SENSE command (6- or 10-byte version)
|
||||
/** Run a MODE_SENSE command (6- or 10-byte version)
|
||||
and put the results in p_buf
|
||||
@return DRIVER_OP_SUCCESS if we ran the command ok.
|
||||
*/
|
||||
@@ -600,21 +597,21 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
int page);
|
||||
|
||||
|
||||
/*! Run a MODE_SENSE command (10-byte version)
|
||||
/** Run a MODE_SENSE command (10-byte version)
|
||||
and put the results in p_buf
|
||||
@return DRIVER_OP_SUCCESS if we ran the command ok.
|
||||
*/
|
||||
int mmc_mode_sense_10( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size,
|
||||
int page);
|
||||
|
||||
/*! Run a MODE_SENSE command (6-byte version)
|
||||
/** Run a MODE_SENSE command (6-byte version)
|
||||
and put the results in p_buf
|
||||
@return DRIVER_OP_SUCCESS if we ran the command ok.
|
||||
*/
|
||||
int mmc_mode_sense_6( CdIo_t *p_cdio, /*out*/ void *p_buf, int i_size,
|
||||
int page);
|
||||
|
||||
/*! Issue a MMC READ_CD command.
|
||||
/** Issue a MMC READ_CD command.
|
||||
|
||||
@param p_cdio object to read from
|
||||
|
||||
@@ -722,7 +719,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
uint8_t subchannel_selection, uint16_t i_blocksize,
|
||||
uint32_t i_blocks );
|
||||
|
||||
/*! Read just the user data part of some sort of data sector (via
|
||||
/** Read just the user data part of some sort of data sector (via
|
||||
mmc_read_cd).
|
||||
|
||||
@param p_cdio object to read from
|
||||
@@ -745,14 +742,14 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
uint16_t i_blocksize,
|
||||
uint32_t i_blocks );
|
||||
|
||||
/*! Read sectors using SCSI-MMC GPCMD_READ_CD.
|
||||
/** Read sectors using SCSI-MMC GPCMD_READ_CD.
|
||||
Can read only up to 25 blocks.
|
||||
*/
|
||||
driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf,
|
||||
lsn_t i_lsn, int read_sector_type,
|
||||
uint32_t i_blocks);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Run a Multimedia command (MMC).
|
||||
|
||||
@param p_cdio CD structure set by cdio_open().
|
||||
@@ -771,13 +768,13 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
const mmc_cdb_t *p_cdb,
|
||||
cdio_mmc_direction_t e_direction, unsigned int i_buf,
|
||||
/*in/out*/ void *p_buf );
|
||||
/*!
|
||||
/**
|
||||
Set the block size for subsequest read requests, via MMC.
|
||||
*/
|
||||
driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio,
|
||||
uint16_t i_blocksize);
|
||||
|
||||
/*!
|
||||
/**
|
||||
Set the drive speed in CD-ROM speed units.
|
||||
|
||||
@param p_cdio CD structure set by cdio_open().
|
||||
@@ -797,7 +794,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
driver_return_code_t mmc_set_drive_speed( const CdIo_t *p_cdio,
|
||||
int i_drive_speed );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Set the drive speed in K bytes per second.
|
||||
|
||||
@param p_cdio CD structure set by cdio_open().
|
||||
@@ -821,7 +818,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
|
||||
driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio,
|
||||
int i_Kbs_speed );
|
||||
|
||||
/*!
|
||||
/**
|
||||
Load or Unload media using a MMC START STOP command.
|
||||
|
||||
@param p_cdio the CD object to be acted upon.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
$Id: udf_file.h,v 1.8 2006/04/11 05:47:57 rocky Exp $
|
||||
Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
||||
$Id: udf_file.h,v 1.9 2006/04/12 09:30:14 rocky Exp $
|
||||
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Common Multimedia Command (MMC) routines.
|
||||
|
||||
$Id: mmc.c,v 1.33 2006/04/05 02:20:06 rocky Exp $
|
||||
$Id: mmc.c,v 1.34 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2004, 2005, 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2004, 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
@@ -981,16 +981,18 @@ mmc_start_stop_media(const CdIo_t *p_cdio, bool b_eject, bool b_immediate,
|
||||
SCSI_MMC_DATA_WRITE, 0, &buf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*!
|
||||
/**
|
||||
* Close tray using a MMC START STOP command.
|
||||
*/
|
||||
driver_return_code_t
|
||||
mmc_close_tray( const CdIo_t *p_cdio )
|
||||
mmc_close_tray( CdIo_t *p_cdio )
|
||||
{
|
||||
if (p_cdio) {
|
||||
return mmc_start_stop_media(p_cdio, false, false, 0);
|
||||
} else {
|
||||
return DRIVER_OP_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Eject using MMC commands. If CD-ROM is "locked" we'll unlock it.
|
||||
|
||||
225
src/mmc-tool.c
225
src/mmc-tool.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
$Id: mmc-tool.c,v 1.5 2006/04/12 03:23:46 rocky Exp $
|
||||
$Id: mmc-tool.c,v 1.6 2006/04/12 09:30:14 rocky Exp $
|
||||
|
||||
Copyright (C) 2006 Rocky Bernstein <rocky@panix.com>
|
||||
Copyright (C) 2006 Rocky Bernstein <rocky@cpan.org>
|
||||
|
||||
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
|
||||
@@ -38,26 +38,18 @@
|
||||
#include "util.h"
|
||||
#include "getopt.h"
|
||||
|
||||
/* Used by `main' to communicate with `parse_opt'. And global options
|
||||
*/
|
||||
struct arguments
|
||||
{
|
||||
int i_speed;
|
||||
int i_blocksize;
|
||||
} opts;
|
||||
|
||||
static void
|
||||
init(const char *argv0)
|
||||
{
|
||||
program_name = strrchr(argv0,'/');
|
||||
program_name = program_name ? strdup(program_name+1) : strdup(argv0);
|
||||
opts.i_blocksize = 0;
|
||||
}
|
||||
|
||||
/* Configuration option codes */
|
||||
typedef enum {
|
||||
OPT_HANDLED = 0,
|
||||
OPT_USAGE,
|
||||
OPT_DRIVE_CAP,
|
||||
OPT_VERSION,
|
||||
} option_t;
|
||||
|
||||
@@ -68,6 +60,7 @@ typedef enum {
|
||||
OP_CLOSETRAY,
|
||||
OP_EJECT,
|
||||
OP_IDLE,
|
||||
OP_MODE_SENSE_2A,
|
||||
OP_MCN,
|
||||
OP_SPEED,
|
||||
} operation_enum_t;
|
||||
@@ -103,6 +96,7 @@ parse_options (int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
operation_t op;
|
||||
int i_blocksize = 0;
|
||||
|
||||
const char* helpText =
|
||||
"Usage: %s [OPTION...]\n"
|
||||
@@ -111,6 +105,9 @@ parse_options (int argc, char *argv[])
|
||||
" -b, --blocksize[=INT] set blocksize. If no block size or a \n"
|
||||
" zero blocksize is given we return the\n"
|
||||
" current setting.\n"
|
||||
" -C, --drive-cap [6|10] print mode sense 2a data\n"
|
||||
" using 6-byte or 10-byte form\n"
|
||||
" -c, --close drive close drive via ALLOW_MEDIUM_REMOVAL\n"
|
||||
" -e, --eject [drive] eject drive via ALLOW_MEDIUM_REMOVAL\n"
|
||||
" and a MMC START/STOP command\n"
|
||||
" -I, --idle set CD-ROM to idle or power down\n"
|
||||
@@ -133,11 +130,12 @@ parse_options (int argc, char *argv[])
|
||||
" [-V|--version] [-?|--help] [--usage]\n";
|
||||
|
||||
/* Command-line options */
|
||||
const char* optionsString = "b::c:e::Is:V?";
|
||||
const char* optionsString = "b::c:C::e::Is:V?";
|
||||
struct option optionsTable[] = {
|
||||
|
||||
{"blocksize", optional_argument, &opts.i_blocksize, 'b' },
|
||||
/* {"close", required_argument, NULL, 'c'}, */
|
||||
{"blocksize", optional_argument, &i_blocksize, 'b' },
|
||||
{"close", required_argument, NULL, 'c'},
|
||||
{"drive-cap", optional_argument, NULL, 'C'},
|
||||
{"eject", optional_argument, NULL, 'e'},
|
||||
{"idle", no_argument, NULL, 'I'},
|
||||
{"mcn", no_argument, NULL, 'm'},
|
||||
@@ -155,9 +153,26 @@ parse_options (int argc, char *argv[])
|
||||
{
|
||||
case 'b':
|
||||
op.op = OP_BLOCKSIZE;
|
||||
op.arg.i_num = opts.i_blocksize;
|
||||
op.arg.i_num = i_blocksize;
|
||||
push_op(&op);
|
||||
break;
|
||||
case 'C':
|
||||
op.arg.i_num = optarg ? atoi(optarg) : 10;
|
||||
switch (op.arg.i_num) {
|
||||
case 10:
|
||||
op.op = OP_MODE_SENSE_2A;
|
||||
op.arg.i_num = 10;
|
||||
push_op(&op);
|
||||
break;
|
||||
case 6:
|
||||
op.op = OP_MODE_SENSE_2A;
|
||||
op.arg.i_num = 6;
|
||||
push_op(&op);
|
||||
break;
|
||||
default:
|
||||
report( stderr, "%s: Expecting 6 or 10 or nothing\n", program_name );
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
op.op = OP_CLOSETRAY;
|
||||
op.arg.psz = strdup(optarg);
|
||||
@@ -209,6 +224,7 @@ parse_options (int argc, char *argv[])
|
||||
|
||||
case OPT_HANDLED:
|
||||
break;
|
||||
i_blocksize = 0;
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
@@ -234,6 +250,163 @@ parse_options (int argc, char *argv[])
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
print_mode_sense (unsigned int i_mmc_size, const uint8_t buf[22])
|
||||
{
|
||||
printf("Mode sense %d information\n", i_mmc_size);
|
||||
if (buf[2] & 0x01) {
|
||||
printf("\tReads CD-R media.\n");
|
||||
}
|
||||
if (buf[2] & 0x02) {
|
||||
printf("\tReads CD-RW media.\n");
|
||||
}
|
||||
if (buf[2] & 0x04) {
|
||||
printf("\tReads fixed-packet tracks when Addressing type is method 2.\n");
|
||||
}
|
||||
if (buf[2] & 0x08) {
|
||||
printf("\tReads DVD ROM media.\n");
|
||||
}
|
||||
if (buf[2] & 0x10) {
|
||||
printf("\tReads DVD-R media.\n");
|
||||
}
|
||||
if (buf[2] & 0x20) {
|
||||
printf("\tReads DVD-RAM media.\n");
|
||||
}
|
||||
if (buf[2] & 0x40) {
|
||||
printf("\tReads DVD-RAM media.\n");
|
||||
}
|
||||
if (buf[3] & 0x01) {
|
||||
printf("\tWrites CD-R media.\n");
|
||||
}
|
||||
if (buf[3] & 0x02) {
|
||||
printf("\tWrites CD-RW media.\n");
|
||||
}
|
||||
if (buf[3] & 0x04) {
|
||||
printf("\tSupports emulation write.\n");
|
||||
}
|
||||
if (buf[3] & 0x10) {
|
||||
printf("\tWrites DVD-R media.\n");
|
||||
}
|
||||
if (buf[3] & 0x20) {
|
||||
printf("\tWrites DVD-RAM media.\n");
|
||||
}
|
||||
if (buf[4] & 0x01) {
|
||||
printf("\tCan play audio.\n");
|
||||
}
|
||||
if (buf[4] & 0x02) {
|
||||
printf("\tDelivers composition A/V stream.\n");
|
||||
}
|
||||
if (buf[4] & 0x04) {
|
||||
printf("\tSupports digital output on port 2.\n");
|
||||
}
|
||||
if (buf[4] & 0x08) {
|
||||
printf("\tSupports digital output on port 1.\n");
|
||||
}
|
||||
if (buf[4] & 0x10) {
|
||||
printf("\tReads Mode-2 form 1 (e.g. XA) media.\n");
|
||||
}
|
||||
if (buf[4] & 0x20) {
|
||||
printf("\tReads Mode-2 form 2 media.\n");
|
||||
}
|
||||
if (buf[4] & 0x40) {
|
||||
printf("\tReads multi-session CD media.\n");
|
||||
}
|
||||
if (buf[4] & 0x80) {
|
||||
printf("\tSupports Buffer under-run free recording on CD-R/RW media.\n");
|
||||
}
|
||||
if (buf[4] & 0x01) {
|
||||
printf("\tCan read audio data with READ CD.\n");
|
||||
}
|
||||
if (buf[4] & 0x02) {
|
||||
printf("\tREAD CD data stream is accurate.\n");
|
||||
}
|
||||
if (buf[5] & 0x04) {
|
||||
printf("\tReads R-W subchannel information.\n");
|
||||
}
|
||||
if (buf[5] & 0x08) {
|
||||
printf("\tReads de-interleaved R-W subchannel.\n");
|
||||
}
|
||||
if (buf[5] & 0x10) {
|
||||
printf("\tSupports C2 error pointers.\n");
|
||||
}
|
||||
if (buf[5] & 0x20) {
|
||||
printf("\tReads ISRC information.\n");
|
||||
}
|
||||
if (buf[5] & 0x40) {
|
||||
printf("\tReads ISRC informaton.\n");
|
||||
}
|
||||
if (buf[5] & 0x40) {
|
||||
printf("\tReads media catalog number (MCN also known as UPC).\n");
|
||||
}
|
||||
if (buf[5] & 0x80) {
|
||||
printf("\tReads bar codes.\n");
|
||||
}
|
||||
if (buf[6] & 0x01) {
|
||||
printf("\tPREVENT/ALLOW may lock media.\n");
|
||||
}
|
||||
printf("\tLock state is %slocked.\n", (buf[6] & 0x02) ? "" : "un");
|
||||
printf("\tPREVENT/ALLOW jumper is %spresent.\n", (buf[6] & 0x04) ? "": "not ");
|
||||
if (buf[6] & 0x08) {
|
||||
printf("\tEjects media with START STOP UNIT.\n");
|
||||
}
|
||||
{
|
||||
const unsigned int i_load_type = (buf[6]>>5 & 0x07);
|
||||
printf("\tLoading mechanism type is %d: ", i_load_type);
|
||||
switch (buf[6]>>5 & 0x07) {
|
||||
case 0:
|
||||
printf("caddy type loading mechanism.\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("tray type loading mechanism.\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("popup type loading mechanism.\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("reserved\n");
|
||||
break;
|
||||
case 4:
|
||||
printf("changer with individually changeable discs.\n");
|
||||
break;
|
||||
case 5:
|
||||
printf("changer using Magazine mechanism.\n");
|
||||
break;
|
||||
case 6:
|
||||
printf("changer using Magazine mechanism.\n");
|
||||
break;
|
||||
default:
|
||||
printf("Invalid.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf[7] & 0x01) {
|
||||
printf("\tVolume controls each channel separately.\n");
|
||||
}
|
||||
if (buf[7] & 0x02) {
|
||||
printf("\tHas a changer that supports disc present reporting.\n");
|
||||
}
|
||||
if (buf[7] & 0x04) {
|
||||
printf("\tCan load empty slot in changer.\n");
|
||||
}
|
||||
if (buf[7] & 0x08) {
|
||||
printf("\tSide change capable.\n");
|
||||
}
|
||||
if (buf[7] & 0x10) {
|
||||
printf("\tReads raw R-W subchannel information from lead in.\n");
|
||||
}
|
||||
{
|
||||
const unsigned int i_speed_Kbs = CDIO_MMC_GETPOS_LEN16(buf, 8);
|
||||
printf("\tMaximum read speed is %d K bytes/sec (about %dX)\n",
|
||||
i_speed_Kbs, i_speed_Kbs / 176) ;
|
||||
}
|
||||
printf("\tNumber of Volume levels is %d\n", CDIO_MMC_GETPOS_LEN16(buf, 10));
|
||||
printf("\tBuffers size for data is %d KB\n", CDIO_MMC_GETPOS_LEN16(buf, 12));
|
||||
printf("\tCurrent read speed is %d KB\n", CDIO_MMC_GETPOS_LEN16(buf, 14));
|
||||
printf("\tMaximum write speed is %d KB\n", CDIO_MMC_GETPOS_LEN16(buf, 18));
|
||||
printf("\tCurrent write speed is %d KB\n", CDIO_MMC_GETPOS_LEN16(buf, 28));
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@@ -276,14 +449,30 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case OP_MODE_SENSE_2A:
|
||||
{
|
||||
uint8_t buf[22] = { 0, }; /* Place to hold returned data */
|
||||
if (p_op->arg.i_num == 10) {
|
||||
rc = mmc_mode_sense_10(p_cdio, buf, sizeof(buf),
|
||||
CDIO_MMC_CAPABILITIES_PAGE);
|
||||
} else {
|
||||
rc = mmc_mode_sense_6(p_cdio, buf, sizeof(buf),
|
||||
CDIO_MMC_CAPABILITIES_PAGE);
|
||||
}
|
||||
if (DRIVER_OP_SUCCESS == rc) {
|
||||
print_mode_sense(p_op->arg.i_num, buf);
|
||||
} else {
|
||||
report(stdout, "%s (mmc_mode_sense 2a - drive_cap %d): %s\n",
|
||||
program_name, p_op->arg.i_num, cdio_driver_errmsg(rc));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_CLOSETRAY:
|
||||
rc = mmc_close_tray(p_cdio, op.arg.psz);
|
||||
rc = mmc_close_tray(p_cdio);
|
||||
report(stdout, "%s (mmc_close_tray): %s\n", program_name,
|
||||
cdio_driver_errmsg(rc));
|
||||
free(p_op->arg.psz);
|
||||
break;
|
||||
#endif
|
||||
case OP_EJECT:
|
||||
rc = mmc_eject_media(p_cdio);
|
||||
report(stdout, "%s (mmc_eject_media): %s\n", program_name,
|
||||
|
||||
Reference in New Issue
Block a user