Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Mar 98 22:48:12 EST
From:      luoqi@watermarkgroup.com (Luoqi Chen)
To:        freebsd-multimedia@FreeBSD.ORG, scottm@cs.ucla.edu
Subject:   Re:  NEC 276 CDrom drive
Message-ID:  <9803250348.AA28812@watermarkgroup.com>

next in thread | raw e-mail | index | archive | help
> I brought this up on this list a few months ago, and now with a minor
> lull in my courses, I did some debugging. I'd been getting "unknown
> phase" errors and was told that this was due to latency in the controller.
> 
> It's not. It's due to a strong predicate in atapi.c. I changed
> 
> 	#define PHASE_COMPLETED (ARI_IN | ARI_CMD)
> 
> to
> 
> 	#define PHASE_COMPLETED (ARI_CMD)
> 
> and the unknown phase (the more common problem for me) goes away.
> Apparently, the controller doesn't assert ARI_IN when the ATAPI_MODE_SENSE
> command is done.
> 
> Question: Is this change to PHASE_COMPLETED, albeit a weaker predicate,
> safe? And can someone commit this change to -current?
You can't do this. According to spec, ARI_IN and ARI_CMD both have to be
asserted when data transfer is done.

I have a NEC 273/4.21 drive, and I saw the same message during bootup.
Signal timing for these NEC drives doesn't exactly follow the spec:
when data transfer is done, the drive should assert IO/CMD first, then
deassert ARQ and BSY, then assert INTRQ.

Try the following patch:

Index: atapi.c
===================================================================
RCS file: /fun/cvs/src/sys/i386/isa/atapi.c,v
retrieving revision 1.24
diff -u -r1.24 atapi.c
--- atapi.c	1998/03/01 18:57:27	1.24
+++ atapi.c	1998/03/24 07:48:05
@@ -711,7 +711,9 @@
 {
 	u_char ireason;
 	u_short len, i;
+	int retry = 100;
 
+again:
 	if (atapi_wait (ata->port, 0) < 0) {
 		ac->result.status = inb (ata->port + AR_STATUS);
 		ac->result.error = inb (ata->port + AR_ERROR);
@@ -734,8 +736,13 @@
 			ac->result.status, ARS_BITS,
 			ac->result.error, AER_BITS);
 	}
-	switch ((ireason & (ARI_CMD | ARI_IN)) | (ac->result.status & ARS_DRQ)) {
+	switch ((ireason & (ARI_CMD|ARI_IN)) | (ac->result.status & ARS_DRQ)) {
 	default:
+		/* we could be between phases for immediate requests */
+		if (!ac->callback && retry--) {
+			DELAY(10);
+			goto again;
+		}
 		printf ("atapi%d.%d: unknown phase\n", ata->ctrlr, ac->unit);
 		ac->result.code = RES_ERR;
 		break;
@@ -948,20 +955,13 @@
 		/* Send packet command. */
 		atapi_send_cmd (ata, ac);
 
-		/* Wait for data i/o phase. */
-		for (cnt=20000; cnt>0; --cnt)
-			if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) |
-			    (inb (ata->port + AR_STATUS) & ARS_DRQ)) != PHASE_CMDOUT)
-				break;
-
-		/* Do all needed i/o. */
-		while (atapi_io (ata, ac))
-			/* Wait for DRQ deassert. */
+		do {
 			for (cnt=2000; cnt>0; --cnt) {
-				if (! (inb (ata->port + AR_STATUS) & ARS_DRQ))
+				u_char s = inb(ata->port + AR_STATUS);
+				if ((s & (ARS_DRQ | ARS_BSY)) == ARS_BSY)
 					break;
-				DELAY(10);
 			}
+		} while (atapi_io(ata, ac));
 	}
 	return (ac->result);
 }

> 
> -scooter
> --
> Scott Michel                        | In life, there are sheep and there are
> UCLA Computer Science		    | wolves.
> PhD Graduate Student                |      ... And I don't bleed ...
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-multimedia" in the body of the message
> 

-lq

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-multimedia" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9803250348.AA28812>