Commit bf81df9b authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/nvif: replace path-based object identification

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a01ca78c
...@@ -354,8 +354,8 @@ struct nvif_control_pstate_user_v0 { ...@@ -354,8 +354,8 @@ struct nvif_control_pstate_user_v0 {
struct nv03_channel_dma_v0 { struct nv03_channel_dma_v0 {
__u8 version; __u8 version;
__u8 chid; __u8 chid;
__u8 pad02[2]; __u8 pad02[6];
__u32 pushbuf; __u64 pushbuf;
__u64 offset; __u64 offset;
}; };
...@@ -368,10 +368,10 @@ struct nv03_channel_dma_v0 { ...@@ -368,10 +368,10 @@ struct nv03_channel_dma_v0 {
struct nv50_channel_gpfifo_v0 { struct nv50_channel_gpfifo_v0 {
__u8 version; __u8 version;
__u8 chid; __u8 chid;
__u8 pad01[6]; __u8 pad02[2];
__u32 pushbuf;
__u32 ilength; __u32 ilength;
__u64 ioffset; __u64 ioffset;
__u64 pushbuf;
}; };
struct kepler_channel_gpfifo_a_v0 { struct kepler_channel_gpfifo_a_v0 {
...@@ -385,10 +385,9 @@ struct kepler_channel_gpfifo_a_v0 { ...@@ -385,10 +385,9 @@ struct kepler_channel_gpfifo_a_v0 {
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40 #define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
__u8 engine; __u8 engine;
__u16 chid; __u16 chid;
__u8 pad04[4];
__u32 pushbuf;
__u32 ilength; __u32 ilength;
__u64 ioffset; __u64 ioffset;
__u64 pushbuf;
}; };
/******************************************************************************* /*******************************************************************************
...@@ -509,8 +508,8 @@ struct nv50_disp_pior_pwr_v0 { ...@@ -509,8 +508,8 @@ struct nv50_disp_pior_pwr_v0 {
/* core */ /* core */
struct nv50_disp_core_channel_dma_v0 { struct nv50_disp_core_channel_dma_v0 {
__u8 version; __u8 version;
__u8 pad01[3]; __u8 pad01[7];
__u32 pushbuf; __u64 pushbuf;
}; };
#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00 #define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
...@@ -527,9 +526,9 @@ struct nv50_disp_cursor_v0 { ...@@ -527,9 +526,9 @@ struct nv50_disp_cursor_v0 {
/* base */ /* base */
struct nv50_disp_base_channel_dma_v0 { struct nv50_disp_base_channel_dma_v0 {
__u8 version; __u8 version;
__u8 pad01[2];
__u8 head; __u8 head;
__u32 pushbuf; __u8 pad02[6];
__u64 pushbuf;
}; };
#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00 #define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
...@@ -537,9 +536,9 @@ struct nv50_disp_base_channel_dma_v0 { ...@@ -537,9 +536,9 @@ struct nv50_disp_base_channel_dma_v0 {
/* overlay */ /* overlay */
struct nv50_disp_overlay_channel_dma_v0 { struct nv50_disp_overlay_channel_dma_v0 {
__u8 version; __u8 version;
__u8 pad01[2];
__u8 head; __u8 head;
__u32 pushbuf; __u8 pad02[6];
__u64 pushbuf;
}; };
#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00 #define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
struct nvif_ioctl_v0 { struct nvif_ioctl_v0 {
__u8 version; __u8 version;
#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
#define NVIF_IOCTL_V0_OWNER_ANY 0xff
__u8 owner;
#define NVIF_IOCTL_V0_NOP 0x00 #define NVIF_IOCTL_V0_NOP 0x00
#define NVIF_IOCTL_V0_SCLASS 0x01 #define NVIF_IOCTL_V0_SCLASS 0x01
#define NVIF_IOCTL_V0_NEW 0x02 #define NVIF_IOCTL_V0_NEW 0x02
...@@ -20,13 +17,15 @@ struct nvif_ioctl_v0 { ...@@ -20,13 +17,15 @@ struct nvif_ioctl_v0 {
#define NVIF_IOCTL_V0_NTFY_GET 0x0b #define NVIF_IOCTL_V0_NTFY_GET 0x0b
#define NVIF_IOCTL_V0_NTFY_PUT 0x0c #define NVIF_IOCTL_V0_NTFY_PUT 0x0c
__u8 type; __u8 type;
__u8 path_nr; __u8 pad02[4];
#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
#define NVIF_IOCTL_V0_OWNER_ANY 0xff
__u8 owner;
#define NVIF_IOCTL_V0_ROUTE_NVIF 0x00 #define NVIF_IOCTL_V0_ROUTE_NVIF 0x00
#define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff #define NVIF_IOCTL_V0_ROUTE_HIDDEN 0xff
__u8 pad04[3];
__u8 route; __u8 route;
__u64 token; __u64 token;
__u32 path[8]; /* in reverse */ __u64 object;
__u8 data[]; /* ioctl data (below) */ __u8 data[]; /* ioctl data (below) */
}; };
...@@ -47,6 +46,7 @@ struct nvif_ioctl_new_v0 { ...@@ -47,6 +46,7 @@ struct nvif_ioctl_new_v0 {
__u8 pad01[6]; __u8 pad01[6];
__u8 route; __u8 route;
__u64 token; __u64 token;
__u64 object;
__u32 handle; __u32 handle;
/* these class numbers are made up by us, and not nvidia-assigned */ /* these class numbers are made up by us, and not nvidia-assigned */
#define NVIF_IOCTL_NEW_V0_PERFMON 0x0000ffff #define NVIF_IOCTL_NEW_V0_PERFMON 0x0000ffff
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
struct nvif_object { struct nvif_object {
struct nvif_client *client; struct nvif_client *client;
struct nvif_object *parent;
u32 handle; u32 handle;
u32 oclass; u32 oclass;
void *priv; /*XXX: hack */ void *priv; /*XXX: hack */
...@@ -26,6 +25,7 @@ int nvif_object_mthd(struct nvif_object *, u32, void *, u32); ...@@ -26,6 +25,7 @@ int nvif_object_mthd(struct nvif_object *, u32, void *, u32);
int nvif_object_map(struct nvif_object *); int nvif_object_map(struct nvif_object *);
void nvif_object_unmap(struct nvif_object *); void nvif_object_unmap(struct nvif_object *);
#define nvif_handle(a) (unsigned long)(void *)(a)
#define nvif_object(a) (a)->object #define nvif_object(a) (a)->object
#define nvif_rd(a,f,b,c) ({ \ #define nvif_rd(a,f,b,c) ({ \
......
...@@ -14,8 +14,14 @@ struct nvkm_client { ...@@ -14,8 +14,14 @@ struct nvkm_client {
int (*ntfy)(const void *, u32, const void *, u32); int (*ntfy)(const void *, u32, const void *, u32);
struct nvkm_client_notify *notify[16]; struct nvkm_client_notify *notify[16];
struct rb_root objroot;
}; };
bool nvkm_client_insert(struct nvkm_client *, struct nvkm_handle *);
void nvkm_client_remove(struct nvkm_client *, struct nvkm_handle *);
struct nvkm_handle *nvkm_client_search(struct nvkm_client *, u64 handle);
static inline struct nvkm_client * static inline struct nvkm_client *
nv_client(void *obj) nv_client(void *obj)
{ {
......
...@@ -17,6 +17,9 @@ struct nvkm_handle { ...@@ -17,6 +17,9 @@ struct nvkm_handle {
struct nvkm_handle *parent; struct nvkm_handle *parent;
struct nvkm_object *object; struct nvkm_object *object;
struct rb_node rb;
u64 handle;
}; };
int nvkm_handle_create(struct nvkm_object *, u32 parent, u32 handle, int nvkm_handle_create(struct nvkm_object *, u32 parent, u32 handle,
...@@ -25,8 +28,6 @@ void nvkm_handle_destroy(struct nvkm_handle *); ...@@ -25,8 +28,6 @@ void nvkm_handle_destroy(struct nvkm_handle *);
int nvkm_handle_init(struct nvkm_handle *); int nvkm_handle_init(struct nvkm_handle *);
int nvkm_handle_fini(struct nvkm_handle *, bool suspend); int nvkm_handle_fini(struct nvkm_handle *, bool suspend);
struct nvkm_object *nvkm_handle_ref(struct nvkm_object *, u32 name);
struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16); struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16);
struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64); struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64);
struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32); struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32);
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
struct nvkm_fifo_chan { struct nvkm_fifo_chan {
struct nvkm_namedb namedb; struct nvkm_namedb namedb;
struct nvkm_dmaobj *pushdma;
struct nvkm_gpuobj *pushgpu; struct nvkm_gpuobj *pushgpu;
void __iomem *user; void __iomem *user;
u64 addr; u64 addr;
...@@ -30,7 +29,7 @@ nvkm_fifo_chan(void *obj) ...@@ -30,7 +29,7 @@ nvkm_fifo_chan(void *obj)
int nvkm_fifo_channel_create_(struct nvkm_object *, int nvkm_fifo_channel_create_(struct nvkm_object *,
struct nvkm_object *, struct nvkm_object *,
struct nvkm_oclass *, struct nvkm_oclass *,
int bar, u32 addr, u32 size, u32 push, int bar, u32 addr, u32 size, u64 push,
u64 engmask, int len, void **); u64 engmask, int len, void **);
void nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *); void nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *);
......
...@@ -209,13 +209,13 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -209,13 +209,13 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) { if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
args.kepler.version = 0; args.kepler.version = 0;
args.kepler.engine = engine; args.kepler.engine = engine;
args.kepler.pushbuf = chan->push.ctxdma.handle; args.kepler.pushbuf = nvif_handle(&chan->push.ctxdma);
args.kepler.ilength = 0x02000; args.kepler.ilength = 0x02000;
args.kepler.ioffset = 0x10000 + chan->push.vma.offset; args.kepler.ioffset = 0x10000 + chan->push.vma.offset;
size = sizeof(args.kepler); size = sizeof(args.kepler);
} else { } else {
args.nv50.version = 0; args.nv50.version = 0;
args.nv50.pushbuf = chan->push.ctxdma.handle; args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
args.nv50.ilength = 0x02000; args.nv50.ilength = 0x02000;
args.nv50.ioffset = 0x10000 + chan->push.vma.offset; args.nv50.ioffset = 0x10000 + chan->push.vma.offset;
size = sizeof(args.nv50); size = sizeof(args.nv50);
...@@ -258,7 +258,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -258,7 +258,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
/* create channel object */ /* create channel object */
args.version = 0; args.version = 0;
args.pushbuf = chan->push.ctxdma.handle; args.pushbuf = nvif_handle(&chan->push.ctxdma);
args.offset = chan->push.vma.offset; args.offset = chan->push.vma.offset;
do { do {
......
...@@ -230,7 +230,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -230,7 +230,7 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
if (!dmac->ptr) if (!dmac->ptr)
return -ENOMEM; return -ENOMEM;
ret = nvif_object_init(&device->object, args->pushbuf, ret = nvif_object_init(&device->object, 0xd0000000,
NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) { NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) {
.target = NV_DMA_V0_TARGET_PCI_US, .target = NV_DMA_V0_TARGET_PCI_US,
.access = NV_DMA_V0_ACCESS_RD, .access = NV_DMA_V0_ACCESS_RD,
...@@ -240,6 +240,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, ...@@ -240,6 +240,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
if (ret) if (ret)
return ret; return ret;
args->pushbuf = nvif_handle(&pushbuf);
ret = nv50_chan_create(device, disp, oclass, head, data, size, ret = nv50_chan_create(device, disp, oclass, head, data, size,
&dmac->base); &dmac->base);
nvif_object_fini(&pushbuf); nvif_object_fini(&pushbuf);
......
...@@ -50,7 +50,6 @@ nvif_client_fini(struct nvif_client *client) ...@@ -50,7 +50,6 @@ nvif_client_fini(struct nvif_client *client)
if (client->driver) { if (client->driver) {
client->driver->fini(client->object.priv); client->driver->fini(client->object.priv);
client->driver = NULL; client->driver = NULL;
client->object.parent = NULL;
client->object.client = NULL; client->object.client = NULL;
nvif_object_fini(&client->object); nvif_object_fini(&client->object);
} }
...@@ -79,7 +78,6 @@ nvif_client_init(const char *driver, const char *name, u64 device, ...@@ -79,7 +78,6 @@ nvif_client_init(const char *driver, const char *name, u64 device,
return ret; return ret;
client->object.client = client; client->object.client = client;
client->object.parent = &client->object;
client->object.handle = ~0; client->object.handle = ~0;
client->route = NVIF_IOCTL_V0_ROUTE_NVIF; client->route = NVIF_IOCTL_V0_ROUTE_NVIF;
client->super = true; client->super = true;
......
...@@ -36,14 +36,11 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) ...@@ -36,14 +36,11 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack)
} *args = data; } *args = data;
if (size >= sizeof(*args) && args->v0.version == 0) { if (size >= sizeof(*args) && args->v0.version == 0) {
if (object != &client->object)
args->v0.object = nvif_handle(object);
else
args->v0.object = 0;
args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY; args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
args->v0.path_nr = 0;
while (args->v0.path_nr < ARRAY_SIZE(args->v0.path)) {
args->v0.path[args->v0.path_nr++] = object->handle;
if (object->parent == object)
break;
object = object->parent;
}
} else } else
return -ENOSYS; return -ENOSYS;
...@@ -216,13 +213,12 @@ nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass, ...@@ -216,13 +213,12 @@ nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass,
int ret = 0; int ret = 0;
object->client = NULL; object->client = NULL;
object->parent = parent;
object->handle = handle; object->handle = handle;
object->oclass = oclass; object->oclass = oclass;
object->map.ptr = NULL; object->map.ptr = NULL;
object->map.size = 0; object->map.size = 0;
if (object->parent) { if (parent) {
if (!(args = kmalloc(sizeof(*args) + size, GFP_KERNEL))) { if (!(args = kmalloc(sizeof(*args) + size, GFP_KERNEL))) {
nvif_object_fini(object); nvif_object_fini(object);
return -ENOMEM; return -ENOMEM;
...@@ -232,7 +228,8 @@ nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass, ...@@ -232,7 +228,8 @@ nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass,
args->ioctl.type = NVIF_IOCTL_V0_NEW; args->ioctl.type = NVIF_IOCTL_V0_NEW;
args->new.version = 0; args->new.version = 0;
args->new.route = parent->client->route; args->new.route = parent->client->route;
args->new.token = (unsigned long)(void *)object; args->new.token = nvif_handle(object);
args->new.object = nvif_handle(object);
args->new.handle = handle; args->new.handle = handle;
args->new.oclass = oclass; args->new.oclass = oclass;
......
...@@ -183,6 +183,55 @@ nvkm_client_oclass = { ...@@ -183,6 +183,55 @@ nvkm_client_oclass = {
}, },
}; };
void
nvkm_client_remove(struct nvkm_client *client, struct nvkm_handle *object)
{
if (!RB_EMPTY_NODE(&object->rb))
rb_erase(&object->rb, &client->objroot);
}
bool
nvkm_client_insert(struct nvkm_client *client, struct nvkm_handle *object)
{
struct rb_node **ptr = &client->objroot.rb_node;
struct rb_node *parent = NULL;
while (*ptr) {
struct nvkm_handle *this =
container_of(*ptr, typeof(*this), rb);
parent = *ptr;
if (object->handle < this->handle)
ptr = &parent->rb_left;
else
if (object->handle > this->handle)
ptr = &parent->rb_right;
else
return false;
}
rb_link_node(&object->rb, parent, ptr);
rb_insert_color(&object->rb, &client->objroot);
return true;
}
struct nvkm_handle *
nvkm_client_search(struct nvkm_client *client, u64 handle)
{
struct rb_node *node = client->objroot.rb_node;
while (node) {
struct nvkm_handle *object =
container_of(node, typeof(*object), rb);
if (handle < object->handle)
node = node->rb_left;
else
if (handle > object->handle)
node = node->rb_right;
else
return object;
}
return NULL;
}
int int
nvkm_client_fini(struct nvkm_client *client, bool suspend) nvkm_client_fini(struct nvkm_client *client, bool suspend)
{ {
...@@ -256,6 +305,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, ...@@ -256,6 +305,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg,
client->device = device; client->device = device;
snprintf(client->name, sizeof(client->name), "%s", name); snprintf(client->name, sizeof(client->name), "%s", name);
client->debug = nvkm_dbgopt(dbg, "CLIENT"); client->debug = nvkm_dbgopt(dbg, "CLIENT");
client->objroot = RB_ROOT;
return 0; return 0;
} }
......
...@@ -113,6 +113,7 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle, ...@@ -113,6 +113,7 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle,
INIT_LIST_HEAD(&handle->tree); INIT_LIST_HEAD(&handle->tree);
handle->name = _handle; handle->name = _handle;
handle->priv = ~0; handle->priv = ~0;
RB_CLEAR_NODE(&handle->rb);
ret = nvkm_namedb_insert(nv_namedb(namedb), _handle, object, handle); ret = nvkm_namedb_insert(nv_namedb(namedb), _handle, object, handle);
if (ret) { if (ret) {
...@@ -149,12 +150,15 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle, ...@@ -149,12 +150,15 @@ nvkm_handle_create(struct nvkm_object *parent, u32 _parent, u32 _handle,
void void
nvkm_handle_destroy(struct nvkm_handle *handle) nvkm_handle_destroy(struct nvkm_handle *handle)
{ {
struct nvkm_client *client = nvkm_client(handle->object);
struct nvkm_handle *item, *temp; struct nvkm_handle *item, *temp;
hprintk(handle, TRACE, "destroy running\n"); hprintk(handle, TRACE, "destroy running\n");
list_for_each_entry_safe(item, temp, &handle->tree, head) { list_for_each_entry_safe(item, temp, &handle->tree, head) {
nvkm_handle_destroy(item); nvkm_handle_destroy(item);
} }
nvkm_client_remove(client, handle);
list_del(&handle->head); list_del(&handle->head);
if (handle->priv != ~0) { if (handle->priv != ~0) {
...@@ -167,24 +171,6 @@ nvkm_handle_destroy(struct nvkm_handle *handle) ...@@ -167,24 +171,6 @@ nvkm_handle_destroy(struct nvkm_handle *handle)
kfree(handle); kfree(handle);
} }
struct nvkm_object *
nvkm_handle_ref(struct nvkm_object *parent, u32 name)
{
struct nvkm_object *object = NULL;
struct nvkm_handle *handle;
while (!nv_iclass(parent, NV_NAMEDB_CLASS))
parent = parent->parent;
handle = nvkm_namedb_get(nv_namedb(parent), name);
if (handle) {
nvkm_object_ref(handle->object, &object);
nvkm_namedb_put(handle);
}
return object;
}
struct nvkm_handle * struct nvkm_handle *
nvkm_handle_get_class(struct nvkm_object *engctx, u16 oclass) nvkm_handle_get_class(struct nvkm_object *engctx, u16 oclass)
{ {
......
...@@ -103,9 +103,9 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) ...@@ -103,9 +103,9 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
return ret; return ret;
nvif_ioctl(handle->object, "new vers %d handle %08x class %08x " nvif_ioctl(handle->object, "new vers %d handle %08x class %08x "
"route %02x token %llx\n", "route %02x token %llx object %016llx\n",
args->v0.version, _handle, _oclass, args->v0.version, _handle, _oclass,
args->v0.route, args->v0.token); args->v0.route, args->v0.token, args->v0.object);
if (!nv_iclass(handle->object, NV_PARENT_CLASS)) { if (!nv_iclass(handle->object, NV_PARENT_CLASS)) {
nvif_debug(handle->object, "cannot have children (ctor)\n"); nvif_debug(handle->object, "cannot have children (ctor)\n");
...@@ -166,6 +166,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) ...@@ -166,6 +166,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
if (ret) if (ret)
nvkm_handle_destroy(handle); nvkm_handle_destroy(handle);
handle->handle = args->v0.object;
nvkm_client_insert(client, handle);
fail_handle: fail_handle:
nvkm_object_dec(object, false); nvkm_object_dec(object, false);
fail_init: fail_init:
...@@ -438,40 +440,31 @@ nvkm_ioctl_v0[] = { ...@@ -438,40 +440,31 @@ nvkm_ioctl_v0[] = {
}; };
static int static int
nvkm_ioctl_path(struct nvkm_handle *parent, u32 type, u32 nr, u32 *path, nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type,
void *data, u32 size, u8 owner, u8 *route, u64 *token) void *data, u32 size, u8 owner, u8 *route, u64 *token)
{ {
struct nvkm_handle *handle = parent; struct nvkm_handle *object;
struct nvkm_namedb *namedb;
struct nvkm_object *object;
int ret; int ret;
while ((object = parent->object), nr--) { if (handle)
nvif_ioctl(object, "path 0x%08x\n", path[nr]); object = nvkm_client_search(client, handle);
if (!nv_iclass(object, NV_PARENT_CLASS)) { else
nvif_debug(object, "cannot have children (path)\n"); object = client->root;
return -EINVAL; if (unlikely(!object)) {
} nvif_ioctl(&client->namedb.parent.object, "object not found\n");
return -ENOENT;
if (!(namedb = (void *)nv_pclass(object, NV_NAMEDB_CLASS)) ||
!(handle = nvkm_namedb_get(namedb, path[nr]))) {
nvif_debug(object, "handle 0x%08x not found\n", path[nr]);
return -ENOENT;
}
nvkm_namedb_put(handle);
parent = handle;
} }
if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != handle->route) { if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != object->route) {
nvif_ioctl(object, "object route != owner\n"); nvif_ioctl(&client->namedb.parent.object, "route != owner\n");
return -EACCES; return -EACCES;
} }
*route = handle->route; *route = object->route;
*token = handle->token; *token = object->token;
if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) { if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) {
if (nvkm_ioctl_v0[type].version == 0) if (nvkm_ioctl_v0[type].version == 0)
ret = nvkm_ioctl_v0[type].func(handle, data, size); ret = nvkm_ioctl_v0[type].func(object, data, size);
} }
return ret; return ret;
...@@ -491,11 +484,11 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor, ...@@ -491,11 +484,11 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor,
nvif_ioctl(object, "size %d\n", size); nvif_ioctl(object, "size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) { if (nvif_unpack(args->v0, 0, 0, true)) {
nvif_ioctl(object, "vers %d type %02x path %d owner %02x\n", nvif_ioctl(object,
args->v0.version, args->v0.type, args->v0.path_nr, "vers %d type %02x object %016llx owner %02x\n",
args->v0.version, args->v0.type, args->v0.object,
args->v0.owner); args->v0.owner);
ret = nvkm_ioctl_path(client->root, args->v0.type, ret = nvkm_ioctl_path(client, args->v0.object, args->v0.type,
args->v0.path_nr, args->v0.path,
data, size, args->v0.owner, data, size, args->v0.owner,
&args->v0.route, &args->v0.token); &args->v0.route, &args->v0.token);
} }
......
...@@ -206,9 +206,12 @@ nv50_disp_dmac_object_detach(struct nvkm_object *parent, int cookie) ...@@ -206,9 +206,12 @@ nv50_disp_dmac_object_detach(struct nvkm_object *parent, int cookie)
static int static int
nv50_disp_dmac_create_(struct nvkm_object *parent, nv50_disp_dmac_create_(struct nvkm_object *parent,
struct nvkm_object *engine, struct nvkm_object *engine,
struct nvkm_oclass *oclass, u32 pushbuf, int head, struct nvkm_oclass *oclass, u64 pushbuf, int head,
int length, void **pobject) int length, void **pobject)
{ {
struct nvkm_client *client = nvkm_client(parent);
struct nvkm_handle *handle;
struct nvkm_dmaobj *dmaobj;
struct nv50_disp_dmac *dmac; struct nv50_disp_dmac *dmac;
int ret; int ret;
...@@ -218,22 +221,23 @@ nv50_disp_dmac_create_(struct nvkm_object *parent, ...@@ -218,22 +221,23 @@ nv50_disp_dmac_create_(struct nvkm_object *parent,
if (ret) if (ret)
return ret; return ret;
dmac->pushdma = (void *)nvkm_handle_ref(parent, pushbuf); handle = nvkm_client_search(client, pushbuf);
if (!dmac->pushdma) if (!handle)
return -ENOENT; return -ENOENT;
dmaobj = (void *)handle->object;
switch (nv_mclass(dmac->pushdma)) { switch (nv_mclass(dmaobj)) {
case 0x0002: case 0x0002:
case 0x003d: case 0x003d:
if (dmac->pushdma->limit - dmac->pushdma->start != 0xfff) if (dmaobj->limit - dmaobj->start != 0xfff)
return -EINVAL; return -EINVAL;
switch (dmac->pushdma->target) { switch (dmaobj->target) {
case NV_MEM_TARGET_VRAM: case NV_MEM_TARGET_VRAM:
dmac->push = 0x00000001 | dmac->pushdma->start >> 8; dmac->push = 0x00000001 | dmaobj->start >> 8;
break; break;
case NV_MEM_TARGET_PCI_NOSNOOP: case NV_MEM_TARGET_PCI_NOSNOOP:
dmac->push = 0x00000003 | dmac->pushdma->start >> 8; dmac->push = 0x00000003 | dmaobj->start >> 8;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -250,7 +254,6 @@ void ...@@ -250,7 +254,6 @@ void
nv50_disp_dmac_dtor(struct nvkm_object *object) nv50_disp_dmac_dtor(struct nvkm_object *object)
{ {
struct nv50_disp_dmac *dmac = (void *)object; struct nv50_disp_dmac *dmac = (void *)object;
nvkm_object_ref(NULL, (struct nvkm_object **)&dmac->pushdma);
nv50_disp_chan_destroy(&dmac->base); nv50_disp_chan_destroy(&dmac->base);
} }
...@@ -513,7 +516,7 @@ nv50_disp_core_ctor(struct nvkm_object *parent, ...@@ -513,7 +516,7 @@ nv50_disp_core_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create disp core channel dma size %d\n", size); nvif_ioctl(parent, "create disp core channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create disp core channel dma vers %d " nvif_ioctl(parent, "create disp core channel dma vers %d "
"pushbuf %08x\n", "pushbuf %016llx\n",
args->v0.version, args->v0.pushbuf); args->v0.version, args->v0.pushbuf);
} else } else
return ret; return ret;
...@@ -682,7 +685,7 @@ nv50_disp_base_ctor(struct nvkm_object *parent, ...@@ -682,7 +685,7 @@ nv50_disp_base_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create disp base channel dma size %d\n", size); nvif_ioctl(parent, "create disp base channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create disp base channel dma vers %d " nvif_ioctl(parent, "create disp base channel dma vers %d "
"pushbuf %08x head %d\n", "pushbuf %016llx head %d\n",
args->v0.version, args->v0.pushbuf, args->v0.head); args->v0.version, args->v0.pushbuf, args->v0.head);
if (args->v0.head > disp->head.nr) if (args->v0.head > disp->head.nr)
return -EINVAL; return -EINVAL;
...@@ -772,7 +775,7 @@ nv50_disp_ovly_ctor(struct nvkm_object *parent, ...@@ -772,7 +775,7 @@ nv50_disp_ovly_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create disp overlay channel dma size %d\n", size); nvif_ioctl(parent, "create disp overlay channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create disp overlay channel dma vers %d " nvif_ioctl(parent, "create disp overlay channel dma vers %d "
"pushbuf %08x head %d\n", "pushbuf %016llx head %d\n",
args->v0.version, args->v0.pushbuf, args->v0.head); args->v0.version, args->v0.pushbuf, args->v0.head);
if (args->v0.head > disp->head.nr) if (args->v0.head > disp->head.nr)
return -EINVAL; return -EINVAL;
......
...@@ -113,7 +113,6 @@ extern const struct nvkm_event_func gf110_disp_chan_uevent; ...@@ -113,7 +113,6 @@ extern const struct nvkm_event_func gf110_disp_chan_uevent;
struct nv50_disp_dmac { struct nv50_disp_dmac {
struct nv50_disp_chan base; struct nv50_disp_chan base;
struct nvkm_dmaobj *pushdma;
u32 push; u32 push;
}; };
......
...@@ -54,9 +54,12 @@ int ...@@ -54,9 +54,12 @@ int
nvkm_fifo_channel_create_(struct nvkm_object *parent, nvkm_fifo_channel_create_(struct nvkm_object *parent,
struct nvkm_object *engine, struct nvkm_object *engine,
struct nvkm_oclass *oclass, struct nvkm_oclass *oclass,
int bar, u32 addr, u32 size, u32 pushbuf, int bar, u32 addr, u32 size, u64 pushbuf,
u64 engmask, int len, void **ptr) u64 engmask, int len, void **ptr)
{ {
struct nvkm_client *client = nvkm_client(parent);
struct nvkm_handle *handle;
struct nvkm_dmaobj *dmaobj;
struct nvkm_fifo *fifo = (void *)engine; struct nvkm_fifo *fifo = (void *)engine;
struct nvkm_fifo_chan *chan; struct nvkm_fifo_chan *chan;
struct nvkm_dmaeng *dmaeng; struct nvkm_dmaeng *dmaeng;
...@@ -73,12 +76,13 @@ nvkm_fifo_channel_create_(struct nvkm_object *parent, ...@@ -73,12 +76,13 @@ nvkm_fifo_channel_create_(struct nvkm_object *parent,
return ret; return ret;
/* validate dma object representing push buffer */ /* validate dma object representing push buffer */
chan->pushdma = (void *)nvkm_handle_ref(parent, pushbuf); handle = nvkm_client_search(client, pushbuf);
if (!chan->pushdma) if (!handle)
return -ENOENT; return -ENOENT;
dmaobj = (void *)handle->object;
dmaeng = (void *)chan->pushdma->base.engine; dmaeng = (void *)dmaobj->base.engine;
switch (chan->pushdma->base.oclass->handle) { switch (dmaobj->base.oclass->handle) {
case NV_DMA_FROM_MEMORY: case NV_DMA_FROM_MEMORY:
case NV_DMA_IN_MEMORY: case NV_DMA_IN_MEMORY:
break; break;
...@@ -86,7 +90,7 @@ nvkm_fifo_channel_create_(struct nvkm_object *parent, ...@@ -86,7 +90,7 @@ nvkm_fifo_channel_create_(struct nvkm_object *parent,
return -EINVAL; return -EINVAL;
} }
ret = dmaeng->bind(chan->pushdma, parent, &chan->pushgpu); ret = dmaeng->bind(dmaobj, parent, &chan->pushgpu);
if (ret) if (ret)
return ret; return ret;
...@@ -126,7 +130,6 @@ nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *chan) ...@@ -126,7 +130,6 @@ nvkm_fifo_channel_destroy(struct nvkm_fifo_chan *chan)
spin_unlock_irqrestore(&fifo->lock, flags); spin_unlock_irqrestore(&fifo->lock, flags);
nvkm_gpuobj_ref(NULL, &chan->pushgpu); nvkm_gpuobj_ref(NULL, &chan->pushgpu);
nvkm_object_ref(NULL, (struct nvkm_object **)&chan->pushdma);
nvkm_namedb_destroy(&chan->namedb); nvkm_namedb_destroy(&chan->namedb);
} }
......
...@@ -182,7 +182,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -182,7 +182,7 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
...@@ -258,7 +258,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -258,7 +258,7 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel gpfifo size %d\n", size); nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
"ioffset %016llx ilength %08x\n", "ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset, args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength); args->v0.ilength);
......
...@@ -210,7 +210,7 @@ gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -210,7 +210,7 @@ gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel gpfifo size %d\n", size); nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
"ioffset %016llx ilength %08x\n", "ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset, args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength); args->v0.ilength);
......
...@@ -251,7 +251,7 @@ gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -251,7 +251,7 @@ gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel gpfifo size %d\n", size); nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
"ioffset %016llx ilength %08x engine %08x\n", "ioffset %016llx ilength %08x engine %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset, args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength, args->v0.engine); args->v0.ilength, args->v0.engine);
......
...@@ -120,7 +120,7 @@ nv04_fifo_chan_ctor(struct nvkm_object *parent, ...@@ -120,7 +120,7 @@ nv04_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
......
...@@ -64,7 +64,7 @@ nv10_fifo_chan_ctor(struct nvkm_object *parent, ...@@ -64,7 +64,7 @@ nv10_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
......
...@@ -69,7 +69,7 @@ nv17_fifo_chan_ctor(struct nvkm_object *parent, ...@@ -69,7 +69,7 @@ nv17_fifo_chan_ctor(struct nvkm_object *parent,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
......
...@@ -192,7 +192,7 @@ nv40_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -192,7 +192,7 @@ nv40_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
......
...@@ -212,7 +212,7 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -212,7 +212,7 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel dma size %d\n", size); nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %08x " nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version, "offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset); args->v0.pushbuf, args->v0.offset);
} else } else
...@@ -276,7 +276,7 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine, ...@@ -276,7 +276,7 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
nvif_ioctl(parent, "create channel gpfifo size %d\n", size); nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) { if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
"ioffset %016llx ilength %08x\n", "ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset, args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength); args->v0.ilength);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment