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