rtwn_attach() may fail due to "unsupported test chip". Unlikely to occur in practice, but still...
Index: ic/rtwn.c =================================================================== RCS file: /cvs/src/sys/dev/ic/rtwn.c,v retrieving revision 1.1 diff -u -p -r1.1 rtwn.c --- ic/rtwn.c 9 Mar 2016 18:18:28 -0000 1.1 +++ ic/rtwn.c 9 Mar 2016 19:03:48 -0000 @@ -152,7 +152,7 @@ void rtwn_stop(struct ifnet *); #define rtwn_bb_write rtwn_write_4 #define rtwn_bb_read rtwn_read_4 -void +int rtwn_attach(struct device *pdev, struct rtwn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -169,7 +169,7 @@ rtwn_attach(struct device *pdev, struct error = rtwn_read_chipid(sc); if (error != 0) { printf("%s: unsupported test chip\n", sc->sc_pdev->dv_xname); - return; + return (ENXIO); } /* Determine number of Tx/Rx chains. */ @@ -250,6 +250,8 @@ rtwn_attach(struct device *pdev, struct sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = rtwn_newstate; ieee80211_media_init(ifp, rtwn_media_change, ieee80211_media_status); + + return (0); } int Index: ic/rtwnvar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/rtwnvar.h,v retrieving revision 1.1 diff -u -p -r1.1 rtwnvar.h --- ic/rtwnvar.h 9 Mar 2016 18:18:28 -0000 1.1 +++ ic/rtwnvar.h 9 Mar 2016 19:02:27 -0000 @@ -76,7 +76,7 @@ struct rtwn_softc { uint32_t rf_chnlbw[R92C_MAX_CHAINS]; }; -void rtwn_attach(struct device *, struct rtwn_softc *); +int rtwn_attach(struct device *, struct rtwn_softc *); int rtwn_detach(struct rtwn_softc *, int); int rtwn_activate(struct rtwn_softc *, int); int8_t rtwn_get_rssi(struct rtwn_softc *, int, void *); Index: pci/if_rtwn.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_rtwn.c,v retrieving revision 1.16 diff -u -p -r1.16 if_rtwn.c --- pci/if_rtwn.c 9 Mar 2016 18:18:28 -0000 1.16 +++ pci/if_rtwn.c 9 Mar 2016 19:07:13 -0000 @@ -305,6 +305,7 @@ rtwn_pci_attach(struct device *parent, s if (error != 0) { printf("%s: could not allocate Tx buffers\n", sc->sc_dev.dv_xname); + rtwn_free_rx_list(sc); return; } } @@ -324,7 +325,13 @@ rtwn_pci_attach(struct device *parent, s sc->sc_sc.sc_ops.disable_intr = rtwn_disable_intr; sc->sc_sc.sc_ops.stop = rtwn_pci_stop; sc->sc_sc.sc_ops.is_oactive = rtwn_is_oactive; - rtwn_attach(&sc->sc_dev, &sc->sc_sc); + error = rtwn_attach(&sc->sc_dev, &sc->sc_sc); + if (error != 0) { + rtwn_free_rx_list(sc); + for (i = 0; i < RTWN_NTXQUEUES; i++) + rtwn_free_tx_list(sc, i); + return; + } /* ifp is now valid */ ifp = &sc->sc_sc.sc_ic.ic_if;