test/review: plug mii leakage
Bjoern A. Zeeb
bzeeb-lists at lists.zabbadoz.net
Sun Mar 27 11:55:09 PST 2005
Hi,
could you please test following patch:
http://sources.zabbadoz.net/freebsd/patchset/mii-20050326-plug-leaks.diff
Any feedback welcome.
Thanks in advance.
--
Greetings
Bjoern A. Zeeb bzeeb at Zabbadoz dot NeT
Index: sys/dev/mii/mii.c
===================================================================
RCS file: /local/mirror/FreeBSD/r/ncvs/src/sys/dev/mii/mii.c,v
retrieving revision 1.25
diff -u -p -r1.25 mii.c
--- sys/dev/mii/mii.c 16 Feb 2005 05:56:39 -0000 1.25
+++ sys/dev/mii/mii.c 26 Mar 2005 19:02:41 -0000
@@ -115,7 +115,7 @@ miibus_probe(device_t dev)
struct mii_attach_args ma, *args;
struct mii_data *mii;
device_t child = NULL, parent;
- int bmsr, capmask = 0xFFFFFFFF;
+ int bmsr, capmask = 0xFFFFFFFF, count = 0;
mii = device_get_softc(dev);
parent = device_get_parent(dev);
@@ -149,12 +149,24 @@ miibus_probe(device_t dev)
args = malloc(sizeof(struct mii_attach_args),
M_DEVBUF, M_NOWAIT);
+ if (args == NULL) {
+ device_printf(dev, "%s: memory allocation failure, "
+ "phyno %d", __func__, ma.mii_phyno);
+ continue;
+ }
bcopy((char *)&ma, (char *)args, sizeof(ma));
child = device_add_child(dev, NULL, -1);
+ if (child == NULL) {
+ free(args, M_DEVBUF);
+ device_printf(dev, "%s: device_add_child failed",
+ __func__);
+ continue;
+ }
device_set_ivars(child, args);
+ count++;
}
- if (child == NULL)
+ if (count == 0)
return(ENXIO);
device_set_desc(dev, "MII bus");
@@ -176,20 +188,40 @@ miibus_attach(device_t dev)
*/
mii->mii_ifp = device_get_softc(device_get_parent(dev));
v = device_get_ivars(dev);
+ if (v == NULL)
+ return (ENXIO); /* XXX */
ifmedia_upd = v[0];
ifmedia_sts = v[1];
ifmedia_init(&mii->mii_media, IFM_IMASK, ifmedia_upd, ifmedia_sts);
- bus_generic_attach(dev);
- return(0);
+ return(bus_generic_attach(dev));
}
int
miibus_detach(device_t dev)
{
struct mii_data *mii;
+ device_t *children, *childp;
+ int error, j, childcount = 0;
+ void *v;
+
+ if (device_get_state(dev) != DS_ATTACHED)
+ return (EBUSY);
- bus_generic_detach(dev);
+ device_get_children(dev, &children, &childcount);
+ for (j = 0, childp = children; j < childcount; j++, childp++) {
+ /*
+ * Free ivars but not before device_detach.
+ * miibus_child_* fuinctions still use them unchecked.
+ */
+ v = device_get_ivars(*childp);
+ if ((error = device_detach(*childp)) != 0)
+ return (error);
+ if (v != NULL) {
+ device_set_ivars(*childp, NULL);
+ free(v, M_DEVBUF);
+ }
+ }
mii = device_get_softc(dev);
ifmedia_removeall(&mii->mii_media);
mii->mii_ifp = NULL;
@@ -300,12 +332,16 @@ mii_phy_probe(device_t dev, device_t *ch
int bmsr, i;
v = malloc(sizeof(vm_offset_t) * 2, M_DEVBUF, M_NOWAIT);
- if (v == 0) {
+ if (v == NULL) {
return (ENOMEM);
}
v[0] = ifmedia_upd;
v[1] = ifmedia_sts;
*child = device_add_child(dev, "miibus", -1);
+ if (*child == NULL) {
+ free(v, M_DEVBUF);
+ return (ENXIO);
+ }
device_set_ivars(*child, v);
for (i = 0; i < MII_NPHY; i++) {
@@ -319,14 +355,23 @@ mii_phy_probe(device_t dev, device_t *ch
}
if (i == MII_NPHY) {
+ device_set_ivars(*child, NULL);
+ free(v, M_DEVBUF);
device_delete_child(dev, *child);
*child = NULL;
return(ENXIO);
}
- bus_generic_attach(dev);
+ i = bus_generic_attach(dev);
- return(0);
+ /* Free ivars as they are no longer needed. */
+ v = device_get_ivars(*child);
+ if (v != NULL) {
+ device_set_ivars(*child, NULL);
+ free(v, M_DEVBUF);
+ }
+
+ return(i);
}
/*
More information about the freebsd-current
mailing list