1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "usb_io_manage.h"
17 #include "usb_raw_api_library.h"
18 #include "usbd_wrapper.h"
19
20 #define HDF_LOG_TAG USB_IO_MANAGE
21
IoCancelRequest(struct UsbInterfacePool * interfacePool,const struct UsbHostRequest * hostRequest)22 static bool IoCancelRequest(struct UsbInterfacePool *interfacePool, const struct UsbHostRequest *hostRequest)
23 {
24 struct UsbIfRequest *requestObj = NULL;
25
26 if (hostRequest == NULL) {
27 HDF_LOGE("%{public}s:%{public}d hostRequest is NULL", __func__, __LINE__);
28 return true;
29 }
30
31 requestObj = (struct UsbIfRequest *)hostRequest->privateObj;
32 if (requestObj == NULL) {
33 HDF_LOGE("%{public}s:%{public}d get request error", __func__, __LINE__);
34 return true;
35 }
36
37 if (interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_RUNNING) {
38 UsbCancelRequest(&requestObj->request);
39 }
40
41 return (requestObj->request.compInfo.status == USB_REQUEST_CANCELLED);
42 }
43
IoSendProcess(const void * interfacePoolArg)44 static int32_t IoSendProcess(const void *interfacePoolArg)
45 {
46 if (interfacePoolArg == NULL) {
47 HDF_LOGE("%{public}s: invalid param", __func__);
48 return HDF_ERR_INVALID_PARAM;
49 }
50
51 struct UsbInterfacePool *interfacePool = (struct UsbInterfacePool *)interfacePoolArg;
52 struct UsbHostRequest *submitRequest = NULL;
53 int32_t ret;
54 int32_t i;
55
56 while (true) {
57 submitRequest = NULL;
58 /* Get a request from curretn submit queue */
59 ret = UsbIoGetRequest(&interfacePool->submitRequestQueue, &submitRequest);
60
61 if (interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_RUNNING) {
62 if (submitRequest != NULL) {
63 submitRequest->status = USB_REQUEST_ERROR;
64 UsbIoSetRequestCompletionInfo(submitRequest);
65 }
66 break;
67 }
68
69 if (ret != HDF_SUCCESS) {
70 HDF_LOGE("%{public}s:%{public}d UsbIoGetRequest failed, ret=%{public}d ", __func__, __LINE__, ret);
71 continue;
72 }
73
74 if (submitRequest == NULL) {
75 continue;
76 }
77
78 if (IoCancelRequest(interfacePool, submitRequest)) {
79 continue;
80 }
81
82 for (i = 0; i < USB_IO_SUBMIT_RETRY_TIME_CNT; i++) {
83 ret = RawSubmitRequest(submitRequest);
84 if (ret != HDF_SUCCESS) {
85 continue;
86 }
87 /* Submit success */
88 OsalSemPost(&interfacePool->ioSem);
89 break;
90 }
91
92 if (i >= USB_IO_SUBMIT_RETRY_TIME_CNT) {
93 HDF_LOGE("%{public}s:%{public}d submit request failed", __func__, __LINE__);
94 submitRequest->status = USB_REQUEST_ERROR;
95 UsbIoSetRequestCompletionInfo(submitRequest);
96 continue;
97 }
98 }
99 HDF_LOGD("%{public}s, stop. ", __func__);
100 return 0;
101 }
102
InitializeIoProcess(struct UsbInterfacePool * interfacePool)103 static void InitializeIoProcess(struct UsbInterfacePool *interfacePool)
104 {
105 if (!interfacePool->ioProcessTid) {
106 interfacePool->ioProcessTid = RawGetTid();
107 }
108 }
109
IoAsyncReceiveProcess(const void * interfacePoolArg)110 static int32_t IoAsyncReceiveProcess(const void *interfacePoolArg)
111 {
112 if (interfacePoolArg == NULL) {
113 HDF_LOGE("%{public}s: invalid param", __func__);
114 return HDF_ERR_INVALID_PARAM;
115 }
116
117 struct UsbInterfacePool *interfacePool = (struct UsbInterfacePool *)interfacePoolArg;
118 if (RawRegisterSignal() != HDF_SUCCESS) {
119 HDF_LOGE("%{public}s:%{public}d RawRegisterSignal error", __func__, __LINE__);
120 }
121
122 HDF_LOGD("%{public}s, enter recv thread", __func__);
123 while (true) {
124 InitializeIoProcess(interfacePool);
125 if (interfacePool->device == NULL) {
126 HDF_LOGE("%{public}s:%{public}d interfacePool->device is NULL!", __func__, __LINE__);
127 OsalMSleep(USB_IO_SLEEP_MS_TIME);
128 continue;
129 }
130
131 if (interfacePool->device->devHandle == NULL) {
132 HDF_LOGE("%{public}s:%{public}d interfacePool->device->devHandle is NULL!", __func__, __LINE__);
133 OsalMSleep(USB_IO_SLEEP_MS_TIME);
134 continue;
135 }
136
137 int32_t ret = OsalSemWait(&interfacePool->ioSem, HDF_WAIT_FOREVER);
138 if (ret != HDF_SUCCESS) {
139 HDF_LOGE("sem wait failed: %{public}d", ret);
140 }
141
142 if (interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_RUNNING ||
143 interfacePool->ioRecvProcessStopStatus != USB_POOL_PROCESS_RUNNING) {
144 break;
145 }
146
147 ret = RawHandleRequest(interfacePool->device->devHandle);
148 if (ret == HDF_DEV_ERR_NO_DEVICE) {
149 HDF_LOGE("%{public}s dev is not found ret: %{public}d", __func__, ret);
150 break;
151 }
152
153 if (ret < 0) {
154 HDF_LOGE("%{public}s RawHandleRequest failed ret: %{public}d", __func__, ret);
155 OsalMSleep(USB_IO_SLEEP_MS_TIME);
156 continue;
157 }
158 }
159 HDF_LOGD("%{public}s, recv thread end. ", __func__);
160 OsalMutexLock(&interfacePool->ioStopLock);
161 interfacePool->ioProcessStopStatus = USB_POOL_PROCESS_STOPED;
162 interfacePool->ioRecvProcessStopStatus = USB_POOL_PROCESS_STOPED;
163 OsalSemPost(&interfacePool->submitRequestQueue.sem);
164 OsalMutexUnlock(&interfacePool->ioStopLock);
165
166 return HDF_SUCCESS;
167 }
168
UsbIoCreateQueue(const struct UsbInterfacePool * interfacePool)169 HDF_STATUS UsbIoCreateQueue(const struct UsbInterfacePool *interfacePool)
170 {
171 if (interfacePool == NULL) {
172 HDF_LOGE("%{public}s: invalid param", __func__);
173 return HDF_ERR_INVALID_PARAM;
174 }
175
176 DListHeadInit((struct DListHead *)&interfacePool->submitRequestQueue.entry);
177 OsalMutexInit((struct OsalMutex *)&interfacePool->submitRequestQueue.mutex);
178 OsalSemInit((struct OsalSem *)&interfacePool->submitRequestQueue.sem, 0);
179
180 return HDF_SUCCESS;
181 }
182
UsbIoDestroyQueue(const struct UsbInterfacePool * interfacePool)183 HDF_STATUS UsbIoDestroyQueue(const struct UsbInterfacePool *interfacePool)
184 {
185 if (interfacePool == NULL) {
186 HDF_LOGE("%{public}s: invalid param", __func__);
187 return HDF_ERR_INVALID_PARAM;
188 }
189
190 if (!DListIsEmpty(&interfacePool->submitRequestQueue.entry)) {
191 HDF_LOGE("%{public}s:%{public}d submitRequestQueue is not empty", __func__, __LINE__);
192 return HDF_FAILURE;
193 }
194
195 OsalMutexDestroy((struct OsalMutex *)&interfacePool->submitRequestQueue.mutex);
196 OsalSemDestroy((struct OsalSem *)&interfacePool->submitRequestQueue.sem);
197
198 return HDF_SUCCESS;
199 }
200
UsbIoSendRequest(const struct UsbMessageQueue * msgQueue,const struct UsbHostRequest * request)201 int32_t UsbIoSendRequest(const struct UsbMessageQueue *msgQueue, const struct UsbHostRequest *request)
202 {
203 if ((msgQueue == NULL) || (request == NULL)) {
204 HDF_LOGE("%{public}s:%{public}d invalid parameter", __func__, __LINE__);
205 return HDF_ERR_INVALID_PARAM;
206 }
207
208 OsalMutexLock((struct OsalMutex *)&msgQueue->mutex);
209 DListInsertTail((struct DListHead *)&request->list, (struct DListHead *)&msgQueue->entry);
210 OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
211
212 OsalSemPost((struct OsalSem *)&msgQueue->sem);
213
214 return HDF_SUCCESS;
215 }
216
UsbIoGetRequest(const struct UsbMessageQueue * msgQueue,struct UsbHostRequest ** request)217 HDF_STATUS UsbIoGetRequest(const struct UsbMessageQueue *msgQueue, struct UsbHostRequest **request)
218 {
219 HDF_STATUS ret;
220 struct UsbHostRequest *reqEntry = NULL;
221
222 if ((msgQueue == NULL) || (request == NULL)) {
223 ret = HDF_ERR_INVALID_OBJECT;
224 HDF_LOGE("%{public}s:%{public}d invalid parameter", __func__, __LINE__);
225 return ret;
226 }
227
228 ret = OsalSemWait((struct OsalSem *)&msgQueue->sem, HDF_WAIT_FOREVER);
229 if (ret != HDF_SUCCESS) {
230 HDF_LOGE("%{public}s:%{public}d OsalSemWait failed, ret=%{public}d", __func__, __LINE__, ret);
231 goto ERROR;
232 }
233 if (DListIsEmpty(&msgQueue->entry)) {
234 ret = HDF_SUCCESS;
235 goto ERROR;
236 }
237
238 OsalMutexLock((struct OsalMutex *)&msgQueue->mutex);
239 if (msgQueue->entry.next == NULL || msgQueue->entry.next->prev == NULL ||
240 msgQueue->entry.prev == NULL || msgQueue->entry.prev->next == NULL) {
241 ret = HDF_ERR_INVALID_OBJECT;
242 OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
243 goto ERROR;
244 }
245 reqEntry = DLIST_FIRST_ENTRY(&msgQueue->entry, struct UsbHostRequest, list);
246 if (reqEntry == NULL || reqEntry->list.prev == NULL || reqEntry->list.next == NULL ||
247 reqEntry->list.prev->next != &reqEntry->list || reqEntry->list.next->prev != &reqEntry->list) {
248 ret = HDF_ERR_INVALID_OBJECT;
249 HDF_LOGE("%{public}s:%{public}d list node is invalid", __func__, __LINE__);
250 OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
251 goto ERROR;
252 }
253 DListRemove(&reqEntry->list);
254 *request = (struct UsbHostRequest *)reqEntry;
255 OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
256
257 return HDF_SUCCESS;
258
259 ERROR:
260 *request = NULL;
261 return ret;
262 }
263
UsbIoStart(struct UsbInterfacePool * interfacePool)264 HDF_STATUS UsbIoStart(struct UsbInterfacePool *interfacePool)
265 {
266 struct OsalThreadParam threadCfg;
267 if (interfacePool == NULL) {
268 HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
269 return HDF_ERR_INVALID_PARAM;
270 }
271
272 OsalMutexLock(&interfacePool->ioStopLock);
273 interfacePool->ioProcessStopStatus = USB_POOL_PROCESS_RUNNING;
274 interfacePool->ioRecvProcessStopStatus = USB_POOL_PROCESS_RUNNING;
275 OsalSemInit(&interfacePool->ioSem, 0);
276 OsalMutexUnlock(&interfacePool->ioStopLock);
277
278 /* create IoSendProcess thread */
279 HDF_STATUS ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
280 if (ret != EOK) {
281 HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
282 return ret;
283 }
284 threadCfg.name = "usb io send process";
285 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
286 threadCfg.stackSize = USB_IO_SEND_PROCESS_STACK_SIZE;
287
288 ret = OsalThreadCreate(&interfacePool->ioSendProcess, (OsalThreadEntry)IoSendProcess, (void *)interfacePool);
289 if (ret != HDF_SUCCESS) {
290 HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
291 return ret;
292 }
293
294 ret = OsalThreadStart(&interfacePool->ioSendProcess, &threadCfg);
295 if (ret != HDF_SUCCESS) {
296 HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
297 goto ERR_DESTROY_SEND;
298 }
299
300 /* create IoAsyncReceiveProcess thread */
301 (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
302 threadCfg.name = "usb io async receive process";
303 threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
304 threadCfg.stackSize = USB_IO_RECEIVE_PROCESS_STACK_SIZE;
305
306 ret = OsalThreadCreate(&interfacePool->ioAsyncReceiveProcess, (void *)IoAsyncReceiveProcess, (void *)interfacePool);
307 if (ret != HDF_SUCCESS) {
308 HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret=%{public}d ", __func__, __LINE__, ret);
309 goto ERR_DESTROY_SEND;
310 }
311
312 ret = OsalThreadStart(&interfacePool->ioAsyncReceiveProcess, &threadCfg);
313 if (ret != HDF_SUCCESS) {
314 HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret=%{public}d ", __func__, __LINE__, ret);
315 goto ERR_DESTROY_RECV;
316 }
317
318 return HDF_SUCCESS;
319
320 ERR_DESTROY_SEND:
321 OsalThreadDestroy(&interfacePool->ioAsyncReceiveProcess);
322 ERR_DESTROY_RECV:
323 OsalThreadDestroy(&interfacePool->ioSendProcess);
324
325 return ret;
326 }
327
UsbIoRecvProcessStop(struct UsbInterfacePool * interfacePool)328 HDF_STATUS UsbIoRecvProcessStop(struct UsbInterfacePool *interfacePool)
329 {
330 if ((interfacePool == NULL) || (interfacePool->device == NULL) || (interfacePool->device->devHandle == NULL)) {
331 HDF_LOGE("%{public}s:%{public}d param is NULL", __func__, __LINE__);
332 return HDF_ERR_INVALID_PARAM;
333 }
334 if ((interfacePool->ioRecvProcessStopStatus != USB_POOL_PROCESS_STOPED)) {
335 OsalMutexLock(&interfacePool->ioStopLock);
336 interfacePool->ioRecvProcessStopStatus = USB_POOL_PROCESS_STOP;
337 OsalSemPost(&interfacePool->submitRequestQueue.sem);
338 OsalMutexUnlock(&interfacePool->ioStopLock);
339 }
340 return HDF_SUCCESS;
341 }
342
UsbIoStop(struct UsbInterfacePool * interfacePool)343 HDF_STATUS UsbIoStop(struct UsbInterfacePool *interfacePool)
344 {
345 if ((interfacePool == NULL) || (interfacePool->device == NULL) || (interfacePool->device->devHandle == NULL)) {
346 HDF_LOGE("%{public}s:%{public}d param is NULL", __func__, __LINE__);
347 return HDF_ERR_INVALID_PARAM;
348 }
349 if ((interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_STOPED)) {
350 OsalMutexLock(&interfacePool->ioStopLock);
351 interfacePool->ioProcessStopStatus = USB_POOL_PROCESS_STOP;
352 OsalSemPost(&interfacePool->ioSem);
353 OsalSemPost(&interfacePool->submitRequestQueue.sem);
354 OsalMutexUnlock(&interfacePool->ioStopLock);
355
356 if (RawKillSignal(interfacePool->device->devHandle, interfacePool->ioProcessTid) != HDF_SUCCESS) {
357 HDF_LOGE(
358 "%{public}s:%{public}d RawKillSignal ioProcessTid=%{public}d failed",
359 __func__, __LINE__, interfacePool->ioProcessTid);
360 }
361 }
362 int32_t i = 0;
363 while (interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_STOPED) {
364 i++;
365 OsalMSleep(USB_IO_SLEEP_MS_TIME);
366 if (i > USB_IO_STOP_WAIT_MAX_TIME) {
367 HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__);
368 break;
369 }
370 }
371
372 HDF_STATUS ret = OsalThreadDestroy(&interfacePool->ioSendProcess);
373 if (ret != HDF_SUCCESS) {
374 HDF_LOGE("%{public}s:%{public}d OsalThreadDestroy failed, ret=%{public}d ", __func__, __LINE__, ret);
375 return ret;
376 }
377 ret = OsalThreadDestroy(&interfacePool->ioAsyncReceiveProcess);
378 if (ret != HDF_SUCCESS) {
379 HDF_LOGE("%{public}s:%{public}d OsalThreadDestroy failed, ret=%{public}d ", __func__, __LINE__, ret);
380 } else {
381 OsalSemDestroy(&interfacePool->ioSem);
382 }
383 return ret;
384 }
385
UsbIoSetRequestCompletionInfo(const void * requestArg)386 void UsbIoSetRequestCompletionInfo(const void *requestArg)
387 {
388 if (requestArg == NULL) {
389 HDF_LOGE("%{public}s:%{public}d parameter error. ", __func__, __LINE__);
390 return;
391 }
392
393 struct UsbHostRequest *hostRequest = (struct UsbHostRequest *)requestArg;
394 struct UsbIfRequest *requestObj = (struct UsbIfRequest *)hostRequest->privateObj;
395 if (requestObj == NULL) {
396 HDF_LOGE("%{public}s:%{public}d get request error. ", __func__, __LINE__);
397 return;
398 }
399 requestObj->request.compInfo.buffer = hostRequest->buffer;
400 requestObj->request.compInfo.length = hostRequest->length;
401 requestObj->request.compInfo.actualLength = (uint32_t)hostRequest->actualLength;
402 requestObj->request.compInfo.status = hostRequest->status;
403 requestObj->request.compInfo.userData = hostRequest->userData;
404 if ((hostRequest->requestType & USB_DDK_ENDPOINT_XFERTYPE_MASK) == USB_DDK_ENDPOINT_XFER_CONTROL) {
405 requestObj->request.compInfo.buffer = requestObj->request.compInfo.buffer + USB_RAW_CONTROL_SETUP_SIZE;
406 }
407
408 /* Fill in the request completion information. */
409 /* Call user callback function. */
410 if (hostRequest->userCallback) {
411 hostRequest->userCallback(&requestObj->request);
412 }
413
414 if (requestObj->isSyncReq) {
415 OsalSemPost(&hostRequest->sem);
416 }
417 }
418