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 <hverkuil@kernel.org> 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 * @access_count: count the number of request accesses that are in progress 57 * @objects: List of @struct media_request_object request objects 58 * @num_incomplete_objects: The number of incomplete objects in the request 59 * @manual_completion: if true, then the request won't be marked as completed 60 * when @num_incomplete_objects reaches 0. Call media_request_manual_complete() 61 * to complete the request after @num_incomplete_objects == 0. 62 * @poll_wait: Wait queue for poll 63 * @lock: Serializes access to this struct 64 */ 65 struct media_request { 66 struct media_device *mdev; 67 struct kref kref; 68 char debug_str[TASK_COMM_LEN + 11]; 69 enum media_request_state state; 70 unsigned int updating_count; 71 unsigned int access_count; 72 struct list_head objects; 73 unsigned int num_incomplete_objects; 74 bool manual_completion; 75 wait_queue_head_t poll_wait; 76 spinlock_t lock; 77 }; 78 79 #ifdef CONFIG_MEDIA_CONTROLLER 80 81 /** 82 * media_request_lock_for_access - Lock the request to access its objects 83 * 84 * @req: The media request 85 * 86 * Use before accessing a completed request. A reference to the request must 87 * be held during the access. This usually takes place automatically through 88 * a file handle. Use @media_request_unlock_for_access when done. 89 */ 90 static inline int __must_check 91 media_request_lock_for_access(struct media_request *req) 92 { 93 unsigned long flags; 94 int ret = -EBUSY; 95 96 spin_lock_irqsave(&req->lock, flags); 97 if (req->state == MEDIA_REQUEST_STATE_COMPLETE) { 98 req->access_count++; 99 ret = 0; 100 } 101 spin_unlock_irqrestore(&req->lock, flags); 102 103 return ret; 104 } 105 106 /** 107 * media_request_unlock_for_access - Unlock a request previously locked for 108 * access 109 * 110 * @req: The media request 111 * 112 * Unlock a request that has previously been locked using 113 * @media_request_lock_for_access. 114 */ 115 static inline void media_request_unlock_for_access(struct media_request *req) 116 { 117 unsigned long flags; 118 119 spin_lock_irqsave(&req->lock, flags); 120 if (!WARN_ON(!req->access_count)) 121 req->access_count--; 122 spin_unlock_irqrestore(&req->lock, flags); 123 } 124 125 /** 126 * media_request_lock_for_update - Lock the request for updating its objects 127 * 128 * @req: The media request 129 * 130 * Use before updating a request, i.e. adding, modifying or removing a request 131 * object in it. A reference to the request must be held during the update. This 132 * usually takes place automatically through a file handle. Use 133 * @media_request_unlock_for_update when done. 134 */ 135 static inline int __must_check 136 media_request_lock_for_update(struct media_request *req) 137 { 138 unsigned long flags; 139 int ret = 0; 140 141 spin_lock_irqsave(&req->lock, flags); 142 if (req->state == MEDIA_REQUEST_STATE_IDLE || 143 req->state == MEDIA_REQUEST_STATE_UPDATING) { 144 req->state = MEDIA_REQUEST_STATE_UPDATING; 145 req->updating_count++; 146 } else { 147 ret = -EBUSY; 148 } 149 spin_unlock_irqrestore(&req->lock, flags); 150 151 return ret; 152 } 153 154 /** 155 * media_request_unlock_for_update - Unlock a request previously locked for 156 * update 157 * 158 * @req: The media request 159 * 160 * Unlock a request that has previously been locked using 161 * @media_request_lock_for_update. 162 */ 163 static inline void media_request_unlock_for_update(struct media_request *req) 164 { 165 unsigned long flags; 166 167 spin_lock_irqsave(&req->lock, flags); 168 WARN_ON(req->updating_count <= 0); 169 if (!--req->updating_count) 170 req->state = MEDIA_REQUEST_STATE_IDLE; 171 spin_unlock_irqrestore(&req->lock, flags); 172 } 173 174 /** 175 * media_request_get - Get the media request 176 * 177 * @req: The media request 178 * 179 * Get the media request. 180 */ 181 static inline void media_request_get(struct media_request *req) 182 { 183 kref_get(&req->kref); 184 } 185 186 /** 187 * media_request_put - Put the media request 188 * 189 * @req: The media request 190 * 191 * Put the media request. The media request will be released 192 * when the refcount reaches 0. 193 */ 194 void media_request_put(struct media_request *req); 195 196 /** 197 * media_request_get_by_fd - Get a media request by fd 198 * 199 * @mdev: Media device this request belongs to 200 * @request_fd: The file descriptor of the request 201 * 202 * Get the request represented by @request_fd that is owned 203 * by the media device. 204 * 205 * Return a -EBADR error pointer if requests are not supported 206 * by this driver. Return -EINVAL if the request was not found. 207 * Return the pointer to the request if found: the caller will 208 * have to call @media_request_put when it finished using the 209 * request. 210 */ 211 struct media_request * 212 media_request_get_by_fd(struct media_device *mdev, int request_fd); 213 214 /** 215 * media_request_alloc - Allocate the media request 216 * 217 * @mdev: Media device this request belongs to 218 * @alloc_fd: Store the request's file descriptor in this int 219 * 220 * Allocated the media request and put the fd in @alloc_fd. 221 */ 222 int media_request_alloc(struct media_device *mdev, 223 int *alloc_fd); 224 225 /** 226 * media_request_mark_manual_completion - Enable manual completion 227 * 228 * @req: The request 229 * 230 * Mark that the request has to be manually completed by calling 231 * media_request_manual_complete(). 232 * 233 * This function shall be called in the req_queue callback. 234 */ 235 static inline void 236 media_request_mark_manual_completion(struct media_request *req) 237 { 238 req->manual_completion = true; 239 } 240 241 /** 242 * media_request_manual_complete - Mark the request as completed 243 * 244 * @req: The request 245 * 246 * This function completes a request that was marked for manual completion by an 247 * earlier call to media_request_mark_manual_completion(). The request's 248 * @manual_completion field is reset to false. 249 * 250 * All objects contained in the request must have been completed previously. It 251 * is an error to call this function otherwise. If such an error occurred, the 252 * function will WARN and the object completion will be delayed until 253 * @num_incomplete_objects is 0. 254 */ 255 void media_request_manual_complete(struct media_request *req); 256 257 #else 258 259 static inline void media_request_get(struct media_request *req) 260 { 261 } 262 263 static inline void media_request_put(struct media_request *req) 264 { 265 } 266 267 static inline struct media_request * 268 media_request_get_by_fd(struct media_device *mdev, int request_fd) 269 { 270 return ERR_PTR(-EBADR); 271 } 272 273 #endif 274 275 /** 276 * struct media_request_object_ops - Media request object operations 277 * @prepare: Validate and prepare the request object, optional. 278 * @unprepare: Unprepare the request object, optional. 279 * @queue: Queue the request object, optional. 280 * @unbind: Unbind the request object, optional. 281 * @release: Release the request object, required. 282 */ 283 struct media_request_object_ops { 284 int (*prepare)(struct media_request_object *object); 285 void (*unprepare)(struct media_request_object *object); 286 void (*queue)(struct media_request_object *object); 287 void (*unbind)(struct media_request_object *object); 288 void (*release)(struct media_request_object *object); 289 }; 290 291 /** 292 * struct media_request_object - An opaque object that belongs to a media 293 * request 294 * 295 * @mdev: Media device this object belongs to 296 * @ops: object's operations 297 * @priv: object's priv pointer 298 * @req: the request this object belongs to (can be NULL) 299 * @list: List entry of the object for @struct media_request 300 * @kref: Reference count of the object, acquire before releasing req->lock 301 * @completed: If true, then this object was completed. 302 * 303 * An object related to the request. This struct is always embedded in 304 * another struct that contains the actual data for this request object. 305 */ 306 struct media_request_object { 307 struct media_device *mdev; 308 const struct media_request_object_ops *ops; 309 void *priv; 310 struct media_request *req; 311 struct list_head list; 312 struct kref kref; 313 bool completed; 314 }; 315 316 #ifdef CONFIG_MEDIA_CONTROLLER 317 318 /** 319 * media_request_object_get - Get a media request object 320 * 321 * @obj: The object 322 * 323 * Get a media request object. 324 */ 325 static inline void media_request_object_get(struct media_request_object *obj) 326 { 327 kref_get(&obj->kref); 328 } 329 330 /** 331 * media_request_object_put - Put a media request object 332 * 333 * @obj: The object 334 * 335 * Put a media request object. Once all references are gone, the 336 * object's memory is released. 337 */ 338 void media_request_object_put(struct media_request_object *obj); 339 340 /** 341 * media_request_object_find - Find an object in a request 342 * 343 * @req: The media request 344 * @ops: Find an object with this ops value 345 * @priv: Find an object with this priv value 346 * 347 * Both @ops and @priv must be non-NULL. 348 * 349 * Returns the object pointer or NULL if not found. The caller must 350 * call media_request_object_put() once it finished using the object. 351 * 352 * Since this function needs to walk the list of objects it takes 353 * the @req->lock spin lock to make this safe. 354 */ 355 struct media_request_object * 356 media_request_object_find(struct media_request *req, 357 const struct media_request_object_ops *ops, 358 void *priv); 359 360 /** 361 * media_request_object_init - Initialise a media request object 362 * 363 * @obj: The object 364 * 365 * Initialise a media request object. The object will be released using the 366 * release callback of the ops once it has no references (this function 367 * initialises references to one). 368 */ 369 void media_request_object_init(struct media_request_object *obj); 370 371 /** 372 * media_request_object_bind - Bind a media request object to a request 373 * 374 * @req: The media request 375 * @ops: The object ops for this object 376 * @priv: A driver-specific priv pointer associated with this object 377 * @is_buffer: Set to true if the object is a buffer object. 378 * @obj: The object 379 * 380 * Bind this object to the request and set the ops and priv values of 381 * the object so it can be found later with media_request_object_find(). 382 * 383 * Every bound object must be unbound or completed by the kernel at some 384 * point in time, otherwise the request will never complete. When the 385 * request is released all completed objects will be unbound by the 386 * request core code. 387 * 388 * Buffer objects will be added to the end of the request's object 389 * list, non-buffer objects will be added to the front of the list. 390 * This ensures that all buffer objects are at the end of the list 391 * and that all non-buffer objects that they depend on are processed 392 * first. 393 */ 394 int media_request_object_bind(struct media_request *req, 395 const struct media_request_object_ops *ops, 396 void *priv, bool is_buffer, 397 struct media_request_object *obj); 398 399 /** 400 * media_request_object_unbind - Unbind a media request object 401 * 402 * @obj: The object 403 * 404 * Unbind the media request object from the request. 405 */ 406 void media_request_object_unbind(struct media_request_object *obj); 407 408 /** 409 * media_request_object_complete - Mark the media request object as complete 410 * 411 * @obj: The object 412 * 413 * Mark the media request object as complete. Only bound objects can 414 * be completed. 415 */ 416 void media_request_object_complete(struct media_request_object *obj); 417 418 #else 419 420 static inline int __must_check 421 media_request_lock_for_access(struct media_request *req) 422 { 423 return -EINVAL; 424 } 425 426 static inline void media_request_unlock_for_access(struct media_request *req) 427 { 428 } 429 430 static inline int __must_check 431 media_request_lock_for_update(struct media_request *req) 432 { 433 return -EINVAL; 434 } 435 436 static inline void media_request_unlock_for_update(struct media_request *req) 437 { 438 } 439 440 static inline void media_request_object_get(struct media_request_object *obj) 441 { 442 } 443 444 static inline void media_request_object_put(struct media_request_object *obj) 445 { 446 } 447 448 static inline struct media_request_object * 449 media_request_object_find(struct media_request *req, 450 const struct media_request_object_ops *ops, 451 void *priv) 452 { 453 return NULL; 454 } 455 456 static inline void media_request_object_init(struct media_request_object *obj) 457 { 458 obj->ops = NULL; 459 obj->req = NULL; 460 } 461 462 static inline int media_request_object_bind(struct media_request *req, 463 const struct media_request_object_ops *ops, 464 void *priv, bool is_buffer, 465 struct media_request_object *obj) 466 { 467 return 0; 468 } 469 470 static inline void media_request_object_unbind(struct media_request_object *obj) 471 { 472 } 473 474 static inline void media_request_object_complete(struct media_request_object *obj) 475 { 476 } 477 478 #endif 479 480 #endif 481