1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-08 13:28:05 +00:00

hyperv/hn: Fix detach and attach error handling.

MFC after:	1 week
Sponsored by:	Microsoft
Differential Revision:	https://reviews.freebsd.org/D8066
This commit is contained in:
Sepherosa Ziehau 2016-09-30 06:30:16 +00:00
parent fed9f4df75
commit 2530eba1c4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=306483

View File

@ -352,6 +352,7 @@ static void hn_resume(struct hn_softc *);
static void hn_rx_drain(struct vmbus_channel *); static void hn_rx_drain(struct vmbus_channel *);
static void hn_tx_resume(struct hn_softc *, int); static void hn_tx_resume(struct hn_softc *, int);
static void hn_tx_ring_qflush(struct hn_tx_ring *); static void hn_tx_ring_qflush(struct hn_tx_ring *);
static int netvsc_detach(device_t dev);
static void hn_nvs_handle_notify(struct hn_softc *sc, static void hn_nvs_handle_notify(struct hn_softc *sc,
const struct vmbus_chanpkt_hdr *pkt); const struct vmbus_chanpkt_hdr *pkt);
@ -739,27 +740,28 @@ netvsc_attach(device_t dev)
return (0); return (0);
failed: failed:
/* TODO: reuse netvsc_detach() */ if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)
hn_destroy_tx_data(sc); hn_synth_detach(sc);
if (ifp != NULL) netvsc_detach(dev);
if_free(ifp);
return (error); return (error);
} }
/*
* TODO: Use this for error handling on attach path.
*/
static int static int
netvsc_detach(device_t dev) netvsc_detach(device_t dev)
{ {
struct hn_softc *sc = device_get_softc(dev); struct hn_softc *sc = device_get_softc(dev);
struct ifnet *ifp = sc->hn_ifp;
/* TODO: ether_ifdetach */ if (device_is_attached(dev)) {
HN_LOCK(sc);
HN_LOCK(sc); if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
/* TODO: hn_stop */ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_synth_detach(sc); hn_stop(sc);
HN_UNLOCK(sc); hn_synth_detach(sc);
}
HN_UNLOCK(sc);
ether_ifdetach(ifp);
}
ifmedia_removeall(&sc->hn_media); ifmedia_removeall(&sc->hn_media);
hn_destroy_rx_data(sc); hn_destroy_rx_data(sc);
@ -768,10 +770,12 @@ netvsc_detach(device_t dev)
if (sc->hn_tx_taskq != hn_tx_taskq) if (sc->hn_tx_taskq != hn_tx_taskq)
taskqueue_free(sc->hn_tx_taskq); taskqueue_free(sc->hn_tx_taskq);
vmbus_xact_ctx_destroy(sc->hn_xact); if (sc->hn_xact != NULL)
HN_LOCK_DESTROY(sc); vmbus_xact_ctx_destroy(sc->hn_xact);
/* TODO: if_free */ if_free(ifp);
HN_LOCK_DESTROY(sc);
return (0); return (0);
} }