diff --git a/include/cdio++/mmc.hpp b/include/cdio++/mmc.hpp index 1e3ef320..04c08ba0 100644 --- a/include/cdio++/mmc.hpp +++ b/include/cdio++/mmc.hpp @@ -418,8 +418,8 @@ void mmcStartStopMedia(bool b_eject, bool b_immediate, uint8_t power_condition) { driver_return_code_t drc = - mmc_start_stop_unit(p_cdio, b_eject, b_immediate, power_condition); - possible_throw_device_exception(drc); + mmc_start_stop_unit(p_cdio, b_eject, b_immediate, power_condition, 0); + possible_throw_device_exception(drc); } diff --git a/include/cdio/mmc_cmds.h b/include/cdio/mmc_cmds.h index 55ae0303..d87983f7 100644 --- a/include/cdio/mmc_cmds.h +++ b/include/cdio/mmc_cmds.h @@ -65,7 +65,7 @@ extern "C" { @param page which "page" of the mode sense command we are interested in - @param i_timeout value in milliseconds to use on timeout. Setting + @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. @@ -73,7 +73,7 @@ extern "C" { */ 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); + unsigned int i_timeout_ms); /** Run a SCSI-MMC MODE_SENSE command (6- or 10-byte version) and put the results in p_buf @@ -266,20 +266,28 @@ extern "C" { @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); + 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); + 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 mmc_start_stop_unit +#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 diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am index 43e98b80..afa6a072 100644 --- a/lib/driver/Makefile.am +++ b/lib/driver/Makefile.am @@ -44,8 +44,10 @@ libcdio_la_CURRENT = 12 libcdio_la_REVISION = 0 libcdio_la_AGE = 0 -EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \ - libcdio.sym +EXTRA_DIST = image/Makefile \ + mmc/Makefile \ + FreeBSD/Makefile MSWindows/Makefile \ + libcdio.sym noinst_HEADERS = cdio_assert.h cdio_private.h portable.h @@ -79,9 +81,11 @@ libcdio_sources = \ image/nrg.c \ image/nrg.h \ logging.c \ - mmc.c \ - mmc_cmds.c \ - mmc_private.h \ + mmc/mmc.c \ + mmc/mmc_cmd_helper.h \ + mmc/mmc_ll_cmds.c \ + mmc/mmc_hl_cmds.c \ + mmc/mmc_private.h \ MSWindows/aspi32.c \ MSWindows/aspi32.h \ MSWindows/win32_ioctl.c \ diff --git a/lib/driver/cdio_private.h b/lib/driver/cdio_private.h index 165ca7b8..2b390dc8 100644 --- a/lib/driver/cdio_private.h +++ b/lib/driver/cdio_private.h @@ -30,7 +30,7 @@ #include #include #include -#include "mmc_private.h" +#include "mmc/mmc_private.h" #ifdef __cplusplus extern "C" { diff --git a/lib/driver/mmc/.gitignore b/lib/driver/mmc/.gitignore new file mode 100644 index 00000000..aeaec0f7 --- /dev/null +++ b/lib/driver/mmc/.gitignore @@ -0,0 +1 @@ +/*~ diff --git a/lib/driver/mmc/Makefile b/lib/driver/mmc/Makefile new file mode 100644 index 00000000..5ba761ce --- /dev/null +++ b/lib/driver/mmc/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile,v 1.2 2008/04/21 18:30:21 karl Exp $ +# +# Copyright (C) 2004, 2008 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 . +# +# The make is done above. This boilerplate Makefile just transfers the call + + +all install check clean: + cd .. && $(MAKE) $@ diff --git a/lib/driver/mmc.c b/lib/driver/mmc/mmc.c similarity index 99% rename from lib/driver/mmc.c rename to lib/driver/mmc/mmc.c index c0f08137..cd5b7b41 100644 --- a/lib/driver/mmc.c +++ b/lib/driver/mmc/mmc.c @@ -1053,9 +1053,9 @@ driver_return_code_t mmc_close_tray( CdIo_t *p_cdio ) { if (p_cdio) { - return mmc_start_stop_unit(p_cdio, false, false, 0); + return mmc_start_stop_unit(p_cdio, false, false, 0, 0); } else { - return DRIVER_OP_ERROR; + return DRIVER_OP_ERROR; } } @@ -1085,7 +1085,7 @@ mmc_eject_media( const CdIo_t *p_cdio ) SCSI_MMC_DATA_WRITE, 0, &buf); if (0 != i_status) return i_status; - return mmc_start_stop_unit(p_cdio, true, false, 0); + return mmc_start_stop_unit(p_cdio, true, false, 0, 0); } diff --git a/lib/driver/mmc/mmc_cmd_helper.h b/lib/driver/mmc/mmc_cmd_helper.h new file mode 100644 index 00000000..b8eb5ae2 --- /dev/null +++ b/lib/driver/mmc/mmc_cmd_helper.h @@ -0,0 +1,64 @@ +/* + 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 . +*/ + +#ifndef __CDIO_MMC_CMD_HELPER_H__ +#define __CDIO_MMC_CMD_HELPER_H__ + +/* Boilerplate initialization code to setup running MMC command. We + assume variables 'p_cdio', 'p_buf', and 'i_size' are previously + defined. It does the following: + + 1. Defines a cdb variable, + 2 Checks to see if we have a cdio object and can run an MMC command + 3. zeros the buffer (p_buf) using i_size. + 4. Sets up the command field of cdb to passed in value mmc_cmd. +*/ +#define MMC_CMD_SETUP(mmc_cmd) \ + 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, mmc_cmd) + +/* Boilerplate initialization code to setup running MMC read command + needs to set the cdb 16-bit length field. See above + comment for MMC_CMD_SETUP. +*/ +#define MMC_CMD_SETUP_READ16(mmc_cmd) \ + MMC_CMD_SETUP(mmc_cmd); \ + \ + /* Setup to read header, to get length of data */ \ + CDIO_MMC_SET_READ_LENGTH16(cdb.field, i_size) + +/* Boilerplate code to run a MMC command. + + We assume variables 'p_cdio', 'mmc_timeout_ms', 'cdb', 'i_size' and + 'p_buf' are defined previously. + + 'direction' is the SCSI direction (read, write, none) of the + command. +*/ +#define MMC_RUN_CMD(direction, i_timeout) \ + p_cdio->op.run_mmc_cmd(p_cdio->env, \ + i_timeout, \ + mmc_get_cmd_len(cdb.field[0]), \ + &cdb, \ + direction, i_size, p_buf) + +#endif /* __CDIO_MMC_CMD_HELPER_H__ */ diff --git a/lib/driver/mmc/mmc_hl_cmds.c b/lib/driver/mmc/mmc_hl_cmds.c new file mode 100644 index 00000000..375dad7c --- /dev/null +++ b/lib/driver/mmc/mmc_hl_cmds.c @@ -0,0 +1,22 @@ +/* + "Higher-level" Multimedia Command (MMC) commands which build on + the "lower-level" commands. + + 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 . +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif diff --git a/lib/driver/mmc_cmds.c b/lib/driver/mmc/mmc_ll_cmds.c similarity index 87% rename from lib/driver/mmc_cmds.c rename to lib/driver/mmc/mmc_ll_cmds.c index 4c9a66da..52c689d8 100644 --- a/lib/driver/mmc_cmds.c +++ b/lib/driver/mmc/mmc_ll_cmds.c @@ -25,55 +25,12 @@ #include #include #include "cdio_private.h" +#include "mmc_cmd_helper.h" #ifdef HAVE_STRING_H #include #endif -/* Boilerplate initialization code to setup running MMC command. We - assume variables 'p_cdio', 'p_buf', and 'i_size' are previously - defined. It does the following: - - 1. Defines a cdb variable, - 2 Checks to see if we have a cdio object and can run an MMC command - 3. zeros the buffer (p_buf) using i_size. - 4. Sets up the command field of cdb to passed in value mmc_cmd. -*/ -#define MMC_CMD_SETUP(mmc_cmd) \ - 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, mmc_cmd) - -/* Boilerplate initialization code to setup running MMC read command - needs to set the cdb 16-bit length field. See above - comment for MMC_CMD_SETUP. -*/ -#define MMC_CMD_SETUP_READ16(mmc_cmd) \ - MMC_CMD_SETUP(mmc_cmd); \ - \ - /* Setup to read header, to get length of data */ \ - CDIO_MMC_SET_READ_LENGTH16(cdb.field, i_size) - -/* Boilerplate code to run a MMC command. - - We assume variables 'p_cdio', 'mmc_timeout_ms', 'cdb', 'i_size' and - 'p_buf' are defined previously. - - 'direction' is the SCSI direction (read, write, none) of the - command. -*/ -#define MMC_RUN_CMD(direction, i_timeout) \ - p_cdio->op.run_mmc_cmd(p_cdio->env, \ - i_timeout, \ - mmc_get_cmd_len(cdb.field[0]), \ - &cdb, \ - direction, i_size, p_buf) - - /** Return results of media status @param p_cdio the CD object to be acted upon. @@ -113,7 +70,7 @@ mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]) @param page which "page" of the mode sense command we are interested in - @param i_timeout value in milliseconds to use on timeout. Setting + @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. @@ -122,12 +79,12 @@ mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]) */ 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) + int page, unsigned int i_timeout_ms) { - if (0 == i_timeout) i_timeout = mmc_timeout_ms; MMC_CMD_SETUP_READ16(CDIO_MMC_GPCMD_MODE_SELECT_10); + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; cdb.field[1] = page; - return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout); + return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms); } /** @@ -411,7 +368,7 @@ mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed) */ driver_return_code_t mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, bool b_immediate, - uint8_t power_condition) + uint8_t power_condition, unsigned int i_timeout_ms) { uint8_t buf[1]; void * p_buf = &buf; @@ -441,10 +398,11 @@ mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, bool b_immediate, @return DRIVER_OP_SUCCESS if we ran the command ok. */ driver_return_code_t -mmc_test_unit_ready(const CdIo_t *p_cdio) +mmc_test_unit_ready(const CdIo_t *p_cdio, unsigned int i_timeout_ms) { const unsigned int i_size = 0; void * p_buf = NULL; + if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; MMC_CMD_SETUP_READ16(CDIO_MMC_GPCMD_TEST_UNIT_READY); - return MMC_RUN_CMD(SCSI_MMC_DATA_NONE, mmc_timeout_ms); + return MMC_RUN_CMD(SCSI_MMC_DATA_NONE, i_timeout_ms); } diff --git a/lib/driver/mmc_private.h b/lib/driver/mmc/mmc_private.h similarity index 100% rename from lib/driver/mmc_private.h rename to lib/driver/mmc/mmc_private.h diff --git a/src/mmc-tool.c b/src/mmc-tool.c index 427e35e4..d76fc8d9 100644 --- a/src/mmc-tool.c +++ b/src/mmc-tool.c @@ -488,7 +488,7 @@ main(int argc, char *argv[]) if (p_op->arg.psz) free(p_op->arg.psz); break; case OP_IDLE: - rc = mmc_start_stop_unit(p_cdio, false, false, true); + rc = mmc_start_stop_unit(p_cdio, false, false, true, 0); report(stdout, "%s (mmc_start_stop_media - powerdown): %s\n", program_name, cdio_driver_errmsg(rc)); break; diff --git a/test/driver/mmc.c b/test/driver/mmc.c index e72acfee..63710dae 100644 --- a/test/driver/mmc.c +++ b/test/driver/mmc.c @@ -151,7 +151,7 @@ tmmc_test_unit_ready(CdIo_t *p_cdio, if (flag & 1) fprintf(stderr, "tmmc_test_unit_ready ... "); - i_status = mmc_test_unit_ready(p_cdio); + i_status = mmc_test_unit_ready(p_cdio, 0); return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply, flag & 1); @@ -172,7 +172,7 @@ tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail, bool b_eject = !!(flag & 4); bool b_immediate = !!(flag & 2); - i_status = mmc_start_stop_unit(p_cdio, b_eject, b_immediate, 0); + i_status = mmc_start_stop_unit(p_cdio, b_eject, b_immediate, 0, 0); if (flag & 1) fprintf(stderr, "tmmc_load_eject(0x%X) ... ", (unsigned int) flag);