diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2008-10-30 15:27:13 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2008-10-30 15:27:13 +0000 |
commit | 5c55d9c1df94b43c6addfdaa79a82e6f779b6cd1 (patch) | |
tree | 809d8cc03b1cf718c388d7e5d5e3820507adf952 /sys/dev/adb/adb_bus.c | |
parent | 1f332d86bf5e4cfc63df682d8859c4f4fac21026 (diff) | |
download | FreeBSD-src-5c55d9c1df94b43c6addfdaa79a82e6f779b6cd1.zip FreeBSD-src-5c55d9c1df94b43c6addfdaa79a82e6f779b6cd1.tar.gz |
Fix some possible infinite loops in the ADB code, and remove some hacks
that were inserted in desperation during bring-up. In addition, move ADB bus
enumeration and child attachment to when interrupts are available.
Diffstat (limited to 'sys/dev/adb/adb_bus.c')
-rw-r--r-- | sys/dev/adb/adb_bus.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/sys/dev/adb/adb_bus.c b/sys/dev/adb/adb_bus.c index cc31a9d..9a2a7fa 100644 --- a/sys/dev/adb/adb_bus.c +++ b/sys/dev/adb/adb_bus.c @@ -44,6 +44,7 @@ static int adb_bus_probe(device_t dev); static int adb_bus_attach(device_t dev); static int adb_bus_detach(device_t dev); +static void adb_bus_enumerate(void *xdev); static void adb_probe_nomatch(device_t dev, device_t child); static int adb_print_child(device_t dev, device_t child); @@ -88,6 +89,27 @@ static int adb_bus_attach(device_t dev) { struct adb_softc *sc = device_get_softc(dev); + sc->enum_hook.ich_func = adb_bus_enumerate; + sc->enum_hook.ich_arg = dev; + + /* + * We should wait until interrupts are enabled to try to probe + * the bus. Enumerating the ADB involves receiving packets, + * which works best with interrupts enabled. + */ + + if (config_intrhook_establish(&sc->enum_hook) != 0) + return (ENOMEM); + + return (0); +} + +static void +adb_bus_enumerate(void *xdev) +{ + device_t dev = (device_t)xdev; + + struct adb_softc *sc = device_get_softc(dev); uint8_t i, next_free; uint16_t r3; @@ -165,7 +187,9 @@ adb_bus_attach(device_t dev) } } - return (bus_generic_attach(dev)); + bus_generic_attach(dev); + + config_intrhook_disestablish(&sc->enum_hook); } static int adb_bus_detach(device_t dev) @@ -315,10 +339,13 @@ adb_send_raw_packet_sync(device_t dev, uint8_t to, uint8_t command, ADB_HB_SEND_RAW_PACKET(sc->parent, command_byte, len, data, 1); while (!atomic_fetchadd_int(&sc->packet_reply,0)) { - /* Sometimes CUDA controllers hang up during cold boots. - Try poking them. */ - if (i > 10) - ADB_HB_CONTROLLER_POLL(sc->parent); + /* + * Maybe the command got lost? Try resending and polling the + * controller. + */ + if (i > 40) + ADB_HB_SEND_RAW_PACKET(sc->parent, command_byte, + len, data, 1); DELAY(100); i++; |