From 588f16262c940e5188386cc9cc4e8028d638eba3 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Mon, 1 Mar 2010 02:09:45 +0000 Subject: Add printing of current profile and feature information to 'info' command with -v. Make a second -v cause printing of raw feature data and a full list of profiles. A few minor tweaks to the feature bitmap handling. Helps in debugging media problems in cdio. Suggestions from fgsch@, man page fixes from jmc@ as usual. ok beck@ deraadt@ --- usr.bin/cdio/cdio.1 | 17 ++++- usr.bin/cdio/cdio.c | 11 ++-- usr.bin/cdio/extern.h | 4 +- usr.bin/cdio/mmc.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 183 insertions(+), 17 deletions(-) diff --git a/usr.bin/cdio/cdio.1 b/usr.bin/cdio/cdio.1 index 1ac9e8510f1..1035e76bc51 100644 --- a/usr.bin/cdio/cdio.1 +++ b/usr.bin/cdio/cdio.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: cdio.1,v 1.54 2009/06/09 22:20:44 jmc Exp $ +.\" $OpenBSD: cdio.1,v 1.55 2010/03/01 02:09:44 krw Exp $ .\" .\" Copyright (c) 1995 Serge V. Vakulenko .\" All rights reserved. @@ -29,7 +29,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 9 2009 $ +.Dd $Mdocdate: March 1 2010 $ .Dt CDIO 1 .Os .Sh NAME @@ -74,7 +74,9 @@ Silent mode. Do not print table headers or human-readable comments. .It Fl v Verbose mode. -Print as much information as possible. +A second occurence of +.Fl v +causes even more information to be printed. .El .Pp The available commands are listed below. @@ -137,6 +139,15 @@ A synonym for Print the list of available commands. .It Ic info Print the Table Of Contents (TOC). +If +.Fl v +is also specified, +the current features and current profile is printed. +If +.Fl v +is specified twice, +the complete list of supported profiles +and a hex dump of each current feature is printed. .It Ic next Play the next track. If we're at the last track, stop. diff --git a/usr.bin/cdio/cdio.c b/usr.bin/cdio/cdio.c index 00bfb3c027b..a792073e97c 100644 --- a/usr.bin/cdio/cdio.c +++ b/usr.bin/cdio/cdio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cdio.c,v 1.71 2009/06/09 22:20:44 jmc Exp $ */ +/* $OpenBSD: cdio.c,v 1.72 2010/03/01 02:09:44 krw Exp $ */ /* Copyright (c) 1995 Serge V. Vakulenko * All rights reserved. @@ -150,7 +150,7 @@ struct cd_toc_entry *toc_buffer; char *cdname; int fd = -1; int writeperm = 0; -int mediacap[MMC_FEATURE_MAX / 8]; +u_int8_t mediacap[MMC_FEATURE_MAX / NBBY]; int verbose = 1; int msf = 1; const char *cddb_host; @@ -246,7 +246,7 @@ main(int argc, char **argv) verbose = 0; break; case 'v': - verbose = 2; + verbose++; break; case 'f': cdname = optarg; @@ -266,7 +266,7 @@ main(int argc, char **argv) if (!cdname) { cdname = DEFAULT_CD_DRIVE; - if (verbose == 2) + if (verbose > 1) fprintf(stderr, "No CD device name specified. Defaulting to %s.\n", cdname); @@ -1217,6 +1217,9 @@ info(char *arg) struct ioc_toc_header h; int rc, i, n; + if (get_media_capabilities(mediacap, 1) == -1) + errx(1, "Can't determine media type"); + rc = ioctl(fd, CDIOREADTOCHEADER, &h); if (rc >= 0) { if (verbose) diff --git a/usr.bin/cdio/extern.h b/usr.bin/cdio/extern.h index 38a18063d9d..31b10e652d7 100644 --- a/usr.bin/cdio/extern.h +++ b/usr.bin/cdio/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.14 2008/08/30 10:41:38 fgsch Exp $ */ +/* $OpenBSD: extern.h,v 1.15 2010/03/01 02:09:44 krw Exp $ */ /* * Copyright (c) 2002 Marc Espie. * @@ -74,7 +74,7 @@ extern char ** cddb(const char *, int, struct cd_toc_entry *, char *); extern unsigned long cddb_discid(int, struct cd_toc_entry *); extern void free_names(char **); extern int get_media_type(void); -extern int get_media_capabilities(int *, int); +extern int get_media_capabilities(u_int8_t *, int); extern int blank(void); extern int unit_ready(void); extern int synchronize_cache(void); diff --git a/usr.bin/cdio/mmc.c b/usr.bin/cdio/mmc.c index f2776b1fe27..0d22735d7ec 100644 --- a/usr.bin/cdio/mmc.c +++ b/usr.bin/cdio/mmc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mmc.c,v 1.27 2009/12/04 07:43:26 claudio Exp $ */ +/* $OpenBSD: mmc.c,v 1.28 2010/03/01 02:09:44 krw Exp $ */ /* * Copyright (c) 2006 Michael Coulter * @@ -31,13 +31,111 @@ #include "extern.h" extern int fd; -extern int mediacap[]; +extern u_int8_t mediacap[]; extern char *cdname; +extern int verbose; #define SCSI_GET_CONFIGURATION 0x46 #define MMC_FEATURE_HDR_LEN 8 +static const struct { + u_int16_t id; + char *name; +} mmc_feature[] = { + { 0x0000, "Profile List" }, + { 0x0001, "Core" }, + { 0x0002, "Morphing" }, + { 0x0003, "Removable Medium" }, + { 0x0004, "Write Protect" }, + { 0x0010, "Random Readable" }, + { 0x001d, "Multi-Read" }, + { 0x001e, "CD Read" }, + { 0x001f, "DVD Read" }, + { 0x0020, "Random Writable" }, + { 0x0021, "Incremental Streaming Writable" }, + { 0x0022, "Sector Erasable" }, + { 0x0023, "Formattable" }, + { 0x0024, "Hardware Defect Management" }, + { 0x0025, "Write Once" }, + { 0x0026, "Restricted Overwrite" }, + { 0x0027, "CD-RW CAV Write" }, + { 0x0028, "MRW" }, + { 0x0029, "Enhanced Defect Reporting" }, + { 0x002a, "DVD+RW" }, + { 0x002b, "DVD+R" }, + { 0x002c, "Rigid Restricted Overwrite" }, + { 0x002d, "CD Track at Once (TAO)" }, + { 0x002e, "CD Mastering (Session at Once)" }, + { 0x002f, "DVD-RW Write" }, + { 0x0030, "DDCD-ROM (Legacy)" }, + { 0x0031, "DDCD-R (Legacy)" }, + { 0x0032, "DDCD-RW (Legacy)" }, + { 0x0033, "Layer Jump Recording" }, + { 0x0037, "CD-RW Media Write Support" }, + { 0x0038, "BD-R Pseudo-Overwrite (POW)" }, + { 0x003a, "DVD+RW Dual Layer" }, + { 0x003b, "DVD+R Dual Layer" }, + { 0x0040, "BD Read" }, + { 0x0041, "BD Write" }, + { 0x0042, "Timely Safe Recording (TSR)" }, + { 0x0050, "HD DVD Read" }, + { 0x0051, "HD DVD Write" }, + { 0x0080, "Hybrid Disc" }, + { 0x0100, "Power Management" }, + { 0x0101, "S.M.A.R.T." }, + { 0x0102, "Embedded Changer" }, + { 0x0103, "CD Audio External Play (Legacy)" }, + { 0x0104, "Microcode Upgrade" }, + { 0x0105, "Timeout" }, + { 0x0106, "DVD CSS" }, + { 0x0107, "Real Time Streaming" }, + { 0x0108, "Drive Serial Number" }, + { 0x0109, "Media Serial Number" }, + { 0x010a, "Disc Control Blocks (DCBs)" }, + { 0x010b, "DVD CPRM" }, + { 0x010c, "Firmware Information" }, + { 0x010d, "AACS" }, + { 0x0110, "VCPS" }, + { 0, NULL } +}; + +static const struct { + u_int16_t id; + char *name; +} mmc_profile[] = { + { 0x0001, "Re-writable disk, capable of changing behaviour" }, + { 0x0002, "Re-writable, with removable media" }, + { 0x0003, "Magneto-Optical disk with sector erase capability" }, + { 0x0004, "Optical write once" }, + { 0x0005, "Advance Storage -- Magneto-Optical" }, + { 0x0008, "Read only Compact Disc" }, + { 0x0009, "Write once Compact Disc" }, + { 0x000a, "Re-writable Compact Disc" }, + { 0x0010, "Read only DVD" }, + { 0x0011, "Write once DVD using Sequential recording" }, + { 0x0012, "Re-writable DVD" }, + { 0x0013, "Re-recordable DVD using Restricted Overwrite" }, + { 0x0014, "Re-recordable DVD using Sequential recording" }, + { 0x0015, "Dual Layer DVD-R using Sequential recording" }, + { 0x0016, "Dual Layer DVD-R using Layer Jump recording" }, + { 0x001a, "DVD+ReWritable" }, + { 0x001b, "DVD+Recordable" }, + { 0x0020, "DDCD-ROM" }, + { 0x0021, "DDCD-R" }, + { 0x0022, "DDCD-RW" }, + { 0x002a, "DVD+Rewritable Dual Layer" }, + { 0x002b, "DVD+Recordable Dual Layer" }, + { 0x003e, "Blu-ray Disc ROM" }, + { 0x003f, "Blu-ray Disc Recordable -- Sequential Recording Mode" }, + { 0x0040, "Blu-ray Disc Recordable -- Random Recording Mode" }, + { 0x0041, "Blu-ray Disc Rewritable" }, + { 0x004e, "Read-only HD DVD" }, + { 0x004f, "Write-once HD DVD" }, + { 0x0050, "Rewritable HD DVD" }, + { 0, NULL } +}; + int get_media_type(void) { @@ -63,7 +161,7 @@ get_media_type(void) scr.senselen = SENSEBUFLEN; error = ioctl(fd, SCIOCCOMMAND, &scr); - if (error != -1 && scr.retsts == 0 && scr.datalen_used > 7) { + if (error != -1 && scr.retsts == SCCMD_OK && scr.datalen_used > 7) { disctype = (buf[6] >> 6) & 0x1; if (disctype == 0) rv = MEDIATYPE_CDR; @@ -75,16 +173,16 @@ get_media_type(void) } int -get_media_capabilities(int *cap, int rt) +get_media_capabilities(u_int8_t *cap, int rt) { scsireq_t scr; u_char buf[4096]; u_int32_t i, dlen; - u_int16_t feature, tmp; + u_int16_t feature, profile, tmp; u_int8_t feature_len; - int error; + int current, error, j, k; - memset(cap, 0, MMC_FEATURE_MAX / 8); + memset(cap, 0, MMC_FEATURE_MAX / NBBY); memset(buf, 0, sizeof(buf)); memset(&scr, 0, sizeof(scr)); @@ -101,7 +199,7 @@ get_media_capabilities(int *cap, int rt) scr.senselen = SENSEBUFLEN; error = ioctl(fd, SCIOCCOMMAND, &scr); - if (error == -1 || scr.retsts != 0) + if (error == -1 || scr.retsts != SCCMD_OK) return (-1); if (scr.datalen_used < MMC_FEATURE_HDR_LEN) return (-1); /* Can't get the header. */ @@ -111,6 +209,8 @@ get_media_capabilities(int *cap, int rt) if (dlen > scr.datalen_used) dlen = scr.datalen_used; + if (verbose > 1) + printf("Features:\n"); for (i = MMC_FEATURE_HDR_LEN; i + 3 < dlen; i += feature_len) { feature_len = buf[i + 3] + 4; if (feature_len + i > dlen) @@ -120,6 +220,58 @@ get_media_capabilities(int *cap, int rt) if (feature >= MMC_FEATURE_MAX) break; + if (verbose > 1) { + printf("0x%04x", feature); + for (j = 0; mmc_feature[j].name != NULL; j++) + if (feature == mmc_feature[j].id) + break; + if (mmc_feature[j].name == NULL) + printf(" "); + else + printf(" %s", mmc_feature[j].name); + if (feature_len > 4) + printf(" (%d bytes of data)", feature_len - 4); + printf("\n"); + if (verbose > 2) { + printf(" "); + for (j = i; j < i + feature_len; j++) { + printf("%02x", buf[j]); + if ((j + 1) == (i + feature_len)) + printf("\n"); + else if ((j > i) && ((j - i + 1) % 16 + == 0)) + printf("\n "); + else if ((j - i) == 3) + printf("|"); + else + printf(" "); + } + } + } + if (feature == 0 && verbose > 1) { + if (verbose > 2) + printf(" Profiles:\n"); + for (j = i + 4; j < i + feature_len; j += 4) { + profile = betoh16(*(u_int16_t *)(buf+j)); + current = buf[j+2] == 1; + if (verbose < 3 && !current) + continue; + if (current) + printf(" * "); + else + printf(" "); + printf("0x%04x", profile); + for (k = 0; mmc_profile[k].name != NULL; k++) + if (profile == mmc_profile[k].id) + break; + if (mmc_profile[k].name == NULL) + printf(" "); + else + printf(" %s", mmc_profile[k].name); + printf(" %s\n", current ? "[Current Profile]" : + "" ); + } + } setbit(cap, feature); } -- cgit v1.2.3