Merge branch 'master' into cleanup
authorDave Airlie <airlied@linux.ie>
Wed, 11 Jul 2007 01:23:41 +0000 (11:23 +1000)
committerDave Airlie <airlied@linux.ie>
Wed, 11 Jul 2007 01:23:41 +0000 (11:23 +1000)
Conflicts:

libdrm/xf86drm.c
linux-core/drm_bo.c
linux-core/drm_fence.c

1  2 
libdrm/xf86drm.c
libdrm/xf86mm.h
linux-core/drm_bo.c
linux-core/drm_compat.c
linux-core/drm_drv.c
linux-core/drm_fence.c
linux-core/drm_objects.h
shared-core/i915_drv.h

diff --combined libdrm/xf86drm.c
@@@ -92,7 -92,7 +92,7 @@@ static drmServerInfoPtr drm_server_info
  
  void drmSetServerInfo(drmServerInfoPtr info)
  {
-   drm_server_info = info;
+     drm_server_info = info;
  }
  
  /**
  
  static int drmDebugPrint(const char *format, va_list ap)
  {
-   return vfprintf(stderr, format, ap);
+     return vfprintf(stderr, format, ap);
  }
  
  static int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
@@@ -131,26 -131,28 +131,28 @@@ drmMsg(const char *format, ...
  void
  drmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
  {
-   drm_debug_print = debug_msg_ptr;
+     drm_debug_print = debug_msg_ptr;
  }
  
  static void *drmHashTable = NULL; /* Context switch callbacks */
  
  void *drmGetHashTable(void)
  {
-   return drmHashTable;
+     return drmHashTable;
  }
  
  void *drmMalloc(int size)
  {
      void *pt;
-     if ((pt = malloc(size))) memset(pt, 0, size);
+     if ((pt = malloc(size)))
+       memset(pt, 0, size);
      return pt;
  }
  
  void drmFree(void *pt)
  {
-     if (pt) free(pt);
+     if (pt)
+       free(pt);
  }
  
  /* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
@@@ -186,7 -188,8 +188,8 @@@ drmHashEntry *drmGetEntry(int fd
      void          *value;
      drmHashEntry  *entry;
  
-     if (!drmHashTable) drmHashTable = drmHashCreate();
+     if (!drmHashTable)
+       drmHashTable = drmHashCreate();
  
      if (drmHashLookup(drmHashTable, key, &value)) {
        entry           = drmMalloc(sizeof(*entry));
@@@ -276,14 -279,15 +279,15 @@@ static int drmOpenDevice(long dev, int 
      drmMsg("drmOpenDevice: node name is %s\n", buf);
  
      if (drm_server_info) {
-       drm_server_info->get_perms(&serv_group, &serv_mode);
-       devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
-       devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
-       group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
+       drm_server_info->get_perms(&serv_group, &serv_mode);
+       devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
+       devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+       group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
      }
  
      if (stat(DRM_DIR_NAME, &st)) {
-       if (!isroot) return DRM_ERR_NOT_ROOT;
+       if (!isroot)
+           return DRM_ERR_NOT_ROOT;
        mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
        chown(DRM_DIR_NAME, 0, 0); /* root:root */
        chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
  
      /* Check if the device node exists and create it if necessary. */
      if (stat(buf, &st)) {
-       if (!isroot) return DRM_ERR_NOT_ROOT;
+       if (!isroot)
+           return DRM_ERR_NOT_ROOT;
        remove(buf);
        mknod(buf, S_IFCHR | devmode, dev);
      }
  
      if (drm_server_info) {
-       chown(buf, user, group);
-       chmod(buf, devmode);
+       chown(buf, user, group);
+       chmod(buf, devmode);
      }
  
      fd = open(buf, O_RDWR, 0);
      drmMsg("drmOpenDevice: open result is %d, (%s)\n",
                fd, fd < 0 ? strerror(errno) : "OK");
-     if (fd >= 0) return fd;
+     if (fd >= 0)
+       return fd;
  
      /* Check if the device node is not what we expect it to be, and recreate it
       * and try again if so.
       */
      if (st.st_rdev != dev) {
-       if (!isroot) return DRM_ERR_NOT_ROOT;
+       if (!isroot)
+           return DRM_ERR_NOT_ROOT;
        remove(buf);
        mknod(buf, S_IFCHR | devmode, dev);
        if (drm_server_info) {
-         chown(buf, user, group);
-         chmod(buf, devmode);
+           chown(buf, user, group);
+           chmod(buf, devmode);
        }
      }
      fd = open(buf, O_RDWR, 0);
      drmMsg("drmOpenDevice: open result is %d, (%s)\n",
                fd, fd < 0 ? strerror(errno) : "OK");
-     if (fd >= 0) return fd;
+     if (fd >= 0)
+       return fd;
  
      drmMsg("drmOpenDevice: Open failed\n");
      remove(buf);
@@@ -346,10 -354,12 +354,12 @@@ static int drmOpenMinor(int minor, int 
      int  fd;
      char buf[64];
      
-     if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
+     if (create)
+       return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
      
      sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
-     if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+     if ((fd = open(buf, O_RDWR, 0)) >= 0)
+       return fd;
      return -errno;
  }
  
@@@ -373,7 -383,8 +383,8 @@@ int drmAvailable(void
      if ((fd = drmOpenMinor(0, 1)) < 0) {
  #ifdef __linux__
        /* Try proc for backward Linux compatibility */
-       if (!access("/proc/dri/0", R_OK)) return 1;
+       if (!access("/proc/dri/0", R_OK))
+           return 1;
  #endif
        return 0;
      }
@@@ -424,7 -435,8 +435,8 @@@ static int drmOpenByBusid(const char *b
                drmFreeBusid(buf);
                return fd;
            }
-           if (buf) drmFreeBusid(buf);
+           if (buf)
+               drmFreeBusid(buf);
            close(fd);
        }
      }
@@@ -454,16 -466,16 +466,16 @@@ static int drmOpenByName(const char *na
      char *        id;
      
      if (!drmAvailable()) {
-       if (!drm_server_info)
-       return -1;
-       else {
-         /* try to load the kernel module now */
-         if (!drm_server_info->load_module(name)) {
-         drmMsg("[drm] failed to load kernel module \"%s\"\n",
-                name);
-         return -1;
-         }
-       }
+       if (!drm_server_info) {
+           return -1;
+       }
+       else {
+           /* try to load the kernel module now */
+           if (!drm_server_info->load_module(name)) {
+               drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
+               return -1;
+           }
+       }
      }
  
      /*
@@@ -548,16 -560,13 +560,13 @@@ int drmOpen(const char *name, const cha
      if (!drmAvailable() && name != NULL && drm_server_info) {
        /* try to load the kernel */
        if (!drm_server_info->load_module(name)) {
-         drmMsg("[drm] failed to load kernel module \"%s\"\n",
-                  name);
+           drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
            return -1;
        }
      }
  
      if (busid) {
-       int fd;
-       fd = drmOpenByBusid(busid);
+       int fd = drmOpenByBusid(busid);
        if (fd >= 0)
            return fd;
      }
   */
  void drmFreeVersion(drmVersionPtr v)
  {
-     if (!v) return;
+     if (!v)
+       return;
      drmFree(v->name);
      drmFree(v->date);
      drmFree(v->desc);
   */
  static void drmFreeKernelVersion(drm_version_t *v)
  {
-     if (!v) return;
+     if (!v)
+       return;
      drmFree(v->name);
      drmFree(v->date);
      drmFree(v->desc);
@@@ -756,9 -767,11 +767,11 @@@ char *drmGetBusid(int fd
      u.unique_len = 0;
      u.unique     = NULL;
  
-     if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+       return NULL;
      u.unique = drmMalloc(u.unique_len + 1);
-     if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
+       return NULL;
      u.unique[u.unique_len] = '\0';
  
      return u.unique;
@@@ -795,7 -808,8 +808,8 @@@ int drmGetMagic(int fd, drm_magic_t * m
      drm_auth_t auth;
  
      *magic = 0;
-     if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
+       return -errno;
      *magic = auth.magic;
      return 0;
  }
@@@ -805,7 -819,8 +819,8 @@@ int drmAuthMagic(int fd, drm_magic_t ma
      drm_auth_t auth;
  
      auth.magic = magic;
-     if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
+       return -errno;
      return 0;
  }
  
@@@ -869,8 -884,10 +884,10 @@@ int drmAddMap(int fd, drm_handle_t offs
      map.handle  = 0;
      map.type    = type;
      map.flags   = flags;
-     if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
-     if (handle) *handle = (drm_handle_t)map.handle;
+     if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map))
+       return -errno;
+     if (handle)
+       *handle = (drm_handle_t)map.handle;
      return 0;
  }
  
@@@ -880,7 -897,8 +897,8 @@@ int drmRmMap(int fd, drm_handle_t handl
  
      map.handle = (void *)handle;
  
-     if(ioctl(fd, DRM_IOCTL_RM_MAP, &map)) return -errno;
+     if(ioctl(fd, DRM_IOCTL_RM_MAP, &map))
+       return -errno;
      return 0;
  }
  
@@@ -912,7 -930,8 +930,8 @@@ int drmAddBufs(int fd, int count, int s
      request.flags     = flags;
      request.agp_start = agp_offset;
  
-     if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request))
+       return -errno;
      return request.count;
  }
  
@@@ -924,9 -943,11 +943,11 @@@ int drmMarkBufs(int fd, double low, dou
      info.count = 0;
      info.list  = NULL;
  
-     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
+     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info))
+       return -EINVAL;
  
-     if (!info.count) return -EINVAL;
+     if (!info.count)
+       return -EINVAL;
  
      if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
        return -ENOMEM;
@@@ -972,7 -993,8 +993,8 @@@ int drmFreeBufs(int fd, int count, int 
  
      request.count = count;
      request.list  = list;
-     if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request))
+       return -errno;
      return 0;
  }
  
@@@ -1020,7 -1042,8 +1042,8 @@@ int drmMap(int fd, drm_handle_t handle
  {
      static unsigned long pagesize_mask = 0;
  
-     if (fd < 0) return -EINVAL;
+     if (fd < 0)
+       return -EINVAL;
  
      if (!pagesize_mask)
        pagesize_mask = getpagesize() - 1;
      size = (size + pagesize_mask) & ~pagesize_mask;
  
      *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
-     if (*address == MAP_FAILED) return -errno;
+     if (*address == MAP_FAILED)
+       return -errno;
      return 0;
  }
  
@@@ -1058,7 -1082,8 +1082,8 @@@ drmBufInfoPtr drmGetBufInfo(int fd
      info.count = 0;
      info.list  = NULL;
  
-     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info))
+       return NULL;
  
      if (info.count) {
        if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
@@@ -1108,9 -1133,11 +1133,11 @@@ drmBufMapPtr drmMapBufs(int fd
      bufs.count = 0;
      bufs.list  = NULL;
      bufs.virtual = NULL;
-     if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
+       return NULL;
  
-     if (!bufs.count) return NULL;
+     if (!bufs.count)
+       return NULL;
  
        if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
            return NULL;
@@@ -1265,20 -1292,25 +1292,25 @@@ drm_context_t *drmGetReservedContextLis
  
      res.count    = 0;
      res.contexts = NULL;
-     if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_RES_CTX, &res))
+       return NULL;
  
-     if (!res.count) return NULL;
+     if (!res.count)
+       return NULL;
  
-     if (!(list   = drmMalloc(res.count * sizeof(*list)))) return NULL;
+     if (!(list   = drmMalloc(res.count * sizeof(*list))))
+       return NULL;
      if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
        drmFree(list);
        return NULL;
      }
  
      res.contexts = list;
-     if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+     if (ioctl(fd, DRM_IOCTL_RES_CTX, &res))
+       return NULL;
  
-     for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
+     for (i = 0; i < res.count; i++)
+       retval[i] = list[i].handle;
      drmFree(list);
  
      *count = res.count;
@@@ -1313,7 -1345,8 +1345,8 @@@ int drmCreateContext(int fd, drm_contex
      drm_ctx_t ctx;
  
      ctx.flags = 0;    /* Modified with functions below */
-     if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
+       return -errno;
      *handle = ctx.handle;
      return 0;
  }
@@@ -1323,7 -1356,8 +1356,8 @@@ int drmSwitchToContext(int fd, drm_cont
      drm_ctx_t ctx;
  
      ctx.handle = context;
-     if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
+       return -errno;
      return 0;
  }
  
@@@ -1339,9 -1373,12 +1373,12 @@@ int drmSetContextFlags(int fd, drm_cont
       */
      ctx.handle = context;
      ctx.flags  = 0;
-     if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
-     if (flags & DRM_CONTEXT_2DONLY)    ctx.flags |= _DRM_CONTEXT_2DONLY;
-     if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
+     if (flags & DRM_CONTEXT_PRESERVED)
+       ctx.flags |= _DRM_CONTEXT_PRESERVED;
+     if (flags & DRM_CONTEXT_2DONLY)
+       ctx.flags |= _DRM_CONTEXT_2DONLY;
+     if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
+       return -errno;
      return 0;
  }
  
@@@ -1351,10 -1388,13 +1388,13 @@@ int drmGetContextFlags(int fd, drm_cont
      drm_ctx_t ctx;
  
      ctx.handle = context;
-     if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx))
+       return -errno;
      *flags = 0;
-     if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
-     if (ctx.flags & _DRM_CONTEXT_2DONLY)    *flags |= DRM_CONTEXT_2DONLY;
+     if (ctx.flags & _DRM_CONTEXT_PRESERVED)
+       *flags |= DRM_CONTEXT_PRESERVED;
+     if (ctx.flags & _DRM_CONTEXT_2DONLY)
+       *flags |= DRM_CONTEXT_2DONLY;
      return 0;
  }
  
@@@ -1379,14 -1419,16 +1419,16 @@@ int drmDestroyContext(int fd, drm_conte
  {
      drm_ctx_t ctx;
      ctx.handle = handle;
-     if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx))
+       return -errno;
      return 0;
  }
  
  int drmCreateDrawable(int fd, drm_drawable_t *handle)
  {
      drm_draw_t draw;
-     if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
+       return -errno;
      *handle = draw.handle;
      return 0;
  }
@@@ -1395,7 -1437,8 +1437,8 @@@ int drmDestroyDrawable(int fd, drm_draw
  {
      drm_draw_t draw;
      draw.handle = handle;
-     if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw))
+       return -errno;
      return 0;
  }
  
@@@ -1410,7 -1453,8 +1453,8 @@@ int drmUpdateDrawableInfo(int fd, drm_d
      update.num = num;
      update.data = (unsigned long long)(unsigned long)data;
  
-     if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
+       return -errno;
  
      return 0;
  }
   */
  int drmAgpAcquire(int fd)
  {
-     if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
+       return -errno;
      return 0;
  }
  
   */
  int drmAgpRelease(int fd)
  {
-     if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
+       return -errno;
      return 0;
  }
  
@@@ -1468,7 -1514,8 +1514,8 @@@ int drmAgpEnable(int fd, unsigned long 
      drm_agp_mode_t m;
  
      m.mode = mode;
-     if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
+       return -errno;
      return 0;
  }
  
@@@ -1498,8 -1545,10 +1545,10 @@@ int drmAgpAlloc(int fd, unsigned long s
      b.size   = size;
      b.handle = 0;
      b.type   = type;
-     if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
-     if (address != 0UL) *address = b.physical;
+     if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
+       return -errno;
+     if (address != 0UL)
+       *address = b.physical;
      *handle = b.handle;
      return 0;
  }
@@@ -1523,7 -1572,8 +1572,8 @@@ int drmAgpFree(int fd, drm_handle_t han
  
      b.size   = 0;
      b.handle = handle;
-     if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b))
+       return -errno;
      return 0;
  }
  
@@@ -1547,7 -1597,8 +1597,8 @@@ int drmAgpBind(int fd, drm_handle_t han
  
      b.handle = handle;
      b.offset = offset;
-     if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b))
+       return -errno;
      return 0;
  }
  
@@@ -1570,7 -1621,8 +1621,8 @@@ int drmAgpUnbind(int fd, drm_handle_t h
  
      b.handle = handle;
      b.offset = 0;
-     if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
+       return -errno;
      return 0;
  }
  
@@@ -1590,7 -1642,8 +1642,8 @@@ int drmAgpVersionMajor(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return -errno;
      return i.agp_version_major;
  }
  
@@@ -1610,7 -1663,8 +1663,8 @@@ int drmAgpVersionMinor(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return -errno;
      return i.agp_version_minor;
  }
  
@@@ -1630,7 -1684,8 +1684,8 @@@ unsigned long drmAgpGetMode(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.mode;
  }
  
@@@ -1650,7 -1705,8 +1705,8 @@@ unsigned long drmAgpBase(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.aperture_base;
  }
  
@@@ -1670,7 -1726,8 +1726,8 @@@ unsigned long drmAgpSize(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.aperture_size;
  }
  
@@@ -1690,7 -1747,8 +1747,8 @@@ unsigned long drmAgpMemoryUsed(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.memory_used;
  }
  
@@@ -1710,7 -1768,8 +1768,8 @@@ unsigned long drmAgpMemoryAvail(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.memory_allowed;
  }
  
@@@ -1730,7 -1789,8 +1789,8 @@@ unsigned int drmAgpVendorId(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.id_vendor;
  }
  
@@@ -1750,7 -1810,8 +1810,8 @@@ unsigned int drmAgpDeviceId(int fd
  {
      drm_agp_info_t i;
  
-     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
+     if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i))
+       return 0;
      return i.id_device;
  }
  
@@@ -1761,7 -1822,8 +1822,8 @@@ int drmScatterGatherAlloc(int fd, unsig
      *handle = 0;
      sg.size   = size;
      sg.handle = 0;
-     if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
+       return -errno;
      *handle = sg.handle;
      return 0;
  }
@@@ -1772,7 -1834,8 +1834,8 @@@ int drmScatterGatherFree(int fd, drm_ha
  
      sg.size   = 0;
      sg.handle = handle;
-     if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg))
+       return -errno;
      return 0;
  }
  
@@@ -1802,12 -1865,21 +1865,21 @@@ int drmWaitVBlank(int fd, drmVBlankPtr 
  int drmError(int err, const char *label)
  {
      switch (err) {
-     case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label);   break;
-     case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label);   break;
-     case DRM_ERR_NOT_ROOT:  fprintf(stderr, "%s: not root\n", label);    break;
-     case DRM_ERR_INVALID:   fprintf(stderr, "%s: invalid args\n", label);break;
+     case DRM_ERR_NO_DEVICE:
+       fprintf(stderr, "%s: no device\n", label);
+       break;
+     case DRM_ERR_NO_ACCESS:
+       fprintf(stderr, "%s: no access\n", label);
+       break;
+     case DRM_ERR_NOT_ROOT:
+       fprintf(stderr, "%s: not root\n", label);
+       break;
+     case DRM_ERR_INVALID:
+       fprintf(stderr, "%s: invalid args\n", label);
+       break;
      default:
-       if (err < 0) err = -err;
+       if (err < 0)
+           err = -err;
        fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
        break;
      }
@@@ -1833,7 -1905,8 +1905,8 @@@ int drmCtlInstHandler(int fd, int irq
  
      ctl.func  = DRM_INST_HANDLER;
      ctl.irq   = irq;
-     if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl))
+       return -errno;
      return 0;
  }
  
@@@ -1855,7 -1928,8 +1928,8 @@@ int drmCtlUninstHandler(int fd
  
      ctl.func  = DRM_UNINST_HANDLER;
      ctl.irq   = 0;
-     if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl))
+       return -errno;
      return 0;
  }
  
@@@ -1871,7 -1945,8 +1945,8 @@@ int drmFinish(int fd, int context, drmL
      if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
      if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
      if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
-     if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_FINISH, &lock))
+       return -errno;
      return 0;
  }
  
@@@ -1896,7 -1971,8 +1971,8 @@@ int drmGetInterruptFromBusID(int fd, in
      p.busnum  = busnum;
      p.devnum  = devnum;
      p.funcnum = funcnum;
-     if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
+       return -errno;
      return p.irq;
  }
  
@@@ -1923,7 -1999,8 +1999,8 @@@ void *drmGetContextTag(int fd, drm_cont
      drmHashEntry  *entry = drmGetEntry(fd);
      void          *value;
  
-     if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
+     if (drmHashLookup(entry->tagTable, context, &value))
+       return NULL;
  
      return value;
  }
@@@ -1936,7 -2013,8 +2013,8 @@@ int drmAddContextPrivateMapping(int fd
      map.ctx_id = ctx_id;
      map.handle = (void *)handle;
  
-     if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
+       return -errno;
      return 0;
  }
  
@@@ -1947,8 -2025,10 +2025,10 @@@ int drmGetContextPrivateMapping(int fd
  
      map.ctx_id = ctx_id;
  
-     if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) return -errno;
-     if (handle) *handle = (drm_handle_t)map.handle;
+     if (ioctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
+       return -errno;
+     if (handle)
+       *handle = (drm_handle_t)map.handle;
  
      return 0;
  }
@@@ -1960,7 -2040,8 +2040,8 @@@ int drmGetMap(int fd, int idx, drm_hand
      drm_map_t map;
  
      map.offset = idx;
-     if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_GET_MAP, &map))
+       return -errno;
      *offset = map.offset;
      *size   = map.size;
      *type   = map.type;
@@@ -1976,7 -2057,8 +2057,8 @@@ int drmGetClient(int fd, int idx, int *
      drm_client_t client;
  
      client.idx = idx;
-     if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client))
+       return -errno;
      *auth      = client.auth;
      *pid       = client.pid;
      *uid       = client.uid;
@@@ -1990,7 -2072,8 +2072,8 @@@ int drmGetStats(int fd, drmStatsT *stat
      drm_stats_t s;
      int         i;
  
-     if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+     if (ioctl(fd, DRM_IOCTL_GET_STATS, &s))
+       return -errno;
  
      stats->count = 0;
      memset(stats, 0, sizeof(*stats));
@@@ -2272,7 -2355,8 +2355,7 @@@ int drmFenceCreate(int fd, unsigned fla
      arg.flags = flags;
      arg.type = type;
      arg.class = class;
 -    arg.op = drm_fence_create;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +    if (ioctl(fd, DRM_IOCTL_FENCE_CREATE, &arg))
        return -errno;
      fence->handle = arg.handle;
      fence->class = arg.class;
  int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
  {
      drm_fence_arg_t arg;
-     
      memset(&arg, 0, sizeof(arg));
      arg.flags = flags;
 -    arg.op = drm_fence_buffers;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_BUFFERS, &arg))
        return -errno;
      fence->handle = arg.handle;
      fence->class = arg.class;
  int drmFenceDestroy(int fd, const drmFence *fence)
  {
      drm_fence_arg_t arg;
-    
      memset(&arg, 0, sizeof(arg));
      arg.handle = fence->handle;
 -    arg.op = drm_fence_destroy;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_DESTROY, &arg))
        return -errno;
      return 0;
  }
  int drmFenceReference(int fd, unsigned handle, drmFence *fence)
  {
      drm_fence_arg_t arg;
-    
      memset(&arg, 0, sizeof(arg));
      arg.handle = handle;
 -    arg.op = drm_fence_reference;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_REFERENCE, &arg))
        return -errno;
      fence->handle = arg.handle;
      fence->class = arg.class;
  int drmFenceUnreference(int fd, const drmFence *fence)
  {
      drm_fence_arg_t arg;
-    
      memset(&arg, 0, sizeof(arg));
      arg.handle = fence->handle;
 -    arg.op = drm_fence_unreference;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_UNREFERENCE, &arg))
        return -errno;
      return 0;
  }
  int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
  {
      drm_fence_arg_t arg;
-    
      memset(&arg, 0, sizeof(arg));
      arg.handle = fence->handle;
      arg.type = flush_type;
 -    arg.op = drm_fence_flush;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_FLUSH, &arg))
        return -errno;
      fence->class = arg.class;
      fence->type = arg.type;
  
  int drmFenceUpdate(int fd, drmFence *fence)
  {
-       drm_fence_arg_t arg;
-       
+     drm_fence_arg_t arg;
      memset(&arg, 0, sizeof(arg));
      arg.handle = fence->handle;
 -    arg.op = drm_fence_signaled;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_SIGNALED, &arg))
        return -errno;
      fence->class = arg.class;
      fence->type = arg.type;
  int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType, 
                     int *signaled)
  {
-     int 
-       ret;
      if ((fence->flags & DRM_FENCE_FLAG_SHAREABLE) ||
        ((fenceType & fence->signaled) != fenceType)) {
-       ret = drmFenceFlush(fd, fence, fenceType);
+       int ret = drmFenceFlush(fd, fence, fenceType);
        if (ret)
            return ret;
      }
@@@ -2412,8 -2492,8 +2491,8 @@@ int drmFenceEmit(int fd, unsigned flags
      arg.flags = flags;
      arg.handle = fence->handle;
      arg.type = emit_type;
 -    arg.op = drm_fence_emit;
 -    if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
 +
 +    if (ioctl(fd, DRM_IOCTL_FENCE_EMIT, &arg))
        return -errno;
      fence->class = arg.class;
      fence->type = arg.type;
@@@ -2446,9 -2526,9 +2525,9 @@@ int drmFenceWait(int fd, unsigned flags
      arg.handle = fence->handle;
      arg.type = flush_type;
      arg.flags = flags;
 -    arg.op = drm_fence_wait;
 +
      do {
 -      ret = ioctl(fd, DRM_IOCTL_FENCE, &arg);
 +      ret = ioctl(fd, DRM_IOCTL_FENCE_WAIT, &arg);
      } while (ret != 0 && errno == EAGAIN);
  
      if (ret)
@@@ -2513,8 -2593,8 +2592,8 @@@ void drmBOFreeList(drmBOList *list
      }
  }
        
- int drmBOResetList(drmBOList *list) {
+ int drmBOResetList(drmBOList *list)
+ {
      drmMMListHead *l;
      int ret;
  
        return ret;
  
      l = list->list.next;
-     while(l != &list->list) {
+     while (l != &list->list) {
        DRMLISTDEL(l);
        DRMLISTADD(l, &list->free);
        list->numOnList--;
@@@ -2546,7 -2626,8 +2625,8 @@@ static drmBONode *drmAddListItem(drmBOL
            return NULL;
        }
        list->numCurrent++;
-     } else {
+     }
+     else {
        DRMLISTDEL(l);
        node = DRMLISTENTRY(drmBONode, l, head);
      }
@@@ -2583,7 -2664,6 +2663,6 @@@ drmBO *drmBOListBuf(void *iterator
      drmBONode *node;
      drmMMListHead *l = (drmMMListHead *) iterator;
      node = DRMLISTENTRY(drmBONode, l, head);
-     
      return node->buf;
  }
  
@@@ -2598,8 -2678,7 +2677,7 @@@ int drmBOCreateList(int numTarget, drmB
      return drmAdjustListNodes(list);
  }
  
- static void drmBOCopyReply(struct drm_bo_info_rep *rep, 
-                          drmBO *buf)
 -static void drmBOCopyReply(const drm_bo_arg_reply_t *rep, drmBO *buf)
++static void drmBOCopyReply(const struct drm_bo_info_rep *rep, drmBO *buf)
  {
      buf->handle = rep->handle;
      buf->flags = rep->flags;
      buf->fenceFlags = rep->fence_flags;
      buf->replyFlags = rep->rep_flags;
      buf->pageAlignment = rep->page_alignment;
 +    buf->tileInfo = rep->tile_info;
 +    buf->hwTileStride = rep->hw_tile_stride;
 +    buf->desiredTileStride = rep->desired_tile_stride;
  }
  
 -int drmBOCreate(int fd, unsigned long start, unsigned long size, 
 -              unsigned pageAlignment, void *user_buffer, drm_bo_type_t type, 
 -              unsigned mask,
 +
 +
 +int drmBOCreate(int fd, unsigned long start, unsigned long size,
 +              unsigned pageAlignment, void *user_buffer, drm_bo_type_t type,
 +              drm_u64_t mask,
                unsigned hint, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_create_arg arg;
 +    struct drm_bo_create_req *req = &arg.d.req;
 +    struct drm_bo_info_rep *rep = &arg.d.rep;
      int ret;
  
      memset(buf, 0, sizeof(*buf));
      default:
        return -EINVAL;
      }
 -    req->op = drm_bo_create;
  
      do {
 -      ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
 +      ret = ioctl(fd, DRM_IOCTL_BO_CREATE, &arg);
      } while (ret != 0 && errno == EAGAIN);
  
      if (ret)
        return -errno;
 -    if (!arg.handled) {
 -      return -EFAULT;
 -    }
 -    if (rep->ret) {
 -        fprintf(stderr, "Error %d\n", rep->ret);
 -      return rep->ret;
 -    }
      
      drmBOCopyReply(rep, buf);
      buf->mapVirtual = NULL;
  
  int drmBODestroy(int fd, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_handle_arg arg;
      
      if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
        (void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
      }
  
      memset(&arg, 0, sizeof(arg));
 -    req->handle = buf->handle;
 -    req->op = drm_bo_destroy;
 +    arg.handle = buf->handle;
  
 -    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
 +    if (ioctl(fd, DRM_IOCTL_BO_DESTROY, &arg))
        return -errno;
 -    if (!arg.handled) {
 -      return -EFAULT;
 -    }
 -    if (rep->ret) {
 -      return rep->ret;
 -    }
  
      buf->handle = 0;
      return 0;
  }
 - 
 +
  int drmBOReference(int fd, unsigned handle, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_reference_info_arg arg;
 +    struct drm_bo_handle_arg *req = &arg.d.req;
 +    struct drm_bo_info_rep *rep = &arg.d.rep;
      
      memset(&arg, 0, sizeof(arg));
      req->handle = handle;
 -    req->op = drm_bo_reference;
      
 -    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
 +    if (ioctl(fd, DRM_IOCTL_BO_REFERENCE, &arg))
        return -errno;
 -    if (!arg.handled) {
 -      return -EFAULT;
 -    }
 -    if (rep->ret) {
 -      return rep->ret;
 -    }
  
      drmBOCopyReply(rep, buf);
      buf->type = drm_bo_type_dc;
  
  int drmBOUnReference(int fd, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_handle_arg arg;
  
      if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
        (void) munmap(buf->mapVirtual, buf->start + buf->size);
      }
  
      memset(&arg, 0, sizeof(arg));
 -    req->handle = buf->handle;
 -    req->op = drm_bo_unreference;
 +    arg.handle = buf->handle;
  
 -    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
 +    if (ioctl(fd, DRM_IOCTL_BO_UNREFERENCE, &arg))
        return -errno;
 -    if (!arg.handled) {
 -      return -EFAULT;
 -    }
 -    if (rep->ret) {
 -      return rep->ret;
 -    }
  
      buf->handle = 0;
      return 0;
  }   
  
 +
  /*
   * Flags can be  DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
   * Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
  int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
             void **address)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_map_wait_idle_arg arg;
 +    struct drm_bo_info_req *req = &arg.d.req;
 +    struct drm_bo_info_rep *rep = &arg.d.rep;
      int ret = 0;
  
      /*
      req->handle = buf->handle;
      req->mask = mapFlags;
      req->hint = mapHint;
 -    req->op = drm_bo_map;
  
      /*
       * May hang if the buffer object is busy.
       */
      
      do {
 -      ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
 +      ret = ioctl(fd, DRM_IOCTL_BO_MAP, &arg);
      } while (ret != 0 && errno == EAGAIN);
  
      if (ret) 
        return -errno;
 -    if (!arg.handled) 
 -      return -EFAULT;
 -    if (rep->ret)
 -      return rep->ret;
  
      drmBOCopyReply(rep, buf); 
      buf->mapFlags = mapFlags;
      return 0;
  }
  
 +
  int drmBOUnmap(int fd, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_handle_arg arg;
-       
      memset(&arg, 0, sizeof(arg));
 -    req->handle = buf->handle;
 -    req->op = drm_bo_unmap;
 +    arg.handle = buf->handle;
  
 -    if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
 +    if (ioctl(fd, DRM_IOCTL_BO_UNMAP, &arg)) {
        return -errno;
      }
 -    if (!arg.handled) 
 -        return -EFAULT;
 -    if (rep->ret)
 -      return rep->ret;
 -
      return 0;
  }
 -    
 -int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, 
 +
 +int drmBOValidate(int fd, drmBO *buf,
 +                drm_u64_t flags, drm_u64_t mask,
                  unsigned hint)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_op_arg arg;
 +    struct drm_bo_op_req *req = &arg.d.req;
 +    struct drm_bo_arg_rep *rep = &arg.d.rep;
      int ret = 0;
  
      memset(&arg, 0, sizeof(arg));
 -    req->handle = buf->handle;
 -    req->mask = flags;
 -    req->hint = hint;
 -    req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
 +    req->bo_req.handle = buf->handle;
 +    req->bo_req.flags = flags;
 +    req->bo_req.mask = mask;
 +    req->bo_req.hint = hint;
 +    req->bo_req.fence_class = 0; /* Backwards compatibility. */
      req->op = drm_bo_validate;
  
      do{
 -      ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
 +      ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
      } while (ret && errno == EAGAIN);
-     
      if (ret) 
        return -errno;
      if (!arg.handled)
      if (rep->ret)
        return rep->ret;
  
 -    drmBOCopyReply(rep, buf);
 +    drmBOCopyReply(&rep->bo_info, buf);
      return 0;
  }
            
  
  int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_op_arg arg;
 +    struct drm_bo_op_req *req = &arg.d.req;
 +    struct drm_bo_arg_rep *rep = &arg.d.rep;
      int ret = 0;
  
      memset(&arg, 0, sizeof(arg));
 -    req->handle = buf->handle;
 -    req->mask = flags;
 +    req->bo_req.handle = buf->handle;
 +    req->bo_req.flags = flags;
      req->arg_handle = fenceHandle;
      req->op = drm_bo_fence;
  
 -    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
 -
 +    ret = ioctl(fd, DRM_IOCTL_BO_OP, &arg);
-     
      if (ret) 
        return -errno;
      if (!arg.handled)
  
  int drmBOInfo(int fd, drmBO *buf)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_reference_info_arg arg;
 +    struct drm_bo_handle_arg *req = &arg.d.req;
 +    struct drm_bo_info_rep *rep = &arg.d.rep;
      int ret = 0;
  
      memset(&arg, 0, sizeof(arg));
      req->handle = buf->handle;
 -    req->op = drm_bo_info;
 -
 -    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
  
-     
 +    ret = ioctl(fd, DRM_IOCTL_BO_INFO, &arg);
      if (ret) 
        return -errno;
 -    if (!arg.handled)
 -      return -EFAULT;
 -    if (rep->ret)
 -      return rep->ret;
 +
      drmBOCopyReply(rep, buf);
      return 0;
  }
  
  int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
  {
 -    drm_bo_arg_t arg;
 -    drm_bo_arg_request_t *req = &arg.d.req;
 -    drm_bo_arg_reply_t *rep = &arg.d.rep;
 +    struct drm_bo_map_wait_idle_arg arg;
 +    struct drm_bo_info_req *req = &arg.d.req;
 +    struct drm_bo_info_rep *rep = &arg.d.rep;
      int ret = 0;
  
      if ((buf->flags & DRM_BO_FLAG_SHAREABLE) ||
        (buf->replyFlags & DRM_BO_REP_BUSY)) {
          memset(&arg, 0, sizeof(arg));
        req->handle = buf->handle;
 -      req->op = drm_bo_wait_idle;
        req->hint = hint;
  
        do {
 -          ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
 +          ret = ioctl(fd, DRM_IOCTL_BO_WAIT_IDLE, &arg);
        } while (ret && errno == EAGAIN);
  
        if (ret) 
            return -errno;
 -      if (!arg.handled)
 -          return -EFAULT;
 -      if (rep->ret)
 -          return rep->ret;
 +
        drmBOCopyReply(rep, buf);
      }
      return 0;
@@@ -2909,7 -3031,8 +2983,8 @@@ int drmBOBusy(int fd, drmBO *buf, int *
        !(buf->replyFlags & DRM_BO_REP_BUSY)) {
        *busy = 0;
        return 0;
-     } else {
+     }
+     else {
        int ret = drmBOInfo(fd, buf);
        if (ret)
            return ret;
      }
  }
      
 -    
  int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 
                       unsigned mask,
                       int *newItem)
        *newItem = 1;
        cur->arg0 = flags;
        cur->arg1 = mask;
-     } else {
+     }
+     else {
        unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
        unsigned memFlags = cur->arg0 & flags & memMask;
        
  
  int drmBOValidateList(int fd, drmBOList *list)
  {
-    
-   drmBONode *node;
-   drmMMListHead *l;
-   struct drm_bo_op_arg *arg, *first;
-   struct drm_bo_op_req *req;
-   struct drm_bo_arg_rep *rep;
-   drm_u64_t *prevNext = NULL;
-   drmBO *buf;
-   int ret;
+     drmBONode *node;
+     drmMMListHead *l;
 -    drm_bo_arg_t *arg, *first;
 -    drm_bo_arg_request_t *req;
 -    drm_bo_arg_reply_t *rep;
++    struct drm_bo_op_arg *arg, *first;
++    struct drm_bo_op_req *req;
++    struct drm_bo_arg_rep *rep;
+     drm_u64_t *prevNext = NULL;
+     drmBO *buf;
+     int ret;
  
-   first = NULL;
+     first = NULL;
  
-   for (l = list->list.next; l != &list->list; l = l->next) {
-       node = DRMLISTENTRY(drmBONode, l, head);
+     for (l = list->list.next; l != &list->list; l = l->next) {
 -      node = DRMLISTENTRY(drmBONode, l, head);
++        node = DRMLISTENTRY(drmBONode, l, head);
  
-       arg = &node->bo_arg;
-       req = &arg->d.req;
 -      arg = &node->bo_arg;
 -      req = &arg->d.req;
++        arg = &node->bo_arg;
++        req = &arg->d.req;
  
-       if (!first)
-         first = arg;
 -      if (!first)
 -          first = arg;
++        if (!first)
++            first = arg;
  
-       if (prevNext)
-         *prevNext = (unsigned long) arg;
+       if (prevNext)
+           *prevNext = (unsigned long) arg;
  
-       memset(arg, 0, sizeof(*arg));
-       prevNext = &arg->next;
-       req->bo_req.handle = node->buf->handle;
-       req->op = drm_bo_validate;
-       req->bo_req.flags = node->arg0;
-       req->bo_req.hint = 0;
-       req->bo_req.mask = node->arg1;
-       req->bo_req.fence_class = 0; /* Backwards compat. */
-   }
+       memset(arg, 0, sizeof(*arg));
+       prevNext = &arg->next;
 -      req->handle = node->buf->handle;
++      req->bo_req.handle = node->buf->handle;
+       req->op = drm_bo_validate;
 -      req->mask = node->arg0;
 -      req->hint = 0;
 -      req->arg_handle = node->arg1;
++      req->bo_req.flags = node->arg0;
++      req->bo_req.hint = 0;
++      req->bo_req.mask = node->arg1;
++      req->bo_req.fence_class = 0; /* Backwards compat. */
+     }
 -  
 -    if (!first) 
 +
-   if (!first)
-       return 0;
++    if (!first)
+       return 0;
  
-   do{
-       ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
-   } while (ret && errno == EAGAIN);
 -    do {
 -      ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
++    do{
++      ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
+     } while (ret && errno == EAGAIN);
  
 -  
+     if (ret)
+       return -errno;
-   if (ret)
-       return -errno;
-   
-   for (l = list->list.next; l != &list->list; l = l->next) {
-       node = DRMLISTENTRY(drmBONode, l, head);
-       arg = &node->bo_arg;
-       rep = &arg->d.rep;
 +
 -
+     for (l = list->list.next; l != &list->list; l = l->next) {
+       node = DRMLISTENTRY(drmBONode, l, head);
+       arg = &node->bo_arg;
+       rep = &arg->d.rep;
-       if (!arg->handled) {
-         drmMsg("Unhandled request\n");
-         return -EFAULT;
-       }
-       if (rep->ret)
-         return rep->ret;
-       buf = node->buf;
-       drmBOCopyReply(&rep->bo_info, buf);
-   }
-   return 0;
 +      
 -
+       if (!arg->handled) {
+           drmMsg("Unhandled request\n");
+           return -EFAULT;
+       }
+       if (rep->ret)
+           return rep->ret;
 -      drmBOCopyReply(rep, buf);
++      
+       buf = node->buf;
 -
++      drmBOCopyReply(&rep->bo_info, buf);
+     }
++    
+     return 0;
  }
          
--
  int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
  {
-    
-   drmBONode *node;
-   drmMMListHead *l;
-   struct drm_bo_op_arg *arg, *first;
-   struct drm_bo_op_req *req;
-   struct drm_bo_arg_rep *rep;
-   drm_u64_t *prevNext = NULL;
-   drmBO *buf;
-   unsigned fence_flags;
-   int ret;
-   first = NULL;
-   for (l = list->list.next; l != &list->list; l = l->next) {
-       node = DRMLISTENTRY(drmBONode, l, head);
-       arg = &node->bo_arg;
-       req = &arg->d.req;
-       if (!first)
-         first = arg;
-       if (prevNext)
-         *prevNext = (unsigned long) arg;
-       memset(arg, 0, sizeof(*arg));
-       prevNext = &arg->next;
-       req->bo_req.handle = node->buf->handle;
-       req->op = drm_bo_fence;
-       req->bo_req.mask = node->arg0;
-       req->arg_handle = fenceHandle;
-   }
+     drmBONode *node;
+     drmMMListHead *l;
 -    drm_bo_arg_t *arg, *first;
 -    drm_bo_arg_request_t *req;
 -    drm_bo_arg_reply_t *rep;
++    struct drm_bo_op_arg *arg, *first;
++    struct drm_bo_op_req *req;
++    struct drm_bo_arg_rep *rep;
+     drm_u64_t *prevNext = NULL;
+     drmBO *buf;
+     unsigned fence_flags;
+     int ret;
+     first = NULL;
+     for (l = list->list.next; l != &list->list; l = l->next) {
 -      node = DRMLISTENTRY(drmBONode, l, head);
 -
++        node = DRMLISTENTRY(drmBONode, l, head);
++      
+       arg = &node->bo_arg;
+       req = &arg->d.req;
+       if (!first)
+           first = arg;
+       if (prevNext)
+           *prevNext = (unsigned long) arg;
+       memset(arg, 0, sizeof(*arg));
+       prevNext = &arg->next;
 -      req->handle = node->buf->handle;
++      req->bo_req.handle = node->buf->handle;
+       req->op = drm_bo_fence;
 -      req->mask = node->arg0;
++      req->bo_req.mask = node->arg0;
+       req->arg_handle = fenceHandle;
+     }
    
-   if (!first) 
-       return 0;
+     if (!first) 
+       return 0;
  
-   ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
 -    ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
++    ret = ioctl(fd, DRM_IOCTL_BO_OP, first);
  
-   if (ret)
-       return -errno;
+     if (ret)
+       return -errno;
    
-   for (l = list->list.next; l != &list->list; l = l->next) {
-       node = DRMLISTENTRY(drmBONode, l, head);
+     for (l = list->list.next; l != &list->list; l = l->next) {
+       node = DRMLISTENTRY(drmBONode, l, head);
 +
-       arg = &node->bo_arg;
-       rep = &arg->d.rep;
-       
-       if (!arg->handled)
-         return -EFAULT;
-       if (rep->ret)
-         return rep->ret;
-       drmBOCopyReply(&rep->bo_info, node->buf);
-   }
+       arg = &node->bo_arg;
+       rep = &arg->d.rep;
++
+               if (!arg->handled)
+           return -EFAULT;
+       if (rep->ret)
+           return rep->ret;
 -      drmBOCopyReply(rep, node->buf);
++      drmBOCopyReply(&rep->bo_info, node->buf);
+     }
  
-   return 0;
+     return 0;
  }
  
  int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
              unsigned memType)
  {
 -    drm_mm_init_arg_t arg;
 +    struct drm_mm_init_arg arg;
-     
      memset(&arg, 0, sizeof(arg));
 -    arg.req.op = mm_init;
 -    arg.req.p_offset = pOffset;
 -    arg.req.p_size = pSize;
 -    arg.req.mem_type = memType;
 +
 +    arg.magic = DRM_BO_INIT_MAGIC;
 +    arg.major = DRM_BO_INIT_MAJOR;
 +    arg.minor = DRM_BO_INIT_MINOR;
 +    arg.p_offset = pOffset;
 +    arg.p_size = pSize;
 +    arg.mem_type = memType;
  
      if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
        return -errno;
-     
      return 0; 
  }
  
  int drmMMTakedown(int fd, unsigned memType)
  {
 -    drm_mm_init_arg_t arg;
 +    struct drm_mm_type_arg arg;
  
      memset(&arg, 0, sizeof(arg));
 -    arg.req.op = mm_takedown;
 -    arg.req.mem_type = memType;
 +    arg.mem_type = memType;
  
 -    if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
 +    if (ioctl(fd, DRM_IOCTL_MM_TAKEDOWN, &arg))
        return -errno;
-     
      return 0; 
  }
  
  int drmMMLock(int fd, unsigned memType)
  {
 -    drm_mm_init_arg_t arg;
 +    struct drm_mm_type_arg arg;
      int ret;
  
      memset(&arg, 0, sizeof(arg));
 -    arg.req.op = mm_lock;
 -    arg.req.mem_type = memType;
 +    arg.mem_type = memType;
  
      do{
 -      ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
 +        ret = ioctl(fd, DRM_IOCTL_MM_LOCK, &arg);
      } while (ret && errno == EAGAIN);
-     
-     return -errno;    
+     return (ret) ? -errno : 0;
  }
  
  int drmMMUnlock(int fd, unsigned memType)
  {
 -    drm_mm_init_arg_t arg;
 +    struct drm_mm_type_arg arg;
      int ret;
  
      memset(&arg, 0, sizeof(arg));
 -    arg.req.op = mm_unlock;
 -    arg.req.mem_type = memType;
 +    
 +    arg.mem_type = memType;
  
      do{
 -      ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
 +      ret = ioctl(fd, DRM_IOCTL_MM_UNLOCK, &arg);
      } while (ret && errno == EAGAIN);
-     
-     return -errno;    
+     return (ret) ? -errno : 0;
  }
  
  #define DRM_MAX_FDS 16
  static struct {
-    char *BusID;
-    int fd;
-    int refcount;
+     char *BusID;
+     int fd;
+     int refcount;
  } connection[DRM_MAX_FDS];
  
  static int nr_fds = 0;
@@@ -3177,50 -3293,50 +3247,50 @@@ int drmOpenOnce(void *unused
                const char *BusID,
                int *newlyopened)
  {
-    int i;
-    int fd;
+     int i;
+     int fd;
     
-    for (i = 0; i < nr_fds; i++)
-       if (strcmp(BusID, connection[i].BusID) == 0) {
-        connection[i].refcount++;
-        *newlyopened = 0;
-        return connection[i].fd;
-       }
-    fd = drmOpen(unused, BusID);
-    if (fd <= 0 || nr_fds == DRM_MAX_FDS)
-       return fd;
+     for (i = 0; i < nr_fds; i++)
+       if (strcmp(BusID, connection[i].BusID) == 0) {
+           connection[i].refcount++;
+           *newlyopened = 0;
+           return connection[i].fd;
+       }
+     fd = drmOpen(unused, BusID);
+     if (fd <= 0 || nr_fds == DRM_MAX_FDS)
+       return fd;
     
-    connection[nr_fds].BusID = strdup(BusID);
-    connection[nr_fds].fd = fd;
-    connection[nr_fds].refcount = 1;
-    *newlyopened = 1;
+     connection[nr_fds].BusID = strdup(BusID);
+     connection[nr_fds].fd = fd;
+     connection[nr_fds].refcount = 1;
+     *newlyopened = 1;
  
-    if (0)
-       fprintf(stderr, "saved connection %d for %s %d\n", 
-               nr_fds, connection[nr_fds].BusID, 
-               strcmp(BusID, connection[nr_fds].BusID));
+     if (0)
+       fprintf(stderr, "saved connection %d for %s %d\n", 
+               nr_fds, connection[nr_fds].BusID, 
+               strcmp(BusID, connection[nr_fds].BusID));
  
-    nr_fds++;
+     nr_fds++;
  
-    return fd;   
+     return fd;
  }
  
  void drmCloseOnce(int fd)
  {
-    int i;
+     int i;
  
-    for (i = 0; i < nr_fds; i++) {
-       if (fd == connection[i].fd) {
-        if (--connection[i].refcount == 0) {
-           drmClose(connection[i].fd);
-           free(connection[i].BusID);
+     for (i = 0; i < nr_fds; i++) {
+       if (fd == connection[i].fd) {
+           if (--connection[i].refcount == 0) {
+               drmClose(connection[i].fd);
+               free(connection[i].BusID);
            
-           if (i < --nr_fds) 
-              connection[i] = connection[nr_fds];
+               if (i < --nr_fds) 
+                   connection[i] = connection[nr_fds];
  
-           return;
-        }
-       }
-    }
+               return;
+           }
+       }
+     }
  }
diff --combined libdrm/xf86mm.h
@@@ -60,7 -60,7 +60,7 @@@ typedef struct _drmMMListHea
      (__item)->next = (__item);                       \
    } while (0)
  
- #define DRMLISTADD(__item, __list)                    \
+ #define DRMLISTADD(__item, __list)            \
    do {                                                \
      (__item)->prev = (__list);                        \
      (__item)->next = (__list)->next;          \
  #define DRMLISTENTRY(__type, __item, __field)   \
      ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
  
- typedef struct _drmFence{
-         unsigned handle;
-         int class;
-         unsigned type; 
-         unsigned flags;
-         unsigned signaled;
-         unsigned pad[4]; /* for future expansion */
+ typedef struct _drmFence
+ {
+     unsigned handle;
+     int class;
+     unsigned type; 
+     unsigned flags;
+     unsigned signaled;
+     unsigned pad[4]; /* for future expansion */
  } drmFence;
  
- typedef struct _drmBO{
+ typedef struct _drmBO
+ {
      drm_bo_type_t type;
      unsigned handle;
      drm_u64_t mapHandle;
 -    unsigned flags;
 -    unsigned mask;
 +    drm_u64_t flags;
 +    drm_u64_t mask;
      unsigned mapFlags;
      unsigned long size;
      unsigned long offset;
      unsigned replyFlags;
      unsigned fenceFlags;
      unsigned pageAlignment;
 +    unsigned tileInfo;
 +    unsigned hwTileStride;
 +    unsigned desiredTileStride;
      void *virtual;
      void *mapVirtual;
      int mapCount;
      unsigned pad[8];     /* for future expansion */
  } drmBO;
  
typedef struct _drmBONode {
+ typedef struct _drmBONode
+ {
      drmMMListHead head;
      drmBO *buf;
 -    drm_bo_arg_t bo_arg;
 +    struct drm_bo_op_arg bo_arg;
      unsigned long arg0;
      unsigned long arg1;
  } drmBONode;
@@@ -141,22 -140,24 +143,24 @@@ typedef struct _drmBOList 
      drmMMListHead free;
  } drmBOList;
  
- /* Fencing */
- extern int           drmFenceCreate(int fd, unsigned flags, int class,
-                                   unsigned type, 
-                                   drmFence *fence);
- extern int           drmFenceDestroy(int fd, const drmFence *fence);
- extern int           drmFenceReference(int fd, unsigned handle, drmFence *fence);
- extern int           drmFenceUnreference(int fd, const drmFence *fence);
- extern int           drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
- extern int           drmFenceSignaled(int fd, drmFence *fence, 
-                                     unsigned fenceType, int *signaled);
- extern int           drmFenceWait(int fd, unsigned flags, drmFence *fence, 
-                                 unsigned flush_type);
- extern int           drmFenceEmit(int fd, unsigned flags, drmFence *fence, 
-                                 unsigned emit_type);
- extern int           drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
+ /*
+  * Fence functions.
+  */
+ extern int drmFenceCreate(int fd, unsigned flags, int class,
+                           unsigned type, drmFence *fence);
+ extern int drmFenceDestroy(int fd, const drmFence *fence);
+ extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
+ extern int drmFenceUnreference(int fd, const drmFence *fence);
+ extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
+ extern int drmFenceSignaled(int fd, drmFence *fence, 
+                             unsigned fenceType, int *signaled);
+ extern int drmFenceWait(int fd, unsigned flags, drmFence *fence, 
+                         unsigned flush_type);
+ extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence, 
+                         unsigned emit_type);
+ extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
  
  
  /*
@@@ -175,8 -176,8 +179,8 @@@ extern int drmBOCreateList(int numTarge
   */
  
  extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
 -                     unsigned pageAlignment,void *user_buffer, 
 -                     drm_bo_type_t type, unsigned mask,
 +                     unsigned pageAlignment,void *user_buffer,
 +                     drm_bo_type_t type, drm_u64_t mask,
                       unsigned hint, drmBO *buf);
  extern int drmBODestroy(int fd, drmBO *buf);
  extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
@@@ -184,14 -185,14 +188,14 @@@ extern int drmBOUnReference(int fd, drm
  extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
                    void **address);
  extern int drmBOUnmap(int fd, drmBO *buf);
 -extern int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask, 
 -                       unsigned hint);
 +extern int drmBOValidate(int fd, drmBO *buf, drm_u64_t flags,
 +                       drm_u64_t mask, unsigned hint);
 +
  extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle);
  extern int drmBOInfo(int fd, drmBO *buf);
  extern int drmBOBusy(int fd, drmBO *buf, int *busy);
  
 -
 -extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags, 
 +extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
                       unsigned mask,
                       int *newItem);
  extern int drmBOValidateList(int fd, drmBOList *list);
diff --combined linux-core/drm_bo.c
@@@ -67,6 -67,9 +67,9 @@@ void drm_bo_add_to_pinned_lru(drm_buffe
  {
        drm_mem_type_manager_t *man;
  
+       DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
+       DRM_ASSERT_LOCKED(&bo->mutex);
        man = &bo->dev->bm.man[bo->pinned_mem_type];
        list_add_tail(&bo->pinned_lru, &man->pinned);
  }
@@@ -75,6 -78,8 +78,8 @@@ void drm_bo_add_to_lru(drm_buffer_objec
  {
        drm_mem_type_manager_t *man;
  
+       DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
        if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
            || bo->mem.mem_type != bo->pinned_mem_type) {
                man = &bo->dev->bm.man[bo->mem.mem_type];
@@@ -134,6 -139,8 +139,8 @@@ static int drm_bo_add_ttm(drm_buffer_ob
        int ret = 0;
        bo->ttm = NULL;
  
+       DRM_ASSERT_LOCKED(&bo->mutex);
        switch (bo->type) {
        case drm_bo_type_dc:
                bo->ttm = drm_ttm_init(dev, bo->mem.num_pages << PAGE_SHIFT);
@@@ -195,8 -202,8 +202,8 @@@ static int drm_bo_handle_move_mem(drm_b
        if ((bo->mem.mem_type == DRM_BO_MEM_LOCAL) && bo->ttm == NULL) {
  
                drm_bo_mem_reg_t *old_mem = &bo->mem;
 -              uint32_t save_flags = old_mem->flags;
 -              uint32_t save_mask = old_mem->mask;
 +              uint64_t save_flags = old_mem->flags;
 +              uint64_t save_mask = old_mem->mask;
  
                *old_mem = *mem;
                mem->mm_node = NULL;
  int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
                int no_wait)
  {
-       drm_fence_object_t *fence = bo->fence;
        int ret;
  
-       if (fence) {
-               drm_device_t *dev = bo->dev;
-               if (drm_fence_object_signaled(fence, bo->fence_type)) {
-                       drm_fence_usage_deref_unlocked(dev, fence);
-                       bo->fence = NULL;
+       DRM_ASSERT_LOCKED(&bo->mutex);
+       if (bo->fence) {
+               if (drm_fence_object_signaled(bo->fence, bo->fence_type, 0)) {
+                       drm_fence_usage_deref_unlocked(&bo->fence);
                        return 0;
                }
                if (no_wait) {
                        return -EBUSY;
                }
                ret =
-                   drm_fence_object_wait(dev, fence, lazy, ignore_signals,
+                   drm_fence_object_wait(bo->fence, lazy, ignore_signals,
                                          bo->fence_type);
                if (ret)
                        return ret;
  
-               drm_fence_usage_deref_unlocked(dev, fence);
-               bo->fence = NULL;
+               drm_fence_usage_deref_unlocked(&bo->fence);
        }
        return 0;
  }
@@@ -312,10 -315,8 +315,8 @@@ static int drm_bo_expire_fence(drm_buff
                                          "Evicting buffer.\n");
                        }
                }
-               if (bo->fence) {
-                       drm_fence_usage_deref_unlocked(dev, bo->fence);
-                       bo->fence = NULL;
-               }
+               if (bo->fence)
+                       drm_fence_usage_deref_unlocked(&bo->fence);
        }
        return 0;
  }
@@@ -331,16 -332,17 +332,17 @@@ static void drm_bo_cleanup_refs(drm_buf
        drm_device_t *dev = bo->dev;
        drm_buffer_manager_t *bm = &dev->bm;
  
+       DRM_ASSERT_LOCKED(&dev->struct_mutex);
        atomic_inc(&bo->usage);
        mutex_unlock(&dev->struct_mutex);
        mutex_lock(&bo->mutex);
  
        DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
  
-       if (bo->fence && drm_fence_object_signaled(bo->fence, bo->fence_type)) {
-               drm_fence_usage_deref_locked(dev, bo->fence);
-               bo->fence = NULL;
-       }
+       if (bo->fence && drm_fence_object_signaled(bo->fence,
+                                                  bo->fence_type, 0))
+               drm_fence_usage_deref_unlocked(&bo->fence);
  
        if (bo->fence && remove_all)
                (void)drm_bo_expire_fence(bo, 0);
        }
  
        if (list_empty(&bo->ddestroy)) {
-               drm_fence_object_flush(dev, bo->fence, bo->fence_type);
+               drm_fence_object_flush(bo->fence, bo->fence_type);
                list_add_tail(&bo->ddestroy, &bm->ddestroy);
                schedule_delayed_work(&bm->wq,
                                      ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
@@@ -392,6 -394,8 +394,8 @@@ static void drm_bo_destroy_locked(drm_b
        drm_device_t *dev = bo->dev;
        drm_buffer_manager_t *bm = &dev->bm;
  
+       DRM_ASSERT_LOCKED(&dev->struct_mutex);
        if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
            list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
            list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) {
  
                atomic_dec(&bm->count);
  
+               BUG_ON(!list_empty(&bo->base.list));
                drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
  
                return;
@@@ -488,10 -493,15 +493,15 @@@ static void drm_bo_delayed_workqueue(st
        mutex_unlock(&dev->struct_mutex);
  }
  
- void drm_bo_usage_deref_locked(drm_buffer_object_t * bo)
+ void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo)
  {
-       if (atomic_dec_and_test(&bo->usage)) {
-               drm_bo_destroy_locked(bo);
+         struct drm_buffer_object *tmp_bo = *bo;
+       bo = NULL;
+       DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
+       if (atomic_dec_and_test(&tmp_bo->usage)) {
+               drm_bo_destroy_locked(tmp_bo);
        }
  }
  
@@@ -500,18 -510,22 +510,22 @@@ static void drm_bo_base_deref_locked(dr
        drm_buffer_object_t *bo =
            drm_user_object_entry(uo, drm_buffer_object_t, base);
  
+       DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
        drm_bo_takedown_vm_locked(bo);
-       drm_bo_usage_deref_locked(bo);
+       drm_bo_usage_deref_locked(&bo);
  }
  
- static void drm_bo_usage_deref_unlocked(drm_buffer_object_t * bo)
+ static void drm_bo_usage_deref_unlocked(drm_buffer_object_t ** bo)
  {
-       drm_device_t *dev = bo->dev;
+       struct drm_buffer_object *tmp_bo = *bo;
+       drm_device_t *dev = tmp_bo->dev;
  
-       if (atomic_dec_and_test(&bo->usage)) {
+       *bo = NULL;
+       if (atomic_dec_and_test(&tmp_bo->usage)) {
                mutex_lock(&dev->struct_mutex);
-               if (atomic_read(&bo->usage) == 0)
-                       drm_bo_destroy_locked(bo);
+               if (atomic_read(&tmp_bo->usage) == 0)
+                       drm_bo_destroy_locked(tmp_bo);
                mutex_unlock(&dev->struct_mutex);
        }
  }
@@@ -597,18 -611,17 +611,17 @@@ int drm_fence_buffer_objects(drm_file_
                if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
                        count++;
                        if (entry->fence)
-                               drm_fence_usage_deref_locked(dev, entry->fence);
-                       entry->fence = fence;
+                               drm_fence_usage_deref_locked(&entry->fence);
+                       entry->fence = drm_fence_reference_locked(fence);
                        DRM_FLAG_MASKED(entry->priv_flags, 0,
                                        _DRM_BO_FLAG_UNFENCED);
                        DRM_WAKEUP(&entry->event_queue);
                        drm_bo_add_to_lru(entry);
                }
                mutex_unlock(&entry->mutex);
-               drm_bo_usage_deref_locked(entry);
+               drm_bo_usage_deref_locked(&entry);
                l = f_list.next;
        }
-       atomic_add(count, &fence->usage);
        DRM_DEBUG("Fenced %d buffers\n", count);
        out:
        mutex_unlock(&dev->struct_mutex);
@@@ -723,7 -736,7 +736,7 @@@ static int drm_bo_mem_force_space(drm_d
  
                ret = drm_bo_evict(entry, mem_type, no_wait);
                mutex_unlock(&entry->mutex);
-               drm_bo_usage_deref_unlocked(entry);
+               drm_bo_usage_deref_unlocked(&entry);
                if (ret)
                        return ret;
                mutex_lock(&dev->struct_mutex);
@@@ -871,7 -884,7 +884,7 @@@ int drm_bo_mem_space(drm_buffer_object_
  EXPORT_SYMBOL(drm_bo_mem_space);
  
  static int drm_bo_new_mask(drm_buffer_object_t * bo,
 -                         uint32_t new_mask, uint32_t hint)
 +                         uint64_t new_mask, uint32_t hint)
  {
        uint32_t new_props;
  
@@@ -943,10 -956,8 +956,8 @@@ static int drm_bo_quick_busy(drm_buffer
  
        BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
        if (fence) {
-               drm_device_t *dev = bo->dev;
-               if (drm_fence_object_signaled(fence, bo->fence_type)) {
-                       drm_fence_usage_deref_unlocked(dev, fence);
-                       bo->fence = NULL;
+               if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+                       drm_fence_usage_deref_unlocked(&bo->fence);
                        return 0;
                }
                return 1;
@@@ -965,16 -976,13 +976,13 @@@ static int drm_bo_busy(drm_buffer_objec
  
        BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
        if (fence) {
-               drm_device_t *dev = bo->dev;
-               if (drm_fence_object_signaled(fence, bo->fence_type)) {
-                       drm_fence_usage_deref_unlocked(dev, fence);
-                       bo->fence = NULL;
+               if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+                       drm_fence_usage_deref_unlocked(&bo->fence);
                        return 0;
                }
-               drm_fence_object_flush(dev, fence, DRM_FENCE_TYPE_EXE);
-               if (drm_fence_object_signaled(fence, bo->fence_type)) {
-                       drm_fence_usage_deref_unlocked(dev, fence);
-                       bo->fence = NULL;
+               drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
+               if (drm_fence_object_signaled(fence, bo->fence_type, 0)) {
+                       drm_fence_usage_deref_unlocked(&bo->fence);
                        return 0;
                }
                return 1;
@@@ -1068,7 -1076,7 +1076,7 @@@ static int drm_bo_wait_unfenced(drm_buf
   */
  
  static void drm_bo_fill_rep_arg(drm_buffer_object_t * bo,
 -                              drm_bo_arg_reply_t * rep)
 +                              struct drm_bo_info_rep *rep)
  {
        rep->handle = bo->base.hash.key;
        rep->flags = bo->mem.flags;
  
  static int drm_buffer_object_map(drm_file_t * priv, uint32_t handle,
                                 uint32_t map_flags, unsigned hint,
 -                               drm_bo_arg_reply_t * rep)
 +                               struct drm_bo_info_rep *rep)
  {
        drm_buffer_object_t *bo;
        drm_device_t *dev = priv->head->dev;
                drm_bo_fill_rep_arg(bo, rep);
        out:
        mutex_unlock(&bo->mutex);
-       drm_bo_usage_deref_unlocked(bo);
+       drm_bo_usage_deref_unlocked(&bo);
        return ret;
  }
  
@@@ -1197,7 -1205,7 +1205,7 @@@ static int drm_buffer_object_unmap(drm_
        }
  
        drm_remove_ref_object(priv, ro);
-       drm_bo_usage_deref_locked(bo);
+       drm_bo_usage_deref_locked(&bo);
        out:
        mutex_unlock(&dev->struct_mutex);
        return ret;
@@@ -1343,8 -1351,7 +1351,8 @@@ static int drm_bo_check_fake(drm_device
                return 0;
        }
  
 -      DRM_ERROR("Illegal fake buffer flags 0x%08x\n", mem->mask);
 +      DRM_ERROR("Illegal fake buffer flags 0x%016llx\n",
 +                (unsigned long long) mem->mask);
        return -EINVAL;
  }
  
   */
  
  static int drm_buffer_object_validate(drm_buffer_object_t * bo,
 +                                    uint32_t fence_class,
                                      int move_unfenced, int no_wait)
  {
        drm_device_t *dev = bo->dev;
        drm_buffer_manager_t *bm = &dev->bm;
        drm_bo_driver_t *driver = dev->driver->bo_driver;
 +      uint32_t ftype;
        int ret;
  
 -      DRM_DEBUG("New flags 0x%08x, Old flags 0x%08x\n", bo->mem.mask,
 -                bo->mem.flags);
 -      ret =
 -          driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
 +      DRM_DEBUG("New flags 0x%016llx, Old flags 0x%016llx\n",
 +                (unsigned long long) bo->mem.mask,
 +                (unsigned long long) bo->mem.flags);
 +
 +      ret = driver->fence_type(bo, &ftype);
 +
        if (ret) {
                DRM_ERROR("Driver did not support given buffer permissions\n");
                return ret;
        }
  
 +      /*
 +       * We're switching command submission mechanism,
 +       * or cannot simply rely on the hardware serializing for us.
 +       *
 +       * Wait for buffer idle.
 +       */
 +
 +      if ((fence_class != bo->fence_class) ||
 +          ((ftype ^ bo->fence_type) & bo->fence_type)) {
 +
 +              ret = drm_bo_wait(bo, 0, 0, no_wait);
 +
 +              if (ret)
 +                      return ret;
 +
 +      }
 +      
 +      bo->fence_class = fence_class;
 +      bo->fence_type = ftype;
        ret = drm_bo_wait_unmapped(bo, no_wait);
        if (ret)
                return ret;
        return 0;
  }
  
 -static int drm_bo_handle_validate(drm_file_t * priv, uint32_t handle,
 -                                uint32_t flags, uint32_t mask, uint32_t hint,
 -                                drm_bo_arg_reply_t * rep)
 +static int drm_bo_handle_validate(drm_file_t * priv,
 +                                uint32_t handle,
 +                                uint32_t fence_class,
 +                                uint64_t flags, uint64_t mask, uint32_t hint,
 +                                struct drm_bo_info_rep *rep)
  {
+       struct drm_device *dev = priv->head->dev;
        drm_buffer_object_t *bo;
        int ret;
        int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
  
+       mutex_lock(&dev->struct_mutex);
        bo = drm_lookup_buffer_object(priv, handle, 1);
+       mutex_unlock(&dev->struct_mutex);
        if (!bo) {
                return -EINVAL;
        }
                goto out;
  
        ret =
 -          drm_buffer_object_validate(bo, !(hint & DRM_BO_HINT_DONT_FENCE),
 +          drm_buffer_object_validate(bo, fence_class,
 +                                     !(hint & DRM_BO_HINT_DONT_FENCE),
                                       no_wait);
        drm_bo_fill_rep_arg(bo, rep);
  
  
        mutex_unlock(&bo->mutex);
  
-       drm_bo_usage_deref_unlocked(bo);
+       drm_bo_usage_deref_unlocked(&bo);
        return ret;
  }
  
 -static int drm_bo_handle_info(drm_file_t * priv, uint32_t handle,
 -                            drm_bo_arg_reply_t * rep)
 +static int drm_bo_handle_info(drm_file_t *priv, uint32_t handle,
 +                            struct drm_bo_info_rep *rep)
  {
+       struct drm_device *dev = priv->head->dev;
        drm_buffer_object_t *bo;
  
+       mutex_lock(&dev->struct_mutex);
        bo = drm_lookup_buffer_object(priv, handle, 1);
+       mutex_unlock(&dev->struct_mutex);
        if (!bo) {
                return -EINVAL;
        }
                (void)drm_bo_busy(bo);
        drm_bo_fill_rep_arg(bo, rep);
        mutex_unlock(&bo->mutex);
-       drm_bo_usage_deref_unlocked(bo);
+       drm_bo_usage_deref_unlocked(&bo);
        return 0;
  }
  
 -static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
 -                            uint32_t hint, drm_bo_arg_reply_t * rep)
 +static int drm_bo_handle_wait(drm_file_t *priv, uint32_t handle,
 +                            uint32_t hint,
 +                            struct drm_bo_info_rep *rep)
  {
+       struct drm_device *dev = priv->head->dev;
        drm_buffer_object_t *bo;
        int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
        int ret;
  
+       mutex_lock(&dev->struct_mutex);
        bo = drm_lookup_buffer_object(priv, handle, 1);
+       mutex_unlock(&dev->struct_mutex);
        if (!bo) {
                return -EINVAL;
        }
  
        out:
        mutex_unlock(&bo->mutex);
-       drm_bo_usage_deref_unlocked(bo);
+       drm_bo_usage_deref_unlocked(&bo);
        return ret;
  }
  
  int drm_buffer_object_create(drm_device_t *dev,
                             unsigned long size,
                             drm_bo_type_t type,
 -                           uint32_t mask,
 +                           uint64_t mask,
                             uint32_t hint,
                             uint32_t page_alignment,
                             unsigned long buffer_start,
                bo->buffer_start = buffer_start;
        }
        bo->priv_flags = 0;
 -      bo->mem.flags = 0;
 -      bo->mem.mask = 0;
 +      bo->mem.flags = 0ULL;
 +      bo->mem.mask = 0ULL;
        atomic_inc(&bm->count);
        ret = drm_bo_new_mask(bo, mask, hint);
  
                if (ret)
                        goto out_err;
        }
 -      ret = drm_buffer_object_validate(bo, 0, hint & DRM_BO_HINT_DONT_BLOCK);
 +      ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
        if (ret)
                goto out_err;
  
        out_err:
        mutex_unlock(&bo->mutex);
  
-       drm_bo_usage_deref_unlocked(bo);
+       drm_bo_usage_deref_unlocked(&bo);
        return ret;
  }
  
@@@ -1680,14 -1671,15 +1699,14 @@@ static int drm_bo_lock_test(drm_device_
        return 0;
  }
  
 -int drm_bo_ioctl(DRM_IOCTL_ARGS)
 +int drm_bo_op_ioctl(DRM_IOCTL_ARGS)
  {
        DRM_DEVICE;
 -      drm_bo_arg_t arg;
 -      drm_bo_arg_request_t *req = &arg.d.req;
 -      drm_bo_arg_reply_t rep;
 +      struct drm_bo_op_arg arg;
 +      struct drm_bo_op_req *req = &arg.d.req;
 +      struct drm_bo_info_rep rep;
        unsigned long next;
 -      drm_user_object_t *uo;
 -      drm_buffer_object_t *entry;
 +      int ret;
  
        if (!dev->bm.initialized) {
                DRM_ERROR("Buffer object manager is not initialized.\n");
                        continue;
                }
  
 -              rep.ret = 0;
 +              ret = 0;
                switch (req->op) {
 -              case drm_bo_create:
 -                      rep.ret = drm_bo_lock_test(dev, filp);
 -                      if (rep.ret)
 -                              break;  
 -                      rep.ret =
 -                          drm_buffer_object_create(priv->head->dev,
 -                                                   req->size,
 -                                                   req->type,
 -                                                   req->mask,
 -                                                   req->hint,
 -                                                   req->page_alignment,
 -                                                   req->buffer_start, &entry);
 -                      if (rep.ret)
 -                              break;
 -
 -                      rep.ret =
 -                          drm_bo_add_user_object(priv, entry,
 -                                                 req->
 -                                                 mask &
 -                                                 DRM_BO_FLAG_SHAREABLE);
 -                      if (rep.ret)
 -                              drm_bo_usage_deref_unlocked(&entry);
 -
 -                      if (rep.ret)
 -                              break;
 -
 -                      mutex_lock(&entry->mutex);
 -                      drm_bo_fill_rep_arg(entry, &rep);
 -                      mutex_unlock(&entry->mutex);
 -                      break;
 -              case drm_bo_unmap:
 -                      rep.ret = drm_buffer_object_unmap(priv, req->handle);
 -                      break;
 -              case drm_bo_map:
 -                      rep.ret = drm_buffer_object_map(priv, req->handle,
 -                                                      req->mask,
 -                                                      req->hint, &rep);
 -                      break;
 -              case drm_bo_destroy:
 -                      mutex_lock(&dev->struct_mutex);
 -                      uo = drm_lookup_user_object(priv, req->handle);
 -                      if (!uo || (uo->type != drm_buffer_type)
 -                          || uo->owner != priv) {
 -                              mutex_unlock(&dev->struct_mutex);
 -                              rep.ret = -EINVAL;
 -                              break;
 -                      }
 -                      rep.ret = drm_remove_user_object(priv, uo);
 -                      mutex_unlock(&dev->struct_mutex);
 -                      break;
 -              case drm_bo_reference:
 -                      rep.ret = drm_user_object_ref(priv, req->handle,
 -                                                    drm_buffer_type, &uo);
 -                      if (rep.ret)
 -                              break;
 -
 -                      rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
 -                      break;
 -              case drm_bo_unreference:
 -                      rep.ret = drm_user_object_unref(priv, req->handle,
 -                                                      drm_buffer_type);
 -                      break;
                case drm_bo_validate:
 -                      rep.ret = drm_bo_lock_test(dev, filp);
 -
 -                      if (rep.ret)
 +                      ret = drm_bo_lock_test(dev, filp);
 +                      if (ret)
                                break;
 -                      rep.ret =
 -                          drm_bo_handle_validate(priv, req->handle, req->mask,
 -                                                 req->arg_handle, req->hint,
 -                                                 &rep);
 +                      ret = drm_bo_handle_validate(priv, req->bo_req.handle,
 +                                                   req->bo_req.fence_class,
 +                                                   req->bo_req.flags,
 +                                                   req->bo_req.mask,
 +                                                   req->bo_req.hint,
 +                                                   &rep);
                        break;
                case drm_bo_fence:
 -                      rep.ret = drm_bo_lock_test(dev, filp);
 -                      if (rep.ret)
 -                              break;
 -                       /**/ break;
 -              case drm_bo_info:
 -                      rep.ret = drm_bo_handle_info(priv, req->handle, &rep);
 -                      break;
 -              case drm_bo_wait_idle:
 -                      rep.ret = drm_bo_handle_wait(priv, req->handle,
 -                                                   req->hint, &rep);
 +                      ret = -EINVAL;
 +                      DRM_ERROR("Function is not implemented yet.\n");
                        break;
                case drm_bo_ref_fence:
 -                      rep.ret = -EINVAL;
 +                      ret = -EINVAL;
                        DRM_ERROR("Function is not implemented yet.\n");
 +                      break;
                default:
 -                      rep.ret = -EINVAL;
 +                      ret = -EINVAL;
                }
                next = arg.next;
  
                 * A signal interrupted us. Make sure the ioctl is restartable.
                 */
  
 -              if (rep.ret == -EAGAIN)
 +              if (ret == -EAGAIN)
                        return -EAGAIN;
  
                arg.handled = 1;
 -              arg.d.rep = rep;
 +              arg.d.rep.ret = ret;
 +              arg.d.rep.bo_info = rep;
                DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
                data = next;
        } while (data);
        return 0;
  }
  
-               drm_bo_usage_deref_unlocked(entry);
 +int drm_bo_create_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_create_arg arg;
 +      struct drm_bo_create_req *req = &arg.d.req;
 +      struct drm_bo_info_rep *rep = &arg.d.rep;
 +      drm_buffer_object_t *entry;
 +      int ret = 0;
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +      
 +      ret = drm_bo_lock_test(dev, filp);
 +      if (ret)
 +              goto out;
 +
 +      ret = drm_buffer_object_create(priv->head->dev,
 +                                     req->size, req->type, req->mask,
 +                                     req->hint, req->page_alignment,
 +                                     req->buffer_start, &entry);
 +      if (ret)
 +              goto out;
 +      
 +      ret = drm_bo_add_user_object(priv, entry,
 +                                   req->mask & DRM_BO_FLAG_SHAREABLE);
 +      if (ret) {
++              drm_bo_usage_deref_unlocked(&entry);
 +              goto out;
 +      }
 +      
 +      mutex_lock(&entry->mutex);
 +      drm_bo_fill_rep_arg(entry, rep);
 +      mutex_unlock(&entry->mutex);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +out:
 +      return ret;
 +}
 +
 +
 +int drm_bo_destroy_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_handle_arg arg;
 +      drm_user_object_t *uo;
 +      int ret = 0;
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      mutex_lock(&dev->struct_mutex);
 +      uo = drm_lookup_user_object(priv, arg.handle);
 +      if (!uo || (uo->type != drm_buffer_type) || uo->owner != priv) {
 +              mutex_unlock(&dev->struct_mutex);
 +              return -EINVAL;
 +      }
 +      ret = drm_remove_user_object(priv, uo);
 +      mutex_unlock(&dev->struct_mutex);
 +      
 +      return ret;
 +}
 +
 +int drm_bo_map_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_map_wait_idle_arg arg;
 +      struct drm_bo_info_req *req = &arg.d.req;
 +      struct drm_bo_info_rep *rep = &arg.d.rep;
 +      int ret;
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_buffer_object_map(priv, req->handle, req->mask,
 +                                  req->hint, rep);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_bo_unmap_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_handle_arg arg;
 +      int ret;
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_buffer_object_unmap(priv, arg.handle);
 +      return ret;
 +}
 +
 +
 +int drm_bo_reference_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_reference_info_arg arg;
 +      struct drm_bo_handle_arg *req = &arg.d.req;
 +      struct drm_bo_info_rep *rep = &arg.d.rep;
 +      drm_user_object_t *uo;
 +      int ret;
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_user_object_ref(priv, req->handle,
 +                                drm_buffer_type, &uo);
 +      if (ret)
 +              return ret;
 +      
 +      ret = drm_bo_handle_info(priv, req->handle, rep);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_bo_unreference_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_handle_arg arg;
 +      int ret = 0;
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_user_object_unref(priv, arg.handle, drm_buffer_type);
 +      return ret;
 +}
 +
 +int drm_bo_info_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_reference_info_arg arg;
 +      struct drm_bo_handle_arg *req = &arg.d.req;
 +      struct drm_bo_info_rep *rep = &arg.d.rep;
 +      int ret;
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_bo_handle_info(priv, req->handle, rep);
 +      if (ret)
 +              return ret;
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_bo_wait_idle_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_bo_map_wait_idle_arg arg;
 +      struct drm_bo_info_req *req = &arg.d.req;
 +      struct drm_bo_info_rep *rep = &arg.d.rep;
 +      int ret;
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      ret = drm_bo_handle_wait(priv, req->handle,
 +                               req->hint, rep);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +
 +
  /**
   *Clean the unfenced list and put on regular LRU.
   *This is part of the memory manager cleanup and should only be
@@@ -2090,7 -1946,7 +2109,7 @@@ restart
                                        allow_errors);
                mutex_lock(&dev->struct_mutex);
  
-               drm_bo_usage_deref_locked(entry);
+               drm_bo_usage_deref_locked(&entry);
                if (ret)
                        return ret;
  
  
                do_restart = ((next->prev != list) && (next->prev != prev));
  
-               if (nentry != NULL && do_restart) {
-                       drm_bo_usage_deref_locked(nentry);
-                       nentry = NULL;
-               }
+               if (nentry != NULL && do_restart)
+                       drm_bo_usage_deref_locked(&nentry);
  
                if (do_restart)
                        goto restart;
@@@ -2321,67 -2175,11 +2338,67 @@@ EXPORT_SYMBOL(drm_bo_driver_init)
  int drm_mm_init_ioctl(DRM_IOCTL_ARGS)
  {
        DRM_DEVICE;
 +      struct drm_mm_init_arg arg;
 +      drm_buffer_manager_t *bm = &dev->bm;
 +      drm_bo_driver_t *driver = dev->driver->bo_driver;
 +      int ret;
  
 -      int ret = 0;
 -      drm_mm_init_arg_t arg;
 +      if (!driver) {
 +              DRM_ERROR("Buffer objects are not supported by this driver\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +      ret = -EINVAL;
 +      if (arg.magic != DRM_BO_INIT_MAGIC) {
 +              DRM_ERROR("You are using an old libdrm that is not compatible with\n"
 +                        "\tthe kernel DRM module. Please upgrade your libdrm.\n");
 +              return -EINVAL;
 +      }
 +      if (arg.major != DRM_BO_INIT_MAJOR) {
 +              DRM_ERROR("libdrm and kernel DRM buffer object interface major\n"
 +                        "\tversion don't match. Got %d, expected %d,\n",
 +                        arg.major, DRM_BO_INIT_MAJOR);
 +              return -EINVAL;
 +      }
 +      if (arg.minor > DRM_BO_INIT_MINOR) {
 +              DRM_ERROR("libdrm expects a newer DRM buffer object interface.\n"
 +                        "\tlibdrm buffer object interface version is %d.%d.\n"
 +                        "\tkernel DRM buffer object interface version is %d.%d\n",
 +                        arg.major, arg.minor, DRM_BO_INIT_MAJOR, DRM_BO_INIT_MINOR);
 +              return -EINVAL;
 +      }
 +
 +      mutex_lock(&dev->bm.init_mutex);
 +      mutex_lock(&dev->struct_mutex);
 +      if (!bm->initialized) {
 +              DRM_ERROR("DRM memory manager was not initialized.\n");
 +              goto out;
 +      }
 +      if (arg.mem_type == 0) {
 +              DRM_ERROR("System memory buffers already initialized.\n");
 +              goto out;
 +      }
 +      ret = drm_bo_init_mm(dev, arg.mem_type,
 +                           arg.p_offset, arg.p_size);
 +
 +out:
 +      mutex_unlock(&dev->struct_mutex);
 +      mutex_unlock(&dev->bm.init_mutex);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_mm_takedown_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_mm_type_arg arg;
        drm_buffer_manager_t *bm = &dev->bm;
        drm_bo_driver_t *driver = dev->driver->bo_driver;
 +      int ret;
  
        if (!driver) {
                DRM_ERROR("Buffer objects are not supported by this driver\n");
  
        DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
  
 -      switch (arg.req.op) {
 -      case mm_init:
 -              ret = -EINVAL;
 -              mutex_lock(&dev->bm.init_mutex);
 -              mutex_lock(&dev->struct_mutex);
 -              if (!bm->initialized) {
 -                      DRM_ERROR("DRM memory manager was not initialized.\n");
 -                      break;
 -              }
 -              if (arg.req.mem_type == 0) {
 -                      DRM_ERROR
 -                          ("System memory buffers already initialized.\n");
 -                      break;
 -              }
 -              ret = drm_bo_init_mm(dev, arg.req.mem_type,
 -                                   arg.req.p_offset, arg.req.p_size);
 -              break;
 -      case mm_takedown:
 -              LOCK_TEST_WITH_RETURN(dev, filp);
 -              mutex_lock(&dev->bm.init_mutex);
 -              mutex_lock(&dev->struct_mutex);
 -              ret = -EINVAL;
 -              if (!bm->initialized) {
 -                      DRM_ERROR("DRM memory manager was not initialized\n");
 -                      break;
 -              }
 -              if (arg.req.mem_type == 0) {
 -                      DRM_ERROR("No takedown for System memory buffers.\n");
 -                      break;
 -              }
 -              ret = 0;
 -              if (drm_bo_clean_mm(dev, arg.req.mem_type)) {
 -                      DRM_ERROR("Memory manager type %d not clean. "
 -                                "Delaying takedown\n", arg.req.mem_type);
 -              }
 -              break;
 -      case mm_lock:
 -              LOCK_TEST_WITH_RETURN(dev, filp);
 -              mutex_lock(&dev->bm.init_mutex);
 -              mutex_lock(&dev->struct_mutex);
 -              ret = drm_bo_lock_mm(dev, arg.req.mem_type);
 -              break;
 -      case mm_unlock:
 -              LOCK_TEST_WITH_RETURN(dev, filp);
 -              mutex_lock(&dev->bm.init_mutex);
 -              mutex_lock(&dev->struct_mutex);
 -              ret = 0;
 -              break;
 -      default:
 -              DRM_ERROR("Function not implemented yet\n");
 +      LOCK_TEST_WITH_RETURN(dev, filp);
 +      mutex_lock(&dev->bm.init_mutex);
 +      mutex_lock(&dev->struct_mutex);
 +      ret = -EINVAL;
 +      if (!bm->initialized) {
 +              DRM_ERROR("DRM memory manager was not initialized\n");
 +              goto out;
 +      }
 +      if (arg.mem_type == 0) {
 +              DRM_ERROR("No takedown for System memory buffers.\n");
 +              goto out;
 +      }
 +      ret = 0;
 +      if (drm_bo_clean_mm(dev, arg.mem_type)) {
 +              DRM_ERROR("Memory manager type %d not clean. "
 +                        "Delaying takedown\n", arg.mem_type);
 +      }
 +out:
 +      mutex_unlock(&dev->struct_mutex);
 +      mutex_unlock(&dev->bm.init_mutex);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_mm_lock_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_mm_type_arg arg;
 +      drm_bo_driver_t *driver = dev->driver->bo_driver;
 +      int ret;
 +
 +      if (!driver) {
 +              DRM_ERROR("Buffer objects are not supported by this driver\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      LOCK_TEST_WITH_RETURN(dev, filp);
 +      mutex_lock(&dev->bm.init_mutex);
 +      mutex_lock(&dev->struct_mutex);
 +      ret = drm_bo_lock_mm(dev, arg.mem_type);
 +      mutex_unlock(&dev->struct_mutex);
 +      mutex_unlock(&dev->bm.init_mutex);
 +      if (ret)
 +              return ret;
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return 0;
 +}
 +
 +int drm_mm_unlock_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      struct drm_mm_type_arg arg;
 +      drm_bo_driver_t *driver = dev->driver->bo_driver;
 +      int ret;
 +
 +      if (!driver) {
 +              DRM_ERROR("Buffer objects are not supported by this driver\n");
                return -EINVAL;
        }
  
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +      LOCK_TEST_WITH_RETURN(dev, filp);
 +      mutex_lock(&dev->bm.init_mutex);
 +      mutex_lock(&dev->struct_mutex);
 +      ret = 0;
 +
        mutex_unlock(&dev->struct_mutex);
        mutex_unlock(&dev->bm.init_mutex);
        if (ret)
@@@ -2556,6 -2335,7 +2573,7 @@@ static void drm_bo_takedown_vm_locked(d
        drm_local_map_t *map;
        drm_device_t *dev = bo->dev;
  
+       DRM_ASSERT_LOCKED(&dev->struct_mutex);
        if (list->user_token) {
                drm_ht_remove_item(&dev->map_hash, &list->hash);
                list->user_token = 0;
        drm_ctl_free(map, sizeof(*map), DRM_MEM_BUFOBJ);
        list->map = NULL;
        list->user_token = 0ULL;
-       drm_bo_usage_deref_locked(bo);
+       drm_bo_usage_deref_locked(&bo);
  }
  
  static int drm_bo_setup_vm_locked(drm_buffer_object_t * bo)
        drm_local_map_t *map;
        drm_device_t *dev = bo->dev;
  
+       DRM_ASSERT_LOCKED(&dev->struct_mutex);
        list->map = drm_ctl_calloc(1, sizeof(*map), DRM_MEM_BUFOBJ);
        if (!list->map)
                return -ENOMEM;
diff --combined linux-core/drm_compat.c
@@@ -196,8 -196,7 +196,8 @@@ static int vm_insert_pfn(struct vm_area
        return ret;
  }
  
 -static struct page *drm_bo_vm_fault(struct vm_area_struct *vma, 
 +
 +static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
                                    struct fault_data *data)
  {
        unsigned long address = data->address;
@@@ -556,3 -555,126 +556,126 @@@ void drm_bo_finish_unmap(drm_buffer_obj
  
  #endif
  
+ #ifdef DRM_IDR_COMPAT_FN
+ /* only called when idp->lock is held */
+ static void __free_layer(struct idr *idp, struct idr_layer *p)
+ {
+       p->ary[0] = idp->id_free;
+       idp->id_free = p;
+       idp->id_free_cnt++;
+ }
+ static void free_layer(struct idr *idp, struct idr_layer *p)
+ {
+       unsigned long flags;
+       /*
+        * Depends on the return element being zeroed.
+        */
+       spin_lock_irqsave(&idp->lock, flags);
+       __free_layer(idp, p);
+       spin_unlock_irqrestore(&idp->lock, flags);
+ }
+ /**
+  * idr_for_each - iterate through all stored pointers
+  * @idp: idr handle
+  * @fn: function to be called for each pointer
+  * @data: data passed back to callback function
+  *
+  * Iterate over the pointers registered with the given idr.  The
+  * callback function will be called for each pointer currently
+  * registered, passing the id, the pointer and the data pointer passed
+  * to this function.  It is not safe to modify the idr tree while in
+  * the callback, so functions such as idr_get_new and idr_remove are
+  * not allowed.
+  *
+  * We check the return of @fn each time. If it returns anything other
+  * than 0, we break out and return that value.
+  *
+ * The caller must serialize idr_find() vs idr_get_new() and idr_remove().
+  */
+ int idr_for_each(struct idr *idp,
+                int (*fn)(int id, void *p, void *data), void *data)
+ {
+       int n, id, max, error = 0;
+       struct idr_layer *p;
+       struct idr_layer *pa[MAX_LEVEL];
+       struct idr_layer **paa = &pa[0];
+       n = idp->layers * IDR_BITS;
+       p = idp->top;
+       max = 1 << n;
+       id = 0;
+       while (id < max) {
+               while (n > 0 && p) {
+                       n -= IDR_BITS;
+                       *paa++ = p;
+                       p = p->ary[(id >> n) & IDR_MASK];
+               }
+               if (p) {
+                       error = fn(id, (void *)p, data);
+                       if (error)
+                               break;
+               }
+               id += 1 << n;
+               while (n < fls(id)) {
+                       n += IDR_BITS;
+                       p = *--paa;
+               }
+       }
+       return error;
+ }
+ EXPORT_SYMBOL(idr_for_each);
+ /**
+  * idr_remove_all - remove all ids from the given idr tree
+  * @idp: idr handle
+  *
+  * idr_destroy() only frees up unused, cached idp_layers, but this
+  * function will remove all id mappings and leave all idp_layers
+  * unused.
+  *
+  * A typical clean-up sequence for objects stored in an idr tree, will
+  * use idr_for_each() to free all objects, if necessay, then
+  * idr_remove_all() to remove all ids, and idr_destroy() to free
+  * up the cached idr_layers.
+  */
+ void idr_remove_all(struct idr *idp)
+ {
+        int n, id, max, error = 0;
+        struct idr_layer *p;
+        struct idr_layer *pa[MAX_LEVEL];
+        struct idr_layer **paa = &pa[0];
+        n = idp->layers * IDR_BITS;
+        p = idp->top;
+        max = 1 << n;
+        id = 0;
+        while (id < max && !error) {
+                while (n > IDR_BITS && p) {
+                        n -= IDR_BITS;
+                        *paa++ = p;
+                        p = p->ary[(id >> n) & IDR_MASK];
+                }
+                id += 1 << n;
+                while (n < fls(id)) {
+                        if (p) {
+                                memset(p, 0, sizeof *p);
+                                free_layer(idp, p);
+                        }
+                        n += IDR_BITS;
+                        p = *--paa;
+                }
+        }
+        idp->top = NULL;
+        idp->layers = 0;
+ }
+ EXPORT_SYMBOL(idr_remove_all);
+ #endif
diff --combined linux-core/drm_drv.c
@@@ -113,47 -113,16 +113,47 @@@ static drm_ioctl_desc_t drm_ioctls[] = 
        [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
  #endif
  
-       [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+       [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
        [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
  
        [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
 -      [DRM_IOCTL_NR(DRM_IOCTL_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
 -      [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
 +
 +      //      [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
 +
 +      [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
 +
 +
        [DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl, 
                                             DRM_AUTH },
 +      [DRM_IOCTL_NR(DRM_IOCTL_MM_TAKEDOWN)] = {drm_mm_takedown_ioctl, 
 +                                           DRM_AUTH },
 +      [DRM_IOCTL_NR(DRM_IOCTL_MM_LOCK)] = {drm_mm_lock_ioctl, 
 +                                           DRM_AUTH },
 +      [DRM_IOCTL_NR(DRM_IOCTL_MM_UNLOCK)] = {drm_mm_unlock_ioctl, 
 +                                           DRM_AUTH },
 +
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_CREATE)] = {drm_fence_create_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_DESTROY)] = {drm_fence_destroy_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_REFERENCE)] = {drm_fence_reference_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_UNREFERENCE)] = {drm_fence_unreference_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_SIGNALED)] = {drm_fence_signaled_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_FLUSH)] = {drm_fence_flush_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_WAIT)] = {drm_fence_wait_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_EMIT)] = {drm_fence_emit_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_FENCE_BUFFERS)] = {drm_fence_buffers_ioctl, DRM_AUTH},
 +
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_CREATE)] = {drm_bo_create_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_DESTROY)] = {drm_bo_destroy_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_MAP)] = {drm_bo_map_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_UNMAP)] = {drm_bo_unmap_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_REFERENCE)] = {drm_bo_reference_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_UNREFERENCE)] = {drm_bo_unreference_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_OP)] = {drm_bo_op_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_INFO)] = {drm_bo_info_ioctl, DRM_AUTH},
 +      [DRM_IOCTL_NR(DRM_IOCTL_BO_WAIT_IDLE)] = {drm_bo_wait_idle_ioctl, DRM_AUTH},
 +
 +
  
 -      [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
  };
  
  #define DRM_CORE_IOCTL_COUNT  ARRAY_SIZE( drm_ioctls )
  int drm_lastclose(drm_device_t * dev)
  {
        drm_magic_entry_t *pt, *next;
-       drm_map_list_t *r_list;
-       drm_vma_entry_t *vma, *vma_next;
+       drm_map_list_t *r_list, *list_t;
+       drm_vma_entry_t *vma, *vma_temp;
        int i;
  
        DRM_DEBUG("\n");
                drm_irq_uninstall(dev);
  
        /* Free drawable information memory */
-       for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield);
-            i++) {
-               drm_drawable_info_t *info = drm_get_drawable_info(dev, i);
-               if (info) {
-                       drm_free(info->rects, info->num_rects *
-                                sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
-                       drm_free(info, sizeof(*info), DRM_MEM_BUFS);
-               }
-       }
        mutex_lock(&dev->struct_mutex);
+       drm_drawable_free_all(dev);
        del_timer(&dev->timer);
  
        if (dev->unique) {
  
        /* Clear AGP information */
        if (drm_core_has_AGP(dev) && dev->agp) {
-               drm_agp_mem_t *entry;
-               drm_agp_mem_t *nexte;
+               drm_agp_mem_t *entry, *tempe;
  
                /* Remove AGP resources, but leave dev->agp
                   intact until drv_cleanup is called. */
-               for (entry = dev->agp->memory; entry; entry = nexte) {
-                       nexte = entry->next;
+               list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
                        if (entry->bound)
                                drm_unbind_agp(entry->memory);
                        drm_free_agp(entry->memory, entry->pages);
                        drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
                }
-               dev->agp->memory = NULL;
+               INIT_LIST_HEAD(&dev->agp->memory);
  
                if (dev->agp->acquired)
                        drm_agp_release(dev);
        }
  
        /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_ctl_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
+       list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
+               list_del(&vma->head);
+               drm_ctl_free(vma, sizeof(*vma), DRM_MEM_VMAS);
        }
-       if (dev->maplist) {
-               while (!list_empty(&dev->maplist->head)) {
-                       struct list_head *list = dev->maplist->head.next;
-                       r_list = list_entry(list, drm_map_list_t, head);
-                       drm_rmmap_locked(dev, r_list->map);
-               }
+       
+       list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
+               drm_rmmap_locked(dev, r_list->map);
+               r_list = NULL;
        }
  
        if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
@@@ -359,7 -311,7 +342,7 @@@ int drm_init(struct drm_driver *driver
        }
  
        if (!drm_fb_loaded)
-               pci_register_driver(&driver->pci_driver);
+               return pci_register_driver(&driver->pci_driver);
        else {
                for (i = 0; pciidlist[i].vendor != 0; i++) {
                        pid = &pciidlist[i];
@@@ -403,13 -355,9 +386,9 @@@ static void drm_cleanup(drm_device_t * 
        drm_lastclose(dev);
        drm_fence_manager_takedown(dev);
  
-       if (dev->maplist) {
-               drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
-               dev->maplist = NULL;
-               drm_ht_remove(&dev->map_hash);
-               drm_mm_takedown(&dev->offset_manager);
-               drm_ht_remove(&dev->object_hash);
-       }
+       drm_ht_remove(&dev->map_hash);
+       drm_mm_takedown(&dev->offset_manager);
+       drm_ht_remove(&dev->object_hash);
  
        if (!drm_fb_loaded)
                pci_disable_device(dev->pdev);
@@@ -625,7 -573,7 +604,7 @@@ int drm_ioctl(struct inode *inode, stru
                goto err_i1;
        if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
                && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
-                       ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+               ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
        else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
                ioctl = &drm_ioctls[nr];
        else
@@@ -654,39 -602,11 +633,11 @@@ err_i1
  }
  EXPORT_SYMBOL(drm_ioctl);
  
- int drm_wait_on(drm_device_t *dev, wait_queue_head_t *queue, int timeout,
-               int (*fn)(drm_device_t *dev, void *priv), void *priv)
- {
-       DECLARE_WAITQUEUE(entry, current);
-       unsigned long end = jiffies + (timeout);
-       int ret = 0;
-       add_wait_queue(queue, &entry);
-       for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-               if ((*fn)(dev, priv))
-                       break;
-               if (time_after_eq(jiffies, end)) {
-                       ret = -EBUSY;
-                       break;
-               }
-               schedule_timeout((HZ/100 > 1) ? HZ/100 : 1);
-               if (signal_pending(current)) {
-                       ret = -EINTR;
-                       break;
-               }
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(queue, &entry);
-       return ret;
- }
- EXPORT_SYMBOL(drm_wait_on);
  drm_local_map_t *drm_getsarea(struct drm_device *dev)
  {
        drm_map_list_t *entry;
  
-       list_for_each_entry(entry, &dev->maplist->head, head) {
+       list_for_each_entry(entry, &dev->maplist, head) {
                if (entry->map && entry->map->type == _DRM_SHM &&
                    (entry->map->flags & _DRM_CONTAINS_LOCK)) {
                        return entry->map;
diff --combined linux-core/drm_fence.c
@@@ -124,52 -124,76 +124,76 @@@ static void drm_fence_unring(drm_device
        write_unlock_irqrestore(&fm->lock, flags);
  }
  
- void drm_fence_usage_deref_locked(drm_device_t * dev,
-                                 drm_fence_object_t * fence)
+ void drm_fence_usage_deref_locked(drm_fence_object_t ** fence)
  {
+       struct drm_fence_object *tmp_fence = *fence;
+       struct drm_device *dev = tmp_fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
  
-       if (atomic_dec_and_test(&fence->usage)) {
-               drm_fence_unring(dev, &fence->ring);
+       DRM_ASSERT_LOCKED(&dev->struct_mutex);
+       *fence = NULL;
+       if (atomic_dec_and_test(&tmp_fence->usage)) {
+               drm_fence_unring(dev, &tmp_fence->ring);
                DRM_DEBUG("Destroyed a fence object 0x%08lx\n",
-                         fence->base.hash.key);
+                         tmp_fence->base.hash.key);
                atomic_dec(&fm->count);
-               drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+               BUG_ON(!list_empty(&tmp_fence->base.list));
+               drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
        }
  }
  
- void drm_fence_usage_deref_unlocked(drm_device_t * dev,
-                                   drm_fence_object_t * fence)
+ void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence)
  {
+       struct drm_fence_object *tmp_fence = *fence;
+       struct drm_device *dev = tmp_fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
  
-       if (atomic_dec_and_test(&fence->usage)) {
+       *fence = NULL;
+       if (atomic_dec_and_test(&tmp_fence->usage)) {
                mutex_lock(&dev->struct_mutex);
-               if (atomic_read(&fence->usage) == 0) {
-                       drm_fence_unring(dev, &fence->ring);
+               if (atomic_read(&tmp_fence->usage) == 0) {
+                       drm_fence_unring(dev, &tmp_fence->ring);
                        atomic_dec(&fm->count);
-                       drm_ctl_free(fence, sizeof(*fence), DRM_MEM_FENCE);
+                       BUG_ON(!list_empty(&tmp_fence->base.list));
+                       drm_ctl_free(tmp_fence, sizeof(*tmp_fence), DRM_MEM_FENCE);
                }
                mutex_unlock(&dev->struct_mutex);
        }
  }
  
- static void drm_fence_object_destroy(drm_file_t * priv,
-                                    drm_user_object_t * base)
+ struct drm_fence_object
+ *drm_fence_reference_locked(struct drm_fence_object *src)
+ {
+       DRM_ASSERT_LOCKED(&src->dev->struct_mutex);
+       atomic_inc(&src->usage);
+       return src;
+ }
+ void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+                                 struct drm_fence_object *src)
+ {
+       mutex_lock(&src->dev->struct_mutex);
+       *dst = src;
+       atomic_inc(&src->usage);
+       mutex_unlock(&src->dev->struct_mutex);
+ }
+ static void drm_fence_object_destroy(drm_file_t *priv, drm_user_object_t * base)
  {
-       drm_device_t *dev = priv->head->dev;
        drm_fence_object_t *fence =
            drm_user_object_entry(base, drm_fence_object_t, base);
  
-       drm_fence_usage_deref_locked(dev, fence);
+       drm_fence_usage_deref_locked(&fence);
  }
  
- static int fence_signaled(drm_device_t * dev,
-                         drm_fence_object_t * fence,
-                         uint32_t mask, int poke_flush)
+ int drm_fence_object_signaled(drm_fence_object_t * fence,
+                             uint32_t mask, int poke_flush)
  {
        unsigned long flags;
        int signaled;
+       struct drm_device *dev = fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
        drm_fence_driver_t *driver = dev->driver->fence_driver;
  
@@@ -200,16 -224,10 +224,10 @@@ static void drm_fence_flush_exe(drm_fen
        }
  }
  
- int drm_fence_object_signaled(drm_fence_object_t * fence,
-                             uint32_t type)
- {
-       return ((fence->signaled & type) == type);
- }
- int drm_fence_object_flush(drm_device_t * dev,
-                          drm_fence_object_t * fence,
+ int drm_fence_object_flush(drm_fence_object_t * fence,
                           uint32_t type)
  {
+       struct drm_device *dev = fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
        drm_fence_class_manager_t *fc = &fm->class[fence->class];
        drm_fence_driver_t *driver = dev->driver->fence_driver;
@@@ -272,24 -290,23 +290,23 @@@ void drm_fence_flush_old(drm_device_t 
                mutex_unlock(&dev->struct_mutex);
                return;
        }
-       fence = list_entry(fc->ring.next, drm_fence_object_t, ring);
-       atomic_inc(&fence->usage);
+       fence = drm_fence_reference_locked(list_entry(fc->ring.next, drm_fence_object_t, ring));
        mutex_unlock(&dev->struct_mutex);
        diff = (old_sequence - fence->sequence) & driver->sequence_mask;
        read_unlock_irqrestore(&fm->lock, flags);
        if (diff < driver->wrap_diff) {
-               drm_fence_object_flush(dev, fence, fence->type);
+               drm_fence_object_flush(fence, fence->type);
        }
-       drm_fence_usage_deref_unlocked(dev, fence);
+       drm_fence_usage_deref_unlocked(&fence);
  }
  
  EXPORT_SYMBOL(drm_fence_flush_old);
  
- static int drm_fence_lazy_wait(drm_device_t *dev,
-                              drm_fence_object_t *fence,
+ static int drm_fence_lazy_wait(drm_fence_object_t *fence,
                               int ignore_signals,
                               uint32_t mask)
  {
+       struct drm_device *dev = fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
        drm_fence_class_manager_t *fc = &fm->class[fence->class];
        int signaled;
  
        do {
                DRM_WAIT_ON(ret, fc->fence_queue, 3 * DRM_HZ,
-                           (signaled = fence_signaled(dev, fence, mask, 1)));
+                           (signaled = drm_fence_object_signaled(fence, mask, 1)));
                if (signaled)
                        return 0;
                if (time_after_eq(jiffies, _end))
                        break;
        } while (ret == -EINTR && ignore_signals);
-       if (fence_signaled(dev, fence, mask, 0))
+       if (drm_fence_object_signaled(fence, mask, 0))
                return 0;
        if (time_after_eq(jiffies, _end))
                ret = -EBUSY;
        return 0;
  }
  
- int drm_fence_object_wait(drm_device_t * dev,
-                         drm_fence_object_t * fence,
+ int drm_fence_object_wait(drm_fence_object_t * fence,
                          int lazy, int ignore_signals, uint32_t mask)
  {
+       struct drm_device *dev = fence->dev;
        drm_fence_driver_t *driver = dev->driver->fence_driver;
        int ret = 0;
        unsigned long _end;
                return -EINVAL;
        }
  
-       if (fence_signaled(dev, fence, mask, 0))
+       if (drm_fence_object_signaled(fence, mask, 0))
                return 0;
  
        _end = jiffies + 3 * DRM_HZ;
  
-       drm_fence_object_flush(dev, fence, mask);
+       drm_fence_object_flush(fence, mask);
  
        if (lazy && driver->lazy_capable) {
  
-               ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask);
+               ret = drm_fence_lazy_wait(fence, ignore_signals, mask);
                if (ret)
                        return ret;
  
  
                if (driver->has_irq(dev, fence->class,
                                    DRM_FENCE_TYPE_EXE)) {
-                       ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+                       ret = drm_fence_lazy_wait(fence, ignore_signals,
                                                  DRM_FENCE_TYPE_EXE);
                        if (ret)
                                return ret;
  
                if (driver->has_irq(dev, fence->class,
                                    mask & ~DRM_FENCE_TYPE_EXE)) {
-                       ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+                       ret = drm_fence_lazy_wait(fence, ignore_signals,
                                                  mask);
                        if (ret)
                                return ret;
                }
        }
-       if (drm_fence_object_signaled(fence, mask))
+       if (drm_fence_object_signaled(fence, mask, 0))
                return 0;
  
        /*
  #endif
        do {
                schedule();
-               signaled = fence_signaled(dev, fence, mask, 1);
+               signaled = drm_fence_object_signaled(fence, mask, 1);
        } while (!signaled && !time_after_eq(jiffies, _end));
  
        if (!signaled)
        return 0;
  }
  
- int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
+ int drm_fence_object_emit(drm_fence_object_t * fence,
                          uint32_t fence_flags, uint32_t class, uint32_t type)
  {
+       struct drm_device *dev = fence->dev;
        drm_fence_manager_t *fm = &dev->fm;
        drm_fence_driver_t *driver = dev->driver->fence_driver;
        drm_fence_class_manager_t *fc = &fm->class[fence->class];
@@@ -432,15 -450,22 +450,22 @@@ static int drm_fence_object_init(drm_de
  
        write_lock_irqsave(&fm->lock, flags);
        INIT_LIST_HEAD(&fence->ring);
+       /* 
+        *  Avoid hitting BUG() for kernel-only fence objects.
+        */
+       INIT_LIST_HEAD(&fence->base.list);
        fence->class = class;
        fence->type = type;
        fence->flush_mask = 0;
        fence->submitted_flush = 0;
        fence->signaled = 0;
        fence->sequence = 0;
+       fence->dev = dev;
        write_unlock_irqrestore(&fm->lock, flags);
        if (fence_flags & DRM_FENCE_FLAG_EMIT) {
-               ret = drm_fence_object_emit(dev, fence, fence_flags,
+               ret = drm_fence_object_emit(fence, fence_flags,
                                            fence->class, type);
        }
        return ret;
@@@ -454,15 -479,16 +479,16 @@@ int drm_fence_add_user_object(drm_file_
  
        mutex_lock(&dev->struct_mutex);
        ret = drm_add_user_object(priv, &fence->base, shareable);
-       mutex_unlock(&dev->struct_mutex);
        if (ret)
-               return ret;
+               goto out;
+       atomic_inc(&fence->usage);
        fence->base.type = drm_fence_type;
        fence->base.remove = &drm_fence_object_destroy;
        DRM_DEBUG("Fence 0x%08lx created\n", fence->base.hash.key);
-       return 0;
+ out:
+       mutex_unlock(&dev->struct_mutex);
+       return ret;
  }
  EXPORT_SYMBOL(drm_fence_add_user_object);
  
  int drm_fence_object_create(drm_device_t * dev, uint32_t class, uint32_t type,
        int ret;
        drm_fence_manager_t *fm = &dev->fm;
  
-       fence = drm_ctl_alloc(sizeof(*fence), DRM_MEM_FENCE);
+       fence = drm_ctl_calloc(1, sizeof(*fence), DRM_MEM_FENCE);
        if (!fence)
                return -ENOMEM;
        ret = drm_fence_object_init(dev, class, type, flags, fence);
        if (ret) {
-               drm_fence_usage_deref_unlocked(dev, fence);
+               drm_fence_usage_deref_unlocked(&fence);
                return ret;
        }
        *c_fence = fence;
@@@ -534,19 -560,19 +560,18 @@@ drm_fence_object_t *drm_lookup_fence_ob
                mutex_unlock(&dev->struct_mutex);
                return NULL;
        }
-       fence = drm_user_object_entry(uo, drm_fence_object_t, base);
-       atomic_inc(&fence->usage);
+       fence = drm_fence_reference_locked(drm_user_object_entry(uo, drm_fence_object_t, base));
        mutex_unlock(&dev->struct_mutex);
        return fence;
  }
  
 -int drm_fence_ioctl(DRM_IOCTL_ARGS)
 +int drm_fence_create_ioctl(DRM_IOCTL_ARGS)
  {
        DRM_DEVICE;
        int ret;
        drm_fence_manager_t *fm = &dev->fm;
        drm_fence_arg_t arg;
        drm_fence_object_t *fence;
 -      drm_user_object_t *uo;
        unsigned long flags;
        ret = 0;
  
        }
  
        DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 -      switch (arg.op) {
 -      case drm_fence_create:
 -              if (arg.flags & DRM_FENCE_FLAG_EMIT)
 -                      LOCK_TEST_WITH_RETURN(dev, filp);
 -              ret = drm_fence_object_create(dev, arg.class,
 -                                            arg.type, arg.flags, &fence);
 -              if (ret)
 -                      return ret;
 -              ret = drm_fence_add_user_object(priv, fence,
 -                                              arg.flags &
 -                                              DRM_FENCE_FLAG_SHAREABLE);
 -              if (ret) {
 -                      drm_fence_usage_deref_unlocked(&fence);
 -                      return ret;
 -              }
 -              arg.handle = fence->base.hash.key;
 +      if (arg.flags & DRM_FENCE_FLAG_EMIT)
 +              LOCK_TEST_WITH_RETURN(dev, filp);
 +      ret = drm_fence_object_create(dev, arg.class,
 +                                    arg.type, arg.flags, &fence);
 +      if (ret)
 +              return ret;
 +      ret = drm_fence_add_user_object(priv, fence,
 +                                      arg.flags &
 +                                      DRM_FENCE_FLAG_SHAREABLE);
 +      if (ret) {
-               drm_fence_usage_deref_unlocked(dev, fence);
++              drm_fence_usage_deref_unlocked(&fence);
 +              return ret;
 +      }
 +      
 +      /*
 +       * usage > 0. No need to lock dev->struct_mutex;
 +       */
 +      
 +      atomic_inc(&fence->usage);
 +      arg.handle = fence->base.hash.key;
  
 -              break;
 -      case drm_fence_destroy:
 -              mutex_lock(&dev->struct_mutex);
 -              uo = drm_lookup_user_object(priv, arg.handle);
 -              if (!uo || (uo->type != drm_fence_type) || uo->owner != priv) {
 -                      mutex_unlock(&dev->struct_mutex);
 -                      return -EINVAL;
 -              }
 -              ret = drm_remove_user_object(priv, uo);
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
-       drm_fence_usage_deref_unlocked(dev, fence);
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +int drm_fence_destroy_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_user_object_t *uo;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      mutex_lock(&dev->struct_mutex);
 +      uo = drm_lookup_user_object(priv, arg.handle);
 +      if (!uo || (uo->type != drm_fence_type) || uo->owner != priv) {
                mutex_unlock(&dev->struct_mutex);
 +              return -EINVAL;
 +      }
 +      ret = drm_remove_user_object(priv, uo);
 +      mutex_unlock(&dev->struct_mutex);
 +      return ret;
 +}
 +
 +
 +int drm_fence_reference_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      drm_user_object_t *uo;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +      ret = drm_user_object_ref(priv, arg.handle, drm_fence_type, &uo);
 +      if (ret)
                return ret;
 -      case drm_fence_reference:
 -              ret =
 -                  drm_user_object_ref(priv, arg.handle, drm_fence_type, &uo);
 -              if (ret)
 -                      return ret;
 -              fence = drm_lookup_fence_object(priv, arg.handle);
 -              break;
 -      case drm_fence_unreference:
 -              ret = drm_user_object_unref(priv, arg.handle, drm_fence_type);
 -              return ret;
 -      case drm_fence_signaled:
 -              fence = drm_lookup_fence_object(priv, arg.handle);
 -              if (!fence)
 -                      return -EINVAL;
 -              break;
 -      case drm_fence_flush:
 -              fence = drm_lookup_fence_object(priv, arg.handle);
 -              if (!fence)
 -                      return -EINVAL;
 -              ret = drm_fence_object_flush(fence, arg.type);
 -              break;
 -      case drm_fence_wait:
 -              fence = drm_lookup_fence_object(priv, arg.handle);
 -              if (!fence)
 -                      return -EINVAL;
 -              ret =
 -                  drm_fence_object_wait(fence,
 -                                        arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
 -                                        0, arg.type);
 -              break;
 -      case drm_fence_emit:
 -              LOCK_TEST_WITH_RETURN(dev, filp);
 -              fence = drm_lookup_fence_object(priv, arg.handle);
 -              if (!fence)
 -                      return -EINVAL;
 -              ret = drm_fence_object_emit(fence, arg.flags, arg.class,
 -                                          arg.type);
 -              break;
 -      case drm_fence_buffers:
 -              if (!dev->bm.initialized) {
 -                      DRM_ERROR("Buffer object manager is not initialized\n");
 -                      return -EINVAL;
 -              }
 -              LOCK_TEST_WITH_RETURN(dev, filp);
 -              ret = drm_fence_buffer_objects(priv, NULL, arg.flags,
 -                                             NULL, &fence);
 -              if (ret)
 -                      return ret;
 -              ret = drm_fence_add_user_object(priv, fence,
 -                                              arg.flags &
 -                                              DRM_FENCE_FLAG_SHAREABLE);
 -              if (ret)
 -                      return ret;
 -              arg.handle = fence->base.hash.key;
 -              break;
 -      default:
 +      fence = drm_lookup_fence_object(priv, arg.handle);
 +
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
-       drm_fence_usage_deref_unlocked(dev, fence);
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +
 +int drm_fence_unreference_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +      return drm_user_object_unref(priv, arg.handle, drm_fence_type);
 +}
 +
 +int drm_fence_signaled_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      fence = drm_lookup_fence_object(priv, arg.handle);
 +      if (!fence)
 +              return -EINVAL;
 +
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
-       drm_fence_usage_deref_unlocked(dev, fence);
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +int drm_fence_flush_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
                return -EINVAL;
        }
-       ret = drm_fence_object_flush(dev, fence, arg.type);
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      fence = drm_lookup_fence_object(priv, arg.handle);
 +      if (!fence)
 +              return -EINVAL;
-       drm_fence_usage_deref_unlocked(dev, fence);
++      ret = drm_fence_object_flush(fence, arg.type);
 +
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
-       ret = drm_fence_object_wait(dev, fence,
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +
 +int drm_fence_wait_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      fence = drm_lookup_fence_object(priv, arg.handle);
 +      if (!fence)
 +              return -EINVAL;
-       drm_fence_usage_deref_unlocked(dev, fence);
++      ret = drm_fence_object_wait(fence,
 +                                  arg.flags & DRM_FENCE_FLAG_WAIT_LAZY,
 +                                  0, arg.type);
 +
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
-       ret = drm_fence_object_emit(dev, fence, arg.flags, arg.class,
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +
 +int drm_fence_emit_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      LOCK_TEST_WITH_RETURN(dev, filp);
 +      fence = drm_lookup_fence_object(priv, arg.handle);
 +      if (!fence)
 +              return -EINVAL;
-       drm_fence_usage_deref_unlocked(dev, fence);
++      ret = drm_fence_object_emit(fence, arg.flags, arg.class,
 +                                  arg.type);
 +
 +      read_lock_irqsave(&fm->lock, flags);
 +      arg.class = fence->class;
 +      arg.type = fence->type;
 +      arg.signaled = fence->signaled;
 +      read_unlock_irqrestore(&fm->lock, flags);
++      drm_fence_usage_deref_unlocked(&fence);
 +
 +      DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
 +      return ret;
 +}
 +
 +int drm_fence_buffers_ioctl(DRM_IOCTL_ARGS)
 +{
 +      DRM_DEVICE;
 +      int ret;
 +      drm_fence_manager_t *fm = &dev->fm;
 +      drm_fence_arg_t arg;
 +      drm_fence_object_t *fence;
 +      unsigned long flags;
 +      ret = 0;
 +
 +      if (!fm->initialized) {
 +              DRM_ERROR("The DRM driver does not support fencing.\n");
 +              return -EINVAL;
 +      }
 +
 +      DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
 +
 +      if (!dev->bm.initialized) {
 +              DRM_ERROR("Buffer object manager is not initialized\n");
 +              return -EINVAL;
 +      }
 +      LOCK_TEST_WITH_RETURN(dev, filp);
 +      ret = drm_fence_buffer_objects(priv, NULL, arg.flags,
 +                                     NULL, &fence);
 +      if (ret)
 +              return ret;
 +      ret = drm_fence_add_user_object(priv, fence,
 +                                      arg.flags &
 +                                      DRM_FENCE_FLAG_SHAREABLE);
 +      if (ret)
 +              return ret;
 +      atomic_inc(&fence->usage);
 +      arg.handle = fence->base.hash.key;
 +
        read_lock_irqsave(&fm->lock, flags);
        arg.class = fence->class;
        arg.type = fence->type;
        arg.signaled = fence->signaled;
        read_unlock_irqrestore(&fm->lock, flags);
-       drm_fence_usage_deref_unlocked(dev, fence);
+       drm_fence_usage_deref_unlocked(&fence);
  
        DRM_COPY_TO_USER_IOCTL((void __user *)data, arg, sizeof(arg));
        return ret;
diff --combined linux-core/drm_objects.h
@@@ -29,7 -29,7 +29,7 @@@
   */
  
  #ifndef _DRM_OBJECTS_H
- #define _DRM_OJBECTS_H
+ #define _DRM_OBJECTS_H
  
  struct drm_device;
  
@@@ -141,6 -141,7 +141,7 @@@ extern int drm_user_object_unref(drm_fi
  
  typedef struct drm_fence_object {
        drm_user_object_t base;
+         struct drm_device *dev;
        atomic_t usage;
  
        /*
@@@ -196,31 -197,23 +197,31 @@@ extern void drm_fence_manager_init(stru
  extern void drm_fence_manager_takedown(struct drm_device *dev);
  extern void drm_fence_flush_old(struct drm_device *dev, uint32_t class,
                                uint32_t sequence);
- extern int drm_fence_object_flush(struct drm_device *dev,
-                                 drm_fence_object_t * fence, uint32_t type);
extern int drm_fence_object_signaled(drm_fence_object_t * fence, uint32_t type);
- extern void drm_fence_usage_deref_locked(struct drm_device *dev,
                                       drm_fence_object_t * fence);
- extern void drm_fence_usage_deref_unlocked(struct drm_device *dev,
-                                          drm_fence_object_t * fence);
- extern int drm_fence_object_wait(struct drm_device *dev,
                               drm_fence_object_t * fence,
+ extern int drm_fence_object_flush(drm_fence_object_t * fence, uint32_t type);
+ extern int drm_fence_object_signaled(drm_fence_object_t * fence,
                                   uint32_t type, int flush);
+ extern void drm_fence_usage_deref_locked(drm_fence_object_t ** fence);
extern void drm_fence_usage_deref_unlocked(drm_fence_object_t ** fence);
+ extern struct drm_fence_object *drm_fence_reference_locked(struct drm_fence_object *src);
+ extern void drm_fence_reference_unlocked(struct drm_fence_object **dst,
+                                        struct drm_fence_object *src);
extern int drm_fence_object_wait(drm_fence_object_t * fence,
                                 int lazy, int ignore_signals, uint32_t mask);
  extern int drm_fence_object_create(struct drm_device *dev, uint32_t type,
                                   uint32_t fence_flags, uint32_t class,
                                   drm_fence_object_t ** c_fence);
  extern int drm_fence_add_user_object(drm_file_t * priv,
                                     drm_fence_object_t * fence, int shareable);
 -extern int drm_fence_ioctl(DRM_IOCTL_ARGS);
  
 +extern int drm_fence_create_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_destroy_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_reference_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_unreference_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_signaled_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_flush_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_wait_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_emit_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_fence_buffers_ioctl(DRM_IOCTL_ARGS);
  /**************************************************
   *TTMs
   */
@@@ -321,8 -314,8 +322,8 @@@ typedef struct drm_bo_mem_reg 
        unsigned long num_pages;
        uint32_t page_alignment;
        uint32_t mem_type;
 -      uint32_t flags;
 -      uint32_t mask;
 +      uint64_t flags;
 +      uint64_t mask;
  } drm_bo_mem_reg_t;
  
  typedef struct drm_buffer_object {
@@@ -423,8 -416,8 +424,8 @@@ typedef struct drm_bo_driver 
        uint32_t num_mem_busy_prio;
        drm_ttm_backend_t *(*create_ttm_backend_entry)
         (struct drm_device * dev);
 -      int (*fence_type) (struct drm_buffer_object *bo, uint32_t * class, uint32_t * type);
 -      int (*invalidate_caches) (struct drm_device * dev, uint32_t flags);
 +      int (*fence_type) (struct drm_buffer_object *bo, uint32_t * type);
 +      int (*invalidate_caches) (struct drm_device * dev, uint64_t flags);
        int (*init_mem_type) (struct drm_device * dev, uint32_t type,
                              drm_mem_type_manager_t * man);
         uint32_t(*evict_mask) (struct drm_buffer_object *bo);
   * buffer objects (drm_bo.c)
   */
  
 -extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_create_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_destroy_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_map_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_unmap_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_reference_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_unreference_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_wait_idle_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_info_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_bo_op_ioctl(DRM_IOCTL_ARGS);
 +
 +
  extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_mm_takedown_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_mm_lock_ioctl(DRM_IOCTL_ARGS);
 +extern int drm_mm_unlock_ioctl(DRM_IOCTL_ARGS);
  extern int drm_bo_driver_finish(struct drm_device *dev);
  extern int drm_bo_driver_init(struct drm_device *dev);
  extern int drm_bo_pci_offset(struct drm_device *dev,
                             unsigned long *bus_size);
  extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem);
  
- extern void drm_bo_usage_deref_locked(drm_buffer_object_t * bo);
+ extern void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo);
  extern int drm_fence_buffer_objects(drm_file_t * priv,
                                    struct list_head *list,
                                    uint32_t fence_flags,
@@@ -492,4 -472,12 +493,12 @@@ extern int drm_bo_move_accel_cleanup(dr
                                     uint32_t fence_flags,
                                     drm_bo_mem_reg_t * new_mem);
  
+ #ifdef CONFIG_DEBUG_MUTEXES
+ #define DRM_ASSERT_LOCKED(_mutex)                                     \
+       BUG_ON(!mutex_is_locked(_mutex) ||                              \
+              ((_mutex)->owner != current_thread_info()))
+ #else
+ #define DRM_ASSERT_LOCKED(_mutex)
+ #endif
  #endif
diff --combined shared-core/i915_drv.h
@@@ -99,6 -99,8 +99,8 @@@ typedef struct drm_i915_private 
        void *hw_status_page;
        dma_addr_t dma_status_page;
        uint32_t counter;
+       unsigned int status_gfx_addr;
+       drm_local_map_t hws_map;
  
        unsigned int cpp;
        int use_mi_batchbuffer_start;
@@@ -196,8 -198,8 +198,8 @@@ extern int i915_fence_has_irq(drm_devic
  #ifdef I915_HAVE_BUFFER
  /* i915_buffer.c */
  extern drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t *dev);
 -extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *class, uint32_t *type);
 -extern int i915_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags);
 +extern int i915_fence_types(drm_buffer_object_t *bo, uint32_t *type);
 +extern int i915_invalidate_caches(drm_device_t *dev, uint64_t buffer_flags);
  extern int i915_init_mem_type(drm_device_t *dev, uint32_t type,
                               drm_mem_type_manager_t *man);
  extern uint32_t i915_evict_mask(drm_buffer_object_t *bo);
@@@ -361,6 -363,9 +363,9 @@@ extern int i915_wait_ring(drm_device_t 
  
  #define CMD_OP_DESTBUFFER_INFO         ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
  
+ #define BREADCRUMB_BITS 31
+ #define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
  #define READ_BREADCRUMB(dev_priv)  (((volatile u32*)(dev_priv->hw_status_page))[5])
  #define READ_HWSP(dev_priv, reg)  (((volatile u32*)(dev_priv->hw_status_page))[reg])
  #endif