diff options
author | av <av@cvs.openbsd.org> | 2008-06-08 21:01:25 +0000 |
---|---|---|
committer | av <av@cvs.openbsd.org> | 2008-06-08 21:01:25 +0000 |
commit | 21683dff667775a17c1fdc1aae7a320c12a1521f (patch) | |
tree | efd8cd13ecadc85a28f90cc12bc70c74fa9dfd26 /usr.bin/cdio | |
parent | 1d1f6d0a19530aaa5dc91d8324c7a6e1d1237515 (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.h | 7 | ||||
-rw-r--r-- | usr.bin/cdio/mmc.c | 59 |
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) { |