[Dvd-devel] dvdrecord speed= option fix

IWAMOTO Toshihiro <[email protected]> Wed, 22 Oct 2003 22:36:55 +0900
Newsgroups gmane.linux.dvdrtools.devel
Message-ID <[email protected]>
Hi,

Recently I burned 2 unreadable DVD-Rs (brand is "3E" ("ritek G03"))
out of 3 attempts.  dvdrecord's speed=1 option didn't work and my
Toshiba SD-R5002 burned them at 2x.
So I tried to make a patch to fix the speed option.
The point is to issue "set streaming" command, but I'm not sure this
patch works other models than mine as the MMC spec isn't quite
descriptive.

Please try this patch if you have same problem.  I guess "set cd
speed" command can be eliminated for DVD case, but I haven't tryed
that.

diff -ur dvdrtools-0.1.5.orig/cdrecord/cdrecord.h dvdrtools-0.1.5/cdrecord/cdrecord.h
--- dvdrtools-0.1.5.orig/cdrecord/cdrecord.h	2003-06-02 01:10:00.000000000 +0900
+++ dvdrtools-0.1.5/cdrecord/cdrecord.h	2003-10-21 01:55:43.000000000 +0900
@@ -601,6 +601,7 @@
 extern	int	scsi_start_stop_unit __PR((SCSI *scgp, int, int));
 extern	int	scsi_set_speed	__PR((SCSI *scgp, int readspeed, int writespeed));
 extern	int	scsi_get_speed	__PR((SCSI *scgp, int *readspeedp, int *writespeedp));
+extern	int	scsi_set_streaming	__PR((SCSI *scgp, int readspeed, int writespeed));
 extern	int	qic02		__PR((SCSI *scgp, int));
 extern	int	write_xg0	__PR((SCSI *scgp, caddr_t, long, long, int));
 extern	int	write_xg1	__PR((SCSI *scgp, caddr_t, long, long, int));
diff -ur dvdrtools-0.1.5.orig/cdrecord/drv_mmc.c dvdrtools-0.1.5/cdrecord/drv_mmc.c
--- dvdrtools-0.1.5.orig/cdrecord/drv_mmc.c	2003-06-02 01:10:00.000000000 +0900
+++ dvdrtools-0.1.5/cdrecord/drv_mmc.c	2003-10-21 01:57:05.000000000 +0900
@@ -62,7 +62,7 @@
 extern	int	lverbose;
 extern	int	xdebug;
 
-LOCAL	int	curspeed = 1;
+LOCAL	int	curspeed = 177;
 
 LOCAL	int	mmc_load		__PR((SCSI *scgp));
 LOCAL	int	mmc_unload		__PR((SCSI *scgp));
@@ -1219,7 +1219,7 @@
 	int	val;
 
 	if (speedp)
-		curspeed = *speedp;
+		curspeed = *speedp * 177;
 	deflt_writemodes_mmc(scgp);
 
 	fillbytes((caddr_t)mode, sizeof(mode), '\0');
@@ -1261,13 +1261,13 @@
 	 * But the standard is rounding the wrong way.
 	 * Furtunately rounding down is guaranteed.
 	 */
-	if (scsi_set_speed(scgp, -1, curspeed*177) < 0)
+	if (scsi_set_speed(scgp, -1, curspeed) < 0)
 		return (-1);
 
 	if (scsi_get_speed(scgp, 0, &val) >= 0) {
 		if (val > 0) {
-			curspeed = val / 176;
-			*speedp = curspeed;
+			curspeed = val;
+			*speedp = curspeed / 176;
 		}
 	}
 	return (0);
@@ -1275,18 +1275,57 @@
 
 LOCAL int speed_select_mdvd(SCSI *scgp, int *speedp, int dummy)
 {
-  int retcode;
-  /* For the moment we just divide the CD speed by 7*/
+	Uchar	mode[0x100];
+	int	len;
+	struct	cd_mode_page_05 *mp;
+	int	val;
 
-  if(speedp!=NULL)
-     (*speedp)=(*speedp)*8;
-  
-  retcode=speed_select_mmc(scgp,speedp,dummy);
+	if (speedp)
+		curspeed = *speedp * 1350;
+	deflt_writemodes_mmc(scgp);
 
-  if(speedp!=NULL)
-     (*speedp)=(*speedp)/7;
-   return retcode;
- 
+	fillbytes((caddr_t)mode, sizeof(mode), '\0');
+
+	if (!get_mode_params(scgp, 0x05, "CD 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);
+#ifdef	DEBUG
+	scg_prbytes("CD write parameter:", (Uchar *)mode, len);
+#endif
+
+
+	mp->test_write = dummy != 0;
+
+#ifdef	DEBUG
+	scg_prbytes("CD write parameter:", (Uchar *)mode, len);
+#endif
+	if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
+		return (-1);
+
+	if (speedp == 0)
+		return (0);
+	/*
+	 * Neither set nor get speed.
+	 */
+
+	if (scsi_set_speed(scgp, -1, curspeed) < 0)
+		return (-1);
+
+	if (scsi_set_streaming(scgp, curspeed, curspeed) < 0)
+		return (-1);
+
+	if (scsi_get_speed(scgp, 0, &val) >= 0) {
+		if (val > 0) {
+			*speedp = curspeed / 1349;
+		}
+	}
+	return (0);
 }
 
 LOCAL int next_wr_addr_mmc(SCSI *scgp, int track, track_t *trackp, long *ap)
@@ -1757,8 +1796,8 @@
 	scgp->silent--;
 
 	if (ret >= 0) {
-		wait_unit_ready(scgp, 420/curspeed);	/* XXX Wait for ATAPI */
-		waitfix_mmc(scgp, 420/curspeed);	/* XXX Wait for ATAPI */
+		wait_unit_ready(scgp, 420*177/curspeed);	/* XXX Wait for ATAPI */
+		waitfix_mmc(scgp, 420*177/curspeed);	/* XXX Wait for ATAPI */
 		return (ret);
 	}
 
@@ -1789,7 +1828,7 @@
 	}
 
 	wait_unit_ready(scgp, 420);	/* XXX Wait for ATAPI */
-	waitfix_mmc(scgp, 420/curspeed);/* XXX Wait for ATAPI */
+	waitfix_mmc(scgp, 420*177/curspeed);/* XXX Wait for ATAPI */
 
 	if (!dummy &&
 		(ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) {
@@ -1801,14 +1840,14 @@
 		 */
 		gettimeofday(&stoptime, (struct timezone *)0);
 		timevaldiff(&starttime, &stoptime);
-		if (stoptime.tv_sec < (220 / curspeed)) {
+		if (stoptime.tv_sec < (220*177 / curspeed)) {
 			unsigned secs;
 
 			if (lverbose) {
 				printf("Actual fixating time: %ld seconds\n",
 							(long)stoptime.tv_sec);
 			}
-			secs = (280 / curspeed) - stoptime.tv_sec;
+			secs = (280*177 / curspeed) - stoptime.tv_sec;
 			if (lverbose) {
 				printf("ATAPI early return: sleeping %d seconds.\n",
 								secs);
diff -ur dvdrtools-0.1.5.orig/cdrecord/scsi_cdr.c dvdrtools-0.1.5/cdrecord/scsi_cdr.c
--- dvdrtools-0.1.5.orig/cdrecord/scsi_cdr.c	2003-06-02 01:10:01.000000000 +0900
+++ dvdrtools-0.1.5/cdrecord/scsi_cdr.c	2003-10-21 01:55:05.000000000 +0900
@@ -76,6 +76,7 @@
 EXPORT	int	scsi_start_stop_unit __PR((SCSI *scgp, int, int));
 EXPORT	int	scsi_set_speed	__PR((SCSI *scgp, int readspeed, int writespeed));
 EXPORT	int	scsi_get_speed	__PR((SCSI *scgp, int *readspeedp, int *writespeedp));
+EXPORT	int	scsi_set_streaming __PR((SCSI *scgp, int readspeed, int writespeed));
 EXPORT	int	qic02		__PR((SCSI *scgp, int));
 EXPORT	int	write_xg0	__PR((SCSI *scgp, caddr_t, long, long, int));
 EXPORT	int	write_xg1	__PR((SCSI *scgp, caddr_t, long, long, int));
@@ -459,6 +460,36 @@
 	return (0);
 }
 
+EXPORT int scsi_set_streaming(SCSI *scgp, int readspeed, int writespeed)
+{
+	register struct	scg_cmd	*scmd = scgp->scmd;
+	char pdesc[28];
+
+	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
+	fillbytes((caddr_t)pdesc, sizeof(pdesc), '\0');
+	scmd->addr = pdesc;
+	scmd->size = sizeof(pdesc);
+	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.g5_cdb.lun = scg_lun(scgp);
+	i_to_2_byte(&scmd->cdb.g5_cdb.addr[7], sizeof(pdesc));
+
+	i_to_4_byte(&pdesc[4], 0);
+	i_to_4_byte(&pdesc[8], scgp->cap->c_baddr);
+	i_to_4_byte(&pdesc[12], readspeed);
+	i_to_4_byte(&pdesc[16], 1000);	/* read time (ms) */
+	i_to_4_byte(&pdesc[20], writespeed);
+	i_to_4_byte(&pdesc[24], 1000);	/* read time (ms) */
+
+	scgp->cmdname = "set streaming";
+
+	if (scg_cmd(scgp) < 0)
+		return (-1);
+	return (0);
+}
+
 
 EXPORT int qic02(SCSI *scgp, int cmd)
 {


--
IWAMOTO Toshihiro