diff options
| author | Sepherosa Ziehau <sephe@FreeBSD.org> | 2016-11-25 09:13:10 +0000 |
|---|---|---|
| committer | Sepherosa Ziehau <sephe@FreeBSD.org> | 2016-11-25 09:13:10 +0000 |
| commit | 2641e757426b0b92d46421eeceb63f24ac002566 (patch) | |
| tree | b2544e2fbeafc60579b74657633e0f48b157624d /sys/dev/hyperv/vmbus | |
| parent | 892b35bc36c3b931d99301cbf751c503726db0ce (diff) | |
Notes
Diffstat (limited to 'sys/dev/hyperv/vmbus')
| -rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_chan.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/sys/dev/hyperv/vmbus/vmbus_chan.c b/sys/dev/hyperv/vmbus/vmbus_chan.c index 4364ac7be837..18f83aa5dbbc 100644 --- a/sys/dev/hyperv/vmbus/vmbus_chan.c +++ b/sys/dev/hyperv/vmbus/vmbus_chan.c @@ -851,6 +851,41 @@ disconnect: return (error); } +int +vmbus_chan_close_direct(struct vmbus_channel *chan) +{ + int error; + +#ifdef INVARIANTS + if (VMBUS_CHAN_ISPRIMARY(chan)) { + struct vmbus_channel *subchan; + + /* + * All sub-channels _must_ have been closed, or are _not_ + * opened at all. + */ + mtx_lock(&chan->ch_subchan_lock); + TAILQ_FOREACH(subchan, &chan->ch_subchans, ch_sublink) { + KASSERT( + (subchan->ch_stflags & VMBUS_CHAN_ST_OPENED) == 0, + ("chan%u: subchan%u is still opened", + chan->ch_id, subchan->ch_subidx)); + } + mtx_unlock(&chan->ch_subchan_lock); + } +#endif + + error = vmbus_chan_close_internal(chan); + if (!VMBUS_CHAN_ISPRIMARY(chan)) { + /* + * This sub-channel is referenced, when it is linked to + * the primary channel; drop that reference now. + */ + vmbus_chan_detach(chan); + } + return (error); +} + /* * Caller should make sure that all sub-channels have * been added to 'chan' and all to-be-closed channels |
