diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index 971d089e..01ac63f4 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -172,7 +172,8 @@ extern "C" { settings. (6 bytes). */ CDIO_MMC_GPCMD_START_STOP_UNIT = 0x1b, /**< Enable/disable Disc operations. (6 bytes). */ - CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL = 0x1e, /**< Enable/disable Disc + CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL + = 0x1e, /**< Enable/disable Disc removal. (6 bytes). */ /** @@ -613,17 +614,6 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, */ 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_unit. - - @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_eject_media( const CdIo_t *p_cdio ); - /** Return a string containing the name of the given feature */ @@ -927,6 +917,8 @@ extern cdio_mmc_mode_page_t debug_cdio_mmc_mode_page; #ifndef DO_NOT_WANT_OLD_MMC_COMPATIBILITY #define CDIO_MMC_GPCMD_START_STOP CDIO_MMC_GPCMD_START_STOP_UNIT +#define CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL \ + CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL #endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ #endif /* __MMC_H__ */ diff --git a/include/cdio/mmc_cmds.h b/include/cdio/mmc_cmds.h index d87983f7..7e9529ca 100644 --- a/include/cdio/mmc_cmds.h +++ b/include/cdio/mmc_cmds.h @@ -39,6 +39,17 @@ extern "C" { #endif /* __cplusplus */ + /** + 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_unit. + + @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_eject_media( const CdIo_t *p_cdio ); + /** Return results of media status @@ -114,6 +125,22 @@ extern "C" { driver_return_code_t mmc_mode_sense_6( CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, int page); + /** + Request preventing/allowing medium removal on a drive via + SCSI-MMC PREVENT/ALLOW MEDIUM REMOVAL. + + @param p_cdio the CD object to be acted upon. + @param b_prevent true of drive locked and false if unlocked + @param b_persisent make b_prevent state persistent + + @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_prevent_allow_medium_removal(const CdIo_t *p_cdio, + bool b_persistent, bool b_prevent, + unsigned int i_timeout_ms); + /** Issue a MMC READ_CD command. diff --git a/lib/driver/gnu_linux.c b/lib/driver/gnu_linux.c index 2c3ea5be..b6ad3667 100644 --- a/lib/driver/gnu_linux.c +++ b/lib/driver/gnu_linux.c @@ -35,6 +35,7 @@ static const char _rcsid[] = "$Id: gnu_linux.c,v 1.33 2008/06/25 07:46:21 rocky #include #include #include +#include #include #include #include "cdtext_private.h" diff --git a/lib/driver/mmc/mmc.c b/lib/driver/mmc/mmc.c index cd5b7b41..4f72a24f 100644 --- a/lib/driver/mmc/mmc.c +++ b/lib/driver/mmc/mmc.c @@ -1059,36 +1059,6 @@ mmc_close_tray( CdIo_t *p_cdio ) } } -/** - 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. - - @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_eject_media( const CdIo_t *p_cdio ) -{ - int i_status = 0; - 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_ALLOW_MEDIUM_REMOVAL); - - i_status = p_cdio->op.run_mmc_cmd (p_cdio->env, mmc_timeout_ms, - mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) return i_status; - - return mmc_start_stop_unit(p_cdio, true, false, 0, 0); - -} - /** Return a string containing the name of the given feature */ @@ -1370,30 +1340,6 @@ 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(). - @param i_drive_speed speed in CD-ROM speed units. Note this - not Kbytes/sec as would be used in the MMC spec or - in mmc_set_speed(). To convert CD-ROM speed units - to Kbs, multiply the number by 176 (for raw data) - and by 150 (for filesystem data). On many CD-ROM - drives, specifying a value too large will result - in using the fastest speed. - - @return the drive speed if greater than 0. -1 if we had an error. is -2 - returned if this is not implemented for the current driver. - - @see cdio_set_speed and mmc_set_speed -*/ -driver_return_code_t -mmc_set_drive_speed( const CdIo_t *p_cdio, int i_drive_speed ) -{ - return mmc_set_speed(p_cdio, i_drive_speed * 176); -} - - /* * Local variables: diff --git a/lib/driver/mmc/mmc_hl_cmds.c b/lib/driver/mmc/mmc_hl_cmds.c index 375dad7c..44d6458b 100644 --- a/lib/driver/mmc/mmc_hl_cmds.c +++ b/lib/driver/mmc/mmc_hl_cmds.c @@ -20,3 +20,72 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +#include +#include + +/** + 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. + + @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_eject_media( const CdIo_t *p_cdio ) +{ + int i_status = 0; + i_status = mmc_prevent_allow_medium_removal(p_cdio, false, false, 0); + if (0 != i_status) return i_status; + + return mmc_start_stop_unit(p_cdio, true, false, 0, 0); + +} + +/** + Run a SCSI-MMC MMC MODE SENSE command (6- or 10-byte version) + and put the results in p_buf + @param p_cdio the CD object to be acted upon. + @param p_buf pointer to location to store mode sense information + @param i_size number of bytes allocated to p_buf + @param page which "page" of the mode sense command we are interested in + @return DRIVER_OP_SUCCESS if we ran the command ok. +*/ +driver_return_code_t +mmc_mode_sense(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, + int page) +{ + /* We used to make a choice as to which routine we'd use based + cdio_have_atapi(). But since that calls this in its determination, + we had an infinite recursion. So we can't use cdio_have_atapi() + (until we put in better capability checks.) + */ + if ( DRIVER_OP_SUCCESS == mmc_mode_sense_6(p_cdio, p_buf, i_size, page) ) + return DRIVER_OP_SUCCESS; + return mmc_mode_sense_10(p_cdio, p_buf, i_size, page); +} + +/** + Set the drive speed in CD-ROM speed units. + + @param p_cdio CD structure set by cdio_open(). + @param i_drive_speed speed in CD-ROM speed units. Note this + not Kbytes/sec as would be used in the MMC spec or + in mmc_set_speed(). To convert CD-ROM speed units + to Kbs, multiply the number by 176 (for raw data) + and by 150 (for filesystem data). On many CD-ROM + drives, specifying a value too large will result + in using the fastest speed. + + @return the drive speed if greater than 0. -1 if we had an error. is -2 + returned if this is not implemented for the current driver. + + @see cdio_set_speed and mmc_set_speed +*/ +driver_return_code_t +mmc_set_drive_speed( const CdIo_t *p_cdio, int i_drive_speed ) +{ + return mmc_set_speed(p_cdio, i_drive_speed * 176); +} diff --git a/lib/driver/mmc/mmc_ll_cmds.c b/lib/driver/mmc/mmc_ll_cmds.c index 52c689d8..ec5a06bd 100644 --- a/lib/driver/mmc/mmc_ll_cmds.c +++ b/lib/driver/mmc/mmc_ll_cmds.c @@ -31,6 +31,35 @@ #include #endif +/** + Request preventing/allowing medium removal on a drive via + SCSI-MMC PREVENT/ALLOW MEDIUM REMOVAL. + + @param p_cdio the CD object to be acted upon. + @param b_prevent true of drive locked and false if unlocked + @param b_persisent make b_prevent state persistent + + @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_prevent_allow_medium_removal(const CdIo_t *p_cdio, + bool b_persistent, bool b_prevent, + unsigned int i_timeout_ms) +{ + uint8_t buf[8] = { 0, }; + void *p_buf = &buf; + const unsigned int i_size = 0; + driver_return_code_t i_status; + + MMC_CMD_SETUP(CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL); + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; + if (b_prevent) cdb.field[4] |= 1; + if (b_persistent) cdb.field[4] |= 2; + + return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms); +} + /** Return results of media status @param p_cdio the CD object to be acted upon. @@ -57,7 +86,6 @@ mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]) } return i_status; } - /** Run a SCSI-MMC MODE SELECT (10-byte) command and put the results in p_buf. @@ -87,29 +115,6 @@ mmc_mode_select_10(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms); } -/** - Run a SCSI-MMC MMC MODE SENSE command (6- or 10-byte version) - and put the results in p_buf - @param p_cdio the CD object to be acted upon. - @param p_buf pointer to location to store mode sense information - @param i_size number of bytes allocated to p_buf - @param page which "page" of the mode sense command we are interested in - @return DRIVER_OP_SUCCESS if we ran the command ok. -*/ -driver_return_code_t -mmc_mode_sense(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, - int page) -{ - /* We used to make a choice as to which routine we'd use based - cdio_have_atapi(). But since that calls this in its determination, - we had an infinite recursion. So we can't use cdio_have_atapi() - (until we put in better capability checks.) - */ - if ( DRIVER_OP_SUCCESS == mmc_mode_sense_6(p_cdio, p_buf, i_size, page) ) - return DRIVER_OP_SUCCESS; - return mmc_mode_sense_10(p_cdio, p_buf, i_size, page); -} - /** Run a SCSI-MMC MODE SENSE command (10-byte version) and put the results in p_buf