drm/nouveau: use ioctl interface for abi16 grobj alloc
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
		
					parent
					
						
							
								fdb751ef2b
							
						
					
				
			
			
				commit
				
					
						a4e610b5e6
					
				
			
		
					 3 changed files with 54 additions and 34 deletions
				
			
		|  | @ -21,7 +21,9 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <nvif/os.h> | #include <nvif/client.h> | ||||||
|  | #include <nvif/driver.h> | ||||||
|  | #include <nvif/ioctl.h> | ||||||
| #include <nvif/class.h> | #include <nvif/class.h> | ||||||
| 
 | 
 | ||||||
| #include "nouveau_drm.h" | #include "nouveau_drm.h" | ||||||
|  | @ -46,7 +48,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) | ||||||
| 			 * opened) | 			 * opened) | ||||||
| 			 */ | 			 */ | ||||||
| 			if (nvif_device_init(&cli->base.base, NULL, | 			if (nvif_device_init(&cli->base.base, NULL, | ||||||
| 					     NVDRM_DEVICE, NV_DEVICE_CLASS, | 					     NOUVEAU_ABI16_DEVICE, NV_DEVICE, | ||||||
| 					     &(struct nv_device_class) { | 					     &(struct nv_device_class) { | ||||||
| 						.device = ~0ULL, | 						.device = ~0ULL, | ||||||
| 					     }, sizeof(struct nv_device_class), | 					     }, sizeof(struct nv_device_class), | ||||||
|  | @ -280,7 +282,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) | ||||||
| 	abi16->handles |= (1ULL << init->channel); | 	abi16->handles |= (1ULL << init->channel); | ||||||
| 
 | 
 | ||||||
| 	/* create channel object and initialise dma and fence management */ | 	/* create channel object and initialise dma and fence management */ | ||||||
| 	ret = nouveau_channel_new(drm, device, NVDRM_CHAN | init->channel, | 	ret = nouveau_channel_new(drm, device, | ||||||
|  | 				  NOUVEAU_ABI16_CHAN(init->channel), | ||||||
| 				  init->fb_ctxdma_handle, | 				  init->fb_ctxdma_handle, | ||||||
| 				  init->tt_ctxdma_handle, &chan->chan); | 				  init->tt_ctxdma_handle, &chan->chan); | ||||||
| 	if (ret) | 	if (ret) | ||||||
|  | @ -330,6 +333,18 @@ done: | ||||||
| 	return nouveau_abi16_put(abi16, ret); | 	return nouveau_abi16_put(abi16, ret); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static struct nouveau_abi16_chan * | ||||||
|  | nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel) | ||||||
|  | { | ||||||
|  | 	struct nouveau_abi16_chan *chan; | ||||||
|  | 
 | ||||||
|  | 	list_for_each_entry(chan, &abi16->channels, head) { | ||||||
|  | 		if (chan->chan->object->handle == NOUVEAU_ABI16_CHAN(channel)) | ||||||
|  | 			return chan; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) | nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) | ||||||
|  | @ -337,28 +352,38 @@ nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) | ||||||
| 	struct drm_nouveau_channel_free *req = data; | 	struct drm_nouveau_channel_free *req = data; | ||||||
| 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | ||||||
| 	struct nouveau_abi16_chan *chan; | 	struct nouveau_abi16_chan *chan; | ||||||
| 	int ret = -ENOENT; |  | ||||||
| 
 | 
 | ||||||
| 	if (unlikely(!abi16)) | 	if (unlikely(!abi16)) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry(chan, &abi16->channels, head) { | 	chan = nouveau_abi16_chan(abi16, req->channel); | ||||||
| 		if (chan->chan->object->handle == (NVDRM_CHAN | req->channel)) { | 	if (!chan) | ||||||
| 			nouveau_abi16_chan_fini(abi16, chan); | 		return nouveau_abi16_put(abi16, -ENOENT); | ||||||
| 			return nouveau_abi16_put(abi16, 0); | 	nouveau_abi16_chan_fini(abi16, chan); | ||||||
| 		} | 	return nouveau_abi16_put(abi16, 0); | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return nouveau_abi16_put(abi16, ret); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | int | ||||||
| nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | ||||||
| { | { | ||||||
| 	struct drm_nouveau_grobj_alloc *init = data; | 	struct drm_nouveau_grobj_alloc *init = data; | ||||||
|  | 	struct { | ||||||
|  | 		struct nvif_ioctl_v0 ioctl; | ||||||
|  | 		struct nvif_ioctl_new_v0 new; | ||||||
|  | 	} args = { | ||||||
|  | 		.ioctl.owner = NVIF_IOCTL_V0_OWNER_ANY, | ||||||
|  | 		.ioctl.type = NVIF_IOCTL_V0_NEW, | ||||||
|  | 		.ioctl.path_nr = 3, | ||||||
|  | 		.ioctl.path[2] = NOUVEAU_ABI16_CLIENT, | ||||||
|  | 		.ioctl.path[1] = NOUVEAU_ABI16_DEVICE, | ||||||
|  | 		.ioctl.path[0] = NOUVEAU_ABI16_CHAN(init->channel), | ||||||
|  | 		.new.route = NVDRM_OBJECT_ABI16, | ||||||
|  | 		.new.handle = init->handle, | ||||||
|  | 		.new.oclass = init->class, | ||||||
|  | 	}; | ||||||
| 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | ||||||
| 	struct nouveau_drm *drm = nouveau_drm(dev); | 	struct nouveau_drm *drm = nouveau_drm(dev); | ||||||
| 	struct nouveau_object *object; | 	struct nvif_client *client; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	if (unlikely(!abi16)) | 	if (unlikely(!abi16)) | ||||||
|  | @ -366,6 +391,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | ||||||
| 
 | 
 | ||||||
| 	if (init->handle == ~0) | 	if (init->handle == ~0) | ||||||
| 		return nouveau_abi16_put(abi16, -EINVAL); | 		return nouveau_abi16_put(abi16, -EINVAL); | ||||||
|  | 	client = nvif_client(nvif_object(&abi16->device)); | ||||||
| 
 | 
 | ||||||
| 	/* compatibility with userspace that assumes 506e for all chipsets */ | 	/* compatibility with userspace that assumes 506e for all chipsets */ | ||||||
| 	if (init->class == 0x506e) { | 	if (init->class == 0x506e) { | ||||||
|  | @ -374,10 +400,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | ||||||
| 			return nouveau_abi16_put(abi16, 0); | 			return nouveau_abi16_put(abi16, 0); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*XXX*/ | 	ret = nvif_client_ioctl(client, &args, sizeof(args)); | ||||||
| 	ret = nouveau_object_new(nv_object(nvkm_client(&abi16->device.base)), |  | ||||||
| 				 NVDRM_CHAN | init->channel, init->handle, |  | ||||||
| 				 init->class, NULL, 0, &object); |  | ||||||
| 	return nouveau_abi16_put(abi16, ret); | 	return nouveau_abi16_put(abi16, ret); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -387,7 +410,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) | ||||||
| 	struct drm_nouveau_notifierobj_alloc *info = data; | 	struct drm_nouveau_notifierobj_alloc *info = data; | ||||||
| 	struct nouveau_drm *drm = nouveau_drm(dev); | 	struct nouveau_drm *drm = nouveau_drm(dev); | ||||||
| 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | ||||||
| 	struct nouveau_abi16_chan *chan = NULL, *temp; | 	struct nouveau_abi16_chan *chan; | ||||||
| 	struct nouveau_abi16_ntfy *ntfy; | 	struct nouveau_abi16_ntfy *ntfy; | ||||||
| 	struct nvif_device *device = &abi16->device; | 	struct nvif_device *device = &abi16->device; | ||||||
| 	struct nouveau_object *object; | 	struct nouveau_object *object; | ||||||
|  | @ -401,13 +424,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) | ||||||
| 	if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI)) | 	if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI)) | ||||||
| 		return nouveau_abi16_put(abi16, -EINVAL); | 		return nouveau_abi16_put(abi16, -EINVAL); | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry(temp, &abi16->channels, head) { | 	chan = nouveau_abi16_chan(abi16, info->channel); | ||||||
| 		if (temp->chan->object->handle == (NVDRM_CHAN | info->channel)) { |  | ||||||
| 			chan = temp; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!chan) | 	if (!chan) | ||||||
| 		return nouveau_abi16_put(abi16, -ENOENT); | 		return nouveau_abi16_put(abi16, -ENOENT); | ||||||
| 
 | 
 | ||||||
|  | @ -461,20 +478,14 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) | ||||||
| { | { | ||||||
| 	struct drm_nouveau_gpuobj_free *fini = data; | 	struct drm_nouveau_gpuobj_free *fini = data; | ||||||
| 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | 	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); | ||||||
| 	struct nouveau_abi16_chan *chan = NULL, *temp; | 	struct nouveau_abi16_chan *chan; | ||||||
| 	struct nouveau_abi16_ntfy *ntfy; | 	struct nouveau_abi16_ntfy *ntfy; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	if (unlikely(!abi16)) | 	if (unlikely(!abi16)) | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry(temp, &abi16->channels, head) { | 	chan = nouveau_abi16_chan(abi16, fini->channel); | ||||||
| 		if (temp->chan->object->handle == (NVDRM_CHAN | fini->channel)) { |  | ||||||
| 			chan = temp; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!chan) | 	if (!chan) | ||||||
| 		return nouveau_abi16_put(abi16, -ENOENT); | 		return nouveau_abi16_put(abi16, -ENOENT); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,6 @@ | ||||||
| #include <core/class.h> | #include <core/class.h> | ||||||
| 
 | 
 | ||||||
| #include <drmP.h> | #include <drmP.h> | ||||||
| #include <drm/nouveau_drm.h> |  | ||||||
| 
 | 
 | ||||||
| #include <drm/ttm/ttm_bo_api.h> | #include <drm/ttm/ttm_bo_api.h> | ||||||
| #include <drm/ttm/ttm_bo_driver.h> | #include <drm/ttm/ttm_bo_driver.h> | ||||||
|  | @ -40,6 +39,8 @@ | ||||||
| #include <drm/ttm/ttm_module.h> | #include <drm/ttm/ttm_module.h> | ||||||
| #include <drm/ttm/ttm_page_alloc.h> | #include <drm/ttm/ttm_page_alloc.h> | ||||||
| 
 | 
 | ||||||
|  | #include "uapi/drm/nouveau_drm.h" | ||||||
|  | 
 | ||||||
| struct nouveau_channel; | struct nouveau_channel; | ||||||
| struct platform_device; | struct platform_device; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,6 +25,14 @@ | ||||||
| #ifndef __NOUVEAU_DRM_H__ | #ifndef __NOUVEAU_DRM_H__ | ||||||
| #define __NOUVEAU_DRM_H__ | #define __NOUVEAU_DRM_H__ | ||||||
| 
 | 
 | ||||||
|  | /* reserved object handles when using deprecated object APIs - these
 | ||||||
|  |  * are here so that libdrm can allow interoperability with the new | ||||||
|  |  * object APIs | ||||||
|  |  */ | ||||||
|  | #define NOUVEAU_ABI16_CLIENT   0xffffffff | ||||||
|  | #define NOUVEAU_ABI16_DEVICE   0xdddddddd | ||||||
|  | #define NOUVEAU_ABI16_CHAN(n) (0xcccc0000 | (n)) | ||||||
|  | 
 | ||||||
| #define NOUVEAU_GEM_DOMAIN_CPU       (1 << 0) | #define NOUVEAU_GEM_DOMAIN_CPU       (1 << 0) | ||||||
| #define NOUVEAU_GEM_DOMAIN_VRAM      (1 << 1) | #define NOUVEAU_GEM_DOMAIN_VRAM      (1 << 1) | ||||||
| #define NOUVEAU_GEM_DOMAIN_GART      (1 << 2) | #define NOUVEAU_GEM_DOMAIN_GART      (1 << 2) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ben Skeggs
				Ben Skeggs