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
This commit is contained in:
parent
7c5a8ab212
commit
6621aa5cc7
@ -282,11 +282,12 @@ atkbd_configure(int flags)
|
||||
int arg[2];
|
||||
int i;
|
||||
|
||||
/* probe the keyboard controller */
|
||||
atkbdc_configure();
|
||||
|
||||
/* if the driver is disabled, unregister the keyboard if any */
|
||||
if (resource_disabled("atkbd", ATKBD_DEFAULT)) {
|
||||
/*
|
||||
* Probe the keyboard controller, if not present or if the driver
|
||||
* is disabled, unregister the keyboard if any.
|
||||
*/
|
||||
if (atkbdc_configure() != 0 ||
|
||||
resource_disabled("atkbd", ATKBD_DEFAULT)) {
|
||||
i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT);
|
||||
if (i >= 0) {
|
||||
kbd = kbd_get_keyboard(i);
|
||||
|
@ -153,6 +153,10 @@ atkbdc_configure(void)
|
||||
bus_space_tag_t tag;
|
||||
bus_space_handle_t h0;
|
||||
bus_space_handle_t h1;
|
||||
#if defined(__i386__)
|
||||
volatile int i;
|
||||
register_t flags;
|
||||
#endif
|
||||
#ifdef __sparc64__
|
||||
char name[32];
|
||||
phandle_t chosen, node;
|
||||
@ -219,6 +223,26 @@ atkbdc_configure(void)
|
||||
h1 = (bus_space_handle_t)port1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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.
|
||||
*/
|
||||
flags = intr_disable();
|
||||
for (i = 0; i != 65535; i++) {
|
||||
if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
|
||||
break;
|
||||
}
|
||||
intr_restore(flags);
|
||||
if (i == 65535)
|
||||
return ENXIO;
|
||||
#endif
|
||||
|
||||
return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user