1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 
24 #include <nvif/client.h>
25 #include <nvif/driver.h>
26 #include <nvif/fifo.h>
27 #include <nvif/ioctl.h>
28 #include <nvif/class.h>
29 #include <nvif/cl0002.h>
30 #include <nvif/unpack.h>
31 
32 #include "nouveau_drv.h"
33 #include "nouveau_dma.h"
34 #include "nouveau_gem.h"
35 #include "nouveau_chan.h"
36 #include "nouveau_abi16.h"
37 #include "nouveau_vmm.h"
38 #include "nouveau_sched.h"
39 
40 static struct nouveau_abi16 *
41 nouveau_abi16(struct drm_file *file_priv)
42 {
43 	struct nouveau_cli *cli = nouveau_cli(file_priv);
44 	if (!cli->abi16) {
45 		struct nouveau_abi16 *abi16;
46 		cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL);
47 		if (cli->abi16) {
48 			struct nv_device_v0 args = {
49 				.device = ~0ULL,
50 			};
51 
52 			INIT_LIST_HEAD(&abi16->channels);
53 
54 			/* allocate device object targeting client's default
55 			 * device (ie. the one that belongs to the fd it
56 			 * opened)
57 			 */
58 			if (nvif_device_ctor(&cli->base.object, "abi16Device",
59 					     0, NV_DEVICE, &args, sizeof(args),
60 					     &abi16->device) == 0)
61 				return cli->abi16;
62 
63 			kfree(cli->abi16);
64 			cli->abi16 = NULL;
65 		}
66 	}
67 	return cli->abi16;
68 }
69 
70 struct nouveau_abi16 *
71 nouveau_abi16_get(struct drm_file *file_priv)
72 {
73 	struct nouveau_cli *cli = nouveau_cli(file_priv);
74 	mutex_lock(&cli->mutex);
75 	if (nouveau_abi16(file_priv))
76 		return cli->abi16;
77 	mutex_unlock(&cli->mutex);
78 	return NULL;
79 }
80 
81 int
82 nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
83 {
84 	struct nouveau_cli *cli = (void *)abi16->device.object.client;
85 	mutex_unlock(&cli->mutex);
86 	return ret;
87 }
88 
89 s32
90 nouveau_abi16_swclass(struct nouveau_drm *drm)
91 {
92 	switch (drm->client.device.info.family) {
93 	case NV_DEVICE_INFO_V0_TNT:
94 		return NVIF_CLASS_SW_NV04;
95 	case NV_DEVICE_INFO_V0_CELSIUS:
96 	case NV_DEVICE_INFO_V0_KELVIN:
97 	case NV_DEVICE_INFO_V0_RANKINE:
98 	case NV_DEVICE_INFO_V0_CURIE:
99 		return NVIF_CLASS_SW_NV10;
100 	case NV_DEVICE_INFO_V0_TESLA:
101 		return NVIF_CLASS_SW_NV50;
102 	case NV_DEVICE_INFO_V0_FERMI:
103 	case NV_DEVICE_INFO_V0_KEPLER:
104 	case NV_DEVICE_INFO_V0_MAXWELL:
105 	case NV_DEVICE_INFO_V0_PASCAL:
106 	case NV_DEVICE_INFO_V0_VOLTA:
107 		return NVIF_CLASS_SW_GF100;
108 	}
109 
110 	return 0x0000;
111 }
112 
113 static void
114 nouveau_abi16_ntfy_fini(struct nouveau_abi16_chan *chan,
115 			struct nouveau_abi16_ntfy *ntfy)
116 {
117 	nvif_object_dtor(&ntfy->object);
118 	nvkm_mm_free(&chan->heap, &ntfy->node);
119 	list_del(&ntfy->head);
120 	kfree(ntfy);
121 }
122 
123 static void
124 nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
125 			struct nouveau_abi16_chan *chan)
126 {
127 	struct nouveau_abi16_ntfy *ntfy, *temp;
128 
129 	/* When a client exits without waiting for it's queued up jobs to
130 	 * finish it might happen that we fault the channel. This is due to
131 	 * drm_file_free() calling drm_gem_release() before the postclose()
132 	 * callback. Hence, we can't tear down this scheduler entity before
133 	 * uvmm mappings are unmapped. Currently, we can't detect this case.
134 	 *
135 	 * However, this should be rare and harmless, since the channel isn't
136 	 * needed anymore.
137 	 */
138 	nouveau_sched_entity_fini(&chan->sched_entity);
139 
140 	/* wait for all activity to stop before cleaning up */
141 	if (chan->chan)
142 		nouveau_channel_idle(chan->chan);
143 
144 	/* cleanup notifier state */
145 	list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
146 		nouveau_abi16_ntfy_fini(chan, ntfy);
147 	}
148 
149 	if (chan->ntfy) {
150 		nouveau_vma_del(&chan->ntfy_vma);
151 		nouveau_bo_unpin(chan->ntfy);
152 		drm_gem_object_put(&chan->ntfy->bo.base);
153 	}
154 
155 	if (chan->heap.block_size)
156 		nvkm_mm_fini(&chan->heap);
157 
158 	/* destroy channel object, all children will be killed too */
159 	if (chan->chan) {
160 		nvif_object_dtor(&chan->ce);
161 		nouveau_channel_del(&chan->chan);
162 	}
163 
164 	list_del(&chan->head);
165 	kfree(chan);
166 }
167 
168 void
169 nouveau_abi16_fini(struct nouveau_abi16 *abi16)
170 {
171 	struct nouveau_cli *cli = (void *)abi16->device.object.client;
172 	struct nouveau_abi16_chan *chan, *temp;
173 
174 	/* cleanup channels */
175 	list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
176 		nouveau_abi16_chan_fini(abi16, chan);
177 	}
178 
179 	/* destroy the device object */
180 	nvif_device_dtor(&abi16->device);
181 
182 	kfree(cli->abi16);
183 	cli->abi16 = NULL;
184 }
185 
186 int
187 nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
188 {
189 	struct nouveau_cli *cli = nouveau_cli(file_priv);
190 	struct nouveau_drm *drm = nouveau_drm(dev);
191 	struct nvif_device *device = &drm->client.device;
192 	struct nvkm_gr *gr = nvxx_gr(device);
193 	struct drm_nouveau_getparam *getparam = data;
194 	struct pci_dev *pdev = to_pci_dev(dev->dev);
195 
196 	switch (getparam->param) {
197 	case NOUVEAU_GETPARAM_CHIPSET_ID:
198 		getparam->value = device->info.chipset;
199 		break;
200 	case NOUVEAU_GETPARAM_PCI_VENDOR:
201 		if (device->info.platform != NV_DEVICE_INFO_V0_SOC)
202 			getparam->value = pdev->vendor;
203 		else
204 			getparam->value = 0;
205 		break;
206 	case NOUVEAU_GETPARAM_PCI_DEVICE:
207 		if (device->info.platform != NV_DEVICE_INFO_V0_SOC)
208 			getparam->value = pdev->device;
209 		else
210 			getparam->value = 0;
211 		break;
212 	case NOUVEAU_GETPARAM_BUS_TYPE:
213 		switch (device->info.platform) {
214 		case NV_DEVICE_INFO_V0_AGP : getparam->value = 0; break;
215 		case NV_DEVICE_INFO_V0_PCI : getparam->value = 1; break;
216 		case NV_DEVICE_INFO_V0_PCIE: getparam->value = 2; break;
217 		case NV_DEVICE_INFO_V0_SOC : getparam->value = 3; break;
218 		case NV_DEVICE_INFO_V0_IGP :
219 			if (!pci_is_pcie(pdev))
220 				getparam->value = 1;
221 			else
222 				getparam->value = 2;
223 			break;
224 		default:
225 			WARN_ON(1);
226 			break;
227 		}
228 		break;
229 	case NOUVEAU_GETPARAM_FB_SIZE:
230 		getparam->value = drm->gem.vram_available;
231 		break;
232 	case NOUVEAU_GETPARAM_AGP_SIZE:
233 		getparam->value = drm->gem.gart_available;
234 		break;
235 	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
236 		getparam->value = 0; /* deprecated */
237 		break;
238 	case NOUVEAU_GETPARAM_PTIMER_TIME:
239 		getparam->value = nvif_device_time(device);
240 		break;
241 	case NOUVEAU_GETPARAM_HAS_BO_USAGE:
242 		getparam->value = 1;
243 		break;
244 	case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
245 		getparam->value = 1;
246 		break;
247 	case NOUVEAU_GETPARAM_GRAPH_UNITS:
248 		getparam->value = nvkm_gr_units(gr);
249 		break;
250 	default:
251 		NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param);
252 		return -EINVAL;
253 	}
254 
255 	return 0;
256 }
257 
258 int
259 nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
260 {
261 	struct drm_nouveau_channel_alloc *init = data;
262 	struct nouveau_cli *cli = nouveau_cli(file_priv);
263 	struct nouveau_drm *drm = nouveau_drm(dev);
264 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
265 	struct nouveau_abi16_chan *chan;
266 	struct nvif_device *device;
267 	u64 engine, runm;
268 	int ret;
269 
270 	if (unlikely(!abi16))
271 		return -ENOMEM;
272 
273 	if (!drm->channel)
274 		return nouveau_abi16_put(abi16, -ENODEV);
275 
276 	/* If uvmm wasn't initialized until now disable it completely to prevent
277 	 * userspace from mixing up UAPIs.
278 	 *
279 	 * The client lock is already acquired by nouveau_abi16_get().
280 	 */
281 	__nouveau_cli_disable_uvmm_noinit(cli);
282 
283 	device = &abi16->device;
284 	engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
285 
286 	/* hack to allow channel engine type specification on kepler */
287 	if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
288 		if (init->fb_ctxdma_handle == ~0) {
289 			switch (init->tt_ctxdma_handle) {
290 			case 0x01: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR    ; break;
291 			case 0x02: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_MSPDEC; break;
292 			case 0x04: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_MSPPP ; break;
293 			case 0x08: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_MSVLD ; break;
294 			case 0x30: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_CE    ; break;
295 			default:
296 				return nouveau_abi16_put(abi16, -ENOSYS);
297 			}
298 
299 			init->fb_ctxdma_handle = 0;
300 			init->tt_ctxdma_handle = 0;
301 		}
302 	}
303 
304 	if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
305 		runm = nvif_fifo_runlist(device, engine);
306 	else
307 		runm = nvif_fifo_runlist_ce(device);
308 
309 	if (!runm || init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
310 		return nouveau_abi16_put(abi16, -EINVAL);
311 
312 	/* allocate "abi16 channel" data and make up a handle for it */
313 	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
314 	if (!chan)
315 		return nouveau_abi16_put(abi16, -ENOMEM);
316 
317 	INIT_LIST_HEAD(&chan->notifiers);
318 	list_add(&chan->head, &abi16->channels);
319 
320 	/* create channel object and initialise dma and fence management */
321 	ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
322 				  init->tt_ctxdma_handle, &chan->chan);
323 	if (ret)
324 		goto done;
325 
326 	ret = nouveau_sched_entity_init(&chan->sched_entity, &drm->sched,
327 					drm->sched_wq);
328 	if (ret)
329 		goto done;
330 
331 	init->channel = chan->chan->chid;
332 
333 	if (device->info.family >= NV_DEVICE_INFO_V0_TESLA)
334 		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
335 					NOUVEAU_GEM_DOMAIN_GART;
336 	else
337 	if (chan->chan->push.buffer->bo.resource->mem_type == TTM_PL_VRAM)
338 		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM;
339 	else
340 		init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART;
341 
342 	if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) {
343 		init->subchan[0].handle = 0x00000000;
344 		init->subchan[0].grclass = 0x0000;
345 		init->subchan[1].handle = chan->chan->nvsw.handle;
346 		init->subchan[1].grclass = 0x506e;
347 		init->nr_subchan = 2;
348 	}
349 
350 	/* Workaround "nvc0" gallium driver using classes it doesn't allocate on
351 	 * Kepler and above.  NVKM no longer always sets CE_CTX_VALID as part of
352 	 * channel init, now we know what that stuff actually is.
353 	 *
354 	 * Doesn't matter for Kepler/Pascal, CE context stored in NV_RAMIN.
355 	 *
356 	 * Userspace was fixed prior to adding Ampere support.
357 	 */
358 	switch (device->info.family) {
359 	case NV_DEVICE_INFO_V0_VOLTA:
360 		ret = nvif_object_ctor(&chan->chan->user, "abi16CeWar", 0, VOLTA_DMA_COPY_A,
361 				       NULL, 0, &chan->ce);
362 		if (ret)
363 			goto done;
364 		break;
365 	case NV_DEVICE_INFO_V0_TURING:
366 		ret = nvif_object_ctor(&chan->chan->user, "abi16CeWar", 0, TURING_DMA_COPY_A,
367 				       NULL, 0, &chan->ce);
368 		if (ret)
369 			goto done;
370 		break;
371 	default:
372 		break;
373 	}
374 
375 	/* Named memory object area */
376 	ret = nouveau_gem_new(cli, PAGE_SIZE, 0, NOUVEAU_GEM_DOMAIN_GART,
377 			      0, 0, &chan->ntfy);
378 	if (ret == 0)
379 		ret = nouveau_bo_pin(chan->ntfy, NOUVEAU_GEM_DOMAIN_GART,
380 				     false);
381 	if (ret)
382 		goto done;
383 
384 	if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
385 		ret = nouveau_vma_new(chan->ntfy, chan->chan->vmm,
386 				      &chan->ntfy_vma);
387 		if (ret)
388 			goto done;
389 	}
390 
391 	ret = drm_gem_handle_create(file_priv, &chan->ntfy->bo.base,
392 				    &init->notifier_handle);
393 	if (ret)
394 		goto done;
395 
396 	ret = nvkm_mm_init(&chan->heap, 0, 0, PAGE_SIZE, 1);
397 done:
398 	if (ret)
399 		nouveau_abi16_chan_fini(abi16, chan);
400 	return nouveau_abi16_put(abi16, ret);
401 }
402 
403 static struct nouveau_abi16_chan *
404 nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
405 {
406 	struct nouveau_abi16_chan *chan;
407 
408 	list_for_each_entry(chan, &abi16->channels, head) {
409 		if (chan->chan->chid == channel)
410 			return chan;
411 	}
412 
413 	return NULL;
414 }
415 
416 int
417 nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
418 {
419 	union {
420 		struct nvif_ioctl_v0 v0;
421 	} *args = data;
422 	struct nouveau_abi16_chan *chan;
423 	struct nouveau_abi16 *abi16;
424 	int ret = -ENOSYS;
425 
426 	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
427 		switch (args->v0.type) {
428 		case NVIF_IOCTL_V0_NEW:
429 		case NVIF_IOCTL_V0_MTHD:
430 		case NVIF_IOCTL_V0_SCLASS:
431 			break;
432 		default:
433 			return -EACCES;
434 		}
435 	} else
436 		return ret;
437 
438 	if (!(abi16 = nouveau_abi16(file_priv)))
439 		return -ENOMEM;
440 
441 	if (args->v0.token != ~0ULL) {
442 		if (!(chan = nouveau_abi16_chan(abi16, args->v0.token)))
443 			return -EINVAL;
444 		args->v0.object = nvif_handle(&chan->chan->user);
445 		args->v0.owner  = NVIF_IOCTL_V0_OWNER_ANY;
446 		return 0;
447 	}
448 
449 	args->v0.object = nvif_handle(&abi16->device.object);
450 	args->v0.owner  = NVIF_IOCTL_V0_OWNER_ANY;
451 	return 0;
452 }
453 
454 int
455 nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
456 {
457 	struct drm_nouveau_channel_free *req = data;
458 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
459 	struct nouveau_abi16_chan *chan;
460 
461 	if (unlikely(!abi16))
462 		return -ENOMEM;
463 
464 	chan = nouveau_abi16_chan(abi16, req->channel);
465 	if (!chan)
466 		return nouveau_abi16_put(abi16, -ENOENT);
467 	nouveau_abi16_chan_fini(abi16, chan);
468 	return nouveau_abi16_put(abi16, 0);
469 }
470 
471 int
472 nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
473 {
474 	struct drm_nouveau_grobj_alloc *init = data;
475 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
476 	struct nouveau_abi16_chan *chan;
477 	struct nouveau_abi16_ntfy *ntfy;
478 	struct nvif_client *client;
479 	struct nvif_sclass *sclass;
480 	s32 oclass = 0;
481 	int ret, i;
482 
483 	if (unlikely(!abi16))
484 		return -ENOMEM;
485 
486 	if (init->handle == ~0)
487 		return nouveau_abi16_put(abi16, -EINVAL);
488 	client = abi16->device.object.client;
489 
490 	chan = nouveau_abi16_chan(abi16, init->channel);
491 	if (!chan)
492 		return nouveau_abi16_put(abi16, -ENOENT);
493 
494 	ret = nvif_object_sclass_get(&chan->chan->user, &sclass);
495 	if (ret < 0)
496 		return nouveau_abi16_put(abi16, ret);
497 
498 	if ((init->class & 0x00ff) == 0x006e) {
499 		/* nvsw: compatibility with older 0x*6e class identifier */
500 		for (i = 0; !oclass && i < ret; i++) {
501 			switch (sclass[i].oclass) {
502 			case NVIF_CLASS_SW_NV04:
503 			case NVIF_CLASS_SW_NV10:
504 			case NVIF_CLASS_SW_NV50:
505 			case NVIF_CLASS_SW_GF100:
506 				oclass = sclass[i].oclass;
507 				break;
508 			default:
509 				break;
510 			}
511 		}
512 	} else
513 	if ((init->class & 0x00ff) == 0x00b1) {
514 		/* msvld: compatibility with incorrect version exposure */
515 		for (i = 0; i < ret; i++) {
516 			if ((sclass[i].oclass & 0x00ff) == 0x00b1) {
517 				oclass = sclass[i].oclass;
518 				break;
519 			}
520 		}
521 	} else
522 	if ((init->class & 0x00ff) == 0x00b2) { /* mspdec */
523 		/* mspdec: compatibility with incorrect version exposure */
524 		for (i = 0; i < ret; i++) {
525 			if ((sclass[i].oclass & 0x00ff) == 0x00b2) {
526 				oclass = sclass[i].oclass;
527 				break;
528 			}
529 		}
530 	} else
531 	if ((init->class & 0x00ff) == 0x00b3) { /* msppp */
532 		/* msppp: compatibility with incorrect version exposure */
533 		for (i = 0; i < ret; i++) {
534 			if ((sclass[i].oclass & 0x00ff) == 0x00b3) {
535 				oclass = sclass[i].oclass;
536 				break;
537 			}
538 		}
539 	} else {
540 		oclass = init->class;
541 	}
542 
543 	nvif_object_sclass_put(&sclass);
544 	if (!oclass)
545 		return nouveau_abi16_put(abi16, -EINVAL);
546 
547 	ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL);
548 	if (!ntfy)
549 		return nouveau_abi16_put(abi16, -ENOMEM);
550 
551 	list_add(&ntfy->head, &chan->notifiers);
552 
553 	client->route = NVDRM_OBJECT_ABI16;
554 	ret = nvif_object_ctor(&chan->chan->user, "abi16EngObj", init->handle,
555 			       oclass, NULL, 0, &ntfy->object);
556 	client->route = NVDRM_OBJECT_NVIF;
557 
558 	if (ret)
559 		nouveau_abi16_ntfy_fini(chan, ntfy);
560 	return nouveau_abi16_put(abi16, ret);
561 }
562 
563 int
564 nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
565 {
566 	struct drm_nouveau_notifierobj_alloc *info = data;
567 	struct nouveau_drm *drm = nouveau_drm(dev);
568 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
569 	struct nouveau_abi16_chan *chan;
570 	struct nouveau_abi16_ntfy *ntfy;
571 	struct nvif_device *device = &abi16->device;
572 	struct nvif_client *client;
573 	struct nv_dma_v0 args = {};
574 	int ret;
575 
576 	if (unlikely(!abi16))
577 		return -ENOMEM;
578 
579 	/* completely unnecessary for these chipsets... */
580 	if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI))
581 		return nouveau_abi16_put(abi16, -EINVAL);
582 	client = abi16->device.object.client;
583 
584 	chan = nouveau_abi16_chan(abi16, info->channel);
585 	if (!chan)
586 		return nouveau_abi16_put(abi16, -ENOENT);
587 
588 	ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL);
589 	if (!ntfy)
590 		return nouveau_abi16_put(abi16, -ENOMEM);
591 
592 	list_add(&ntfy->head, &chan->notifiers);
593 
594 	ret = nvkm_mm_head(&chan->heap, 0, 1, info->size, info->size, 1,
595 			   &ntfy->node);
596 	if (ret)
597 		goto done;
598 
599 	args.start = ntfy->node->offset;
600 	args.limit = ntfy->node->offset + ntfy->node->length - 1;
601 	if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
602 		args.target = NV_DMA_V0_TARGET_VM;
603 		args.access = NV_DMA_V0_ACCESS_VM;
604 		args.start += chan->ntfy_vma->addr;
605 		args.limit += chan->ntfy_vma->addr;
606 	} else
607 	if (drm->agp.bridge) {
608 		args.target = NV_DMA_V0_TARGET_AGP;
609 		args.access = NV_DMA_V0_ACCESS_RDWR;
610 		args.start += drm->agp.base + chan->ntfy->offset;
611 		args.limit += drm->agp.base + chan->ntfy->offset;
612 	} else {
613 		args.target = NV_DMA_V0_TARGET_VM;
614 		args.access = NV_DMA_V0_ACCESS_RDWR;
615 		args.start += chan->ntfy->offset;
616 		args.limit += chan->ntfy->offset;
617 	}
618 
619 	client->route = NVDRM_OBJECT_ABI16;
620 	ret = nvif_object_ctor(&chan->chan->user, "abi16Ntfy", info->handle,
621 			       NV_DMA_IN_MEMORY, &args, sizeof(args),
622 			       &ntfy->object);
623 	client->route = NVDRM_OBJECT_NVIF;
624 	if (ret)
625 		goto done;
626 
627 	info->offset = ntfy->node->offset;
628 done:
629 	if (ret)
630 		nouveau_abi16_ntfy_fini(chan, ntfy);
631 	return nouveau_abi16_put(abi16, ret);
632 }
633 
634 int
635 nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
636 {
637 	struct drm_nouveau_gpuobj_free *fini = data;
638 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
639 	struct nouveau_abi16_chan *chan;
640 	struct nouveau_abi16_ntfy *ntfy;
641 	int ret = -ENOENT;
642 
643 	if (unlikely(!abi16))
644 		return -ENOMEM;
645 
646 	chan = nouveau_abi16_chan(abi16, fini->channel);
647 	if (!chan)
648 		return nouveau_abi16_put(abi16, -EINVAL);
649 
650 	/* synchronize with the user channel and destroy the gpu object */
651 	nouveau_channel_idle(chan->chan);
652 
653 	list_for_each_entry(ntfy, &chan->notifiers, head) {
654 		if (ntfy->object.handle == fini->handle) {
655 			nouveau_abi16_ntfy_fini(chan, ntfy);
656 			ret = 0;
657 			break;
658 		}
659 	}
660 
661 	return nouveau_abi16_put(abi16, ret);
662 }
663