0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include "vmwgfx_drv.h"
0029 #include "vmwgfx_resource_priv.h"
0030
0031
0032
0033
0034
0035
0036
0037 struct vmw_user_simple_resource {
0038 struct ttm_base_object base;
0039 struct vmw_simple_resource simple;
0040
0041
0042
0043
0044 };
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 static int vmw_simple_resource_init(struct vmw_private *dev_priv,
0061 struct vmw_simple_resource *simple,
0062 void *data,
0063 void (*res_free)(struct vmw_resource *res))
0064 {
0065 struct vmw_resource *res = &simple->res;
0066 int ret;
0067
0068 ret = vmw_resource_init(dev_priv, res, false, res_free,
0069 &simple->func->res_func);
0070
0071 if (ret) {
0072 res_free(res);
0073 return ret;
0074 }
0075
0076 ret = simple->func->init(res, data);
0077 if (ret) {
0078 vmw_resource_unreference(&res);
0079 return ret;
0080 }
0081
0082 simple->res.hw_destroy = simple->func->hw_destroy;
0083
0084 return 0;
0085 }
0086
0087
0088
0089
0090
0091
0092
0093
0094 static void vmw_simple_resource_free(struct vmw_resource *res)
0095 {
0096 struct vmw_user_simple_resource *usimple =
0097 container_of(res, struct vmw_user_simple_resource,
0098 simple.res);
0099
0100 ttm_base_object_kfree(usimple, base);
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 static void vmw_simple_resource_base_release(struct ttm_base_object **p_base)
0113 {
0114 struct ttm_base_object *base = *p_base;
0115 struct vmw_user_simple_resource *usimple =
0116 container_of(base, struct vmw_user_simple_resource, base);
0117 struct vmw_resource *res = &usimple->simple.res;
0118
0119 *p_base = NULL;
0120 vmw_resource_unreference(&res);
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 int
0138 vmw_simple_resource_create_ioctl(struct drm_device *dev, void *data,
0139 struct drm_file *file_priv,
0140 const struct vmw_simple_resource_func *func)
0141 {
0142 struct vmw_private *dev_priv = vmw_priv(dev);
0143 struct vmw_user_simple_resource *usimple;
0144 struct vmw_resource *res;
0145 struct vmw_resource *tmp;
0146 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
0147 size_t alloc_size;
0148 int ret;
0149
0150 alloc_size = offsetof(struct vmw_user_simple_resource, simple) +
0151 func->size;
0152
0153 usimple = kzalloc(alloc_size, GFP_KERNEL);
0154 if (!usimple) {
0155 ret = -ENOMEM;
0156 goto out_ret;
0157 }
0158
0159 usimple->simple.func = func;
0160 res = &usimple->simple.res;
0161 usimple->base.shareable = false;
0162 usimple->base.tfile = NULL;
0163
0164
0165
0166
0167 ret = vmw_simple_resource_init(dev_priv, &usimple->simple,
0168 data, vmw_simple_resource_free);
0169 if (ret)
0170 goto out_ret;
0171
0172 tmp = vmw_resource_reference(res);
0173 ret = ttm_base_object_init(tfile, &usimple->base, false,
0174 func->ttm_res_type,
0175 &vmw_simple_resource_base_release);
0176
0177 if (ret) {
0178 vmw_resource_unreference(&tmp);
0179 goto out_err;
0180 }
0181
0182 func->set_arg_handle(data, usimple->base.handle);
0183 out_err:
0184 vmw_resource_unreference(&res);
0185 out_ret:
0186 return ret;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201 struct vmw_resource *
0202 vmw_simple_resource_lookup(struct ttm_object_file *tfile,
0203 uint32_t handle,
0204 const struct vmw_simple_resource_func *func)
0205 {
0206 struct vmw_user_simple_resource *usimple;
0207 struct ttm_base_object *base;
0208 struct vmw_resource *res;
0209
0210 base = ttm_base_object_lookup(tfile, handle);
0211 if (!base) {
0212 VMW_DEBUG_USER("Invalid %s handle 0x%08lx.\n",
0213 func->res_func.type_name,
0214 (unsigned long) handle);
0215 return ERR_PTR(-ESRCH);
0216 }
0217
0218 if (ttm_base_object_type(base) != func->ttm_res_type) {
0219 ttm_base_object_unref(&base);
0220 VMW_DEBUG_USER("Invalid type of %s handle 0x%08lx.\n",
0221 func->res_func.type_name,
0222 (unsigned long) handle);
0223 return ERR_PTR(-EINVAL);
0224 }
0225
0226 usimple = container_of(base, typeof(*usimple), base);
0227 res = vmw_resource_reference(&usimple->simple.res);
0228 ttm_base_object_unref(&base);
0229
0230 return res;
0231 }