Add MMC START STOP interface.

This commit is contained in:
rocky
2005-03-09 10:23:01 +00:00
parent 912ab1082d
commit 8e8c54a457
3 changed files with 401 additions and 349 deletions

View File

@@ -1,5 +1,5 @@
/* /*
$Id: mmc.h,v 1.17 2005/03/06 02:59:26 rocky Exp $ $Id: mmc.h,v 1.18 2005/03/09 10:23:01 rocky Exp $
Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -432,11 +432,11 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, cdio_subchannel_t *p_subchannel);
const char *mmc_audio_state2str( uint8_t i_audio_state ); const char *mmc_audio_state2str( uint8_t i_audio_state );
/*! /*!
* Eject using MMC commands. 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.
@return 0 if successful. For a more general (and lower-level) routine, @see mmc_start_stop_media.
*/ */
int mmc_eject_media( const CdIo_t *p_cdio ); driver_return_code_t mmc_eject_media( const CdIo_t *p_cdio );
/*! /*!
Return a string containing the name of the given feature Return a string containing the name of the given feature
@@ -461,6 +461,14 @@ uint8_t mmc_get_cmd_len(uint8_t mmc_cmd);
*/ */
int mmc_get_blocksize ( CdIo_t *p_cdio ); 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
/*! /*!
Get the lsn of the end of the CD Get the lsn of the end of the CD
@@ -705,8 +713,8 @@ driver_return_code_t mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf,
@param p_cdio CD structure set by cdio_open(). @param p_cdio CD structure set by cdio_open().
@param i_timeout_ms time in milliseconds we will wait for the command @param i_timeout_ms time in milliseconds we will wait for the command
to complete. to complete.
@param p_cdb CDB bytes. All values that are needed should be set on @param p_cdb CDB bytes. All values that are needed should be set
input. We'll figure out what the right CDB length on input. We'll figure out what the right CDB length
should be. should be.
@param e_direction direction the transfer is to go. @param e_direction direction the transfer is to go.
@param i_buf Size of buffer @param i_buf Size of buffer
@@ -729,6 +737,21 @@ driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio,
*/ */
driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, int i_speed ); driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, int i_speed );
/*!
Load or Unload media using a MMC START STOP command.
@param p_cdio the CD object to be acted upon.
@param b_eject eject if true and close tray if false
@param b_immediate wait or don't wait for operation to complete
@param power_condition Set CD-ROM to idle/standby/sleep. If nonzero
eject/load is ignored, so set to 0 if you want to eject or load.
@see mmc_eject_media or mmc_close_tray
*/
driver_return_code_t
mmc_start_stop_media(const CdIo_t *p_cdio, bool b_eject, bool b_immediate,
uint8_t power_condition);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -185,5 +185,6 @@ mmc_read_sectors
mmc_run_cmd mmc_run_cmd
mmc_set_blocksize mmc_set_blocksize
mmc_set_speed mmc_set_speed
mmc_start_stop
track_format2str track_format2str
CDIO_SECTOR_SYNC_HEADER CDIO_SECTOR_SYNC_HEADER

View File

@@ -1,6 +1,6 @@
/* Common Multimedia Command (MMC) routines. /* Common Multimedia Command (MMC) routines.
$Id: mmc.c,v 1.21 2005/03/06 02:59:26 rocky Exp $ $Id: mmc.c,v 1.22 2005/03/09 10:23:03 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
@@ -521,7 +521,7 @@ mmc_set_blocksize_private ( void *p_env,
************************************************************/ ************************************************************/
/*! /*!
Return the number of length in bytes of the Command Descriptor Return the number of length in bytes of the Command Descriptor
buffer (CDB) for a given SCSI MMC command. The length will be buffer (CDB) for a given MMC command. The length will be
either 6, 10, or 12. either 6, 10, or 12.
*/ */
uint8_t uint8_t
@@ -623,7 +623,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, cdio_subchannel_t *p_subchannel)
command. command.
Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP) Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
pages 56-62 from the SCSI MMC draft specification, revision 10a pages 56-62 from the MMC draft specification, revision 10a
at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
especially tables 72, 73 and 75. especially tables 72, 73 and 75.
*/ */
@@ -744,14 +744,14 @@ mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, cdio_dvd_struct_t *s)
} }
/*! /*!
Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. Get the CD-ROM hardware info via a MMC INQUIRY command.
False is returned if we had an error getting the information. False is returned if we had an error getting the information.
*/ */
bool bool
mmc_get_hwinfo ( const CdIo_t *p_cdio, mmc_get_hwinfo ( const CdIo_t *p_cdio,
/*out*/ cdio_hwinfo_t *hw_info ) /*out*/ cdio_hwinfo_t *hw_info )
{ {
int i_status; /* Result of SCSI MMC command */ int i_status; /* Result of MMC command */
char buf[36] = { 0, }; /* Place to hold returned data */ char buf[36] = { 0, }; /* Place to hold returned data */
mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */ mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */
@@ -823,7 +823,7 @@ mmc_get_mcn ( const CdIo_t *p_cdio )
} }
/*! /*!
Run a SCSI MMC command. Run a MMC command.
cdio CD structure set by cdio_open(). cdio CD structure set by cdio_open().
i_timeout time in milliseconds we will wait for the command i_timeout time in milliseconds we will wait for the command
@@ -892,7 +892,51 @@ mmc_get_blocksize ( CdIo_t *p_cdio)
/*! /*!
* Eject using SCSI MMC commands. Return 0 if successful. * Load or Unload media using a MMC START STOP command.
*/
driver_return_code_t
mmc_start_stop_media(const CdIo_t *p_cdio, bool b_eject, bool b_immediate,
uint8_t power_condition)
{
mmc_cdb_t cdb = {{0, }};
uint8_t buf[1];
if ( ! p_cdio ) return DRIVER_OP_UNINIT;
if ( ! p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
if (b_immediate) cdb.field[1] |= 1;
if (power_condition)
cdb.field[4] = power_condition << 4;
else {
if (b_eject)
cdb.field[4] = 2; /* eject */
else
cdb.field[4] = 3; /* close tray for tray-type */
}
return p_cdio->op.run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
mmc_get_cmd_len(cdb.field[0]), &cdb,
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 )
{
return mmc_start_stop_media(p_cdio, false, false, 0);
}
#endif
/*!
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 driver_return_code_t
mmc_eject_media( const CdIo_t *p_cdio ) mmc_eject_media( const CdIo_t *p_cdio )
@@ -900,34 +944,18 @@ mmc_eject_media( const CdIo_t *p_cdio )
int i_status = 0; int i_status = 0;
mmc_cdb_t cdb = {{0, }}; mmc_cdb_t cdb = {{0, }};
uint8_t buf[1]; uint8_t buf[1];
mmc_run_cmd_fn_t run_mmc_cmd;
if ( ! p_cdio ) return DRIVER_OP_UNINIT; if ( ! p_cdio ) return DRIVER_OP_UNINIT;
if ( ! p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED; if ( ! p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
run_mmc_cmd = p_cdio->op.run_mmc_cmd;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL); CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL);
i_status = run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS, i_status = p_cdio->op.run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
mmc_get_cmd_len(cdb.field[0]), &cdb, mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf); SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status) return i_status; if (0 != i_status) return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); return mmc_start_stop_media(p_cdio, true, false, 0);
cdb.field[4] = 1;
i_status = run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status)
return i_status;
CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP);
cdb.field[4] = 2; /* eject */
return run_mmc_cmd (p_cdio->env, DEFAULT_TIMEOUT_MS,
mmc_get_cmd_len(cdb.field[0]), &cdb,
SCSI_MMC_DATA_WRITE, 0, &buf);
} }