summaryrefslogtreecommitdiffstats
path: root/sys/dev/atkbdc/atkbdc_isa.c
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2006-04-26 06:05:16 +0000
committersobomax <sobomax@FreeBSD.org>2006-04-26 06:05:16 +0000
commit3a261b12ba712500c22f2573fe0ecf720a38fff1 (patch)
tree31c9afb9d7cef07046a1b2f22ee408243d31cdbd /sys/dev/atkbdc/atkbdc_isa.c
parent4ede1798dbf32250b03b5535ae4619969686fa06 (diff)
downloadFreeBSD-src-3a261b12ba712500c22f2573fe0ecf720a38fff1.zip
FreeBSD-src-3a261b12ba712500c22f2573fe0ecf720a38fff1.tar.gz
Use the same method for detecting actual presence of AT-style keyboard
controller as we use in boot blocks (querying status register until bit 1 goes off). If that doesn't happed during reasonable period assume that the hardware doesn't have AT-style keyboard controller. This makes FreeBSD working almost OOB on MacBook Pro (still there are issues with putting second CPU core on-line, but since installation CD comes with UP kernel with this change one should be able to install FreeBSD without playing tricks with hints). Other legacy-free hardware (e.g. IBM NetVista S40) should benefit from this as well, but since I don't have any I can't verify. It should make no difference on the ordinary i386 hardware (since in that case that hardware already would be having an issues with A20 routines in boot blocks). I don't know much about AT-style keyboard controller on other platforms (and don't have dedicated access to one), therefore, the code is restricted to i386 for now. I suspect that amd64 may need this as well, but I would rather leave this decision to someone who knows better about the platform(s) in question. I have tested this change on as many "ordinary i386 boxes" as I can get my hands on, and it doesn't create any false negatives on hardware with AT-style keyboard present. MFC after: 1 month
Diffstat (limited to 'sys/dev/atkbdc/atkbdc_isa.c')
-rw-r--r--sys/dev/atkbdc/atkbdc_isa.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/dev/atkbdc/atkbdc_isa.c b/sys/dev/atkbdc/atkbdc_isa.c
index deeb7a0..96abfb5 100644
--- a/sys/dev/atkbdc/atkbdc_isa.c
+++ b/sys/dev/atkbdc/atkbdc_isa.c
@@ -93,6 +93,12 @@ atkbdc_isa_probe(device_t dev)
u_long count;
int error;
int rid;
+#if defined(__i386__)
+ bus_space_tag_t tag;
+ bus_space_handle_t ioh1;
+ volatile int i;
+ register_t flags;
+#endif
/* check PnP IDs */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
@@ -127,6 +133,31 @@ atkbdc_isa_probe(device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
return ENXIO;
}
+
+#if defined(__i386__)
+ /*
+ * Check if we really have AT keyboard controller. Poll status
+ * register until we get "all clear" indication. If no such
+ * indication comes, it probably means that there is no AT
+ * keyboard controller present. Give up in such case. Check relies
+ * on the fact that reading from non-existing in/out port returns
+ * 0xff on i386. May or may not be true on other platforms.
+ */
+ tag = rman_get_bustag(port0);
+ ioh1 = rman_get_bushandle(port1);
+ flags = intr_disable();
+ for (i = 0; i != 65535; i++) {
+ if ((bus_space_read_1(tag, ioh1, 0) & 0x2) == 0)
+ break;
+ }
+ intr_restore(flags);
+ if (i == 65535) {
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
+ bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
+ return ENXIO;
+ }
+#endif
+
device_verbose(dev);
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
OpenPOWER on IntegriCloud