diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index f2b7a037f40c..15a7ea7e21ea 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -278,6 +278,7 @@ dev/hyperv/vmbus/hv_hv.c optional hyperv dev/hyperv/vmbus/hv_et.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c optional hyperv +dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/amd64/hv_vector.S optional hyperv dev/kbd/kbd.c optional atkbd | sc | ukbd | vt dev/lindev/full.c optional lindev diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 127ef2cbbd60..2045c7cad0d8 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -254,6 +254,7 @@ dev/hyperv/vmbus/hv_hv.c optional hyperv dev/hyperv/vmbus/hv_et.c optional hyperv dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c optional hyperv +dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/i386/hv_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd dev/if_ndis/if_ndis.c optional ndis diff --git a/sys/dev/hyperv/include/hyperv_busdma.h b/sys/dev/hyperv/include/hyperv_busdma.h new file mode 100644 index 000000000000..f4ea8cf83fe9 --- /dev/null +++ b/sys/dev/hyperv/include/hyperv_busdma.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2016 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _HYPERV_BUSDMA_H_ +#define _HYPERV_BUSDMA_H_ + +struct hyperv_dma { + bus_addr_t hv_paddr; + bus_dma_tag_t hv_dtag; + bus_dmamap_t hv_dmap; +}; + +void hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, + int error); +void *hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag, bus_size_t alignment, + bus_addr_t boundary, bus_size_t size, struct hyperv_dma *dma, + int flags); +void hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr); + +#endif /* !_HYPERV_BUSDMA_H_ */ diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index f670c12bb839..520cbf730665 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include "hv_net_vsc.h" #include "hv_rndis.h" #include "hv_rndis_filter.h" @@ -2216,18 +2217,6 @@ hn_check_iplen(const struct mbuf *m, int hoff) return ip->ip_p; } -static void -hn_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - bus_addr_t *paddr = arg; - - if (error) - return; - - KASSERT(nseg == 1, ("too many segments %d!", nseg)); - *paddr = segs->ds_addr; -} - static void hn_create_rx_data(struct hn_softc *sc, int ring_cnt) { @@ -2528,7 +2517,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id) error = bus_dmamap_load(txr->hn_tx_rndis_dtag, txd->rndis_msg_dmap, txd->rndis_msg, HN_RNDIS_MSG_LEN, - hn_dma_map_paddr, &txd->rndis_msg_paddr, + hyperv_dma_map_paddr, &txd->rndis_msg_paddr, BUS_DMA_NOWAIT); if (error) { device_printf(sc->hn_dev, diff --git a/sys/dev/hyperv/vmbus/hyperv_busdma.c b/sys/dev/hyperv/vmbus/hyperv_busdma.c new file mode 100644 index 000000000000..07f4e748660d --- /dev/null +++ b/sys/dev/hyperv/vmbus/hyperv_busdma.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2016 Microsoft Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include + +#include + +#define HYPERV_DMA_WAITMASK (BUS_DMA_WAITOK | BUS_DMA_NOWAIT) + +void +hyperv_dma_map_paddr(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *paddr = arg; + + if (error) + return; + + KASSERT(nseg == 1, ("too many segments %d!", nseg)); + *paddr = segs->ds_addr; +} + +void * +hyperv_dmamem_alloc(bus_dma_tag_t parent_dtag, bus_size_t alignment, + bus_addr_t boundary, bus_size_t size, struct hyperv_dma *dma, int flags) +{ + void *ret; + int error; + + error = bus_dma_tag_create(parent_dtag, /* parent */ + alignment, /* alignment */ + boundary, /* boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + size, /* maxsize */ + 1, /* nsegments */ + size, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockfuncarg */ + &dma->hv_dtag); + if (error) + return NULL; + + error = bus_dmamem_alloc(dma->hv_dtag, &ret, + (flags & HYPERV_DMA_WAITMASK) | BUS_DMA_COHERENT, &dma->hv_dmap); + if (error) { + bus_dma_tag_destroy(dma->hv_dtag); + return NULL; + } + + error = bus_dmamap_load(dma->hv_dtag, dma->hv_dmap, ret, size, + hyperv_dma_map_paddr, &dma->hv_paddr, BUS_DMA_NOWAIT); + if (error) { + bus_dmamem_free(dma->hv_dtag, ret, dma->hv_dmap); + bus_dma_tag_destroy(dma->hv_dtag); + return NULL; + } + return ret; +} + +void +hyperv_dmamem_free(struct hyperv_dma *dma, void *ptr) +{ + bus_dmamap_unload(dma->hv_dtag, dma->hv_dmap); + bus_dmamem_free(dma->hv_dtag, ptr, dma->hv_dmap); + bus_dma_tag_destroy(dma->hv_dtag); +} diff --git a/sys/modules/hyperv/vmbus/Makefile b/sys/modules/hyperv/vmbus/Makefile index 8187146ae9dc..cfbd2cf66c07 100644 --- a/sys/modules/hyperv/vmbus/Makefile +++ b/sys/modules/hyperv/vmbus/Makefile @@ -11,7 +11,8 @@ SRCS= hv_channel.c \ hv_hv.c \ hv_ring_buffer.c \ hv_vmbus_drv_freebsd.c \ - hv_vmbus_priv.h + hv_vmbus_priv.h \ + hyperv_busdma.c SRCS+= acpi_if.h bus_if.h device_if.h opt_acpi.h # XXX: for assym.s