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:
@@ -418,8 +418,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ 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 \
|
||||||
libcdio.sym
|
mmc/Makefile \
|
||||||
|
FreeBSD/Makefile MSWindows/Makefile \
|
||||||
|
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 \
|
||||||
|
|||||||
@@ -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
1
lib/driver/mmc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/*~
|
||||||
22
lib/driver/mmc/Makefile
Normal file
22
lib/driver/mmc/Makefile
Normal 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) $@
|
||||||
@@ -1053,9 +1053,9 @@ 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
64
lib/driver/mmc/mmc_cmd_helper.h
Normal file
64
lib/driver/mmc/mmc_cmd_helper.h
Normal 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__ */
|
||||||
22
lib/driver/mmc/mmc_hl_cmds.c
Normal file
22
lib/driver/mmc/mmc_hl_cmds.c
Normal 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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user