--- sys/dev/atkbdc/atkbdc.c.orig 2010-06-14 04:09:06.000000000 +0200 +++ sys/dev/atkbdc/atkbdc.c 2010-11-03 01:13:02.000000000 +0100 @@ -44,6 +44,10 @@ #include #include +#if defined(__amd64__) +#include +#endif + #include #ifdef __sparc64__ @@ -153,7 +157,7 @@ bus_space_tag_t tag; bus_space_handle_t h0; bus_space_handle_t h1; -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) volatile int i; register_t flags; #endif @@ -222,7 +226,7 @@ #endif #endif -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) /* * Check if we really have AT keyboard controller. Poll status * register until we get "all clear" indication. If no such @@ -248,6 +252,11 @@ atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, bus_space_handle_t h1) { +#if defined(__amd64__) + u_int64_t tscval[3], read_delay; + register_t flags; +#endif + if (sc->ioh0 == 0) { /* XXX */ sc->command_byte = -1; sc->command_mask = 0; @@ -264,6 +273,22 @@ sc->iot = tag; sc->ioh0 = h0; sc->ioh1 = h1; + +#if defined(__amd64__) + flags = intr_disable(); + tscval[0] = rdtsc(); + read_status(sc); + tscval[1] = rdtsc(); + DELAY(1000); + tscval[2] = rdtsc(); + intr_restore(flags); + read_delay = tscval[1] - tscval[0]; + read_delay /= (tscval[2] - tscval[1]) / 1000; + sc->retry = 100000 / ((KBDD_DELAYTIME * 2) + read_delay); +#else + sc->retry = 5000; +#endif + return 0; } @@ -380,10 +405,12 @@ static int wait_while_controller_busy(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 100msec at most */ - int retry = 5000; + int retry; int f; + /* CPU will stay inside the loop for 100msec at most */ + retry = kbdc->retry; + while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) { if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { DELAY(KBDD_DELAYTIME); @@ -406,10 +433,12 @@ static int wait_for_data(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 200msec at most */ - int retry = 10000; + int retry; int f; + /* CPU will stay inside the loop for 200msec at most */ + retry = kbdc->retry * 2; + while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) { DELAY(KBDC_DELAYTIME); if (--retry < 0) @@ -423,10 +452,12 @@ static int wait_for_kbd_data(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 200msec at most */ - int retry = 10000; + int retry; int f; + /* CPU will stay inside the loop for 200msec at most */ + retry = kbdc->retry * 2; + while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) != KBDS_KBD_BUFFER_FULL) { if (f == KBDS_AUX_BUFFER_FULL) { @@ -448,11 +479,13 @@ static int wait_for_kbd_ack(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 200msec at most */ - int retry = 10000; + int retry; int f; int b; + /* CPU will stay inside the loop for 200msec at most */ + retry = kbdc->retry * 2; + while (retry-- > 0) { if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { DELAY(KBDD_DELAYTIME); @@ -475,10 +508,12 @@ static int wait_for_aux_data(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 200msec at most */ - int retry = 10000; + int retry; int f; + /* CPU will stay inside the loop for 200msec at most */ + retry = kbdc->retry * 2; + while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) != KBDS_AUX_BUFFER_FULL) { if (f == KBDS_KBD_BUFFER_FULL) { @@ -500,11 +535,13 @@ static int wait_for_aux_ack(struct atkbdc_softc *kbdc) { - /* CPU will stay inside the loop for 200msec at most */ - int retry = 10000; + int retry; int f; int b; + /* CPU will stay inside the loop for 200msec at most */ + retry = kbdc->retry * 2; + while (retry-- > 0) { if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { DELAY(KBDD_DELAYTIME); --- sys/dev/atkbdc/atkbdc_ebus.c.orig 2010-06-14 04:09:06.000000000 +0200 +++ sys/dev/atkbdc/atkbdc_ebus.c 2010-11-03 01:13:02.000000000 +0100 @@ -202,6 +202,7 @@ "cannot determine command/data port resource\n"); return (ENXIO); } + sc->retry = 5000; sc->port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1, RF_ACTIVE); if (sc->port0 == NULL) { --- sys/dev/atkbdc/atkbdc_isa.c.orig 2010-06-14 04:09:06.000000000 +0200 +++ sys/dev/atkbdc/atkbdc_isa.c 2010-11-03 01:13:02.000000000 +0100 @@ -94,7 +94,7 @@ u_long count; int error; int rid; -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) bus_space_tag_t tag; bus_space_handle_t ioh1; volatile int i; @@ -141,7 +141,7 @@ return ENXIO; } -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) /* * Check if we really have AT keyboard controller. Poll status * register until we get "all clear" indication. If no such @@ -161,6 +161,8 @@ if (i == 65535) { bus_release_resource(dev, SYS_RES_IOPORT, 0, port0); bus_release_resource(dev, SYS_RES_IOPORT, 1, port1); + if (bootverbose) + device_printf(dev, "AT keyboard controller not found\n"); return ENXIO; } #endif @@ -201,6 +203,7 @@ } rid = 0; + sc->retry = 5000; sc->port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); if (sc->port0 == NULL) --- sys/dev/atkbdc/atkbdcreg.h.orig 2010-06-14 04:09:06.000000000 +0200 +++ sys/dev/atkbdc/atkbdcreg.h 2010-11-03 01:13:02.000000000 +0100 @@ -200,6 +200,7 @@ int lock; /* FIXME: XXX not quite a semaphore... */ kqueue kbd; /* keyboard data queue */ kqueue aux; /* auxiliary data queue */ + int retry; } atkbdc_softc_t; enum kbdc_device_ivar {