summaryrefslogtreecommitdiffstats
path: root/freebsd/sys
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-01-21 10:13:58 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-01-21 10:13:58 +0100
commit1354d9bf97e49525282529e43dff50427f420f80 (patch)
treef0900858ccb90aedf7b66c400d90f3a3f93c0019 /freebsd/sys
parentUpdate to FreeBSD stable/12 2019-01-16 (diff)
downloadrtems-libbsd-1354d9bf97e49525282529e43dff50427f420f80.tar.bz2
Update to FreeBSD stable/12 2019-01-21
Git mirror commit 3a48f3689d65c5304cf706bbf2c5576daeb60a96. Update #3472.
Diffstat (limited to 'freebsd/sys')
-rw-r--r--freebsd/sys/dev/evdev/evdev_utils.c7
-rw-r--r--freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c2
-rw-r--r--freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c2
-rw-r--r--freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h3
-rw-r--r--freebsd/sys/dev/usb/input/uhid.c21
-rw-r--r--freebsd/sys/dev/usb/usb_generic.c11
-rw-r--r--freebsd/sys/dev/usb/usb_hub.c22
-rw-r--r--freebsd/sys/dev/usb/usb_request.c5
-rw-r--r--freebsd/sys/kern/uipc_socket.c2
-rw-r--r--freebsd/sys/net80211/ieee80211_output.c95
-rw-r--r--freebsd/sys/netinet6/ip6_output.c82
-rw-r--r--freebsd/sys/netpfil/pf/if_pfsync.c1
-rw-r--r--freebsd/sys/sys/random.h3
13 files changed, 212 insertions, 44 deletions
diff --git a/freebsd/sys/dev/evdev/evdev_utils.c b/freebsd/sys/dev/evdev/evdev_utils.c
index 17a815fb..9bdc5a23 100644
--- a/freebsd/sys/dev/evdev/evdev_utils.c
+++ b/freebsd/sys/dev/evdev/evdev_utils.c
@@ -252,12 +252,15 @@ evdev_scancode2key(int *state, int scancode)
*/
*state = 0;
if ((scancode & 0x7f) == 0x1D)
- *state = 0x1D;
+ *state = scancode;
return (NONE);
/* NOT REACHED */
case 0x1D: /* pause / break */
+ case 0x9D:
+ if ((*state ^ scancode) & 0x80)
+ return (NONE);
*state = 0;
- if (scancode != 0x45)
+ if ((scancode & 0x7f) != 0x45)
return (NONE);
keycode = KEY_PAUSE;
break;
diff --git a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
index 5c80af90..a020c21f 100644
--- a/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8192c/r92c_tx.c
@@ -105,7 +105,7 @@ r92c_tx_protection(struct rtwn_softc *sc, struct r92c_tx_desc *txd,
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
else
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
- ridx = rate2ridx(rate);
+ ridx = rate2ridx(IEEE80211_RV(rate));
txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, ridx));
/* RTS rate fallback limit (max). */
diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
index 77e9e423..910a06eb 100644
--- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
+++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_tx.c
@@ -113,7 +113,7 @@ r12a_tx_protection(struct rtwn_softc *sc, struct r12a_tx_desc *txd,
rate = rtwn_ctl_mcsrate(ic->ic_rt, ridx);
else
rate = ieee80211_ctl_rate(ic->ic_rt, ridx2rate[ridx]);
- ridx = rate2ridx(rate);
+ ridx = rate2ridx(IEEE80211_RV(rate));
txd->txdw4 |= htole32(SM(R12A_TXDW4_RTSRATE, ridx));
/* RTS rate fallback limit (max). */
diff --git a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
index 437787a7..1b54e540 100644
--- a/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
+++ b/freebsd/sys/dev/rtwn/usb/rtwn_usb_attach.h
@@ -156,7 +156,8 @@ static const STRUCT_USB_HOST_ID rtwn_devs[] = {
RTWN_RTL8821AU_DEV(EDIMAX, EW7811UTC_2),
RTWN_RTL8821AU_DEV(HAWKING, HD65U),
RTWN_RTL8821AU_DEV(MELCO, WIU2433DM),
- RTWN_RTL8821AU_DEV(NETGEAR, A6100)
+ RTWN_RTL8821AU_DEV(NETGEAR, A6100),
+ RTWN_RTL8821AU_DEV(REALTEK, RTL8821AU)
#undef RTWN_RTL8821AU_DEV
};
diff --git a/freebsd/sys/dev/usb/input/uhid.c b/freebsd/sys/dev/usb/input/uhid.c
index 90761ab7..8570f676 100644
--- a/freebsd/sys/dev/usb/input/uhid.c
+++ b/freebsd/sys/dev/usb/input/uhid.c
@@ -677,6 +677,8 @@ uhid_probe(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
int error;
+ void *buf;
+ uint16_t len;
DPRINTFN(11, "\n");
@@ -703,6 +705,25 @@ uhid_probe(device_t dev)
!usb_test_quirk(uaa, UQ_UMS_IGNORE))))
return (ENXIO);
+ /* Check for mandatory multitouch usages to give wmt(4) a chance */
+ if (!usb_test_quirk(uaa, UQ_WMT_IGNORE)) {
+ error = usbd_req_get_hid_desc(uaa->device, NULL,
+ &buf, &len, M_USBDEV, uaa->info.bIfaceIndex);
+ /* Let HID decscriptor-less devices to be handled at attach */
+ if (!error) {
+ if (hid_locate(buf, len,
+ HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACT_MAX),
+ hid_feature, 0, NULL, NULL, NULL) &&
+ hid_locate(buf, len,
+ HID_USAGE2(HUP_DIGITIZERS, HUD_CONTACTID),
+ hid_input, 0, NULL, NULL, NULL)) {
+ free(buf, M_USBDEV);
+ return (ENXIO);
+ }
+ free(buf, M_USBDEV);
+ }
+ }
+
return (BUS_PROBE_GENERIC);
}
diff --git a/freebsd/sys/dev/usb/usb_generic.c b/freebsd/sys/dev/usb/usb_generic.c
index 29a27d53..364b8cc5 100644
--- a/freebsd/sys/dev/usb/usb_generic.c
+++ b/freebsd/sys/dev/usb/usb_generic.c
@@ -185,7 +185,10 @@ ugen_open(struct usb_fifo *f, int fflags)
struct usb_endpoint_descriptor *ed = ep->edesc;
uint8_t type;
- DPRINTFN(6, "flag=0x%x\n", fflags);
+#ifndef __rtems__
+ DPRINTFN(1, "flag=0x%x pid=%d name=%s\n", fflags,
+ curthread->td_proc->p_pid, curthread->td_proc->p_comm);
+#endif /* __rtems__ */
mtx_lock(f->priv_mtx);
switch (usbd_get_speed(f->udev)) {
@@ -215,7 +218,11 @@ ugen_open(struct usb_fifo *f, int fflags)
static void
ugen_close(struct usb_fifo *f, int fflags)
{
- DPRINTFN(6, "flag=0x%x\n", fflags);
+
+#ifndef __rtems__
+ DPRINTFN(1, "flag=0x%x pid=%d name=%s\n", fflags,
+ curthread->td_proc->p_pid, curthread->td_proc->p_comm);
+#endif /* __rtems__ */
/* cleanup */
diff --git a/freebsd/sys/dev/usb/usb_hub.c b/freebsd/sys/dev/usb/usb_hub.c
index a0ad462f..7afe5d9e 100644
--- a/freebsd/sys/dev/usb/usb_hub.c
+++ b/freebsd/sys/dev/usb/usb_hub.c
@@ -131,6 +131,8 @@ struct uhub_softc {
int sc_disable_enumeration;
int sc_disable_port_power;
#endif
+ uint8_t sc_usb_port_errors; /* error counter */
+#define UHUB_USB_PORT_ERRORS_MAX 4
uint8_t sc_flags;
#define UHUB_FLAG_DID_EXPLORE 0x01
};
@@ -589,13 +591,25 @@ uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
struct usb_port_status ps;
usb_error_t err;
+ if (sc->sc_usb_port_errors >= UHUB_USB_PORT_ERRORS_MAX) {
+ DPRINTFN(4, "port %d, HUB looks dead, too many errors\n", portno);
+ sc->sc_st.port_status = 0;
+ sc->sc_st.port_change = 0;
+ return (USB_ERR_TIMEOUT);
+ }
+
err = usbd_req_get_port_status(
sc->sc_udev, NULL, &ps, portno);
- /* update status regardless of error */
-
- sc->sc_st.port_status = UGETW(ps.wPortStatus);
- sc->sc_st.port_change = UGETW(ps.wPortChange);
+ if (err == 0) {
+ sc->sc_st.port_status = UGETW(ps.wPortStatus);
+ sc->sc_st.port_change = UGETW(ps.wPortChange);
+ sc->sc_usb_port_errors = 0;
+ } else {
+ sc->sc_st.port_status = 0;
+ sc->sc_st.port_change = 0;
+ sc->sc_usb_port_errors++;
+ }
/* debugging print */
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index d2a15f3c..f288378e 100644
--- a/freebsd/sys/dev/usb/usb_request.c
+++ b/freebsd/sys/dev/usb/usb_request.c
@@ -1603,8 +1603,9 @@ usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx,
USETW(req.wValue, 0);
req.wIndex[0] = port;
req.wIndex[1] = 0;
- USETW(req.wLength, sizeof *ps);
- return (usbd_do_request(udev, mtx, &req, ps));
+ USETW(req.wLength, sizeof(*ps));
+
+ return (usbd_do_request_flags(udev, mtx, &req, ps, 0, NULL, 1000));
}
/*------------------------------------------------------------------------*
diff --git a/freebsd/sys/kern/uipc_socket.c b/freebsd/sys/kern/uipc_socket.c
index a0cb0c67..37578ff4 100644
--- a/freebsd/sys/kern/uipc_socket.c
+++ b/freebsd/sys/kern/uipc_socket.c
@@ -911,6 +911,8 @@ solisten_wakeup(struct socket *sol)
}
SOLISTEN_UNLOCK(sol);
wakeup_one(&sol->sol_comp);
+ if ((sol->so_state & SS_ASYNC) && sol->so_sigio != NULL)
+ pgsigio(&sol->so_sigio, SIGIO, 0);
}
/*
diff --git a/freebsd/sys/net80211/ieee80211_output.c b/freebsd/sys/net80211/ieee80211_output.c
index 2458bdaf..4c4d8daa 100644
--- a/freebsd/sys/net80211/ieee80211_output.c
+++ b/freebsd/sys/net80211/ieee80211_output.c
@@ -606,6 +606,97 @@ ieee80211_validate_frame(struct mbuf *m,
return (0);
}
+static int
+ieee80211_validate_rate(struct ieee80211_node *ni, uint8_t rate)
+{
+ struct ieee80211com *ic = ni->ni_ic;
+
+ if (IEEE80211_IS_HT_RATE(rate)) {
+ if ((ic->ic_htcaps & IEEE80211_HTC_HT) == 0)
+ return (EINVAL);
+
+ rate = IEEE80211_RV(rate);
+ if (rate <= 31) {
+ if (rate > ic->ic_txstream * 8 - 1)
+ return (EINVAL);
+
+ return (0);
+ }
+
+ if (rate == 32) {
+ if ((ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0)
+ return (EINVAL);
+
+ return (0);
+ }
+
+ if ((ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) == 0)
+ return (EINVAL);
+
+ switch (ic->ic_txstream) {
+ case 0:
+ case 1:
+ return (EINVAL);
+ case 2:
+ if (rate > 38)
+ return (EINVAL);
+
+ return (0);
+ case 3:
+ if (rate > 52)
+ return (EINVAL);
+
+ return (0);
+ case 4:
+ default:
+ if (rate > 76)
+ return (EINVAL);
+
+ return (0);
+ }
+ }
+
+ if (!ieee80211_isratevalid(ic->ic_rt, rate))
+ return (EINVAL);
+
+ return (0);
+}
+
+static int
+ieee80211_sanitize_rates(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ int error;
+
+ if (!params)
+ return (0); /* nothing to do */
+
+ /* NB: most drivers assume that ibp_rate0 is set (!= 0). */
+ if (params->ibp_rate0 != 0) {
+ error = ieee80211_validate_rate(ni, params->ibp_rate0);
+ if (error != 0)
+ return (error);
+ } else {
+ /* XXX pre-setup some default (e.g., mgmt / mcast) rate */
+ /* XXX __DECONST? */
+ (void) m;
+ }
+
+ if (params->ibp_rate1 != 0 &&
+ (error = ieee80211_validate_rate(ni, params->ibp_rate1)) != 0)
+ return (error);
+
+ if (params->ibp_rate2 != 0 &&
+ (error = ieee80211_validate_rate(ni, params->ibp_rate2)) != 0)
+ return (error);
+
+ if (params->ibp_rate3 != 0 &&
+ (error = ieee80211_validate_rate(ni, params->ibp_rate3)) != 0)
+ return (error);
+
+ return (0);
+}
+
/*
* 802.11 output routine. This is (currently) used only to
* connect bpf write calls to the 802.11 layer for injecting
@@ -720,6 +811,10 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
} else
M_WME_SETAC(m, WME_AC_BE);
+ error = ieee80211_sanitize_rates(ni, m, params);
+ if (error != 0)
+ senderr(error);
+
IEEE80211_NODE_STAT(ni, tx_data);
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
IEEE80211_NODE_STAT(ni, tx_mcast);
diff --git a/freebsd/sys/netinet6/ip6_output.c b/freebsd/sys/netinet6/ip6_output.c
index d3e530a6..a0ce4027 100644
--- a/freebsd/sys/netinet6/ip6_output.c
+++ b/freebsd/sys/netinet6/ip6_output.c
@@ -573,52 +573,72 @@ again:
counter_u64_add(rt->rt_pksent, 1);
}
-
- /*
- * The outgoing interface must be in the zone of source and
- * destination addresses.
- */
- origifp = ifp;
-
+ /* Setup data structures for scope ID checks. */
src0 = ip6->ip6_src;
- if (in6_setscope(&src0, origifp, &zone))
- goto badscope;
bzero(&src_sa, sizeof(src_sa));
src_sa.sin6_family = AF_INET6;
src_sa.sin6_len = sizeof(src_sa);
src_sa.sin6_addr = ip6->ip6_src;
- if (sa6_recoverscope(&src_sa) || zone != src_sa.sin6_scope_id)
- goto badscope;
dst0 = ip6->ip6_dst;
- if (in6_setscope(&dst0, origifp, &zone))
- goto badscope;
/* re-initialize to be sure */
bzero(&dst_sa, sizeof(dst_sa));
dst_sa.sin6_family = AF_INET6;
dst_sa.sin6_len = sizeof(dst_sa);
dst_sa.sin6_addr = ip6->ip6_dst;
- if (sa6_recoverscope(&dst_sa) || zone != dst_sa.sin6_scope_id) {
- goto badscope;
- }
- /* We should use ia_ifp to support the case of
- * sending packets to an address of our own.
- */
- if (ia != NULL && ia->ia_ifp)
- ifp = ia->ia_ifp;
-
- /* scope check is done. */
- goto routefound;
+ /* Check for valid scope ID. */
+ if (in6_setscope(&src0, ifp, &zone) == 0 &&
+ sa6_recoverscope(&src_sa) == 0 && zone == src_sa.sin6_scope_id &&
+ in6_setscope(&dst0, ifp, &zone) == 0 &&
+ sa6_recoverscope(&dst_sa) == 0 && zone == dst_sa.sin6_scope_id) {
+ /*
+ * The outgoing interface is in the zone of the source
+ * and destination addresses.
+ *
+ * Because the loopback interface cannot receive
+ * packets with a different scope ID than its own,
+ * there is a trick is to pretend the outgoing packet
+ * was received by the real network interface, by
+ * setting "origifp" different from "ifp". This is
+ * only allowed when "ifp" is a loopback network
+ * interface. Refer to code in nd6_output_ifp() for
+ * more details.
+ */
+ origifp = ifp;
+
+ /*
+ * We should use ia_ifp to support the case of sending
+ * packets to an address of our own.
+ */
+ if (ia != NULL && ia->ia_ifp)
+ ifp = ia->ia_ifp;
+
+ } else if ((ifp->if_flags & IFF_LOOPBACK) == 0 ||
+ sa6_recoverscope(&src_sa) != 0 ||
+ sa6_recoverscope(&dst_sa) != 0 ||
+ dst_sa.sin6_scope_id == 0 ||
+ (src_sa.sin6_scope_id != 0 &&
+ src_sa.sin6_scope_id != dst_sa.sin6_scope_id) ||
+ (origifp = ifnet_byindex(dst_sa.sin6_scope_id)) == NULL) {
+ /*
+ * If the destination network interface is not a
+ * loopback interface, or the destination network
+ * address has no scope ID, or the source address has
+ * a scope ID set which is different from the
+ * destination address one, or there is no network
+ * interface representing this scope ID, the address
+ * pair is considered invalid.
+ */
+ IP6STAT_INC(ip6s_badscope);
+ in6_ifstat_inc(ifp, ifs6_out_discard);
+ if (error == 0)
+ error = EHOSTUNREACH; /* XXX */
+ goto bad;
+ }
- badscope:
- IP6STAT_INC(ip6s_badscope);
- in6_ifstat_inc(origifp, ifs6_out_discard);
- if (error == 0)
- error = EHOSTUNREACH; /* XXX */
- goto bad;
+ /* All scope ID checks are successful. */
- routefound:
if (rt && !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
if (opt && opt->ip6po_nextroute.ro_rt) {
/*
diff --git a/freebsd/sys/netpfil/pf/if_pfsync.c b/freebsd/sys/netpfil/pf/if_pfsync.c
index 026d19a3..ec07bd80 100644
--- a/freebsd/sys/netpfil/pf/if_pfsync.c
+++ b/freebsd/sys/netpfil/pf/if_pfsync.c
@@ -337,6 +337,7 @@ pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
pfsync_buckets = mp_ncpus * 2;
sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
+ sc->sc_flags |= PFSYNCF_OK;
sc->sc_maxupdates = 128;
ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
diff --git a/freebsd/sys/sys/random.h b/freebsd/sys/sys/random.h
index f32d3f66..32d8122d 100644
--- a/freebsd/sys/sys/random.h
+++ b/freebsd/sys/sys/random.h
@@ -167,6 +167,9 @@ void random_harvest_deregister_source(enum random_entropy_source);
#define GRND_NONBLOCK 0x1
#define GRND_RANDOM 0x2
+
+__BEGIN_DECLS
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
+__END_DECLS
#endif /* _SYS_RANDOM_H_ */