Date: Thu, 30 Oct 2008 15:27:13 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r184473 - in head/sys: dev/adb powerpc/powermac Message-ID: <200810301527.m9UFRDPD054780@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Thu Oct 30 15:27:13 2008 New Revision: 184473 URL: http://svn.freebsd.org/changeset/base/184473 Log: 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. Modified: head/sys/dev/adb/adb_bus.c head/sys/dev/adb/adbvar.h head/sys/powerpc/powermac/cuda.c head/sys/powerpc/powermac/pmu.c Modified: head/sys/dev/adb/adb_bus.c ============================================================================== --- head/sys/dev/adb/adb_bus.c Thu Oct 30 14:30:49 2008 (r184472) +++ head/sys/dev/adb/adb_bus.c Thu Oct 30 15:27:13 2008 (r184473) @@ -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, u 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++; Modified: head/sys/dev/adb/adbvar.h ============================================================================== --- head/sys/dev/adb/adbvar.h Thu Oct 30 14:30:49 2008 (r184472) +++ head/sys/dev/adb/adbvar.h Thu Oct 30 15:27:13 2008 (r184473) @@ -37,16 +37,15 @@ enum { struct adb_softc { device_t sc_dev; - device_t parent; + struct intr_config_hook enum_hook; struct mtx sc_sync_mtx; volatile int sync_packet; volatile int packet_reply; uint16_t autopoll_mask; - uint8_t syncreg[8]; device_t children[16]; Modified: head/sys/powerpc/powermac/cuda.c ============================================================================== --- head/sys/powerpc/powermac/cuda.c Thu Oct 30 14:30:49 2008 (r184472) +++ head/sys/powerpc/powermac/cuda.c Thu Oct 30 15:27:13 2008 (r184473) @@ -341,10 +341,7 @@ cuda_send(void *cookie, int poll, int le mtx_lock(&sc->sc_mutex); - if ((sc->sc_state == CUDA_IDLE) /*&& - ((cuda_read_reg(sc, vBufB) & vPB3) == vPB3)*/) { - /* fine */ - } else { + if (sc->sc_state != CUDA_IDLE) { if (sc->sc_waiting == 0) { sc->sc_waiting = 1; } else { @@ -381,12 +378,12 @@ cuda_poll(device_t dev) { struct cuda_softc *sc = device_get_softc(dev); - while ((sc->sc_state != CUDA_IDLE) || - (cuda_intr_state(sc)) || - (sc->sc_waiting == 1)) { - if ((cuda_read_reg(sc, vIFR) & vSR_INT) == vSR_INT) - cuda_intr(dev); - } + if (sc->sc_state == CUDA_IDLE && !cuda_intr_state(sc) && + !sc->sc_waiting) + return; + + if ((cuda_read_reg(sc, vIFR) & vSR_INT) == vSR_INT) + cuda_intr(dev); } static void @@ -615,6 +612,7 @@ cuda_adb_autopoll(device_t dev, uint16_t uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, mask != 0}; mtx_lock(&sc->sc_mutex); + if (cmd[2] == sc->sc_autopoll) { mtx_unlock(&sc->sc_mutex); return 0; @@ -624,18 +622,10 @@ cuda_adb_autopoll(device_t dev, uint16_t mtx_sleep(dev,&sc->sc_mutex,0,"cuda",1); sc->sc_autopoll = -1; - mtx_unlock(&sc->sc_mutex); - cuda_send(sc, 0, 3, cmd); - - mtx_lock(&sc->sc_mutex); - while(sc->sc_autopoll == -1) { - mtx_sleep(dev,&sc->sc_mutex,0,"cuda",100); - cuda_poll(dev); - } mtx_unlock(&sc->sc_mutex); - + return 0; } Modified: head/sys/powerpc/powermac/pmu.c ============================================================================== --- head/sys/powerpc/powermac/pmu.c Thu Oct 30 14:30:49 2008 (r184472) +++ head/sys/powerpc/powermac/pmu.c Thu Oct 30 15:27:13 2008 (r184473) @@ -591,8 +591,6 @@ pmu_adb_autopoll(device_t dev, uint16_t { struct pmu_softc *sc = device_get_softc(dev); - mask = 0xffff; - /* magical incantation to re-enable autopolling */ uint8_t cmd[] = {0, PMU_SET_POLL_MASK, (mask >> 8) & 0xff, mask & 0xff}; uint8_t resp[16];
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810301527.m9UFRDPD054780>