Move more towards making MMC a library. Start to reorganize more to

break out 1-1 SCSI-MMC commands (in mmc_ll_cmds.c) from higher-level
commands which use the lower-level ones.
This commit is contained in:
R. Bernstein
2010-02-07 18:35:47 -05:00
parent bf7d63b435
commit d3a0ba06e1
13 changed files with 149 additions and 70 deletions

View File

@@ -418,7 +418,7 @@ void mmcStartStopMedia(bool b_eject, bool b_immediate,
uint8_t power_condition) uint8_t power_condition)
{ {
driver_return_code_t drc = driver_return_code_t drc =
mmc_start_stop_unit(p_cdio, b_eject, b_immediate, power_condition); mmc_start_stop_unit(p_cdio, b_eject, b_immediate, power_condition, 0);
possible_throw_device_exception(drc); possible_throw_device_exception(drc);
} }

View File

@@ -65,7 +65,7 @@ extern "C" {
@param page which "page" of the mode sense command we are interested in @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 to 0 uses the default time-out value stored in
mmc_timeout_ms. 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, 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_size, int page,
unsigned int i_timeout); unsigned int i_timeout_ms);
/** /**
Run a SCSI-MMC MODE_SENSE command (6- or 10-byte version) Run a SCSI-MMC MODE_SENSE command (6- or 10-byte version)
and put the results in p_buf and put the results in p_buf
@@ -266,20 +266,28 @@ extern "C" {
@see mmc_eject_media or mmc_close_tray @see mmc_eject_media or mmc_close_tray
*/ */
driver_return_code_t mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, 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. Check if drive is ready using SCSI-MMC TEST UNIT READY command.
@param p_cdio the CD object to be acted upon. @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. @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 #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*/ #endif /*DO_NOT_WANT_PARANOIA_COMPATIBILITY*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -44,7 +44,9 @@ libcdio_la_CURRENT = 12
libcdio_la_REVISION = 0 libcdio_la_REVISION = 0
libcdio_la_AGE = 0 libcdio_la_AGE = 0
EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \ EXTRA_DIST = image/Makefile \
mmc/Makefile \
FreeBSD/Makefile MSWindows/Makefile \
libcdio.sym libcdio.sym
noinst_HEADERS = cdio_assert.h cdio_private.h portable.h noinst_HEADERS = cdio_assert.h cdio_private.h portable.h
@@ -79,9 +81,11 @@ libcdio_sources = \
image/nrg.c \ image/nrg.c \
image/nrg.h \ image/nrg.h \
logging.c \ logging.c \
mmc.c \ mmc/mmc.c \
mmc_cmds.c \ mmc/mmc_cmd_helper.h \
mmc_private.h \ mmc/mmc_ll_cmds.c \
mmc/mmc_hl_cmds.c \
mmc/mmc_private.h \
MSWindows/aspi32.c \ MSWindows/aspi32.c \
MSWindows/aspi32.h \ MSWindows/aspi32.h \
MSWindows/win32_ioctl.c \ MSWindows/win32_ioctl.c \

View File

@@ -30,7 +30,7 @@
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/audio.h> #include <cdio/audio.h>
#include <cdio/cdtext.h> #include <cdio/cdtext.h>
#include "mmc_private.h" #include "mmc/mmc_private.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

1
lib/driver/mmc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*~

22
lib/driver/mmc/Makefile Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
#
# The make is done above. This boilerplate Makefile just transfers the call
all install check clean:
cd .. && $(MAKE) $@

View File

@@ -1053,7 +1053,7 @@ driver_return_code_t
mmc_close_tray( CdIo_t *p_cdio ) mmc_close_tray( CdIo_t *p_cdio )
{ {
if (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 { } 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); SCSI_MMC_DATA_WRITE, 0, &buf);
if (0 != i_status) return i_status; 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);
} }

View File

@@ -0,0 +1,64 @@
/*
Copyright (C) 2010 Rocky Bernstein <rocky@gnu.org>
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 <http://www.gnu.org/licenses/>.
*/
#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__ */

View File

@@ -0,0 +1,22 @@
/*
"Higher-level" Multimedia Command (MMC) commands which build on
the "lower-level" commands.
Copyright (C) 2010 Rocky Bernstein <rocky@gnu.org>
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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

View File

@@ -25,55 +25,12 @@
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/mmc_cmds.h> #include <cdio/mmc_cmds.h>
#include "cdio_private.h" #include "cdio_private.h"
#include "mmc_cmd_helper.h"
#ifdef HAVE_STRING_H #ifdef HAVE_STRING_H
#include <string.h> #include <string.h>
#endif #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 Return results of media status
@param p_cdio the CD object to be acted upon. @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 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 to 0 uses the default time-out value stored in
mmc_timeout_ms. 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 driver_return_code_t
mmc_mode_select_10(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size, 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); 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; 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 driver_return_code_t
mmc_start_stop_unit(const CdIo_t *p_cdio, bool b_eject, bool b_immediate, 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]; uint8_t buf[1];
void * p_buf = &buf; 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. @return DRIVER_OP_SUCCESS if we ran the command ok.
*/ */
driver_return_code_t 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; const unsigned int i_size = 0;
void * p_buf = NULL; 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); 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);
} }

View File

@@ -488,7 +488,7 @@ main(int argc, char *argv[])
if (p_op->arg.psz) free(p_op->arg.psz); if (p_op->arg.psz) free(p_op->arg.psz);
break; break;
case OP_IDLE: 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", report(stdout, "%s (mmc_start_stop_media - powerdown): %s\n",
program_name, cdio_driver_errmsg(rc)); program_name, cdio_driver_errmsg(rc));
break; break;

View File

@@ -151,7 +151,7 @@ tmmc_test_unit_ready(CdIo_t *p_cdio,
if (flag & 1) if (flag & 1)
fprintf(stderr, "tmmc_test_unit_ready ... "); 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, return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply,
flag & 1); flag & 1);
@@ -172,7 +172,7 @@ tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
bool b_eject = !!(flag & 4); bool b_eject = !!(flag & 4);
bool b_immediate = !!(flag & 2); 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) if (flag & 1)
fprintf(stderr, "tmmc_load_eject(0x%X) ... ", (unsigned int) flag); fprintf(stderr, "tmmc_load_eject(0x%X) ... ", (unsigned int) flag);