1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Media device request objects 4 * 5 * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 * Copyright (C) 2018 Intel Corporation 7 * 8 * Author: Hans Verkuil <hans.verkuil@cisco.com> 9 * Author: Sakari Ailus <sakari.ailus@linux.intel.com> 10 */ 11 12 #ifndef MEDIA_REQUEST_H 13 #define MEDIA_REQUEST_H 14 15 #include <linux/list.h> 16 #include <linux/slab.h> 17 #include <linux/spinlock.h> 18 #include <linux/refcount.h> 19 20 #include <media/media-device.h> 21 22 /** 23 * enum media_request_state - media request state 24 * 25 * @MEDIA_REQUEST_STATE_IDLE: Idle 26 * @MEDIA_REQUEST_STATE_VALIDATING: Validating the request, no state changes 27 * allowed 28 * @MEDIA_REQUEST_STATE_QUEUED: Queued 29 * @MEDIA_REQUEST_STATE_COMPLETE: Completed, the request is done 30 * @MEDIA_REQUEST_STATE_CLEANING: Cleaning, the request is being re-inited 31 * @MEDIA_REQUEST_STATE_UPDATING: The request is being updated, i.e. 32 * request objects are being added, 33 * modified or removed 34 * @NR_OF_MEDIA_REQUEST_STATE: The number of media request states, used 35 * internally for sanity check purposes 36 */ 37 enum media_request_state { 38 MEDIA_REQUEST_STATE_IDLE, 39 MEDIA_REQUEST_STATE_VALIDATING, 40 MEDIA_REQUEST_STATE_QUEUED, 41 MEDIA_REQUEST_STATE_COMPLETE, 42 MEDIA_REQUEST_STATE_CLEANING, 43 MEDIA_REQUEST_STATE_UPDATING, 44 NR_OF_MEDIA_REQUEST_STATE, 45 }; 46 47 struct media_request_object; 48 49 /** 50 * struct media_request - Media device request 51 * @mdev: Media device this request belongs to 52 * @kref: Reference count 53 * @debug_str: Prefix for debug messages (process name:fd) 54 * @state: The state of the request 55 * @updating_count: count the number of request updates that are in progress 56 * @objects: List of @struct media_request_object request objects 57 * @num_incomplete_objects: The number of incomplete objects in the request 58 * @poll_wait: Wait queue for poll 59 * @lock: Serializes access to this struct 60 */ 61 struct media_request { 62 struct media_device *mdev; 63 struct kref kref; 64 char debug_str[TASK_COMM_LEN + 11]; 65 enum media_request_state state; 66 unsigned int updating_count; 67 struct list_head objects; 68 unsigned int num_incomplete_objects; 69 struct wait_queue_head poll_wait; 70 spinlock_t lock; 71 }; 72 73 #ifdef CONFIG_MEDIA_CONTROLLER 74 75 /** 76 * media_request_lock_for_update - Lock the request for updating its objects 77 * 78 * @req: The media request 79 * 80 * Use before updating a request, i.e. adding, modifying or removing a request 81 * object in it. A reference to the request must be held during the update. This 82 * usually takes place automatically through a file handle. Use 83 * @media_request_unlock_for_update when done. 84 */ 85 static inline int __must_check 86 media_request_lock_for_update(struct media_request *req) 87 { 88 unsigned long flags; 89 int ret = 0; 90 91 spin_lock_irqsave(&req->lock, flags); 92 if (req->state == MEDIA_REQUEST_STATE_IDLE || 93 req->state == MEDIA_REQUEST_STATE_UPDATING) { 94 req->state = MEDIA_REQUEST_STATE_UPDATING; 95 req->updating_count++; 96 } else { 97 ret = -EBUSY; 98 } 99 spin_unlock_irqrestore(&req->lock, flags); 100 101 return ret; 102 } 103 104 /** 105 * media_request_unlock_for_update - Unlock a request previously locked for 106 * update 107 * 108 * @req: The media request 109 * 110 * Unlock a request that has previously been locked using 111 * @media_request_lock_for_update. 112 */ 113 static inline void media_request_unlock_for_update(struct media_request *req) 114 { 115 unsigned long flags; 116 117 spin_lock_irqsave(&req->lock, flags); 118 WARN_ON(req->updating_count <= 0); 119 if (!--req->updating_count) 120 req->state = MEDIA_REQUEST_STATE_IDLE; 121 spin_unlock_irqrestore(&req->lock, flags); 122 } 123 124 /** 125 * media_request_get - Get the media request 126 * 127 * @req: The media request 128 * 129 * Get the media request. 130 */ 131 static inline void media_request_get(struct media_request *req) 132 { 133 kref_get(&req->kref); 134 } 135 136 /** 137 * media_request_put - Put the media request 138 * 139 * @req: The media request 140 * 141 * Put the media request. The media request will be released 142 * when the refcount reaches 0. 143 */ 144 void media_request_put(struct media_request *req); 145 146 /** 147 * media_request_get_by_fd - Get a media request by fd 148 * 149 * @mdev: Media device this request belongs to 150 * @request_fd: The file descriptor of the request 151 * 152 * Get the request represented by @request_fd that is owned 153 * by the media device. 154 * 155 * Return a -EPERM error pointer if requests are not supported 156 * by this driver. Return -ENOENT if the request was not found. 157 * Return the pointer to the request if found: the caller will 158 * have to call @media_request_put when it finished using the 159 * request. 160 */ 161 struct media_request * 162 media_request_get_by_fd(struct media_device *mdev, int request_fd); 163 164 /** 165 * media_request_alloc - Allocate the media request 166 * 167 * @mdev: Media device this request belongs to 168 * @alloc_fd: Store the request's file descriptor in this int 169 * 170 * Allocated the media request and put the fd in @alloc_fd. 171 */ 172 int media_request_alloc(struct media_device *mdev, 173 int *alloc_fd); 174 175 #else 176 177 static inline void media_request_get(struct media_request *req) 178 { 179 } 180 181 static inline void media_request_put(struct media_request *req) 182 { 183 } 184 185 static inline struct media_request * 186 media_request_get_by_fd(struct media_device *mdev, int request_fd) 187 { 188 return ERR_PTR(-EPERM); 189 } 190 191 #endif 192 193 /** 194 * struct media_request_object_ops - Media request object operations 195 * @prepare: Validate and prepare the request object, optional. 196 * @unprepare: Unprepare the request object, optional. 197 * @queue: Queue the request object, optional. 198 * @unbind: Unbind the request object, optional. 199 * @release: Release the request object, required. 200 */ 201 struct media_request_object_ops { 202 int (*prepare)(struct media_request_object *object); 203 void (*unprepare)(struct media_request_object *object); 204 void (*queue)(struct media_request_object *object); 205 void (*unbind)(struct media_request_object *object); 206 void (*release)(struct media_request_object *object); 207 }; 208 209 /** 210 * struct media_request_object - An opaque object that belongs to a media 211 * request 212 * 213 * @ops: object's operations 214 * @priv: object's priv pointer 215 * @req: the request this object belongs to (can be NULL) 216 * @list: List entry of the object for @struct media_request 217 * @kref: Reference count of the object, acquire before releasing req->lock 218 * @completed: If true, then this object was completed. 219 * 220 * An object related to the request. This struct is always embedded in 221 * another struct that contains the actual data for this request object. 222 */ 223 struct media_request_object { 224 const struct media_request_object_ops *ops; 225 void *priv; 226 struct media_request *req; 227 struct list_head list; 228 struct kref kref; 229 bool completed; 230 }; 231 232 #ifdef CONFIG_MEDIA_CONTROLLER 233 234 /** 235 * media_request_object_get - Get a media request object 236 * 237 * @obj: The object 238 * 239 * Get a media request object. 240 */ 241 static inline void media_request_object_get(struct media_request_object *obj) 242 { 243 kref_get(&obj->kref); 244 } 245 246 /** 247 * media_request_object_put - Put a media request object 248 * 249 * @obj: The object 250 * 251 * Put a media request object. Once all references are gone, the 252 * object's memory is released. 253 */ 254 void media_request_object_put(struct media_request_object *obj); 255 256 /** 257 * media_request_object_find - Find an object in a request 258 * 259 * @req: The media request 260 * @ops: Find an object with this ops value 261 * @priv: Find an object with this priv value 262 * 263 * Both @ops and @priv must be non-NULL. 264 * 265 * Returns the object pointer or NULL if not found. The caller must 266 * call media_request_object_put() once it finished using the object. 267 * 268 * Since this function needs to walk the list of objects it takes 269 * the @req->lock spin lock to make this safe. 270 */ 271 struct media_request_object * 272 media_request_object_find(struct media_request *req, 273 const struct media_request_object_ops *ops, 274 void *priv); 275 276 /** 277 * media_request_object_init - Initialise a media request object 278 * 279 * @obj: The object 280 * 281 * Initialise a media request object. The object will be released using the 282 * release callback of the ops once it has no references (this function 283 * initialises references to one). 284 */ 285 void media_request_object_init(struct media_request_object *obj); 286 287 /** 288 * media_request_object_bind - Bind a media request object to a request 289 * 290 * @req: The media request 291 * @ops: The object ops for this object 292 * @priv: A driver-specific priv pointer associated with this object 293 * @is_buffer: Set to true if the object a buffer object. 294 * @obj: The object 295 * 296 * Bind this object to the request and set the ops and priv values of 297 * the object so it can be found later with media_request_object_find(). 298 * 299 * Every bound object must be unbound or completed by the kernel at some 300 * point in time, otherwise the request will never complete. When the 301 * request is released all completed objects will be unbound by the 302 * request core code. 303 * 304 * Buffer objects will be added to the end of the request's object 305 * list, non-buffer objects will be added to the front of the list. 306 * This ensures that all buffer objects are at the end of the list 307 * and that all non-buffer objects that they depend on are processed 308 * first. 309 */ 310 int media_request_object_bind(struct media_request *req, 311 const struct media_request_object_ops *ops, 312 void *priv, bool is_buffer, 313 struct media_request_object *obj); 314 315 /** 316 * media_request_object_unbind - Unbind a media request object 317 * 318 * @obj: The object 319 * 320 * Unbind the media request object from the request. 321 */ 322 void media_request_object_unbind(struct media_request_object *obj); 323 324 /** 325 * media_request_object_complete - Mark the media request object as complete 326 * 327 * @obj: The object 328 * 329 * Mark the media request object as complete. Only bound objects can 330 * be completed. 331 */ 332 void media_request_object_complete(struct media_request_object *obj); 333 334 #else 335 336 static inline int __must_check 337 media_request_lock_for_update(struct media_request *req) 338 { 339 return -EINVAL; 340 } 341 342 static inline void media_request_unlock_for_update(struct media_request *req) 343 { 344 } 345 346 static inline void media_request_object_get(struct media_request_object *obj) 347 { 348 } 349 350 static inline void media_request_object_put(struct media_request_object *obj) 351 { 352 } 353 354 static inline struct media_request_object * 355 media_request_object_find(struct media_request *req, 356 const struct media_request_object_ops *ops, 357 void *priv) 358 { 359 return NULL; 360 } 361 362 static inline void media_request_object_init(struct media_request_object *obj) 363 { 364 obj->ops = NULL; 365 obj->req = NULL; 366 } 367 368 static inline int media_request_object_bind(struct media_request *req, 369 const struct media_request_object_ops *ops, 370 void *priv, bool is_buffer, 371 struct media_request_object *obj) 372 { 373 return 0; 374 } 375 376 static inline void media_request_object_unbind(struct media_request_object *obj) 377 { 378 } 379 380 static inline void media_request_object_complete(struct media_request_object *obj) 381 { 382 } 383 384 #endif 385 386 #endif 387