From 2d3b7d28b4ab9dc39a79d20c07acf90260500c67 Mon Sep 17 00:00:00 2001 From: "R. Bernstein" Date: Sun, 7 Feb 2010 21:04:21 -0500 Subject: [PATCH] Add SCSI-MMC GET CONFIGURATION. Add Frank Endres' disc type determination via MMC. Be more careful to suffix with CDIO_MMC which I hope will reduce possible name conflicts. --- include/cdio++/mmc.hpp | 2 +- include/cdio/mmc.h | 102 +++++++++++++++++------------ include/cdio/mmc_cmds.h | 59 ++++++++++++++++- lib/driver/MSWindows/win32_ioctl.c | 4 +- lib/driver/gnu_linux.c | 3 +- lib/driver/libcdio.sym | 11 +++- lib/driver/mmc/mmc.c | 99 +++++++++++++++++++++++++++- lib/driver/mmc/mmc_hl_cmds.c | 64 +++++++++++++++++- lib/driver/mmc/mmc_ll_cmds.c | 28 +++++++- src/mmc-tool.c | 2 +- test/driver/mmc.c | 8 +-- 11 files changed, 323 insertions(+), 59 deletions(-) diff --git a/include/cdio++/mmc.hpp b/include/cdio++/mmc.hpp index 04c08ba0..e94169b4 100644 --- a/include/cdio++/mmc.hpp +++ b/include/cdio++/mmc.hpp @@ -397,7 +397,7 @@ void mmcSetBlocksize ( uint16_t i_blocksize) */ void mmcSetSpeed( int i_speed ) { - driver_return_code_t drc = mmc_set_speed( p_cdio, i_speed ); + driver_return_code_t drc = mmc_set_speed( p_cdio, i_speed, 0); possible_throw_device_exception(drc); } diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index 01ac63f4..8b8292d4 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -65,7 +65,7 @@ extern "C" { include this for direct MMC access. See SCSI Primary Commands-2 (SPC-3) table 26 page 38. */ - typedef struct mmc_request_sense { + typedef struct cdio_mmc_request_sense { #if defined(__MMC_BIG_ENDIAN_BITFIELD) uint8_t valid : 1; /**< valid bit is 1 if info is valid */ uint8_t error_code : 7; @@ -101,27 +101,27 @@ extern "C" { uint8_t fruc; /**< Field replaceable unit code */ uint8_t sks[3]; /**< Sense-key specific */ uint8_t asb[46]; /**< Additional sense bytes */ - } mmc_request_sense_t; + } cdio_mmc_request_sense_t; /** Meanings of the values of mmc_request_sense.sense_key */ typedef enum { - MMC_SENSE_KEY_NO_SENSE = 0, - MMC_SENSE_KEY_RECOVERED_ERROR = 1, - MMC_SENSE_KEY_NOT_READY = 2, - MMC_SENSE_KEY_MEDIUM_ERROR = 3, - MMC_SENSE_KEY_HARDWARE_ERROR = 4, - MMC_SENSE_KEY_ILLEGAL_REQUEST = 5, - MMC_SENSE_KEY_UNIT_ATTENTION = 6, - MMC_SENSE_KEY_DATA_PROTECT = 7, - MMC_SENSE_KEY_BLANK_CHECK = 8, - MMC_SENSE_KEY_VENDOR_SPECIFIC = 9, - MMC_SENSE_KEY_COPY_ABORTED = 10, - MMC_SENSE_KEY_ABORTED_COMMAND = 11, - MMC_SENSE_KEY_OBSOLTE = 12, - } mmc_sense_key_t; + CDIO_MMC_SENSE_KEY_NO_SENSE = 0, + CDIO_MMC_SENSE_KEY_RECOVERED_ERROR = 1, + CDIO_MMC_SENSE_KEY_NOT_READY = 2, + CDIO_MMC_SENSE_KEY_MEDIUM_ERROR = 3, + CDIO_MMC_SENSE_KEY_HARDWARE_ERROR = 4, + CDIO_MMC_SENSE_KEY_ILLEGAL_REQUEST = 5, + CDIO_MMC_SENSE_KEY_UNIT_ATTENTION = 6, + CDIO_MMC_SENSE_KEY_DATA_PROTECT = 7, + CDIO_MMC_SENSE_KEY_BLANK_CHECK = 8, + CDIO_MMC_SENSE_KEY_VENDOR_SPECIFIC = 9, + CDIO_MMC_SENSE_KEY_COPY_ABORTED = 10, + CDIO_MMC_SENSE_KEY_ABORTED_COMMAND = 11, + CDIO_MMC_SENSE_KEY_OBSOLTE = 12, + } cdio_mmc_sense_key_t; /** Maps a mmc_sense_key_t into a string name. @@ -419,7 +419,7 @@ typedef enum { /** Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */ typedef enum { - CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable + CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disc, capable of changing behavior */ CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with removable media */ @@ -483,6 +483,37 @@ typedef enum { } cdio_mmc_feature_interface_t; +typedef enum { + CDIO_MMC_DISCTYPE_NO_DISC = 0x00, + + CDIO_MMC_DISCTYPE_CD_ROM = 0x08, + CDIO_MMC_DISCTYPE_CD_R = 0x09, + CDIO_MMC_DISCTYPE_CD_RW = 0x0A, + + CDIO_MMC_DISCTYPE_DVD_ROM = 0x10, + CDIO_MMC_DISCTYPE_DVD_R = 0x11, + CDIO_MMC_DISCTYPE_DVD_RAM = 0x12, + CDIO_MMC_DISCTYPE_DVD_RW_RO = 0x13, /**< DVD-RW Restricted Overwrite */ + CDIO_MMC_DISCTYPE_DVD_RW_SR = 0x14, /**< DVD-RW Sequential Recording */ + CDIO_MMC_DISCTYPE_DVD_R_DL_SR = 0x15, /**< DVD-R Dual Layer Sequential + Recording */ + CDIO_MMC_DISCTYPE_DVD_R_DL_JR = 0x16, /**< DVD-R Dual Layer Jump + Recording */ + CDIO_MMC_DISCTYPE_DVD_PRW = 0x1A, /**< DVD+RW */ + CDIO_MMC_DISCTYPE_DVD_PR = 0x1B, /**< DVD+R */ + CDIO_MMC_DISCTYPE_DVD_PRW_DL = 0x2A, /**< DVD+RW Dual Layer */ + CDIO_MMC_DISCTYPE_DVD_PR_DL = 0x2B, /**< DVD+R Dual Layer */ + + CDIO_MMC_DISCTYPE_BD_ROM = 0x40, + CDIO_MMC_DISCTYPE_BD_R_SR = 0x41, /**< Sequential Recording */ + CDIO_MMC_DISCTYPE_BD_R_RR = 0x42, /**< Random Recording */ + CDIO_MMC_DISCTYPE_BD_RE = 0x43, + + CDIO_MMC_DISCTYPE_HD_DVD_ROM = 0x50, + CDIO_MMC_DISCTYPE_HD_DVD_R = 0x51, + CDIO_MMC_DISCTYPE_HD_DVD_RAM = 0x52 +} cdio_mmc_disctype_t; + /** The largest Command Descriptor Block (CDB) size. The possible sizes are 6, 10, and 12 bytes. @@ -760,7 +791,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, string when done with it. */ - char * mmc_get_mcn ( const CdIo_t *p_cdio ); + char * mmc_get_mcn(const CdIo_t *p_cdio); /** Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...) @@ -770,9 +801,17 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, @param e_interface @return true if we have the interface and false if not. */ - bool_3way_t mmc_have_interface( CdIo_t *p_cdio, - cdio_mmc_feature_interface_t e_interface ); + bool_3way_t mmc_have_interface(CdIo_t *p_cdio, + cdio_mmc_feature_interface_t e_interface ); + bool mmc_is_disctype_bd(cdio_mmc_disctype_t disctype); + bool mmc_is_disctype_cdrom(cdio_mmc_disctype_t disctype); + bool mmc_is_disctype_dvd(cdio_mmc_disctype_t disctype); + bool mmc_is_disctype_hd_dvd (cdio_mmc_disctype_t disctype); + bool mmc_is_disctype_overwritable (cdio_mmc_disctype_t disctype); + bool mmc_is_disctype_rewritable(cdio_mmc_disctype_t disctype); + + /** Read just the user data part of some sort of data sector (via mmc_read_cd). @@ -867,7 +906,8 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, @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, mmc_request_sense_t **pp_sense); + int mmc_last_cmd_sense ( const CdIo_t *p_cdio, + cdio_mmc_request_sense_t **pp_sense); /** Set the block size for subsequest read requests, via MMC. @@ -875,26 +915,6 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, 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(). - @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 */ diff --git a/include/cdio/mmc_cmds.h b/include/cdio/mmc_cmds.h index 7e9529ca..b48787a5 100644 --- a/include/cdio/mmc_cmds.h +++ b/include/cdio/mmc_cmds.h @@ -35,10 +35,42 @@ #ifndef __CDIO_MMC_CMDS_H__ #define __CDIO_MMC_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); + + /** + 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_disctype_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. @@ -251,6 +283,26 @@ extern "C" { 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. . @@ -268,13 +320,18 @@ extern "C" { 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 ); + int i_Kbs_speed, + unsigned int i_timeout_ms); /** Load or Unload media using a MMC START STOP UNIT command. diff --git a/lib/driver/MSWindows/win32_ioctl.c b/lib/driver/MSWindows/win32_ioctl.c index 10d93206..9a509ba8 100644 --- a/lib/driver/MSWindows/win32_ioctl.c +++ b/lib/driver/MSWindows/win32_ioctl.c @@ -103,14 +103,14 @@ typedef struct _CDROM_TOC_FULL { typedef struct { SCSI_PASS_THROUGH_DIRECT sptd; ULONG Filler; /* Realign buffer to double-word boundary */ - mmc_request_sense_t SenseBuf; + cdio_mmc_request_sense_t SenseBuf; UCHAR DataBuf[512]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; typedef struct _SCSI_PASS_THROUGH_WITH_BUFFER { SCSI_PASS_THROUGH Spt; ULONG Filler; /* realign buffer to double-word boundary */ - mmc_request_sense_t SenseBuf; + cdio_mmc_request_sense_t SenseBuf; UCHAR DataBuf[512]; } SCSI_PASS_THROUGH_WITH_BUFFER; diff --git a/lib/driver/gnu_linux.c b/lib/driver/gnu_linux.c index b6ad3667..c8d721cd 100644 --- a/lib/driver/gnu_linux.c +++ b/lib/driver/gnu_linux.c @@ -34,7 +34,6 @@ 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 @@ -1251,7 +1250,7 @@ run_mmc_cmd_linux(void *p_user_data, { _img_private_t *p_env = p_user_data; struct cdrom_generic_command cgc; - mmc_request_sense_t sense; + cdio_mmc_request_sense_t sense; unsigned char *u_sense = (unsigned char *) &sense; p_env->gen.scsi_mmc_sense_valid = 0; diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index 69198a69..3a50c57e 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -200,19 +200,28 @@ mmc_feature2str mmc_feature_profile2str mmc_get_blocksize mmc_get_cmd_len +mmc_get_configuration mmc_get_discmode mmc_get_drive_mmc_cap mmc_get_dvd_struct_physical +mmc_get_event_status mmc_get_hwinfo mmc_get_last_lsn mmc_get_mcn mmc_get_media_changed mmc_get_tray_status mmc_have_interface +mmc_is_disctype_bd +mmc_is_disctype_cdrom +mmc_is_disctype_dvd +mmc_is_disctype_hd_dvd +mmc_is_disctype_overwritable mmc_last_cmd_sense +mmc_mode_select_10 mmc_mode_sense mmc_mode_sense_10 mmc_mode_sense_6 +mmc_prevent_allow_meduim_removal mmc_read_cd mmc_read_data_sectors mmc_read_sectors @@ -221,6 +230,6 @@ mmc_run_cmd mmc_run_cmd_len mmc_set_blocksize mmc_set_speed -mmc_start_stop_media +mmc_start_stop_unit mmc_timeout_ms track_format2str diff --git a/lib/driver/mmc/mmc.c b/lib/driver/mmc/mmc.c index 4f72a24f..02614fa4 100644 --- a/lib/driver/mmc/mmc.c +++ b/lib/driver/mmc/mmc.c @@ -231,7 +231,7 @@ set_speed_mmc (void *p_user_data, int i_speed) { generic_img_private_t *p_env = p_user_data; if (!p_env) return DRIVER_OP_UNINIT; - return mmc_set_speed( p_env->cdio, i_speed ); + return mmc_set_speed( p_env->cdio, i_speed, 0); } /** @@ -966,7 +966,7 @@ int mmc_get_tray_status(const CdIo_t *p_cdio) bytes available, <0 in case of internal error. */ int -mmc_last_cmd_sense(const CdIo_t *p_cdio, mmc_request_sense_t **pp_sense) +mmc_last_cmd_sense(const CdIo_t *p_cdio, cdio_mmc_request_sense_t **pp_sense) { generic_img_private_t *gen; @@ -1275,6 +1275,99 @@ mmc_have_interface( CdIo_t *p_cdio, cdio_mmc_feature_interface_t e_interface ) return dunno; } +bool +mmc_is_disctype_bd (cdio_mmc_disctype_t disctype) { + switch (disctype) { + case CDIO_MMC_DISCTYPE_BD_ROM: + case CDIO_MMC_DISCTYPE_BD_R_SR: + case CDIO_MMC_DISCTYPE_BD_R_RR: + case CDIO_MMC_DISCTYPE_BD_RE: + return true; + default: + return false; + } +} + +bool +mmc_is_disctype_cdrom (cdio_mmc_disctype_t disctype) { + switch (disctype) { + case CDIO_MMC_DISCTYPE_CD_ROM: + case CDIO_MMC_DISCTYPE_CD_R: + case CDIO_MMC_DISCTYPE_CD_RW: + return true; + default: + return false; + } +} + + +bool +mmc_is_disctype_dvd (cdio_mmc_disctype_t disctype) { + switch (disctype) { + case CDIO_MMC_DISCTYPE_DVD_ROM: + case CDIO_MMC_DISCTYPE_DVD_RAM: + case CDIO_MMC_DISCTYPE_DVD_R: + case CDIO_MMC_DISCTYPE_DVD_RW_RO: + case CDIO_MMC_DISCTYPE_DVD_RW_SR: + case CDIO_MMC_DISCTYPE_DVD_R_DL_SR: + case CDIO_MMC_DISCTYPE_DVD_R_DL_JR: + case CDIO_MMC_DISCTYPE_DVD_PRW: + case CDIO_MMC_DISCTYPE_DVD_PR: + case CDIO_MMC_DISCTYPE_DVD_PRW_DL: + case CDIO_MMC_DISCTYPE_DVD_PR_DL: + return true; + default: + return false; + } +} + +bool +mmc_is_disctype_hd_dvd (cdio_mmc_disctype_t disctype) { + switch (disctype) { + case CDIO_MMC_DISCTYPE_HD_DVD_ROM: + case CDIO_MMC_DISCTYPE_HD_DVD_R: + case CDIO_MMC_DISCTYPE_HD_DVD_RAM: + return true; + default: + return false; + } +} + + +bool +mmc_is_disctype_overwritable (cdio_mmc_disctype_t disctype) { + switch (disctype) { + case CDIO_MMC_DISCTYPE_DVD_RW_RO: + case CDIO_MMC_DISCTYPE_DVD_R_DL_JR: + case CDIO_MMC_DISCTYPE_DVD_PRW: + case CDIO_MMC_DISCTYPE_DVD_PRW_DL: + case CDIO_MMC_DISCTYPE_BD_R_RR: /* pseudo-overwritable */ + case CDIO_MMC_DISCTYPE_BD_RE: + case CDIO_MMC_DISCTYPE_HD_DVD_RAM: + return true; + default: + return false; + } +} + + +bool +mmc_is_disctype_rewritable (cdio_mmc_disctype_t disctype) { + /* discs that need blanking before re-use */ + if (mmc_is_disctype_overwritable (disctype)) + return true; + + switch (disctype) { + case CDIO_MMC_DISCTYPE_CD_RW: + case CDIO_MMC_DISCTYPE_DVD_RW_SR: + case CDIO_MMC_DISCTYPE_BD_R_SR: + return true; + default: + return false; + } +} + + /** Read sectors using SCSI-MMC GPCMD_READ_CD. */ @@ -1340,6 +1433,8 @@ mmc_set_blocksize ( const CdIo_t *p_cdio, uint16_t i_blocksize) } + + /* * Local variables: diff --git a/lib/driver/mmc/mmc_hl_cmds.c b/lib/driver/mmc/mmc_hl_cmds.c index 44d6458b..71ac27f9 100644 --- a/lib/driver/mmc/mmc_hl_cmds.c +++ b/lib/driver/mmc/mmc_hl_cmds.c @@ -44,6 +44,68 @@ mmc_eject_media( const CdIo_t *p_cdio ) } +/* From Frank Endres: */ +/** + 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_disctype_t *p_disctype) +{ + uint8_t buf[500] = { 0, }; + driver_return_code_t i_status; + + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; + i_status = mmc_get_configuration(p_cdio, &buf, sizeof(buf), + CDIO_MMC_GET_CONF_ALL_FEATURES, + 0, i_timeout_ms); + + if (DRIVER_OP_SUCCESS == i_status) { + uint8_t *p, *q; + uint8_t profiles_list_length; + uint16_t profile_number; + bool profile_active; + + /* there is always a profile list feature listed at the + first place of the features list */ + p = buf + 8; + profiles_list_length = p[3]; + q = p+4; + *p_disctype = CDIO_MMC_DISCTYPE_NO_DISC; + + while ((p_disctype == CDIO_MMC_DISCTYPE_NO_DISC) && + (q < p + profiles_list_length)) { + profile_number = CDIO_MMC_GET_LEN16(q); + profile_active = q[2] & 0x01; + + if (profile_active) + switch (profile_number) { + case 0x08: case 0x09: case 0x0A: + case 0x10: case 0x11: case 0x12: + case 0x13: case 0x14: case 0x15: + case 0x16: case 0x1A: case 0x1B: + case 0x2A: case 0x2B: case 0x40: + case 0x41: case 0x42: case 0x43: + case 0x50: case 0x51: case 0x52: + *p_disctype = (cdio_mmc_disctype_t) profile_number; + break; + } + q += 4; + } + } + return i_status; +} + /** Run a SCSI-MMC MMC MODE SENSE command (6- or 10-byte version) and put the results in p_buf @@ -87,5 +149,5 @@ mmc_mode_sense(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, 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); + return mmc_set_speed(p_cdio, i_drive_speed * 176, 0); } diff --git a/lib/driver/mmc/mmc_ll_cmds.c b/lib/driver/mmc/mmc_ll_cmds.c index ec5a06bd..0b58b791 100644 --- a/lib/driver/mmc/mmc_ll_cmds.c +++ b/lib/driver/mmc/mmc_ll_cmds.c @@ -50,7 +50,6 @@ mmc_prevent_allow_medium_removal(const CdIo_t *p_cdio, 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; @@ -60,6 +59,28 @@ mmc_prevent_allow_medium_removal(const CdIo_t *p_cdio, 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. + @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) + +{ + MMC_CMD_SETUP(CDIO_MMC_GPCMD_GET_CONFIGURATION); + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; + cdb.field[1] = return_type & 0x3; + + CDIO_MMC_SET_LEN16(cdb.field, 2, i_starting_feature_number); + return MMC_RUN_CMD(SCSI_MMC_DATA_READ, i_timeout_ms); +} + /** Return results of media status @param p_cdio the CD object to be acted upon. @@ -335,12 +356,13 @@ mmc_read_cd(const CdIo_t *p_cdio, void *p_buf1, lsn_t i_lsn, @return DRIVER_OP_SUCCESS if we ran the command ok. */ int -mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed) +mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed, unsigned int i_timeout_ms) { uint8_t buf[14] = { 0, }; void * p_buf = &buf; const unsigned int i_size = sizeof(buf); + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; MMC_CMD_SETUP(CDIO_MMC_GPCMD_SET_SPEED); @@ -357,7 +379,7 @@ mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed) the maximum allowable speed. */ CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff); - return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, mmc_timeout_ms); + return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms); } /** diff --git a/src/mmc-tool.c b/src/mmc-tool.c index d76fc8d9..0eb32543 100644 --- a/src/mmc-tool.c +++ b/src/mmc-tool.c @@ -437,7 +437,7 @@ main(int argc, char *argv[]) const operation_t *p_op = &operation[i]; switch (p_op->op) { case OP_SPEED: - rc = mmc_set_speed(p_cdio, p_op->arg.i_num); + rc = mmc_set_speed(p_cdio, p_op->arg.i_num, 0); report(stdout, "%s (mmc_set_speed): %s\n", program_name, cdio_driver_errmsg(rc)); break; diff --git a/test/driver/mmc.c b/test/driver/mmc.c index 63710dae..fec0a1e3 100644 --- a/test/driver/mmc.c +++ b/test/driver/mmc.c @@ -55,7 +55,7 @@ static int tmmc_handle_outcome(CdIo_t *p_cdio, int i_status, unsigned char sense_reply[18], int flag); static void tmmc_print_status_sense(int i_status, int sense_valid, - mmc_request_sense_t *, int flag); + cdio_mmc_request_sense_t *, int flag); static int tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail, unsigned char sense_reply[18], int flag); @@ -98,7 +98,7 @@ tmmc_get_disc_erasable(const CdIo_t *p_cdio, const char *psz_source, */ static void tmmc_print_status_sense(int i_status, int sense_valid, - mmc_request_sense_t *p_sense, int flag) + cdio_mmc_request_sense_t *p_sense, int flag) { if (!(flag & 1)) return; @@ -119,7 +119,7 @@ static int tmmc_handle_outcome(CdIo_t *p_cdio, int i_status, int *sense_avail, unsigned char sense_reply[18], int flag) { - mmc_request_sense_t *p_sense = NULL; + cdio_mmc_request_sense_t *p_sense = NULL; *sense_avail = mmc_last_cmd_sense(p_cdio, &p_sense); tmmc_print_status_sense(i_status, *sense_avail, p_sense, flag & 1); @@ -295,7 +295,7 @@ tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag) { int ret, i, sense_avail; unsigned char sense_reply[18]; - mmc_request_sense_t *p_sense_reply = (mmc_request_sense_t *) sense_reply; + cdio_mmc_request_sense_t *p_sense_reply = (cdio_mmc_request_sense_t *) sense_reply; for (i = 0; i < max_tries; i++) { ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense_reply, flag & 1);