Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > by-pkgid > 21f13155242f3dc81c4414a9b60319f5 > files > 9

cdrecord-2.01.01-0.a11.2.2mdv2007.0.src.rpm

--- cdrtools-2.01.01/libscg/scsi-linux-sg.c.dvd	2005-11-22 23:09:39.000000000 +0100
+++ cdrtools-2.01.01/libscg/scsi-linux-sg.c	2006-01-26 14:32:51.000000000 +0100
@@ -372,7 +372,7 @@
 				 * own belly button.
 				 */
 				js_fprintf((FILE *)scgp->errfile,
-				"Warning: Using badly designed ATAPI via /dev/hd* interface.\n");
+				"#########################################################################################\n#\n#  Warning: Using ATAPI via /dev/hd* interface. Use dev=ATA:X,Y,Z or dev=/dev/hdX\n\#\n#########################################################################################\n");
 			}
 		}
 	}
--- cdrtools-2.01.01/libscg/scsitransp.c.dvd	2004-06-17 22:20:27.000000000 +0200
+++ cdrtools-2.01.01/libscg/scsitransp.c	2006-01-26 14:32:51.000000000 +0100
@@ -107,6 +107,7 @@
 EXPORT	int	scg_sense_key	__PR((SCSI *scgp));
 EXPORT	int	scg_sense_code	__PR((SCSI *scgp));
 EXPORT	int	scg_sense_qual	__PR((SCSI *scgp));
+EXPORT	unsigned char *scg_sense_table	__PR((SCSI *scgp));
 EXPORT	void	scg_fprintdev	__PR((FILE *, struct scsi_inquiry *));
 EXPORT	void	scg_printdev	__PR((struct scsi_inquiry *));
 EXPORT	int	scg_printf	__PR((SCSI *scgp, const char *form, ...));
@@ -1239,6 +1240,23 @@
 }
 
 /*
+ * Return all the SCSI sense table last command.
+ */
+EXPORT unsigned char *
+scg_sense_table(scgp)
+	SCSI	*scgp;
+{
+	register struct scg_cmd *cp = scgp->scmd;
+
+	if(!scg_cmd_err(scgp))
+		return (0);
+
+	if (cp->sense.code >= 0x70)
+	return &(cp->sense);
+}
+
+
+/*
  * Return the SCSI sense code for last command.
  */
 EXPORT int
--- cdrtools-2.01.01/cdrecord/cdr_drv.c.dvd	2004-03-02 02:06:26.000000000 +0100
+++ cdrtools-2.01.01/cdrecord/cdr_drv.c	2006-01-26 14:32:51.000000000 +0100
@@ -41,6 +41,7 @@
 extern	cdr_t	cdr_oldcd;
 extern	cdr_t	cdr_cd;
 extern	cdr_t	cdr_mmc;
+extern  cdr_t   cdr_mdvd;
 extern	cdr_t	cdr_mmc_sony;
 extern	cdr_t	cdr_cd_dvd;
 extern	cdr_t	cdr_philips_cdd521O;
@@ -79,6 +80,7 @@
 cdr_t	*drivers[] = {
 	&cdr_cd_dvd,
 	&cdr_mmc,
+        &cdr_mdvd,
 	&cdr_mmc_sony,
 	&cdr_cd,
 	&cdr_oldcd,
--- cdrtools-2.01.01/cdrecord/cdrecord.c.dvd	2006-01-26 14:31:31.000000000 +0100
+++ cdrtools-2.01.01/cdrecord/cdrecord.c	2006-01-26 14:32:51.000000000 +0100
@@ -179,6 +179,7 @@
 LOCAL	void	susage		__PR((int));
 LOCAL	void	usage		__PR((int));
 LOCAL	void	blusage		__PR((int));
+LOCAL	void	formattypeusage	__PR((int));
 LOCAL	void	intr		__PR((int sig));
 LOCAL	void	catchsig	__PR((int sig));
 LOCAL	int	scsi_cb		__PR((void *arg));
@@ -215,9 +216,9 @@
 LOCAL	BOOL	checkdsize	__PR((SCSI *scgp, cdr_t *dp,
 					long tsize, int flags));
 LOCAL	void	raise_fdlim	__PR((void));
-LOCAL	void	gargs		__PR((int, char **, int *, track_t *, char **,
+LOCAL	int	gargs		__PR((int, char **, int *, track_t *, char **,
 					int *, cdr_t **,
-					int *, long *, int *));
+					int *, long *, int *, int *));
 LOCAL	void	set_trsizes	__PR((cdr_t *, int, track_t *));
 EXPORT	void	load_media	__PR((SCSI *scgp, cdr_t *, BOOL));
 EXPORT	void	unload_media	__PR((SCSI *scgp, cdr_t *, int));
@@ -237,6 +238,7 @@
 LOCAL	void	wait_input	__PR((void));
 LOCAL	void	checkgui	__PR((void));
 LOCAL	int	getbltype	__PR((char *optstr, long *typep));
+LOCAL	int	getformattype	__PR((char *optstr, long *typep));
 LOCAL	void	print_drflags	__PR((cdr_t *dp));
 LOCAL	void	print_wrmodes	__PR((cdr_t *dp));
 LOCAL	BOOL	check_wrmode	__PR((cdr_t *dp, int wmode, int tflags));
@@ -261,6 +263,7 @@
 	int	speed = -1;
 	long	flags = 0L;
 	int	blanktype = 0;
+	int	formattype = 0;
 	int	i;
 	int	tracks = 0;
 	int	trackno;
@@ -272,6 +275,9 @@
 	SCSI	*scgp = NULL;
 	char	errstr[80];
 	BOOL	gracedone = FALSE;
+	int     ispacket;
+	BOOL	is_cdwr = FALSE;
+	BOOL	is_dvdwr = FALSE;
 
 #ifdef __EMX__
 	/* This gives wildcard expansion with Non-Posix shells with EMX */
@@ -280,14 +286,13 @@
 	save_args(ac, av);
 	oeuid = geteuid();		/* Remember saved set uid	*/
 
-
 	fillbytes(track, sizeof (track), '\0');
 	for (i = 0; i < MAX_TRACK+2; i++)
 		track[i].track = track[i].trackno = i;
 	track[0].tracktype = TOC_MASK;
 	raise_fdlim();
-	gargs(ac, av, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
-							&blanktype);
+	ispacket = gargs(ac, av, &tracks, track, &dev, &timeout, &dp, &speed, &flags,
+							&blanktype, &formattype);
 	if ((track[0].tracktype & TOC_MASK) == TOC_MASK)
 		comerrno(EX_BAD, "Internal error: Bad TOC type.\n");
 
@@ -464,7 +469,6 @@
 		wait_input();
 	}
 
-
 	/*
 	 * Call scg_remote() to force loading the remote SCSI transport library
 	 * code that is located in librscg instead of the dummy remote routines
@@ -482,12 +486,18 @@
 	 */
 	if ((scgp = scg_open(dev, errstr, sizeof (errstr),
 				debug, (flags & F_MSINFO) == 0 || lverbose)) == (SCSI *)0) {
+ 	    	if (dev != NULL || (flags & F_SCANBUS) == 0 || (scgp = scg_open("ATA", errstr, sizeof (errstr),
+ 		       	        debug, (flags & F_MSINFO) == 0 || lverbose)) == (SCSI *)0) {
 			errmsg("%s%sCannot open SCSI driver.\n", errstr, errstr[0]?". ":"");
 			errmsgno(EX_BAD, "For possible targets try 'cdrecord -scanbus'.%s\n",
 						geteuid() ? " Make sure you are root.":"");
 			errmsgno(EX_BAD, "For possible transport specifiers try 'cdrecord dev=help'.\n");
 			exit(EX_BAD);
+ 		} else {
+ 			dev = "ATA";
+ 		}
 	}
+
 	/*
 	 * XXX Below this point we do not need root privilleges anymore.
 	 */
@@ -504,6 +514,7 @@
 #endif
 			comerr("Panic cannot set back effective uid.\n");
 	}
+
 	/*
 	 * WARNING: We now are no more able to do any privilleged operation
 	 * unless we have been called by root.
@@ -579,6 +590,7 @@
 			comerr("Cannot reset target.\n");
 		exit(0);
 	}
+
 	/*
 	 * First try to check which type of SCSI device we
 	 * have.
@@ -619,6 +631,46 @@
 	} else if (!is_unknown_dev(scgp) && dp != get_cdrcmds(scgp)) {
 		errmsgno(EX_BAD, "WARNING: Trying to use other driver on known device.\n");
 	}
+        is_mmc(scgp, &is_cdwr, &is_dvdwr);
+        if (ispacket) {
+	    if (is_dvdwr) {
+		track[0].flags |= TI_PACKET; 
+		/*XXX put here to only affect DVD writing, should be in gargs.
+		 * however if set in args for all mode, packet writing is then
+		 * broken for all disc as cdrecord assume that PACKET imply TAO which  
+		 * is not true at all???? */ 
+		track[0].flags &= ~TI_TAO;
+	    }
+	}
+	/* DVD does not support TAO */
+	if (dp->is_dvd) {
+	        printf("Using Session At Once (SAO) for DVD mode.\n");
+		dp->cdr_flags |= F_SAO;
+		for (i = 0; i <= MAX_TRACK; i++) {
+		    track[i].flags &= ~TI_TAO;
+		    track[i].flags |= TI_SAO;
+		}
+	}
+        is_mmc(scgp, &is_cdwr, &is_dvdwr);
+        if (ispacket) {
+	    if (is_dvdwr) {
+		track[0].flags |= TI_PACKET; 
+		/*XXX put here to only affect DVD writing, should be in gargs.
+		 * however if set in args for all mode, packet writing is then
+		 * broken for all disc as cdrecord assume that PACKET imply TAO which  
+		 * is not true at all???? */ 
+		track[0].flags &= ~TI_TAO;
+	    }
+	}
+	/* DVD does not support TAO */
+	if (dp->is_dvd) {
+	        printf("Using Session At Once (SAO) for DVD mode.\n");
+		dp->cdr_flags |= F_SAO;
+		for (i = 0; i <= MAX_TRACK; i++) {
+		    track[i].flags &= ~TI_TAO;
+		    track[i].flags |= TI_SAO;
+		}
+	}
 
 	if (!is_cddrive(scgp))
 		comerrno(EX_BAD, "Sorry, no CD/DVD-Drive found on this target.\n");
@@ -644,13 +696,31 @@
 		dsp->ds_minbuf = 0xFFFF;
 		dp->cdr_dstat = dsp;
 	}
+        is_mmc(scgp, &is_cdwr, &is_dvdwr);
+        if (ispacket) {
+	    if (is_dvdwr) {
+		track[0].flags |= TI_PACKET; 
+		/*XXX put here to only affect DVD writing, should be in gargs.
+		 * however if set in args for all mode, packet writing is then
+		 * broken for all disc as cdrecord assume that PACKET imply TAO which  
+		 * is not true at all???? */ 
+		track[0].flags &= ~TI_TAO;
+	    }
+	}
+	/* DVD does not support TAO */
+	if (dp->is_dvd) {
+	        printf("Using Session At Once (SAO) for DVD mode.\n");
+		dp->cdr_flags |= F_SAO;
+		for (i = 0; i <= MAX_TRACK; i++) {
+		    track[i].flags &= ~TI_TAO;
+		    track[i].flags |= TI_SAO;
+		}
+	}
 
 	if ((flags & (F_MSINFO|F_TOC|F_LOAD|F_DLCK|F_EJECT)) == 0 ||
 	    tracks > 0 ||
 	    cuefilename != NULL) {
 
-		BOOL	is_cdwr = FALSE;
-		BOOL	is_dvdwr = FALSE;
 
 		if ((dp->cdr_flags & CDR_ISREADER) != 0) {
 			errmsgno(EX_BAD,
@@ -660,7 +730,7 @@
 		if (!is_mmc(scgp, &is_cdwr, &is_dvdwr))
 			is_cdwr = TRUE;			/* If it is not MMC, it must be a CD writer */
 
-		if (is_dvdwr && !set_cdrcmds("mmc_dvd", (cdr_t **)NULL)) {
+		if (is_dvdwr && !set_cdrcmds("mmc_mdvd", (cdr_t **)NULL)) {
 			errmsgno(EX_BAD,
 			"This version of cdrecord does not include DVD-R/DVD-RW support code.\n");
 			errmsgno(EX_BAD,
@@ -965,11 +1035,6 @@
 		print_toc(scgp, dp);
 		comexit(0);
 	}
-	if ((flags & F_FORMAT) != 0) {
-		errmsgno(EX_BAD, "Format option not implemented in this version.\n");
-		comexit(EX_BAD);
-	}
-
 #ifdef	XXX
 	if ((*dp->cdr_check_session)() < 0) {
 		comexit(EX_BAD);
@@ -1013,6 +1078,7 @@
 			if (setreuid(-1, oeuid) < 0)
 				errmsg("Could set back effective uid.\n");
 		}
+
 #endif
 		/*
 		 * fork() here to start the extra process needed for
@@ -1032,6 +1098,7 @@
 			if (setreuid(-1, getuid()) < 0)
 				comerr("Panic cannot set back effective uid.\n");
 		}
+
 #endif
 	}
 	if ((*dp->cdr_set_speed_dummy)(scgp, dp, &speed) < 0) {
@@ -1173,6 +1240,15 @@
 		errs++;
 		goto restore_it;
 	}
+	
+	if (dp->profile == 0x2B && flags & F_SAO && tsize > 0) {
+	    printf("Preparing middle zone location for this DVD+R dual layer disc\n");
+	    if (!dp->cdr_layer_split(scgp, dp, tsize)) {
+		errmsgno(EX_BAD, "Cannot send structure for middle zone location.\n");
+		comexit(EX_BAD);
+	    }
+	}
+
 	if (tracks > 0 && fs > 0l) {
 		/*
 		 * Wait for the read-buffer to become full.
@@ -1194,7 +1270,39 @@
 	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
 		errmsg("Cannot get start time\n");
 
-	/*
+	if (flags & F_FORMAT) {
+	    	printf("cdrecord: media format asked\n");
+		/*
+		 * Do not abort if OPC failes. Just give it a chance
+		 * for better laser power calibration than without OPC.
+		 *
+		 * Ricoh drives return with a vendor unique sense code.
+		 * This is most likely because they refuse to do OPC
+		 * on a non blank media.
+		 */
+		scgp->silent++;
+		do_opc(scgp, dp, flags);
+		scgp->silent--;
+		wait_unit_ready(scgp, 120);
+		if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+			errmsg("Cannot get start time\n");
+
+		if ((*dp->cdr_format)(scgp, dp, formattype) < 0) {
+			errmsgno(EX_BAD, "Cannot format disk, aborting.\n");
+			comexit(EX_BAD);
+		}
+		if (gettimeofday(&fixtime, (struct timezone *)0) < 0)
+			errmsg("Cannot get format time\n");
+		if (lverbose)
+			prtimediff("Formatting time: ", &starttime, &fixtime);
+
+		if (!wait_unit_ready(scgp, 240) || tracks == 0) {
+			comexit(0);
+		}
+		if (gettimeofday(&starttime, (struct timezone *)0) < 0)
+			errmsg("Cannot get start time\n");
+	}	
+        /*
 	 * Blank the media if we were requested to do so
 	 */
 	if (flags & F_BLANK) {
@@ -1251,6 +1359,14 @@
 		trackno = 0;
 	}
 	scgp->silent--;
+	
+	/* If it is DVD, the information in TOC is fabricated :)
+	 The real information is from read disk info command*/
+	if((dp->cdr_dstat->ds_disktype&DT_DVD) && (dp->cdr_dstat->ds_trlast>0)){
+	    trackno=dp->cdr_dstat->ds_trlast-1;
+	    printf("trackno=%d\n",trackno);
+	}
+
 	if ((tracks + trackno) > MAX_TRACK) {
 		/*
 		 * XXX How many tracks are allowed on a DVD?
@@ -1435,8 +1551,8 @@
 	if (gracetime > 999)
 		gracetime = 999;
 
-	printf("Starting to write CD/DVD at speed %d in %s%s %s mode for %s session.\n",
-		(int)dp->cdr_dstat->ds_wspeed,
+	printf("Starting to write CD/DVD at speed %5.1f in %s%s %s mode for %s session.\n",
+		(float)dp->cdr_dstat->ds_wspeed,
 		(dp->cdr_cmdflags & F_DUMMY) ? "dummy" : "real",
 		(dp->cdr_cmdflags & F_FORCE) ? " force" : "",
 		wm2name[dp->cdr_dstat->ds_wrmode],
@@ -1552,6 +1668,7 @@
 			(tlast.tv_sec * 1.0 + tlast.tv_usec * 0.000001);
 		if (fspeed > 999.0)
 			fspeed = 999.0;
+		if (dp->is_dvd) fspeed /= 9;
 		printf("Average write speed %5.1fx.\n", fspeed);
 	}
 
@@ -1606,7 +1723,7 @@
 	error("\t-checkdrive	check if a driver for the drive is present\n");
 	error("\t-prcap		print drive capabilities for MMC compliant drives\n");
 	error("\t-inq		do an inquiry for the drive and exit\n");
-	error("\t-scanbus	scan the SCSI bus and exit\n");
+	error("\t-scanbus	scan the SCSI and IDE buses and exit\n");
 	error("\t-reset		reset the SCSI bus with the cdrecorder (if possible)\n");
 	error("\t-abort		send an abort sequence to the drive (may help if hung)\n");
 	error("\t-overburn	allow to write more than the official size of a medium\n");
@@ -1614,7 +1731,8 @@
 	error("\t-useinfo	use *.inf files to overwrite audio options.\n");
 	error("\tspeed=#		set speed of drive\n");
 	error("\tblank=type	blank a CD-RW disc (see blank=help)\n");
-	error("\t-format		format a CD-RW/DVD-RW/DVD+RW disc\n");
+	error("\tformat		format a CD-RW/DVD-RW/DVD+RW disc\n");
+	error("\tformattype=#	select the format method for DVD+RW disc\n");
 #ifdef	FIFO
 	error("\tfs=#		Set fifo size to # (0 to disable, default is %ld MB)\n",
 							DEFAULT_FIFOSIZE/(1024L*1024L));
@@ -1700,6 +1818,18 @@
 	/* NOTREACHED */
 }
 
+LOCAL void
+formattypeusage(ret)
+	int	ret;
+{
+	error("Formating options:\n");
+	error("\tfull\t\tstandard formating\n");
+	error("\tbackground\t\tbackground formating\n");
+	error("\tforce\t\tforce reformat\n");
+
+	exit(ret);
+	/* NOTREACHED */
+}
 /* ARGSUSED */
 LOCAL void
 intr(sig)
@@ -2169,6 +2299,7 @@
 					usleep(wt*1000);
 			}
 #endif
+			if (dp->is_dvd) fspeed /= 9;
 			printf(" %5.1fx", fspeed);
 			printf(".");
 			savbytes = (bytes >> 20) << 20;
@@ -2186,6 +2317,7 @@
 			oper = per;
 			flush();
 		}
+
 #endif
 	} while (tracksize < 0 || bytes_read < tracksize);
 
@@ -2882,6 +3014,7 @@
 	long	startsec = 0L;
 	long	endsec = 0L;
 	dstat_t	*dsp = dp->cdr_dstat;
+	int	profile;
 
 	scgp->silent++;
 	(*dp->cdr_next_wr_address)(scgp, (track_t *)0, &startsec);
@@ -2982,13 +3115,23 @@
 		/*
 		 * dsp->ds_maxblocks == 0 (disk capacity is unknown).
 		 */
-		if (endsec >= (405000-300)) {			/*<90 min disk*/
+	        profile = dp->profile;
+	        if (endsec >= (4200000)) {
+		        errmsgno(EX_BAD,
+			"ERROR: Could not manage to find medium size, and more than 8.0 GB of data.\n");
+  		        goto toolarge;  
+		} else if (profile != 0x2B) { 
+		    if (endsec >= (2300000)) {
 			errmsgno(EX_BAD,
-				"Data will not fit on any disk.\n");
+				"ERROR: Could not manage to find medium size, and more than 4.3 GB of data for a non dual layer disc.\n");
 			goto toolarge;
-		} else if (endsec >= (333000-150)) {		/* 74 min disk*/
+		    } else if (endsec >= (405000-300)) {            /*<90 min disk or DVD*/
+			errmsgno(EX_BAD,
+				"WARNING: Could not manage to find medium size, and more than 90 mins of data.\n");
+		    } else if (endsec >= (333000-150)) {		/* 74 min disk*/
 			errmsgno(EX_BAD,
-			"WARNING: Data may not fit on standard 74min disk.\n");
+				"WARNING: Data may not fit on standard 74min disk.\n");
+		    }
 		}
 	}
 	if (dsp->ds_maxblocks <= 0 || endsec <= dsp->ds_maxblocks)
@@ -3059,7 +3202,7 @@
 }
 
 char	*opts =
-"help,version,checkdrive,prcap,inq,scanbus,reset,abort,overburn,ignsize,useinfo,dev*,timeout#,driver*,driveropts*,setdropts,tsize&,padsize&,pregap&,defpregap&,speed#,load,lock,eject,dummy,msinfo,toc,atip,multi,fix,nofix,waiti,immed,debug#,d+,kdebug#,kd#,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,audio,data,mode2,xa,xa1,xa2,xamix,cdi,isosize,nopreemp,preemp,nocopy,copy,nopad,pad,swab,fs&,ts&,blank&,format,pktsize#,packet,noclose,force,tao,dao,sao,raw,raw96r,raw96p,raw16,clone,scms,isrc*,mcn*,index*,cuefile*,textfile*,text,shorttrack,noshorttrack,gracetime#,minbuf#";
+"help,version,checkdrive,prcap,inq,scanbus,reset,abort,overburn,ignsize,useinfo,dev*,timeout#,driver*,driveropts*,setdropts,tsize&,padsize&,pregap&,defpregap&,speed#,load,lock,eject,dummy,msinfo,toc,atip,multi,fix,nofix,waiti,immed,debug#,d+,kdebug#,kd#,verbose+,v+,Verbose+,V+,x+,xd#,silent,s,audio,data,mode2,xa,xa1,xa2,xamix,cdi,isosize,nopreemp,preemp,nocopy,copy,nopad,pad,swab,fs&,ts&,blank&,format,formattype&,pktsize#,packet,noclose,force,tao,dao,sao,raw,raw96r,raw96p,raw16,clone,scms,isrc*,mcn*,index*,cuefile*,textfile*,text,shorttrack,noshorttrack,gracetime#,minbuf#";
 
 /*
  * Defines used to find whether a write mode has been specified.
@@ -3069,8 +3212,8 @@
 #define	M_RAW		4	/* Raw mode */
 #define	M_PACKET	8	/* Packed mode */
 
-LOCAL void
-gargs(ac, av, tracksp, trackp, devp, timeoutp, dpp, speedp, flagsp, blankp)
+LOCAL int
+gargs(ac, av, tracksp, trackp, devp, timeoutp, dpp, speedp, flagsp, blankp, formatp)
 	int	ac;
 	char	**av;
 	int	*tracksp;
@@ -3081,6 +3224,7 @@
 	int	*speedp;
 	long	*flagsp;
 	int	*blankp;
+	int	*formatp;
 {
 	int	cac;
 	char	* const*cav;
@@ -3093,6 +3237,7 @@
 	char	*textfile = NULL;
 	long	bltype = -1;
 	int	doformat = 0;
+	int	formattype = -1;
 	Llong	tracksize;
 	Llong	padsize;
 	long	pregapsize;
@@ -3208,7 +3353,7 @@
 				&nopreemp, &preemp,
 				&nocopy, &copy,
 				&nopad, &pad, &bswab, getnum, &fs, getnum, &bufsize,
-				getbltype, &bltype, &doformat, &pktsize,
+				getbltype, &bltype, &doformat, getformattype, &formattype, &pktsize,
 				&ispacket, &noclose, &force,
 				&tao, &dao, &dao, &raw, &raw96r, &raw96p, &raw16,
 				&clone,
@@ -3289,8 +3434,14 @@
 				*flagsp |= F_BLANK;
 				*blankp = bltype;
 			}
-			if (doformat)
-				*flagsp |= F_FORMAT;
+ 			if (doformat > 0) {
+ 				*flagsp |= F_FORMAT;
+ 				*formatp |= FULL_FORMAT;
+ 			}
+ 			if (formattype >= 0) {
+ 				*flagsp |= F_FORMAT;
+ 				*formatp |= formattype;
+ 			}
 			if (ispacket)
 				wm |= M_PACKET;
 			if (tao)
@@ -3595,8 +3746,6 @@
 			errmsgno(EX_BAD, "No write mode specified.\n");
 			errmsgno(EX_BAD, "Asuming -tao mode.\n");
 			errmsgno(EX_BAD, "Future versions of cdrecord may have different drive dependent defaults.\n");
-			errmsgno(EX_BAD, "Continuing in 5 seconds...\n");
-			sleep(5);
 			tao = 1;
 		}
 		tracks++;
@@ -3737,14 +3886,14 @@
 	    ((strncmp(*devp, "HELP", 4) == 0) ||
 	    (strncmp(*devp, "help", 4) == 0))) {
 		*flagsp |= F_CHECKDRIVE; /* Set this for not calling mlockall() */
-		return;
+		return ispacket;
 	}
 	if (*flagsp & (F_LOAD|F_DLCK|F_SETDROPTS|F_MSINFO|F_TOC|F_PRATIP|F_FIX|F_VERSION|F_CHECKDRIVE|F_PRCAP|F_INQUIRY|F_SCANBUS|F_RESET|F_ABORT)) {
 		if (tracks != 0) {
 			errmsgno(EX_BAD, "No tracks allowed with this option\n");
 			susage(EX_BAD);
 		}
-		return;
+		return ispacket;
 	}
 	*tracksp = tracks;
 	if (*flagsp & F_SAO) {
@@ -3773,12 +3922,13 @@
 			susage(EX_BAD);
 		}
 		cuefilename = cuefile;
-		return;
+		return ispacket;
 	}
 	if (tracks == 0 && (*flagsp & (F_LOAD|F_DLCK|F_EJECT|F_BLANK|F_FORMAT)) == 0) {
 		errmsgno(EX_BAD, "No tracks specified. Need at least one.\n");
 		susage(EX_BAD);
 	}
+	return ispacket;
 }
 
 LOCAL void
@@ -4451,6 +4601,26 @@
 	return (TRUE);
 }
 
+LOCAL int
+getformattype(optstr, typep)
+	char	*optstr;
+	long	*typep;
+{
+	if (streql(optstr, "full")) {
+		*typep = FULL_FORMAT;
+	} else if (streql(optstr, "background")) {
+		*typep = BACKGROUND_FORMAT;
+	} else if (streql(optstr, "force")) {
+		*typep = FORCE_FORMAT;
+	} else if (streql(optstr, "help")) {
+		formattypeusage(0);
+	} else {
+		error("Illegal blanking type '%s'.\n", optstr);
+		formattypeusage(EX_BAD);
+		return (-1);
+	}
+	return (TRUE);
+}
 LOCAL void
 print_drflags(dp)
 	cdr_t	*dp;
@@ -4618,6 +4788,7 @@
 	int	tflags;
 {
 	dstat_t	*dsp = dp->cdr_dstat;
+	int	profile;
 
 	if ((tflags & TI_PACKET) != 0) {
 		dsp->ds_wrmode = WM_PACKET;
@@ -4740,3 +4911,4 @@
 	}
 #endif
 }
+
--- cdrtools-2.01.01/cdrecord/cdrecord.h.dvd	2005-06-11 14:16:14.000000000 +0200
+++ cdrtools-2.01.01/cdrecord/cdrecord.h	2006-01-26 14:32:51.000000000 +0100
@@ -100,7 +100,7 @@
  * start writing.
  */
 #ifndef	MIN_GRACE_TIME
-#define	MIN_GRACE_TIME	3		/* 3 seconds */
+#define	MIN_GRACE_TIME	0		/* 3 seconds */
 #endif
 #ifndef	GRACE_TIME
 #define	GRACE_TIME	9		/* 9 seconds */
@@ -464,6 +464,20 @@
 #define	BLANK_SESSION	0x06	/* Erase the last session		  */
 
 /*
+ * Defines for formating DVD (custom values)
+ */
+#define	FULL_FORMAT       0x00    /* Interactive format  */
+#define	BACKGROUND_FORMAT 0x01    /* Background format   */
+#define	FORCE_FORMAT      0x02    /* Force reformat      */
+
+/*
+ * Defines for formating DVD (custom values)
+ */
+#define	FULL_FORMAT       0x00    /* Interactive format  */
+#define	BACKGROUND_FORMAT 0x01    /* Background format   */
+#define	FORCE_FORMAT      0x02    /* Force reformat      */
+
+/*
  * Useful definitions for audio tracks
  */
 #define	msample		(44100 * 2)		/* one 16bit audio sample */
@@ -578,6 +592,18 @@
 #define	DSF_NEED_FORMAT	0x0800	/* Disk needs to be formatted		*/
 
 /*
+ * Definitions for disktype flags
+ */
+#define DT_CD           0x001  /*is a CD                                */
+#define DT_DVD          0x002  /*is a DVD                               */
+
+/*
+ * Definitions for disktype flags
+ */
+#define DT_CD           0x001  /*is a CD                                */
+#define DT_DVD          0x002  /*is a DVD                               */
+
+/*
  * Definitions for disk_status disk type
  * used in "ds_type".
  */
@@ -719,6 +745,9 @@
 	int	(*cdr_opc)		__PR((SCSI *scgp, caddr_t bp, int cnt, int doopc));	/* Do OPC */
 	int	(*cdr_opt1)		__PR((SCSI *scgp, cdr_t *));			/* do early option processing*/
 	int	(*cdr_opt2)		__PR((SCSI *scgp, cdr_t *));			/* do late option processing */
+	int	(*cdr_layer_split)	__PR((SCSI *scgp, cdr_t *, long tsize));	/* calculate optimale split */
+	int	profile;
+	BOOL	is_dvd;
 };
 #endif
 
@@ -913,12 +942,16 @@
 extern	int	read_rzone_info	__PR((SCSI *scgp, caddr_t bp, int cnt));
 extern	int	reserve_tr_rzone __PR((SCSI *scgp, long size));
 extern	int	read_dvd_structure __PR((SCSI *scgp, caddr_t bp, int cnt, int addr, int layer, int fmt));
+extern	int	send_dvd_structure __PR((SCSI *scgp, caddr_t bp, int cnt, int layer, int fmt));
 extern	int	send_opc	__PR((SCSI *scgp, caddr_t, int cnt, int doopc));
 
 #define	CL_TYPE_STOP_DEICE	0	/* Stop De-icing a DVD+RW Media */
 #define	CL_TYPE_TRACK		1	/* Close Track # */
 #define	CL_TYPE_SESSION		2	/* Close Session/Border / Stop backgrnd. format */
 #define	CL_TYPE_INTER_BORDER	3	/* Close intermediate Border */
+#define	CL_TYPE_OPEN_SESSION	4	/* Close the Open Session and Record an Extended lead-out */
+#define	CL_TYPE_FINALISE_MINRAD	5	/* Finalize the Disc with a Minimum Recorded Radius */
+#define	CL_TYPE_FINALISE	6	/* Finalize the disc */
 extern	int	scsi_close_tr_session __PR((SCSI *scgp, int type, int track, BOOL immed));
 extern	int	read_master_cue	__PR((SCSI *scgp, caddr_t bp, int sheet, int cnt));
 extern	int	send_cue_sheet	__PR((SCSI *scgp, caddr_t bp, long size));
--- cdrtools-2.01.01/cdrecord/drv_mmc.c.dvd	2006-01-12 00:07:26.000000000 +0100
+++ cdrtools-2.01.01/cdrecord/drv_mmc.c	2006-01-26 14:32:51.000000000 +0100
@@ -83,8 +83,11 @@
 EXPORT	char	*hasdrvopt		__PR((char *optstr, char *optname));
 LOCAL	cdr_t	*identify_mmc		__PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
 LOCAL	int	attach_mmc		__PR((SCSI *scgp, cdr_t *));
+LOCAL   int     attach_mdvd             __PR((SCSI *scgp, cdr_t *));
 EXPORT	int	check_writemodes_mmc	__PR((SCSI *scgp, cdr_t *dp));
+EXPORT  int     check_writemodes_mdvd   __PR((SCSI *scgp, cdr_t *dp));
 LOCAL	int	deflt_writemodes_mmc	__PR((SCSI *scgp, BOOL reset_dummy));
+LOCAL   int     deflt_writemodes_mdvd   __PR((SCSI *scgp, BOOL reset_dummy));
 LOCAL	int	get_diskinfo		__PR((SCSI *scgp, struct disk_info *dip));
 LOCAL	void	di_to_dstat		__PR((struct disk_info *dip, dstat_t *dsp));
 LOCAL	int	get_atip		__PR((SCSI *scgp, struct atipinfo *atp));
@@ -93,18 +96,27 @@
 #endif
 LOCAL	int	init_mmc		__PR((SCSI *scgp, cdr_t *dp));
 LOCAL	int	getdisktype_mmc		__PR((SCSI *scgp, cdr_t *dp));
+LOCAL   int     getdisktype_mdvd        __PR((SCSI *scgp, cdr_t *dp));
 LOCAL	int	speed_select_mmc	__PR((SCSI *scgp, cdr_t *dp, int *speedp));
+LOCAL   int     speed_select_mdvd       __PR((SCSI *scgp, cdr_t *dp, int *speedp));
 LOCAL	int	mmc_set_speed		__PR((SCSI *scgp, int readspeed, int writespeed, int rotctl));
 LOCAL	int	next_wr_addr_mmc	__PR((SCSI *scgp, track_t *trackp, long *ap));
+LOCAL   int     next_wr_addr_mdvd       __PR((SCSI *scgp, track_t *trackp, long *ap));
 LOCAL	int	write_leadin_mmc	__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
 LOCAL	int	open_track_mmc		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL   int     open_track_mdvd         __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
 LOCAL	int	close_track_mmc		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL   int     close_track_mdvd        __PR((SCSI *scgp, cdr_t *dp, track_t *trackp)); 
 LOCAL	int	open_session_mmc	__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL   int     open_session_mdvd       __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
 LOCAL	int	waitfix_mmc		__PR((SCSI *scgp, int secs));
 LOCAL	int	fixate_mmc		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
+LOCAL   int     fixate_mdvd             __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
 LOCAL	int	blank_mmc		__PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
+LOCAL	int	format_mdvd		__PR((SCSI *scgp, cdr_t *dp, int formattype));
 LOCAL	int	send_opc_mmc		__PR((SCSI *scgp, caddr_t, int cnt, int doopc));
 LOCAL	int	opt1_mmc		__PR((SCSI *scgp, cdr_t *dp));
+LOCAL	int	opt1_mdvd		__PR((SCSI *scgp, cdr_t *dp));
 LOCAL	int	opt2_mmc		__PR((SCSI *scgp, cdr_t *dp));
 LOCAL	int	scsi_sony_write		__PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
 LOCAL	int	gen_cue_mmc		__PR((track_t *trackp, void *vcuep, BOOL needgap));
@@ -138,6 +150,7 @@
 LOCAL int	do_tattoo_yamaha	__PR((SCSI *scgp, FILE *f));
 LOCAL int	yamaha_write_buffer	__PR((SCSI *scgp, int mode, int bufferid, long offset,
 							long parlen, void *buffer, long buflen));
+LOCAL	int	dvd_dual_layer_split	__PR((SCSI *scgp, cdr_t *dp, long tsize));
 
 #ifdef	__needed__
 LOCAL int
@@ -201,6 +214,48 @@
 	opt2_mmc,
 };
 
+cdr_t   cdr_mdvd = {
+         0, 0,
+         CDR_SWABAUDIO,
+	 CDR_CDRW_ALL,
+ 	 370,370,
+         "mmc_mdvd",
+         "generic SCSI-3/mmc DVD-R(W) driver",
+         0,
+ 	 (dstat_t *)0,
+         identify_mmc,
+         attach_mdvd,
+	 init_mmc,
+         getdisktype_mdvd,
+         scsi_load,
+         scsi_unload,
+         read_buff_cap,
+         cmd_dummy,                              /* recovery_needed      */
+         (int(*)__PR((SCSI *, int)))cmd_dummy,   /* recover              */
+         speed_select_mdvd,
+         select_secsize,
+         next_wr_addr_mdvd,
+         (int(*)__PR((SCSI *, Ulong)))cmd_ill,   /* reserve_track        */
+         scsi_cdr_write,
+         (int(*)__PR((SCSI *scgp, int, track_t *)))cmd_dummy, /* gen_cue */
+	 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* send_cue */
+ 	 write_leadin_mmc,
+         open_track_mdvd,
+         close_track_mdvd,
+         open_session_mdvd,
+         cmd_dummy,
+	 cmd_dummy,					/* abort	*/
+         read_session_offset,
+         fixate_mdvd,
+ 	 stats_mmc,
+         blank_mmc,
+	 format_mdvd,
+         send_opc_mmc,
+ 	 opt1_mdvd,
+ 	 opt2_mmc,
+	 dvd_dual_layer_split,
+};
+
 /*
  * Sony MMC CD-writer
  */
@@ -568,7 +623,22 @@
 	if (profile >= 0) {
 		if (lverbose)
 			print_profiles(scgp);
-		if (profile == 0 || profile == 0x12 || profile > 0x19) {
+		if (profile == 0 || profile >= 0x10 && profile <= 0x15 || profile > 0x19) {
+		    /*
+		     * 10h DVD-ROM
+		     * 11h DVD-R
+		     * 12h DVD-RAM
+		     * 13h DVD-RW (Restricted overwrite)
+		     * 14h DVD-RW (Sequential recording)
+		     * 1Ah DVD+RW
+		     * 1Bh DVD+R
+		     * 2Bh DVD+R DL
+		     * 
+		     */
+		    if (profile == 0x11 || profile == 0x13 || profile == 0x14 || profile == 0x1A || profile == 0x1B || profile == 0x2B) {
+			is_dvd = TRUE;
+			dp = &cdr_mdvd;
+		    } else {
 			is_dvd = FALSE;
 			dp = &cdr_cd;
 
@@ -590,23 +660,8 @@
 				errmsgno(EX_BAD,
 				"Found unsupported DVD-RAM media.\n");
 				return (dp);
-			} else {			/* DVD+RW DVD+R */
-				errmsgno(EX_BAD,
-				"Found DVD+ media but DVD+R/DVD+RW support code is missing.\n");
-				errmsgno(EX_BAD,
-				"If you need DVD+R/DVD+RW support, ask the Author for cdrecord-ProDVD.\n");
-				errmsgno(EX_BAD,
-				"Free test versions and free keys for personal use are at ftp://ftp.berlios.de/pub/cdrecord/ProDVD/\n");
-				return (dp);
 			}
-		} else if (profile >= 0x10 && profile < 0x18) {
-			errmsgno(EX_BAD,
-			"Found DVD media but DVD-R/DVD-RW support code is missing.\n");
-			errmsgno(EX_BAD,
-			"If you need DVD-R/DVD-RW support, ask the Author for cdrecord-ProDVD.\n");
-			errmsgno(EX_BAD,
-			"Free test versions and free keys for personal use are at ftp://ftp.berlios.de/pub/cdrecord/ProDVD/\n");
-			return (dp);
+		    }
 		}
 	} else {
 		if (xdebug)
@@ -673,13 +728,12 @@
 #endif
 	}
 	if (is_dvd) {
-		errmsgno(EX_BAD,
-		"Found DVD media but DVD-R/DVD-RW support code is missing.\n");
-		errmsgno(EX_BAD,
-		"If you need DVD-R/DVD-RW support, ask the Author for cdrecord-ProDVD.\n");
-		errmsgno(EX_BAD,
-		"Free test versions and free keys for personal use are at ftp://ftp.berlios.de/pub/cdrecord/ProDVD/\n");
+ 	        errmsgno(EX_BAD, 
+                 "Found DVD media: using cdr_mdvd.\n");  
+                 dp = &cdr_mdvd; 
 	}
+	dp->profile = profile;
+	dp->is_dvd = is_dvd;
 	return (dp);
 }
 
@@ -885,6 +939,42 @@
 	return (0);
 }
 
+LOCAL int
+attach_mdvd(scgp, dp)
+        SCSI    *scgp;
+        cdr_t                   *dp;
+{
+        struct  cd_mode_page_2A *mp;
+	
+
+        allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */
+
+        scgp->silent++;
+        mp = mmc_cap(scgp, NULL);/* Get MMC capabilities in allocated mp */
+        scgp->silent--;
+        if (mp == NULL)
+                return (-1);    /* Pre SCSI-3/mmc drive         */
+
+        dp->cdr_cdcap = mp;     /* Store MMC cap pointer        */
+
+        if (mp->loading_type == LT_TRAY)
+                dp->cdr_flags |= CDR_TRAYLOAD;
+        else if (mp->loading_type == LT_CADDY)
+                dp->cdr_flags |= CDR_CADDYLOAD;
+
+        if (mp->BUF != 0)
+                dp->cdr_flags |= CDR_BURNFREE;
+
+        check_writemodes_mdvd(scgp, dp);
+
+        if (driveropts != NULL) {
+                if (strcmp(driveropts, "help") == 0) {
+                        mmc_opthelp(dp, 0);
+                }
+        }
+
+        return (0);
+}
 
 EXPORT int
 check_writemodes_mmc(scgp, dp)
@@ -956,8 +1046,6 @@
 	mp->fp = 0;
 	i_to_4_byte(mp->packet_size, 0);
 	mp->track_mode = TM_DATA;
-
-
 	mp->write_type = WT_SAO;
 
 	if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
@@ -1035,6 +1123,77 @@
 	return (0);
 }
 
+EXPORT int
+check_writemodes_mdvd(scgp, dp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+{
+	Uchar	mode[0x100];
+	int	len;
+	struct	cd_mode_page_05 *mp;
+
+	if (xdebug)
+		printf("Checking possible write modes: ");
+
+	deflt_writemodes_mdvd(scgp, FALSE);
+
+	fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+	scgp->silent++;
+	if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+			mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
+		scgp->silent--;
+		return (-1);
+	}
+	if (len == 0) {
+		scgp->silent--;
+		return (-1);
+	}
+
+	mp = (struct cd_mode_page_05 *)
+		(mode + sizeof(struct scsi_mode_header) +
+		((struct scsi_mode_header *)mode)->blockdesc_len);
+
+	mp->test_write = 0;
+
+	/*We only check for PACKET and SAO since these are the only supported modes for DVD */
+	/*XXX these checks are irrelevant because they are not medium sensitive. ie the device returns 
+	  error only when it does not support a given mode for ALL mediums. It should check using 
+	  GET CONFIGURATION command.*/
+
+	mp->write_type = WT_PACKET;
+	mp->fp = 0;
+	i_to_4_byte(mp->packet_size, 0);
+
+	if (set_mode_params(scgp, "DVD write parameter", mode, len, 0, -1)) {
+		dp->cdr_flags |= CDR_PACKET;
+		if (xdebug)
+		  printf("PACKET ");
+	} else
+	  dp->cdr_flags &= ~CDR_PACKET;
+	mp->fp = 0;
+	i_to_4_byte(mp->packet_size, 0);
+	mp->track_mode = TM_DATA; 
+
+
+	mp->write_type = WT_SAO;
+
+	if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
+		dp->cdr_flags |= CDR_SAO;
+		if (xdebug)
+			printf("SAO ");
+	} else
+		dp->cdr_flags &= ~CDR_SAO;
+
+
+	if (xdebug)
+		printf("\n");
+
+	deflt_writemodes_mdvd(scgp, TRUE);
+	scgp->silent--;
+	return (0);
+}
+
 LOCAL int
 deflt_writemodes_mmc(scgp, reset_dummy)
 	SCSI	*scgp;
@@ -1109,6 +1268,61 @@
 	return (0);
 }
 
+LOCAL int
+deflt_writemodes_mdvd(scgp, reset_dummy)
+	SCSI	*scgp;
+	BOOL	reset_dummy;
+{
+	Uchar	mode[0x100];
+	int	len;
+	struct	cd_mode_page_05 *mp;
+
+	fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+	scgp->silent++;
+	if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+			mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
+		scgp->silent--;
+		return (-1);
+	}
+	if (len == 0) {
+		scgp->silent--;
+		return (-1);
+	}
+
+	mp = (struct cd_mode_page_05 *)
+		(mode + sizeof(struct scsi_mode_header) +
+		((struct scsi_mode_header *)mode)->blockdesc_len);
+
+	mp->test_write = 0;
+	/*
+	 * This is the only place where we reset mp->test_write (-dummy)
+	 */
+	if (reset_dummy)
+		mp->test_write = 0;
+
+
+	/*
+	 * Set default values:
+	 * Write type = 02 (session at once)
+	 *
+	 * XXX Note:	the same code appears in check_writemodes_mmc() and
+	 * XXX		in speed_select_mmc().
+	 */
+	mp->write_type = WT_SAO;
+	mp->track_mode = TM_DATA; 
+	mp->dbtype = DB_ROM_MODE1;
+	mp->session_format = SES_DA_ROM;
+
+
+	if (set_mode_params(scgp, "DVD write parameter", mode, len, 0, -1) < 0) {
+		scgp->silent--;
+		return (-1);
+	}
+	scgp->silent--;
+	return (0);
+}
+
 #ifdef	PRINT_ATIP
 LOCAL	void	print_di		__PR((struct disk_info *dip));
 LOCAL	void	atip_printspeed		__PR((char *fmt, int speedindex, char speedtab[]));
@@ -1178,6 +1392,9 @@
 
 	if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
 		dsp->ds_last_leadout = dsp->ds_maxblocks;
+	dsp->ds_trfirst=dip->first_track; 
+	dsp->ds_trlast=dip->last_track_ls;
+	dsp->ds_trfirst_ls=dip->first_track_ls;
 }
 
 LOCAL int
@@ -1288,6 +1505,30 @@
 }
 
 LOCAL int
+getdisktype_mdvd(scgp, dp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+{
+       int ret = 0;
+       dstat_t	*dsp = dp->cdr_dstat;
+
+       struct track_info track_info;
+       if(getdisktype_mmc(scgp, dp)<0)
+	 return -1;
+
+       /* read rzone info to get the space left on disk */
+       /*ds_trlast is the last rzone on disk, can be invisible */
+       if(read_rzone_info(scgp, (caddr_t)&track_info, sizeof(track_info))>=0)
+	  dsp->ds_maxblocks=a_to_u_4_byte(track_info.free_blocks)+a_to_4_byte(track_info.next_writable_addr);
+       
+       dsp->ds_disktype&= ~DT_CD;
+       dsp->ds_disktype|= DT_DVD;
+	
+       return (ret);
+  
+}
+
+LOCAL int
 getdisktype_mmc(scgp, dp)
 	SCSI	*scgp;
 	cdr_t	*dp;
@@ -1299,6 +1540,7 @@
 	msf_t	msf;
 	BOOL	did_atip = FALSE;
 	BOOL	did_dummy = FALSE;
+	int 	rplus;
 
 	msf.msf_min = msf.msf_sec = msf.msf_frame = 0;
 
@@ -1366,8 +1608,13 @@
 	/*
 	 * Check for non writable disk first.
 	 */
+	
+	/* DVD+RW does not need to be blanked */
+	rplus = dsp->ds_cdrflags;
+	if (dp->profile == 0x1A) rplus = RF_BLANK;
+	
 	if (dip->disk_status == DS_COMPLETE &&
-			(dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
+			(rplus & dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
 		if (!did_dummy) {
 			int	xspeed = 0xFFFF;
 			int	oflags = dp->cdr_cmdflags;
@@ -1731,6 +1978,7 @@
 
 	if (scsi_get_speed(scgp, 0, &val) >= 0) {
 		if (val > 0) {
+		        printf("Speed set to %d KB/s\n", val); 
 			curspeed = val / 176;
 			*speedp = curspeed;
 		}
@@ -1793,6 +2041,68 @@
 }
 
 LOCAL int
+speed_select_mdvd(scgp, dp, speedp)
+	SCSI	*scgp;
+	cdr_t   *dp;
+	int	*speedp;
+{
+  int retcode;
+  unsigned char perf_desc[28];
+  int write_speed = *speedp * 1385;
+  int val = 0, val2 = 0;
+  int i;
+   
+  /* For the moment we just divide the CD speed by 7*/
+
+  if(speedp!=NULL)
+     (*speedp)=(*speedp)*8;
+  
+  memset(perf_desc, 0, sizeof(perf_desc));
+
+  /* Write Rotation Control = ROTCTL_CLV 
+   * | Restore Logical Unit Defaults = 0 
+   * | Exact = 0 
+   * | Random Access = 0) 
+   */
+  perf_desc[0]= ROTCTL_CLV << 3 | 0 << 2 | 0 << 1 | 0; 
+  /* Start LBA to 0 */
+  perf_desc[4] = 0;
+  perf_desc[5] = 0;
+  perf_desc[6] = 0;
+  perf_desc[7] = 0;
+  /* End LBA set to 0 (setting to 0xffffffff failed on my LG burner
+   */
+  perf_desc[8] = 0;
+  perf_desc[9] = 0;
+  perf_desc[10] = 0;
+  perf_desc[11] = 0;
+  /* Read Speed = 0xFFFF */
+  perf_desc[12] = 0;
+  perf_desc[13] = 0;
+  perf_desc[14] = 0xFF;
+  perf_desc[15] = 0xFF;
+  /* Read Time = 1s */
+  perf_desc[18] = 1000 >> 8;
+  perf_desc[19] = 1000 & 0xFF;   
+  /* Write Speed */
+  perf_desc[20] = write_speed >> 24;
+  perf_desc[21] = write_speed >> 16 & 0xFF;
+  perf_desc[22] = write_speed >> 8 & 0xFF;
+  perf_desc[23] = write_speed & 0xFF;
+  /* Write Time = 1s */
+  perf_desc[26] = 1000 >> 8;
+  perf_desc[27] = 1000 & 0xFF;  
+  
+  //retcode = scsi_set_streaming(scgp, NULL, 0);
+  retcode = scsi_set_streaming(scgp, &perf_desc, sizeof(perf_desc));
+  if (retcode == -1) return retcode;
+  retcode = speed_select_mmc(scgp, dp, speedp);
+  if(speedp!=NULL)
+     (*speedp)=(*speedp)/7;
+   return retcode;
+}
+
+LOCAL int
 next_wr_addr_mmc(scgp, trackp, ap)
 	SCSI	*scgp;
 	track_t	*trackp;
@@ -1929,6 +2239,49 @@
 };
 
 LOCAL int
+next_wr_addr_mdvd(scgp, trackp, ap)
+	SCSI	*scgp;
+	track_t	*trackp;
+	long	*ap;
+{
+	int     track=0;
+	struct	track_info	track_info;
+	long	next_addr;
+	int	result = -1;
+	struct  disk_info disk_info;
+	if (trackp){
+	    track = trackp->trackno;
+	}
+
+	if (trackp != 0 && track > 0 && is_packet(trackp)) {
+		scgp->silent++;
+		result = read_track_info(scgp, (caddr_t)&track_info, TI_TYPE_SESS, track, sizeof(track_info));
+		scgp->silent--;
+		if (scsi_in_progress(scgp)){
+		  return -1;
+		}
+		
+	}
+
+	if (result < 0) {
+	  /* Get the last rzone*/
+	        if(read_disk_info(scgp,(caddr_t)&disk_info,8)<0)
+		  return (-1);
+	     
+		/* if (read_track_info(scgp, (caddr_t)&track_info, TI_TYPE_SESS, 0xFF, sizeof(track_info)) < 0) */
+		    if (read_rzone_info(scgp, (caddr_t)&track_info, sizeof(track_info)) < 0)
+			return (-1);
+	}
+	if (scgp->verbose)
+		scg_prbytes("track info:", (Uchar *)&track_info,
+				sizeof(track_info)-scg_getresid(scgp));
+	next_addr = a_to_4_byte(track_info.next_writable_addr);
+	if (ap)
+		*ap = next_addr;
+	return (0);
+}
+
+LOCAL int
 open_track_mmc(scgp, dp, trackp)
 	SCSI	*scgp;
 	cdr_t	*dp;
@@ -2009,6 +2362,45 @@
 }
 
 LOCAL int
+open_track_mdvd(scgp, dp, trackp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+	track_t *trackp;
+{
+	Uchar	mode[0x100];
+	int	len;
+	struct	cd_mode_page_05 *mp;
+
+	if (is_packet(trackp)) {
+	       fillbytes((caddr_t)mode, sizeof(mode), '\0');
+	  
+	       if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+			mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
+	              return (-1);
+	       if (len == 0)
+		      return (-1);
+
+	        mp = (struct cd_mode_page_05 *)
+	              (mode + sizeof(struct scsi_mode_header) +
+		      ((struct scsi_mode_header *)mode)->blockdesc_len);
+
+		mp->write_type = WT_PACKET;
+		mp->LS_V = 1;
+		/*For now we set the link size to 0x10(32k) because Pioneer-A03 only support this */
+		mp->link_size=0x10;
+		mp->fp = 1;
+		i_to_4_byte(mp->packet_size, trackp->pktsize);
+	} else {
+	     return 0;
+	}
+ 
+	if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, trackp->secsize))
+		return (-1);
+
+	return (0);
+}
+
+LOCAL int
 close_track_mmc(scgp, dp, trackp)
 	SCSI	*scgp;
 	cdr_t	*dp;
@@ -2034,6 +2426,30 @@
 	return (0);
 }
 
+LOCAL int
+close_track_mdvd(scgp, dp, trackp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+	track_t	*trackp;
+{
+	int	ret;
+	if (!is_packet(trackp))
+	     return (0);
+
+	if (scsi_flush_cache(scgp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
+		printf("Trouble flushing the cache\n");
+		return -1;
+	}
+	wait_unit_ready(scgp, 300);		/* XXX Wait for ATAPI */
+	if (is_packet(trackp) && !is_noclose(trackp)) {
+			/* close the incomplete track */
+		ret = scsi_close_tr_session(scgp, 1, 0xFF, (dp->cdr_cmdflags&F_IMMED) != 0);
+		wait_unit_ready(scgp, 300);	/* XXX Wait for ATAPI */
+		return (ret);
+	}
+	return (0);
+}
+
 int	toc2sess[] = {
 	SES_DA_ROM,	/* CD-DA		 */
 	SES_DA_ROM,	/* CD-ROM		 */
@@ -2117,6 +2533,84 @@
 }
 
 LOCAL int
+open_session_mdvd(scgp, dp, trackp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+	track_t	*trackp;
+{
+	Uchar	mode[0x100];
+	int	tracks = trackp->tracks;
+
+	int	len;
+	struct	cd_mode_page_05 *mp;
+	Ulong totalsize;
+	int i;
+	struct	track_info	track_info;
+	int profile;
+
+	fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+	if (!get_mode_params(scgp, 0x05, "DVD write parameter",
+			mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
+		return (-1);
+	if (len == 0)
+		return (-1);
+
+	mp = (struct cd_mode_page_05 *)
+		(mode + sizeof(struct scsi_mode_header) +
+		((struct scsi_mode_header *)mode)->blockdesc_len);
+	if(is_packet(trackp)){
+	  mp->write_type=WT_PACKET;
+	  mp->fp=0;
+	  mp->BUFE=1;
+	  mp->track_mode=1;
+	}else{
+	  mp->write_type = WT_SAO; 
+	}
+
+	mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ?
+				MS_MULTI : MS_NONE;
+	mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
+	
+	if (lverbose && dp->cdr_cdcap->BUF != 0)
+		printf("BURN-Free is %s.\n", mp->BUFE?"ON":"OFF");
+	if (driveropts != NULL) {
+		if ((strcmp(driveropts, "burnproof") == 0 ||
+		    strcmp(driveropts, "burnfree") == 0) && dp->cdr_cdcap->BUF != 0) {
+			errmsgno(EX_BAD, "Turning BURN-Free on\n");
+			mp->BUFE = 1;
+		} else if ((strcmp(driveropts, "noburnproof") == 0 ||
+			   strcmp(driveropts, "noburnfree") == 0)) {
+			errmsgno(EX_BAD, "Turning BURN-Free off\n");
+			mp->BUFE = 0;
+		} else if (strcmp(driveropts, "help") == 0) {
+			mmc_opthelp(dp, 0);
+		} else {
+			errmsgno(EX_BAD, "Bad driver opts '%s'.\n", driveropts);
+			mmc_opthelp(dp, EX_BAD);
+		}
+	}
+
+
+	if (!set_mode_params(scgp, "DVD write parameter", mode, len, 0, -1))
+		return (-1);
+
+		
+	totalsize=0;
+	for(i=1;i<=tracks;i++) {
+	  totalsize+=trackp[i].tracksecs;
+	}
+       
+	profile = get_curprofile(scgp);
+	if(!is_packet(trackp) && profile != 0x1A){
+	  /* in DAO mode we need to reserve space for the track*/
+	  if(reserve_track(scgp, totalsize)<0)
+	    return (-1);
+	  }
+	return (0);
+}
+
+LOCAL int
 waitfix_mmc(scgp, secs)
 	SCSI	*scgp;
 	int	secs;
@@ -2155,6 +2649,7 @@
 	struct timeval stoptime;
 	int	dummy = (track_base(trackp)->tracktype & TOCF_DUMMY) != 0;
 
+	printf("fixate_mmc\n");
 	starttime.tv_sec = 0;
 	starttime.tv_usec = 0;
 	stoptime = starttime;
@@ -2164,6 +2659,7 @@
 		printf("WARNING: Some drives don't like fixation in dummy mode.\n");
 
 	scgp->silent++;
+	printf("is_tao: %d,is_packet: %d\n", is_tao(trackp), is_packet(trackp));
 	if (is_tao(trackp) || is_packet(trackp)) {
 		ret = scsi_close_tr_session(scgp, CL_TYPE_SESSION, 0,
 				(dp->cdr_cmdflags&F_IMMED) != 0);
@@ -2246,6 +2742,30 @@
 	return (ret);
 }
 
+LOCAL int
+fixate_mdvd(scgp, dp, trackp)
+	SCSI	*scgp;
+	cdr_t   *dp;
+	track_t	*trackp;
+{
+      /*set a really BIG timeout and call fixate_mmc
+	 The BIG timeout is needed in case there was a very short rzone to write at the 
+	 beginning of the disk, because lead-out needs to be at some distance.
+      */
+      printf("fixate_mdvd\n");
+      scg_settimeout(scgp, 1000);
+      if(is_packet(trackp) || dp->profile == 0x1B){
+	  scsi_close_tr_session(scgp, CL_TYPE_SESSION, 0, FALSE);
+      }
+      fixate_mmc(scgp, dp, trackp);
+      if (dp->profile == 0x2B) {
+	  scsi_close_tr_session(scgp, CL_TYPE_OPEN_SESSION, 0, FALSE);
+	  scsi_close_tr_session(scgp, CL_TYPE_FINALISE_MINRAD, 0, FALSE);
+      }
+      scg_settimeout(scgp, 200);
+      
+}
+
 char	*blank_types[] = {
 	"entire disk",
 	"PMA, TOC, pregap",
@@ -2257,6 +2777,12 @@
 	"reserved blanking type",
 };
 
+char	*format_types[] = {
+	"full format",
+	"background format",
+	"forced format",
+};
+
 LOCAL int
 blank_mmc(scgp, dp, addr, blanktype)
 	SCSI	*scgp;
@@ -2269,11 +2795,16 @@
 	BOOL	cdrrw	 = FALSE;	/* Read CD-RW	*/
 	BOOL	cdwrw	 = FALSE;	/* Write CD-RW	*/
 	int	ret;
+	int 	profile;
 
 	mmc_check(scgp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, NULL);
 	if (!cdwrw)
 		return (blank_dummy(scgp, dp, addr, blanktype));
 
+	if (dp->profile == 0x1A) {
+		printf("Error: this media does not support blanking, ignoring.\n");
+		return (blank_dummy(scgp, dp, addr, blanktype));
+	}
 	if (lverbose) {
 		printf("Blanking %s\n", blank_types[blanktype & 0x07]);
 		flush();
@@ -2289,6 +2820,80 @@
 }
 
 LOCAL int
+format_mdvd(scgp, dp, formattype)
+	SCSI	*scgp;
+	cdr_t	*dp;
+	int	formattype;
+{
+extern	char	*buf;
+	BOOL	dvdwr	 = FALSE;	/* Write DVD	*/
+	int	ret;
+	int 	profile;
+	char	addr[12];
+	struct disk_info *dip;
+
+	printf("format_mdvd\n");
+	mmc_check(scgp, NULL, NULL, NULL, NULL, NULL, &dvdwr);
+	if (!dvdwr)
+		return (format_dummy(scgp, dp, formattype));
+
+	printf("format_mdvd: drive is a dvd burner.\n");
+	profile = get_curprofile(scgp);
+	if (profile != 0x1A) {
+		printf("Error: only support DVD+RW formating, ignoring.\n");
+	        return (format_dummy(scgp, dp, formattype));
+	}
+	printf("format_mdvd: media is a DVD+RW.\n");
+	dip = (struct disk_info *)buf;
+	if (get_diskinfo(scgp, dip) < 0)
+		return ret;
+	
+	if (dip->disk_status & 3 && formattype != FORCE_FORMAT) {
+		printf("Error: disk already formated, ignoring.\n");
+	        return ret;
+        }
+	addr[0] = 0;           // "Reserved"
+	addr[1] = 2;           // "IMMED" flag
+	addr[2] = 0;           // "Descriptor Length" (MSB)
+	addr[3] = 8;           // "Descriptor Length" (LSB)
+	addr[4+0] = 0xff;
+	addr[4+1] = 0xff;
+	addr[4+2] = 0xff;
+	addr[4+3] = 0xff;
+	addr[4+4] = 0x26<<2;
+	addr[4+5] = 0;
+	addr[4+6] = 0;
+	addr[4+7] = 0;
+	if (formattype == FORCE_FORMAT) {
+	    printf("format_mdvd: forcing reformat.\n"); 
+	    formattype = FULL_FORMAT;
+	    addr[4+0] = 0;
+	    addr[4+1] = 0;
+	    addr[4+2] = 0;
+	    addr[4+3] = 0;
+	    addr[4+7] = 1;
+	} else {
+	    printf("format_mdvd: media is unformated.\n"); 
+	}
+
+	if (lverbose) {
+		printf("Formating %s\n", format_types[formattype & 0x07]);
+		flush();
+	}
+	if (formattype == FULL_FORMAT) {
+	    ret = scsi_format(scgp, &addr, sizeof(addr), FALSE);
+	} else {
+	    ret = scsi_format(scgp, &addr, sizeof(addr), TRUE);
+	}
+	if (ret < 0)
+		return (ret);
+
+	wait_unit_ready(scgp, 90*60/curspeed);	/* XXX Wait for ATAPI */
+	waitfix_mmc(scgp, 90*60/curspeed);	/* XXX Wait for ATAPI */
+	return (ret);
+}
+
+LOCAL int
 send_opc_mmc(scgp, bp, cnt, doopc)
 	SCSI	*scgp;
 	caddr_t	bp;
@@ -2518,6 +3123,43 @@
 }
 
 LOCAL int
+opt1_mdvd(scgp, dp)
+	SCSI	*scgp;
+	cdr_t	*dp;
+{
+	int	oflags = dp->cdr_dstat->ds_cdrflags;
+
+	if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) {
+		printf("Turning Audio Master Q. R. on\n");
+		if (set_audiomaster_yamaha(scgp, dp, TRUE) < 0)
+			return (-1);
+		if (!debug && lverbose <= 1)
+			dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP;
+		if (getdisktype_mdvd(scgp, dp) < 0) {
+			dp->cdr_dstat->ds_cdrflags = oflags;
+			return (-1);
+		}
+		dp->cdr_dstat->ds_cdrflags = oflags;
+		if (oflags & RF_PRATIP) {
+			msf_t   msf;
+			lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
+			printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
+				(long)dp->cdr_dstat->ds_first_leadin,
+		                msf.msf_min,
+        		        msf.msf_sec,
+                		msf.msf_frame);
+			lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
+			printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
+				(long)dp->cdr_dstat->ds_maxblocks,
+		                msf.msf_min,
+        		        msf.msf_sec,
+                		msf.msf_frame);
+		}
+	}
+	return (0);
+}
+
+LOCAL int
 scsi_sony_write(scgp, bp, sectaddr, size, blocks, islast)
 	SCSI	*scgp;
 	caddr_t	bp;		/* address of buffer */
@@ -3780,3 +4422,48 @@
 		return (1);
 	return (0);
 }
+
+LOCAL int
+dvd_dual_layer_split(scgp, dp, tsize)
+	SCSI	*scgp;
+	cdr_t 	*dp;
+	long 	tsize;
+{
+    unsigned char	xb[12];
+    int		i;
+    long 	l0_size;
+    
+    /* Get the Layer 0 defined data zone*/
+    if (read_dvd_structure(scgp, (caddr_t)xb, 12, 0, 0, 0x20) >= 0) {
+	if ((xb[1] | xb[0] << 8) < 13) {
+	    error("dvd_dual_layer_split: read_dvd_structure returns invalid data\n");
+	    return 1;
+	}
+	if (xb[4] & 0x80) {
+	    printf("L0 zone size already set\n");
+	    return 1;
+	}
+	l0_size = xb[11] | xb[10] << 8 | xb[9] << 16 | xb[8] << 24;
+	if (tsize < l0_size) {
+	    error("track size smaller than one layer, use --force to force burning.");
+	    return 0;
+	}
+	printf("L0 size: %l (track size %l)\n", l0_size, tsize);
+	l0_size = tsize / 2;
+	l0_size = l0_size - 1 + 16 - (l0_size - 1) % 16;
+	printf("New L0 size: %l\n", l0_size);
+
+	memset (xb, 0, sizeof(xb));
+	xb[1]  = sizeof(xb) - 2;
+	xb[8]  = l0_size >> 24;
+	xb[9]  = l0_size >> 16;
+	xb[10] = l0_size >> 8;
+	xb[11] = l0_size;
+	if (send_dvd_structure(scgp, (caddr_t)xb, 12, 0, 0x20)) {
+	    error("dvd_dual_layer_split: send_dvd_structure failed, could not set middle zone location.\n");
+	    return 0;
+	}
+    }
+   return 1;
+}
+
--- cdrtools-2.01.01/cdrecord/scsi_cdr.c.dvd	2004-05-25 00:36:01.000000000 +0200
+++ cdrtools-2.01.01/cdrecord/scsi_cdr.c	2006-01-26 14:32:51.000000000 +0100
@@ -99,6 +99,7 @@
 EXPORT	int	read_rzone_info	__PR((SCSI *scgp, caddr_t bp, int cnt));
 EXPORT	int	reserve_tr_rzone __PR((SCSI *scgp, long size));
 EXPORT	int	read_dvd_structure __PR((SCSI *scgp, caddr_t bp, int cnt, int addr, int layer, int fmt));
+EXPORT	int	send_dvd_structure __PR((SCSI *scgp, caddr_t bp, int cnt, int layer, int fmt));
 EXPORT	int	send_opc	__PR((SCSI *scgp, caddr_t, int cnt, int doopc));
 EXPORT	int	read_track_info_philips	__PR((SCSI *scgp, caddr_t, int, int));
 EXPORT	int	scsi_close_tr_session __PR((SCSI *scgp, int type, int track, BOOL immed));
@@ -106,6 +107,8 @@
 EXPORT	int	send_cue_sheet	__PR((SCSI *scgp, caddr_t bp, long size));
 EXPORT	int	read_buff_cap	__PR((SCSI *scgp, long *, long *));
 EXPORT	int	scsi_blank	__PR((SCSI *scgp, long addr, int blanktype, BOOL immed));
+EXPORT	int	scsi_format	__PR((SCSI *scgp, caddr_t addr, int size, BOOL background));
+EXPORT	int	scsi_set_streaming	__PR((SCSI *scgp, caddr_t addr, int size));
 EXPORT	BOOL	allow_atapi	__PR((SCSI *scgp, BOOL new));
 EXPORT	int	mode_select	__PR((SCSI *scgp, Uchar *, int, int, int));
 EXPORT	int	mode_sense	__PR((SCSI *scgp, Uchar *dp, int cnt, int page, int pcf));
@@ -518,6 +521,32 @@
 }
 
 EXPORT int
+scsi_set_streaming(scgp, perf_desc, size)
+	SCSI	*scgp;
+	caddr_t	perf_desc;
+	int	size;
+{
+	register struct	scg_cmd	*scmd = scgp->scmd;
+
+	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
+	scmd->addr = perf_desc;
+	scmd->size = size;
+	scmd->flags = SCG_DISRE_ENA;
+	scmd->cdb_len = SC_G5_CDBLEN;
+	scmd->sense_len = CCS_SENSE_LEN;
+	scmd->cdb.g5_cdb.cmd = 0xB6;
+	scmd->cdb.cmd_cdb[11] = 0;
+	scmd->cdb.cmd_cdb[10] = size;
+
+	scgp->cmdname = "set streaming";
+
+	printf("scsi_set_streaming\n");
+	if (scg_cmd(scgp) < 0)
+		return (-1);
+	return (0);
+}
+    
+EXPORT int
 scsi_set_speed(scgp, readspeed, writespeed, rotctl)
 	SCSI	*scgp;
 	int	readspeed;
@@ -1042,6 +1071,31 @@
 }
 
 EXPORT int
+reserve_track(scgp, size)
+	SCSI	*scgp;
+	Ulong	size;
+
+{
+	register struct	scg_cmd	*scmd = scgp->scmd;
+
+	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+	scmd->flags = SCG_DISRE_ENA;
+	scmd->cdb_len = SC_G1_CDBLEN;
+	scmd->sense_len = CCS_SENSE_LEN;
+	scmd->cdb.g1_cdb.cmd = 0x53;
+	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
+	i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size);
+
+	scgp->cmdname = "reserve track";
+
+	if (scg_cmd(scgp) < 0) 
+		return (-1);
+
+	return (0);
+
+}
+
+EXPORT int
 read_rzone_info(scgp, bp, cnt)
 	SCSI	*scgp;
 	caddr_t	bp;
@@ -1108,6 +1162,36 @@
 }
 
 EXPORT int
+send_dvd_structure(scgp, bp, cnt, layer, fmt)
+	SCSI	*scgp;
+	caddr_t	bp;
+	int	cnt;
+	int	layer;
+	int	fmt;
+{
+	register struct	scg_cmd	*scmd = scgp->scmd;
+
+	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
+	scmd->addr = bp;
+	scmd->size = cnt;
+	scmd->flags = SCG_DISRE_ENA;
+	scmd->cdb_len = SC_G5_CDBLEN;
+	scmd->sense_len = CCS_SENSE_LEN;
+	scmd->timeout = 4 * 60;		/* Needs up to 2 minutes ??? */
+	scmd->cdb.g5_cdb.cmd = 0xBF;
+	scmd->cdb.g5_cdb.lun = scg_lun(scgp);
+	g5_cdblen(&scmd->cdb.g5_cdb, cnt);
+
+	scmd->cdb.cmd_cdb[7] = fmt;
+
+	scgp->cmdname = "send dvd structure";
+
+	if (scg_cmd(scgp) < 0)
+		return (-1);
+	return (0);
+}
+
+EXPORT int
 send_opc(scgp, bp, cnt, doopc)
 	SCSI	*scgp;
 	caddr_t	bp;
@@ -1322,6 +1406,71 @@
 	return (scg_cmd(scgp));
 }
 
+EXPORT int
+scsi_format(scgp, addr, size, background)
+	SCSI	*scgp;
+	caddr_t	addr;
+	int 	size;
+	BOOL 	background;
+{
+	register struct	scg_cmd	*scmd = scgp->scmd;
+	int progress=0, ret=-1, pid=-1;
+	unsigned char sense_table[18];
+	int i;
+	
+	printf("scsi_format: preparing\n");
+
+	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+	scmd->addr = addr;
+	scmd->size = size;
+	scmd->flags = SCG_DISRE_ENA;
+	scmd->cdb_len = SC_G5_CDBLEN;
+	scmd->sense_len = CCS_SENSE_LEN;
+	scmd->timeout = 160 * 60;     /* Do not know what to set */
+	scmd->cdb.g5_cdb.cmd = 0x04;   /* Format Unit */
+	scmd->cdb.cmd_cdb[1] = 0x11;  /* "FmtData" and "Format Code" */
+	scmd->cdb.cmd_cdb[5] = 0;
+
+	scgp->cmdname = "format unit";
+
+	printf("scsi_format: running\n");
+	ret = (scg_cmd(scgp));
+	printf("scsi_format: post processing %d\n", ret);
+	if (ret == -1) return ret;
+	if (background) {
+		if ((pid=fork()) == (pid_t)-1)
+			perror ("- [unable to fork()]");
+		else {
+			if (!pid) {
+			    while (1) {
+				if (test_unit_ready(scgp) >= 0)
+				    break;
+				sleep(1);
+			    }
+			    return ret;
+			}
+		}
+	}
+	printf("Formating in progress: 0.00 %% done.");
+	sleep(20);
+	i = 0;
+	while (progress < 0xfff0 && !(progress == 0 && i > 50)) {
+		test_unit_ready(scgp);
+		request_sense_b(scgp, (caddr_t)sense_table, 18);
+		progress = sense_table[16]<<8|sense_table[17];
+		printf("\rFormating in progress: %.2f %% done [%d].                           ", (float)(progress*100)/0x10000,progress);
+		usleep(100000);
+		i++;
+		/*for (i=0; i < 18; i++) {
+		    printf("%d ", sense_table[i]);
+		}*/
+	}
+	sleep(10);
+	printf("\rFormating in progress: 100.00 %% done.        \n");
+	if (pid) exit (0);
+	return ret;
+}
+
 /*
  * XXX First try to handle ATAPI:
  * XXX ATAPI cannot handle SCSI 6 byte commands.