1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include <securec.h>
10 #include <hdf_log.h>
11 #include <osal_mem.h>
12 #include "osal_uaccess.h"
13 #include "buffer_queue.h"
14 #include "camera_buffer_manager.h"
15 
16 #define HDF_LOG_TAG HDF_CAMERA_BUFFER_MANAGER
17 struct BufferQueue *g_queueForMmap = NULL;
18 
CameraBufferDone(struct CameraBuffer * buffer,enum BufferState state)19 void CameraBufferDone(struct CameraBuffer *buffer, enum BufferState state)
20 {
21     struct BufferQueue *queue = buffer->bufferQueue;
22     uint32_t flags;
23 
24     if (buffer->state != BUFFER_STATE_ACTIVE) {
25         return;
26     }
27 
28     if (state != BUFFER_STATE_DONE && state != BUFFER_STATE_ERROR && state != BUFFER_STATE_QUEUED) {
29         state = BUFFER_STATE_ERROR;
30     }
31     HDF_LOGI("%s: Done processing on buffer %{public}u!", __func__, buffer->id);
32 
33     if (state != BUFFER_STATE_QUEUED) {
34         CameraBufferSyncForUser(buffer);
35     }
36     OsalSpinLockIrqSave(&queue->doneLock, &flags);
37     buffer->state = state;
38     if (state != BUFFER_STATE_QUEUED) {
39         DListInsertTail(&buffer->doneEntry, &queue->doneList);
40     }
41 
42     OsalAtomicDec(&queue->driverOwnCount);
43     OsalSpinUnlockIrqRestore(&queue->doneLock, &flags);
44     if (state != BUFFER_STATE_QUEUED) {
45         wake_up(&queue->doneWait);
46     }
47 }
48 
BufferQueueFindPlaneByOffset(struct BufferQueue * queue,unsigned long off,uint32_t * bufferId,uint32_t * planeId)49 int32_t BufferQueueFindPlaneByOffset(struct BufferQueue *queue,
50     unsigned long off, uint32_t *bufferId, uint32_t *planeId)
51 {
52     struct CameraBuffer *buffer = NULL;
53     uint32_t bufferCnt;
54     uint32_t planeCnt;
55 
56     if (queue == NULL || bufferId == NULL || planeId == NULL) {
57         return HDF_ERR_INVALID_PARAM;
58     }
59 
60     for (bufferCnt = 0; bufferCnt < queue->numBuffers; ++bufferCnt) {
61         buffer = queue->buffers[bufferCnt];
62         for (planeCnt = 0; planeCnt < buffer->numPlanes; ++planeCnt) {
63             if (buffer->planes[planeCnt].memory.offset == off) {
64                 *bufferId = bufferCnt;
65                 *planeId = planeCnt;
66                 return HDF_SUCCESS;
67             }
68         }
69     }
70 
71     return HDF_FAILURE;
72 }
73 
CameraBufferGetPlaneVaddr(struct CameraBuffer * buffer,uint32_t planeId)74 void *CameraBufferGetPlaneVaddr(struct CameraBuffer *buffer, uint32_t planeId)
75 {
76     struct BufferQueue *queue = buffer->bufferQueue;
77     if (planeId >= buffer->numPlanes || buffer->planes[planeId].memPriv == NULL) {
78         return NULL;
79     }
80 
81     if (queue->memOps->getVaddr != NULL) {
82         return queue->memOps->getVaddr(buffer->planes[planeId].memPriv);
83     }
84 
85     return NULL;
86 }
87 
88 /* init queue */
BufferQueueInit(struct BufferQueue * queue)89 int32_t BufferQueueInit(struct BufferQueue *queue)
90 {
91     if (queue == NULL) {
92         HDF_LOGE("%s: queue ptr is null", __func__);
93         return HDF_ERR_INVALID_PARAM;
94     }
95 
96     if (queue->queueIsInit == true) {
97         return HDF_SUCCESS;
98     }
99 
100     if (queue->queueOps == NULL || queue->memOps == NULL || queue->ioModes == 0) {
101         HDF_LOGE("%s: queueOps/memOps is null or ioModes is 0", __func__);
102         return HDF_FAILURE;
103     }
104 
105     if (queue->queueOps->queueSetup == NULL || queue->queueOps->queueBuffer == NULL) {
106         HDF_LOGE("%s: queueSetup or queueBuffer is null", __func__);
107         return HDF_FAILURE;
108     }
109 
110     if (queue->bufferSize == 0) {
111         queue->bufferSize = sizeof(struct CameraBuffer);
112     }
113     queue->memType = MEMTYPE_UNKNOWN;
114     DListHeadInit(&queue->queuedList);
115     DListHeadInit(&queue->doneList);
116     OsalSpinInit(&queue->doneLock);
117     OsalMutexInit(&queue->mmapLock);
118     init_waitqueue_head(&queue->doneWait);
119     MemoryAdapterQueueImpInit(queue);
120     queue->queueIsInit = true;
121 
122     return HDF_SUCCESS;
123 }
124 
125 /* request buffers */
BufferQueueRequest(struct BufferQueue * queue,struct UserCameraReq * userRequest)126 int32_t BufferQueueRequest(struct BufferQueue *queue, struct UserCameraReq *userRequest)
127 {
128     uint32_t numBuffers;
129     uint32_t numPlanes = 0;
130     uint32_t planeSizes[MAX_PLANES] = { 0 };
131     uint32_t i;
132     int32_t ret;
133 
134     ret = BufferQueueCheckMemOps(queue, userRequest->memType);
135     if (ret != HDF_SUCCESS) {
136         HDF_LOGE("%s: BufferQueueCheckMemOps failed, ret = %{public}d", __func__, ret);
137         return HDF_FAILURE;
138     }
139     if (BufferQueueReleaseBuffers(queue, userRequest) != HDF_SUCCESS) {
140         return HDF_FAILURE;
141     }
142     if (userRequest->count == 0) {
143         return HDF_SUCCESS;
144     }
145     if (queue->minBuffersNeeded > MAX_FRAME) {
146         HDF_LOGW("%s: Buffer needed is too many", __func__);
147     }
148 
149     numBuffers = userRequest->count > queue->minBuffersNeeded ? userRequest->count : queue->minBuffersNeeded;
150     numBuffers = numBuffers > MAX_FRAME ? MAX_FRAME : numBuffers;
151     queue->memType = userRequest->memType;
152     ret = queue->queueOps->queueSetup != NULL ? queue->queueOps->queueSetup(queue, &numBuffers,
153         &numPlanes, planeSizes) : HDF_SUCCESS;
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s: queue setup failed", __func__);
156         return ret;
157     }
158     if (numPlanes == 0) {
159         HDF_LOGE("%s: numPlanes cannot be zero", __func__);
160         return HDF_FAILURE;
161     }
162     for (i = 0; i < numPlanes; ++i) {
163         if (planeSizes[i] == 0) {
164             return HDF_FAILURE;
165         }
166     }
167 
168     ret = BufferQueueRequestBuffers(queue, userRequest, numBuffers, numPlanes, planeSizes);
169     if (ret != HDF_SUCCESS) {
170         return ret;
171     }
172 
173     return HDF_SUCCESS;
174 }
175 
176 /* query buffer */
BufferQueueQueryBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)177 int32_t BufferQueueQueryBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
178 {
179     struct CameraBuffer *buffer = NULL;
180     int32_t ret;
181 
182     if (userBuffer->id >= queue->numBuffers) {
183         HDF_LOGE("%s: user buffer id cannot >= queue numBuffers", __func__);
184         return HDF_FAILURE;
185     }
186 
187     buffer = queue->buffers[userBuffer->id];
188     ret = CameraBufferCheckPlanes(buffer, userBuffer);
189     if (ret == HDF_SUCCESS) {
190         CameraBufferToUserBuffer(buffer, userBuffer);
191     }
192 
193     return ret;
194 }
195 
196 /* return buffer */
BufferQueueReturnBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)197 int32_t BufferQueueReturnBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
198 {
199     if (userBuffer == NULL) {
200         return HDF_ERR_INVALID_PARAM;
201     }
202     struct CameraBuffer *buffer = NULL;
203     int32_t ret;
204     ret = BufferQueuePrepare(queue, userBuffer);
205     if (ret != HDF_SUCCESS) {
206         return ret;
207     }
208     if ((queue->flags & QUEUE_STATE_ERROR) != 0) {
209         HDF_LOGE("%s: fatal error occurred on queue", __func__);
210         return HDF_FAILURE;
211     }
212     buffer = queue->buffers[userBuffer->id];
213     if (buffer->state != BUFFER_STATE_DEQUEUED) {
214         HDF_LOGE("%s: invalid buffer state", __func__);
215         return HDF_FAILURE;
216     }
217     if ((buffer->flags & BUFFER_PREPARED) == 0) {
218         ret = CameraBufferFromUserBuffer(buffer, userBuffer);
219         if (ret != HDF_SUCCESS) {
220             HDF_LOGE("%s: Buffer prepare failed", __func__);
221             return ret;
222         }
223     }
224     CameraBufferQueueBuffer(buffer);
225     CameraBufferToUserBuffer(buffer, userBuffer);
226 
227     if ((queue->flags & QUEUE_STATE_STREAMING) != 0 && (queue->flags & QUEUE_STATE_STREAMING_CALLED) == 0 &&
228         (queue->queuedCount >= queue->minBuffersNeeded)) {
229         ret = BufferQueueStart(queue);
230         if (ret != HDF_SUCCESS) {
231             HDF_LOGE("%s: BufferQueueStart failed", __func__);
232             return ret;
233         }
234     }
235     return HDF_SUCCESS;
236 }
237 
WaitForDoneBuffer(struct BufferQueue * queue,uint32_t blocking)238 static int32_t WaitForDoneBuffer(struct BufferQueue *queue, uint32_t blocking)
239 {
240     while (true) {
241         if ((queue->flags & QUEUE_STATE_WAITING_DEQUEUE) != 0 || (queue->flags & QUEUE_STATE_STREAMING) == 0 ||
242             (queue->flags & QUEUE_STATE_ERROR) != 0 || (queue->flags & QUEUE_STATE_LAST_BUFFER_DEQUEUED) != 0) {
243             return HDF_FAILURE;
244         }
245 
246         if (!DListIsEmpty(&queue->doneList)) {
247             break;
248         }
249 
250         if (blocking == 0) {
251             return HDF_FAILURE;
252         }
253         queue->flags |= QUEUE_STATE_WAITING_DEQUEUE;
254 
255         MemoryAdapterDriverMutexLock(queue);
256         int32_t ret = wait_event_interruptible(queue->doneWait, !DListIsEmpty(&queue->doneList) ||
257             (queue->flags & QUEUE_STATE_STREAMING) == 0 || (queue->flags & QUEUE_STATE_ERROR) != 0);
258         MemoryAdapterDriverMutexUnLock(queue);
259 
260         queue->flags &= ~QUEUE_STATE_WAITING_DEQUEUE;
261         if (ret != 0) {
262             HDF_LOGE("%s: wait function failed", __func__);
263             return HDF_FAILURE;
264         }
265     }
266 
267     return HDF_SUCCESS;
268 }
269 
GetDoneBuffer(struct BufferQueue * queue,struct CameraBuffer ** buffer,struct UserCameraBuffer * userBuffer)270 static int32_t GetDoneBuffer(struct BufferQueue *queue,
271     struct CameraBuffer **buffer, struct UserCameraBuffer *userBuffer)
272 {
273     uint32_t flags;
274     int32_t ret;
275 
276     ret = WaitForDoneBuffer(queue, userBuffer->flags & USER_BUFFER_BLOCKING);
277     if (ret == HDF_FAILURE) {
278         return ret;
279     }
280     OsalSpinLockIrqSave(&queue->doneLock, &flags);
281     *buffer = DLIST_FIRST_ENTRY(&queue->doneList, struct CameraBuffer, doneEntry);
282     ret = CameraBufferCheckPlanes(*buffer, userBuffer);
283     if (ret == HDF_SUCCESS) {
284         DListRemove(&(*buffer)->doneEntry);
285     }
286     OsalSpinUnlockIrqRestore(&queue->doneLock, &flags);
287 
288     return ret;
289 }
290 
291 /* acquire buffer */
BufferQueueAcquireBuffer(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)292 int32_t BufferQueueAcquireBuffer(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
293 {
294     struct CameraBuffer *buffer = NULL;
295     int32_t ret;
296 
297     if (userBuffer == NULL) {
298         return HDF_FAILURE;
299     }
300     ret = GetDoneBuffer(queue, &buffer, userBuffer);
301     if (ret != HDF_SUCCESS) {
302         HDF_LOGE("%s: get buffer from doneList failed", __func__);
303         return ret;
304     }
305     switch (buffer->state) {
306         case BUFFER_STATE_DONE:
307             HDF_LOGE("%s: return done buffer", __func__);
308             break;
309         case BUFFER_STATE_ERROR:
310             HDF_LOGE("%s: return done buffer with error", __func__);
311             break;
312         default:
313             HDF_LOGE("%s: invalid buffer state", __func__);
314             return HDF_FAILURE;
315     }
316     buffer->flags &= ~BUFFER_PREPARED;
317 
318     CameraBufferToUserBuffer(buffer, userBuffer);
319     DListRemove(&buffer->queueEntry);
320     queue->queuedCount--;
321     buffer->state = BUFFER_STATE_DEQUEUED;
322     userBuffer->flags |= USER_BUFFER_DONE;
323 
324     return ret;
325 }
326 
327 /* stream on */
BufferQueueStreamOn(struct BufferQueue * queue)328 int32_t BufferQueueStreamOn(struct BufferQueue *queue)
329 {
330     if ((queue->flags & QUEUE_STATE_STREAMING) != 0 || (queue->numBuffers) == 0 ||
331         (queue->numBuffers < queue->minBuffersNeeded)) {
332         return HDF_FAILURE;
333     }
334 
335     if (queue->queuedCount >= queue->minBuffersNeeded) {
336         int32_t ret = BufferQueueStart(queue);
337         if (ret != HDF_SUCCESS) {
338             HDF_LOGE("%s: BufferQueueStart failed", __func__);
339             return ret;
340         }
341     }
342     queue->flags |= QUEUE_STATE_STREAMING;
343     return HDF_SUCCESS;
344 }
345 
346 /* stream off */
BufferQueueStreamOff(struct BufferQueue * queue)347 int32_t BufferQueueStreamOff(struct BufferQueue *queue)
348 {
349     BufferQueueStop(queue);
350 
351     queue->flags |= QUEUE_STATE_WAITING_BUFFERS;
352     queue->flags &= ~QUEUE_STATE_LAST_BUFFER_DEQUEUED;
353     HDF_LOGD("%s: stream off success", __func__);
354 
355     return HDF_SUCCESS;
356 }
357 
BufferQueueSetQueueForMmap(struct BufferQueue * queue)358 void BufferQueueSetQueueForMmap(struct BufferQueue *queue)
359 {
360     g_queueForMmap = queue;
361 }
362 
BufferQueueGetQueueForMmap(void)363 struct BufferQueue *BufferQueueGetQueueForMmap(void)
364 {
365     return g_queueForMmap;
366 }
367