Add mmc_get_disc_erasable courtesy of Frank Endres.

This commit is contained in:
R. Bernstein
2010-01-28 19:38:34 -05:00
parent 2a125e3471
commit edf69959c1
6 changed files with 263 additions and 215 deletions

1
NEWS
View File

@@ -9,6 +9,7 @@ version 0.83 (git)
programs that wanto to cd-record compatible. programs that wanto to cd-record compatible.
- Tolerance for OS's without timezone in their struct tm (e.g. Solaris) - Tolerance for OS's without timezone in their struct tm (e.g. Solaris)
added iso9660_set_{d,l}time_with_timezone added iso9660_set_{d,l}time_with_timezone
- Add mmc_get_disk_erasable
version 0.82 version 0.82
2009-10-27 2009-10-27

3
THANKS
View File

@@ -10,6 +10,9 @@ Carlo Bramini
Diego 'Flameeyes' Petten<65> Diego 'Flameeyes' Petten<65>
patches to FreeBSD and making Gentoo-friendly patches to FreeBSD and making Gentoo-friendly
Frank Endres
mmc_get_disc_erasable
Frantisek Dvorak <valtri at atlas.cz>: Frantisek Dvorak <valtri at atlas.cz>:
bug reports and miscellaneous fixes bug reports and miscellaneous fixes

View File

@@ -322,8 +322,7 @@ typedef enum {
} cdio_mmc_feature_t; } cdio_mmc_feature_t;
/** /**
Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
*/
typedef enum { typedef enum {
CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable
of changing behavior */ of changing behavior */
@@ -377,14 +376,16 @@ typedef enum {
*/ */
#define MAX_CDB_LEN 12 #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. commands.
*/ */
typedef struct mmc_cdb_s { typedef struct mmc_cdb_s {
uint8_t field[MAX_CDB_LEN]; uint8_t field[MAX_CDB_LEN];
} mmc_cdb_t; } 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. GET_CONFIGURATION command.
*/ */
typedef struct mmc_feature_list_header_s { typedef struct mmc_feature_list_header_s {
@@ -398,18 +399,20 @@ typedef struct mmc_cdb_s {
unsigned char profile_lsb; unsigned char profile_lsb;
} cdio_mmc_feature_list_header_t; } cdio_mmc_feature_list_header_t;
/** An enumeration indicating whether an MMC command is sending /**
data, or getting data, or does none of both. An enumeration indicating whether an MMC command is sending
data, or getting data, or does none of both.
*/ */
typedef enum mmc_direction_s { typedef enum mmc_direction_s {
SCSI_MMC_DATA_READ, SCSI_MMC_DATA_READ,
SCSI_MMC_DATA_WRITE, SCSI_MMC_DATA_WRITE,
SCSI_MMC_DATA_NONE SCSI_MMC_DATA_NONE
} cdio_mmc_direction_t; } cdio_mmc_direction_t;
/** Indicate to applications that SCSI_MMC_DATA_NONE is available. /**
It has been added after version 0.82 and should be used with commands Indicate to applications that SCSI_MMC_DATA_NONE is available.
that neither read nor write payload bytes. (At least on Linux such It has been added after version 0.82 and should be used with commands
commands did work with SCSI_MMC_DATA_READ or SCSI_MMC_DATA_WRITE, too.) that neither read nor write payload bytes. (At least on Linux such
commands did work with SCSI_MMC_DATA_READ or SCSI_MMC_DATA_WRITE, too.)
*/ */
#define SCSI_MMC_HAS_DIR_NONE 1 #define SCSI_MMC_HAS_DIR_NONE 1
@@ -471,6 +474,17 @@ typedef struct mmc_cdb_s {
#define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \ #define CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb, val) \
cdb[9] = val << 3; cdb[9] = val << 3;
/**
Get the output port volumes and port selections used on AUDIO PLAY
commands via a MMC MODE SENSE command using the CD Audio Control
Page.
@param p_cdio the CD object to be acted upon.
@param p_volume volume parameters retrieved
@return DRIVER_OP_SUCCESS if we ran the command ok.
*/
driver_return_code_t mmc_audio_get_volume (CdIo_t *p_cdio, /*out*/
mmc_audio_volume_t *p_volume);
/** /**
Read Audio Subchannel information Read Audio Subchannel information
@@ -508,13 +522,6 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
*/ */
const char *mmc_feature_profile2str( int i_feature_profile ); 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 (e.g. READ_10, Get the block size used in read requests, via MMC (e.g. READ_10,
READ_MSF, ...) READ_MSF, ...)
@@ -524,12 +531,20 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
int mmc_get_blocksize ( CdIo_t *p_cdio ); int mmc_get_blocksize ( CdIo_t *p_cdio );
/** /**
Close tray using a MMC START STOP command. Return the length in bytes of the Command Descriptor
@param p_cdio the CD object to be acted upon. Buffer (CDB) for a given MMC command. The length will be
@return DRIVER_OP_SUCCESS (0) if we got the status. either 6, 10, or 12.
return codes are the same as driver_return_code_t
*/ */
driver_return_code_t mmc_close_tray( CdIo_t *p_cdio ); uint8_t mmc_get_cmd_len(uint8_t mmc_cmd);
/**
Detects if a disc (CD or DVD) is erasable or not.
@param p_user_data the CD object to be acted upon.
@return true if the disc is detected as erasable (rewritable), false
otherwise.
*/
bool
mmc_get_disc_erasable( const CdIo_t *p_cdio );
/** /**
Get the lsn of the end of the CD Get the lsn of the end of the CD
@@ -539,6 +554,14 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
*/ */
lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio ); lsn_t mmc_get_disc_last_lsn( const CdIo_t *p_cdio );
/**
Close tray using a MMC START STOP command.
@param p_cdio the CD object to be acted upon.
@return DRIVER_OP_SUCCESS (0) if we got the status.
return codes are the same as driver_return_code_t
*/
driver_return_code_t mmc_close_tray( CdIo_t *p_cdio );
/** /**
Return the discmode as reported by the MMC Read (FULL) TOC Return the discmode as reported by the MMC Read (FULL) TOC
command. command.
@@ -640,17 +663,6 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
*/ */
char * mmc_get_mcn ( const CdIo_t *p_cdio ); char * mmc_get_mcn ( const CdIo_t *p_cdio );
/**
Get the output port volumes and port selections used on AUDIO PLAY
commands via a MMC MODE SENSE command using the CD Audio Control
Page.
@param p_cdio the CD object to be acted upon.
@param p_volume volume parameters retrieved
@return DRIVER_OP_SUCCESS if we ran the command ok.
*/
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, ...) Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...)
Is it possible for an interface to have serveral? If not this Is it possible for an interface to have serveral? If not this

View File

@@ -1,7 +1,4 @@
/* Common Multimedia Command (MMC) routines. /* Common Multimedia Command (MMC) routines.
$Id: mmc.c,v 1.40 2008/05/09 09:54:39 edsdead Exp $
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
Rocky Bernstein <rocky@gnu.org> Rocky Bernstein <rocky@gnu.org>
@@ -580,60 +577,6 @@ mmc_set_blocksize_private ( void *p_env,
/*********************************************************** /***********************************************************
User-accessible Operations. User-accessible Operations.
************************************************************/ ************************************************************/
/**
Return the number of 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 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.
@param p_cdio the CD object to be acted upon.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t
mmc_get_disc_last_lsn ( const CdIo_t *p_cdio )
{
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 = mmc_run_cmd(p_cdio, mmc_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;
}
/** /**
Read Audio Subchannel information Read Audio Subchannel information
@@ -679,6 +622,132 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, cdio_subchannel_t *p_subchannel)
return i_rc; return i_rc;
} }
/**
Get the block size used in read requests, via MMC (e.g. READ_10,
READ_MSF, ...)
@param p_cdio the CD object to be acted upon.
@return the blocksize if > 0; error if <= 0
*/
int
mmc_get_blocksize ( CdIo_t *p_cdio)
{
int i_status;
uint8_t buf[255] = { 0, };
uint8_t *p;
/* First try using the 6-byte MODE SENSE command. */
i_status = mmc_mode_sense_6(p_cdio, buf, sizeof(buf),
CDIO_MMC_R_W_ERROR_PAGE);
if (DRIVER_OP_SUCCESS == i_status && buf[3]>=8) {
p = &buf[4+5];
return CDIO_MMC_GET_LEN16(p);
}
/* Next try using the 10-byte MODE SENSE command. */
i_status = mmc_mode_sense_10(p_cdio, buf, sizeof(buf),
CDIO_MMC_R_W_ERROR_PAGE);
p = &buf[6];
if (DRIVER_OP_SUCCESS == i_status && CDIO_MMC_GET_LEN16(p)>=8) {
return CDIO_MMC_GET_LEN16(p);
}
#ifdef IS_THIS_CORRECT
/* Lastly try using the READ CAPACITY command. */
{
lba_t lba = 0;
uint16_t i_blocksize;
i_status = mmc_read_capacity(p_cdio, &lba, &i_blocksize);
if ( DRIVER_OP_SUCCESS == i_status )
return i_blocksize;
#endif
return DRIVER_OP_UNSUPPORTED;
}
/**
Return the number of 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 scsi_cmd)
{
static const uint8_t scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
return scsi_cdblen[((scsi_cmd >> 5) & 7)];
}
/**
Detects if a disc (CD or DVD) is erasable or not.
@param p_user_data the CD object to be acted upon.
@return true if the disc is detected as erasable (rewritable), false
otherwise.
*/
bool
mmc_get_disc_erasable( const CdIo_t *p_cdio ) {
mmc_cdb_t cdb = {{0, }};
uint8_t buf[42] = { 0, };
int i_status;
CDIO_MMC_SET_COMMAND (cdb.field, CDIO_MMC_GPCMD_READ_DISC_INFO);
CDIO_MMC_SET_READ_LENGTH8 (cdb.field, sizeof(buf));
i_status = mmc_run_cmd (p_cdio, 0, &cdb, SCSI_MMC_DATA_READ,
sizeof(buf), &buf);
if (i_status == 0) {
if (buf[2] & 0x10)
return true;
else
return false;
} else
return false;
}
/**
Return the size of the CD in logical block address (LBA) units.
@param p_cdio the CD object to be acted upon.
@return the lsn. On error 0 or CDIO_INVALD_LSN.
*/
lsn_t
mmc_get_disc_last_lsn ( const CdIo_t *p_cdio )
{
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 = mmc_run_cmd(p_cdio, mmc_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 Return the discmode as reported by the SCSI-MMC Read (FULL) TOC
command. command.
@@ -972,6 +1041,40 @@ int mmc_get_tray_status(const CdIo_t *p_cdio)
return (status_buf[1] & 0x01) ? 1 : 0; return (status_buf[1] & 0x01) ? 1 : 0;
} }
/* Added in version 0.83 by scdbackup */
/**
Obtain the SCSI sense reply of the most-recently-performed MMC command.
These bytes give an indication of possible problems which occured in
the drive while the command was performed. With some commands they tell
about the current state of the drive (e.g. 00h TEST UNIT READY).
@param sense returns the sense bytes received from the drive.
This is allocated memory or NULL if no sense bytes are
available. Dispose non-NULL pointers by free() when
no longer needed.
See SPC-3 4.5.3 Fixed format sense data.
SCSI error codes as of SPC-3 Annex D, MMC-5 Annex F:
sense[2]&15 = Key , sense[12] = ASC , sense[13] = ASCQ
@return number of valid bytes in sense,
0 in case of no sense bytes available,
<0 in case of internal error.
*/
int
mmc_last_cmd_sense( const CdIo_t *p_cdio, unsigned char **sense)
{
generic_img_private_t *gen;
if (!p_cdio) return DRIVER_OP_UNINIT;
gen = p_cdio->env;
*sense = NULL;
if (gen->scsi_mmc_sense_valid <= 0)
return 0;
*sense = calloc(1, gen->scsi_mmc_sense_valid);
if (*sense == NULL)
return DRIVER_OP_ERROR;
memcpy(*sense, gen->scsi_mmc_sense, gen->scsi_mmc_sense_valid);
return gen->scsi_mmc_sense_valid;
}
/** /**
Run a MMC command. Run a MMC command.
@@ -1019,6 +1122,7 @@ mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
@return 0 if command completed successfully. @return 0 if command completed successfully.
*/ */
driver_return_code_t driver_return_code_t
mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms, mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
const mmc_cdb_t *p_cdb, unsigned int i_cdb, const mmc_cdb_t *p_cdb, unsigned int i_cdb,
@@ -1032,87 +1136,6 @@ mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
p_cdb, e_direction, i_buf, p_buf); p_cdb, e_direction, i_buf, p_buf);
} }
/* Added in version 0.83 by scdbackup */
/**
Obtain the SCSI sense reply of the most-recently-performed MMC command.
These bytes give an indication of possible problems which occured in
the drive while the command was performed. With some commands they tell
about the current state of the drive (e.g. 00h TEST UNIT READY).
@param sense returns the sense bytes received from the drive.
This is allocated memory or NULL if no sense bytes are
available. Dispose non-NULL pointers by free() when
no longer needed.
See SPC-3 4.5.3 Fixed format sense data.
SCSI error codes as of SPC-3 Annex D, MMC-5 Annex F:
sense[2]&15 = Key , sense[12] = ASC , sense[13] = ASCQ
@return number of valid bytes in sense,
0 in case of no sense bytes available,
<0 in case of internal error.
*/
int
mmc_last_cmd_sense( const CdIo_t *p_cdio, unsigned char **sense)
{
generic_img_private_t *gen;
if (!p_cdio) return DRIVER_OP_UNINIT;
gen = p_cdio->env;
*sense = NULL;
if (gen->scsi_mmc_sense_valid <= 0)
return 0;
*sense = calloc(1, gen->scsi_mmc_sense_valid);
if (*sense == NULL)
return DRIVER_OP_ERROR;
memcpy(*sense, gen->scsi_mmc_sense, gen->scsi_mmc_sense_valid);
return gen->scsi_mmc_sense_valid;
}
/**
Get the block size used in read requests, via MMC (e.g. READ_10,
READ_MSF, ...)
@param p_cdio the CD object to be acted upon.
@return the blocksize if > 0; error if <= 0
*/
int
mmc_get_blocksize ( CdIo_t *p_cdio)
{
int i_status;
uint8_t buf[255] = { 0, };
uint8_t *p;
/* First try using the 6-byte MODE SENSE command. */
i_status = mmc_mode_sense_6(p_cdio, buf, sizeof(buf),
CDIO_MMC_R_W_ERROR_PAGE);
if (DRIVER_OP_SUCCESS == i_status && buf[3]>=8) {
p = &buf[4+5];
return CDIO_MMC_GET_LEN16(p);
}
/* Next try using the 10-byte MODE SENSE command. */
i_status = mmc_mode_sense_10(p_cdio, buf, sizeof(buf),
CDIO_MMC_R_W_ERROR_PAGE);
p = &buf[6];
if (DRIVER_OP_SUCCESS == i_status && CDIO_MMC_GET_LEN16(p)>=8) {
return CDIO_MMC_GET_LEN16(p);
}
#ifdef IS_THIS_CORRECT
/* Lastly try using the READ CAPACITY command. */
{
lba_t lba = 0;
uint16_t i_blocksize;
i_status = mmc_read_capacity(p_cdio, &lba, &i_blocksize);
if ( DRIVER_OP_SUCCESS == i_status )
return i_blocksize;
#endif
return DRIVER_OP_UNSUPPORTED;
}
/** /**
Load or Unload media using a MMC START STOP command. Load or Unload media using a MMC START STOP command.

View File

@@ -1,7 +1,4 @@
/* private MMC helper routines. /* private MMC helper routines.
$Id: mmc_private.h,v 1.12 2008/04/22 15:29:12 karl Exp $
Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify

View File

@@ -1,5 +1,6 @@
/* -*- C -*- /* -*- C -*-
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net> Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 20010 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -40,44 +41,52 @@
/* The compiler warns if no prototypes are given before function definition */ /* The compiler warns if no prototypes are given before function definition */
static void static int tmmc_eject_load_cycle(CdIo_t *p_cdio, int flag);
tmmc_print_status_sense(int i_status, int sense_valid,
unsigned char sense_reply[18], int flag);
static int
tmmc_handle_outcome(CdIo_t *p_cdio, int i_status,
int *sense_avail, unsigned char sense_reply[18], int flag);
int static int tmmc_eject_test_load(CdIo_t *p_cdio, int flag);
tmmc_test_unit_ready(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag);
int
tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag);
int
tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18],
int page_code, int subpage_code, int alloc_len,
unsigned char *buf, int *buf_fill, int flag);
int
tmmc_mode_select(CdIo_t *p_cdio,
int *sense_avail, unsigned char sense_reply[18],
unsigned char *buf, int buf_fill, int flag);
int static void tmmc_get_disc_erasable(const CdIo_t *p_cdio, const char *psz_source,
tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag); int verbose);
int
tmmc_eject_load_cycle(CdIo_t *p_cdio, int flag);
int
tmmc_eject_test_load(CdIo_t *p_cdio, int flag);
int
tmmc_rwr_mode_page(CdIo_t *p_cdio, int flag);
int static int tmmc_handle_outcome(CdIo_t *p_cdio, int i_status,
tmmc_test(char *drive_path, int flag); int *sense_avail,
unsigned char sense_reply[18], int flag);
static void tmmc_print_status_sense(int i_status, int sense_valid,
unsigned char sense_reply[18], int flag);
static int tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag);
static int tmmc_mode_select(CdIo_t *p_cdio,
int *sense_avail, unsigned char sense_reply[18],
unsigned char *buf, int buf_fill, int flag);
static int tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18],
int page_code, int subpage_code, int alloc_len,
unsigned char *buf, int *buf_fill, int flag);
static int tmmc_test_unit_ready(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag);
static int tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag);
static int tmmc_rwr_mode_page(CdIo_t *p_cdio, int flag);
static int tmmc_test(char *drive_path, int flag);
/* ------------------------- Helper functions ---------------------------- */ /* ------------------------- Helper functions ---------------------------- */
static void
tmmc_get_disc_erasable(const CdIo_t *p_cdio, const char *psz_source,
int verbose)
{
bool b_erasable = mmc_get_disc_erasable(p_cdio);
printf("disk is %serasable.\n", b_erasable ? "" : "not ");
}
/* @param flag bit0= verbose /* @param flag bit0= verbose
*/ */
static void static void
@@ -125,7 +134,7 @@ tmmc_handle_outcome(CdIo_t *p_cdio, int i_status,
@param sense_reply eventual sense bytes @param sense_reply eventual sense bytes
@return return value of mmc_run_cmd() @return return value of mmc_run_cmd()
*/ */
int static int
tmmc_test_unit_ready(CdIo_t *p_cdio, tmmc_test_unit_ready(CdIo_t *p_cdio,
int *sense_avail, unsigned char sense_reply[18], int flag) int *sense_avail, unsigned char sense_reply[18], int flag)
{ {
@@ -151,7 +160,7 @@ tmmc_test_unit_ready(CdIo_t *p_cdio,
bit2= Load (else Eject) bit2= Load (else Eject)
@return return value of mmc_run_cmd() @return return value of mmc_run_cmd()
*/ */
int static int
tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail, tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag) unsigned char sense_reply[18], int flag)
{ {
@@ -193,7 +202,7 @@ tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
@return return value of mmc_run_cmd(), @return return value of mmc_run_cmd(),
or other driver_return_code_t or other driver_return_code_t
*/ */
int static int
tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18], tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18],
int page_code, int subpage_code, int alloc_len, int page_code, int subpage_code, int alloc_len,
unsigned char *buf, int *buf_fill, int flag) unsigned char *buf, int *buf_fill, int flag)
@@ -238,7 +247,7 @@ tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18],
@return return value of mmc_run_cmd(), @return return value of mmc_run_cmd(),
or other driver_return_code_t or other driver_return_code_t
*/ */
int static int
tmmc_mode_select(CdIo_t *p_cdio, tmmc_mode_select(CdIo_t *p_cdio,
int *sense_avail, unsigned char sense_reply[18], int *sense_avail, unsigned char sense_reply[18],
unsigned char *buf, int buf_fill, int flag) unsigned char *buf, int buf_fill, int flag)
@@ -284,7 +293,7 @@ tmmc_mode_select(CdIo_t *p_cdio,
bit1= expect media (do not end on no-media sense) bit1= expect media (do not end on no-media sense)
@return 1= all seems well , 0= minor failure , -1= severe failure @return 1= all seems well , 0= minor failure , -1= severe failure
*/ */
int static int
tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag) tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag)
{ {
int ret, i, sense_avail; int ret, i, sense_avail;
@@ -338,7 +347,7 @@ tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag)
bit1= expect media (do not end on no-media sense) bit1= expect media (do not end on no-media sense)
@return 1= all seems well , 0= minor failure , -1= severe failure @return 1= all seems well , 0= minor failure , -1= severe failure
*/ */
int static int
tmmc_eject_load_cycle(CdIo_t *p_cdio, int flag) tmmc_eject_load_cycle(CdIo_t *p_cdio, int flag)
{ {
int ret, sense_avail; int ret, sense_avail;
@@ -371,7 +380,7 @@ tmmc_eject_load_cycle(CdIo_t *p_cdio, int flag)
@param flag bit0= verbose @param flag bit0= verbose
@return 1= all seems well , 0= minor failure , -1= severe failure @return 1= all seems well , 0= minor failure , -1= severe failure
*/ */
int static int
tmmc_eject_test_load(CdIo_t *p_cdio, int flag) tmmc_eject_test_load(CdIo_t *p_cdio, int flag)
{ {
int ret, sense_avail; int ret, sense_avail;
@@ -420,7 +429,7 @@ tmmc_eject_test_load(CdIo_t *p_cdio, int flag)
@param flag bit0= verbose @param flag bit0= verbose
@return 1= all seems well , 0= minor failure , -1= severe failure @return 1= all seems well , 0= minor failure , -1= severe failure
*/ */
int static int
tmmc_rwr_mode_page(CdIo_t *p_cdio, int flag) tmmc_rwr_mode_page(CdIo_t *p_cdio, int flag)
{ {
int ret, sense_avail, page_code = 5, subpage_code = 0, alloc_len, buf_fill; int ret, sense_avail, page_code = 5, subpage_code = 0, alloc_len, buf_fill;
@@ -547,7 +556,7 @@ tmmc_rwr_mode_page(CdIo_t *p_cdio, int flag)
@return 0= no severe failure @return 0= no severe failure
else an proposal for an exit() value is returned else an proposal for an exit() value is returned
*/ */
int static int
tmmc_test(char *drive_path, int flag) tmmc_test(char *drive_path, int flag)
{ {
int sense_avail = 0, ret, sense_valid, buf_fill, alloc_len = 10, verbose; int sense_avail = 0, ret, sense_valid, buf_fill, alloc_len = 10, verbose;
@@ -734,8 +743,9 @@ main(int argc, const char *argv[])
char **ppsz_drives=NULL; char **ppsz_drives=NULL;
const char *psz_source = NULL; const char *psz_source = NULL;
int ret; int ret;
bool b_verbose = (argc > 1);
cdio_loglevel_default = (argc > 1) ? CDIO_LOG_DEBUG : CDIO_LOG_INFO; cdio_loglevel_default = b_verbose ? CDIO_LOG_DEBUG : CDIO_LOG_INFO;
/* snprintf(psz_nrgfile, sizeof(psz_nrgfile)-1, /* snprintf(psz_nrgfile, sizeof(psz_nrgfile)-1,
"%s/%s", TEST_DIR, cue_file[i]); "%s/%s", TEST_DIR, cue_file[i]);
@@ -759,6 +769,8 @@ main(int argc, const char *argv[])
exit(1); exit(1);
} }
tmmc_get_disc_erasable(p_cdio, psz_source, b_verbose);
if ( psz_have_mmc if ( psz_have_mmc
&& 0 == strncmp("true", psz_have_mmc, sizeof("true")) && 0 == strncmp("true", psz_have_mmc, sizeof("true"))
&& (DRIVER_WIN32 != cdio_get_driver_id(p_cdio)) ) { && (DRIVER_WIN32 != cdio_get_driver_id(p_cdio)) ) {