diff --git a/include/cdio/scsi_mmc.h b/include/cdio/scsi_mmc.h index 9ef904e9..f1f2862f 100644 --- a/include/cdio/scsi_mmc.h +++ b/include/cdio/scsi_mmc.h @@ -1,5 +1,5 @@ /* - $Id: scsi_mmc.h,v 1.38 2005/01/18 00:57:20 rocky Exp $ + $Id: scsi_mmc.h,v 1.39 2005/01/18 05:41:58 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -436,4 +436,16 @@ int scsi_mmc_set_blocksize ( const CdIo_t *p_cdio, unsigned int i_bsize); */ int scsi_mmc_get_blocksize ( const CdIo_t *p_cdio ); +/*! + Set the drive speed. + + @return -1 if we had an error. is -2 returned if this is not + implemented for the current driver. + + @see scsi_mmc_get_speed +*/ +int +scsi_mmc_set_speed( const CdIo_t *p_cdio, int i_speed ); + + #endif /* __SCSI_MMC_H__ */ diff --git a/lib/driver/MSWindows/win32.c b/lib/driver/MSWindows/win32.c index 71f23fb2..b2324020 100644 --- a/lib/driver/MSWindows/win32.c +++ b/lib/driver/MSWindows/win32.c @@ -1,5 +1,5 @@ /* - $Id: win32.c,v 1.5 2005/01/17 17:20:09 rocky Exp $ + $Id: win32.c,v 1.6 2005/01/18 05:41:58 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: win32.c,v 1.5 2005/01/17 17:20:09 rocky Exp $"; +static const char _rcsid[] = "$Id: win32.c,v 1.6 2005/01/18 05:41:58 rocky Exp $"; #include #include @@ -494,6 +494,20 @@ _get_arg_win32 (void *user_data, const char key[]) return NULL; } +static int +set_speed_win32 (void *p_user_data, int i_speed) { + const _img_private_t *p_env = p_user_data; + if (!p_env) return -1; + return scsi_mmc_set_speed( p_env->gen.cdio, i_speed ); +} + +static int +set_blocksize_win32 (void *p_user_data, int i_blocksize) { + const _img_private_t *p_env = p_user_data; + if (!p_env) return -1; + return scsi_mmc_set_blocksize( p_env->gen.cdio, i_blocksize ); +} + /*! Return the media catalog number MCN. @@ -759,6 +773,8 @@ cdio_open_am_win32 (const char *psz_orig_source, const char *psz_access_mode) _funcs.read_toc = &read_toc_win32; _funcs.run_scsi_mmc_cmd = &run_scsi_cmd_win32; _funcs.set_arg = set_arg_win32; + _funcs.set_blocksize = set_blocksize_win32; + _funcs.set_speed = set_speed_win32; _funcs.stat_size = stat_size_win32; _data = _cdio_malloc (sizeof (_img_private_t)); diff --git a/lib/driver/scsi_mmc.c b/lib/driver/scsi_mmc.c index 57840960..d043a7e6 100644 --- a/lib/driver/scsi_mmc.c +++ b/lib/driver/scsi_mmc.c @@ -1,6 +1,6 @@ /* Common SCSI Multimedia Command (MMC) routines. - $Id: scsi_mmc.c,v 1.4 2005/01/18 00:57:20 rocky Exp $ + $Id: scsi_mmc.c,v 1.5 2005/01/18 05:41:58 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -77,6 +77,37 @@ scsi_mmc_get_discmode( const CdIo_t *p_cdio ) return CDIO_DISC_MODE_NO_INFO; } +/*! + Set the drive speed. + + @return the drive speed if greater than 0. -1 if we had an error. is -2 + returned if this is not implemented for the current driver. + + @see scsi_mmc_set_speed +*/ +int +scsi_mmc_set_speed( const CdIo_t *p_cdio, int i_speed ) + +{ + uint8_t buf[14] = { 0, }; + scsi_mmc_cdb_t cdb; + + /* If the requested speed is less than 1x 176 kb/s this command + will return an error - it's part of the ATAPI specs. Therefore, + test and stop early. */ + + if ( i_speed < 1 ) return -1; + + memset(&cdb, 0, sizeof(scsi_mmc_cdb_t)); + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_SET_SPEED); + CDIO_MMC_SET_LEN16(cdb.field, 2, i_speed); + /* Some drives like the Creative 24x CDRW require one to set a nonzero + write speed. So we set to the maximum value. */ + CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff); + return scsi_mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ, + sizeof(buf), buf); +} + /*! 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