Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 08 Nov 2009 01:02:06 +0100 (CET)
From:      Alexander Best <alexbestms@math.uni-muenster.de>
To:        <freebsd-current@FreeBSD.org>
Subject:   [patch] prevent burncd from failing when device is busy while trying to eject
Message-ID:  <permail-20091108000206f0889e8400007fe2-a_best01@message-id.uni-muenster.de>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
this patch was submitted by Jaakko Heinonen in january, but didn't get
committed to HEAD yet.

when burncd is used in combination with the eject switch it doesn't care if
the device is busy or not. if eject doesn't succeed burncd fails with EIO.

the patch issues ATAPI_TEST_UNIT_READY by calling (ioctl(fd, CDIOCRESET). this
gets repeated as long as the device isn't busy anymore or a timeout is being
reached.

this patch depends upon the removal of a bogus privilege check in
sys/dev/ata/ata-cd.c

would be nice if somebody could commit both patches. they've been tested for
almost a year now and cause no breakage to occur.

they can also safely be merged to 8-stable.

in order to make it into 7- and 6-stable this other patch (bin/95979) has to
be mfc'ed to those branches first.

thanks in advance.
alex

[-- Attachment #2 --]
Index: usr.sbin/burncd/burncd.c
===================================================================
--- usr.sbin/burncd/burncd.c	(revision 199016)
+++ usr.sbin/burncd/burncd.c	(working copy)
@@ -65,6 +65,7 @@
 void do_DAO(int fd, int, int);
 void do_TAO(int fd, int, int, int);
 void do_format(int, int, char *);
+void wait_for_ready(int);
 int write_file(int fd, struct track_info *);
 int roundup_blocks(struct track_info *);
 void cue_ent(struct cdr_cue_entry *, int, int, int, int, int, int, int);
@@ -219,6 +220,8 @@
 					break;
 				last = pct;
 			}
+			wait_for_ready(fd);
+
 			if (!quiet)
 				printf("\n");
 			continue;
@@ -322,6 +325,7 @@
 		err_set_exit(NULL);
 		err(EX_IOERR, "ioctl(CDRIOCSETBLOCKSIZE)");
 	}
+	wait_for_ready(fd);
 
 	if (eject)
 		if (ioctl(fd, CDIOCEJECT) < 0)
@@ -600,6 +604,27 @@
 		fprintf(stderr, "\n");
 }
 
+void
+wait_for_ready(int fd)
+{
+	int timeout = 10 * 1000;
+
+	while (timeout > 0) {
+		/*
+		 * CDIOCRESET issues ATAPI_TEST_UNIT_READY command.
+		 */
+		if (ioctl(fd, CDIOCRESET) == 0)
+			return;
+		else if (errno != EBUSY)
+			err(EX_IOERR, "ioctl(CDIOCRESET)");
+
+		usleep(500 * 1000);
+		timeout -= 500;
+	}
+
+        errx(EX_IOERR, "timed out while waiting for the drive to become ready");
+}
+
 int
 write_file(int fd, struct track_info *track_info)
 {

[-- Attachment #3 --]
Index: sys/dev/ata/atapi-cd.c
===================================================================
--- sys/dev/ata/atapi-cd.c	(revision 199016)
+++ sys/dev/ata/atapi-cd.c	(working copy)
@@ -256,13 +256,7 @@
 	cdp->flags |= F_LOCKED;
 	break;
 
-    /*
-     * XXXRW: Why does this require privilege?
-     */
     case CDIOCRESET:
-	error = priv_check(td, PRIV_DRIVER);
-	if (error)
-	    break;
 	error = acd_test_ready(dev);
 	break;
 

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?permail-20091108000206f0889e8400007fe2-a_best01>