diff --git a/example/mmc1.c b/example/mmc1.c index 8feae0c9..f0266a6f 100644 --- a/example/mmc1.c +++ b/example/mmc1.c @@ -83,7 +83,9 @@ main(int argc, const char *argv[]) { driver_return_code_t i_status; - bool b_erasable = mmc_get_disc_erasable(p_cdio, &i_status); + bool b_erasable; + + i_status = mmc_get_disc_erasable(p_cdio, &b_erasable); cdio_mmc_feature_profile_t disctype; if (DRIVER_OP_SUCCESS == i_status) printf("Disc is %serasable.\n", b_erasable ? "" : "not "); diff --git a/include/cdio/Makefile.am b/include/cdio/Makefile.am index 7040c18c..b558c85b 100644 --- a/include/cdio/Makefile.am +++ b/include/cdio/Makefile.am @@ -41,6 +41,8 @@ libcdioinclude_HEADERS = \ logging.h \ mmc.h \ mmc_cmds.h \ + mmc_hl_cmds.h \ + mmc_ll_cmds.h \ paranoia.h \ posix.h \ read.h \ diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index 3876b0a8..c95872e4 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -307,17 +307,26 @@ extern "C" { Page codes for MODE SENSE and MODE SET. */ typedef enum { - CDIO_MMC_R_W_ERROR_PAGE = 0x01, - CDIO_MMC_WRITE_PARMS_PAGE = 0x05, - CDIO_MMC_CDR_PARMS_PAGE = 0x0d, - CDIO_MMC_AUDIO_CTL_PAGE = 0x0e, - CDIO_MMC_POWER_PAGE = 0x1a, - CDIO_MMC_FAULT_FAIL_PAGE = 0x1c, - CDIO_MMC_TO_PROTECT_PAGE = 0x1d, - CDIO_MMC_CAPABILITIES_PAGE = 0x2a, - CDIO_MMC_ALL_PAGES = 0x3f, + CDIO_MMC_R_W_ERROR_PAGE = 0x01, + CDIO_MMC_WRITE_PARMS_PAGE = 0x05, + CDIO_MMC_CDR_PARMS_PAGE = 0x0d, + CDIO_MMC_AUDIO_CTL_PAGE = 0x0e, + CDIO_MMC_POWER_PAGE = 0x1a, + CDIO_MMC_FAULT_FAIL_PAGE = 0x1c, + CDIO_MMC_TO_PROTECT_PAGE = 0x1d, + CDIO_MMC_CAPABILITIES_PAGE = 0x2a, + CDIO_MMC_ALL_PAGES = 0x3f, } cdio_mmc_mode_page_t; - + + /** + READ DISC INFORMATION Data Types + */ + typedef enum { + CDIO_MMC_READ_DISC_INFO_STANDARD = 0x0, + CDIO_MMC_READ_DISC_INFO_TRACK = 0x1, + CDIO_MMC_READ_DISC_INFO_POW = 0x2, + } cdio_mmc_read_disc_info_datatype_t; + PRAGMA_BEGIN_PACKED struct mmc_audio_volume_entry_s @@ -640,21 +649,6 @@ mmc_audio_read_subchannel (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. - - @param i_status, if not NULL, on return will be set indicate - whether the operation was a success (DRIVER_OP_SUCCESS) or if not - to some other value. - - @return true if the disc is detected as erasable (rewritable), - false otherwise. - */ - bool mmc_get_disc_erasable( const CdIo_t *p_cdio, - driver_return_code_t *i_status ); - /** Get the lsn of the end of the CD diff --git a/include/cdio/mmc_cmds.h b/include/cdio/mmc_cmds.h index b56e6a0e..2a4659de 100644 --- a/include/cdio/mmc_cmds.h +++ b/include/cdio/mmc_cmds.h @@ -15,370 +15,14 @@ along with this program. If not, see . */ -/** - \file mmc_cmds.h - - \brief Wrappers for specific Multimedia Command (MMC) commands e.g., READ - DISC, START/STOP UNIT. - - The documents we make use of are described in several - specifications made by the SCSI committee T10 - http://www.t10.org. In particular, SCSI Primary Commands (SPC), - SCSI Block Commands (SBC), and Multi-Media Commands (MMC). These - documents generally have a numeric level number appended. For - example SPC-3 refers to ``SCSI Primary Commands - 3'. - - In year 2010 the current versions were SPC-3, SBC-2, MMC-5. - -*/ - #ifndef __CDIO_MMC_CMDS_H__ #define __CDIO_MMC_CMDS_H__ #include +#include +#include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - /** - Get drive capabilities vis SCSI-MMC GET CONFIGURATION - @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_get_configuration(const CdIo_t *p_cdio, void *p_buf, - unsigned int i_size, - unsigned int return_type, - unsigned int i_starting_feature_number, - unsigned int i_timeout_ms); - - /** - Detects the disc type using the SCSI-MMC GET CONFIGURATION command. - - @param p_cdio the CD object to be acted upon. - - @param i_status, if not NULL, on return will be set indicate whether - the operation was a success (DRIVER_OP_SUCCESS) or if not to some - other value. - - @param p_disctype the disc type set on success. - @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_get_disctype( const CdIo_t *p_cdio, - unsigned int i_timeout_ms, - cdio_mmc_feature_profile_t *p_disctype); - - /** - 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 - - @param p_cdio the CD object to be acted upon. - - @param out_buf media status code from operation - - @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_get_event_status(const CdIo_t *p_cdio, - uint8_t out_buf[2]); - - - /** - Run a SCSI-MMC MODE SELECT (10-byte) command - 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 - - @param i_timeout_ms value in milliseconds to use on timeout. Setting - to 0 uses the default time-out value stored in - mmc_timeout_ms. - - @return DRIVER_OP_SUCCESS if we ran the command ok. - */ - driver_return_code_t mmc_mode_select_10(CdIo_t *p_cdio, /*out*/ void *p_buf, - unsigned int i_size, int page, - unsigned int i_timeout_ms); - /** - Run a SCSI-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); - - /** - Run a SCSI-MMC MODE SENSE command (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_10( CdIo_t *p_cdio, /*out*/ void *p_buf, - unsigned int i_size, int page); - - /** - Run a SCSI-MMC MODE SENSE command (6-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_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. - - @param p_cdio object to read from - - @param p_buf Place to store data. The caller should ensure that - p_buf can hold at least i_blocksize * i_blocks bytes. - - @param i_lsn sector to read - - @param expected_sector_type restricts reading to a specific CD - sector type. Only 3 bits with values 1-5 are used: - 0 all sector types - 1 CD-DA sectors only - 2 Mode 1 sectors only - 3 Mode 2 formless sectors only. Note in contrast to all other - values an MMC CD-ROM is not required to support this mode. - 4 Mode 2 Form 1 sectors only - 5 Mode 2 Form 2 sectors only - - @param b_digital_audio_play Control error concealment when the - data being read is CD-DA. If the data being read is not CD-DA, - this parameter is ignored. If the data being read is CD-DA and - DAP is false zero, then the user data returned should not be - modified by flaw obscuring mechanisms such as audio data mute and - interpolate. If the data being read is CD-DA and DAP is true, - then the user data returned should be modified by flaw obscuring - mechanisms such as audio data mute and interpolate. - - b_sync_header return the sync header (which will probably have - the same value as CDIO_SECTOR_SYNC_HEADER of size - CDIO_CD_SYNC_SIZE). - - @param header_codes Header Codes refer to the sector header and - the sub-header that is present in mode 2 formed sectors: - - 0 No header information is returned. - 1 The 4-byte sector header of data sectors is be returned, - 2 The 8-byte sector sub-header of mode 2 formed sectors is - returned. - 3 Both sector header and sub-header (12 bytes) is returned. - The Header preceeds the rest of the bytes (e.g. user-data bytes) - that might get returned. - - @param b_user_data Return user data if true. - - For CD-DA, the User Data is CDIO_CD_FRAMESIZE_RAW bytes. - - For Mode 1, The User Data is ISO_BLOCKSIZE bytes beginning at - offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. - - For Mode 2 formless, The User Data is M2RAW_SECTOR_SIZE bytes - beginning at offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. - - For data Mode 2, form 1, User Data is ISO_BLOCKSIZE bytes beginning at - offset CDIO_CD_XA_SYNC_HEADER. - - For data Mode 2, form 2, User Data is 2 324 bytes beginning at - offset CDIO_CD_XA_SYNC_HEADER. - - @param b_sync - - @param b_edc_ecc true if we return EDC/ECC error detection/correction bits. - - The presence and size of EDC redundancy or ECC parity is defined - according to sector type: - - CD-DA sectors have neither EDC redundancy nor ECC parity. - - Data Mode 1 sectors have 288 bytes of EDC redundancy, Pad, and - ECC parity beginning at offset 2064. - - Data Mode 2 formless sectors have neither EDC redundancy nor ECC - parity - - Data Mode 2 form 1 sectors have 280 bytes of EDC redundancy and - ECC parity beginning at offset 2072 - - Data Mode 2 form 2 sectors optionally have 4 bytes of EDC - redundancy beginning at offset 2348. - - - @param c2_error_information If true associate a bit with each - sector for C2 error The resulting bit field is ordered exactly as - the main channel bytes. Each 8-bit boundary defines a byte of - flag bits. - - @param subchannel_selection subchannel-selection bits - - 0 No Sub-channel data shall be returned. (0 bytes) - 1 RAW P-W Sub-channel data shall be returned. (96 byte) - 2 Formatted Q sub-channel data shall be transferred (16 bytes) - 3 Reserved - 4 Corrected and de-interleaved R-W sub-channel (96 bytes) - 5-7 Reserved - - @param i_blocksize size of the a block expected to be returned - - @param i_blocks number of blocks expected to be returned. - - @return DRIVER_OP_SUCCESS if we ran the command ok. - */ - driver_return_code_t - mmc_read_cd ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, - int expected_sector_type, bool b_digital_audio_play, - bool b_sync, uint8_t header_codes, bool b_user_data, - bool b_edc_ecc, uint8_t c2_error_information, - uint8_t subchannel_selection, uint16_t i_blocksize, - uint32_t i_blocks ); - - /** - 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 Kbs 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 ); - - /** - Set the drive speed in K bytes per second using SCSI-MMC SET SPEED. -. - - @param p_cdio CD structure set by cdio_open(). - @param i_Kbs_speed speed in K bytes per second. Note this is - not in standard CD-ROM speed units, e.g. - 1x, 4x, 16x as it is in cdio_set_speed. - To convert CD-ROM speed units to Kbs, - multiply the number by 176 (for raw data) - and by 150 (for filesystem data). - Also note that ATAPI specs say that a value - less than 176 will result in an error. - On many CD-ROM drives, - specifying a value too large will result in using - the fastest speed. - - @param i_timeout_ms value in milliseconds to use on timeout. Setting - to 0 uses the default time-out value stored in - mmc_timeout_ms. - - @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_drive_speed - */ - driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, - int i_Kbs_speed, - unsigned int i_timeout_ms); - - /** - Load or Unload media using a MMC START STOP UNIT 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. - - @return DRIVER_OP_SUCCESS if we ran the command ok. - - @see mmc_eject_media or mmc_close_tray - */ - driver_return_code_t mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, - bool b_immediate, - uint8_t power_condition, - unsigned int i_timeout_ms); - - /** - Check if drive is ready using SCSI-MMC TEST UNIT READY command. - - @param p_cdio the CD object to be acted upon. - - @param i_timeout_ms value in milliseconds to use on timeout. Setting - to 0 uses the default time-out value stored in - mmc_timeout_ms. - - @return DRIVER_OP_SUCCESS if we ran the command ok. - */ - driver_return_code_t mmc_test_unit_ready(const CdIo_t *p_cdio, - unsigned int i_timeout_ms); - - -#ifndef DO_NOT_WANT_OLD_MMC_COMPATIBILITY -#define mmc_start_stop_media(c, e, i, p, t) \ - mmc_start_stop_unit(c, e, i, p, t, 0) -#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MMC_H__ */ +#endif /* __CDIO_MMC_CMDS_H__ */ /* * Local variables: diff --git a/include/cdio/mmc_hl_cmds.h b/include/cdio/mmc_hl_cmds.h new file mode 100644 index 00000000..30940d59 --- /dev/null +++ b/include/cdio/mmc_hl_cmds.h @@ -0,0 +1,126 @@ +/* + Copyright (C) 2010 Rocky Bernstein + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + \file mmc_hl_cmds.h + + \brief Higher-level MMC commands which build on top of the lower-level + MMC commands. + */ + +#ifndef __CDIO_MMC_HL_CMDS_H__ +#define __CDIO_MMC_HL_CMDS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** + Detects if a disc (CD or DVD) is erasable or not. + + @param p_user_data the CD object to be acted upon. + + @param b_erasable, if not NULL, on return will be set indicate whether + the operation was a success (DRIVER_OP_SUCCESS) or if not to some + other value. + + @return true if the disc is detected as erasable (rewritable), false + otherwise. + */ + driver_return_code_t mmc_get_disc_erasable(const CdIo_t *p_cdio, + bool *b_erasable); + + /** + 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 ); + + /** + Detects the disc type using the SCSI-MMC GET CONFIGURATION command. + + @param p_cdio the CD object to be acted upon. + + @param i_status, if not NULL, on return will be set indicate whether + the operation was a success (DRIVER_OP_SUCCESS) or if not to some + other value. + + @param p_disctype the disc type set on success. + @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_get_disctype(const CdIo_t *p_cdio, + unsigned int i_timeout_ms, + cdio_mmc_feature_profile_t *p_disctype); + + /** + Run a SCSI-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); + + /** + 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 Kbs 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 ); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_MMC_HL_CMDS_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/cdio/mmc_ll_cmds.h b/include/cdio/mmc_ll_cmds.h new file mode 100644 index 00000000..a4c429b3 --- /dev/null +++ b/include/cdio/mmc_ll_cmds.h @@ -0,0 +1,345 @@ +/* + Copyright (C) 2010 Rocky Bernstein + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + \file mmc_ll_cmds.h + + \brief Wrappers for specific Multimedia Command (MMC) commands e.g., READ + DISC, START/STOP UNIT. + + The documents we make use of are described in several + specifications made by the SCSI committee T10 + http://www.t10.org. In particular, SCSI Primary Commands (SPC), + SCSI Block Commands (SBC), and Multi-Media Commands (MMC). These + documents generally have a numeric level number appended. For + example SPC-3 refers to ``SCSI Primary Commands - 3'. + + In year 2010 the current versions were SPC-3, SBC-2, MMC-5. + +*/ + +#ifndef __CDIO_MMC_LL_CMDS_H__ +#define __CDIO_MMC_LL_CMDS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /** + Get drive capabilities vis SCSI-MMC GET CONFIGURATION + @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_get_configuration(const CdIo_t *p_cdio, void *p_buf, + unsigned int i_size, + unsigned int return_type, + unsigned int i_starting_feature_number, + unsigned int i_timeout_ms); + + /** + Return results of media event status via SCSI-MMC GET EVENT STATUS + + @param p_cdio the CD object to be acted upon. + + @param out_buf media status code from operation + + @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_get_event_status(const CdIo_t *p_cdio, + uint8_t out_buf[2]); + + + /** + Run a SCSI-MMC MODE SELECT (10-byte) command + 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 + + @param i_timeout_ms value in milliseconds to use on timeout. Setting + to 0 uses the default time-out value stored in + mmc_timeout_ms. + + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + driver_return_code_t mmc_mode_select_10(CdIo_t *p_cdio, /*out*/ void *p_buf, + unsigned int i_size, int page, + unsigned int i_timeout_ms); + /** + Run a SCSI-MMC MODE SENSE command (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_10( CdIo_t *p_cdio, /*out*/ void *p_buf, + unsigned int i_size, int page); + + /** + Run a SCSI-MMC MODE SENSE command (6-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_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. + + @param p_cdio object to read from + + @param p_buf Place to store data. The caller should ensure that + p_buf can hold at least i_blocksize * i_blocks bytes. + + @param i_lsn sector to read + + @param expected_sector_type restricts reading to a specific CD + sector type. Only 3 bits with values 1-5 are used: + 0 all sector types + 1 CD-DA sectors only + 2 Mode 1 sectors only + 3 Mode 2 formless sectors only. Note in contrast to all other + values an MMC CD-ROM is not required to support this mode. + 4 Mode 2 Form 1 sectors only + 5 Mode 2 Form 2 sectors only + + @param b_digital_audio_play Control error concealment when the + data being read is CD-DA. If the data being read is not CD-DA, + this parameter is ignored. If the data being read is CD-DA and + DAP is false zero, then the user data returned should not be + modified by flaw obscuring mechanisms such as audio data mute and + interpolate. If the data being read is CD-DA and DAP is true, + then the user data returned should be modified by flaw obscuring + mechanisms such as audio data mute and interpolate. + + b_sync_header return the sync header (which will probably have + the same value as CDIO_SECTOR_SYNC_HEADER of size + CDIO_CD_SYNC_SIZE). + + @param header_codes Header Codes refer to the sector header and + the sub-header that is present in mode 2 formed sectors: + + 0 No header information is returned. + 1 The 4-byte sector header of data sectors is be returned, + 2 The 8-byte sector sub-header of mode 2 formed sectors is + returned. + 3 Both sector header and sub-header (12 bytes) is returned. + The Header preceeds the rest of the bytes (e.g. user-data bytes) + that might get returned. + + @param b_user_data Return user data if true. + + For CD-DA, the User Data is CDIO_CD_FRAMESIZE_RAW bytes. + + For Mode 1, The User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For Mode 2 formless, The User Data is M2RAW_SECTOR_SIZE bytes + beginning at offset CDIO_CD_HEADER_SIZE+CDIO_CD_SUBHEADER_SIZE. + + For data Mode 2, form 1, User Data is ISO_BLOCKSIZE bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + For data Mode 2, form 2, User Data is 2 324 bytes beginning at + offset CDIO_CD_XA_SYNC_HEADER. + + @param b_sync + + @param b_edc_ecc true if we return EDC/ECC error detection/correction bits. + + The presence and size of EDC redundancy or ECC parity is defined + according to sector type: + + CD-DA sectors have neither EDC redundancy nor ECC parity. + + Data Mode 1 sectors have 288 bytes of EDC redundancy, Pad, and + ECC parity beginning at offset 2064. + + Data Mode 2 formless sectors have neither EDC redundancy nor ECC + parity + + Data Mode 2 form 1 sectors have 280 bytes of EDC redundancy and + ECC parity beginning at offset 2072 + + Data Mode 2 form 2 sectors optionally have 4 bytes of EDC + redundancy beginning at offset 2348. + + + @param c2_error_information If true associate a bit with each + sector for C2 error The resulting bit field is ordered exactly as + the main channel bytes. Each 8-bit boundary defines a byte of + flag bits. + + @param subchannel_selection subchannel-selection bits + + 0 No Sub-channel data shall be returned. (0 bytes) + 1 RAW P-W Sub-channel data shall be returned. (96 byte) + 2 Formatted Q sub-channel data shall be transferred (16 bytes) + 3 Reserved + 4 Corrected and de-interleaved R-W sub-channel (96 bytes) + 5-7 Reserved + + @param i_blocksize size of the a block expected to be returned + + @param i_blocks number of blocks expected to be returned. + + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + driver_return_code_t + mmc_read_cd(const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn, + int expected_sector_type, bool b_digital_audio_play, + bool b_sync, uint8_t header_codes, bool b_user_data, + bool b_edc_ecc, uint8_t c2_error_information, + uint8_t subchannel_selection, uint16_t i_blocksize, + uint32_t i_blocks); + + /** + Request information about et drive capabilities vis SCSI-MMC READ + DISC INFORMATION + + @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 data_type kind of information to retrieve. + + @return DRIVER_OP_SUCCESS (0) if we got the status. + */ + driver_return_code_t + mmc_read_disc_information(const CdIo_t *p_cdio, /*out*/ void *p_buf, + unsigned int i_size, + cdio_mmc_read_disc_info_datatype_t data_type, + unsigned int i_timeout_ms); + + /** + Set the drive speed in K bytes per second using SCSI-MMC SET SPEED. +. + + @param p_cdio CD structure set by cdio_open(). + @param i_Kbs_speed speed in K bytes per second. Note this is + not in standard CD-ROM speed units, e.g. + 1x, 4x, 16x as it is in cdio_set_speed. + To convert CD-ROM speed units to Kbs, + multiply the number by 176 (for raw data) + and by 150 (for filesystem data). + Also note that ATAPI specs say that a value + less than 176 will result in an error. + On many CD-ROM drives, + specifying a value too large will result in using + the fastest speed. + + @param i_timeout_ms value in milliseconds to use on timeout. Setting + to 0 uses the default time-out value stored in + mmc_timeout_ms. + + @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_drive_speed + */ + driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, + int i_Kbs_speed, + unsigned int i_timeout_ms); + + /** + Load or Unload media using a MMC START STOP UNIT 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. + + @return DRIVER_OP_SUCCESS if we ran the command ok. + + @see mmc_eject_media or mmc_close_tray + */ + driver_return_code_t mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, + bool b_immediate, + uint8_t power_condition, + unsigned int i_timeout_ms); + + /** + Check if drive is ready using SCSI-MMC TEST UNIT READY command. + + @param p_cdio the CD object to be acted upon. + + @param i_timeout_ms value in milliseconds to use on timeout. Setting + to 0 uses the default time-out value stored in + mmc_timeout_ms. + + @return DRIVER_OP_SUCCESS if we ran the command ok. + */ + driver_return_code_t mmc_test_unit_ready(const CdIo_t *p_cdio, + unsigned int i_timeout_ms); + + +#ifndef DO_NOT_WANT_OLD_MMC_COMPATIBILITY +#define mmc_start_stop_media(c, e, i, p, t) \ + mmc_start_stop_unit(c, e, i, p, t, 0) +#endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __CDIO_MMC_HL_CMDS_H__ */ + +/* + * Local variables: + * c-file-style: "gnu" + * tab-width: 8 + * indent-tabs-mode: nil + * End: + */ diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index 8b2e0d36..7dc6c418 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -226,6 +226,7 @@ mmc_mode_sense_6 mmc_prevent_allow_meduim_removal mmc_read_cd mmc_read_data_sectors +mmc_read_disc_information mmc_read_sectors mmc_read_timeout_ms mmc_run_cmd diff --git a/lib/driver/mmc/mmc.c b/lib/driver/mmc/mmc.c index cdd44849..35de3b08 100644 --- a/lib/driver/mmc/mmc.c +++ b/lib/driver/mmc/mmc.c @@ -618,35 +618,6 @@ mmc_get_cmd_len(uint8_t scsi_cmd) 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. - - @param i_status, if not NULL, on return will be set indicate whether - the operation was a success (DRIVER_OP_SUCCESS) or if not to some - other value. - - @return true if the disc is detected as erasable (rewritable), false -otherwise. - */ -bool mmc_get_disc_erasable(const CdIo_t *p_cdio, - driver_return_code_t *opt_i_status) { - mmc_cdb_t cdb = {{0, }}; - uint8_t buf[42] = { 0, }; - driver_return_code_t 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 (opt_i_status != NULL) *opt_i_status = i_status; - return (DRIVER_OP_SUCCESS == i_status) ? - ((buf[2] & 0x10) ? true : false) - : false; -} - /** Return the size of the CD in logical block address (LBA) units. @param p_cdio the CD object to be acted upon. diff --git a/lib/driver/mmc/mmc_hl_cmds.c b/lib/driver/mmc/mmc_hl_cmds.c index 8cad1d12..2912161c 100644 --- a/lib/driver/mmc/mmc_hl_cmds.c +++ b/lib/driver/mmc/mmc_hl_cmds.c @@ -44,6 +44,33 @@ mmc_eject_media( const CdIo_t *p_cdio ) } +/** + Detects if a disc (CD or DVD) is erasable or not. + + @param p_user_data the CD object to be acted upon. + + @param b_erasable, if not NULL, on return will be set indicate whether + the operation was a success (DRIVER_OP_SUCCESS) or if not to some + other value. + + @return true if the disc is detected as erasable (rewritable), false +otherwise. + */ +/* From Frank Endres: */ +driver_return_code_t mmc_get_disc_erasable(const CdIo_t *p_cdio, + bool *b_erasable) { + uint8_t buf[42] = { 0, }; + driver_return_code_t i_status; + + i_status = mmc_read_disc_information(p_cdio, buf, sizeof(buf), + CDIO_MMC_READ_DISC_INFO_STANDARD, 0); + + *b_erasable = (DRIVER_OP_SUCCESS == i_status) + ? (*b_erasable = ((buf[2] & 0x10) ? true : false)) + : false; + return i_status; +} + /* From Frank Endres: */ /** Detects the disc type using the SCSI-MMC GET CONFIGURATION command. diff --git a/lib/driver/mmc/mmc_ll_cmds.c b/lib/driver/mmc/mmc_ll_cmds.c index de6fd6c6..99044756 100644 --- a/lib/driver/mmc/mmc_ll_cmds.c +++ b/lib/driver/mmc/mmc_ll_cmds.c @@ -23,7 +23,7 @@ #endif #include -#include +#include #include "cdio_private.h" #include "mmc_cmd_helper.h" @@ -31,34 +31,6 @@ #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; - - 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); -} - /** Get drive capabilities vis SCSI-MMC GET CONFIGURATION @param p_cdio the CD object to be acted upon. @@ -82,11 +54,15 @@ mmc_get_configuration(const CdIo_t *p_cdio, void *p_buf, } /** - Return results of media status - @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 -*/ + Return results of media event status via SCSI-MMC GET EVENT STATUS + + @param p_cdio the CD object to be acted upon. + + @param out_buf media status code from operation + + @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_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]) { @@ -173,6 +149,34 @@ mmc_mode_sense_6(CdIo_t *p_cdio, void *p_buf, unsigned int i_size, int page) return MMC_RUN_CMD(SCSI_MMC_DATA_READ, mmc_timeout_ms); } +/** + 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; + + 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); +} + /* Maximum blocks to retrieve. Would be nice to customize this based on drive capabilities. */ @@ -329,6 +333,33 @@ mmc_read_cd(const CdIo_t *p_cdio, void *p_buf1, lsn_t i_lsn, } } +/** + Request information about et drive capabilities vis SCSI-MMC READ + DISC INFORMATION + + @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 data_type kind of information to retrieve. + + @return DRIVER_OP_SUCCESS (0) if we got the status. + */ +driver_return_code_t +mmc_read_disc_information(const CdIo_t *p_cdio, /*out*/ void *p_buf, + unsigned int i_size, + cdio_mmc_read_disc_info_datatype_t data_type, + unsigned int i_timeout_ms) +{ + MMC_CMD_SETUP(CDIO_MMC_GPCMD_READ_DISC_INFO); + CDIO_MMC_SET_READ_LENGTH8(cdb.field, i_size); + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; + cdb.field[1] = data_type & 0x7; + return MMC_RUN_CMD(SCSI_MMC_DATA_READ, i_timeout_ms); +} + /** Set the drive speed in K bytes per second using SCSI-MMC SET SPEED. . diff --git a/test/driver/mmc.c b/test/driver/mmc.c index 884ece58..a5875c5d 100644 --- a/test/driver/mmc.c +++ b/test/driver/mmc.c @@ -92,13 +92,13 @@ static driver_return_code_t test_get_disc_erasable(const CdIo_t *p_cdio, const char *psz_source, bool verbose) { - driver_return_code_t drc; - bool b_erasable = mmc_get_disc_erasable(p_cdio, &drc); - if (verbose) + driver_return_code_t i_status; + bool b_erasable; + + i_status = mmc_get_disc_erasable(p_cdio, &b_erasable); + if (verbose && DRIVER_OP_SUCCESS == i_status) printf("Disc is %serasable.\n", b_erasable ? "" : "not "); - /* Try also with NULL. */ - b_erasable = mmc_get_disc_erasable(p_cdio, NULL); - return drc; + return i_status; }