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