Lines Matching +full:lock +full:- +full:state

1 // SPDX-License-Identifier: GPL-2.0
17 #include <media/media-device.h>
18 #include <media/media-request.h>
30 media_request_state_str(enum media_request_state state) in media_request_state_str() argument
34 if (WARN_ON(state >= ARRAY_SIZE(request_state))) in media_request_state_str()
36 return request_state[state]; in media_request_state_str()
44 WARN_ON(req->state != MEDIA_REQUEST_STATE_CLEANING); in media_request_clean()
45 WARN_ON(req->updating_count); in media_request_clean()
46 WARN_ON(req->access_count); in media_request_clean()
48 list_for_each_entry_safe(obj, obj_safe, &req->objects, list) { in media_request_clean()
53 req->updating_count = 0; in media_request_clean()
54 req->access_count = 0; in media_request_clean()
55 WARN_ON(req->num_incomplete_objects); in media_request_clean()
56 req->num_incomplete_objects = 0; in media_request_clean()
57 wake_up_interruptible_all(&req->poll_wait); in media_request_clean()
64 struct media_device *mdev = req->mdev; in media_request_release()
66 dev_dbg(mdev->dev, "request: release %s\n", req->debug_str); in media_request_release()
69 req->state = MEDIA_REQUEST_STATE_CLEANING; in media_request_release()
73 if (mdev->ops->req_free) in media_request_release()
74 mdev->ops->req_free(req); in media_request_release()
81 kref_put(&req->kref, media_request_release); in media_request_put()
87 struct media_request *req = filp->private_data; in media_request_close()
96 struct media_request *req = filp->private_data; in media_request_poll()
103 poll_wait(filp, &req->poll_wait, wait); in media_request_poll()
104 spin_lock_irqsave(&req->lock, flags); in media_request_poll()
105 if (req->state == MEDIA_REQUEST_STATE_COMPLETE) { in media_request_poll()
109 if (req->state != MEDIA_REQUEST_STATE_QUEUED) { in media_request_poll()
115 spin_unlock_irqrestore(&req->lock, flags); in media_request_poll()
121 struct media_device *mdev = req->mdev; in media_request_ioctl_queue()
122 enum media_request_state state; in media_request_ioctl_queue() local
126 dev_dbg(mdev->dev, "request: queue %s\n", req->debug_str); in media_request_ioctl_queue()
134 mutex_lock(&mdev->req_queue_mutex); in media_request_ioctl_queue()
138 spin_lock_irqsave(&req->lock, flags); in media_request_ioctl_queue()
139 if (req->state == MEDIA_REQUEST_STATE_IDLE) in media_request_ioctl_queue()
140 req->state = MEDIA_REQUEST_STATE_VALIDATING; in media_request_ioctl_queue()
141 state = req->state; in media_request_ioctl_queue()
142 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_queue()
143 if (state != MEDIA_REQUEST_STATE_VALIDATING) { in media_request_ioctl_queue()
144 dev_dbg(mdev->dev, in media_request_ioctl_queue()
145 "request: unable to queue %s, request in state %s\n", in media_request_ioctl_queue()
146 req->debug_str, media_request_state_str(state)); in media_request_ioctl_queue()
148 mutex_unlock(&mdev->req_queue_mutex); in media_request_ioctl_queue()
149 return -EBUSY; in media_request_ioctl_queue()
152 ret = mdev->ops->req_validate(req); in media_request_ioctl_queue()
155 * If the req_validate was successful, then we mark the state as QUEUED in media_request_ioctl_queue()
156 * and call req_queue. The reason we set the state first is that this in media_request_ioctl_queue()
158 * they are immediately 'consumed'. State changes from QUEUED to another in media_request_ioctl_queue()
159 * state can only happen if either the driver changes the state or if in media_request_ioctl_queue()
160 * the user cancels the vb2 queue. The driver can only change the state in media_request_ioctl_queue()
162 * that op cannot fail), so setting the state to QUEUED up front is in media_request_ioctl_queue()
165 * The other reason for changing the state is if the vb2 queue is in media_request_ioctl_queue()
169 spin_lock_irqsave(&req->lock, flags); in media_request_ioctl_queue()
170 req->state = ret ? MEDIA_REQUEST_STATE_IDLE in media_request_ioctl_queue()
172 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_queue()
175 mdev->ops->req_queue(req); in media_request_ioctl_queue()
177 mutex_unlock(&mdev->req_queue_mutex); in media_request_ioctl_queue()
180 dev_dbg(mdev->dev, "request: can't queue %s (%d)\n", in media_request_ioctl_queue()
181 req->debug_str, ret); in media_request_ioctl_queue()
190 struct media_device *mdev = req->mdev; in media_request_ioctl_reinit()
193 spin_lock_irqsave(&req->lock, flags); in media_request_ioctl_reinit()
194 if (req->state != MEDIA_REQUEST_STATE_IDLE && in media_request_ioctl_reinit()
195 req->state != MEDIA_REQUEST_STATE_COMPLETE) { in media_request_ioctl_reinit()
196 dev_dbg(mdev->dev, in media_request_ioctl_reinit()
197 "request: %s not in idle or complete state, cannot reinit\n", in media_request_ioctl_reinit()
198 req->debug_str); in media_request_ioctl_reinit()
199 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_reinit()
200 return -EBUSY; in media_request_ioctl_reinit()
202 if (req->access_count) { in media_request_ioctl_reinit()
203 dev_dbg(mdev->dev, in media_request_ioctl_reinit()
205 req->debug_str); in media_request_ioctl_reinit()
206 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_reinit()
207 return -EBUSY; in media_request_ioctl_reinit()
209 req->state = MEDIA_REQUEST_STATE_CLEANING; in media_request_ioctl_reinit()
210 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_reinit()
214 spin_lock_irqsave(&req->lock, flags); in media_request_ioctl_reinit()
215 req->state = MEDIA_REQUEST_STATE_IDLE; in media_request_ioctl_reinit()
216 spin_unlock_irqrestore(&req->lock, flags); in media_request_ioctl_reinit()
224 struct media_request *req = filp->private_data; in media_request_ioctl()
232 return -ENOIOCTLCMD; in media_request_ioctl()
251 if (!mdev || !mdev->ops || in media_request_get_by_fd()
252 !mdev->ops->req_validate || !mdev->ops->req_queue) in media_request_get_by_fd()
253 return ERR_PTR(-EBADR); in media_request_get_by_fd()
259 if (fd_file(f)->f_op != &request_fops) in media_request_get_by_fd()
261 req = fd_file(f)->private_data; in media_request_get_by_fd()
262 if (req->mdev != mdev) in media_request_get_by_fd()
277 dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd); in media_request_get_by_fd()
278 return ERR_PTR(-EINVAL); in media_request_get_by_fd()
289 /* Either both are NULL or both are non-NULL */ in media_request_alloc()
290 if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free)) in media_request_alloc()
291 return -ENOMEM; in media_request_alloc()
293 if (mdev->ops->req_alloc) in media_request_alloc()
294 req = mdev->ops->req_alloc(mdev); in media_request_alloc()
298 return -ENOMEM; in media_request_alloc()
312 filp->private_data = req; in media_request_alloc()
313 req->mdev = mdev; in media_request_alloc()
314 req->state = MEDIA_REQUEST_STATE_IDLE; in media_request_alloc()
315 req->num_incomplete_objects = 0; in media_request_alloc()
316 kref_init(&req->kref); in media_request_alloc()
317 INIT_LIST_HEAD(&req->objects); in media_request_alloc()
318 spin_lock_init(&req->lock); in media_request_alloc()
319 init_waitqueue_head(&req->poll_wait); in media_request_alloc()
320 req->updating_count = 0; in media_request_alloc()
321 req->access_count = 0; in media_request_alloc()
325 snprintf(req->debug_str, sizeof(req->debug_str), "%u:%d", in media_request_alloc()
326 atomic_inc_return(&mdev->request_id), fd); in media_request_alloc()
327 dev_dbg(mdev->dev, "request: allocated %s\n", req->debug_str); in media_request_alloc()
337 if (mdev->ops->req_free) in media_request_alloc()
338 mdev->ops->req_free(req); in media_request_alloc()
349 struct media_request *req = obj->req; in media_request_object_release()
353 obj->ops->release(obj); in media_request_object_release()
368 spin_lock_irqsave(&req->lock, flags); in media_request_object_find()
369 list_for_each_entry(obj, &req->objects, list) { in media_request_object_find()
370 if (obj->ops == ops && obj->priv == priv) { in media_request_object_find()
376 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_find()
383 kref_put(&obj->kref, media_request_object_release); in media_request_object_put()
389 obj->ops = NULL; in media_request_object_init()
390 obj->req = NULL; in media_request_object_init()
391 obj->priv = NULL; in media_request_object_init()
392 obj->completed = false; in media_request_object_init()
393 INIT_LIST_HEAD(&obj->list); in media_request_object_init()
394 kref_init(&obj->kref); in media_request_object_init()
404 int ret = -EBUSY; in media_request_object_bind()
406 if (WARN_ON(!ops->release)) in media_request_object_bind()
407 return -EBADR; in media_request_object_bind()
409 spin_lock_irqsave(&req->lock, flags); in media_request_object_bind()
411 if (WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING && in media_request_object_bind()
412 req->state != MEDIA_REQUEST_STATE_QUEUED)) in media_request_object_bind()
415 obj->req = req; in media_request_object_bind()
416 obj->ops = ops; in media_request_object_bind()
417 obj->priv = priv; in media_request_object_bind()
420 list_add_tail(&obj->list, &req->objects); in media_request_object_bind()
422 list_add(&obj->list, &req->objects); in media_request_object_bind()
423 req->num_incomplete_objects++; in media_request_object_bind()
427 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_bind()
434 struct media_request *req = obj->req; in media_request_object_unbind()
441 spin_lock_irqsave(&req->lock, flags); in media_request_object_unbind()
442 list_del(&obj->list); in media_request_object_unbind()
443 obj->req = NULL; in media_request_object_unbind()
445 if (req->state == MEDIA_REQUEST_STATE_COMPLETE) in media_request_object_unbind()
448 if (WARN_ON(req->state == MEDIA_REQUEST_STATE_VALIDATING)) in media_request_object_unbind()
451 if (req->state == MEDIA_REQUEST_STATE_CLEANING) { in media_request_object_unbind()
452 if (!obj->completed) in media_request_object_unbind()
453 req->num_incomplete_objects--; in media_request_object_unbind()
457 if (WARN_ON(!req->num_incomplete_objects)) in media_request_object_unbind()
460 req->num_incomplete_objects--; in media_request_object_unbind()
461 if (req->state == MEDIA_REQUEST_STATE_QUEUED && in media_request_object_unbind()
462 !req->num_incomplete_objects) { in media_request_object_unbind()
463 req->state = MEDIA_REQUEST_STATE_COMPLETE; in media_request_object_unbind()
465 wake_up_interruptible_all(&req->poll_wait); in media_request_object_unbind()
469 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_unbind()
470 if (obj->ops->unbind) in media_request_object_unbind()
471 obj->ops->unbind(obj); in media_request_object_unbind()
479 struct media_request *req = obj->req; in media_request_object_complete()
483 spin_lock_irqsave(&req->lock, flags); in media_request_object_complete()
484 if (obj->completed) in media_request_object_complete()
486 obj->completed = true; in media_request_object_complete()
487 if (WARN_ON(!req->num_incomplete_objects) || in media_request_object_complete()
488 WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) in media_request_object_complete()
491 if (!--req->num_incomplete_objects) { in media_request_object_complete()
492 req->state = MEDIA_REQUEST_STATE_COMPLETE; in media_request_object_complete()
493 wake_up_interruptible_all(&req->poll_wait); in media_request_object_complete()
497 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_complete()