Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/hyperv/vmbus/vmbus_chan.c
Show All 37 Lines | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <machine/stdarg.h> | #include <machine/stdarg.h> | ||||
#include <dev/hyperv/include/hyperv_busdma.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | |||||
#include <vm/vm_extern.h> | |||||
#include <dev/hyperv/include/vmbus_xact.h> | #include <dev/hyperv/include/vmbus_xact.h> | ||||
#include <dev/hyperv/vmbus/hyperv_var.h> | #include <dev/hyperv/vmbus/hyperv_var.h> | ||||
#include <dev/hyperv/vmbus/vmbus_reg.h> | #include <dev/hyperv/vmbus/vmbus_reg.h> | ||||
#include <dev/hyperv/vmbus/vmbus_var.h> | #include <dev/hyperv/vmbus/vmbus_var.h> | ||||
#include <dev/hyperv/vmbus/vmbus_brvar.h> | #include <dev/hyperv/vmbus/vmbus_brvar.h> | ||||
#include <dev/hyperv/vmbus/vmbus_chanvar.h> | #include <dev/hyperv/vmbus/vmbus_chanvar.h> | ||||
struct vmbus_chan_pollarg { | struct vmbus_chan_pollarg { | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static __inline void | static __inline void | ||||
vmbus_chan_signal(const struct vmbus_channel *chan) | vmbus_chan_signal(const struct vmbus_channel *chan) | ||||
{ | { | ||||
atomic_set_long(chan->ch_evtflag, chan->ch_evtflag_mask); | atomic_set_long(chan->ch_evtflag, chan->ch_evtflag_mask); | ||||
if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF) | if (chan->ch_txflags & VMBUS_CHAN_TXF_HASMNF) | ||||
atomic_set_int(chan->ch_montrig, chan->ch_montrig_mask); | atomic_set_int(chan->ch_montrig, chan->ch_montrig_mask); | ||||
else | else | ||||
hypercall_signal_event(chan->ch_monprm_dma.hv_paddr); | hypercall_signal_event(pmap_kextract( | ||||
(vm_offset_t)chan->ch_monprm)); | |||||
} | } | ||||
static __inline void | static __inline void | ||||
vmbus_chan_signal_tx(struct vmbus_channel *chan) | vmbus_chan_signal_tx(struct vmbus_channel *chan) | ||||
{ | { | ||||
chan->ch_txbr.txbr_intrcnt ++; | chan->ch_txbr.txbr_intrcnt ++; | ||||
vmbus_chan_signal(chan); | vmbus_chan_signal(chan); | ||||
▲ Show 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct vmbus_chan_br cbr; | struct vmbus_chan_br cbr; | ||||
int error; | int error; | ||||
/* | /* | ||||
* Allocate the TX+RX bufrings. | * Allocate the TX+RX bufrings. | ||||
*/ | */ | ||||
KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated")); | KASSERT(chan->ch_bufring == NULL, ("bufrings are allocated")); | ||||
chan->ch_bufring = hyperv_dmamem_alloc(bus_get_dma_tag(chan->ch_dev), | chan->ch_bufring_size = txbr_size + rxbr_size; | ||||
PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, | chan->ch_bufring = contigmalloc(chan->ch_bufring_size, M_DEVBUF, | ||||
BUS_DMA_WAITOK); | M_WAITOK | M_ZERO, 0ul, ~0ul, PAGE_SIZE, 0); | ||||
if (chan->ch_bufring == NULL) { | if (chan->ch_bufring == NULL) { | ||||
vmbus_chan_printf(chan, "bufring allocation failed\n"); | vmbus_chan_printf(chan, "bufring allocation failed\n"); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
cbr.cbr = chan->ch_bufring; | cbr.cbr = chan->ch_bufring; | ||||
cbr.cbr_paddr = chan->ch_bufring_dma.hv_paddr; | cbr.cbr_paddr = pmap_kextract((vm_offset_t)chan->ch_bufring); | ||||
cbr.cbr_txsz = txbr_size; | cbr.cbr_txsz = txbr_size; | ||||
cbr.cbr_rxsz = rxbr_size; | cbr.cbr_rxsz = rxbr_size; | ||||
error = vmbus_chan_open_br(chan, &cbr, udata, udlen, cb, cbarg); | error = vmbus_chan_open_br(chan, &cbr, udata, udlen, cb, cbarg); | ||||
if (error) { | if (error) { | ||||
if (error == EISCONN) { | if (error == EISCONN) { | ||||
/* | /* | ||||
* XXX | * XXX | ||||
* The bufring GPADL is still connected; abandon | * The bufring GPADL is still connected; abandon | ||||
* this bufring, instead of having mysterious | * this bufring, instead of having mysterious | ||||
* crash or trashed data later on. | * crash or trashed data later on. | ||||
*/ | */ | ||||
vmbus_chan_printf(chan, "chan%u bufring GPADL " | vmbus_chan_printf(chan, "chan%u bufring GPADL " | ||||
"is still connected upon channel open error; " | "is still connected upon channel open error; " | ||||
"leak %d bytes memory\n", chan->ch_id, | "leak %d bytes memory\n", chan->ch_id, | ||||
txbr_size + rxbr_size); | txbr_size + rxbr_size); | ||||
} else { | } else { | ||||
hyperv_dmamem_free(&chan->ch_bufring_dma, | contigfree(chan->ch_bufring, chan->ch_bufring_size, | ||||
chan->ch_bufring); | M_DEVBUF); | ||||
} | } | ||||
chan->ch_bufring = NULL; | chan->ch_bufring = NULL; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, | vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, | ||||
▲ Show 20 Lines • Show All 553 Lines • ▼ Show 20 Lines | if (chan->ch_bufring_gpadl != 0) { | ||||
} | } | ||||
chan->ch_bufring_gpadl = 0; | chan->ch_bufring_gpadl = 0; | ||||
} | } | ||||
/* | /* | ||||
* Destroy the TX+RX bufrings. | * Destroy the TX+RX bufrings. | ||||
*/ | */ | ||||
if (chan->ch_bufring != NULL) { | if (chan->ch_bufring != NULL) { | ||||
hyperv_dmamem_free(&chan->ch_bufring_dma, chan->ch_bufring); | contigfree(chan->ch_bufring, PAGE_SIZE, M_DEVBUF); | ||||
chan->ch_bufring = NULL; | chan->ch_bufring = NULL; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
vmbus_chan_close_direct(struct vmbus_channel *chan) | vmbus_chan_close_direct(struct vmbus_channel *chan) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 675 Lines • ▼ Show 20 Lines | |||||
static struct vmbus_channel * | static struct vmbus_channel * | ||||
vmbus_chan_alloc(struct vmbus_softc *sc) | vmbus_chan_alloc(struct vmbus_softc *sc) | ||||
{ | { | ||||
struct vmbus_channel *chan; | struct vmbus_channel *chan; | ||||
chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO); | chan = malloc(sizeof(*chan), M_DEVBUF, M_WAITOK | M_ZERO); | ||||
chan->ch_monprm = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), | chan->ch_monprm = contigmalloc(sizeof(struct hyperv_mon_param), | ||||
HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param), | M_DEVBUF, M_WAITOK | M_ZERO, 0ul, ~0ul, HYPERCALL_PARAM_ALIGN, 0); | ||||
&chan->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); | |||||
if (chan->ch_monprm == NULL) { | if (chan->ch_monprm == NULL) { | ||||
device_printf(sc->vmbus_dev, "monprm alloc failed\n"); | device_printf(sc->vmbus_dev, "monprm alloc failed\n"); | ||||
free(chan, M_DEVBUF); | free(chan, M_DEVBUF); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
schakrabarti_microsoft.com: Please handle null return scenarios. | |||||
chan->ch_refs = 1; | chan->ch_refs = 1; | ||||
chan->ch_vmbus = sc; | chan->ch_vmbus = sc; | ||||
mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); | mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF); | ||||
sx_init(&chan->ch_orphan_lock, "vmbus chorphan"); | sx_init(&chan->ch_orphan_lock, "vmbus chorphan"); | ||||
TAILQ_INIT(&chan->ch_subchans); | TAILQ_INIT(&chan->ch_subchans); | ||||
vmbus_rxbr_init(&chan->ch_rxbr); | vmbus_rxbr_init(&chan->ch_rxbr); | ||||
vmbus_txbr_init(&chan->ch_txbr); | vmbus_txbr_init(&chan->ch_txbr); | ||||
Show All 17 Lines | KASSERT((chan->ch_stflags & | ||||
VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel")); | VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel")); | ||||
KASSERT(chan->ch_orphan_xact == NULL, | KASSERT(chan->ch_orphan_xact == NULL, | ||||
("still has orphan xact installed")); | ("still has orphan xact installed")); | ||||
KASSERT(chan->ch_refs == 0, ("chan%u: invalid refcnt %d", | KASSERT(chan->ch_refs == 0, ("chan%u: invalid refcnt %d", | ||||
chan->ch_id, chan->ch_refs)); | chan->ch_id, chan->ch_refs)); | ||||
KASSERT(chan->ch_poll_intvl == 0, ("chan%u: polling is activated", | KASSERT(chan->ch_poll_intvl == 0, ("chan%u: polling is activated", | ||||
chan->ch_id)); | chan->ch_id)); | ||||
hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm); | contigfree(chan->ch_monprm, sizeof(struct hyperv_mon_param), M_DEVBUF); | ||||
mtx_destroy(&chan->ch_subchan_lock); | mtx_destroy(&chan->ch_subchan_lock); | ||||
sx_destroy(&chan->ch_orphan_lock); | sx_destroy(&chan->ch_orphan_lock); | ||||
vmbus_rxbr_deinit(&chan->ch_rxbr); | vmbus_rxbr_deinit(&chan->ch_rxbr); | ||||
vmbus_txbr_deinit(&chan->ch_txbr); | vmbus_txbr_deinit(&chan->ch_txbr); | ||||
free(chan, M_DEVBUF); | free(chan, M_DEVBUF); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 708 Lines • Show Last 20 Lines |
Please handle null return scenarios.