New DRM driver model - gets rid of DRM() macros!

Jon Smirl
2004-09-28T15:54:42Z

I've checked two new directories into DRM CVS for Linux 2.6 -
linux-core, shared-core. This code implements a new model for DRM
where DRM is split into a core piece and personality modules that
share the core. The major reason for doing this is that it allows me
to remove all of the DRM() macros; something that is causing lot's of
complaints from the Linux kernel people.

cvs -z3 -d:pserver:anonymous@dri.freedesktop.org:/cvs/dri co drm

The patch for this is quite large, 500K, and it will mess up the Linux
2.4/BSD DRM builds since it removes the DRM() macro. Instead of doing
this as a patch I made the new CVS directories.

I've checked radeon and r128 and they work. Everything else should
work except ffb, please check the other drivers and let me know. I've
probably made some typos with a edit this large.

ffb should work in principle but since I don't own one or a Sparc
machine so I can't compile the driver. I suspect ffb has compiler
errors but the are easily fixed just by copying similar code from one
of the working modules. Please send patches.

The API between the core and personalities doesn't look to be all that
huge. With work I'd guess that 10% of the entry points could be
eliminated. After another year of development we might be able to
specify a stable core API.

What are everyone's thoughts on this? There is no technical reason it
can't be implemented on Linux 2.4/BSD, although I don't see any reason
to do it for 2.4.

Any ideas on how to generate a unique identifier for the core? It
probably should be regenerated by the Makefile whenever the core
changes. Personalities would have to match the core identifier. This
would stop people from loading binary modules that don't match the
core.

After sometime testing and fixing obvious problems I'll generate a
patch for the 2.6 kernel and lkml.

[root@smirl linux-2.6]# lsmod | more
Module Size Used by
tdfx 2816 0
sis 10176 0
mga 56704 0
i915 16896 0
via 19428 0
savage 3840 0
r128 44672 0
radeon 70272 0
drm 59684 8 tdfx,sis,mga,i915,via,savage,r128,radeon

The core provides these entry points....

[root@smirl linux-2.6]# grep EXPORT_SYMBOL *
drm_bufs.c:EXPORT_SYMBOL(drm_order);
drm_bufs.c:EXPORT_SYMBOL(drm_initmap);
drm_dma.c:EXPORT_SYMBOL(drm_core_reclaim_buffers);
drm_drv.c:EXPORT_SYMBOL(drm_cleanup_pci);
drm_drv.c:EXPORT_SYMBOL(drm_init);
drm_drv.c:EXPORT_SYMBOL(drm_exit);
drm_drv.c:EXPORT_SYMBOL(drm_open);
drm_drv.c:EXPORT_SYMBOL(drm_release);
drm_drv.c:EXPORT_SYMBOL(drm_ioctl);
drm_fops.c:EXPORT_SYMBOL(drm_flush);
drm_fops.c:EXPORT_SYMBOL(drm_fasync);
drm_init.c:EXPORT_SYMBOL(drm_flags);
drm_irq.c:EXPORT_SYMBOL(drm_irq_uninstall);
drm_irq.c:EXPORT_SYMBOL(drm_vbl_send_signals);
drm_memory.c:EXPORT_SYMBOL(drm_calloc);
drm_pci.c:EXPORT_SYMBOL(drm_pci_alloc);
drm_pci.c:EXPORT_SYMBOL(drm_pci_free);
drm_stub.c:EXPORT_SYMBOL(drm_probe);
drm_vm.c:EXPORT_SYMBOL(drm_core_get_map_ofs);
drm_vm.c:EXPORT_SYMBOL(drm_core_get_reg_ofs);

Drivers provide these callbacks......

struct drm_driver_fn {
u32 driver_features;
int dev_priv_size;
int permanent_maps;
drm_ioctl_desc_t *ioctls;
int num_ioctls;
int (*preinit)(struct drm_device *, unsigned long flags);
void (*prerelease)(struct drm_device *, struct file *filp);
void (*pretakedown)(struct drm_device *);
int (*postcleanup)(struct drm_device *);
int (*presetup)(struct drm_device *);
int (*postsetup)(struct drm_device *);
int (*dma_ioctl)( DRM_IOCTL_ARGS );
/* these are opposites at the moment */
int (*open_helper)(struct drm_device *, drm_file_t *);
void (*free_filp_priv)(struct drm_device *, drm_file_t *);

void (*release)(struct drm_device *, struct file *filp);
void (*dma_ready)(struct drm_device *);
int (*dma_quiescent)(struct drm_device *);
int (*context_ctor)(struct drm_device *dev, int context);
int (*context_dtor)(struct drm_device *dev, int context);
int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
int (*kernel_context_switch_unlock)(struct drm_device *dev);
int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
/* these have to be filled in */
int (*postinit)(struct drm_device *, unsigned long flags);
irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
void (*irq_preinstall)(struct drm_device *dev);
void (*irq_postinstall)(struct drm_device *dev);
void (*irq_uninstall)(struct drm_device *dev);
void (*reclaim_buffers)(struct file *filp);
unsigned long (*get_map_ofs)(drm_map_t *map);
unsigned long (*get_reg_ofs)(struct drm_device *dev);
void (*set_version)(struct drm_device *dev, drm_set_version_t *sv);
int (*version)(drm_version_t *version);
};

--
Jon Smirl
jonsmirl@gmail.com