hyperv/hn: Fix attach error handling
MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8620
This commit is contained in:
parent
a4364cfea9
commit
71e8ac5696
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=309229
@ -273,8 +273,14 @@ hn_nvs_conn_chim(struct hn_softc *sc)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (sectsz == 0) {
|
if (sectsz == 0) {
|
||||||
|
/*
|
||||||
|
* Can't use chimney sending buffer; done!
|
||||||
|
*/
|
||||||
if_printf(sc->hn_ifp, "zero chimney sending buffer "
|
if_printf(sc->hn_ifp, "zero chimney sending buffer "
|
||||||
"section size\n");
|
"section size\n");
|
||||||
|
sc->hn_chim_szmax = 0;
|
||||||
|
sc->hn_chim_cnt = 0;
|
||||||
|
sc->hn_flags |= HN_FLAG_CHIM_CONNECTED;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,6 +437,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
|
|||||||
if (sc->hn_chim_bmap != NULL) {
|
if (sc->hn_chim_bmap != NULL) {
|
||||||
free(sc->hn_chim_bmap, M_DEVBUF);
|
free(sc->hn_chim_bmap, M_DEVBUF);
|
||||||
sc->hn_chim_bmap = NULL;
|
sc->hn_chim_bmap = NULL;
|
||||||
|
sc->hn_chim_bmap_cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,8 +627,10 @@ hn_nvs_attach(struct hn_softc *sc, int mtu)
|
|||||||
* Connect chimney sending buffer.
|
* Connect chimney sending buffer.
|
||||||
*/
|
*/
|
||||||
error = hn_nvs_conn_chim(sc);
|
error = hn_nvs_conn_chim(sc);
|
||||||
if (error)
|
if (error) {
|
||||||
|
hn_nvs_disconn_rxbuf(sc);
|
||||||
return (error);
|
return (error);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +979,6 @@ hn_rndis_attach(struct hn_softc *sc, int mtu)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure NDIS offload settings.
|
* Configure NDIS offload settings.
|
||||||
* XXX no offloading, if error happened?
|
|
||||||
*/
|
*/
|
||||||
hn_rndis_conf_offload(sc, mtu);
|
hn_rndis_conf_offload(sc, mtu);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -4215,11 +4215,14 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan)
|
|||||||
cbr.cbr_rxsz = HN_RXBR_SIZE;
|
cbr.cbr_rxsz = HN_RXBR_SIZE;
|
||||||
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
|
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
|
||||||
if (error) {
|
if (error) {
|
||||||
if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
|
if (error == EISCONN) {
|
||||||
vmbus_chan_id(chan), error);
|
if_printf(sc->hn_ifp, "bufring is connected after "
|
||||||
rxr->hn_rx_flags &= ~HN_RX_FLAG_ATTACHED;
|
"chan%u open failure\n", vmbus_chan_id(chan));
|
||||||
if (txr != NULL)
|
rxr->hn_rx_flags |= HN_RX_FLAG_BR_REF;
|
||||||
txr->hn_tx_flags &= ~HN_TX_FLAG_ATTACHED;
|
} else {
|
||||||
|
if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
|
||||||
|
vmbus_chan_id(chan), error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -4276,15 +4279,18 @@ hn_attach_subchans(struct hn_softc *sc)
|
|||||||
int subchan_cnt = sc->hn_rx_ring_inuse - 1;
|
int subchan_cnt = sc->hn_rx_ring_inuse - 1;
|
||||||
int i, error = 0;
|
int i, error = 0;
|
||||||
|
|
||||||
if (subchan_cnt == 0)
|
KASSERT(subchan_cnt > 0, ("no sub-channels"));
|
||||||
return (0);
|
|
||||||
|
|
||||||
/* Attach the sub-channels. */
|
/* Attach the sub-channels. */
|
||||||
subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt);
|
subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt);
|
||||||
for (i = 0; i < subchan_cnt; ++i) {
|
for (i = 0; i < subchan_cnt; ++i) {
|
||||||
error = hn_chan_attach(sc, subchans[i]);
|
int error1;
|
||||||
if (error)
|
|
||||||
break;
|
error1 = hn_chan_attach(sc, subchans[i]);
|
||||||
|
if (error1) {
|
||||||
|
error = error1;
|
||||||
|
/* Move on; all channels will be detached later. */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vmbus_subchan_rel(subchans, subchan_cnt);
|
vmbus_subchan_rel(subchans, subchan_cnt);
|
||||||
|
|
||||||
@ -4416,9 +4422,12 @@ hn_synth_attachable(const struct hn_softc *sc)
|
|||||||
static int
|
static int
|
||||||
hn_synth_attach(struct hn_softc *sc, int mtu)
|
hn_synth_attach(struct hn_softc *sc, int mtu)
|
||||||
{
|
{
|
||||||
|
#define ATTACHED_NVS 0x0002
|
||||||
|
#define ATTACHED_RNDIS 0x0004
|
||||||
|
|
||||||
struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
|
struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
|
||||||
int error, nsubch, nchan, i;
|
int error, nsubch, nchan, i;
|
||||||
uint32_t old_caps;
|
uint32_t old_caps, attached = 0;
|
||||||
|
|
||||||
KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0,
|
KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0,
|
||||||
("synthetic parts were attached"));
|
("synthetic parts were attached"));
|
||||||
@ -4439,21 +4448,23 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
|||||||
*/
|
*/
|
||||||
error = hn_chan_attach(sc, sc->hn_prichan);
|
error = hn_chan_attach(sc, sc->hn_prichan);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
goto failed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach NVS.
|
* Attach NVS.
|
||||||
*/
|
*/
|
||||||
error = hn_nvs_attach(sc, mtu);
|
error = hn_nvs_attach(sc, mtu);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
goto failed;
|
||||||
|
attached |= ATTACHED_NVS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach RNDIS _after_ NVS is attached.
|
* Attach RNDIS _after_ NVS is attached.
|
||||||
*/
|
*/
|
||||||
error = hn_rndis_attach(sc, mtu);
|
error = hn_rndis_attach(sc, mtu);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
goto failed;
|
||||||
|
attached |= ATTACHED_RNDIS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure capabilities are not changed.
|
* Make sure capabilities are not changed.
|
||||||
@ -4461,9 +4472,8 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
|||||||
if (device_is_attached(sc->hn_dev) && old_caps != sc->hn_caps) {
|
if (device_is_attached(sc->hn_dev) && old_caps != sc->hn_caps) {
|
||||||
if_printf(sc->hn_ifp, "caps mismatch old 0x%08x, new 0x%08x\n",
|
if_printf(sc->hn_ifp, "caps mismatch old 0x%08x, new 0x%08x\n",
|
||||||
old_caps, sc->hn_caps);
|
old_caps, sc->hn_caps);
|
||||||
/* Restore old capabilities and abort. */
|
error = ENXIO;
|
||||||
sc->hn_caps = old_caps;
|
goto failed;
|
||||||
return ENXIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4476,19 +4486,32 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
|||||||
nsubch = sc->hn_rx_ring_cnt - 1;
|
nsubch = sc->hn_rx_ring_cnt - 1;
|
||||||
error = hn_synth_alloc_subchans(sc, &nsubch);
|
error = hn_synth_alloc_subchans(sc, &nsubch);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
goto failed;
|
||||||
|
/* NOTE: _Full_ synthetic parts detach is required now. */
|
||||||
|
sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the # of TX/RX rings that could be used according to
|
||||||
|
* the # of channels that NVS offered.
|
||||||
|
*/
|
||||||
nchan = nsubch + 1;
|
nchan = nsubch + 1;
|
||||||
|
hn_set_ring_inuse(sc, nchan);
|
||||||
if (nchan == 1) {
|
if (nchan == 1) {
|
||||||
/* Only the primary channel can be used; done */
|
/* Only the primary channel can be used; done */
|
||||||
goto back;
|
goto back;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure RSS key and indirect table _after_ all sub-channels
|
* Attach the sub-channels.
|
||||||
* are allocated.
|
|
||||||
*/
|
*/
|
||||||
|
error = hn_attach_subchans(sc);
|
||||||
|
if (error)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure RSS key and indirect table _after_ all sub-channels
|
||||||
|
* are attached.
|
||||||
|
*/
|
||||||
if ((sc->hn_flags & HN_FLAG_HAS_RSSKEY) == 0) {
|
if ((sc->hn_flags & HN_FLAG_HAS_RSSKEY) == 0) {
|
||||||
/*
|
/*
|
||||||
* RSS key is not set yet; set it to the default RSS key.
|
* RSS key is not set yet; set it to the default RSS key.
|
||||||
@ -4521,34 +4544,31 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
|
error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
|
||||||
if (error) {
|
|
||||||
/*
|
|
||||||
* Failed to configure RSS key or indirect table; only
|
|
||||||
* the primary channel can be used.
|
|
||||||
*/
|
|
||||||
nchan = 1;
|
|
||||||
}
|
|
||||||
back:
|
|
||||||
/*
|
|
||||||
* Set the # of TX/RX rings that could be used according to
|
|
||||||
* the # of channels that NVS offered.
|
|
||||||
*/
|
|
||||||
hn_set_ring_inuse(sc, nchan);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Attach the sub-channels, if any.
|
|
||||||
*/
|
|
||||||
error = hn_attach_subchans(sc);
|
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
goto failed;
|
||||||
|
back:
|
||||||
/*
|
/*
|
||||||
* Fixup transmission aggregation setup.
|
* Fixup transmission aggregation setup.
|
||||||
*/
|
*/
|
||||||
hn_set_txagg(sc);
|
hn_set_txagg(sc);
|
||||||
|
|
||||||
sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED;
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
failed:
|
||||||
|
if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
|
||||||
|
hn_synth_detach(sc);
|
||||||
|
} else {
|
||||||
|
if (attached & ATTACHED_RNDIS)
|
||||||
|
hn_rndis_detach(sc);
|
||||||
|
if (attached & ATTACHED_NVS)
|
||||||
|
hn_nvs_detach(sc);
|
||||||
|
hn_chan_detach(sc, sc->hn_prichan);
|
||||||
|
/* Restore old capabilities. */
|
||||||
|
sc->hn_caps = old_caps;
|
||||||
|
}
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
#undef ATTACHED_RNDIS
|
||||||
|
#undef ATTACHED_NVS
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4559,7 +4579,6 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
|
|||||||
static void
|
static void
|
||||||
hn_synth_detach(struct hn_softc *sc)
|
hn_synth_detach(struct hn_softc *sc)
|
||||||
{
|
{
|
||||||
HN_LOCK_ASSERT(sc);
|
|
||||||
|
|
||||||
KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
|
KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
|
||||||
("synthetic parts were not attached"));
|
("synthetic parts were not attached"));
|
||||||
|
Loading…
Reference in New Issue
Block a user