nouveau: support multiple channels per client (breaks drm interface)
parent
209870a882
commit
e22225416a
|
@ -25,7 +25,7 @@
|
|||
#ifndef __NOUVEAU_DRM_H__
|
||||
#define __NOUVEAU_DRM_H__
|
||||
|
||||
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 4
|
||||
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 5
|
||||
|
||||
typedef struct drm_nouveau_fifo_alloc {
|
||||
int channel;
|
||||
|
@ -40,6 +40,7 @@ typedef struct drm_nouveau_fifo_alloc {
|
|||
drm_nouveau_fifo_alloc_t;
|
||||
|
||||
typedef struct drm_nouveau_object_init {
|
||||
int channel;
|
||||
uint32_t handle;
|
||||
int class;
|
||||
}
|
||||
|
@ -49,6 +50,7 @@ drm_nouveau_object_init_t;
|
|||
#define NOUVEAU_MEM_ACCESS_WO 2
|
||||
#define NOUVEAU_MEM_ACCESS_RW 3
|
||||
typedef struct drm_nouveau_dma_object_init {
|
||||
int channel;
|
||||
uint32_t handle;
|
||||
int class;
|
||||
int access;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#define DRIVER_MAJOR 0
|
||||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 4
|
||||
#define DRIVER_PATCHLEVEL 5
|
||||
|
||||
#define NOUVEAU_FAMILY 0x0000FFFF
|
||||
#define NOUVEAU_FLAGS 0xFFFF0000
|
||||
|
@ -187,7 +187,7 @@ extern void nouveau_instmem_w32(drm_nouveau_private_t *dev_priv,
|
|||
extern int nouveau_fifo_init(drm_device_t *dev);
|
||||
extern int nouveau_fifo_number(drm_device_t *dev);
|
||||
extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp);
|
||||
extern int nouveau_fifo_id_get(drm_device_t *dev, DRMFILE filp);
|
||||
extern int nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel);
|
||||
extern void nouveau_fifo_free(drm_device_t *dev, int channel);
|
||||
|
||||
/* nouveau_object.c */
|
||||
|
|
|
@ -725,15 +725,16 @@ void nouveau_fifo_cleanup(drm_device_t* dev, DRMFILE filp)
|
|||
nouveau_fifo_init(dev);*/
|
||||
}
|
||||
|
||||
int nouveau_fifo_id_get(drm_device_t* dev, DRMFILE filp)
|
||||
int
|
||||
nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv=dev->dev_private;
|
||||
int i;
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
for(i=0;i<nouveau_fifo_number(dev);i++)
|
||||
if (dev_priv->fifos[i].used && dev_priv->fifos[i].filp == filp)
|
||||
return i;
|
||||
return -1;
|
||||
if (channel >= nouveau_fifo_number(dev))
|
||||
return 0;
|
||||
if (dev_priv->fifos[channel].used == 0)
|
||||
return 0;
|
||||
return (dev_priv->fifos[channel].filp == filp);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
|
|
|
@ -475,28 +475,29 @@ int nouveau_ioctl_object_init(DRM_IOCTL_ARGS)
|
|||
DRM_DEVICE;
|
||||
drm_nouveau_object_init_t init;
|
||||
struct nouveau_object *obj;
|
||||
int channel;
|
||||
|
||||
channel = nouveau_fifo_id_get(dev, filp);
|
||||
if (channel == -1)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_object_init_t __user *)
|
||||
data, sizeof(init));
|
||||
|
||||
//FIXME: check args, only allow trusted objects to be created
|
||||
|
||||
if (nouveau_object_handle_find(dev, channel, init.handle)) {
|
||||
DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
|
||||
channel, init.handle);
|
||||
if (!nouveau_fifo_owner(dev, filp, init.channel)) {
|
||||
DRM_ERROR("pid %d doesn't own channel %d\n",
|
||||
DRM_CURRENTPID, init.channel);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
obj = nouveau_object_gr_create(dev, channel, init.class);
|
||||
//FIXME: check args, only allow trusted objects to be created
|
||||
|
||||
if (nouveau_object_handle_find(dev, init.channel, init.handle)) {
|
||||
DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
|
||||
init.channel, init.handle);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
obj = nouveau_object_gr_create(dev, init.channel, init.class);
|
||||
if (!obj)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) {
|
||||
if (nouveau_ht_object_insert(dev, init.channel, init.handle, obj)) {
|
||||
nouveau_object_free(dev, obj);
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
@ -567,32 +568,33 @@ int nouveau_ioctl_dma_object_init(DRM_IOCTL_ARGS)
|
|||
DRM_DEVICE;
|
||||
drm_nouveau_dma_object_init_t init;
|
||||
struct nouveau_object *obj;
|
||||
int channel;
|
||||
|
||||
channel = nouveau_fifo_id_get(dev, filp);
|
||||
if (channel == -1)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_dma_object_init_t __user *)
|
||||
data, sizeof(init));
|
||||
|
||||
if (nouveau_dma_object_check_access(dev, &init))
|
||||
return DRM_ERR(EPERM);
|
||||
|
||||
if (nouveau_object_handle_find(dev, channel, init.handle)) {
|
||||
DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
|
||||
channel, init.handle);
|
||||
if (!nouveau_fifo_owner(dev, filp, init.channel)) {
|
||||
DRM_ERROR("pid %d doesn't own channel %d\n",
|
||||
DRM_CURRENTPID, init.channel);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
obj = nouveau_object_dma_create(dev, channel, init.class,
|
||||
init.offset, init.size,
|
||||
init.access, init.target);
|
||||
if (nouveau_dma_object_check_access(dev, &init))
|
||||
return DRM_ERR(EPERM);
|
||||
|
||||
if (nouveau_object_handle_find(dev, init.channel, init.handle)) {
|
||||
DRM_ERROR("Channel %d: handle 0x%08x already exists\n",
|
||||
init.channel, init.handle);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
obj = nouveau_object_dma_create(dev, init.channel, init.class,
|
||||
init.offset, init.size,
|
||||
init.access, init.target);
|
||||
if (!obj)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
obj->handle = init.handle;
|
||||
if (nouveau_ht_object_insert(dev, channel, init.handle, obj)) {
|
||||
if (nouveau_ht_object_insert(dev, init.channel, init.handle, obj)) {
|
||||
nouveau_object_free(dev, obj);
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue