1  // SPDX-License-Identifier: GPL-2.0 OR MIT
2  /**************************************************************************
3   *
4   * Copyright 2012-2016 VMware, Inc., Palo Alto, CA., USA
5   *
6   * Permission is hereby granted, free of charge, to any person obtaining a
7   * copy of this software and associated documentation files (the
8   * "Software"), to deal in the Software without restriction, including
9   * without limitation the rights to use, copy, modify, merge, publish,
10   * distribute, sub license, and/or sell copies of the Software, and to
11   * permit persons to whom the Software is furnished to do so, subject to
12   * the following conditions:
13   *
14   * The above copyright notice and this permission notice (including the
15   * next paragraph) shall be included in all copies or substantial portions
16   * of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22   * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23   * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24   * USE OR OTHER DEALINGS IN THE SOFTWARE.
25   *
26   **************************************************************************/
27  
28  #include "vmwgfx_bo.h"
29  #include "vmwgfx_drv.h"
30  #include "vmwgfx_resource_priv.h"
31  
32  /**
33   * struct vmw_stream - Overlay stream simple resource.
34   * @sres: The simple resource we derive from.
35   * @stream_id: The overlay stream id.
36   */
37  struct vmw_stream {
38  	struct vmw_simple_resource sres;
39  	u32 stream_id;
40  };
41  
42  /**
43   * vmw_stream - Typecast a struct vmw_resource to a struct vmw_stream.
44   * @res: Pointer to the struct vmw_resource.
45   *
46   * Returns: Returns a pointer to the struct vmw_stream.
47   */
48  static struct vmw_stream *
vmw_stream(struct vmw_resource * res)49  vmw_stream(struct vmw_resource *res)
50  {
51  	return container_of(res, struct vmw_stream, sres.res);
52  }
53  
54  /***************************************************************************
55   * Simple resource callbacks for struct vmw_stream
56   **************************************************************************/
vmw_stream_hw_destroy(struct vmw_resource * res)57  static void vmw_stream_hw_destroy(struct vmw_resource *res)
58  {
59  	struct vmw_private *dev_priv = res->dev_priv;
60  	struct vmw_stream *stream = vmw_stream(res);
61  	int ret;
62  
63  	ret = vmw_overlay_unref(dev_priv, stream->stream_id);
64  	WARN_ON_ONCE(ret != 0);
65  }
66  
vmw_stream_init(struct vmw_resource * res,void * data)67  static int vmw_stream_init(struct vmw_resource *res, void *data)
68  {
69  	struct vmw_stream *stream = vmw_stream(res);
70  
71  	return vmw_overlay_claim(res->dev_priv, &stream->stream_id);
72  }
73  
vmw_stream_set_arg_handle(void * data,u32 handle)74  static void vmw_stream_set_arg_handle(void *data, u32 handle)
75  {
76  	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
77  
78  	arg->stream_id = handle;
79  }
80  
81  static const struct vmw_simple_resource_func va_stream_func = {
82  	.res_func = {
83  		.res_type = vmw_res_stream,
84  		.needs_guest_memory = false,
85  		.may_evict = false,
86  		.type_name = "overlay stream",
87  		.domain = VMW_BO_DOMAIN_SYS,
88  		.busy_domain = VMW_BO_DOMAIN_SYS,
89  		.create = NULL,
90  		.destroy = NULL,
91  		.bind = NULL,
92  		.unbind = NULL
93  	},
94  	.ttm_res_type = VMW_RES_STREAM,
95  	.size = sizeof(struct vmw_stream),
96  	.init = vmw_stream_init,
97  	.hw_destroy = vmw_stream_hw_destroy,
98  	.set_arg_handle = vmw_stream_set_arg_handle,
99  };
100  
101  /***************************************************************************
102   * End simple resource callbacks for struct vmw_stream
103   **************************************************************************/
104  
105  /**
106   * vmw_stream_unref_ioctl - Ioctl to unreference a user-space handle to
107   * a struct vmw_stream.
108   * @dev: Pointer to the drm device.
109   * @data: The ioctl argument
110   * @file_priv: Pointer to a struct drm_file identifying the caller.
111   *
112   * Return:
113   *   0 if successful.
114   *   Negative error value on failure.
115   */
vmw_stream_unref_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)116  int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
117  			   struct drm_file *file_priv)
118  {
119  	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
120  
121  	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
122  					 arg->stream_id);
123  }
124  
125  /**
126   * vmw_stream_claim_ioctl - Ioctl to claim a struct vmw_stream overlay.
127   * @dev: Pointer to the drm device.
128   * @data: The ioctl argument
129   * @file_priv: Pointer to a struct drm_file identifying the caller.
130   *
131   * Return:
132   *   0 if successful.
133   *   Negative error value on failure.
134   */
vmw_stream_claim_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)135  int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
136  			   struct drm_file *file_priv)
137  {
138  	return vmw_simple_resource_create_ioctl(dev, data, file_priv,
139  						&va_stream_func);
140  }
141  
142  /**
143   * vmw_user_stream_lookup - Look up a struct vmw_user_stream from a handle.
144   * @dev_priv: Pointer to a struct vmw_private.
145   * @tfile: struct ttm_object_file identifying the caller.
146   * @inout_id: In: The user-space handle. Out: The stream id.
147   * @out: On output contains a refcounted pointer to the embedded
148   * struct vmw_resource.
149   *
150   * Return:
151   *   0 if successful.
152   *   Negative error value on failure.
153   */
vmw_user_stream_lookup(struct vmw_private * dev_priv,struct ttm_object_file * tfile,uint32_t * inout_id,struct vmw_resource ** out)154  int vmw_user_stream_lookup(struct vmw_private *dev_priv,
155  			   struct ttm_object_file *tfile,
156  			   uint32_t *inout_id, struct vmw_resource **out)
157  {
158  	struct vmw_stream *stream;
159  	struct vmw_resource *res =
160  		vmw_simple_resource_lookup(tfile, *inout_id, &va_stream_func);
161  
162  	if (IS_ERR(res))
163  		return PTR_ERR(res);
164  
165  	stream = vmw_stream(res);
166  	*inout_id = stream->stream_id;
167  	*out = res;
168  
169  	return 0;
170  }
171