Index: boot/i386/cdboot/cdboot.S =================================================================== RCS file: /home/source/dragonfly/cvs/src/sys/boot/i386/cdboot/cdboot.S,v retrieving revision 1.7 diff -u -p -r1.7 cdboot.S --- boot/i386/cdboot/cdboot.S 13 Jan 2006 19:41:50 -0000 1.7 +++ boot/i386/cdboot/cdboot.S 27 Feb 2007 23:57:54 -0000 @@ -461,10 +461,17 @@ twiddle: push %ax # Save ret /* - * Enable A20 + * Enable A20. Put upper limit on amount of time we wait for the + * keyboard controller to get ready (65K x ISA access time). If + * we wait more than that amount it's likely that the hardware + * is legacy-free and simply doesn't have keyboard controller + * and don't need enabling A20 at all. */ seta20: cli # Disable interrupts -seta20.1: in $0x64,%al # Get status + xor %cx,%cx # Clear +seta20.1: inc %cx # Increment, overflow? + jz seta20.3 # Yes + in $0x64,%al # Get status test $0x2,%al # Busy? jnz seta20.1 # Yes mov $0xd1,%al # Command: Write @@ -474,7 +481,7 @@ seta20.2: in $0x64,%al # Get status jnz seta20.2 # Yes mov $0xdf,%al # Enable out %al,$0x60 # A20 - sti # Enable interrupts +seta20.3: sti # Enable interrupts ret # To caller /* Index: boot/i386/pxeldr/pxeldr.S =================================================================== RCS file: /home/source/dragonfly/cvs/src/sys/boot/i386/pxeldr/pxeldr.S,v retrieving revision 1.4 diff -u -p -r1.4 pxeldr.S --- boot/i386/pxeldr/pxeldr.S 18 Jul 2004 23:40:09 -0000 1.4 +++ boot/i386/pxeldr/pxeldr.S 28 Feb 2007 14:26:15 -0000 @@ -234,10 +234,17 @@ putc: movw $0x7,%bx # attribute for o jmp putstr # keep looping /* - * Enable A20 + * Enable A20. Put upper limit on amount of time we wait for the + * keyboard controller to get ready (65K x ISA access time). If + * we wait more than that amount it's likely that the hardware + * is legacy-free and simply doesn't have keyboard controller + * and don't need enabling A20 at all. */ seta20: cli # Disable interrupts -seta20.1: inb $0x64,%al # Get status + xor %cx,%cx # Clear +seta20.1: inc %cx # Increment, overflow? + jz seta20.3 # Yes + inb $0x64,%al # Get status testb $0x2,%al # Busy? jnz seta20.1 # Yes movb $0xd1,%al # Command: Write @@ -247,7 +254,7 @@ seta20.2: inb $0x64,%al # Get status jnz seta20.2 # Yes movb $0xdf,%al # Enable outb %al,$0x60 # A20 - sti # Enable interrupts +seta20.3: sti # Enable interrupts retw # To caller /* Index: dev/misc/atkbdc_layer/atkbdc_isa.c =================================================================== RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/atkbdc_layer/atkbdc_isa.c,v retrieving revision 1.7 diff -u -p -r1.7 atkbdc_isa.c --- dev/misc/atkbdc_layer/atkbdc_isa.c 22 Dec 2006 23:26:17 -0000 1.7 +++ dev/misc/atkbdc_layer/atkbdc_isa.c 7 Mar 2007 13:57:22 -0000 @@ -101,6 +101,11 @@ atkbdc_probe(device_t dev) struct resource *port1; int error; int rid; +#if defined(__i386__) + bus_space_tag_t tag; + bus_space_handle_t ioh1; + volatile int i; +#endif /* check PnP IDs */ if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO) @@ -126,6 +131,28 @@ atkbdc_probe(device_t dev) 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); + for (i = 0; i != 65535; i++) { + if ((bus_space_read_1(tag, ioh1, 0) & 0x2) == 0) + break; + } + if (i == 65535) { + bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); + bus_release_resource(dev, SYS_RES_IOPORT, 1, port1); + return ENXIO; + } +#endif + error = atkbdc_probe_unit(device_get_unit(dev), port0, port1); bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); Index: dev/misc/kbd/atkbd.c =================================================================== RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/kbd/atkbd.c,v retrieving revision 1.13 diff -u -p -r1.13 atkbd.c --- dev/misc/kbd/atkbd.c 22 Dec 2006 23:26:17 -0000 1.13 +++ dev/misc/kbd/atkbd.c 28 Feb 2007 12:22:00 -0000 @@ -270,12 +270,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_int_value("atkbd", ATKBD_DEFAULT, "disabled", &i) == 0) - && i != 0) { + /* + * 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); Index: dev/misc/kbd/atkbdc.c =================================================================== RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/kbd/atkbdc.c,v retrieving revision 1.9 diff -u -p -r1.9 atkbdc.c --- dev/misc/kbd/atkbdc.c 15 Jan 2007 00:11:36 -0000 1.9 +++ dev/misc/kbd/atkbdc.c 10 Mar 2007 10:54:08 -0000 @@ -143,6 +143,9 @@ atkbdc_configure(void) bus_space_handle_t h1; int port0; int port1; +#if defined(__i386__) + volatile int i; +#endif port0 = IO_KBD; resource_int_value("atkbdc", 0, "port", &port0); @@ -163,6 +166,24 @@ atkbdc_configure(void) h0 = (bus_space_handle_t)port0; h1 = (bus_space_handle_t)port1; #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. + */ + for (i = 0; i != 65535; i++) { + if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0) + break; + } + if (i == 65535) + return ENXIO; +#endif + return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); }