From owner-freebsd-current Sun Aug 27 10:53:51 1995 Return-Path: current-owner Received: (from majordom@localhost) by freefall.FreeBSD.org (8.6.11/8.6.6) id KAA28254 for current-outgoing; Sun, 27 Aug 1995 10:53:51 -0700 Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.34]) by freefall.FreeBSD.org (8.6.11/8.6.6) with ESMTP id KAA28248 for ; Sun, 27 Aug 1995 10:53:48 -0700 Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.9/8.6.9) id DAA24683; Mon, 28 Aug 1995 03:52:01 +1000 Date: Mon, 28 Aug 1995 03:52:01 +1000 From: Bruce Evans Message-Id: <199508271752.DAA24683@godzilla.zeta.org.au> To: current@freebsd.org, root@io.cts.com Subject: Re: wd0 detect fails Cc: vak@cronyx.ru Sender: current-owner@freebsd.org Precedence: bulk >I put a 2MB caching Promise IDE controller into my 486 and moved the >drives off the onboard IDE controller that this motherboard supports. >I disabled the BIOS settings for the onboard IDE, then restarted. >Under a current kernel built just two days ago, it fails to find wdc0 >at 0x1f0, can't mount /root, and panics. >If I go back to my previous kernel built August 8, it can find it just >fine (which is what I'm using now) and 0x1f0-0x1f7 irq 14. >So something has changed in the probing at startup that is causing it >to miss the drives hanging off this older caching controller. Cdrom support was added. The following change looks wrong (but works here): diff -c -2 -r1.81 wd.c *** 1.81 1995/05/16 07:52:04 --- wd.c 1995/08/19 19:40:54 *************** *** 1863,1868 **** DELAY(10 * 1000); outb(wdc + wd_ctlr, WDCTL_IDS); ! if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0 ! || (du->dk_error = inb(wdc + wd_error)) != 0x01) return (1); outb(wdc + wd_ctlr, WDCTL_4BIT); --- 1903,1912 ---- DELAY(10 * 1000); outb(wdc + wd_ctlr, WDCTL_IDS); ! if (wdwait(du, 0, TIMEOUT) != 0) ! return (1); ! du->dk_status = inb(wdc + wd_status); ! du->dk_error = inb(wdc + wd_error); ! if ((du->dk_status & ~(WDCS_READY | WDCS_SEEKCMPLT)) != 0 || ! du->dk_error != 0x01) return (1); outb(wdc + wd_ctlr, WDCTL_4BIT); The ATA spec (revision 4c, section B.6) says that the hardware shall set the status to 0x50 (WDCS_READY | WDCS_SEEKCMPLT) within 31 seconds of reset. This is what the old code tested for, except for the follow bugs: oldbug1) The other status bits (except WDCS_BUSY) aren't required to be zero. oldbug2) TIMEOUT is to small. It is 10000 ms but should be 31000 ms. The new code only waits for the WDCS_BUSY bit to go low; then it tests the other bits. This may be OK - the spec seems to say that the status register is set atomically, and reading the status register again might fix any timing problems (normally the status register shouldn't be read twice because of side effects. Reading it twice is is probably a harmless no-op here). The new code then tests the bits sloppily: newbug1) The (WDCS_READY | WDCS_SEEKCMPLT) bits aren't required to be one. It is being fussier. than the old code about the bits that should be zero and sloppier about the bits that should be one. I wouldn't have expected this to matter for drives that meet the spec. The new code also has some changes involving the b_active state. These seemed OK. Bruce