the DRM_{READ,WRITE}$NUMBER() macros currently use
authoroga <oga@openbsd.org>
Thu, 10 Jul 2008 00:10:22 +0000 (00:10 +0000)
committeroga <oga@openbsd.org>
Thu, 10 Jul 2008 00:10:22 +0000 (00:10 +0000)
bus_space_{read,write}(). A bug in the code this was based on means that
this is also used for scatter gather maps, which are bus_dma memory, not
pci memory.  This obviously fails. Pull them out into a function and
Special case scatter gather to use the mapped virtual address to write
instead. Makes writeback test pass on pci and pci express radeon cards.

Tested by, among others ckuethe@ and sthen@.

sys/dev/pci/drm/drmP.h
sys/dev/pci/drm/drm_memory.c

index 3b448af..24f8c6b 100644 (file)
@@ -229,18 +229,12 @@ typedef u_int8_t u8;
                                        "lock; addl $0,0(%%rsp)" : : : "memory");
 #endif
 
-#define DRM_READ8(map, offset)         \
-       bus_space_read_1( (map)->bst, (map)->bsh, (offset))
-#define DRM_READ16(map, offset)                \
-       bus_space_read_2( (map)->bst, (map)->bsh, (offset))
-#define DRM_READ32(map, offset)                \
-       bus_space_read_4( (map)->bst, (map)->bsh, (offset))
-#define DRM_WRITE8(map, offset, val)   \
-       bus_space_write_1((map)->bst, (map)->bsh, (offset), (val))
-#define DRM_WRITE16(map, offset, val)  \
-       bus_space_write_2((map)->bst, (map)->bsh, (offset), (val))
-#define DRM_WRITE32(map, offset, val)  \
-       bus_space_write_4((map)->bst, (map)->bsh, (offset), (val))
+#define DRM_READ8(map, offset) drm_read8(map, offset)
+#define DRM_READ16(map, offset) drm_read16(map, offset)
+#define DRM_READ32(map, offset) drm_read32(map, offset)
+#define DRM_WRITE8(map, offset, val) drm_write8(map, offset, val)
+#define DRM_WRITE16(map, offset, val) drm_write16(map, offset, val)
+#define DRM_WRITE32(map, offset, val) drm_write32(map, offset, val)
 
 #define DRM_VERIFYAREA_READ( uaddr, size )                             \
        (!uvm_map_checkprot(&(curproc->p_vmspace->vm_map),              \
@@ -757,6 +751,12 @@ int        drm_ctxbitmap_init(struct drm_device *);
 void   drm_ctxbitmap_cleanup(struct drm_device *);
 void   drm_ctxbitmap_free(struct drm_device *, int);
 int    drm_ctxbitmap_next(struct drm_device *);
+u_int8_t       drm_read8(drm_local_map_t *, unsigned long);
+u_int16_t drm_read16(drm_local_map_t *, unsigned long);
+u_int32_t drm_read32(drm_local_map_t *, unsigned long);
+void   drm_write8(drm_local_map_t *, unsigned long, u_int8_t);
+void   drm_write16(drm_local_map_t *, unsigned long, u_int16_t);
+void   drm_write32(drm_local_map_t *, unsigned long, u_int32_t);
 
 /* Locking IOCTL support (drm_lock.c) */
 int    drm_lock_take(__volatile__ unsigned int *, unsigned int);
index c727da1..44714ca 100644 (file)
@@ -174,3 +174,86 @@ drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags)
        return 0;
 #endif
 }
+
+u_int8_t
+drm_read8(drm_local_map_t *map, unsigned long offset)
+{
+       u_int8_t *ptr;
+
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               return  (*ptr);
+               
+       default:
+               return (bus_space_read_1(map->bst, map->bsh, offset));
+       }
+}
+
+u_int16_t
+drm_read16(drm_local_map_t *map, unsigned long offset)
+{
+       u_int16_t *ptr;
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               return  (*ptr);
+       default:
+               return (bus_space_read_2(map->bst, map->bsh, offset));
+       }
+}
+
+u_int32_t
+drm_read32(drm_local_map_t *map, unsigned long offset)
+{
+       u_int32_t *ptr;
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               return  (*ptr);
+       default:
+               return (bus_space_read_4(map->bst, map->bsh, offset));
+       }
+}
+
+void
+drm_write8(drm_local_map_t *map, unsigned long offset, u_int8_t val)
+{
+       u_int8_t *ptr;
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               *ptr = val;
+               break;
+       default:
+               bus_space_write_1(map->bst, map->bsh, offset, val);
+       }
+}
+
+void
+drm_write16(drm_local_map_t *map, unsigned long offset, u_int16_t val)
+{
+       u_int16_t *ptr;
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               *ptr = val;
+               break;
+       default:
+               bus_space_write_2(map->bst, map->bsh, offset, val);
+       }
+}
+
+void
+drm_write32(drm_local_map_t *map, unsigned long offset, u_int32_t val)
+{
+       u_int32_t *ptr;
+       switch (map->type) {
+       case _DRM_SCATTER_GATHER:
+               ptr = map->handle + offset;
+               *ptr = val;
+               break;
+       default:
+               bus_space_write_4(map->bst, map->bsh, offset, val);
+       }
+}