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>