summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/if_media.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-10-07 15:10:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:31 +0100
commitc40e45b75eb76d79a05c7fa85c1fa9b5c728a12f (patch)
treead4f2519067709f00ab98b3c591186c26dc3a21f /freebsd/sys/net/if_media.c
parentuserspace-header-gen.py: Simplify program ports (diff)
downloadrtems-libbsd-c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f.tar.bz2
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
Diffstat (limited to 'freebsd/sys/net/if_media.c')
-rw-r--r--freebsd/sys/net/if_media.c105
1 files changed, 42 insertions, 63 deletions
diff --git a/freebsd/sys/net/if_media.c b/freebsd/sys/net/if_media.c
index 264d3535..66b13568 100644
--- a/freebsd/sys/net/if_media.c
+++ b/freebsd/sys/net/if_media.c
@@ -48,6 +48,8 @@
* to implement this interface.
*/
+#include <rtems/bsd/local/opt_ifmedia.h>
+
#include <rtems/bsd/sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
@@ -70,6 +72,7 @@ static struct ifmedia_entry *ifmedia_match(struct ifmedia *ifm,
int flags, int mask);
#ifdef IFMEDIA_DEBUG
+#include <net/if_var.h>
int ifmedia_debug = 0;
SYSCTL_INT(_debug, OID_AUTO, ifmedia, CTLFLAG_RW, &ifmedia_debug,
0, "if_media debugging msgs");
@@ -195,6 +198,21 @@ ifmedia_set(ifm, target)
}
/*
+ * Given a media word, return one suitable for an application
+ * using the original encoding.
+ */
+static int
+compat_media(int media)
+{
+
+ if (IFM_TYPE(media) == IFM_ETHER && IFM_SUBTYPE(media) > IFM_OTHER) {
+ media &= ~(IFM_ETH_XTYPE|IFM_TMASK);
+ media |= IFM_OTHER;
+ }
+ return (media);
+}
+
+/*
* Device-independent media ioctl support function.
*/
int
@@ -206,7 +224,7 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
{
struct ifmedia_entry *match;
struct ifmediareq *ifmr = (struct ifmediareq *) ifr;
- int error = 0, sticky;
+ int error = 0;
if (ifp == NULL || ifr == NULL || ifm == NULL)
return(EINVAL);
@@ -273,80 +291,42 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
* Get list of available media and current media on interface.
*/
case SIOCGIFMEDIA:
+ case SIOCGIFXMEDIA:
{
struct ifmedia_entry *ep;
- int *kptr, count;
- int usermax; /* user requested max */
+ int i;
- kptr = NULL; /* XXX gcc */
+ if (ifmr->ifm_count < 0)
+ return (EINVAL);
- ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
- ifm->ifm_cur->ifm_media : IFM_NONE;
+ if (cmd == SIOCGIFMEDIA) {
+ ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
+ compat_media(ifm->ifm_cur->ifm_media) : IFM_NONE;
+ } else {
+ ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
+ ifm->ifm_cur->ifm_media : IFM_NONE;
+ }
ifmr->ifm_mask = ifm->ifm_mask;
ifmr->ifm_status = 0;
(*ifm->ifm_status)(ifp, ifmr);
- count = 0;
- usermax = 0;
-
/*
* If there are more interfaces on the list, count
* them. This allows the caller to set ifmr->ifm_count
* to 0 on the first call to know how much space to
* allocate.
*/
+ i = 0;
LIST_FOREACH(ep, &ifm->ifm_list, ifm_list)
- usermax++;
-
- /*
- * Don't allow the user to ask for too many
- * or a negative number.
- */
- if (ifmr->ifm_count > usermax)
- ifmr->ifm_count = usermax;
- else if (ifmr->ifm_count < 0)
- return (EINVAL);
-
- if (ifmr->ifm_count != 0) {
- kptr = (int *)malloc(ifmr->ifm_count * sizeof(int),
- M_TEMP, M_NOWAIT);
-
- if (kptr == NULL)
- return (ENOMEM);
- /*
- * Get the media words from the interface's list.
- */
- ep = LIST_FIRST(&ifm->ifm_list);
- for (; ep != NULL && count < ifmr->ifm_count;
- ep = LIST_NEXT(ep, ifm_list), count++)
- kptr[count] = ep->ifm_media;
-
- if (ep != NULL)
- error = E2BIG; /* oops! */
- } else {
- count = usermax;
- }
-
- /*
- * We do the copyout on E2BIG, because that's
- * just our way of telling userland that there
- * are more. This is the behavior I've observed
- * under BSD/OS 3.0
- */
- sticky = error;
- if ((error == 0 || error == E2BIG) && ifmr->ifm_count != 0) {
- error = copyout((caddr_t)kptr,
- (caddr_t)ifmr->ifm_ulist,
- ifmr->ifm_count * sizeof(int));
- }
-
- if (error == 0)
- error = sticky;
-
- if (ifmr->ifm_count != 0)
- free(kptr, M_TEMP);
-
- ifmr->ifm_count = count;
+ if (i++ < ifmr->ifm_count) {
+ error = copyout(&ep->ifm_media,
+ ifmr->ifm_ulist + i - 1, sizeof(int));
+ if (error)
+ break;
+ }
+ if (error == 0 && i > ifmr->ifm_count)
+ error = ifmr->ifm_count ? E2BIG : 0;
+ ifmr->ifm_count = i;
break;
}
@@ -400,8 +380,7 @@ ifmedia_baudrate(int mword)
int i;
for (i = 0; ifmedia_baudrate_descriptions[i].ifmb_word != 0; i++) {
- if ((mword & (IFM_NMASK|IFM_TMASK)) ==
- ifmedia_baudrate_descriptions[i].ifmb_word)
+ if (IFM_TYPE_MATCH(mword, ifmedia_baudrate_descriptions[i].ifmb_word))
return (ifmedia_baudrate_descriptions[i].ifmb_baudrate);
}
@@ -507,7 +486,7 @@ ifmedia_printword(ifmw)
printf("<unknown type>\n");
return;
}
- printf(desc->ifmt_string);
+ printf("%s", desc->ifmt_string);
/* Any mode. */
for (desc = ttos->modes; desc && desc->ifmt_string != NULL; desc++)