summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-02-20 01:19:18 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-02-20 01:19:18 +0000
commit39d54ce8d711607de7700c8617b90b0f4e8faf41 (patch)
treeed425e71010b90840c38dc17025808a6e6da151a /sys/net
parent3a16ed17b50e0fc823e33268045b663eb57d6d70 (diff)
ifmedia_set() should not panic, nor can it really fail. So if there is
some problem setting the media to the requested value (usually IFM_AUTO), we now force the media selection to IFM_NONE. From NetBSD
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_media.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/sys/net/if_media.c b/sys/net/if_media.c
index f4609f43b87..1897f195ccc 100644
--- a/sys/net/if_media.c
+++ b/sys/net/if_media.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_media.c,v 1.11 2005/02/15 23:18:55 brad Exp $ */
+/* $OpenBSD: if_media.c,v 1.12 2005/02/20 01:19:17 brad Exp $ */
/* $NetBSD: if_media.c,v 1.10 2000/03/13 23:52:39 soren Exp $ */
/*-
@@ -188,16 +188,37 @@ void
ifmedia_set(ifm, target)
struct ifmedia *ifm;
int target;
-
{
struct ifmedia_entry *match;
match = ifmedia_match(ifm, target, ifm->ifm_mask);
+ /*
+ * If we didn't find the requested media, then we try to fall
+ * back to target-type (IFM_ETHER, e.g.) | IFM_NONE. If that's
+ * not on the list, then we add it and set the media to it.
+ *
+ * Since ifmedia_set is almost always called with IFM_AUTO or
+ * with a known-good media, this really should only occur if we:
+ *
+ * a) didn't find any PHYs, or
+ * b) didn't find an autoselect option on the PHY when the
+ * parent ethernet driver expected to.
+ *
+ * In either case, it makes sense to select no media.
+ */
if (match == NULL) {
printf("ifmedia_set: no match for 0x%x/0x%x\n",
target, ~ifm->ifm_mask);
- panic("ifmedia_set");
+ target = (target & IFM_NMASK) | IFM_NONE;
+ match = ifmedia_match(ifm, target, ifm->ifm_mask);
+ if (match == NULL) {
+ ifmedia_add(ifm, target, 0, NULL);
+ match = ifmedia_match(ifm, target, ifm->ifm_mask);
+ if (match == NULL) {
+ panic("ifmedia_set failed");
+ }
+ }
}
ifm->ifm_cur = match;