diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2011-07-06 05:35:54 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2011-07-06 05:35:54 +0000 |
commit | c3a60f6a2203e487a9cab88ae4892126da058e8f (patch) | |
tree | 4b002d2ac304e66b98c10514b46b7140b8241f9e /sys | |
parent | 04c2eb54a519692ed461b53c475f60e112f62e77 (diff) |
Split some generic MSI code out into its own file.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/conf/files.sparc64 | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/msi.c | 86 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/msivar.h | 26 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/vpci.c | 81 |
4 files changed, 124 insertions, 76 deletions
diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index b373269cd5f..07cb5dcf5b0 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.sparc64,v 1.132 2011/01/14 20:12:39 matthieu Exp $ +# $OpenBSD: files.sparc64,v 1.133 2011/07/06 05:35:53 kettenis Exp $ # $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $ # maxpartitions must be first item in files.${ARCH} @@ -91,6 +91,9 @@ define viommu file arch/sparc64/dev/iommu.c iommu | viommu | sbus file arch/sparc64/dev/viommu.c viommu +define msi +file arch/sparc64/dev/msi.c msi + attach sbus at mainbus with sbus_mb attach sbus at xbox with sbus_xbox file arch/sparc64/dev/sbus.c sbus @@ -120,7 +123,7 @@ device pyro: pcibus, iommu attach pyro at mainbus file arch/sparc64/dev/pyro.c pyro -device vpci: pcibus, viommu +device vpci: pcibus, viommu, msi attach vpci at mainbus file arch/sparc64/dev/vpci.c vpci diff --git a/sys/arch/sparc64/dev/msi.c b/sys/arch/sparc64/dev/msi.c new file mode 100644 index 00000000000..1bd6cc9925d --- /dev/null +++ b/sys/arch/sparc64/dev/msi.c @@ -0,0 +1,86 @@ +/* $OpenBSD: msi.c,v 1.1 2011/07/06 05:35:53 kettenis Exp $ */ +/* + * Copyright (c) 2011 Mark Kettenis <kettenis@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <machine/bus.h> + +#include <sparc64/dev/msivar.h> + +struct msi_msg { + uint64_t mm_data[8]; +}; + +struct msi_eq * +msi_eq_alloc(bus_dma_tag_t t, int msi_eq_size) +{ + struct msi_eq *meq; + bus_size_t size; + caddr_t va; + int nsegs; + + meq = malloc(sizeof(struct msi_eq), M_DEVBUF, M_NOWAIT); + if (meq == NULL) + return NULL; + + size = roundup(msi_eq_size * sizeof(struct msi_msg), PAGE_SIZE); + + if (bus_dmamap_create(t, size, 1, size, 0, + BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &meq->meq_map) != 0) + return (NULL); + + if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &meq->meq_seg, 1, + &nsegs, BUS_DMA_NOWAIT) != 0) + goto destroy; + + if (bus_dmamem_map(t, &meq->meq_seg, 1, size, &va, + BUS_DMA_NOWAIT) != 0) + goto free; + + if (bus_dmamap_load(t, meq->meq_map, va, size, NULL, + BUS_DMA_NOWAIT) != 0) + goto unmap; + + meq->meq_va = va; + meq->meq_nentries = msi_eq_size; + return (meq); + +unmap: + bus_dmamem_unmap(t, va, size); +free: + bus_dmamem_free(t, &meq->meq_seg, 1); +destroy: + bus_dmamap_destroy(t, meq->meq_map); + + return (NULL); +} + +void +msi_eq_free(bus_dma_tag_t t, struct msi_eq *meq) +{ + bus_size_t size; + + size = roundup(meq->meq_nentries * sizeof(struct msi_msg), PAGE_SIZE); + + bus_dmamap_unload(t, meq->meq_map); + bus_dmamem_unmap(t, meq->meq_va, size); + bus_dmamem_free(t, &meq->meq_seg, 1); + bus_dmamap_destroy(t, meq->meq_map); + free(meq, M_DEVBUF); +} diff --git a/sys/arch/sparc64/dev/msivar.h b/sys/arch/sparc64/dev/msivar.h new file mode 100644 index 00000000000..b55552f1ad3 --- /dev/null +++ b/sys/arch/sparc64/dev/msivar.h @@ -0,0 +1,26 @@ +/* $OpenBSD: msivar.h,v 1.1 2011/07/06 05:35:53 kettenis Exp $ */ +/* + * Copyright (c) 2011 Mark Kettenis <kettenis@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct msi_eq *msi_eq_alloc(bus_dma_tag_t, int); +void msi_eq_free(bus_dma_tag_t t, struct msi_eq *); + +struct msi_eq { + bus_dmamap_t meq_map; + bus_dma_segment_t meq_seg; + caddr_t meq_va; + int meq_nentries; +}; diff --git a/sys/arch/sparc64/dev/vpci.c b/sys/arch/sparc64/dev/vpci.c index ec671732671..fc1eb53891e 100644 --- a/sys/arch/sparc64/dev/vpci.c +++ b/sys/arch/sparc64/dev/vpci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vpci.c,v 1.9 2011/07/06 05:08:50 kettenis Exp $ */ +/* $OpenBSD: vpci.c,v 1.10 2011/07/06 05:35:53 kettenis Exp $ */ /* * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org> * @@ -33,17 +33,11 @@ #include <dev/pci/pcireg.h> #include <sparc64/dev/viommuvar.h> +#include <sparc64/dev/msivar.h> extern struct sparc_pci_chipset _sparc_pci_chipset; -struct msi_eq { - bus_dmamap_t meq_map; - bus_dma_segment_t meq_seg; - caddr_t meq_va; - int meq_nentries; -}; - -struct msi_msg { +struct vpci_msi_msg { uint32_t mm_version; uint8_t mm_reserved[3]; uint8_t mm_type; @@ -125,9 +119,6 @@ void vpci_msi_ack(struct intrhand *); int vpci_msi_eq_intr(void *); -struct msi_eq *msi_eq_alloc(bus_dma_tag_t, int); -void msi_eq_free(bus_dma_tag_t t, struct msi_eq *); - int vpci_dmamap_create(bus_dma_tag_t, bus_dma_tag_t, bus_size_t, int, bus_size_t, bus_size_t, int, bus_dmamap_t *); void vpci_dmamap_destroy(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t); @@ -586,7 +577,7 @@ vpci_msi_eq_intr(void *arg) { struct vpci_pbm *pbm = arg; struct msi_eq *meq = pbm->vp_meq; - struct msi_msg *msg; + struct vpci_msi_msg *msg; uint64_t head, tail; struct intrhand *ih; int err; @@ -603,7 +594,7 @@ vpci_msi_eq_intr(void *arg) return (0); while (head != tail) { - msg = (struct msi_msg *)(meq->meq_va + head); + msg = (struct vpci_msi_msg *)(meq->meq_va + head); ih = pbm->vp_msi[msg->mm_data]; err = hv_pci_msi_setstate(pbm->vp_devhandle, msg->mm_data, PCI_MSISTATE_IDLE); @@ -612,8 +603,8 @@ vpci_msi_eq_intr(void *arg) send_softint(-1, ih->ih_pil, ih); - head += sizeof(struct msi_msg); - head &= ((meq->meq_nentries * sizeof(struct msi_msg)) - 1); + head += sizeof(struct vpci_msi_msg); + head &= ((meq->meq_nentries * sizeof(struct vpci_msi_msg)) - 1); } err = hv_pci_msiq_sethead(pbm->vp_devhandle, 0, head); @@ -623,64 +614,6 @@ vpci_msi_eq_intr(void *arg) return (1); } -struct msi_eq * -msi_eq_alloc(bus_dma_tag_t t, int msi_eq_size) -{ - struct msi_eq *meq; - bus_size_t size; - caddr_t va; - int nsegs; - - meq = malloc(sizeof(struct msi_eq), M_DEVBUF, M_NOWAIT); - if (meq == NULL) - return NULL; - - size = roundup(msi_eq_size * sizeof(struct msi_msg), PAGE_SIZE); - - if (bus_dmamap_create(t, size, 1, size, 0, - BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &meq->meq_map) != 0) - return (NULL); - - if (bus_dmamem_alloc(t, size, PAGE_SIZE, 0, &meq->meq_seg, 1, - &nsegs, BUS_DMA_NOWAIT) != 0) - goto destroy; - - if (bus_dmamem_map(t, &meq->meq_seg, 1, size, &va, - BUS_DMA_NOWAIT) != 0) - goto free; - - if (bus_dmamap_load(t, meq->meq_map, va, size, NULL, - BUS_DMA_NOWAIT) != 0) - goto unmap; - - meq->meq_va = va; - meq->meq_nentries = msi_eq_size; - return (meq); - -unmap: - bus_dmamem_unmap(t, va, size); -free: - bus_dmamem_free(t, &meq->meq_seg, 1); -destroy: - bus_dmamap_destroy(t, meq->meq_map); - - return (NULL); -} - -void -msi_eq_free(bus_dma_tag_t t, struct msi_eq *meq) -{ - bus_size_t size; - - size = roundup(meq->meq_nentries * sizeof(struct msi_msg), PAGE_SIZE); - - bus_dmamap_unload(t, meq->meq_map); - bus_dmamem_unmap(t, meq->meq_va, size); - bus_dmamem_free(t, &meq->meq_seg, 1); - bus_dmamap_destroy(t, meq->meq_map); - free(meq, M_DEVBUF); -} - const struct cfattach vpci_ca = { sizeof(struct vpci_softc), vpci_match, vpci_attach }; |