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()
252 if (!mdev || !mdev->ops || in media_request_get_by_fd()
253 !mdev->ops->req_validate || !mdev->ops->req_queue) in media_request_get_by_fd()
254 return ERR_PTR(-EBADR); in media_request_get_by_fd()
260 if (fd_file(f)->f_op != &request_fops) in media_request_get_by_fd()
262 req = fd_file(f)->private_data; in media_request_get_by_fd()
263 if (req->mdev != mdev) in media_request_get_by_fd()
283 dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd); in media_request_get_by_fd()
284 return ERR_PTR(-EINVAL); in media_request_get_by_fd()
295 /* Either both are NULL or both are non-NULL */ in media_request_alloc()
296 if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free)) in media_request_alloc()
297 return -ENOMEM; in media_request_alloc()
299 if (mdev->ops->req_alloc) in media_request_alloc()
300 req = mdev->ops->req_alloc(mdev); in media_request_alloc()
304 return -ENOMEM; in media_request_alloc()
318 filp->private_data = req; in media_request_alloc()
319 req->mdev = mdev; in media_request_alloc()
320 req->state = MEDIA_REQUEST_STATE_IDLE; in media_request_alloc()
321 req->num_incomplete_objects = 0; in media_request_alloc()
322 kref_init(&req->kref); in media_request_alloc()
323 INIT_LIST_HEAD(&req->objects); in media_request_alloc()
324 spin_lock_init(&req->lock); in media_request_alloc()
325 init_waitqueue_head(&req->poll_wait); in media_request_alloc()
326 req->updating_count = 0; in media_request_alloc()
327 req->access_count = 0; in media_request_alloc()
331 snprintf(req->debug_str, sizeof(req->debug_str), "%u:%d", in media_request_alloc()
332 atomic_inc_return(&mdev->request_id), fd); in media_request_alloc()
333 dev_dbg(mdev->dev, "request: allocated %s\n", req->debug_str); in media_request_alloc()
343 if (mdev->ops->req_free) in media_request_alloc()
344 mdev->ops->req_free(req); in media_request_alloc()
355 struct media_request *req = obj->req; in media_request_object_release()
359 obj->ops->release(obj); in media_request_object_release()
374 spin_lock_irqsave(&req->lock, flags); in media_request_object_find()
375 list_for_each_entry(obj, &req->objects, list) { in media_request_object_find()
376 if (obj->ops == ops && obj->priv == priv) { in media_request_object_find()
382 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_find()
389 kref_put(&obj->kref, media_request_object_release); in media_request_object_put()
395 obj->ops = NULL; in media_request_object_init()
396 obj->req = NULL; in media_request_object_init()
397 obj->priv = NULL; in media_request_object_init()
398 obj->completed = false; in media_request_object_init()
399 INIT_LIST_HEAD(&obj->list); in media_request_object_init()
400 kref_init(&obj->kref); in media_request_object_init()
410 int ret = -EBUSY; in media_request_object_bind()
412 if (WARN_ON(!ops->release)) in media_request_object_bind()
413 return -EBADR; in media_request_object_bind()
415 spin_lock_irqsave(&req->lock, flags); in media_request_object_bind()
417 if (WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING && in media_request_object_bind()
418 req->state != MEDIA_REQUEST_STATE_QUEUED)) in media_request_object_bind()
421 obj->req = req; in media_request_object_bind()
422 obj->ops = ops; in media_request_object_bind()
423 obj->priv = priv; in media_request_object_bind()
426 list_add_tail(&obj->list, &req->objects); in media_request_object_bind()
428 list_add(&obj->list, &req->objects); in media_request_object_bind()
429 req->num_incomplete_objects++; in media_request_object_bind()
433 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_bind()
440 struct media_request *req = obj->req; in media_request_object_unbind()
447 spin_lock_irqsave(&req->lock, flags); in media_request_object_unbind()
448 list_del(&obj->list); in media_request_object_unbind()
449 obj->req = NULL; in media_request_object_unbind()
451 if (req->state == MEDIA_REQUEST_STATE_COMPLETE) in media_request_object_unbind()
454 if (WARN_ON(req->state == MEDIA_REQUEST_STATE_VALIDATING)) in media_request_object_unbind()
457 if (req->state == MEDIA_REQUEST_STATE_CLEANING) { in media_request_object_unbind()
458 if (!obj->completed) in media_request_object_unbind()
459 req->num_incomplete_objects--; in media_request_object_unbind()
463 if (WARN_ON(!req->num_incomplete_objects)) in media_request_object_unbind()
466 req->num_incomplete_objects--; in media_request_object_unbind()
467 if (req->state == MEDIA_REQUEST_STATE_QUEUED && in media_request_object_unbind()
468 !req->num_incomplete_objects) { in media_request_object_unbind()
469 req->state = MEDIA_REQUEST_STATE_COMPLETE; in media_request_object_unbind()
471 wake_up_interruptible_all(&req->poll_wait); in media_request_object_unbind()
475 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_unbind()
476 if (obj->ops->unbind) in media_request_object_unbind()
477 obj->ops->unbind(obj); in media_request_object_unbind()
485 struct media_request *req = obj->req; in media_request_object_complete()
489 spin_lock_irqsave(&req->lock, flags); in media_request_object_complete()
490 if (obj->completed) in media_request_object_complete()
492 obj->completed = true; in media_request_object_complete()
493 if (WARN_ON(!req->num_incomplete_objects) || in media_request_object_complete()
494 WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) in media_request_object_complete()
497 if (!--req->num_incomplete_objects) { in media_request_object_complete()
498 req->state = MEDIA_REQUEST_STATE_COMPLETE; in media_request_object_complete()
499 wake_up_interruptible_all(&req->poll_wait); in media_request_object_complete()
503 spin_unlock_irqrestore(&req->lock, flags); in media_request_object_complete()