http://drm.bkbits.net/drm-2.6
airlied@starflyer.(none)|ChangeSet|20041105090041|59355 airlied

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/11/05 20:00:41+11:00 airlied@starflyer.(none) 
#   drm: make pcigart functions inline
#   
#   with these unstatic uninline the kernel wouldn't build with both configured.
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_cp.c
#   2004/11/05 20:00:30+11:00 airlied@starflyer.(none) +1 -0
#   drm: make pcigart functions inline
#   
#   with these unstatic uninline the kernel wouldn't build with both configured.
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_cce.c
#   2004/11/05 20:00:30+11:00 airlied@starflyer.(none) +1 -0
#   drm: make pcigart functions inline
#   
#   with these unstatic uninline the kernel wouldn't build with both configured.
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/ati_pcigart.h
#   2004/11/05 20:00:30+11:00 airlied@starflyer.(none) +39 -38
#   drm: make pcigart functions inline
#   
#   with these unstatic uninline the kernel wouldn't build with both configured.
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/11/04 22:32:38+11:00 airlied@starflyer.(none) 
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_stub.c
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +73 -7
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_lock.c
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +139 -4
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_ioctl.c
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +8 -0
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_fops.c
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +290 -0
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drv.c
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +7 -503
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/11/04 22:32:28+11:00 airlied@starflyer.(none) +12 -10
#   drm: rearrange some functions for new split
#   
#   This change moves some functions into different C files to align things
#   a bit more correctly...
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/11/04 21:35:52+11:00 airlied@starflyer.(none) 
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/tdfx_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +9 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_vm.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +1 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_stub.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +1 -1
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_fops.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +1 -0
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drv.c
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +0 -13
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/11/04 21:35:43+11:00 airlied@starflyer.(none) +1 -3
#   drm: move fops into drivers
#   
#   move the drm file operations into the driver.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Approved-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/11/02 22:20:24+11:00 airlied@starflyer.(none) 
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/tdfx_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/gamma_dma.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +6 -6
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/ffb_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +8 -8
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_vm.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +2 -2
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_stub.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +2 -2
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_proc.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +2 -2
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_irq.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +6 -6
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_ioctl.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +6 -6
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_fops.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +2 -2
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drv.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +45 -45
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_context.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +4 -4
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_bufs.c
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +3 -3
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/11/02 22:20:15+11:00 airlied@starflyer.(none) +7 -7
#   drm: rename fn_tbl to driver as it is no longer a function table
#   
#   This renames the drm_driver_fn to drm_driver and fn_tbl to driver,
#   this name is makes much more sense now.
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/11/02 21:59:29+11:00 airlied@starflyer.(none) 
#   drm: drm_memory.c missing from build
#   
#   Add drm_memory.c to build.
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_memory.c
#   2004/11/02 21:57:07+11:00 airlied@starflyer.(none) +181 -0
# 
# drivers/char/drm/drm_memory.c
#   2004/11/02 21:57:07+11:00 airlied@starflyer.(none) +0 -0
#   BitKeeper file /home/airlied/bitkeeper/drm-test/drivers/char/drm/drm_memory.c
# 
# ChangeSet
#   2004/11/02 21:55:16+11:00 airlied@starflyer.(none) 
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/tdfx_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +59 -4
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_mm.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +2 -10
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_ds.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +8 -9
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +14 -0
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +75 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/sis_drm.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +15 -6
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_state.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +7 -23
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_mem.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +10 -11
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +5 -6
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +21 -0
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +136 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_cp.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +6 -7
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_state.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +44 -57
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +1 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +16 -1
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +99 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_cce.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +8 -9
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_warp.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +0 -1
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_state.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +0 -1
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +1 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +15 -0
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +92 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/mga_dma.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +8 -26
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_mem.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +10 -11
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +0 -1
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +24 -0
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +92 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_drm.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +25 -12
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_dma.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +5 -22
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +0 -1
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +33 -0
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +101 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_drm.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +29 -14
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i830_dma.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +15 -40
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_drv.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +31 -4
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +93 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_drm.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +31 -15
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i810_dma.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +16 -32
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/ffb_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +4 -6
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_vm.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +61 -59
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_stub.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +34 -120
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_scatter.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +18 -18
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_proc.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +40 -40
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_memory.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +0 -158
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_lock.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +5 -5
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_irq.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +20 -18
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_ioctl.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +17 -19
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_init.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +1 -77
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_fops.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +12 -10
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drv.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +277 -275
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drawable.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +2 -2
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_dma.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +14 -13
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_core.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +11 -17
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_context.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +32 -32
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_bufs.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +70 -69
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_auth.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +15 -15
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_agpsupport.c
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +31 -31
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +157 -137
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/ati_pcigart.h
#   2004/11/02 21:55:07+11:00 airlied@starflyer.(none) +8 -8
#   drm: core/personality split for 2.6 kernel
#   
#   This changeset gets rid of the DRM() macros and implements a core DRM module
#   linked to a per graphics card personality module..
#   
#   Remove old 2.4 module parameters and switch to 2.6 module parameters 
#   
#   From: Jon Smirl <jonsmirl@gmail.com> and Dave Airlie <airlied@linux.ie>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_memory.h
#   2004/11/01 20:27:56+11:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_memory.c -> drivers/char/drm/drm_memory.h
# 
# drivers/char/drm/tdfx_drv.h
#   2004/11/01 20:12:34+11:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/tdfx.h -> drivers/char/drm/tdfx_drv.h
# 
# ChangeSet
#   2004/10/31 20:52:40+11:00 airlied@starflyer.(none) 
#   Merge starflyer.(none):/home/airlied/bitkeeper/drm-core
#   into starflyer.(none):/home/airlied/bitkeeper/drm-test
# 
# drivers/char/drm/drm_stub.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_proc.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_memory.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_irq.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_drv.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Auto merged
# 
# drivers/char/drm/drm_stub.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Merge rename: drivers/char/drm/drm_stub.h -> drivers/char/drm/drm_stub.c
# 
# drivers/char/drm/drm_proc.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Merge rename: drivers/char/drm/drm_proc.h -> drivers/char/drm/drm_proc.c
# 
# drivers/char/drm/drm_memory.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Merge rename: drivers/char/drm/drm_memory.h -> drivers/char/drm/drm_memory.c
# 
# drivers/char/drm/drm_irq.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Merge rename: drivers/char/drm/drm_irq.h -> drivers/char/drm/drm_irq.c
# 
# drivers/char/drm/drm_drv.c
#   2004/10/31 20:52:36+11:00 airlied@starflyer.(none) +0 -0
#   Merge rename: drivers/char/drm/drm_drv.h -> drivers/char/drm/drm_drv.c
# 
# ChangeSet
#   2004/10/27 22:33:20+10:00 airlied@starflyer.(none) 
#   drm: device minor fixups and /proc fixups
#   
#   This patch fixes up the DRM to do better minor number accounting
#   and /proc directory creation, the old code was buggy in a number
#   of situations with multiple cards, and rather ugly. It is also 
#   a step on the way to the drm_core module.
#   
#   From: Jon Smirl and Dave Airlie
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_stub.h
#   2004/10/27 22:33:12+10:00 airlied@starflyer.(none) +173 -135
#   drm: device minor fixups and /proc fixups
#   
#   This patch fixes up the DRM to do better minor number accounting
#   and /proc directory creation, the old code was buggy in a number
#   of situations with multiple cards, and rather ugly. It is also 
#   a step on the way to the drm_core module.
#   
#   From: Jon Smirl and Dave Airlie
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_proc.h
#   2004/10/27 22:33:12+10:00 airlied@starflyer.(none) +6 -14
#   drm: device minor fixups and /proc fixups
#   
#   This patch fixes up the DRM to do better minor number accounting
#   and /proc directory creation, the old code was buggy in a number
#   of situations with multiple cards, and rather ugly. It is also 
#   a step on the way to the drm_core module.
#   
#   From: Jon Smirl and Dave Airlie
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_drv.h
#   2004/10/27 22:33:12+10:00 airlied@starflyer.(none) +89 -97
#   drm: device minor fixups and /proc fixups
#   
#   This patch fixes up the DRM to do better minor number accounting
#   and /proc directory creation, the old code was buggy in a number
#   of situations with multiple cards, and rather ugly. It is also 
#   a step on the way to the drm_core module.
#   
#   From: Jon Smirl and Dave Airlie
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/10/27 22:33:12+10:00 airlied@starflyer.(none) +24 -5
#   drm: device minor fixups and /proc fixups
#   
#   This patch fixes up the DRM to do better minor number accounting
#   and /proc directory creation, the old code was buggy in a number
#   of situations with multiple cards, and rather ugly. It is also 
#   a step on the way to the drm_core module.
#   
#   From: Jon Smirl and Dave Airlie
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/10/24 16:44:56+10:00 airlied@starflyer.(none) 
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_state.c
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +2 -1
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/radeon_mem.c
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +10 -10
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/r128_state.c
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +42 -42
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/i915_mem.c
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +10 -10
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_os_linux.h
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +0 -5
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_memory_debug.h
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +1 -1
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_memory.h
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +3 -17
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_irq.h
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +2 -2
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drmP.h
#   2004/10/24 16:44:47+10:00 airlied@starflyer.(none) +20 -2
#   drm: memory allocation patch 
#   
#   This removes some unnecessary macros for allocating DRM memory.
#   It doesn't change any functionality.
#   
#   From: Jon Smirl <jonsmirl@gmail.com>
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# ChangeSet
#   2004/10/24 11:54:23+10:00 airlied@starflyer.(none) 
#   drm: initial core move infrastructure change
#   
#   Initial infrastructure - move old H files to C files
#   also Kconfig and Makefile changes
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/Makefile
#   2004/10/24 11:54:11+10:00 airlied@starflyer.(none) +6 -0
#   drm: initial core move infrastructure change
#   
#   Initial infrastructure - move old H files to C files
#   also Kconfig and Makefile changes
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/Kconfig
#   2004/10/24 11:54:11+10:00 airlied@starflyer.(none) +1 -1
#   drm: initial core move infrastructure change
#   
#   Initial infrastructure - move old H files to C files
#   also Kconfig and Makefile changes
#   
#   Signed-off-by: Dave Airlie <airlied@linux.ie>
# 
# drivers/char/drm/drm_scatter.c
#   2004/10/24 11:49:08+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_scatter.h -> drivers/char/drm/drm_scatter.c
# 
# drivers/char/drm/drm_agpsupport.c
#   2004/10/24 11:49:02+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_agpsupport.h -> drivers/char/drm/drm_agpsupport.c
# 
# drivers/char/drm/drm_vm.c
#   2004/10/24 11:48:49+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_vm.h -> drivers/char/drm/drm_vm.c
# 
# drivers/char/drm/drm_stub.c
#   2004/10/24 11:48:41+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_stub.h -> drivers/char/drm/drm_stub.c
# 
# drivers/char/drm/drm_proc.c
#   2004/10/24 11:48:34+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_proc.h -> drivers/char/drm/drm_proc.c
# 
# drivers/char/drm/drm_memory.c
#   2004/10/24 11:48:27+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_memory.h -> drivers/char/drm/drm_memory.c
# 
# drivers/char/drm/drm_lock.c
#   2004/10/24 11:48:21+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_lock.h -> drivers/char/drm/drm_lock.c
# 
# drivers/char/drm/drm_irq.c
#   2004/10/24 11:48:14+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_irq.h -> drivers/char/drm/drm_irq.c
# 
# drivers/char/drm/drm_ioctl.c
#   2004/10/24 11:48:08+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_ioctl.h -> drivers/char/drm/drm_ioctl.c
# 
# drivers/char/drm/drm_init.c
#   2004/10/24 11:48:02+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_init.h -> drivers/char/drm/drm_init.c
# 
# drivers/char/drm/drm_fops.c
#   2004/10/24 11:47:54+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_fops.h -> drivers/char/drm/drm_fops.c
# 
# drivers/char/drm/drm_drv.c
#   2004/10/24 11:47:46+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_drv.h -> drivers/char/drm/drm_drv.c
# 
# drivers/char/drm/drm_drawable.c
#   2004/10/24 11:47:39+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_drawable.h -> drivers/char/drm/drm_drawable.c
# 
# drivers/char/drm/drm_dma.c
#   2004/10/24 11:47:32+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_dma.h -> drivers/char/drm/drm_dma.c
# 
# drivers/char/drm/drm_context.c
#   2004/10/24 11:47:27+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_context.h -> drivers/char/drm/drm_context.c
# 
# drivers/char/drm/drm_bufs.c
#   2004/10/24 11:47:19+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_bufs.h -> drivers/char/drm/drm_bufs.c
# 
# drivers/char/drm/drm_auth.c
#   2004/10/24 11:46:56+10:00 airlied@starflyer.(none) +0 -0
#   Rename: drivers/char/drm/drm_auth.h -> drivers/char/drm/drm_auth.c
# 
diff -Nru a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
--- a/drivers/char/drm/Kconfig	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/Kconfig	2004-11-09 00:25:55 -08:00
@@ -5,7 +5,7 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 #
 config DRM
-	bool "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
+	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
diff -Nru a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
--- a/drivers/char/drm/Makefile	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/Makefile	2004-11-09 00:25:55 -08:00
@@ -2,6 +2,11 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
+drm-objs    :=	drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
+		drm_drv.o drm_fops.o drm_init.o drm_ioctl.o drm_irq.o \
+		drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
+		drm_agpsupport.o drm_scatter.o
+
 gamma-objs  := gamma_drv.o gamma_dma.o
 tdfx-objs   := tdfx_drv.o
 r128-objs   := r128_drv.o r128_cce.o r128_state.o r128_irq.o
@@ -13,6 +18,7 @@
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 
+obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
 obj-$(CONFIG_DRM_TDFX)	+= tdfx.o
 obj-$(CONFIG_DRM_R128)	+= r128.o
diff -Nru a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h
--- a/drivers/char/drm/ati_pcigart.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/ati_pcigart.h	2004-11-09 00:25:55 -08:00
@@ -52,7 +52,7 @@
 # define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
 # define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
 
-static unsigned long DRM(ati_alloc_pcigart_table)( void )
+static inline unsigned long drm_ati_alloc_pcigart_table( void )
 {
 	unsigned long address;
 	struct page *page;
@@ -75,7 +75,7 @@
 	return address;
 }
 
-static void DRM(ati_free_pcigart_table)( unsigned long address )
+static inline void drm_ati_free_pcigart_table( unsigned long address )
 {
 	struct page *page;
 	int i;
@@ -91,7 +91,43 @@
 	free_pages( address, ATI_PCIGART_TABLE_ORDER );
 }
 
-int DRM(ati_pcigart_init)( drm_device_t *dev,
+static inline int drm_ati_pcigart_cleanup( drm_device_t *dev,
+			      unsigned long addr,
+			      dma_addr_t bus_addr)
+{
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long pages;
+	int i;
+
+	/* we need to support large memory configurations */
+	if ( !entry ) {
+		DRM_ERROR( "no scatter/gather memory!\n" );
+		return 0;
+	}
+
+	if ( bus_addr ) {
+		pci_unmap_single(dev->pdev, bus_addr,
+				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				 PCI_DMA_TODEVICE);
+
+		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+		for ( i = 0 ; i < pages ; i++ ) {
+			if ( !entry->busaddr[i] ) break;
+			pci_unmap_single(dev->pdev, entry->busaddr[i],
+					 PAGE_SIZE, PCI_DMA_TODEVICE);
+		}
+	}
+
+	if ( addr ) {
+		drm_ati_free_pcigart_table( addr );
+	}
+
+	return 1;
+}
+
+static inline int drm_ati_pcigart_init( drm_device_t *dev,
 			   unsigned long *addr,
 			   dma_addr_t *bus_addr)
 {
@@ -106,7 +142,7 @@
 		goto done;
 	}
 
-	address = DRM(ati_alloc_pcigart_table)();
+	address = drm_ati_alloc_pcigart_table();
 	if ( !address ) {
 		DRM_ERROR( "cannot allocate PCI GART page!\n" );
 		goto done;
@@ -122,7 +158,7 @@
 				  PCI_DMA_TODEVICE);
 	if (bus_address == 0) {
 		DRM_ERROR( "unable to map PCIGART pages!\n" );
-		DRM(ati_free_pcigart_table)( address );
+		drm_ati_free_pcigart_table( address );
 		address = 0;
 		goto done;
 	}
@@ -142,7 +178,7 @@
 					   PCI_DMA_TODEVICE);
 		if (entry->busaddr[i] == 0) {
 			DRM_ERROR( "unable to map PCIGART pages!\n" );
-			DRM(ati_pcigart_cleanup)( dev, address, bus_address );
+			drm_ati_pcigart_cleanup( dev, address, bus_address );
 			address = 0;
 			bus_address = 0;
 			goto done;
@@ -169,38 +205,3 @@
 	return ret;
 }
 
-int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
-			      unsigned long addr,
-			      dma_addr_t bus_addr)
-{
-	drm_sg_mem_t *entry = dev->sg;
-	unsigned long pages;
-	int i;
-
-	/* we need to support large memory configurations */
-	if ( !entry ) {
-		DRM_ERROR( "no scatter/gather memory!\n" );
-		return 0;
-	}
-
-	if ( bus_addr ) {
-		pci_unmap_single(dev->pdev, bus_addr,
-				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
-				 PCI_DMA_TODEVICE);
-
-		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
-		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
-
-		for ( i = 0 ; i < pages ; i++ ) {
-			if ( !entry->busaddr[i] ) break;
-			pci_unmap_single(dev->pdev, entry->busaddr[i],
-					 PAGE_SIZE, PCI_DMA_TODEVICE);
-		}
-	}
-
-	if ( addr ) {
-		DRM(ati_free_pcigart_table)( addr );
-	}
-
-	return 1;
-}
diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
--- a/drivers/char/drm/drmP.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/drmP.h	2004-11-09 00:25:55 -08:00
@@ -34,6 +34,8 @@
 #ifndef _DRM_P_H_
 #define _DRM_P_H_
 
+/* If you want the memory alloc debug functionality, change define below */
+/* #define DEBUG_MEMORY */
 
 #ifdef __KERNEL__
 #ifdef __alpha__
@@ -55,6 +57,7 @@
 #include <linux/jiffies.h>
 #include <linux/smp_lock.h>	/* For (un)lock_kernel */
 #include <linux/mm.h>
+#include <linux/cdev.h>
 #if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h> /* For pte_wrprotect */
 #endif
@@ -215,7 +218,8 @@
  */
 #define DRM_MEM_ERROR(area, fmt, arg...) \
 	printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
-	       DRM(mem_stats)[area].name , ##arg)
+	       drm_mem_stats[area].name , ##arg)
+
 #define DRM_INFO(fmt, arg...)  printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
 
 /**
@@ -227,7 +231,7 @@
 #if DRM_DEBUG_CODE
 #define DRM_DEBUG(fmt, arg...)						\
 	do {								\
-		if ( DRM(flags) & DRM_FLAG_DEBUG )			\
+		if ( drm_debug )			\
 			printk(KERN_DEBUG				\
 			       "[" DRM_NAME ":%s] " fmt ,	\
 			       __FUNCTION__ , ##arg);			\
@@ -290,6 +294,18 @@
 } while (0)
 
 /**
+ * Copy and IOCTL return string to user space
+ */
+#define DRM_COPY( name, value )						\
+	len = strlen( value );						\
+	if ( len > name##_len ) len = name##_len;			\
+	name##_len = strlen( value );					\
+	if ( len && name ) {						\
+		if ( copy_to_user( name, value, len ) )			\
+			return -EFAULT;					\
+	}
+	
+/**
  * Ioctl function type.
  *
  * \param inode device inode.
@@ -475,7 +491,7 @@
 /**
  * AGP data.
  *
- * \sa DRM(agp_init)() and drm_device::agp.
+ * \sa drm_agp_init() and drm_device::agp.
  */
 typedef struct drm_agp_head {
 	DRM_AGP_KERN       agp_info;	/**< AGP device information */
@@ -533,19 +549,21 @@
 } drm_vbl_sig_t;
 
 
-/** 
- * DRM device functions structure
+/**
+ * DRM driver structure. This structure represent the common code for
+ * a family of cards. There will one drm_device for each card present
+ * in this family
  */
 struct drm_device;
 
-struct drm_driver_fn {
+struct drm_driver {
 	int (*preinit)(struct drm_device *);
-	int (*postinit)(struct drm_device *);
 	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 );
 	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);
@@ -557,6 +575,7 @@
 	void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
 	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);
@@ -565,12 +584,18 @@
 	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);
+	u32 driver_features;
+	int dev_priv_size;
+	drm_ioctl_desc_t *ioctls;
+	int num_ioctls;
+	struct file_operations fops;
+	struct pci_driver pci_driver;
 };
 /**
  * DRM device structure.
  */
 typedef struct drm_device {
-	const char	  *name;	/**< Simple driver name */
 	char		  *unique;	/**< Unique identifier: e.g., busid */
 	int		  unique_len;	/**< Length of unique field */
 	dev_t		  device;	/**< Device number for mknod */
@@ -693,15 +718,22 @@
 	drm_sigdata_t     sigdata; /**< For block_all_signals */
 	sigset_t          sigmask;
 
-	struct            drm_driver_fn fn_tbl;
+	struct            drm_driver *driver;
 	drm_local_map_t   *agp_buffer_map;
-	int               dev_priv_size;
-	u32               driver_features;
 } drm_device_t;
 
+typedef struct drm_minor {
+	enum {
+		DRM_MINOR_FREE = 0,
+		DRM_MINOR_PRIMARY,
+	} type;
+	drm_device_t *dev;
+	struct proc_dir_entry  *dev_root; /**< proc directory entry */
+} drm_minor_t;
+
 static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature)
 {
-	return ((dev->driver_features & feature) ? 1 : 0);
+	return ((dev->driver->driver_features & feature) ? 1 : 0);
 }
 
 #if __OS_HAS_AGP
@@ -722,231 +754,238 @@
 #define drm_core_has_MTRR(dev) (0)
 #endif
 
-extern void DRM(driver_register_fns)(struct drm_device *dev);
-
 /******************************************************************/
 /** \name Internal function definitions */
 /*@{*/
 
 				/* Misc. support (drm_init.h) */
-extern int	     DRM(flags);
-extern void	     DRM(parse_options)( char *s );
-extern int           DRM(cpu_valid)( void );
+extern int	     drm_flags;
+extern void	     drm_parse_options( char *s );
+extern int           drm_cpu_valid( void );
 
 				/* Driver support (drm_drv.h) */
-extern int           DRM(version)(struct inode *inode, struct file *filp,
+extern int           drm_init(struct drm_driver *driver);
+extern void          drm_exit(struct drm_driver *driver);
+extern int           drm_version(struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg);
-extern int           DRM(open)(struct inode *inode, struct file *filp);
-extern int           DRM(release)(struct inode *inode, struct file *filp);
-extern int           DRM(ioctl)(struct inode *inode, struct file *filp,
+extern int           drm_ioctl(struct inode *inode, struct file *filp,
 				unsigned int cmd, unsigned long arg);
-extern int           DRM(lock)(struct inode *inode, struct file *filp,
-			       unsigned int cmd, unsigned long arg);
-extern int           DRM(unlock)(struct inode *inode, struct file *filp,
-				 unsigned int cmd, unsigned long arg);
+extern int           drm_takedown(drm_device_t * dev);
 
 				/* Device support (drm_fops.h) */
-extern int	     DRM(open_helper)(struct inode *inode, struct file *filp,
+extern int           drm_open(struct inode *inode, struct file *filp);
+extern int           drm_stub_open(struct inode *inode, struct file *filp);
+extern int	     drm_open_helper(struct inode *inode, struct file *filp,
 				      drm_device_t *dev);
-extern int	     DRM(flush)(struct file *filp);
-extern int	     DRM(fasync)(int fd, struct file *filp, int on);
+extern int	     drm_flush(struct file *filp);
+extern int	     drm_fasync(int fd, struct file *filp, int on);
+extern int           drm_release(struct inode *inode, struct file *filp);
 
 				/* Mapping support (drm_vm.h) */
-extern void	     DRM(vm_open)(struct vm_area_struct *vma);
-extern void	     DRM(vm_close)(struct vm_area_struct *vma);
-extern void	     DRM(vm_shm_close)(struct vm_area_struct *vma);
-extern int	     DRM(mmap_dma)(struct file *filp,
+extern void	     drm_vm_open(struct vm_area_struct *vma);
+extern void	     drm_vm_close(struct vm_area_struct *vma);
+extern void	     drm_vm_shm_close(struct vm_area_struct *vma);
+extern int	     drm_mmap_dma(struct file *filp,
 				   struct vm_area_struct *vma);
-extern int	     DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
-extern unsigned int  DRM(poll)(struct file *filp, struct poll_table_struct *wait);
-extern ssize_t       DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off);
+extern int	     drm_mmap(struct file *filp, struct vm_area_struct *vma);
+extern unsigned int  drm_poll(struct file *filp, struct poll_table_struct *wait);
+extern ssize_t       drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off);
 
 				/* Memory management support (drm_memory.h) */
-extern void	     DRM(mem_init)(void);
-extern int	     DRM(mem_info)(char *buf, char **start, off_t offset,
+#include "drm_memory.h"
+extern void	     drm_mem_init(void);
+extern int	     drm_mem_info(char *buf, char **start, off_t offset,
 				   int request, int *eof, void *data);
-extern void	     *DRM(alloc)(size_t size, int area);
-extern void	     *DRM(calloc)(size_t nmemb, size_t size, int area);
-extern void	     *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
+extern void	     *drm_calloc(size_t nmemb, size_t size, int area);
+extern void	     *drm_realloc(void *oldpt, size_t oldsize, size_t size,
 				   int area);
-extern void	     DRM(free)(void *pt, size_t size, int area);
-extern unsigned long DRM(alloc_pages)(int order, int area);
-extern void	     DRM(free_pages)(unsigned long address, int order,
+extern unsigned long drm_alloc_pages(int order, int area);
+extern void	     drm_free_pages(unsigned long address, int order,
 				     int area);
-extern void	     *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev);
-extern void	     *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
+extern void	     *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void	     *drm_ioremap_nocache(unsigned long offset, unsigned long size,
 					   drm_device_t *dev);
-extern void	     DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
+extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
 
-extern DRM_AGP_MEM   *DRM(alloc_agp)(int pages, u32 type);
-extern int           DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
-extern int           DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
-extern int           DRM(unbind_agp)(DRM_AGP_MEM *handle);
+extern DRM_AGP_MEM   *drm_alloc_agp(int pages, u32 type);
+extern int           drm_free_agp(DRM_AGP_MEM *handle, int pages);
+extern int           drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
+extern int           drm_unbind_agp(DRM_AGP_MEM *handle);
 
 				/* Misc. IOCTL support (drm_ioctl.h) */
-extern int	     DRM(irq_by_busid)(struct inode *inode, struct file *filp,
+extern int	     drm_irq_by_busid(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern int	     DRM(getunique)(struct inode *inode, struct file *filp,
+extern int	     drm_getunique(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(setunique)(struct inode *inode, struct file *filp,
+extern int	     drm_setunique(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(getmap)(struct inode *inode, struct file *filp,
+extern int	     drm_getmap(struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg);
-extern int	     DRM(getclient)(struct inode *inode, struct file *filp,
+extern int	     drm_getclient(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int	     DRM(getstats)(struct inode *inode, struct file *filp,
+extern int	     drm_getstats(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
-extern int	     DRM(setversion)(struct inode *inode, struct file *filp,
+extern int	     drm_setversion(struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg);
 
 				/* Context IOCTL support (drm_context.h) */
-extern int	     DRM(resctx)( struct inode *inode, struct file *filp,
+extern int	     drm_resctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(addctx)( struct inode *inode, struct file *filp,
+extern int	     drm_addctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(modctx)( struct inode *inode, struct file *filp,
+extern int	     drm_modctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(getctx)( struct inode *inode, struct file *filp,
+extern int	     drm_getctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(switchctx)( struct inode *inode, struct file *filp,
+extern int	     drm_switchctx( struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg );
-extern int	     DRM(newctx)( struct inode *inode, struct file *filp,
+extern int	     drm_newctx( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(rmctx)( struct inode *inode, struct file *filp,
+extern int	     drm_rmctx( struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg );
 
-extern int	     DRM(context_switch)(drm_device_t *dev, int old, int new);
-extern int	     DRM(context_switch_complete)(drm_device_t *dev, int new);
+extern int	     drm_context_switch(drm_device_t *dev, int old, int new);
+extern int	     drm_context_switch_complete(drm_device_t *dev, int new);
 
-extern int	     DRM(ctxbitmap_init)( drm_device_t *dev );
-extern void	     DRM(ctxbitmap_cleanup)( drm_device_t *dev );
+extern int	     drm_ctxbitmap_init( drm_device_t *dev );
+extern void	     drm_ctxbitmap_cleanup( drm_device_t *dev );
+extern void          drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle );
 
-extern int	     DRM(setsareactx)( struct inode *inode, struct file *filp,
+extern int	     drm_setsareactx( struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg );
-extern int	     DRM(getsareactx)( struct inode *inode, struct file *filp,
+extern int	     drm_getsareactx( struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg );
 
 				/* Drawable IOCTL support (drm_drawable.h) */
-extern int	     DRM(adddraw)(struct inode *inode, struct file *filp,
+extern int	     drm_adddraw(struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg);
-extern int	     DRM(rmdraw)(struct inode *inode, struct file *filp,
+extern int	     drm_rmdraw(struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg);
 
 
 				/* Authentication IOCTL support (drm_auth.h) */
-extern int	     DRM(add_magic)(drm_device_t *dev, drm_file_t *priv,
+extern int	     drm_add_magic(drm_device_t *dev, drm_file_t *priv,
 				    drm_magic_t magic);
-extern int	     DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic);
-extern int	     DRM(getmagic)(struct inode *inode, struct file *filp,
+extern int	     drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
+extern int	     drm_getmagic(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
-extern int	     DRM(authmagic)(struct inode *inode, struct file *filp,
+extern int	     drm_authmagic(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
 
                                 /* Placeholder for ioctls past */
-extern int	     DRM(noop)(struct inode *inode, struct file *filp,
+extern int	     drm_noop(struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg);
 
 				/* Locking IOCTL support (drm_lock.h) */
-extern int	     DRM(lock_take)(__volatile__ unsigned int *lock,
+extern int           drm_lock(struct inode *inode, struct file *filp,
+			       unsigned int cmd, unsigned long arg);
+extern int           drm_unlock(struct inode *inode, struct file *filp,
+				 unsigned int cmd, unsigned long arg);
+extern int	     drm_lock_take(__volatile__ unsigned int *lock,
 				    unsigned int context);
-extern int	     DRM(lock_transfer)(drm_device_t *dev,
+extern int	     drm_lock_transfer(drm_device_t *dev,
 					__volatile__ unsigned int *lock,
 					unsigned int context);
-extern int	     DRM(lock_free)(drm_device_t *dev,
+extern int	     drm_lock_free(drm_device_t *dev,
 				    __volatile__ unsigned int *lock,
 				    unsigned int context);
-extern int           DRM(notifier)(void *priv);
+extern int           drm_notifier(void *priv);
 
 				/* Buffer management support (drm_bufs.h) */
-extern int	     DRM(order)( unsigned long size );
-extern int	     DRM(addmap)( struct inode *inode, struct file *filp,
+extern int	     drm_order( unsigned long size );
+extern int	     drm_addmap( struct inode *inode, struct file *filp,
 				  unsigned int cmd, unsigned long arg );
-extern int	     DRM(rmmap)( struct inode *inode, struct file *filp,
+extern int	     drm_rmmap( struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg );
-extern int	     DRM(addbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_addbufs( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
-extern int	     DRM(infobufs)( struct inode *inode, struct file *filp,
+extern int	     drm_infobufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(markbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_markbufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(freebufs)( struct inode *inode, struct file *filp,
+extern int	     drm_freebufs( struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg );
-extern int	     DRM(mapbufs)( struct inode *inode, struct file *filp,
+extern int	     drm_mapbufs( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
 
 				/* DMA support (drm_dma.h) */
-extern int	     DRM(dma_setup)(drm_device_t *dev);
-extern void	     DRM(dma_takedown)(drm_device_t *dev);
-extern void	     DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
-extern void	     DRM(reclaim_buffers)( struct file *filp );
+extern int	     drm_dma_setup(drm_device_t *dev);
+extern void	     drm_dma_takedown(drm_device_t *dev);
+extern void	     drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
+extern void	     drm_core_reclaim_buffers( struct file *filp );
 
 				/* IRQ support (drm_irq.h) */
-extern int           DRM(control)( struct inode *inode, struct file *filp,
+extern int           drm_control( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
-extern int           DRM(irq_install)( drm_device_t *dev );
-extern int           DRM(irq_uninstall)( drm_device_t *dev );
-extern irqreturn_t   DRM(irq_handler)( DRM_IRQ_ARGS );
-extern void          DRM(driver_irq_preinstall)( drm_device_t *dev );
-extern void          DRM(driver_irq_postinstall)( drm_device_t *dev );
-extern void          DRM(driver_irq_uninstall)( drm_device_t *dev );
+extern int           drm_irq_install( drm_device_t *dev );
+extern int           drm_irq_uninstall( drm_device_t *dev );
+extern irqreturn_t   drm_irq_handler( DRM_IRQ_ARGS );
+extern void          drm_driver_irq_preinstall( drm_device_t *dev );
+extern void          drm_driver_irq_postinstall( drm_device_t *dev );
+extern void          drm_driver_irq_uninstall( drm_device_t *dev );
 
-extern int           DRM(wait_vblank)(struct inode *inode, struct file *filp,
+extern int           drm_wait_vblank(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int           DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
-extern void          DRM(vbl_send_signals)( drm_device_t *dev );
+extern int           drm_vblank_wait(drm_device_t *dev, unsigned int *vbl_seq);
+extern void          drm_vbl_send_signals( drm_device_t *dev );
 
 				/* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *DRM(agp_init)(void);
-extern void           DRM(agp_uninit)(void);
-extern int            DRM(agp_acquire)(struct inode *inode, struct file *filp,
+extern drm_agp_head_t *drm_agp_init(void);
+extern void           drm_agp_uninit(void);
+extern int            drm_agp_acquire(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern void           DRM(agp_do_release)(void);
-extern int            DRM(agp_release)(struct inode *inode, struct file *filp,
+extern void           drm_agp_do_release(void);
+extern int            drm_agp_release(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_enable)(struct inode *inode, struct file *filp,
+extern int            drm_agp_enable(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_info)(struct inode *inode, struct file *filp,
+extern int            drm_agp_info(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_alloc)(struct inode *inode, struct file *filp,
+extern int            drm_agp_alloc(struct inode *inode, struct file *filp,
 				     unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_free)(struct inode *inode, struct file *filp,
+extern int            drm_agp_free(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_unbind)(struct inode *inode, struct file *filp,
+extern int            drm_agp_unbind(struct inode *inode, struct file *filp,
 				      unsigned int cmd, unsigned long arg);
-extern int            DRM(agp_bind)(struct inode *inode, struct file *filp,
+extern int            drm_agp_bind(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern DRM_AGP_MEM    *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int            DRM(agp_free_memory)(DRM_AGP_MEM *handle);
-extern int            DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start);
-extern int            DRM(agp_unbind_memory)(DRM_AGP_MEM *handle);
+extern DRM_AGP_MEM    *drm_agp_allocate_memory(size_t pages, u32 type);
+extern int            drm_agp_free_memory(DRM_AGP_MEM *handle);
+extern int            drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
+extern int            drm_agp_unbind_memory(DRM_AGP_MEM *handle);
 
 				/* Stub support (drm_stub.h) */
-int                   DRM(stub_register)(const char *name,
-					 struct file_operations *fops,
-					 drm_device_t *dev);
-int                   DRM(stub_unregister)(int minor);
+extern int            drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver);
+
+extern int 	      drm_put_minor(drm_device_t *dev);
+extern unsigned int   drm_debug;
+extern unsigned int   drm_cards_limit;
+extern drm_minor_t    *drm_minors;
+extern struct class_simple *drm_class;
+extern struct proc_dir_entry *drm_proc_root;
+extern struct file_operations drm_stub_fops;
 
 				/* Proc support (drm_proc.h) */
-extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
+extern int            drm_proc_init(drm_device_t *dev,
 					     int minor,
 					     struct proc_dir_entry *root,
 					     struct proc_dir_entry **dev_root);
-extern int            DRM(proc_cleanup)(int minor,
+extern int            drm_proc_cleanup(int minor,
 					struct proc_dir_entry *root,
 					struct proc_dir_entry *dev_root);
 
 				/* Scatter Gather Support (drm_scatter.h) */
-extern void           DRM(sg_cleanup)(drm_sg_mem_t *entry);
-extern int            DRM(sg_alloc)(struct inode *inode, struct file *filp,
+extern void           drm_sg_cleanup(drm_sg_mem_t *entry);
+extern int            drm_sg_alloc(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern int            DRM(sg_free)(struct inode *inode, struct file *filp,
+extern int            drm_sg_free(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
 
                                /* ATI PCIGART support (ati_pcigart.h) */
-extern int            DRM(ati_pcigart_init)(drm_device_t *dev,
+extern int            drm_ati_pcigart_init(drm_device_t *dev,
 					    unsigned long *addr,
 					    dma_addr_t *bus_addr);
-extern int            DRM(ati_pcigart_cleanup)(drm_device_t *dev,
+extern int            drm_ati_pcigart_cleanup(drm_device_t *dev,
 					       unsigned long addr,
 					       dma_addr_t bus_addr);
 
@@ -954,18 +993,18 @@
 /* Inline replacements for DRM_IOREMAP macros */
 static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
 {
-	map->handle = DRM(ioremap)( map->offset, map->size, dev );
+	map->handle = drm_ioremap( map->offset, map->size, dev );
 }
 
 static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
 {
-	map->handle = DRM(ioremap_nocache)(map->offset, map->size, dev);
+	map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
 }
 
 static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
 {
 	if ( map->handle && map->size )
-		DRM(ioremapfree)( map->handle, map->size, dev );
+		drm_ioremapfree( map->handle, map->size, dev );
 }
 
 static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
@@ -984,10 +1023,28 @@
 static __inline__ void drm_core_dropmap(struct drm_map *map)
 {
 }
+
+#ifndef DEBUG_MEMORY
+/** Wrapper around kmalloc() */
+static __inline__ void *drm_alloc(size_t size, int area)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+/** Wrapper around kfree() */
+static __inline__ void drm_free(void *pt, size_t size, int area)
+{
+	kfree(pt);
+}
+#else
+extern void *drm_alloc(size_t size, int area);
+extern void drm_free(void *pt, size_t size, int area);
+#endif
+
 /*@}*/
 
-extern unsigned long DRM(core_get_map_ofs)(drm_map_t *map);
-extern unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev);
+extern unsigned long drm_core_get_map_ofs(drm_map_t *map);
+extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
 
 #endif /* __KERNEL__ */
 #endif
diff -Nru a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_agpsupport.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,468 @@
+/**
+ * \file drm_agpsupport.h 
+ * DRM support for AGP/GART backend
+ *    
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+#include <linux/module.h>
+
+#if __OS_HAS_AGP
+
+#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
+#define DRM_AGP_PUT inter_module_put("drm_agp")
+
+/**
+ * Pointer to the drm_agp_t structure made available by the agpgart module.
+ */
+static const drm_agp_t *drm_agp = NULL;
+
+/**
+ * AGP information ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a (output) drm_agp_info structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been initialized and acquired and fills in the
+ * drm_agp_info structure with the information in drm_agp_head::agp_info.
+ */
+int drm_agp_info(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	DRM_AGP_KERN     *kern;
+	drm_agp_info_t   info;
+
+	if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
+		return -EINVAL;
+
+	kern                   = &dev->agp->agp_info;
+	info.agp_version_major = kern->version.major;
+	info.agp_version_minor = kern->version.minor;
+	info.mode              = kern->mode;
+	info.aperture_base     = kern->aper_base;
+	info.aperture_size     = kern->aper_size * 1024 * 1024;
+	info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
+	info.memory_used       = kern->current_memory << PAGE_SHIFT;
+	info.id_vendor         = kern->device->vendor;
+	info.id_device         = kern->device->device;
+
+	if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Acquire the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure. 
+ *
+ * Verifies the AGP device hasn't been acquired before and calls
+ * drm_agp->acquire().
+ */
+int drm_agp_acquire(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	int              retcode;
+
+	if (!dev->agp)
+		return -ENODEV;
+	if (dev->agp->acquired)
+		return -EBUSY;
+	if (!drm_agp->acquire)
+		return -EINVAL;
+	if ((retcode = drm_agp->acquire()))
+		return retcode;
+	dev->agp->acquired = 1;
+	return 0;
+}
+
+/**
+ * Release the AGP device (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired and calls drm_agp->release().
+ */
+int drm_agp_release(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+
+	if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
+		return -EINVAL;
+	drm_agp->release();
+	dev->agp->acquired = 0;
+	return 0;
+
+}
+
+/**
+ * Release the AGP device.
+ *
+ * Calls drm_agp->release().
+ */
+void drm_agp_do_release(void)
+{
+	if (drm_agp->release)
+		drm_agp->release();
+}
+
+/**
+ * Enable the AGP bus.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_mode structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device has been acquired but not enabled, and calls
+ * drm_agp->enable().
+ */
+int drm_agp_enable(struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_mode_t   mode;
+
+	if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
+		return -EINVAL;
+
+	if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
+		return -EFAULT;
+
+	dev->agp->mode    = mode.mode;
+	drm_agp->enable(mode.mode);
+	dev->agp->base    = dev->agp->agp_info.aper_base;
+	dev->agp->enabled = 1;
+	return 0;
+}
+
+/**
+ * Allocate AGP memory.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Verifies the AGP device is present and has been acquired, allocates the
+ * memory via alloc_agp() and creates a drm_agp_mem entry for it.
+ */
+int drm_agp_alloc(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_buffer_t request;
+	drm_agp_mem_t    *entry;
+	DRM_AGP_MEM      *memory;
+	unsigned long    pages;
+	u32 		 type;
+	drm_agp_buffer_t __user *argp = (void __user *)arg;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, argp, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
+		return -ENOMEM;
+
+   	memset(entry, 0, sizeof(*entry));
+
+	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+	type = (u32) request.type;
+
+	if (!(memory = drm_alloc_agp(pages, type))) {
+		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+		return -ENOMEM;
+	}
+
+	entry->handle    = (unsigned long)memory->key + 1;
+	entry->memory    = memory;
+	entry->bound     = 0;
+	entry->pages     = pages;
+	entry->prev      = NULL;
+	entry->next      = dev->agp->memory;
+	if (dev->agp->memory)
+		dev->agp->memory->prev = entry;
+	dev->agp->memory = entry;
+
+	request.handle   = entry->handle;
+	request.physical = memory->physical;
+
+	if (copy_to_user(argp, &request, sizeof(request))) {
+		dev->agp->memory       = entry->next;
+		dev->agp->memory->prev = NULL;
+		drm_free_agp(memory, pages);
+		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+		return -EFAULT;
+	}
+	return 0;
+}
+
+/**
+ * Search for the AGP memory entry associated with a handle.
+ *
+ * \param dev DRM device structure.
+ * \param handle AGP memory handle.
+ * \return pointer to the drm_agp_mem structure associated with \p handle.
+ * 
+ * Walks through drm_agp_head::memory until finding a matching handle.
+ */
+static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
+					    unsigned long handle)
+{
+	drm_agp_mem_t *entry;
+
+	for (entry = dev->agp->memory; entry; entry = entry->next) {
+		if (entry->handle == handle)
+			return entry;
+	}
+	return NULL;
+}
+
+/**
+ * Unbind AGP memory from the GATT (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and acquired, looks-up the AGP memory
+ * entry and passes it to the unbind_agp() function.
+ */
+int drm_agp_unbind(struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	  *priv	 = filp->private_data;
+	drm_device_t	  *dev	 = priv->dev;
+	drm_agp_binding_t request;
+	drm_agp_mem_t     *entry;
+	int ret;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (!entry->bound)
+		return -EINVAL;
+	ret = drm_unbind_agp(entry->memory);
+	if (ret == 0)
+	    entry->bound = 0;
+	return ret;
+}
+
+/**
+ * Bind AGP memory into the GATT (ioctl)
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_binding structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and that no memory
+ * is currently bound into the GATT. Looks-up the AGP memory entry and passes
+ * it to bind_agp() function.
+ */
+int drm_agp_bind(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	  *priv	 = filp->private_data;
+	drm_device_t	  *dev	 = priv->dev;
+	drm_agp_binding_t request;
+	drm_agp_mem_t     *entry;
+	int               retcode;
+	int               page;
+
+	if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (entry->bound)
+		return -EINVAL;
+	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+	if ((retcode = drm_bind_agp(entry->memory, page)))
+		return retcode;
+	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+	DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
+		  dev->agp->base, entry->bound);
+	return 0;
+}
+
+/**
+ * Free AGP memory (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_agp_buffer structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the AGP device is present and has been acquired and looks up the
+ * AGP memory entry. If the memory it's currently bound, unbind it via
+ * unbind_agp(). Frees it via free_agp() as well as the entry itself
+ * and unlinks from the doubly linked list it's inserted in.
+ */
+int drm_agp_free(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_agp_buffer_t request;
+	drm_agp_mem_t    *entry;
+
+	if (!dev->agp || !dev->agp->acquired)
+		return -EINVAL;
+	if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
+		return -EFAULT;
+	if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
+		return -EINVAL;
+	if (entry->bound)
+		drm_unbind_agp(entry->memory);
+
+	if (entry->prev)
+		entry->prev->next = entry->next;
+	else
+		dev->agp->memory = entry->next;
+
+	if (entry->next)
+		entry->next->prev = entry->prev;
+
+	drm_free_agp(entry->memory, entry->pages);
+	drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+	return 0;
+}
+
+/**
+ * Initialize the AGP resources.
+ *
+ * \return pointer to a drm_agp_head structure.
+ *
+ * Gets the drm_agp_t structure which is made available by the agpgart module
+ * via the inter_module_* functions. Creates and initializes a drm_agp_head
+ * structure.
+ */
+drm_agp_head_t *drm_agp_init(void)
+{
+	drm_agp_head_t *head         = NULL;
+
+	drm_agp = DRM_AGP_GET;
+	if (drm_agp) {
+		if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
+			return NULL;
+		memset((void *)head, 0, sizeof(*head));
+		drm_agp->copy_info(&head->agp_info);
+		if (head->agp_info.chipset == NOT_SUPPORTED) {
+			drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
+			return NULL;
+		}
+		head->memory = NULL;
+#if LINUX_VERSION_CODE <= 0x020408
+		head->cant_use_aperture = 0;
+		head->page_mask = ~(0xfff);
+#else
+		head->cant_use_aperture = head->agp_info.cant_use_aperture;
+		head->page_mask = head->agp_info.page_mask;
+#endif
+	}
+	return head;
+}
+
+/**
+ * Free the AGP resources.
+ *
+ * Releases the pointer in ::drm_agp.
+ */
+void drm_agp_uninit(void)
+{
+	DRM_AGP_PUT;
+	drm_agp = NULL;
+}
+
+/** Calls drm_agp->allocate_memory() */
+DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type)
+{
+	if (!drm_agp->allocate_memory)
+		return NULL;
+	return drm_agp->allocate_memory(pages, type);
+}
+
+/** Calls drm_agp->free_memory() */
+int drm_agp_free_memory(DRM_AGP_MEM *handle)
+{
+	if (!handle || !drm_agp->free_memory)
+		return 0;
+	drm_agp->free_memory(handle);
+	return 1;
+}
+
+/** Calls drm_agp->bind_memory() */
+int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
+{
+	if (!handle || !drm_agp->bind_memory)
+		return -EINVAL;
+	return drm_agp->bind_memory(handle, start);
+}
+
+/** Calls drm_agp->unbind_memory() */
+int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
+{
+	if (!handle || !drm_agp->unbind_memory)
+		return -EINVAL;
+	return drm_agp->unbind_memory(handle);
+}
+
+#endif /* __OS_HAS_AGP */
diff -Nru a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h
--- a/drivers/char/drm/drm_agpsupport.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,468 +0,0 @@
-/**
- * \file drm_agpsupport.h 
- * DRM support for AGP/GART backend
- *    
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-#include <linux/module.h>
-
-#if __OS_HAS_AGP
-
-#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
-#define DRM_AGP_PUT inter_module_put("drm_agp")
-
-/**
- * Pointer to the drm_agp_t structure made available by the agpgart module.
- */
-static const drm_agp_t *drm_agp = NULL;
-
-/**
- * AGP information ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a (output) drm_agp_info structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been initialized and acquired and fills in the
- * drm_agp_info structure with the information in drm_agp_head::agp_info.
- */
-int DRM(agp_info)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	DRM_AGP_KERN     *kern;
-	drm_agp_info_t   info;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
-		return -EINVAL;
-
-	kern                   = &dev->agp->agp_info;
-	info.agp_version_major = kern->version.major;
-	info.agp_version_minor = kern->version.minor;
-	info.mode              = kern->mode;
-	info.aperture_base     = kern->aper_base;
-	info.aperture_size     = kern->aper_size * 1024 * 1024;
-	info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
-	info.memory_used       = kern->current_memory << PAGE_SHIFT;
-	info.id_vendor         = kern->device->vendor;
-	info.id_device         = kern->device->device;
-
-	if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Acquire the AGP device (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or a negative number on failure. 
- *
- * Verifies the AGP device hasn't been acquired before and calls
- * drm_agp->acquire().
- */
-int DRM(agp_acquire)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	int              retcode;
-
-	if (!dev->agp)
-		return -ENODEV;
-	if (dev->agp->acquired)
-		return -EBUSY;
-	if (!drm_agp->acquire)
-		return -EINVAL;
-	if ((retcode = drm_agp->acquire()))
-		return retcode;
-	dev->agp->acquired = 1;
-	return 0;
-}
-
-/**
- * Release the AGP device (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been acquired and calls drm_agp->release().
- */
-int DRM(agp_release)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
-		return -EINVAL;
-	drm_agp->release();
-	dev->agp->acquired = 0;
-	return 0;
-
-}
-
-/**
- * Release the AGP device.
- *
- * Calls drm_agp->release().
- */
-void DRM(agp_do_release)(void)
-{
-	if (drm_agp->release)
-		drm_agp->release();
-}
-
-/**
- * Enable the AGP bus.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_mode structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device has been acquired but not enabled, and calls
- * drm_agp->enable().
- */
-int DRM(agp_enable)(struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_mode_t   mode;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
-		return -EINVAL;
-
-	if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
-		return -EFAULT;
-
-	dev->agp->mode    = mode.mode;
-	drm_agp->enable(mode.mode);
-	dev->agp->base    = dev->agp->agp_info.aper_base;
-	dev->agp->enabled = 1;
-	return 0;
-}
-
-/**
- * Allocate AGP memory.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_buffer structure.
- * \return zero on success or a negative number on failure.
- * 
- * Verifies the AGP device is present and has been acquired, allocates the
- * memory via alloc_agp() and creates a drm_agp_mem entry for it.
- */
-int DRM(agp_alloc)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_buffer_t request;
-	drm_agp_mem_t    *entry;
-	DRM_AGP_MEM      *memory;
-	unsigned long    pages;
-	u32 		 type;
-	drm_agp_buffer_t __user *argp = (void __user *)arg;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, argp, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
-		return -ENOMEM;
-
-   	memset(entry, 0, sizeof(*entry));
-
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	type = (u32) request.type;
-
-	if (!(memory = DRM(alloc_agp)(pages, type))) {
-		DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-		return -ENOMEM;
-	}
-
-	entry->handle    = (unsigned long)memory->key + 1;
-	entry->memory    = memory;
-	entry->bound     = 0;
-	entry->pages     = pages;
-	entry->prev      = NULL;
-	entry->next      = dev->agp->memory;
-	if (dev->agp->memory)
-		dev->agp->memory->prev = entry;
-	dev->agp->memory = entry;
-
-	request.handle   = entry->handle;
-	request.physical = memory->physical;
-
-	if (copy_to_user(argp, &request, sizeof(request))) {
-		dev->agp->memory       = entry->next;
-		dev->agp->memory->prev = NULL;
-		DRM(free_agp)(memory, pages);
-		DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-		return -EFAULT;
-	}
-	return 0;
-}
-
-/**
- * Search for the AGP memory entry associated with a handle.
- *
- * \param dev DRM device structure.
- * \param handle AGP memory handle.
- * \return pointer to the drm_agp_mem structure associated with \p handle.
- * 
- * Walks through drm_agp_head::memory until finding a matching handle.
- */
-static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
-					    unsigned long handle)
-{
-	drm_agp_mem_t *entry;
-
-	for (entry = dev->agp->memory; entry; entry = entry->next) {
-		if (entry->handle == handle)
-			return entry;
-	}
-	return NULL;
-}
-
-/**
- * Unbind AGP memory from the GATT (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_binding structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and acquired, looks-up the AGP memory
- * entry and passes it to the unbind_agp() function.
- */
-int DRM(agp_unbind)(struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	  *priv	 = filp->private_data;
-	drm_device_t	  *dev	 = priv->dev;
-	drm_agp_binding_t request;
-	drm_agp_mem_t     *entry;
-	int ret;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (!entry->bound)
-		return -EINVAL;
-	ret = DRM(unbind_agp)(entry->memory);
-	if (ret == 0)
-	    entry->bound = 0;
-	return ret;
-}
-
-/**
- * Bind AGP memory into the GATT (ioctl)
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_binding structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and has been acquired and that no memory
- * is currently bound into the GATT. Looks-up the AGP memory entry and passes
- * it to bind_agp() function.
- */
-int DRM(agp_bind)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	  *priv	 = filp->private_data;
-	drm_device_t	  *dev	 = priv->dev;
-	drm_agp_binding_t request;
-	drm_agp_mem_t     *entry;
-	int               retcode;
-	int               page;
-
-	if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (entry->bound)
-		return -EINVAL;
-	page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
-	if ((retcode = DRM(bind_agp)(entry->memory, page)))
-		return retcode;
-	entry->bound = dev->agp->base + (page << PAGE_SHIFT);
-	DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
-		  dev->agp->base, entry->bound);
-	return 0;
-}
-
-/**
- * Free AGP memory (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_agp_buffer structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the AGP device is present and has been acquired and looks up the
- * AGP memory entry. If the memory it's currently bound, unbind it via
- * unbind_agp(). Frees it via free_agp() as well as the entry itself
- * and unlinks from the doubly linked list it's inserted in.
- */
-int DRM(agp_free)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_agp_buffer_t request;
-	drm_agp_mem_t    *entry;
-
-	if (!dev->agp || !dev->agp->acquired)
-		return -EINVAL;
-	if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
-		return -EFAULT;
-	if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
-		return -EINVAL;
-	if (entry->bound)
-		DRM(unbind_agp)(entry->memory);
-
-	if (entry->prev)
-		entry->prev->next = entry->next;
-	else
-		dev->agp->memory = entry->next;
-
-	if (entry->next)
-		entry->next->prev = entry->prev;
-
-	DRM(free_agp)(entry->memory, entry->pages);
-	DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-	return 0;
-}
-
-/**
- * Initialize the AGP resources.
- *
- * \return pointer to a drm_agp_head structure.
- *
- * Gets the drm_agp_t structure which is made available by the agpgart module
- * via the inter_module_* functions. Creates and initializes a drm_agp_head
- * structure.
- */
-drm_agp_head_t *DRM(agp_init)(void)
-{
-	drm_agp_head_t *head         = NULL;
-
-	drm_agp = DRM_AGP_GET;
-	if (drm_agp) {
-		if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
-			return NULL;
-		memset((void *)head, 0, sizeof(*head));
-		drm_agp->copy_info(&head->agp_info);
-		if (head->agp_info.chipset == NOT_SUPPORTED) {
-			DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
-			return NULL;
-		}
-		head->memory = NULL;
-#if LINUX_VERSION_CODE <= 0x020408
-		head->cant_use_aperture = 0;
-		head->page_mask = ~(0xfff);
-#else
-		head->cant_use_aperture = head->agp_info.cant_use_aperture;
-		head->page_mask = head->agp_info.page_mask;
-#endif
-	}
-	return head;
-}
-
-/**
- * Free the AGP resources.
- *
- * Releases the pointer in ::drm_agp.
- */
-void DRM(agp_uninit)(void)
-{
-	DRM_AGP_PUT;
-	drm_agp = NULL;
-}
-
-/** Calls drm_agp->allocate_memory() */
-DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type)
-{
-	if (!drm_agp->allocate_memory)
-		return NULL;
-	return drm_agp->allocate_memory(pages, type);
-}
-
-/** Calls drm_agp->free_memory() */
-int DRM(agp_free_memory)(DRM_AGP_MEM *handle)
-{
-	if (!handle || !drm_agp->free_memory)
-		return 0;
-	drm_agp->free_memory(handle);
-	return 1;
-}
-
-/** Calls drm_agp->bind_memory() */
-int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start)
-{
-	if (!handle || !drm_agp->bind_memory)
-		return -EINVAL;
-	return drm_agp->bind_memory(handle, start);
-}
-
-/** Calls drm_agp->unbind_memory() */
-int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle)
-{
-	if (!handle || !drm_agp->unbind_memory)
-		return -EINVAL;
-	return drm_agp->unbind_memory(handle);
-}
-
-#endif /* __OS_HAS_AGP */
diff -Nru a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_auth.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,230 @@
+/**
+ * \file drm_auth.h 
+ * IOCTLs for authentication
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+/**
+ * Generate a hash key from a magic.
+ *
+ * \param magic magic.
+ * \return hash key.
+ *
+ * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
+ * a power of 2.
+ */
+static int drm_hash_magic(drm_magic_t magic)
+{
+	return magic & (DRM_HASH_SIZE-1);
+}
+
+/**
+ * Find the file with the given magic number.
+ *
+ * \param dev DRM device.
+ * \param magic magic number.
+ *
+ * Searches in drm_device::magiclist within all files with the same hash key
+ * the one with matching magic number, while holding the drm_device::struct_sem
+ * lock.
+ */
+static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
+{
+	drm_file_t	  *retval = NULL;
+	drm_magic_entry_t *pt;
+	int		  hash	  = drm_hash_magic(magic);
+
+	down(&dev->struct_sem);
+	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+		if (pt->magic == magic) {
+			retval = pt->priv;
+			break;
+		}
+	}
+	up(&dev->struct_sem);
+	return retval;
+}
+
+/**
+ * Adds a magic number.
+ * 
+ * \param dev DRM device.
+ * \param priv file private data.
+ * \param magic magic number.
+ *
+ * Creates a drm_magic_entry structure and appends to the linked list
+ * associated the magic number hash key in drm_device::magiclist, while holding
+ * the drm_device::struct_sem lock.
+ */
+int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+{
+	int		  hash;
+	drm_magic_entry_t *entry;
+
+	DRM_DEBUG("%d\n", magic);
+
+	hash	     = drm_hash_magic(magic);
+	entry	     = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+	if (!entry) return -ENOMEM;
+	memset(entry, 0, sizeof(*entry));
+	entry->magic = magic;
+	entry->priv  = priv;
+	entry->next  = NULL;
+
+	down(&dev->struct_sem);
+	if (dev->magiclist[hash].tail) {
+		dev->magiclist[hash].tail->next = entry;
+		dev->magiclist[hash].tail	= entry;
+	} else {
+		dev->magiclist[hash].head	= entry;
+		dev->magiclist[hash].tail	= entry;
+	}
+	up(&dev->struct_sem);
+
+	return 0;
+}
+
+/**
+ * Remove a magic number.
+ * 
+ * \param dev DRM device.
+ * \param magic magic number.
+ *
+ * Searches and unlinks the entry in drm_device::magiclist with the magic
+ * number hash key, while holding the drm_device::struct_sem lock.
+ */
+int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+{
+	drm_magic_entry_t *prev = NULL;
+	drm_magic_entry_t *pt;
+	int		  hash;
+
+
+	DRM_DEBUG("%d\n", magic);
+	hash = drm_hash_magic(magic);
+
+	down(&dev->struct_sem);
+	for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
+		if (pt->magic == magic) {
+			if (dev->magiclist[hash].head == pt) {
+				dev->magiclist[hash].head = pt->next;
+			}
+			if (dev->magiclist[hash].tail == pt) {
+				dev->magiclist[hash].tail = prev;
+			}
+			if (prev) {
+				prev->next = pt->next;
+			}
+			up(&dev->struct_sem);
+			return 0;
+		}
+	}
+	up(&dev->struct_sem);
+
+	drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+
+	return -EINVAL;
+}
+
+/**
+ * Get a unique magic number (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a resulting drm_auth structure.
+ * \return zero on success, or a negative number on failure.
+ *
+ * If there is a magic number in drm_file::magic then use it, otherwise
+ * searches an unique non-zero magic number and add it associating it with \p
+ * filp.
+ */
+int drm_getmagic(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	static drm_magic_t sequence = 0;
+	static spinlock_t  lock	    = SPIN_LOCK_UNLOCKED;
+	drm_file_t	   *priv    = filp->private_data;
+	drm_device_t	   *dev	    = priv->dev;
+	drm_auth_t	   auth;
+
+				/* Find unique magic */
+	if (priv->magic) {
+		auth.magic = priv->magic;
+	} else {
+		do {
+			spin_lock(&lock);
+			if (!sequence) ++sequence; /* reserve 0 */
+			auth.magic = sequence++;
+			spin_unlock(&lock);
+		} while (drm_find_file(dev, auth.magic));
+		priv->magic = auth.magic;
+		drm_add_magic(dev, priv, auth.magic);
+	}
+
+	DRM_DEBUG("%u\n", auth.magic);
+	if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Authenticate with a magic.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_auth structure.
+ * \return zero if authentication successed, or a negative number otherwise.
+ *
+ * Checks if \p filp is associated with the magic number passed in \arg.
+ */
+int drm_authmagic(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	   *priv    = filp->private_data;
+	drm_device_t	   *dev	    = priv->dev;
+	drm_auth_t	   auth;
+	drm_file_t	   *file;
+
+	if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
+		return -EFAULT;
+	DRM_DEBUG("%u\n", auth.magic);
+	if ((file = drm_find_file(dev, auth.magic))) {
+		file->authenticated = 1;
+		drm_remove_magic(dev, auth.magic);
+		return 0;
+	}
+	return -EINVAL;
+}
diff -Nru a/drivers/char/drm/drm_auth.h b/drivers/char/drm/drm_auth.h
--- a/drivers/char/drm/drm_auth.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,230 +0,0 @@
-/**
- * \file drm_auth.h 
- * IOCTLs for authentication
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-/**
- * Generate a hash key from a magic.
- *
- * \param magic magic.
- * \return hash key.
- *
- * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
- * a power of 2.
- */
-static int DRM(hash_magic)(drm_magic_t magic)
-{
-	return magic & (DRM_HASH_SIZE-1);
-}
-
-/**
- * Find the file with the given magic number.
- *
- * \param dev DRM device.
- * \param magic magic number.
- *
- * Searches in drm_device::magiclist within all files with the same hash key
- * the one with matching magic number, while holding the drm_device::struct_sem
- * lock.
- */
-static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
-{
-	drm_file_t	  *retval = NULL;
-	drm_magic_entry_t *pt;
-	int		  hash	  = DRM(hash_magic)(magic);
-
-	down(&dev->struct_sem);
-	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
-		if (pt->magic == magic) {
-			retval = pt->priv;
-			break;
-		}
-	}
-	up(&dev->struct_sem);
-	return retval;
-}
-
-/**
- * Adds a magic number.
- * 
- * \param dev DRM device.
- * \param priv file private data.
- * \param magic magic number.
- *
- * Creates a drm_magic_entry structure and appends to the linked list
- * associated the magic number hash key in drm_device::magiclist, while holding
- * the drm_device::struct_sem lock.
- */
-int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
-{
-	int		  hash;
-	drm_magic_entry_t *entry;
-
-	DRM_DEBUG("%d\n", magic);
-
-	hash	     = DRM(hash_magic)(magic);
-	entry	     = DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
-	if (!entry) return -ENOMEM;
-	memset(entry, 0, sizeof(*entry));
-	entry->magic = magic;
-	entry->priv  = priv;
-	entry->next  = NULL;
-
-	down(&dev->struct_sem);
-	if (dev->magiclist[hash].tail) {
-		dev->magiclist[hash].tail->next = entry;
-		dev->magiclist[hash].tail	= entry;
-	} else {
-		dev->magiclist[hash].head	= entry;
-		dev->magiclist[hash].tail	= entry;
-	}
-	up(&dev->struct_sem);
-
-	return 0;
-}
-
-/**
- * Remove a magic number.
- * 
- * \param dev DRM device.
- * \param magic magic number.
- *
- * Searches and unlinks the entry in drm_device::magiclist with the magic
- * number hash key, while holding the drm_device::struct_sem lock.
- */
-int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
-{
-	drm_magic_entry_t *prev = NULL;
-	drm_magic_entry_t *pt;
-	int		  hash;
-
-
-	DRM_DEBUG("%d\n", magic);
-	hash = DRM(hash_magic)(magic);
-
-	down(&dev->struct_sem);
-	for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
-		if (pt->magic == magic) {
-			if (dev->magiclist[hash].head == pt) {
-				dev->magiclist[hash].head = pt->next;
-			}
-			if (dev->magiclist[hash].tail == pt) {
-				dev->magiclist[hash].tail = prev;
-			}
-			if (prev) {
-				prev->next = pt->next;
-			}
-			up(&dev->struct_sem);
-			return 0;
-		}
-	}
-	up(&dev->struct_sem);
-
-	DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
-
-	return -EINVAL;
-}
-
-/**
- * Get a unique magic number (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a resulting drm_auth structure.
- * \return zero on success, or a negative number on failure.
- *
- * If there is a magic number in drm_file::magic then use it, otherwise
- * searches an unique non-zero magic number and add it associating it with \p
- * filp.
- */
-int DRM(getmagic)(struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg)
-{
-	static drm_magic_t sequence = 0;
-	static spinlock_t  lock	    = SPIN_LOCK_UNLOCKED;
-	drm_file_t	   *priv    = filp->private_data;
-	drm_device_t	   *dev	    = priv->dev;
-	drm_auth_t	   auth;
-
-				/* Find unique magic */
-	if (priv->magic) {
-		auth.magic = priv->magic;
-	} else {
-		do {
-			spin_lock(&lock);
-			if (!sequence) ++sequence; /* reserve 0 */
-			auth.magic = sequence++;
-			spin_unlock(&lock);
-		} while (DRM(find_file)(dev, auth.magic));
-		priv->magic = auth.magic;
-		DRM(add_magic)(dev, priv, auth.magic);
-	}
-
-	DRM_DEBUG("%u\n", auth.magic);
-	if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Authenticate with a magic.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_auth structure.
- * \return zero if authentication successed, or a negative number otherwise.
- *
- * Checks if \p filp is associated with the magic number passed in \arg.
- */
-int DRM(authmagic)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	   *priv    = filp->private_data;
-	drm_device_t	   *dev	    = priv->dev;
-	drm_auth_t	   auth;
-	drm_file_t	   *file;
-
-	if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
-		return -EFAULT;
-	DRM_DEBUG("%u\n", auth.magic);
-	if ((file = DRM(find_file)(dev, auth.magic))) {
-		file->authenticated = 1;
-		DRM(remove_magic)(dev, auth.magic);
-		return 0;
-	}
-	return -EINVAL;
-}
diff -Nru a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_bufs.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,1270 @@
+/**
+ * \file drm_bufs.h 
+ * Generic buffer template
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+/**
+ * Compute size order.  Returns the exponent of the smaller power of two which
+ * is greater or equal to given number.
+ * 
+ * \param size size.
+ * \return order.
+ *
+ * \todo Can be made faster.
+ */
+int drm_order( unsigned long size )
+{
+	int order;
+	unsigned long tmp;
+
+	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
+		;
+
+	if (size & (size - 1))
+		++order;
+
+	return order;
+}
+EXPORT_SYMBOL(drm_order);
+
+/**
+ * Ioctl to specify a range of memory that is available for mapping by a non-root process.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_map structure.
+ * \return zero on success or a negative value on error.
+ *
+ * Adjusts the memory offset to its absolute value according to the mapping
+ * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
+ * applicable and if supported by the kernel.
+ */
+int drm_addmap( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map;
+	drm_map_t __user *argp = (void __user *)arg;
+	drm_map_list_t *list;
+
+	if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
+
+	map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
+	if ( !map )
+		return -ENOMEM;
+
+	if ( copy_from_user( map, argp, sizeof(*map) ) ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EFAULT;
+	}
+
+	/* Only allow shared memory to be removable since we only keep enough
+	 * book keeping information about shared memory to allow for removal
+	 * when processes fork.
+	 */
+	if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+	DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+		   map->offset, map->size, map->type );
+	if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+	map->mtrr   = -1;
+	map->handle = NULL;
+
+	switch ( map->type ) {
+	case _DRM_REGISTERS:
+	case _DRM_FRAME_BUFFER:
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
+		if ( map->offset + map->size < map->offset ||
+		     map->offset < virt_to_phys(high_memory) ) {
+			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+			return -EINVAL;
+		}
+#endif
+#ifdef __alpha__
+		map->offset += dev->hose->mem_space->start;
+#endif
+		if (drm_core_has_MTRR(dev)) {
+			if ( map->type == _DRM_FRAME_BUFFER ||
+			     (map->flags & _DRM_WRITE_COMBINING) ) {
+				map->mtrr = mtrr_add( map->offset, map->size,
+						      MTRR_TYPE_WRCOMB, 1 );
+			}
+		}
+		if (map->type == _DRM_REGISTERS)
+			map->handle = drm_ioremap( map->offset, map->size,
+						    dev );
+		break;
+
+	case _DRM_SHM:
+		map->handle = vmalloc_32(map->size);
+		DRM_DEBUG( "%lu %d %p\n",
+			   map->size, drm_order( map->size ), map->handle );
+		if ( !map->handle ) {
+			drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+			return -ENOMEM;
+		}
+		map->offset = (unsigned long)map->handle;
+		if ( map->flags & _DRM_CONTAINS_LOCK ) {
+			/* Prevent a 2nd X Server from creating a 2nd lock */
+			if (dev->lock.hw_lock != NULL) {
+				vfree( map->handle );
+				drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+				return -EBUSY;
+			}
+			dev->sigdata.lock =
+			dev->lock.hw_lock = map->handle; /* Pointer to lock */
+		}
+		break;
+	case _DRM_AGP:
+		if (drm_core_has_AGP(dev)) {
+#ifdef __alpha__
+			map->offset += dev->hose->mem_space->start;
+#endif
+			map->offset += dev->agp->base;
+			map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
+		}
+		break;
+	case _DRM_SCATTER_GATHER:
+		if (!dev->sg) {
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			return -EINVAL;
+		}
+		map->offset += dev->sg->handle;
+		break;
+
+	default:
+		drm_free( map, sizeof(*map), DRM_MEM_MAPS );
+		return -EINVAL;
+	}
+
+	list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
+	if(!list) {
+		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+		return -EINVAL;
+	}
+	memset(list, 0, sizeof(*list));
+	list->map = map;
+
+	down(&dev->struct_sem);
+	list_add(&list->head, &dev->maplist->head);
+ 	up(&dev->struct_sem);
+
+	if ( copy_to_user( argp, map, sizeof(*map) ) )
+		return -EFAULT;
+	if ( map->type != _DRM_SHM ) {
+		if ( copy_to_user( &argp->handle,
+				   &map->offset,
+				   sizeof(map->offset) ) )
+			return -EFAULT;
+	}
+	return 0;
+}
+
+
+/**
+ * Remove a map private from list and deallocate resources if the mapping
+ * isn't in use.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_map_t structure.
+ * \return zero on success or a negative value on error.
+ *
+ * Searches the map on drm_device::maplist, removes it from the list, see if
+ * its being used, and free any associate resource (such as MTRR's) if it's not
+ * being on use.
+ *
+ * \sa addmap().
+ */
+int drm_rmmap(struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	struct list_head *list;
+	drm_map_list_t *r_list = NULL;
+	drm_vma_entry_t *pt, *prev;
+	drm_map_t *map;
+	drm_map_t request;
+	int found_maps = 0;
+
+	if (copy_from_user(&request, (drm_map_t __user *)arg,
+			   sizeof(request))) {
+		return -EFAULT;
+	}
+
+	down(&dev->struct_sem);
+	list = &dev->maplist->head;
+	list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+
+		if(r_list->map &&
+		   r_list->map->handle == request.handle &&
+		   r_list->map->flags & _DRM_REMOVABLE) break;
+	}
+
+	/* List has wrapped around to the head pointer, or its empty we didn't
+	 * find anything.
+	 */
+	if(list == (&dev->maplist->head)) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+	map = r_list->map;
+	list_del(list);
+	drm_free(list, sizeof(*list), DRM_MEM_MAPS);
+
+	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+		if (pt->vma->vm_private_data == map) found_maps++;
+	}
+
+	if(!found_maps) {
+		switch (map->type) {
+		case _DRM_REGISTERS:
+		case _DRM_FRAME_BUFFER:
+		  if (drm_core_has_MTRR(dev)) {
+				if (map->mtrr >= 0) {
+					int retcode;
+					retcode = mtrr_del(map->mtrr,
+							   map->offset,
+							   map->size);
+					DRM_DEBUG("mtrr_del = %d\n", retcode);
+				}
+			}
+			drm_ioremapfree(map->handle, map->size, dev);
+			break;
+		case _DRM_SHM:
+			vfree(map->handle);
+			break;
+		case _DRM_AGP:
+		case _DRM_SCATTER_GATHER:
+			break;
+		}
+		drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+	}
+	up(&dev->struct_sem);
+	return 0;
+}
+
+/**
+ * Cleanup after an error on one of the addbufs() functions.
+ *
+ * \param entry buffer entry where the error occurred.
+ *
+ * Frees any pages and buffers associated with the given entry.
+ */
+static void drm_cleanup_buf_error(drm_device_t *dev, drm_buf_entry_t *entry)
+{
+	int i;
+
+	if (entry->seg_count) {
+		for (i = 0; i < entry->seg_count; i++) {
+			if (entry->seglist[i]) {
+				drm_free_pages(entry->seglist[i],
+					        entry->page_order,
+					        DRM_MEM_DMA);
+			}
+		}
+		drm_free(entry->seglist,
+			  entry->seg_count *
+			  sizeof(*entry->seglist),
+			  DRM_MEM_SEGS);
+
+		entry->seg_count = 0;
+	}
+
+   	if (entry->buf_count) {
+	   	for (i = 0; i < entry->buf_count; i++) {
+			if (entry->buflist[i].dev_private) {
+				drm_free(entry->buflist[i].dev_private,
+					  entry->buflist[i].dev_priv_size,
+					  DRM_MEM_BUFS);
+			}
+		}
+		drm_free(entry->buflist,
+			  entry->buf_count *
+			  sizeof(*entry->buflist),
+			  DRM_MEM_BUFS);
+
+		entry->buf_count = 0;
+	}
+}
+
+#if __OS_HAS_AGP
+/**
+ * Add AGP buffers for DMA transfers (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_desc_t request.
+ * \return zero on success or a negative number on failure.
+ * 
+ * After some sanity checks creates a drm_buf structure for each buffer and
+ * reallocates the buffer list of the same size order to accommodate the new
+ * buffers.
+ */
+int drm_addbufs_agp( struct inode *inode, struct file *filp,
+		      unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	drm_buf_entry_t *entry;
+	drm_buf_t *buf;
+	unsigned long offset;
+	unsigned long agp_offset;
+	int count;
+	int order;
+	int size;
+	int alignment;
+	int page_order;
+	int total;
+	int byte_count;
+	int i;
+	drm_buf_t **temp_buflist;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	alignment  = (request.flags & _DRM_PAGE_ALIGN)
+		? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	byte_count = 0;
+	agp_offset = dev->agp->base + request.agp_start;
+
+	DRM_DEBUG( "count:      %d\n",  count );
+	DRM_DEBUG( "order:      %d\n",  order );
+	DRM_DEBUG( "size:       %d\n",  size );
+	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+	DRM_DEBUG( "alignment:  %d\n",  alignment );
+	DRM_DEBUG( "page_order: %d\n",  page_order );
+	DRM_DEBUG( "total:      %d\n",  total );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM; /* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				    DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->buf_size = size;
+	entry->page_order = page_order;
+
+	offset = 0;
+
+	while ( entry->buf_count < count ) {
+		buf          = &entry->buflist[entry->buf_count];
+		buf->idx     = dma->buf_count + entry->buf_count;
+		buf->total   = alignment;
+		buf->order   = order;
+		buf->used    = 0;
+
+		buf->offset  = (dma->byte_count + offset);
+		buf->bus_address = agp_offset + offset;
+		buf->address = (void *)(agp_offset + offset);
+		buf->next    = NULL;
+		buf->waiting = 0;
+		buf->pending = 0;
+		init_waitqueue_head( &buf->dma_wait );
+		buf->filp    = NULL;
+
+		buf->dev_priv_size = dev->driver->dev_priv_size;
+		buf->dev_private = drm_alloc( buf->dev_priv_size,
+					       DRM_MEM_BUFS );
+		if(!buf->dev_private) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			drm_cleanup_buf_error(dev,entry);
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+		memset( buf->dev_private, 0, buf->dev_priv_size );
+
+		DRM_DEBUG( "buffer %d @ %p\n",
+			   entry->buf_count, buf->address );
+
+		offset += alignment;
+		entry->buf_count++;
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if(!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	dma->buf_count += entry->buf_count;
+	dma->byte_count += byte_count;
+
+	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	dma->flags = _DRM_DMA_USE_AGP;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+}
+#endif /* __OS_HAS_AGP */
+
+int drm_addbufs_pci( struct inode *inode, struct file *filp,
+		      unsigned int cmd, unsigned long arg )
+{
+   	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	int count;
+	int order;
+	int size;
+	int total;
+	int page_order;
+	drm_buf_entry_t *entry;
+	unsigned long page;
+	drm_buf_t *buf;
+	int alignment;
+	unsigned long offset;
+	int i;
+	int byte_count;
+	int page_count;
+	unsigned long *temp_pagelist;
+	drm_buf_t **temp_buflist;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+
+	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
+		   request.count, request.size, size,
+		   order, dev->queue_count );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	alignment = (request.flags & _DRM_PAGE_ALIGN)
+		? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;	/* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				    DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->seglist = drm_alloc( count * sizeof(*entry->seglist),
+				    DRM_MEM_SEGS );
+	if ( !entry->seglist ) {
+		drm_free( entry->buflist,
+			  count * sizeof(*entry->buflist),
+			  DRM_MEM_BUFS );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
+
+	/* Keep the original pagelist until we know all the allocations
+	 * have succeeded
+	 */
+	temp_pagelist = drm_alloc( (dma->page_count + (count << page_order))
+				    * sizeof(*dma->pagelist),
+				    DRM_MEM_PAGES );
+	if (!temp_pagelist) {
+		drm_free( entry->buflist,
+			   count * sizeof(*entry->buflist),
+			   DRM_MEM_BUFS );
+		drm_free( entry->seglist,
+			   count * sizeof(*entry->seglist),
+			   DRM_MEM_SEGS );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memcpy(temp_pagelist,
+	       dma->pagelist,
+	       dma->page_count * sizeof(*dma->pagelist));
+	DRM_DEBUG( "pagelist: %d entries\n",
+		   dma->page_count + (count << page_order) );
+
+	entry->buf_size	= size;
+	entry->page_order = page_order;
+	byte_count = 0;
+	page_count = 0;
+
+	while ( entry->buf_count < count ) {
+		page = drm_alloc_pages( page_order, DRM_MEM_DMA );
+		if ( !page ) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			entry->seg_count = count;
+			drm_cleanup_buf_error(dev, entry);
+			drm_free( temp_pagelist,
+				   (dma->page_count + (count << page_order))
+				   * sizeof(*dma->pagelist),
+				   DRM_MEM_PAGES );
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+		entry->seglist[entry->seg_count++] = page;
+		for ( i = 0 ; i < (1 << page_order) ; i++ ) {
+			DRM_DEBUG( "page %d @ 0x%08lx\n",
+				   dma->page_count + page_count,
+				   page + PAGE_SIZE * i );
+			temp_pagelist[dma->page_count + page_count++]
+				= page + PAGE_SIZE * i;
+		}
+		for ( offset = 0 ;
+		      offset + size <= total && entry->buf_count < count ;
+		      offset += alignment, ++entry->buf_count ) {
+			buf	     = &entry->buflist[entry->buf_count];
+			buf->idx     = dma->buf_count + entry->buf_count;
+			buf->total   = alignment;
+			buf->order   = order;
+			buf->used    = 0;
+			buf->offset  = (dma->byte_count + byte_count + offset);
+			buf->address = (void *)(page + offset);
+			buf->next    = NULL;
+			buf->waiting = 0;
+			buf->pending = 0;
+			init_waitqueue_head( &buf->dma_wait );
+			buf->filp    = NULL;
+
+			buf->dev_priv_size = dev->driver->dev_priv_size;
+			buf->dev_private = drm_alloc( buf->dev_priv_size,
+						       DRM_MEM_BUFS );
+			if(!buf->dev_private) {
+				/* Set count correctly so we free the proper amount. */
+				entry->buf_count = count;
+				entry->seg_count = count;
+				drm_cleanup_buf_error(dev,entry);
+				drm_free( temp_pagelist,
+					   (dma->page_count + (count << page_order))
+					   * sizeof(*dma->pagelist),
+					   DRM_MEM_PAGES );
+				up( &dev->struct_sem );
+				atomic_dec( &dev->buf_alloc );
+				return -ENOMEM;
+			}
+			memset( buf->dev_private, 0, buf->dev_priv_size );
+
+			DRM_DEBUG( "buffer %d @ %p\n",
+				   entry->buf_count, buf->address );
+		}
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if (!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		drm_free( temp_pagelist,
+			   (dma->page_count + (count << page_order))
+			   * sizeof(*dma->pagelist),
+			   DRM_MEM_PAGES );
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	/* No allocations failed, so now we can replace the orginal pagelist
+	 * with the new one.
+	 */
+	if (dma->page_count) {
+		drm_free(dma->pagelist,
+			  dma->page_count * sizeof(*dma->pagelist),
+			  DRM_MEM_PAGES);
+	}
+	dma->pagelist = temp_pagelist;
+
+	dma->buf_count += entry->buf_count;
+	dma->seg_count += entry->seg_count;
+	dma->page_count += entry->seg_count << page_order;
+	dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+
+}
+
+int drm_addbufs_sg( struct inode *inode, struct file *filp,
+                     unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t __user *argp = (void __user *)arg;
+	drm_buf_desc_t request;
+	drm_buf_entry_t *entry;
+	drm_buf_t *buf;
+	unsigned long offset;
+	unsigned long agp_offset;
+	int count;
+	int order;
+	int size;
+	int alignment;
+	int page_order;
+	int total;
+	int byte_count;
+	int i;
+	drm_buf_t **temp_buflist;
+
+	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
+	
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	count = request.count;
+	order = drm_order( request.size );
+	size = 1 << order;
+
+	alignment  = (request.flags & _DRM_PAGE_ALIGN)
+			? PAGE_ALIGN(size) : size;
+	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+	total = PAGE_SIZE << page_order;
+
+	byte_count = 0;
+	agp_offset = request.agp_start;
+
+	DRM_DEBUG( "count:      %d\n",  count );
+	DRM_DEBUG( "order:      %d\n",  order );
+	DRM_DEBUG( "size:       %d\n",  size );
+	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
+	DRM_DEBUG( "alignment:  %d\n",  alignment );
+	DRM_DEBUG( "page_order: %d\n",  page_order );
+	DRM_DEBUG( "total:      %d\n",  total );
+
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+	spin_lock( &dev->count_lock );
+	if ( dev->buf_use ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	atomic_inc( &dev->buf_alloc );
+	spin_unlock( &dev->count_lock );
+
+	down( &dev->struct_sem );
+	entry = &dma->bufs[order];
+	if ( entry->buf_count ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM; /* May only call once for each order */
+	}
+
+	if (count < 0 || count > 4096) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -EINVAL;
+	}
+
+	entry->buflist = drm_alloc( count * sizeof(*entry->buflist),
+				     DRM_MEM_BUFS );
+	if ( !entry->buflist ) {
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
+
+	entry->buf_size = size;
+	entry->page_order = page_order;
+
+	offset = 0;
+
+	while ( entry->buf_count < count ) {
+		buf          = &entry->buflist[entry->buf_count];
+		buf->idx     = dma->buf_count + entry->buf_count;
+		buf->total   = alignment;
+		buf->order   = order;
+		buf->used    = 0;
+
+		buf->offset  = (dma->byte_count + offset);
+		buf->bus_address = agp_offset + offset;
+		buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+		buf->next    = NULL;
+		buf->waiting = 0;
+		buf->pending = 0;
+		init_waitqueue_head( &buf->dma_wait );
+		buf->filp    = NULL;
+
+		buf->dev_priv_size = dev->driver->dev_priv_size;
+		buf->dev_private = drm_alloc( buf->dev_priv_size,
+					       DRM_MEM_BUFS );
+		if(!buf->dev_private) {
+			/* Set count correctly so we free the proper amount. */
+			entry->buf_count = count;
+			drm_cleanup_buf_error(dev,entry);
+			up( &dev->struct_sem );
+			atomic_dec( &dev->buf_alloc );
+			return -ENOMEM;
+		}
+
+		memset( buf->dev_private, 0, buf->dev_priv_size );
+
+		DRM_DEBUG( "buffer %d @ %p\n",
+			   entry->buf_count, buf->address );
+
+		offset += alignment;
+		entry->buf_count++;
+		byte_count += PAGE_SIZE << page_order;
+	}
+
+	DRM_DEBUG( "byte_count: %d\n", byte_count );
+
+	temp_buflist = drm_realloc( dma->buflist,
+				     dma->buf_count * sizeof(*dma->buflist),
+				     (dma->buf_count + entry->buf_count)
+				     * sizeof(*dma->buflist),
+				     DRM_MEM_BUFS );
+	if(!temp_buflist) {
+		/* Free the entry because it isn't valid */
+		drm_cleanup_buf_error(dev,entry);
+		up( &dev->struct_sem );
+		atomic_dec( &dev->buf_alloc );
+		return -ENOMEM;
+	}
+	dma->buflist = temp_buflist;
+
+	for ( i = 0 ; i < entry->buf_count ; i++ ) {
+		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
+	}
+
+	dma->buf_count += entry->buf_count;
+	dma->byte_count += byte_count;
+
+	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
+	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
+
+	up( &dev->struct_sem );
+
+	request.count = entry->buf_count;
+	request.size = size;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	dma->flags = _DRM_DMA_USE_SG;
+
+	atomic_dec( &dev->buf_alloc );
+	return 0;
+}
+
+/**
+ * Add buffers for DMA transfers (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_desc_t request.
+ * \return zero on success or a negative number on failure.
+ *
+ * According with the memory type specified in drm_buf_desc::flags and the
+ * build options, it dispatches the call either to addbufs_agp(),
+ * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
+ * PCI memory respectively.
+ */
+int drm_addbufs( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_buf_desc_t request;
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+#if __OS_HAS_AGP
+	if ( request.flags & _DRM_AGP_BUFFER )
+		return drm_addbufs_agp( inode, filp, cmd, arg );
+	else
+#endif
+	if ( request.flags & _DRM_SG_BUFFER )
+		return drm_addbufs_sg( inode, filp, cmd, arg );
+	else
+		return drm_addbufs_pci( inode, filp, cmd, arg );
+}
+
+
+/**
+ * Get information about the buffer mappings.
+ *
+ * This was originally mean for debugging purposes, or by a sophisticated
+ * client library to determine how best to use the available buffers (e.g.,
+ * large buffers can be used for image transfer).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_info structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Increments drm_device::buf_use while holding the drm_device::count_lock
+ * lock, preventing of allocating more buffers after this call. Information
+ * about each requested buffer is then copied into user space.
+ */
+int drm_infobufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_info_t request;
+	drm_buf_info_t __user *argp = (void __user *)arg;
+	int i;
+	int count;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	spin_lock( &dev->count_lock );
+	if ( atomic_read( &dev->buf_alloc ) ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	++dev->buf_use;		/* Can't allocate more after this call */
+	spin_unlock( &dev->count_lock );
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+		if ( dma->bufs[i].buf_count ) ++count;
+	}
+
+	DRM_DEBUG( "count = %d\n", count );
+
+	if ( request.count >= count ) {
+		for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
+			if ( dma->bufs[i].buf_count ) {
+				drm_buf_desc_t __user *to = &request.list[count];
+				drm_buf_entry_t *from = &dma->bufs[i];
+				drm_freelist_t *list = &dma->bufs[i].freelist;
+				if ( copy_to_user( &to->count,
+						   &from->buf_count,
+						   sizeof(from->buf_count) ) ||
+				     copy_to_user( &to->size,
+						   &from->buf_size,
+						   sizeof(from->buf_size) ) ||
+				     copy_to_user( &to->low_mark,
+						   &list->low_mark,
+						   sizeof(list->low_mark) ) ||
+				     copy_to_user( &to->high_mark,
+						   &list->high_mark,
+						   sizeof(list->high_mark) ) )
+					return -EFAULT;
+
+				DRM_DEBUG( "%d %d %d %d %d\n",
+					   i,
+					   dma->bufs[i].buf_count,
+					   dma->bufs[i].buf_size,
+					   dma->bufs[i].freelist.low_mark,
+					   dma->bufs[i].freelist.high_mark );
+				++count;
+			}
+		}
+	}
+	request.count = count;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	return 0;
+}
+
+/**
+ * Specifies a low and high water mark for buffer allocation
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg a pointer to a drm_buf_desc structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies that the size order is bounded between the admissible orders and
+ * updates the respective drm_device_dma::bufs entry low and high water mark.
+ *
+ * \note This ioctl is deprecated and mostly never used.
+ */
+int drm_markbufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_desc_t request;
+	int order;
+	drm_buf_entry_t *entry;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_buf_desc_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d, %d, %d\n",
+		   request.size, request.low_mark, request.high_mark );
+	order = drm_order( request.size );
+	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+	entry = &dma->bufs[order];
+
+	if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
+		return -EINVAL;
+	if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
+		return -EINVAL;
+
+	entry->freelist.low_mark  = request.low_mark;
+	entry->freelist.high_mark = request.high_mark;
+
+	return 0;
+}
+
+/**
+ * Unreserve the buffers in list, previously reserved using drmDMA. 
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_free structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Calls free_buffer() for each used buffer.
+ * This function is primarily used for debugging.
+ */
+int drm_freebufs( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_free_t request;
+	int i;
+	int idx;
+	drm_buf_t *buf;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_buf_free_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", request.count );
+	for ( i = 0 ; i < request.count ; i++ ) {
+		if ( copy_from_user( &idx,
+				     &request.list[i],
+				     sizeof(idx) ) )
+			return -EFAULT;
+		if ( idx < 0 || idx >= dma->buf_count ) {
+			DRM_ERROR( "Index %d (of %d max)\n",
+				   idx, dma->buf_count - 1 );
+			return -EINVAL;
+		}
+		buf = dma->buflist[idx];
+		if ( buf->filp != filp ) {
+			DRM_ERROR( "Process %d freeing buffer not owned\n",
+				   current->pid );
+			return -EINVAL;
+		}
+		drm_free_buffer( dev, buf );
+	}
+
+	return 0;
+}
+
+/**
+ * Maps all of the DMA buffers into client-virtual space (ioctl).
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg pointer to a drm_buf_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Maps the AGP or SG buffer region with do_mmap(), and copies information
+ * about each buffer into user space. The PCI buffers are already mapped on the
+ * addbufs_pci() call.
+ */
+int drm_mapbufs( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_map_t __user *argp = (void __user *)arg;
+	int retcode = 0;
+	const int zero = 0;
+	unsigned long virtual;
+	unsigned long address;
+	drm_buf_map_t request;
+	int i;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		return -EINVAL;
+
+	if ( !dma ) return -EINVAL;
+
+	spin_lock( &dev->count_lock );
+	if ( atomic_read( &dev->buf_alloc ) ) {
+		spin_unlock( &dev->count_lock );
+		return -EBUSY;
+	}
+	dev->buf_use++;		/* Can't allocate more after this call */
+	spin_unlock( &dev->count_lock );
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	if ( request.count >= dma->buf_count ) {
+		if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) ||
+		    (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) ) {
+			drm_map_t *map = dev->agp_buffer_map;
+
+			if ( !map ) {
+				retcode = -EINVAL;
+				goto done;
+			}
+
+#if LINUX_VERSION_CODE <= 0x020402
+			down( &current->mm->mmap_sem );
+#else
+			down_write( &current->mm->mmap_sem );
+#endif
+			virtual = do_mmap( filp, 0, map->size,
+					   PROT_READ | PROT_WRITE,
+					   MAP_SHARED,
+					   (unsigned long)map->offset );
+#if LINUX_VERSION_CODE <= 0x020402
+			up( &current->mm->mmap_sem );
+#else
+			up_write( &current->mm->mmap_sem );
+#endif
+		} else {
+#if LINUX_VERSION_CODE <= 0x020402
+			down( &current->mm->mmap_sem );
+#else
+			down_write( &current->mm->mmap_sem );
+#endif
+			virtual = do_mmap( filp, 0, dma->byte_count,
+					   PROT_READ | PROT_WRITE,
+					   MAP_SHARED, 0 );
+#if LINUX_VERSION_CODE <= 0x020402
+			up( &current->mm->mmap_sem );
+#else
+			up_write( &current->mm->mmap_sem );
+#endif
+		}
+		if ( virtual > -1024UL ) {
+			/* Real error */
+			retcode = (signed long)virtual;
+			goto done;
+		}
+		request.virtual = (void __user *)virtual;
+
+		for ( i = 0 ; i < dma->buf_count ; i++ ) {
+			if ( copy_to_user( &request.list[i].idx,
+					   &dma->buflist[i]->idx,
+					   sizeof(request.list[0].idx) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			if ( copy_to_user( &request.list[i].total,
+					   &dma->buflist[i]->total,
+					   sizeof(request.list[0].total) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			if ( copy_to_user( &request.list[i].used,
+					   &zero,
+					   sizeof(zero) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+			address = virtual + dma->buflist[i]->offset; /* *** */
+			if ( copy_to_user( &request.list[i].address,
+					   &address,
+					   sizeof(address) ) ) {
+				retcode = -EFAULT;
+				goto done;
+			}
+		}
+	}
+ done:
+	request.count = dma->buf_count;
+	DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) )
+		return -EFAULT;
+
+	return retcode;
+}
+
diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h
--- a/drivers/char/drm/drm_bufs.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1269 +0,0 @@
-/**
- * \file drm_bufs.h 
- * Generic buffer template
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include <linux/vmalloc.h>
-#include "drmP.h"
-
-/**
- * Compute size order.  Returns the exponent of the smaller power of two which
- * is greater or equal to given number.
- * 
- * \param size size.
- * \return order.
- *
- * \todo Can be made faster.
- */
-int DRM(order)( unsigned long size )
-{
-	int order;
-	unsigned long tmp;
-
-	for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++)
-		;
-
-	if (size & (size - 1))
-		++order;
-
-	return order;
-}
-
-/**
- * Ioctl to specify a range of memory that is available for mapping by a non-root process.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_map structure.
- * \return zero on success or a negative value on error.
- *
- * Adjusts the memory offset to its absolute value according to the mapping
- * type.  Adds the map to the map list drm_device::maplist. Adds MTRR's where
- * applicable and if supported by the kernel.
- */
-int DRM(addmap)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_map_t *map;
-	drm_map_t __user *argp = (void __user *)arg;
-	drm_map_list_t *list;
-
-	if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
-
-	map = DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
-	if ( !map )
-		return -ENOMEM;
-
-	if ( copy_from_user( map, argp, sizeof(*map) ) ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EFAULT;
-	}
-
-	/* Only allow shared memory to be removable since we only keep enough
-	 * book keeping information about shared memory to allow for removal
-	 * when processes fork.
-	 */
-	if ( (map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-	DRM_DEBUG( "offset = 0x%08lx, size = 0x%08lx, type = %d\n",
-		   map->offset, map->size, map->type );
-	if ( (map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK)) ) {
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-	map->mtrr   = -1;
-	map->handle = NULL;
-
-	switch ( map->type ) {
-	case _DRM_REGISTERS:
-	case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
-		if ( map->offset + map->size < map->offset ||
-		     map->offset < virt_to_phys(high_memory) ) {
-			DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-			return -EINVAL;
-		}
-#endif
-#ifdef __alpha__
-		map->offset += dev->hose->mem_space->start;
-#endif
-		if (drm_core_has_MTRR(dev)) {
-			if ( map->type == _DRM_FRAME_BUFFER ||
-			     (map->flags & _DRM_WRITE_COMBINING) ) {
-				map->mtrr = mtrr_add( map->offset, map->size,
-						      MTRR_TYPE_WRCOMB, 1 );
-			}
-		}
-		if (map->type == _DRM_REGISTERS)
-			map->handle = DRM(ioremap)( map->offset, map->size,
-						    dev );
-		break;
-
-	case _DRM_SHM:
-		map->handle = vmalloc_32(map->size);
-		DRM_DEBUG( "%lu %d %p\n",
-			   map->size, DRM(order)( map->size ), map->handle );
-		if ( !map->handle ) {
-			DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-			return -ENOMEM;
-		}
-		map->offset = (unsigned long)map->handle;
-		if ( map->flags & _DRM_CONTAINS_LOCK ) {
-			/* Prevent a 2nd X Server from creating a 2nd lock */
-			if (dev->lock.hw_lock != NULL) {
-				vfree( map->handle );
-				DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-				return -EBUSY;
-			}
-			dev->sigdata.lock =
-			dev->lock.hw_lock = map->handle; /* Pointer to lock */
-		}
-		break;
-	case _DRM_AGP:
-		if (drm_core_has_AGP(dev)) {
-#ifdef __alpha__
-			map->offset += dev->hose->mem_space->start;
-#endif
-			map->offset += dev->agp->base;
-			map->mtrr   = dev->agp->agp_mtrr; /* for getmap */
-		}
-		break;
-	case _DRM_SCATTER_GATHER:
-		if (!dev->sg) {
-			DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-			return -EINVAL;
-		}
-		map->offset += dev->sg->handle;
-		break;
-
-	default:
-		DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-		return -EINVAL;
-	}
-
-	list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
-	if(!list) {
-		DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-		return -EINVAL;
-	}
-	memset(list, 0, sizeof(*list));
-	list->map = map;
-
-	down(&dev->struct_sem);
-	list_add(&list->head, &dev->maplist->head);
- 	up(&dev->struct_sem);
-
-	if ( copy_to_user( argp, map, sizeof(*map) ) )
-		return -EFAULT;
-	if ( map->type != _DRM_SHM ) {
-		if ( copy_to_user( &argp->handle,
-				   &map->offset,
-				   sizeof(map->offset) ) )
-			return -EFAULT;
-	}
-	return 0;
-}
-
-
-/**
- * Remove a map private from list and deallocate resources if the mapping
- * isn't in use.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_map_t structure.
- * \return zero on success or a negative value on error.
- *
- * Searches the map on drm_device::maplist, removes it from the list, see if
- * its being used, and free any associate resource (such as MTRR's) if it's not
- * being on use.
- *
- * \sa addmap().
- */
-int DRM(rmmap)(struct inode *inode, struct file *filp,
-	       unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	struct list_head *list;
-	drm_map_list_t *r_list = NULL;
-	drm_vma_entry_t *pt, *prev;
-	drm_map_t *map;
-	drm_map_t request;
-	int found_maps = 0;
-
-	if (copy_from_user(&request, (drm_map_t __user *)arg,
-			   sizeof(request))) {
-		return -EFAULT;
-	}
-
-	down(&dev->struct_sem);
-	list = &dev->maplist->head;
-	list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-
-		if(r_list->map &&
-		   r_list->map->handle == request.handle &&
-		   r_list->map->flags & _DRM_REMOVABLE) break;
-	}
-
-	/* List has wrapped around to the head pointer, or its empty we didn't
-	 * find anything.
-	 */
-	if(list == (&dev->maplist->head)) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-	map = r_list->map;
-	list_del(list);
-	DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
-
-	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-		if (pt->vma->vm_private_data == map) found_maps++;
-	}
-
-	if(!found_maps) {
-		switch (map->type) {
-		case _DRM_REGISTERS:
-		case _DRM_FRAME_BUFFER:
-		  if (drm_core_has_MTRR(dev)) {
-				if (map->mtrr >= 0) {
-					int retcode;
-					retcode = mtrr_del(map->mtrr,
-							   map->offset,
-							   map->size);
-					DRM_DEBUG("mtrr_del = %d\n", retcode);
-				}
-			}
-			DRM(ioremapfree)(map->handle, map->size, dev);
-			break;
-		case _DRM_SHM:
-			vfree(map->handle);
-			break;
-		case _DRM_AGP:
-		case _DRM_SCATTER_GATHER:
-			break;
-		}
-		DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-	}
-	up(&dev->struct_sem);
-	return 0;
-}
-
-/**
- * Cleanup after an error on one of the addbufs() functions.
- *
- * \param entry buffer entry where the error occurred.
- *
- * Frees any pages and buffers associated with the given entry.
- */
-static void DRM(cleanup_buf_error)(drm_buf_entry_t *entry)
-{
-	int i;
-
-	if (entry->seg_count) {
-		for (i = 0; i < entry->seg_count; i++) {
-			if (entry->seglist[i]) {
-				DRM(free_pages)(entry->seglist[i],
-					        entry->page_order,
-					        DRM_MEM_DMA);
-			}
-		}
-		DRM(free)(entry->seglist,
-			  entry->seg_count *
-			  sizeof(*entry->seglist),
-			  DRM_MEM_SEGS);
-
-		entry->seg_count = 0;
-	}
-
-   	if (entry->buf_count) {
-	   	for (i = 0; i < entry->buf_count; i++) {
-			if (entry->buflist[i].dev_private) {
-				DRM(free)(entry->buflist[i].dev_private,
-					  entry->buflist[i].dev_priv_size,
-					  DRM_MEM_BUFS);
-			}
-		}
-		DRM(free)(entry->buflist,
-			  entry->buf_count *
-			  sizeof(*entry->buflist),
-			  DRM_MEM_BUFS);
-
-		entry->buf_count = 0;
-	}
-}
-
-#if __OS_HAS_AGP
-/**
- * Add AGP buffers for DMA transfers (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_desc_t request.
- * \return zero on success or a negative number on failure.
- * 
- * After some sanity checks creates a drm_buf structure for each buffer and
- * reallocates the buffer list of the same size order to accommodate the new
- * buffers.
- */
-int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	drm_buf_entry_t *entry;
-	drm_buf_t *buf;
-	unsigned long offset;
-	unsigned long agp_offset;
-	int count;
-	int order;
-	int size;
-	int alignment;
-	int page_order;
-	int total;
-	int byte_count;
-	int i;
-	drm_buf_t **temp_buflist;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	alignment  = (request.flags & _DRM_PAGE_ALIGN)
-		? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	byte_count = 0;
-	agp_offset = dev->agp->base + request.agp_start;
-
-	DRM_DEBUG( "count:      %d\n",  count );
-	DRM_DEBUG( "order:      %d\n",  order );
-	DRM_DEBUG( "size:       %d\n",  size );
-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
-	DRM_DEBUG( "alignment:  %d\n",  alignment );
-	DRM_DEBUG( "page_order: %d\n",  page_order );
-	DRM_DEBUG( "total:      %d\n",  total );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM; /* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				    DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->buf_size = size;
-	entry->page_order = page_order;
-
-	offset = 0;
-
-	while ( entry->buf_count < count ) {
-		buf          = &entry->buflist[entry->buf_count];
-		buf->idx     = dma->buf_count + entry->buf_count;
-		buf->total   = alignment;
-		buf->order   = order;
-		buf->used    = 0;
-
-		buf->offset  = (dma->byte_count + offset);
-		buf->bus_address = agp_offset + offset;
-		buf->address = (void *)(agp_offset + offset);
-		buf->next    = NULL;
-		buf->waiting = 0;
-		buf->pending = 0;
-		init_waitqueue_head( &buf->dma_wait );
-		buf->filp    = NULL;
-
-		buf->dev_priv_size = dev->dev_priv_size;
-		buf->dev_private = DRM(alloc)( buf->dev_priv_size,
-					       DRM_MEM_BUFS );
-		if(!buf->dev_private) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			DRM(cleanup_buf_error)(entry);
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-		memset( buf->dev_private, 0, buf->dev_priv_size );
-
-		DRM_DEBUG( "buffer %d @ %p\n",
-			   entry->buf_count, buf->address );
-
-		offset += alignment;
-		entry->buf_count++;
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	DRM_DEBUG( "byte_count: %d\n", byte_count );
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if(!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	dma->buf_count += entry->buf_count;
-	dma->byte_count += byte_count;
-
-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	dma->flags = _DRM_DMA_USE_AGP;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-}
-#endif /* __OS_HAS_AGP */
-
-int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
-{
-   	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	int count;
-	int order;
-	int size;
-	int total;
-	int page_order;
-	drm_buf_entry_t *entry;
-	unsigned long page;
-	drm_buf_t *buf;
-	int alignment;
-	unsigned long offset;
-	int i;
-	int byte_count;
-	int page_count;
-	unsigned long *temp_pagelist;
-	drm_buf_t **temp_buflist;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-
-	if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) return -EINVAL;
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
-		   request.count, request.size, size,
-		   order, dev->queue_count );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	alignment = (request.flags & _DRM_PAGE_ALIGN)
-		? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;	/* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				    DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->seglist = DRM(alloc)( count * sizeof(*entry->seglist),
-				    DRM_MEM_SEGS );
-	if ( !entry->seglist ) {
-		DRM(free)( entry->buflist,
-			  count * sizeof(*entry->buflist),
-			  DRM_MEM_BUFS );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->seglist, 0, count * sizeof(*entry->seglist) );
-
-	/* Keep the original pagelist until we know all the allocations
-	 * have succeeded
-	 */
-	temp_pagelist = DRM(alloc)( (dma->page_count + (count << page_order))
-				    * sizeof(*dma->pagelist),
-				    DRM_MEM_PAGES );
-	if (!temp_pagelist) {
-		DRM(free)( entry->buflist,
-			   count * sizeof(*entry->buflist),
-			   DRM_MEM_BUFS );
-		DRM(free)( entry->seglist,
-			   count * sizeof(*entry->seglist),
-			   DRM_MEM_SEGS );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memcpy(temp_pagelist,
-	       dma->pagelist,
-	       dma->page_count * sizeof(*dma->pagelist));
-	DRM_DEBUG( "pagelist: %d entries\n",
-		   dma->page_count + (count << page_order) );
-
-	entry->buf_size	= size;
-	entry->page_order = page_order;
-	byte_count = 0;
-	page_count = 0;
-
-	while ( entry->buf_count < count ) {
-		page = DRM(alloc_pages)( page_order, DRM_MEM_DMA );
-		if ( !page ) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			entry->seg_count = count;
-			DRM(cleanup_buf_error)(entry);
-			DRM(free)( temp_pagelist,
-				   (dma->page_count + (count << page_order))
-				   * sizeof(*dma->pagelist),
-				   DRM_MEM_PAGES );
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-		entry->seglist[entry->seg_count++] = page;
-		for ( i = 0 ; i < (1 << page_order) ; i++ ) {
-			DRM_DEBUG( "page %d @ 0x%08lx\n",
-				   dma->page_count + page_count,
-				   page + PAGE_SIZE * i );
-			temp_pagelist[dma->page_count + page_count++]
-				= page + PAGE_SIZE * i;
-		}
-		for ( offset = 0 ;
-		      offset + size <= total && entry->buf_count < count ;
-		      offset += alignment, ++entry->buf_count ) {
-			buf	     = &entry->buflist[entry->buf_count];
-			buf->idx     = dma->buf_count + entry->buf_count;
-			buf->total   = alignment;
-			buf->order   = order;
-			buf->used    = 0;
-			buf->offset  = (dma->byte_count + byte_count + offset);
-			buf->address = (void *)(page + offset);
-			buf->next    = NULL;
-			buf->waiting = 0;
-			buf->pending = 0;
-			init_waitqueue_head( &buf->dma_wait );
-			buf->filp    = NULL;
-
-			buf->dev_priv_size = dev->dev_priv_size;
-			buf->dev_private = DRM(alloc)( dev->dev_priv_size,
-						       DRM_MEM_BUFS );
-			if(!buf->dev_private) {
-				/* Set count correctly so we free the proper amount. */
-				entry->buf_count = count;
-				entry->seg_count = count;
-				DRM(cleanup_buf_error)(entry);
-				DRM(free)( temp_pagelist,
-					   (dma->page_count + (count << page_order))
-					   * sizeof(*dma->pagelist),
-					   DRM_MEM_PAGES );
-				up( &dev->struct_sem );
-				atomic_dec( &dev->buf_alloc );
-				return -ENOMEM;
-			}
-			memset( buf->dev_private, 0, buf->dev_priv_size );
-
-			DRM_DEBUG( "buffer %d @ %p\n",
-				   entry->buf_count, buf->address );
-		}
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if (!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		DRM(free)( temp_pagelist,
-			   (dma->page_count + (count << page_order))
-			   * sizeof(*dma->pagelist),
-			   DRM_MEM_PAGES );
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	/* No allocations failed, so now we can replace the orginal pagelist
-	 * with the new one.
-	 */
-	if (dma->page_count) {
-		DRM(free)(dma->pagelist,
-			  dma->page_count * sizeof(*dma->pagelist),
-			  DRM_MEM_PAGES);
-	}
-	dma->pagelist = temp_pagelist;
-
-	dma->buf_count += entry->buf_count;
-	dma->seg_count += entry->seg_count;
-	dma->page_count += entry->seg_count << page_order;
-	dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-
-}
-
-int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t __user *argp = (void __user *)arg;
-	drm_buf_desc_t request;
-	drm_buf_entry_t *entry;
-	drm_buf_t *buf;
-	unsigned long offset;
-	unsigned long agp_offset;
-	int count;
-	int order;
-	int size;
-	int alignment;
-	int page_order;
-	int total;
-	int byte_count;
-	int i;
-	drm_buf_t **temp_buflist;
-
-	if (!drm_core_check_feature(dev, DRIVER_SG)) return -EINVAL;
-	
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	count = request.count;
-	order = DRM(order)( request.size );
-	size = 1 << order;
-
-	alignment  = (request.flags & _DRM_PAGE_ALIGN)
-			? PAGE_ALIGN(size) : size;
-	page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-	total = PAGE_SIZE << page_order;
-
-	byte_count = 0;
-	agp_offset = request.agp_start;
-
-	DRM_DEBUG( "count:      %d\n",  count );
-	DRM_DEBUG( "order:      %d\n",  order );
-	DRM_DEBUG( "size:       %d\n",  size );
-	DRM_DEBUG( "agp_offset: %lu\n", agp_offset );
-	DRM_DEBUG( "alignment:  %d\n",  alignment );
-	DRM_DEBUG( "page_order: %d\n",  page_order );
-	DRM_DEBUG( "total:      %d\n",  total );
-
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	if ( dev->queue_count ) return -EBUSY; /* Not while in use */
-
-	spin_lock( &dev->count_lock );
-	if ( dev->buf_use ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	atomic_inc( &dev->buf_alloc );
-	spin_unlock( &dev->count_lock );
-
-	down( &dev->struct_sem );
-	entry = &dma->bufs[order];
-	if ( entry->buf_count ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM; /* May only call once for each order */
-	}
-
-	if (count < 0 || count > 4096) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -EINVAL;
-	}
-
-	entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
-				     DRM_MEM_BUFS );
-	if ( !entry->buflist ) {
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
-
-	entry->buf_size = size;
-	entry->page_order = page_order;
-
-	offset = 0;
-
-	while ( entry->buf_count < count ) {
-		buf          = &entry->buflist[entry->buf_count];
-		buf->idx     = dma->buf_count + entry->buf_count;
-		buf->total   = alignment;
-		buf->order   = order;
-		buf->used    = 0;
-
-		buf->offset  = (dma->byte_count + offset);
-		buf->bus_address = agp_offset + offset;
-		buf->address = (void *)(agp_offset + offset + dev->sg->handle);
-		buf->next    = NULL;
-		buf->waiting = 0;
-		buf->pending = 0;
-		init_waitqueue_head( &buf->dma_wait );
-		buf->filp    = NULL;
-
-		buf->dev_priv_size = dev->dev_priv_size;
-		buf->dev_private = DRM(alloc)( dev->dev_priv_size,
-					       DRM_MEM_BUFS );
-		if(!buf->dev_private) {
-			/* Set count correctly so we free the proper amount. */
-			entry->buf_count = count;
-			DRM(cleanup_buf_error)(entry);
-			up( &dev->struct_sem );
-			atomic_dec( &dev->buf_alloc );
-			return -ENOMEM;
-		}
-
-		memset( buf->dev_private, 0, buf->dev_priv_size );
-
-		DRM_DEBUG( "buffer %d @ %p\n",
-			   entry->buf_count, buf->address );
-
-		offset += alignment;
-		entry->buf_count++;
-		byte_count += PAGE_SIZE << page_order;
-	}
-
-	DRM_DEBUG( "byte_count: %d\n", byte_count );
-
-	temp_buflist = DRM(realloc)( dma->buflist,
-				     dma->buf_count * sizeof(*dma->buflist),
-				     (dma->buf_count + entry->buf_count)
-				     * sizeof(*dma->buflist),
-				     DRM_MEM_BUFS );
-	if(!temp_buflist) {
-		/* Free the entry because it isn't valid */
-		DRM(cleanup_buf_error)(entry);
-		up( &dev->struct_sem );
-		atomic_dec( &dev->buf_alloc );
-		return -ENOMEM;
-	}
-	dma->buflist = temp_buflist;
-
-	for ( i = 0 ; i < entry->buf_count ; i++ ) {
-		dma->buflist[i + dma->buf_count] = &entry->buflist[i];
-	}
-
-	dma->buf_count += entry->buf_count;
-	dma->byte_count += byte_count;
-
-	DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
-	DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-
-	up( &dev->struct_sem );
-
-	request.count = entry->buf_count;
-	request.size = size;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	dma->flags = _DRM_DMA_USE_SG;
-
-	atomic_dec( &dev->buf_alloc );
-	return 0;
-}
-
-/**
- * Add buffers for DMA transfers (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_desc_t request.
- * \return zero on success or a negative number on failure.
- *
- * According with the memory type specified in drm_buf_desc::flags and the
- * build options, it dispatches the call either to addbufs_agp(),
- * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
- * PCI memory respectively.
- */
-int DRM(addbufs)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_buf_desc_t request;
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( copy_from_user( &request, (drm_buf_desc_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-#if __OS_HAS_AGP
-	if ( request.flags & _DRM_AGP_BUFFER )
-		return DRM(addbufs_agp)( inode, filp, cmd, arg );
-	else
-#endif
-	if ( request.flags & _DRM_SG_BUFFER )
-		return DRM(addbufs_sg)( inode, filp, cmd, arg );
-	else
-		return DRM(addbufs_pci)( inode, filp, cmd, arg );
-}
-
-
-/**
- * Get information about the buffer mappings.
- *
- * This was originally mean for debugging purposes, or by a sophisticated
- * client library to determine how best to use the available buffers (e.g.,
- * large buffers can be used for image transfer).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_info structure.
- * \return zero on success or a negative number on failure.
- *
- * Increments drm_device::buf_use while holding the drm_device::count_lock
- * lock, preventing of allocating more buffers after this call. Information
- * about each requested buffer is then copied into user space.
- */
-int DRM(infobufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_info_t request;
-	drm_buf_info_t __user *argp = (void __user *)arg;
-	int i;
-	int count;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	spin_lock( &dev->count_lock );
-	if ( atomic_read( &dev->buf_alloc ) ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	++dev->buf_use;		/* Can't allocate more after this call */
-	spin_unlock( &dev->count_lock );
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
-		if ( dma->bufs[i].buf_count ) ++count;
-	}
-
-	DRM_DEBUG( "count = %d\n", count );
-
-	if ( request.count >= count ) {
-		for ( i = 0, count = 0 ; i < DRM_MAX_ORDER + 1 ; i++ ) {
-			if ( dma->bufs[i].buf_count ) {
-				drm_buf_desc_t __user *to = &request.list[count];
-				drm_buf_entry_t *from = &dma->bufs[i];
-				drm_freelist_t *list = &dma->bufs[i].freelist;
-				if ( copy_to_user( &to->count,
-						   &from->buf_count,
-						   sizeof(from->buf_count) ) ||
-				     copy_to_user( &to->size,
-						   &from->buf_size,
-						   sizeof(from->buf_size) ) ||
-				     copy_to_user( &to->low_mark,
-						   &list->low_mark,
-						   sizeof(list->low_mark) ) ||
-				     copy_to_user( &to->high_mark,
-						   &list->high_mark,
-						   sizeof(list->high_mark) ) )
-					return -EFAULT;
-
-				DRM_DEBUG( "%d %d %d %d %d\n",
-					   i,
-					   dma->bufs[i].buf_count,
-					   dma->bufs[i].buf_size,
-					   dma->bufs[i].freelist.low_mark,
-					   dma->bufs[i].freelist.high_mark );
-				++count;
-			}
-		}
-	}
-	request.count = count;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	return 0;
-}
-
-/**
- * Specifies a low and high water mark for buffer allocation
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg a pointer to a drm_buf_desc structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies that the size order is bounded between the admissible orders and
- * updates the respective drm_device_dma::bufs entry low and high water mark.
- *
- * \note This ioctl is deprecated and mostly never used.
- */
-int DRM(markbufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_desc_t request;
-	int order;
-	drm_buf_entry_t *entry;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_buf_desc_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d, %d, %d\n",
-		   request.size, request.low_mark, request.high_mark );
-	order = DRM(order)( request.size );
-	if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
-	entry = &dma->bufs[order];
-
-	if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
-		return -EINVAL;
-	if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
-		return -EINVAL;
-
-	entry->freelist.low_mark  = request.low_mark;
-	entry->freelist.high_mark = request.high_mark;
-
-	return 0;
-}
-
-/**
- * Unreserve the buffers in list, previously reserved using drmDMA. 
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_free structure.
- * \return zero on success or a negative number on failure.
- * 
- * Calls free_buffer() for each used buffer.
- * This function is primarily used for debugging.
- */
-int DRM(freebufs)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_free_t request;
-	int i;
-	int idx;
-	drm_buf_t *buf;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_buf_free_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", request.count );
-	for ( i = 0 ; i < request.count ; i++ ) {
-		if ( copy_from_user( &idx,
-				     &request.list[i],
-				     sizeof(idx) ) )
-			return -EFAULT;
-		if ( idx < 0 || idx >= dma->buf_count ) {
-			DRM_ERROR( "Index %d (of %d max)\n",
-				   idx, dma->buf_count - 1 );
-			return -EINVAL;
-		}
-		buf = dma->buflist[idx];
-		if ( buf->filp != filp ) {
-			DRM_ERROR( "Process %d freeing buffer not owned\n",
-				   current->pid );
-			return -EINVAL;
-		}
-		DRM(free_buffer)( dev, buf );
-	}
-
-	return 0;
-}
-
-/**
- * Maps all of the DMA buffers into client-virtual space (ioctl).
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg pointer to a drm_buf_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Maps the AGP or SG buffer region with do_mmap(), and copies information
- * about each buffer into user space. The PCI buffers are already mapped on the
- * addbufs_pci() call.
- */
-int DRM(mapbufs)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	drm_buf_map_t __user *argp = (void __user *)arg;
-	int retcode = 0;
-	const int zero = 0;
-	unsigned long virtual;
-	unsigned long address;
-	drm_buf_map_t request;
-	int i;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		return -EINVAL;
-
-	if ( !dma ) return -EINVAL;
-
-	spin_lock( &dev->count_lock );
-	if ( atomic_read( &dev->buf_alloc ) ) {
-		spin_unlock( &dev->count_lock );
-		return -EBUSY;
-	}
-	dev->buf_use++;		/* Can't allocate more after this call */
-	spin_unlock( &dev->count_lock );
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	if ( request.count >= dma->buf_count ) {
-		if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) ||
-		    (drm_core_check_feature(dev, DRIVER_SG) && (dma->flags & _DRM_DMA_USE_SG)) ) {
-			drm_map_t *map = dev->agp_buffer_map;
-
-			if ( !map ) {
-				retcode = -EINVAL;
-				goto done;
-			}
-
-#if LINUX_VERSION_CODE <= 0x020402
-			down( &current->mm->mmap_sem );
-#else
-			down_write( &current->mm->mmap_sem );
-#endif
-			virtual = do_mmap( filp, 0, map->size,
-					   PROT_READ | PROT_WRITE,
-					   MAP_SHARED,
-					   (unsigned long)map->offset );
-#if LINUX_VERSION_CODE <= 0x020402
-			up( &current->mm->mmap_sem );
-#else
-			up_write( &current->mm->mmap_sem );
-#endif
-		} else {
-#if LINUX_VERSION_CODE <= 0x020402
-			down( &current->mm->mmap_sem );
-#else
-			down_write( &current->mm->mmap_sem );
-#endif
-			virtual = do_mmap( filp, 0, dma->byte_count,
-					   PROT_READ | PROT_WRITE,
-					   MAP_SHARED, 0 );
-#if LINUX_VERSION_CODE <= 0x020402
-			up( &current->mm->mmap_sem );
-#else
-			up_write( &current->mm->mmap_sem );
-#endif
-		}
-		if ( virtual > -1024UL ) {
-			/* Real error */
-			retcode = (signed long)virtual;
-			goto done;
-		}
-		request.virtual = (void __user *)virtual;
-
-		for ( i = 0 ; i < dma->buf_count ; i++ ) {
-			if ( copy_to_user( &request.list[i].idx,
-					   &dma->buflist[i]->idx,
-					   sizeof(request.list[0].idx) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			if ( copy_to_user( &request.list[i].total,
-					   &dma->buflist[i]->total,
-					   sizeof(request.list[0].total) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			if ( copy_to_user( &request.list[i].used,
-					   &zero,
-					   sizeof(zero) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-			address = virtual + dma->buflist[i]->offset; /* *** */
-			if ( copy_to_user( &request.list[i].address,
-					   &address,
-					   sizeof(address) ) ) {
-				retcode = -EFAULT;
-				goto done;
-			}
-		}
-	}
- done:
-	request.count = dma->buf_count;
-	DRM_DEBUG( "%d buffers, retcode = %d\n", request.count, retcode );
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) )
-		return -EFAULT;
-
-	return retcode;
-}
-
diff -Nru a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_context.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,578 @@
+/**
+ * \file drm_context.h 
+ * IOCTLs for generic contexts
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+/*
+ * ChangeLog:
+ *  2001-11-16	Torsten Duwe <duwe@caldera.de>
+ *		added context constructor/destructor hooks,
+ *		needed by SiS driver's memory management.
+ */
+
+#include "drmP.h"
+
+/******************************************************************/
+/** \name Context bitmap support */
+/*@{*/
+
+/**
+ * Free a handle from the context bitmap.
+ *
+ * \param dev DRM device.
+ * \param ctx_handle context handle.
+ *
+ * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
+ * in drm_device::context_sareas, while holding the drm_device::struct_sem
+ * lock.
+ */
+void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
+{
+	if ( ctx_handle < 0 ) goto failed;
+	if ( !dev->ctx_bitmap ) goto failed;
+
+	if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
+		down(&dev->struct_sem);
+		clear_bit( ctx_handle, dev->ctx_bitmap );
+		dev->context_sareas[ctx_handle] = NULL;
+		up(&dev->struct_sem);
+		return;
+	}
+failed:
+       	DRM_ERROR( "Attempt to free invalid context handle: %d\n",
+		   ctx_handle );
+       	return;
+}
+
+/** 
+ * Context bitmap allocation.
+ *
+ * \param dev DRM device.
+ * \return (non-negative) context handle on success or a negative number on failure.
+ *
+ * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
+ * drm_device::context_sareas to accommodate the new entry while holding the
+ * drm_device::struct_sem lock.
+ */
+int drm_ctxbitmap_next( drm_device_t *dev )
+{
+	int bit;
+
+	if(!dev->ctx_bitmap) return -1;
+
+	down(&dev->struct_sem);
+	bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
+	if ( bit < DRM_MAX_CTXBITMAP ) {
+		set_bit( bit, dev->ctx_bitmap );
+	   	DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
+		if((bit+1) > dev->max_context) {
+			dev->max_context = (bit+1);
+			if(dev->context_sareas) {
+				drm_map_t **ctx_sareas;
+
+				ctx_sareas = drm_realloc(dev->context_sareas,
+						(dev->max_context - 1) * 
+						sizeof(*dev->context_sareas),
+						dev->max_context * 
+						sizeof(*dev->context_sareas),
+						DRM_MEM_MAPS);
+				if(!ctx_sareas) {
+					clear_bit(bit, dev->ctx_bitmap);
+					up(&dev->struct_sem);
+					return -1;
+				}
+				dev->context_sareas = ctx_sareas;
+				dev->context_sareas[bit] = NULL;
+			} else {
+				/* max_context == 1 at this point */
+				dev->context_sareas = drm_alloc(
+						dev->max_context * 
+						sizeof(*dev->context_sareas),
+						DRM_MEM_MAPS);
+				if(!dev->context_sareas) {
+					clear_bit(bit, dev->ctx_bitmap);
+					up(&dev->struct_sem);
+					return -1;
+				}
+				dev->context_sareas[bit] = NULL;
+			}
+		}
+		up(&dev->struct_sem);
+		return bit;
+	}
+	up(&dev->struct_sem);
+	return -1;
+}
+
+/**
+ * Context bitmap initialization.
+ *
+ * \param dev DRM device.
+ *
+ * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
+int drm_ctxbitmap_init( drm_device_t *dev )
+{
+	int i;
+   	int temp;
+
+	down(&dev->struct_sem);
+	dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE,
+							DRM_MEM_CTXBITMAP );
+	if ( dev->ctx_bitmap == NULL ) {
+		up(&dev->struct_sem);
+		return -ENOMEM;
+	}
+	memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
+	dev->context_sareas = NULL;
+	dev->max_context = -1;
+	up(&dev->struct_sem);
+
+	for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+		temp = drm_ctxbitmap_next( dev );
+	   	DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
+	}
+
+	return 0;
+}
+
+/**
+ * Context bitmap cleanup.
+ *
+ * \param dev DRM device.
+ *
+ * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
+ * the drm_device::struct_sem lock.
+ */
+void drm_ctxbitmap_cleanup( drm_device_t *dev )
+{
+	down(&dev->struct_sem);
+	if( dev->context_sareas ) drm_free( dev->context_sareas,
+					     sizeof(*dev->context_sareas) * 
+					     dev->max_context,
+					     DRM_MEM_MAPS );
+	drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
+	up(&dev->struct_sem);
+}
+
+/*@}*/
+
+/******************************************************************/
+/** \name Per Context SAREA Support */
+/*@{*/
+
+/**
+ * Get per-context SAREA.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Gets the map from drm_device::context_sareas with the handle specified and
+ * returns its handle.
+ */
+int drm_getsareactx(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_ctx_priv_map_t __user *argp = (void __user *)arg;
+	drm_ctx_priv_map_t request;
+	drm_map_t *map;
+
+	if (copy_from_user(&request, argp, sizeof(request)))
+		return -EFAULT;
+
+	down(&dev->struct_sem);
+	if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	map = dev->context_sareas[request.ctx_id];
+	up(&dev->struct_sem);
+
+	request.handle = map->handle;
+	if (copy_to_user(argp, &request, sizeof(request)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Set per-context SAREA.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_priv_map structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the mapping specified in \p arg and update the entry in
+ * drm_device::context_sareas with it.
+ */
+int drm_setsareactx(struct inode *inode, struct file *filp,
+		     unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_ctx_priv_map_t request;
+	drm_map_t *map = NULL;
+	drm_map_list_t *r_list = NULL;
+	struct list_head *list;
+
+	if (copy_from_user(&request,
+			   (drm_ctx_priv_map_t __user *)arg,
+			   sizeof(request)))
+		return -EFAULT;
+
+	down(&dev->struct_sem);
+	list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+		if(r_list->map &&
+		   r_list->map->handle == request.handle)
+			goto found;
+	}
+bad:
+	up(&dev->struct_sem);
+	return -EINVAL;
+
+found:
+	map = r_list->map;
+	if (!map) goto bad;
+	if (dev->max_context < 0)
+		goto bad;
+	if (request.ctx_id >= (unsigned) dev->max_context)
+		goto bad;
+	dev->context_sareas[request.ctx_id] = map;
+	up(&dev->struct_sem);
+	return 0;
+}
+
+/*@}*/
+
+/******************************************************************/
+/** \name The actual DRM context handling routines */
+/*@{*/
+
+/**
+ * Switch context.
+ *
+ * \param dev DRM device.
+ * \param old old context handle.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to set drm_device::context_flag.
+ */
+int drm_context_switch( drm_device_t *dev, int old, int new )
+{
+        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
+                DRM_ERROR( "Reentering -- FIXME\n" );
+                return -EBUSY;
+        }
+
+
+        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
+
+        if ( new == dev->last_context ) {
+                clear_bit( 0, &dev->context_flag );
+                return 0;
+        }
+
+        return 0;
+}
+
+/**
+ * Complete context switch.
+ *
+ * \param dev DRM device.
+ * \param new new context handle.
+ * \return zero on success or a negative number on failure.
+ *
+ * Updates drm_device::last_context and drm_device::last_switch. Verifies the
+ * hardware lock is held, clears the drm_device::context_flag and wakes up
+ * drm_device::context_wait.
+ */
+int drm_context_switch_complete( drm_device_t *dev, int new )
+{
+        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
+        dev->last_switch  = jiffies;
+
+        if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
+                DRM_ERROR( "Lock isn't held after context switch\n" );
+        }
+
+				/* If a context switch is ever initiated
+                                   when the kernel holds the lock, release
+                                   that lock here. */
+        clear_bit( 0, &dev->context_flag );
+        wake_up( &dev->context_wait );
+
+        return 0;
+}
+
+/**
+ * Reserve contexts.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx_res structure.
+ * \return zero on success or a negative number on failure.
+ */
+int drm_resctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_ctx_res_t res;
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+	int i;
+
+	if ( copy_from_user( &res, argp, sizeof(res) ) )
+		return -EFAULT;
+
+	if ( res.count >= DRM_RESERVED_CONTEXTS ) {
+		memset( &ctx, 0, sizeof(ctx) );
+		for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+			ctx.handle = i;
+			if ( copy_to_user( &res.contexts[i],
+					   &i, sizeof(i) ) )
+				return -EFAULT;
+		}
+	}
+	res.count = DRM_RESERVED_CONTEXTS;
+
+	if ( copy_to_user( argp, &res, sizeof(res) ) )
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Add context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Get a new handle for the context and copy to userspace.
+ */
+int drm_addctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_list_t * ctx_entry;
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+		return -EFAULT;
+
+	ctx.handle = drm_ctxbitmap_next( dev );
+	if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
+				/* Skip kernel's context and get a new one. */
+		ctx.handle = drm_ctxbitmap_next( dev );
+	}
+	DRM_DEBUG( "%d\n", ctx.handle );
+	if ( ctx.handle == -1 ) {
+		DRM_DEBUG( "Not enough free contexts.\n" );
+				/* Should this return -EBUSY instead? */
+		return -ENOMEM;
+	}
+
+	if ( ctx.handle != DRM_KERNEL_CONTEXT )
+	{
+		if (dev->driver->context_ctor)
+			dev->driver->context_ctor(dev, ctx.handle);
+	}
+
+	ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
+	if ( !ctx_entry ) {
+		DRM_DEBUG("out of memory\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD( &ctx_entry->head );
+	ctx_entry->handle = ctx.handle;
+	ctx_entry->tag = priv;
+
+	down( &dev->ctxlist_sem );
+	list_add( &ctx_entry->head, &dev->ctxlist->head );
+	++dev->ctx_count;
+	up( &dev->ctxlist_sem );
+
+	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+		return -EFAULT;
+	return 0;
+}
+
+int drm_modctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	/* This does nothing */
+	return 0;
+}
+
+/**
+ * Get context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ */
+int drm_getctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_ctx_t __user *argp = (void __user *)arg;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
+		return -EFAULT;
+
+	/* This is 0, because we don't handle any context flags */
+	ctx.flags = 0;
+
+	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Switch context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch().
+ */
+int drm_switchctx( struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	return drm_context_switch( dev, dev->last_context, ctx.handle );
+}
+
+/**
+ * New context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls context_switch_complete().
+ */
+int drm_newctx( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	drm_context_switch_complete( dev, ctx.handle );
+
+	return 0;
+}
+
+/**
+ * Remove context.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument pointing to a drm_ctx structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
+ */
+int drm_rmctx( struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ctx_t ctx;
+
+	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "%d\n", ctx.handle );
+	if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
+		priv->remove_auth_on_close = 1;
+	}
+	if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
+		if (dev->driver->context_dtor)
+			dev->driver->context_dtor(dev, ctx.handle);
+		drm_ctxbitmap_free( dev, ctx.handle );
+	}
+
+	down( &dev->ctxlist_sem );
+	if ( !list_empty( &dev->ctxlist->head ) ) {
+		drm_ctx_list_t *pos, *n;
+
+		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+			if ( pos->handle == ctx.handle ) {
+				list_del( &pos->head );
+				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+				--dev->ctx_count;
+			}
+		}
+	}
+	up( &dev->ctxlist_sem );
+
+	return 0;
+}
+
+/*@}*/
+
diff -Nru a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h
--- a/drivers/char/drm/drm_context.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,578 +0,0 @@
-/**
- * \file drm_context.h 
- * IOCTLs for generic contexts
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-/*
- * ChangeLog:
- *  2001-11-16	Torsten Duwe <duwe@caldera.de>
- *		added context constructor/destructor hooks,
- *		needed by SiS driver's memory management.
- */
-
-#include "drmP.h"
-
-/******************************************************************/
-/** \name Context bitmap support */
-/*@{*/
-
-/**
- * Free a handle from the context bitmap.
- *
- * \param dev DRM device.
- * \param ctx_handle context handle.
- *
- * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
- * in drm_device::context_sareas, while holding the drm_device::struct_sem
- * lock.
- */
-void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
-{
-	if ( ctx_handle < 0 ) goto failed;
-	if ( !dev->ctx_bitmap ) goto failed;
-
-	if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
-		down(&dev->struct_sem);
-		clear_bit( ctx_handle, dev->ctx_bitmap );
-		dev->context_sareas[ctx_handle] = NULL;
-		up(&dev->struct_sem);
-		return;
-	}
-failed:
-       	DRM_ERROR( "Attempt to free invalid context handle: %d\n",
-		   ctx_handle );
-       	return;
-}
-
-/** 
- * Context bitmap allocation.
- *
- * \param dev DRM device.
- * \return (non-negative) context handle on success or a negative number on failure.
- *
- * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
- * drm_device::context_sareas to accommodate the new entry while holding the
- * drm_device::struct_sem lock.
- */
-int DRM(ctxbitmap_next)( drm_device_t *dev )
-{
-	int bit;
-
-	if(!dev->ctx_bitmap) return -1;
-
-	down(&dev->struct_sem);
-	bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
-	if ( bit < DRM_MAX_CTXBITMAP ) {
-		set_bit( bit, dev->ctx_bitmap );
-	   	DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
-		if((bit+1) > dev->max_context) {
-			dev->max_context = (bit+1);
-			if(dev->context_sareas) {
-				drm_map_t **ctx_sareas;
-
-				ctx_sareas = DRM(realloc)(dev->context_sareas,
-						(dev->max_context - 1) * 
-						sizeof(*dev->context_sareas),
-						dev->max_context * 
-						sizeof(*dev->context_sareas),
-						DRM_MEM_MAPS);
-				if(!ctx_sareas) {
-					clear_bit(bit, dev->ctx_bitmap);
-					up(&dev->struct_sem);
-					return -1;
-				}
-				dev->context_sareas = ctx_sareas;
-				dev->context_sareas[bit] = NULL;
-			} else {
-				/* max_context == 1 at this point */
-				dev->context_sareas = DRM(alloc)(
-						dev->max_context * 
-						sizeof(*dev->context_sareas),
-						DRM_MEM_MAPS);
-				if(!dev->context_sareas) {
-					clear_bit(bit, dev->ctx_bitmap);
-					up(&dev->struct_sem);
-					return -1;
-				}
-				dev->context_sareas[bit] = NULL;
-			}
-		}
-		up(&dev->struct_sem);
-		return bit;
-	}
-	up(&dev->struct_sem);
-	return -1;
-}
-
-/**
- * Context bitmap initialization.
- *
- * \param dev DRM device.
- *
- * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
- */
-int DRM(ctxbitmap_init)( drm_device_t *dev )
-{
-	int i;
-   	int temp;
-
-	down(&dev->struct_sem);
-	dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
-							DRM_MEM_CTXBITMAP );
-	if ( dev->ctx_bitmap == NULL ) {
-		up(&dev->struct_sem);
-		return -ENOMEM;
-	}
-	memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
-	dev->context_sareas = NULL;
-	dev->max_context = -1;
-	up(&dev->struct_sem);
-
-	for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
-		temp = DRM(ctxbitmap_next)( dev );
-	   	DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
-	}
-
-	return 0;
-}
-
-/**
- * Context bitmap cleanup.
- *
- * \param dev DRM device.
- *
- * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
- * the drm_device::struct_sem lock.
- */
-void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
-{
-	down(&dev->struct_sem);
-	if( dev->context_sareas ) DRM(free)( dev->context_sareas,
-					     sizeof(*dev->context_sareas) * 
-					     dev->max_context,
-					     DRM_MEM_MAPS );
-	DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
-	up(&dev->struct_sem);
-}
-
-/*@}*/
-
-/******************************************************************/
-/** \name Per Context SAREA Support */
-/*@{*/
-
-/**
- * Get per-context SAREA.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_priv_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Gets the map from drm_device::context_sareas with the handle specified and
- * returns its handle.
- */
-int DRM(getsareactx)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_ctx_priv_map_t __user *argp = (void __user *)arg;
-	drm_ctx_priv_map_t request;
-	drm_map_t *map;
-
-	if (copy_from_user(&request, argp, sizeof(request)))
-		return -EFAULT;
-
-	down(&dev->struct_sem);
-	if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	map = dev->context_sareas[request.ctx_id];
-	up(&dev->struct_sem);
-
-	request.handle = map->handle;
-	if (copy_to_user(argp, &request, sizeof(request)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Set per-context SAREA.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_priv_map structure.
- * \return zero on success or a negative number on failure.
- *
- * Searches the mapping specified in \p arg and update the entry in
- * drm_device::context_sareas with it.
- */
-int DRM(setsareactx)(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_ctx_priv_map_t request;
-	drm_map_t *map = NULL;
-	drm_map_list_t *r_list = NULL;
-	struct list_head *list;
-
-	if (copy_from_user(&request,
-			   (drm_ctx_priv_map_t __user *)arg,
-			   sizeof(request)))
-		return -EFAULT;
-
-	down(&dev->struct_sem);
-	list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-		if(r_list->map &&
-		   r_list->map->handle == request.handle)
-			goto found;
-	}
-bad:
-	up(&dev->struct_sem);
-	return -EINVAL;
-
-found:
-	map = r_list->map;
-	if (!map) goto bad;
-	if (dev->max_context < 0)
-		goto bad;
-	if (request.ctx_id >= (unsigned) dev->max_context)
-		goto bad;
-	dev->context_sareas[request.ctx_id] = map;
-	up(&dev->struct_sem);
-	return 0;
-}
-
-/*@}*/
-
-/******************************************************************/
-/** \name The actual DRM context handling routines */
-/*@{*/
-
-/**
- * Switch context.
- *
- * \param dev DRM device.
- * \param old old context handle.
- * \param new new context handle.
- * \return zero on success or a negative number on failure.
- *
- * Attempt to set drm_device::context_flag.
- */
-int DRM(context_switch)( drm_device_t *dev, int old, int new )
-{
-        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
-                DRM_ERROR( "Reentering -- FIXME\n" );
-                return -EBUSY;
-        }
-
-
-        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
-
-        if ( new == dev->last_context ) {
-                clear_bit( 0, &dev->context_flag );
-                return 0;
-        }
-
-        return 0;
-}
-
-/**
- * Complete context switch.
- *
- * \param dev DRM device.
- * \param new new context handle.
- * \return zero on success or a negative number on failure.
- *
- * Updates drm_device::last_context and drm_device::last_switch. Verifies the
- * hardware lock is held, clears the drm_device::context_flag and wakes up
- * drm_device::context_wait.
- */
-int DRM(context_switch_complete)( drm_device_t *dev, int new )
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-
-        if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
-                DRM_ERROR( "Lock isn't held after context switch\n" );
-        }
-
-				/* If a context switch is ever initiated
-                                   when the kernel holds the lock, release
-                                   that lock here. */
-        clear_bit( 0, &dev->context_flag );
-        wake_up( &dev->context_wait );
-
-        return 0;
-}
-
-/**
- * Reserve contexts.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx_res structure.
- * \return zero on success or a negative number on failure.
- */
-int DRM(resctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_ctx_res_t res;
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-	int i;
-
-	if ( copy_from_user( &res, argp, sizeof(res) ) )
-		return -EFAULT;
-
-	if ( res.count >= DRM_RESERVED_CONTEXTS ) {
-		memset( &ctx, 0, sizeof(ctx) );
-		for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
-			ctx.handle = i;
-			if ( copy_to_user( &res.contexts[i],
-					   &i, sizeof(i) ) )
-				return -EFAULT;
-		}
-	}
-	res.count = DRM_RESERVED_CONTEXTS;
-
-	if ( copy_to_user( argp, &res, sizeof(res) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Add context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Get a new handle for the context and copy to userspace.
- */
-int DRM(addctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_list_t * ctx_entry;
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
-		return -EFAULT;
-
-	ctx.handle = DRM(ctxbitmap_next)( dev );
-	if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
-				/* Skip kernel's context and get a new one. */
-		ctx.handle = DRM(ctxbitmap_next)( dev );
-	}
-	DRM_DEBUG( "%d\n", ctx.handle );
-	if ( ctx.handle == -1 ) {
-		DRM_DEBUG( "Not enough free contexts.\n" );
-				/* Should this return -EBUSY instead? */
-		return -ENOMEM;
-	}
-
-	if ( ctx.handle != DRM_KERNEL_CONTEXT )
-	{
-		if (dev->fn_tbl.context_ctor)
-			dev->fn_tbl.context_ctor(dev, ctx.handle);
-	}
-
-	ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
-	if ( !ctx_entry ) {
-		DRM_DEBUG("out of memory\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD( &ctx_entry->head );
-	ctx_entry->handle = ctx.handle;
-	ctx_entry->tag = priv;
-
-	down( &dev->ctxlist_sem );
-	list_add( &ctx_entry->head, &dev->ctxlist->head );
-	++dev->ctx_count;
-	up( &dev->ctxlist_sem );
-
-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
-		return -EFAULT;
-	return 0;
-}
-
-int DRM(modctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	/* This does nothing */
-	return 0;
-}
-
-/**
- * Get context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- */
-int DRM(getctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_ctx_t __user *argp = (void __user *)arg;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
-		return -EFAULT;
-
-	/* This is 0, because we don't handle any context flags */
-	ctx.flags = 0;
-
-	if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Switch context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls context_switch().
- */
-int DRM(switchctx)( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	return DRM(context_switch)( dev, dev->last_context, ctx.handle );
-}
-
-/**
- * New context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls context_switch_complete().
- */
-int DRM(newctx)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	DRM(context_switch_complete)( dev, ctx.handle );
-
-	return 0;
-}
-
-/**
- * Remove context.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument pointing to a drm_ctx structure.
- * \return zero on success or a negative number on failure.
- *
- * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
- */
-int DRM(rmctx)( struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
-		return -EFAULT;
-
-	DRM_DEBUG( "%d\n", ctx.handle );
-	if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
-		priv->remove_auth_on_close = 1;
-	}
-	if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
-		if (dev->fn_tbl.context_dtor)
-			dev->fn_tbl.context_dtor(dev, ctx.handle);
-		DRM(ctxbitmap_free)( dev, ctx.handle );
-	}
-
-	down( &dev->ctxlist_sem );
-	if ( !list_empty( &dev->ctxlist->head ) ) {
-		drm_ctx_list_t *pos, *n;
-
-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
-			if ( pos->handle == ctx.handle ) {
-				list_del( &pos->head );
-				DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
-				--dev->ctx_count;
-			}
-		}
-	}
-	up( &dev->ctxlist_sem );
-
-	return 0;
-}
-
-/*@}*/
-
diff -Nru a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
--- a/drivers/char/drm/drm_core.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/drm_core.h	2004-11-09 00:25:55 -08:00
@@ -20,21 +20,15 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+#define DRIVER_AUTHOR		"Gareth Hughes, Leif Delgass, JosÃ© Fonseca, Jon Smirl"
 
-#include "drm_auth.h"
-#include "drm_agpsupport.h"
-#include "drm_bufs.h"
-#include "drm_context.h"
-#include "drm_dma.h"
-#include "drm_irq.h"
-#include "drm_drawable.h"
-#include "drm_drv.h"
-#include "drm_fops.h"
-#include "drm_init.h"
-#include "drm_ioctl.h"
-#include "drm_lock.h"
-#include "drm_memory.h"
-#include "drm_proc.h"
-#include "drm_vm.h"
-#include "drm_stub.h"
-#include "drm_scatter.h"
+#define DRIVER_NAME		"drm"
+#define DRIVER_DESC		"DRM shared core routines"
+#define DRIVER_DATE		"20040925"
+
+#define DRM_IF_MAJOR	1
+#define DRM_IF_MINOR	2
+
+#define DRIVER_MAJOR	1
+#define DRIVER_MINOR	0
+#define DRIVER_PATCHLEVEL 0
diff -Nru a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_dma.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,182 @@
+/**
+ * \file drm_dma.h 
+ * DMA IOCTL and function support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+/**
+ * Initialize the DMA data.
+ * 
+ * \param dev DRM device.
+ * \return zero on success or a negative value on failure.
+ *
+ * Allocate and initialize a drm_device_dma structure.
+ */
+int drm_dma_setup( drm_device_t *dev )
+{
+	int i;
+
+	dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
+	if ( !dev->dma )
+		return -ENOMEM;
+
+	memset( dev->dma, 0, sizeof(*dev->dma) );
+
+	for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
+		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
+
+	return 0;
+}
+
+/**
+ * Cleanup the DMA resources.
+ *
+ * \param dev DRM device.
+ *
+ * Free all pages associated with DMA buffers, the buffers and pages lists, and
+ * finally the the drm_device::dma structure itself.
+ */
+void drm_dma_takedown(drm_device_t *dev)
+{
+	drm_device_dma_t  *dma = dev->dma;
+	int		  i, j;
+
+	if (!dma) return;
+
+				/* Clear dma buffers */
+	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+		if (dma->bufs[i].seg_count) {
+			DRM_DEBUG("order %d: buf_count = %d,"
+				  " seg_count = %d\n",
+				  i,
+				  dma->bufs[i].buf_count,
+				  dma->bufs[i].seg_count);
+			for (j = 0; j < dma->bufs[i].seg_count; j++) {
+				if (dma->bufs[i].seglist[j]) {
+					drm_free_pages(dma->bufs[i].seglist[j],
+							dma->bufs[i].page_order,
+							DRM_MEM_DMA);
+				}
+			}
+			drm_free(dma->bufs[i].seglist,
+				  dma->bufs[i].seg_count
+				  * sizeof(*dma->bufs[0].seglist),
+				  DRM_MEM_SEGS);
+		}
+	   	if (dma->bufs[i].buf_count) {
+		   	for (j = 0; j < dma->bufs[i].buf_count; j++) {
+				if (dma->bufs[i].buflist[j].dev_private) {
+					drm_free(dma->bufs[i].buflist[j].dev_private,
+						  dma->bufs[i].buflist[j].dev_priv_size,
+						  DRM_MEM_BUFS);
+				}
+			}
+		   	drm_free(dma->bufs[i].buflist,
+				  dma->bufs[i].buf_count *
+				  sizeof(*dma->bufs[0].buflist),
+				  DRM_MEM_BUFS);
+		}
+	}
+
+	if (dma->buflist) {
+		drm_free(dma->buflist,
+			  dma->buf_count * sizeof(*dma->buflist),
+			  DRM_MEM_BUFS);
+	}
+
+	if (dma->pagelist) {
+		drm_free(dma->pagelist,
+			  dma->page_count * sizeof(*dma->pagelist),
+			  DRM_MEM_PAGES);
+	}
+	drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
+	dev->dma = NULL;
+}
+
+
+/**
+ * Free a buffer.
+ *
+ * \param dev DRM device.
+ * \param buf buffer to free.
+ * 
+ * Resets the fields of \p buf.
+ */
+void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+{
+	if (!buf) return;
+
+	buf->waiting  = 0;
+	buf->pending  = 0;
+	buf->filp     = NULL;
+	buf->used     = 0;
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
+		wake_up_interruptible(&buf->dma_wait);
+	}
+}
+
+/**
+ * Reclaim the buffers.
+ *
+ * \param filp file pointer.
+ *
+ * Frees each buffer associated with \p filp not already on the hardware.
+ */
+void drm_core_reclaim_buffers( struct file *filp )
+{
+	drm_file_t    *priv   = filp->private_data;
+	drm_device_t  *dev    = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+
+	if (!dma) return;
+	for (i = 0; i < dma->buf_count; i++) {
+		if (dma->buflist[i]->filp == filp) {
+			switch (dma->buflist[i]->list) {
+			case DRM_LIST_NONE:
+				drm_free_buffer(dev, dma->buflist[i]);
+				break;
+			case DRM_LIST_WAIT:
+				dma->buflist[i]->list = DRM_LIST_RECLAIM;
+				break;
+			default:
+				/* Buffer already on hardware. */
+				break;
+			}
+		}
+	}
+}
+EXPORT_SYMBOL(drm_core_reclaim_buffers);
+
diff -Nru a/drivers/char/drm/drm_dma.h b/drivers/char/drm/drm_dma.h
--- a/drivers/char/drm/drm_dma.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,181 +0,0 @@
-/**
- * \file drm_dma.h 
- * DMA IOCTL and function support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-/**
- * Initialize the DMA data.
- * 
- * \param dev DRM device.
- * \return zero on success or a negative value on failure.
- *
- * Allocate and initialize a drm_device_dma structure.
- */
-int DRM(dma_setup)( drm_device_t *dev )
-{
-	int i;
-
-	dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER );
-	if ( !dev->dma )
-		return -ENOMEM;
-
-	memset( dev->dma, 0, sizeof(*dev->dma) );
-
-	for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
-		memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
-
-	return 0;
-}
-
-/**
- * Cleanup the DMA resources.
- *
- * \param dev DRM device.
- *
- * Free all pages associated with DMA buffers, the buffers and pages lists, and
- * finally the the drm_device::dma structure itself.
- */
-void DRM(dma_takedown)(drm_device_t *dev)
-{
-	drm_device_dma_t  *dma = dev->dma;
-	int		  i, j;
-
-	if (!dma) return;
-
-				/* Clear dma buffers */
-	for (i = 0; i <= DRM_MAX_ORDER; i++) {
-		if (dma->bufs[i].seg_count) {
-			DRM_DEBUG("order %d: buf_count = %d,"
-				  " seg_count = %d\n",
-				  i,
-				  dma->bufs[i].buf_count,
-				  dma->bufs[i].seg_count);
-			for (j = 0; j < dma->bufs[i].seg_count; j++) {
-				if (dma->bufs[i].seglist[j]) {
-					DRM(free_pages)(dma->bufs[i].seglist[j],
-							dma->bufs[i].page_order,
-							DRM_MEM_DMA);
-				}
-			}
-			DRM(free)(dma->bufs[i].seglist,
-				  dma->bufs[i].seg_count
-				  * sizeof(*dma->bufs[0].seglist),
-				  DRM_MEM_SEGS);
-		}
-	   	if (dma->bufs[i].buf_count) {
-		   	for (j = 0; j < dma->bufs[i].buf_count; j++) {
-				if (dma->bufs[i].buflist[j].dev_private) {
-					DRM(free)(dma->bufs[i].buflist[j].dev_private,
-						  dma->bufs[i].buflist[j].dev_priv_size,
-						  DRM_MEM_BUFS);
-				}
-			}
-		   	DRM(free)(dma->bufs[i].buflist,
-				  dma->bufs[i].buf_count *
-				  sizeof(*dma->bufs[0].buflist),
-				  DRM_MEM_BUFS);
-		}
-	}
-
-	if (dma->buflist) {
-		DRM(free)(dma->buflist,
-			  dma->buf_count * sizeof(*dma->buflist),
-			  DRM_MEM_BUFS);
-	}
-
-	if (dma->pagelist) {
-		DRM(free)(dma->pagelist,
-			  dma->page_count * sizeof(*dma->pagelist),
-			  DRM_MEM_PAGES);
-	}
-	DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
-	dev->dma = NULL;
-}
-
-
-/**
- * Free a buffer.
- *
- * \param dev DRM device.
- * \param buf buffer to free.
- * 
- * Resets the fields of \p buf.
- */
-void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
-{
-	if (!buf) return;
-
-	buf->waiting  = 0;
-	buf->pending  = 0;
-	buf->filp     = NULL;
-	buf->used     = 0;
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
-		wake_up_interruptible(&buf->dma_wait);
-	}
-}
-
-/**
- * Reclaim the buffers.
- *
- * \param filp file pointer.
- *
- * Frees each buffer associated with \p filp not already on the hardware.
- */
-void DRM(core_reclaim_buffers)( struct file *filp )
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-	drm_device_dma_t *dma = dev->dma;
-	int		 i;
-
-	if (!dma) return;
-	for (i = 0; i < dma->buf_count; i++) {
-		if (dma->buflist[i]->filp == filp) {
-			switch (dma->buflist[i]->list) {
-			case DRM_LIST_NONE:
-				DRM(free_buffer)(dev, dma->buflist[i]);
-				break;
-			case DRM_LIST_WAIT:
-				dma->buflist[i]->list = DRM_LIST_RECLAIM;
-				break;
-			default:
-				/* Buffer already on hardware. */
-				break;
-			}
-		}
-	}
-}
-
diff -Nru a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_drawable.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,56 @@
+/**
+ * \file drm_drawable.h 
+ * IOCTLs for drawables
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+/** No-op. */
+int drm_adddraw(struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg)
+{
+	drm_draw_t draw;
+
+	draw.handle = 0;	/* NOOP */
+	DRM_DEBUG("%d\n", draw.handle);
+	if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
+		return -EFAULT;
+	return 0;
+}
+
+/** No-op. */
+int drm_rmdraw(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	return 0;		/* NOOP */
+}
diff -Nru a/drivers/char/drm/drm_drawable.h b/drivers/char/drm/drm_drawable.h
--- a/drivers/char/drm/drm_drawable.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,56 +0,0 @@
-/**
- * \file drm_drawable.h 
- * IOCTLs for drawables
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-/** No-op. */
-int DRM(adddraw)(struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg)
-{
-	drm_draw_t draw;
-
-	draw.handle = 0;	/* NOOP */
-	DRM_DEBUG("%d\n", draw.handle);
-	if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
-		return -EFAULT;
-	return 0;
-}
-
-/** No-op. */
-int DRM(rmdraw)(struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg)
-{
-	return 0;		/* NOOP */
-}
diff -Nru a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_drv.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,546 @@
+/**
+ * \file drm_drv.h 
+ * Generic driver template
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ *
+ * To use this template, you must at least define the following (samples
+ * given for the MGA driver):
+ *
+ * \code
+ * #define DRIVER_AUTHOR	"VA Linux Systems, Inc."
+ *
+ * #define DRIVER_NAME		"mga"
+ * #define DRIVER_DESC		"Matrox G200/G400"
+ * #define DRIVER_DATE		"20001127"
+ *
+ * #define DRIVER_MAJOR		2
+ * #define DRIVER_MINOR		0
+ * #define DRIVER_PATCHLEVEL	2
+ *
+ * #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( mga_ioctls )
+ *
+ * #define drm_x		mga_##x
+ * \endcode
+ */
+
+/*
+ * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+#include "drm_core.h"
+
+/** Ioctl table */
+drm_ioctl_desc_t		  drm_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { drm_version,     0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { drm_getunique,   0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { drm_getmagic,    0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { drm_irq_by_busid, 0, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { drm_getmap,      0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { drm_getclient,   0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { drm_getstats,    0, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)]   = { drm_setversion,  0, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { drm_setunique,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { drm_noop,        1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { drm_noop,        1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { drm_authmagic,   1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { drm_addmap,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { drm_rmmap,       1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { drm_addctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { drm_rmctx,       1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { drm_modctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { drm_getctx,      1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { drm_switchctx,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { drm_newctx,      1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { drm_resctx,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { drm_adddraw,     1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { drm_rmdraw,      1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { drm_lock,        1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { drm_unlock,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { drm_noop,      1, 0 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { drm_addbufs,     1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { drm_markbufs,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { drm_infobufs,    1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { drm_mapbufs,     1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { drm_freebufs,    1, 0 },
+	/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
+
+	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { drm_control,     1, 1 },
+
+#if __OS_HAS_AGP
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { drm_agp_acquire, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release, 1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable,  1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info,    1, 0 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,   1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,  1, 1 },
+#endif
+
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { drm_sg_alloc,    1, 1 },
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { drm_sg_free,     1, 1 },
+
+	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)]   = { drm_wait_vblank, 0, 0 },
+};
+
+#define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( drm_ioctls )
+
+/**
+ * Take down the DRM device.
+ *
+ * \param dev DRM device structure.
+ *
+ * Frees every resource in \p dev.
+ *
+ * \sa drm_device and setup().
+ */
+int drm_takedown( drm_device_t *dev )
+{
+	drm_magic_entry_t *pt, *next;
+	drm_map_t *map;
+	drm_map_list_t *r_list;
+	struct list_head *list, *list_next;
+	drm_vma_entry_t *vma, *vma_next;
+	int i;
+
+	DRM_DEBUG( "\n" );
+
+	if (dev->driver->pretakedown)
+	  dev->driver->pretakedown(dev);
+
+	if ( dev->irq_enabled ) drm_irq_uninstall( dev );
+
+	down( &dev->struct_sem );
+	del_timer( &dev->timer );
+
+	if ( dev->devname ) {
+		drm_free( dev->devname, strlen( dev->devname ) + 1,
+			   DRM_MEM_DRIVER );
+		dev->devname = NULL;
+	}
+
+	if ( dev->unique ) {
+		drm_free( dev->unique, strlen( dev->unique ) + 1,
+			   DRM_MEM_DRIVER );
+		dev->unique = NULL;
+		dev->unique_len = 0;
+	}
+				/* Clear pid list */
+	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
+			next = pt->next;
+			drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC );
+		}
+		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+	}
+
+				/* Clear AGP information */
+	if (drm_core_has_AGP(dev) && dev->agp) {
+		drm_agp_mem_t *entry;
+		drm_agp_mem_t *nexte;
+
+				/* Remove AGP resources, but leave dev->agp
+                                   intact until drv_cleanup is called. */
+		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+			nexte = entry->next;
+			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;
+
+		if ( dev->agp->acquired ) drm_agp_do_release();
+
+		dev->agp->acquired = 0;
+		dev->agp->enabled  = 0;
+	}
+
+				/* Clear vma list (only built for debugging) */
+	if ( dev->vmalist ) {
+		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
+			vma_next = vma->next;
+			drm_free( vma, sizeof(*vma), DRM_MEM_VMAS );
+		}
+		dev->vmalist = NULL;
+	}
+
+	if( dev->maplist ) {
+		list_for_each_safe( list, list_next, &dev->maplist->head ) {
+			r_list = (drm_map_list_t *)list;
+
+			if ( ( map = r_list->map ) ) {
+				switch ( map->type ) {
+				case _DRM_REGISTERS:
+				case _DRM_FRAME_BUFFER:
+					if (drm_core_has_MTRR(dev)) {
+						if ( map->mtrr >= 0 ) {
+							int retcode;
+							retcode = mtrr_del( map->mtrr,
+									    map->offset,
+									    map->size );
+							DRM_DEBUG( "mtrr_del=%d\n", retcode );
+						}
+					}
+					drm_ioremapfree( map->handle, map->size, dev );
+					break;
+				case _DRM_SHM:
+					vfree(map->handle);
+					break;
+
+				case _DRM_AGP:
+					/* Do nothing here, because this is all
+					 * handled in the AGP/GART driver.
+					 */
+					break;
+				case _DRM_SCATTER_GATHER:
+					/* Handle it */
+					if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
+						drm_sg_cleanup(dev->sg);
+						dev->sg = NULL;
+					}
+					break;
+				}
+				drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+			}
+			list_del( list );
+			drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+ 		}
+		drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+		dev->maplist = NULL;
+ 	}
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
+		for ( i = 0 ; i < dev->queue_count ; i++ ) {
+			if ( dev->queuelist[i] ) {
+				drm_free( dev->queuelist[i],
+					  sizeof(*dev->queuelist[0]),
+					  DRM_MEM_QUEUES );
+				dev->queuelist[i] = NULL;
+			}
+		}
+		drm_free( dev->queuelist,
+			  dev->queue_slots * sizeof(*dev->queuelist),
+			  DRM_MEM_QUEUES );
+		dev->queuelist = NULL;
+	}
+	dev->queue_count = 0;
+
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+		drm_dma_takedown( dev );
+
+	if ( dev->lock.hw_lock ) {
+		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
+		dev->lock.filp = NULL;
+		wake_up_interruptible( &dev->lock.lock_queue );
+	}
+	up( &dev->struct_sem );
+
+	return 0;
+}
+
+
+
+/**
+ * Module initialization. Called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported).
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * Initializes an array of drm_device structures, and attempts to
+ * initialize all available devices, using consecutive minors, registering the
+ * stubs and initializing the AGP device.
+ * 
+ * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
+ * after the initialization for driver customization.
+ */
+int drm_init( struct drm_driver *driver )
+{
+	struct pci_dev *pdev = NULL;
+	struct pci_device_id *pid;
+	int i;
+
+	DRM_DEBUG( "\n" );
+
+	drm_mem_init();
+
+	for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
+		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+		
+		pdev=NULL;
+		/* pass back in pdev to account for multiple identical cards */		
+		while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) {
+			/* stealth mode requires a manual probe */
+			pci_dev_get(pdev);
+			drm_probe(pdev, pid, driver);
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_init);
+
+/**
+ * Called via cleanup_module() at module unload time.
+ *
+ * Cleans up all DRM device, calling takedown().
+ * 
+ * \sa drm_init().
+ */
+static void drm_cleanup( drm_device_t *dev )
+{
+	DRM_DEBUG( "\n" );
+
+	if (!dev) {
+		DRM_ERROR("cleanup called no dev\n");
+		return;
+	}
+
+	drm_takedown( dev );	
+
+	drm_ctxbitmap_cleanup( dev );
+	
+	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+	    dev->agp && dev->agp->agp_mtrr >= 0) {
+		int retval;
+		retval = mtrr_del( dev->agp->agp_mtrr,
+				   dev->agp->agp_info.aper_base,
+				   dev->agp->agp_info.aper_size*1024*1024 );
+		DRM_DEBUG( "mtrr_del=%d\n", retval );
+	}
+	
+	if (drm_core_has_AGP(dev) && dev->agp ) {
+		drm_agp_uninit();
+		drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+		dev->agp = NULL;
+	}
+
+	if (dev->driver->postcleanup)
+		dev->driver->postcleanup(dev);
+	
+	if ( drm_put_minor(dev) )
+		DRM_ERROR( "Cannot unload module\n" );
+}
+
+void drm_exit (struct drm_driver *driver)
+{
+	int i;
+	drm_device_t *dev = NULL;
+	drm_minor_t *minor;
+	
+	DRM_DEBUG( "\n" );
+
+	for (i = 0; i < drm_cards_limit; i++) {
+		minor = &drm_minors[i];
+		if (!minor->dev)
+			continue;
+		if (minor->dev->driver!=driver)
+			continue;
+
+		dev = minor->dev;
+		
+	}
+	if (dev) {
+		/* release the pci driver */
+		if (dev->pdev)
+			pci_dev_put(dev->pdev);
+		drm_cleanup(dev);
+	}
+	
+	DRM_INFO( "Module unloaded\n" );
+}
+EXPORT_SYMBOL(drm_exit);
+
+/** File operations structure */
+static struct file_operations drm_stub_fops = {
+	.owner = THIS_MODULE,
+	.open  = drm_stub_open
+};
+
+static int __init drm_core_init(void)
+{
+	int ret = -ENOMEM;
+	
+	drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
+	drm_minors = drm_calloc(drm_cards_limit,
+				sizeof(*drm_minors), DRM_MEM_STUB);
+	if(!drm_minors) 
+		goto err_p1;
+	
+	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
+		goto err_p1;
+	
+	drm_class = class_simple_create(THIS_MODULE, "drm");
+	if (IS_ERR(drm_class)) {
+		printk (KERN_ERR "DRM: Error creating drm class.\n");
+		ret = PTR_ERR(drm_class);
+		goto err_p2;
+	}
+
+	drm_proc_root = create_proc_entry("dri", S_IFDIR, NULL);
+	if (!drm_proc_root) {
+		DRM_ERROR("Cannot create /proc/dri\n");
+		ret = -1;
+		goto err_p3;
+	}
+		
+	DRM_INFO( "Initialized %s %d.%d.%d %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE
+		);
+	return 0;
+err_p3:
+	class_simple_destroy(drm_class);
+err_p2:
+	unregister_chrdev(DRM_MAJOR, "drm");
+	drm_free(drm_minors, sizeof(*drm_minors) * drm_cards_limit, DRM_MEM_STUB);
+err_p1:	
+	return ret;
+}
+
+static void __exit drm_core_exit (void)
+{
+	remove_proc_entry("dri", NULL);
+	class_simple_destroy(drm_class);
+
+	unregister_chrdev(DRM_MAJOR, "drm");
+
+	drm_free(drm_minors, sizeof(*drm_minors) *
+				drm_cards_limit, DRM_MEM_STUB);
+}
+
+
+module_init( drm_core_init );
+module_exit( drm_core_exit );
+
+
+/**
+ * Get version information
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_version structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Fills in the version information in \p arg.
+ */
+int drm_version( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_version_t __user *argp = (void __user *)arg;
+	drm_version_t version;
+	int ret;
+
+	if ( copy_from_user( &version, argp, sizeof(version) ) )
+		return -EFAULT;
+
+	/* version is a required function to return the personality module version */
+	if ((ret = dev->driver->version(&version)))
+		return ret;
+		
+	if ( copy_to_user( argp, &version, sizeof(version) ) )
+		return -EFAULT;
+	return 0;
+}
+
+
+
+/** 
+ * Called whenever a process performs an ioctl on /dev/drm.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ *
+ * Looks up the ioctl function in the ::ioctls table, checking for root
+ * previleges if so required, and dispatches to the respective function.
+ */
+int drm_ioctl( struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_ioctl_desc_t *ioctl;
+	drm_ioctl_t *func;
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	int retcode = -EINVAL;
+
+	atomic_inc( &dev->ioctl_count );
+	atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
+	++priv->ioctl_count;
+
+	DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
+		   current->pid, cmd, nr, (long)old_encode_dev(dev->device), 
+		   priv->authenticated );
+	
+	if (nr < DRIVER_IOCTL_COUNT)
+		ioctl = &drm_ioctls[nr];
+	else if ((nr >= DRM_COMMAND_BASE) || (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+	else
+		goto err_i1;
+	
+	func = ioctl->func;
+	/* is there a local override? */
+	if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
+		func = dev->driver->dma_ioctl;
+	
+	if ( !func ) {
+		DRM_DEBUG( "no function\n" );
+		retcode = -EINVAL;
+	} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
+		    ( ioctl->auth_needed && !priv->authenticated ) ) {
+		retcode = -EACCES;
+	} else {
+		retcode = func( inode, filp, cmd, arg );
+	}
+	
+err_i1:
+	atomic_dec( &dev->ioctl_count );
+	if (retcode) DRM_DEBUG( "ret = %x\n", retcode);
+	return retcode;
+}
+EXPORT_SYMBOL(drm_ioctl);
+
diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
--- a/drivers/char/drm/drm_drv.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1061 +0,0 @@
-/**
- * \file drm_drv.h 
- * Generic driver template
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- *
- * To use this template, you must at least define the following (samples
- * given for the MGA driver):
- *
- * \code
- * #define DRIVER_AUTHOR	"VA Linux Systems, Inc."
- *
- * #define DRIVER_NAME		"mga"
- * #define DRIVER_DESC		"Matrox G200/G400"
- * #define DRIVER_DATE		"20001127"
- *
- * #define DRIVER_MAJOR		2
- * #define DRIVER_MINOR		0
- * #define DRIVER_PATCHLEVEL	2
- *
- * #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( mga_ioctls )
- *
- * #define DRM(x)		mga_##x
- * \endcode
- */
-
-/*
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#ifndef DRIVER_IOCTLS
-#define DRIVER_IOCTLS
-#endif
-
-#ifndef MODULE
-/** Use an additional macro to avoid preprocessor troubles */
-#define DRM_OPTIONS_FUNC DRM(options)
-/**
- * Called by the kernel to parse command-line options passed via the
- * boot-loader (e.g., LILO).  It calls the insmod option routine,
- * parse_options().
- */
-static int __init DRM(options)( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
-#undef DRM_OPTIONS_FUNC
-#endif
-
-#define MAX_DEVICES 4
-static drm_device_t	DRM(device)[MAX_DEVICES];
-static int		DRM(numdevs) = 0;
-
-struct file_operations	DRM(fops) = {
-	.owner   = THIS_MODULE,
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
-	.mmap	 = DRM(mmap),
-	.fasync  = DRM(fasync),
-	.poll	 = DRM(poll),
-	.read	 = DRM(read),
-};
-
-/** Ioctl table */
-drm_ioctl_desc_t		  DRM(ioctls)[] = {
-	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { DRM(version),     0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { DRM(getunique),   0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { DRM(getmagic),    0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { DRM(irq_by_busid), 0, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { DRM(getmap),      0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { DRM(getclient),   0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { DRM(getstats),    0, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)]   = { DRM(setversion),  0, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { DRM(setunique),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { DRM(noop),        1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { DRM(noop),        1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { DRM(authmagic),   1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { DRM(addmap),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { DRM(rmmap),       1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { DRM(addctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { DRM(rmctx),       1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { DRM(modctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { DRM(getctx),      1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { DRM(switchctx),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { DRM(newctx),      1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { DRM(resctx),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { DRM(adddraw),     1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { DRM(rmdraw),      1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { DRM(lock),        1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { DRM(unlock),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { DRM(noop),      1, 0 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { DRM(addbufs),     1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { DRM(markbufs),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { DRM(infobufs),    1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { DRM(mapbufs),     1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { DRM(freebufs),    1, 0 },
-	/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
-
-	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { DRM(control),     1, 1 },
-
-#if __OS_HAS_AGP
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { DRM(agp_acquire), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { DRM(agp_release), 1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { DRM(agp_enable),  1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { DRM(agp_info),    1, 0 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { DRM(agp_alloc),   1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { DRM(agp_free),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { DRM(agp_bind),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { DRM(agp_unbind),  1, 1 },
-#endif
-
-	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { DRM(sg_alloc),    1, 1 },
-	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { DRM(sg_free),     1, 1 },
-
-	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)]   = { DRM(wait_vblank), 0, 0 },
-
-	DRIVER_IOCTLS
-};
-
-#define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( DRM(ioctls) )
-
-#ifdef MODULE
-static char *drm_opts = NULL;
-#endif
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_PARM( drm_opts, "s" );
-MODULE_LICENSE("GPL and additional rights");
-
-static int DRM(setup)( drm_device_t *dev )
-{
-	int i;
-	int ret;
-
-	if (dev->fn_tbl.presetup)
-	{
-		ret=dev->fn_tbl.presetup(dev);
-		if (ret!=0) 
-			return ret;
-	}
-
-	atomic_set( &dev->ioctl_count, 0 );
-	atomic_set( &dev->vma_count, 0 );
-	dev->buf_use = 0;
-	atomic_set( &dev->buf_alloc, 0 );
-
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-	{
-		i = DRM(dma_setup)( dev );
-		if ( i < 0 )
-			return i;
-	}
-
-	for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
-		atomic_set( &dev->counts[i], 0 );
-
-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
-		dev->magiclist[i].head = NULL;
-		dev->magiclist[i].tail = NULL;
-	}
-
-	dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
-				  DRM_MEM_MAPS);
-	if(dev->maplist == NULL) return -ENOMEM;
-	memset(dev->maplist, 0, sizeof(*dev->maplist));
-	INIT_LIST_HEAD(&dev->maplist->head);
-
-	dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist),
-				  DRM_MEM_CTXLIST);
-	if(dev->ctxlist == NULL) return -ENOMEM;
-	memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
-	INIT_LIST_HEAD(&dev->ctxlist->head);
-
-	dev->vmalist = NULL;
-	dev->sigdata.lock = dev->lock.hw_lock = NULL;
-	init_waitqueue_head( &dev->lock.lock_queue );
-	dev->queue_count = 0;
-	dev->queue_reserved = 0;
-	dev->queue_slots = 0;
-	dev->queuelist = NULL;
-	dev->irq_enabled = 0;
-	dev->context_flag = 0;
-	dev->interrupt_flag = 0;
-	dev->dma_flag = 0;
-	dev->last_context = 0;
-	dev->last_switch = 0;
-	dev->last_checked = 0;
-	init_waitqueue_head( &dev->context_wait );
-	dev->if_version = 0;
-
-	dev->ctx_start = 0;
-	dev->lck_start = 0;
-
-	dev->buf_rp = dev->buf;
-	dev->buf_wp = dev->buf;
-	dev->buf_end = dev->buf + DRM_BSZ;
-	dev->buf_async = NULL;
-	init_waitqueue_head( &dev->buf_readers );
-	init_waitqueue_head( &dev->buf_writers );
-
-	DRM_DEBUG( "\n" );
-
-	/*
-	 * The kernel's context could be created here, but is now created
-	 * in drm_dma_enqueue.	This is more resource-efficient for
-	 * hardware that does not do DMA, but may mean that
-	 * drm_select_queue fails between the time the interrupt is
-	 * initialized and the time the queues are initialized.
-	 */
-	if (dev->fn_tbl.postsetup)
-		dev->fn_tbl.postsetup(dev);
-
-	return 0;
-}
-
-
-/**
- * Take down the DRM device.
- *
- * \param dev DRM device structure.
- *
- * Frees every resource in \p dev.
- *
- * \sa drm_device and setup().
- */
-static int DRM(takedown)( drm_device_t *dev )
-{
-	drm_magic_entry_t *pt, *next;
-	drm_map_t *map;
-	drm_map_list_t *r_list;
-	struct list_head *list, *list_next;
-	drm_vma_entry_t *vma, *vma_next;
-	int i;
-
-	DRM_DEBUG( "\n" );
-
-	if (dev->fn_tbl.pretakedown)
-	  dev->fn_tbl.pretakedown(dev);
-
-	if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
-
-	down( &dev->struct_sem );
-	del_timer( &dev->timer );
-
-	if ( dev->devname ) {
-		DRM(free)( dev->devname, strlen( dev->devname ) + 1,
-			   DRM_MEM_DRIVER );
-		dev->devname = NULL;
-	}
-
-	if ( dev->unique ) {
-		DRM(free)( dev->unique, strlen( dev->unique ) + 1,
-			   DRM_MEM_DRIVER );
-		dev->unique = NULL;
-		dev->unique_len = 0;
-	}
-				/* Clear pid list */
-	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
-		for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
-			next = pt->next;
-			DRM(free)( pt, sizeof(*pt), DRM_MEM_MAGIC );
-		}
-		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-	}
-
-				/* Clear AGP information */
-	if (drm_core_has_AGP(dev) && dev->agp) {
-		drm_agp_mem_t *entry;
-		drm_agp_mem_t *nexte;
-
-				/* Remove AGP resources, but leave dev->agp
-                                   intact until drv_cleanup is called. */
-		for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
-			nexte = entry->next;
-			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;
-
-		if ( dev->agp->acquired ) DRM(agp_do_release)();
-
-		dev->agp->acquired = 0;
-		dev->agp->enabled  = 0;
-	}
-
-				/* Clear vma list (only built for debugging) */
-	if ( dev->vmalist ) {
-		for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
-			vma_next = vma->next;
-			DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS );
-		}
-		dev->vmalist = NULL;
-	}
-
-	if( dev->maplist ) {
-		list_for_each_safe( list, list_next, &dev->maplist->head ) {
-			r_list = (drm_map_list_t *)list;
-
-			if ( ( map = r_list->map ) ) {
-				switch ( map->type ) {
-				case _DRM_REGISTERS:
-				case _DRM_FRAME_BUFFER:
-					if (drm_core_has_MTRR(dev)) {
-						if ( map->mtrr >= 0 ) {
-							int retcode;
-							retcode = mtrr_del( map->mtrr,
-									    map->offset,
-									    map->size );
-							DRM_DEBUG( "mtrr_del=%d\n", retcode );
-						}
-					}
-					DRM(ioremapfree)( map->handle, map->size, dev );
-					break;
-				case _DRM_SHM:
-					vfree(map->handle);
-					break;
-
-				case _DRM_AGP:
-					/* Do nothing here, because this is all
-					 * handled in the AGP/GART driver.
-					 */
-					break;
-				case _DRM_SCATTER_GATHER:
-					/* Handle it */
-					if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
-						DRM(sg_cleanup)(dev->sg);
-						dev->sg = NULL;
-					}
-					break;
-				}
-				DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-			}
-			list_del( list );
-			DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
- 		}
-		DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
-		dev->maplist = NULL;
- 	}
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
-		for ( i = 0 ; i < dev->queue_count ; i++ ) {
-			if ( dev->queuelist[i] ) {
-				DRM(free)( dev->queuelist[i],
-					  sizeof(*dev->queuelist[0]),
-					  DRM_MEM_QUEUES );
-				dev->queuelist[i] = NULL;
-			}
-		}
-		DRM(free)( dev->queuelist,
-			  dev->queue_slots * sizeof(*dev->queuelist),
-			  DRM_MEM_QUEUES );
-		dev->queuelist = NULL;
-	}
-	dev->queue_count = 0;
-
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-		DRM(dma_takedown)( dev );
-
-	if ( dev->lock.hw_lock ) {
-		dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
-		dev->lock.filp = NULL;
-		wake_up_interruptible( &dev->lock.lock_queue );
-	}
-	up( &dev->struct_sem );
-
-	return 0;
-}
-
-static void DRM(init_fn_table)(struct drm_device *dev)
-{
-	dev->fn_tbl.reclaim_buffers = DRM(core_reclaim_buffers);
-	dev->fn_tbl.get_map_ofs = DRM(core_get_map_ofs);
-	dev->fn_tbl.get_reg_ofs = DRM(core_get_reg_ofs);
-}
-
-#include "drm_pciids.h"
-
-static struct pci_device_id DRM(pciidlist)[] = {
-	DRM(PCI_IDS)
-};
-
-static int DRM(probe)(struct pci_dev *pdev)
-{
-	drm_device_t *dev;
-	int retcode;
-	int i;
-	int is_compat = 0;
-
-	DRM_DEBUG( "\n" );
-
-	for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
-		if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&
-		    (DRM(pciidlist)[i].device == pdev->device)) {
-			is_compat = 1;
-		}
-	}
-	if (is_compat == 0)
-		return -ENODEV;
-
-	if (DRM(numdevs) >= MAX_DEVICES)
-		return -ENODEV;
-
-	if ((retcode=pci_enable_device(pdev)))
-		return retcode;
-
-	dev = &(DRM(device)[DRM(numdevs)]);
-
-	memset( (void *)dev, 0, sizeof(*dev) );
-	dev->count_lock = SPIN_LOCK_UNLOCKED;
-	init_timer( &dev->timer );
-	sema_init( &dev->struct_sem, 1 );
-	sema_init( &dev->ctxlist_sem, 1 );
-
-	if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
-		return -EPERM;
-	dev->device = MKDEV(DRM_MAJOR, dev->minor );
-	dev->name   = DRIVER_NAME;
-
-	dev->pdev   = pdev;
-#ifdef __alpha__
-	dev->hose   = pdev->sysdata;
-	dev->pci_domain = dev->hose->bus->number;
-#else
-	dev->pci_domain = 0;
-#endif
-	dev->pci_bus = pdev->bus->number;
-	dev->pci_slot = PCI_SLOT(pdev->devfn);
-	dev->pci_func = PCI_FUNC(pdev->devfn);
-	dev->irq = pdev->irq;
-
-	/* dev_priv_size can be changed by a driver in driver_register_fns */
-	dev->dev_priv_size = sizeof(u32);
-
-	/* the DRM has 6 basic counters - drivers add theirs in register_fns */
-	dev->counters = 6;
-	dev->types[0]  = _DRM_STAT_LOCK;
-	dev->types[1]  = _DRM_STAT_OPENS;
-	dev->types[2]  = _DRM_STAT_CLOSES;
-	dev->types[3]  = _DRM_STAT_IOCTLS;
-	dev->types[4]  = _DRM_STAT_LOCKS;
-	dev->types[5]  = _DRM_STAT_UNLOCKS;
-
-	DRM(init_fn_table)(dev);
-
-	DRM(driver_register_fns)(dev);
-
-	if (dev->fn_tbl.preinit)
-	  dev->fn_tbl.preinit(dev);
-
-	if (drm_core_has_AGP(dev))
-	{
-		dev->agp = DRM(agp_init)();
-		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
-			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
-			DRM(stub_unregister)(dev->minor);
-			DRM(takedown)( dev );
-			return -EINVAL;
-		}
-		if (drm_core_has_MTRR(dev)) {
-			if (dev->agp)
-				dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
-							       dev->agp->agp_info.aper_size*1024*1024,
-							       MTRR_TYPE_WRCOMB,
-							       1 );
-		}
-	}
-
-	retcode = DRM(ctxbitmap_init)( dev );
-	if( retcode ) {
-		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
-		DRM(stub_unregister)(dev->minor);
-		DRM(takedown)( dev );
-		return retcode;
-	}
-
-	DRM(numdevs)++; /* no errors, mark it reserved */
-	
-	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		DRIVER_NAME,
-		DRIVER_MAJOR,
-		DRIVER_MINOR,
-		DRIVER_PATCHLEVEL,
-		DRIVER_DATE,
-		dev->minor,
-		pci_pretty_name(pdev));
-
-	if (dev->fn_tbl.postinit)
-	  dev->fn_tbl.postinit(dev);
-
-	return 0;
-}
-
-/**
- * Module initialization. Called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported).
- *
- * \return zero on success or a negative number on failure.
- *
- * Initializes an array of drm_device structures, and attempts to
- * initialize all available devices, using consecutive minors, registering the
- * stubs and initializing the AGP device.
- * 
- * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
- * after the initialization for driver customization.
- */
-static int __init drm_init( void )
-{
-	struct pci_dev *pdev = NULL;
-
-	DRM_DEBUG( "\n" );
-
-#ifdef MODULE
-	DRM(parse_options)( drm_opts );
-#endif
-
-	DRM(mem_init)();
-
-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-		DRM(probe)(pdev);
-	}
-	return 0;
-}
-
-/**
- * Called via cleanup_module() at module unload time.
- *
- * Cleans up all DRM device, calling takedown().
- * 
- * \sa drm_init().
- */
-static void __exit drm_cleanup( void )
-{
-	drm_device_t *dev;
-	int i;
-
-	DRM_DEBUG( "\n" );
-
-	for (i = DRM(numdevs) - 1; i >= 0; i--) {
-		dev = &(DRM(device)[i]);
-		if ( DRM(stub_unregister)(dev->minor) ) {
-			DRM_ERROR( "Cannot unload module\n" );
-		} else {
-			DRM_DEBUG("minor %d unregistered\n", dev->minor);
-			if (i == 0) {
-				DRM_INFO( "Module unloaded\n" );
-			}
-		}
-
-		DRM(ctxbitmap_cleanup)( dev );
-
-		if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
-		    dev->agp && dev->agp->agp_mtrr >= 0) {
-			int retval;
-			retval = mtrr_del( dev->agp->agp_mtrr,
-				   dev->agp->agp_info.aper_base,
-				   dev->agp->agp_info.aper_size*1024*1024 );
-			DRM_DEBUG( "mtrr_del=%d\n", retval );
-		}
-
-		DRM(takedown)( dev );
-
-		if (drm_core_has_AGP(dev) && dev->agp ) {
-			DRM(agp_uninit)();
-			DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
-			dev->agp = NULL;
-		}
-
-		if (dev->fn_tbl.postcleanup)
-		  dev->fn_tbl.postcleanup(dev);
-
-	}
-	DRM(numdevs) = 0;
-}
-
-module_init( drm_init );
-module_exit( drm_cleanup );
-
-
-/**
- * Get version information
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_version structure.
- * \return zero on success or negative number on failure.
- *
- * Fills in the version information in \p arg.
- */
-int DRM(version)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_version_t __user *argp = (void __user *)arg;
-	drm_version_t version;
-	int len;
-
-	if ( copy_from_user( &version, argp, sizeof(version) ) )
-		return -EFAULT;
-
-#define DRM_COPY( name, value )						\
-	len = strlen( value );						\
-	if ( len > name##_len ) len = name##_len;			\
-	name##_len = strlen( value );					\
-	if ( len && name ) {						\
-		if ( copy_to_user( name, value, len ) )			\
-			return -EFAULT;					\
-	}
-
-	version.version_major = DRIVER_MAJOR;
-	version.version_minor = DRIVER_MINOR;
-	version.version_patchlevel = DRIVER_PATCHLEVEL;
-
-	DRM_COPY( version.name, DRIVER_NAME );
-	DRM_COPY( version.date, DRIVER_DATE );
-	DRM_COPY( version.desc, DRIVER_DESC );
-
-	if ( copy_to_user( argp, &version, sizeof(version) ) )
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Open file.
- * 
- * \param inode device inode
- * \param filp file pointer.
- * \return zero on success or a negative number on failure.
- *
- * Searches the DRM device with the same minor number, calls open_helper(), and
- * increments the device open count. If the open count was previous at zero,
- * i.e., it's the first that the device is open, then calls setup().
- */
-int DRM(open)( struct inode *inode, struct file *filp )
-{
-	drm_device_t *dev = NULL;
-	int retcode = 0;
-	int i;
-
-	for (i = 0; i < DRM(numdevs); i++) {
-		if (iminor(inode) == DRM(device)[i].minor) {
-			dev = &(DRM(device)[i]);
-			break;
-		}
-	}
-	if (!dev) {
-		return -ENODEV;
-	}
-
-	retcode = DRM(open_helper)( inode, filp, dev );
-	if ( !retcode ) {
-		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
-		spin_lock( &dev->count_lock );
-		if ( !dev->open_count++ ) {
-			spin_unlock( &dev->count_lock );
-			return DRM(setup)( dev );
-		}
-		spin_unlock( &dev->count_lock );
-	}
-
-	return retcode;
-}
-
-/**
- * Release file.
- *
- * \param inode device inode
- * \param filp file pointer.
- * \return zero on success or a negative number on failure.
- *
- * If the hardware lock is held then free it, and take it again for the kernel
- * context since it's necessary to reclaim buffers. Unlink the file private
- * data from its list and free it. Decreases the open count and if it reaches
- * zero calls takedown().
- */
-int DRM(release)( struct inode *inode, struct file *filp )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev;
-	int retcode = 0;
-
-	lock_kernel();
-	dev = priv->dev;
-
-	DRM_DEBUG( "open_count = %d\n", dev->open_count );
-
-	if (dev->fn_tbl.prerelease)
-		dev->fn_tbl.prerelease(dev, filp);
-
-	/* ========================================================
-	 * Begin inline drm_release
-	 */
-
-	DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
-		   current->pid, (long)old_encode_dev(dev->device), dev->open_count );
-
-	if ( priv->lock_count && dev->lock.hw_lock &&
-	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
-	     dev->lock.filp == filp ) {
-		DRM_DEBUG( "File %p released, freeing lock for context %d\n",
-			filp,
-			_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-		
-		if (dev->fn_tbl.release)
-			dev->fn_tbl.release(dev, filp);
-
-		DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-				_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-
-				/* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
-	}
-	else if ( dev->fn_tbl.release && priv->lock_count && dev->lock.hw_lock ) {
-		/* The lock is required to reclaim buffers */
-		DECLARE_WAITQUEUE( entry, current );
-
-		add_wait_queue( &dev->lock.lock_queue, &entry );
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			if ( !dev->lock.hw_lock ) {
-				/* Device has been unregistered */
-				retcode = -EINTR;
-				break;
-			}
-			if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
-					     DRM_KERNEL_CONTEXT ) ) {
-				dev->lock.filp	    = filp;
-				dev->lock.lock_time = jiffies;
-                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
-				break;	/* Got lock */
-			}
-				/* Contention */
-			schedule();
-			if ( signal_pending( current ) ) {
-				retcode = -ERESTARTSYS;
-				break;
-			}
-		}
-		__set_current_state(TASK_RUNNING);
-		remove_wait_queue( &dev->lock.lock_queue, &entry );
-		if( !retcode ) {
-			if (dev->fn_tbl.release)
-				dev->fn_tbl.release(dev, filp);
-			DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-					DRM_KERNEL_CONTEXT );
-		}
-	}
-	
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
-	{
-		dev->fn_tbl.reclaim_buffers(filp);
-	}
-
-	DRM(fasync)( -1, filp, 0 );
-
-	down( &dev->ctxlist_sem );
-	if ( !list_empty( &dev->ctxlist->head ) ) {
-		drm_ctx_list_t *pos, *n;
-
-		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
-			if ( pos->tag == priv &&
-			     pos->handle != DRM_KERNEL_CONTEXT ) {
-				if (dev->fn_tbl.context_dtor)
-					dev->fn_tbl.context_dtor(dev, pos->handle);
-
-				DRM(ctxbitmap_free)( dev, pos->handle );
-
-				list_del( &pos->head );
-				DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
-				--dev->ctx_count;
-			}
-		}
-	}
-	up( &dev->ctxlist_sem );
-
-	down( &dev->struct_sem );
-	if ( priv->remove_auth_on_close == 1 ) {
-		drm_file_t *temp = dev->file_first;
-		while ( temp ) {
-			temp->authenticated = 0;
-			temp = temp->next;
-		}
-	}
-	if ( priv->prev ) {
-		priv->prev->next = priv->next;
-	} else {
-		dev->file_first	 = priv->next;
-	}
-	if ( priv->next ) {
-		priv->next->prev = priv->prev;
-	} else {
-		dev->file_last	 = priv->prev;
-	}
-	up( &dev->struct_sem );
-	
-	if (dev->fn_tbl.free_filp_priv)
-		dev->fn_tbl.free_filp_priv(dev, priv);
-
-	DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES );
-
-	/* ========================================================
-	 * End inline drm_release
-	 */
-
-	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
-	spin_lock( &dev->count_lock );
-	if ( !--dev->open_count ) {
-		if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
-			DRM_ERROR( "Device busy: %d %d\n",
-				   atomic_read( &dev->ioctl_count ),
-				   dev->blocked );
-			spin_unlock( &dev->count_lock );
-			unlock_kernel();
-			return -EBUSY;
-		}
-		spin_unlock( &dev->count_lock );
-		unlock_kernel();
-		return DRM(takedown)( dev );
-	}
-	spin_unlock( &dev->count_lock );
-
-	unlock_kernel();
-
-	return retcode;
-}
-
-/** 
- * Called whenever a process performs an ioctl on /dev/drm.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or negative number on failure.
- *
- * Looks up the ioctl function in the ::ioctls table, checking for root
- * previleges if so required, and dispatches to the respective function.
- */
-int DRM(ioctl)( struct inode *inode, struct file *filp,
-		unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ioctl_desc_t *ioctl;
-	drm_ioctl_t *func;
-	int nr = DRM_IOCTL_NR(cmd);
-	int retcode = 0;
-
-	atomic_inc( &dev->ioctl_count );
-	atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
-	++priv->ioctl_count;
-
-	DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-		   current->pid, cmd, nr, (long)old_encode_dev(dev->device), 
-		   priv->authenticated );
-
-	if ( nr >= DRIVER_IOCTL_COUNT ) {
-		retcode = -EINVAL;
-	} else {
-		ioctl = &DRM(ioctls)[nr];
-		func = ioctl->func;
-
-		if ( !func ) {
-			DRM_DEBUG( "no function\n" );
-			retcode = -EINVAL;
-		} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
-			    ( ioctl->auth_needed && !priv->authenticated ) ) {
-			retcode = -EACCES;
-		} else {
-			retcode = func( inode, filp, cmd, arg );
-		}
-	}
-
-	atomic_dec( &dev->ioctl_count );
-	return retcode;
-}
-
-/** 
- * Lock ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_lock structure.
- * \return zero on success or negative number on failure.
- *
- * Add the current task to the lock wait queue, and attempt to take to lock.
- */
-int DRM(lock)( struct inode *inode, struct file *filp,
-	       unsigned int cmd, unsigned long arg )
-{
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
-        DECLARE_WAITQUEUE( entry, current );
-        drm_lock_t lock;
-        int ret = 0;
-
-	++priv->lock_count;
-
-        if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
-		return -EFAULT;
-
-        if ( lock.context == DRM_KERNEL_CONTEXT ) {
-                DRM_ERROR( "Process %d using kernel context %d\n",
-			   current->pid, lock.context );
-                return -EINVAL;
-        }
-
-        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-		   lock.context, current->pid,
-		   dev->lock.hw_lock->lock, lock.flags );
-
-	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
-		if ( lock.context < 0 )
-			return -EINVAL;
-
-	add_wait_queue( &dev->lock.lock_queue, &entry );
-	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-		if ( !dev->lock.hw_lock ) {
-			/* Device has been unregistered */
-			ret = -EINTR;
-			break;
-		}
-		if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
-				     lock.context ) ) {
-			dev->lock.filp      = filp;
-			dev->lock.lock_time = jiffies;
-			atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
-			break;  /* Got lock */
-		}
-		
-		/* Contention */
-		schedule();
-		if ( signal_pending( current ) ) {
-			ret = -ERESTARTSYS;
-			break;
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue( &dev->lock.lock_queue, &entry );
-
-	sigemptyset( &dev->sigmask );
-	sigaddset( &dev->sigmask, SIGSTOP );
-	sigaddset( &dev->sigmask, SIGTSTP );
-	sigaddset( &dev->sigmask, SIGTTIN );
-	sigaddset( &dev->sigmask, SIGTTOU );
-	dev->sigdata.context = lock.context;
-	dev->sigdata.lock    = dev->lock.hw_lock;
-	block_all_signals( DRM(notifier),
-			   &dev->sigdata, &dev->sigmask );
-	
-	if (dev->fn_tbl.dma_ready && (lock.flags & _DRM_LOCK_READY))
-		dev->fn_tbl.dma_ready(dev);
-	
-	if ( dev->fn_tbl.dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
-		return dev->fn_tbl.dma_quiescent(dev);
-	
-	/* dev->fn_tbl.kernel_context_switch isn't used by any of the x86 
-	 *  drivers but is used by the Sparc driver.
-	 */
-	
-	if (dev->fn_tbl.kernel_context_switch && 
-	    dev->last_context != lock.context) {
-	  dev->fn_tbl.kernel_context_switch(dev, dev->last_context, 
-					    lock.context);
-	}
-        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-
-        return ret;
-}
-
-/** 
- * Unlock ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_lock structure.
- * \return zero on success or negative number on failure.
- *
- * Transfer and free the lock.
- */
-int DRM(unlock)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_lock_t lock;
-
-	if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
-		return -EFAULT;
-
-	if ( lock.context == DRM_KERNEL_CONTEXT ) {
-		DRM_ERROR( "Process %d using kernel context %d\n",
-			   current->pid, lock.context );
-		return -EINVAL;
-	}
-
-	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
-
-	/* kernel_context_switch isn't used by any of the x86 drm
-	 * modules but is required by the Sparc driver.
-	 */
-	if (dev->fn_tbl.kernel_context_switch_unlock)
-		dev->fn_tbl.kernel_context_switch_unlock(dev, &lock);
-	else {
-		DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock, 
-				    DRM_KERNEL_CONTEXT );
-		
-		if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
-				     DRM_KERNEL_CONTEXT ) ) {
-			DRM_ERROR( "\n" );
-		}
-	}
-
-	unblock_all_signals();
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_fops.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,449 @@
+/**
+ * \file drm_fops.h 
+ * File operations for DRM
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Daryll Strauss <daryll@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+#include <linux/poll.h>
+
+static int drm_setup( drm_device_t *dev )
+{
+	int i;
+	int ret;
+
+	if (dev->driver->presetup)
+	{
+		ret=dev->driver->presetup(dev);
+		if (ret!=0) 
+			return ret;
+	}
+
+	atomic_set( &dev->ioctl_count, 0 );
+	atomic_set( &dev->vma_count, 0 );
+	dev->buf_use = 0;
+	atomic_set( &dev->buf_alloc, 0 );
+
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+	{
+		i = drm_dma_setup( dev );
+		if ( i < 0 )
+			return i;
+	}
+
+	for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+		atomic_set( &dev->counts[i], 0 );
+
+	for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+		dev->magiclist[i].head = NULL;
+		dev->magiclist[i].tail = NULL;
+	}
+
+	dev->maplist = drm_alloc(sizeof(*dev->maplist),
+				  DRM_MEM_MAPS);
+	if(dev->maplist == NULL) return -ENOMEM;
+	memset(dev->maplist, 0, sizeof(*dev->maplist));
+	INIT_LIST_HEAD(&dev->maplist->head);
+
+	dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
+				  DRM_MEM_CTXLIST);
+	if(dev->ctxlist == NULL) return -ENOMEM;
+	memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
+	INIT_LIST_HEAD(&dev->ctxlist->head);
+
+	dev->vmalist = NULL;
+	dev->sigdata.lock = dev->lock.hw_lock = NULL;
+	init_waitqueue_head( &dev->lock.lock_queue );
+	dev->queue_count = 0;
+	dev->queue_reserved = 0;
+	dev->queue_slots = 0;
+	dev->queuelist = NULL;
+	dev->irq_enabled = 0;
+	dev->context_flag = 0;
+	dev->interrupt_flag = 0;
+	dev->dma_flag = 0;
+	dev->last_context = 0;
+	dev->last_switch = 0;
+	dev->last_checked = 0;
+	init_waitqueue_head( &dev->context_wait );
+	dev->if_version = 0;
+
+	dev->ctx_start = 0;
+	dev->lck_start = 0;
+
+	dev->buf_rp = dev->buf;
+	dev->buf_wp = dev->buf;
+	dev->buf_end = dev->buf + DRM_BSZ;
+	dev->buf_async = NULL;
+	init_waitqueue_head( &dev->buf_readers );
+	init_waitqueue_head( &dev->buf_writers );
+
+	DRM_DEBUG( "\n" );
+
+	/*
+	 * The kernel's context could be created here, but is now created
+	 * in drm_dma_enqueue.	This is more resource-efficient for
+	 * hardware that does not do DMA, but may mean that
+	 * drm_select_queue fails between the time the interrupt is
+	 * initialized and the time the queues are initialized.
+	 */
+	if (dev->driver->postsetup)
+		dev->driver->postsetup(dev);
+
+	return 0;
+}
+
+/**
+ * Open file.
+ * 
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches the DRM device with the same minor number, calls open_helper(), and
+ * increments the device open count. If the open count was previous at zero,
+ * i.e., it's the first that the device is open, then calls setup().
+ */
+int drm_open( struct inode *inode, struct file *filp )
+{
+	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
+	int retcode = 0;
+
+	if (!((minor >= 0) && (minor < drm_cards_limit)))
+		return -ENODEV;
+		
+	dev = drm_minors[minor].dev;
+	if (!dev)
+		return -ENODEV;
+	
+	retcode = drm_open_helper( inode, filp, dev );
+	if ( !retcode ) {
+		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+		spin_lock( &dev->count_lock );
+		if ( !dev->open_count++ ) {
+			spin_unlock( &dev->count_lock );
+			return drm_setup( dev );
+		}
+		spin_unlock( &dev->count_lock );
+	}
+
+	return retcode;
+}
+EXPORT_SYMBOL(drm_open);
+
+/**
+ * Release file.
+ *
+ * \param inode device inode
+ * \param filp file pointer.
+ * \return zero on success or a negative number on failure.
+ *
+ * If the hardware lock is held then free it, and take it again for the kernel
+ * context since it's necessary to reclaim buffers. Unlink the file private
+ * data from its list and free it. Decreases the open count and if it reaches
+ * zero calls takedown().
+ */
+int drm_release( struct inode *inode, struct file *filp )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev;
+	int retcode = 0;
+
+	lock_kernel();
+	dev = priv->dev;
+
+	DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+	if (dev->driver->prerelease)
+		dev->driver->prerelease(dev, filp);
+
+	/* ========================================================
+	 * Begin inline drm_release
+	 */
+
+	DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
+		   current->pid, (long)old_encode_dev(dev->device), dev->open_count );
+
+	if ( priv->lock_count && dev->lock.hw_lock &&
+	     _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+	     dev->lock.filp == filp ) {
+		DRM_DEBUG( "File %p released, freeing lock for context %d\n",
+			filp,
+			_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+		
+		if (dev->driver->release)
+			dev->driver->release(dev, filp);
+
+		drm_lock_free( dev, &dev->lock.hw_lock->lock,
+				_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+
+				/* FIXME: may require heavy-handed reset of
+                                   hardware at this point, possibly
+                                   processed via a callback to the X
+                                   server. */
+	}
+	else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) {
+		/* The lock is required to reclaim buffers */
+		DECLARE_WAITQUEUE( entry, current );
+
+		add_wait_queue( &dev->lock.lock_queue, &entry );
+		for (;;) {
+			__set_current_state(TASK_INTERRUPTIBLE);
+			if ( !dev->lock.hw_lock ) {
+				/* Device has been unregistered */
+				retcode = -EINTR;
+				break;
+			}
+			if ( drm_lock_take( &dev->lock.hw_lock->lock,
+					     DRM_KERNEL_CONTEXT ) ) {
+				dev->lock.filp	    = filp;
+				dev->lock.lock_time = jiffies;
+                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+				break;	/* Got lock */
+			}
+				/* Contention */
+			schedule();
+			if ( signal_pending( current ) ) {
+				retcode = -ERESTARTSYS;
+				break;
+			}
+		}
+		__set_current_state(TASK_RUNNING);
+		remove_wait_queue( &dev->lock.lock_queue, &entry );
+		if( !retcode ) {
+			if (dev->driver->release)
+				dev->driver->release(dev, filp);
+			drm_lock_free( dev, &dev->lock.hw_lock->lock,
+					DRM_KERNEL_CONTEXT );
+		}
+	}
+	
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+	{
+		dev->driver->reclaim_buffers(filp);
+	}
+
+	drm_fasync( -1, filp, 0 );
+
+	down( &dev->ctxlist_sem );
+	if ( !list_empty( &dev->ctxlist->head ) ) {
+		drm_ctx_list_t *pos, *n;
+
+		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
+			if ( pos->tag == priv &&
+			     pos->handle != DRM_KERNEL_CONTEXT ) {
+				if (dev->driver->context_dtor)
+					dev->driver->context_dtor(dev, pos->handle);
+
+				drm_ctxbitmap_free( dev, pos->handle );
+
+				list_del( &pos->head );
+				drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
+				--dev->ctx_count;
+			}
+		}
+	}
+	up( &dev->ctxlist_sem );
+
+	down( &dev->struct_sem );
+	if ( priv->remove_auth_on_close == 1 ) {
+		drm_file_t *temp = dev->file_first;
+		while ( temp ) {
+			temp->authenticated = 0;
+			temp = temp->next;
+		}
+	}
+	if ( priv->prev ) {
+		priv->prev->next = priv->next;
+	} else {
+		dev->file_first	 = priv->next;
+	}
+	if ( priv->next ) {
+		priv->next->prev = priv->prev;
+	} else {
+		dev->file_last	 = priv->prev;
+	}
+	up( &dev->struct_sem );
+	
+	if (dev->driver->free_filp_priv)
+		dev->driver->free_filp_priv(dev, priv);
+
+	drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
+
+	/* ========================================================
+	 * End inline drm_release
+	 */
+
+	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+	spin_lock( &dev->count_lock );
+	if ( !--dev->open_count ) {
+		if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
+			DRM_ERROR( "Device busy: %d %d\n",
+				   atomic_read( &dev->ioctl_count ),
+				   dev->blocked );
+			spin_unlock( &dev->count_lock );
+			unlock_kernel();
+			return -EBUSY;
+		}
+		spin_unlock( &dev->count_lock );
+		unlock_kernel();
+		return drm_takedown( dev );
+	}
+	spin_unlock( &dev->count_lock );
+
+	unlock_kernel();
+
+	return retcode;
+}
+EXPORT_SYMBOL(drm_release);
+
+/**
+ * Called whenever a process opens /dev/drm. 
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param dev device.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Creates and initializes a drm_file structure for the file private data in \p
+ * filp and add it into the double linked list in \p dev.
+ */
+int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
+{
+	int	     minor = iminor(inode);
+	drm_file_t   *priv;
+	int ret;
+
+	if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
+	if (!drm_cpu_valid())        return -EINVAL;
+
+	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+
+	priv		    = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+	if(!priv) return -ENOMEM;
+
+	memset(priv, 0, sizeof(*priv));
+	filp->private_data  = priv;
+	priv->uid	    = current->euid;
+	priv->pid	    = current->pid;
+	priv->minor	    = minor;
+	priv->dev	    = dev;
+	priv->ioctl_count   = 0;
+	priv->authenticated = capable(CAP_SYS_ADMIN);
+	priv->lock_count    = 0;
+
+	if (dev->driver->open_helper) {
+		ret=dev->driver->open_helper(dev, priv);
+		if (ret < 0)
+			goto out_free;
+	}
+
+	down(&dev->struct_sem);
+	if (!dev->file_last) {
+		priv->next	= NULL;
+		priv->prev	= NULL;
+		dev->file_first = priv;
+		dev->file_last	= priv;
+	} else {
+		priv->next	     = NULL;
+		priv->prev	     = dev->file_last;
+		dev->file_last->next = priv;
+		dev->file_last	     = priv;
+	}
+	up(&dev->struct_sem);
+
+#ifdef __alpha__
+	/*
+	 * Default the hose
+	 */
+	if (!dev->hose) {
+		struct pci_dev *pci_dev;
+		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+		if (pci_dev) {
+			dev->hose = pci_dev->sysdata;
+			pci_dev_put(pci_dev);
+		}
+		if (!dev->hose) {
+			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+			if (b) dev->hose = b->sysdata;
+		}
+	}
+#endif
+
+	return 0;
+out_free:
+	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+	filp->private_data=NULL;
+	return ret;
+}
+
+/** No-op. */
+int drm_flush(struct file *filp)
+{
+	drm_file_t    *priv   = filp->private_data;
+	drm_device_t  *dev    = priv->dev;
+
+	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+		  current->pid, (long)old_encode_dev(dev->device), dev->open_count);
+	return 0;
+}
+EXPORT_SYMBOL(drm_flush);
+
+/** No-op. */
+int drm_fasync(int fd, struct file *filp, int on)
+{
+	drm_file_t    *priv   = filp->private_data;
+	drm_device_t  *dev    = priv->dev;
+	int	      retcode;
+
+	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
+	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+	if (retcode < 0) return retcode;
+	return 0;
+}
+EXPORT_SYMBOL(drm_fasync);
+
+/** No-op. */
+unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	return 0;
+}
+EXPORT_SYMBOL(drm_poll);
+
+
+/** No-op. */
+ssize_t drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
+{
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h
--- a/drivers/char/drm/drm_fops.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,156 +0,0 @@
-/**
- * \file drm_fops.h 
- * File operations for DRM
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Daryll Strauss <daryll@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-#include <linux/poll.h>
-
-
-/**
- * Called whenever a process opens /dev/drm. 
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param dev device.
- * \return zero on success or a negative number on failure.
- * 
- * Creates and initializes a drm_file structure for the file private data in \p
- * filp and add it into the double linked list in \p dev.
- */
-int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
-{
-	int	     minor = iminor(inode);
-	drm_file_t   *priv;
-	int ret;
-
-	if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
-	if (!DRM(cpu_valid)())        return -EINVAL;
-
-	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
-
-	priv		    = DRM(alloc)(sizeof(*priv), DRM_MEM_FILES);
-	if(!priv) return -ENOMEM;
-
-	memset(priv, 0, sizeof(*priv));
-	filp->private_data  = priv;
-	priv->uid	    = current->euid;
-	priv->pid	    = current->pid;
-	priv->minor	    = minor;
-	priv->dev	    = dev;
-	priv->ioctl_count   = 0;
-	priv->authenticated = capable(CAP_SYS_ADMIN);
-	priv->lock_count    = 0;
-
-	if (dev->fn_tbl.open_helper) {
-		ret=dev->fn_tbl.open_helper(dev, priv);
-		if (ret < 0)
-			goto out_free;
-	}
-
-	down(&dev->struct_sem);
-	if (!dev->file_last) {
-		priv->next	= NULL;
-		priv->prev	= NULL;
-		dev->file_first = priv;
-		dev->file_last	= priv;
-	} else {
-		priv->next	     = NULL;
-		priv->prev	     = dev->file_last;
-		dev->file_last->next = priv;
-		dev->file_last	     = priv;
-	}
-	up(&dev->struct_sem);
-
-#ifdef __alpha__
-	/*
-	 * Default the hose
-	 */
-	if (!dev->hose) {
-		struct pci_dev *pci_dev;
-		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
-		if (pci_dev) {
-			dev->hose = pci_dev->sysdata;
-			pci_dev_put(pci_dev);
-		}
-		if (!dev->hose) {
-			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
-			if (b) dev->hose = b->sysdata;
-		}
-	}
-#endif
-
-	return 0;
-out_free:
-	DRM(free)(priv, sizeof(*priv), DRM_MEM_FILES);
-	filp->private_data=NULL;
-	return ret;
-}
-
-/** No-op. */
-int DRM(flush)(struct file *filp)
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-
-	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
-		  current->pid, (long)old_encode_dev(dev->device), dev->open_count);
-	return 0;
-}
-
-/** No-op. */
-int DRM(fasync)(int fd, struct file *filp, int on)
-{
-	drm_file_t    *priv   = filp->private_data;
-	drm_device_t  *dev    = priv->dev;
-	int	      retcode;
-
-	DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
-	retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-	if (retcode < 0) return retcode;
-	return 0;
-}
-
-/** No-op. */
-unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
-{
-	return 0;
-}
-
-
-/** No-op. */
-ssize_t DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off)
-{
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_init.c b/drivers/char/drm/drm_init.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_init.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,52 @@
+/**
+ * \file drm_init.h 
+ * Setup/Cleanup for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+/**
+ * Check whether DRI will run on this CPU.
+ *
+ * \return non-zero if the DRI will run on this CPU, or zero otherwise.
+ */
+int drm_cpu_valid(void)
+{
+#if defined(__i386__)
+	if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+#endif
+#if defined(__sparc__) && !defined(__sparc_v9__)
+	return 0; /* No cmpxchg before v9 sparc. */
+#endif
+	return 1;
+}
diff -Nru a/drivers/char/drm/drm_init.h b/drivers/char/drm/drm_init.h
--- a/drivers/char/drm/drm_init.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,128 +0,0 @@
-/**
- * \file drm_init.h 
- * Setup/Cleanup for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-/** Debug flags.  Set by parse_option(). */
-#if 0
-int DRM(flags) = DRM_FLAG_DEBUG;
-#else
-int DRM(flags) = 0;
-#endif
-
-/**
- * Parse a single option.
- *
- * \param s option string.
- *
- * \sa See parse_options() for details.
- */
-static void DRM(parse_option)(char *s)
-{
-	char *c, *r;
-
-	DRM_DEBUG("\"%s\"\n", s);
-	if (!s || !*s) return;
-	for (c = s; *c && *c != ':'; c++); /* find : or \0 */
-	if (*c) r = c + 1; else r = NULL;  /* remember remainder */
-	*c = '\0';			   /* terminate */
-	if (!strcmp(s, "debug")) {
-		DRM(flags) |= DRM_FLAG_DEBUG;
-		DRM_INFO("Debug messages ON\n");
-		return;
-	}
-	DRM_ERROR("\"%s\" is not a valid option\n", s);
-	return;
-}
-
-/**
- * Parse the insmod "drm_opts=" options, or the command-line
- * options passed to the kernel via LILO.  
- *
- * \param s contains option_list without the 'drm_opts=' part.
- *
- * The grammar of the format is as
- * follows:
- *
- * \code
- * drm		::= 'drm_opts=' option_list
- * option_list	::= option [ ';' option_list ]
- * option	::= 'device:' major
- *		|   'debug'
- *		|   'noctx'
- * major	::= INTEGER
- * \endcode
- *
- * - device=major,minor specifies the device number used for /dev/drm
- *   - if major == 0 then the misc device is used
- *   - if major == 0 and minor == 0 then dynamic misc allocation is used
- * - debug=on specifies that debugging messages will be printk'd
- * - debug=trace specifies that each function call will be logged via printk
- * - debug=off turns off all debugging options
- *
- * \todo Actually only the \e presence of the 'debug' option is currently
- * checked.
- */
-
-void DRM(parse_options)(char *s)
-{
-	char *h, *t, *n;
-
-	DRM_DEBUG("\"%s\"\n", s ?: "");
-	if (!s || !*s) return;
-
-	for (h = t = n = s; h && *h; h = n) {
-		for (; *t && *t != ';'; t++);	       /* find ; or \0 */
-		if (*t) n = t + 1; else n = NULL;      /* remember next */
-		*t = '\0';			       /* terminate */
-		DRM(parse_option)(h);		       /* parse */
-	}
-}
-
-/**
- * Check whether DRI will run on this CPU.
- *
- * \return non-zero if the DRI will run on this CPU, or zero otherwise.
- */
-int DRM(cpu_valid)(void)
-{
-#if defined(__i386__)
-	if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
-#endif
-#if defined(__sparc__) && !defined(__sparc_v9__)
-	return 0; /* No cmpxchg before v9 sparc. */
-#endif
-	return 1;
-}
diff -Nru a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_ioctl.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,355 @@
+/**
+ * \file drm_ioctl.h 
+ * IOCTL processing for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+#include "drm_core.h"
+
+#include "linux/pci.h"
+
+/**
+ * Get the bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_unique structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Copies the bus id from drm_device::unique into user space.
+ */
+int drm_getunique(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_unique_t	 __user *argp = (void __user *)arg;
+	drm_unique_t	 u;
+
+	if (copy_from_user(&u, argp, sizeof(u)))
+		return -EFAULT;
+	if (u.unique_len >= dev->unique_len) {
+		if (copy_to_user(u.unique, dev->unique, dev->unique_len))
+			return -EFAULT;
+	}
+	u.unique_len = dev->unique_len;
+	if (copy_to_user(argp, &u, sizeof(u)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Set the bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_unique structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Copies the bus id from userspace into drm_device::unique, and verifies that
+ * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
+ * in interface version 1.1 and will return EBUSY when setversion has requested
+ * version 1.1 or greater.
+ */
+int drm_setunique(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_unique_t	 u;
+	int		 domain, bus, slot, func, ret;
+
+	if (dev->unique_len || dev->unique) return -EBUSY;
+
+	if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
+		return -EFAULT;
+
+	if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
+
+	dev->unique_len = u.unique_len;
+	dev->unique	= drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
+	if(!dev->unique) return -ENOMEM;
+	if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+		return -EFAULT;
+
+	dev->unique[dev->unique_len] = '\0';
+
+	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
+				  DRM_MEM_DRIVER);
+	if (!dev->devname)
+		return -ENOMEM;
+
+	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+
+	/* Return error if the busid submitted doesn't match the device's actual
+	 * busid.
+	 */
+	ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
+	if (ret != 3)
+		return DRM_ERR(EINVAL);
+	domain = bus >> 8;
+	bus &= 0xff;
+	
+	if ((domain != dev->pci_domain) ||
+	    (bus != dev->pci_bus) ||
+	    (slot != dev->pci_slot) ||
+	    (func != dev->pci_func))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+drm_set_busid(drm_device_t *dev)
+{
+	if (dev->unique != NULL)
+		return EBUSY;
+
+	dev->unique_len = 20;
+	dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
+	if (dev->unique == NULL)
+		return ENOMEM;
+
+	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
+		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+
+	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
+				DRM_MEM_DRIVER);
+	if (dev->devname == NULL)
+		return ENOMEM;
+
+	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+
+	return 0;
+}
+
+
+/**
+ * Get a mapping information.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_map structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches for the mapping with the specified offset and copies its information
+ * into userspace
+ */
+int drm_getmap( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_map_t    __user *argp = (void __user *)arg;
+	drm_map_t    map;
+	drm_map_list_t *r_list = NULL;
+	struct list_head *list;
+	int          idx;
+	int	     i;
+
+	if (copy_from_user(&map, argp, sizeof(map)))
+		return -EFAULT;
+	idx = map.offset;
+
+	down(&dev->struct_sem);
+	if (idx < 0) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	i = 0;
+	list_for_each(list, &dev->maplist->head) {
+		if(i == idx) {
+			r_list = list_entry(list, drm_map_list_t, head);
+			break;
+		}
+		i++;
+	}
+	if(!r_list || !r_list->map) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+
+	map.offset = r_list->map->offset;
+	map.size   = r_list->map->size;
+	map.type   = r_list->map->type;
+	map.flags  = r_list->map->flags;
+	map.handle = r_list->map->handle;
+	map.mtrr   = r_list->map->mtrr;
+	up(&dev->struct_sem);
+
+	if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
+	return 0;
+}
+
+/**
+ * Get client information.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_client structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ *
+ * Searches for the client with the specified index and copies its information
+ * into userspace
+ */
+int drm_getclient( struct inode *inode, struct file *filp,
+		    unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_client_t __user *argp = (void __user *)arg;
+	drm_client_t client;
+	drm_file_t   *pt;
+	int          idx;
+	int          i;
+
+	if (copy_from_user(&client, argp, sizeof(client)))
+		return -EFAULT;
+	idx = client.idx;
+	down(&dev->struct_sem);
+	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
+		;
+
+	if (!pt) {
+		up(&dev->struct_sem);
+		return -EINVAL;
+	}
+	client.auth  = pt->authenticated;
+	client.pid   = pt->pid;
+	client.uid   = pt->uid;
+	client.magic = pt->magic;
+	client.iocs  = pt->ioctl_count;
+	up(&dev->struct_sem);
+
+	if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
+		return -EFAULT;
+	return 0;
+}
+
+/** 
+ * Get statistics information. 
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_stats structure.
+ * 
+ * \return zero on success or a negative number on failure.
+ */
+int drm_getstats( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t   *priv = filp->private_data;
+	drm_device_t *dev  = priv->dev;
+	drm_stats_t  stats;
+	int          i;
+
+	memset(&stats, 0, sizeof(stats));
+	
+	down(&dev->struct_sem);
+
+	for (i = 0; i < dev->counters; i++) {
+		if (dev->types[i] == _DRM_STAT_LOCK)
+			stats.data[i].value
+				= (dev->lock.hw_lock
+				   ? dev->lock.hw_lock->lock : 0);
+		else 
+			stats.data[i].value = atomic_read(&dev->counts[i]);
+		stats.data[i].type  = dev->types[i];
+	}
+	
+	stats.count = dev->counters;
+
+	up(&dev->struct_sem);
+
+	if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
+		return -EFAULT;
+	return 0;
+}
+
+int drm_setversion(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_set_version_t sv;
+	drm_set_version_t retv;
+	int if_version;
+	drm_set_version_t __user *argp = (void __user *)data;
+
+	DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
+
+	retv.drm_di_major = DRM_IF_MAJOR;
+	retv.drm_di_minor = DRM_IF_MINOR;
+	retv.drm_dd_major = DRIVER_MAJOR;
+	retv.drm_dd_minor = DRIVER_MINOR;
+
+	DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
+
+	if (sv.drm_di_major != -1) {
+		if (sv.drm_di_major != DRM_IF_MAJOR ||
+		    sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
+			return EINVAL;
+		if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
+		dev->if_version = DRM_MAX(if_version, dev->if_version);
+		if (sv.drm_di_minor >= 1) {
+			/*
+			 * Version 1.1 includes tying of DRM to specific device
+			 */
+			drm_set_busid(dev);
+		}
+	}
+
+	if (sv.drm_dd_major != -1) {
+		if (sv.drm_dd_major != DRIVER_MAJOR ||
+		    sv.drm_dd_minor < 0 || sv.drm_dd_minor > DRIVER_MINOR)
+			return EINVAL;
+
+		if (dev->driver->set_version)
+			dev->driver->set_version(dev, &sv);
+	}
+	return 0;
+}
+
+/** No-op ioctl. */
+int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
+	       unsigned long arg)
+{
+	DRM_DEBUG("\n");
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_ioctl.h b/drivers/char/drm/drm_ioctl.h
--- a/drivers/char/drm/drm_ioctl.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,349 +0,0 @@
-/**
- * \file drm_ioctl.h 
- * IOCTL processing for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-#include "linux/pci.h"
-
-/**
- * Get the bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_unique structure.
- * \return zero on success or a negative number on failure.
- *
- * Copies the bus id from drm_device::unique into user space.
- */
-int DRM(getunique)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_unique_t	 __user *argp = (void __user *)arg;
-	drm_unique_t	 u;
-
-	if (copy_from_user(&u, argp, sizeof(u)))
-		return -EFAULT;
-	if (u.unique_len >= dev->unique_len) {
-		if (copy_to_user(u.unique, dev->unique, dev->unique_len))
-			return -EFAULT;
-	}
-	u.unique_len = dev->unique_len;
-	if (copy_to_user(argp, &u, sizeof(u)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Set the bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_unique structure.
- * \return zero on success or a negative number on failure.
- *
- * Copies the bus id from userspace into drm_device::unique, and verifies that
- * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
- * in interface version 1.1 and will return EBUSY when setversion has requested
- * version 1.1 or greater.
- */
-int DRM(setunique)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_unique_t	 u;
-	int		 domain, bus, slot, func, ret;
-
-	if (dev->unique_len || dev->unique) return -EBUSY;
-
-	if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
-		return -EFAULT;
-
-	if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
-
-	dev->unique_len = u.unique_len;
-	dev->unique	= DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER);
-	if(!dev->unique) return -ENOMEM;
-	if (copy_from_user(dev->unique, u.unique, dev->unique_len))
-		return -EFAULT;
-
-	dev->unique[dev->unique_len] = '\0';
-
-	dev->devname = DRM(alloc)(strlen(dev->name) + strlen(dev->unique) + 2,
-				  DRM_MEM_DRIVER);
-	if (!dev->devname)
-		return -ENOMEM;
-
-	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
-
-	/* Return error if the busid submitted doesn't match the device's actual
-	 * busid.
-	 */
-	ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
-	if (ret != 3)
-		return DRM_ERR(EINVAL);
-	domain = bus >> 8;
-	bus &= 0xff;
-	
-	if ((domain != dev->pci_domain) ||
-	    (bus != dev->pci_bus) ||
-	    (slot != dev->pci_slot) ||
-	    (func != dev->pci_func))
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
-DRM(set_busid)(drm_device_t *dev)
-{
-	if (dev->unique != NULL)
-		return EBUSY;
-
-	dev->unique_len = 20;
-	dev->unique = DRM(alloc)(dev->unique_len + 1, DRM_MEM_DRIVER);
-	if (dev->unique == NULL)
-		return ENOMEM;
-
-	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
-		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
-
-	dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2,
-				DRM_MEM_DRIVER);
-	if (dev->devname == NULL)
-		return ENOMEM;
-
-	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
-
-	return 0;
-}
-
-
-/**
- * Get a mapping information.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_map structure.
- * 
- * \return zero on success or a negative number on failure.
- *
- * Searches for the mapping with the specified offset and copies its information
- * into userspace
- */
-int DRM(getmap)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_map_t    __user *argp = (void __user *)arg;
-	drm_map_t    map;
-	drm_map_list_t *r_list = NULL;
-	struct list_head *list;
-	int          idx;
-	int	     i;
-
-	if (copy_from_user(&map, argp, sizeof(map)))
-		return -EFAULT;
-	idx = map.offset;
-
-	down(&dev->struct_sem);
-	if (idx < 0) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	i = 0;
-	list_for_each(list, &dev->maplist->head) {
-		if(i == idx) {
-			r_list = list_entry(list, drm_map_list_t, head);
-			break;
-		}
-		i++;
-	}
-	if(!r_list || !r_list->map) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-
-	map.offset = r_list->map->offset;
-	map.size   = r_list->map->size;
-	map.type   = r_list->map->type;
-	map.flags  = r_list->map->flags;
-	map.handle = r_list->map->handle;
-	map.mtrr   = r_list->map->mtrr;
-	up(&dev->struct_sem);
-
-	if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
-	return 0;
-}
-
-/**
- * Get client information.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_client structure.
- * 
- * \return zero on success or a negative number on failure.
- *
- * Searches for the client with the specified index and copies its information
- * into userspace
- */
-int DRM(getclient)( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_client_t __user *argp = (void __user *)arg;
-	drm_client_t client;
-	drm_file_t   *pt;
-	int          idx;
-	int          i;
-
-	if (copy_from_user(&client, argp, sizeof(client)))
-		return -EFAULT;
-	idx = client.idx;
-	down(&dev->struct_sem);
-	for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
-		;
-
-	if (!pt) {
-		up(&dev->struct_sem);
-		return -EINVAL;
-	}
-	client.auth  = pt->authenticated;
-	client.pid   = pt->pid;
-	client.uid   = pt->uid;
-	client.magic = pt->magic;
-	client.iocs  = pt->ioctl_count;
-	up(&dev->struct_sem);
-
-	if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
-		return -EFAULT;
-	return 0;
-}
-
-/** 
- * Get statistics information. 
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_stats structure.
- * 
- * \return zero on success or a negative number on failure.
- */
-int DRM(getstats)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t   *priv = filp->private_data;
-	drm_device_t *dev  = priv->dev;
-	drm_stats_t  stats;
-	int          i;
-
-	memset(&stats, 0, sizeof(stats));
-	
-	down(&dev->struct_sem);
-
-	for (i = 0; i < dev->counters; i++) {
-		if (dev->types[i] == _DRM_STAT_LOCK)
-			stats.data[i].value
-				= (dev->lock.hw_lock
-				   ? dev->lock.hw_lock->lock : 0);
-		else 
-			stats.data[i].value = atomic_read(&dev->counts[i]);
-		stats.data[i].type  = dev->types[i];
-	}
-	
-	stats.count = dev->counters;
-
-	up(&dev->struct_sem);
-
-	if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
-		return -EFAULT;
-	return 0;
-}
-
-#define DRM_IF_MAJOR	1
-#define DRM_IF_MINOR	2
-
-int DRM(setversion)(DRM_IOCTL_ARGS)
-{
-	DRM_DEVICE;
-	drm_set_version_t sv;
-	drm_set_version_t retv;
-	int if_version;
-	drm_set_version_t __user *argp = (void __user *)data;
-
-	DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
-
-	retv.drm_di_major = DRM_IF_MAJOR;
-	retv.drm_di_minor = DRM_IF_MINOR;
-	retv.drm_dd_major = DRIVER_MAJOR;
-	retv.drm_dd_minor = DRIVER_MINOR;
-
-	DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
-
-	if (sv.drm_di_major != -1) {
-		if (sv.drm_di_major != DRM_IF_MAJOR ||
-		    sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
-			return EINVAL;
-		if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
-		dev->if_version = DRM_MAX(if_version, dev->if_version);
-		if (sv.drm_di_minor >= 1) {
-			/*
-			 * Version 1.1 includes tying of DRM to specific device
-			 */
-			DRM(set_busid)(dev);
-		}
-	}
-
-	if (sv.drm_dd_major != -1) {
-		if (sv.drm_dd_major != DRIVER_MAJOR ||
-		    sv.drm_dd_minor < 0 || sv.drm_dd_minor > DRIVER_MINOR)
-			return EINVAL;
-
-		if (dev->fn_tbl.set_version)
-			dev->fn_tbl.set_version(dev, &sv);
-	}
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_irq.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,370 @@
+/**
+ * \file drm_irq.h 
+ * IRQ support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+#include <linux/interrupt.h>	/* For task queue support */
+
+/**
+ * Get interrupt from bus id.
+ * 
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_irq_busid structure.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Finds the PCI device with the specified bus id and gets its IRQ number.
+ * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
+ * to that of the device that this DRM instance attached to.
+ */
+int drm_irq_by_busid(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_irq_busid_t __user *argp = (void __user *)arg;
+	drm_irq_busid_t p;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	if (copy_from_user(&p, argp, sizeof(p)))
+		return -EFAULT;
+
+	if ((p.busnum >> 8) != dev->pci_domain ||
+	    (p.busnum & 0xff) != dev->pci_bus ||
+	    p.devnum != dev->pci_slot ||
+	    p.funcnum != dev->pci_func)
+		return -EINVAL;
+
+	p.irq = dev->irq;
+
+	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
+		  p.busnum, p.devnum, p.funcnum, p.irq);
+	if (copy_to_user(argp, &p, sizeof(p)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ * Install IRQ handler.
+ *
+ * \param dev DRM device.
+ * \param irq IRQ number.
+ *
+ * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
+ * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
+ * before and after the installation.
+ */
+int drm_irq_install( drm_device_t *dev )
+{
+	int ret;
+	unsigned long sh_flags=0;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	if ( dev->irq == 0 )
+		return -EINVAL;
+
+	down( &dev->struct_sem );
+
+	/* Driver must have been initialized */
+	if ( !dev->dev_private ) {
+		up( &dev->struct_sem );
+		return -EINVAL;
+	}
+
+	if ( dev->irq_enabled ) {
+		up( &dev->struct_sem );
+		return -EBUSY;
+	}
+	dev->irq_enabled = 1;
+	up( &dev->struct_sem );
+
+	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+	if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
+		init_waitqueue_head(&dev->vbl_queue);
+		
+		spin_lock_init( &dev->vbl_lock );
+		
+		INIT_LIST_HEAD( &dev->vbl_sigs.head );
+		
+		dev->vbl_pending = 0;
+	}
+
+				/* Before installing handler */
+	dev->driver->irq_preinstall(dev);
+
+				/* Install handler */
+	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
+		sh_flags = SA_SHIRQ;
+	
+	ret = request_irq( dev->irq, dev->driver->irq_handler,
+			   sh_flags, dev->devname, dev );
+	if ( ret < 0 ) {
+		down( &dev->struct_sem );
+		dev->irq_enabled = 0;
+		up( &dev->struct_sem );
+		return ret;
+	}
+
+				/* After installing handler */
+	dev->driver->irq_postinstall(dev);
+
+	return 0;
+}
+
+/**
+ * Uninstall the IRQ handler.
+ *
+ * \param dev DRM device.
+ *
+ * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
+ */
+int drm_irq_uninstall( drm_device_t *dev )
+{
+	int irq_enabled;
+
+	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+		return -EINVAL;
+
+	down( &dev->struct_sem );
+	irq_enabled = dev->irq_enabled;
+	dev->irq_enabled = 0;
+	up( &dev->struct_sem );
+
+	if ( !irq_enabled )
+		return -EINVAL;
+
+	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
+
+	dev->driver->irq_uninstall(dev);
+
+	free_irq( dev->irq, dev );
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_irq_uninstall);
+
+/**
+ * IRQ control ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_control structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Calls irq_install() or irq_uninstall() according to \p arg.
+ */
+int drm_control( struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_control_t ctl;
+	
+	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
+
+	if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
+		return -EFAULT;
+
+	switch ( ctl.func ) {
+	case DRM_INST_HANDLER:
+		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+			return 0;
+		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
+		    ctl.irq != dev->irq)
+			return -EINVAL;
+		return drm_irq_install( dev );
+	case DRM_UNINST_HANDLER:
+		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+			return 0;
+		return drm_irq_uninstall( dev );
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * Wait for VBLANK.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param data user argument, pointing to a drm_wait_vblank structure.
+ * \return zero on success or a negative number on failure.
+ *
+ * Verifies the IRQ is installed. 
+ *
+ * If a signal is requested checks if this task has already scheduled the same signal
+ * for the same vblank sequence number - nothing to be done in
+ * that case. If the number of tasks waiting for the interrupt exceeds 100 the
+ * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
+ * task.
+ *
+ * If a signal is not requested, then calls vblank_wait().
+ */
+int drm_wait_vblank( DRM_IOCTL_ARGS )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_wait_vblank_t __user *argp = (void __user *)data;
+	drm_wait_vblank_t vblwait;
+	struct timeval now;
+	int ret = 0;
+	unsigned int flags;
+
+	if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
+		return -EINVAL;
+
+	if (!dev->irq)
+		return -EINVAL;
+
+	DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
+
+	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
+	case _DRM_VBLANK_RELATIVE:
+		vblwait.request.sequence += atomic_read( &dev->vbl_received );
+		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+	case _DRM_VBLANK_ABSOLUTE:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+	
+	if ( flags & _DRM_VBLANK_SIGNAL ) {
+		unsigned long irqflags;
+		drm_vbl_sig_t *vbl_sig;
+		
+		vblwait.reply.sequence = atomic_read( &dev->vbl_received );
+
+		spin_lock_irqsave( &dev->vbl_lock, irqflags );
+
+		/* Check if this task has already scheduled the same signal
+		 * for the same vblank sequence number; nothing to be done in
+		 * that case
+		 */
+		list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
+			if (vbl_sig->sequence == vblwait.request.sequence
+			    && vbl_sig->info.si_signo == vblwait.request.signal
+			    && vbl_sig->task == current)
+			{
+				spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+				goto done;
+			}
+		}
+
+		if ( dev->vbl_pending >= 100 ) {
+			spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+			return -EBUSY;
+		}
+
+		dev->vbl_pending++;
+
+		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+
+		if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
+			return -ENOMEM;
+		}
+
+		memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
+
+		vbl_sig->sequence = vblwait.request.sequence;
+		vbl_sig->info.si_signo = vblwait.request.signal;
+		vbl_sig->task = current;
+
+		spin_lock_irqsave( &dev->vbl_lock, irqflags );
+
+		list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
+
+		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
+	} else {
+		if (dev->driver->vblank_wait)
+			ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
+
+		do_gettimeofday( &now );
+		vblwait.reply.tval_sec = now.tv_sec;
+		vblwait.reply.tval_usec = now.tv_usec;
+	}
+
+done:
+	DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
+
+	return ret;
+}
+
+/**
+ * Send the VBLANK signals.
+ *
+ * \param dev DRM device.
+ *
+ * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
+ *
+ * If a signal is not requested, then calls vblank_wait().
+ */
+void drm_vbl_send_signals( drm_device_t *dev )
+{
+	struct list_head *list, *tmp;
+	drm_vbl_sig_t *vbl_sig;
+	unsigned int vbl_seq = atomic_read( &dev->vbl_received );
+	unsigned long flags;
+
+	spin_lock_irqsave( &dev->vbl_lock, flags );
+
+	list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
+		vbl_sig = list_entry( list, drm_vbl_sig_t, head );
+		if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
+			vbl_sig->info.si_code = vbl_seq;
+			send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
+
+			list_del( list );
+
+			drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
+
+			dev->vbl_pending--;
+		}
+	}
+
+	spin_unlock_irqrestore( &dev->vbl_lock, flags );
+}
+EXPORT_SYMBOL(drm_vbl_send_signals);
+
+
diff -Nru a/drivers/char/drm/drm_irq.h b/drivers/char/drm/drm_irq.h
--- a/drivers/char/drm/drm_irq.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,368 +0,0 @@
-/**
- * \file drm_irq.h 
- * IRQ support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-#include <linux/interrupt.h>	/* For task queue support */
-
-/**
- * Get interrupt from bus id.
- * 
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_irq_busid structure.
- * \return zero on success or a negative number on failure.
- * 
- * Finds the PCI device with the specified bus id and gets its IRQ number.
- * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
- * to that of the device that this DRM instance attached to.
- */
-int DRM(irq_by_busid)(struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_irq_busid_t __user *argp = (void __user *)arg;
-	drm_irq_busid_t p;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	if (copy_from_user(&p, argp, sizeof(p)))
-		return -EFAULT;
-
-	if ((p.busnum >> 8) != dev->pci_domain ||
-	    (p.busnum & 0xff) != dev->pci_bus ||
-	    p.devnum != dev->pci_slot ||
-	    p.funcnum != dev->pci_func)
-		return -EINVAL;
-
-	p.irq = dev->irq;
-
-	DRM_DEBUG("%d:%d:%d => IRQ %d\n",
-		  p.busnum, p.devnum, p.funcnum, p.irq);
-	if (copy_to_user(argp, &p, sizeof(p)))
-		return -EFAULT;
-	return 0;
-}
-
-/**
- * Install IRQ handler.
- *
- * \param dev DRM device.
- * \param irq IRQ number.
- *
- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
- * \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions
- * before and after the installation.
- */
-int DRM(irq_install)( drm_device_t *dev )
-{
-	int ret;
-	unsigned long sh_flags=0;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	if ( dev->irq == 0 )
-		return -EINVAL;
-
-	down( &dev->struct_sem );
-
-	/* Driver must have been initialized */
-	if ( !dev->dev_private ) {
-		up( &dev->struct_sem );
-		return -EINVAL;
-	}
-
-	if ( dev->irq_enabled ) {
-		up( &dev->struct_sem );
-		return -EBUSY;
-	}
-	dev->irq_enabled = 1;
-	up( &dev->struct_sem );
-
-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
-
-	if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
-		init_waitqueue_head(&dev->vbl_queue);
-		
-		spin_lock_init( &dev->vbl_lock );
-		
-		INIT_LIST_HEAD( &dev->vbl_sigs.head );
-		
-		dev->vbl_pending = 0;
-	}
-
-				/* Before installing handler */
-	dev->fn_tbl.irq_preinstall(dev);
-
-				/* Install handler */
-	if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
-		sh_flags = SA_SHIRQ;
-	
-	ret = request_irq( dev->irq, dev->fn_tbl.irq_handler,
-			   sh_flags, dev->devname, dev );
-	if ( ret < 0 ) {
-		down( &dev->struct_sem );
-		dev->irq_enabled = 0;
-		up( &dev->struct_sem );
-		return ret;
-	}
-
-				/* After installing handler */
-	dev->fn_tbl.irq_postinstall(dev);
-
-	return 0;
-}
-
-/**
- * Uninstall the IRQ handler.
- *
- * \param dev DRM device.
- *
- * Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
- */
-int DRM(irq_uninstall)( drm_device_t *dev )
-{
-	int irq_enabled;
-
-	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-		return -EINVAL;
-
-	down( &dev->struct_sem );
-	irq_enabled = dev->irq_enabled;
-	dev->irq_enabled = 0;
-	up( &dev->struct_sem );
-
-	if ( !irq_enabled )
-		return -EINVAL;
-
-	DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
-
-	dev->fn_tbl.irq_uninstall(dev);
-
-	free_irq( dev->irq, dev );
-
-	return 0;
-}
-
-/**
- * IRQ control ioctl.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_control structure.
- * \return zero on success or a negative number on failure.
- *
- * Calls irq_install() or irq_uninstall() according to \p arg.
- */
-int DRM(control)( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_control_t ctl;
-	
-	/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
-
-	if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
-		return -EFAULT;
-
-	switch ( ctl.func ) {
-	case DRM_INST_HANDLER:
-		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-			return 0;
-		if (dev->if_version < DRM_IF_VERSION(1, 2) &&
-		    ctl.irq != dev->irq)
-			return -EINVAL;
-		return DRM(irq_install)( dev );
-	case DRM_UNINST_HANDLER:
-		if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-			return 0;
-		return DRM(irq_uninstall)( dev );
-	default:
-		return -EINVAL;
-	}
-}
-
-/**
- * Wait for VBLANK.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param data user argument, pointing to a drm_wait_vblank structure.
- * \return zero on success or a negative number on failure.
- *
- * Verifies the IRQ is installed. 
- *
- * If a signal is requested checks if this task has already scheduled the same signal
- * for the same vblank sequence number - nothing to be done in
- * that case. If the number of tasks waiting for the interrupt exceeds 100 the
- * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
- * task.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-int DRM(wait_vblank)( DRM_IOCTL_ARGS )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_wait_vblank_t __user *argp = (void __user *)data;
-	drm_wait_vblank_t vblwait;
-	struct timeval now;
-	int ret = 0;
-	unsigned int flags;
-
-	if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
-		return -EINVAL;
-
-	if (!dev->irq)
-		return -EINVAL;
-
-	DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
-
-	switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
-	case _DRM_VBLANK_RELATIVE:
-		vblwait.request.sequence += atomic_read( &dev->vbl_received );
-		vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
-	case _DRM_VBLANK_ABSOLUTE:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
-	
-	if ( flags & _DRM_VBLANK_SIGNAL ) {
-		unsigned long irqflags;
-		drm_vbl_sig_t *vbl_sig;
-		
-		vblwait.reply.sequence = atomic_read( &dev->vbl_received );
-
-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
-
-		/* Check if this task has already scheduled the same signal
-		 * for the same vblank sequence number; nothing to be done in
-		 * that case
-		 */
-		list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
-			if (vbl_sig->sequence == vblwait.request.sequence
-			    && vbl_sig->info.si_signo == vblwait.request.signal
-			    && vbl_sig->task == current)
-			{
-				spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-				goto done;
-			}
-		}
-
-		if ( dev->vbl_pending >= 100 ) {
-			spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-			return -EBUSY;
-		}
-
-		dev->vbl_pending++;
-
-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-
-		if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) {
-			return -ENOMEM;
-		}
-
-		memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
-
-		vbl_sig->sequence = vblwait.request.sequence;
-		vbl_sig->info.si_signo = vblwait.request.signal;
-		vbl_sig->task = current;
-
-		spin_lock_irqsave( &dev->vbl_lock, irqflags );
-
-		list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
-
-		spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
-	} else {
-		if (dev->fn_tbl.vblank_wait)
-			ret = dev->fn_tbl.vblank_wait( dev, &vblwait.request.sequence );
-
-		do_gettimeofday( &now );
-		vblwait.reply.tval_sec = now.tv_sec;
-		vblwait.reply.tval_usec = now.tv_usec;
-	}
-
-done:
-	DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
-
-	return ret;
-}
-
-/**
- * Send the VBLANK signals.
- *
- * \param dev DRM device.
- *
- * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-void DRM(vbl_send_signals)( drm_device_t *dev )
-{
-	struct list_head *list, *tmp;
-	drm_vbl_sig_t *vbl_sig;
-	unsigned int vbl_seq = atomic_read( &dev->vbl_received );
-	unsigned long flags;
-
-	spin_lock_irqsave( &dev->vbl_lock, flags );
-
-	list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
-		vbl_sig = list_entry( list, drm_vbl_sig_t, head );
-		if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
-			vbl_sig->info.si_code = vbl_seq;
-			send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
-
-			list_del( list );
-
-			DRM_FREE( vbl_sig, sizeof(*vbl_sig) );
-
-			dev->vbl_pending--;
-		}
-	}
-
-	spin_unlock_irqrestore( &dev->vbl_lock, flags );
-}
-
-
diff -Nru a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_lock.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,303 @@
+/**
+ * \file drm_lock.h 
+ * IOCTLs for locking
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+/** 
+ * Lock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Add the current task to the lock wait queue, and attempt to take to lock.
+ */
+int drm_lock( struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg )
+{
+        drm_file_t *priv = filp->private_data;
+        drm_device_t *dev = priv->dev;
+        DECLARE_WAITQUEUE( entry, current );
+        drm_lock_t lock;
+        int ret = 0;
+
+	++priv->lock_count;
+
+        if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+		return -EFAULT;
+
+        if ( lock.context == DRM_KERNEL_CONTEXT ) {
+                DRM_ERROR( "Process %d using kernel context %d\n",
+			   current->pid, lock.context );
+                return -EINVAL;
+        }
+
+        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+		   lock.context, current->pid,
+		   dev->lock.hw_lock->lock, lock.flags );
+
+	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
+		if ( lock.context < 0 )
+			return -EINVAL;
+
+	add_wait_queue( &dev->lock.lock_queue, &entry );
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		if ( !dev->lock.hw_lock ) {
+			/* Device has been unregistered */
+			ret = -EINTR;
+			break;
+		}
+		if ( drm_lock_take( &dev->lock.hw_lock->lock,
+				     lock.context ) ) {
+			dev->lock.filp      = filp;
+			dev->lock.lock_time = jiffies;
+			atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+			break;  /* Got lock */
+		}
+		
+		/* Contention */
+		schedule();
+		if ( signal_pending( current ) ) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue( &dev->lock.lock_queue, &entry );
+
+	sigemptyset( &dev->sigmask );
+	sigaddset( &dev->sigmask, SIGSTOP );
+	sigaddset( &dev->sigmask, SIGTSTP );
+	sigaddset( &dev->sigmask, SIGTTIN );
+	sigaddset( &dev->sigmask, SIGTTOU );
+	dev->sigdata.context = lock.context;
+	dev->sigdata.lock    = dev->lock.hw_lock;
+	block_all_signals( drm_notifier,
+			   &dev->sigdata, &dev->sigmask );
+	
+	if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
+		dev->driver->dma_ready(dev);
+	
+	if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
+		return dev->driver->dma_quiescent(dev);
+	
+	/* dev->driver->kernel_context_switch isn't used by any of the x86 
+	 *  drivers but is used by the Sparc driver.
+	 */
+	
+	if (dev->driver->kernel_context_switch && 
+	    dev->last_context != lock.context) {
+	  dev->driver->kernel_context_switch(dev, dev->last_context, 
+					    lock.context);
+	}
+        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+
+        return ret;
+}
+
+/** 
+ * Unlock ioctl.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_lock structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Transfer and free the lock.
+ */
+int drm_unlock( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_lock_t lock;
+
+	if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
+		return -EFAULT;
+
+	if ( lock.context == DRM_KERNEL_CONTEXT ) {
+		DRM_ERROR( "Process %d using kernel context %d\n",
+			   current->pid, lock.context );
+		return -EINVAL;
+	}
+
+	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+
+	/* kernel_context_switch isn't used by any of the x86 drm
+	 * modules but is required by the Sparc driver.
+	 */
+	if (dev->driver->kernel_context_switch_unlock)
+		dev->driver->kernel_context_switch_unlock(dev, &lock);
+	else {
+		drm_lock_transfer( dev, &dev->lock.hw_lock->lock, 
+				    DRM_KERNEL_CONTEXT );
+		
+		if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
+				     DRM_KERNEL_CONTEXT ) ) {
+			DRM_ERROR( "\n" );
+		}
+	}
+
+	unblock_all_signals();
+	return 0;
+}
+
+/**
+ * Take the heavyweight lock.
+ *
+ * \param lock lock pointer.
+ * \param context locking context.
+ * \return one if the lock is held, or zero otherwise.
+ *
+ * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
+ */
+int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+{
+	unsigned int old, new, prev;
+
+	do {
+		old = *lock;
+		if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+		else			  new = context | _DRM_LOCK_HELD;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	if (_DRM_LOCKING_CONTEXT(old) == context) {
+		if (old & _DRM_LOCK_HELD) {
+			if (context != DRM_KERNEL_CONTEXT) {
+				DRM_ERROR("%d holds heavyweight lock\n",
+					  context);
+			}
+			return 0;
+		}
+	}
+	if (new == (context | _DRM_LOCK_HELD)) {
+				/* Have lock */
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * This takes a lock forcibly and hands it to context.	Should ONLY be used
+ * inside *_unlock to give lock to kernel before calling *_dma_schedule. 
+ * 
+ * \param dev DRM device.
+ * \param lock lock pointer.
+ * \param context locking context.
+ * \return always one.
+ *
+ * Resets the lock file pointer.
+ * Marks the lock as held by the given context, via the \p cmpxchg instruction.
+ */
+int drm_lock_transfer(drm_device_t *dev,
+		       __volatile__ unsigned int *lock, unsigned int context)
+{
+	unsigned int old, new, prev;
+
+	dev->lock.filp = NULL;
+	do {
+		old  = *lock;
+		new  = context | _DRM_LOCK_HELD;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	return 1;
+}
+
+/**
+ * Free lock.
+ * 
+ * \param dev DRM device.
+ * \param lock lock.
+ * \param context context.
+ * 
+ * Resets the lock file pointer.
+ * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
+ * waiting on the lock queue.
+ */
+int drm_lock_free(drm_device_t *dev,
+		   __volatile__ unsigned int *lock, unsigned int context)
+{
+	unsigned int old, new, prev;
+
+	dev->lock.filp = NULL;
+	do {
+		old  = *lock;
+		new  = 0;
+		prev = cmpxchg(lock, old, new);
+	} while (prev != old);
+	if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+		DRM_ERROR("%d freed heavyweight lock held by %d\n",
+			  context,
+			  _DRM_LOCKING_CONTEXT(old));
+		return 1;
+	}
+	wake_up_interruptible(&dev->lock.lock_queue);
+	return 0;
+}
+
+/**
+ * If we get here, it means that the process has called DRM_IOCTL_LOCK
+ * without calling DRM_IOCTL_UNLOCK.
+ *
+ * If the lock is not held, then let the signal proceed as usual.  If the lock
+ * is held, then set the contended flag and keep the signal blocked.
+ *
+ * \param priv pointer to a drm_sigdata structure.
+ * \return one if the signal should be delivered normally, or zero if the
+ * signal should be blocked.
+ */
+int drm_notifier(void *priv)
+{
+	drm_sigdata_t *s = (drm_sigdata_t *)priv;
+	unsigned int  old, new, prev;
+
+
+				/* Allow signal delivery if lock isn't held */
+	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
+	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
+
+				/* Otherwise, set flag to force call to
+                                   drmUnlock */
+	do {
+		old  = s->lock->lock;
+		new  = old | _DRM_LOCK_CONT;
+		prev = cmpxchg(&s->lock->lock, old, new);
+	} while (prev != old);
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_lock.h b/drivers/char/drm/drm_lock.h
--- a/drivers/char/drm/drm_lock.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,168 +0,0 @@
-/**
- * \file drm_lock.h 
- * IOCTLs for locking
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-/** No-op ioctl. */
-int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd,
-	       unsigned long arg)
-{
-	DRM_DEBUG("\n");
-	return 0;
-}
-
-/**
- * Take the heavyweight lock.
- *
- * \param lock lock pointer.
- * \param context locking context.
- * \return one if the lock is held, or zero otherwise.
- *
- * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
- */
-int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
-{
-	unsigned int old, new, prev;
-
-	do {
-		old = *lock;
-		if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
-		else			  new = context | _DRM_LOCK_HELD;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	if (_DRM_LOCKING_CONTEXT(old) == context) {
-		if (old & _DRM_LOCK_HELD) {
-			if (context != DRM_KERNEL_CONTEXT) {
-				DRM_ERROR("%d holds heavyweight lock\n",
-					  context);
-			}
-			return 0;
-		}
-	}
-	if (new == (context | _DRM_LOCK_HELD)) {
-				/* Have lock */
-		return 1;
-	}
-	return 0;
-}
-
-/**
- * This takes a lock forcibly and hands it to context.	Should ONLY be used
- * inside *_unlock to give lock to kernel before calling *_dma_schedule. 
- * 
- * \param dev DRM device.
- * \param lock lock pointer.
- * \param context locking context.
- * \return always one.
- *
- * Resets the lock file pointer.
- * Marks the lock as held by the given context, via the \p cmpxchg instruction.
- */
-int DRM(lock_transfer)(drm_device_t *dev,
-		       __volatile__ unsigned int *lock, unsigned int context)
-{
-	unsigned int old, new, prev;
-
-	dev->lock.filp = NULL;
-	do {
-		old  = *lock;
-		new  = context | _DRM_LOCK_HELD;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	return 1;
-}
-
-/**
- * Free lock.
- * 
- * \param dev DRM device.
- * \param lock lock.
- * \param context context.
- * 
- * Resets the lock file pointer.
- * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
- * waiting on the lock queue.
- */
-int DRM(lock_free)(drm_device_t *dev,
-		   __volatile__ unsigned int *lock, unsigned int context)
-{
-	unsigned int old, new, prev;
-
-	dev->lock.filp = NULL;
-	do {
-		old  = *lock;
-		new  = 0;
-		prev = cmpxchg(lock, old, new);
-	} while (prev != old);
-	if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
-		DRM_ERROR("%d freed heavyweight lock held by %d\n",
-			  context,
-			  _DRM_LOCKING_CONTEXT(old));
-		return 1;
-	}
-	wake_up_interruptible(&dev->lock.lock_queue);
-	return 0;
-}
-
-/**
- * If we get here, it means that the process has called DRM_IOCTL_LOCK
- * without calling DRM_IOCTL_UNLOCK.
- *
- * If the lock is not held, then let the signal proceed as usual.  If the lock
- * is held, then set the contended flag and keep the signal blocked.
- *
- * \param priv pointer to a drm_sigdata structure.
- * \return one if the signal should be delivered normally, or zero if the
- * signal should be blocked.
- */
-int DRM(notifier)(void *priv)
-{
-	drm_sigdata_t *s = (drm_sigdata_t *)priv;
-	unsigned int  old, new, prev;
-
-
-				/* Allow signal delivery if lock isn't held */
-	if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
-	    || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
-
-				/* Otherwise, set flag to force call to
-                                   drmUnlock */
-	do {
-		old  = s->lock->lock;
-		new  = old | _DRM_LOCK_CONT;
-		prev = cmpxchg(&s->lock->lock, old, new);
-	} while (prev != old);
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_memory.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,181 @@
+/** 
+ * \file drm_memory.h 
+ * Memory management wrappers for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/* 
+ * Created: Thu Feb  4 14:00:34 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include <linux/config.h>
+#include <linux/highmem.h>
+#include "drmP.h"
+
+#ifdef DEBUG_MEMORY
+#include "drm_memory_debug.h"
+#else
+
+/** No-op. */
+void drm_mem_init(void)
+{
+}
+
+/**
+ * Called when "/proc/dri/%dev%/mem" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param len requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ *
+ * No-op. 
+ */
+int drm_mem_info(char *buf, char **start, off_t offset,
+		  int len, int *eof, void *data)
+{
+	return 0;
+}
+
+/** Wrapper around kmalloc() */
+void *drm_calloc(size_t nmemb, size_t size, int area)
+{
+	void *addr;
+
+	addr = kmalloc(size * nmemb, GFP_KERNEL);
+	if (addr != NULL)
+		memset((void *)addr, 0, size * nmemb);
+
+	return addr;
+}
+EXPORT_SYMBOL(drm_calloc);
+
+/** Wrapper around kmalloc() and kfree() */
+void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
+{
+	void *pt;
+
+	if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
+	if (oldpt && oldsize) {
+		memcpy(pt, oldpt, oldsize);
+		kfree(oldpt);
+	}
+	return pt;
+}
+
+/**
+ * Allocate pages.
+ *
+ * \param order size order.
+ * \param area memory area. (Not used.)
+ * \return page address on success, or zero on failure.
+ *
+ * Allocate and reserve free pages.
+ */
+unsigned long drm_alloc_pages(int order, int area)
+{
+	unsigned long address;
+	unsigned long bytes	  = PAGE_SIZE << order;
+	unsigned long addr;
+	unsigned int  sz;
+
+	address = __get_free_pages(GFP_KERNEL, order);
+	if (!address) 
+		return 0;
+
+				/* Zero */
+	memset((void *)address, 0, bytes);
+
+				/* Reserve */
+	for (addr = address, sz = bytes;
+	     sz > 0;
+	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+		SetPageReserved(virt_to_page(addr));
+	}
+
+	return address;
+}
+
+/**
+ * Free pages.
+ * 
+ * \param address address of the pages to free.
+ * \param order size order.
+ * \param area memory area. (Not used.)
+ *
+ * Unreserve and free pages allocated by alloc_pages().
+ */
+void drm_free_pages(unsigned long address, int order, int area)
+{
+	unsigned long bytes = PAGE_SIZE << order;
+	unsigned long addr;
+	unsigned int  sz;
+
+	if (!address) 
+		return;
+
+	/* Unreserve */
+	for (addr = address, sz = bytes;
+	     sz > 0;
+	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+	}
+
+	free_pages(address, order);
+}
+
+
+#if __OS_HAS_AGP
+/** Wrapper around agp_allocate_memory() */
+DRM_AGP_MEM *drm_alloc_agp(int pages, u32 type)
+{
+	return drm_agp_allocate_memory(pages, type);
+}
+
+/** Wrapper around agp_free_memory() */
+int drm_free_agp(DRM_AGP_MEM *handle, int pages)
+{
+	return drm_agp_free_memory(handle) ? 0 : -EINVAL;
+}
+
+/** Wrapper around agp_bind_memory() */
+int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
+{
+	return drm_agp_bind_memory(handle, start);
+}
+
+/** Wrapper around agp_unbind_memory() */
+int drm_unbind_agp(DRM_AGP_MEM *handle)
+{
+	return drm_agp_unbind_memory(handle);
+}
+#endif /* agp */
+#endif /* debug_memory */
diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
--- a/drivers/char/drm/drm_memory.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/drm_memory.h	2004-11-09 00:25:55 -08:00
@@ -39,10 +39,8 @@
 
 /**
  * Cut down version of drm_memory_debug.h, which used to be called
- * drm_memory.h.  If you want the debug functionality, change 0 to 1
- * below.
+ * drm_memory.h.  
  */
-#define DEBUG_MEMORY 0
 
 #if __OS_HAS_AGP
 
@@ -197,173 +195,3 @@
 }
 
 
-#if DEBUG_MEMORY
-#include "drm_memory_debug.h"
-#else
-
-/** No-op. */
-void DRM(mem_init)(void)
-{
-}
-
-/**
- * Called when "/proc/dri/%dev%/mem" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param len requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * No-op. 
- */
-int DRM(mem_info)(char *buf, char **start, off_t offset,
-		  int len, int *eof, void *data)
-{
-	return 0;
-}
-
-/** Wrapper around kmalloc() */
-void *DRM(alloc)(size_t size, int area)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-/** Wrapper around kmalloc() */
-void *DRM(calloc)(size_t size, size_t nmemb, int area)
-{
-	void *addr;
-
-	addr = kmalloc(size * nmemb, GFP_KERNEL);
-	if (addr != NULL)
-		memset((void *)addr, 0, size * nmemb);
-
-	return addr;
-}
-
-/** Wrapper around kmalloc() and kfree() */
-void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
-{
-	void *pt;
-
-	if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
-	if (oldpt && oldsize) {
-		memcpy(pt, oldpt, oldsize);
-		kfree(oldpt);
-	}
-	return pt;
-}
-
-/** Wrapper around kfree() */
-void DRM(free)(void *pt, size_t size, int area)
-{
-	kfree(pt);
-}
-
-/**
- * Allocate pages.
- *
- * \param order size order.
- * \param area memory area. (Not used.)
- * \return page address on success, or zero on failure.
- *
- * Allocate and reserve free pages.
- */
-unsigned long DRM(alloc_pages)(int order, int area)
-{
-	unsigned long address;
-	unsigned long bytes	  = PAGE_SIZE << order;
-	unsigned long addr;
-	unsigned int  sz;
-
-	address = __get_free_pages(GFP_KERNEL, order);
-	if (!address) 
-		return 0;
-
-				/* Zero */
-	memset((void *)address, 0, bytes);
-
-				/* Reserve */
-	for (addr = address, sz = bytes;
-	     sz > 0;
-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-		SetPageReserved(virt_to_page(addr));
-	}
-
-	return address;
-}
-
-/**
- * Free pages.
- * 
- * \param address address of the pages to free.
- * \param order size order.
- * \param area memory area. (Not used.)
- *
- * Unreserve and free pages allocated by alloc_pages().
- */
-void DRM(free_pages)(unsigned long address, int order, int area)
-{
-	unsigned long bytes = PAGE_SIZE << order;
-	unsigned long addr;
-	unsigned int  sz;
-
-	if (!address) 
-		return;
-
-	/* Unreserve */
-	for (addr = address, sz = bytes;
-	     sz > 0;
-	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-	}
-
-	free_pages(address, order);
-}
-
-/** Wrapper around drm_ioremap() */
-void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
-	return drm_ioremap(offset, size, dev);
-}
-
-/** Wrapper around drm_ioremap_nocache() */
-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
-{
-	return drm_ioremap_nocache(offset, size, dev);
-}
-
-/** Wrapper around drm_iounmap() */
-void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
-{
-	drm_ioremapfree(pt, size, dev);
-}
-
-#if __OS_HAS_AGP
-/** Wrapper around agp_allocate_memory() */
-DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
-{
-	return DRM(agp_allocate_memory)(pages, type);
-}
-
-/** Wrapper around agp_free_memory() */
-int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
-{
-	return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
-}
-
-/** Wrapper around agp_bind_memory() */
-int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
-{
-	return DRM(agp_bind_memory)(handle, start);
-}
-
-/** Wrapper around agp_unbind_memory() */
-int DRM(unbind_agp)(DRM_AGP_MEM *handle)
-{
-	return DRM(agp_unbind_memory)(handle);
-}
-#endif /* agp */
-#endif /* debug_memory */
diff -Nru a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
--- a/drivers/char/drm/drm_memory_debug.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/drm_memory_debug.h	2004-11-09 00:25:55 -08:00
@@ -167,7 +167,7 @@
 	return pt;
 }
 
-void *DRM(calloc)(size_t size, size_t nmemb, int area)
+void *DRM(calloc)(size_t nmemb, size_t size, int area)
 {
 	void *addr;
 
diff -Nru a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
--- a/drivers/char/drm/drm_os_linux.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/drm_os_linux.h	2004-11-09 00:25:55 -08:00
@@ -100,11 +100,6 @@
 	__put_user(val, uaddr)
 
 
-/** 'malloc' without the overhead of DRM(alloc)() */
-#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
-/** 'free' without the overhead of DRM(free)() */
-#define DRM_FREE(x,size) kfree(x)
-
 #define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
 
 /** 
diff -Nru a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_proc.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,539 @@
+/**
+ * \file drm_proc.h 
+ * /proc support for DRM
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ *
+ * \par Acknowledgements:
+ *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
+ *    the problem with the proc files not outputting all their information.
+ */
+
+/*
+ * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+static int	   drm_name_info(char *buf, char **start, off_t offset,
+				  int request, int *eof, void *data);
+static int	   drm_vm_info(char *buf, char **start, off_t offset,
+				int request, int *eof, void *data);
+static int	   drm_clients_info(char *buf, char **start, off_t offset,
+				     int request, int *eof, void *data);
+static int	   drm_queues_info(char *buf, char **start, off_t offset,
+				    int request, int *eof, void *data);
+static int	   drm_bufs_info(char *buf, char **start, off_t offset,
+				  int request, int *eof, void *data);
+#if DRM_DEBUG_CODE
+static int	   drm_vma_info(char *buf, char **start, off_t offset,
+				 int request, int *eof, void *data);
+#endif
+
+/**
+ * Proc file list.
+ */
+struct drm_proc_list {
+	const char *name;	/**< file name */
+	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
+} drm_proc_list[] = {
+	{ "name",    drm_name_info    },
+	{ "mem",     drm_mem_info     },
+	{ "vm",	     drm_vm_info      },
+	{ "clients", drm_clients_info },
+	{ "queues",  drm_queues_info  },
+	{ "bufs",    drm_bufs_info    },
+#if DRM_DEBUG_CODE
+	{ "vma",     drm_vma_info     },
+#endif
+};
+#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+
+/**
+ * Initialize the DRI proc filesystem for a device.
+ *
+ * \param dev DRM device.
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root resulting DRI device proc dir entry.
+ * \return root entry pointer on success, or NULL on failure.
+ * 
+ * Create the DRI proc root entry "/proc/dri", the device proc root entry
+ * "/proc/dri/%minor%/", and each entry in proc_list as
+ * "/proc/dri/%minor%/%name%".
+ */
+int drm_proc_init(drm_device_t *dev, int minor,
+		    struct proc_dir_entry *root,
+		    struct proc_dir_entry **dev_root)
+{
+	struct proc_dir_entry *ent;
+	int		      i, j;
+	char                  name[64];
+
+	sprintf(name, "%d", minor);
+	*dev_root = create_proc_entry(name, S_IFDIR, root);
+	if (!*dev_root) {
+		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
+		return -1;
+	}
+
+	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+		ent = create_proc_entry(drm_proc_list[i].name,
+					S_IFREG|S_IRUGO, *dev_root);
+		if (!ent) {
+			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
+				  name, drm_proc_list[i].name);
+			for (j = 0; j < i; j++)
+				remove_proc_entry(drm_proc_list[i].name,
+						  *dev_root);
+			remove_proc_entry(name, root);
+			return -1;
+		}
+		ent->read_proc = drm_proc_list[i].f;
+		ent->data      = dev;
+	}
+
+	return 0;
+}
+
+
+/**
+ * Cleanup the proc filesystem resources.
+ *
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root DRI device proc dir entry.
+ * \return always zero.
+ *
+ * Remove all proc entries created by proc_init().
+ */
+int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
+		      struct proc_dir_entry *dev_root)
+{
+	int  i;
+	char name[64];
+
+	if (!root || !dev_root) return 0;
+
+	for (i = 0; i < DRM_PROC_ENTRIES; i++)
+		remove_proc_entry(drm_proc_list[i].name, dev_root);
+	sprintf(name, "%d", minor);
+	remove_proc_entry(name, root);
+
+	return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../name" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ * 
+ * Prints the device name together with the bus id if available.
+ */
+static int drm_name_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	if (dev->unique) {
+		DRM_PROC_PRINT("%s 0x%lx %s\n",
+			       dev->driver->pci_driver.name, (long)old_encode_dev(dev->device), dev->unique);
+	} else {
+		DRM_PROC_PRINT("%s 0x%lx\n", dev->driver->pci_driver.name, (long)old_encode_dev(dev->device));
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Called when "/proc/dri/.../vm" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ * 
+ * Prints information about all mappings in drm_device::maplist.
+ */
+static int drm__vm_info(char *buf, char **start, off_t offset, int request,
+			 int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	drm_map_t    *map;
+	drm_map_list_t *r_list;
+	struct list_head *list;
+
+				/* Hardcoded from _DRM_FRAME_BUFFER,
+                                   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+                                   _DRM_SCATTER_GATHER. */
+	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+	const char   *type;
+	int	     i;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
+		       "address mtrr\n\n");
+	i = 0;
+	if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if(!map) continue;
+		if (map->type < 0 || map->type > 4) type = "??";
+		else				    type = types[map->type];
+		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
+			       i,
+			       map->offset,
+			       map->size,
+			       type,
+			       map->flags,
+			       (unsigned long)map->handle);
+		if (map->mtrr < 0) {
+			DRM_PROC_PRINT("none\n");
+		} else {
+			DRM_PROC_PRINT("%4d\n", map->mtrr);
+		}
+		i++;
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_vm_info(char *buf, char **start, off_t offset, int request,
+			int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__vm_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../queues" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__queues_info(char *buf, char **start, off_t offset,
+			     int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	int	     i;
+	drm_queue_t  *q;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("  ctx/flags   use   fin"
+		       "   blk/rw/rwf  wait    flushed	   queued"
+		       "      locks\n\n");
+	for (i = 0; i < dev->queue_count; i++) {
+		q = dev->queuelist[i];
+		atomic_inc(&q->use_count);
+		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
+				   "%5d/0x%03x %5d %5d"
+				   " %5d/%c%c/%c%c%c %5Zd\n",
+				   i,
+				   q->flags,
+				   atomic_read(&q->use_count),
+				   atomic_read(&q->finalization),
+				   atomic_read(&q->block_count),
+				   atomic_read(&q->block_read) ? 'r' : '-',
+				   atomic_read(&q->block_write) ? 'w' : '-',
+				   waitqueue_active(&q->read_queue) ? 'r':'-',
+				   waitqueue_active(&q->write_queue) ? 'w':'-',
+				   waitqueue_active(&q->flush_queue) ? 'f':'-',
+				   DRM_BUFCOUNT(&q->waitlist));
+		atomic_dec(&q->use_count);
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_queues_info(char *buf, char **start, off_t offset, int request,
+			    int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__queues_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../bufs" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
+			   int *eof, void *data)
+{
+	drm_device_t	 *dev = (drm_device_t *)data;
+	int              len  = 0;
+	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+
+	if (!dma || offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
+	for (i = 0; i <= DRM_MAX_ORDER; i++) {
+		if (dma->bufs[i].buf_count)
+			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
+				       i,
+				       dma->bufs[i].buf_size,
+				       dma->bufs[i].buf_count,
+				       atomic_read(&dma->bufs[i]
+						   .freelist.count),
+				       dma->bufs[i].seg_count,
+				       dma->bufs[i].seg_count
+				       *(1 << dma->bufs[i].page_order),
+				       (dma->bufs[i].seg_count
+					* (1 << dma->bufs[i].page_order))
+				       * PAGE_SIZE / 1024);
+	}
+	DRM_PROC_PRINT("\n");
+	for (i = 0; i < dma->buf_count; i++) {
+		if (i && !(i%32)) DRM_PROC_PRINT("\n");
+		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+	}
+	DRM_PROC_PRINT("\n");
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__bufs_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+/**
+ * Called when "/proc/dri/.../clients" is read.
+ * 
+ * \param buf output buffer.
+ * \param start start of output data.
+ * \param offset requested start offset.
+ * \param request requested number of bytes.
+ * \param eof whether there is no more data to return.
+ * \param data private data.
+ * \return number of written bytes.
+ */
+static int drm__clients_info(char *buf, char **start, off_t offset,
+			      int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int          len  = 0;
+	drm_file_t   *priv;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
+	for (priv = dev->file_first; priv; priv = priv->next) {
+		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
+			       priv->authenticated ? 'y' : 'n',
+			       priv->minor,
+			       priv->pid,
+			       priv->uid,
+			       priv->magic,
+			       priv->ioctl_count);
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+/**
+ * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
+ */
+static int drm_clients_info(char *buf, char **start, off_t offset,
+			     int request, int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__clients_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+
+#if DRM_DEBUG_CODE
+
+static int drm__vma_info(char *buf, char **start, off_t offset, int request,
+			  int *eof, void *data)
+{
+	drm_device_t	      *dev = (drm_device_t *)data;
+	int                   len  = 0;
+	drm_vma_entry_t	      *pt;
+	struct vm_area_struct *vma;
+#if defined(__i386__)
+	unsigned int	      pgprot;
+#endif
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+	*start = &buf[offset];
+	*eof   = 0;
+
+	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+		       atomic_read(&dev->vma_count),
+		       high_memory, virt_to_phys(high_memory));
+	for (pt = dev->vmalist; pt; pt = pt->next) {
+		if (!(vma = pt->vma)) continue;
+		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+			       pt->pid,
+			       vma->vm_start,
+			       vma->vm_end,
+			       vma->vm_flags & VM_READ	   ? 'r' : '-',
+			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
+			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
+			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
+			       vma->vm_flags & VM_IO	   ? 'i' : '-',
+			       VM_OFFSET(vma));
+
+#if defined(__i386__)
+		pgprot = pgprot_val(vma->vm_page_prot);
+		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
+			       pgprot & _PAGE_RW       ? 'w' : 'r',
+			       pgprot & _PAGE_USER     ? 'u' : 's',
+			       pgprot & _PAGE_PWT      ? 't' : 'b',
+			       pgprot & _PAGE_PCD      ? 'u' : 'c',
+			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
+			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
+			       pgprot & _PAGE_PSE      ? 'm' : 'k',
+			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
+#endif
+		DRM_PROC_PRINT("\n");
+	}
+
+	if (len > request + offset) return request;
+	*eof = 1;
+	return len - offset;
+}
+
+static int drm_vma_info(char *buf, char **start, off_t offset, int request,
+			 int *eof, void *data)
+{
+	drm_device_t *dev = (drm_device_t *)data;
+	int	     ret;
+
+	down(&dev->struct_sem);
+	ret = drm__vma_info(buf, start, offset, request, eof, data);
+	up(&dev->struct_sem);
+	return ret;
+}
+#endif
+
+
diff -Nru a/drivers/char/drm/drm_proc.h b/drivers/char/drm/drm_proc.h
--- a/drivers/char/drm/drm_proc.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,547 +0,0 @@
-/**
- * \file drm_proc.h 
- * /proc support for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- *
- * \par Acknowledgements:
- *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
- *    the problem with the proc files not outputting all their information.
- */
-
-/*
- * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-static int	   DRM(name_info)(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data);
-static int	   DRM(vm_info)(char *buf, char **start, off_t offset,
-				int request, int *eof, void *data);
-static int	   DRM(clients_info)(char *buf, char **start, off_t offset,
-				     int request, int *eof, void *data);
-static int	   DRM(queues_info)(char *buf, char **start, off_t offset,
-				    int request, int *eof, void *data);
-static int	   DRM(bufs_info)(char *buf, char **start, off_t offset,
-				  int request, int *eof, void *data);
-#if DRM_DEBUG_CODE
-static int	   DRM(vma_info)(char *buf, char **start, off_t offset,
-				 int request, int *eof, void *data);
-#endif
-
-/**
- * Proc file list.
- */
-struct drm_proc_list {
-	const char *name;	/**< file name */
-	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
-} DRM(proc_list)[] = {
-	{ "name",    DRM(name_info)    },
-	{ "mem",     DRM(mem_info)     },
-	{ "vm",	     DRM(vm_info)      },
-	{ "clients", DRM(clients_info) },
-	{ "queues",  DRM(queues_info)  },
-	{ "bufs",    DRM(bufs_info)    },
-#if DRM_DEBUG_CODE
-	{ "vma",     DRM(vma_info)     },
-#endif
-};
-#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
-
-/**
- * Initialize the DRI proc filesystem for a device.
- *
- * \param dev DRM device.
- * \param minor device minor number.
- * \param root DRI proc dir entry.
- * \param dev_root resulting DRI device proc dir entry.
- * \return root entry pointer on success, or NULL on failure.
- * 
- * Create the DRI proc root entry "/proc/dri", the device proc root entry
- * "/proc/dri/%minor%/", and each entry in proc_list as
- * "/proc/dri/%minor%/%name%".
- */
-struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
-				      struct proc_dir_entry *root,
-				      struct proc_dir_entry **dev_root)
-{
-	struct proc_dir_entry *ent;
-	int		      i, j;
-	char                  name[64];
-
-	if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
-	if (!root) {
-		DRM_ERROR("Cannot create /proc/dri\n");
-		return NULL;
-	}
-
-	sprintf(name, "%d", minor);
-	*dev_root = create_proc_entry(name, S_IFDIR, root);
-	if (!*dev_root) {
-		DRM_ERROR("Cannot create /proc/dri/%s\n", name);
-		return NULL;
-	}
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-		ent = create_proc_entry(DRM(proc_list)[i].name,
-					S_IFREG|S_IRUGO, *dev_root);
-		if (!ent) {
-			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
-				  name, DRM(proc_list)[i].name);
-			for (j = 0; j < i; j++)
-				remove_proc_entry(DRM(proc_list)[i].name,
-						  *dev_root);
-			remove_proc_entry(name, root);
-			if (!minor) remove_proc_entry("dri", NULL);
-			return NULL;
-		}
-		ent->read_proc = DRM(proc_list)[i].f;
-		ent->data      = dev;
-	}
-
-	return root;
-}
-
-
-/**
- * Cleanup the proc filesystem resources.
- *
- * \param minor device minor number.
- * \param root DRI proc dir entry.
- * \param dev_root DRI device proc dir entry.
- * \return always zero.
- *
- * Remove all proc entries created by proc_init().
- */
-int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
-		      struct proc_dir_entry *dev_root)
-{
-	int  i;
-	char name[64];
-
-	if (!root || !dev_root) return 0;
-
-	for (i = 0; i < DRM_PROC_ENTRIES; i++)
-		remove_proc_entry(DRM(proc_list)[i].name, dev_root);
-	sprintf(name, "%d", minor);
-	remove_proc_entry(name, root);
-	if (!minor) remove_proc_entry("dri", NULL);
-
-	return 0;
-}
-
-/**
- * Called when "/proc/dri/.../name" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- * 
- * Prints the device name together with the bus id if available.
- */
-static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	if (dev->unique) {
-		DRM_PROC_PRINT("%s 0x%lx %s\n",
-			       dev->name, (long)old_encode_dev(dev->device), dev->unique);
-	} else {
-		DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)old_encode_dev(dev->device));
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Called when "/proc/dri/.../vm" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- * 
- * Prints information about all mappings in drm_device::maplist.
- */
-static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	drm_map_t    *map;
-	drm_map_list_t *r_list;
-	struct list_head *list;
-
-				/* Hardcoded from _DRM_FRAME_BUFFER,
-                                   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
-                                   _DRM_SCATTER_GATHER. */
-	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
-	const char   *type;
-	int	     i;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
-		       "address mtrr\n\n");
-	i = 0;
-	if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if(!map) continue;
-		if (map->type < 0 || map->type > 4) type = "??";
-		else				    type = types[map->type];
-		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
-			       i,
-			       map->offset,
-			       map->size,
-			       type,
-			       map->flags,
-			       (unsigned long)map->handle);
-		if (map->mtrr < 0) {
-			DRM_PROC_PRINT("none\n");
-		} else {
-			DRM_PROC_PRINT("%4d\n", map->mtrr);
-		}
-		i++;
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
-			int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../queues" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_queues_info)(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	int	     i;
-	drm_queue_t  *q;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("  ctx/flags   use   fin"
-		       "   blk/rw/rwf  wait    flushed	   queued"
-		       "      locks\n\n");
-	for (i = 0; i < dev->queue_count; i++) {
-		q = dev->queuelist[i];
-		atomic_inc(&q->use_count);
-		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
-				   "%5d/0x%03x %5d %5d"
-				   " %5d/%c%c/%c%c%c %5Zd\n",
-				   i,
-				   q->flags,
-				   atomic_read(&q->use_count),
-				   atomic_read(&q->finalization),
-				   atomic_read(&q->block_count),
-				   atomic_read(&q->block_read) ? 'r' : '-',
-				   atomic_read(&q->block_write) ? 'w' : '-',
-				   waitqueue_active(&q->read_queue) ? 'r':'-',
-				   waitqueue_active(&q->write_queue) ? 'w':'-',
-				   waitqueue_active(&q->flush_queue) ? 'f':'-',
-				   DRM_BUFCOUNT(&q->waitlist));
-		atomic_dec(&q->use_count);
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
-			    int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../bufs" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
-			   int *eof, void *data)
-{
-	drm_device_t	 *dev = (drm_device_t *)data;
-	int              len  = 0;
-	drm_device_dma_t *dma = dev->dma;
-	int		 i;
-
-	if (!dma || offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
-	for (i = 0; i <= DRM_MAX_ORDER; i++) {
-		if (dma->bufs[i].buf_count)
-			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
-				       i,
-				       dma->bufs[i].buf_size,
-				       dma->bufs[i].buf_count,
-				       atomic_read(&dma->bufs[i]
-						   .freelist.count),
-				       dma->bufs[i].seg_count,
-				       dma->bufs[i].seg_count
-				       *(1 << dma->bufs[i].page_order),
-				       (dma->bufs[i].seg_count
-					* (1 << dma->bufs[i].page_order))
-				       * PAGE_SIZE / 1024);
-	}
-	DRM_PROC_PRINT("\n");
-	for (i = 0; i < dma->buf_count; i++) {
-		if (i && !(i%32)) DRM_PROC_PRINT("\n");
-		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
-	}
-	DRM_PROC_PRINT("\n");
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-/**
- * Called when "/proc/dri/.../clients" is read.
- * 
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int DRM(_clients_info)(char *buf, char **start, off_t offset,
-			      int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int          len  = 0;
-	drm_file_t   *priv;
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
-	for (priv = dev->file_first; priv; priv = priv->next) {
-		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
-			       priv->authenticated ? 'y' : 'n',
-			       priv->minor,
-			       priv->pid,
-			       priv->uid,
-			       priv->magic,
-			       priv->ioctl_count);
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-/**
- * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
- */
-static int DRM(clients_info)(char *buf, char **start, off_t offset,
-			     int request, int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-
-#if DRM_DEBUG_CODE
-
-static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
-			  int *eof, void *data)
-{
-	drm_device_t	      *dev = (drm_device_t *)data;
-	int                   len  = 0;
-	drm_vma_entry_t	      *pt;
-	struct vm_area_struct *vma;
-#if defined(__i386__)
-	unsigned int	      pgprot;
-#endif
-
-	if (offset > DRM_PROC_LIMIT) {
-		*eof = 1;
-		return 0;
-	}
-
-	*start = &buf[offset];
-	*eof   = 0;
-
-	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
-		       atomic_read(&dev->vma_count),
-		       high_memory, virt_to_phys(high_memory));
-	for (pt = dev->vmalist; pt; pt = pt->next) {
-		if (!(vma = pt->vma)) continue;
-		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
-			       pt->pid,
-			       vma->vm_start,
-			       vma->vm_end,
-			       vma->vm_flags & VM_READ	   ? 'r' : '-',
-			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
-			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
-			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
-			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
-			       vma->vm_flags & VM_IO	   ? 'i' : '-',
-			       VM_OFFSET(vma));
-
-#if defined(__i386__)
-		pgprot = pgprot_val(vma->vm_page_prot);
-		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
-			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
-			       pgprot & _PAGE_RW       ? 'w' : 'r',
-			       pgprot & _PAGE_USER     ? 'u' : 's',
-			       pgprot & _PAGE_PWT      ? 't' : 'b',
-			       pgprot & _PAGE_PCD      ? 'u' : 'c',
-			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
-			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
-			       pgprot & _PAGE_PSE      ? 'm' : 'k',
-			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
-#endif
-		DRM_PROC_PRINT("\n");
-	}
-
-	if (len > request + offset) return request;
-	*eof = 1;
-	return len - offset;
-}
-
-static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
-			 int *eof, void *data)
-{
-	drm_device_t *dev = (drm_device_t *)data;
-	int	     ret;
-
-	down(&dev->struct_sem);
-	ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
-	up(&dev->struct_sem);
-	return ret;
-}
-#endif
-
-
diff -Nru a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_scatter.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,231 @@
+/**
+ * \file drm_scatter.h 
+ * IOCTLs to manage scatter/gather memory
+ *
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include <linux/config.h>
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+#define DEBUG_SCATTER 0
+
+void drm_sg_cleanup( drm_sg_mem_t *entry )
+{
+	struct page *page;
+	int i;
+
+	for ( i = 0 ; i < entry->pages ; i++ ) {
+		page = entry->pagelist[i];
+		if ( page )
+			ClearPageReserved( page );
+	}
+
+	vfree( entry->virtual );
+
+	drm_free( entry->busaddr,
+		   entry->pages * sizeof(*entry->busaddr),
+		   DRM_MEM_PAGES );
+	drm_free( entry->pagelist,
+		   entry->pages * sizeof(*entry->pagelist),
+		   DRM_MEM_PAGES );
+	drm_free( entry,
+		   sizeof(*entry),
+		   DRM_MEM_SGLISTS );
+}
+
+int drm_sg_alloc( struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_scatter_gather_t __user *argp = (void __user *)arg;
+	drm_scatter_gather_t request;
+	drm_sg_mem_t *entry;
+	unsigned long pages, i, j;
+
+	DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+	if (!drm_core_check_feature(dev, DRIVER_SG))
+		return -EINVAL;
+
+	if ( dev->sg )
+		return -EINVAL;
+
+	if ( copy_from_user( &request, argp, sizeof(request) ) )
+		return -EFAULT;
+
+	entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
+	if ( !entry )
+		return -ENOMEM;
+
+   	memset( entry, 0, sizeof(*entry) );
+
+	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+	DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+
+	entry->pages = pages;
+	entry->pagelist = drm_alloc( pages * sizeof(*entry->pagelist),
+				     DRM_MEM_PAGES );
+	if ( !entry->pagelist ) {
+		drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+
+	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+	entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr),
+				     DRM_MEM_PAGES );
+	if ( !entry->busaddr ) {
+		drm_free( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		drm_free( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
+
+	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+	if ( !entry->virtual ) {
+		drm_free( entry->busaddr,
+			   entry->pages * sizeof(*entry->busaddr),
+			   DRM_MEM_PAGES );
+		drm_free( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		drm_free( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+
+	/* This also forces the mapping of COW pages, so our page list
+	 * will be valid.  Please don't remove it...
+	 */
+	memset( entry->virtual, 0, pages << PAGE_SHIFT );
+
+	entry->handle = (unsigned long)entry->virtual;
+
+	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
+	DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
+
+	for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
+		entry->pagelist[j] = vmalloc_to_page((void *)i);
+		if (!entry->pagelist[j])
+			goto failed;
+		SetPageReserved(entry->pagelist[j]);
+	}
+
+	request.handle = entry->handle;
+
+	if ( copy_to_user( argp, &request, sizeof(request) ) ) {
+		drm_sg_cleanup( entry );
+		return -EFAULT;
+	}
+
+	dev->sg = entry;
+
+#if DEBUG_SCATTER
+	/* Verify that each page points to its virtual address, and vice
+	 * versa.
+	 */
+	{
+	int error = 0;
+
+	for ( i = 0 ; i < pages ; i++ ) {
+		unsigned long *tmp;
+
+		tmp = page_address( entry->pagelist[i] );
+		for ( j = 0 ;
+		      j < PAGE_SIZE / sizeof(unsigned long) ;
+		      j++, tmp++ ) {
+			*tmp = 0xcafebabe;
+		}
+		tmp = (unsigned long *)((u8 *)entry->virtual +
+					(PAGE_SIZE * i));
+		for( j = 0 ;
+		     j < PAGE_SIZE / sizeof(unsigned long) ;
+		     j++, tmp++ ) {
+			if ( *tmp != 0xcafebabe && error == 0 ) {
+				error = 1;
+				DRM_ERROR( "Scatter allocation error, "
+					   "pagelist does not match "
+					   "virtual mapping\n" );
+			}
+		}
+		tmp = page_address( entry->pagelist[i] );
+		for(j = 0 ;
+		    j < PAGE_SIZE / sizeof(unsigned long) ;
+		    j++, tmp++) {
+			*tmp = 0;
+		}
+	}
+	if (error == 0)
+		DRM_ERROR( "Scatter allocation matches pagelist\n" );
+	}
+#endif
+
+	return 0;
+
+ failed:
+	drm_sg_cleanup( entry );
+	return -ENOMEM;
+}
+
+int drm_sg_free( struct inode *inode, struct file *filp,
+		 unsigned int cmd, unsigned long arg )
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_scatter_gather_t request;
+	drm_sg_mem_t *entry;
+
+	if (!drm_core_check_feature(dev, DRIVER_SG))
+		return -EINVAL;
+
+	if ( copy_from_user( &request,
+			     (drm_scatter_gather_t __user *)arg,
+			     sizeof(request) ) )
+		return -EFAULT;
+
+	entry = dev->sg;
+	dev->sg = NULL;
+
+	if ( !entry || entry->handle != request.handle )
+		return -EINVAL;
+
+	DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
+
+	drm_sg_cleanup( entry );
+
+	return 0;
+}
diff -Nru a/drivers/char/drm/drm_scatter.h b/drivers/char/drm/drm_scatter.h
--- a/drivers/char/drm/drm_scatter.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,231 +0,0 @@
-/**
- * \file drm_scatter.h 
- * IOCTLs to manage scatter/gather memory
- *
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT 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.
- */
-
-#include <linux/config.h>
-#include <linux/vmalloc.h>
-#include "drmP.h"
-
-#define DEBUG_SCATTER 0
-
-void DRM(sg_cleanup)( drm_sg_mem_t *entry )
-{
-	struct page *page;
-	int i;
-
-	for ( i = 0 ; i < entry->pages ; i++ ) {
-		page = entry->pagelist[i];
-		if ( page )
-			ClearPageReserved( page );
-	}
-
-	vfree( entry->virtual );
-
-	DRM(free)( entry->busaddr,
-		   entry->pages * sizeof(*entry->busaddr),
-		   DRM_MEM_PAGES );
-	DRM(free)( entry->pagelist,
-		   entry->pages * sizeof(*entry->pagelist),
-		   DRM_MEM_PAGES );
-	DRM(free)( entry,
-		   sizeof(*entry),
-		   DRM_MEM_SGLISTS );
-}
-
-int DRM(sg_alloc)( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_scatter_gather_t __user *argp = (void __user *)arg;
-	drm_scatter_gather_t request;
-	drm_sg_mem_t *entry;
-	unsigned long pages, i, j;
-
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
-
-	if (!drm_core_check_feature(dev, DRIVER_SG))
-		return -EINVAL;
-
-	if ( dev->sg )
-		return -EINVAL;
-
-	if ( copy_from_user( &request, argp, sizeof(request) ) )
-		return -EFAULT;
-
-	entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
-	if ( !entry )
-		return -ENOMEM;
-
-   	memset( entry, 0, sizeof(*entry) );
-
-	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-	DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
-
-	entry->pages = pages;
-	entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
-				     DRM_MEM_PAGES );
-	if ( !entry->pagelist ) {
-		DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-
-	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
-
-	entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
-				     DRM_MEM_PAGES );
-	if ( !entry->busaddr ) {
-		DRM(free)( entry->pagelist,
-			   entry->pages * sizeof(*entry->pagelist),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry,
-			   sizeof(*entry),
-			   DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
-
-	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
-	if ( !entry->virtual ) {
-		DRM(free)( entry->busaddr,
-			   entry->pages * sizeof(*entry->busaddr),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry->pagelist,
-			   entry->pages * sizeof(*entry->pagelist),
-			   DRM_MEM_PAGES );
-		DRM(free)( entry,
-			   sizeof(*entry),
-			   DRM_MEM_SGLISTS );
-		return -ENOMEM;
-	}
-
-	/* This also forces the mapping of COW pages, so our page list
-	 * will be valid.  Please don't remove it...
-	 */
-	memset( entry->virtual, 0, pages << PAGE_SHIFT );
-
-	entry->handle = (unsigned long)entry->virtual;
-
-	DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
-	DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
-
-	for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
-		entry->pagelist[j] = vmalloc_to_page((void *)i);
-		if (!entry->pagelist[j])
-			goto failed;
-		SetPageReserved(entry->pagelist[j]);
-	}
-
-	request.handle = entry->handle;
-
-	if ( copy_to_user( argp, &request, sizeof(request) ) ) {
-		DRM(sg_cleanup)( entry );
-		return -EFAULT;
-	}
-
-	dev->sg = entry;
-
-#if DEBUG_SCATTER
-	/* Verify that each page points to its virtual address, and vice
-	 * versa.
-	 */
-	{
-	int error = 0;
-
-	for ( i = 0 ; i < pages ; i++ ) {
-		unsigned long *tmp;
-
-		tmp = page_address( entry->pagelist[i] );
-		for ( j = 0 ;
-		      j < PAGE_SIZE / sizeof(unsigned long) ;
-		      j++, tmp++ ) {
-			*tmp = 0xcafebabe;
-		}
-		tmp = (unsigned long *)((u8 *)entry->virtual +
-					(PAGE_SIZE * i));
-		for( j = 0 ;
-		     j < PAGE_SIZE / sizeof(unsigned long) ;
-		     j++, tmp++ ) {
-			if ( *tmp != 0xcafebabe && error == 0 ) {
-				error = 1;
-				DRM_ERROR( "Scatter allocation error, "
-					   "pagelist does not match "
-					   "virtual mapping\n" );
-			}
-		}
-		tmp = page_address( entry->pagelist[i] );
-		for(j = 0 ;
-		    j < PAGE_SIZE / sizeof(unsigned long) ;
-		    j++, tmp++) {
-			*tmp = 0;
-		}
-	}
-	if (error == 0)
-		DRM_ERROR( "Scatter allocation matches pagelist\n" );
-	}
-#endif
-
-	return 0;
-
- failed:
-	DRM(sg_cleanup)( entry );
-	return -ENOMEM;
-}
-
-int DRM(sg_free)( struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg )
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_scatter_gather_t request;
-	drm_sg_mem_t *entry;
-
-	if (!drm_core_check_feature(dev, DRIVER_SG))
-		return -EINVAL;
-
-	if ( copy_from_user( &request,
-			     (drm_scatter_gather_t __user *)arg,
-			     sizeof(request) ) )
-		return -EFAULT;
-
-	entry = dev->sg;
-	dev->sg = NULL;
-
-	if ( !entry || entry->handle != request.handle )
-		return -EINVAL;
-
-	DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
-
-	DRM(sg_cleanup)( entry );
-
-	return 0;
-}
diff -Nru a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_stub.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,254 @@
+/**
+ * \file drm_stub.h
+ * Stub support
+ *
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ */
+
+/*
+ * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
+ *
+ * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * PRECISION INSIGHT 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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include "drmP.h"
+#include "drm_core.h"
+
+unsigned int drm_cards_limit = 16;	/* Enough for one machine */
+unsigned int drm_debug = 0;		/* 1 to enable debug output */
+EXPORT_SYMBOL(drm_debug);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
+MODULE_PARM_DESC(drm_cards_limit, "Maximum number of graphics cards");
+MODULE_PARM_DESC(drm_debug, "Enable debug output");
+
+module_param_named(cards_limit, drm_cards_limit, int, 0444);
+module_param_named(debug, drm_debug, int, 0666);
+
+drm_minor_t *drm_minors;
+struct class_simple *drm_class;
+struct proc_dir_entry *drm_proc_root;
+
+static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
+{
+	int retcode;
+
+	dev->count_lock = SPIN_LOCK_UNLOCKED;
+	init_timer( &dev->timer );
+	sema_init( &dev->struct_sem, 1 );
+	sema_init( &dev->ctxlist_sem, 1 );
+
+	dev->pdev   = pdev;
+
+#ifdef __alpha__
+	dev->hose   = pdev->sysdata;
+	dev->pci_domain = dev->hose->bus->number;
+#else
+	dev->pci_domain = 0;
+#endif
+	dev->pci_bus = pdev->bus->number;
+	dev->pci_slot = PCI_SLOT(pdev->devfn);
+	dev->pci_func = PCI_FUNC(pdev->devfn);
+	dev->irq = pdev->irq;
+
+	/* the DRM has 6 basic counters */
+	dev->counters = 6;
+	dev->types[0]  = _DRM_STAT_LOCK;
+	dev->types[1]  = _DRM_STAT_OPENS;
+	dev->types[2]  = _DRM_STAT_CLOSES;
+	dev->types[3]  = _DRM_STAT_IOCTLS;
+	dev->types[4]  = _DRM_STAT_LOCKS;
+	dev->types[5]  = _DRM_STAT_UNLOCKS;
+
+	dev->driver = driver;
+	
+	if (dev->driver->preinit)
+		if ((retcode = dev->driver->preinit(dev)))
+			goto error_out_unreg;
+
+	if (drm_core_has_AGP(dev)) {
+		dev->agp = drm_agp_init();
+		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
+			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+			retcode = -EINVAL;
+			goto error_out_unreg;
+		}
+		if (drm_core_has_MTRR(dev)) {
+			if (dev->agp)
+				dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+							       dev->agp->agp_info.aper_size*1024*1024,
+							       MTRR_TYPE_WRCOMB,
+							       1 );
+		}
+	}
+
+	retcode = drm_ctxbitmap_init( dev );
+	if( retcode ) {
+		DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+		goto error_out_unreg;
+	}
+
+	dev->device = MKDEV(DRM_MAJOR, dev->minor );
+
+	/* postinit is a required function to display the signon banner */
+	if ((retcode = dev->driver->postinit(dev, ent->driver_data)))
+		goto error_out_unreg;
+
+	return 0;
+	
+error_out_unreg:
+	drm_takedown(dev);
+	return retcode;
+}
+
+/**
+ * File \c open operation.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ *
+ * Puts the dev->fops corresponding to the device minor number into
+ * \p filp, call the \c open method, and restore the file operations.
+ */
+int drm_stub_open(struct inode *inode, struct file *filp)
+{
+	drm_device_t *dev = NULL;
+	int minor = iminor(inode);
+	int err = -ENODEV;
+	struct file_operations *old_fops;
+	
+	DRM_DEBUG("\n");
+
+	if (!((minor >= 0) && (minor < drm_cards_limit)))
+		return -ENODEV;
+
+	dev = drm_minors[minor].dev;
+	if (!dev)
+		return -ENODEV;
+
+	old_fops = filp->f_op;
+	filp->f_op = fops_get(&dev->driver->fops);
+	if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+		fops_put(filp->f_op);
+		filp->f_op = fops_get(old_fops);
+	}
+	fops_put(old_fops);
+
+	return err;
+}
+
+/**
+ * Get a device minor number.
+ *
+ * \param pdev PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
+{
+	struct class_device *dev_class;
+	drm_device_t *dev;
+	int ret;
+	int minor;
+	drm_minor_t *minors = &drm_minors[0];
+
+	DRM_DEBUG("\n");
+
+	for (minor = 0; minor < drm_cards_limit; minor++, minors++) {
+		if (minors->type == DRM_MINOR_FREE) {
+
+			DRM_DEBUG("assigning minor %d\n", minor);
+			dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+			if (!dev)
+				return -ENOMEM;
+
+			*minors = (drm_minor_t){.dev = dev, .type=DRM_MINOR_PRIMARY};
+			dev->minor = minor;
+			if ((ret=drm_fill_in_dev(dev, pdev, ent, driver))) {
+				printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+				goto err_g1;
+			}
+			if ((ret = drm_proc_init(dev, minor, drm_proc_root, &minors->dev_root))) {
+				printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
+				goto err_g1;
+			}
+
+			pci_enable_device(pdev);
+			
+			dev_class = class_simple_device_add(drm_class, 
+							    MKDEV(DRM_MAJOR, minor), &pdev->dev, "card%d", minor);
+			if (IS_ERR(dev_class)) {
+				printk(KERN_ERR "DRM: Error class_simple_device_add.\n");
+				ret = PTR_ERR(dev_class);
+				goto err_g2;
+			}
+			
+			DRM_DEBUG("new minor assigned %d\n", minor);
+			return 0;
+		}
+	}
+	DRM_ERROR("out of minors\n");
+	return -ENOMEM;
+err_g2:
+	drm_proc_cleanup(minor, drm_proc_root, minors->dev_root);
+err_g1:
+	*minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE};
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+	return ret;
+}
+EXPORT_SYMBOL(drm_probe);
+		
+
+/**
+ * Put a device minor number.
+ *
+ * \param minor minor number.
+ * \return always zero.
+ *
+ * Cleans up the proc resources. If a minor is zero then release the foreign
+ * "drm" data, otherwise unregisters the "drm" data, frees the stub list and
+ * unregisters the character device. 
+ */
+int drm_put_minor(drm_device_t *dev)
+{
+	drm_minor_t *minors = &drm_minors[dev->minor];
+	
+	DRM_DEBUG("release minor %d\n", dev->minor);
+	
+	drm_proc_cleanup(dev->minor, drm_proc_root, minors->dev_root);
+	class_simple_device_remove(MKDEV(DRM_MAJOR, dev->minor));
+	
+	*minors = (drm_minor_t){.dev = NULL, .type = DRM_MINOR_FREE};
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+	
+	return 0;
+}
+
diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h
--- a/drivers/char/drm/drm_stub.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,236 +0,0 @@
-/**
- * \file drm_stub.h
- * Stub support
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-/*
- * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
- *
- * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * PRECISION INSIGHT 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.
- */
-
-#include "drmP.h"
-
-#define DRM_STUB_MAXCARDS 16	/* Enough for one machine */
-
-static struct class_simple *drm_class;
-
-/** Stub list. One for each minor. */
-static struct drm_stub_list {
-	const char             *name;
-	struct file_operations *fops;	/**< file operations */
-	struct proc_dir_entry  *dev_root;	/**< proc directory entry */
-} *DRM(stub_list);
-
-static struct proc_dir_entry *DRM(stub_root);
-
-/** Stub information */
-static struct drm_stub_info {
-	int (*info_register)(const char *name, struct file_operations *fops,
-			     drm_device_t *dev);
-	int (*info_unregister)(int minor);
-} DRM(stub_info);
-
-/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the drm_stub_list::fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-static int DRM(stub_open)(struct inode *inode, struct file *filp)
-{
-	int                    minor = iminor(inode);
-	int                    err   = -ENODEV;
-	struct file_operations *old_fops;
-
-	if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
-	old_fops   = filp->f_op;
-	filp->f_op = fops_get(DRM(stub_list)[minor].fops);
-	if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
-		fops_put(filp->f_op);
-		filp->f_op = fops_get(old_fops);
-	}
-	fops_put(old_fops);
-
-	return err;
-}
-
-/** File operations structure */
-static struct file_operations DRM(stub_fops) = {
-	.owner = THIS_MODULE,
-	.open  = DRM(stub_open)
-};
-
-/**
- * Get a device minor number.
- *
- * \param name driver name.
- * \param fops file operations.
- * \param dev DRM device.
- * \return minor number on success, or a negative number on failure.
- *
- * Allocate and initialize ::stub_list if one doesn't exist already.  Search an
- * empty entry and initialize it to the given parameters, and create the proc
- * init entry via proc_init().
- */
-static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
-			      drm_device_t *dev)
-{
-	int i;
-
-	if (!DRM(stub_list)) {
-		DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
-					    * DRM_STUB_MAXCARDS, DRM_MEM_STUB);
-		if(!DRM(stub_list)) return -1;
-		for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
-			DRM(stub_list)[i].name = NULL;
-			DRM(stub_list)[i].fops = NULL;
-		}
-	}
-	for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
-		if (!DRM(stub_list)[i].fops) {
-			DRM(stub_list)[i].name = name;
-			DRM(stub_list)[i].fops = fops;
-			DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
-							&DRM(stub_list)[i]
-							.dev_root);
-			class_simple_device_add(drm_class, MKDEV(DRM_MAJOR, i), NULL, name);
-			return i;
-		}
-	}
-	return -1;
-}
-
-/**
- * Put a device minor number.
- *
- * \param minor minor number.
- * \return always zero.
- *
- * Cleans up the proc resources. If a minor is zero then release the foreign
- * "drm" data, otherwise unregisters the "drm" data, frees the stub list and
- * unregisters the character device. 
- */
-static int DRM(stub_putminor)(int minor)
-{
-	if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
-	DRM(stub_list)[minor].name = NULL;
-	DRM(stub_list)[minor].fops = NULL;
-	DRM(proc_cleanup)(minor, DRM(stub_root),
-			  DRM(stub_list)[minor].dev_root);
-	if (minor) {
-		class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
-		inter_module_put("drm");
-	} else {
-		inter_module_unregister("drm");
-		DRM(free)(DRM(stub_list),
-			  sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
-			  DRM_MEM_STUB);
-		unregister_chrdev(DRM_MAJOR, "drm");
-		class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
-		class_simple_destroy(drm_class);
-	}
-	return 0;
-}
-
-/**
- * Register.
- *
- * \param name driver name.
- * \param fops file operations
- * \param dev DRM device.
- * \return zero on success or a negative number on failure.
- *
- * Attempt to register the char device and get the foreign "drm" data. If
- * successful then another module already registered so gets the stub info,
- * otherwise use this module stub info and make it available for other modules.
- *
- * Finally calls stub_info::info_register.
- */
-int DRM(stub_register)(const char *name, struct file_operations *fops,
-		       drm_device_t *dev)
-{
-	struct drm_stub_info *i = NULL;
-	int ret1;
-	int ret2;
-
-	DRM_DEBUG("\n");
-	ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops));
-	if (!ret1) {
-		drm_class = class_simple_create(THIS_MODULE, "drm");
-		if (IS_ERR(drm_class)) {
-			printk (KERN_ERR "Error creating drm class.\n");
-			unregister_chrdev(DRM_MAJOR, "drm");
-			return PTR_ERR(drm_class);
-		}
-	}
-	else if (ret1 == -EBUSY)
-		i = (struct drm_stub_info *)inter_module_get("drm");
-	else
-		return -1;
-
-	if (i) {
-				/* Already registered */
-		DRM(stub_info).info_register   = i->info_register;
-		DRM(stub_info).info_unregister = i->info_unregister;
-		DRM_DEBUG("already registered\n");
-	} else if (DRM(stub_info).info_register != DRM(stub_getminor)) {
-		DRM(stub_info).info_register   = DRM(stub_getminor);
-		DRM(stub_info).info_unregister = DRM(stub_putminor);
-		DRM_DEBUG("calling inter_module_register\n");
-		inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
-	}
-	if (DRM(stub_info).info_register) {
-		ret2 = DRM(stub_info).info_register(name, fops, dev);
-		if (ret2) {
-			if (!ret1) {
-				unregister_chrdev(DRM_MAJOR, "drm");
-				class_simple_destroy(drm_class);
-			}
-			if (!i)
-				inter_module_unregister("drm");
-		}
-		return ret2;
-	}
-	return -1;
-}
-
-/**
- * Unregister.
- *
- * \param minor
- *
- * Calls drm_stub_info::unregister.
- */
-int DRM(stub_unregister)(int minor)
-{
-	DRM_DEBUG("%d\n", minor);
-	if (DRM(stub_info).info_unregister)
-		return DRM(stub_info).info_unregister(minor);
-	return -1;
-}
diff -Nru a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/drm_vm.c	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,670 @@
+/**
+ * \file drm_vm.h
+ * Memory mapping for DRM
+ * 
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ * \author Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ */
+
+#include "drmP.h"
+
+
+/**
+ * \c nopage method for AGP virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Find the right map and if it's AGP memory find the real physical page to
+ * map, get the page, increment the use count and return it.
+ */
+#if __OS_HAS_AGP
+static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+						 unsigned long address)
+{
+	drm_file_t *priv  = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map    = NULL;
+	drm_map_list_t  *r_list;
+	struct list_head *list;
+
+	/*
+         * Find the right map
+         */
+	if (!drm_core_has_AGP(dev))
+		goto vm_nopage_error;
+
+	if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
+
+	list_for_each(list, &dev->maplist->head) {
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if (!map) continue;
+		if (map->offset == VM_OFFSET(vma)) break;
+	}
+
+	if (map && map->type == _DRM_AGP) {
+		unsigned long offset = address - vma->vm_start;
+		unsigned long baddr = VM_OFFSET(vma) + offset;
+		struct drm_agp_mem *agpmem;
+		struct page *page;
+
+#ifdef __alpha__
+		/*
+                 * Adjust to a bus-relative address
+                 */
+		baddr -= dev->hose->mem_space->start;
+#endif
+
+		/*
+                 * It's AGP memory - find the real physical page to map
+                 */
+		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+			if (agpmem->bound <= baddr &&
+			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
+				break;
+		}
+
+		if (!agpmem) goto vm_nopage_error;
+
+		/*
+                 * Get the page, inc the use count, and return it
+                 */
+		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+		get_page(page);
+
+		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
+			  baddr, __va(agpmem->memory->memory[offset]), offset,
+			  page_count(page));
+
+		return page;
+        }
+vm_nopage_error:
+	return NOPAGE_SIGBUS;		/* Disallow mremap */
+}
+#else /* __OS_HAS_AGP */
+static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
+						 unsigned long address)
+{
+	return NOPAGE_SIGBUS;
+}
+#endif /* __OS_HAS_AGP */
+
+/**
+ * \c nopage method for shared virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Get the the mapping, find the real physical page to map, get the page, and
+ * return it.
+ */
+static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
+						     unsigned long address)
+{
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
+	unsigned long	 offset;
+	unsigned long	 i;
+	struct page	 *page;
+
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
+
+	offset	 = address - vma->vm_start;
+	i = (unsigned long)map->handle + offset;
+	page = vmalloc_to_page((void *)i);
+	if (!page)
+		return NOPAGE_OOM;
+	get_page(page);
+
+	DRM_DEBUG("shm_nopage 0x%lx\n", address);
+	return page;
+}
+
+
+/**
+ * \c close method for shared virtual memory.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * Deletes map information if we are the last
+ * person to close a mapping and it's not in the global maplist.
+ */
+void drm_vm_shm_close(struct vm_area_struct *vma)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *pt, *prev, *next;
+	drm_map_t *map;
+	drm_map_list_t *r_list;
+	struct list_head *list;
+	int found_maps = 0;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_dec(&dev->vma_count);
+
+	map = vma->vm_private_data;
+
+	down(&dev->struct_sem);
+	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
+		next = pt->next;
+		if (pt->vma->vm_private_data == map) found_maps++;
+		if (pt->vma == vma) {
+			if (prev) {
+				prev->next = pt->next;
+			} else {
+				dev->vmalist = pt->next;
+			}
+			drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+		} else {
+			prev = pt;
+		}
+	}
+	/* We were the only map that was found */
+	if(found_maps == 1 &&
+	   map->flags & _DRM_REMOVABLE) {
+		/* Check to see if we are in the maplist, if we are not, then
+		 * we delete this mappings information.
+		 */
+		found_maps = 0;
+		list = &dev->maplist->head;
+		list_for_each(list, &dev->maplist->head) {
+			r_list = list_entry(list, drm_map_list_t, head);
+			if (r_list->map == map) found_maps++;
+		}
+
+		if(!found_maps) {
+			switch (map->type) {
+			case _DRM_REGISTERS:
+			case _DRM_FRAME_BUFFER:
+				if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
+					int retcode;
+					retcode = mtrr_del(map->mtrr,
+							   map->offset,
+							   map->size);
+					DRM_DEBUG("mtrr_del = %d\n", retcode);
+				}
+				drm_ioremapfree(map->handle, map->size, dev);
+				break;
+			case _DRM_SHM:
+				vfree(map->handle);
+				break;
+			case _DRM_AGP:
+			case _DRM_SCATTER_GATHER:
+				break;
+			}
+			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+		}
+	}
+	up(&dev->struct_sem);
+}
+
+/**
+ * \c nopage method for DMA virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
+ */
+static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
+						     unsigned long address)
+{
+	drm_file_t	 *priv	 = vma->vm_file->private_data;
+	drm_device_t	 *dev	 = priv->dev;
+	drm_device_dma_t *dma	 = dev->dma;
+	unsigned long	 offset;
+	unsigned long	 page_nr;
+	struct page	 *page;
+
+	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
+
+	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+	page_nr  = offset >> PAGE_SHIFT;
+	page = virt_to_page((dma->pagelist[page_nr] + 
+			     (offset & (~PAGE_MASK))));
+
+	get_page(page);
+
+	DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
+	return page;
+}
+
+/**
+ * \c nopage method for scatter-gather virtual memory.
+ *
+ * \param vma virtual memory area.
+ * \param address access address.
+ * \return pointer to the page structure.
+ * 
+ * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
+ */
+static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
+						    unsigned long address)
+{
+	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+	drm_file_t *priv = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long offset;
+	unsigned long map_offset;
+	unsigned long page_offset;
+	struct page *page;
+
+	if (!entry)                return NOPAGE_SIGBUS; /* Error */
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
+
+
+	offset = address - vma->vm_start;
+	map_offset = map->offset - dev->sg->handle;
+	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+	page = entry->pagelist[page_offset];
+	get_page(page);
+
+	return page;
+}
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+
+static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+				   unsigned long address,
+				   int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_nopage(vma, address);
+}
+
+static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_shm_nopage(vma, address);
+}
+
+static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_dma_nopage(vma, address);
+}
+
+static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+				      unsigned long address,
+				      int *type) {
+	if (type) *type = VM_FAULT_MINOR;
+	return drm_do_vm_sg_nopage(vma, address);
+}
+
+#else	/* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
+
+static struct page *drm_vm_nopage(struct vm_area_struct *vma,
+				   unsigned long address,
+				   int unused) {
+	return drm_do_vm_nopage(vma, address);
+}
+
+static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int unused) {
+	return drm_do_vm_shm_nopage(vma, address);
+}
+
+static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+				       unsigned long address,
+				       int unused) {
+	return drm_do_vm_dma_nopage(vma, address);
+}
+
+static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
+				      unsigned long address,
+				      int unused) {
+	return drm_do_vm_sg_nopage(vma, address);
+}
+
+#endif
+
+
+/** AGP virtual memory operations */
+static struct vm_operations_struct   drm_vm_ops = {
+	.nopage = drm_vm_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_close,
+};
+
+/** Shared virtual memory operations */
+static struct vm_operations_struct   drm_vm_shm_ops = {
+	.nopage = drm_vm_shm_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_shm_close,
+};
+
+/** DMA virtual memory operations */
+static struct vm_operations_struct   drm_vm_dma_ops = {
+	.nopage = drm_vm_dma_nopage,
+	.open	= drm_vm_open,
+	.close	= drm_vm_close,
+};
+
+/** Scatter-gather virtual memory operations */
+static struct vm_operations_struct   drm_vm_sg_ops = {
+	.nopage = drm_vm_sg_nopage,
+	.open   = drm_vm_open,
+	.close  = drm_vm_close,
+};
+
+
+/**
+ * \c open method for shared virtual memory.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * Create a new drm_vma_entry structure as the \p vma private data entry and
+ * add it to drm_device::vmalist.
+ */
+void drm_vm_open(struct vm_area_struct *vma)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *vma_entry;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_inc(&dev->vma_count);
+
+	vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
+	if (vma_entry) {
+		down(&dev->struct_sem);
+		vma_entry->vma	= vma;
+		vma_entry->next = dev->vmalist;
+		vma_entry->pid	= current->pid;
+		dev->vmalist	= vma_entry;
+		up(&dev->struct_sem);
+	}
+}
+
+/**
+ * \c close method for all virtual memory types.
+ * 
+ * \param vma virtual memory area.
+ * 
+ * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
+ * free it.
+ */
+void drm_vm_close(struct vm_area_struct *vma)
+{
+	drm_file_t	*priv	= vma->vm_file->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_vma_entry_t *pt, *prev;
+
+	DRM_DEBUG("0x%08lx,0x%08lx\n",
+		  vma->vm_start, vma->vm_end - vma->vm_start);
+	atomic_dec(&dev->vma_count);
+
+	down(&dev->struct_sem);
+	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+		if (pt->vma == vma) {
+			if (prev) {
+				prev->next = pt->next;
+			} else {
+				dev->vmalist = pt->next;
+			}
+			drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+			break;
+		}
+	}
+	up(&dev->struct_sem);
+}
+
+/**
+ * mmap DMA memory.
+ *
+ * \param filp file pointer.
+ * \param vma virtual memory area.
+ * \return zero on success or a negative number on failure.
+ * 
+ * Sets the virtual memory area operations structure to vm_dma_ops, the file
+ * pointer, and calls vm_open().
+ */
+int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+{
+	drm_file_t	 *priv	 = filp->private_data;
+	drm_device_t	 *dev;
+	drm_device_dma_t *dma;
+	unsigned long	 length	 = vma->vm_end - vma->vm_start;
+
+	lock_kernel();
+	dev	 = priv->dev;
+	dma	 = dev->dma;
+	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+				/* Length must match exact page count */
+	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	unlock_kernel();
+
+	vma->vm_ops   = &drm_vm_dma_ops;
+
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
+	vma->vm_flags |= VM_RESERVED; /* Don't swap */
+#endif
+
+	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
+	drm_vm_open(vma);
+	return 0;
+}
+
+unsigned long drm_core_get_map_ofs(drm_map_t *map)
+{
+	return map->offset;
+}
+EXPORT_SYMBOL(drm_core_get_map_ofs);
+
+unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+{
+#ifdef __alpha__
+	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
+#else
+	return 0;
+#endif
+}
+EXPORT_SYMBOL(drm_core_get_reg_ofs);
+
+/**
+ * mmap DMA memory.
+ *
+ * \param filp file pointer.
+ * \param vma virtual memory area.
+ * \return zero on success or a negative number on failure.
+ * 
+ * If the virtual memory area has no offset associated with it then it's a DMA
+ * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
+ * checks that the restricted flag is not set, sets the virtual memory operations
+ * according to the mapping type and remaps the pages. Finally sets the file
+ * pointer and calls vm_open().
+ */
+int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	drm_file_t	*priv	= filp->private_data;
+	drm_device_t	*dev	= priv->dev;
+	drm_map_t	*map	= NULL;
+	drm_map_list_t  *r_list;
+	unsigned long   offset  = 0;
+	struct list_head *list;
+
+	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+	if ( !priv->authenticated ) return -EACCES;
+
+	/* We check for "dma". On Apple's UniNorth, it's valid to have
+	 * the AGP mapped at physical address 0
+	 * --BenH.
+	 */
+	if (!VM_OFFSET(vma)
+#if __OS_HAS_AGP
+	    && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
+#endif
+	    )
+		return drm_mmap_dma(filp, vma);
+
+				/* A sequential search of a linked list is
+				   fine here because: 1) there will only be
+				   about 5-10 entries in the list and, 2) a
+				   DRI client only has to do this mapping
+				   once, so it doesn't have to be optimized
+				   for performance, even if the list was a
+				   bit longer. */
+	list_for_each(list, &dev->maplist->head) {
+		unsigned long off;
+
+		r_list = list_entry(list, drm_map_list_t, head);
+		map = r_list->map;
+		if (!map) continue;
+		off = dev->driver->get_map_ofs(map);
+		if (off == VM_OFFSET(vma)) break;
+	}
+
+	if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+		return -EPERM;
+
+				/* Check for valid size. */
+	if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+
+	if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
+		vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
+#if defined(__i386__) || defined(__x86_64__)
+		pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+				/* Ye gads this is ugly.  With more thought
+                                   we could move this up higher and use
+                                   `protection_map' instead.  */
+		vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+			__pte(pgprot_val(vma->vm_page_prot)))));
+#endif
+	}
+
+	switch (map->type) {
+        case _DRM_AGP:
+	  if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
+                /*
+                 * On some platforms we can't talk to bus dma address from the CPU, so for
+                 * memory of type DRM_AGP, we'll deal with sorting out the real physical
+                 * pages and mappings in nopage()
+                 */
+#if defined(__powerpc__)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+#endif
+                vma->vm_ops = &drm_vm_ops;
+                break;
+	  }
+                /* fall through to _DRM_FRAME_BUFFER... */        
+	case _DRM_FRAME_BUFFER:
+	case _DRM_REGISTERS:
+		if (VM_OFFSET(vma) >= __pa(high_memory)) {
+#if defined(__i386__) || defined(__x86_64__)
+			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+				pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+			}
+#elif defined(__powerpc__)
+			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+#endif
+			vma->vm_flags |= VM_IO;	/* not in core dump */
+		}
+#if defined(__ia64__)
+		if (map->type != _DRM_AGP)
+			vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+#endif
+		offset = dev->driver->get_reg_ofs(dev);
+#ifdef __sparc__
+		if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
+					VM_OFFSET(vma) + offset,
+					vma->vm_end - vma->vm_start,
+					vma->vm_page_prot, 0))
+#else
+		if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+				     (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
+				     vma->vm_end - vma->vm_start,
+				     vma->vm_page_prot))
+#endif
+				return -EAGAIN;
+		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
+			  " offset = 0x%lx\n",
+			  map->type,
+			  vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
+		vma->vm_ops = &drm_vm_ops;
+		break;
+	case _DRM_SHM:
+		vma->vm_ops = &drm_vm_shm_ops;
+		vma->vm_private_data = (void *)map;
+				/* Don't let this area swap.  Change when
+				   DRM_KERNEL advisory is supported. */
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+		vma->vm_flags |= VM_LOCKED;
+#else
+		vma->vm_flags |= VM_RESERVED;
+#endif
+		break;
+	case _DRM_SCATTER_GATHER:
+		vma->vm_ops = &drm_vm_sg_ops;
+		vma->vm_private_data = (void *)map;
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+		vma->vm_flags |= VM_LOCKED;
+#else
+		vma->vm_flags |= VM_RESERVED;
+#endif
+                break;
+	default:
+		return -EINVAL;	/* This should never happen. */
+	}
+#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
+	vma->vm_flags |= VM_RESERVED; /* Don't swap */
+#endif
+
+	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
+	drm_vm_open(vma);
+	return 0;
+}
+EXPORT_SYMBOL(drm_mmap);
diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
--- a/drivers/char/drm/drm_vm.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,667 +0,0 @@
-/**
- * \file drm_vm.h
- * Memory mapping for DRM
- * 
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- */
-
-#include "drmP.h"
-
-
-/**
- * \c nopage method for AGP virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Find the right map and if it's AGP memory find the real physical page to
- * map, get the page, increment the use count and return it.
- */
-#if __OS_HAS_AGP
-static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
-						 unsigned long address)
-{
-	drm_file_t *priv  = vma->vm_file->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_map_t *map    = NULL;
-	drm_map_list_t  *r_list;
-	struct list_head *list;
-
-	/*
-         * Find the right map
-         */
-	if (!drm_core_has_AGP(dev))
-		goto vm_nopage_error;
-
-	if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
-
-	list_for_each(list, &dev->maplist->head) {
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if (!map) continue;
-		if (map->offset == VM_OFFSET(vma)) break;
-	}
-
-	if (map && map->type == _DRM_AGP) {
-		unsigned long offset = address - vma->vm_start;
-		unsigned long baddr = VM_OFFSET(vma) + offset;
-		struct drm_agp_mem *agpmem;
-		struct page *page;
-
-#ifdef __alpha__
-		/*
-                 * Adjust to a bus-relative address
-                 */
-		baddr -= dev->hose->mem_space->start;
-#endif
-
-		/*
-                 * It's AGP memory - find the real physical page to map
-                 */
-		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
-			if (agpmem->bound <= baddr &&
-			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
-				break;
-		}
-
-		if (!agpmem) goto vm_nopage_error;
-
-		/*
-                 * Get the page, inc the use count, and return it
-                 */
-		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
-		page = virt_to_page(__va(agpmem->memory->memory[offset]));
-		get_page(page);
-
-		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
-			  baddr, __va(agpmem->memory->memory[offset]), offset,
-			  page_count(page));
-
-		return page;
-        }
-vm_nopage_error:
-	return NOPAGE_SIGBUS;		/* Disallow mremap */
-}
-#else /* __OS_HAS_AGP */
-static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
-						 unsigned long address)
-{
-	return NOPAGE_SIGBUS;
-}
-#endif /* __OS_HAS_AGP */
-
-/**
- * \c nopage method for shared virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Get the the mapping, find the real physical page to map, get the page, and
- * return it.
- */
-static __inline__ struct page *DRM(do_vm_shm_nopage)(struct vm_area_struct *vma,
-						     unsigned long address)
-{
-	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
-	unsigned long	 offset;
-	unsigned long	 i;
-	struct page	 *page;
-
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
-
-	offset	 = address - vma->vm_start;
-	i = (unsigned long)map->handle + offset;
-	page = vmalloc_to_page((void *)i);
-	if (!page)
-		return NOPAGE_OOM;
-	get_page(page);
-
-	DRM_DEBUG("shm_nopage 0x%lx\n", address);
-	return page;
-}
-
-
-/**
- * \c close method for shared virtual memory.
- * 
- * \param vma virtual memory area.
- * 
- * Deletes map information if we are the last
- * person to close a mapping and it's not in the global maplist.
- */
-void DRM(vm_shm_close)(struct vm_area_struct *vma)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *pt, *prev, *next;
-	drm_map_t *map;
-	drm_map_list_t *r_list;
-	struct list_head *list;
-	int found_maps = 0;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_dec(&dev->vma_count);
-
-	map = vma->vm_private_data;
-
-	down(&dev->struct_sem);
-	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
-		next = pt->next;
-		if (pt->vma->vm_private_data == map) found_maps++;
-		if (pt->vma == vma) {
-			if (prev) {
-				prev->next = pt->next;
-			} else {
-				dev->vmalist = pt->next;
-			}
-			DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
-		} else {
-			prev = pt;
-		}
-	}
-	/* We were the only map that was found */
-	if(found_maps == 1 &&
-	   map->flags & _DRM_REMOVABLE) {
-		/* Check to see if we are in the maplist, if we are not, then
-		 * we delete this mappings information.
-		 */
-		found_maps = 0;
-		list = &dev->maplist->head;
-		list_for_each(list, &dev->maplist->head) {
-			r_list = list_entry(list, drm_map_list_t, head);
-			if (r_list->map == map) found_maps++;
-		}
-
-		if(!found_maps) {
-			switch (map->type) {
-			case _DRM_REGISTERS:
-			case _DRM_FRAME_BUFFER:
-				if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
-					int retcode;
-					retcode = mtrr_del(map->mtrr,
-							   map->offset,
-							   map->size);
-					DRM_DEBUG("mtrr_del = %d\n", retcode);
-				}
-				DRM(ioremapfree)(map->handle, map->size, dev);
-				break;
-			case _DRM_SHM:
-				vfree(map->handle);
-				break;
-			case _DRM_AGP:
-			case _DRM_SCATTER_GATHER:
-				break;
-			}
-			DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
-		}
-	}
-	up(&dev->struct_sem);
-}
-
-/**
- * \c nopage method for DMA virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
- */
-static __inline__ struct page *DRM(do_vm_dma_nopage)(struct vm_area_struct *vma,
-						     unsigned long address)
-{
-	drm_file_t	 *priv	 = vma->vm_file->private_data;
-	drm_device_t	 *dev	 = priv->dev;
-	drm_device_dma_t *dma	 = dev->dma;
-	unsigned long	 offset;
-	unsigned long	 page_nr;
-	struct page	 *page;
-
-	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
-
-	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
-	page_nr  = offset >> PAGE_SHIFT;
-	page = virt_to_page((dma->pagelist[page_nr] + 
-			     (offset & (~PAGE_MASK))));
-
-	get_page(page);
-
-	DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
-	return page;
-}
-
-/**
- * \c nopage method for scatter-gather virtual memory.
- *
- * \param vma virtual memory area.
- * \param address access address.
- * \return pointer to the page structure.
- * 
- * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
- */
-static __inline__ struct page *DRM(do_vm_sg_nopage)(struct vm_area_struct *vma,
-						    unsigned long address)
-{
-	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
-	drm_file_t *priv = vma->vm_file->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_sg_mem_t *entry = dev->sg;
-	unsigned long offset;
-	unsigned long map_offset;
-	unsigned long page_offset;
-	struct page *page;
-
-	if (!entry)                return NOPAGE_SIGBUS; /* Error */
-	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-	if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
-
-
-	offset = address - vma->vm_start;
-	map_offset = map->offset - dev->sg->handle;
-	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
-	page = entry->pagelist[page_offset];
-	get_page(page);
-
-	return page;
-}
-
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
-
-static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
-				   unsigned long address,
-				   int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_shm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_dma_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				      unsigned long address,
-				      int *type) {
-	if (type) *type = VM_FAULT_MINOR;
-	return DRM(do_vm_sg_nopage)(vma, address);
-}
-
-#else	/* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
-
-static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
-				   unsigned long address,
-				   int unused) {
-	return DRM(do_vm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int unused) {
-	return DRM(do_vm_shm_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int unused) {
-	return DRM(do_vm_dma_nopage)(vma, address);
-}
-
-static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				      unsigned long address,
-				      int unused) {
-	return DRM(do_vm_sg_nopage)(vma, address);
-}
-
-#endif
-
-
-/** AGP virtual memory operations */
-static struct vm_operations_struct   DRM(vm_ops) = {
-	.nopage = DRM(vm_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_close),
-};
-
-/** Shared virtual memory operations */
-static struct vm_operations_struct   DRM(vm_shm_ops) = {
-	.nopage = DRM(vm_shm_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_shm_close),
-};
-
-/** DMA virtual memory operations */
-static struct vm_operations_struct   DRM(vm_dma_ops) = {
-	.nopage = DRM(vm_dma_nopage),
-	.open	= DRM(vm_open),
-	.close	= DRM(vm_close),
-};
-
-/** Scatter-gather virtual memory operations */
-static struct vm_operations_struct   DRM(vm_sg_ops) = {
-	.nopage = DRM(vm_sg_nopage),
-	.open   = DRM(vm_open),
-	.close  = DRM(vm_close),
-};
-
-
-/**
- * \c open method for shared virtual memory.
- * 
- * \param vma virtual memory area.
- * 
- * Create a new drm_vma_entry structure as the \p vma private data entry and
- * add it to drm_device::vmalist.
- */
-void DRM(vm_open)(struct vm_area_struct *vma)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *vma_entry;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_inc(&dev->vma_count);
-
-	vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
-	if (vma_entry) {
-		down(&dev->struct_sem);
-		vma_entry->vma	= vma;
-		vma_entry->next = dev->vmalist;
-		vma_entry->pid	= current->pid;
-		dev->vmalist	= vma_entry;
-		up(&dev->struct_sem);
-	}
-}
-
-/**
- * \c close method for all virtual memory types.
- * 
- * \param vma virtual memory area.
- * 
- * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
- * free it.
- */
-void DRM(vm_close)(struct vm_area_struct *vma)
-{
-	drm_file_t	*priv	= vma->vm_file->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_vma_entry_t *pt, *prev;
-
-	DRM_DEBUG("0x%08lx,0x%08lx\n",
-		  vma->vm_start, vma->vm_end - vma->vm_start);
-	atomic_dec(&dev->vma_count);
-
-	down(&dev->struct_sem);
-	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-		if (pt->vma == vma) {
-			if (prev) {
-				prev->next = pt->next;
-			} else {
-				dev->vmalist = pt->next;
-			}
-			DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
-			break;
-		}
-	}
-	up(&dev->struct_sem);
-}
-
-/**
- * mmap DMA memory.
- *
- * \param filp file pointer.
- * \param vma virtual memory area.
- * \return zero on success or a negative number on failure.
- * 
- * Sets the virtual memory area operations structure to vm_dma_ops, the file
- * pointer, and calls vm_open().
- */
-int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
-{
-	drm_file_t	 *priv	 = filp->private_data;
-	drm_device_t	 *dev;
-	drm_device_dma_t *dma;
-	unsigned long	 length	 = vma->vm_end - vma->vm_start;
-
-	lock_kernel();
-	dev	 = priv->dev;
-	dma	 = dev->dma;
-	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-				/* Length must match exact page count */
-	if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
-		unlock_kernel();
-		return -EINVAL;
-	}
-	unlock_kernel();
-
-	vma->vm_ops   = &DRM(vm_dma_ops);
-
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-#else
-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
-#endif
-
-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
-	DRM(vm_open)(vma);
-	return 0;
-}
-
-unsigned long DRM(core_get_map_ofs)(drm_map_t *map)
-{
-	return map->offset;
-}
-
-unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev)
-{
-#ifdef __alpha__
-	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
-#else
-	return 0;
-#endif
-}
-
-/**
- * mmap DMA memory.
- *
- * \param filp file pointer.
- * \param vma virtual memory area.
- * \return zero on success or a negative number on failure.
- * 
- * If the virtual memory area has no offset associated with it then it's a DMA
- * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
- * checks that the restricted flag is not set, sets the virtual memory operations
- * according to the mapping type and remaps the pages. Finally sets the file
- * pointer and calls vm_open().
- */
-int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
-{
-	drm_file_t	*priv	= filp->private_data;
-	drm_device_t	*dev	= priv->dev;
-	drm_map_t	*map	= NULL;
-	drm_map_list_t  *r_list;
-	unsigned long   offset  = 0;
-	struct list_head *list;
-
-	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-	if ( !priv->authenticated ) return -EACCES;
-
-	/* We check for "dma". On Apple's UniNorth, it's valid to have
-	 * the AGP mapped at physical address 0
-	 * --BenH.
-	 */
-	if (!VM_OFFSET(vma)
-#if __OS_HAS_AGP
-	    && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
-#endif
-	    )
-		return DRM(mmap_dma)(filp, vma);
-
-				/* A sequential search of a linked list is
-				   fine here because: 1) there will only be
-				   about 5-10 entries in the list and, 2) a
-				   DRI client only has to do this mapping
-				   once, so it doesn't have to be optimized
-				   for performance, even if the list was a
-				   bit longer. */
-	list_for_each(list, &dev->maplist->head) {
-		unsigned long off;
-
-		r_list = list_entry(list, drm_map_list_t, head);
-		map = r_list->map;
-		if (!map) continue;
-		off = dev->fn_tbl.get_map_ofs(map);
-		if (off == VM_OFFSET(vma)) break;
-	}
-
-	if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
-		return -EPERM;
-
-				/* Check for valid size. */
-	if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
-		vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
-#if defined(__i386__) || defined(__x86_64__)
-		pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-#else
-				/* Ye gads this is ugly.  With more thought
-                                   we could move this up higher and use
-                                   `protection_map' instead.  */
-		vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
-			__pte(pgprot_val(vma->vm_page_prot)))));
-#endif
-	}
-
-	switch (map->type) {
-        case _DRM_AGP:
-	  if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
-                /*
-                 * On some platforms we can't talk to bus dma address from the CPU, so for
-                 * memory of type DRM_AGP, we'll deal with sorting out the real physical
-                 * pages and mappings in nopage()
-                 */
-#if defined(__powerpc__)
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-#endif
-                vma->vm_ops = &DRM(vm_ops);
-                break;
-	  }
-                /* fall through to _DRM_FRAME_BUFFER... */        
-	case _DRM_FRAME_BUFFER:
-	case _DRM_REGISTERS:
-		if (VM_OFFSET(vma) >= __pa(high_memory)) {
-#if defined(__i386__) || defined(__x86_64__)
-			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
-				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-				pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
-			}
-#elif defined(__powerpc__)
-			pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-#endif
-			vma->vm_flags |= VM_IO;	/* not in core dump */
-		}
-#if defined(__ia64__)
-		if (map->type != _DRM_AGP)
-			vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-#endif
-		offset = dev->fn_tbl.get_reg_ofs(dev);
-#ifdef __sparc__
-		if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
-					VM_OFFSET(vma) + offset,
-					vma->vm_end - vma->vm_start,
-					vma->vm_page_prot, 0))
-#else
-		if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
-				     (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
-				     vma->vm_end - vma->vm_start,
-				     vma->vm_page_prot))
-#endif
-				return -EAGAIN;
-		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
-			  " offset = 0x%lx\n",
-			  map->type,
-			  vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
-		vma->vm_ops = &DRM(vm_ops);
-		break;
-	case _DRM_SHM:
-		vma->vm_ops = &DRM(vm_shm_ops);
-		vma->vm_private_data = (void *)map;
-				/* Don't let this area swap.  Change when
-				   DRM_KERNEL advisory is supported. */
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-		vma->vm_flags |= VM_LOCKED;
-#else
-		vma->vm_flags |= VM_RESERVED;
-#endif
-		break;
-	case _DRM_SCATTER_GATHER:
-		vma->vm_ops = &DRM(vm_sg_ops);
-		vma->vm_private_data = (void *)map;
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-		vma->vm_flags |= VM_LOCKED;
-#else
-		vma->vm_flags |= VM_RESERVED;
-#endif
-                break;
-	default:
-		return -EINVAL;	/* This should never happen. */
-	}
-#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
-	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-#else
-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
-#endif
-
-	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
-	DRM(vm_open)(vma);
-	return 0;
-}
diff -Nru a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
--- a/drivers/char/drm/ffb_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/ffb_drv.c	2004-11-09 00:25:55 -08:00
@@ -210,9 +210,7 @@
 	return addr;
 }
 
-#include "drm_core.h"
-
-/* This functions must be here since it references DRM(numdevs)
+/* This functions must be here since it references drm_numdevs)
  * which drm_drv.h declares.
  */
 static int ffb_presetup(drm_device_t *dev)
@@ -227,13 +225,13 @@
 		return -ENODEV;
 
 	/* Find our instance number by finding our device in dev structure */
-	for (i = 0; i < DRM(numdevs); i++) {
-		temp_dev = &(DRM(device)[i]);
+	for (i = 0; i < drm_numdevs; i++) {
+		temp_dev = &(drm_device[i]);
 		if(temp_dev == dev)
 			break;
 	}
 
-	if (i == DRM(numdevs))
+	if (i == drm_numdevs)
 		return -ENODEV;
 
 	ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
@@ -311,12 +309,12 @@
 {
 	ffb_set_context_ioctls();
 	DRM(fops).get_unmapped_area = ffb_get_unmapped_area;
-	dev->fn_tbl.release = ffb_driver_release;
-	dev->fn_tbl.presetup = ffb_presetup;
-	dev->fn_tbl.pretakedown = ffb_driver_pretakedown;
-	dev->fn_tbl.postcleanup = ffb_driver_postcleanup;
-	dev->fn_tbl.kernel_context_switch = ffb_context_switch;
-	dev->fn_tbl.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock;
-	dev->fn_tbl.get_map_ofs = ffb_driver_get_map_ofs;
-	dev->fn_tbl.get_reg_ofs = ffb_driver_get_reg_ofs;
+	dev->driver.release = ffb_driver_release;
+	dev->driver.presetup = ffb_presetup;
+	dev->driver.pretakedown = ffb_driver_pretakedown;
+	dev->driver.postcleanup = ffb_driver_postcleanup;
+	dev->driver.kernel_context_switch = ffb_context_switch;
+	dev->driver.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock;
+	dev->driver.get_map_ofs = ffb_driver_get_map_ofs;
+	dev->driver.get_reg_ofs = ffb_driver_get_reg_ofs;
 }
diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c
--- a/drivers/char/drm/gamma_dma.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/gamma_dma.c	2004-11-09 00:25:55 -08:00
@@ -937,10 +937,10 @@
 	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
 	DRM(fops).read = gamma_fops_read;
 	DRM(fops).poll = gamma_fops_poll;
-	dev->fn_tbl.preinit = gamma_driver_preinit;
-	dev->fn_tbl.pretakedown = gamma_driver_pretakedown;
-	dev->fn_tbl.dma_ready = gamma_driver_dma_ready;
-	dev->fn_tbl.dma_quiescent = gamma_driver_dma_quiescent;
-	dev->fn_tbl.dma_flush_block_and_flush = gamma_flush_block_and_flush;
-	dev->fn_tbl.dma_flush_unblock = gamma_flush_unblock;
+	dev->driver.preinit = gamma_driver_preinit;
+	dev->driver.pretakedown = gamma_driver_pretakedown;
+	dev->driver.dma_ready = gamma_driver_dma_ready;
+	dev->driver.dma_quiescent = gamma_driver_dma_quiescent;
+	dev->driver.dma_flush_block_and_flush = gamma_flush_block_and_flush;
+	dev->driver.dma_flush_unblock = gamma_flush_unblock;
 }
diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
--- a/drivers/char/drm/i810_dma.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i810_dma.c	2004-11-09 00:25:55 -08:00
@@ -30,7 +30,6 @@
  *
  */
 
-#include "i810.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i810_drm.h"
@@ -110,12 +109,12 @@
 }
 
 static struct file_operations i810_buffer_fops = {
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
+	.open	 = drm_open,
+	.flush	 = drm_flush,
+	.release = drm_release,
+	.ioctl	 = drm_ioctl,
 	.mmap	 = i810_mmap_buffers,
-	.fasync  = DRM(fasync),
+	.fasync  = drm_fasync,
 };
 
 int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
@@ -237,7 +236,7 @@
 	 * is freed, it's too late.
 	 */
 	if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
-		DRM(irq_uninstall)(dev);
+		drm_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		int i;
@@ -245,7 +244,7 @@
 	     		(drm_i810_private_t *) dev->dev_private;
 
 		if (dev_priv->ring.virtual_start) {
-		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
 					 dev_priv->ring.Size, dev);
 		}
 	   	if (dev_priv->hw_status_page) {
@@ -255,7 +254,7 @@
 		   	/* Need to rewrite hardware status page */
 		   	I810_WRITE(0x02080, 0x1ffff000);
 		}
-	   	DRM(free)(dev->dev_private, sizeof(drm_i810_private_t),
+	   	drm_free(dev->dev_private, sizeof(drm_i810_private_t),
 			 DRM_MEM_DRIVER);
 	   	dev->dev_private = NULL;
 
@@ -263,7 +262,7 @@
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
 			if ( buf_priv->kernel_virtual && buf->total )
-				DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
+				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -334,7 +333,7 @@
 
 	   	*buf_priv->in_use = I810_BUF_FREE;
 
-		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address,
+		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address,
 							buf->total, dev);
 	}
 	return 0;
@@ -386,7 +385,7 @@
    	dev_priv->ring.End = init->ring_end;
    	dev_priv->ring.Size = init->ring_size;
 
-   	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base +
+   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base +
 						    init->ring_start,
 						    init->ring_size, dev);
 
@@ -510,7 +509,7 @@
 			if (retcode)
 				return retcode;
 
-	   		dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
+	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
 					     DRM_MEM_DRIVER);
 	   		if (dev_priv == NULL)
 				return -ENOMEM;
@@ -524,7 +523,7 @@
 					  sizeof(drm_i810_init_t))) {
 				return -EFAULT;
 			}
-	   		dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
+	   		dev_priv = drm_alloc(sizeof(drm_i810_private_t),
 					     DRM_MEM_DRIVER);
 			if (dev_priv == NULL) 
 				return -ENOMEM;
@@ -1388,35 +1387,20 @@
    	return 0;
 }
 
-static void i810_driver_pretakedown(drm_device_t *dev)
+void i810_driver_pretakedown(drm_device_t *dev)
 {
 	i810_dma_cleanup( dev );
 }
 
-static void i810_driver_release(drm_device_t *dev, struct file *filp)
+void i810_driver_release(drm_device_t *dev, struct file *filp)
 {
 	i810_reclaim_buffers(filp);
 }
 
-static int i810_driver_dma_quiescent(drm_device_t *dev)
+int i810_driver_dma_quiescent(drm_device_t *dev)
 {
 	i810_dma_quiescent( dev );
 	return 0;
 }
 
-void i810_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE;
-	dev->dev_priv_size = sizeof(drm_i810_buf_priv_t);
-	dev->fn_tbl.pretakedown = i810_driver_pretakedown;
-	dev->fn_tbl.release = i810_driver_release;
-	dev->fn_tbl.dma_quiescent = i810_driver_dma_quiescent;
-	dev->fn_tbl.reclaim_buffers = i810_reclaim_buffers;
-
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-}
 
diff -Nru a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
--- a/drivers/char/drm/i810_drm.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i810_drm.h	2004-11-09 00:25:55 -08:00
@@ -199,21 +199,37 @@
 /* i810 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I810_INIT		DRM_IOW( 0x40, drm_i810_init_t)
-#define DRM_IOCTL_I810_VERTEX		DRM_IOW( 0x41, drm_i810_vertex_t)
-#define DRM_IOCTL_I810_CLEAR		DRM_IOW( 0x42, drm_i810_clear_t)
-#define DRM_IOCTL_I810_FLUSH		DRM_IO(  0x43)
-#define DRM_IOCTL_I810_GETAGE		DRM_IO(  0x44)
-#define DRM_IOCTL_I810_GETBUF		DRM_IOWR(0x45, drm_i810_dma_t)
-#define DRM_IOCTL_I810_SWAP		DRM_IO(  0x46)
-#define DRM_IOCTL_I810_COPY		DRM_IOW( 0x47, drm_i810_copy_t)
-#define DRM_IOCTL_I810_DOCOPY		DRM_IO(  0x48)
-#define DRM_IOCTL_I810_OV0INFO		DRM_IOR( 0x49, drm_i810_overlay_t)
-#define DRM_IOCTL_I810_FSTATUS		DRM_IO ( 0x4a)
-#define DRM_IOCTL_I810_OV0FLIP		DRM_IO ( 0x4b)
-#define DRM_IOCTL_I810_MC		DRM_IOW( 0x4c, drm_i810_mc_t)
-#define DRM_IOCTL_I810_RSTATUS		DRM_IO ( 0x4d )
-#define DRM_IOCTL_I810_FLIP             DRM_IO ( 0x4e )
+#define DRM_I810_INIT		0x00
+#define DRM_I810_VERTEX		0x01
+#define DRM_I810_CLEAR		0x02
+#define DRM_I810_FLUSH		0x03
+#define DRM_I810_GETAGE		0x04
+#define DRM_I810_GETBUF		0x05
+#define DRM_I810_SWAP		0x06
+#define DRM_I810_COPY		0x07
+#define DRM_I810_DOCOPY		0x08
+#define DRM_I810_OV0INFO	0x09
+#define DRM_I810_FSTATUS	0x0a
+#define DRM_I810_OV0FLIP	0x0b
+#define DRM_I810_MC		0x0c
+#define DRM_I810_RSTATUS	0x0d
+#define DRM_I810_FLIP		0x0e
+
+#define DRM_IOCTL_I810_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_INIT, drm_i810_init_t)
+#define DRM_IOCTL_I810_VERTEX		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
+#define DRM_IOCTL_I810_CLEAR		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_CLEAR, drm_i810_clear_t)
+#define DRM_IOCTL_I810_FLUSH		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_FLUSH)
+#define DRM_IOCTL_I810_GETAGE		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_GETAGE)
+#define DRM_IOCTL_I810_GETBUF		DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
+#define DRM_IOCTL_I810_SWAP		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_SWAP)
+#define DRM_IOCTL_I810_COPY		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_COPY, drm_i810_copy_t)
+#define DRM_IOCTL_I810_DOCOPY		DRM_IO(  DRM_COMMAND_BASE + DRM_I810_DOCOPY)
+#define DRM_IOCTL_I810_OV0INFO		DRM_IOR( DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
+#define DRM_IOCTL_I810_FSTATUS		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FSTATUS)
+#define DRM_IOCTL_I810_OV0FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_OV0FLIP)
+#define DRM_IOCTL_I810_MC		DRM_IOW( DRM_COMMAND_BASE + DRM_I810_MC, drm_i810_mc_t)
+#define DRM_IOCTL_I810_RSTATUS		DRM_IO ( DRM_COMMAND_BASE + DRM_I810_RSTATUS)
+#define DRM_IOCTL_I810_FLIP             DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FLIP)
 
 typedef struct _drm_i810_clear {
 	int clear_color;
diff -Nru a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
--- a/drivers/char/drm/i810_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i810_drv.c	2004-11-09 00:25:55 -08:00
@@ -31,10 +31,110 @@
  */
 
 #include <linux/config.h>
-#include "i810.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i810_drm.h"
 #include "i810_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	/* i810 has 4 more counters */
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	i810_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I810_INIT)]    = { i810_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_I810_VERTEX)]  = { i810_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_CLEAR)]   = { i810_clear_bufs,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FLUSH)]   = { i810_flush_ioctl, 1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_GETAGE)]  = { i810_getage,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_GETBUF)]  = { i810_getbuf,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_SWAP)]    = { i810_swap_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_COPY)]    = { i810_copybuf,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_DOCOPY)]  = { i810_docopy,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_OV0INFO)] = { i810_ov0_info,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FSTATUS)] = { i810_fstatus,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_OV0FLIP)] = { i810_ov0_flip,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_MC)]      = { i810_dma_mc,      1, 1 },
+	[DRM_IOCTL_NR(DRM_I810_RSTATUS)] = { i810_rstatus,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I810_FLIP)]    = { i810_flip_bufs,   1, 0 }
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+	.dev_priv_size = sizeof(drm_i810_buf_priv_t),
+	.pretakedown = i810_driver_pretakedown,
+	.release = i810_driver_release,
+	.dma_quiescent = i810_driver_dma_quiescent,
+	.reclaim_buffers = i810_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = i810_mmap_buffers,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	},
+};
+
+static int __init i810_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit i810_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i810_init);
+module_exit(i810_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
--- a/drivers/char/drm/i810_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i810_drv.h	2004-11-09 00:25:55 -08:00
@@ -32,6 +32,29 @@
 #ifndef _I810_DRV_H_
 #define _I810_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i810"
+#define DRIVER_DESC		"Intel i810"
+#define DRIVER_DATE		"20030605"
+
+/* Interface history
+ *
+ * 1.1   - XFree86 4.1
+ * 1.2   - XvMC interfaces
+ *       - XFree86 4.2
+ * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
+ *       - Remove requirement for interrupt (leave stubs again)
+ * 1.3   - Add page flipping.
+ * 1.4   - fix DRM interface
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		4
+#define DRIVER_PATCHLEVEL	0
+
 typedef struct drm_i810_buf_priv {
    	u32 *in_use;
    	int my_use_idx;
@@ -127,17 +150,21 @@
 
 extern void i810_dma_quiescent(drm_device_t *dev);
 
-int i810_dma_vertex(struct inode *inode, struct file *filp,
+extern int i810_dma_vertex(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg);
 
-int i810_swap_bufs(struct inode *inode, struct file *filp,
+extern int i810_swap_bufs(struct inode *inode, struct file *filp,
 		   unsigned int cmd, unsigned long arg);
 
-int i810_clear_bufs(struct inode *inode, struct file *filp,
+extern int i810_clear_bufs(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long arg);
 
-int i810_flip_bufs(struct inode *inode, struct file *filp,
+extern int i810_flip_bufs(struct inode *inode, struct file *filp,
 		   unsigned int cmd, unsigned long arg);
+
+extern int i810_driver_dma_quiescent(drm_device_t *dev);
+extern void i810_driver_release(drm_device_t *dev, struct file *filp);
+extern void i810_driver_pretakedown(drm_device_t *dev);
 
 #define I810_BASE(reg)		((unsigned long) \
 				dev_priv->mmio_map->handle)
diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i830_dma.c	2004-11-09 00:25:55 -08:00
@@ -31,7 +31,6 @@
  *
  */
 
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
@@ -111,12 +110,12 @@
 }
 
 static struct file_operations i830_buffer_fops = {
-	.open	 = DRM(open),
-	.flush	 = DRM(flush),
-	.release = DRM(release),
-	.ioctl	 = DRM(ioctl),
+	.open	 = drm_open,
+	.flush	 = drm_flush,
+	.release = drm_release,
+	.ioctl	 = drm_ioctl,
 	.mmap	 = i830_mmap_buffers,
-	.fasync  = DRM(fasync),
+	.fasync  = drm_fasync,
 };
 
 int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
@@ -237,7 +236,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		int i;
@@ -245,7 +244,7 @@
 	     		(drm_i830_private_t *) dev->dev_private;
 	   
 	   	if (dev_priv->ring.virtual_start) {
-		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
 					 dev_priv->ring.Size, dev);
 		}
 	   	if (dev_priv->hw_status_page) {
@@ -256,7 +255,7 @@
 		   	I830_WRITE(0x02080, 0x1ffff000);
 		}
 
-	   	DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), 
+	   	drm_free(dev->dev_private, sizeof(drm_i830_private_t), 
 			 DRM_MEM_DRIVER);
 	   	dev->dev_private = NULL;
 
@@ -264,7 +263,7 @@
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i830_buf_priv_t *buf_priv = buf->dev_private;
 			if ( buf_priv->kernel_virtual && buf->total )
-				DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
+				drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -339,7 +338,7 @@
 
 	   	*buf_priv->in_use = I830_BUF_FREE;
 
-		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, 
+		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 
 							buf->total, dev);
 	}
 	return 0;
@@ -392,7 +391,7 @@
    	dev_priv->ring.End = init->ring_end;
    	dev_priv->ring.Size = init->ring_size;
 
-   	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + 
+   	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 
 						    init->ring_start, 
 						    init->ring_size, dev);
 
@@ -475,7 +474,7 @@
 	
    	switch(init.func) {
 	 	case I830_INIT_DMA:
-			dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), 
+			dev_priv = drm_alloc(sizeof(drm_i830_private_t), 
 					      DRM_MEM_DRIVER);
 	   		if(dev_priv == NULL) return -ENOMEM;
 	   		retcode = i830_dma_initialize(dev, dev_priv, &init);
@@ -1582,43 +1581,19 @@
 }
 
 
-static void i830_driver_pretakedown(drm_device_t *dev)
+void i830_driver_pretakedown(drm_device_t *dev)
 {
 	i830_dma_cleanup( dev );
 }
 
-static void i830_driver_release(drm_device_t *dev, struct file *filp)
+void i830_driver_release(drm_device_t *dev, struct file *filp)
 {
 	i830_reclaim_buffers(filp);
 }
 
-static int i830_driver_dma_quiescent(drm_device_t *dev)
+int i830_driver_dma_quiescent(drm_device_t *dev)
 {
 	i830_dma_quiescent( dev );
 	return 0;
-}
-
-void i830_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE;
-#if USE_IRQS
-	dev->driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ;
-#endif
-	dev->dev_priv_size = sizeof(drm_i830_buf_priv_t);
-	dev->fn_tbl.pretakedown = i830_driver_pretakedown;
-	dev->fn_tbl.release = i830_driver_release;
-	dev->fn_tbl.dma_quiescent = i830_driver_dma_quiescent;
-	dev->fn_tbl.reclaim_buffers = i830_reclaim_buffers;
-#if USE_IRQS
-	dev->fn_tbl.irq_preinstall = i830_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = i830_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = i830_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = i830_driver_irq_handler;
-#endif
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
 }
 
diff -Nru a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
--- a/drivers/char/drm/i830_drm.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i830_drm.h	2004-11-09 00:25:55 -08:00
@@ -251,20 +251,35 @@
 /* I830 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I830_INIT		DRM_IOW( 0x40, drm_i830_init_t)
-#define DRM_IOCTL_I830_VERTEX		DRM_IOW( 0x41, drm_i830_vertex_t)
-#define DRM_IOCTL_I830_CLEAR		DRM_IOW( 0x42, drm_i830_clear_t)
-#define DRM_IOCTL_I830_FLUSH		DRM_IO ( 0x43)
-#define DRM_IOCTL_I830_GETAGE		DRM_IO ( 0x44)
-#define DRM_IOCTL_I830_GETBUF		DRM_IOWR(0x45, drm_i830_dma_t)
-#define DRM_IOCTL_I830_SWAP		DRM_IO ( 0x46)
-#define DRM_IOCTL_I830_COPY		DRM_IOW( 0x47, drm_i830_copy_t)
-#define DRM_IOCTL_I830_DOCOPY		DRM_IO ( 0x48)
-#define DRM_IOCTL_I830_FLIP		DRM_IO ( 0x49)
-#define DRM_IOCTL_I830_IRQ_EMIT         DRM_IOWR(0x4a, drm_i830_irq_emit_t)
-#define DRM_IOCTL_I830_IRQ_WAIT         DRM_IOW( 0x4b, drm_i830_irq_wait_t)
-#define DRM_IOCTL_I830_GETPARAM         DRM_IOWR(0x4c, drm_i830_getparam_t)
-#define DRM_IOCTL_I830_SETPARAM         DRM_IOWR(0x4d, drm_i830_setparam_t)
+#define DRM_I830_INIT	0x00
+#define DRM_I830_VERTEX	0x01
+#define DRM_I830_CLEAR	0x02
+#define DRM_I830_FLUSH	0x03
+#define DRM_I830_GETAGE	0x04
+#define DRM_I830_GETBUF	0x05
+#define DRM_I830_SWAP	0x06
+#define DRM_I830_COPY	0x07
+#define DRM_I830_DOCOPY	0x08
+#define DRM_I830_FLIP	0x09
+#define DRM_I830_IRQ_EMIT	0x0a
+#define DRM_I830_IRQ_WAIT	0x0b
+#define DRM_I830_GETPARAM	0x0c
+#define DRM_I830_SETPARAM	0x0d
+
+#define DRM_IOCTL_I830_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t)
+#define DRM_IOCTL_I830_VERTEX		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t)
+#define DRM_IOCTL_I830_CLEAR		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t)
+#define DRM_IOCTL_I830_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH)
+#define DRM_IOCTL_I830_GETAGE		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE)
+#define DRM_IOCTL_I830_GETBUF		DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t)
+#define DRM_IOCTL_I830_SWAP		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP)
+#define DRM_IOCTL_I830_COPY		DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t)
+#define DRM_IOCTL_I830_DOCOPY		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY)
+#define DRM_IOCTL_I830_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP)
+#define DRM_IOCTL_I830_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t)
+#define DRM_IOCTL_I830_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t)
+#define DRM_IOCTL_I830_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t)
+#define DRM_IOCTL_I830_SETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t)
 
 typedef struct _drm_i830_clear {
 	int clear_color;
diff -Nru a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
--- a/drivers/char/drm/i830_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i830_drv.c	2004-11-09 00:25:55 -08:00
@@ -33,10 +33,118 @@
  */
 
 #include <linux/config.h>
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
 #include "i830_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	i830_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I830_INIT)]     = { i830_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_I830_VERTEX)]   = { i830_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_CLEAR)]    = { i830_clear_bufs,  1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_FLUSH)]    = { i830_flush_ioctl, 1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETAGE)]   = { i830_getage,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETBUF)]   = { i830_getbuf,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_SWAP)]     = { i830_swap_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_COPY)]     = { i830_copybuf,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_DOCOPY)]   = { i830_docopy,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_FLIP)]     = { i830_flip_bufs,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = { i830_irq_emit,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = { i830_irq_wait,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = { i830_getparam,    1, 0 },
+	[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = { i830_setparam,    1, 0 } 
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
+#if USE_IRQS
+	.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
+#endif
+	.dev_priv_size = sizeof(drm_i830_buf_priv_t),
+	.pretakedown = i830_driver_pretakedown,
+	.release = i830_driver_release,
+	.dma_quiescent = i830_driver_dma_quiescent,
+	.reclaim_buffers = i830_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+#if USE_IRQS
+	.irq_preinstall = i830_driver_irq_preinstall,
+	.irq_postinstall = i830_driver_irq_postinstall,
+	.irq_uninstall = i830_driver_irq_uninstall,
+	.irq_handler = i830_driver_irq_handler,
+#endif
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = i830_mmap_buffers,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+
+};
+
+static int __init i830_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit i830_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i830_init);
+module_exit(i830_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
--- a/drivers/char/drm/i830_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i830_drv.h	2004-11-09 00:25:55 -08:00
@@ -32,6 +32,36 @@
 #ifndef _I830_DRV_H_
 #define _I830_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i830"
+#define DRIVER_DESC		"Intel 830M"
+#define DRIVER_DATE		"20021108"
+
+/* Interface history:
+ *
+ * 1.1: Original.
+ * 1.2: ?
+ * 1.3: New irq emit/wait ioctls.
+ *      New pageflip ioctl.
+ *      New getparam ioctl.
+ *      State for texunits 3&4 in sarea.
+ *      New (alternative) layout for texture state.
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		3
+#define DRIVER_PATCHLEVEL	2
+
+/* Driver will work either way: IRQ's save cpu time when waiting for
+ * the card, but are subject to subtle interactions between bios,
+ * hardware and the driver.
+ */
+/* XXX: Add vblank support? */
+#define USE_IRQS 0
+
 typedef struct drm_i830_buf_priv {
    	u32 *in_use;
    	int my_use_idx;
@@ -140,6 +170,9 @@
 extern void i830_driver_irq_preinstall( drm_device_t *dev );
 extern void i830_driver_irq_postinstall( drm_device_t *dev );
 extern void i830_driver_irq_uninstall( drm_device_t *dev );
+extern void i830_driver_pretakedown(drm_device_t *dev);
+extern void i830_driver_release(drm_device_t *dev, struct file *filp);
+extern int i830_driver_dma_quiescent(drm_device_t *dev);
 
 #define I830_BASE(reg)		((unsigned long) \
 				dev_priv->mmio_map->handle)
diff -Nru a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
--- a/drivers/char/drm/i830_irq.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i830_irq.c	2004-11-09 00:25:55 -08:00
@@ -26,7 +26,6 @@
  *
  */
 
-#include "i830.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i830_drm.h"
diff -Nru a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
--- a/drivers/char/drm/i915_dma.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_dma.c	2004-11-09 00:25:55 -08:00
@@ -7,7 +7,6 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -84,7 +83,7 @@
 	 * is freed, it's too late.
 	 */
 	if (dev->irq)
-		DRM(irq_uninstall) (dev);
+		drm_irq_uninstall (dev);
 
 	if (dev->dev_private) {
 		drm_i915_private_t *dev_priv =
@@ -102,7 +101,7 @@
 			I915_WRITE(0x02080, 0x1ffff000);
 		}
 
-		DRM(free) (dev->dev_private, sizeof(drm_i915_private_t),
+		drm_free (dev->dev_private, sizeof(drm_i915_private_t),
 			   DRM_MEM_DRIVER);
 
 		dev->dev_private = NULL;
@@ -242,7 +241,7 @@
 
 	switch (init.func) {
 	case I915_INIT_DMA:
-		dev_priv = DRM(alloc) (sizeof(drm_i915_private_t),
+		dev_priv = drm_alloc (sizeof(drm_i915_private_t),
 				       DRM_MEM_DRIVER);
 		if (dev_priv == NULL)
 			return DRM_ERR(ENOMEM);
@@ -720,7 +719,7 @@
 	return 0;
 }
 
-static void i915_driver_pretakedown(drm_device_t *dev)
+void i915_driver_pretakedown(drm_device_t *dev)
 {
 	if ( dev->dev_private ) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
@@ -729,7 +728,7 @@
 	i915_dma_cleanup( dev );
 }
 
-static void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
@@ -737,19 +736,3 @@
 	}
 }
 
-void i915_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED;
-	dev->fn_tbl.pretakedown = i915_driver_pretakedown;
-	dev->fn_tbl.prerelease = i915_driver_prerelease;
-	dev->fn_tbl.irq_preinstall = i915_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = i915_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = i915_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = i915_driver_irq_handler;
-	
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-}
diff -Nru a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
--- a/drivers/char/drm/i915_drm.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_drm.h	2004-11-09 00:25:55 -08:00
@@ -61,18 +61,31 @@
 /* I915 specific ioctls
  * The device specific ioctl range is 0x40 to 0x79.
  */
-#define DRM_IOCTL_I915_INIT		DRM_IOW( 0x40, drm_i915_init_t)
-#define DRM_IOCTL_I915_FLUSH		DRM_IO ( 0x41)
-#define DRM_IOCTL_I915_FLIP		DRM_IO ( 0x42)
-#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( 0x43, drm_i915_batchbuffer_t)
-#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(0x44, drm_i915_irq_emit_t)
-#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( 0x45, drm_i915_irq_wait_t)
-#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(0x46, drm_i915_getparam_t)
-#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( 0x47, drm_i915_setparam_t)
-#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(0x48, drm_i915_mem_alloc_t)
-#define DRM_IOCTL_I915_FREE             DRM_IOW( 0x49, drm_i915_mem_free_t)
-#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( 0x4a, drm_i915_mem_init_heap_t)
-#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( 0x4b, drm_i915_cmdbuffer_t)
+#define DRM_I915_INIT		0x00
+#define DRM_I915_FLUSH		0x01
+#define DRM_I915_FLIP		0x02
+#define DRM_I915_BATCHBUFFER	0x03
+#define DRM_I915_IRQ_EMIT	0x04
+#define DRM_I915_IRQ_WAIT	0x05
+#define DRM_I915_GETPARAM	0x06
+#define DRM_I915_SETPARAM	0x07
+#define DRM_I915_ALLOC		0x08
+#define DRM_I915_FREE		0x09
+#define DRM_I915_INIT_HEAP	0x0a
+#define DRM_I915_CMDBUFFER	0x0b
+
+#define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
+#define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
+#define DRM_IOCTL_I915_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
+#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
+#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
+#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
+#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
+#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
+#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
+#define DRM_IOCTL_I915_FREE             DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
+#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
+#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
 
 /* Allow drivers to submit batchbuffers directly to hardware, relying
  * on the security mechanisms provided by hardware.
diff -Nru a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
--- a/drivers/char/drm/i915_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_drv.c	2004-11-09 00:25:55 -08:00
@@ -8,10 +8,109 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+	
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	i915_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I915_INIT)]        = { i915_dma_init,      1, 1 },
+	[DRM_IOCTL_NR(DRM_I915_FLUSH)]       = { i915_flush_ioctl,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_FLIP)]        = { i915_flip_bufs,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = { i915_batchbuffer,   1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)]    = { i915_irq_emit,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)]    = { i915_irq_wait,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_GETPARAM)]    = { i915_getparam,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_SETPARAM)]    = { i915_setparam,      1, 1 },
+	[DRM_IOCTL_NR(DRM_I915_ALLOC)]       = { i915_mem_alloc,     1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_FREE)]        = { i915_mem_free,      1, 0 },
+	[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)]   = { i915_mem_init_heap, 1, 1 },
+	[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)]   = { i915_cmdbuffer,     1, 0 }
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
+				DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
+	.pretakedown = i915_driver_pretakedown,
+	.prerelease = i915_driver_prerelease,
+	.irq_preinstall = i915_driver_irq_preinstall,
+	.irq_postinstall = i915_driver_irq_postinstall,
+	.irq_uninstall = i915_driver_irq_uninstall,
+	.irq_handler = i915_driver_irq_handler,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+};
+
+static int __init i915_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit i915_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(i915_init);
+module_exit(i915_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
--- a/drivers/char/drm/i915_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_drv.h	2004-11-09 00:25:55 -08:00
@@ -10,6 +10,28 @@
 #ifndef _I915_DRV_H_
 #define _I915_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Tungsten Graphics, Inc."
+
+#define DRIVER_NAME		"i915"
+#define DRIVER_DESC		"Intel Graphics"
+#define DRIVER_DATE		"20040405"
+
+/* Interface history:
+ *
+ * 1.1: Original.
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
+/* We use our own dma mechanisms, not the drm template code.  However,
+ * the shared IRQ code is useful to us:
+ */
+#define __HAVE_PM		1
+
 typedef struct _drm_i915_ring_buffer {
 	int tail_mask;
 	unsigned long Start;
@@ -66,6 +88,8 @@
 extern int i915_setparam(DRM_IOCTL_ARGS);
 extern int i915_cmdbuffer(DRM_IOCTL_ARGS);
 extern void i915_kernel_lost_context(drm_device_t * dev);
+extern void i915_driver_pretakedown(drm_device_t *dev);
+extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
 
 /* i915_irq.c */
 extern int i915_irq_emit(DRM_IOCTL_ARGS);
diff -Nru a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
--- a/drivers/char/drm/i915_irq.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_irq.c	2004-11-09 00:25:55 -08:00
@@ -7,7 +7,6 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
diff -Nru a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
--- a/drivers/char/drm/i915_mem.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/i915_mem.c	2004-11-09 00:25:55 -08:00
@@ -7,7 +7,6 @@
  * 
  **************************************************************************/
 
-#include "i915.h"
 #include "drmP.h"
 #include "drm.h"
 #include "i915_drm.h"
@@ -75,7 +74,7 @@
 {
 	/* Maybe cut off the start of an existing block */
 	if (start > p->start) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
 		if (!newblock)
 			goto out;
 		newblock->start = start;
@@ -91,7 +90,7 @@
 
 	/* Maybe cut off the end of an existing block */
 	if (size < p->size) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
 		if (!newblock)
 			goto out;
 		newblock->start = start + size;
@@ -148,7 +147,7 @@
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 
 	if (p->prev->filp == NULL) {
@@ -156,7 +155,7 @@
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 }
 
@@ -164,14 +163,14 @@
  */
 static int init_heap(struct mem_block **heap, int start, int size)
 {
-	struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFLISTS);
 
 	if (!blocks)
 		return -ENOMEM;
 
-	*heap = DRM_MALLOC(sizeof(**heap));
+	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS);
 	if (!*heap) {
-		DRM_FREE(blocks, sizeof(*blocks));
+		drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS);
 		return -ENOMEM;
 	}
 
@@ -211,7 +210,7 @@
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 		}
 	}
 }
@@ -228,10 +227,10 @@
 	for (p = (*heap)->next; p != *heap;) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
 	}
 
-	DRM_FREE(*heap, sizeof(**heap));
+	drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS);
 	*heap = NULL;
 }
 
diff -Nru a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
--- a/drivers/char/drm/mga_dma.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_dma.c	2004-11-09 00:25:55 -08:00
@@ -33,7 +33,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
@@ -308,7 +307,7 @@
 	int i;
 	DRM_DEBUG( "count=%d\n", dma->buf_count );
 
-	dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
+	dev_priv->head = drm_alloc( sizeof(drm_mga_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
 		return DRM_ERR(ENOMEM);
@@ -320,7 +319,7 @@
 		buf = dma->buflist[i];
 	        buf_priv = buf->dev_private;
 
-		entry = DRM(alloc)( sizeof(drm_mga_freelist_t),
+		entry = drm_alloc( sizeof(drm_mga_freelist_t),
 				    DRM_MEM_DRIVER );
 		if ( entry == NULL )
 			return DRM_ERR(ENOMEM);
@@ -357,7 +356,7 @@
 	entry = dev_priv->head;
 	while ( entry ) {
 		next = entry->next;
-		DRM(free)( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
+		drm_free( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
 		entry = next;
 	}
 
@@ -458,7 +457,7 @@
 	int ret;
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
+	dev_priv = drm_alloc( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
 	if ( !dev_priv )
 		return DRM_ERR(ENOMEM);
 
@@ -634,7 +633,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if ( dev->dev_private ) {
 		drm_mga_private_t *dev_priv = dev->dev_private;
@@ -650,7 +649,7 @@
 			mga_freelist_cleanup( dev );
 		}
 
-		DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),
+		drm_free( dev->dev_private, sizeof(drm_mga_private_t),
 			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
@@ -798,30 +797,13 @@
 	return ret;
 }
 
-static void mga_driver_pretakedown(drm_device_t *dev)
+void mga_driver_pretakedown(drm_device_t *dev)
 {
 	mga_do_cleanup_dma( dev );
 }
 
-static int mga_driver_dma_quiescent(drm_device_t *dev)
+int mga_driver_dma_quiescent(drm_device_t *dev)
 {
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	return mga_do_wait_for_idle( dev_priv );
-}
-
-void mga_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->fn_tbl.pretakedown = mga_driver_pretakedown;
-	dev->fn_tbl.dma_quiescent = mga_driver_dma_quiescent;
-	dev->fn_tbl.vblank_wait = mga_driver_vblank_wait;
-	dev->fn_tbl.irq_preinstall = mga_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = mga_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = mga_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = mga_driver_irq_handler;
-	
-	dev->counters += 3;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
 }
diff -Nru a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
--- a/drivers/char/drm/mga_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_drv.c	2004-11-09 00:25:55 -08:00
@@ -30,9 +30,108 @@
  */
 
 #include <linux/config.h>
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
-#include "drm_core.h"
+
+  
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	dev->counters += 3;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	mga_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_MGA_INIT)]    = { mga_dma_init,    1, 1 },
+	[DRM_IOCTL_NR(DRM_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_RESET)]   = { mga_dma_reset,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_SWAP)]    = { mga_dma_swap,    1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_INDICES)] = { mga_dma_indices, 1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_BLIT)]    = { mga_dma_blit,    1, 0 },
+	[DRM_IOCTL_NR(DRM_MGA_GETPARAM)]= { mga_getparam,    1, 0 },
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.pretakedown = mga_driver_pretakedown,
+	.dma_quiescent = mga_driver_dma_quiescent,
+	.vblank_wait = mga_driver_vblank_wait,
+	.irq_preinstall = mga_driver_irq_preinstall,
+	.irq_postinstall = mga_driver_irq_postinstall,
+	.irq_uninstall = mga_driver_irq_uninstall,
+	.irq_handler = mga_driver_irq_handler,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.dma_ioctl = mga_dma_buffers,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name = DRIVER_NAME,
+		.id_table = pciidlist,
+	}
+};
+
+static int __init mga_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit mga_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(mga_init);
+module_exit(mga_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
--- a/drivers/char/drm/mga_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_drv.h	2004-11-09 00:25:55 -08:00
@@ -31,6 +31,19 @@
 #ifndef __MGA_DRV_H__
 #define __MGA_DRV_H__
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"mga"
+#define DRIVER_DESC		"Matrox G200/G400"
+#define DRIVER_DATE		"20021029"
+
+#define DRIVER_MAJOR		3
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
 typedef struct drm_mga_primary_buffer {
 	u8 *start;
 	u8 *end;
@@ -104,6 +117,8 @@
 extern int mga_dma_flush( DRM_IOCTL_ARGS );
 extern int mga_dma_reset( DRM_IOCTL_ARGS );
 extern int mga_dma_buffers( DRM_IOCTL_ARGS );
+extern void mga_driver_pretakedown(drm_device_t *dev);
+extern int mga_driver_dma_quiescent(drm_device_t *dev);
 
 extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
 extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
diff -Nru a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
--- a/drivers/char/drm/mga_irq.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_irq.c	2004-11-09 00:25:55 -08:00
@@ -30,7 +30,6 @@
  *    Eric Anholt <anholt@FreeBSD.org>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
@@ -50,7 +49,7 @@
 		MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
diff -Nru a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
--- a/drivers/char/drm/mga_state.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_state.c	2004-11-09 00:25:55 -08:00
@@ -32,7 +32,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
diff -Nru a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
--- a/drivers/char/drm/mga_warp.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/mga_warp.c	2004-11-09 00:25:55 -08:00
@@ -27,7 +27,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
--- a/drivers/char/drm/r128_cce.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/r128_cce.c	2004-11-09 00:25:55 -08:00
@@ -28,11 +28,11 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
+#include "ati_pcigart.h"
 
 #define R128_FIFO_DEBUG		0
 
@@ -355,7 +355,7 @@
 
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
+	dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
 		return DRM_ERR(ENOMEM);
 
@@ -544,7 +544,7 @@
 	dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
 			      + init->ring_size / sizeof(u32));
 	dev_priv->ring.size = init->ring_size;
-	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
+	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
 
 	dev_priv->ring.tail_mask =
 		(dev_priv->ring.size / sizeof(u32)) - 1;
@@ -561,7 +561,7 @@
 #if __OS_HAS_AGP
 	if ( dev_priv->is_pci ) {
 #endif
-		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
      					    &dev_priv->bus_pci_gart) ) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
@@ -590,7 +590,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
@@ -606,13 +606,13 @@
 		} else
 #endif
 		{
-			if (!DRM(ati_pcigart_cleanup)( dev,
+			if (!drm_ati_pcigart_cleanup( dev,
 						dev_priv->phys_pci_gart,
 						dev_priv->bus_pci_gart ))
 				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
-		DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
+		drm_free( dev->dev_private, sizeof(drm_r128_private_t),
 			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
@@ -771,7 +771,7 @@
 	drm_r128_freelist_t *entry;
 	int i;
 
-	dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t),
+	dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
 		return DRM_ERR(ENOMEM);
@@ -783,7 +783,7 @@
 		buf = dma->buflist[i];
 		buf_priv = buf->dev_private;
 
-		entry = DRM(alloc)( sizeof(drm_r128_freelist_t),
+		entry = drm_alloc( sizeof(drm_r128_freelist_t),
 				    DRM_MEM_DRIVER );
 		if ( !entry ) return DRM_ERR(ENOMEM);
 
diff -Nru a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
--- a/drivers/char/drm/r128_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/r128_drv.c	2004-11-09 00:25:55 -08:00
@@ -30,11 +30,117 @@
  */
 
 #include <linux/config.h>
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
 #include "ati_pcigart.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	r128_PCI_IDS
+};
+
+/* Interface history:
+ *
+ * ??  - ??
+ * 2.4 - Add support for ycbcr textures (no new ioctls)
+ * 2.5 - Add FLIP ioctl, disable FULLSCREEN.
+ */
+static drm_ioctl_desc_t ioctls[] = {
+   [DRM_IOCTL_NR(DRM_R128_INIT)]       = { r128_cce_init,     1, 1 },
+   [DRM_IOCTL_NR(DRM_R128_CCE_START)]  = { r128_cce_start,    1, 1 },
+   [DRM_IOCTL_NR(DRM_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 },
+   [DRM_IOCTL_NR(DRM_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 },
+   [DRM_IOCTL_NR(DRM_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_RESET)]      = { r128_engine_reset, 1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_SWAP)]       = { r128_cce_swap,     1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_FLIP)]       = { r128_cce_flip,     1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_CLEAR)]      = { r128_cce_clear,    1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_INDICES)]    = { r128_cce_indices,  1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_BLIT)]       = { r128_cce_blit,     1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_DEPTH)]      = { r128_cce_depth,    1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 },
+   [DRM_IOCTL_NR(DRM_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
+   [DRM_IOCTL_NR(DRM_R128_GETPARAM)]   = { r128_getparam, 1, 0 },
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.dev_priv_size = sizeof(drm_r128_buf_priv_t),
+	.prerelease = r128_driver_prerelease,
+	.pretakedown = r128_driver_pretakedown,
+	.vblank_wait = r128_driver_vblank_wait,
+	.irq_preinstall = r128_driver_irq_preinstall,
+	.irq_postinstall = r128_driver_irq_postinstall,
+	.irq_uninstall = r128_driver_irq_uninstall,
+	.irq_handler = r128_driver_irq_handler,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.dma_ioctl = r128_cce_buffers,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+};
+
+static int __init r128_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit r128_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(r128_init);
+module_exit(r128_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
--- a/drivers/char/drm/r128_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/r128_drv.h	2004-11-09 00:25:55 -08:00
@@ -28,12 +28,25 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *    Michel Dänzer <daenzerm@student.ethz.ch>
+ *    Michel Dï¿½zer <daenzerm@student.ethz.ch>
  */
 
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
+/* General customization:
+ */
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"r128"
+#define DRIVER_DESC		"ATI Rage 128"
+#define DRIVER_DATE		"20030725"
+
+#define DRIVER_MAJOR		2
+#define DRIVER_MINOR		5
+#define DRIVER_PATCHLEVEL	0
+
+
 #define GET_RING_HEAD(dev_priv)		R128_READ( R128_PM4_BUFFER_DL_RPTR )
 
 typedef struct drm_r128_freelist {
@@ -148,6 +161,8 @@
 extern void r128_driver_irq_preinstall( drm_device_t *dev );
 extern void r128_driver_irq_postinstall( drm_device_t *dev );
 extern void r128_driver_irq_uninstall( drm_device_t *dev );
+extern void r128_driver_pretakedown(drm_device_t *dev);
+extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
 
 /* Register definitions, register access macros and drmAddMap constants
  * for Rage 128 kernel driver.
diff -Nru a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
--- a/drivers/char/drm/r128_irq.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/r128_irq.c	2004-11-09 00:25:55 -08:00
@@ -30,7 +30,6 @@
  *    Eric Anholt <anholt@FreeBSD.org>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
@@ -50,7 +49,7 @@
 		R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
diff -Nru a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
--- a/drivers/char/drm/r128_state.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/r128_state.c	2004-11-09 00:25:55 -08:00
@@ -27,7 +27,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
@@ -926,24 +925,24 @@
 	}
 
 	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
 	if ( buffer == NULL )
 		return DRM_ERR(ENOMEM);
 	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( buffer, buffer_size);
+		drm_free( buffer, buffer_size, DRM_MEM_BUFS);
 		return DRM_ERR(EFAULT);
 	}
 
 	mask_size = depth->n * sizeof(u8);
 	if ( depth->mask ) {
-		mask = DRM_MALLOC( mask_size );
+		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
 		if ( mask == NULL ) {
-			DRM_FREE( buffer, buffer_size );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 			return DRM_ERR(ENOMEM);
 		}
 		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
+			drm_free( mask, mask_size, DRM_MEM_BUFS );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -970,7 +969,7 @@
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		drm_free( mask, mask_size, DRM_MEM_BUFS );
 	} else {
 		for ( i = 0 ; i < count ; i++, x++ ) {
 			BEGIN_RING( 6 );
@@ -994,7 +993,7 @@
 		}
 	}
 
-	DRM_FREE( buffer, buffer_size );
+	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1016,54 +1015,54 @@
 
 	xbuf_size = count * sizeof(*x);
 	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 	if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
 	buffer_size = depth->n * sizeof(u32);
-	buffer = DRM_MALLOC( buffer_size );
+	buffer = drm_alloc( buffer_size, DRM_MEM_BUFS );
 	if ( buffer == NULL ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
-		DRM_FREE( buffer, buffer_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
+		drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
 		mask_size = depth->n * sizeof(u8);
-		mask = DRM_MALLOC( mask_size );
+		mask = drm_alloc( mask_size, DRM_MEM_BUFS );
 		if ( mask == NULL ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
+			drm_free( x, xbuf_size, DRM_MEM_BUFS );
+			drm_free( y, ybuf_size, DRM_MEM_BUFS );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 			return DRM_ERR(ENOMEM);
 		}
 		if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
-			DRM_FREE( x, xbuf_size );
-			DRM_FREE( y, ybuf_size );
-			DRM_FREE( buffer, buffer_size );
-			DRM_FREE( mask, mask_size );
+			drm_free( x, xbuf_size, DRM_MEM_BUFS  );
+			drm_free( y, ybuf_size, DRM_MEM_BUFS  );
+			drm_free( buffer, buffer_size, DRM_MEM_BUFS  );
+			drm_free( mask, mask_size, DRM_MEM_BUFS  );
 			return DRM_ERR(EFAULT);
 		}
 
@@ -1090,7 +1089,7 @@
 			}
 		}
 
-		DRM_FREE( mask, mask_size );
+		drm_free( mask, mask_size, DRM_MEM_BUFS );
 	} else {
 		for ( i = 0 ; i < count ; i++ ) {
 			BEGIN_RING( 6 );
@@ -1114,9 +1113,9 @@
 		}
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
-	DRM_FREE( buffer, buffer_size );
+	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+	drm_free( y, ybuf_size, DRM_MEM_BUFS );
+	drm_free( buffer, buffer_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1184,23 +1183,23 @@
 
 	xbuf_size = count * sizeof(*x);
 	ybuf_size = count * sizeof(*y);
-	x = DRM_MALLOC( xbuf_size );
+	x = drm_alloc( xbuf_size, DRM_MEM_BUFS );
 	if ( x == NULL ) {
 		return DRM_ERR(ENOMEM);
 	}
-	y = DRM_MALLOC( ybuf_size );
+	y = drm_alloc( ybuf_size, DRM_MEM_BUFS );
 	if ( y == NULL ) {
-		DRM_FREE( x, xbuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 	if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 	if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
-		DRM_FREE( x, xbuf_size );
-		DRM_FREE( y, ybuf_size );
+		drm_free( x, xbuf_size, DRM_MEM_BUFS );
+		drm_free( y, ybuf_size, DRM_MEM_BUFS );
 		return DRM_ERR(EFAULT);
 	}
 
@@ -1228,8 +1227,8 @@
 		ADVANCE_RING();
 	}
 
-	DRM_FREE( x, xbuf_size );
-	DRM_FREE( y, ybuf_size );
+	drm_free( x, xbuf_size, DRM_MEM_BUFS );
+	drm_free( y, ybuf_size, DRM_MEM_BUFS );
 
 	return 0;
 }
@@ -1695,7 +1694,7 @@
 	return 0;
 }
 
-static void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1705,20 +1704,8 @@
 	}			
 }
 
-static void r128_driver_pretakedown(drm_device_t *dev)
+void r128_driver_pretakedown(drm_device_t *dev)
 {
 	r128_do_cleanup_cce( dev );
 }
 
-void r128_driver_register_fns(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->dev_priv_size = sizeof(drm_r128_buf_priv_t);
-	dev->fn_tbl.prerelease = r128_driver_prerelease;
-	dev->fn_tbl.pretakedown = r128_driver_pretakedown;
-	dev->fn_tbl.vblank_wait = r128_driver_vblank_wait;
-	dev->fn_tbl.irq_preinstall = r128_driver_irq_preinstall;
-	dev->fn_tbl.irq_postinstall = r128_driver_irq_postinstall;
-	dev->fn_tbl.irq_uninstall = r128_driver_irq_uninstall;
-	dev->fn_tbl.irq_handler = r128_driver_irq_handler;
-}
diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
--- a/drivers/char/drm/radeon_cp.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_cp.c	2004-11-09 00:25:55 -08:00
@@ -28,11 +28,11 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
+#include "ati_pcigart.h"
 
 #define RADEON_FIFO_DEBUG	0
 
@@ -1006,7 +1006,7 @@
 	drm_radeon_private_t *dev_priv;
 	DRM_DEBUG( "\n" );
 
-	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
+	dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
 		return DRM_ERR(ENOMEM);
 
@@ -1233,7 +1233,7 @@
 	dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
 			      + init->ring_size / sizeof(u32));
 	dev_priv->ring.size = init->ring_size;
-	dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
+	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
 
 	dev_priv->ring.tail_mask =
 		(dev_priv->ring.size / sizeof(u32)) - 1;
@@ -1247,7 +1247,7 @@
 	} else
 #endif
 	{
-		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,
 					    &dev_priv->bus_pci_gart)) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
@@ -1279,7 +1279,7 @@
 	 * may not have been called from userspace and after dev_private
 	 * is freed, it's too late.
 	 */
-	if ( dev->irq_enabled ) DRM(irq_uninstall)(dev);
+	if ( dev->irq_enabled ) drm_irq_uninstall(dev);
 
 	if ( dev->dev_private ) {
 		drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1295,13 +1295,13 @@
 		} else
 #endif
 		{
-			if (!DRM(ati_pcigart_cleanup)( dev,
+			if (!drm_ati_pcigart_cleanup( dev,
 						dev_priv->phys_pci_gart,
 						dev_priv->bus_pci_gart ))
 				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
-		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
+		drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
 			   DRM_MEM_DRIVER );
 		dev->dev_private = NULL;
 	}
diff -Nru a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
--- a/drivers/char/drm/radeon_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_drv.c	2004-11-09 00:25:55 -08:00
@@ -31,11 +31,154 @@
 
 
 #include <linux/config.h>
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 #include "ati_pcigart.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	radeon_PCI_IDS
+};
+
+/* Interface history:
+ *
+ * 1.1 - ??
+ * 1.2 - Add vertex2 ioctl (keith)
+ *     - Add stencil capability to clear ioctl (gareth, keith)
+ *     - Increase MAX_TEXTURE_LEVELS (brian)
+ * 1.3 - Add cmdbuf ioctl (keith)
+ *     - Add support for new radeon packets (keith)
+ *     - Add getparam ioctl (keith)
+ *     - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
+ * 1.4 - Add scratch registers to get_param ioctl.
+ * 1.5 - Add r200 packets to cmdbuf ioctl
+ *     - Add r200 function to init ioctl
+ *     - Add 'scalar2' instruction to cmdbuf
+ * 1.6 - Add static GART memory manager
+ *       Add irq handler (won't be turned on unless X server knows to)
+ *       Add irq ioctls and irq_active getparam.
+ *       Add wait command for cmdbuf ioctl
+ *       Add GART offset query for getparam
+ * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
+ *       and R200_PP_CUBIC_OFFSET_F1_[0..5].
+ *       Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
+ *       R200_EMIT_PP_CUBIC_OFFSETS_[0..5].  (brian)
+ * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
+ *       Add 'GET' queries for starting additional clients on different VT's.
+ * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
+ *       Add texture rectangle support for r100.
+ * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
+ *       clients use to tell the DRM where they think the framebuffer is 
+ *       located in the card's address space
+ * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
+ *       and GL_EXT_blend_[func|equation]_separate on r200
+ */
+static drm_ioctl_desc_t ioctls[] = {
+ [DRM_IOCTL_NR(DRM_RADEON_CP_INIT)]    = { radeon_cp_init,      1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_CP_START)]   = { radeon_cp_start,     1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_CP_STOP)]    = { radeon_cp_stop,      1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESET)]   = { radeon_cp_reset,     1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_CP_IDLE)]    = { radeon_cp_idle,      1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_CP_RESUME)]  = { radeon_cp_resume,    1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_RESET)]      = { radeon_engine_reset, 1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_FULLSCREEN)] = { radeon_fullscreen,   1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_SWAP)]       = { radeon_cp_swap,      1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_CLEAR)]      = { radeon_cp_clear,     1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX)]     = { radeon_cp_vertex,    1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_INDICES)]    = { radeon_cp_indices,   1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_TEXTURE)]    = { radeon_cp_texture,   1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_STIPPLE)]    = { radeon_cp_stipple,   1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_INDIRECT)]   = { radeon_cp_indirect,  1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_VERTEX2)]    = { radeon_cp_vertex2,   1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,    1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_GETPARAM)]   = { radeon_cp_getparam,  1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_FLIP)]       = { radeon_cp_flip,      1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_ALLOC)]      = { radeon_mem_alloc,    1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_FREE)]       = { radeon_mem_free,     1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_INIT_HEAP)]  = { radeon_mem_init_heap,1, 1 },
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_EMIT)]   = { radeon_irq_emit,     1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_IRQ_WAIT)]   = { radeon_irq_wait,     1, 0 },
+ [DRM_IOCTL_NR(DRM_RADEON_SETPARAM)]   = { radeon_cp_setparam,  1, 0 },
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
+	.prerelease = radeon_driver_prerelease,
+	.pretakedown = radeon_driver_pretakedown,
+	.open_helper = radeon_driver_open_helper,
+	.vblank_wait = radeon_driver_vblank_wait,
+	.irq_preinstall = radeon_driver_irq_preinstall,
+	.irq_postinstall = radeon_driver_irq_postinstall,
+	.irq_uninstall = radeon_driver_irq_uninstall,
+	.irq_handler = radeon_driver_irq_handler,
+	.free_filp_priv = radeon_driver_free_filp_priv,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.dma_ioctl = radeon_cp_buffers,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+};
+
+static int __init radeon_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit radeon_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(radeon_init);
+module_exit(radeon_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
--- a/drivers/char/drm/radeon_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_drv.h	2004-11-09 00:25:55 -08:00
@@ -31,6 +31,19 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"Gareth Hughes, Keith Whitwell, others."
+
+#define DRIVER_NAME		"radeon"
+#define DRIVER_DESC		"ATI Radeon"
+#define DRIVER_DATE		"20020828"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		11
+#define DRIVER_PATCHLEVEL	0
+
 #define GET_RING_HEAD(dev_priv)		DRM_READ32(  (dev_priv)->ring_rptr, 0 )
 #define SET_RING_HEAD(dev_priv,val)	DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
 
@@ -210,6 +223,14 @@
 extern void radeon_driver_irq_preinstall( drm_device_t *dev );
 extern void radeon_driver_irq_postinstall( drm_device_t *dev );
 extern void radeon_driver_irq_uninstall( drm_device_t *dev );
+extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp);
+extern void radeon_driver_pretakedown(drm_device_t *dev);
+extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv);
+extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv);
+
+extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
+extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
+extern int radeon_postcleanup( struct drm_device *dev );
 
 /* Flags for stats.boxes
  */
diff -Nru a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
--- a/drivers/char/drm/radeon_irq.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_irq.c	2004-11-09 00:25:55 -08:00
@@ -27,10 +27,9 @@
  *
  * Authors:
  *    Keith Whitwell <keith@tungstengraphics.com>
- *    Michel Dänzer <michel@daenzer.net>
+ *    Michel Dï¿½zer <michel@daenzer.net>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -78,7 +77,7 @@
 	if (stat & RADEON_CRTC_VBLANK_STAT) {
 		atomic_inc(&dev->vbl_received);
 		DRM_WAKEUP(&dev->vbl_queue);
-		DRM(vbl_send_signals)( dev );
+		drm_vbl_send_signals( dev );
 	}
 
 	/* Acknowledge interrupts we handle */
@@ -223,7 +222,7 @@
 
 /* drm_dma.h hooks
 */
-void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
+void radeon_driver_irq_preinstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 
@@ -234,7 +233,7 @@
 	radeon_acknowledge_irqs( dev_priv );
 }
 
-void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
+void radeon_driver_irq_postinstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 
@@ -247,7 +246,7 @@
 		      RADEON_SW_INT_ENABLE );
 }
 
-void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
+void radeon_driver_irq_uninstall( drm_device_t *dev ) {
 	drm_radeon_private_t *dev_priv =
 		(drm_radeon_private_t *)dev->dev_private;
 	if (!dev_priv)
diff -Nru a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
--- a/drivers/char/drm/radeon_mem.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_mem.c	2004-11-09 00:25:55 -08:00
@@ -29,7 +29,6 @@
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
@@ -44,7 +43,7 @@
 {
 	/* Maybe cut off the start of an existing block */
 	if (start > p->start) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
 		if (!newblock) 
 			goto out;
 		newblock->start = start;
@@ -60,7 +59,7 @@
    
 	/* Maybe cut off the end of an existing block */
 	if (size < p->size) {
-		struct mem_block *newblock = DRM_MALLOC(sizeof(*newblock));
+		struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
 		if (!newblock)
 			goto out;
 		newblock->start = start + size;
@@ -118,7 +117,7 @@
 		p->size += q->size;
 		p->next = q->next;
 		p->next->prev = p;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q), DRM_MEM_BUFS );
 	}
 
 	if (p->prev->filp == 0) {
@@ -126,7 +125,7 @@
 		q->size += p->size;
 		q->next = p->next;
 		q->next->prev = q;
-		DRM_FREE(p, sizeof(*q));
+		drm_free(p, sizeof(*q), DRM_MEM_BUFS );
 	}
 }
 
@@ -134,14 +133,14 @@
  */
 static int init_heap(struct mem_block **heap, int start, int size)
 {
-	struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
+	struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS );
 
 	if (!blocks) 
 		return DRM_ERR(ENOMEM);
 	
-	*heap = DRM_MALLOC(sizeof(**heap));
+	*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS );
 	if (!*heap) {
-		DRM_FREE( blocks, sizeof(*blocks) );
+		drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS );
 		return DRM_ERR(ENOMEM);
 	}
 
@@ -180,7 +179,7 @@
 			p->size += q->size;
 			p->next = q->next;
 			p->next->prev = p;
-			DRM_FREE(q, sizeof(*q));
+			drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
 		}
 	}
 }
@@ -197,10 +196,10 @@
 	for (p = (*heap)->next ; p != *heap ; ) {
 		struct mem_block *q = p;
 		p = p->next;
-		DRM_FREE(q, sizeof(*q));
+		drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
 	}
 
-	DRM_FREE( *heap, sizeof(**heap) );
+	drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER );
 	*heap = NULL;
 }
 
diff -Nru a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
--- a/drivers/char/drm/radeon_state.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/radeon_state.c	2004-11-09 00:25:55 -08:00
@@ -27,7 +27,6 @@
  *    Kevin E. Martin <martin@valinux.com>
  */
 
-#include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "drm_sarea.h"
@@ -1440,7 +1439,8 @@
 		}
 		if ( !buf ) {
 			DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
-			DRM_COPY_TO_USER( tex->image, image, sizeof(*image) );
+			if (DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ))
+				return DRM_ERR(EFAULT);
 			return DRM_ERR(EAGAIN);
 		}
 
@@ -1596,7 +1596,7 @@
 	return 0;
 }
 
-/* Called whenever a client dies, from DRM(release).
+/* Called whenever a client dies, from drm_release.
  * NOTE:  Lock isn't necessarily held when this is called!
  */
 int radeon_do_cleanup_pageflip( drm_device_t *dev )
@@ -2553,7 +2553,7 @@
  *
  * DRM infrastructure takes care of reclaiming dma buffers.
  */
-static void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
+void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp)
 {
 	if ( dev->dev_private ) {				
 		drm_radeon_private_t *dev_priv = dev->dev_private; 
@@ -2565,17 +2565,17 @@
 	}				
 }
 
-static void radeon_driver_pretakedown(drm_device_t *dev)
+void radeon_driver_pretakedown(drm_device_t *dev)
 {
 	radeon_do_release(dev);
 }
 
-static int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
+int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	struct drm_radeon_driver_file_fields *radeon_priv;
 	
-	radeon_priv = (struct drm_radeon_driver_file_fields *)DRM(alloc)(sizeof(*radeon_priv), DRM_MEM_FILES);
+	radeon_priv = (struct drm_radeon_driver_file_fields *)drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
 	
 	if (!radeon_priv)
 		return -ENOMEM;
@@ -2589,24 +2589,9 @@
 }
 
 
-static void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
+void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv)
 {
 	 struct drm_radeon_driver_file_fields *radeon_priv = filp_priv->driver_priv;
 	 
-	 DRM(free)(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
-}
-
-void radeon_driver_register_fns(struct drm_device *dev)
-{	
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL;
-	dev->dev_priv_size = sizeof(drm_radeon_buf_priv_t);
-	dev->fn_tbl.prerelease = radeon_driver_prerelease;
-	dev->fn_tbl.pretakedown = radeon_driver_pretakedown;
-	dev->fn_tbl.open_helper = radeon_driver_open_helper;
-	dev->fn_tbl.free_filp_priv = radeon_driver_free_filp_priv;
-	dev->fn_tbl.vblank_wait = radeon_driver_vblank_wait;
- 	dev->fn_tbl.irq_preinstall = radeon_driver_irq_preinstall;
- 	dev->fn_tbl.irq_postinstall = radeon_driver_irq_postinstall;
- 	dev->fn_tbl.irq_uninstall = radeon_driver_irq_uninstall;
- 	dev->fn_tbl.irq_handler = radeon_driver_irq_handler;
+	 drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
 }
diff -Nru a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
--- a/drivers/char/drm/sis_drm.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/sis_drm.h	2004-11-09 00:25:55 -08:00
@@ -3,12 +3,21 @@
 #define __SIS_DRM_H__
 
 /* SiS specific ioctls */
-#define DRM_IOCTL_SIS_FB_ALLOC		DRM_IOWR(0x44, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_FREE		DRM_IOW( 0x45, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_INIT		DRM_IOWR(0x53, drm_sis_agp_t)
-#define DRM_IOCTL_SIS_AGP_ALLOC		DRM_IOWR(0x54, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_AGP_FREE		DRM_IOW( 0x55, drm_sis_mem_t)
-#define DRM_IOCTL_SIS_FB_INIT		DRM_IOW( 0x56, drm_sis_fb_t)
+#define NOT_USED_0_3
+#define DRM_SIS_FB_ALLOC	0x04
+#define DRM_SIS_FB_FREE	        0x05
+#define NOT_USED_6_12
+#define DRM_SIS_AGP_INIT	0x13
+#define DRM_SIS_AGP_ALLOC	0x14
+#define DRM_SIS_AGP_FREE	0x15
+#define DRM_SIS_FB_INIT	        0x16
+
+#define DRM_IOCTL_SIS_FB_ALLOC		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_FB_FREE		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_AGP_INIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t)
+#define DRM_IOCTL_SIS_AGP_ALLOC		DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_AGP_FREE		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t)
+#define DRM_IOCTL_SIS_FB_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t)
 /*
 #define DRM_IOCTL_SIS_FLIP		DRM_IOW( 0x48, drm_sis_flip_t)
 #define DRM_IOCTL_SIS_FLIP_INIT		DRM_IO(  0x49)
diff -Nru a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
--- a/drivers/char/drm/sis_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/sis_drv.c	2004-11-09 00:25:55 -08:00
@@ -26,9 +26,91 @@
  */
 
 #include <linux/config.h>
-#include "sis.h"
 #include "drmP.h"
 #include "sis_drm.h"
 #include "sis_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
+  
+static int postinit( struct drm_device *dev, unsigned long flags )
+{
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
+}
+
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	sisdrv_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)]  = { sis_fb_alloc,        1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_FB_FREE)]   = { sis_fb_free,         1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)]  = { sis_ioctl_agp_init,  1, 1 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)]  = { sis_ioctl_agp_free,  1, 0 },
+	[DRM_IOCTL_NR(DRM_SIS_FB_INIT)]   = { sis_fb_init,         1, 1 }
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
+	.context_ctor = sis_init_context,
+	.context_dtor = sis_final_context,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+};
+
+static int __init sis_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit sis_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(sis_init);
+module_exit(sis_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
--- a/drivers/char/drm/sis_drv.h	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/sis_drv.h	2004-11-09 00:25:55 -08:00
@@ -28,6 +28,17 @@
 #ifndef _SIS_DRV_H_
 #define _SIS_DRV_H_
 
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"SIS"
+#define DRIVER_NAME		"sis"
+#define DRIVER_DESC		"SIS 300/630/540"
+#define DRIVER_DATE		"20030826"
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		1
+#define DRIVER_PATCHLEVEL	0
+
 #include "sis_ds.h"
 
 typedef struct drm_sis_private {
@@ -41,5 +52,8 @@
 extern int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS );
 extern int sis_ioctl_agp_free( DRM_IOCTL_ARGS );
 extern int sis_fb_init( DRM_IOCTL_ARGS );
+
+extern int sis_init_context(drm_device_t *dev, int context);
+extern int sis_final_context(drm_device_t *dev, int context);
 
 #endif
diff -Nru a/drivers/char/drm/sis_ds.c b/drivers/char/drm/sis_ds.c
--- a/drivers/char/drm/sis_ds.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/sis_ds.c	2004-11-09 00:25:55 -08:00
@@ -28,7 +28,6 @@
  * 
  */
 
-#include "sis.h"
 #include "drmP.h"
 #include "drm.h"
 #include "sis_ds.h"
@@ -42,7 +41,7 @@
 	int i;
 	set_t *set;
 
-	set = (set_t *)DRM(alloc)(sizeof(set_t), DRM_MEM_DRIVER);
+	set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
 	if (set != NULL) {
 		for (i = 0; i < SET_SIZE; i++) {
 			set->list[i].free_next = i + 1;    
@@ -128,7 +127,7 @@
 
 int setDestroy(set_t *set)
 {
-	DRM(free)(set, sizeof(set_t), DRM_MEM_DRIVER);
+	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
 
 	return 1;
 }
@@ -167,7 +166,7 @@
 	if (size <= 0)
 		return NULL;
 
-	blocks = (TMemBlock *)DRM(calloc)(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+	blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
 	if (blocks != NULL) {
 		blocks->ofs = ofs;
 		blocks->size = size;
@@ -202,7 +201,7 @@
 		       int size )
 {
 	PMemBlock blocks;
-	blocks = (TMemBlock *)DRM(calloc)(2, sizeof(TMemBlock), DRM_MEM_DRIVER);
+	blocks = (TMemBlock *)drm_calloc(2, sizeof(TMemBlock), DRM_MEM_DRIVER);
 	if (blocks != NULL) {
 		blocks[0].size = size;
 		blocks[0].free = 1;
@@ -229,7 +228,7 @@
 
 	/* break left */
 	if (startofs > p->ofs) {
-		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
+		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
 		    DRM_MEM_DRIVER);
 		newblock->ofs = startofs;
 		newblock->size = p->size - (startofs - p->ofs);
@@ -242,7 +241,7 @@
 
 	/* break right */
 	if (size < p->size) {
-		newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock),
+		newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
 		    DRM_MEM_DRIVER);
 		newblock->ofs = startofs + size;
 		newblock->size = p->size - size;
@@ -295,7 +294,7 @@
 		TMemBlock *q = p->next;
 		p->size += q->size;
 		p->next = q->next;
-		DRM(free)(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
+		drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
 		return 1;
 	}
 	return 0;
@@ -380,7 +379,7 @@
 	p = (TMemBlock *)heap;
 	while (p != NULL) {
 		q = p->next;
-		DRM(free)(p, sizeof(TMemBlock), DRM_MEM_DRIVER);
+		drm_free(p, sizeof(TMemBlock), DRM_MEM_DRIVER);
 		p = q;
 	}
 }
diff -Nru a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
--- a/drivers/char/drm/sis_mm.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/sis_mm.c	2004-11-09 00:25:55 -08:00
@@ -28,7 +28,6 @@
  * 
  */
 
-#include "sis.h"
 #include "drmP.h"
 #include "sis_drm.h"
 #include "sis_drv.h"
@@ -159,7 +158,7 @@
 	DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb));
 
 	if (dev_priv == NULL) {
-		dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
 		    DRM_MEM_DRIVER);
 		dev_priv = dev->dev_private;
 		if (dev_priv == NULL)
@@ -247,7 +246,7 @@
 	drm_sis_agp_t agp;
 
 	if (dev_priv == NULL) {
-		dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
+		dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
 		    DRM_MEM_DRIVER);
 		dev_priv = dev->dev_private;
 		if (dev_priv == NULL)
@@ -403,11 +402,4 @@
         }
 	
 	return 1;
-}
-
-void DRM(driver_register_fns)(drm_device_t *dev)
-{
-	dev->driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR;
-	dev->fn_tbl.context_ctor = sis_init_context;
-	dev->fn_tbl.context_dtor = sis_final_context;
 }
diff -Nru a/drivers/char/drm/tdfx.h b/drivers/char/drm/tdfx.h
--- a/drivers/char/drm/tdfx.h	2004-11-09 00:25:55 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,50 +0,0 @@
-/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
- * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
- *
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * 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, 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 (including the next
- * paragraph) 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
- * VA LINUX SYSTEMS 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.
- *
- * Authors:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-#ifndef __TDFX_H__
-#define __TDFX_H__
-
-/* This remains constant for all DRM template files.
- */
-#define DRM(x) tdfx_##x
-
-/* General customization:
- */
-
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"tdfx"
-#define DRIVER_DESC		"3dfx Banshee/Voodoo3+"
-#define DRIVER_DATE		"20010216"
-
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	0
-
-#endif
diff -Nru a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
--- a/drivers/char/drm/tdfx_drv.c	2004-11-09 00:25:55 -08:00
+++ b/drivers/char/drm/tdfx_drv.c	2004-11-09 00:25:55 -08:00
@@ -31,13 +31,77 @@
  */
 
 #include <linux/config.h>
-#include "tdfx.h"
 #include "drmP.h"
+#include "tdfx_drv.h"
 
-#include "drm_core.h"
+#include "drm_pciids.h"
 
-void DRM(driver_register_fns)(drm_device_t *dev)
+static int postinit( struct drm_device *dev, unsigned long flags )
 {
-	dev->driver_features = DRIVER_USE_MTRR;
+	DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		DRIVER_NAME,
+		DRIVER_MAJOR,
+		DRIVER_MINOR,
+		DRIVER_PATCHLEVEL,
+		DRIVER_DATE,
+		dev->minor,
+		pci_pretty_name(dev->pdev)
+		);
+	return 0;
 }
 
+static int version( drm_version_t *version )
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY( version->name, DRIVER_NAME );
+	DRM_COPY( version->date, DRIVER_DATE );
+	DRM_COPY( version->desc, DRIVER_DESC );
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	tdfx_PCI_IDS
+};
+
+static struct drm_driver driver = {
+	.driver_features = DRIVER_USE_MTRR,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+	},
+	.pci_driver = {
+		.name          = DRIVER_NAME,
+		.id_table      = pciidlist,
+	}
+};
+
+static int __init tdfx_init(void)
+{
+	return drm_init(&driver);
+}
+
+static void __exit tdfx_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(tdfx_init);
+module_exit(tdfx_exit);
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/char/drm/tdfx_drv.h	2004-11-09 00:25:55 -08:00
@@ -0,0 +1,50 @@
+/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * 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, 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 (including the next
+ * paragraph) 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
+ * VA LINUX SYSTEMS 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.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __TDFX_H__
+#define __TDFX_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) tdfx_##x
+
+/* General customization:
+ */
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"tdfx"
+#define DRIVER_DESC		"3dfx Banshee/Voodoo3+"
+#define DRIVER_DATE		"20010216"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	0
+
+#endif
