summaryrefslogtreecommitdiffstats
path: root/sys/dev/iicbus/ad7418.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-08-04 21:14:24 +0000
committerjhb <jhb@FreeBSD.org>2008-08-04 21:14:24 +0000
commit86456c4430d5918f4b6cc1b5e3e7c9bf70f74bd1 (patch)
tree66af55d001db1b8421e532f726830245c5ba9d43 /sys/dev/iicbus/ad7418.c
parent3b547d7c3ff7d40672c49c58d43eeea9f09423a4 (diff)
downloadFreeBSD-src-86456c4430d5918f4b6cc1b5e3e7c9bf70f74bd1.zip
FreeBSD-src-86456c4430d5918f4b6cc1b5e3e7c9bf70f74bd1.tar.gz
Lock the consumers of the iicbus(4) infrastructure:
- ad7418(4) uses an sx lock instead of a mtx since the iicbus(4) stuff it calls can sleep (request_bus()). Also, I expanded the locking slightly to serialize writes to data stored in the softc. - Similarly, the icee(4) driver now uses an sx lock instead of a mutex. I also removed the pointless OPENED flag and flags field from the softc. - The locking for the ic(4) driver was a bit trickier: - Add a mutex to the softc to protect softc data. - The driver uses malloc'd buffers that are the size of the interface MTU to send and receive packets. Previously, these were allocated every time the interface was brought up and anytime the MTU was changed, with various races that could result in memory leaks. I changed this to be a bit simpler and more like other NIC drivers in that we allocate buffers during attach for the default MTU size and only reallocate them on MTU changes. The reallocation procedure goes to some lengths with various flags to not replace either the the receive or transmit buffers while the driver is busy receiving or transmitting a packet. - Store the device_t of the driver in the softc instead of detours into new-bus using if_dunit from the ifnet and an even more bizarre detour to get the softc instead of using if_softc. - Drop the driver mutex when invoking netisr_dispatch() to pass the packet up to IP. - Use if_printf().
Diffstat (limited to 'sys/dev/iicbus/ad7418.c')
-rw-r--r--sys/dev/iicbus/ad7418.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/sys/dev/iicbus/ad7418.c b/sys/dev/iicbus/ad7418.c
index ec68fc1..b7e99d7 100644
--- a/sys/dev/iicbus/ad7418.c
+++ b/sys/dev/iicbus/ad7418.c
@@ -32,11 +32,11 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
-#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
+#include <sys/sx.h>
#include <machine/bus.h>
#include <machine/cpu.h>
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
struct ad7418_softc {
device_t sc_dev;
- struct mtx sc_mtx;
+ struct sx sc_lock;
int sc_curchan; /* current channel */
int sc_curtemp;
int sc_curvolt;
@@ -91,8 +91,10 @@ ad7418_sysctl_temp(SYSCTL_HANDLER_ARGS)
struct ad7418_softc *sc = arg1;
int temp;
+ sx_xlock(&sc->sc_lock);
ad7418_update(sc);
temp = (sc->sc_curtemp / 64) * 25;
+ sx_xunlock(&sc->sc_lock);
return sysctl_handle_int(oidp, &temp, 0, req);
}
@@ -102,8 +104,10 @@ ad7418_sysctl_voltage(SYSCTL_HANDLER_ARGS)
struct ad7418_softc *sc = arg1;
int volt;
+ sx_xlock(&sc->sc_lock);
ad7418_update(sc);
volt = (sc->sc_curvolt >> 6) * 564 / 10;
+ sx_xunlock(&sc->sc_lock);
return sysctl_handle_int(oidp, &volt, 0, req);
}
@@ -116,7 +120,7 @@ ad7418_attach(device_t dev)
int conf;
sc->sc_dev = dev;
- mtx_init(&sc->sc_mtx, "ad7418", "ad7418", MTX_DEF);
+ sx_init(&sc->sc_mtx, "ad7418");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"temp", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
@@ -170,13 +174,10 @@ ad7418_set_channel(struct ad7418_softc *sc, int chan)
/*
* NB: Linux driver delays here but chip data sheet
* says nothing and things appear to work fine w/o
- * a delay on channel change. If this is enabled
- * be sure to account for losing the mutex below
- * in ad7418_update.
+ * a delay on channel change.
*/
- mtx_assert(&sc->sc_mtx, MA_OWNED);
/* let channel change settle, 1 tick should be 'nuf (need ~1ms) */
- msleep(sc, &sc->sc_mtx, 0, "ad7418", 1);
+ tsleep(sc, 0, "ad7418", hz/1000);
#endif
}
@@ -199,7 +200,7 @@ ad7418_update(struct ad7418_softc *sc)
{
int v;
- mtx_lock(&sc->sc_mtx);
+ sx_assert(&sc->sc_lock, SA_XLOCKED);
/* NB: no point in updating any faster than the chip */
if (ticks - sc->sc_lastupdate > hz) {
ad7418_set_channel(sc, AD7418_CHAN_TEMP);
@@ -212,7 +213,6 @@ ad7418_update(struct ad7418_softc *sc)
sc->sc_curvolt = v;
sc->sc_lastupdate = ticks;
}
- mtx_unlock(&sc->sc_mtx);
}
static device_method_t ad7418_methods[] = {
OpenPOWER on IntegriCloud