From 20e8974df8da997761769f1a4a9059e135d07e83 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 26 Jul 2004 02:54:37 +0000 Subject: [PATCH] Big change! We now are starting to have universal MMC routines. To do this we need to have function pointers to the OS-specific MMC send/run command. Expect some breakage. Down the line though this will increase code reuse, reliabilty, and make the library more user-customizable. --- include/cdio/scsi_mmc.h | 16 ++++- lib/Makefile.am | 3 +- lib/_cdio_linux.c | 126 ++++----------------------------------- lib/cdio.c | 23 ++++---- lib/cdio_private.h | 26 ++++---- lib/image/bincue.c | 6 +- lib/image/cdrdao.c | 6 +- lib/image/nrg.c | 6 +- lib/scsi_mmc.c | 128 +++++++++++++++++++++++++++++++++++++++- lib/scsi_mmc_private.h | 30 ++++++++++ 10 files changed, 220 insertions(+), 150 deletions(-) create mode 100644 lib/scsi_mmc_private.h diff --git a/include/cdio/scsi_mmc.h b/include/cdio/scsi_mmc.h index 1ea7e72c..773295a8 100644 --- a/include/cdio/scsi_mmc.h +++ b/include/cdio/scsi_mmc.h @@ -1,5 +1,5 @@ /* - $Id: scsi_mmc.h,v 1.15 2004/07/25 16:38:05 rocky Exp $ + $Id: scsi_mmc.h,v 1.16 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -195,4 +195,18 @@ void scsi_mmc_get_drive_cap(const uint8_t *p, /*out*/ cdio_drive_write_cap_t *p_write_cap, /*out*/ cdio_drive_misc_cap_t *p_misc_cap); +/*! + * Eject using SCSI MMC commands. Return 0 if successful. + */ +int scsi_mmc_eject_media( const CdIo *cdio); + +/*! Packet driver to read mode2 sectors. + Can read only up to 25 blocks. +*/ +int scsi_mmc_read_sectors ( const CdIo *cdio, void *p_buf, lba_t lba, + int sector_type, unsigned int nblocks); + +int scsi_mmc_set_bsize ( const CdIo *cdio, unsigned int bsize); + + #endif /* __SCSI_MMC_H__ */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 5b1742d6..9d106c3e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.42 2004/07/10 02:17:58 rocky Exp $ +# $Id: Makefile.am,v 1.43 2004/07/26 02:54:37 rocky Exp $ # # Copyright (C) 2003, 2004 Rocky Bernstein # @@ -89,6 +89,7 @@ libcdio_sources = \ MSWindows/win32.h \ sector.c \ scsi_mmc.c \ + scsi_mmc_private.h \ util.c lib_LTLIBRARIES = libcdio.la libiso9660.la diff --git a/lib/_cdio_linux.c b/lib/_cdio_linux.c index 831a1e60..3e363c98 100644 --- a/lib/_cdio_linux.c +++ b/lib/_cdio_linux.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_linux.c,v 1.80 2004/07/25 18:37:09 rocky Exp $ + $Id: _cdio_linux.c,v 1.81 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.80 2004/07/25 18:37:09 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.81 2004/07/26 02:54:37 rocky Exp $"; #include @@ -118,7 +118,6 @@ static int scsi_mmc_run_cmd_linux( const void *p_user_data, int i_timeout, scsi_mmc_direction_t e_direction, unsigned int i_buf, /*in/out*/ void *p_buf ); -static int set_bsize (_img_private_t *p_env, unsigned int bsize); static access_mode_t str_to_access_mode_linux(const char *psz_access_mode) @@ -431,47 +430,6 @@ _get_track_msf_linux(void *p_user_data, track_t i_track, msf_t *msf) } } -/*! - * Eject using SCSI MMC commands. Return 0 if successful. - */ -static int -eject_media_mmc(_img_private_t *p_env) -{ - int i_status; - scsi_mmc_cdb_t cdb = {{0, }}; - uint8_t buf[1]; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL); - - i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) - return i_status; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); - cdb.field[4] = 1; - i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) - return i_status; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); - cdb.field[4] = 2; /* eject */ - - i_status = scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) - return i_status; - - /* force kernel to reread partition table when new disc inserted */ - i_status = ioctl(p_env->gen.fd, BLKRRPART); - return (i_status); - -} - /*! Eject media in CD drive. Return 0 if success and 1 for failure, and 2 if no routine. @@ -497,13 +455,15 @@ eject_media_linux (void *p_user_data) { if((ret = ioctl(fd, CDROMEJECT)) != 0) { int eject_error = errno; /* Try ejecting the MMC way... */ - ret = eject_media_mmc(p_env); + ret = scsi_mmc_eject_media(p_env->gen.cdio); if (0 != ret) { cdio_warn("ioctl CDROMEJECT failed: %s\n", strerror(eject_error)); ret = 1; } } + /* force kernel to reread partition table when new disc inserted */ + ret = ioctl(p_env->gen.fd, BLKRRPART); break; default: cdio_warn ("Unknown CD-ROM (%d)\n", status); @@ -602,29 +562,6 @@ is_cdrom_linux(const char *drive, char *mnttype) return(is_cd); } -/* Packet driver to read mode2 sectors. - Can read only up to 25 blocks. -*/ -static int -_read_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, - int sector_type, unsigned int nblocks) -{ - scsi_mmc_cdb_t cdb = {{0, }}; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); - CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type); - CDIO_MMC_SET_READ_LBA (cdb.field, lba); - CDIO_MMC_SET_READ_LENGTH(cdb.field, nblocks); - CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field, - CDIO_MMC_MCSB_ALL_HEADERS); - - return scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_READ, - CDIO_CD_FRAMESIZE_RAW * nblocks, - p_buf); -} - /* MMC driver to read audio sectors. Can read only up to 25 blocks. */ @@ -633,8 +570,8 @@ _read_audio_sectors_linux (void *p_user_data, void *buf, lsn_t lsn, unsigned int nblocks) { _img_private_t *p_env = p_user_data; - return _read_sectors_mmc( p_env, buf, lsn, - CDIO_MMC_READ_TYPE_CDDA, nblocks); + return scsi_mmc_read_sectors( p_env->gen.cdio, buf, lsn, + CDIO_MMC_READ_TYPE_CDDA, nblocks); } /* Packet driver to read mode2 sectors. @@ -660,7 +597,7 @@ _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, if (b_read_10) { int retval; - if ((retval = set_bsize (p_env, M2RAW_SECTOR_SIZE))) + if ((retval = scsi_mmc_set_bsize (p_env->gen.cdio, M2RAW_SECTOR_SIZE))) return retval; if ((retval = scsi_mmc_run_cmd_linux (p_env, 0, @@ -670,11 +607,11 @@ _read_mode2_sectors_mmc (_img_private_t *p_env, void *p_buf, lba_t lba, M2RAW_SECTOR_SIZE * nblocks, p_buf))) { - set_bsize (p_env, CDIO_CD_FRAMESIZE); + scsi_mmc_set_bsize (p_env->gen.cdio, CDIO_CD_FRAMESIZE); return retval; } - if ((retval = set_bsize (p_env, CDIO_CD_FRAMESIZE))) + if ((retval = scsi_mmc_set_bsize (p_env->gen.cdio, CDIO_CD_FRAMESIZE))) return retval; } else return scsi_mmc_run_cmd_linux (p_env, 0, @@ -991,43 +928,6 @@ scsi_mmc_run_cmd_linux( const void *p_user_data, int i_timeout, return ioctl (p_env->gen.fd, CDROM_SEND_PACKET, &cgc); } -static int -set_bsize (_img_private_t *p_env, unsigned int bsize) -{ - 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; - - memset (&mh, 0, sizeof (mh)); - mh.block_desc_length = 0x08; - mh.block_length_hi = (bsize >> 16) & 0xff; - mh.block_length_med = (bsize >> 8) & 0xff; - mh.block_length_lo = (bsize >> 0) & 0xff; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6); - - cdb.field[1] = 1 << 4; - cdb.field[4] = 12; - - return scsi_mmc_run_cmd_linux (p_env, DEFAULT_TIMEOUT, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, sizeof(mh), &mh); -} - /*! Return the size of the CD in logical block address (LBA) units. */ @@ -1362,12 +1262,12 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode) } } - ret = cdio_new (_data, &_funcs); + ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) return NULL; - if (cdio_generic_init(_data)) + if (cdio_generic_init(_data)) { return ret; - else { + } else { cdio_generic_free (_data); return NULL; } diff --git a/lib/cdio.c b/lib/cdio.c index 31a31cb3..1e080c54 100644 --- a/lib/cdio.c +++ b/lib/cdio.c @@ -1,5 +1,5 @@ /* - $Id: cdio.c,v 1.65 2004/07/21 11:28:32 rocky Exp $ + $Id: cdio.c,v 1.66 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -39,7 +39,7 @@ #include #include "cdio_private.h" -static const char _rcsid[] = "$Id: cdio.c,v 1.65 2004/07/21 11:28:32 rocky Exp $"; +static const char _rcsid[] = "$Id: cdio.c,v 1.66 2004/07/26 02:54:37 rocky Exp $"; const char *track_format2str[6] = @@ -721,16 +721,19 @@ cdio_init(void) } CdIo * -cdio_new (void *env, const cdio_funcs *funcs) +cdio_new (generic_img_private_t *p_env, cdio_funcs *p_funcs) { - CdIo *new_cdio; + CdIo *p_new_cdio = _cdio_malloc (sizeof (CdIo)); - new_cdio = _cdio_malloc (sizeof (CdIo)); - - new_cdio->env = env; - new_cdio->op = *funcs; - - return new_cdio; + if (NULL == p_new_cdio) return NULL; + + p_new_cdio->env = p_env; /* This is the private "environment" that + driver-dependent routines use. */ + p_new_cdio->op = *p_funcs; + p_env->cdio = p_new_cdio; /* A way for the driver-dependent routines + to access the higher-level general cdio + object. */ + return p_new_cdio; } /*! diff --git a/lib/cdio_private.h b/lib/cdio_private.h index f0858b01..58c84cd2 100644 --- a/lib/cdio_private.h +++ b/lib/cdio_private.h @@ -1,5 +1,5 @@ /* - $Id: cdio_private.h,v 1.33 2004/07/22 11:00:59 rocky Exp $ + $Id: cdio_private.h,v 1.34 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -30,7 +30,7 @@ #include #include -#include +#include "scsi_mmc_private.h" #ifdef __cplusplus extern "C" { @@ -216,11 +216,7 @@ extern "C" { Returns 0 if command completed successfully. */ - int (*run_scsi_mmc_cmd) ( const void *env, int i_timeout, - unsigned int cdb_len, - const scsi_mmc_cdb_t *p_cdb, - scsi_mmc_direction_t e_direction, - unsigned int len, /*in/out*/ void *p_buf ); + scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd; /*! Set the arg "key" with "value" in the source device. @@ -231,6 +227,9 @@ extern "C" { Return the size of the CD in logical block address (LBA) units. */ uint32_t (*stat_size) (void *env); + + /*! Pointer to parent container object. */ + CdIo *cdio; } cdio_funcs; @@ -249,16 +248,17 @@ extern "C" { code. */ typedef struct { - char *source_name; /* Name used in open. */ - bool init; /* True if structure has been initialized */ - bool toc_init; /* True TOC read in */ - int ioctls_debugged; /* for debugging */ + char *source_name; /**< Name used in open. */ + bool init; /**< True if structure has been initialized */ + bool toc_init; /**< True TOC read in */ + int ioctls_debugged; /**< for debugging */ /* Only one of the below is used. The first is for CD-ROM devices and the second for stream reading (bincue, nrg, toc, network). */ - int fd; /* File descriptor of device */ + int fd; /**< File descriptor of device */ CdioDataSource *data_source; + CdIo *cdio; /**< a way to call general cdio routines. */ } generic_img_private_t; /* This is used in drivers that must keep their own internal @@ -272,7 +272,7 @@ extern "C" { lba_t lba; /* Current LBA */ } internal_position_t; - CdIo * cdio_new (void *env, const cdio_funcs *funcs); + CdIo * cdio_new (generic_img_private_t *p_env, cdio_funcs *funcs); /* The below structure describes a specific CD Input driver */ typedef struct diff --git a/lib/image/bincue.c b/lib/image/bincue.c index 2381e6ce..fb8be569 100644 --- a/lib/image/bincue.c +++ b/lib/image/bincue.c @@ -1,5 +1,5 @@ /* - $Id: bincue.c,v 1.37 2004/07/25 18:37:09 rocky Exp $ + $Id: bincue.c,v 1.38 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2002, 2003, 2004 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -26,7 +26,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: bincue.c,v 1.37 2004/07/25 18:37:09 rocky Exp $"; +static const char _rcsid[] = "$Id: bincue.c,v 1.38 2004/07/26 02:54:37 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -1167,7 +1167,7 @@ cdio_open_cue (const char *psz_cue_name) _data->gen.init = false; _data->psz_cue_name = NULL; - ret = cdio_new (_data, &_funcs); + ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) { free(_data); diff --git a/lib/image/cdrdao.c b/lib/image/cdrdao.c index 2b6d9d86..27a7483e 100644 --- a/lib/image/cdrdao.c +++ b/lib/image/cdrdao.c @@ -1,5 +1,5 @@ /* - $Id: cdrdao.c,v 1.22 2004/07/25 18:37:09 rocky Exp $ + $Id: cdrdao.c,v 1.23 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2004 Rocky Bernstein toc reading routine adapted from cuetools @@ -25,7 +25,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: cdrdao.c,v 1.22 2004/07/25 18:37:09 rocky Exp $"; +static const char _rcsid[] = "$Id: cdrdao.c,v 1.23 2004/07/26 02:54:37 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -1149,7 +1149,7 @@ cdio_open_cdrdao (const char *psz_cue_name) _data->gen.data_source = NULL; _data->gen.source_name = NULL; - ret = cdio_new (_data, &_funcs); + ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) { free(_data); diff --git a/lib/image/nrg.c b/lib/image/nrg.c index dbf79fc2..abfe7879 100644 --- a/lib/image/nrg.c +++ b/lib/image/nrg.c @@ -1,5 +1,5 @@ /* - $Id: nrg.c,v 1.34 2004/07/25 18:37:09 rocky Exp $ + $Id: nrg.c,v 1.35 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein Copyright (C) 2001, 2003 Herbert Valerio Riedel @@ -45,7 +45,7 @@ #include "_cdio_stdio.h" #include "nrg.h" -static const char _rcsid[] = "$Id: nrg.c,v 1.34 2004/07/25 18:37:09 rocky Exp $"; +static const char _rcsid[] = "$Id: nrg.c,v 1.35 2004/07/26 02:54:37 rocky Exp $"; /* reader */ @@ -1220,7 +1220,7 @@ cdio_open_nrg (const char *psz_source) _data->is_dao = false; _data->is_cues = false; /* FIXME: remove is_cues. */ - ret = cdio_new (_data, &_funcs); + ret = cdio_new ((void *)_data, &_funcs); if (ret == NULL) { free(_data); diff --git a/lib/scsi_mmc.c b/lib/scsi_mmc.c index 292b5550..dabcf81d 100644 --- a/lib/scsi_mmc.c +++ b/lib/scsi_mmc.c @@ -1,6 +1,6 @@ -/* Common MMC routines. +/* Common SCSI Multimedia Command (MMC) routines. - $Id: scsi_mmc.c,v 1.7 2004/07/22 09:52:17 rocky Exp $ + $Id: scsi_mmc.c,v 1.8 2004/07/26 02:54:37 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -27,6 +27,10 @@ #include #include "cdio_private.h" +#ifdef HAVE_STRING_H +#include +#endif + /*! 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 @@ -89,7 +93,8 @@ scsi_mmc_get_cmd_len(uint8_t scsi_cmd) We return 0 if command completed successfully and 1 if not. */ int -scsi_mmc_run_cmd( const CdIo *cdio, int i_timeout, const scsi_mmc_cdb_t *p_cdb, +scsi_mmc_run_cmd( const CdIo *cdio, int i_timeout, + const scsi_mmc_cdb_t *p_cdb, scsi_mmc_direction_t e_direction, unsigned int i_buf, /*in/out*/ void *p_buf ) { @@ -100,3 +105,120 @@ scsi_mmc_run_cmd( const CdIo *cdio, int i_timeout, const scsi_mmc_cdb_t *p_cdb, } else return 1; } + +#define DEFAULT_TIMEOUT_MS 6000 + +/*! + * Eject using SCSI MMC commands. Return 0 if successful. + */ +int +scsi_mmc_eject_media( const CdIo *cdio ) +{ + int i_status; + scsi_mmc_cdb_t cdb = {{0, }}; + uint8_t buf[1]; + scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd; + + if ( ! cdio || ! cdio->op.run_scsi_mmc_cmd ) + return -2; + + run_scsi_mmc_cmd = cdio->op.run_scsi_mmc_cmd; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL); + + i_status = run_scsi_mmc_cmd (cdio->env, DEFAULT_TIMEOUT_MS, + scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_WRITE, 0, &buf); + if (0 != i_status) + return i_status; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); + cdb.field[4] = 1; + i_status = run_scsi_mmc_cmd (cdio->env, DEFAULT_TIMEOUT_MS, + scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_WRITE, 0, &buf); + if (0 != i_status) + return i_status; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); + cdb.field[4] = 2; /* eject */ + + return run_scsi_mmc_cmd (cdio->env, DEFAULT_TIMEOUT_MS, + scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_WRITE, 0, &buf); + +} + +/*! Packet driver to read mode2 sectors. + Can read only up to 25 blocks. +*/ +int +scsi_mmc_read_sectors ( const CdIo *cdio, void *p_buf, lba_t lba, + int sector_type, unsigned int nblocks ) +{ + scsi_mmc_cdb_t cdb = {{0, }}; + + scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd; + + if ( ! cdio || ! cdio->op.run_scsi_mmc_cmd ) + return -2; + + run_scsi_mmc_cmd = cdio->op.run_scsi_mmc_cmd; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); + CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type); + CDIO_MMC_SET_READ_LBA (cdb.field, lba); + CDIO_MMC_SET_READ_LENGTH(cdb.field, nblocks); + CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field, + CDIO_MMC_MCSB_ALL_HEADERS); + + return run_scsi_mmc_cmd (cdio->env, DEFAULT_TIMEOUT_MS, + scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_READ, + CDIO_CD_FRAMESIZE_RAW * nblocks, + p_buf); +} + +int +scsi_mmc_set_bsize ( const CdIo *cdio, unsigned int bsize) +{ + 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; + + scsi_mmc_run_cmd_fn_t run_scsi_mmc_cmd; + + if ( ! cdio || ! cdio->op.run_scsi_mmc_cmd ) + return -2; + + run_scsi_mmc_cmd = cdio->op.run_scsi_mmc_cmd; + + memset (&mh, 0, sizeof (mh)); + mh.block_desc_length = 0x08; + mh.block_length_hi = (bsize >> 16) & 0xff; + mh.block_length_med = (bsize >> 8) & 0xff; + mh.block_length_lo = (bsize >> 0) & 0xff; + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6); + + cdb.field[1] = 1 << 4; + cdb.field[4] = 12; + + return run_scsi_mmc_cmd (cdio->env, DEFAULT_TIMEOUT_MS, + scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, + SCSI_MMC_DATA_WRITE, sizeof(mh), &mh); +} diff --git a/lib/scsi_mmc_private.h b/lib/scsi_mmc_private.h new file mode 100644 index 00000000..6fba5131 --- /dev/null +++ b/lib/scsi_mmc_private.h @@ -0,0 +1,30 @@ +/* private MMC helper routines. + + $Id: scsi_mmc_private.h,v 1.1 2004/07/26 02:54:37 rocky Exp $ + + Copyright (C) 2004 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +typedef +int (*scsi_mmc_run_cmd_fn_t) ( const void *p_user_data, int i_timeout, + unsigned int i_cdb, + const scsi_mmc_cdb_t *p_cdb, + scsi_mmc_direction_t e_direction, + unsigned int i_buf, /*in/out*/ void *p_buf ); +