DA: patch from Matthew upgraded to latest DRI head to solve issue with i810

compatibility
This commit is contained in:
Dave Airlie 2003-08-13 23:35:40 +00:00
parent 03e6674c13
commit 428cbe0b91
5 changed files with 198 additions and 17 deletions

View file

@ -450,6 +450,49 @@ static int i810_dma_initialize(drm_device_t *dev,
return 0;
}
/* i810 DRM version 1.1 used a smaller init structure with different
* ordering of values than is currently used (drm >= 1.2). There is
* no defined way to detect the XFree version to correct this problem,
* however by checking using this procedure we can detect the correct
* thing to do.
*
* #1 Read the Smaller init structure from user-space
* #2 Verify the overlay_physical is a valid physical address, or NULL
* If it isn't then we have a v1.1 client. Fix up params.
* If it is, then we have a 1.2 client... get the rest of the data.
*/
int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
{
/* Get v1.1 init data */
if(copy_from_user(init, (drm_i810_pre12_init_t *)arg,
sizeof(drm_i810_pre12_init_t))) {
return -EFAULT;
}
if ((!init->overlay_physical) || (init->overlay_physical > 4096)) {
/* This is a v1.2 client, just get the v1.2 init data */
DRM_INFO("Using POST v1.2 init.\n");
if(copy_from_user(init, (drm_i810_init_t *)arg,
sizeof(drm_i810_init_t))) {
return -EFAULT;
}
} else {
/* This is a v1.1 client, fix the params */
DRM_INFO("Using PRE v1.2 init.\n");
init->pitch_bits = init->h;
init->pitch = init->w;
init->h = init->overlay_physical;
init->w = init->overlay_offset;
init->overlay_physical = 0;
init->overlay_offset = 0;
}
return 0;
}
int i810_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@ -459,22 +502,43 @@ int i810_dma_init(struct inode *inode, struct file *filp,
drm_i810_init_t init;
int retcode = 0;
if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init)))
/* Get only the init func */
if (copy_from_user(&init, (void *)arg, sizeof(drm_i810_init_func_t))) {
return -EFAULT;
}
switch(init.func) {
case I810_INIT_DMA:
/* This case is for backward compatibility. It
* handles XFree 4.1.0 and 4.2.0, and has to
* do some parameter checking as described below.
* It will someday go away.
*/
retcode = i810_dma_init_compat(&init, arg);
if(retcode) {
return retcode;
}
dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
if(dev_priv == NULL) return -ENOMEM;
retcode = i810_dma_initialize(dev, dev_priv, &init);
break;
default:
case I810_INIT_DMA_1_4:
DRM_INFO("Using v1.4 init.\n");
if(copy_from_user(&init, (drm_i810_init_t *)arg,
sizeof(drm_i810_init_t))) {
return -EFAULT;
}
dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
if(dev_priv == NULL) return -ENOMEM;
retcode = i810_dma_initialize(dev, dev_priv, &init);
break;
case I810_CLEANUP_DMA:
DRM_INFO("DMA Cleanup\n");
retcode = i810_dma_cleanup(dev);
break;
default:
retcode = -EINVAL;
break;
}
return retcode;

View file

@ -94,12 +94,15 @@
#define I810_BACK 0x2
#define I810_DEPTH 0x4
typedef enum _drm_i810_init_func {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02,
I810_INIT_DMA_1_4 = 0x03
} drm_i810_init_func_t;
/* This is the init structure after v1.2 */
typedef struct _drm_i810_init {
enum {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02
} func;
drm_i810_init_func_t func;
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
int ring_map_idx;
int buffer_map_idx;
@ -122,6 +125,29 @@ typedef struct _drm_i810_init {
unsigned int pitch_bits;
} drm_i810_init_t;
/* This is the init structure prior to v1.2 */
typedef struct _drm_i810_pre12_init {
drm_i810_init_func_t func;
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
int ring_map_idx;
int buffer_map_idx;
#else
unsigned int mmio_offset;
unsigned int buffers_offset;
#endif
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
unsigned int ring_size;
unsigned int front_offset;
unsigned int back_offset;
unsigned int depth_offset;
unsigned int w;
unsigned int h;
unsigned int pitch;
unsigned int pitch_bits;
} drm_i810_pre12_init_t;
/* Warning: If you change the SAREA structure you must change the Xserver
* structure as well */

View file

@ -55,9 +55,10 @@
* 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
* - Remove requirement for interrupt (leave stubs again)
* 1.3 - Add page flipping.
* 1.4 - fix DRM interface
*/
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 3
#define DRIVER_MINOR 4
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \

View file

@ -450,6 +450,49 @@ static int i810_dma_initialize(drm_device_t *dev,
return 0;
}
/* i810 DRM version 1.1 used a smaller init structure with different
* ordering of values than is currently used (drm >= 1.2). There is
* no defined way to detect the XFree version to correct this problem,
* however by checking using this procedure we can detect the correct
* thing to do.
*
* #1 Read the Smaller init structure from user-space
* #2 Verify the overlay_physical is a valid physical address, or NULL
* If it isn't then we have a v1.1 client. Fix up params.
* If it is, then we have a 1.2 client... get the rest of the data.
*/
int i810_dma_init_compat(drm_i810_init_t *init, unsigned long arg)
{
/* Get v1.1 init data */
if(copy_from_user(init, (drm_i810_pre12_init_t *)arg,
sizeof(drm_i810_pre12_init_t))) {
return -EFAULT;
}
if ((!init->overlay_physical) || (init->overlay_physical > 4096)) {
/* This is a v1.2 client, just get the v1.2 init data */
DRM_INFO("Using POST v1.2 init.\n");
if(copy_from_user(init, (drm_i810_init_t *)arg,
sizeof(drm_i810_init_t))) {
return -EFAULT;
}
} else {
/* This is a v1.1 client, fix the params */
DRM_INFO("Using PRE v1.2 init.\n");
init->pitch_bits = init->h;
init->pitch = init->w;
init->h = init->overlay_physical;
init->w = init->overlay_offset;
init->overlay_physical = 0;
init->overlay_offset = 0;
}
return 0;
}
int i810_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@ -459,22 +502,43 @@ int i810_dma_init(struct inode *inode, struct file *filp,
drm_i810_init_t init;
int retcode = 0;
if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init)))
/* Get only the init func */
if (copy_from_user(&init, (void *)arg, sizeof(drm_i810_init_func_t))) {
return -EFAULT;
}
switch(init.func) {
case I810_INIT_DMA:
/* This case is for backward compatibility. It
* handles XFree 4.1.0 and 4.2.0, and has to
* do some parameter checking as described below.
* It will someday go away.
*/
retcode = i810_dma_init_compat(&init, arg);
if(retcode) {
return retcode;
}
dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
if(dev_priv == NULL) return -ENOMEM;
retcode = i810_dma_initialize(dev, dev_priv, &init);
break;
default:
case I810_INIT_DMA_1_4:
DRM_INFO("Using v1.4 init.\n");
if(copy_from_user(&init, (drm_i810_init_t *)arg,
sizeof(drm_i810_init_t))) {
return -EFAULT;
}
dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
DRM_MEM_DRIVER);
if(dev_priv == NULL) return -ENOMEM;
retcode = i810_dma_initialize(dev, dev_priv, &init);
break;
case I810_CLEANUP_DMA:
DRM_INFO("DMA Cleanup\n");
retcode = i810_dma_cleanup(dev);
break;
default:
retcode = -EINVAL;
break;
}
return retcode;

View file

@ -94,12 +94,15 @@
#define I810_BACK 0x2
#define I810_DEPTH 0x4
typedef enum _drm_i810_init_func {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02,
I810_INIT_DMA_1_4 = 0x03
} drm_i810_init_func_t;
/* This is the init structure after v1.2 */
typedef struct _drm_i810_init {
enum {
I810_INIT_DMA = 0x01,
I810_CLEANUP_DMA = 0x02
} func;
drm_i810_init_func_t func;
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
int ring_map_idx;
int buffer_map_idx;
@ -122,6 +125,29 @@ typedef struct _drm_i810_init {
unsigned int pitch_bits;
} drm_i810_init_t;
/* This is the init structure prior to v1.2 */
typedef struct _drm_i810_pre12_init {
drm_i810_init_func_t func;
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
int ring_map_idx;
int buffer_map_idx;
#else
unsigned int mmio_offset;
unsigned int buffers_offset;
#endif
int sarea_priv_offset;
unsigned int ring_start;
unsigned int ring_end;
unsigned int ring_size;
unsigned int front_offset;
unsigned int back_offset;
unsigned int depth_offset;
unsigned int w;
unsigned int h;
unsigned int pitch;
unsigned int pitch_bits;
} drm_i810_pre12_init_t;
/* Warning: If you change the SAREA structure you must change the Xserver
* structure as well */