PR/48964: In urndis(4), initialization of ifnet structure is not enough,
cause panic. Update urndis_init to return and error and use as if_init based on the patch in the PR with stylistic changes from me. XXX IFF_RUNNING should be ignored here?
This commit is contained in:
parent
1c0f21ce7d
commit
d143bb9ac3
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: if_urndis.c,v 1.7 2014/07/05 09:30:08 skrll Exp $ */
|
/* $NetBSD: if_urndis.c,v 1.8 2014/07/05 11:13:13 skrll Exp $ */
|
||||||
/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
|
/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.7 2014/07/05 09:30:08 skrll Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.8 2014/07/05 11:13:13 skrll Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -76,7 +76,7 @@ static void urndis_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
|
|||||||
static int urndis_rx_list_init(struct urndis_softc *);
|
static int urndis_rx_list_init(struct urndis_softc *);
|
||||||
static int urndis_tx_list_init(struct urndis_softc *);
|
static int urndis_tx_list_init(struct urndis_softc *);
|
||||||
|
|
||||||
static void urndis_init(struct ifnet *);
|
static int urndis_init(struct ifnet *);
|
||||||
static void urndis_stop(struct ifnet *);
|
static void urndis_stop(struct ifnet *);
|
||||||
|
|
||||||
static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t,
|
static usbd_status urndis_ctrl_msg(struct urndis_softc *, uint8_t, uint8_t,
|
||||||
@ -1022,53 +1022,57 @@ urndis_watchdog(struct ifnet *ifp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static int
|
||||||
urndis_init(struct ifnet *ifp)
|
urndis_init(struct ifnet *ifp)
|
||||||
{
|
{
|
||||||
struct urndis_softc *sc;
|
struct urndis_softc *sc;
|
||||||
int i, s;
|
int i, s;
|
||||||
usbd_status err;
|
int err;
|
||||||
|
usbd_status usberr;
|
||||||
|
|
||||||
sc = ifp->if_softc;
|
sc = ifp->if_softc;
|
||||||
|
|
||||||
if (ifp->if_flags & IFF_RUNNING)
|
if (ifp->if_flags & IFF_RUNNING)
|
||||||
return;
|
return EBUSY;
|
||||||
|
|
||||||
if (urndis_ctrl_init(sc) != RNDIS_STATUS_SUCCESS)
|
err = urndis_ctrl_init(sc);
|
||||||
return;
|
if (err != RNDIS_STATUS_SUCCESS)
|
||||||
|
return EIO;
|
||||||
|
|
||||||
s = splnet();
|
s = splnet();
|
||||||
|
|
||||||
if (urndis_tx_list_init(sc) == ENOBUFS) {
|
err = urndis_tx_list_init(sc);
|
||||||
|
if (err) {
|
||||||
printf("%s: tx list init failed\n",
|
printf("%s: tx list init failed\n",
|
||||||
DEVNAME(sc));
|
DEVNAME(sc));
|
||||||
splx(s);
|
splx(s);
|
||||||
return;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (urndis_rx_list_init(sc) == ENOBUFS) {
|
err = urndis_rx_list_init(sc);
|
||||||
|
if (err) {
|
||||||
printf("%s: rx list init failed\n",
|
printf("%s: rx list init failed\n",
|
||||||
DEVNAME(sc));
|
DEVNAME(sc));
|
||||||
splx(s);
|
splx(s);
|
||||||
return;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no,
|
usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no,
|
||||||
USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
|
USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
|
||||||
if (err) {
|
if (usberr) {
|
||||||
printf("%s: open rx pipe failed: %s\n", DEVNAME(sc),
|
printf("%s: open rx pipe failed: %s\n", DEVNAME(sc),
|
||||||
usbd_errstr(err));
|
usbd_errstr(err));
|
||||||
splx(s);
|
splx(s);
|
||||||
return;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no,
|
usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkout_no,
|
||||||
USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
|
USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
|
||||||
if (err) {
|
if (usberr) {
|
||||||
printf("%s: open tx pipe failed: %s\n", DEVNAME(sc),
|
printf("%s: open tx pipe failed: %s\n", DEVNAME(sc),
|
||||||
usbd_errstr(err));
|
usbd_errstr(err));
|
||||||
splx(s);
|
splx(s);
|
||||||
return;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
|
for (i = 0; i < RNDIS_RX_LIST_CNT; i++) {
|
||||||
@ -1086,6 +1090,7 @@ urndis_init(struct ifnet *ifp)
|
|||||||
ifp->if_flags &= ~IFF_OACTIVE;
|
ifp->if_flags &= ~IFF_OACTIVE;
|
||||||
|
|
||||||
splx(s);
|
splx(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1440,6 +1445,7 @@ urndis_attach(device_t parent, device_t self, void *aux)
|
|||||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||||
ifp->if_start = urndis_start;
|
ifp->if_start = urndis_start;
|
||||||
ifp->if_ioctl = urndis_ioctl;
|
ifp->if_ioctl = urndis_ioctl;
|
||||||
|
ifp->if_init = urndis_init;
|
||||||
#if 0
|
#if 0
|
||||||
ifp->if_watchdog = urndis_watchdog;
|
ifp->if_watchdog = urndis_watchdog;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user