[patch] prevent burncd from failing when device is busy while trying to eject

Alexander Best alexbestms at math.uni-muenster.de
Sun Nov 8 00:02:40 UTC 2009


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
-------------- next part --------------
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)
 {
-------------- next part --------------
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;
 


More information about the freebsd-current mailing list