[Libburn] Erase patch

Tiago Cogumbreiro cogumbreiro@linus.uac.pt
Thu, 04 Dec 2003 14:47:48 -0100


--=-pIRI6xUk7jKcwMEBXSSK
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Here is the patch i told you i would do, it simply adds more types of
blanking operations it doesn't include 2 modes:
- Blank a track: because it needs an argument
- Blank a track tail: only used for packet writing

PS: this diff already includes the alterations i did in the last mail
i've sent about blanking progress

--=-pIRI6xUk7jKcwMEBXSSK
Content-Disposition: attachment; filename=blank_enum.diff
Content-Type: text/x-patch; name=blank_enum.diff; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Index: libburn/async.c
===================================================================
RCS file: /cvs/burn/burn/libburn/async.c,v
retrieving revision 1.9
diff -p -u -r1.9 async.c
--- libburn/async.c	2 Dec 2003 02:53:48 -0000	1.9
+++ libburn/async.c	4 Dec 2003 15:41:46 -0000
@@ -25,7 +25,7 @@ struct scan_opts
 struct erase_opts
 {
 	struct drive *drive;
-	int fast;
+	enum libburn_erase_types type;
 };
 
 struct write_opts
@@ -133,12 +133,12 @@ int libburn_drive_scan(struct libburn_dr
 
 static void* erase_worker_func(struct w_list *w)
 {
-	libburn_erase_disc_sync(w->u.erase.drive, w->u.erase.fast);
+	libburn_erase_disc_sync(w->u.erase.drive, w->u.erase.type);
 	remove_worker(pthread_self());
 	return NULL;
 }
 
-void libburn_erase_disc(struct drive *drive, int fast)
+void libburn_erase_disc(struct drive *drive, enum libburn_erase_types type)
 {
 	struct erase_opts o;
 
@@ -147,7 +147,7 @@ void libburn_erase_disc(struct drive *dr
 	assert(!find_worker(drive));
 	
 	o.drive = drive;
-	o.fast = fast;
+	o.type = type;
 	add_worker(drive, (WorkerFunc) erase_worker_func, &o);
 }
 
Index: libburn/drive.c
===================================================================
RCS file: /cvs/burn/burn/libburn/drive.c,v
retrieving revision 1.228
diff -p -u -r1.228 drive.c
--- libburn/drive.c	2 Dec 2003 03:04:16 -0000	1.228
+++ libburn/drive.c	4 Dec 2003 15:41:46 -0000
@@ -143,8 +143,11 @@ void libburn_wait_all()
 	}
 }
 
-void libburn_erase_disc_sync(struct drive *d, int fast)
+void libburn_erase_disc_sync(struct drive *d, enum libburn_erase_types type)
 {
+	struct buffer buf;
+	int started = 0;
+	
 	libburn_message_clear_queue();
 
 	libburn_print(1, "erasing drive %s %s\n", d->idata->vendor,
@@ -152,10 +155,24 @@ void libburn_erase_disc_sync(struct driv
 
 	if (d->status != LIBBURN_STATUS_FULL)
 		return;
-
 	d->cancel = 0;
 	d->busy = LIBBURN_BUSY_ERASING;
-	d->erase(d, fast);
+	d->erase(d, type);
+	/* We might have a problem with fast blanking discs
+	 * if the blanking lasts less then half a second we won't ever know
+	 * if it started, thus we'll never know if it'll end.
+	 * This will never happen because drives are slow.
+	 */
+	do {
+		/* we'll check if the drive is still blanking
+		 * in 1/2 second interval
+		 */
+		usleep(500);
+		d->request_sense(d, &buf);
+		if(!started && buf.data[16] != 0 && buf.data[17] != 0)
+			started = 1;
+	} while(!started || buf.data[16] != 0 || buf.data[17] != 0);
+
 	d->busy = LIBBURN_BUSY_NO;
 }
 
@@ -168,6 +185,21 @@ enum libburn_drive_status libburn_drive_
 int libburn_drive_get_busy(struct drive *d, struct libburn_progress *p)
 {
 	if (p) {
+		if(d->busy == LIBBURN_BUSY_ERASING) {
+			struct buffer *buf = malloc(sizeof(struct buffer));
+			p->session = 1;
+			p->sessions = 1;
+			p->track = 1;
+			p->tracks = 1;
+			p->index = 1;
+			p->indices = 1;
+			p->abs_sectors = 0x10000;
+			p->rel_sectors = 0x10000;
+			d->request_sense(d, buf);
+			p->abs_sector = (buf->data[16] << 8) | buf->data[17];
+			p->rel_sector = p->abs_sector;
+			free(buf);
+		}
 		/* this is where we do stuff! */
 	}
 	return d->busy != LIBBURN_BUSY_NO;
Index: libburn/drive.h
===================================================================
RCS file: /cvs/burn/burn/libburn/drive.h,v
retrieving revision 1.75
diff -p -u -r1.75 drive.h
--- libburn/drive.h	28 Nov 2003 05:05:22 -0000	1.75
+++ libburn/drive.h	4 Dec 2003 15:41:47 -0000
@@ -67,6 +67,6 @@ void libburn_send_toc(struct drive *d, s
 
 int libburn_drive_scan_sync(struct libburn_drive_info *drives[],
 			    unsigned int *n_drives);
-void libburn_erase_disc_sync(struct drive *d, int fast);
+void libburn_erase_disc_sync(struct drive *d, enum libburn_erase_types type);
 
 #endif /* __DRIVE */
Index: libburn/libburn.h
===================================================================
RCS file: /cvs/burn/burn/libburn/libburn.h,v
retrieving revision 1.152
diff -p -u -r1.152 libburn.h
--- libburn/libburn.h	2 Dec 2003 04:49:18 -0000	1.152
+++ libburn/libburn.h	4 Dec 2003 15:41:48 -0000
@@ -133,6 +133,24 @@ enum libburn_track_types
 	LIBBURN_MODE_RAW_DATA
 };
 
+/** Types of erasing media */
+enum libburn_erase_types
+{
+	/** Erase the entire disc */
+	LIBBURN_ERASE_FULL = 0,
+	/** Minimally blank the disc */
+	LIBBURN_ERASE_MINIMAL = 1,
+	/** All the data in the last track in the incomplete
+	 * session shall be erased
+	 */
+	LIBBURN_ERASE_UNRESERVE_TRACK = 3,
+	/** The Lead-In and Lead-Out of the last complete 
+	 * session shall be blanked */
+	LIBBURN_ERASE_UNCLOSE_SESSION = 5,
+	/** Blank the last non-empty session */
+	LIBBURN_ERASE_BLANK_SESSION = 6
+};
+
 /** Possible status' of the drive in regard to the disc in it. */
 enum libburn_drive_status
 {
@@ -495,10 +513,9 @@ void libburn_read_opts_free(struct libbu
     cancellable, as control of the operation is passed wholly to the drive and
     there is no way to interrupt it safely.
     @param drive The drive with which to erase a disc.
-    @param fast Nonzero to do a fast erase, where only the disc's headers are
-                erased; zero to erase the entire disc.
+    @param type The type of erase operatin to perform (see also libburn_erase_types)
 */
-void libburn_erase_disc(struct drive *drive, int fast);
+void libburn_erase_disc(struct drive *drive, enum libburn_erase_types type);
 
 /** Read a disc from the drive and write it to an fd pair. The drive must be
     grabbed successfully BEFORE calling this function. Always ensure that the
Index: libburn/mmc.c
===================================================================
RCS file: /cvs/burn/burn/libburn/mmc.c,v
retrieving revision 1.114
diff -p -u -r1.114 mmc.c
--- libburn/mmc.c	2 Dec 2003 02:23:29 -0000	1.114
+++ libburn/mmc.c	4 Dec 2003 15:41:49 -0000
@@ -26,6 +26,19 @@ static unsigned char MMC_WRITE_10[] = { 
 static unsigned char MMC_GET_CONFIGURATION[] ={ 0x46, 0, 0, 0, 0, 0, 16, 0, 0 };
 static unsigned char MMC_SYNC_CACHE[] = { 0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 16, 0, 0, 0, 8, 0 };
+static unsigned char MMC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0};
+
+void mmc_request_sense(struct drive *d, struct buffer *buf)
+{
+	struct command c;
+	c.oplen = sizeof(MMC_REQUEST_SENSE);
+	memcpy(c.opcode, MMC_REQUEST_SENSE, sizeof(MMC_REQUEST_SENSE));
+	c.page = buf;
+	c.page->sectors = 0;
+	c.page->bytes = 0;
+	c.dir = FROM_DRIVE;
+	d->issue_command(d, &c);
+}
 
 void mmc_get_event(struct drive *d)
 {
@@ -302,13 +315,15 @@ printf("%d, %d, %d, %d\n", c.sense[3], c
 	}
 }
 
-void mmc_erase(struct drive *d, int fast)
+void mmc_erase(struct drive *d, enum libburn_erase_types type)
 {
 	struct command c;
 
 	memcpy(c.opcode, MMC_ERASE, sizeof(MMC_ERASE));
-
-	c.opcode[1] = !!fast;
+	/* we need IMMED set to 1 to get the progress status */
+	c.opcode[1] = 16;
+	/* erasing type */
+	c.opcode[1] |= type;
 	c.oplen = sizeof(MMC_ERASE);
 	c.page = NULL;
 	c.dir = NO_TRANSFER;
Index: libburn/mmc.h
===================================================================
RCS file: /cvs/burn/burn/libburn/mmc.h,v
retrieving revision 1.32
diff -p -u -r1.32 mmc.h
--- libburn/mmc.h	13 Oct 2003 19:45:03 -0000	1.32
+++ libburn/mmc.h	4 Dec 2003 15:41:49 -0000
@@ -12,11 +12,11 @@ struct buffer;
 void mmc_read(struct drive *);
 
 void mmc_get_event(struct drive *);
-void mmc_write(struct drive *, int start, struct buffer *buf);
+void mmc_write(struct drive *, int, struct buffer *);
 void mmc_sync_cache(struct drive *);
 void mmc_load(struct drive *);
 void mmc_eject(struct drive *);
-void mmc_erase(struct drive *, int);
+void mmc_erase(struct drive *, enum libburn_erase_types type);
 void mmc_read_toc(struct drive *);
 void mmc_read_disc_info(struct drive *);
 void mmc_read_atip(struct drive *);
@@ -29,5 +29,6 @@ void mmc_set_speed(struct drive *, int, 
 void mmc_read_lead_in(struct drive *, struct buffer *);
 void mmc_perform_opc(struct drive *);
 void mmc_get_configuration(struct drive *);
+void mmc_request_sense(struct drive *, struct buffer *);
 
 #endif /*__MMC*/
Index: libburn/sg.c
===================================================================
RCS file: /cvs/burn/burn/libburn/sg.c,v
retrieving revision 1.106
diff -p -u -r1.106 sg.c
--- libburn/sg.c	2 Dec 2003 00:02:12 -0000	1.106
+++ libburn/sg.c	4 Dec 2003 15:41:51 -0000
@@ -121,6 +121,7 @@ static void enumerate_common(char *fname
 	out.send_parameters = spc_select_error_params;
 	out.send_write_parameters = spc_select_write_params;
 	out.sync_cache = mmc_sync_cache;
+	out.request_sense = mmc_request_sense;
 
 	out.idata = malloc(sizeof(struct scsi_inquiry_data));
 	out.idata->valid = 0;
Index: libburn/transport.h
===================================================================
RCS file: /cvs/burn/burn/libburn/transport.h,v
retrieving revision 1.87
diff -p -u -r1.87 transport.h
--- libburn/transport.h	2 Dec 2003 03:04:17 -0000	1.87
+++ libburn/transport.h	4 Dec 2003 15:41:52 -0000
@@ -114,7 +114,7 @@ unsigned char mediacatalog[13];
 	int (*issue_command) (struct drive *, struct command *);
 
 /* lower level functions */
-	void (*erase) (struct drive *, int);
+	void (*erase) (struct drive *, enum libburn_erase_types);
 	void (*getcaps) (struct drive *);
 	void (*write) (struct drive *, int, struct buffer *);
 	void (*read_toc) (struct drive *);
@@ -135,6 +135,7 @@ unsigned char mediacatalog[13];
 	void (*send_write_parameters) (struct drive *,
 	                               const struct libburn_write_opts *);
 	void (*sync_cache) (struct drive *);
+	void (*request_sense) (struct drive *, struct buffer *);
 	struct params params;
 	struct scsi_inquiry_data *idata;
 	struct scsi_mode_data *mdata;
Index: test/blank.c
===================================================================
RCS file: /cvs/burn/burn/test/blank.c,v
retrieving revision 1.11
diff -p -u -r1.11 blank.c
--- test/blank.c	25 Oct 2003 03:38:23 -0000	1.11
+++ test/blank.c	4 Dec 2003 15:41:52 -0000
@@ -15,6 +15,7 @@ static unsigned int n_drives;
 static void blank_disc(struct drive *drive)
 {
 	enum libburn_drive_status s;
+	struct libburn_progress progress;
 
 	if (libburn_drive_grab(drive, 1) != LIBBURN_GRAB_OK) {
 		fprintf(stderr, "Unable to open the drive!\n");
@@ -33,11 +34,14 @@ static void blank_disc(struct drive *dri
 		return;
 	}
 
-	fprintf(stderr, "Blanking disc...");
-	libburn_erase_disc(drive, 1);
-
-	while (libburn_drive_get_busy(drive, NULL))
-		usleep(1000);
+	fprintf(stderr, "Blanking disc...\n");
+	libburn_erase_disc(drive, LIBBURN_ERASE_MINIMAL);
+	fprintf(stderr, "please wait...\n");
+
+	while (libburn_drive_get_busy(drive, &progress)) {
+		fprintf(stderr, "%d\n", progress.abs_sector);
+		usleep(500);
+	}
 	fprintf(stderr, "Done\n");
 
 	libburn_drive_release(drive, 0);
Index: test/burniso.c
===================================================================
RCS file: /cvs/burn/burn/test/burniso.c,v
retrieving revision 1.35
diff -p -u -r1.35 burniso.c
--- test/burniso.c	2 Dec 2003 02:25:22 -0000	1.35
+++ test/burniso.c	4 Dec 2003 15:41:52 -0000
@@ -54,10 +54,10 @@ void burn_iso(struct drive *drive, const
 		return;
 	}
 	o = libburn_write_opts_new();
-	o->perform_opc = 1;
+	o->perform_opc = 0;
 	o->write_type = LIBBURN_WRITE_RAW;
 	o->block_type = LIBBURN_BLOCK_RAW16;
-	o->simulate = 1;
+	o->simulate = 0;
 	o->underrun_proof = 0;
 
 	libburn_structure_print_disc(disc);
@@ -65,7 +65,7 @@ void burn_iso(struct drive *drive, const
 	libburn_write_opts_free(o);
 
 	while (libburn_drive_get_busy(drive, NULL)) {
-		sleep(1);
+		sleep(100);
 	}
 	printf("\n");
 	libburn_drive_release(drive, 0);

--=-pIRI6xUk7jKcwMEBXSSK--