Browse Source

Plan 9 from Bell Labs 2008-03-12

David du Colombier 16 years ago
parent
commit
2411169244

+ 8 - 7
dist/replica/_plan9.db

@@ -172,7 +172,7 @@
 386/bin/calendar - 775 sys sys 1200262736 79060
 386/bin/cat - 775 sys sys 1148500611 37482
 386/bin/cb - 775 sys sys 1168402293 77628
-386/bin/cdfs - 775 sys sys 1205008816 166835
+386/bin/cdfs - 775 sys sys 1205293084 169996
 386/bin/cec - 775 sys sys 1193714267 75896
 386/bin/cfs - 775 sys sys 1190863294 130565
 386/bin/chgrp - 775 sys sys 1168402294 59522
@@ -5513,7 +5513,7 @@ rc/bin/dial - 20000000775 sys sys 1059180057 0
 rc/bin/diffy - 775 sys sys 1140694870 277
 rc/bin/dircp - 775 sys sys 1186289104 181
 rc/bin/diskparts - 775 sys sys 1178399618 624
-rc/bin/dmaon - 775 sys sys 1178214935 213
+rc/bin/dmaon - 775 sys sys 1205288448 220
 rc/bin/doc2ps - 775 sys sys 1069793831 244
 rc/bin/doc2txt - 775 sys sys 1025197880 563
 rc/bin/doctype - 775 sys sys 1162921755 1727
@@ -7721,7 +7721,7 @@ sys/man/4/INDEX - 664 sys sys 1196638942 1026
 sys/man/4/INDEX.html - 664 sys sys 1196638942 5147
 sys/man/4/acme - 664 sys sys 1196638943 10435
 sys/man/4/archfs - 664 sys sys 1196638943 533
-sys/man/4/cdfs - 664 sys sys 1205203382 4352
+sys/man/4/cdfs - 664 sys sys 1205253247 4351
 sys/man/4/cfs - 664 sys sys 1196638943 2136
 sys/man/4/consolefs - 664 sys sys 1196638943 4389
 sys/man/4/cwfs - 664 sys sys 1196638943 6553
@@ -10015,12 +10015,12 @@ sys/src/cmd/cc/scon.c - 664 sys sys 1138463621 8788
 sys/src/cmd/cc/sub.c - 664 sys sys 1143759345 34268
 sys/src/cmd/cc/y.tab.h - 664 sys sys 1098501521 1680
 sys/src/cmd/cdfs - 20000000775 sys sys 1039727558 0
-sys/src/cmd/cdfs/buf.c - 664 sys sys 1205203460 1851
-sys/src/cmd/cdfs/dat.h - 664 sys sys 1205203455 3753
+sys/src/cmd/cdfs/buf.c - 664 sys sys 1205271166 1923
+sys/src/cmd/cdfs/dat.h - 664 sys sys 1205281336 4538
 sys/src/cmd/cdfs/fns.h - 664 sys sys 969542122 297
-sys/src/cmd/cdfs/main.c - 664 sys sys 1205203482 11360
+sys/src/cmd/cdfs/main.c - 664 sys sys 1205281456 11687
 sys/src/cmd/cdfs/mkfile - 664 sys sys 1204937991 153
-sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205203566 26493
+sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205281492 27209
 sys/src/cmd/cec - 20000000775 sys sys 1193683647 0
 sys/src/cmd/cec/LICENSE - 664 sys sys 1186248056 1554
 sys/src/cmd/cec/Protocol - 664 sys sys 1186248056 2881
@@ -15869,3 +15869,4 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205295078 27297

+ 7 - 7
dist/replica/plan9.db

@@ -172,7 +172,7 @@
 386/bin/calendar - 775 sys sys 1200262736 79060
 386/bin/cat - 775 sys sys 1148500611 37482
 386/bin/cb - 775 sys sys 1168402293 77628
-386/bin/cdfs - 775 sys sys 1205008816 166835
+386/bin/cdfs - 775 sys sys 1205293084 169996
 386/bin/cec - 775 sys sys 1193714267 75896
 386/bin/cfs - 775 sys sys 1190863294 130565
 386/bin/chgrp - 775 sys sys 1168402294 59522
@@ -5513,7 +5513,7 @@ rc/bin/dial - 20000000775 sys sys 1059180057 0
 rc/bin/diffy - 775 sys sys 1140694870 277
 rc/bin/dircp - 775 sys sys 1186289104 181
 rc/bin/diskparts - 775 sys sys 1178399618 624
-rc/bin/dmaon - 775 sys sys 1178214935 213
+rc/bin/dmaon - 775 sys sys 1205288448 220
 rc/bin/doc2ps - 775 sys sys 1069793831 244
 rc/bin/doc2txt - 775 sys sys 1025197880 563
 rc/bin/doctype - 775 sys sys 1162921755 1727
@@ -7721,7 +7721,7 @@ sys/man/4/INDEX - 664 sys sys 1196638942 1026
 sys/man/4/INDEX.html - 664 sys sys 1196638942 5147
 sys/man/4/acme - 664 sys sys 1196638943 10435
 sys/man/4/archfs - 664 sys sys 1196638943 533
-sys/man/4/cdfs - 664 sys sys 1205203382 4352
+sys/man/4/cdfs - 664 sys sys 1205253247 4351
 sys/man/4/cfs - 664 sys sys 1196638943 2136
 sys/man/4/consolefs - 664 sys sys 1196638943 4389
 sys/man/4/cwfs - 664 sys sys 1196638943 6553
@@ -10015,12 +10015,12 @@ sys/src/cmd/cc/scon.c - 664 sys sys 1138463621 8788
 sys/src/cmd/cc/sub.c - 664 sys sys 1143759345 34268
 sys/src/cmd/cc/y.tab.h - 664 sys sys 1098501521 1680
 sys/src/cmd/cdfs - 20000000775 sys sys 1039727558 0
-sys/src/cmd/cdfs/buf.c - 664 sys sys 1205203460 1851
-sys/src/cmd/cdfs/dat.h - 664 sys sys 1205203455 3753
+sys/src/cmd/cdfs/buf.c - 664 sys sys 1205271166 1923
+sys/src/cmd/cdfs/dat.h - 664 sys sys 1205281336 4538
 sys/src/cmd/cdfs/fns.h - 664 sys sys 969542122 297
-sys/src/cmd/cdfs/main.c - 664 sys sys 1205203482 11360
+sys/src/cmd/cdfs/main.c - 664 sys sys 1205281456 11687
 sys/src/cmd/cdfs/mkfile - 664 sys sys 1204937991 153
-sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205203566 26493
+sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205295078 27297
 sys/src/cmd/cec - 20000000775 sys sys 1193683647 0
 sys/src/cmd/cec/LICENSE - 664 sys sys 1186248056 1554
 sys/src/cmd/cec/Protocol - 664 sys sys 1186248056 2881

+ 14 - 0
dist/replica/plan9.log

@@ -18738,3 +18738,17 @@
 1205204404 3 c sys/src/cmd/cdfs/main.c - 664 sys sys 1205203482 11360
 1205204404 4 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205203566 26493
 1205208004 0 c 386/bin/col - 775 sys sys 1205206380 63487
+1205254805 0 c sys/man/4/cdfs - 664 sys sys 1205253247 4351
+1205256604 0 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205256625 26641
+1205262004 0 c sys/src/cmd/cdfs/main.c - 664 sys sys 1205260953 11651
+1205263804 0 c 386/bin/cdfs - 775 sys sys 1205263179 169891
+1205265603 0 c sys/src/cmd/cdfs/dat.h - 664 sys sys 1205265191 3838
+1205271004 0 c sys/src/cmd/cdfs/dat.h - 664 sys sys 1205271109 4242
+1205271004 1 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205270965 26971
+1205272804 0 c sys/src/cmd/cdfs/buf.c - 664 sys sys 1205271166 1923
+1205281804 0 c sys/src/cmd/cdfs/dat.h - 664 sys sys 1205281336 4538
+1205281804 1 c sys/src/cmd/cdfs/main.c - 664 sys sys 1205281456 11687
+1205281804 2 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205281492 27209
+1205289005 0 c rc/bin/dmaon - 775 sys sys 1205288448 220
+1205294404 0 c 386/bin/cdfs - 775 sys sys 1205293084 169996
+1205296204 0 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1205295078 27297

+ 1 - 1
rc/bin/dmaon

@@ -3,5 +3,5 @@
 rfork e
 for (ctl in /dev/sd[C-H]?/ctl)
 	if (test -e $ctl && grep -s '^config .* dma ' $ctl &&
-	    ! grep -s '^config .* dma 00000000 ' $ctl)
+	    ! grep -s '^config (848A|.* dma 00000000 )' $ctl)
 		echo 'dma on' >$ctl

+ 1 - 1
sys/man/4/cdfs

@@ -185,7 +185,7 @@ Backup to a BD-RW disc:
 .EX
 9fs boot
 cdfs
-tar cbf /mnt/cd/wd/x /n/boot
+tar cf /mnt/cd/wd/x /n/boot
 .EE
 .br
 .ne 3

+ 1 - 0
sys/src/cmd/cdfs/buf.c

@@ -102,6 +102,7 @@ bwrite(Buf *b, void *v, long n)
 void
 bterm(Buf *b)
 {
+	/* DVD & BD prefer full ecc blocks (tracks), but can cope with less */
 	if(b->omode == OWRITE && b->ndata)
 		b->fn(b, b->data, (b->ndata+b->bs-1)/b->bs, b->off); 
 

+ 28 - 4
sys/src/cmd/cdfs/dat.h

@@ -17,7 +17,8 @@ enum {
 	/* MMC-3 device types */
 	Subtypenone	= 0,
 	Subtypecd,
-	Subtypedvd,
+	Subtypedvdminus,
+	Subtypedvdplus,
 	Subtypebd,
 
 	/* disc or track types */
@@ -44,6 +45,29 @@ enum {
 	Capcdda		= 1<<0,		/* Capmisc bits */
 	Caprw		= 1<<2,
 
+	/* Pagwrparams bits */
+	Bufe	= 1<<6,		/* buffer under-run free recording enable */
+
+	/* close track session cdb bits */
+	Closetrack	= 1,
+	Closesessfinal	= 2,	/* close session / finalize disc */
+	Closefinaldvdrw	= 3,	/* dvd-rw special: finalize */
+	/* dvd+r dl special: close session, write extended lead-out */
+	Closesessextdvdrdl = 4,
+	Closefinal30mm	= 5,	/* dvd+r special: finalize with ≥30mm radius */
+	Closedvdrbdfinal= 6,	/* dvd+r, bd-r special: finalize */
+
+	/* read toc format values */
+	Tocfmttoc	= 0,
+	Tocfmtsessnos	= 1,
+	Tocfmtqleadin	= 2,
+	Tocfmtqpma	= 3,
+	Tocfmtatip	= 4,
+	Tocfmtcdtext	= 5,
+
+	/* read toc cdb[1] bit */
+	Msfbit	= 1<<1,
+
 	/* write types, MMC-6 §7.5.4.9 */
 	Wtpkt	= 0,
 	Wttrackonce,
@@ -103,8 +127,8 @@ struct Track
 struct DTrack
 {
 	uchar	name[32];
-	uchar	beg[4];
-	uchar	end[4];
+	uchar	beg[4];		/* msf value; only used for audio */
+	uchar	end[4];		/* msf value; only used for audio */
 	uchar	size[8];
 	uchar	magic[4];
 };
@@ -148,7 +172,7 @@ struct Drive
 	int	changetime;
 	int	nameok;
 	int	writeok;
-	int	blank;
+	int	blank;			/* (not used for anything yet) */
 	int	blankset;
 	int	recordable;		/* writable by burning? */
 	int	recordableset;

+ 12 - 3
sys/src/cmd/cdfs/main.c

@@ -98,7 +98,9 @@ fswalk1(Fid *fid, char *name, Qid *qid)
 			*qid = (Qid){Qctl, 0, 0};
 			return nil;
 		}
-		if(strcmp(name, "wa") == 0 && drive->writeok) {
+		if(strcmp(name, "wa") == 0 && drive->writeok &&
+		    (drive->subtype == Subtypenone ||
+		     drive->subtype == Subtypecd)) {
 			*qid = (Qid){Qwa, drive->nchange, QTDIR};
 			return nil;
 		}
@@ -149,6 +151,11 @@ fscreate(Req *r)
 		return;
 
 	case Qwa:
+		if (drive->subtype != Subtypenone &&
+		    drive->subtype != Subtypecd) {
+			respond(r, "audio supported only on cd");
+			return;
+		}
 		type = TypeAudio;
 		break;
 
@@ -225,7 +232,9 @@ fillstat(ulong qid, Dir *d)
 		break;
 
 	case Qwa:
-		if(drive->writeok == 0)
+		if(drive->writeok == 0 ||
+		    drive->subtype != Subtypenone &&
+		    drive->subtype != Subtypecd)
 			return 0;
 		d->name = "wa";
 		d->qid.type = QTDIR;
@@ -656,7 +665,7 @@ main(int argc, char **argv)
 			if(fd != 1 && fd != 2)
 				close(fd);
 			vflag++;
-			scsiverbose++;
+			scsiverbose = 2; /* verbose but no Readtoc errs */
 		}
 		break;
 	default:

+ 90 - 82
sys/src/cmd/cdfs/mmc.c

@@ -390,8 +390,9 @@ mmcprobe(Scsi *scsi)
 	 * see SBC-2 §6.3.3 but also MMC-6 §7.6.
 	 */
 	n = mmcgetpage(drive, Pagcache, buf);
-	if (n >= 0) {
+	if (n >= 3) {
 		/* n == 255; buf[1] == 10 (10 bytes after buf[1]) */
+		buf[0] &= 077;		/* clear reserved bits, MMC-6 §7.2.3 */
 		assert(buf[0] == Pagcache);
 		assert(buf[1] >= 10);
 		buf[2] = Ccwce;
@@ -485,8 +486,9 @@ mmcreadtoc(Drive *drive, int type, int track, void *data, int nbytes)
 
 	memset(cmd, 0, sizeof(cmd));
 	cmd[0] = ScmdRTOC;
-	cmd[1] = type;
-	cmd[6] = track;
+	cmd[1] = type;				/* msf bit & reserved */
+	cmd[2] = Tocfmttoc;
+	cmd[6] = track;				/* track/session */
 	cmd[7] = nbytes>>8;
 	cmd[8] = nbytes;
 
@@ -530,8 +532,11 @@ getdiscinfo(Drive *drive, uchar resp[], int resplen)
 	int n;
 
 	n = mmcreaddiscinfo(drive, resp, resplen);
-	if(n < 3)
+	if(n < 3) {
+		if (vflag)
+			fprint(2, "read disc info failed\n");
 		return n;
+	}
 	if (vflag)
 		fprint(2, "read disc info succeeded\n");
 	assert((resp[2] & 0340) == 0);			/* data type 0 */
@@ -543,7 +548,7 @@ getdiscinfo(Drive *drive, uchar resp[], int resplen)
 static int
 getdvdstruct(Drive *drive)
 {
-	int n;
+	int n, cat;
 	uchar cmd[12], resp[Pagesz];
 
 	initcdb(cmd, sizeof cmd, ScmdReadDVD); /* actually, read disc structure */
@@ -554,32 +559,31 @@ getdvdstruct(Drive *drive)
 	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof resp, Sread);
 	if (n < 7)
 		return -1;
-	/*
-	 * resp[0..1] is resp length
-	 * (resp[4] & 0xf0) >> 4 is dvd type (disk category), MMC-6 §6.22.3.2.1
-	 */
+
+//	print("dvd structure:\n");
+//	hexdump(resp, n);
+
+	/* resp[0..1] is resp length */
+	cat = (resp[4] & 0xf0) >> 4;	/* disk category, MMC-6 §6.22.3.2.1 */
 	if (vflag)
-		fprint(2, "dvd type is %s\n", dvdtype[(resp[4] & 0xf0) >> 4]);
+		fprint(2, "dvd type is %s\n", dvdtype[cat]);
 	/* write parameters mode page may suffice to compute writeok for dvd */
 	drive->erasable = drive->recordable = 0;
-	switch (resp[6] & 0xf) {		/* layer type */
-	case 0:					/* embossed data */
+	/*
+	 * the layer-type field is a *bit array*,
+	 * though an enumeration of types would make more sense,
+	 * since the types are exclusive, not orthogonal.
+	 */
+	if (resp[6] & (1<<2))			/* rewritable? */
+		drive->erasable = 1;
+	else if (resp[6] & (1<<1))		/* recordable once? */
+		drive->recordable = 1;
+	else {					/* factory-pressed disk */
 		drive->blank = 0;
 		drive->blankset = 1;
-		break;
-	case 1:					/* recordable */
-		drive->recordable = 1;
-		break;
-	case 2:					/* rewritable */
-		drive->erasable = 1;
-		break;
-	default:
-		fprint(2, "%s: unknown dvd layer type %d\n",
-			argv0, resp[6] & 0xf);
-		return -1;
 	}
 	drive->erasableset = drive->recordableset = 1;
-	drive->subtype = Subtypedvd;
+	drive->subtype = (cat >= 8? Subtypedvdplus: Subtypedvdminus);
 	return 0;
 }
 
@@ -595,26 +599,27 @@ getbdstruct(Drive *drive)
 	cmd[8] = sizeof resp >> 8;	/* allocation length */
 	cmd[9] = sizeof resp;
 	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof resp, Sread);
-	if (n < 4+8+3)
-		return -1;
-	if (vflag)
-		fprint(2, "read disc structure (bd) succeeded\n");
 	/*
-	 * resp[0..1] is resp length
+	 * resp[0..1] is resp length.
 	 * resp[4+8..4+8+2] is bd type (disc type identifier):
-	 * BDO|BDW|BDR, MMC-6 §6.22.3.3.1
+	 * BDO|BDW|BDR, MMC-6 §6.22.3.3.1.  The above command should
+	 * fail on DVD drives, but some seem to ignore media type
+	 * and return successfully, so verify that it's a BD drive.
 	 */
-	assert(resp[4+8] == 'B' && resp[4+8+1] == 'D');
+	if (n < 4+8+3 || resp[4+8] != 'B' || resp[4+8+1] != 'D')
+		return -1;
+	if (vflag)
+		fprint(2, "read disc structure (bd) succeeded\n");
 	drive->erasable = drive->recordable = 0;
 	switch (resp[4+8+2]) {
 	case 'O':
 		drive->blank = 0;
 		drive->blankset = 1;
 		break;
-	case 'W':				/* recordable */
+	case 'R':				/* Recordable */
 		drive->recordable = 1;
 		break;
-	case 'R':				/* rewritable */
+	case 'W':				/* reWritable */
 		drive->erasable = 1;
 		break;
 	default:
@@ -668,7 +673,7 @@ mmcgettoc(Drive *drive)
 	/*
 	 * find number of tracks
 	 */
-	if((n=mmcreadtoc(drive, 0x02, 0, resp, sizeof(resp))) < 4) {
+	if((n = mmcreadtoc(drive, Msfbit, 0, resp, sizeof(resp))) < 4) {
 		/*
 		 * on a blank disc in a cd-rw, use readdiscinfo
 		 * to find the track info.
@@ -676,20 +681,20 @@ mmcgettoc(Drive *drive)
 		if(getdiscinfo(drive, resp, sizeof(resp)) < 7)
 			return -1;
 		assert((resp[2] & 0340) == 0);	/* data type 0 */
-		drive->erasable = ((resp[2] & 0x10) != 0);
-		drive->erasableset = 1;
 		if(resp[4] != 1)
 			print("multi-session disc %d\n", resp[4]);
 		first = resp[3];
 		last = resp[6];
 		if(vflag)
 			print("blank disc %d %d\n", first, last);
+		/* the assumption of blankness may be unwarranted */
 		drive->writeok = drive->blank = drive->blankset = 1;
 	} else {
 		first = resp[2];
 		last = resp[3];
 
 		if(n >= 4+8*(last-first+2)) {
+			/* resp[4 + i*8 + 2] is track # */
 			/* <=: track[last-first+1] = end */
 			for(i=0; i<=last-first+1; i++)
 				drive->track[i].mbeg = rdmsf(resp+4+i*8+5);
@@ -710,8 +715,9 @@ mmcgettoc(Drive *drive)
 
 	if (vflag) {
 		fprint(2, "writeok %d", drive->writeok);
-		if (drive->blankset)
-			fprint(2, " blank %d", drive->blank);
+		/* drive->blank is never used and hard to figure out */
+//		if (drive->blankset)
+//			fprint(2, " blank %d", drive->blank);
 		if (drive->recordableset)
 			fprint(2, " recordable %d", drive->recordable);
 		if (drive->erasableset)
@@ -742,7 +748,7 @@ mmcgettoc(Drive *drive)
 		 */
 		for(i = first; i <= last; i++) {
 			memset(resp, 0, sizeof(resp));
-			if(mmcreadtoc(drive, 0x00, i, resp, sizeof(resp)) < 0)
+			if(mmcreadtoc(drive, 0, i, resp, sizeof(resp)) < 0)
 				break;
 			t = &drive->track[i-first];
 			t->mtime = drive->changetime;
@@ -760,7 +766,8 @@ mmcgettoc(Drive *drive)
 
 		tot = 0;
 		memset(resp, 0, sizeof(resp));
-		if(mmcreadtoc(drive, 0x00, 0xAA, resp, sizeof(resp)) < 0)
+		/* 0xAA is lead-out */
+		if(mmcreadtoc(drive, 0, 0xAA, resp, sizeof(resp)) < 0)
 			print("bad\n");
 		if(resp[6])
 			tot = bige(resp+8);
@@ -804,7 +811,8 @@ mmcsetbs(Drive *drive, int bs)
 	 * p[4] & 0xf is data-block type.
 	 * p[8] is session format.
 	 */
-	p[2] = Wttrackonce;
+	p[0] &= 077;			/* clear reserved bits, MMC-6 §7.2.3 */
+	p[2] = Bufe | Wttrackonce;
 //	if(xflag)
 //		p[2] |= 0x10;		/* test-write */
 	p[3] &= ~0xf;
@@ -831,7 +839,8 @@ mmcsetbs(Drive *drive, int bs)
 			assert(0);
 		}
 		break;
-	case Subtypedvd:
+	case Subtypedvdminus:
+	case Subtypedvdplus:
 	case Subtypebd:
 		break;
 	default:
@@ -1090,6 +1099,22 @@ mmccreate(Drive *drive, int type)
 	return o;
 }
 
+/*
+ * issue some form of close track, close session or finalize disc command.
+ */
+static int
+mmcxclose(Drive *drive, int clf, int trackno)
+{
+	uchar cmd[10];
+
+	memset(cmd, 0, sizeof(cmd));
+	cmd[0] = ScmdClosetracksess;
+	cmd[2] = clf;				/* close function */
+	if(clf == Closetrack)
+		cmd[5] = trackno;
+	return scsi(drive, cmd, sizeof(cmd), cmd, 0, Snone);
+}
+
 void
 mmcsynccache(Drive *drive)
 {
@@ -1104,9 +1129,15 @@ mmcsynccache(Drive *drive)
 		print("mmcsynccache: bytes = %lld blocks = %ld, mmcnwa 0x%luX\n",
 			aux->ntotby, aux->ntotbk, aux->mmcnwa);
 	}
-/* rsc: seems not to work on some drives; 	mmcclose(1, 0xFF); */
+	/* rsc: seems not to work on some drives */
+	/* don't issue on dvd+rw */
+	if (drive->subtype != Subtypedvdplus || !drive->erasable)
+ 		mmcxclose(drive, Closetrack, 0xFF);
 }
 
+/*
+ * close the open track `o'.
+ */
 static void
 mmcclose(Otrack *o)
 {
@@ -1125,25 +1156,13 @@ mmcclose(Otrack *o)
 	free(o);
 }
 
-static int
-mmcxclose(Drive *drive, int ts, int trackno)
-{
-	uchar cmd[10];
-
-	/*
-	 * ts: 1 == track, 2 == session
-	 */
-	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = ScmdClosetracksess;		/* fixate */
-	cmd[2] = ts;				/* close function */
-	if(ts == 1)
-		cmd[5] = trackno;
-	return scsi(drive, cmd, sizeof(cmd), cmd, 0, Snone);
-}
-
+/*
+ * close the current session, then finalize the disc.
+ */
 static int
 mmcfixate(Drive *drive)
 {
+	int r;
 	uchar *p;
 	Mmcaux *aux;
 
@@ -1151,7 +1170,6 @@ mmcfixate(Drive *drive)
 		werrstr("not a writer");
 		return -1;
 	}
-
 	drive->nchange = -1;		/* force reread toc */
 
 	/* page 5 is legacy and now read-only */
@@ -1162,28 +1180,18 @@ mmcfixate(Drive *drive)
 	if(mmcsetpage(drive, Pagwrparams, p) < 0)
 		return -1;
 
-/* rsc: seems not to work on some drives; 	mmcclose(1, 0xFF); */
-	return mmcxclose(drive, 0x02, 0);
-}
-
-static int
-mmcsession(Drive *drive)
-{
-	uchar *p;
-	Mmcaux *aux;
-
-	drive->nchange = -1;	/* force reread toc */
-
-	/* page 5 is legacy and now read-only */
-	aux = drive->aux;
-	p = aux->page05;
-	/* zero multi-session field: next session not allowed */
-	p[3] &= ~0xC0;
-	if(mmcsetpage(drive, Pagwrparams, p) < 0)
-		return -1;
-
-/* rsc: seems not to work on some drives; 	mmcclose(1, 0xFF); */
-	return mmcxclose(drive, 0x02, 0);
+	/* rsc: seems not to work on some drives */
+	/* don't issue on dvd+rw */
+//	if (drive->subtype != Subtypedvdplus || !drive->erasable)
+//		mmcxclose(drive, Closetrack, 0xFF);
+	r = mmcxclose(drive, Closesessfinal, 0);
+	/*
+	 * Closesessfinal only closes & doesn't finalize on dvd+r and bd-r.
+	 */
+	if ((drive->subtype == Subtypedvdplus || drive->subtype == Subtypebd) &&
+	    !drive->erasable)
+		return mmcxclose(drive, Closedvdrbdfinal, 0);
+	return r;
 }
 
 static int