use a bitmap to store the features. simplify the code a bit and allow for
authorfgsch <fgsch@openbsd.org>
Sat, 30 Aug 2008 10:41:38 +0000 (10:41 +0000)
committerfgsch <fgsch@openbsd.org>
Sat, 30 Aug 2008 10:41:38 +0000 (10:41 +0000)
future work.  ok av@ a similar diff.

usr.bin/cdio/cdio.c
usr.bin/cdio/extern.h
usr.bin/cdio/mmc.c

index a5d2a89..54bd03b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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.
@@ -149,7 +149,7 @@ struct cd_toc_entry *toc_buffer;
 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;
@@ -513,11 +513,11 @@ run(int cmd, char *arg)
                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);
@@ -658,9 +658,9 @@ tao(int argc, char **argv)
 
        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);
index fd26816..38a1806 100644 (file)
@@ -1,4 +1,4 @@
-/* $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.
  *
@@ -39,11 +39,6 @@ struct track_info {
 };
 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 */
@@ -60,9 +55,14 @@ SLIST_HEAD(track_head, track_info) tracks;
  */
 #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
@@ -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 *cap);
+extern int             get_media_capabilities(int *, int);
 extern int             blank(void);
 extern int             unit_ready(void);
 extern int             synchronize_cache(void);
index df9b898..4482caf 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
  *
@@ -18,6 +18,7 @@
 #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)
@@ -76,21 +75,22 @@ 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;
@@ -102,28 +102,24 @@ get_media_capabilities(int *cap)
        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);
@@ -137,7 +133,7 @@ set_speed(int wspeed)
 
        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);