Date: Sat, 27 Feb 1999 19:20:34 +1100 From: Bruce Evans <bde@zeta.org.au> To: dcs@newsguy.com, sos@freebsd.dk Cc: beyssac@enst.fr, freebsd-current@FreeBSD.ORG, grog@lemis.com, sheldonh@iafrica.com Subject: Re: IDE CDROM not found with PIIX4 chipset, -current kernel Message-ID: <199902270820.TAA24763@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>> Nope, that code snippet is in atapi.c its not in any of the drivers...
>> (and newer has been).
>
>You're right. Goes to show how long I haven't touched this part of
>the code. Alas, just reviewed it out of curiosity. It sure got more
>readable... :-) But I still hate those inb loops without DELAY...
There's only one, at least in my version.
I sent this in for review a year or so ago, but received no reply.
The main points are that it honours ATA timing in atapi_wait() and
checks for ARS_BUSY in atapi_wait(). This hopefully makes bogus checks
like the one in rev.1.22 unnecessary (status 0xff has ARS_BSY set so it
is invalid). I haven't tested the PC98 case. I removed PC98 code that
seems to only compensate for bugs in atapi_wait().
Bruce
diff -c2 atapi.c~ atapi.c
*** atapi.c~ Sat Feb 27 19:05:47 1999
--- atapi.c Tue Dec 29 01:17:34 1998
***************
*** 229,234 ****
*/
if (ata->accel && ata->intrcmd) {
! ata->intrcmd = 0;
! ata->slow = 1;
}
--- 229,234 ----
*/
if (ata->accel && ata->intrcmd) {
! ata->intrcmd = 0;
! ata->slow = 1;
}
***************
*** 399,414 ****
struct atapi_params *ap;
char tb [DEV_BSIZE];
- #ifdef PC98
- int cnt;
- outb(0x432,unit%2);
- print(("unit = %d,select %d\n",unit,unit%2));
- #endif
/* Wait for controller not busy. */
- #ifdef PC98
- outb (port + AR_DRIVE, unit / 2 ? ARD_DRIVE1 : ARD_DRIVE0);
- #else
- outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
- #endif
if (atapi_wait (port, 0) < 0) {
print (("atapiX.%d at 0x%x: controller busy, status=%b\n",
--- 399,404 ----
***************
*** 417,461 ****
}
! /* Issue ATAPI IDENTIFY command. */
#ifdef PC98
! outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
!
! /* Wait for DRQ deassert. */
! for (cnt=2000; cnt>0; --cnt)
! if (! (inb (port + AR_STATUS) & ARS_DRQ))
! break;
!
! outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
! DELAY(500);
#else
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
- outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
#endif
! /* Check that device is present. */
! if (inb (port + AR_STATUS) == 0xff) {
! print (("atapiX.%d at 0x%x: no device\n", unit, port));
! if (unit == 1)
! /* Select unit 0. */
! outb (port + AR_DRIVE, ARD_DRIVE0);
return (0);
}
/* Wait for data ready. */
if (atapi_wait (port, ARS_DRQ) != 0) {
print (("atapiX.%d at 0x%x: identify not ready, status=%b\n",
unit, port, inb (port + AR_STATUS), ARS_BITS));
- if (unit == 1)
- /* Select unit 0. */
- outb (port + AR_DRIVE, ARD_DRIVE0);
- return (0);
- }
-
- /* check that DRQ isn't a fake */
- if (inb (port + AR_STATUS) == 0xff) {
- print (("atapiX.%d at 0x%x: no device\n", unit, port));
- if (unit == 1)
- /* Select unit 0. */
- outb (port + AR_DRIVE, ARD_DRIVE0);
return (0);
}
--- 407,434 ----
}
! /* Select the drive. */
#ifdef PC98
! /* XXX what is this? */
! outb(0x432,unit%2);
! print(("unit = %d,select %d\n",unit,unit%2));
! outb (port + AR_DRIVE, unit / 2 ? ARD_DRIVE1 : ARD_DRIVE0);
#else
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
#endif
! /* Wait for controller not busy again. Necessary? */
! if (atapi_wait (port, 0) < 0) {
! print (("atapiX.%d at 0x%x: controller busy, status=%b\n",
! unit, port, inb (port + AR_STATUS), ARS_BITS));
return (0);
}
+ /* Issue ATAPI IDENTIFY command. */
+ outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
+
/* Wait for data ready. */
if (atapi_wait (port, ARS_DRQ) != 0) {
print (("atapiX.%d at 0x%x: identify not ready, status=%b\n",
unit, port, inb (port + AR_STATUS), ARS_BITS));
return (0);
}
***************
*** 499,503 ****
u_char s;
! /* Wait 5 sec for BUSY deassert. */
for (cnt=500000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
--- 472,479 ----
u_char s;
! /* Wait at least 400 nsec for BSY to become valid. */
! DELAY(1);
!
! /* Wait 5 sec for BSY deassert. */
for (cnt=500000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
***************
*** 511,518 ****
return (s & ARS_CHECK);
! /* Wait 50 msec for bits wanted. */
for (cnt=5000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
! if ((s & bits_wanted) == bits_wanted)
return (s & ARS_CHECK);
DELAY (10);
--- 487,494 ----
return (s & ARS_CHECK);
! /* Wait 50 msec for bits wanted and BSY still deasserted. */
for (cnt=5000; cnt>0; --cnt) {
s = inb (port + AR_STATUS);
! if ((s & (bits_wanted | ARS_BSY)) == bits_wanted)
return (s & ARS_CHECK);
DELAY (10);
***************
*** 1019,1023 ****
extern int atapi_lock (int ctlr);
! extern void wdintr (int);
/*
--- 995,999 ----
extern int atapi_lock (int ctlr);
! void wdintr(void *vunit);
/*
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199902270820.TAA24763>
