summaryrefslogtreecommitdiff
path: root/usr.bin/cdio
diff options
context:
space:
mode:
authorav <av@cvs.openbsd.org>2008-06-08 21:01:25 +0000
committerav <av@cvs.openbsd.org>2008-06-08 21:01:25 +0000
commit21683dff667775a17c1fdc1aae7a320c12a1521f (patch)
treeefd8cd13ecadc85a28f90cc12bc70c74fa9dfd26 /usr.bin/cdio
parent1d1f6d0a19530aaa5dc91d8324c7a6e1d1237515 (diff)
add ability to determine media capabilities (what we can do with media).
ok fgsch
Diffstat (limited to 'usr.bin/cdio')
-rw-r--r--usr.bin/cdio/extern.h7
-rw-r--r--usr.bin/cdio/mmc.c59
2 files changed, 64 insertions, 2 deletions
diff --git a/usr.bin/cdio/extern.h b/usr.bin/cdio/extern.h
index 1c237328b79..818e9c78164 100644
--- a/usr.bin/cdio/extern.h
+++ b/usr.bin/cdio/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.9 2008/04/30 17:10:55 fgsch Exp $ */
+/* $OpenBSD: extern.h,v 1.10 2008/06/08 21:01:24 av Exp $ */
/*
* Copyright (c) 2002 Marc Espie.
*
@@ -37,12 +37,17 @@ struct track_info {
};
SLIST_HEAD(track_head, track_info) tracks;
+/* Media capabilities */
+#define MEDIACAP_TAO 0x01
+#define MEDIACAP_CDRW_WRITE 0x02
+
extern unsigned long entry2time(struct cd_toc_entry *);
extern unsigned long entry2frames(struct cd_toc_entry *);
extern int open_cd(char *, int);
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_capabilities(int *cap);
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 da2f86ef8ba..cd4850a6c25 100644
--- a/usr.bin/cdio/mmc.c
+++ b/usr.bin/cdio/mmc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mmc.c,v 1.19 2008/06/06 10:16:52 av Exp $ */
+/* $OpenBSD: mmc.c,v 1.20 2008/06/08 21:01:24 av Exp $ */
/*
* Copyright (c) 2006 Michael Coulter <mjc@openbsd.org>
@@ -33,6 +33,63 @@
extern int fd;
extern char *cdname;
+#define SCSI_GET_CONFIGURATION 0x46
+
+#define MMC_FEATURE_CD_TAO 0x2d
+#define MMC_FEATURE_CDRW_WRITE 0x37
+
+int
+get_media_capabilities(int *cap)
+{
+ scsireq_t scr;
+ char buf[4096];
+ int error;
+ u_int32_t i, dsz;
+ u_int16_t feature;
+
+ *cap = 0;
+ memset(buf, 0, sizeof(buf));
+ memset(&scr, 0, sizeof(scr));
+
+ scr.cmd[0] = SCSI_GET_CONFIGURATION;
+ scr.cmd[1] = 1; /* enumerate only "current" features */
+ *(u_int16_t *)(scr.cmd + 7) = betoh16(sizeof(buf));
+
+ scr.flags = SCCMD_ESCAPE | SCCMD_READ;
+ scr.databuf = buf;
+ scr.datalen = sizeof(buf);
+ scr.cmdlen = 10;
+ scr.timeout = 120000;
+ scr.senselen = SENSEBUFLEN;
+
+ error = ioctl(fd, SCIOCCOMMAND, &scr);
+ if (error == -1 || scr.retsts != 0)
+ return (-1);
+ if (scr.datalen_used < 8)
+ return (-1); /* can't get header */
+
+ dsz = betoh32(*(u_int32_t *)buf);
+ if (dsz > scr.datalen_used - 4)
+ dsz = scr.datalen_used - 4;
+
+ dsz += 4; /* total size of bufer for all features */
+ i = 8;
+ while (i <= dsz - 4) {
+ if (dsz - i < 4 + buf[i + 3])
+ break; /* partial feature descriptor */
+ feature = betoh16(*(u_int16_t *)(buf + i));
+
+ if (feature == MMC_FEATURE_CD_TAO)
+ *cap |= MEDIACAP_TAO;
+ else if (feature == MMC_FEATURE_CDRW_WRITE)
+ *cap |= MEDIACAP_CDRW_WRITE;
+
+ i += 4 + buf[i + 3];
+ }
+
+ return (0);
+}
+
int
blank(void)
{