summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/pci/agp_machdep.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/sys/arch/i386/pci/agp_machdep.c b/sys/arch/i386/pci/agp_machdep.c
index e63e00cc243..e6eaa41a00c 100644
--- a/sys/arch/i386/pci/agp_machdep.c
+++ b/sys/arch/i386/pci/agp_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_machdep.c,v 1.11 2010/04/08 01:26:44 oga Exp $ */
+/* $OpenBSD: agp_machdep.c,v 1.12 2010/05/10 22:06:04 oga Exp $ */
/*
* Copyright (c) 2008 - 2009 Owain G. Ainsworth <oga@openbsd.org>
@@ -174,6 +174,100 @@ agp_bus_dma_set_alignment(bus_dma_tag_t tag, bus_dmamap_t dmam,
sg_dmamap_set_alignment(tag, dmam, alignment);
}
+struct agp_map {
+ bus_space_tag_t bst;
+ bus_addr_t addr;
+ bus_size_t size;
+ int flags;
+};
+
+extern struct extent *ioport_ex;
+extern struct extent *iomem_ex;
+
+int
+agp_init_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
+ int flags, struct agp_map **mapp)
+{
+ struct extent *ex;
+ struct agp_map *map;
+ int error;
+
+ switch (tag) {
+ case I386_BUS_SPACE_IO:
+ ex = ioport_ex;
+ if (flags & BUS_SPACE_MAP_LINEAR)
+ return (EINVAL);
+ break;
+
+ case I386_BUS_SPACE_MEM:
+ ex = iomem_ex;
+ break;
+
+ default:
+ panic("agp_init_map: bad bus space tag");
+ }
+ /*
+ * We grab the extent out of the bus region ourselves
+ * so we don't need to do these allocations every time.
+ */
+ error = extent_alloc_region(ex, address, size,
+ EX_NOWAIT | EX_MALLOCOK);
+ if (error)
+ return (error);
+
+ map = malloc(sizeof(*map), M_AGP, M_WAITOK | M_CANFAIL);
+ if (map == NULL)
+ return (ENOMEM);
+
+ map->bst = tag;
+ map->addr = address;
+ map->size = size;
+ map->flags = flags;
+
+ *mapp = map;
+ return (0);
+}
+
+void
+agp_destroy_map(struct agp_map *map)
+{
+ struct extent *ex;
+
+ switch (map->bst) {
+ case I386_BUS_SPACE_IO:
+ ex = ioport_ex;
+ break;
+
+ case I386_BUS_SPACE_MEM:
+ ex = iomem_ex;
+ break;
+
+ default:
+ panic("agp_destroy_map: bad bus space tag");
+ }
+
+ if (extent_free(ex, map->addr, map->size,
+ EX_NOWAIT | EX_MALLOCOK ))
+ printf("agp_destroy_map: can't free region\n");
+ free(map, M_AGP);
+}
+
+
+int
+agp_map_subregion(struct agp_map *map, bus_size_t offset, bus_size_t size,
+ bus_space_handle_t *bshp)
+{
+ return (_bus_space_map(map->bst, map->addr + offset, size,
+ map->flags, bshp));
+}
+
+void
+agp_unmap_subregion(struct agp_map *map, bus_space_handle_t bsh,
+ bus_size_t size)
+{
+ return (_bus_space_unmap(map->bst, bsh, size, NULL));
+}
+
/*
* ick ick ick. However, the rest of this driver is supposedly MI (though
* they only exist on x86), so this can't be in dev/pci.