From owner-freebsd-current@FreeBSD.ORG Fri Nov 7 01:10:58 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3084816A4CF; Fri, 7 Nov 2003 01:10:58 -0800 (PST) Received: from mail.broadpark.no (mail.broadpark.no [217.13.4.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9634243FE3; Fri, 7 Nov 2003 01:10:56 -0800 (PST) (envelope-from des@des.no) Received: from smtp.des.no (37.80-203-228.nextgentel.com [80.203.228.37]) by mail.broadpark.no (Postfix) with ESMTP id 12ABC78F5C; Fri, 7 Nov 2003 10:10:55 +0100 (MET) Received: by smtp.des.no (Pony Express, from userid 666) id CDD4C9BEC6; Fri, 7 Nov 2003 10:10:54 +0100 (CET) Received: from dwp.des.no (dwp.des.no [10.0.0.4]) by smtp.des.no (Pony Express) with ESMTP id 6BCEF9B568; Fri, 7 Nov 2003 10:10:40 +0100 (CET) Received: by dwp.des.no (Postfix, from userid 2602) id 6289AB824; Fri, 7 Nov 2003 10:10:40 +0100 (CET) To: current@freebsd.org From: des@des.no (Dag-Erling =?iso-8859-1?q?Sm=F8rgrav?=) Date: Fri, 07 Nov 2003 10:10:40 +0100 Message-ID: User-Agent: Gnus/5.090024 (Oort Gnus v0.24) Emacs/21.3 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Checker-Version: SpamAssassin 2.60 (1.212-2003-09-23-exp) on dsa.des.no X-Spam-Level: X-Spam-Status: No, hits=0.0 required=5.0 tests=none autolearn=no version=2.60 Subject: burncd block size X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Nov 2003 09:10:58 -0000 --=-=-= 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"; 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 sensekey=3DILLEGAL REQUEST error=3D4" 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 at ata1-master WDMA2 # atacontrol info ata1 Master: acd0 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 #include -#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); } --=-=-=--