summaryrefslogtreecommitdiff
path: root/usr.bin/cdio
diff options
context:
space:
mode:
authorav <av@cvs.openbsd.org>2008-06-30 23:35:40 +0000
committerav <av@cvs.openbsd.org>2008-06-30 23:35:40 +0000
commit18d2e2d2106a01c55babb507cdb2188bee28e6d5 (patch)
tree4387dc28189e5383baca788410ae6868b5b33fb4 /usr.bin/cdio
parent1ab1e704c992505e56e6c41e808331016b8e1e20 (diff)
set speed for writing tracks in TAO.
ok and tweaks by fgsch manual page by jmc
Diffstat (limited to 'usr.bin/cdio')
-rw-r--r--usr.bin/cdio/cdio.115
-rw-r--r--usr.bin/cdio/cdio.c41
-rw-r--r--usr.bin/cdio/extern.h26
-rw-r--r--usr.bin/cdio/mmc.c33
-rw-r--r--usr.bin/cdio/rip.c12
5 files changed, 103 insertions, 24 deletions
diff --git a/usr.bin/cdio/cdio.1 b/usr.bin/cdio/cdio.1
index 8a63d15a1bf..41190ad87a3 100644
--- a/usr.bin/cdio/cdio.1
+++ b/usr.bin/cdio/cdio.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: cdio.1,v 1.50 2008/06/24 14:00:01 jmc Exp $
+.\" $OpenBSD: cdio.1,v 1.51 2008/06/30 23:35:39 av 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 24 2008 $
+.Dd $Mdocdate: June 30 2008 $
.Dt CDIO 1
.Os
.Sh NAME
@@ -210,6 +210,7 @@ and the current values of the volume for left and right channels.
Stop the disc.
.It Xo Ic tao
.Op Fl ad
+.Op Fl s Ar speed
.Ar trackfile ...
.Xc
.Bq command line only
@@ -226,6 +227,16 @@ with 2 channels of PCM audio,
signed 16-bit (little endian) values sampled at 44100 Hz.
.It Fl d
Write files as data tracks (the default).
+.It Fl s Ar speed
+Specify a write speed for tracks.
+.Ar speed
+may be a numerical value between 1 and
+the maximum speed supported by the media and drive,
+or one of the literal strings
+.Dq auto
+or
+.Dq max ,
+meaning the optimal or maximum speed detected.
.El
.It Ic volume Ar left_channel Ar right_channel
Set the volume of the left channel to
diff --git a/usr.bin/cdio/cdio.c b/usr.bin/cdio/cdio.c
index bbe157f6b18..2691f97bb0d 100644
--- a/usr.bin/cdio/cdio.c
+++ b/usr.bin/cdio/cdio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cdio.c,v 1.62 2008/06/22 21:04:01 av Exp $ */
+/* $OpenBSD: cdio.c,v 1.63 2008/06/30 23:35:39 av Exp $ */
/* Copyright (c) 1995 Serge V. Vakulenko
* All rights reserved.
@@ -149,6 +149,7 @@ struct cd_toc_entry *toc_buffer;
char *cdname;
int fd = -1;
int writeperm = 0;
+int mediacap = 0;
int verbose = 1;
int msf = 1;
const char *cddb_host;
@@ -166,7 +167,7 @@ int play_msf(int, int, int, int, int, int);
int play_track(int, int, int, int);
int get_vol(int *, int *);
int status(int *, int *, int *, int *);
-int is_wave(int fd);
+int is_wave(int);
__dead void tao(int argc, char **argv);
int play(char *arg);
int info(char *arg);
@@ -315,7 +316,7 @@ main(int argc, char **argv)
int
run(int cmd, char *arg)
{
- int l, r, rc, cap;
+ int l, r, rc;
static char newcdname[MAXPATHLEN];
switch (cmd) {
@@ -513,11 +514,11 @@ run(int cmd, char *arg)
if (!open_cd(cdname, 1))
return 0;
- if (get_media_capabilities(&cap) == -1) {
+ if (get_media_capabilities(&mediacap) == -1) {
warnx("Can't determine media type");
return (0);
}
- if ((cap & MEDIACAP_CDRW_WRITE) == 0) {
+ if ((mediacap & MEDIACAP_CDRW_WRITE) == 0) {
warnx("The media doesn't support blanking");
return (0);
}
@@ -576,23 +577,24 @@ tao(int argc, char **argv)
u_int blklen;
u_int ntracks = 0;
char type;
- int ch, cap;
+ int ch, speed;
+ const char *errstr;
if (argc == 1)
usage();
SLIST_INIT(&tracks);
type = 'd';
+ speed = DRIVE_SPEED_OPTIMAL;
blklen = 2048;
while (argc > 1) {
tr = malloc(sizeof(struct track_info));
if (tr == NULL)
err(1, "tao");
- tr->type = type;
optreset = 1;
optind = 1;
- while ((ch = getopt(argc, argv, "ad")) != -1) {
+ while ((ch = getopt(argc, argv, "ads:")) != -1) {
switch (ch) {
case 'a':
type = 'a';
@@ -602,12 +604,31 @@ tao(int argc, char **argv)
type = 'd';
blklen = 2048;
break;
+ case 's':
+ if (strcmp(optarg, "auto") == 0) {
+ speed = DRIVE_SPEED_OPTIMAL;
+ } else if (strcmp(optarg, "max") == 0) {
+ speed = DRIVE_SPEED_MAX;
+ } else {
+ speed = (int)strtonum(optarg, 1,
+ CD_MAX_SPEED, &errstr);
+ if (errstr != NULL) {
+ errx(1,
+ "incorrect speed value");
+ }
+ }
+ break;
default:
usage();
/* NOTREACHED */
}
}
+ if (speed != DRIVE_SPEED_OPTIMAL && speed != DRIVE_SPEED_MAX)
+ tr->speed = CD_SPEED_TO_KBPS(speed, blklen);
+ else
+ tr->speed = speed;
+
tr->type = type;
tr->blklen = blklen;
argc -= optind;
@@ -637,9 +658,9 @@ tao(int argc, char **argv)
if (!open_cd(cdname, 1))
exit(1);
- if (get_media_capabilities(&cap) == -1)
+ if (get_media_capabilities(&mediacap) == -1)
errx(1, "Can't determine media type");
- if ((cap & MEDIACAP_TAO) == 0)
+ if ((mediacap & MEDIACAP_TAO) == 0)
errx(1, "The media can't be written in TAO mode");
get_disc_size(&availblk);
diff --git a/usr.bin/cdio/extern.h b/usr.bin/cdio/extern.h
index 90c33cebf04..6a6a45b716b 100644
--- a/usr.bin/cdio/extern.h
+++ b/usr.bin/cdio/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.11 2008/06/22 21:04:01 av Exp $ */
+/* $OpenBSD: extern.h,v 1.12 2008/06/30 23:35:39 av Exp $ */
/*
* Copyright (c) 2002 Marc Espie.
*
@@ -35,12 +35,30 @@ struct track_info {
char *file;
SLIST_ENTRY(track_info) track_list;
char type;
+ int speed;
};
SLIST_HEAD(track_head, track_info) tracks;
-/* Media capabilities */
-#define MEDIACAP_TAO 0x01
-#define MEDIACAP_CDRW_WRITE 0x02
+/* 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 */
+
+/* Convert writing speed into Kbytes/sec (1x - 75 frames per second) */
+#define CD_SPEED_TO_KBPS(x, blksz) ((x) * 75 * (blksz) / 1024)
+
+/*
+ * It's maximum possible speed for CD (audio track).
+ * Data tracks theoretically can be written at 436x but in practice I
+ * believe, 380x will be never reached.
+ * NOTE: this value must never be changed to a bigger value, it can cause
+ * DRIVE_SPEED_MAX overrun.
+ */
+#define CD_MAX_SPEED 380
extern unsigned long entry2time(struct cd_toc_entry *);
extern unsigned long entry2frames(struct cd_toc_entry *);
diff --git a/usr.bin/cdio/mmc.c b/usr.bin/cdio/mmc.c
index 42b7d3845b6..6089ef7730b 100644
--- a/usr.bin/cdio/mmc.c
+++ b/usr.bin/cdio/mmc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mmc.c,v 1.21 2008/06/22 21:04:01 av Exp $ */
+/* $OpenBSD: mmc.c,v 1.22 2008/06/30 23:35:39 av Exp $ */
/*
* Copyright (c) 2006 Michael Coulter <mjc@openbsd.org>
@@ -31,10 +31,13 @@
#include "extern.h"
extern int fd;
+extern int mediacap;
extern char *cdname;
#define SCSI_GET_CONFIGURATION 0x46
+#define SCSI_SET_SPEED 0xbb
+#define MMC_FEATURE_CDRW_CAV 0x27
#define MMC_FEATURE_CD_TAO 0x2d
#define MMC_FEATURE_CDRW_WRITE 0x37
@@ -79,7 +82,9 @@ get_media_capabilities(int *cap)
break; /* partial feature descriptor */
feature = betoh16(*(u_int16_t *)(buf + i));
- if (feature == MMC_FEATURE_CD_TAO)
+ 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;
@@ -91,6 +96,28 @@ get_media_capabilities(int *cap)
}
int
+set_speed(int wspeed)
+{
+ scsireq_t scr;
+ int r;
+
+ memset(&scr, 0, sizeof(scr));
+ scr.cmd[0] = SCSI_SET_SPEED;
+ scr.cmd[1] = (mediacap & MEDIACAP_CDRW_CAV) != 0;
+ *(u_int16_t *)(scr.cmd + 2) = htobe16(DRIVE_SPEED_OPTIMAL);
+ *(u_int16_t *)(scr.cmd + 4) = htobe16(wspeed);
+
+ scr.cmdlen = 12;
+ scr.datalen = 0;
+ scr.timeout = 120000;
+ scr.flags = SCCMD_ESCAPE;
+ scr.senselen = SENSEBUFLEN;
+
+ r = ioctl(fd, SCIOCCOMMAND, &scr);
+ return (r == 0 ? scr.retsts : -1);
+}
+
+int
blank(void)
{
struct scsi_blank *scb;
@@ -210,6 +237,8 @@ writetao(struct track_head *thp)
warnx("mode select failed: %d", r);
return (r);
}
+
+ set_speed(tr->speed);
writetrack(tr, track);
synchronize_cache();
}
diff --git a/usr.bin/cdio/rip.c b/usr.bin/cdio/rip.c
index 47bbbf9b12a..3a93cabfa25 100644
--- a/usr.bin/cdio/rip.c
+++ b/usr.bin/cdio/rip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rip.c,v 1.7 2007/08/02 07:31:16 jakemsr Exp $ */
+/* $OpenBSD: rip.c,v 1.8 2008/06/30 23:35:39 av Exp $ */
/*
* Copyright (c) 2007 Alexey Vatchenko <av@bsdua.org>
@@ -80,9 +80,9 @@ static u_char wavehdr[44] = {
'd', 'a', 't', 'a', 0x0, 0x0, 0x0, 0x0
};
-static int write_sector(int fd, u_char *sec, u_int32_t secsize);
+static int write_sector(int, u_char *, u_int32_t);
-int read_data_sector(u_int32_t lba, u_char *sec, u_int32_t secsize);
+int read_data_sector(u_int32_t, u_char *, u_int32_t);
struct track_info {
int fd; /* descriptor of output file */
@@ -93,10 +93,10 @@ struct track_info {
u_int32_t end_lba; /* starting address of the next track */
};
-int read_track(int fd, struct track_info *ti);
+int read_track(int, struct track_info *);
-int rip_next_track(struct track_info *info);
-int play_next_track(struct track_info *info);
+int rip_next_track(struct track_info *);
+int play_next_track(struct track_info *);
static int rip_tracks_loop(struct track_pair *tp, u_int n_tracks,
int (*next_track)(struct track_info *));