Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 07 Nov 2003 10:10:40 +0100
From:      des@des.no (Dag-Erling =?iso-8859-1?q?Sm=F8rgrav?=)
To:        current@freebsd.org
Subject:   burncd block size
Message-ID:  <xzp4qxgsfvz.fsf@dwp.des.no>

next in thread | raw e-mail | index | archive | help
--=-=-=
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

I've been having a variety of problems burning CDs with atang:

 - burncd consistently failing in exactly the same spot in the ISO,
   and reporting "only wrote 0 of 32768 bytes: Unknown error: 0"

 - burncd failing right at the start with "only wrote -1 of 32768
   bytes: Input/output error" (this generally happens after a couple
   of the previous, and once it starts happening I have to reboot)

 - burncd getting stuck in acdcld for a long time while fixating

 - a *lot* of "sensekey=3DILLEGAL REQUEST error=3D4<ABORTED>"; fixating a
   CD causes about half a dozen TEST_UNIT_READY failures, and I
   occasionally get READ_BIG, START_STOP, PREVENT_ALLOW and SET_SPEED
   failures as well, all of them with "status=3D51<READY,DSC,ERROR>
   sensekey=3DILLEGAL REQUEST error=3D4<ABORTED>"

I've discovered that reducing the buffer size in burncd fixes at least
the first problem, and possibly the second, but not the third.  I've
attached a patch that adds a command-line option for that (the default
will still be 16 blocks at a time, but you can specify anything from 1
to 64 on the command line)

The drive is an LG 8400B with which I've previously had little or no
trouble; prior to atang, it burned CDs just fine at 40x with a failure
rate of precisely 0.

# dmesg | grep acd
acd0: CDRW <HL-DT-ST GCE-8400B> at ata1-master WDMA2
# atacontrol info ata1
Master: acd0 <HL-DT-ST GCE-8400B/1.00> ATA/ATAPI rev 0
Slave:       no device present
# atacontrol cap ata1 0
ATA channel 1, Master, device acd0:

ATA/ATAPI revision    0
device model          HL-DT-ST GCE-8400B
serial number
firmware revision     1.00
cylinders             0
heads                 0
sectors/track         0
lba supported
lba48 not supported
dma supported
overlap not supported

Feature                      Support  Enable    Value   Vendor
write cache                    no       no
read ahead                     no       no
dma queued                     no       no      0/0x00
SMART                          no       no
microcode download             no       no
security                       no       no
power management               no       no
advanced power management      no       no      0/0x00
automatic acoustic management  no       no      0/0x00  0/0x00

DES
--=20
Dag-Erling Sm=F8rgrav - des@des.no


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=burncd.diff

Index: burncd.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/burncd/burncd.c,v
retrieving revision 1.37
diff -u -r1.37 burncd.c
--- burncd.c	26 Jul 2003 12:14:58 -0000	1.37
+++ burncd.c	6 Nov 2003 22:01:00 -0000
@@ -45,7 +45,8 @@
 #include <sys/param.h>
 #include <arpa/inet.h>
 
-#define BLOCKS	16
+#define DEFAULT_BLOCKS 16
+#define MAX_BLOCKS 64
 
 struct track_info {
 	int	file;
@@ -58,6 +59,7 @@
 };
 static struct track_info tracks[100];
 static int global_fd_for_cleanup, quiet, verbose, saved_block_size, notracks;
+static int blocks = DEFAULT_BLOCKS;
 
 void add_track(char *, int, int, int);
 void do_DAO(int fd, int, int);
@@ -81,8 +83,15 @@
 	if ((dev = getenv("CDROM")) == NULL)
 		dev = "/dev/acd0";
 
-	while ((ch = getopt(argc, argv, "def:Flmnpqs:tv")) != -1) {
+	while ((ch = getopt(argc, argv, "b:def:Flmnpqs:tv")) != -1) {
 		switch (ch) {
+		case 'b':
+			blocks = atoi(optarg);
+			if (blocks < 0)
+				blocks = 1;
+			if (blocks > MAX_BLOCKS)
+				blocks = MAX_BLOCKS;
+			break;
 		case 'd':
 			dao = 1;
 			break;
@@ -94,7 +103,7 @@
 		case 'f':
 			dev = optarg;
 			break;
-	
+
 		case 'F':
 			force = 1;
 			break;
@@ -136,7 +145,7 @@
 			verbose = 1;
 			break;
 
-		default: 
+		default:
 			usage();
 		}
 	}
@@ -149,11 +158,11 @@
 	if ((fd = open(dev, O_RDWR, 0)) < 0)
 		err(EX_NOINPUT, "open(%s)", dev);
 
-	if (ioctl(fd, CDRIOCGETBLOCKSIZE, &saved_block_size) < 0) 
-       		err(EX_IOERR, "ioctl(CDRIOCGETBLOCKSIZE)");
+	if (ioctl(fd, CDRIOCGETBLOCKSIZE, &saved_block_size) < 0)
+		err(EX_IOERR, "ioctl(CDRIOCGETBLOCKSIZE)");
 
-	if (ioctl(fd, CDRIOCWRITESPEED, &speed) < 0) 
-       		err(EX_IOERR, "ioctl(CDRIOCWRITESPEED)");
+	if (ioctl(fd, CDRIOCWRITESPEED, &speed) < 0)
+		err(EX_IOERR, "ioctl(CDRIOCWRITESPEED)");
 
 	global_fd_for_cleanup = fd;
 	err_set_exit(cleanup);
@@ -164,26 +173,26 @@
 			break;
 		}
 		if (!strcasecmp(argv[arg], "msinfo")) {
-		        struct ioc_read_toc_single_entry entry;
+			struct ioc_read_toc_single_entry entry;
 			struct ioc_toc_header header;
 
-			if (ioctl(fd, CDIOREADTOCHEADER, &header) < 0) 
+			if (ioctl(fd, CDIOREADTOCHEADER, &header) < 0)
 				err(EX_IOERR, "ioctl(CDIOREADTOCHEADER)");
 			bzero(&entry, sizeof(struct ioc_read_toc_single_entry));
 			entry.address_format = CD_LBA_FORMAT;
 			entry.track = header.ending_track;
-			if (ioctl(fd, CDIOREADTOCENTRY, &entry) < 0) 
+			if (ioctl(fd, CDIOREADTOCENTRY, &entry) < 0)
 				err(EX_IOERR, "ioctl(CDIOREADTOCENTRY)");
-			if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0) 
+			if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
 				err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
-			fprintf(stdout, "%d,%d\n", 
+			fprintf(stdout, "%d,%d\n",
 				ntohl(entry.entry.addr.lba), addr);
 
 			break;
 		}
 		if ((!strcasecmp(argv[arg], "erase") ||
 		     !strcasecmp(argv[arg], "blank")) && !test_write) {
-		    	int blank, pct, last = 0;
+			int blank, pct, last = 0;
 
 			if (!strcasecmp(argv[arg], "erase"))
 				blank = CDR_B_ALL;
@@ -194,15 +203,15 @@
 					blank == CDR_B_ALL ? "eras" : "blank");
 
 			if (ioctl(fd, CDRIOCBLANK, &blank) < 0)
-        			err(EX_IOERR, "ioctl(CDRIOCBLANK)");
+				err(EX_IOERR, "ioctl(CDRIOCBLANK)");
 			while (1) {
 				sleep(1);
 				if (ioctl(fd, CDRIOCGETPROGRESS, &pct) == -1)
 					err(EX_IOERR,"ioctl(CDRIOGETPROGRESS)");
 				if (pct > 0 && !quiet)
-					fprintf(stderr, 
+					fprintf(stderr,
 						"%sing CD - %d %% done     \r",
-						blank == CDR_B_ALL ? 
+						blank == CDR_B_ALL ?
 						"eras" : "blank", pct);
 				if (pct == 100 || (pct == 0 && last > 90))
 					break;
@@ -268,7 +277,7 @@
 			FILE *fp;
 
 			if ((fp = fopen(argv[arg], "r")) == NULL)
-	 			err(EX_NOINPUT, "fopen(%s)", argv[arg]);
+				err(EX_NOINPUT, "fopen(%s)", argv[arg]);
 
 			while (fgets(file_buf, sizeof(file_buf), fp) != NULL) {
 				if (*file_buf == '#' || *file_buf == '\n')
@@ -295,7 +304,7 @@
 				err(EX_IOERR, "ioctl(CDRIOCINITWRITER)");
 			cdopen = 1;
 		}
-		if (dao) 
+		if (dao)
 			do_DAO(fd, test_write, multi);
 		else
 			do_TAO(fd, test_write, preemp, dvdrw);
@@ -304,7 +313,7 @@
 		if (!quiet)
 			fprintf(stderr, "fixating CD, please wait..\n");
 		if (ioctl(fd, CDRIOCFIXATE, &multi) < 0)
-        		err(EX_IOERR, "ioctl(CDRIOCFIXATE)");
+			err(EX_IOERR, "ioctl(CDRIOCFIXATE)");
 	}
 
 	if (ioctl(fd, CDRIOCSETBLOCKSIZE, &saved_block_size) < 0) {
@@ -362,7 +371,7 @@
 		if (tracks[notracks].file_size / tracks[notracks].block_size !=
 		    roundup_blocks(&tracks[notracks]))
 			pad = 1;
-		fprintf(stderr, 
+		fprintf(stderr,
 			"adding type 0x%02x file %s size %d KB %d blocks %s\n",
 			tracks[notracks].block_type, name, (int)sb.st_size/1024,
 			roundup_blocks(&tracks[notracks]),
@@ -384,14 +393,14 @@
 
 	int bt2df[16] = { 0x0,    -1,   -1,   -1,   -1,   -1,   -1,   -1,
 			  0x10, 0x30, 0x20,   -1, 0x21,   -1,   -1,   -1 };
-	
-	if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0) 
+
+	if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, &addr) < 0)
 		err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
 	if (verbose)
 		fprintf(stderr, "next writeable LBA %d\n", addr);
 
 	cue_ent(&cue[j++], bt2ctl[tracks[0].block_type], 0x01, 0x00, 0x0,
-		(bt2df[tracks[0].block_type] & 0xf0) | 
+		(bt2df[tracks[0].block_type] & 0xf0) |
 		(tracks[0].block_type < 8 ? 0x01 : 0x04), 0x00, addr);
 
 	for (i = 0; i < notracks; i++) {
@@ -406,7 +415,7 @@
 			addr += tracks[i].pregap;
 			tracks[i].addr = addr;
 
-			cue_ent(&cue[j++], bt2ctl[tracks[i].block_type], 
+			cue_ent(&cue[j++], bt2ctl[tracks[i].block_type],
 				0x01, i+1, 0x1, bt2df[tracks[i].block_type],
 				0x00, addr);
 
@@ -414,14 +423,14 @@
 		else {
 			if (tracks[i].pregap) {
 				if (tracks[i].block_type > 0x7) {
-					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], 
+					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
 						0x01, i+1, 0x0,
-						(bt2df[tracks[i].block_type] & 0xf0) | 
+						(bt2df[tracks[i].block_type] & 0xf0) |
 						(tracks[i].block_type < 8 ? 0x01 :0x04),
 						0x00, addr);
 				}
 				else
-					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type], 
+					cue_ent(&cue[j++],bt2ctl[tracks[i].block_type],
 						0x01, i+1, 0x0,
 						bt2df[tracks[i].block_type],
 						0x00, addr);
@@ -440,7 +449,7 @@
 	}
 
 	cue_ent(&cue[j++], bt2ctl[tracks[i - 1].block_type], 0x01, 0xaa, 0x01,
-		(bt2df[tracks[i - 1].block_type] & 0xf0) | 
+		(bt2df[tracks[i - 1].block_type] & 0xf0) |
 		(tracks[i - 1].block_type < 8 ? 0x01 : 0x04), 0x00, addr);
 
 	sheet.len = j * 8;
@@ -450,7 +459,7 @@
 	sheet.session_format = format;
 	if (verbose) {
 		u_int8_t *ptr = (u_int8_t *)sheet.entries;
-		
+
 		fprintf(stderr,"CUE sheet:");
 		for (i = 0; i < sheet.len; i++)
 			if (i % 8)
@@ -459,7 +468,7 @@
 				fprintf(stderr,"\n%02x", ptr[i]);
 		fprintf(stderr,"\n");
 	}
-	
+
 	if (ioctl(fd, CDRIOCSENDCUE, &sheet) < 0)
 		err(EX_IOERR, "ioctl(CDRIOCSENDCUE)");
 
@@ -487,7 +496,7 @@
 		if (dvdrw)
 			tracks[i].addr = 0;
 		else
-			if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR, 
+			if (ioctl(fd, CDRIOCNEXTWRITEABLEADDR,
 				  &tracks[i].addr) < 0)
 				err(EX_IOERR, "ioctl(CDRIOCNEXTWRITEABLEADDR)");
 
@@ -514,10 +523,10 @@
 		err(EX_IOERR, "ioctl(CDRIOCREADFORMATCAPS)");
 
 	if (verbose) {
-		fprintf(stderr, "format list entries=%zd\n", 
+		fprintf(stderr, "format list entries=%zd\n",
 			capacities.length / sizeof(struct cdr_format_capacity));
 		fprintf(stderr, "current format: blocks=%u type=0x%x block_size=%u\n",
-			ntohl(capacities.blocks), capacities.type, 
+			ntohl(capacities.blocks), capacities.type,
 			NTOH3B(capacities.block_size));
 	}
 
@@ -545,7 +554,7 @@
 	}
 	if (i == count)
 		err(EX_IOERR, "could not find a valid format capacity");
-	
+
 	if (!quiet)
 		fprintf(stderr,"formatting with blocks=%u type=0x%x param=%u\n",
 			ntohl(capacities.format[i].blocks),
@@ -570,7 +579,7 @@
 		if (ioctl(the_fd, CDRIOCGETPROGRESS, &pct) == -1)
 			err(EX_IOERR, "ioctl(CDRIOGETPROGRESS)");
 		if (pct > 0 && !quiet)
-			fprintf(stderr, "formatting DVD - %d %% done     \r", 
+			fprintf(stderr, "formatting DVD - %d %% done     \r",
 				pct);
 		if (pct == 100 || (pct == 0 && last > 90))
 			break;
@@ -584,7 +593,7 @@
 write_file(int fd, struct track_info *track_info)
 {
 	off_t size, count, filesize;
-	char buf[2352*BLOCKS];
+	char buf[2352*MAX_BLOCKS];
 	static off_t tot_size = 0;
 
 	filesize = track_info->file_size / 1024;
@@ -604,7 +613,7 @@
 		if (track_info->file == STDIN_FILENO)
 			fprintf(stderr, "writing from stdin\n");
 		else
-			fprintf(stderr, 
+			fprintf(stderr,
 				"writing from file %s size %jd KB\n",
 				track_info->file_name, (intmax_t)filesize);
 	}
@@ -612,19 +621,22 @@
 
 	while ((count = read(track_info->file, buf,
 			     track_info->file_size == -1
-				? track_info->block_size * BLOCKS
+				? track_info->block_size * blocks
 				: MIN((track_info->file_size - size),
-				      track_info->block_size * BLOCKS))) > 0) {	
+				      track_info->block_size * blocks))) > 0) {
 		int res;
 
 		if (count % track_info->block_size) {
 			/* pad file to % block_size */
 			bzero(&buf[count],
-			      (track_info->block_size * BLOCKS) - count);
+			      (track_info->block_size * blocks) - count);
 			count = ((count / track_info->block_size) + 1) *
 				track_info->block_size;
 		}
-		if ((res = write(fd, buf, count)) != count) {
+		do {
+			res = write(fd, buf, count);
+		} while (res == 0);
+		if (res != count) {
 			fprintf(stderr, "\nonly wrote %d of %jd bytes: %s\n",
 				res, (intmax_t)count, strerror(errno));
 			break;
@@ -640,7 +652,7 @@
 				pct = (size / 1024) * 100 / filesize;
 				fprintf(stderr, " (%d%%)", pct);
 			}
-			fprintf(stderr, " total %jd KB\r", 
+			fprintf(stderr, " total %jd KB\r",
 			    (intmax_t)tot_size / 1024);
 		}
 		if (track_info->file_size != -1
@@ -680,7 +692,7 @@
 cleanup(int dummy __unused)
 {
 	if (ioctl(global_fd_for_cleanup, CDRIOCSETBLOCKSIZE,
-	    &saved_block_size) < 0) 
+	    &saved_block_size) < 0)
 		err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
 }
 
@@ -688,7 +700,7 @@
 usage(void)
 {
 	fprintf(stderr,
-	    "usage: %s [-delmnpqtv] [-f device] [-s speed] [command]"
-	    " [command file ...]\n", getprogname());
+	    "usage: %s [-delmnpqtv] [-b blocks] [-f device] [-s speed] "
+	    " [command] [command file ...]\n", getprogname());
 	exit(EX_USAGE);
 }

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzp4qxgsfvz.fsf>