From 3755da8d0cb49da08e9aa895a982a5809792e2ce Mon Sep 17 00:00:00 2001 From: rocky Date: Wed, 9 Feb 2005 02:50:46 +0000 Subject: [PATCH] Add mode_sense6() and mode_sense10() MMC commands. Use them to hopefully clean up code a little. Remove some unused MMC "private" commands. iso4 -> isofuzzy --- example/.cvsignore | 1 + example/Makefile.am | 16 +- example/README | 4 +- example/{iso4.c => isofuzzy.c} | 2 +- include/cdio/mmc.h | 11 +- lib/driver/mmc.c | 284 ++++++++++++++++----------------- lib/driver/mmc_private.h | 19 +-- test/check_fuzzyiso.sh | 4 +- 8 files changed, 162 insertions(+), 179 deletions(-) rename example/{iso4.c => isofuzzy.c} (97%) diff --git a/example/.cvsignore b/example/.cvsignore index 0bb0f101..f0a71262 100644 --- a/example/.cvsignore +++ b/example/.cvsignore @@ -9,6 +9,7 @@ device drives iso? iso?cpp +isofuzzy mmc1 mmc2 paranoia diff --git a/example/Makefile.am b/example/Makefile.am index f7f71950..ddbcdd99 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.17 2005/02/06 15:09:10 rocky Exp $ +# $Id: Makefile.am,v 1.18 2005/02/09 02:50:47 rocky Exp $ # # Copyright (C) 2003, 2004, 2005 Rocky Bernstein # @@ -21,10 +21,10 @@ #################################################### # if DISABLE_CPP -noinst_PROGRAMS = cdtext device drives iso1 iso2 iso3 iso4 mmc1 mmc2 \ +noinst_PROGRAMS = cdtext device drives iso1 iso2 iso3 isofuzzy mmc1 mmc2 \ paranoia paranoia2 tracks sample3 sample4 else -noinst_PROGRAMS = cdtext device drives iso1 iso2 iso3 iso4 mmc1 mmc2 \ +noinst_PROGRAMS = cdtext device drives iso1 iso2 iso3 isofuzzy mmc1 mmc2 \ paranoia paranoia2 tracks sample3 sample4 \ iso1cpp iso2cpp iso3cpp endif @@ -37,13 +37,13 @@ device_LDADD = $(LIBCDIO_LIBS) drives_LDADD = $(LIBCDIO_LIBS) -paranoia_LDADD = $(LIBCDIO_PARANOIA_LIBS) $(LIBCDIO_CDDA_LIBS) $(LIBCDIO_LIBS) +paranoia_LDADD = $(LIBCDIO_PARANOIA_LIBS) $(LIBCDIO_CDDA_LIBS) $(LIBCDIO_LIBS) paranoia2_LDADD = $(LIBCDIO_PARANOIA_LIBS) $(LIBCDIO_CDDA_LIBS) $(LIBCDIO_LIBS) -iso1_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) -iso2_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) -iso3_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) -iso4_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) +iso1_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) +iso2_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) +iso3_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) +isofuzzy_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS) $(LIBICONV) if !DISABLE_CPP iso1cpp_SOURCES = iso1cpp.cpp diff --git a/example/README b/example/README index 90f6bf1f..8450ba81 100644 --- a/example/README +++ b/example/README @@ -1,4 +1,4 @@ -$Id: README,v 1.14 2005/02/06 15:09:10 rocky Exp $ +$Id: README,v 1.15 2005/02/09 02:50:47 rocky Exp $ This directory contains some simple examples of the use of the libcdio library. @@ -29,7 +29,7 @@ iso2.c: A program to show using libiso9660 to extract a file iso3.c: A program to show using libiso9660 to extract a file from an ISO-9660 image. -iso4.c: A program showing fuzzy ISO-9660 detection/reading. +isofuzzy.c : A program showing fuzzy ISO-9660 detection/reading. iso1cpp.cpp: iso1.c compiled via C++ iso2cpp.cpp: iso2.c compiled via C++ diff --git a/example/iso4.c b/example/isofuzzy.c similarity index 97% rename from example/iso4.c rename to example/isofuzzy.c index 01f07c20..2619e339 100644 --- a/example/iso4.c +++ b/example/isofuzzy.c @@ -1,5 +1,5 @@ /* - $Id: iso4.c,v 1.2 2005/02/05 18:58:36 rocky Exp $ + $Id: isofuzzy.c,v 1.1 2005/02/09 02:50:47 rocky Exp $ Copyright (C) 2005 Rocky Bernstein diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index 06a06dca..4108e6c8 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -1,5 +1,5 @@ /* - $Id: mmc.h,v 1.4 2005/02/08 04:14:28 rocky Exp $ + $Id: mmc.h,v 1.5 2005/02/09 02:50:47 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -468,6 +468,15 @@ char * mmc_get_mcn ( const CdIo_t *p_cdio ); bool mmc_have_interface( const CdIo_t *p_cdio, mmc_feature_interface_t e_interface ); +/*! Run a MODE_SENSE_10 and put the results in p_buf */ +int mmc_mode_sense_10( const CdIo_t *p_cdio, void *p_buf, int i_size, + int page); + +/*! Run a MODE_SENSE_6 and put the results in p_buf */ +int mmc_mode_sense_6( const CdIo_t *p_cdio, void *p_buf, int i_size, + int page); + + /*! Packet driver to read mode2 sectors. Can read only up to 25 blocks. */ diff --git a/lib/driver/mmc.c b/lib/driver/mmc.c index ca0dcaab..8b873ec4 100644 --- a/lib/driver/mmc.c +++ b/lib/driver/mmc.c @@ -1,6 +1,6 @@ /* Common Multimedia Command (MMC) routines. - $Id: mmc.c,v 1.5 2005/02/09 01:24:17 rocky Exp $ + $Id: mmc.c,v 1.6 2005/02/09 02:50:47 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -84,7 +84,7 @@ get_drive_cap_mmc (const void *p_user_data, { const generic_img_private_t *p_env = p_user_data; mmc_get_drive_cap( p_env->cdio, - p_read_cap, p_write_cap, p_misc_cap ); + p_read_cap, p_write_cap, p_misc_cap ); } int @@ -119,54 +119,6 @@ set_speed_mmc (void *p_user_data, int i_speed) return mmc_set_speed( p_env->cdio, i_speed ); } -/************************************************************************* - Miscellaenous other "private" routines. Probably need to better - classify these. -*************************************************************************/ - -int -mmc_get_blocksize_private ( void *p_env, - const mmc_run_cmd_fn_t run_mmc_cmd) -{ - int i_status = 0; - scsi_mmc_cdb_t cdb = {{0, }}; - - struct - { - uint8_t reserved1; - uint8_t medium; - uint8_t reserved2; - uint8_t block_desc_length; - uint8_t density; - uint8_t number_of_blocks_hi; - uint8_t number_of_blocks_med; - uint8_t number_of_blocks_lo; - uint8_t reserved3; - uint8_t block_length_hi; - uint8_t block_length_med; - uint8_t block_length_lo; - } mh; - - uint8_t *p = &mh.block_length_med; - - if ( ! p_env ) return DRIVER_OP_UNINIT; - if ( ! run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED; - - memset (&mh, 0, sizeof (mh)); - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SENSE_6); - - cdb.field[1] = 0x3F&1; - cdb.field[4] = 12; - - i_status = run_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS, - mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, sizeof(mh), &mh); - if (DRIVER_OP_SUCCESS != i_status) return i_status; - - return CDIO_MMC_GET_LEN16(p); -} - /*! On input a MODE_SENSE command was issued and we have the results in p. We interpret this and return a bit mask set according to the @@ -204,97 +156,6 @@ mmc_get_drive_cap_buf(const uint8_t *p, *p_misc_cap |= CDIO_DRIVE_CAP_MISC_CLOSE_TRAY; } -/*! - Return the the kind of drive capabilities of device. - */ -void -mmc_get_drive_cap_private (void *p_env, - const mmc_run_cmd_fn_t run_mmc_cmd, - /*out*/ cdio_drive_read_cap_t *p_read_cap, - /*out*/ cdio_drive_write_cap_t *p_write_cap, - /*out*/ cdio_drive_misc_cap_t *p_misc_cap) -{ - /* Largest buffer size we use. */ -#define BUF_MAX 2048 - uint8_t buf[BUF_MAX] = { 0, }; - - scsi_mmc_cdb_t cdb = {{0, }}; - int i_status; - uint16_t i_data = BUF_MAX; - - if ( ! p_env || ! run_mmc_cmd ) - return; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SENSE_10); - cdb.field[1] = 0x0; - cdb.field[2] = CDIO_MMC_ALL_PAGES; - - retry: - CDIO_MMC_SET_READ_LENGTH16(cdb.field, 8); - - /* In the first run we run MODE SENSE 10 we are trying to get the - length of the data features. */ - i_status = run_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS, - mmc_get_cmd_len(cdb.field[0]), - &cdb, SCSI_MMC_DATA_READ, - sizeof(buf), &buf); - if (0 == i_status) { - uint16_t i_data_try = (uint16_t) CDIO_MMC_GET_LEN16(buf); - if (i_data_try < BUF_MAX) i_data = i_data_try; - } - - /* Now try getting all features with length set above, possibly - truncated or the default length if we couldn't get the proper - length. */ - CDIO_MMC_SET_READ_LENGTH16(cdb.field, i_data); - - i_status = run_mmc_cmd (p_env, DEFAULT_TIMEOUT_MS, - mmc_get_cmd_len(cdb.field[0]), - &cdb, SCSI_MMC_DATA_READ, - sizeof(buf), &buf); - - if (0 != i_status && CDIO_MMC_CAPABILITIES_PAGE != cdb.field[2]) { - cdb.field[2] = CDIO_MMC_CAPABILITIES_PAGE; - goto retry; - } - - if (0 == i_status) { - uint8_t *p; - uint8_t *p_max = buf + 256; - - *p_read_cap = 0; - *p_write_cap = 0; - *p_misc_cap = 0; - - /* set to first sense mask, and then walk through the masks */ - p = buf + 8; - while( (p < &(buf[2+i_data])) && (p < p_max) ) { - uint8_t which_page; - - which_page = p[0] & 0x3F; - switch( which_page ) - { - case CDIO_MMC_AUDIO_CTL_PAGE: - case CDIO_MMC_R_W_ERROR_PAGE: - case CDIO_MMC_CDR_PARMS_PAGE: - /* Don't handle these yet. */ - break; - case CDIO_MMC_CAPABILITIES_PAGE: - mmc_get_drive_cap_buf(p, p_read_cap, p_write_cap, p_misc_cap); - break; - default: ; - } - p += (p[1] + 2); - } - } else { - cdio_info("%s: %s\n", "error in MODE_SELECT", strerror(errno)); - *p_read_cap = CDIO_DRIVE_CAP_ERROR; - *p_write_cap = CDIO_DRIVE_CAP_ERROR; - *p_misc_cap = CDIO_DRIVE_CAP_ERROR; - } - return; -} - /*! Get the DVD type associated with cd object. */ @@ -388,6 +249,50 @@ mmc_get_mcn_private ( void *p_env, return NULL; } +int +mmc_mode_sense_6( const CdIo_t *p_cdio, void *p_buf, int i_size, int page) +{ + scsi_mmc_cdb_t cdb = {{0, }}; + + if ( ! p_cdio ) return DRIVER_OP_UNINIT; + if ( ! p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED; + + memset (p_buf, 0, i_size); + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SENSE_6); + + cdb.field[2] = 0x3F & page; + cdb.field[4] = i_size; + + 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, i_size, p_buf); +} + + +int +mmc_mode_sense_10( const CdIo_t *p_cdio, void *p_buf, int i_size, int page) +{ + scsi_mmc_cdb_t cdb = {{0, }}; + + if ( ! p_cdio ) return DRIVER_OP_UNINIT; + if ( ! p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED; + + memset (p_buf, 0, i_size); + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SENSE_10); + + cdb.field[2] = 0x3F & page; + CDIO_MMC_SET_READ_LENGTH16(cdb.field, i_size); + + 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, i_size, p_buf); +} + + /* Read cdtext information for a CdIo_t object . @@ -601,9 +506,69 @@ mmc_get_drive_cap (const CdIo_t *p_cdio, /*out*/ cdio_drive_misc_cap_t *p_misc_cap) { if ( ! p_cdio ) return; - mmc_get_drive_cap_private (p_cdio->env, - p_cdio->op.run_mmc_cmd, - p_read_cap, p_write_cap, p_misc_cap); + /* Largest buffer size we use. */ +#define BUF_MAX 2048 + uint8_t buf[BUF_MAX] = { 0, }; + + int i_status; + uint16_t i_data = BUF_MAX; + int page = CDIO_MMC_ALL_PAGES; + + retry: + + /* In the first run we run MODE SENSE 10 we are trying to get the + length of the data features. */ + i_status = mmc_mode_sense_10(p_cdio, buf, 8, CDIO_MMC_ALL_PAGES); + + if (DRIVER_OP_SUCCESS == i_status) { + uint16_t i_data_try = (uint16_t) CDIO_MMC_GET_LEN16(buf); + if (i_data_try < BUF_MAX) i_data = i_data_try; + } + + /* Now try getting all features with length set above, possibly + truncated or the default length if we couldn't get the proper + length. */ + i_status = mmc_mode_sense_10(p_cdio, buf, i_data, CDIO_MMC_ALL_PAGES); + if (0 != i_status && CDIO_MMC_CAPABILITIES_PAGE != page) { + page = CDIO_MMC_CAPABILITIES_PAGE; + goto retry; + } + + if (DRIVER_OP_SUCCESS == i_status) { + uint8_t *p; + uint8_t *p_max = buf + 256; + + *p_read_cap = 0; + *p_write_cap = 0; + *p_misc_cap = 0; + + /* set to first sense mask, and then walk through the masks */ + p = buf + 8; + while( (p < &(buf[2+i_data])) && (p < p_max) ) { + uint8_t which_page; + + which_page = p[0] & 0x3F; + switch( which_page ) + { + case CDIO_MMC_AUDIO_CTL_PAGE: + case CDIO_MMC_R_W_ERROR_PAGE: + case CDIO_MMC_CDR_PARMS_PAGE: + /* Don't handle these yet. */ + break; + case CDIO_MMC_CAPABILITIES_PAGE: + mmc_get_drive_cap_buf(p, p_read_cap, p_write_cap, p_misc_cap); + break; + default: ; + } + p += (p[1] + 2); + } + } else { + cdio_info("%s: %s\n", "error in MODE_SELECT", strerror(errno)); + *p_read_cap = CDIO_DRIVE_CAP_ERROR; + *p_write_cap = CDIO_DRIVE_CAP_ERROR; + *p_misc_cap = CDIO_DRIVE_CAP_ERROR; + } + return; } /*! @@ -725,9 +690,34 @@ mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms, int mmc_get_blocksize ( const CdIo_t *p_cdio) { - if ( ! p_cdio ) return DRIVER_OP_UNINIT; - return - mmc_get_blocksize_private (p_cdio->env, p_cdio->op.run_mmc_cmd); + int i_status; + + struct + { + uint8_t reserved1; + uint8_t medium; + uint8_t reserved2; + uint8_t block_desc_length; + uint8_t density; + uint8_t number_of_blocks_hi; + uint8_t number_of_blocks_med; + uint8_t number_of_blocks_lo; + uint8_t reserved3; + uint8_t block_length_hi; + uint8_t block_length_med; + uint8_t block_length_lo; + } mh; + + uint8_t *p = &mh.block_length_med; + + memset (&mh, 0, sizeof (mh)); + + i_status = mmc_mode_sense_6(p_cdio, &mh, sizeof(&mh), + CDIO_MMC_R_W_ERROR_PAGE); + + if (DRIVER_OP_SUCCESS != i_status) return i_status; + + return CDIO_MMC_GET_LEN16(p); } diff --git a/lib/driver/mmc_private.h b/lib/driver/mmc_private.h index b454af47..14c4ac47 100644 --- a/lib/driver/mmc_private.h +++ b/lib/driver/mmc_private.h @@ -1,6 +1,6 @@ /* private MMC helper routines. - $Id: mmc_private.h,v 1.3 2005/02/07 03:36:02 rocky Exp $ + $Id: mmc_private.h,v 1.4 2005/02/09 02:50:47 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -91,10 +91,6 @@ mmc_get_dvd_struct_physical_private ( void *p_env, cdio_dvd_struct_t *s ); -int -mmc_get_blocksize_private ( void *p_env, - mmc_run_cmd_fn_t run_mmc_cmd); - char *mmc_get_mcn_private ( void *p_env, mmc_run_cmd_fn_t run_mmc_cmd ); @@ -114,19 +110,6 @@ void mmc_get_drive_cap_buf(const uint8_t *p, /*out*/ cdio_drive_write_cap_t *p_write_cap, /*out*/ cdio_drive_misc_cap_t *p_misc_cap); -/*! - Return the the kind of drive capabilities of device. - - Note: string is malloc'd so caller should free() then returned - string when done with it. - - */ -void -mmc_get_drive_cap_private ( void *p_env, - const mmc_run_cmd_fn_t run_mmc_cmd, - /*out*/ cdio_drive_read_cap_t *p_read_cap, - /*out*/ cdio_drive_write_cap_t *p_write_cap, - /*out*/ cdio_drive_misc_cap_t *p_misc_cap); driver_return_code_t mmc_set_blocksize_private ( void *p_env, const mmc_run_cmd_fn_t run_mmc_cmd, diff --git a/test/check_fuzzyiso.sh b/test/check_fuzzyiso.sh index 90278cee..03ac7d86 100755 --- a/test/check_fuzzyiso.sh +++ b/test/check_fuzzyiso.sh @@ -1,11 +1,11 @@ #!/bin/sh -#$Id: check_fuzzyiso.sh,v 1.1 2005/02/08 04:38:05 rocky Exp $ +#$Id: check_fuzzyiso.sh,v 1.2 2005/02/09 02:50:47 rocky Exp $ if test -z $srcdir ; then srcdir=`pwd` fi -check_program="../example/iso4" +check_program="../example/isofuzzy" if test ! -x $check_program ; then exit 77