Nigel Horne | 25 May 17:48
Picon

Bug#674575: xorg eats CPU time

Package: xorg
Version: 1:7.6+13
Severity: important

Dear Maintainer,
*** Please consider answering these questions, where appropriate ***

   * What led up to the situation?
   I logged in
   * What exactly did you do (or not do) that was effective (or
     ineffective)?
   Nothing
   * What was the outcome of this action?
   N/A
   * What outcome did you expect instead?
   N/A


Xorg eats CPU.  Even when I do nothing for 5 minutes to let the system
settle down, uptime gives a value of nearly 1 and 'top' shows Xorg is using
a lot of CPU.


-- Package-specific info:
X server symlink status:
------------------------
lrwxrwxrwx 1 root root 13 Sep 22  2009 /etc/X11/X -> /usr/bin/Xorg
-rwxr-xr-x 1 root root 2044664 May 20 04:59 /usr/bin/Xorg

VGA-compatible devices on PCI bus:
(Continue reading)

Andreas Beckmann | 25 May 14:56
Picon

Bug#674563: mesa: install libGL.so* into $libdir/mesa, add links to $libdir

Source: mesa
Version: 7.11.2-1
Severity: wishlist
Tags: patch

Hi,

this is in response to a thread started here:
http://lists.debian.org/debian-x/2011/07/msg00292.html
and later continued here:
http://lists.debian.org/debian-x/2011/10/msg00137.html

In order to simplify managing alternative GL implementations, I propose
to ship the MESA libraries in $libdir/mesa/ with symlinks to libGL.so.1
and libGL.so in $libdir/
This is a first start and helps to reduce the number of diversions
needed.
The next step would be the use of some alternatives system directly
in the MESA packages (that needs to be multi-arch aware). This will
remove the need for diversions at all, but needs more discussion ...

I also sent some patches to debian-x@ but never submitted a bug report,
so these patches for moving libGL* probably were forgotten:
http://lists.debian.org/debian-x/2011/10/msg00149.html (for GL)
http://lists.debian.org/debian-x/2011/10/msg00378.html (for EGL, GLES)

If anyone is interested, I'll update the patches for MESA 8.

Andreas

(Continue reading)

Loïc Fejoz | 25 May 11:37
Gravatar

Bug#661073: xorg crashes [SOLVED]

Hi,

I was having the same trouble and after lurking on the web, especially 
[1], I found how to avoid it:
jsut remove the FontPath with unix paths style from /etc/X11/xorg.conf !

I have just rebooted and launch previously applications known to crash 
and it works...

I do not know what/who has written this line in the configuration. I 
have migrated from Squeeze to testing a while ago, may it helps?

[1] 
https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers/+bug/927288

--

-- 
Regards,
Loïc Fejoz

Fred Korz | 25 May 05:38

Bug#674501: xserver-xorg-video-openchrome: gdm3 spawns tens of slaves and X servers after upgrade to 0.2.904+svn1050-1+b1

Package: xserver-xorg-video-openchrome
Version: 1:0.2.904+svn1050-1+b1
Severity: important

Dear Maintainer,

   [* What led up to the situation?]

Been running "testing" for 8 years now.  Currently that's wheezy. Do
dist-upgrade daily and reboot & backup weekly.

Reboot on 2012.05.20 after dist-upgrade failed to bring up network and display.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?

Rebooted single user, manually configured network to get debugging
access off of console.  (New startup sequences, network configured by
network manager and that isn't started until it has a screen to start
on.  So if gdm3 doesn't come up, you loose your network path onto the
system, e.g. sshd. *boo*) Worked around that by reinstalling the old
ifupdown package, which had been autoremoved but config data left in
place.

With ssh access, investigated server and found 40 to 80
/usr/lib/gdm3/gdm-simple-slave processes, all children of one
/usr/sbin/gdm3, and each slave had started a /usr/bin/Xorg instance.

Putting an xorg.conf in place that forces vesa driver rather than
automatically picking up openchrome, got at least default 1024x768
(Continue reading)

Chase Douglas | 24 May 19:35
Picon
Favicon

xserver-xorg-input-evdev: Changes to 'ubuntu'

 debian/changelog |    7 +++++++
 1 file changed, 7 insertions(+)

New commits:
commit 8855f38a4e45a5d27d3c03b5809d63791c659980
Author: Chase Douglas <chase.douglas <at> canonical.com>
Date:   Fri May 18 11:10:10 2012 -0700

    releasing version 1:2.7.0-0ubuntu1.1

diff --git a/debian/changelog b/debian/changelog
index 8fc1ffb..afc9845 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+xserver-xorg-input-evdev (1:2.7.0-0ubuntu1.1) precise-proposed; urgency=low
+
+  * Rebuild to fix an ABI breakage causing crashes when headsets are plugged in
+    (LP: #973297)
+
+ -- Chase Douglas <chase.douglas <at> ubuntu.com>  Fri, 18 May 2012 11:05:44 -0700
+
 xserver-xorg-input-evdev (1:2.7.0-0ubuntu1) precise; urgency=low

   * New upstream release

Stefan Nagy | 24 May 15:06
Picon
Gravatar

Bug#667754: xserver-xorg-video-radeon: [RV250] Gnome shell unusable (permanent crashes)

After installing some updates – sorry, I don't know which was the
relevant one, I assume gnome-shell – I'm forced into GNOME fallback mode
now; I suppose my graphics hardware got blacklisted.

xsession-errors contains the following lines:
> gnome-session-is-accelerated: No hardware 3D support.
> gnome-session-check-accelerated: Helper exited with code 256

Does it make any sense to switch to GNOME shell with 'gnome-shell
--replace' and add more information to this report? Or is there a way to
avoid fallback mode for testing purposes?

Thanks,
Stefan.
Sven Joachim | 24 May 14:53
Picon
Favicon

xserver-xorg-video-nouveau: Changes to 'debian-unstable'

 debian/patches/02-drm-nouveau-newabi.patch |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

New commits:
commit 860471c98557a538a7bcd70183e6ed49113145b4
Author: Sven Joachim <svenjoac <at> gmx.de>
Date:   Thu May 24 14:45:44 2012 +0200

    Amend Maarten's hack by setting AC_SYS_LARGEFILE in configure.ac

    The driver does not need this, but the included libdrm_nouveau
    requires a 64-bit off_t.  With a 32-bit off_t, mmap in
    nouveau_bo_map() could easily fail since nvbo->map_handle is of type
    uint64_t.

diff --git a/debian/patches/02-drm-nouveau-newabi.patch b/debian/patches/02-drm-nouveau-newabi.patch
index 8179f9f..95ffce9 100644
--- a/debian/patches/02-drm-nouveau-newabi.patch
+++ b/debian/patches/02-drm-nouveau-newabi.patch
@@ -4,11 +4,24 @@ Date:   Wed May 23 09:29:29 2012 +0200

     awful hack to remove dependency on libdrm_nouveau

+[ Amendment by Sven Joachim <svenjoac <at> gmx.de>: Set AC_SYS_LARGEFILE
+  in configure.ac, required by the included libdrm_nouveau. ]
+
 diff --git a/configure.ac b/configure.ac
-index afb6cde..7326144 100644
+index afb6cde..233b4ba 100644
 --- a/configure.ac
(Continue reading)

Picon

Processed: Re: xfonts-100dpi: fonts not available until X restarted

Processing commands for control <at> bugs.debian.org:

> reopen 673170
Bug #673170 {Done: Julien Cristau <jcristau <at> debian.org>} [xfs] xfonts-100dpi: fonts not available
until X restarted
Bug reopened
Ignoring request to alter fixed versions of bug #673170 to the same values previously set
>
End of message, stopping processing here.

Please contact me if you need assistance.
--

-- 
673170: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=673170
Debian Bug Tracking System
Contact owner <at> bugs.debian.org with problems

DAVID HAND | 23 May 16:58
Favicon

Bug#673669: Additional info

Forgot to say I have a laptop with VGA out - with an nvidia go 7600 with which I could test the monitor bypassing the DVI>VGA adapter, though my hunch is that the adapter is not the problem. Not only does windows work with the same hardware configuration, but I remember having resolution issues since 2006, when the monitor was being used with a different machine using an ATI video card.

Michal Suchanek | 23 May 11:13
Picon

Bug#642433: xserver-xorg-core: crashes on pressing random keys on the keyboard while screen locked

Package: xserver-xorg-core
Version: 2:1.12.1.902-1
Followup-For: Bug #642433

With 1.12.1 and 1.12.1.902-1 the X server crashes again.

Attaching patch.

VGA-compatible devices on PCI bus:
----------------------------------
01:00.0 VGA compatible controller [0300]: Advanced Micro Devices [AMD] nee ATI Cedar PRO [Radeon HD 5450] [1002:68f9]

/etc/X11/xorg.conf does not exist.

Contents of /etc/X11/xorg.conf.d:
---------------------------------
total 8
-rw-r--r-- 1 root root 129 Oct  6  2011 10-trackball-middle-emu.conf
-rw-r--r-- 1 root root 150 Oct  6  2011 10-trackball-middle-emu.conf~

KMS configuration files:
------------------------
/etc/modprobe.d/radeon-kms.conf:
  options radeon modeset=1

Kernel version (/proc/version):
-------------------------------
Linux version 3.2.0-2-amd64 (Debian 3.2.16-1) (debian-kernel <at> lists.debian.org) (gcc version 4.6.3
(Debian 4.6.3-1) ) #1 SMP Mon Apr 30 05:20:23 UTC 2012

Xorg X server log files on system:
----------------------------------
-rw-r--r-- 1 root root 43446 Oct  7  2011 /var/log/Xorg.2.log
-rw-r--r-- 1 root root 32234 May  2 13:06 /var/log/Xorg.!.log
-rw-r--r-- 1 root root 56401 May 23 10:28 /var/log/Xorg.1.log
-rw-r--r-- 1 root root 51686 May 23 11:07 /var/log/Xorg.0.log

-- System Information:
Debian Release: wheezy/sid
  APT prefers stable
  APT policy: (900, 'stable'), (500, 'testing'), (410, 'unstable'), (200, 'experimental'), (111, 'oldstable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to en_US.UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages xserver-xorg-core depends on:
ii  keyboard-configuration  1.68+squeeze2
ii  libaudit0               1:1.7.18-1.1
ii  libc6                   2.13-32
ii  libdrm2                 2.4.33+git20120502.52887298-0ubuntu0sarvatt~precise
ii  libgcrypt11             1.5.0-3
ii  libpciaccess0           0.13.1-2
ii  libpixman-1-0           0.24.4-1
ii  libselinux1             2.1.9-2
ii  libudev0                164-3
ii  libxau6                 1:1.0.7-1
ii  libxdmcp6               1:1.1.1-1
ii  libxfont1               1:1.4.5-2
ii  udev                    164-3
ii  xserver-common          2:1.13+git-20120423113043~6a1fdcd

Versions of packages xserver-xorg-core recommends:
ii  libgl1-mesa-dri  8.1~git20120503.1bd3dafe-0ubuntu0ricotz~precisenw1

Versions of packages xserver-xorg-core suggests:
pn  xfonts-100dpi | xfonts-75dpi  <none>
pn  xfonts-scalable               <none>

-- no debconf information
Attachment (fix-crash.patch): text/x-diff, 526 bytes
Maarten Lankhorst | 23 May 10:31
Picon
Favicon

xserver-xorg-video-nouveau: Changes to 'debian-unstable'

 ChangeLog                                  |  195 ++
 configure.ac                               |    2 
 debian/changelog                           |    9 
 debian/patches/02-drm-nouveau-newabi.patch | 2272 +++++++++++++++++++++++++++++
 debian/patches/series                      |    1 
 src/Makefile.am                            |    4 
 src/drmmode_display.c                      |   30 
 src/nouveau_dri2.c                         |   32 
 src/nouveau_exa.c                          |   29 
 src/nouveau_local.h                        |  186 +-
 src/nouveau_wfb.c                          |    4 
 src/nouveau_xv.c                           |   69 
 src/nv04_accel.h                           |   83 +
 src/nv04_exa.c                             |  524 +++---
 src/nv04_xv_blit.c                         |  262 +--
 src/nv10_exa.c                             |  857 ++++------
 src/nv30_exa.c                             |  975 ++++++------
 src/nv30_shaders.c                         |  347 ----
 src/nv30_shaders.h                         |   72 
 src/nv30_xv_tex.c                          |  302 +--
 src/nv40_exa.c                             |  994 +++++++-----
 src/nv40_xv_tex.c                          |  293 +--
 src/nv50_accel.c                           |  670 ++++----
 src/nv50_accel.h                           |   66 
 src/nv50_exa.c                             |  895 +++++------
 src/nv50_xv.c                              |  381 +---
 src/nv_accel_common.c                      |  582 +++----
 src/nv_dma.c                               |   77 
 src/nv_dma.h                               |    4 
 src/nv_driver.c                            |   43 
 src/nv_include.h                           |   11 
 src/nv_proto.h                             |    7 
 src/nv_shadow.c                            |    3 
 src/nv_type.h                              |   53 
 src/nvc0_accel.c                           |  841 ++--------
 src/nvc0_accel.h                           |  120 -
 src/nvc0_exa.c                             |  974 +++++-------
 src/nvc0_shader.h                          |  444 +++++
 src/nvc0_xv.c                              |  374 +---
 src/nve0_shader.h                          |  460 +++++
 40 files changed, 8045 insertions(+), 5502 deletions(-)

New commits:
commit c20b687c6f92abb63eb019c1778cb5b465ac1b57
Author: Maarten Lankhorst <m.b.lankhorst <at> gmail.com>
Date:   Wed May 23 10:08:34 2012 +0200

    Add 02-drm-nouveau-newabi.patch to build with old libdrm

    Until mesa 8.1 is released, we cannot build with new libdrm yet

diff --git a/debian/changelog b/debian/changelog
index 55d53bb..e96e86b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,8 @@ xserver-xorg-video-nouveau (1:0.0.16+git20120523+5815644-1) UNRELEASED; urgency=

   [ Maarten Lankhorst ]
   * New upstream snapshot. First one to have the new ABI.
+  * Add 02-drm-nouveau-newabi.patch to build with old libdrm
+  - Until mesa 8.1 is released, we cannot build with new libdrm yet

  -- Maarten Lankhorst <maarten.lankhorst <at> canonical.com>  Wed, 23 May 2012 09:45:06 +0200

diff --git a/debian/patches/02-drm-nouveau-newabi.patch b/debian/patches/02-drm-nouveau-newabi.patch
new file mode 100644
index 0000000..8179f9f
--- /dev/null
+++ b/debian/patches/02-drm-nouveau-newabi.patch
@@ -0,0 +1,2272 @@
+commit d99486bda5601cb887ac898037a2dfad795aeb8f
+Author: Maarten Lankhorst <m.b.lankhorst <at> gmail.com>
+Date:   Wed May 23 09:29:29 2012 +0200
+
+    awful hack to remove dependency on libdrm_nouveau
+
+diff --git a/configure.ac b/configure.ac
+index afb6cde..7326144 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -67,7 +67,8 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto)
+ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
+ 
+ # Checks for pkg-config packages
+-PKG_CHECK_MODULES(LIBDRM_NOUVEAU, [libdrm_nouveau >= 2.4.25])
++PKG_CHECK_MODULES(LIBDRM_NOUVEAU_DUMMY, [libdrm_nouveau = 0.6])
++PKG_CHECK_MODULES(LIBDRM_NOUVEAU, [libdrm])
+ AC_SUBST(LIBDRM_NOUVEAU_CFLAGS)
+ AC_SUBST(LIBDRM_NOUVEAU_LIBS)
+ 
+diff --git a/drm_nouveau/abi16.c b/drm_nouveau/abi16.c
+new file mode 100644
+index 0000000..69a0a9b
+--- /dev/null
++++ b/drm_nouveau/abi16.c
+@@ -0,0 +1,198 @@
++/*
++ * Copyright 2012 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Ben Skeggs
++ */
++
++#include <stdlib.h>
++#include <stdint.h>
++
++#include "private.h"
++
++int
++abi16_chan_nv04(struct nouveau_object *obj)
++{
++	struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
++	struct drm_nouveau_channel_alloc req;
++	struct nv04_fifo *nv04 = obj->data;
++	int ret;
++
++	req.fb_ctxdma_handle = nv04->vram;
++	req.tt_ctxdma_handle = nv04->gart;
++
++	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
++				  &req, sizeof(req));
++	if (ret)
++		return ret;
++
++	nv04->base.channel = req.channel;
++	nv04->base.pushbuf = req.pushbuf_domains;
++	nv04->notify = req.notifier_handle;
++	nv04->base.object->handle = req.channel;
++	nv04->base.object->length = sizeof(*nv04);
++	return 0;
++}
++
++int
++abi16_chan_nvc0(struct nouveau_object *obj)
++{
++	struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
++	struct drm_nouveau_channel_alloc req = {};
++	struct nvc0_fifo *nvc0 = obj->data;
++	int ret;
++
++	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
++				  &req, sizeof(req));
++	if (ret)
++		return ret;
++
++	nvc0->base.channel = req.channel;
++	nvc0->base.pushbuf = req.pushbuf_domains;
++	nvc0->notify = req.notifier_handle;
++	nvc0->base.object->handle = req.channel;
++	nvc0->base.object->length = sizeof(*nvc0);
++	return 0;
++}
++
++int
++abi16_engobj(struct nouveau_object *obj)
++{
++	struct drm_nouveau_grobj_alloc req = {
++		obj->parent->handle, obj->handle, obj->oclass
++	};
++	struct nouveau_device *dev;
++	int ret;
++
++	dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
++	ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
++			      &req, sizeof(req));
++	if (ret)
++		return ret;
++
++	obj->length = sizeof(struct nouveau_object *);
++	return 0;
++}
++
++int
++abi16_ntfy(struct nouveau_object *obj)
++{
++	struct nv04_notify *ntfy = obj->data;
++	struct drm_nouveau_notifierobj_alloc req = {
++		obj->parent->handle, ntfy->object->handle, ntfy->length
++	};
++	struct nouveau_device *dev;
++	int ret;
++
++	dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
++	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
++				  &req, sizeof(req));
++	if (ret)
++		return ret;
++
++	ntfy->offset = req.offset;
++	ntfy->object->length = sizeof(*ntfy);
++	return 0;
++}
++
++void
++abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
++{
++	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
++
++	nvbo->map_handle = info->map_handle;
++	bo->handle = info->handle;
++	bo->size = info->size;
++	bo->offset = info->offset;
++
++	bo->flags = 0;
++	if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM)
++		bo->flags |= NOUVEAU_BO_VRAM;
++	if (info->domain & NOUVEAU_GEM_DOMAIN_GART)
++		bo->flags |= NOUVEAU_BO_GART;
++	if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG))
++		bo->flags |= NOUVEAU_BO_CONTIG;
++	if (nvbo->map_handle)
++		bo->flags |= NOUVEAU_BO_MAP;
++
++	if (bo->device->chipset >= 0xc0) {
++		bo->config.nvc0.memtype   = (info->tile_flags & 0xff00) >> 8;
++		bo->config.nvc0.tile_mode = info->tile_mode;
++	} else
++	if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) {
++		bo->config.nv50.memtype   = (info->tile_flags & 0x07f00) >> 8 |
++					    (info->tile_flags & 0x30000) >> 9;
++		bo->config.nv50.tile_mode = info->tile_mode << 4;
++	} else {
++		bo->config.nv04.surf_flags = info->tile_flags & 7;
++		bo->config.nv04.surf_pitch = info->tile_mode;
++	}
++}
++
++int
++abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
++	      union nouveau_bo_config *config)
++{
++	struct nouveau_device *dev = bo->device;
++	struct drm_nouveau_gem_new req = {};
++	struct drm_nouveau_gem_info *info = &req.info;
++	int ret;
++
++	if (bo->flags & NOUVEAU_BO_VRAM)
++		info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
++	if (bo->flags & NOUVEAU_BO_GART)
++		info->domain |= NOUVEAU_GEM_DOMAIN_GART;
++	if (!info->domain)
++		info->domain |= NOUVEAU_GEM_DOMAIN_VRAM |
++				NOUVEAU_GEM_DOMAIN_GART;
++
++	if (bo->flags & NOUVEAU_BO_MAP)
++		info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
++
++	if (!(bo->flags & NOUVEAU_BO_CONTIG))
++		info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
++
++	info->size = bo->size;
++	req.align = alignment;
++
++	if (config) {
++		if (dev->chipset >= 0xc0) {
++			info->tile_flags = (config->nvc0.memtype & 0xff) << 8;
++			info->tile_mode  = config->nvc0.tile_mode;
++		} else
++		if (dev->chipset >= 0x80 || dev->chipset == 0x50) {
++			info->tile_flags = (config->nv50.memtype & 0x07f) << 8 |
++					   (config->nv50.memtype & 0x180) << 9;
++			info->tile_mode  = config->nv50.tile_mode >> 4;
++		} else {
++			info->tile_flags = config->nv04.surf_flags & 7;
++			info->tile_mode  = config->nv04.surf_pitch;
++		}
++	}
++
++	if (!nouveau_device(dev)->have_bo_usage)
++		info->tile_flags &= 0x0000ff00;
++
++	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
++				  &req, sizeof(req));
++	if (ret == 0)
++		abi16_bo_info(bo, &req.info);
++	return ret;
++}
+diff --git a/drm_nouveau/bufctx.c b/drm_nouveau/bufctx.c
+new file mode 100644
+index 0000000..23d6f09
+--- /dev/null
++++ b/drm_nouveau/bufctx.c
+@@ -0,0 +1,170 @@
++/*
++ * Copyright 2012 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Ben Skeggs
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <stdbool.h>
++#include <assert.h>
++#include <errno.h>
++
++#include "libdrm_lists.h"
++
++#include "nouveau.h"
++#include "private.h"
++
++struct nouveau_bufref_priv {
++	struct nouveau_bufref base;
++	struct nouveau_bufref_priv *next;
++	struct nouveau_bufctx *bufctx;
++};
++
++static inline struct nouveau_bufref_priv *
++nouveau_bufref(struct nouveau_bufref *bctx)
++{
++	return (struct nouveau_bufref_priv *)bctx;
++}
++
++struct nouveau_bufbin_priv {
++	struct nouveau_bufref_priv *list;
++	int relocs;
++};
++
++struct nouveau_bufctx_priv {
++	struct nouveau_bufctx base;
++	struct nouveau_bufref_priv *free;
++	int nr_bins;
++	struct nouveau_bufbin_priv bins[];
++};
++
++static inline struct nouveau_bufctx_priv *
++nouveau_bufctx(struct nouveau_bufctx *bctx)
++{
++	return (struct nouveau_bufctx_priv *)bctx;
++}
++
++int
++nouveau_bufctx_new(struct nouveau_client *client, int bins,
++		   struct nouveau_bufctx **pbctx)
++{
++	struct nouveau_bufctx_priv *priv;
++
++	priv = calloc(1, sizeof(*priv) + sizeof(priv->bins[0]) * bins);
++	if (priv) {
++		DRMINITLISTHEAD(&priv->base.head);
++		DRMINITLISTHEAD(&priv->base.pending);
++		DRMINITLISTHEAD(&priv->base.current);
++		priv->base.client = client;
++		priv->nr_bins = bins;
++		*pbctx = &priv->base;
++		return 0;
++	}
++
++	return -ENOMEM;
++}
++
++void
++nouveau_bufctx_del(struct nouveau_bufctx **pbctx)
++{
++	struct nouveau_bufctx_priv *pctx = nouveau_bufctx(*pbctx);
++	struct nouveau_bufref_priv *pref;
++	if (pctx) {
++		while (pctx->nr_bins--)
++			nouveau_bufctx_reset(&pctx->base, pctx->nr_bins);
++		while ((pref = pctx->free)) {
++			pctx->free = pref->next;
++			free(pref);
++		}
++		free(pctx);
++		*pbctx = NULL;
++	}
++}
++
++void
++nouveau_bufctx_reset(struct nouveau_bufctx *bctx, int bin)
++{
++	struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
++	struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
++	struct nouveau_bufref_priv *pref;
++
++	while ((pref = pbin->list)) {
++		DRMLISTDELINIT(&pref->base.thead);
++		pbin->list = pref->next;
++		pref->next = pctx->free;
++		pctx->free = pref;
++	}
++
++	bctx->relocs -= pbin->relocs;
++	pbin->relocs  = 0;
++}
++
++struct nouveau_bufref *
++nouveau_bufctx_refn(struct nouveau_bufctx *bctx, int bin,
++		    struct nouveau_bo *bo, uint32_t flags)
++{
++	struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
++	struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
++	struct nouveau_bufref_priv *pref = pctx->free;
++
++	if (!pref)
++		pref = malloc(sizeof(*pref));
++	else
++		pctx->free = pref->next;
++
++	if (pref) {
++		pref->base.bo = bo;
++		pref->base.flags = flags;
++		pref->base.packet = 0;
++
++		DRMLISTADDTAIL(&pref->base.thead, &bctx->pending);
++		pref->bufctx = bctx;
++		pref->next = pbin->list;
++		pbin->list = pref;
++	}
++
++	return &pref->base;
++}
++
++struct nouveau_bufref *
++nouveau_bufctx_mthd(struct nouveau_bufctx *bctx, int bin, uint32_t packet,
++		    struct nouveau_bo *bo, uint64_t data, uint32_t flags,
++		    uint32_t vor, uint32_t tor)
++{
++	struct nouveau_bufctx_priv *pctx = nouveau_bufctx(bctx);
++	struct nouveau_bufbin_priv *pbin = &pctx->bins[bin];
++	struct nouveau_bufref *bref = nouveau_bufctx_refn(bctx, bin, bo, flags);
++	if (bref) {
++		bref->packet = packet;
++		bref->data = data;
++		bref->vor = vor;
++		bref->tor = tor;
++		pbin->relocs++;
++		bctx->relocs++;
++	}
++	return bref;
++}
+diff --git a/drm_nouveau/libdrm_lists.h b/drm_nouveau/libdrm_lists.h
+new file mode 100644
+index 0000000..8926d8d
+--- /dev/null
++++ b/drm_nouveau/libdrm_lists.h
+@@ -0,0 +1,118 @@
++/**************************************************************************
++ *
++ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sub license, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
++ * USE OR OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial portions
++ * of the Software.
++ */
++
++/*
++ * List macros heavily inspired by the Linux kernel
++ * list handling. No list looping yet.
++ */
++
++#include <stddef.h>
++
++typedef struct _drmMMListHead
++{
++    struct _drmMMListHead *prev;
++    struct _drmMMListHead *next;
++} drmMMListHead;
++
++#define DRMINITLISTHEAD(__item)		       \
++  do{					       \
++    (__item)->prev = (__item);		       \
++    (__item)->next = (__item);		       \
++  } while (0)
++
++#define DRMLISTADD(__item, __list)		\
++  do {						\
++    (__item)->prev = (__list);			\
++    (__item)->next = (__list)->next;		\
++    (__list)->next->prev = (__item);		\
++    (__list)->next = (__item);			\
++  } while (0)
++
++#define DRMLISTADDTAIL(__item, __list)		\
++  do {						\
++    (__item)->next = (__list);			\
++    (__item)->prev = (__list)->prev;		\
++    (__list)->prev->next = (__item);		\
++    (__list)->prev = (__item);			\
++  } while(0)
++
++#define DRMLISTDEL(__item)			\
++  do {						\
++    (__item)->prev->next = (__item)->next;	\
++    (__item)->next->prev = (__item)->prev;	\
++  } while(0)
++
++#define DRMLISTDELINIT(__item)			\
++  do {						\
++    (__item)->prev->next = (__item)->next;	\
++    (__item)->next->prev = (__item)->prev;	\
++    (__item)->next = (__item);			\
++    (__item)->prev = (__item);			\
++  } while(0)
++
++#define DRMLISTENTRY(__type, __item, __field)   \
++    ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
++
++#define DRMLISTEMPTY(__item) ((__item)->next == (__item))
++
++#define DRMLISTSINGLE(__list) \
++	(!DRMLISTEMPTY(__list) && ((__list)->next == (__list)->prev))
++
++#define DRMLISTFOREACH(__item, __list)					\
++	for ((__item) = (__list)->next;					\
++	     (__item) != (__list); (__item) = (__item)->next)
++
++#define DRMLISTFOREACHSAFE(__item, __temp, __list)			\
++	for ((__item) = (__list)->next, (__temp) = (__item)->next;	\
++	     (__item) != (__list);					\
++	     (__item) = (__temp), (__temp) = (__item)->next)
++
++#define DRMLISTFOREACHSAFEREVERSE(__item, __temp, __list)		\
++	for ((__item) = (__list)->prev, (__temp) = (__item)->prev;	\
++	     (__item) != (__list);					\
++	     (__item) = (__temp), (__temp) = (__item)->prev)
++
++#define DRMLISTFOREACHENTRY(__item, __list, __head)                            \
++	for ((__item) = DRMLISTENTRY(typeof(*__item), (__list)->next, __head); \
++	     &(__item)->__head != (__list);                                    \
++	     (__item) = DRMLISTENTRY(typeof(*__item),                          \
++				     (__item)->__head.next, __head))
++
++#define DRMLISTFOREACHENTRYSAFE(__item, __temp, __list, __head)                \
++	for ((__item) = DRMLISTENTRY(typeof(*__item), (__list)->next, __head), \
++	     (__temp) = DRMLISTENTRY(typeof(*__item),                          \
++				     (__item)->__head.next, __head);           \
++	     &(__item)->__head != (__list);                                    \
++	     (__item) = (__temp),                                              \
++	     (__temp) = DRMLISTENTRY(typeof(*__item),                          \
++				     (__temp)->__head.next, __head))
++
++#define DRMLISTJOIN(__list, __join) if (!DRMLISTEMPTY(__list)) {	\
++	(__list)->next->prev = (__join);				\
++	(__list)->prev->next = (__join)->next;				\
++	(__join)->next->prev = (__list)->prev;				\
++	(__join)->next = (__list)->next;				\
++}
+diff --git a/drm_nouveau/nouveau.c b/drm_nouveau/nouveau.c
+new file mode 100644
+index 0000000..5aa4107
+--- /dev/null
++++ b/drm_nouveau/nouveau.c
+@@ -0,0 +1,492 @@
++/*
++ * Copyright 2012 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Ben Skeggs
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <string.h>
++#include <stdbool.h>
++#include <assert.h>
++#include <errno.h>
++#include <sys/mman.h>
++
++#include <xf86drm.h>
++#include <xf86atomic.h>
++#include "libdrm_lists.h"
++#include "nouveau_drm.h"
++
++#include "nouveau.h"
++#include "private.h"
++
++#ifdef DEBUG
++uint32_t nouveau_debug = 0;
++
++static void
++debug_init(char *args)
++{
++	if (args) {
++		int n = strtol(args, NULL, 0);
++		if (n >= 0)
++			nouveau_debug = n;
++	}
++}
++#endif
++
++/* this is the old libdrm's version of nouveau_device_wrap(), the symbol
++ * is kept here to prevent AIGLX from crashing if the DDX is linked against
++ * the new libdrm, but the DRI driver against the old
++ */
++int
++nouveau_device_open_existing(struct nouveau_device **pdev, int close, int fd,
++			     drm_context_t ctx)
++{
++	return -EACCES;
++}
++
++int
++nouveau_device_wrap(int fd, int close, struct nouveau_device **pdev)
++{
++	struct nouveau_device_priv *nvdev = calloc(1, sizeof(*nvdev));
++	struct nouveau_device *dev = &nvdev->base;
++	uint64_t chipset, vram, gart, bousage;
++	drmVersionPtr ver;
++	int ret;
++
++#ifdef DEBUG
++	debug_init(getenv("NOUVEAU_LIBDRM_DEBUG"));
++#endif
++
++	if (!nvdev)
++		return -ENOMEM;
++	nvdev->base.fd = fd;
++
++	ver = drmGetVersion(fd);
++	if (ver) dev->drm_version = (ver->version_major << 24) |
++				    (ver->version_minor << 8) |
++				     ver->version_patchlevel;
++	drmFreeVersion(ver);
++
++	if ( dev->drm_version != 0x00000010 &&
++	    (dev->drm_version <  0x01000000 ||
++	     dev->drm_version >= 0x02000000)) {
++		nouveau_device_del(&dev);
++		return -EINVAL;
++	}
++
++	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_CHIPSET_ID, &chipset);
++	if (ret == 0)
++	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_FB_SIZE, &vram);
++	if (ret == 0)
++	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_AGP_SIZE, &gart);
++	if (ret) {
++		nouveau_device_del(&dev);
++		return ret;
++	}
++
++	ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_HAS_BO_USAGE, &bousage);
++	if (ret == 0)
++		nvdev->have_bo_usage = (bousage != 0);
++
++	nvdev->close = close;
++	DRMINITLISTHEAD(&nvdev->bo_list);
++	nvdev->base.object.oclass = NOUVEAU_DEVICE_CLASS;
++	nvdev->base.lib_version = 0x01000000;
++	nvdev->base.chipset = chipset;
++	nvdev->base.vram_size = vram;
++	nvdev->base.gart_size = gart;
++	nvdev->base.vram_limit = (nvdev->base.vram_size * 80) / 100;
++	nvdev->base.gart_limit = (nvdev->base.gart_size * 80) / 100;
++
++	*pdev = &nvdev->base;
++	return 0;
++}
++
++int
++nouveau_device_open(const char *busid, struct nouveau_device **pdev)
++{
++	int ret = -ENODEV, fd = drmOpen("nouveau", busid);
++	if (fd >= 0) {
++		ret = nouveau_device_wrap(fd, 1, pdev);
++		if (ret)
++			drmClose(fd);
++	}
++	return ret;
++}
++
++void
++nouveau_device_del(struct nouveau_device **pdev)
++{
++	struct nouveau_device_priv *nvdev = nouveau_device(*pdev);
++	if (nvdev) {
++		if (nvdev->close)
++			drmClose(nvdev->base.fd);
++		free(nvdev->client);
++		free(nvdev);
++		*pdev = NULL;
++	}
++}
++
++int
++nouveau_getparam(struct nouveau_device *dev, uint64_t param, uint64_t *value)
++{
++	struct drm_nouveau_getparam r = { param, 0 };
++	int fd = dev->fd, ret =
++		drmCommandWriteRead(fd, DRM_NOUVEAU_GETPARAM, &r, sizeof(r));
++	*value = r.value;
++	return ret;
++}
++
++int
++nouveau_setparam(struct nouveau_device *dev, uint64_t param, uint64_t value)
++{
++	struct drm_nouveau_setparam r = { param, value };
++	return drmCommandWrite(dev->fd, DRM_NOUVEAU_SETPARAM, &r, sizeof(r));
++}
++
++int
++nouveau_client_new(struct nouveau_device *dev, struct nouveau_client **pclient)
++{
++	struct nouveau_device_priv *nvdev = nouveau_device(dev);
++	struct nouveau_client_priv *pcli;
++	int id = 0, i, ret = -ENOMEM;
++	uint32_t *clients;
++
++	for (i = 0; i < nvdev->nr_client; i++) {
++		id = ffs(nvdev->client[i]) - 1;
++		if (id >= 0)
++			goto out;
++	}
++
++	clients = realloc(nvdev->client, sizeof(uint32_t) * (i + 1));
++	if (!clients)
++		return ret;
++	nvdev->client = clients;
++	nvdev->client[i] = 0;
++	nvdev->nr_client++;
++
++out:
++	pcli = calloc(1, sizeof(*pcli));
++	if (pcli) {
++		nvdev->client[i] |= (1 << id);
++		pcli->base.device = dev;
++		pcli->base.id = (i * 32) + id;
++		ret = 0;
++	}
++
++	*pclient = &pcli->base;
++	return ret;
++}
++
++void
++nouveau_client_del(struct nouveau_client **pclient)
++{
++	struct nouveau_client_priv *pcli = nouveau_client(*pclient);
++	struct nouveau_device_priv *nvdev;
++	if (pcli) {
++		int id = pcli->base.id;
++		nvdev = nouveau_device(pcli->base.device);
++		nvdev->client[id / 32] &= ~(1 << (id % 32));
++		free(pcli->kref);
++		free(pcli);
++	}
++}
++
++int
++nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
++		   uint32_t oclass, void *data, uint32_t length,
++		   struct nouveau_object **pobj)
++{
++	struct nouveau_device *dev;
++	struct nouveau_object *obj;
++	int ret = -EINVAL;
++
++	if (length == 0)
++		length = sizeof(struct nouveau_object *);
++	obj = malloc(sizeof(*obj) + length);
++	obj->parent = parent;
++	obj->handle = handle;
++	obj->oclass = oclass;
++	obj->length = length;
++	obj->data = obj + 1;
++	if (data)
++		memcpy(obj->data, data, length);
++	*(struct nouveau_object **)obj->data = obj;
++
++	dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
++	switch (parent->oclass) {
++	case NOUVEAU_DEVICE_CLASS:
++		switch (obj->oclass) {
++		case NOUVEAU_FIFO_CHANNEL_CLASS:
++		{
++			if (dev->chipset < 0xc0)
++				ret = abi16_chan_nv04(obj);
++			else
++				ret = abi16_chan_nvc0(obj);
++		}
++			break;
++		default:
++			break;
++		}
++		break;
++	case NOUVEAU_FIFO_CHANNEL_CLASS:
++		switch (obj->oclass) {
++		case NOUVEAU_NOTIFIER_CLASS:
++			ret = abi16_ntfy(obj);
++			break;
++		default:
++			ret = abi16_engobj(obj);
++			break;
++		}
++	default:
++		break;
++	}
++
++	if (ret) {
++		free(obj);
++		return ret;
++	}
++
++	*pobj = obj;
++	return 0;
++}
++
++void
++nouveau_object_del(struct nouveau_object **pobj)
++{
++	struct nouveau_object *obj = *pobj;
++	struct nouveau_device *dev;
++	if (obj) {
++		dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
++		if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) {
++			struct drm_nouveau_channel_free req;
++			req.channel = obj->handle;
++			drmCommandWrite(dev->fd, DRM_NOUVEAU_CHANNEL_FREE,
++					&req, sizeof(req));
++		} else {
++			struct drm_nouveau_gpuobj_free req;
++			req.channel = obj->parent->handle;
++			req.handle  = obj->handle;
++			drmCommandWrite(dev->fd, DRM_NOUVEAU_GPUOBJ_FREE,
++					&req, sizeof(req));
++		}
++	}
++	free(obj);
++	*pobj = NULL;
++}
++
++void *
++nouveau_object_find(struct nouveau_object *obj, uint32_t pclass)
++{
++	while (obj && obj->oclass != pclass) {
++		obj = obj->parent;
++		if (pclass == NOUVEAU_PARENT_CLASS)
++			break;
++	}
++	return obj;
++}
++
++static void
++nouveau_bo_del(struct nouveau_bo *bo)
++{
++	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
++	struct drm_gem_close req = { bo->handle };
++	DRMLISTDEL(&nvbo->head);
++	if (bo->map)
++		munmap(bo->map, bo->size);
++	drmIoctl(bo->device->fd, DRM_IOCTL_GEM_CLOSE, &req);
++	free(nvbo);
++}
++
++int
++nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, uint32_t align,
++	       uint64_t size, union nouveau_bo_config *config,
++	       struct nouveau_bo **pbo)
++{
++	struct nouveau_device_priv *nvdev = nouveau_device(dev);
++	struct nouveau_bo_priv *nvbo = calloc(1, sizeof(*nvbo));
++	struct nouveau_bo *bo = &nvbo->base;
++	int ret;
++
++	if (!nvbo)
++		return -ENOMEM;
++	atomic_set(&nvbo->refcnt, 1);
++	bo->device = dev;
++	bo->flags = flags;
++	bo->size = size;
++
++	ret = abi16_bo_init(bo, align, config);
++	if (ret) {
++		free(nvbo);
++		return ret;
++	}
++
++	DRMLISTADD(&nvbo->head, &nvdev->bo_list);
++
++	*pbo = bo;
++	return 0;
++}
++
++int
++nouveau_bo_wrap(struct nouveau_device *dev, uint32_t handle,
++		struct nouveau_bo **pbo)
++{
++	struct nouveau_device_priv *nvdev = nouveau_device(dev);
++	struct drm_nouveau_gem_info req = { .handle = handle };
++	struct nouveau_bo_priv *nvbo;
++	int ret;
++
++	DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
++		if (nvbo->base.handle == handle) {
++			*pbo = NULL;
++			nouveau_bo_ref(&nvbo->base, pbo);
++			return 0;
++		}
++	}
++
++	ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_INFO,
++				  &req, sizeof(req));
++	if (ret)
++		return ret;
++
++	nvbo = calloc(1, sizeof(*nvbo));
++	if (nvbo) {
++		atomic_set(&nvbo->refcnt, 1);
++		nvbo->base.device = dev;
++		abi16_bo_info(&nvbo->base, &req);
++		DRMLISTADD(&nvbo->head, &nvdev->bo_list);
++		*pbo = &nvbo->base;
++		return 0;
++	}
++
++	return -ENOMEM;
++}
++
++int
++nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
++		    struct nouveau_bo **pbo)
++{
++	struct nouveau_device_priv *nvdev = nouveau_device(dev);
++	struct nouveau_bo_priv *nvbo;
++	struct drm_gem_open req = { .name = name };
++	int ret;
++
++	DRMLISTFOREACHENTRY(nvbo, &nvdev->bo_list, head) {
++		if (nvbo->name == name) {
++			*pbo = NULL;


Gmane