From c1f11393acb06f3b66e725727810b4cd1275c1f9 Mon Sep 17 00:00:00 2001 From: rocky Date: Wed, 11 Oct 2006 12:38:17 +0000 Subject: [PATCH] Add routine to get tray status (open/closed) and sample program. Seems broken at least on SuSE 10.1 if not other GNU/Linux's though. --- example/.cvsignore | 1 + example/Makefile.am | 7 ++- example/mmc3.c | 131 +++++++++++++++++++++++++++++++++++++++ include/cdio/mmc.h | 18 +++++- lib/driver/Makefile.am | 4 +- lib/driver/libcdio.sym | 1 + lib/driver/mmc.c | 53 ++++++++++++++-- lib/driver/mmc_private.h | 6 +- lib/iso9660/Makefile.am | 4 +- 9 files changed, 211 insertions(+), 14 deletions(-) create mode 100644 example/mmc3.c diff --git a/example/.cvsignore b/example/.cvsignore index 1bac1ddd..f9918b2d 100644 --- a/example/.cvsignore +++ b/example/.cvsignore @@ -17,6 +17,7 @@ isofuzzy mmc1 mmc2 mmc2a +mmc3 paranoia paranoia2 sample? diff --git a/example/Makefile.am b/example/Makefile.am index d73f9322..87635bd5 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.37 2006/04/17 03:37:58 rocky Exp $ +# $Id: Makefile.am,v 1.38 2006/10/11 12:38:18 rocky Exp $ # # Copyright (C) 2003, 2004, 2005, 2006 # Rocky Bernstein @@ -29,7 +29,7 @@ paranoia_progs = paranoia paranoia2 endif noinst_PROGRAMS = audio cdchange cdtext device drives eject \ isofile isofile2 isofuzzy isolist \ - mmc1 mmc2 mmc2a $(paranoia_progs) tracks \ + mmc1 mmc2 mmc2a mmc3 $(paranoia_progs) tracks \ sample3 sample4 udf1 udffile INCLUDES = -I$(top_srcdir) $(LIBCDIO_CFLAGS) @@ -70,6 +70,9 @@ mmc2_LDADD = $(LIBCDIO_LIBS) mmc2a_DEPENDENCIES = $(LIBCDIO_DEPS) mmc2a_LDADD = $(LIBCDIO_LIBS) +mmc3_DEPENDENCIES = $(LIBCDIO_DEPS) +mmc3_LDADD = $(LIBCDIO_LIBS) + sample3_DEPENDENCIES = $(LIBCDIO_DEPS) sample3_LDADD = $(LIBCDIO_LIBS) diff --git a/example/mmc3.c b/example/mmc3.c new file mode 100644 index 00000000..898f7cea --- /dev/null +++ b/example/mmc3.c @@ -0,0 +1,131 @@ +/* + $Id: mmc3.c,v 1.1 2006/10/11 12:38:18 rocky Exp $ + + Copyright (C) 2006 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 +*/ + +/* Simple program to show use of SCSI MMC interface. Is basically the + the libdio scsi_mmc_get_hwinfo() routine. +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include + +/* Set how long to wait for MMC commands to complete */ +#define DEFAULT_TIMEOUT_MS 10000 + +int +main(int argc, const char *argv[]) +{ + CdIo_t *p_cdio; + driver_return_code_t ret; + driver_id_t driver_id = DRIVER_DEVICE; + char *psz_drive = NULL; + bool do_eject = false; + + if (argc > 1) + psz_drive = strdup(argv[1]); + + if (!psz_drive) { + psz_drive = cdio_get_default_device_driver(&driver_id); + if (!psz_drive) { + printf("Can't find a CD-ROM\n"); + exit(1); + } + } + + p_cdio = cdio_open (psz_drive, driver_id); + if (!p_cdio) { + printf("Can't open %s\n", psz_drive); + exit(2); + } + + ret = mmc_get_tray_status(p_cdio); + switch(ret) { + case 0: + printf("CD-ROM drive %s is closed.\n", psz_drive); + do_eject = true; + break; + case 1: + printf("CD-ROM drive %s is open.\n", psz_drive); + break; + default: + printf("Error status for drive %s: %s.\n", psz_drive, + cdio_driver_errmsg(ret)); + return 1; + } + + ret = mmc_get_media_changed(p_cdio); + switch(ret) { + case 0: + printf("CD-ROM drive %s media not changed since last test.\n", psz_drive); + break; + case 1: + printf("CD-ROM drive %s media changed since last test.\n", psz_drive); + break; + default: + printf("Error status for drive %s: %s.\n", psz_drive, + cdio_driver_errmsg(ret)); + return 1; + } + + if (do_eject) + ret = cdio_eject_media_drive(psz_drive); + else + ret = cdio_close_tray(psz_drive, &driver_id); + + ret = mmc_get_tray_status(p_cdio); + switch(ret) { + case 0: + printf("CD-ROM drive %s is closed.\n", psz_drive); + break; + case 1: + printf("CD-ROM drive %s is open.\n", psz_drive); + break; + default: + printf("Error status for drive %s: %s.\n", psz_drive, + cdio_driver_errmsg(ret)); + return 1; + } + + ret = mmc_get_media_changed(p_cdio); + switch(ret) { + case 0: + printf("CD-ROM drive %s media not changed since last test.\n", psz_drive); + break; + case 1: + printf("CD-ROM drive %s media changed since last test.\n", psz_drive); + break; + default: + printf("Error status for drive %s: %s.\n", psz_drive, + cdio_driver_errmsg(ret)); + return 1; + } + + free(psz_drive); + cdio_destroy(p_cdio); + + return 0; +} diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index f8dc2d46..b6167d18 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -1,5 +1,5 @@ /* - $Id: mmc.h,v 1.27 2006/04/12 09:30:14 rocky Exp $ + $Id: mmc.h,v 1.28 2006/10/11 12:38:18 rocky Exp $ Copyright (C) 2003, 2004, 2005, 2006 Rocky Bernstein @@ -543,6 +543,22 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio, discmode_t mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, cdio_dvd_struct_t *s); + /*! + Return results of media status + @param p_cdio the CD object to be acted upon. + @return DRIVER_OP_SUCCESS (0) if we got the status. + return codes are the same as driver_return_code_t + */ + int mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]); + + /*! + Find out if media tray is open or closed. + @param p_cdio the CD object to be acted upon. + @return 1 if media is open, 0 if closed. Error + return codes are the same as driver_return_code_t + */ + int mmc_get_tray_status ( const CdIo_t *p_cdio ); + /** Get the CD-ROM hardware info via an MMC INQUIRY command. diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am index 6053a53d..24d3e7f1 100644 --- a/lib/driver/Makefile.am +++ b/lib/driver/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.17 2006/08/20 23:50:16 rocky Exp $ +# $Id: Makefile.am,v 1.18 2006/10/11 12:38:18 rocky Exp $ # # Copyright (C) 2003, 2004, 2005, 2006 Rocky Bernstein # @@ -45,7 +45,7 @@ libcdio_la_CURRENT := 7 libcdio_la_REVISION := 0 -libcdio_la_AGE := 0 +libcdio_la_AGE := 1 EXTRA_DIST = image/Makefile FreeBSD/Makefile MSWindows/Makefile \ libcdio.sym diff --git a/lib/driver/libcdio.sym b/lib/driver/libcdio.sym index fa5a9202..2c118e35 100644 --- a/lib/driver/libcdio.sym +++ b/lib/driver/libcdio.sym @@ -191,6 +191,7 @@ mmc_get_hwinfo mmc_get_last_lsn mmc_get_mcn mmc_get_media_changed +mmc_get_tray_status mmc_have_interface mmc_mode_sense mmc_mode_sense_10 diff --git a/lib/driver/mmc.c b/lib/driver/mmc.c index 85a36b08..2e6a1d4c 100644 --- a/lib/driver/mmc.c +++ b/lib/driver/mmc.c @@ -1,6 +1,6 @@ /* Common Multimedia Command (MMC) routines. - $Id: mmc.c,v 1.34 2006/04/12 09:30:14 rocky Exp $ + $Id: mmc.c,v 1.35 2006/10/11 12:38:18 rocky Exp $ Copyright (C) 2004, 2005, 2006 Rocky Bernstein @@ -169,6 +169,13 @@ get_mcn_mmc (const void *p_user_data) return mmc_get_mcn( p_env->cdio ); } +driver_return_code_t +get_tray_status (const void *p_user_data) +{ + const generic_img_private_t *p_env = p_user_data; + return mmc_get_tray_status( p_env->cdio ); +} + /*! Read sectors using SCSI-MMC GPCMD_READ_CD. Can read only up to 25 blocks. */ @@ -842,12 +849,12 @@ mmc_get_hwinfo ( const CdIo_t *p_cdio, } /*! - Find out if media has changed since the last call. + Return results of media status @param p_cdio the CD object to be acted upon. - @return 1 if media has changed since last call, 0 if not. Error + @return DRIVER_OP_SUCCESS (0) if we got the status. return codes are the same as driver_return_code_t */ -int mmc_get_media_changed(const CdIo_t *p_cdio) +int mmc_get_event_status(const CdIo_t *p_cdio, uint8_t out_buf[2]) { mmc_cdb_t cdb = {{0, }}; uint8_t buf[8] = { 0, }; @@ -869,11 +876,30 @@ int mmc_get_media_changed(const CdIo_t *p_cdio) &cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf); if(i_status == 0) { - return 0 != (buf[4] & 0x02); + out_buf[0] = buf[4]; + out_buf[1] = buf[5]; + return DRIVER_OP_SUCCESS; } return DRIVER_OP_ERROR; } +/*! + Find out if media has changed since the last call. + @param p_cdio the CD object to be acted upon. + @return 1 if media has changed since last call, 0 if not. Error + return codes are the same as driver_return_code_t + */ +int mmc_get_media_changed(const CdIo_t *p_cdio) +{ + uint8_t status_buf[2]; + int i_status; + + i_status = mmc_get_event_status(p_cdio, status_buf); + if (i_status != DRIVER_OP_SUCCESS) + return i_status; + return (status_buf[0] & 0x02) ? 1 : 0; +} + char * mmc_get_mcn ( const CdIo_t *p_cdio ) { @@ -881,6 +907,23 @@ mmc_get_mcn ( const CdIo_t *p_cdio ) return mmc_get_mcn_private (p_cdio->env, p_cdio->op.run_mmc_cmd ); } +/*! + Find out if media tray is open or closed. + @param p_cdio the CD object to be acted upon. + @return 1 if media is open, 0 if closed. Error + return codes are the same as driver_return_code_t + */ +int mmc_get_tray_status(const CdIo_t *p_cdio) +{ + uint8_t status_buf[2]; + int i_status; + + i_status = mmc_get_event_status(p_cdio, status_buf); + if (i_status != DRIVER_OP_SUCCESS) + return i_status; + return (status_buf[1] & 0x01) ? 1 : 0; +} + /*! Run a MMC command. diff --git a/lib/driver/mmc_private.h b/lib/driver/mmc_private.h index 3b068500..eb9b16f1 100644 --- a/lib/driver/mmc_private.h +++ b/lib/driver/mmc_private.h @@ -1,8 +1,8 @@ /* private MMC helper routines. - $Id: mmc_private.h,v 1.10 2006/04/05 02:20:07 rocky Exp $ + $Id: mmc_private.h,v 1.11 2006/10/11 12:38:18 rocky Exp $ - Copyright (C) 2004, 2005 Rocky Bernstein + Copyright (C) 2004, 2005, 2006 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 @@ -69,6 +69,8 @@ int get_media_changed_mmc (const void *p_user_data); char *get_mcn_mmc (const void *p_user_data); +driver_return_code_t get_tray_status (const void *p_user_data); + /*! Read just the user data part of some sort of data sector (via mmc_read_cd). diff --git a/lib/iso9660/Makefile.am b/lib/iso9660/Makefile.am index 1b6eaea6..d0a0fa56 100644 --- a/lib/iso9660/Makefile.am +++ b/lib/iso9660/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.11 2006/03/14 12:05:16 rocky Exp $ +# $Id: Makefile.am,v 1.12 2006/10/11 12:38:18 rocky Exp $ # # Copyright (C) 2003, 2004, 2005, 2006 Rocky Bernstein # @@ -44,7 +44,7 @@ # incompatibility with previous versions. libiso9660_la_CURRENT := 5 -libiso9660_la_REVISION := 0 +libiso9660_la_REVISION := 1 libiso9660_la_AGE := 0 EXTRA_DIST = libiso9660.sym