http://freedesktop.org:1234/drm-2.6/ airlied@pdx.freedesktop.org|ChangeSet|20040410135643|23869 airlied # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/10 06:56:43-07:00 airlied@pdx.freedesktop.org # From Jon Smirl: # This code allows the mesa drivers to use a single definition of the DRM sarea/IOCTLS # # drivers/char/drm/radeon_drm.h # 2004/04/10 06:56:33-07:00 airlied@pdx.freedesktop.org +60 -27 # From Jon Smirl: # This code allows the mesa drivers to use a single definition of the DRM sarea/IOCTLS # # drivers/char/drm/r128_drm.h # 2004/04/10 06:56:33-07:00 airlied@pdx.freedesktop.org +42 -19 # From Jon Smirl: # This code allows the mesa drivers to use a single definition of the DRM sarea/IOCTLS # # drivers/char/drm/mga_drm.h # 2004/04/10 06:56:33-07:00 airlied@pdx.freedesktop.org +24 -11 # From Jon Smirl: # This code allows the mesa drivers to use a single definition of the DRM sarea/IOCTLS # # drivers/char/drm/drm_sarea.h # 2004/04/10 06:56:33-07:00 airlied@pdx.freedesktop.org +14 -0 # From Jon Smirl: # This code allows the mesa drivers to use a single definition of the DRM sarea/IOCTLS # # ChangeSet # 2004/04/10 06:27:26-07:00 airlied@pdx.freedesktop.org # * Introduce COMMIT_RING() as in radeon DRM, stop using error prone # writeback for ring read pointer (Paul Mackerras) # * Get rid of some superfluous stuff, minor fixes # # drivers/char/drm/r128_state.c # 2004/04/10 06:27:19-07:00 airlied@pdx.freedesktop.org +25 -9 # * Introduce COMMIT_RING() as in radeon DRM, stop using error prone # writeback for ring read pointer (Paul Mackerras) # * Get rid of some superfluous stuff, minor fixes # # drivers/char/drm/r128_drv.h # 2004/04/10 06:27:19-07:00 airlied@pdx.freedesktop.org +32 -25 # * Introduce COMMIT_RING() as in radeon DRM, stop using error prone # writeback for ring read pointer (Paul Mackerras) # * Get rid of some superfluous stuff, minor fixes # # drivers/char/drm/r128_cce.c # 2004/04/10 06:27:19-07:00 airlied@pdx.freedesktop.org +9 -30 # * Introduce COMMIT_RING() as in radeon DRM, stop using error prone # writeback for ring read pointer (Paul Mackerras) # * Get rid of some superfluous stuff, minor fixes # # ChangeSet # 2004/04/10 05:26:04-07:00 airlied@pdx.freedesktop.org # radeon_drm.h: # missing define from previous checkin # # drivers/char/drm/radeon_drm.h # 2004/04/10 05:25:29-07:00 airlied@pdx.freedesktop.org +1 -0 # missing define from previous checkin # # ChangeSet # 2004/04/10 00:52:10-07:00 airlied@pdx.freedesktop.org # Miscellaneous changes from DRM CVS # # drivers/char/drm/drm_stub.h # 2004/04/10 00:52:04-07:00 airlied@pdx.freedesktop.org +2 -2 # retab.. # # drivers/char/drm/drm_bufs.h # 2004/04/10 00:52:04-07:00 airlied@pdx.freedesktop.org +1 -1 # use correct preproc directive.. # # drivers/char/drm/drm_agpsupport.h # 2004/04/10 00:52:04-07:00 airlied@pdx.freedesktop.org +2 -0 # add another error test for 2.6 # # drivers/char/drm/drmP.h # 2004/04/10 00:52:04-07:00 airlied@pdx.freedesktop.org +0 -12 # move lock to drm.h # # drivers/char/drm/drm.h # 2004/04/10 00:52:04-07:00 airlied@pdx.freedesktop.org +14 -2 # move the lcok to drm.h align some preprocesor stuff # # ChangeSet # 2004/04/10 00:06:33-07:00 airlied@pdx.freedesktop.org # drm_ctx_dtor.patch # Submitted by: Erdi Chen # # drivers/char/drm/drm_memory_debug.h # 2004/04/10 00:06:27-07:00 airlied@pdx.freedesktop.org +1 -0 # drm_ctx_dtor.patch # Submitted by: Erdi Chen # # drivers/char/drm/drm_drv.h # 2004/04/10 00:06:27-07:00 airlied@pdx.freedesktop.org +27 -0 # drm_ctx_dtor.patch # Submitted by: Erdi Chen # # drivers/char/drm/drm_context.h # 2004/04/10 00:06:27-07:00 airlied@pdx.freedesktop.org +29 -0 # drm_ctx_dtor.patch # Submitted by: Erdi Chen # # drivers/char/drm/drmP.h # 2004/04/10 00:06:27-07:00 airlied@pdx.freedesktop.org +16 -0 # drm_ctx_dtor.patch # Submitted by: Erdi Chen # # ChangeSet # 2004/04/09 23:56:13-07:00 airlied@pdx.freedesktop.org # More differentiated error codes for DRM(agp_acquire) # # drivers/char/drm/drm_agpsupport.h # 2004/04/09 23:56:07-07:00 airlied@pdx.freedesktop.org +5 -1 # More differentiated error codes for DRM(agp_acquire) # # ChangeSet # 2004/04/09 23:44:36-07:00 airlied@pdx.freedesktop.org # From Michel Daenzer: # Adapt to nopage() prototype change in Linux 2.6.1. # # Reviewed by: Arjan van de Ven , additional feedback # from William Lee Irwin III and Linus Torvalds. # # drivers/char/drm/drm_vm.h # 2004/04/09 23:44:27-07:00 airlied@pdx.freedesktop.org +97 -51 # From Michel Daenzer: # Adapt to nopage() prototype change in Linux 2.6.1. # # Reviewed by: Arjan van de Ven , additional feedback # from William Lee Irwin III and Linus Torvalds. # # drivers/char/drm/drmP.h # 2004/04/09 23:44:27-07:00 airlied@pdx.freedesktop.org +0 -12 # From Michel Daenzer: # Adapt to nopage() prototype change in Linux 2.6.1. # # Reviewed by: Arjan van de Ven , additional feedback # from William Lee Irwin III and Linus Torvalds. # # ChangeSet # 2004/04/09 23:20:06-07:00 airlied@pdx.freedesktop.org # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/radeon_drv.h # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -1 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/radeon_cp.c # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -7 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/r128_drv.h # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -1 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/r128_cce.c # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -7 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/mga_drv.h # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -1 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/mga_dma.c # 2004/04/09 23:19:59-07:00 airlied@pdx.freedesktop.org +0 -8 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # drivers/char/drm/drm_bufs.h # 2004/04/09 23:19:58-07:00 airlied@pdx.freedesktop.org +3 -1 # From Eric Anholt + Jon Smirl: # Don't ioremap the framebuffer area. The ioremapped area wasn't used by # anything. # # ChangeSet # 2004/04/09 23:07:59-07:00 airlied@pdx.freedesktop.org # From Eric Anholt: # Return EBUSY when attempting to addmap a DRM_SHM area with a lock in it if # dev->lock.hw_lock is already set. This fixes the case of two X Servers running # on the same head on different VTs with interface 1.1, by making the 2nd head # fail to inizialize like before. # # drivers/char/drm/drm_bufs.h # 2004/04/09 23:07:52-07:00 airlied@pdx.freedesktop.org +6 -0 # From Eric Anholt: # Return EBUSY when attempting to addmap a DRM_SHM area with a lock in it if # dev->lock.hw_lock is already set. This fixes the case of two X Servers running # on the same head on different VTs with interface 1.1, by making the 2nd head # fail to inizialize like before. # # ChangeSet # 2004/04/09 23:00:48-07:00 airlied@pdx.freedesktop.org # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/radeon_cp.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +1 -1 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/r128_cce.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +1 -1 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/mga_dma.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +1 -1 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/i830_dma.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +2 -2 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/i810_dma.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +1 -1 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/gamma_dma.c # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +1 -1 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/drm_irq.h # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +57 -18 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/drm_ioctl.h # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +36 -137 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/drm_drv.h # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +14 -4 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # drivers/char/drm/drmP.h # 2004/04/09 23:00:37-07:00 airlied@pdx.freedesktop.org +12 -4 # From Eric Anholt: some cleanups from AlanH: # - Tie the DRM to a specific device: setunique no longer succeeds when given # a busid that doesn't correspond to the device the DRM is attached to. This # is a breaking of backwards-compatibility only for the multiple-DRI-head case # with X Servers that don't use interface 1.1. # - Move irq_busid to drm_irq.h and make it only return the IRQ for the current # device. Retains compatibility with previous X Servers, cleans up unnecessary # code. This means no irq_busid on !__HAVE_IRQ, but can be changed if # necessary. # - Bump interface version to 1.2. This version when set signifies that the # control ioctl should ignore the irq number passed in and enable the # interrupt handler for the attached device. Otherwise it errors out when # the passed-in irq is not equal to the device's. # - Store the highest version the interface has been set to in the device. # # ChangeSet # 2004/04/09 22:34:54-07:00 airlied@pdx.freedesktop.org # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/radeon_state.c # 2004/04/09 22:34:48-07:00 airlied@pdx.freedesktop.org +370 -42 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/radeon_drv.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +5 -0 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/radeon_drm.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +14 -1 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/radeon_cp.c # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +20 -9 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/radeon.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +19 -3 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/drm_os_linux.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +4 -0 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/drm_fops.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +2 -0 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/drm_drv.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +3 -0 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # drivers/char/drm/drmP.h # 2004/04/09 22:34:47-07:00 airlied@pdx.freedesktop.org +3 -0 # From: Michel Daenzer: # Memory layout transition: # # * the 2D driver initializes MC_FB_LOCATION and related registers sanely # * the DRM deduces the layout from these registers # * clients use the new SETPARAM ioctl to tell the DRM where they think the # framebuffer is located in the card's address space # * the DRM uses all this information to check client state and fix it up if # necessary # # This is a prerequisite for things like direct rendering with IGP chips and # video capturing. # # ChangeSet # 2004/04/09 21:32:02-07:00 airlied@pdx.freedesktop.org # From Eric Anholt: # Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows the server # or client to notify the DRM that it expects a certain version of the device # dependent or device independent interface. If the major doesn't match or minor # is too large, EINVAL is returned. A major of -1 means that the requestor # doesn't care about that portion of the interface. The ioctl returns the actual # versions in the same struct. # # drivers/char/drm/drm_ioctl.h # 2004/04/09 21:28:47-07:00 airlied@pdx.freedesktop.org +74 -1 # From Eric Anholt: # Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows the server # or client to notify the DRM that it expects a certain version of the device # dependent or device independent interface. If the major doesn't match or minor # is too large, EINVAL is returned. A major of -1 means that the requestor # doesn't care about that portion of the interface. The ioctl returns the actual # versions in the same struct. # # drivers/char/drm/drm_drv.h # 2004/04/09 21:28:47-07:00 airlied@pdx.freedesktop.org +1 -0 # From Eric Anholt: # Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows the server # or client to notify the DRM that it expects a certain version of the device # dependent or device independent interface. If the major doesn't match or minor # is too large, EINVAL is returned. A major of -1 means that the requestor # doesn't care about that portion of the interface. The ioctl returns the actual # versions in the same struct. # # drivers/char/drm/drmP.h # 2004/04/09 21:28:47-07:00 airlied@pdx.freedesktop.org +2 -0 # From Eric Anholt: # Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows the server # or client to notify the DRM that it expects a certain version of the device # dependent or device independent interface. If the major doesn't match or minor # is too large, EINVAL is returned. A major of -1 means that the requestor # doesn't care about that portion of the interface. The ioctl returns the actual # versions in the same struct. # # drivers/char/drm/drm.h # 2004/04/09 21:28:47-07:00 airlied@pdx.freedesktop.org +11 -0 # From Eric Anholt: # Introduce a new ioctl, DRM_IOCTL_SET_VERSION. This ioctl allows the server # or client to notify the DRM that it expects a certain version of the device # dependent or device independent interface. If the major doesn't match or minor # is too large, EINVAL is returned. A major of -1 means that the requestor # doesn't care about that portion of the interface. The ioctl returns the actual # versions in the same struct. # # ChangeSet # 2004/04/09 20:03:25-07:00 airlied@pdx.freedesktop.org # - Add DRM_GET_PRIV_WITH_RETURN macro. This can be used in shared code to get # the drm_file_t * based on the filp passed in ioctl handlers. # # drivers/char/drm/drm_os_linux.h # 2004/04/09 20:03:19-07:00 airlied@pdx.freedesktop.org +2 -0 # - Add DRM_GET_PRIV_WITH_RETURN macro. This can be used in shared code to get # the drm_file_t * based on the filp passed in ioctl handlers. # # ChangeSet # 2004/04/09 19:35:05-07:00 airlied@pdx.freedesktop.org # left gamma_dma.c out of last changeset # # drivers/char/drm/gamma_dma.c # 2004/04/09 19:34:58-07:00 airlied@pdx.freedesktop.org +3 -3 # FRom Eric Anholt: # Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit. # # ChangeSet # 2004/04/09 19:12:53-07:00 airlied@pdx.freedesktop.org # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/drm_irq.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +333 -0 # # drivers/char/drm/radeon_irq.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/radeon_drv.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -0 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/radeon_cp.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/radeon.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/r128_irq.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/r128_drv.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -0 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/r128_cce.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/r128.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/mga_irq.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/mga_drv.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -0 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/mga_dma.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/mga.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i830_irq.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i830_drv.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -0 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i830_dma.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i830.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +2 -2 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i810_dma.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/i810.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -1 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/gamma_drv.c # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +1 -0 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/gamma.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +2 -2 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/drm_irq.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +0 -0 # BitKeeper file /home/airlied/linux/drm-dev/drivers/char/drm/drm_irq.h # # drivers/char/drm/drm_drv.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +6 -6 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/drm_dma.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +5 -298 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # drivers/char/drm/drmP.h # 2004/04/09 19:12:45-07:00 airlied@pdx.freedesktop.org +11 -7 # From: Eric Anholt: # - Move IRQ functions from drm_dma.h to new drm_irq.h and disentangle them from # __HAVE_DMA. This will be useful for adding vblank sync support to sis and # tdfx. Rename dma_service to irq_handler, which is more accurately what it is. # - Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have # the right number of underscores. This may have been a problem in the case # that the server died without doing its DRM_IOCTL_CONTROL to uninit # # ChangeSet # 2004/04/09 00:28:45-07:00 airlied@pdx.freedesktop.org # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. clean up tdfx to look like everyone else.. # # drivers/char/drm/tdfx_drv.c # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +0 -41 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. clean up tdfx to look like everyone else.. # # drivers/char/drm/tdfx.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +18 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. clean up tdfx to look like everyone else.. # # drivers/char/drm/sis.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +7 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/radeon.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +60 -1 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/r128.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +40 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/mga.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +6 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/i830.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +7 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/i810.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +8 -1 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/gamma.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +4 -0 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/drm_drv.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +87 -115 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # # drivers/char/drm/drmP.h # 2004/04/09 00:28:35-07:00 airlied@pdx.freedesktop.org +7 -4 # - Converted Linux drivers to initialize DRM instances based on PCI IDs, not # just a single instance. The PCI ID lists include a driver private field, which may be used # by drivers for chip family or other information. Based on work by jonsmirl # and Eric Anholt. I've left out the PCI device naming for this patch as # that might be a bit controversial. # diff -Nru a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h --- a/drivers/char/drm/drm.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm.h Sat Apr 10 15:20:07 2004 @@ -46,8 +46,8 @@ #define DRM_IOC_WRITE _IOC_WRITE #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -#elif defined(__FreeBSD__) || defined(__NetBSD__) -#if defined(__FreeBSD__) && defined(XFree86Server) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) && defined(IN_MODULE) /* Prevent name collision when including sys/ioccom.h */ #undef ioctl #include @@ -130,6 +130,18 @@ unsigned int age; } drm_tex_region_t; +/** + * Hardware lock. + * + * The lock structure is a simple cache-line aligned integer. To avoid + * processor bus contention on a multiprocessor system, there should not be any + * other data stored in the same cache line. + */ +typedef struct drm_hw_lock { + __volatile__ unsigned int lock; /**< lock variable */ + char padding[60]; /**< Pad to cache line */ +} drm_hw_lock_t; + /** * DRM_IOCTL_VERSION ioctl argument type. @@ -580,6 +592,16 @@ unsigned long handle; /**< Used for mapping / unmapping */ } drm_scatter_gather_t; +/** + * DRM_IOCTL_SET_VERSION ioctl argument type. + */ +typedef struct drm_set_version { + int drm_di_major; + int drm_di_minor; + int drm_dd_major; + int drm_dd_minor; +} drm_set_version_t; + #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) @@ -594,6 +616,7 @@ #define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t) #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t) #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t) #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h --- a/drivers/char/drm/drmP.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drmP.h Sat Apr 10 15:20:07 2004 @@ -92,8 +92,8 @@ #ifndef __HAVE_DMA #define __HAVE_DMA 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #ifndef __HAVE_DMA_WAITLIST #define __HAVE_DMA_WAITLIST 0 @@ -148,6 +148,7 @@ #define DRM_MEM_CTXBITMAP 18 #define DRM_MEM_STUB 19 #define DRM_MEM_SGLISTS 20 +#define DRM_MEM_CTXLIST 21 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) @@ -324,6 +325,7 @@ #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) #define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) +#define DRM_IF_VERSION(maj, min) (maj << 16 | min) /** * Get the private SAREA mapping. * @@ -362,10 +364,12 @@ typedef int drm_ioctl_t( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -typedef struct drm_pci_list { - u16 vendor; - u16 device; -} drm_pci_list_t; +typedef struct drm_pci_id_list +{ + int vendor; + int device; + long driver_private; +} drm_pci_id_list_t; typedef struct drm_ioctl_desc { drm_ioctl_t *func; @@ -463,18 +467,6 @@ drm_freelist_t freelist; } drm_buf_entry_t; -/** - * Hardware lock. - * - * The lock structure is a simple cache-line aligned integer. To avoid - * processor bus contention on a multiprocessor system, there should not be any - * other data stored in the same cache line. - */ -typedef struct drm_hw_lock { - __volatile__ unsigned int lock; /**< lock variable */ - char padding[60]; /**< Pad to cache line */ -} drm_hw_lock_t; - /** File private data */ typedef struct drm_file { int authenticated; @@ -488,6 +480,9 @@ struct drm_device *dev; int remove_auth_on_close; unsigned long lock_count; +#ifdef DRIVER_FILE_FIELDS + DRIVER_FILE_FIELDS; +#endif } drm_file_t; /** Wait queue */ @@ -602,6 +597,15 @@ typedef drm_map_t drm_local_map_t; +/** + * Context handle list + */ +typedef struct drm_ctx_list { + struct list_head head; /**< list head */ + drm_context_t handle; /**< context handle */ + drm_file_t *tag; /**< associated fd private data */ +} drm_ctx_list_t; + #if __HAVE_VBL_IRQ typedef struct drm_vbl_sig { @@ -622,6 +626,8 @@ int unique_len; /**< Length of unique field */ dev_t device; /**< Device number for mknod */ char *devname; /**< For /proc/interrupts */ + int minor; /**< Minor device number */ + int if_version; /**< Highest interface version set */ int blocked; /**< Blocked due to VC switch? */ struct proc_dir_entry *root; /**< Root for this device's entries */ @@ -660,6 +666,12 @@ drm_map_list_t *maplist; /**< Linked list of regions */ int map_count; /**< Number of mappable regions */ + /** \name Context handle management */ + /*@{*/ + drm_ctx_list_t *ctxlist; /**< Linked list of context handles */ + int ctx_count; /**< Number of context handles */ + struct semaphore ctxlist_sem; /**< For ctxlist */ + drm_map_t **context_sareas; /**< per-context SAREA's */ int max_context; @@ -679,6 +691,7 @@ /** \name Context support */ /*@{*/ int irq; /**< Interrupt used by board */ + int irq_enabled; /**< True if irq handler is enabled */ __volatile__ long context_flag; /**< Context swapping flag */ __volatile__ long interrupt_flag; /**< Interruption handler flag */ __volatile__ long dma_flag; /**< DMA dispatch flag */ @@ -714,7 +727,12 @@ #if __REALLY_HAVE_AGP drm_agp_head_t *agp; /**< AGP data */ #endif - struct pci_dev *pdev; /**< PCI device structure */ + + struct pci_dev *pdev; /**< PCI device structure */ + int pci_domain; /**< PCI bus domain number */ + int pci_bus; /**< PCI bus number */ + int pci_slot; /**< PCI slot number */ + int pci_func; /**< PCI function number */ #ifdef __alpha__ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) struct pci_controler *hose; @@ -758,18 +776,6 @@ extern int DRM(fasync)(int fd, struct file *filp, int on); /* Mapping support (drm_vm.h) */ -extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type); -extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type); -extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type); -extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type); 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); @@ -804,8 +810,8 @@ #endif /* Misc. IOCTL support (drm_ioctl.h) */ -extern int DRM(irq_busid)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +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, unsigned int cmd, unsigned long arg); extern int DRM(setunique)(struct inode *inode, struct file *filp, @@ -816,6 +822,8 @@ unsigned int cmd, unsigned long arg); 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, + unsigned int cmd, unsigned long arg); /* Context IOCTL support (drm_context.h) */ extern int DRM(resctx)( struct inode *inode, struct file *filp, @@ -900,12 +908,17 @@ 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 ); -#if __HAVE_DMA_IRQ +#endif /* __HAVE_DMA */ + + /* IRQ support (drm_irq.h) */ +#if __HAVE_IRQ || __HAVE_DMA 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, int irq ); +#endif +#if __HAVE_IRQ +extern int DRM(irq_install)( drm_device_t *dev ); extern int DRM(irq_uninstall)( drm_device_t *dev ); -extern irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ); +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 ); @@ -915,12 +928,11 @@ extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq); extern void DRM(vbl_send_signals)( drm_device_t *dev ); #endif -#if __HAVE_DMA_IRQ_BH -extern void DRM(dma_immediate_bh)( void *dev ); +#if __HAVE_IRQ_BH +extern void DRM(irq_immediate_bh)( void *dev ); #endif #endif -#endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP /* AGP/GART support (drm_agpsupport.h) */ diff -Nru a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h --- a/drivers/char/drm/drm_agpsupport.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_agpsupport.h Sat Apr 10 15:20:07 2004 @@ -103,7 +103,13 @@ drm_device_t *dev = priv->dev; int retcode; - if (!dev->agp || dev->agp->acquired || !drm_agp->acquire) + if (!dev->agp) + return -ENODEV; + if (dev->agp->acquired) + return -EBUSY; + if (!drm_agp->acquire) + return -EINVAL; + if ( dev->agp->cant_use_aperture ) return -EINVAL; if ((retcode = drm_agp->acquire())) 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 Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_bufs.h Sat Apr 10 15:20:07 2004 @@ -147,7 +147,9 @@ MTRR_TYPE_WRCOMB, 1 ); } #endif - map->handle = DRM(ioremap)( map->offset, map->size, dev ); + if (map->type == _DRM_REGISTERS) + map->handle = DRM(ioremap)( map->offset, map->size, + dev ); break; case _DRM_SHM: @@ -160,6 +162,12 @@ } 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 */ } @@ -767,7 +775,7 @@ } #endif /* __HAVE_PCI_DMA */ -#ifdef __HAVE_SG +#if __HAVE_SG int DRM(addbufs_sg)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { diff -Nru a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h --- a/drivers/char/drm/drm_context.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_context.h Sat Apr 10 15:20:07 2004 @@ -401,6 +401,7 @@ { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_ctx_list_t * ctx_entry; drm_ctx_t ctx; if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) ) @@ -421,6 +422,20 @@ if ( ctx.handle != DRM_KERNEL_CONTEXT ) DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */ #endif + 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( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) ) return -EFAULT; @@ -542,6 +557,20 @@ #endif 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_dma.h b/drivers/char/drm/drm_dma.h --- a/drivers/char/drm/drm_dma.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_dma.h Sat Apr 10 15:20:07 2004 @@ -35,7 +35,6 @@ #include "drmP.h" -#include /* For task queue support */ #ifndef __HAVE_DMA_WAITQUEUE #define __HAVE_DMA_WAITQUEUE 0 @@ -43,15 +42,6 @@ #ifndef __HAVE_DMA_RECLAIM #define __HAVE_DMA_RECLAIM 0 #endif -#ifndef __HAVE_SHARED_IRQ -#define __HAVE_SHARED_IRQ 0 -#endif - -#if __HAVE_SHARED_IRQ -#define DRM_IRQ_TYPE SA_SHIRQ -#else -#define DRM_IRQ_TYPE 0 -#endif #if __HAVE_DMA @@ -214,293 +204,11 @@ } #endif - - - -#if __HAVE_DMA_IRQ - -/** - * 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 irq ) -{ - int ret; - - if ( !irq ) - return -EINVAL; - - down( &dev->struct_sem ); - - /* Driver must have been initialized */ - if ( !dev->dev_private ) { - up( &dev->struct_sem ); - return -EINVAL; - } - - if ( dev->irq ) { - up( &dev->struct_sem ); - return -EBUSY; - } - dev->irq = irq; - up( &dev->struct_sem ); - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - -#if __HAVE_DMA_IRQ_BH - INIT_WORK(&dev->work, DRM(dma_immediate_bh), dev); -#endif - -#if __HAVE_VBL_IRQ - init_waitqueue_head(&dev->vbl_queue); - - spin_lock_init( &dev->vbl_lock ); - - INIT_LIST_HEAD( &dev->vbl_sigs.head ); - - dev->vbl_pending = 0; -#endif - - /* Before installing handler */ - DRM(driver_irq_preinstall)(dev); - - /* Install handler */ - ret = request_irq( dev->irq, DRM(dma_service), - DRM_IRQ_TYPE, dev->devname, dev ); - if ( ret < 0 ) { - down( &dev->struct_sem ); - dev->irq = 0; - up( &dev->struct_sem ); - return ret; - } - - /* After installing handler */ - DRM(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; - - down( &dev->struct_sem ); - irq = dev->irq; - dev->irq = 0; - up( &dev->struct_sem ); - - if ( !irq ) - return -EINVAL; - - DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); - - DRM(driver_irq_uninstall)( dev ); - - free_irq( 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 ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) - return -EFAULT; - - switch ( ctl.func ) { - case DRM_INST_HANDLER: - return DRM(irq_install)( dev, ctl.irq ); - case DRM_UNINST_HANDLER: - return DRM(irq_uninstall)( dev ); - default: - return -EINVAL; - } -} - -#if __HAVE_VBL_IRQ - -/** - * 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 vblwait; - struct timeval now; - int ret = 0; - unsigned int flags; - - if (!dev->irq) - return -EINVAL; - - DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, - 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 { - ret = DRM(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( (drm_wait_vblank_t *)data, 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(). +#if !__HAVE_IRQ +/* This stub DRM_IOCTL_CONTROL handler is for the drivers that used to require + * IRQs for DMA but no longer do. It maintains compatibility with the X Servers + * that try to use the control ioctl by simply returning success. */ -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 ); -} - -#endif /* __HAVE_VBL_IRQ */ - -#else - int DRM(control)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) { @@ -517,7 +225,6 @@ return -EINVAL; } } - -#endif /* __HAVE_DMA_IRQ */ +#endif #endif /* __HAVE_DMA */ diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h --- a/drivers/char/drm/drm_drv.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_drv.h Sat Apr 10 15:20:07 2004 @@ -58,8 +58,8 @@ #ifndef __HAVE_CTX_BITMAP #define __HAVE_CTX_BITMAP 0 #endif -#ifndef __HAVE_DMA_IRQ -#define __HAVE_DMA_IRQ 0 +#ifndef __HAVE_IRQ +#define __HAVE_IRQ 0 #endif #ifndef __HAVE_DMA_QUEUE #define __HAVE_DMA_QUEUE 0 @@ -126,6 +126,9 @@ #ifndef DRIVER_IOCTLS #define DRIVER_IOCTLS #endif +#ifndef DRIVER_OPEN_HELPER +#define DRIVER_OPEN_HELPER( priv, dev ) +#endif #ifndef DRIVER_FOPS #define DRIVER_FOPS \ static struct file_operations DRM(fops) = { \ @@ -159,15 +162,8 @@ #undef DRM_OPTIONS_FUNC #endif -/** - * The default number of instances (minor numbers) to initialize. - */ -#ifndef DRIVER_NUM_CARDS -#define DRIVER_NUM_CARDS 1 -#endif - -static drm_device_t *DRM(device); -static int *DRM(minor); +#define MAX_DEVICES 4 +static drm_device_t DRM(device)[MAX_DEVICES]; static int DRM(numdevs) = 0; DRIVER_FOPS; @@ -177,10 +173,13 @@ [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_busid), 0, 1 }, +#if __HAVE_IRQ + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_by_busid), 0, 1 }, +#endif [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 }, @@ -222,9 +221,9 @@ [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. - */ + /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ +#endif +#if __HAVE_IRQ || __HAVE_DMA [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 }, #endif @@ -330,6 +329,12 @@ 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 ); @@ -337,7 +342,7 @@ dev->queue_reserved = 0; dev->queue_slots = 0; dev->queuelist = NULL; - dev->irq = 0; + dev->irq_enabled = 0; dev->context_flag = 0; dev->interrupt_flag = 0; dev->dma_flag = 0; @@ -345,6 +350,7 @@ 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; @@ -391,8 +397,8 @@ DRM_DEBUG( "\n" ); DRIVER_PRETAKEDOWN(); -#if __HAVE_DMA_IRQ - if ( dev->irq ) DRM(irq_uninstall)( dev ); +#if __HAVE_IRQ + if ( dev->irq_enabled ) DRM(irq_uninstall)( dev ); #endif down( &dev->struct_sem ); @@ -534,43 +540,101 @@ return 0; } -/** - * Figure out how many instances to initialize. - * - * \return number of cards found. - * - * Searches for every PCI card in \c DRIVER_CARD_LIST with matching vendor and device ids. - */ -static int drm_count_cards(void) +static drm_pci_id_list_t DRM(pciidlist)[] = { + DRIVER_PCI_IDS +}; + +static int DRM(probe)(struct pci_dev *pdev) { - int num = 0; -#if defined(DRIVER_CARD_LIST) - int i; - drm_pci_list_t *l; - u16 device, vendor; - struct pci_dev *pdev = NULL; + drm_device_t *dev; +#if __HAVE_CTX_BITMAP + int retcode; #endif + int i; + int is_compat = 0; DRM_DEBUG( "\n" ); -#if defined(DRIVER_COUNT_CARDS) - num = DRIVER_COUNT_CARDS(); -#elif defined(DRIVER_CARD_LIST) - for (i = 0, l = DRIVER_CARD_LIST; l[i].vendor != 0; i++) { - pdev = NULL; - vendor = l[i].vendor; - device = l[i].device; - if(device == 0xffff) device = PCI_ANY_ID; - if(vendor == 0xffff) vendor = PCI_ANY_ID; - while ((pdev = pci_find_device(vendor, device, pdev))) { - num++; + 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; + + 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 - num = DRIVER_NUM_CARDS; + 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; + + DRIVER_PREINIT(); + +#if __REALLY_HAVE_AGP + dev->agp = DRM(agp_init)(); +#if __MUST_HAVE_AGP + if ( dev->agp == NULL ) { + DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + DRM(stub_unregister)(dev->minor); + DRM(takedown)( dev ); + return -EINVAL; + } +#endif +#if __REALLY_HAVE_MTRR + 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 ); +#endif #endif - DRM_DEBUG("numdevs = %d\n", num); - return num; + +#if __HAVE_CTX_BITMAP + 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; + } +#endif + DRM(numdevs)++; /* no errors, mark it reserved */ + + DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", + DRIVER_NAME, + DRIVER_MAJOR, + DRIVER_MINOR, + DRIVER_PATCHLEVEL, + DRIVER_DATE, + dev->minor); + + DRIVER_POSTINIT(); + + return 0; } /** @@ -579,7 +643,7 @@ * * \return zero on success or a negative number on failure. * - * Allocates and initialize an array of drm_device structures, and attempts to + * 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. * @@ -588,88 +652,19 @@ */ static int __init drm_init( void ) { + struct pci_dev *pdev = NULL; - drm_device_t *dev; - int i; -#if __HAVE_CTX_BITMAP - int retcode; -#endif DRM_DEBUG( "\n" ); #ifdef MODULE DRM(parse_options)( drm_opts ); #endif - DRM(numdevs) = drm_count_cards(); - /* Force at least one instance. */ - if (DRM(numdevs) <= 0) - DRM(numdevs) = 1; - - DRM(device) = kmalloc(sizeof(*DRM(device)) * DRM(numdevs), GFP_KERNEL); - if (!DRM(device)) { - return -ENOMEM; - } - DRM(minor) = kmalloc(sizeof(*DRM(minor)) * DRM(numdevs), GFP_KERNEL); - if (!DRM(minor)) { - kfree(DRM(device)); - return -ENOMEM; - } - - DRIVER_PREINIT(); - DRM(mem_init)(); - for (i = 0; i < DRM(numdevs); i++) { - dev = &(DRM(device)[i]); - memset( (void *)dev, 0, sizeof(*dev) ); - dev->count_lock = SPIN_LOCK_UNLOCKED; - init_timer( &dev->timer ); - sema_init( &dev->struct_sem, 1 ); - - if ((DRM(minor)[i] = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) - return -EPERM; - dev->device = MKDEV(DRM_MAJOR, DRM(minor)[i] ); - dev->name = DRIVER_NAME; - -#if __REALLY_HAVE_AGP - dev->agp = DRM(agp_init)(); -#if __MUST_HAVE_AGP - if ( dev->agp == NULL ) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); - DRM(stub_unregister)(DRM(minor)[i]); - DRM(takedown)( dev ); - return -EINVAL; - } -#endif -#if __REALLY_HAVE_MTRR - 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 ); -#endif -#endif - -#if __HAVE_CTX_BITMAP - retcode = DRM(ctxbitmap_init)( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); - DRM(stub_unregister)(DRM(minor)[i]); - DRM(takedown)( dev ); - return retcode; - } -#endif - DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n", - DRIVER_NAME, - DRIVER_MAJOR, - DRIVER_MINOR, - DRIVER_PATCHLEVEL, - DRIVER_DATE, - DRM(minor)[i] ); + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { + DRM(probe)(pdev); } - - DRIVER_POSTINIT(); - return 0; } @@ -689,10 +684,10 @@ for (i = DRM(numdevs) - 1; i >= 0; i--) { dev = &(DRM(device)[i]); - if ( DRM(stub_unregister)(DRM(minor)[i]) ) { + if ( DRM(stub_unregister)(dev->minor) ) { DRM_ERROR( "Cannot unload module\n" ); } else { - DRM_DEBUG("minor %d unregistered\n", DRM(minor)[i]); + DRM_DEBUG("minor %d unregistered\n", dev->minor); if (i == 0) { DRM_INFO( "Module unloaded\n" ); } @@ -722,8 +717,6 @@ #endif } DRIVER_POSTCLEANUP(); - kfree(DRM(minor)); - kfree(DRM(device)); DRM(numdevs) = 0; } @@ -795,7 +788,7 @@ int i; for (i = 0; i < DRM(numdevs); i++) { - if (iminor(inode) == DRM(minor)[i]) { + if (iminor(inode) == DRM(device)[i].minor) { dev = &(DRM(device)[i]); break; } @@ -907,6 +900,26 @@ #endif 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 ) { +#ifdef DRIVER_CTX_DTOR + DRIVER_CTX_DTOR(pos->handle); +#endif +#if __HAVE_CTX_BITMAP + DRM(ctxbitmap_free)( dev, pos->handle ); +#endif + list_del( &pos->head ); + DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST ); + } + } + } + up( &dev->ctxlist_sem ); down( &dev->struct_sem ); if ( priv->remove_auth_on_close == 1 ) { diff -Nru a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h --- a/drivers/char/drm/drm_fops.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_fops.h Sat Apr 10 15:20:07 2004 @@ -72,6 +72,8 @@ priv->authenticated = capable(CAP_SYS_ADMIN); priv->lock_count = 0; + DRIVER_OPEN_HELPER( priv, dev ); + down(&dev->struct_sem); if (!dev->file_last) { priv->next = NULL; diff -Nru a/drivers/char/drm/drm_ioctl.h b/drivers/char/drm/drm_ioctl.h --- a/drivers/char/drm/drm_ioctl.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_ioctl.h Sat Apr 10 15:20:07 2004 @@ -35,69 +35,7 @@ #include "drmP.h" - -/** - * 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. - */ -int DRM(irq_busid)(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_irq_busid_t p; - struct pci_dev *dev; - - if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) - return -EFAULT; -#ifdef __alpha__ - { - int domain = p.busnum >> 8; - p.busnum &= 0xff; - - /* - * Find the hose the device is on (the domain number is the - * hose index) and offset the bus by the root bus of that - * hose. - */ - for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); - dev; - dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) { - struct pci_controller *hose = dev->sysdata; - - if (hose->index == domain) { - p.busnum += hose->bus->number; - break; - } - } - } -#endif - dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); - if (!dev) { - DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", - p.busnum, p.devnum, p.funcnum); - p.irq = 0; - goto out; - } - if (pci_enable_device(dev) != 0) { - DRM_ERROR("pci_enable_device failed for %d:%d:%d\n", - p.busnum, p.devnum, p.funcnum); - p.irq = 0; - goto out; - } - p.irq = dev->irq; - out: - DRM_DEBUG("%d:%d:%d => IRQ %d\n", - p.busnum, p.devnum, p.funcnum, p.irq); - if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p))) - return -EFAULT; - return 0; -} +#include "linux/pci.h" /** * Get the bus id. @@ -138,8 +76,10 @@ * \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 searches for - * the respective PCI device, updating drm_device::pdev. + * 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) @@ -147,6 +87,7 @@ 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; @@ -164,55 +105,42 @@ dev->devname = DRM(alloc)(strlen(dev->name) + strlen(dev->unique) + 2, DRM_MEM_DRIVER); - if(!dev->devname) { - DRM(free)(dev->devname, sizeof(*dev->devname), DRM_MEM_DRIVER); + if (!dev->devname) return -ENOMEM; - } + sprintf(dev->devname, "%s@%s", dev->name, dev->unique); - do { - struct pci_dev *pci_dev; - int domain, b, d, f; - char *p; - - for(p = dev->unique; p && *p && *p != ':'; p++); - if (!p || !*p) break; - b = (int)simple_strtoul(p+1, &p, 10); - if (*p != ':') break; - d = (int)simple_strtoul(p+1, &p, 10); - if (*p != ':') break; - f = (int)simple_strtoul(p+1, &p, 10); - if (*p) break; - - domain = b >> 8; - b &= 0xff; - -#ifdef __alpha__ - /* - * Find the hose the device is on (the domain number is the - * hose index) and offset the bus by the root bus of that - * hose. - */ - for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); - pci_dev; - pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { - struct pci_controller *hose = pci_dev->sysdata; - - if (hose->index == domain) { - b += hose->bus->number; - break; - } - } -#endif + /* 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; - pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); - if (pci_dev) { - dev->pdev = pci_dev; -#ifdef __alpha__ - dev->hose = pci_dev->sysdata; -#endif - } - } while(0); + 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); return 0; } @@ -361,5 +289,49 @@ if (copy_to_user((drm_stats_t *)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_COPY_FROM_USER_IOCTL(sv, (drm_set_version_t *)data, 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((drm_set_version_t *)data, 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; +#ifdef DRIVER_SETVERSION + DRIVER_SETVERSION(dev, &sv); +#endif + } return 0; } diff -Nru a/drivers/char/drm/drm_irq.h b/drivers/char/drm/drm_irq.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/drm/drm_irq.h Sat Apr 10 15:20:07 2004 @@ -0,0 +1,372 @@ +/** + * \file drm_irq.h + * IRQ support + * + * \author Rickard E. (Rik) Faith + * \author Gareth Hughes + */ + +/* + * 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. + */ + +#define __NO_VERSION__ +#include "drmP.h" + +#include /* For task queue support */ + +#ifndef __HAVE_SHARED_IRQ +#define __HAVE_SHARED_IRQ 0 +#endif + +#if __HAVE_SHARED_IRQ +#define DRM_IRQ_TYPE SA_SHIRQ +#else +#define DRM_IRQ_TYPE 0 +#endif + +/** + * 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 p; + + if (copy_from_user(&p, (drm_irq_busid_t *)arg, 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((drm_irq_busid_t *)arg, &p, sizeof(p))) + return -EFAULT; + return 0; +} + +#if __HAVE_IRQ + +/** + * 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; + + 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 __HAVE_DMA + dev->dma->next_buffer = NULL; + dev->dma->next_queue = NULL; + dev->dma->this_buffer = NULL; +#endif + +#if __HAVE_IRQ_BH + INIT_WORK(&dev->work, DRM(irq_immediate_bh), dev); +#endif + +#if __HAVE_VBL_IRQ + init_waitqueue_head(&dev->vbl_queue); + + spin_lock_init( &dev->vbl_lock ); + + INIT_LIST_HEAD( &dev->vbl_sigs.head ); + + dev->vbl_pending = 0; +#endif + + /* Before installing handler */ + DRM(driver_irq_preinstall)(dev); + + /* Install handler */ + ret = request_irq( dev->irq, DRM(irq_handler), + DRM_IRQ_TYPE, dev->devname, dev ); + if ( ret < 0 ) { + down( &dev->struct_sem ); + dev->irq_enabled = 0; + up( &dev->struct_sem ); + return ret; + } + + /* After installing handler */ + DRM(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; + + 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 ); + + DRM(driver_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 ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + if (dev->if_version < DRM_IF_VERSION(1, 2) && + ctl.irq != dev->irq) + return -EINVAL; + return DRM(irq_install)( dev ); + case DRM_UNINST_HANDLER: + return DRM(irq_uninstall)( dev ); + default: + return -EINVAL; + } +} + +#if __HAVE_VBL_IRQ + +/** + * 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 vblwait; + struct timeval now; + int ret = 0; + unsigned int flags; + + if (!dev->irq) + return -EINVAL; + + DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data, + 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 { + ret = DRM(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( (drm_wait_vblank_t *)data, 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 ); +} + +#endif /* __HAVE_VBL_IRQ */ + +#endif /* __HAVE_IRQ */ 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 Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_memory_debug.h Sat Apr 10 15:20:07 2004 @@ -67,6 +67,7 @@ [DRM_MEM_TOTALAGP] = { "totalagp" }, [DRM_MEM_BOUNDAGP] = { "boundagp" }, [DRM_MEM_CTXBITMAP] = { "ctxbitmap"}, + [DRM_MEM_CTXLIST] = { "ctxlist" }, [DRM_MEM_STUB] = { "stub" }, { NULL, 0, } /* Last entry must be null */ }; 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 Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_os_linux.h Sat Apr 10 15:20:07 2004 @@ -62,14 +62,20 @@ verify_area( VERIFY_READ, uaddr, size ) #define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ __copy_from_user(arg1, arg2, arg3) +#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \ + __copy_to_user(arg1, arg2, arg3) #define DRM_GET_USER_UNCHECKED(val, uaddr) \ __get_user(val, uaddr) +#define DRM_PUT_USER_UNCHECKED(uaddr, val) \ + __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 /** * Get the pointer to the SAREA. diff -Nru a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h --- a/drivers/char/drm/drm_sarea.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_sarea.h Sat Apr 10 15:20:07 2004 @@ -32,8 +32,22 @@ #ifndef _DRM_SAREA_H_ #define _DRM_SAREA_H_ +#include "drm.h" + +/* SAREA area needs to be at least a page */ +#if defined(__alpha__) +#define SAREA_MAX 0x2000 +#elif defined(__ia64__) +#define SAREA_MAX 0x10000 /* 64kB */ +#else +/* Intel 830M driver needs at least 8k SAREA */ +#define SAREA_MAX 0x2000 +#endif + /** Maximum number of drawables in the SAREA */ #define SAREA_MAX_DRAWABLES 256 + +#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000 /** SAREA drawable */ typedef struct drm_sarea_drawable { diff -Nru a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h --- a/drivers/char/drm/drm_stub.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_stub.h Sat Apr 10 15:20:07 2004 @@ -209,8 +209,8 @@ ret2 = DRM(stub_info).info_register(name, fops, dev); if (ret2) { if (!ret1) { - unregister_chrdev(DRM_MAJOR, "drm"); - class_simple_destroy(drm_class); + unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_destroy(drm_class); } if (!i) inter_module_unregister("drm"); diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h --- a/drivers/char/drm/drm_vm.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/drm_vm.h Sat Apr 10 15:20:07 2004 @@ -35,48 +35,19 @@ #include "drmP.h" -/** AGP virtual memory operations */ -struct vm_operations_struct DRM(vm_ops) = { - .nopage = DRM(vm_nopage), - .open = DRM(vm_open), - .close = DRM(vm_close), -}; - -/** Shared virtual memory operations */ -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 */ -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 */ -struct vm_operations_struct DRM(vm_sg_ops) = { - .nopage = DRM(vm_sg_nopage), - .open = DRM(vm_open), - .close = DRM(vm_close), -}; /** * \c nopage method for AGP virtual memory. * * \param vma virtual memory area. * \param address access address. - * \param write_access sharing. * \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. */ -struct page *DRM(vm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type) +static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma, + unsigned long address) { #if __REALLY_HAVE_AGP drm_file_t *priv = vma->vm_file->private_data; @@ -133,8 +104,6 @@ baddr, __va(agpmem->memory->memory[offset]), offset, atomic_read(&page->count)); - if (type) - *type = VM_FAULT_MINOR; return page; } vm_nopage_error: @@ -148,15 +117,13 @@ * * \param vma virtual memory area. * \param address access address. - * \param write_access sharing. * \return pointer to the page structure. * * Get the the mapping, find the real physical page to map, get the page, and * return it. */ -struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type) +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; @@ -172,8 +139,6 @@ if (!page) return NOPAGE_OOM; get_page(page); - if (type) - *type = VM_FAULT_MINOR; DRM_DEBUG("shm_nopage 0x%lx\n", address); return page; @@ -265,14 +230,12 @@ * * \param vma virtual memory area. * \param address access address. - * \param write_access sharing. * \return pointer to the page structure. * * Determine the page number from the page offset and get it from drm_device_dma::pagelist. */ -struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type) +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; @@ -291,8 +254,6 @@ (offset & (~PAGE_MASK)))); get_page(page); - if (type) - *type = VM_FAULT_MINOR; DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); return page; @@ -303,14 +264,12 @@ * * \param vma virtual memory area. * \param address access address. - * \param write_access sharing. * \return pointer to the page structure. * * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. */ -struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma, - unsigned long address, - int *type) +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; @@ -331,11 +290,98 @@ page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); page = entry->pagelist[page_offset]; get_page(page); - if (type) - *type = VM_FAULT_MINOR; 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. diff -Nru a/drivers/char/drm/gamma.h b/drivers/char/drm/gamma.h --- a/drivers/char/drm/gamma.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/gamma.h Sat Apr 10 15:20:07 2004 @@ -53,6 +53,10 @@ [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \ [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 } +#define DRIVER_PCI_IDS \ + {0x3d3d, 0x0008, 0}, \ + {0, 0, 0} + #define IOCTL_TABLE_NAME DRM(ioctls) #define IOCTL_FUNC_NAME DRM(ioctl) @@ -104,8 +108,8 @@ return 0; \ } while (0) -#define __HAVE_DMA_IRQ 1 -#define __HAVE_DMA_IRQ_BH 1 +#define __HAVE_IRQ 1 +#define __HAVE_IRQ_BH 1 #define DRIVER_AGP_BUFFERS_MAP( dev ) \ ((drm_gamma_private_t *)((dev)->dev_private))->buffers diff -Nru a/drivers/char/drm/gamma_dma.c b/drivers/char/drm/gamma_dma.c --- a/drivers/char/drm/gamma_dma.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/gamma_dma.c Sat Apr 10 15:20:07 2004 @@ -116,7 +116,7 @@ return (!GAMMA_READ(GAMMA_DMACOUNT)); } -irqreturn_t gamma_dma_service( DRM_IRQ_ARGS ) +irqreturn_t gamma_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *)arg; drm_device_dma_t *dma = dev->dma; @@ -262,7 +262,7 @@ gamma_dma_schedule((drm_device_t *)dev, 0); } -void gamma_dma_immediate_bh(void *dev) +void gamma_irq_immediate_bh(void *dev) { gamma_dma_schedule(dev, 0); } @@ -656,12 +656,12 @@ { DRM_DEBUG( "%s\n", __FUNCTION__ ); -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq ) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if ( dev->dev_private ) { diff -Nru a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c --- a/drivers/char/drm/gamma_drv.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/gamma_drv.c Sat Apr 10 15:20:07 2004 @@ -48,6 +48,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "gamma_lists.h" /* NOTE */ #include "drm_lock.h" #include "gamma_lock.h" /* NOTE */ diff -Nru a/drivers/char/drm/i810.h b/drivers/char/drm/i810.h --- a/drivers/char/drm/i810.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i810.h Sat Apr 10 15:20:07 2004 @@ -77,7 +77,14 @@ [DRM_IOCTL_NR(DRM_IOCTL_I810_MC)] = { i810_dma_mc, 1, 1 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_FLIP)] = { i810_flip_bufs, 1, 0 } - + +#define DRIVER_PCI_IDS \ + {0x8086, 0x7121, 0}, \ + {0x8086, 0x7123, 0}, \ + {0x8086, 0x7125, 0}, \ + {0x8086, 0x1132, 0}, \ + {0, 0, 0} + #define __HAVE_COUNTERS 4 #define __HAVE_COUNTER6 _DRM_STAT_IRQ @@ -112,7 +119,7 @@ * a noop stub is generated for compatibility. */ /* XXX: Add vblank support? */ -#define __HAVE_DMA_IRQ 0 +#define __HAVE_IRQ 0 /* Buffer customization: */ diff -Nru a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c --- a/drivers/char/drm/i810_dma.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i810_dma.c Sat Apr 10 15:20:07 2004 @@ -232,12 +232,12 @@ { drm_device_dma_t *dma = dev->dma; -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if (dev->irq) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if (dev->dev_private) { diff -Nru a/drivers/char/drm/i830.h b/drivers/char/drm/i830.h --- a/drivers/char/drm/i830.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i830.h Sat Apr 10 15:20:07 2004 @@ -77,6 +77,13 @@ [DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 } +#define DRIVER_PCI_IDS \ + {0x8086, 0x3577, 0}, \ + {0x8086, 0x2562, 0}, \ + {0x8086, 0x3582, 0}, \ + {0x8086, 0x2572, 0}, \ + {0, 0, 0} + #define __HAVE_COUNTERS 4 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY @@ -115,10 +122,10 @@ #define USE_IRQS 0 #if USE_IRQS -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_SHARED_IRQ 1 #else -#define __HAVE_DMA_IRQ 0 +#define __HAVE_IRQ 0 #endif diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c --- a/drivers/char/drm/i830_dma.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i830_dma.c Sat Apr 10 15:20:07 2004 @@ -231,12 +231,12 @@ { drm_device_dma_t *dma = dev->dma; -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if (dev->irq) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if (dev->dev_private) { @@ -1539,7 +1539,7 @@ switch( param.param ) { case I830_PARAM_IRQ_ACTIVE: - value = dev->irq ? 1 : 0; + value = dev->irq_enabled; break; default: return -EINVAL; diff -Nru a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c --- a/drivers/char/drm/i830_drv.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i830_drv.c Sat Apr 10 15:20:07 2004 @@ -50,6 +50,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff -Nru a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c --- a/drivers/char/drm/i830_irq.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/i830_irq.c Sat Apr 10 15:20:07 2004 @@ -35,7 +35,7 @@ #include -irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ) +irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *)arg; drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private; diff -Nru a/drivers/char/drm/mga.h b/drivers/char/drm/mga.h --- a/drivers/char/drm/mga.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga.h Sat Apr 10 15:20:07 2004 @@ -64,6 +64,12 @@ [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_GETPARAM)]= { mga_getparam, 1, 0 }, +#define DRIVER_PCI_IDS \ + {0x102b, 0x0521, 0}, \ + {0x102b, 0x0525, 0}, \ + {0x102b, 0x2527, 0}, \ + {0, 0, 0} + #define __HAVE_COUNTERS 3 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY @@ -78,7 +84,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff -Nru a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c --- a/drivers/char/drm/mga_dma.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga_dma.c Sat Apr 10 15:20:07 2004 @@ -500,14 +500,6 @@ return DRM_ERR(EINVAL); } - DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); - if(!dev_priv->fb) { - DRM_ERROR( "failed to find framebuffer!\n" ); - /* Assign dev_private so we can do cleanup. */ - dev->dev_private = (void *)dev_priv; - mga_do_cleanup_dma( dev ); - return DRM_ERR(EINVAL); - } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { DRM_ERROR( "failed to find mmio region!\n" ); @@ -639,12 +631,12 @@ { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq ) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if ( dev->dev_private ) { diff -Nru a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h --- a/drivers/char/drm/mga_drm.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga_drm.h Sat Apr 10 15:20:07 2004 @@ -117,6 +117,8 @@ #define MGA_NR_TEX_REGIONS 16 #define MGA_LOG_MIN_TEX_REGION_SIZE 16 +#define DRM_MGA_IDLE_RETRY 2048 + #endif /* __MGA_SAREA_DEFINES__ */ @@ -230,16 +232,27 @@ /* MGA specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t) -#define DRM_IOCTL_MGA_RESET DRM_IO( 0x42) -#define DRM_IOCTL_MGA_SWAP DRM_IO( 0x43) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x44, drm_mga_clear_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x45, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x47, drm_mga_iload_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x48, drm_mga_blit_t) -#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(0x49, drm_mga_getparam_t) +#define DRM_MGA_INIT 0x00 +#define DRM_MGA_FLUSH 0x01 +#define DRM_MGA_RESET 0x02 +#define DRM_MGA_SWAP 0x03 +#define DRM_MGA_CLEAR 0x04 +#define DRM_MGA_VERTEX 0x05 +#define DRM_MGA_INDICES 0x06 +#define DRM_MGA_ILOAD 0x07 +#define DRM_MGA_BLIT 0x08 +#define DRM_MGA_GETPARAM 0x09 + +#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) +#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) +#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t) +#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t) typedef struct _drm_mga_warp_index { int installed; @@ -330,7 +343,7 @@ typedef struct drm_mga_getparam { int param; - int *value; + void *value; } drm_mga_getparam_t; #endif diff -Nru a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c --- a/drivers/char/drm/mga_drv.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga_drv.c Sat Apr 10 15:20:07 2004 @@ -45,6 +45,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff -Nru a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h --- a/drivers/char/drm/mga_drv.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga_drv.h Sat Apr 10 15:20:07 2004 @@ -91,7 +91,6 @@ unsigned int texture_size; drm_local_map_t *sarea; - drm_local_map_t *fb; drm_local_map_t *mmio; drm_local_map_t *status; drm_local_map_t *warp; diff -Nru a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c --- a/drivers/char/drm/mga_irq.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/mga_irq.c Sat Apr 10 15:20:07 2004 @@ -36,7 +36,7 @@ #include "mga_drm.h" #include "mga_drv.h" -irqreturn_t mga_dma_service( DRM_IRQ_ARGS ) +irqreturn_t mga_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_mga_private_t *dev_priv = diff -Nru a/drivers/char/drm/r128.h b/drivers/char/drm/r128.h --- a/drivers/char/drm/r128.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128.h Sat Apr 10 15:20:07 2004 @@ -79,6 +79,46 @@ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_GETPARAM)] = { r128_getparam, 1, 0 }, +#define DRIVER_PCI_IDS \ + {0x1002, 0x4c45, 0}, \ + {0x1002, 0x4c46, 0}, \ + {0x1002, 0x4d46, 0}, \ + {0x1002, 0x4d4c, 0}, \ + {0x1002, 0x5041, 0}, \ + {0x1002, 0x5042, 0}, \ + {0x1002, 0x5043, 0}, \ + {0x1002, 0x5044, 0}, \ + {0x1002, 0x5045, 0}, \ + {0x1002, 0x5046, 0}, \ + {0x1002, 0x5047, 0}, \ + {0x1002, 0x5048, 0}, \ + {0x1002, 0x5049, 0}, \ + {0x1002, 0x504A, 0}, \ + {0x1002, 0x504B, 0}, \ + {0x1002, 0x504C, 0}, \ + {0x1002, 0x504D, 0}, \ + {0x1002, 0x504E, 0}, \ + {0x1002, 0x504F, 0}, \ + {0x1002, 0x5050, 0}, \ + {0x1002, 0x5051, 0}, \ + {0x1002, 0x5052, 0}, \ + {0x1002, 0x5053, 0}, \ + {0x1002, 0x5054, 0}, \ + {0x1002, 0x5055, 0}, \ + {0x1002, 0x5056, 0}, \ + {0x1002, 0x5057, 0}, \ + {0x1002, 0x5058, 0}, \ + {0x1002, 0x5245, 0}, \ + {0x1002, 0x5246, 0}, \ + {0x1002, 0x5247, 0}, \ + {0x1002, 0x524b, 0}, \ + {0x1002, 0x524c, 0}, \ + {0x1002, 0x534d, 0}, \ + {0x1002, 0x5446, 0}, \ + {0x1002, 0x544C, 0}, \ + {0x1002, 0x5452, 0}, \ + {0, 0, 0} + /* Driver customization: */ #define DRIVER_PRERELEASE() do { \ @@ -97,7 +137,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c --- a/drivers/char/drm/r128_cce.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_cce.c Sat Apr 10 15:20:07 2004 @@ -212,7 +212,7 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { + if ( GET_RING_HEAD( dev_priv ) == dev_priv->ring.tail ) { int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -238,7 +238,8 @@ r128_do_wait_for_idle( dev_priv ); R128_WRITE( R128_PM4_BUFFER_CNTL, - dev_priv->cce_mode | dev_priv->ring.size_l2qw ); + dev_priv->cce_mode | dev_priv->ring.size_l2qw + | R128_PM4_BUFFER_CNTL_NOUPDATE ); R128_READ( R128_PM4_BUFFER_ADDR ); /* as per the sample code */ R128_WRITE( R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN ); @@ -253,7 +254,6 @@ { R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); - SET_RING_HEAD( &dev_priv->ring, 0 ); dev_priv->ring.tail = 0; } @@ -264,7 +264,8 @@ static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) { R128_WRITE( R128_PM4_MICRO_CNTL, 0 ); - R128_WRITE( R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4 ); + R128_WRITE( R128_PM4_BUFFER_CNTL, + R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE ); dev_priv->cce_running = 0; } @@ -333,26 +334,6 @@ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); - /* DL_RPTR_ADDR is a physical address in AGP space. */ - SET_RING_HEAD( &dev_priv->ring, 0 ); - - if ( !dev_priv->is_pci ) { - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); - } else { - drm_sg_mem_t *entry = dev->sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle; - page_ofs = tmp_ofs >> PAGE_SHIFT; - - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - entry->busaddr[page_ofs]); - DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long) entry->busaddr[page_ofs], - entry->handle + tmp_ofs ); - } - /* Set watermark control */ R128_WRITE( R128_PM4_BUFFER_WM_CNTL, ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) @@ -486,13 +467,6 @@ return DRM_ERR(EINVAL); } - DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); - if(!dev_priv->fb) { - DRM_ERROR("could not find framebuffer!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce( dev ); - return DRM_ERR(EINVAL); - } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); @@ -567,9 +541,6 @@ #endif dev_priv->cce_buffers_offset = dev->sg->handle; - dev_priv->ring.head = ((__volatile__ u32 *) - dev_priv->ring_rptr->handle); - dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle + init->ring_size / sizeof(u32)); @@ -580,7 +551,6 @@ (dev_priv->ring.size / sizeof(u32)) - 1; dev_priv->ring.high_mark = 128; - dev_priv->ring.ring_rptr = dev_priv->ring_rptr; dev_priv->sarea_priv->last_frame = 0; R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame ); @@ -589,8 +559,9 @@ R128_WRITE( R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch ); -#if __REALLY_HAVE_SG +#if __REALLY_HAVE_AGP if ( dev_priv->is_pci ) { +#endif if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, &dev_priv->bus_pci_gart) ) { DRM_ERROR( "failed to init PCI GART!\n" ); @@ -599,6 +570,7 @@ return DRM_ERR(ENOMEM); } R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart ); +#if __REALLY_HAVE_AGP } #endif @@ -615,12 +587,12 @@ int r128_do_cleanup_cce( drm_device_t *dev ) { -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq ) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if ( dev->dev_private ) { @@ -901,7 +873,7 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { - r128_update_ring_snapshot( ring ); + r128_update_ring_snapshot( dev_priv ); if ( ring->space >= n ) return 0; DRM_UDELAY( 1 ); diff -Nru a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h --- a/drivers/char/drm/r128_drm.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_drm.h Sat Apr 10 15:20:07 2004 @@ -176,24 +176,47 @@ /* Rage 128 specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) -#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) -#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) -#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t) -#define DRM_IOCTL_R128_GETPARAM DRM_IOW( 0x52, drm_r128_getparam_t) -#define DRM_IOCTL_R128_FLIP DRM_IO( 0x53) +#define DRM_R128_INIT 0x00 +#define DRM_R128_CCE_START 0x01 +#define DRM_R128_CCE_STOP 0x02 +#define DRM_R128_CCE_RESET 0x03 +#define DRM_R128_CCE_IDLE 0x04 +/* 0x05 not used */ +#define DRM_R128_RESET 0x06 +#define DRM_R128_SWAP 0x07 +#define DRM_R128_CLEAR 0x08 +#define DRM_R128_VERTEX 0x09 +#define DRM_R128_INDICES 0x0a +#define DRM_R128_BLIT 0x0b +#define DRM_R128_DEPTH 0x0c +#define DRM_R128_STIPPLE 0x0d +/* 0x0e not used */ +#define DRM_R128_INDIRECT 0x0f +#define DRM_R128_FULLSCREEN 0x10 +#define DRM_R128_CLEAR2 0x11 +#define DRM_R128_GETPARAM 0x12 +#define DRM_R128_FLIP 0x13 + +#define DRM_IOCTL_R128_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_START) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_RESET) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_IDLE) +/* 0x05 not used */ +#define DRM_IOCTL_R128_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_RESET) +#define DRM_IOCTL_R128_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_R128_SWAP) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t) +/* 0x0e not used */ +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t) +#define DRM_IOCTL_R128_GETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) +#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP) typedef struct drm_r128_init { enum { @@ -316,7 +339,7 @@ typedef struct drm_r128_getparam { int param; - int *value; + void *value; } drm_r128_getparam_t; #endif diff -Nru a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c --- a/drivers/char/drm/r128_drv.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_drv.c Sat Apr 10 15:20:07 2004 @@ -47,6 +47,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff -Nru a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h --- a/drivers/char/drm/r128_drv.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_drv.h Sat Apr 10 15:20:07 2004 @@ -34,8 +34,7 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */ -#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */ +#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) typedef struct drm_r128_freelist { unsigned int age; @@ -50,13 +49,11 @@ int size; int size_l2qw; - volatile u32 *head; u32 tail; u32 tail_mask; int space; int high_mark; - drm_local_map_t *ring_rptr; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { @@ -100,7 +97,6 @@ u32 span_pitch_offset_c; drm_local_map_t *sarea; - drm_local_map_t *fb; drm_local_map_t *mmio; drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; @@ -132,14 +128,6 @@ extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n ); -static __inline__ void -r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring ) -{ - ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32); - if ( ring->space <= 0 ) - ring->space += ring->size; -} - extern int r128_do_cce_idle( drm_r128_private_t *dev_priv ); extern int r128_do_cleanup_cce( drm_device_t *dev ); extern int r128_do_cleanup_pageflip( drm_device_t *dev ); @@ -279,6 +267,7 @@ # define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) # define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) # define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) +# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27) #define R128_PM4_BUFFER_WM_CNTL 0x0708 # define R128_WMA_SHIFT 0 @@ -403,6 +392,15 @@ (pkt) | ((n) << 16)) +static __inline__ void +r128_update_ring_snapshot( drm_r128_private_t *dev_priv ) +{ + drm_r128_ring_buffer_t *ring = &dev_priv->ring; + ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32); + if ( ring->space <= 0 ) + ring->space += ring->size; +} + /* ================================================================ * Misc helper macros */ @@ -412,7 +410,7 @@ drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ if ( ring->space < ring->high_mark ) { \ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \ - r128_update_ring_snapshot( ring ); \ + r128_update_ring_snapshot( dev_priv ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ DRM_UDELAY(1); \ @@ -445,17 +443,10 @@ * Ring control */ -#if defined(__powerpc__) -#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) -#else -#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER() -#endif - - #define R128_VERBOSE 0 #define RING_LOCALS \ - int write; unsigned int tail_mask; volatile u32 *ring; + int write, _nr; unsigned int tail_mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ @@ -463,9 +454,10 @@ (n), __FUNCTION__ ); \ } \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ + COMMIT_RING(); \ r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ tail_mask = dev_priv->ring.tail_mask; \ @@ -488,9 +480,23 @@ dev_priv->ring.start, \ write * sizeof(u32) ); \ } \ - r128_flush_write_combine(); \ - dev_priv->ring.tail = write; \ - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \ + if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ + ((dev_priv->ring.tail + _nr) & tail_mask), \ + write, __LINE__); \ + } else \ + dev_priv->ring.tail = write; \ +} while (0) + +#define COMMIT_RING() do { \ + if ( R128_VERBOSE ) { \ + DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \ + dev_priv->ring.tail ); \ + } \ + DRM_MEMORYBARRIER(); \ + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ + R128_READ( R128_PM4_BUFFER_DL_WPTR ); \ } while (0) #define OUT_RING( x ) do { \ diff -Nru a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c --- a/drivers/char/drm/r128_irq.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_irq.c Sat Apr 10 15:20:07 2004 @@ -36,7 +36,7 @@ #include "r128_drm.h" #include "r128_drv.h" -irqreturn_t r128_dma_service( DRM_IRQ_ARGS ) +irqreturn_t r128_irq_handler( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_r128_private_t *dev_priv = diff -Nru a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c --- a/drivers/char/drm/r128_state.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/r128_state.c Sat Apr 10 15:20:07 2004 @@ -45,7 +45,7 @@ RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 17 ); + BEGIN_RING( (count < 3? count: 3) * 5 + 2 ); if ( count >= 1 ) { OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) ); @@ -1011,7 +1011,7 @@ DRM_DEBUG( "\n" ); count = depth->n; - if (count > 4096 || count <= 0) + if (count > 4096 || count <= 0) return -EMSGSIZE; xbuf_size = count * sizeof(*x); @@ -1280,6 +1280,7 @@ sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; r128_cce_dispatch_clear( dev, &clear ); + COMMIT_RING(); /* Make sure we restore the 3D state next time. */ @@ -1315,8 +1316,10 @@ R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); - if (dev_priv->current_page != 0) + if (dev_priv->current_page != 0) { r128_cce_dispatch_flip( dev ); + COMMIT_RING(); + } dev_priv->page_flipping = 0; return 0; @@ -1341,6 +1344,7 @@ r128_cce_dispatch_flip( dev ); + COMMIT_RING(); return 0; } @@ -1362,6 +1366,7 @@ dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS); + COMMIT_RING(); return 0; } @@ -1421,6 +1426,7 @@ r128_cce_dispatch_vertex( dev, buf ); + COMMIT_RING(); return 0; } @@ -1492,6 +1498,7 @@ r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); + COMMIT_RING(); return 0; } @@ -1501,6 +1508,7 @@ drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; + int ret; LOCK_TEST_WITH_RETURN( dev, filp ); @@ -1518,7 +1526,10 @@ RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return r128_cce_dispatch_blit( filp, dev, &blit ); + ret = r128_cce_dispatch_blit( filp, dev, &blit ); + + COMMIT_RING(); + return ret; } int r128_cce_depth( DRM_IOCTL_ARGS ) @@ -1526,6 +1537,7 @@ DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; + int ret; LOCK_TEST_WITH_RETURN( dev, filp ); @@ -1534,18 +1546,20 @@ RING_SPACE_TEST_WITH_RETURN( dev_priv ); + ret = DRM_ERR(EINVAL); switch ( depth.func ) { case R128_WRITE_SPAN: - return r128_cce_dispatch_write_span( dev, &depth ); + ret = r128_cce_dispatch_write_span( dev, &depth ); case R128_WRITE_PIXELS: - return r128_cce_dispatch_write_pixels( dev, &depth ); + ret = r128_cce_dispatch_write_pixels( dev, &depth ); case R128_READ_SPAN: - return r128_cce_dispatch_read_span( dev, &depth ); + ret = r128_cce_dispatch_read_span( dev, &depth ); case R128_READ_PIXELS: - return r128_cce_dispatch_read_pixels( dev, &depth ); + ret = r128_cce_dispatch_read_pixels( dev, &depth ); } - return DRM_ERR(EINVAL); + COMMIT_RING(); + return ret; } int r128_cce_stipple( DRM_IOCTL_ARGS ) @@ -1568,6 +1582,7 @@ r128_cce_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1643,6 +1658,7 @@ */ r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + COMMIT_RING(); return 0; } diff -Nru a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h --- a/drivers/char/drm/radeon.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon.h Sat Apr 10 15:20:07 2004 @@ -51,7 +51,7 @@ #define DRIVER_DATE "20020828" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 9 +#define DRIVER_MINOR 10 #define DRIVER_PATCHLEVEL 0 /* Interface history: @@ -81,6 +81,9 @@ * 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 */ #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \ @@ -106,10 +109,82 @@ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_ALLOC)] = { radeon_mem_alloc, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FREE)] = { radeon_mem_free, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INIT_HEAP)] = { radeon_mem_init_heap, 1, 1 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SETPARAM)] = { radeon_cp_setparam, 1, 0 }, \ + +#define DRIVER_PCI_IDS \ + {0x1002, 0x4136, 0}, \ + {0x1002, 0x4137, 0}, \ + {0x1002, 0x4237, 0}, \ + {0x1002, 0x4242, 0}, \ + {0x1002, 0x4242, 0}, \ + {0x1002, 0x4336, 0}, \ + {0x1002, 0x4337, 0}, \ + {0x1002, 0x4437, 0}, \ + {0x1002, 0x4964, 0}, \ + {0x1002, 0x4965, 0}, \ + {0x1002, 0x4966, 0}, \ + {0x1002, 0x4967, 0}, \ + {0x1002, 0x4C57, 0}, \ + {0x1002, 0x4C58, 0}, \ + {0x1002, 0x4C59, 0}, \ + {0x1002, 0x4C5A, 0}, \ + {0x1002, 0x4C64, 0}, \ + {0x1002, 0x4C65, 0}, \ + {0x1002, 0x4C66, 0}, \ + {0x1002, 0x4C67, 0}, \ + {0x1002, 0x5144, 0}, \ + {0x1002, 0x5145, 0}, \ + {0x1002, 0x5146, 0}, \ + {0x1002, 0x5147, 0}, \ + {0x1002, 0x5148, 0}, \ + {0x1002, 0x5149, 0}, \ + {0x1002, 0x514A, 0}, \ + {0x1002, 0x514B, 0}, \ + {0x1002, 0x514C, 0}, \ + {0x1002, 0x514D, 0}, \ + {0x1002, 0x514E, 0}, \ + {0x1002, 0x514F, 0}, \ + {0x1002, 0x5157, 0}, \ + {0x1002, 0x5158, 0}, \ + {0x1002, 0x5159, 0}, \ + {0x1002, 0x515A, 0}, \ + {0x1002, 0x5168, 0}, \ + {0x1002, 0x5169, 0}, \ + {0x1002, 0x516A, 0}, \ + {0x1002, 0x516B, 0}, \ + {0x1002, 0x516C, 0}, \ + {0x1002, 0x5834, 0}, \ + {0x1002, 0x5835, 0}, \ + {0x1002, 0x5836, 0}, \ + {0x1002, 0x5837, 0}, \ + {0x1002, 0x5960, 0}, \ + {0x1002, 0x5961, 0}, \ + {0x1002, 0x5962, 0}, \ + {0x1002, 0x5963, 0}, \ + {0x1002, 0x5964, 0}, \ + {0x1002, 0x5968, 0}, \ + {0x1002, 0x5969, 0}, \ + {0x1002, 0x596A, 0}, \ + {0x1002, 0x596B, 0}, \ + {0x1002, 0x5c61, 0}, \ + {0x1002, 0x5c62, 0}, \ + {0x1002, 0x5c63, 0}, \ + {0x1002, 0x5c64, 0}, \ + {0, 0, 0} +#define DRIVER_FILE_FIELDS \ + int64_t radeon_fb_delta; \ +#define DRIVER_OPEN_HELPER( filp_priv, dev ) \ +do { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + if ( dev_priv ) \ + filp_priv->radeon_fb_delta = dev_priv->fb_location; \ + else \ + filp_priv->radeon_fb_delta = 0; \ +} while( 0 ) /* When a client dies: * - Check for and clean up flipped page state @@ -142,7 +217,7 @@ /* DMA customization: */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 +#define __HAVE_IRQ 1 #define __HAVE_VBL_IRQ 1 #define __HAVE_SHARED_IRQ 1 diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c --- a/drivers/char/drm/radeon_cp.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_cp.c Sat Apr 10 15:20:07 2004 @@ -855,7 +855,8 @@ /* Initialize the memory controller */ RADEON_WRITE( RADEON_MC_FB_LOCATION, - (dev_priv->gart_vm_start - 1) & 0xffff0000 ); + ( ( dev_priv->gart_vm_start - 1 ) & 0xffff0000 ) + | ( dev_priv->fb_location >> 16 ) ); #if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) { @@ -1071,13 +1072,6 @@ dev_priv->depth_offset = init->depth_offset; dev_priv->depth_pitch = init->depth_pitch; - dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | - (dev_priv->front_offset >> 10)); - dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | - (dev_priv->back_offset >> 10)); - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | - (dev_priv->depth_offset >> 10)); - /* Hardware state for depth clears. Remove this if/when we no * longer clear the depth buffer with a 3D rectangle. Hard-code * all values to prevent unwanted 3D state from slipping through @@ -1124,13 +1118,6 @@ return DRM_ERR(EINVAL); } - DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); - if(!dev_priv->fb) { - DRM_ERROR("could not find framebuffer!\n"); - dev->dev_private = (void *)dev_priv; - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { DRM_ERROR("could not find mmio region!\n"); @@ -1204,9 +1191,26 @@ dev_priv->buffers->handle ); } + dev_priv->fb_location = ( RADEON_READ( RADEON_MC_FB_LOCATION ) + & 0xffff ) << 16; + + dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | + ( ( dev_priv->front_offset + + dev_priv->fb_location ) >> 10 ) ); + + dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | + ( ( dev_priv->back_offset + + dev_priv->fb_location ) >> 10 ) ); + + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | + ( ( dev_priv->depth_offset + + dev_priv->fb_location ) >> 10 ) ); + dev_priv->gart_size = init->gart_size; - dev_priv->gart_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); + dev_priv->gart_vm_start = dev_priv->fb_location + + RADEON_READ( RADEON_CONFIG_APER_SIZE ); + #if __REALLY_HAVE_AGP if ( !dev_priv->is_pci ) dev_priv->gart_buffers_offset = (dev_priv->buffers->offset @@ -1271,12 +1275,12 @@ { DRM_DEBUG( "\n" ); -#if _HAVE_DMA_IRQ +#if __HAVE_IRQ /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. */ - if ( dev->irq ) DRM(irq_uninstall)(dev); + if ( dev->irq_enabled ) DRM(irq_uninstall)(dev); #endif if ( dev->dev_private ) { diff -Nru a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h --- a/drivers/char/drm/radeon_drm.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_drm.h Sat Apr 10 15:20:07 2004 @@ -226,6 +226,13 @@ #define RADEON_MAX_TEXTURE_LEVELS 12 #define RADEON_MAX_TEXTURE_UNITS 3 +/* Blits have strict offset rules. All blit offset must be aligned on + * a 1K-byte boundary. + */ +#define RADEON_OFFSET_SHIFT 10 +#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT) +#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1) + #endif /* __RADEON_SAREA_DEFINES__ */ typedef struct { @@ -365,31 +372,58 @@ /* Radeon specific ioctls * The device specific ioctl range is 0x40 to 0x79. */ -#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) -#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) -#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) -#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) -#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) -#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) -#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) -#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) -#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) -#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) -#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) -#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t) -#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex2_t) -#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t) -#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t) -#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52) -#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR( 0x53, drm_radeon_mem_alloc_t) -#define DRM_IOCTL_RADEON_FREE DRM_IOW( 0x54, drm_radeon_mem_free_t) -#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( 0x55, drm_radeon_mem_init_heap_t) -#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR( 0x56, drm_radeon_irq_emit_t) -#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( 0x57, drm_radeon_irq_wait_t) -/* added by Charl P. Botha - see radeon_cp.c for details */ -#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO(0x58) +#define DRM_RADEON_CP_INIT 0x00 +#define DRM_RADEON_CP_START 0x01 +#define DRM_RADEON_CP_STOP 0x02 +#define DRM_RADEON_CP_RESET 0x03 +#define DRM_RADEON_CP_IDLE 0x04 +#define DRM_RADEON_RESET 0x05 +#define DRM_RADEON_FULLSCREEN 0x06 +#define DRM_RADEON_SWAP 0x07 +#define DRM_RADEON_CLEAR 0x08 +#define DRM_RADEON_VERTEX 0x09 +#define DRM_RADEON_INDICES 0x0A +#define DRM_RADEON_NOT_USED +#define DRM_RADEON_STIPPLE 0x0C +#define DRM_RADEON_INDIRECT 0x0D +#define DRM_RADEON_TEXTURE 0x0E +#define DRM_RADEON_VERTEX2 0x0F +#define DRM_RADEON_CMDBUF 0x10 +#define DRM_RADEON_GETPARAM 0x11 +#define DRM_RADEON_FLIP 0x12 +#define DRM_RADEON_ALLOC 0x13 +#define DRM_RADEON_FREE 0x14 +#define DRM_RADEON_INIT_HEAP 0x15 +#define DRM_RADEON_IRQ_EMIT 0x16 +#define DRM_RADEON_IRQ_WAIT 0x17 +#define DRM_RADEON_CP_RESUME 0x18 +#define DRM_RADEON_SETPARAM 0x19 + +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESET) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_IDLE) +#define DRM_IOCTL_RADEON_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_RESET) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FULLSCREEN, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_SWAP) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CLEAR, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INDICES, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_STIPPLE, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INDIRECT, drm_radeon_indirect_t) +#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_TEXTURE, drm_radeon_texture_t) +#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX2, drm_radeon_vertex2_t) +#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CMDBUF, drm_radeon_cmd_buffer_t) +#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GETPARAM, drm_radeon_getparam_t) +#define DRM_IOCTL_RADEON_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_FLIP) +#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_ALLOC, drm_radeon_mem_alloc_t) +#define DRM_IOCTL_RADEON_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FREE, drm_radeon_mem_free_t) +#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INIT_HEAP, drm_radeon_mem_init_heap_t) +#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_IRQ_EMIT, drm_radeon_irq_emit_t) +#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t) +#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME) +#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t) typedef struct drm_radeon_init { enum { @@ -502,7 +536,7 @@ } drm_radeon_tex_image_t; typedef struct drm_radeon_texture { - int offset; + unsigned int offset; int pitch; int format; int width; /* Texture image coordinates */ @@ -537,10 +571,11 @@ #define RADEON_PARAM_STATUS_HANDLE 8 #define RADEON_PARAM_SAREA_HANDLE 9 #define RADEON_PARAM_GART_TEX_HANDLE 10 +#define RADEON_PARAM_SCRATCH_OFFSET 11 typedef struct drm_radeon_getparam { int param; - int *value; + void *value; } drm_radeon_getparam_t; /* 1.6: Set up a memory manager for regions of shared memory: @@ -576,6 +611,18 @@ typedef struct drm_radeon_irq_wait { int irq_seq; } drm_radeon_irq_wait_t; + + +/* 1.10: Clients tell the DRM where they think the framebuffer is located in + * the card's address space, via a new generic ioctl to set parameters + */ + +typedef struct drm_radeon_setparam { + unsigned int param; + int64_t value; +} drm_radeon_setparam_t; + +#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #endif diff -Nru a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c --- a/drivers/char/drm/radeon_drv.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_drv.c Sat Apr 10 15:20:07 2004 @@ -48,6 +48,7 @@ #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" +#include "drm_irq.h" #include "drm_lock.h" #include "drm_memory.h" #include "drm_proc.h" diff -Nru a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h --- a/drivers/char/drm/radeon_drv.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_drv.h Sat Apr 10 15:20:07 2004 @@ -73,6 +73,8 @@ drm_radeon_ring_buffer_t ring; drm_radeon_sarea_t *sarea_priv; + u32 fb_location; + int gart_size; u32 gart_vm_start; unsigned long gart_buffers_offset; @@ -133,7 +135,6 @@ unsigned long gart_textures_offset; drm_local_map_t *sarea; - drm_local_map_t *fb; drm_local_map_t *mmio; drm_local_map_t *cp_ring; drm_local_map_t *ring_rptr; @@ -184,6 +185,7 @@ extern int radeon_cp_vertex2( DRM_IOCTL_ARGS ); extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ); extern int radeon_cp_getparam( DRM_IOCTL_ARGS ); +extern int radeon_cp_setparam( DRM_IOCTL_ARGS ); extern int radeon_cp_flip( DRM_IOCTL_ARGS ); extern int radeon_mem_alloc( DRM_IOCTL_ARGS ); @@ -239,6 +241,7 @@ #define RADEON_CRTC2_OFFSET 0x0324 #define RADEON_CRTC2_OFFSET_CNTL 0x0328 +#define RADEON_RB3D_COLOROFFSET 0x1c40 #define RADEON_RB3D_COLORPITCH 0x1c48 #define RADEON_DP_GUI_MASTER_CNTL 0x146c @@ -332,6 +335,7 @@ #define RADEON_PP_MISC 0x1c14 #define RADEON_PP_ROT_MATRIX_0 0x1d58 #define RADEON_PP_TXFILTER_0 0x1c54 +#define RADEON_PP_TXOFFSET_0 0x1c5c #define RADEON_PP_TXFILTER_1 0x1c6c #define RADEON_PP_TXFILTER_2 0x1c84 diff -Nru a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c --- a/drivers/char/drm/radeon_irq.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_irq.c Sat Apr 10 15:20:07 2004 @@ -54,7 +54,7 @@ * tied to dma at all, this is just a hangover from dri prehistory. */ -irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS ) +irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS ) { drm_device_t *dev = (drm_device_t *) arg; drm_radeon_private_t *dev_priv = diff -Nru a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c --- a/drivers/char/drm/radeon_state.c Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/radeon_state.c Sat Apr 10 15:20:07 2004 @@ -36,6 +36,240 @@ /* ================================================================ + * Helper functions for client state checking and fixup + */ + +static __inline__ int radeon_check_and_fixup_offset( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + u32 *offset ) { + u32 off = *offset; + + if ( off >= dev_priv->fb_location && + off < ( dev_priv->gart_vm_start + dev_priv->gart_size ) ) + return 0; + + off += filp_priv->radeon_fb_delta; + + DRM_DEBUG( "offset fixed up to 0x%x\n", off ); + + if ( off < dev_priv->fb_location || + off >= ( dev_priv->gart_vm_start + dev_priv->gart_size ) ) + return DRM_ERR( EINVAL ); + + *offset = off; + + return 0; +} + +static __inline__ int radeon_check_and_fixup_offset_user( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + u32 *offset ) { + u32 off; + + DRM_GET_USER_UNCHECKED( off, offset ); + + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &off ) ) + return DRM_ERR( EINVAL ); + + DRM_PUT_USER_UNCHECKED( offset, off ); + + return 0; +} + +static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + int id, + u32 *data ) { + switch ( id ) { + + case RADEON_EMIT_PP_MISC: + if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, + &data[( RADEON_RB3D_DEPTHOFFSET + - RADEON_PP_MISC ) / 4] ) ) { + DRM_ERROR( "Invalid depth buffer offset\n" ); + return DRM_ERR( EINVAL ); + } + break; + + case RADEON_EMIT_PP_CNTL: + if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, + &data[( RADEON_RB3D_COLOROFFSET + - RADEON_PP_CNTL ) / 4] ) ) { + DRM_ERROR( "Invalid colour buffer offset\n" ); + return DRM_ERR( EINVAL ); + } + break; + + case R200_EMIT_PP_TXOFFSET_0: + case R200_EMIT_PP_TXOFFSET_1: + case R200_EMIT_PP_TXOFFSET_2: + case R200_EMIT_PP_TXOFFSET_3: + case R200_EMIT_PP_TXOFFSET_4: + case R200_EMIT_PP_TXOFFSET_5: + if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, + &data[0] ) ) { + DRM_ERROR( "Invalid R200 texture offset\n" ); + return DRM_ERR( EINVAL ); + } + break; + + case RADEON_EMIT_PP_TXFILTER_0: + case RADEON_EMIT_PP_TXFILTER_1: + case RADEON_EMIT_PP_TXFILTER_2: + if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, + &data[( RADEON_PP_TXOFFSET_0 + - RADEON_PP_TXFILTER_0 ) / 4] ) ) { + DRM_ERROR( "Invalid R100 texture offset\n" ); + return DRM_ERR( EINVAL ); + } + break; + + case R200_EMIT_PP_CUBIC_OFFSETS_0: + case R200_EMIT_PP_CUBIC_OFFSETS_1: + case R200_EMIT_PP_CUBIC_OFFSETS_2: + case R200_EMIT_PP_CUBIC_OFFSETS_3: + case R200_EMIT_PP_CUBIC_OFFSETS_4: + case R200_EMIT_PP_CUBIC_OFFSETS_5: { + int i; + for ( i = 0; i < 5; i++ ) { + if ( radeon_check_and_fixup_offset_user( dev_priv, + filp_priv, + &data[i] ) ) { + DRM_ERROR( "Invalid R200 cubic texture offset\n" ); + return DRM_ERR( EINVAL ); + } + } + break; + } + + case RADEON_EMIT_RB3D_COLORPITCH: + case RADEON_EMIT_RE_LINE_PATTERN: + case RADEON_EMIT_SE_LINE_WIDTH: + case RADEON_EMIT_PP_LUM_MATRIX: + case RADEON_EMIT_PP_ROT_MATRIX_0: + case RADEON_EMIT_RB3D_STENCILREFMASK: + case RADEON_EMIT_SE_VPORT_XSCALE: + case RADEON_EMIT_SE_CNTL: + case RADEON_EMIT_SE_CNTL_STATUS: + case RADEON_EMIT_RE_MISC: + case RADEON_EMIT_PP_BORDER_COLOR_0: + case RADEON_EMIT_PP_BORDER_COLOR_1: + case RADEON_EMIT_PP_BORDER_COLOR_2: + case RADEON_EMIT_SE_ZBIAS_FACTOR: + case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT: + case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED: + case R200_EMIT_PP_TXCBLEND_0: + case R200_EMIT_PP_TXCBLEND_1: + case R200_EMIT_PP_TXCBLEND_2: + case R200_EMIT_PP_TXCBLEND_3: + case R200_EMIT_PP_TXCBLEND_4: + case R200_EMIT_PP_TXCBLEND_5: + case R200_EMIT_PP_TXCBLEND_6: + case R200_EMIT_PP_TXCBLEND_7: + case R200_EMIT_TCL_LIGHT_MODEL_CTL_0: + case R200_EMIT_TFACTOR_0: + case R200_EMIT_VTX_FMT_0: + case R200_EMIT_VAP_CTL: + case R200_EMIT_MATRIX_SELECT_0: + case R200_EMIT_TEX_PROC_CTL_2: + case R200_EMIT_TCL_UCP_VERT_BLEND_CTL: + case R200_EMIT_PP_TXFILTER_0: + case R200_EMIT_PP_TXFILTER_1: + case R200_EMIT_PP_TXFILTER_2: + case R200_EMIT_PP_TXFILTER_3: + case R200_EMIT_PP_TXFILTER_4: + case R200_EMIT_PP_TXFILTER_5: + case R200_EMIT_VTE_CNTL: + case R200_EMIT_OUTPUT_VTX_COMP_SEL: + case R200_EMIT_PP_TAM_DEBUG3: + case R200_EMIT_PP_CNTL_X: + case R200_EMIT_RB3D_DEPTHXY_OFFSET: + case R200_EMIT_RE_AUX_SCISSOR_CNTL: + case R200_EMIT_RE_SCISSOR_TL_0: + case R200_EMIT_RE_SCISSOR_TL_1: + case R200_EMIT_RE_SCISSOR_TL_2: + case R200_EMIT_SE_VAP_CNTL_STATUS: + case R200_EMIT_SE_VTX_STATE_CNTL: + case R200_EMIT_RE_POINTSIZE: + case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0: + case R200_EMIT_PP_CUBIC_FACES_0: + case R200_EMIT_PP_CUBIC_FACES_1: + case R200_EMIT_PP_CUBIC_FACES_2: + case R200_EMIT_PP_CUBIC_FACES_3: + case R200_EMIT_PP_CUBIC_FACES_4: + case R200_EMIT_PP_CUBIC_FACES_5: + case RADEON_EMIT_PP_TEX_SIZE_0: + case RADEON_EMIT_PP_TEX_SIZE_1: + case RADEON_EMIT_PP_TEX_SIZE_2: + /* These packets don't contain memory offsets */ + break; + + default: + DRM_ERROR( "Unknown state packet ID %d\n", id ); + return DRM_ERR( EINVAL ); + } + + return 0; +} + +static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + drm_radeon_cmd_buffer_t *cmdbuf, + unsigned int *cmdsz ) { + u32 tmp[4], *cmd = ( u32* )cmdbuf->buf; + + if ( DRM_COPY_FROM_USER_UNCHECKED( tmp, cmd, sizeof( tmp ) ) ) { + DRM_ERROR( "Failed to copy data from user space\n" ); + return DRM_ERR( EFAULT ); + } + + *cmdsz = 2 + ( ( tmp[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); + + if ( ( tmp[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { + DRM_ERROR( "Not a type 3 packet\n" ); + return DRM_ERR( EINVAL ); + } + + if ( 4 * *cmdsz > cmdbuf->bufsz ) { + DRM_ERROR( "Packet size larger than size of data provided\n" ); + return DRM_ERR( EINVAL ); + } + + /* Check client state and fix it up if necessary */ + if ( tmp[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ + u32 offset; + + if ( tmp[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL + | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { + offset = tmp[2] << 10; + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { + DRM_ERROR( "Invalid first packet offset\n" ); + return DRM_ERR( EINVAL ); + } + tmp[2] = ( tmp[2] & 0xffc00000 ) | offset >> 10; + } + + if ( ( tmp[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && + ( tmp[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { + offset = tmp[3] << 10; + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { + DRM_ERROR( "Invalid second packet offset\n" ); + return DRM_ERR( EINVAL ); + } + tmp[3] = ( tmp[3] & 0xffc00000 ) | offset >> 10; + } + + if ( DRM_COPY_TO_USER_UNCHECKED( cmd, tmp, sizeof( tmp ) ) ) { + DRM_ERROR( "Failed to copy data to user space\n" ); + return DRM_ERR( EFAULT ); + } + } + + return 0; +} + + +/* ================================================================ * CP hardware state programming functions */ @@ -57,15 +291,28 @@ /* Emit 1.1 state */ -static void radeon_emit_state( drm_radeon_private_t *dev_priv, - drm_radeon_context_regs_t *ctx, - drm_radeon_texture_regs_t *tex, - unsigned int dirty ) +static int radeon_emit_state( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + drm_radeon_context_regs_t *ctx, + drm_radeon_texture_regs_t *tex, + unsigned int dirty ) { RING_LOCALS; DRM_DEBUG( "dirty=0x%08x\n", dirty ); if ( dirty & RADEON_UPLOAD_CONTEXT ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &ctx->rb3d_depthoffset ) ) { + DRM_ERROR( "Invalid depth buffer offset\n" ); + return DRM_ERR( EINVAL ); + } + + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &ctx->rb3d_coloroffset ) ) { + DRM_ERROR( "Invalid depth buffer offset\n" ); + return DRM_ERR( EINVAL ); + } + BEGIN_RING( 14 ); OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); OUT_RING( ctx->pp_misc ); @@ -149,6 +396,12 @@ } if ( dirty & RADEON_UPLOAD_TEX0 ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &tex[0].pp_txoffset ) ) { + DRM_ERROR( "Invalid texture offset for unit 0\n" ); + return DRM_ERR( EINVAL ); + } + BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); OUT_RING( tex[0].pp_txfilter ); @@ -163,6 +416,12 @@ } if ( dirty & RADEON_UPLOAD_TEX1 ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &tex[1].pp_txoffset ) ) { + DRM_ERROR( "Invalid texture offset for unit 1\n" ); + return DRM_ERR( EINVAL ); + } + BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); OUT_RING( tex[1].pp_txfilter ); @@ -177,6 +436,12 @@ } if ( dirty & RADEON_UPLOAD_TEX2 ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &tex[2].pp_txoffset ) ) { + DRM_ERROR( "Invalid texture offset for unit 2\n" ); + return DRM_ERR( EINVAL ); + } + BEGIN_RING( 9 ); OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); OUT_RING( tex[2].pp_txfilter ); @@ -189,12 +454,15 @@ OUT_RING( tex[2].pp_border_color ); ADVANCE_RING(); } + + return 0; } /* Emit 1.2 state */ -static void radeon_emit_state2( drm_radeon_private_t *dev_priv, - drm_radeon_state_t *state ) +static int radeon_emit_state2( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, + drm_radeon_state_t *state ) { RING_LOCALS; @@ -206,7 +474,7 @@ ADVANCE_RING(); } - radeon_emit_state( dev_priv, &state->context, + return radeon_emit_state( dev_priv, filp_priv, &state->context, state->tex, state->dirty ); } @@ -1065,6 +1333,7 @@ drm_radeon_tex_image_t *image ) { drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; drm_buf_t *buf; u32 format; u32 *buffer; @@ -1074,6 +1343,13 @@ int i; RING_LOCALS; + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &tex->offset ) ) { + DRM_ERROR( "Invalid destination offset\n" ); + return DRM_ERR( EINVAL ); + } + dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; /* Flush the pixel cache. This ensures no pixel data gets mixed @@ -1377,6 +1653,7 @@ { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1390,6 +1667,8 @@ return DRM_ERR(EINVAL); } + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data, sizeof(vertex) ); @@ -1429,11 +1708,14 @@ buf->used = vertex.count; /* not used? */ if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty ); - + if ( radeon_emit_state( dev_priv, filp_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ) ) { + DRM_ERROR( "radeon_emit_state failed\n" ); + return DRM_ERR( EINVAL ); + } + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | RADEON_UPLOAD_TEX1IMAGES | RADEON_UPLOAD_TEX2IMAGES | @@ -1461,6 +1743,7 @@ { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1475,6 +1758,8 @@ return DRM_ERR(EINVAL); } + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data, sizeof(elts) ); @@ -1523,10 +1808,13 @@ buf->used = elts.end; if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty ); + if ( radeon_emit_state( dev_priv, filp_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ) ) { + DRM_ERROR( "radeon_emit_state failed\n" ); + return DRM_ERR( EINVAL ); + } sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | RADEON_UPLOAD_TEX1IMAGES | @@ -1686,6 +1974,7 @@ { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; @@ -1700,6 +1989,8 @@ return DRM_ERR(EINVAL); } + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data, sizeof(vertex) ); @@ -1747,7 +2038,10 @@ sizeof(state) ) ) return DRM_ERR(EFAULT); - radeon_emit_state2( dev_priv, &state ); + if ( radeon_emit_state2( dev_priv, filp_priv, &state ) ) { + DRM_ERROR( "radeon_emit_state2 failed\n" ); + return DRM_ERR( EINVAL ); + } laststate = prim.stateidx; } @@ -1784,6 +2078,7 @@ static int radeon_emit_packets( drm_radeon_private_t *dev_priv, + drm_file_t *filp_priv, drm_radeon_cmd_header_t header, drm_radeon_cmd_buffer_t *cmdbuf ) { @@ -1798,8 +2093,15 @@ sz = packet[id].len; reg = packet[id].start; - if (sz * sizeof(int) > cmdbuf->bufsz) + if (sz * sizeof(int) > cmdbuf->bufsz) { + DRM_ERROR( "Packet size provided larger than data provided\n" ); return DRM_ERR(EINVAL); + } + + if ( radeon_check_and_fixup_packets( dev_priv, filp_priv, id, data ) ) { + DRM_ERROR( "Packet verification failed\n" ); + return DRM_ERR( EINVAL ); + } BEGIN_RING(sz+1); OUT_RING( CP_PACKET0( reg, (sz-1) ) ); @@ -1882,24 +2184,21 @@ static int radeon_emit_packet3( drm_device_t *dev, + drm_file_t *filp_priv, drm_radeon_cmd_buffer_t *cmdbuf ) { drm_radeon_private_t *dev_priv = dev->dev_private; - int cmdsz, tmp; - int *cmd = (int *)cmdbuf->buf; + unsigned int cmdsz; + int *cmd = (int *)cmdbuf->buf, ret; RING_LOCALS; - DRM_DEBUG("\n"); - if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) - return DRM_ERR(EFAULT); - - cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); - - if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || - cmdsz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv, + cmdbuf, &cmdsz ) ) ) { + DRM_ERROR( "Packet verification failed\n" ); + return ret; + } BEGIN_RING( cmdsz ); OUT_RING_USER_TABLE( cmd, cmdsz ); @@ -1912,27 +2211,25 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, + drm_file_t *filp_priv, drm_radeon_cmd_buffer_t *cmdbuf, int orig_nbox ) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_clip_rect_t box; - int cmdsz, tmp; - int *cmd = (int *)cmdbuf->buf; + unsigned int cmdsz; + int *cmd = (int *)cmdbuf->buf, ret; drm_clip_rect_t *boxes = cmdbuf->boxes; int i = 0; RING_LOCALS; DRM_DEBUG("\n"); - if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0])) - return DRM_ERR(EFAULT); - - cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16); - - if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 || - cmdsz * 4 > cmdbuf->bufsz) - return DRM_ERR(EINVAL); + if ( ( ret = radeon_check_and_fixup_packet3( dev_priv, filp_priv, + cmdbuf, &cmdsz ) ) ) { + DRM_ERROR( "Packet verification failed\n" ); + return ret; + } if (!orig_nbox) goto out; @@ -2009,6 +2306,7 @@ { DRM_DEVICE; drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf = 0; int idx; @@ -2023,6 +2321,8 @@ return DRM_ERR(EINVAL); } + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data, sizeof(cmdbuf) ); @@ -2053,7 +2353,7 @@ switch (header.header.cmd_type) { case RADEON_CMD_PACKET: DRM_DEBUG("RADEON_CMD_PACKET\n"); - if (radeon_emit_packets( dev_priv, header, &cmdbuf )) { + if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_packets failed\n"); return DRM_ERR(EINVAL); } @@ -2096,7 +2396,7 @@ case RADEON_CMD_PACKET3: DRM_DEBUG("RADEON_CMD_PACKET3\n"); - if (radeon_emit_packet3( dev, &cmdbuf )) { + if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) { DRM_ERROR("radeon_emit_packet3 failed\n"); return DRM_ERR(EINVAL); } @@ -2104,7 +2404,7 @@ case RADEON_CMD_PACKET3_CLIP: DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); - if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { + if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); return DRM_ERR(EINVAL); } @@ -2212,5 +2512,33 @@ return DRM_ERR(EFAULT); } + return 0; +} + +int radeon_cp_setparam( DRM_IOCTL_ARGS ) { + DRM_DEVICE; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_file_t *filp_priv; + drm_radeon_setparam_t sp; + + if ( !dev_priv ) { + DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); + return DRM_ERR( EINVAL ); + } + + DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); + + DRM_COPY_FROM_USER_IOCTL( sp, ( drm_radeon_setparam_t* )data, + sizeof( sp ) ); + + switch( sp.param ) { + case RADEON_SETPARAM_FB_LOCATION: + filp_priv->radeon_fb_delta = dev_priv->fb_location - sp.value; + break; + default: + DRM_DEBUG( "Invalid parameter %d\n", sp.param ); + return DRM_ERR( EINVAL ); + } + return 0; } diff -Nru a/drivers/char/drm/sis.h b/drivers/char/drm/sis.h --- a/drivers/char/drm/sis.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/sis.h Sat Apr 10 15:20:07 2004 @@ -62,6 +62,13 @@ [DRM_IOCTL_NR(DRM_IOCTL_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_SIS_FB_INIT)] = { sis_fb_init, 1, 1 } +#define DRIVER_PCI_IDS \ + {0x1039, 0x0300, 0}, \ + {0x1039, 0x5300, 0}, \ + {0x1039, 0x6300, 0}, \ + {0x1039, 0x7300, 0}, \ + {0, 0, 0} + #define __HAVE_COUNTERS 5 /* Buffer customization: diff -Nru a/drivers/char/drm/tdfx.h b/drivers/char/drm/tdfx.h --- a/drivers/char/drm/tdfx.h Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/tdfx.h Sat Apr 10 15:20:07 2004 @@ -39,4 +39,22 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#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 + +#define DRIVER_PCI_IDS \ + {0x121a, 0x0003, 0}, \ + {0x121a, 0x0004, 0}, \ + {0x121a, 0x0005, 0}, \ + {0x121a, 0x0007, 0}, \ + {0x121a, 0x0009, 0}, \ + {0, 0, 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 Sat Apr 10 15:20:07 2004 +++ b/drivers/char/drm/tdfx_drv.c Sat Apr 10 15:20:07 2004 @@ -34,47 +34,6 @@ #include "tdfx.h" #include "drmP.h" -#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 - -#ifndef PCI_VENDOR_ID_3DFX -#define PCI_VENDOR_ID_3DFX 0x121A -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO5 -#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO4 -#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000 /* Voodoo3 3000 */ -#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005 -#endif -#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000 /* Voodoo3 3000 */ -#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004 -#endif -#ifndef PCI_DEVICE_ID_3DFX_BANSHEE -#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 -#endif - -static drm_pci_list_t DRM(idlist)[] = { - { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE }, - { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_2000 }, - { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_3000 }, - { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO4 }, - { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5 }, - { 0, 0 } -}; - -#define DRIVER_CARD_LIST DRM(idlist) - - #include "drm_auth.h" #include "drm_bufs.h" #include "drm_context.h"