Browse Source

Plan 9 from Bell Labs 2007-04-28

David du Colombier 13 years ago
parent
commit
76a652a0b9

+ 8 - 6
dist/replica/_plan9.db

@@ -5597,7 +5597,7 @@ rc/bin/start - 775 sys sys 945617209 120
 rc/bin/stock - 775 sys sys 1143126371 292
 rc/bin/stop - 775 sys sys 945617209 110
 rc/bin/tel - 775 sys sys 1161209756 128
-rc/bin/termrc - 775 sys sys 1177629021 2240
+rc/bin/termrc - 775 sys sys 1177705963 2281
 rc/bin/termrc.local - 775 sys sys 1176500067 425
 rc/bin/thesaurus - 775 sys sys 1068054167 246
 rc/bin/tlsclienttunnel - 775 sys sys 1024375633 153
@@ -8102,7 +8102,7 @@ sys/src/9/pc/sdmylex.c - 664 sys sys 1171321627 28237
 sys/src/9/pc/sdscsi.c - 664 sys sys 1158889425 7241
 sys/src/9/pc/trap.c - 664 sys sys 1168306369 21848
 sys/src/9/pc/uartaxp.c - 664 sys sys 1166247784 18879
-sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
+sys/src/9/pc/uarti8250.c - 664 sys sys 1177676872 13957
 sys/src/9/pc/uartisa.c - 664 sys sys 1127126907 1777
 sys/src/9/pc/uartpci.c - 664 sys sys 1162859151 3617
 sys/src/9/pc/usb.h - 664 sys sys 1165555430 4257
@@ -13356,10 +13356,11 @@ sys/src/cmd/scuzz/cdaudio.c - 664 sys sys 944961085 2821
 sys/src/cmd/scuzz/cdr.c - 664 sys sys 944961084 3849
 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/scsireq.c - 664 sys sys 1168308290 13609
-sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1168308261 6011
-sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1158891727 38135
-sys/src/cmd/scuzz/sense.c - 664 sys sys 969510790 3901
+sys/src/cmd/scuzz/mo.words - 664 sys sys 1177702138 1262
+sys/src/cmd/scuzz/scsireq.c - 664 sys sys 1177702327 13464
+sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1177702200 6958
+sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1177702170 38155
+sys/src/cmd/scuzz/sense.c - 664 sys sys 1177702138 5680
 sys/src/cmd/sed.c - 664 sys sys 1100962924 27001
 sys/src/cmd/seq.c - 664 sys sys 1161442158 1691
 sys/src/cmd/sh.C - 664 sys sys 1055701754 10303
@@ -15811,3 +15812,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
+386/bin/scuzz - 775 sys sys 1177730506 115274

+ 8 - 7
dist/replica/plan9.db

@@ -397,7 +397,7 @@
 386/bin/sam - 775 sys sys 1168633586 159364
 386/bin/scat - 775 sys sys 1176520494 284766
 386/bin/scp - 775 sys sys 1176520495 152584
-386/bin/scuzz - 775 sys sys 1176520495 113699
+386/bin/scuzz - 775 sys sys 1177730506 115274
 386/bin/sed - 775 sys sys 1168402348 89763
 386/bin/seq - 775 sys sys 1162241047 38441
 386/bin/sha1sum - 775 sys sys 1168402348 61366
@@ -5597,7 +5597,7 @@ rc/bin/start - 775 sys sys 945617209 120
 rc/bin/stock - 775 sys sys 1143126371 292
 rc/bin/stop - 775 sys sys 945617209 110
 rc/bin/tel - 775 sys sys 1161209756 128
-rc/bin/termrc - 775 sys sys 1177629021 2240
+rc/bin/termrc - 775 sys sys 1177705963 2281
 rc/bin/termrc.local - 775 sys sys 1176500067 425
 rc/bin/thesaurus - 775 sys sys 1068054167 246
 rc/bin/tlsclienttunnel - 775 sys sys 1024375633 153
@@ -8102,7 +8102,7 @@ sys/src/9/pc/sdmylex.c - 664 sys sys 1171321627 28237
 sys/src/9/pc/sdscsi.c - 664 sys sys 1158889425 7241
 sys/src/9/pc/trap.c - 664 sys sys 1168306369 21848
 sys/src/9/pc/uartaxp.c - 664 sys sys 1166247784 18879
-sys/src/9/pc/uarti8250.c - 664 sys sys 1102820421 13958
+sys/src/9/pc/uarti8250.c - 664 sys sys 1177676872 13957
 sys/src/9/pc/uartisa.c - 664 sys sys 1127126907 1777
 sys/src/9/pc/uartpci.c - 664 sys sys 1162859151 3617
 sys/src/9/pc/usb.h - 664 sys sys 1165555430 4257
@@ -13356,10 +13356,11 @@ sys/src/cmd/scuzz/cdaudio.c - 664 sys sys 944961085 2821
 sys/src/cmd/scuzz/cdr.c - 664 sys sys 944961084 3849
 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/scsireq.c - 664 sys sys 1168308290 13609
-sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1168308261 6011
-sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1158891727 38135
-sys/src/cmd/scuzz/sense.c - 664 sys sys 969510790 3901
+sys/src/cmd/scuzz/mo.words - 664 sys sys 1177702138 1262
+sys/src/cmd/scuzz/scsireq.c - 664 sys sys 1177702327 13464
+sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1177702200 6958
+sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1177702170 38155
+sys/src/cmd/scuzz/sense.c - 664 sys sys 1177702138 5680
 sys/src/cmd/sed.c - 664 sys sys 1100962924 27001
 sys/src/cmd/seq.c - 664 sys sys 1161442158 1691
 sys/src/cmd/sh.C - 664 sys sys 1055701754 10303

+ 8 - 0
dist/replica/plan9.log

@@ -48507,3 +48507,11 @@
 1177630205 0 c cfg/example/termrc - 775 sys sys 1177628544 195
 1177630205 1 m cfg/example/termrc - 775 sys sys 1177628544 195
 1177630205 2 c rc/bin/termrc - 775 sys sys 1177629021 2240
+1177677007 0 c sys/src/9/pc/uarti8250.c - 664 sys sys 1177676872 13957
+1177702207 0 a sys/src/cmd/scuzz/mo.words - 664 sys sys 1177702138 1262
+1177702207 1 c sys/src/cmd/scuzz/scsireq.h - 664 sys sys 1177702200 6958
+1177702207 2 c sys/src/cmd/scuzz/scuzz.c - 664 sys sys 1177702170 38155
+1177702207 3 c sys/src/cmd/scuzz/sense.c - 664 sys sys 1177702138 5680
+1177704005 0 c sys/src/cmd/scuzz/scsireq.c - 664 sys sys 1177702327 13464
+1177707605 0 c rc/bin/termrc - 775 sys sys 1177705963 2281
+1177731006 0 c 386/bin/scuzz - 775 sys sys 1177730506 115274

+ 4 - 0
rc/bin/termrc

@@ -90,3 +90,7 @@ if(test -f /dev/mousectl){
 			pipefile -dr /bin/aux/accupoint /dev/mouse
 	}
 }
+
+usbstart
+if (test -f /dev/apm)
+	aux/apm

+ 1 - 1
sys/src/9/pc/uarti8250.c

@@ -563,7 +563,7 @@ i8250enable(Uart* uart, int ie)
 	 * the transmitter is really empty.
 	 * Also, reading the Iir outwith i8250interrupt()
 	 * can be dangerous, but this should only happen
-	 * once, before interrupts are enabled.
+	 * once before interrupts are enabled.
 	 */
 	ilock(ctlr);
 	if(!ctlr->checkfifo){

+ 54 - 0
sys/src/cmd/scuzz/mo.words

@@ -0,0 +1,54 @@
+/*
+ * these scuzz modesense commands return the following for an hp worm drive:
+ *
+ * modesense
+ *  Header
+ *     00 5E 02 90 00 00 00 08
+ *  Block 0
+ *     00 13 47 70 00 00 08 00    (density 00 blocks 1263472 length 2048)
+ *  Page 01 10
+ *     80 05 00 00 00 00 05 00 00 00
+ *  Page 02 14
+ *     20 20 00 00 00 00 00 00 00 20 00 00 00 00
+ *  Page 08 10
+ *     06 00 00 40 00 01 00 01 00 40
+ *  Page 0A 6
+ *     00 00 00 00 00 00
+ *  Page 0B 6
+ *     00 00 02 03 00 00
+ *  Page 20 10
+ *     04 00 00 00 00 00 00 00 00 18
+ *  Page 21 10
+ *     00 00 01 00 02 00 00 00 00 00
+ *  Page 00 0
+ *
+ * modesense6
+ *  Header
+ *     5B 02 90 08
+ *  Block 0
+ *     00 13 47 70 00 00 08 00    (density 00 blocks 1263472 length 2048)
+ *  Page 01 10
+ *     80 05 00 00 00 00 05 00 00 00
+ *  Page 02 14
+ *     20 20 00 00 00 00 00 00 00 20 00 00 00 00
+ *  Page 08 10
+ *     06 00 00 40 00 01 00 01 00 40
+ *  Page 0A 6
+ *     00 00 00 00 00 00
+ *  Page 0B 6
+ *     00 00 02 03 00 00
+ *  Page 20 10
+ *     04 00 00 00 00 00 00 00 00 18
+ *  Page 21 10
+ *     00 00 01 00 02 00 00 00 00 00
+ *  Page 00 0
+ *     Page 00 0
+ *    ok 92
+ *
+ * the drive is:
+ *
+ * # cat ctl
+ * inquiry HP      C1113J          1.099904323710    8XMO  
+ * geometry 1263472 2048
+ * part data 0 1263472
+ */

+ 149 - 158
sys/src/cmd/scuzz/scsireq.c

@@ -26,9 +26,9 @@ SRready(ScsiReq *rp)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 0;
 	rp->data.write = 1;
@@ -40,10 +40,10 @@ SRrewind(ScsiReq *rp)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdRewind;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 0;
 	rp->data.write = 1;
@@ -65,13 +65,13 @@ SRreqsense(ScsiReq *rp)
 		rp->status = STok;
 		return 0;
 	}
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdRsense;
 	cmd[4] = sizeof(req.sense);
 	memset(&req, 0, sizeof(req));
 	req.fd = rp->fd;
 	req.cmd.p = cmd;
-	req.cmd.count = sizeof(cmd);
+	req.cmd.count = sizeof cmd;
 	req.data.p = rp->sense;
 	req.data.count = sizeof(rp->sense);
 	req.data.write = 0;
@@ -85,10 +85,10 @@ SRformat(ScsiReq *rp)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdFormat;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 6;
 	rp->data.write = 0;
@@ -100,10 +100,10 @@ SRrblimits(ScsiReq *rp, uchar *list)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdRblimits;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = list;
 	rp->data.count = 6;
 	rp->data.write = 0;
@@ -115,21 +115,16 @@ dirdevrw(ScsiReq *rp, uchar *cmd, long nbytes)
 {
 	long n;
 
-	n = nbytes/rp->lbsize;
-	if(rp->offset <= 0x1fffff && n <= 256 && (rp->flags & Frw10) == 0){
-		cmd[1] = rp->offset>>16;
-		cmd[2] = rp->offset>>8;
-		cmd[3] = rp->offset;
+	n = nbytes / rp->lbsize;
+	if(rp->offset <= Max24off && n <= 256 && (rp->flags & Frw10) == 0){
+		PUTBE24(cmd+1, rp->offset);
 		cmd[4] = n;
 		cmd[5] = 0;
 		return 6;
 	}
 	cmd[0] |= ScmdExtread;
 	cmd[1] = 0;
-	cmd[2] = rp->offset>>24;
-	cmd[3] = rp->offset>>16;
-	cmd[4] = rp->offset>>8;
-	cmd[5] = rp->offset;
+	PUTBELONG(cmd+2, rp->offset);
 	cmd[6] = 0;
 	cmd[7] = n>>8;
 	cmd[8] = n;
@@ -142,12 +137,10 @@ seqdevrw(ScsiReq *rp, uchar *cmd, long nbytes)
 {
 	long n;
 
-	cmd[1] = rp->flags&Fbfixed? 0x01: 0x00;
-	/* cmd[1]&2 is the SILI bit: don't report `incorrect' block lengths */
-	n = nbytes/rp->lbsize;
-	cmd[2] = n>>16;
-	cmd[3] = n>>8;
-	cmd[4] = n;
+	/* don't set Cmd1sili; we want the ILI bit instead of a fatal error */
+	cmd[1] = rp->flags&Fbfixed? Cmd1fixed: 0;
+	n = nbytes / rp->lbsize;
+	PUTBE24(cmd+2, n);
 	cmd[5] = 0;
 	return 6;
 }
@@ -162,6 +155,8 @@ SRread(ScsiReq *rp, void *buf, long nbytes)
 		rp->status = Status_BADARG;
 		return -1;
 	}
+
+	/* set up scsi read cmd */
 	cmd[0] = ScmdRead;
 	if(rp->flags & Fseqdev)
 		rp->cmd.count = seqdevrw(rp, cmd, nbytes);
@@ -171,36 +166,43 @@ SRread(ScsiReq *rp, void *buf, long nbytes)
 	rp->data.p = buf;
 	rp->data.count = nbytes;
 	rp->data.write = 0;
-	if((n = SRrequest(rp)) == -1){
-		/* maybe we just read a short record? */
-		if (exabyte) {
-			fprint(2, "read error\n");
-			rp->status = STcheck;
-			return n;
-		}
-		if(rp->status != Status_SD || (rp->sense[0] & 0x80) == 0)
-			return -1;
-		if (debug)
-			fprint(2, "SRread: SRrequest failed with sense data; reading byte count from sense\n");
-		n = ((rp->sense[3]<<24)
-		   | (rp->sense[4]<<16)
-		   | (rp->sense[5]<<8)
-		   | rp->sense[6])
-		   * rp->lbsize;
-		if(!(rp->flags & Fseqdev))
-			return -1;
-		if(rp->sense[2] == 0x80 || rp->sense[2] == 0x08)
-			rp->data.count = nbytes - n;
-		else if(rp->sense[2] == 0x20 && n > 0)
-			rp->data.count = nbytes - n;
-		else
-			return -1;
-		if (debug)
-			fprint(2, "SRread: computing byte count from sense\n");
-		n = rp->data.count;
-		rp->status = STok;
+
+	/* issue it */
+	n = SRrequest(rp);
+	if(n != -1){			/* it worked? */
+		rp->offset += n / rp->lbsize;
+		return n;
 	}
-	rp->offset += n/rp->lbsize;
+
+	/* request failed; maybe we just read a short record? */
+	if (exabyte) {
+		fprint(2, "read error\n");
+		rp->status = STcheck;
+		return n;
+	}
+	if(rp->status != Status_SD || !(rp->sense[0] & Sd0valid))
+		return -1;
+	/* compute # of bytes not read */
+	n = GETBELONG(rp->sense+3) * rp->lbsize;
+	if (debug)
+		fprint(2,
+	"SRread: request failed with sense data; sense byte count %ld\n",
+			n);
+	if(!(rp->flags & Fseqdev))
+		return -1;
+
+	/* device is a tape or something similar */
+	if (rp->sense[2] == Sd2filemark || rp->sense[2] == 0x08 ||
+	    rp->sense[2] & Sd2ili && n > 0)
+		rp->data.count = nbytes - n;
+	else
+		return -1;
+	n = rp->data.count;
+	if (!rp->readblock++ || debug)
+		fprint(2, "SRread: tape data count %ld%s\n", n,
+			(rp->sense[2] & Sd2ili? " with ILI": ""));
+	rp->status = STok;
+	rp->offset += n / rp->lbsize;
 	return n;
 }
 
@@ -214,6 +216,8 @@ SRwrite(ScsiReq *rp, void *buf, long nbytes)
 		rp->status = Status_BADARG;
 		return -1;
 	}
+
+	/* set up scsi write cmd */
 	cmd[0] = ScmdWrite;
 	if(rp->flags & Fseqdev)
 		rp->cmd.count = seqdevrw(rp, cmd, nbytes);
@@ -223,27 +227,25 @@ SRwrite(ScsiReq *rp, void *buf, long nbytes)
 	rp->data.p = buf;
 	rp->data.count = nbytes;
 	rp->data.write = 1;
+
+	/* issue it */
 	if((n = SRrequest(rp)) == -1){
 		if (exabyte) {
 			fprint(2, "write error\n");
 			rp->status = STcheck;
 			return n;
 		}
-		if(rp->status != Status_SD || rp->sense[2] != 0x40)
+		if(rp->status != Status_SD || rp->sense[2] != Sd2eom)
 			return -1;
-		if(rp->sense[0] & 0x80){
-			n -= ((rp->sense[3]<<24)
-			    | (rp->sense[4]<<16)
-			    | (rp->sense[5]<<8)
-			    | rp->sense[6])
-			    * rp->lbsize;
+		if(rp->sense[0] & Sd0valid){
+			n -= GETBELONG(rp->sense+3) * rp->lbsize;
 			rp->data.count = nbytes - n;
 		}
 		else
 			rp->data.count = nbytes;
 		n = rp->data.count;
 	}
-	rp->offset += n/rp->lbsize;
+	rp->offset += n / rp->lbsize;
 	return n;
 }
 
@@ -253,7 +255,6 @@ SRseek(ScsiReq *rp, long offset, int type)
 	uchar cmd[10];
 
 	switch(type){
-
 	case 0:
 		break;
 
@@ -262,30 +263,18 @@ SRseek(ScsiReq *rp, long offset, int type)
 		if(offset >= 0)
 			break;
 		/*FALLTHROUGH*/
-
 	default:
 		rp->status = Status_BADARG;
 		return -1;
 	}
-	if(offset <= 0x1fffff && (rp->flags & Frw10) == 0){
+	memset(cmd, 0, sizeof cmd);
+	if(offset <= Max24off && (rp->flags & Frw10) == 0){
 		cmd[0] = ScmdSeek;
-		cmd[1] = (offset>>16) & 0x1F;
-		cmd[2] = offset>>8;
-		cmd[3] = offset;
-		cmd[4] = 0;
-		cmd[5] = 0;
+		PUTBE24(cmd+1, offset & Max24off);
 		rp->cmd.count = 6;
 	}else{
 		cmd[0] = ScmdExtseek;
-		cmd[1] = 0;
-		cmd[2] = offset>>24;
-		cmd[3] = offset>>16;
-		cmd[4] = offset>>8;
-		cmd[5] = offset;
-		cmd[6] = 0;
-		cmd[7] = 0;
-		cmd[8] = 0;
-		cmd[9] = 0;
+		PUTBELONG(cmd+2, offset);
 		rp->cmd.count = 10;
 	}
 	rp->cmd.p = cmd;
@@ -303,14 +292,11 @@ SRfilemark(ScsiReq *rp, ulong howmany)
 {
 	uchar cmd[6];
 
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdFmark;
-	cmd[1] = 0;
-	cmd[2] = howmany>>16;
-	cmd[3] = howmany>>8;
-	cmd[4] = howmany;
-	cmd[5] = 0;
+	PUTBE24(cmd+2, howmany);
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 0;
 	rp->data.write = 1;
@@ -322,14 +308,12 @@ SRspace(ScsiReq *rp, uchar code, long howmany)
 {
 	uchar cmd[6];
 
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdSpace;
 	cmd[1] = code;
-	cmd[2] = howmany>>16;
-	cmd[3] = howmany>>8;
-	cmd[4] = howmany;
-	cmd[5] = 0;
+	PUTBE24(cmd+2, howmany);
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 0;
 	rp->data.write = 1;
@@ -344,13 +328,13 @@ SRinquiry(ScsiReq *rp)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdInq;
-	cmd[4] = sizeof(rp->inquiry);
+	cmd[4] = sizeof rp->inquiry;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = rp->inquiry;
-	rp->data.count = sizeof(rp->inquiry);
+	rp->data.count = sizeof rp->inquiry;
 	rp->data.write = 0;
 	if(SRrequest(rp) >= 0){
 		rp->flags |= Finqok;
@@ -365,13 +349,13 @@ SRmodeselect6(ScsiReq *rp, uchar *list, long nbytes)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdMselect6;
 	if((rp->flags & Finqok) && (rp->inquiry[2] & 0x07) >= 2)
 		cmd[1] = 0x10;
 	cmd[4] = nbytes;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = list;
 	rp->data.count = nbytes;
 	rp->data.write = 1;
@@ -383,14 +367,14 @@ SRmodeselect10(ScsiReq *rp, uchar *list, long nbytes)
 {
 	uchar cmd[10];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	if((rp->flags & Finqok) && (rp->inquiry[2] & 0x07) >= 2)
 		cmd[1] = 0x10;
 	cmd[0] = ScmdMselect10;
 	cmd[7] = nbytes>>8;
 	cmd[8] = nbytes;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = list;
 	rp->data.count = nbytes;
 	rp->data.write = 1;
@@ -402,12 +386,12 @@ SRmodesense6(ScsiReq *rp, uchar page, uchar *list, long nbytes)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdMsense6;
 	cmd[2] = page;
 	cmd[4] = nbytes;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = list;
 	rp->data.count = nbytes;
 	rp->data.write = 0;
@@ -419,13 +403,13 @@ SRmodesense10(ScsiReq *rp, uchar page, uchar *list, long nbytes)
 {
 	uchar cmd[10];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdMsense10;
 	cmd[2] = page;
 	cmd[7] = nbytes>>8;
 	cmd[8] = nbytes;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = list;
 	rp->data.count = nbytes;
 	rp->data.write = 0;
@@ -437,11 +421,11 @@ SRstart(ScsiReq *rp, uchar code)
 {
 	uchar cmd[6];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdStart;
 	cmd[4] = code;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = cmd;
 	rp->data.count = 0;
 	rp->data.write = 1;
@@ -453,10 +437,10 @@ SRrcapacity(ScsiReq *rp, uchar *data)
 {
 	uchar cmd[10];
 
-	memset(cmd, 0, sizeof(cmd));
+	memset(cmd, 0, sizeof cmd);
 	cmd[0] = ScmdRcapacity;
 	rp->cmd.p = cmd;
-	rp->cmd.count = sizeof(cmd);
+	rp->cmd.count = sizeof cmd;
 	rp->data.p = data;
 	rp->data.count = 8;
 	rp->data.write = 0;
@@ -480,6 +464,7 @@ request(int fd, ScsiPtr *cmd, ScsiPtr *data, int *status)
 	}
 
 	/* read or write actual data */
+	werrstr("");
 	if(data->write)
 		n = write(fd, data->p, data->count);
 	else {
@@ -489,11 +474,13 @@ request(int fd, ScsiPtr *cmd, ScsiPtr *data, int *status)
 		else if (n < data->count)
 			memset(data->p + n, 0, data->count - n);
 	}
-	if (n != data->count && n <= 0)
-		fprint(2,
+	if (n != data->count && n <= 0) {
+		if (debug)
+			fprint(2,
 	"request: tried to %s %ld bytes of data for cmd 0x%x but got %r\n",
-			(data->write? "write": "read"), data->count, cmd->p[0]);
-	else if (n != data->count && (data->write || debug))
+				(data->write? "write": "read"),
+				data->count, cmd->p[0]);
+	} else if (n != data->count && (data->write || debug))
 		fprint(2, "request: %s %ld of %ld bytes of actual data\n",
 			(data->write? "wrote": "read"), n, data->count);
 
@@ -509,7 +496,8 @@ request(int fd, ScsiPtr *cmd, ScsiPtr *data, int *status)
 		buf[r] = '\0';
 	*status = atoi(buf);
 	if(n < 0 && (exabyte || *status != STcheck))
-		fprint(2, "scsireq: status 0x%2.2uX: data transfer: %r\n", *status);
+		fprint(2, "scsireq: status 0x%2.2uX: data transfer: %r\n",
+			*status);
 	return n;
 }
 
@@ -565,10 +553,10 @@ dirdevopen(ScsiReq *rp)
 
 	if(SRstart(rp, 1) == -1 || SRrcapacity(rp, data) == -1)
 		return -1;
-	rp->lbsize = (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7];
-	blocks =     (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
+	rp->lbsize = GETBELONG(data+4);
+	blocks =     GETBELONG(data);
 	/* some newer dev's don't support 6-byte commands */
-	if(blocks > 0x1fffff && !force6bytecmds)
+	if(blocks > Max24off && !force6bytecmds)
 		rp->flags |= Frw10;
 	return 0;
 }
@@ -580,47 +568,46 @@ seqdevopen(ScsiReq *rp)
 
 	if(SRrblimits(rp, limits) == -1)
 		return -1;
-	if(limits[1] || limits[2] != limits[4] || limits[3] != limits[5]){
+	if(limits[1] == 0 && limits[2] == limits[4] && limits[3] == limits[5]){
+		rp->flags |= Fbfixed;
+		rp->lbsize = limits[4]<<8 | limits[5];
+		return 0;
+	}
+	/*
+	 * On some older hardware the optional 10-byte
+	 * modeselect command isn't implemented.
+	 */
+	if (force6bytecmds)
+		rp->flags |= Fmode6;
+	if(!(rp->flags & Fmode6)){
+		/* try 10-byte command first */
+		memset(mode, 0, sizeof mode);
+		mode[3] = 0x10;		/* device-specific param. */
+		mode[7] = 8;		/* block descriptor length */
 		/*
-		 * On some older hardware the optional 10-byte
-		 * modeselect command isn't implemented.
+		 * exabytes can't handle this, and
+		 * modeselect(10) is optional.
 		 */
-		if (force6bytecmds)
-			rp->flags |= Fmode6;
-		if(!(rp->flags & Fmode6)){
-			/* try 10-byte command first */
-			memset(mode, 0, sizeof(mode));
-			mode[3] = 0x10;		/* device-specific param. */
-			mode[7] = 8;		/* block descriptor length */
-			/*
-			 * exabytes can't handle this, and
-			 * modeselect(10) is optional.
-			 */
-			if(SRmodeselect10(rp, mode, sizeof(mode)) != -1){
-				rp->lbsize = 1;
-				return 0;	/* success */
-			}
-			/* can't do 10-byte commands, back off to 6-byte ones */
-			rp->flags |= Fmode6;
+		if(SRmodeselect10(rp, mode, sizeof mode) != -1){
+			rp->lbsize = 1;
+			return 0;	/* success */
 		}
-
-		/* 6-byte command */
-		memset(mode, 0, sizeof(mode));
-		mode[2] = 0x10;		/* device-specific param. */
-		mode[3] = 8;		/* block descriptor length */
-		/*
-		 * bsd sez exabytes need this bit (NBE) in vendor-specific
-		 * page (0), but so far we haven't needed it.
-		 */
-		if (0)
-			mode[12] |= 8;
-		if(SRmodeselect6(rp, mode, 4+8) == -1)
-			return -1;
-		rp->lbsize = 1;
-	}else{
-		rp->flags |= Fbfixed;
-		rp->lbsize = (limits[4]<<8)|limits[5];
+		/* can't do 10-byte commands, back off to 6-byte ones */
+		rp->flags |= Fmode6;
 	}
+
+	/* 6-byte command */
+	memset(mode, 0, sizeof mode);
+	mode[2] = 0x10;		/* device-specific param. */
+	mode[3] = 8;		/* block descriptor length */
+	/*
+	 * bsd sez exabytes need this bit (NBE: no busy enable) in
+	 * vendor-specific page (0), but so far we haven't needed it.
+	mode[12] |= 8;
+	 */
+	if(SRmodeselect6(rp, mode, 4+8) == -1)
+		return -1;
+	rp->lbsize = 1;
 	return 0;
 }
 
@@ -628,16 +615,20 @@ static int
 wormdevopen(ScsiReq *rp)
 {
 	uchar list[MaxDirData];
-	long status;
+	long status, blen;
 
-	if(SRstart(rp, 1) == -1)
-		return -1;
-	if((status = SRmodesense10(rp, 0x3F, list, sizeof(list))) == -1)
+	if (SRstart(rp, 1) == -1 ||
+	    (status = SRmodesense10(rp, Allmodepages, list, sizeof list)) == -1)
 		return -1;
-	if(((list[6]<<8)|list[3]) < 8)
+	/* nbytes = list[0]<<8 | list[1]; */
+
+	/* # of bytes of block descriptors of 8 bytes each */
+	blen = list[6]<<8 | list[7];
+	if(blen < 8)			/* not even 1 block descriptor? */
 		rp->lbsize = 2048;
 	else
-		rp->lbsize = (list[13]<<8)|(list[14]<<8)|list[15];
+		/* last 3 bytes of block 0 descriptor */
+		rp->lbsize = GETBE24(list+13);
 	return status;
 }
 
@@ -650,7 +641,7 @@ SRopenraw(ScsiReq *rp, char *unit)
 		rp->status = Status_BADARG;
 		return -1;
 	}
-	memset(rp, 0, sizeof(*rp));
+	memset(rp, 0, sizeof *rp);
 	rp->unit = unit;
 
 	sprint(name, "%s/raw", unit);

+ 30 - 1
sys/src/cmd/scuzz/scsireq.h

@@ -29,9 +29,10 @@ typedef struct {
 	int	status;			/* returned status */
 	uchar	sense[MaxDirData];	/* returned sense data */
 	uchar	inquiry[MaxDirData];	/* returned inquiry data */
+	int	readblock;		/* flag: read a block since open */
 } ScsiReq;
 
-enum {					/* flags */
+enum {					/* software flags */
 	Fopen		= 0x0001,	/* open */
 	Fseqdev		= 0x0002,	/* sequential-access device */
 	Fwritten	= 0x0004,	/* device written */
@@ -121,6 +122,34 @@ enum {					/* SCSI command codes */
 	ScmdSendKey	= 0xA3,		/* write dvd key */
 };
 
+enum {
+	/* sense data byte 0 */
+	Sd0valid	= 0x80,		/* valid sense data present */
+
+	/* sense data byte 2 */
+	/* incorrect-length indicator, difference in bytes 3—6 */
+	Sd2ili		= 0x20,
+	Sd2eom		= 0x40,		/* end of medium (tape) */
+	Sd2filemark	= 0x80,		/* at a filemark (tape) */
+
+	/* command byte 1 */
+	Cmd1fixed	= 1,		/* use fixed-length blocks */
+	Cmd1sili	= 2,		/* don't set Sd2ili */
+
+	/* limit of block #s in 24-bit ccbs */
+	Max24off	= (1<<21) - 1,	/* 2⁲ⁱ - 1 */
+
+	/* mode pages */
+	Allmodepages = 0x3F,
+};
+
+/* p arguments should be of type uchar* */
+#define GETBELONG(p) ((ulong)(p)[0]<<24 | (ulong)(p)[1]<<16 | (p)[2]<<8 | (p)[3])
+#define PUTBELONG(p, ul) ((p)[0] = (ul)>>24, (p)[1] = (ul)>>16, \
+			  (p)[2] = (ul)>>8,  (p)[3] = (ul))
+#define GETBE24(p)	((ulong)(p)[0]<<16 | (p)[1]<<8 | (p)[2])
+#define PUTBE24(p, ul)	((p)[0] = (ul)>>16, (p)[1] = (ul)>>8, (p)[2] = (ul))
+
 extern long SRready(ScsiReq*);
 extern long SRrewind(ScsiReq*);
 extern long SRreqsense(ScsiReq*);

+ 23 - 24
sys/src/cmd/scuzz/scuzz.c

@@ -380,7 +380,7 @@ cmdmodeselect6(ScsiReq *rp, int argc, char *argv[])
 	long nbytes, ul;
 	char *p;
 
-	memset(list, 0, sizeof(list));
+	memset(list, 0, sizeof list);
 	for(nbytes = 0; argc; argc--, argv++, nbytes++){
 		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){
 			rp->status = Status_BADARG;
@@ -401,7 +401,7 @@ cmdmodeselect10(ScsiReq *rp, int argc, char *argv[])
 	long nbytes, ul;
 	char *p;
 
-	memset(list, 0, sizeof(list));
+	memset(list, 0, sizeof list);
 	for(nbytes = 0; argc; argc--, argv++, nbytes++){
 		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){
 			rp->status = Status_BADARG;
@@ -422,7 +422,7 @@ cmdmodesense6(ScsiReq *rp, int argc, char *argv[])
 	long i, n, nbytes, status;
 	char *p;
 
-	nbytes = sizeof(list);
+	nbytes = sizeof list;
 	switch(argc){
 
 	default:
@@ -444,7 +444,7 @@ cmdmodesense6(ScsiReq *rp, int argc, char *argv[])
 		break;
 
 	case 0:
-		page = 0x3F;
+		page = Allmodepages;
 		break;
 	}
 	if((status = SRmodesense6(rp, page, list, nbytes)) == -1)
@@ -498,7 +498,6 @@ cmdmodesense10(ScsiReq *rp, int argc, char *argv[])
 
 	nbytes = MaxDirData;
 	switch(argc){
-
 	default:
 		rp->status = Status_BADARG;
 		return -1;
@@ -509,7 +508,6 @@ cmdmodesense10(ScsiReq *rp, int argc, char *argv[])
 			return -1;
 		}
 		/*FALLTHROUGH*/
-
 	case 1:
 		if((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){
 			rp->status = Status_BADARG;
@@ -518,7 +516,7 @@ cmdmodesense10(ScsiReq *rp, int argc, char *argv[])
 		break;
 
 	case 0:
-		page = 0x3F;
+		page = Allmodepages;
 		break;
 	}
 	list = malloc(nbytes);
@@ -565,20 +563,21 @@ cmdmodesense10(ScsiReq *rp, int argc, char *argv[])
 		}
 		Bputc(&bout, '\n');
 	}
-	else while(nbytes > 0){				/* pages */
-		i = *(lp+1);
-		nbytes -= i+2;
-		Bprint(&bout, " Page %2.2uX %d\n   ", *lp & 0x3F, *(lp+1));
-		lp += 2;
-		for(n = 0; n < i; n++){
-			if(n && ((n & 0x0F) == 0))
-				Bprint(&bout, "\n   ");
-			Bprint(&bout, " %2.2uX", *lp);
-			lp++;
+	else
+		while(nbytes > 0){				/* pages */
+			i = *(lp+1);
+			nbytes -= i+2;
+			Bprint(&bout, " Page %2.2uX %d\n   ", *lp & 0x3F, lp[1]);
+			lp += 2;
+			for(n = 0; n < i; n++){
+				if(n && ((n & 0x0F) == 0))
+					Bprint(&bout, "\n   ");
+				Bprint(&bout, " %2.2uX", *lp);
+				lp++;
+			}
+			if(n && (n & 0x0F))
+				Bputc(&bout, '\n');
 		}
-		if(n && (n & 0x0F))
-			Bputc(&bout, '\n');
-	}
 	free(list);
 	return status;
 }
@@ -714,7 +713,7 @@ cmdrtoc(ScsiReq *rp, int argc, char *argv[])
 	case 0:
 		break;
 	}
-	if((nbytes = SRTOC(rp, d, sizeof(d), format, track)) == -1){
+	if((nbytes = SRTOC(rp, d, sizeof d, format, track)) == -1){
 		if(rp->status == STok)
 			Bprint(&bout, "\t(probably empty)\n");
 		return -1;
@@ -814,7 +813,7 @@ cmdrdiscinfo(ScsiReq *rp, int argc, char*[])
 	case 0:
 		break;
 	}
-	if((nbytes = SRrdiscinfo(rp, d, sizeof(d))) == -1)
+	if((nbytes = SRrdiscinfo(rp, d, sizeof d)) == -1)
 		return -1;
 
 	dl = (d[0]<<8)|d[1];
@@ -933,7 +932,7 @@ cmdrtrackinfo(ScsiReq *rp, int argc, char *argv[])
 	case 0:
 		break;
 	}
-	if((nbytes = SRrtrackinfo(rp, d, sizeof(d), track)) == -1)
+	if((nbytes = SRrtrackinfo(rp, d, sizeof d, track)) == -1)
 		return -1;
 
 	dl = (d[0]<<8)|d[1];
@@ -1902,7 +1901,7 @@ main(int argc, char *argv[])
 		exits("Binit");
 	}
 
-	memset(&target, 0, sizeof(target));
+	memset(&target, 0, sizeof target);
 	if (raw) {			/* hack for -r */
 		++argc;
 		--argv;

+ 52 - 14
sys/src/cmd/scuzz/sense.c

@@ -4,9 +4,7 @@
 
 #include "scsireq.h"
 
-static
-char*	key[16] =
-{
+static char* key[16] = {
 	"no sense",
 	"recovered error",
 	"not ready",
@@ -25,39 +23,64 @@ char*	key[16] =
 	"reserved",
 };
 
-static
-struct
-{
+static struct {
 	uchar	asc;
 	uchar	ascq;
 	char*	diag;
-} code[] =
-{
-0x03,0x00,	"tray out",
+} code[] = {				/* see /sys/lib/scsicodes */
+0x00,0x01,	"filemark detected",
+0x00,0x17,	"cleaning requested",
+0x01,0x00,	"no index/sector signal",
+0x02,0x00,	"no seek complete",
+0x03,0x00,	"peripheral device write fault",
 0x04,0x00,	"drive not ready",
-0x08,0x00,	"communication failure",
-0x09,0x00,	"track following error",
+0x04,0x01,	"drive becoming ready",
+0x04,0x01,	"drive need initializing cmd",
+0x05,0x00,	"logical unit does not respond to selection",
+0x08,0x00,	"logical unit communication failure",
+0x09,0x00,	"track-following error",
+0x0c,0x00,	"write error",
+0x0c,0x01,	"write error - recovered with auto reallocation",
+0x0c,0x02,	"write error - auto reallocation failed",
+0x0c,0x03,	"write error - recommend reassignment",
 
 0x11,0x00,	"unrecovered read error",
 0x15,0x00,	"positioning error",
 0x17,0x00,	"recovered read data with retries",
 0x18,0x00,	"recovered read with ecc correction",
 0x1A,0x00,	"parameter list length error",
+0x1B,0x00,	"synchronous data transfer error",
 
 0x20,0x00,	"invalid command",
 0x21,0x00,	"invalid block address",
+0x22,0x00,	"illegal function (use 20 00, 24 00, or 26 00)",
 0x24,0x00,	"illegal field in command list",
 0x25,0x00,	"invalid lun",
-0x26,0x00,	"invalid field parameter list",
+0x26,0x00,	"invalid field in parameter list",
+0x27,0x00,	"write protected",
 0x28,0x00,	"medium changed",
 0x29,0x00,	"power-on reset or bus reset occurred",
 0x2C,0x00,	"command sequence error",
 
+0x30,0x00,	"incompatible medium installed",
 0x31,0x00,	"medium format corrupted",
-0x33,0x00,	"monitor atip error",
-0x34,0x00,	"absorption control error",
+0x33,0x00,	"tape length error / monitor atip error",
+0x34,0x00,	"enclosure failure / absorption control error",
 0x3A,0x00,	"medium not present",
+0x3B,0x00,	"sequential positioning error",
+0x3B,0x01,	"tape position error at beginning-of-medium",
+0x3B,0x02,	"tape position error at end-of-medium",
+0x3B,0x08,	"reposition error",
+0x3B,0x09,	"read past end of medium",
+0x3B,0x0A,	"read past beginning of medium",
+0x3B,0x0B,	"position past end of medium",
+0x3B,0x0C,	"position past beginning of medium",
+0x3B,0x0D,	"medium destination element full",
+0x3B,0x0E,	"medium source element empty",
+0x3B,0x0F,	"end of medium reached",
+0x3B,0x16,	"mechanical positioning or changer error",
 0x3D,0x00,	"invalid bits in identify message",
+0x3E,0x00,	"logical unit has not self-configured yet",
 
 0x40,0x00,	"diagnostic failure",
 0x42,0x00,	"power-on or self test failure",
@@ -65,13 +88,21 @@ struct
 0x47,0x00,	"scsi parity error",
 
 0x50,0x00,	"write append error",
+0x51,0x00,	"erase failure",
 0x53,0x00,	"medium load or eject failed",
+0x54,0x00,	"scsi to host system interface failure",
+0x55,0x00,	"system resource failure",
 0x57,0x00,	"unable to read toc, pma or subcode",
 0x5A,0x00,	"operator medium removal request",
+0x5D,0x00,	"failure prediction threshold exceeded",
 
+/* cd/dvd? */
 0x63,0x00,	"end of user area encountered on this track",
 0x64,0x00,	"illegal mode for this track",
 0x65,0x00,	"verify failed",
+0x67,0x00,	"configuration failure",
+0x68,0x00,	"logical unit not configured",
+0x69,0x00,	"data loss on logical unit",
 0x6f,0x01,	"copy protection key exchange failure - key not present",
 0x6f,0x02,	"copy protection key exchange failure - key not established",
 0x6f,0x03,	"read of scrambled sector without authentication",
@@ -79,6 +110,12 @@ struct
 0x6f,0x05,	"drive region must be permanent/region reset count error",
 0x6f,0x00,	"copy protection key exchange failure",
 
+0x72,0x00,	"session fixation error",
+0x73,0x00,	"cd control error",
+0x74,0x00,	"security error",
+
+/* vendor specific */
+
 0x81,0x00,	"illegal track",
 0x82,0x00,	"command now not valid",
 0x83,0x00,	"medium removal is prevented",
@@ -109,6 +146,7 @@ struct
 0xB6,0x00,	"block size format conflict",
 0xB7,0x00,	"current command aborted",
 
+/* cd/dvd burning? */
 0xD0,0x00,	"recovery needed",
 0xD1,0x00,	"can't recover from track",
 0xD2,0x00,	"can't recover from program memory area",