Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jan 1998 23:29:06 +1100
From:      Bruce Evans <bde@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
Message-ID:  <199801281229.XAA05384@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>  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



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