Date: Thu, 31 Aug 1995 05:17:15 +1000 From: Bruce Evans <bde@zeta.org.au> To: hackers@freebsd.org, jdl@chrome.onramp.net Subject: Re: More ATAPI -- possible insight into probe problems...? Message-ID: <199508301917.FAA18876@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>Oh my! Let's peek at my highly superior wd.c: >... > #ifdef WDDEBUG_PROBE > printf("wd%d: checking RW register on port 0x%x + 0x%x\n", > unit, du->dk_port, wd_cyl_lo); > #endif > /* check if we have registers that work */ > outb(du->dk_port + wd_cyl_lo, 0xa5); /* wd_cyl_lo is read/write */ > if (inb(du->dk_port + wd_cyl_lo) == 0xff) /* XXX too weak */ > goto nodevice; > >So who can tell me any details about that lovely weak check for R/W >registers that appears to be failing for me? Simple things like: > - Is this a valid register for a CDROM drive too? Ie, is this check > tacitly assuming a hard disk beneath it? > - Is it subject to timing problems? > - It *claims* to be "too weak", however it appears to be too strong! It's too weak for ST506...EIDE controllers with normal drives attached. These all have read/write registers, so the inb() should return what was written. That used to be tested for, but someone weakened the test without documenting why. I don't know what happens for CDROM drives. The point of the test is to attempt to limit the damage if there is a device other than an ST506...EIDE controller behind the port. It is far too weak for that (if 0xff wasn't so magic, then the test would have much less than a 1/256 chance of detecting conflicts). Even if it tested for `== 0xa5', then any device with a read/write port at the probed address would pass the test. The test is very sloppy. It should do something like: int is_rw_port(port) u_int_port; { u_char in1, in2, was; DELAY(5); was = inb(port); DELAY(5); outb(port, 0xa5); DELAY(5); (void)inb(0x20); /* attempt to eliminate bus echoes */ DELAY(5); in1 = inb(port); DELAY(5); outb(port, 0x5a); DELAY(5); (void)inb(0x20); DELAY(5); in2 = inb(port); DELAY(5); outb(port, was); DELAY(5); return (in1 == 0xa5 && in2 == 0x5a); } ... if (!is_rw_port(du->dk_port + wd_cyl_lo)) goto nodevice; Then the test would be stronger and your CDROM would be sure to fail :-). Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199508301917.FAA18876>