public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: Dave Airlie <airlied@linux.ie>
Cc: "Jon Smirl" <jonsmirl@gmail.com>,
	"Felix Kühling" <fxkuehl@gmx.de>,
	"DRI Devel" <dri-devel@lists.sourceforge.net>,
	lkml <linux-kernel@vger.kernel.org>,
	"Linus Torvalds" <torvalds@osdl.org>
Subject: Re: radeon-pre-2
Date: Mon, 13 Sep 2004 12:26:33 +0100	[thread overview]
Message-ID: <1095074778.14374.41.camel@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.58.0409122319550.20080@skynet>

[-- Attachment #1: Type: text/plain, Size: 1060 bytes --]

On Sul, 2004-09-12 at 23:42, Dave Airlie wrote:
> The worst things that will happen for all concerened is this:
> Jon does all this work on a merged solution outside the kernel, and it
> works well, and the X team decide to do a decent X on mesa-solo on Jons
> super-DRM, now the super-DRM gets pushed via the X tree and distributions
> start relasing kernels with it merged into it 

Unlikely. Its rapidly unmaintainable because the core kernel changes
will obsolete it (see for example KGI).

> I think yourself and Linus's ideas for a locking scheme look good, I also
> know they won't please Jon too much as he can see where the potential
> ineffecienes with saving/restore card state on driver swap are, especailly
> on running fbcon and X on a dual-head card with different users.

Well this is what I came up with so far. It creates a vga class so you
can bind the drivers to functions of the card (and we can add/remove
functions later as appropriate), tells functions about each other and
now implements Linux lock proposal as I understood it.

Alan


[-- Attachment #2: vga_class.c --]
[-- Type: text/x-csrc, Size: 13514 bytes --]

/*
 * drivers/video/vga-driver.c
 *
 */

#include <linux/pci.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/semaphore.h>
#include "vga_class.h"

/*
 *  Registration of video drivers and handling of hot-pluggable devices.
 */

static LIST_HEAD(vga_devices);	/* No I don't know why its not DECLARE_LIST_HEAD either */

/**
 * vga_match_one_device - Tell if a PCI device structure has a matching
 *                        PCI device id structure
 * @id: single PCI device id structure to match
 * @dev: the PCI device structure to match against
 * 
 * Returns the matching vga_device_id structure or %NULL if there is no match.
 */

static inline const struct vga_device_id *
vga_match_one_device(const struct vga_device_id *id, const struct pci_dev *dev)
{
	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
	    !((id->class ^ dev->class) & id->class_mask))
		return id;
	return NULL;
}


/**
 * vga_match_device - Tell if a VGA device structure has a matching
 *                    PCI device id structure
 * @ids: array of PCI device id structures to search in
 * @dev: the PCI device structure to match against
 * 
 * Used by a driver to check whether a PCI device present in the
 * system is in its list of supported devices.Returns the matching
 * vga_device_id structure or %NULL if there is no match.
 */
static const struct vga_device_id *
vga_match_device(const struct vga_device_id *ids, const struct vga_dev *vdev)
{
	struct pci_dev *pdev = vdev->pci_dev;
	while (ids->vendor || ids->subvendor || ids->class_mask) {
		if (vga_match_one_device(ids, pdev) && ids->unit == vdev->unit)
			return ids;
		ids++;
	}
	return NULL;
}


static void vga_device_notify_install(struct vga_dev *vdev, int type)
{
	int i;
	for(i = TYPE_MEM; i < TYPE_LAST; i++) {
		struct vga_dev *v = vdev->shared->device[i];
		if(v != NULL && v->driver && i != type)
			v->driver->notify_attach(v, type);
	}
}

static void vga_device_notify_remove(struct vga_dev *vdev, int type)
{
	int i;
	for(i = TYPE_MEM; i < TYPE_LAST; i++) {
		struct vga_dev *v = vdev->shared->device[i];
		if(v != NULL && v->driver && i != type)
			v->driver->notify_detach(v, type);
	}
}

/**
 * vga_device_probe_static()
 * 
 * returns 0 and sets vdev->driver when drv claims vdev, else error.
 */
static int
vga_device_probe_static(struct vga_driver *vdrv, struct vga_dev *vdev)
{		   
	int error = -ENODEV;
	const struct vga_device_id *id;

	if (!vdrv->id_table)
		return error;
	id = vga_match_device(vdrv->id_table, vdev);
	if (id)
		error = vdrv->probe(vdev, id);
	if (error >= 0) {
		vdev->driver = vdrv;
		down(&vdev->shared->shared_sem);
		vdev->shared->users++;
		vga_device_notify_install(vdev, vdev->unit);
		up(&vdev->shared->shared_sem);
		error = 0;
	}
	return error;
}

/**
 * __vga_device_probe()
 * 
 * returns 0  on success, else error.
 * side-effect: vdev->driver is set to vdrv when drv claims vdev.
 */
static int
__vga_device_probe(struct vga_driver *vdrv, struct vga_dev *vdev)
{		   
	int error = 0;

	if (!vdev->driver && vdrv->probe) {
		error = vga_device_probe_static(vdrv, vdev);
	}
	return error;
}

static int vga_device_probe(struct device *dev)
{
	int error = 0;
	struct vga_driver *drv;
	struct vga_dev *vdev;

	drv = to_vga_driver(dev->driver);
	vdev = to_vga_dev(dev);
	vga_dev_get(vdev);
	error = __vga_device_probe(drv, vdev);
	if (error)
		vga_dev_put(vdev);

	return error;
}

static int vga_device_remove(struct device *dev)
{
	struct vga_dev *vdev = to_vga_dev(dev);
	struct vga_driver *vdrv = vdev->driver;

	down(&vdev->shared->shared_sem);	
	vdev->shared->users--;
	if (vdrv) {
		vga_device_notify_remove(vdev, vdev->unit);
		if (vdrv->remove)
			vdrv->remove(vdev, vdev->shared->count);
		vdev->driver = NULL;
	}
	vdev->shared->device[vdev->unit] = NULL;
	up(&vdev->shared->shared_sem);	
	
	vga_dev_put(vdev);
	return 0;
}

static int vga_device_suspend(struct device *dev, u32 state)
{
	return 0;
}


/* 
 * Default resume method for devices that have no driver provided resume,
 * or not even a driver at all.
 */

static int vga_device_resume(struct device *dev)
{
	return 0;
}

static struct kobj_type vga_driver_kobj_type = {
};

/**
 * vga_register_driver - register a new pci driver
 * @drv: the driver structure to register
 * 
 * Adds the driver structure to the list of registered drivers
 * Returns the number of vga devices which were claimed by the driver
 * during registration.  The driver remains registered even if the
 * return value is zero.
 */

int vga_register_driver(struct vga_driver *drv)
{
	/* initialize common driver fields */
	drv->driver.name = drv->name;
	drv->driver.bus = &vga_bus_type;
	drv->driver.probe = vga_device_probe;
	drv->driver.remove = vga_device_remove;
	drv->driver.kobj.ktype = &vga_driver_kobj_type;

	/* register with core */
	return driver_register(&drv->driver);
}

/**
 * vga_unregister_driver - unregister a pci driver
 * @drv: the driver structure to unregister
 * 
 * Deletes the driver structure from the list of registered VGA drivers,
 * gives it a chance to clean up by calling its remove() function for
 * each device it was responsible for, and marks those devices as
 * driverless.
 */

void vga_unregister_driver(struct vga_driver *vdrv)
{
	driver_unregister(&vdrv->driver);
}

/**
 * vga_dev_driver - get the vga_driver of a device
 * @dev: the device to query
 * @type: type of device
 *
 * Returns the appropriate vga_driver structure or %NULL if there is no 
 * registered driver for the device. The shared block is used so that
 * you can pass your own vdev to receive driver information about
 * other attached drivers to the same PCI device. Caller must be careful
 * about locking and use of shared_sem.
 */

struct vga_driver *vga_dev_driver(const struct vga_dev *vdev, int type)
{
	struct vga_dev *v = vdev->shared->device[type];
	if(v == NULL)
		return NULL;
	return v->driver;
}

/**
 * vga_bus_match - Tell if a VGA device structure has a matching PCI device id structure
 * @ids: array of PCI device id structures to search in
 * @dev: the VGA device structure to match against
 * 
 * Used by a driver to check whether a VGA device present in the
 * system is in its list of supported devices.Returns the matching
 * vga_device_id structure or %NULL if there is no match.
 */

static int vga_bus_match(struct device *dev, struct device_driver * drv) 
{
	const struct vga_dev *vdev = to_vga_dev(dev);
	struct vga_driver *vdrv = to_vga_driver(drv);
	const struct vga_device_id * ids = vdrv->id_table;
	if (!ids)
		return 0;
	return vga_match_device(ids, vdev) ? 1 : 0;
}

/**
 * vga_dev_get - increments the reference count of the pci device structure
 * @dev: the device being referenced
 *
 * Each live reference to a device should be refcounted.
 *
 * Drivers for VGA devices should normally record such references in
 * their probe() methods, when they bind to a device, and release
 * them by calling vga_dev_put(), in their disconnect() methods.
 *
 * A pointer to the device with the incremented reference counter is returned.
 */
struct vga_dev *vga_dev_get(struct vga_dev *vdev)
{
	struct device *tmp;

	if (!vdev)
		return NULL;

	tmp = get_device(&vdev->dev);
	if (tmp)        
		return to_vga_dev(tmp);
	else
		return NULL;
}

/**
 * vga_dev_put - release a use of the vga_dev structure
 * @dev: device that's been disconnected
 *
 * Must be called when a user of a device is finished with it.  When the last
 * user of the device calls this function, the memory of the device is freed.
 */
void vga_dev_put(struct vga_dev *dev)
{
	if (dev)
		put_device(&dev->dev);
}

/* For now */
int vga_hotplug (struct device *dev, char **envp, int num_envp,
		 char *buffer, int buffer_size)
{
	return -ENODEV;
}

struct bus_type vga_bus_type = {
	.name		= "vga",
	.match		= vga_bus_match,
	.hotplug	= vga_hotplug,
	.suspend	= vga_device_suspend,
	.resume		= vga_device_resume,
};



/*
 *	Helper for VESAfb and friends.
 */

static int mmio_resource_overlap(struct pci_dev *dev, int i, unsigned long mmio)
{
	unsigned long st = pci_resource_start(dev, i);
	unsigned long size = pci_resource_len(dev, i);
	unsigned long flags = pci_resource_flags(dev, i);
	
	if(st == 0 || size == 0)
	   	return 0;
	if(st + size < mmio)
		return 0;
	if(st > mmio)
		return 0;
	if(flags & IORESOURCE_IO)
		return 0;
	return 1;
}

static struct pci_dev *vga_find_by_mmio(unsigned long mmio)
{
	struct list_head *l;
	list_for_each(l, &vga_devices) {
		struct vga_dev *vdev = list_entry(l, struct vga_dev, next);
		int i;
		for (i = 0; i < 6; i++) {
			if (mmio_resource_overlap(vdev->pci_dev, i, mmio))
				return vdev->pci_dev;
		}
	}
	/* Check ISA window routing ? */
	return NULL;
}


/*
 *	Big locking as suggested by Linus. Drivers can of course be
 *	more friendly and work together on some things.
 */
 
void vga_take_lock(struct vga_dev *vdev, struct vga_driver *vdrv, void *context)
{
	struct vga_shared *v = vdev->shared;
	
	down(&v->shared_sem);
	down(&v->fb_sem);
	if(v->lock_owner != vdrv || v->lock_context != context)
	{
		if(v->lock_release)
			v->lock_release(vdev, v->lock_context);
		v->lock_release = NULL;
	}
	v->lock_owner = vdrv;
	v->lock_context = context;
}

EXPORT_SYMBOL_GPL(vga_take_lock);

/*
 *	Drop the big locking
 */
 
void vga_drop_lock(struct vga_dev *vdev, void (*lock_release)(struct vga_dev *, void *))
{
	struct vga_shared *v = vdev->shared;
	v->lock_release = lock_release;
	up(&v->fb_sem);
	up(&v->shared_sem);
}

EXPORT_SYMBOL_GPL(vga_drop_lock);

/*
 *	VGA device discovery from the PCI side
 */
 
 
/**
 * vga_release_dev - free a pci device structure when all users of it are finished.
 * @dev: device that's been disconnected
 *
 * Will be called only by the device core when all users of this vga device are
 * done.
 */

static void vga_release_dev(struct device *dev)
{
	struct vga_dev *vdev = to_vga_dev(dev);
	/* We want this very late because the remove methods might want to
	   use the locks */
	vga_take_lock(vdev, NULL, NULL);
	vga_drop_lock(vdev, NULL);
	down(&vdev->shared->shared_sem);
	vdev->shared->device[vdev->unit] = NULL;
	vdev->shared->count --;
	up(&vdev->shared->shared_sem);
	if(vdev->shared->count == 0)
		kfree(vdev->shared);
	kfree(vdev);
}

/**
 *	vga_remove_one		-	Remove vga adapter
 *	@pdev: PCI device
 *
 *	A VGA adapter has been removed. We must propogate this into the
 *	VGA bus world
 */
 
static void vga_remove_one(struct pci_dev *pdev)
{
	struct vga_dev *vdev = (struct vga_dev *)pdev->dev.driver_data;
	device_unregister(&vdev->dev);
	/* Remove from lists etc here */
	vga_dev_put(vdev);
}

/**
 *	vga_found_one		-	Add vga adapter
 *	@pdev: PCI device
 *	@ent: matching PCI entity
 *
 *	Allocate and install a new VGA class entity set after the PCI layer
 *	discovers it.  We create device objects for the frame buffer, 
 *	memory manager and dri objects at the moment. Additional frame
 *	buffer objects (multihead) can be allocated by the callers.
 */
 
static int vga_found_one(struct pci_dev *pdev, 
					const struct pci_device_id *ent)
{
	struct vga_shared *vshar = kmalloc(sizeof(*vshar), GFP_KERNEL);
	int i;
	if(vshar == NULL)
		return -ENOMEM;
	
	memset(vshar, 0, sizeof(*vshar));
	init_MUTEX(&vshar->shared_sem);
	init_MUTEX(&vshar->fb_sem);
	vshar->lock_owner = NULL;
	
	for(i = TYPE_MEM; i <= TYPE_FB0; i++)
	{
		struct vga_dev *vdev = kmalloc(sizeof(*vdev), GFP_KERNEL);
		if(vdev == NULL)
			return -ENOMEM;
		memset(vdev, 0, sizeof(*vdev));
	
		vdev->pci_dev = pdev;
		vdev->shared = vshar;
		vdev->unit = i;
		
		vshar->device[i] = vdev;
		vshar->count ++;
	
		vdev->dev.bus = &vga_bus_type;
		vdev->dev.parent = NULL;	/* ? */
		vdev->dev.driver_data = pdev;
		device_initialize(&vdev->dev);
		vdev->dev.release = vga_release_dev;
		vdev->dev.dma_mask = pdev->dev.dma_mask;
		vdev->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask;
		vga_dev_get(vdev);

		INIT_LIST_HEAD(&vdev->next);
		list_add_tail(&vdev->next, &vga_devices);
	}
	return 1;
}

/*
 *	Match all video VGA class objects
 */
 
static struct pci_device_id vga_id_table[] = {
	{ PCI_DEVICE_CLASS(((PCI_CLASS_DISPLAY_VGA << 8) | 0x00), ~0), },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, vga_id_table);

static struct pci_driver vga_driver = {
	.name		= "vga",
	.probe		= vga_found_one,
	.remove		= vga_remove_one,
	.id_table	= vga_id_table,
	/* Could use suspend/resume hooks ? */
};
 
EXPORT_SYMBOL(vga_register_driver);
EXPORT_SYMBOL(vga_unregister_driver);
EXPORT_SYMBOL(vga_dev_driver);
EXPORT_SYMBOL(vga_bus_type);
EXPORT_SYMBOL(vga_dev_get);
EXPORT_SYMBOL(vga_dev_put);

int __init vga_driver_init(void)
{
	if( bus_register(&vga_bus_type) < 0)
		printk(KERN_ERR "Unable to register VGA bus type.\n");
	return pci_module_init(&vga_driver);
}


postcore_initcall(vga_driver_init);

[-- Attachment #3: vga_class.h --]
[-- Type: text/x-chdr, Size: 2286 bytes --]

#define TYPE_MEM		0	/* Memory manager */
#define TYPE_DRI		1	/* Direct render agent */
#define TYPE_FB0		2	/* Frame buffer head 0 */
#define TYPE_FB1		3	/* Frame buffer head 1 */
#define TYPE_FB2		4	/* Frame buffer head 2 */
#define TYPE_FB3		5	/* Frame buffer head 3 */
#define TYPE_LAST		5
#define NUM_TYPES		6

struct vga_shared {
	struct vga_dev *device[NUM_TYPES];
	struct semaphore shared_sem;
	int count;			/* Devices */
	int users;			/* Active users */
	struct semaphore fb_sem;
	void (*lock_release)(struct vga_dev *, void *);
	void *lock_context;
	struct vga_driver *lock_owner;
};

struct vga_dev {
	struct list_head next;		/* All VGA devices */
	struct list_head router_list;	/* By VGA router (not yet done) */
	struct vga_driver *driver;
	struct pci_dev *pci_dev;
	struct device dev;
	int unit;
	struct vga_shared *shared;
};

struct vga_device_id {
	__u32 vendor, device;		/* Vendor and device ID or PCI_ANY_ID*/
	__u32 subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */
	__u32 class, class_mask;	/* (class,subclass,prog-if) triplet */
	__u32 unit;			/* Logical unit for attach */
	kernel_ulong_t driver_data;	/* Data private to the driver */
};


#define	to_vga_dev(n) container_of(n, struct vga_dev, dev)

struct vga_driver {
	struct list_head node;
	int type;
	char *name;
	int (*probe) (struct vga_dev *vdev, const struct vga_device_id *id);
	void (*remove) (struct vga_dev *dev, int users);	/* Device removed (NULL if not a hot-plug capable driver) */
	int  (*suspend) (struct vga_dev *vdev, u32 state);	/* Device suspended */	int  (*resume) (struct vga_dev *vdev);	                /* Device woken up */
	void (*notify_attach) (struct vga_dev *, int);
	void (*notify_detach) (struct vga_dev *, int);
	struct device_driver driver;
	struct vga_device_id *id_table;
};

#define to_vga_driver(drv) container_of(drv, struct vga_driver, driver)

extern struct bus_type vga_bus_type;

extern int vga_register_driver(struct vga_driver *drv);
extern void vg_unregister_driver(struct vga_driver *drv);
extern struct vga_driver *vga_dev_driver(const struct vga_dev *, int);
extern struct bus_type vga_bus_type;
extern struct vga_dev *vga_dev_get(struct vga_dev *);
extern void vga_dev_put(struct vga_dev *);

  parent reply	other threads:[~2004-09-13 12:31 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <E3389AF2-0272-11D9-A8D1-000A95F07A7A@fs.ei.tum.de>
     [not found] ` <DA459966-02B9-11D9-A8D1-000A95F07A7A@fs.ei.tum.de>
     [not found]   ` <9e47339104090917353554a586@mail.gmail.com>
     [not found]     ` <Pine.LNX.4.58.0409100209100.32064@skynet>
     [not found]       ` <9e47339104090919015b5b5a4d@mail.gmail.com>
     [not found]         ` <20040910153135.4310c13a.felix@trabant>
     [not found]           ` <9e47339104091008115b821912@mail.gmail.com>
     [not found]             ` <1094829278.17801.18.camel@localhost.localdomain>
     [not found]               ` <9e4733910409100937126dc0e7@mail.gmail.com>
     [not found]                 ` <1094832031.17883.1.camel@localhost.localdomain>
2004-09-10 17:22                   ` radeon-pre-2 Jon Smirl
2004-09-10 17:04                     ` radeon-pre-2 Alan Cox
2004-09-10 18:40                       ` radeon-pre-2 Jon Smirl
2004-09-10 22:19                         ` radeon-pre-2 Dave Airlie
2004-09-10 22:00                           ` radeon-pre-2 Alan Cox
2004-09-10 23:24                             ` radeon-pre-2 Dave Airlie
2004-09-11  7:40                               ` radeon-pre-2 Geert Uytterhoeven
2004-09-11  8:42                               ` radeon-pre-2 Keith Whitwell
2004-09-11 13:59                               ` radeon-pre-2 Alan Cox
2004-09-11  0:47                             ` radeon-pre-2 Vladimir Dergachev
2004-09-11  8:43                               ` radeon-pre-2 Keith Whitwell
2004-09-11 12:23                                 ` radeon-pre-2 Mike Mestnik
2004-09-11 15:39                                 ` radeon-pre-2 Vladimir Dergachev
2004-09-11 14:14                               ` radeon-pre-2 Alan Cox
2004-09-11  0:50                             ` radeon-pre-2 Dave Airlie
2004-09-11  3:30                               ` radeon-pre-2 Michel Dänzer
2004-09-11  5:19                                 ` radeon-pre-2 Dave Airlie
2004-09-11  6:12                                   ` radeon-pre-2 Michel Dänzer
2004-09-11  7:11                                     ` radeon-pre-2 Vladimir Dergachev
2004-09-11 14:36                                       ` radeon-pre-2 Alan Cox
2004-09-11 15:53                                         ` radeon-pre-2 Vladimir Dergachev
2004-09-11 15:14                                           ` radeon-pre-2 Alan Cox
2004-09-11 17:10                                             ` radeon-pre-2 Vladimir Dergachev
2004-09-11 16:20                                               ` radeon-pre-2 Alan Cox
2004-09-11 17:49                                                 ` radeon-pre-2 Vladimir Dergachev
2004-09-11 17:59                                                   ` radeon-pre-2 Jon Smirl
2004-09-11 18:05                                                     ` radeon-pre-2 Vladimir Dergachev
2004-09-11 18:09                                                       ` radeon-pre-2 Jon Smirl
2004-09-12  1:55                                             ` radeon-pre-2 Mike Mestnik
2004-09-11  9:20                                   ` radeon-pre-2 Antonino A. Daplas
2004-09-11 14:40                                     ` radeon-pre-2 Alan Cox
2004-09-11 16:34                                     ` radeon-pre-2 Jon Smirl
2004-09-11 14:33                                   ` radeon-pre-2 Alan Cox
2004-09-11 16:46                                     ` radeon-pre-2 Jon Smirl
2004-09-11 16:21                                       ` radeon-pre-2 Alan Cox
2004-09-11 17:27                                         ` radeon-pre-2 Jon Smirl
2004-09-13 11:40                                           ` radeon-pre-2 Keith Whitwell
2004-09-11 19:10                                         ` radeon-pre-2 Hamie
2004-09-11 23:20                                           ` radeon-pre-2 Alan Cox
2004-09-12  9:13                                             ` radeon-pre-2 Geert Uytterhoeven
2004-09-12 11:36                                             ` radeon-pre-2 Hamie
2004-09-12 17:31                                               ` radeon-pre-2 Alan Cox
2004-09-11 16:23                                       ` radeon-pre-2 Alan Cox
2004-09-11 14:25                               ` radeon-pre-2 Alan Cox
2004-09-12 22:42                                 ` radeon-pre-2 Dave Airlie
2004-09-12 23:03                                   ` radeon-pre-2 Linus Torvalds
2004-09-13  0:27                                   ` radeon-pre-2 Michel Dänzer
2004-09-13  0:45                                     ` radeon-pre-2 Vladimir Dergachev
2004-09-13  0:52                                       ` radeon-pre-2 Michel Dänzer
2004-09-13 14:52                                         ` radeon-pre-2 Vladimir Dergachev
2004-09-13 13:57                                           ` radeon-pre-2 Alan Cox
2004-09-13 15:20                                             ` radeon-pre-2 Vladimir Dergachev
2004-09-13 15:07                                               ` radeon-pre-2 Alan Cox
2004-09-13 15:20                                           ` radeon-pre-2 Linus Torvalds
2004-09-13 19:21                                             ` radeon-pre-2 Alex Deucher
2004-09-13 20:42                                               ` radeon-pre-2 David Bronaugh
2004-09-13 21:57                                                 ` radeon-pre-2 Alex Deucher
2004-09-13 16:26                                           ` radeon-pre-2 Michel Dänzer
2004-09-13  6:05                                       ` radeon-pre-2 Alex Deucher
2004-09-13 16:29                                         ` radeon-pre-2 Michel Dänzer
2004-09-13  6:41                                   ` radeon-pre-2 Arjan van de Ven
2004-09-13 11:26                                   ` Alan Cox [this message]
2004-09-13 15:06                                     ` radeon-pre-2 Jon Smirl
2004-09-13 15:04                                       ` radeon-pre-2 Alan Cox
2004-09-13 16:28                                         ` radeon-pre-2 Jon Smirl
2004-09-13 16:43                                           ` radeon-pre-2 Alan Cox
2004-09-13 18:11                                             ` radeon-pre-2 Jon Smirl
2004-09-13 18:49                                               ` radeon-pre-2 Jesse Barnes
2004-09-13 22:17                                           ` radeon-pre-2 Antonino A. Daplas
2004-09-13 17:50                                         ` radeon-pre-2 Jon Smirl
2004-09-14 10:27                                           ` radeon-pre-2 Alan Cox
2004-09-11  8:38                             ` radeon-pre-2 Keith Whitwell
2004-09-10 23:10                           ` radeon-pre-2 Jon Smirl
2004-09-10 22:17                             ` radeon-pre-2 Alan Cox
2004-09-11 12:27                           ` radeon-pre-2 Christoph Hellwig
2004-09-11 12:49                             ` radeon-pre-2 Mike Mestnik
2004-09-11 16:45                               ` radeon-pre-2 Christoph Hellwig
2004-09-11 16:11                             ` radeon-pre-2 Jon Smirl
2004-09-11 16:45                               ` radeon-pre-2 Christoph Hellwig
2004-09-11 17:02                               ` radeon-pre-2 Linus Torvalds
2004-09-11 16:18                                 ` radeon-pre-2 Alan Cox
2004-09-11 17:49                                   ` radeon-pre-2 Linus Torvalds
2004-09-11 17:13                                 ` radeon-pre-2 Jon Smirl
2004-09-11 16:23                                   ` radeon-pre-2 Alan Cox
2004-09-11 17:41                                   ` radeon-pre-2 Linus Torvalds
2004-09-11 17:57                                   ` radeon-pre-2 Michel Dänzer
2004-09-11 20:29                                   ` radeon-pre-2 Eric Anholt
2004-09-11 21:41                                     ` radeon-pre-2 Jon Smirl
2004-09-11 17:54                                 ` radeon-pre-2 Jon Smirl
2004-09-11 18:13                                   ` radeon-pre-2 Linus Torvalds
2004-09-11 21:02                                     ` radeon-pre-2 Jon Smirl
2004-09-11 21:06                                       ` radeon-pre-2 Christoph Hellwig
2004-09-11 21:37                                         ` radeon-pre-2 Jon Smirl
2004-09-11 23:23                                           ` radeon-pre-2 Alan Cox
2004-09-12  7:12                                           ` radeon-pre-2 Eric Anholt
2004-09-12  0:21                                     ` radeon-pre-2 Jon Smirl
2004-09-12  0:28                                       ` radeon-pre-2 Linus Torvalds
2004-09-12 23:53                                         ` radeon-pre-2 Dave Airlie
2004-09-11 18:17                                   ` radeon-pre-2 Vladimir Dergachev
2004-09-10 17:12                     ` radeon-pre-2 Alan Cox
     [not found]           ` <1094853894.18235.17.camel@localhost.localdomain>
2004-09-11  2:20             ` radeon-pre-2 Jon Smirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1095074778.14374.41.camel@localhost.localdomain \
    --to=alan@lxorguk.ukuu.org.uk \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.sourceforge.net \
    --cc=fxkuehl@gmx.de \
    --cc=jonsmirl@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox