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,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);
}

View File

@@ -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

View File

@@ -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 \

View File

@@ -30,7 +30,7 @@
#include <cdio/cdio.h>
#include <cdio/audio.h>
#include <cdio/cdtext.h>
#include "mmc_private.h"
#include "mmc/mmc_private.h"
#ifdef __cplusplus
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,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);
}

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/mmc_cmds.h>
#include "cdio_private.h"
#include "mmc_cmd_helper.h"
#ifdef HAVE_STRING_H
#include <string.h>
#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);
}

View File

@@ -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;

View File

@@ -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);