Module Name:    src
Committed By:   riastradh
Date:           Wed Jul 24 03:17:48 UTC 2013

Modified Files:
        src/sys/external/bsd/drm2/include/linux [riastradh-drm2]: io-mapping.h

Log Message:
Fill <linux/io-mapping.h> with an io_mapping abstraction.

Mapped to bus space reservations.  This might not be appropriate --
non-x86 platforms don't have them yet, and I'm not 100% confident
that Linux uses io_mappings for regions exclusively like bus space
reservations will require, but if that requirement is violated then
at least it will fail noisily, whether because of a bug or because
Linux io_mappings work differently.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 \
    src/sys/external/bsd/drm2/include/linux/io-mapping.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/include/linux/io-mapping.h
diff -u src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.1.2.1 src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.1.2.2
--- src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.1.2.1	Wed Jul 24 00:33:12 2013
+++ src/sys/external/bsd/drm2/include/linux/io-mapping.h	Wed Jul 24 03:17:48 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: io-mapping.h,v 1.1.2.1 2013/07/24 00:33:12 riastradh Exp $	*/
+/*	$NetBSD: io-mapping.h,v 1.1.2.2 2013/07/24 03:17:48 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,4 +32,92 @@
 #ifndef _LINUX_IO_MAPPING_H_
 #define _LINUX_IO_MAPPING_H_
 
+#include <sys/bus.h>
+#include <sys/kmem.h>
+#include <sys/systm.h>
+
+/*
+ * XXX This uses NetBSD bus space reservations, which are currently
+ * implemented only for x86.
+ */
+
+struct io_mapping {
+	bus_space_tag_t		diom_bst;
+	bus_addr_t		diom_addr;
+	bus_addr_t		diom_size;
+	int			diom_flags;
+	bus_space_reservation_t	diom_bsr;
+	bool			diom_mapped;
+	bus_space_handle_t	diom_bsh;
+};
+
+static inline struct io_mapping *
+bus_space_io_mapping_create_wc(bus_space_tag_t bst, bus_addr_t addr,
+    bus_size_t size)
+{
+	struct io_mapping *const mapping = kmem_alloc(sizeof(*mapping),
+	    KM_SLEEP);
+	mapping->diom_bst = bst;
+	mapping->diom_addr = addr;
+	mapping->diom_size = size;
+	mapping->diom_flags = 0;
+	mapping->diom_flags |= BUS_SPACE_MAP_LINEAR;
+	mapping->diom_flags |= BUS_SPACE_MAP_PREFETCHABLE;
+	mapping->diom_mapped = false;
+
+	if (bus_space_reserve(mapping->diom_bst, addr, size,
+		mapping->diom_flags, &mapping->diom_bsr)) {
+		kmem_free(mapping, sizeof(*mapping));
+		return NULL;
+	}
+
+	return mapping;
+}
+
+static inline void
+io_mapping_free(struct io_mapping *mapping)
+{
+
+	KASSERT(!mapping->diom_mapped);
+	bus_space_release(mapping->diom_bst, &mapping->diom_bsr);
+	kmem_free(mapping, sizeof(*mapping));
+}
+
+static inline void *
+io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset)
+{
+
+	KASSERT(!mapping->diom_mapped);
+	KASSERT(ISSET(mapping->diom_flags, BUS_SPACE_MAP_LINEAR));
+	if (bus_space_reservation_map(mapping->diom_bst, &mapping->diom_bsr,
+		mapping->diom_flags, &mapping->diom_bsh))
+		panic("Unable to make I/O mapping!"); /* XXX */
+	mapping->diom_mapped = true;
+
+	return (char *)bus_space_vaddr(mapping->diom_bst, mapping->diom_bsh)
+	    + offset;		/* XXX arithmetic overflow */
+}
+
+static inline void
+io_mapping_unmap(struct io_mapping *mapping, void *vaddr __unused)
+{
+
+	KASSERT(mapping->diom_mapped);
+	bus_space_reservation_unmap(mapping->diom_bst, mapping->diom_bsh,
+	    mapping->diom_size);
+	mapping->diom_mapped = false;
+}
+
+static inline void *
+io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset)
+{
+	return io_mapping_map_wc(mapping, offset);
+}
+
+static inline void
+io_mapping_unmap_atomic(struct io_mapping *mapping, void *vaddr __unused)
+{
+	return io_mapping_unmap(mapping, vaddr);
+}
+
 #endif  /* _LINUX_IO_MAPPING_H_ */

Reply via email to