Browse Source

Plan 9 from Bell Labs 2008-03-08

David du Colombier 16 years ago
parent
commit
bc7dc51531

+ 9 - 8
dist/replica/_plan9.db

@@ -16,7 +16,7 @@
 386/bin/8a - 775 sys sys 1168402260 116604
 386/bin/8c - 775 sys sys 1190520740 367214
 386/bin/8l - 775 sys sys 1148500567 115711
-386/bin/9660srv - 775 sys sys 1168402261 104975
+386/bin/9660srv - 775 sys sys 1204948766 104897
 386/bin/aan - 775 sys sys 1196742429 129831
 386/bin/acid - 775 sys sys 1200262712 405315
 386/bin/acme - 775 sys sys 1200262719 431779
@@ -9423,10 +9423,10 @@ sys/src/cmd/8l/pass.c - 664 sys sys 1095107668 13675
 sys/src/cmd/8l/span.c - 664 sys sys 1107721554 23294
 sys/src/cmd/9660srv - 20000000775 sys sys 1048644372 0
 sys/src/cmd/9660srv/9660srv.c - 664 sys sys 1132451689 17151
-sys/src/cmd/9660srv/dat.h - 664 sys sys 1091904429 2097
+sys/src/cmd/9660srv/dat.h - 664 sys sys 1204937773 2129
 sys/src/cmd/9660srv/data.c - 664 sys sys 944960735 373
-sys/src/cmd/9660srv/fns.h - 664 sys sys 1019425186 428
-sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1168307362 3152
+sys/src/cmd/9660srv/fns.h - 664 sys sys 1204937773 429
+sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1204937829 3153
 sys/src/cmd/9660srv/iso9660.h - 664 sys sys 1014924873 2607
 sys/src/cmd/9660srv/main.c - 664 sys sys 1168307369 9808
 sys/src/cmd/9660srv/mkfile - 664 sys sys 1048644372 238
@@ -10016,11 +10016,11 @@ 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 964456822 1848
-sys/src/cmd/cdfs/dat.h - 664 sys sys 1014925665 2334
+sys/src/cmd/cdfs/dat.h - 664 sys sys 1204937945 2834
 sys/src/cmd/cdfs/fns.h - 664 sys sys 969542122 297
-sys/src/cmd/cdfs/main.c - 664 sys sys 1017679316 11040
-sys/src/cmd/cdfs/mkfile - 664 sys sys 959922196 182
-sys/src/cmd/cdfs/mmc.c - 664 sys sys 1146318348 17198
+sys/src/cmd/cdfs/main.c - 664 sys sys 1204937969 11147
+sys/src/cmd/cdfs/mkfile - 664 sys sys 1204937991 153
+sys/src/cmd/cdfs/mmc.c - 664 sys sys 1204938193 20926
 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/scuzz/scsireq.h - 664 sys sys 1204949623 6861

+ 9 - 9
dist/replica/plan9.db

@@ -16,7 +16,7 @@
 386/bin/8a - 775 sys sys 1168402260 116604
 386/bin/8c - 775 sys sys 1190520740 367214
 386/bin/8l - 775 sys sys 1148500567 115711
-386/bin/9660srv - 775 sys sys 1168402261 104975
+386/bin/9660srv - 775 sys sys 1204948766 104897
 386/bin/aan - 775 sys sys 1196742429 129831
 386/bin/acid - 775 sys sys 1200262712 405315
 386/bin/acme - 775 sys sys 1200262719 431779
@@ -9423,10 +9423,10 @@ sys/src/cmd/8l/pass.c - 664 sys sys 1095107668 13675
 sys/src/cmd/8l/span.c - 664 sys sys 1107721554 23294
 sys/src/cmd/9660srv - 20000000775 sys sys 1048644372 0
 sys/src/cmd/9660srv/9660srv.c - 664 sys sys 1132451689 17151
-sys/src/cmd/9660srv/dat.h - 664 sys sys 1091904429 2097
+sys/src/cmd/9660srv/dat.h - 664 sys sys 1204937773 2129
 sys/src/cmd/9660srv/data.c - 664 sys sys 944960735 373
-sys/src/cmd/9660srv/fns.h - 664 sys sys 1019425186 428
-sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1168307362 3152
+sys/src/cmd/9660srv/fns.h - 664 sys sys 1204937773 429
+sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1204937829 3153
 sys/src/cmd/9660srv/iso9660.h - 664 sys sys 1014924873 2607
 sys/src/cmd/9660srv/main.c - 664 sys sys 1168307369 9808
 sys/src/cmd/9660srv/mkfile - 664 sys sys 1048644372 238
@@ -10016,11 +10016,11 @@ 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 964456822 1848
-sys/src/cmd/cdfs/dat.h - 664 sys sys 1014925665 2334
+sys/src/cmd/cdfs/dat.h - 664 sys sys 1204937945 2834
 sys/src/cmd/cdfs/fns.h - 664 sys sys 969542122 297
-sys/src/cmd/cdfs/main.c - 664 sys sys 1017679316 11040
-sys/src/cmd/cdfs/mkfile - 664 sys sys 959922196 182
-sys/src/cmd/cdfs/mmc.c - 664 sys sys 1146318348 17198
+sys/src/cmd/cdfs/main.c - 664 sys sys 1204937969 11147
+sys/src/cmd/cdfs/mkfile - 664 sys sys 1204937991 153
+sys/src/cmd/cdfs/mmc.c - 664 sys sys 1204938193 20926
 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
@@ -13390,7 +13390,7 @@ sys/src/cmd/scuzz/changer.c - 664 sys sys 944961084 1137
 sys/src/cmd/scuzz/mkfile - 664 sys sys 1032060571 231
 sys/src/cmd/scuzz/mo.words - 664 sys sys 1177702138 1262
 sys/src/cmd/scuzz/scsireq.c - 664 sys sys 1181436637 13594
-sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1181435455 6692
+sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1204949623 6861
 sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1181436627 38286
 sys/src/cmd/scuzz/sense.c - 664 sys sys 1177702138 5680
 sys/src/cmd/sed.c - 664 sys sys 1182465504 26844

+ 9 - 0
dist/replica/plan9.log

@@ -18712,3 +18712,12 @@
 1204761604 1 c sys/lib/lp/process/generic - 775 sys sys 1204761143 4465
 1204761604 2 c sys/lib/lp/process/pdfgs - 775 sys sys 1204761083 1631
 1204837204 0 c sys/man/2/ip - 664 sys sys 1204837245 7271
+1204938004 0 c sys/src/cmd/9660srv/dat.h - 664 sys sys 1204937773 2129
+1204938004 1 c sys/src/cmd/9660srv/fns.h - 664 sys sys 1204937773 429
+1204938004 2 c sys/src/cmd/9660srv/iobuf.c - 664 sys sys 1204937829 3153
+1204938004 3 c sys/src/cmd/cdfs/dat.h - 664 sys sys 1204937945 2834
+1204938004 4 c sys/src/cmd/cdfs/main.c - 664 sys sys 1204937969 11147
+1204938004 5 c sys/src/cmd/cdfs/mkfile - 664 sys sys 1204937991 153
+1204939804 0 c sys/src/cmd/cdfs/mmc.c - 664 sys sys 1204938193 20926
+1204948803 0 c 386/bin/9660srv - 775 sys sys 1204948766 104897
+1204950604 0 c sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1204949623 6861

+ 1 - 1
sys/src/cmd/9660srv/dat.h

@@ -23,7 +23,7 @@ struct Iobuf
 
 struct Ioclust
 {
-	long	addr;
+	long	addr;			/* in sectors; good to 8TB */
 	Xdata*	dev;
 	Ioclust*	next;
 	Ioclust*	prev;

+ 1 - 1
sys/src/cmd/9660srv/fns.h

@@ -1,7 +1,7 @@
 void	chat(char*, ...);
 void*	ealloc(long);
 void	error(char*);
-Iobuf*	getbuf(Xdata*, long);
+Iobuf*	getbuf(Xdata*, ulong);
 Xdata*	getxdata(char*);
 void	iobuf_init(void);
 void	nexterror(void);

+ 1 - 1
sys/src/cmd/9660srv/iobuf.c

@@ -140,7 +140,7 @@ putclust(Ioclust *c)
 }
 
 Iobuf*
-getbuf(Xdata *dev, long addr)
+getbuf(Xdata *dev, ulong addr)
 {
 	int off;
 	Ioclust *c;

+ 49 - 37
sys/src/cmd/cdfs/dat.h

@@ -1,6 +1,5 @@
-
 enum {
-	Maxtrack		= 200,
+	Maxtrack	= 200,
 	Ntrack		= Maxtrack+1,
 	BScdrom		= 2048,
 	BScdda		= 2352,
@@ -9,12 +8,13 @@ enum {
 	Nalloc		= 12*BScdda,
 	DictBlock	= 1,
 
-	TypeDA		= 0,		/* Direct Access */
-	TypeSA		= 1,		/* Sequential Access */
-	TypeWO		= 4,		/* Worm */
-	TypeCD		= 5,		/* CD-ROM */
-	TypeMO		= 7,		/* rewriteable Magneto-Optical */
-	TypeMC		= 8,		/* Medium Changer */
+	/* scsi peripheral device types */
+	TypeDA		= 0,		/* Direct Access (SBC) */
+	TypeSA		= 1,		/* Sequential Access (SSC-2) */
+	TypeWO		= 4,		/* Worm (SBC)*/
+	TypeCD		= 5,		/* CD/DVD/BD (MMC-3) */
+	TypeMO		= 7,		/* rewriteable Magneto-Optical (SBC) */
+	TypeMC		= 8,		/* Medium Changer (SMC-2) */
 
 	TypeNone	= 0,
 	TypeAudio,
@@ -24,8 +24,18 @@ enum {
 	TypeDisk,
 	TypeBlank,
 
-	Cwrite = 1<<0,
-	Ccdda = 1<<1,
+	/* Cache control bits in page 8 byte 2 */
+	Ccrcd	= 1<<0,		/* read cache disabled */
+	Ccmf	= 1<<1,		/* multiplication factor */
+	Ccwce	= 1<<2,		/* writeback cache enabled */
+	Ccsize	= 1<<3, /* use `cache segment size', not `# of cache segments' */
+	Ccdisc	= 1<<4,		/* discontinuity */
+	Cccap	= 1<<5,		/* caching analysis permitted */
+	Ccabpf	= 1<<6,		/* abort pre-fetch */
+	Ccic	= 1<<7,		/* initiator control */
+
+	Cwrite	= 1<<0,
+	Ccdda	= 1<<1,
 
 	Nblock = 12,
 };
@@ -35,12 +45,12 @@ typedef struct Drive Drive;
 typedef struct Track Track;
 typedef struct Otrack Otrack;
 typedef struct Dev Dev;
-typedef struct Msf Msf;	/* minute, second, frame */
+typedef struct Msf Msf;		/* minute, second, frame */
 
 struct Msf {
-	int m;
-	int s;
-	int f;
+	int	m;
+	int	s;
+	int	f;
 };
 
 struct Track
@@ -72,26 +82,26 @@ struct DTrack
 
 struct Otrack
 {
-	Track *track;
-	Drive *drive;
-	int nchange;
-	int omode;
-	Buf *buf;
+	Track	*track;
+	Drive	*drive;
+	int	nchange;
+	int	omode;
+	Buf	*buf;
 
-	int nref;	/* kept by file server */
+	int	nref;		/* kept by file server */
 };
 
 struct Dev
 {
-	Otrack* (*openrd)(Drive *d, int trackno);
-	Otrack* (*create)(Drive *d, int bs);
-	long (*read)(Otrack *t, void *v, long n, long off);
-	long (*write)(Otrack *t, void *v, long n);
-	void (*close)(Otrack *t);
-	int (*gettoc)(Drive*);
-	int (*fixate)(Drive *d);
-	char* (*ctl)(Drive *d, int argc, char **argv);
-	char* (*setspeed)(Drive *d, int r, int w);
+	Otrack*	(*openrd)(Drive *d, int trackno);
+	Otrack*	(*create)(Drive *d, int bs);
+	long	(*read)(Otrack *t, void *v, long n, long off);
+	long	(*write)(Otrack *t, void *v, long n);
+	void	(*close)(Otrack *t);
+	int	(*gettoc)(Drive*);
+	int	(*fixate)(Drive *d);
+	char*	(*ctl)(Drive *d, int argc, char **argv);
+	char*	(*setspeed)(Drive *d, int r, int w);
 };
 
 struct Drive
@@ -107,30 +117,32 @@ struct Drive
 	int	changetime;
 	int	nameok;
 	int	writeok;
+
 	Track	track[Ntrack];
 	ulong	cap;
 	uchar	blkbuf[BScdda];
+
 	int	maxreadspeed;
 	int	maxwritespeed;
 	int	readspeed;
 	int	writespeed;
 	Dev;
 
-	void *aux;	/* kept by driver */
+	void *aux;		/* kept by driver */
 };
 
 struct Buf
 {
-	uchar *data;	/* buffer */
-	long off;		/* data[0] at offset off in file */
-	int bs;		/* block size */
-	long ndata;	/* no. valid bytes in data */
-	int nblock;	/* total buffer size in blocks */
-	int	omode;	/* OREAD, OWRITE */
+	uchar	*data;		/* buffer */
+	long	off;		/* data[0] at offset off in file */
+	int	bs;		/* block size */
+	long	ndata;		/* no. valid bytes in data */
+	int	nblock;		/* total buffer size in blocks */
+	int	omode;		/* OREAD, OWRITE */
 	long	(*fn)(Buf*, void*, long, long);	/* read, write */
 
 	/* used only by client */
-	Otrack *otrack;
+	Otrack	*otrack;
 };
 
 extern int	vflag;

+ 11 - 7
sys/src/cmd/cdfs/main.c

@@ -1,3 +1,4 @@
+/* cdfs - CD, DVD and BD reader and writer file system */
 #include <u.h>
 #include <libc.h>
 #include <auth.h>
@@ -10,8 +11,8 @@
 
 typedef struct Aux Aux;
 struct Aux {
-	int doff;
-	Otrack *o;
+	int	doff;
+	Otrack	*o;
 };
 
 static void checktoc(Drive*);
@@ -200,13 +201,16 @@ fillstat(ulong qid, Dir *d)
 {
 	Track *t;
 
-	memset(d, 0, sizeof(Dir));
+	nulldir(d);
+	d->type = L'M';
+	d->dev = 1;
+	d->length = 0;
 	d->uid = "cd";
 	d->gid = "cd";
 	d->muid = "";
 	d->qid = (Qid){qid, drive->nchange, 0};
 	d->atime = time(0);
-	d->atime = drive->changetime;
+	d->mtime = drive->changetime;
 
 	switch(qid){
 	case Qdir:
@@ -562,7 +566,7 @@ checktoc(Drive *drive)
 		switch(t->type){
 		case TypeNone:
 			t->name[0] = 'u';
-			t->mode = 0;
+//			t->mode = 0;
 			break;
 		case TypeData:
 			t->name[0] = 'd';
@@ -629,10 +633,10 @@ main(int argc, char **argv)
 		chatty9p++;
 		break;
 	case 'd':
-		dev = ARGF();
+		dev = EARGF(usage());
 		break;
 	case 'm':
-		mtpt = ARGF();
+		mtpt = EARGF(usage());
 		break;
 	case 'v':
 		if((fd = create("/tmp/cdfs.log", OWRITE, 0666)) >= 0) {

+ 1 - 1
sys/src/cmd/cdfs/mkfile

@@ -10,7 +10,7 @@ OFILES=\
 HFILES=\
 	dat.h\
 	fns.h\
+	../scuzz/scsireq.h\
 
-LIB=/$objtype/lib/lib9p.a /$objtype/lib/libdisk.a
 BIN=/$objtype/bin
 </sys/src/cmd/mkone

+ 211 - 97
sys/src/cmd/cdfs/mmc.c

@@ -1,28 +1,40 @@
+/*
+ * multi-media commands
+ *
+ * as of mmc-6, mode page 0x2a (capabilities & mechanical status) is legacy
+ * and read-only, last defined in mmc-3.  mode page 5 (write parameters)
+ * applies only to cd-r(w) and dvd-r(w); *-rom, dvd+* and bd-* are right out.
+ */
 #include <u.h>
 #include <libc.h>
 #include <disk.h>
+#include "../scuzz/scsireq.h"
 #include "dat.h"
 #include "fns.h"
 
 enum
 {
 	Pagesz		= 255,
+
+	Pagwrparams	= 5,		/* write parameters */
+	Pagcache	= 8,
+	Pagcapmechsts	= 0x2a,
 };
 
 static Dev mmcdev;
 
 typedef struct Mmcaux Mmcaux;
 struct Mmcaux {
-	uchar page05[Pagesz];
-	int page05ok;
+	uchar	page05[Pagesz];		/* (cd|dvd)-r(w) write parameters */
+	int	page05ok;
 
-	int pagecmdsz;
-	ulong mmcnwa;
+	int	pagecmdsz;
+	ulong	mmcnwa;
 
-	int nropen;
-	int nwopen;
-	long ntotby;
-	long ntotbk;
+	int	nropen;
+	int	nwopen;
+	vlong	ntotby;
+	long	ntotbk;
 };
 
 static ulong
@@ -59,6 +71,42 @@ hexdump(void *v, int n)
 		print("\n");
 }
 
+/*
+ * SCSI CCBs (cmd arrays) are 6, 10, 12, 16 or 32 bytes long.
+ * The mode sense/select commands implicitly refer to
+ * a mode parameter list, which consists of an 8-byte
+ * mode parameter header, followed by zero or more block
+ * descriptors and zero or more mode pages (MMC-2 §5.5.2).
+ * We'll ignore mode sub-pages.
+ * Integers are stored big-endian.
+ *
+ * The format of the mode parameter (10) header is:
+ *	ushort	mode_data_length;		// of following bytes
+ *	uchar	medium_type;
+ *	uchar	device_specific;
+ *	uchar	reserved[2];
+ *	ushort	block_descriptor_length;	// zero
+ *
+ * The format of the mode parameter (6) header is:
+ *	uchar	mode_data_length;		// of following bytes
+ *	uchar	medium_type;
+ *	uchar	device_specific;
+ *	uchar	block_descriptor_length;	// zero
+ *
+ * The format of the mode pages is:
+ *	uchar	page_code_and_PS;
+ *	uchar	page_len;			// of following bytes
+ *	uchar	parameter[page_len];
+ *
+ * see SPC-3 §4.3.4.6 for allocation length and §7.4 for mode parameter lists.
+ */
+
+enum {
+	Mode10parmhdrlen= 8,
+	Mode6parmhdrlen	= 4,
+	Modepaghdrlen	= 2,
+};
+
 static int
 mmcgetpage10(Drive *drive, int page, void *v)
 {
@@ -66,22 +114,32 @@ mmcgetpage10(Drive *drive, int page, void *v)
 	int n, r;
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x5A;
+	cmd[0] = ScmdMsense10;
 	cmd[2] = page;
-	cmd[8] = 255;
+	cmd[8] = 255;			/* allocation length: buffer size */
+
+//	print("get: sending cmd\n");
+//	hexdump(cmd, 10);
+
 	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
-	if(n < 8)
+	if(n < Mode10parmhdrlen)
 		return -1;
 
-	r = (resp[6]<<8) | resp[7];
-	n -= 8+r;
+	r = (resp[6]<<8) | resp[7];	/* block descriptor length */
+	n -= Mode10parmhdrlen + r;
 
 	if(n < 0)
 		return -1;
 	if(n > Pagesz)
 		n = Pagesz;
 
-	memmove(v, &resp[8+r], n);
+	memmove(v, &resp[Mode10parmhdrlen + r], n);
+
+//	print("get: got cmd\n");
+//	hexdump(cmd, 10);
+//	print("page\n");
+//	hexdump(v, n);
+
 	return n;
 }
 
@@ -92,20 +150,21 @@ mmcgetpage6(Drive *drive, int page, void *v)
 	int n;
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x1A;
+	cmd[0] = ScmdMsense6;
 	cmd[2] = page;
-	cmd[4] = 255;
+	cmd[4] = 255;			/* allocation length */
+
 	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
-	if(n < 4)
+	if(n < Mode6parmhdrlen)
 		return -1;
 
-	n -= 4+resp[3];
+	n -= Mode6parmhdrlen + resp[3];
 	if(n < 0)
 		return -1;
 	if(n > Pagesz)
 		n = Pagesz;
 
-	memmove(v, &resp[4+resp[3]], n);
+	memmove(v, &resp[Mode6parmhdrlen + resp[3]], n);
 	return n;
 }
 
@@ -115,22 +174,34 @@ mmcsetpage10(Drive *drive, int page, void *v)
 	uchar cmd[10], *p, *pagedata;
 	int len, n;
 
+	/* allocate parameter list, copy in mode page, fill in header */
 	pagedata = v;
 	assert(pagedata[0] == page);
-	len = 8+2+pagedata[1];
+	len = Mode10parmhdrlen + Modepaghdrlen + pagedata[1];
 	p = emalloc(len);
-	memmove(p+8, pagedata, pagedata[1]);
+	memmove(p + Mode10parmhdrlen, pagedata, pagedata[1]);
+	/* parameter list header */
+	p[0] = 0;
+	p[1] = len - 2;
+
+	/* set up CCB */
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x55;
-	cmd[1] = 0x10;
+	cmd[0] = ScmdMselect10;
+	cmd[1] = 0x10;			/* format not vendor-specific */
 	cmd[8] = len;
 
-//	print("cmd\n");
+//	print("set: sending cmd\n");
 //	hexdump(cmd, 10);
+//	print("parameter list header\n");
+//	hexdump(p, Mode10parmhdrlen);
 //	print("page\n");
-//	hexdump(p, len);
+//	hexdump(p + Mode10parmhdrlen, len - Mode10parmhdrlen);
 
 	n = scsi(drive, cmd, sizeof(cmd), p, len, Swrite);
+
+//	print("set: got cmd\n");
+//	hexdump(cmd, 10);
+
 	free(p);
 	if(n < len)
 		return -1;
@@ -142,15 +213,18 @@ mmcsetpage6(Drive *drive, int page, void *v)
 {
 	uchar cmd[6], *p, *pagedata;
 	int len, n;
-	
+
+	if (vflag)
+		print("mmcsetpage6 called!\n");
 	pagedata = v;
 	assert(pagedata[0] == page);
-	len = 4+2+pagedata[1];
+	len = Mode6parmhdrlen + Modepaghdrlen + pagedata[1];
 	p = emalloc(len);
-	memmove(p+4, pagedata, pagedata[1]);
+	memmove(p + Mode6parmhdrlen, pagedata, pagedata[1]);
+
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x15;
-	cmd[1] = 0x10;
+	cmd[0] = ScmdMselect6;
+	cmd[1] = 0x10;			/* format not vendor-specific */
 	cmd[4] = len;
 
 	n = scsi(drive, cmd, sizeof(cmd), p, len, Swrite);
@@ -200,7 +274,7 @@ mmcstatus(Drive *drive)
 	uchar cmd[12];
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0xBD;
+	cmd[0] = ScmdCDstatus;			/* mechanism status */
 	return scsi(drive, cmd, sizeof(cmd), nil, 0, Sread);
 }
 
@@ -210,14 +284,14 @@ mmcgetspeed(Drive *drive)
 	int n, maxread, curread, maxwrite, curwrite;
 	uchar buf[Pagesz];
 
-	n = mmcgetpage(drive, 0x2A, buf);
+	n = mmcgetpage(drive, Pagcapmechsts, buf);
 	maxread = (buf[8]<<8)|buf[9];
 	curread = (buf[14]<<8)|buf[15];
 	maxwrite = (buf[18]<<8)|buf[19];
 	curwrite = (buf[20]<<8)|buf[21];
 
 	if(n < 22 || (maxread && maxread < 170) || (curread && curread < 170))
-		return;	/* bogus data */
+		return;			/* bogus data */
 
 	drive->readspeed = curread;
 	drive->writespeed = curwrite;
@@ -231,20 +305,21 @@ mmcprobe(Scsi *scsi)
 	Mmcaux *aux;
 	Drive *drive;
 	uchar buf[Pagesz];
-	int cap;
-
-	/* BUG: confirm mmc better? */
+	int cap, n;
 
+	/* BUG: confirm mmc better! */
+	if (vflag)
+		print("mmcprobe: inquiry: %s\n", scsi->inquire);
 	drive = emalloc(sizeof(Drive));
 	drive->Scsi = *scsi;
 	drive->Dev = mmcdev;
 	aux = emalloc(sizeof(Mmcaux));
 	drive->aux = aux;
 
-	/* attempt to read CD capabilities page */
-	if(mmcgetpage10(drive, 0x2A, buf) >= 0)
+	/* attempt to read CD capabilities page, but it's now legacy */
+	if(mmcgetpage10(drive, Pagcapmechsts, buf) >= 0)
 		aux->pagecmdsz = 10;
-	else if(mmcgetpage6(drive, 0x2A, buf) >= 0)
+	else if(mmcgetpage6(drive, Pagcapmechsts, buf) >= 0)
 		aux->pagecmdsz = 6;
 	else {
 		werrstr("not an mmc device");
@@ -253,7 +328,7 @@ mmcprobe(Scsi *scsi)
 	}
 
 	cap = 0;
-	if(buf[3] & 3)	/* 2=cdrw, 1=cdr */
+	if(buf[3] & 3)		/* 2=cdrw, 1=cdr */
 		cap |= Cwrite;
 	if(buf[5] & 1)
 		cap |= Ccdda;
@@ -261,8 +336,8 @@ mmcprobe(Scsi *scsi)
 //	print("read %d max %d\n", biges(buf+14), biges(buf+8));
 //	print("write %d max %d\n", biges(buf+20), biges(buf+18));
 
-	/* cache page 05 (write parameter page) */
-	if((cap & Cwrite) && mmcgetpage(drive, 0x05, aux->page05) >= 0)
+	/* cache optional page 05 (write parameter page) */
+	if((cap & Cwrite) && mmcgetpage(drive, Pagwrparams, aux->page05) >= 0)
 		aux->page05ok = 1;
 	else
 		cap &= ~Cwrite;
@@ -270,6 +345,21 @@ mmcprobe(Scsi *scsi)
 	drive->cap = cap;
 
 	mmcgetspeed(drive);
+
+	/*
+	 * we can't actually control caching much.
+	 * see SBC-2 §6.3.3 but also MMC-6 §7.6.
+	 */
+	n = mmcgetpage(drive, Pagcache, buf);
+	if (n >= 0) {
+		/* n == 255; buf[1] == 10 (10 bytes after buf[1]) */
+		assert(buf[0] == Pagcache);
+		assert(buf[1] >= 10);
+		buf[2] = Ccwce;
+		if (mmcsetpage(drive, Pagcache, buf) < 0)
+			if (vflag)
+				print("mmcprobe: cache control NOT set\n");
+	}
 	return drive;
 }
 
@@ -284,7 +374,7 @@ mmctrackinfo(Drive *drive, int t, int i)
 
 	aux = drive->aux;
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x52;	/* get track info */
+	cmd[0] = ScmdRtrackinfo;
 	cmd[1] = 1;
 	cmd[2] = t>>24;
 	cmd[3] = t>>16;
@@ -314,19 +404,24 @@ mmctrackinfo(Drive *drive, int t, int i)
 		type = TypeAudio;
 		bs = BScdda;
 		break;
-	case 1:	/* 2 audio channels, with pre-emphasis 50/15 μs */
+	case 1:		/* 2 audio channels, with pre-emphasis 50/15 μs */
 		if(vflag)
 			print("audio channels with preemphasis on track %d (u%.3d)\n", t, i);
 		type = TypeNone;
 		break;
-	case 4:	/* data track, recorded uninterrupted */
+	case 4:		/* data track, recorded uninterrupted */
+		type = TypeData;
+		bs = BScdrom;
+		break;
+	case 5:		/* data track, recorded interrupted */
+		/* treat it as cdrom; probably dvd or bd */
 		type = TypeData;
 		bs = BScdrom;
 		break;
-	case 5:	/* data track, recorded interrupted */
 	default:
 		if(vflag)
 			print("unknown track type %d\n", tmode);
+		break;
 	}
 
 	drive->track[i].mtime = drive->changetime;
@@ -353,7 +448,7 @@ mmcreadtoc(Drive *drive, int type, int track, void *data, int nbytes)
 	uchar cmd[10];
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x43;
+	cmd[0] = ScmdRTOC;
 	cmd[1] = type;
 	cmd[6] = track;
 	cmd[7] = nbytes>>8;
@@ -369,7 +464,7 @@ mmcreaddiscinfo(Drive *drive, void *data, int nbytes)
 	int n;
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x51;
+	cmd[0] = ScmdRdiscinfo;
 	cmd[7] = nbytes>>8;
 	cmd[8] = nbytes;
 	n = scsi(drive, cmd, sizeof(cmd), data, nbytes, Sread);
@@ -437,7 +532,7 @@ mmcgettoc(Drive *drive)
 		 */
 		if(mmcreaddiscinfo(drive, resp, sizeof(resp)) < 0)
 			return -1;
-		if(resp[4] != 1) 
+		if(resp[4] != 1)
 			print("multi-session disc %d\n", resp[4]);
 		first = resp[3];
 		last = resp[6];
@@ -521,6 +616,9 @@ mmcgettoc(Drive *drive)
 	return 0;
 }
 
+/*
+ * this uses page 5, which is optional.
+ */
 static int
 mmcsetbs(Drive *drive, int bs)
 {
@@ -528,14 +626,14 @@ mmcsetbs(Drive *drive, int bs)
 	Mmcaux *aux;
 
 	aux = drive->aux;
-
-	assert(aux->page05ok);
+	if (!aux->page05ok)
+		return 0;			/* harmless; assume 2k */
 
 	p = aux->page05;
 	p[2] = 0x01;				/* track-at-once */
 //	if(xflag)
 //		p[2] |= 0x10;			/* test-write */
-	
+
 	switch(bs){
 	case BScdrom:
 		p[3] = (p[3] & ~0x07)|0x04;	/* data track, uninterrupted */
@@ -559,7 +657,7 @@ mmcsetbs(Drive *drive, int bs)
 		assert(0);
 	}
 
-	if(mmcsetpage(drive, 0x05, p) < 0)
+	if(mmcsetpage(drive, Pagwrparams, p) < 0)
 		return -1;
 	return 0;
 }
@@ -589,7 +687,8 @@ mmcread(Buf *buf, void *v, long nblock, long off)
 	if(off > o->track->end - 2) {
 		werrstr("read past end of track");
 		if(vflag)
-			fprint(2, "end of track (%ld->%ld off %ld)", o->track->beg, o->track->end-2, off);
+			fprint(2, "end of track (%ld->%ld off %ld)",
+				o->track->beg, o->track->end - 2, off);
 		return -1;
 	}
 	if(off == o->track->end - 2)
@@ -598,42 +697,55 @@ mmcread(Buf *buf, void *v, long nblock, long off)
 	if(off+nblock > o->track->end - 2)
 		nblock = o->track->end - 2 - off;
 
+	/*
+	 * `read cd' only works for CDs; for everybody else,
+	 * we'll try plain `read (12)'.
+	 */
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0xBE;
-	cmd[2] = off>>24;
-	cmd[3] = off>>16;
-	cmd[4] = off>>8;
-	cmd[5] = off>>0;
-	cmd[6] = nblock>>16;
-	cmd[7] = nblock>>8;
-	cmd[8] = nblock>>0;
-	cmd[9] = 0x10;
-
-	switch(bs){
-	case BScdda:
-		cmd[1] = 0x04;
-		break;
-
-	case BScdrom:
-		cmd[1] = 0x08;
-		break;
-
-	case BScdxa:
-		cmd[1] = 0x0C;
-		break;
-
-	default:
-		werrstr("unknown bs %d", bs);
-		return -1;
+	if (drive->type == TypeCD) {
+		cmd[0] = ScmdReadcd;
+		cmd[2] = off>>24;
+		cmd[3] = off>>16;
+		cmd[4] = off>>8;
+		cmd[5] = off>>0;
+		cmd[6] = nblock>>16;
+		cmd[7] = nblock>>8;
+		cmd[8] = nblock>>0;
+		cmd[9] = 0x10;
+		switch(bs){
+		case BScdda:
+			cmd[1] = 0x04;
+			break;
+		case BScdrom:
+			cmd[1] = 0x08;
+			break;
+		case BScdxa:
+			cmd[1] = 0x0C;
+			break;
+		default:
+			werrstr("unknown bs %d", bs);
+			return -1;
+		}
+	} else {			/* e.g., TypeDA */
+		cmd[0] = ScmdRead12;
+		cmd[2] = off>>24;
+		cmd[3] = off>>16;
+		cmd[4] = off>>8;
+		cmd[5] = off>>0;
+		cmd[6] = nblock>>24;
+		cmd[7] = nblock>>16;
+		cmd[8] = nblock>>8;
+		cmd[9] = nblock;
+		// cmd[10] = 0x80;	/* streaming */
 	}
-
 	n = nblock*bs;
 	nn = scsi(drive, cmd, sizeof(cmd), v, n, Sread);
 	if(nn != n) {
 		if(nn != -1)
 			werrstr("short read %ld/%ld", nn, n);
 		if(vflag)
-			print("read off %lud nblock %ld bs %d failed\n", off, nblock, bs);
+			print("read off %lud nblock %ld bs %d failed\n",
+				off, nblock, bs);
 		return -1;
 	}
 
@@ -682,7 +794,7 @@ mmcxwrite(Otrack *o, void *v, long nblk)
 	aux->ntotby += nblk*o->track->bs;
 	aux->ntotbk += nblk;
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x2a;	/* write */
+	cmd[0] = ScmdExtwrite;		/* write (10) */
 	cmd[2] = aux->mmcnwa>>24;
 	cmd[3] = aux->mmcnwa>>16;
 	cmd[4] = aux->mmcnwa>>8;
@@ -728,7 +840,7 @@ mmccreate(Drive *drive, int type)
 		return nil;
 	}
 
-	if(mmctrackinfo(drive, 0xFF, Maxtrack)) {		/* the invisible track */
+	if(mmctrackinfo(drive, 0xFF, Maxtrack)) {	/* the invisible track */
 		werrstr("CD not writable");
 		return nil;
 	}
@@ -736,7 +848,7 @@ mmccreate(Drive *drive, int type)
 		werrstr("cannot set bs mode");
 		return nil;
 	}
-	if(mmctrackinfo(drive, 0xFF, Maxtrack)) {		/* the invisible track */
+	if(mmctrackinfo(drive, 0xFF, Maxtrack)) {	/* the invisible track */
 		werrstr("CD not writable 2");
 		return nil;
 	}
@@ -775,11 +887,11 @@ mmcsynccache(Drive *drive)
 	Mmcaux *aux;
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x35;	/* flush */
+	cmd[0] = ScmdSynccache;		/* flush */
 	scsi(drive, cmd, sizeof(cmd), cmd, 0, Snone);
 	if(vflag) {
 		aux = drive->aux;
-		print("mmcsynccache: bytes = %ld blocks = %ld, mmcnwa 0x%luX\n",
+		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); */
@@ -812,7 +924,7 @@ mmcxclose(Drive *drive, int ts, int trackno)
 	 * ts: 1 == track, 2 == session
 	 */
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x5B;
+	cmd[0] = ScmdClosetracksess;
 	cmd[2] = ts;
 	if(ts == 1)
 		cmd[5] = trackno;
@@ -830,12 +942,13 @@ mmcfixate(Drive *drive)
 		return -1;
 	}
 
-	drive->nchange = -1;	/* force reread toc */
+	drive->nchange = -1;		/* force reread toc */
 
+	/* TODO: page 5 is legacy and now read-only */
 	aux = drive->aux;
 	p = aux->page05;
-	p[3] = (p[3] & ~0xC0);
-	if(mmcsetpage(drive, 0x05, p) < 0)
+	p[3] &= ~0xC0;
+	if(mmcsetpage(drive, Pagwrparams, p) < 0)
 		return -1;
 
 /* rsc: seems not to work on some drives; 	mmcclose(1, 0xFF); */
@@ -850,10 +963,11 @@ mmcsession(Drive *drive)
 
 	drive->nchange = -1;	/* force reread toc */
 
+	/* TODO: page 5 is legacy and now read-only */
 	aux = drive->aux;
 	p = aux->page05;
-	p[3] = (p[3] & ~0xC0);
-	if(mmcsetpage(drive, 0x05, p) < 0)
+	p[3] &= ~0xC0;
+	if(mmcsetpage(drive, Pagwrparams, p) < 0)
 		return -1;
 
 /* rsc: seems not to work on some drives; 	mmcclose(1, 0xFF); */
@@ -865,10 +979,10 @@ mmcblank(Drive *drive, int quick)
 {
 	uchar cmd[12];
 
-	drive->nchange = -1;	/* force reread toc */
+	drive->nchange = -1;		/* force reread toc */
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0xA1;	/* blank */
+	cmd[0] = ScmdBlank;		/* blank cd-rw media */
 	/* cmd[1] = 0 means blank the whole disc; = 1 just the header */
 	cmd[1] = quick ? 0x01 : 0x00;
 
@@ -881,7 +995,7 @@ start(Drive *drive, int code)
 	uchar cmd[6];
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0x1B;
+	cmd[0] = ScmdStart;		/* start/stop unit */
 	cmd[4] = code;
 	return scsi(drive, cmd, sizeof(cmd), cmd, 0, Snone);
 }
@@ -918,7 +1032,7 @@ mmcsetspeed(Drive *drive, int r, int w)
 	uchar cmd[12];
 
 	memset(cmd, 0, sizeof(cmd));
-	cmd[0] = 0xBB;
+	cmd[0] = ScmdSetcdspeed;
 	cmd[2] = r>>8;
 	cmd[3] = r;
 	cmd[4] = w>>8;

+ 14 - 7
sys/src/cmd/scuzz/scsireq.h

@@ -1,3 +1,4 @@
+/* this file is also included by usb/disk and cdfs */
 typedef struct Umsc Umsc;
 #pragma incomplete Umsc
 
@@ -103,13 +104,6 @@ enum {					/* SCSI command codes */
 	ScmdCDstatus	= 0xBD,		/* mechanism status */
 	Scmdgetconf	= 0x46,		/* get configuration */
 
-	ScmdFwaddr	= 0xE2,		/* first writeable address */
-	ScmdTreserve	= 0xE4,		/* reserve track */
-	ScmdTinfo	= 0xE5,		/* read track info */
-	ScmdTwrite	= 0xE6,		/* write track */
-	ScmdMload	= 0xE7,		/* medium load/unload */
-	ScmdFixation	= 0xE9,		/* fixation */
-
 	ScmdEInitialise	= 0x07,		/* initialise element status */
 	ScmdMMove	= 0xA5,		/* move medium */
 	ScmdEStatus	= 0xB8,		/* read element status */
@@ -119,6 +113,19 @@ enum {					/* SCSI command codes */
 	ScmdReadDVD	= 0xAD,		/* read dvd structure */
 	ScmdReportKey	= 0xA4,		/* read dvd key */
 	ScmdSendKey	= 0xA3,		/* write dvd key */
+
+	ScmdClosetracksess= 0x5B,
+	ScmdRead12	= 0xA8,
+	ScmdSetcdspeed	= 0xBB,
+	ScmdReadcd	= 0xBE,
+
+	/* vendor-specific */
+	ScmdFwaddr	= 0xE2,		/* first writeable address */
+	ScmdTreserve	= 0xE4,		/* reserve track */
+	ScmdTinfo	= 0xE5,		/* read track info */
+	ScmdTwrite	= 0xE6,		/* write track */
+	ScmdMload	= 0xE7,		/* medium load/unload */
+	ScmdFixation	= 0xE9,		/* fixation */
 };
 
 enum {