• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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