-/* $OpenBSD: cdio.c,v 1.66 2008/08/13 12:21:19 av Exp $ */
+/* $OpenBSD: cdio.c,v 1.67 2008/08/30 10:41:38 fgsch Exp $ */
/* Copyright (c) 1995 Serge V. Vakulenko
* All rights reserved.
char *cdname;
int fd = -1;
int writeperm = 0;
-int mediacap = 0;
+int mediacap[MMC_FEATURE_MAX / 8];
int verbose = 1;
int msf = 1;
const char *cddb_host;
if (!open_cd(cdname, 1))
return 0;
- if (get_media_capabilities(&mediacap) == -1) {
+ if (get_media_capabilities(mediacap, 1) == -1) {
warnx("Can't determine media type");
return (0);
}
- if ((mediacap & MEDIACAP_CDRW_WRITE) == 0 &&
+ if (isset(mediacap, MMC_FEATURE_CDRW_WRITE) == 0 &&
get_media_type() != MEDIATYPE_CDRW) {
warnx("The media doesn't support blanking");
return (0);
if (!open_cd(cdname, 1))
exit(1);
- if (get_media_capabilities(&mediacap) == -1)
+ if (get_media_capabilities(mediacap, 1) == -1)
errx(1, "Can't determine media type");
- if ((mediacap & MEDIACAP_TAO) == 0)
+ if (isset(mediacap, MMC_FEATURE_CD_TAO) == 0)
errx(1, "The media can't be written in TAO mode");
get_disc_size(&availblk);
-/* $OpenBSD: extern.h,v 1.13 2008/08/13 12:21:19 av Exp $ */
+/* $OpenBSD: extern.h,v 1.14 2008/08/30 10:41:38 fgsch Exp $ */
/*
* Copyright (c) 2002 Marc Espie.
*
};
SLIST_HEAD(track_head, track_info) tracks;
-/* Media capabilities (bitmask) */
-#define MEDIACAP_TAO 0x01 /* Track-At-Once writing mode */
-#define MEDIACAP_CDRW_WRITE 0x02 /* media is CD-RW and can be written */
-#define MEDIACAP_CDRW_CAV 0x04 /* Constant Angular Velocity */
-
/* Read/Write speed */
#define DRIVE_SPEED_MAX 0xfffe
#define DRIVE_SPEED_OPTIMAL 0xffff /* automatically adjusted by drive */
*/
#define CD_MAX_SPEED 380
-/*
- * Media types
- */
+/* MMC feature codes */
+#define MMC_FEATURE_CDRW_CAV 0x27 /* Constant Angular Velocity */
+#define MMC_FEATURE_CD_TAO 0x2d /* Track-At-Once writing mode */
+#define MMC_FEATURE_CDRW_WRITE 0x37 /* media is CD-RW and can be written */
+
+#define MMC_FEATURE_MAX 0x0110
+
+/* Media types */
#define MEDIATYPE_UNKNOWN 0
#define MEDIATYPE_CDR 1
#define MEDIATYPE_CDRW 2
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 *cap);
+extern int get_media_capabilities(int *, int);
extern int blank(void);
extern int unit_ready(void);
extern int synchronize_cache(void);
-/* $OpenBSD: mmc.c,v 1.25 2008/08/13 12:21:19 av Exp $ */
+/* $OpenBSD: mmc.c,v 1.26 2008/08/30 10:41:38 fgsch Exp $ */
/*
* Copyright (c) 2006 Michael Coulter <mjc@openbsd.org>
*
#include <sys/limits.h>
#include <sys/types.h>
#include <sys/scsiio.h>
+#include <sys/param.h>
#include <scsi/cd.h>
#include <scsi/scsi_all.h>
#include <scsi/scsi_disk.h>
#include "extern.h"
extern int fd;
-extern int mediacap;
+extern int mediacap[];
extern char *cdname;
#define SCSI_GET_CONFIGURATION 0x46
-#define MMC_FEATURE_CDRW_CAV 0x27
-#define MMC_FEATURE_CD_TAO 0x2d
-#define MMC_FEATURE_CDRW_WRITE 0x37
+#define MMC_FEATURE_HDR_LEN 8
int
get_media_type(void)
}
int
-get_media_capabilities(int *cap)
+get_media_capabilities(int *cap, int rt)
{
scsireq_t scr;
u_char buf[4096];
- int error;
- u_int32_t i, dsz;
+ u_int32_t i, dlen;
u_int16_t feature;
+ u_int8_t feature_len;
+ int error;
- *cap = 0;
+ memset(cap, 0, MMC_FEATURE_MAX / 8);
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.cmd[1] = rt;
+ *(u_int16_t *)(scr.cmd + 7) = htobe16(sizeof(buf));
scr.flags = SCCMD_ESCAPE | SCCMD_READ;
scr.databuf = buf;
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 < (u_int32_t)buf[i + 3] + 4)
- break; /* partial feature descriptor */
- feature = betoh16(*(u_int16_t *)(buf + i));
+ if (scr.datalen_used < MMC_FEATURE_HDR_LEN)
+ return (-1); /* Can't get the header. */
+
+ /* Include the whole header in the length. */
+ dlen = betoh32(*(u_int32_t *)buf) + 4;
+ if (dlen > scr.datalen_used)
+ dlen = scr.datalen_used;
- if (feature == MMC_FEATURE_CDRW_CAV)
- *cap |= MEDIACAP_CDRW_CAV;
- else if (feature == MMC_FEATURE_CD_TAO)
- *cap |= MEDIACAP_TAO;
- else if (feature == MMC_FEATURE_CDRW_WRITE)
- *cap |= MEDIACAP_CDRW_WRITE;
+ for (i = MMC_FEATURE_HDR_LEN; i + 3 < dlen; i += feature_len) {
+ feature_len = buf[i + 3] + 4;
+ if (feature_len + i > dlen)
+ break;
+
+ feature = betoh16(*(u_int16_t *)(buf + i));
+ if (feature >= MMC_FEATURE_MAX)
+ break;
- i += 4 + buf[i + 3];
+ setbit(cap, feature);
}
return (0);
memset(&scr, 0, sizeof(scr));
scr.cmd[0] = SET_CD_SPEED;
- scr.cmd[1] = (mediacap & MEDIACAP_CDRW_CAV) != 0;
+ scr.cmd[1] = (isset(mediacap, MMC_FEATURE_CDRW_CAV)) != 0;
*(u_int16_t *)(scr.cmd + 2) = htobe16(DRIVE_SPEED_OPTIMAL);
*(u_int16_t *)(scr.cmd + 4) = htobe16(wspeed);