From owner-cvs-all Wed Jan 28 04:30:48 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id EAA22178 for cvs-all-outgoing; Wed, 28 Jan 1998 04:30:48 -0800 (PST) (envelope-from owner-cvs-all@FreeBSD.ORG) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id EAA22160; Wed, 28 Jan 1998 04:30:37 -0800 (PST) (envelope-from bde@godzilla.zeta.org.au) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.7/8.8.7) id XAA05384; Wed, 28 Jan 1998 23:29:06 +1100 Date: Wed, 28 Jan 1998 23:29:06 +1100 From: Bruce Evans Message-Id: <199801281229.XAA05384@godzilla.zeta.org.au> To: cvs-all@FreeBSD.ORG, cvs-committers@FreeBSD.ORG, cvs-sys@FreeBSD.ORG, msmith@FreeBSD.ORG Subject: Re: cvs commit: src/sys/i386/isa atapi.c Sender: owner-cvs-all@FreeBSD.ORG Precedence: bulk > Modified files: > sys/i386/isa atapi.c > Log: > Check the status port after waiting for DRQ; some drives seem to be very > slow coming off the bus (eg. Iomega's ATAPI Zip). Failure to do > this results in a false probe of an ATAPI device with garbage > data. > > Revision Changes Path > 1.22 +9 -0 src/sys/i386/isa/atapi.c How can this help? The status port has been checked about 1 usec before and has been found to have a value that would pass the new check (ARS_CHECK was clear on the previous read, and ARS_BUSY was clear on a read before that, so the bits are unlikely to be all 1). Answer: it probably helps by changing the timing. The DELAY(10)'s in atapi_wait() don't help since they aren't executed between reads of a good status and return. It isn't clear how this matters, since the new delay is between an inb() and an insw(), and the data should be ready before the inb() reports that it is. Perhaps the problem is earlier. According to an old draft version of the ATA spec, the timing for issueing a polled-mode input command is: driver drive ------ ----- 1. Write to command register. 2. "sets BSY within 400 nsec". 3. Wait at least 400 nsec to avoid seeing a stale BSY bit. 4. Spin waiting for BSY. 5. Data finishes arriving. 6. "sets DRQ within 700 usec". I think "usec" should be "nsec" here. Note that it doesn't matter if DRQ is set before the data finishes arriving, provided BSY remains set. 7. "clears BSY within 400 nsec of setting DRQ". I hope BSY can't be cleared 400 nsec _before_ setting DRQ. 8. Find BSY set. 9. If BSY can be cleared before DRQ is set, wait at least 400 nsec to avoid seeing a stale DRQ bit. 10. If DRQ is not set, some error bits should be set. Abort. 11. Read the data register. Provided step 9 is unnecessary, everything seems to be correct except that atapi_wait() doesn't do step 2 and is sloppy in step 9, so the following timing is possible: Step 4: see a stale clear BSY. Step 9: doesn't check for BSY again, so it may see DRQ set up to 400 nsec before the drive is ready. Step 2 is often unnecessary in wdwait(), since BSY is checked in a spinloop for step 9 (actually the same spinloop as for step 4), so so there is no problem unless both BSY and the bits being waited for are stale. Bruce