• 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 || msgQueue->entry.next->prev == NULL || msgQueue->entry.prev == NULL ||
221         msgQueue->entry.prev->next == NULL) {
222         ret = HDF_ERR_INVALID_OBJECT;
223         OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
224         goto ERROR;
225     }
226     reqEntry = DLIST_FIRST_ENTRY(&msgQueue->entry, struct UsbHostRequest, list);
227     if (reqEntry == NULL) {
228         ret = HDF_ERR_INVALID_OBJECT;
229         OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
230         goto ERROR;
231     }
232     if (reqEntry->list.prev == NULL || reqEntry->list.next == NULL) {
233         ret = HDF_ERR_INVALID_OBJECT;
234         HDF_LOGE("%{public}s:%d list node is invalid", __func__, __LINE__);
235         OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
236         goto ERROR;
237     }
238     DListRemove(&reqEntry->list);
239     *request = (struct UsbHostRequest *)reqEntry;
240     OsalMutexUnlock((struct OsalMutex *)&msgQueue->mutex);
241 
242     return HDF_SUCCESS;
243 
244 ERROR:
245     *request = NULL;
246     return ret;
247 }
248 
UsbIoStart(struct UsbInterfacePool * interfacePool)249 HDF_STATUS UsbIoStart(struct UsbInterfacePool *interfacePool)
250 {
251     HDF_STATUS ret;
252     struct OsalThreadParam threadCfg;
253 
254     if (interfacePool == NULL) {
255         HDF_LOGE("%{public}s:%d", __func__, __LINE__);
256         return HDF_ERR_INVALID_PARAM;
257     }
258 
259     OsalMutexLock(&interfacePool->ioStopLock);
260     interfacePool->ioProcessStopStatus = USB_POOL_PROCESS_RUNNING;
261     OsalMutexUnlock(&interfacePool->ioStopLock);
262 
263     /* create IoSendProcess thread */
264     ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
265     if (ret != EOK) {
266         HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
267         return ret;
268     }
269     threadCfg.name = "usb io send process";
270     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
271     threadCfg.stackSize = USB_IO_SEND_PROCESS_STACK_SIZE;
272 
273     ret = OsalThreadCreate(&interfacePool->ioSendProcess, (OsalThreadEntry)IoSendProcess, (void *)interfacePool);
274     if (ret != HDF_SUCCESS) {
275         HDF_LOGE("%{public}s:%d OsalThreadCreate failed, ret=%d ", __func__, __LINE__, ret);
276         return ret;
277     }
278 
279     ret = OsalThreadStart(&interfacePool->ioSendProcess, &threadCfg);
280     if (ret != HDF_SUCCESS) {
281         HDF_LOGE("%{public}s:%d OsalThreadStart failed, ret=%d ", __func__, __LINE__, ret);
282         goto ERR_DESTROY_SEND;
283     }
284 
285     /* create IoAsyncReceiveProcess thread */
286     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
287     threadCfg.name = "usb io async receive process";
288     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
289     threadCfg.stackSize = USB_IO_RECEIVE_PROCESS_STACK_SIZE;
290 
291     ret = OsalThreadCreate(
292         &interfacePool->ioAsyncReceiveProcess, (OsalThreadEntry)IoAsyncReceiveProcess, (void *)interfacePool);
293     if (ret != HDF_SUCCESS) {
294         HDF_LOGE("%{public}s:%d OsalThreadCreate failed, ret=%d ", __func__, __LINE__, ret);
295         goto ERR_DESTROY_SEND;
296     }
297 
298     ret = OsalThreadStart(&interfacePool->ioAsyncReceiveProcess, &threadCfg);
299     if (ret != HDF_SUCCESS) {
300         HDF_LOGE("%{public}s:%d OsalThreadStart failed, ret=%d ", __func__, __LINE__, ret);
301         goto ERR_DESTROY_RECV;
302     }
303 
304     return HDF_SUCCESS;
305 
306 ERR_DESTROY_SEND:
307     OsalThreadDestroy(&interfacePool->ioAsyncReceiveProcess);
308 ERR_DESTROY_RECV:
309     OsalThreadDestroy(&interfacePool->ioSendProcess);
310 
311     return ret;
312 }
313 
UsbIoStop(struct UsbInterfacePool * interfacePool)314 HDF_STATUS UsbIoStop(struct UsbInterfacePool *interfacePool)
315 {
316     HDF_STATUS ret;
317     int32_t i = 0;
318 
319     if ((interfacePool == NULL) || (interfacePool->device == NULL) || (interfacePool->device->devHandle == NULL)) {
320         HDF_LOGE("%{public}s:%d param is NULL", __func__, __LINE__);
321         return HDF_ERR_INVALID_PARAM;
322     }
323     if ((interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_STOPED)) {
324         OsalMutexLock(&interfacePool->ioStopLock);
325         interfacePool->ioProcessStopStatus = USB_POOL_PROCESS_STOP;
326         OsalSemPost(&interfacePool->submitRequestQueue.sem);
327         OsalMutexUnlock(&interfacePool->ioStopLock);
328 
329         if (RawKillSignal(interfacePool->device->devHandle, interfacePool->ioProcessTid) != HDF_SUCCESS) {
330             HDF_LOGE(
331                 "%{public}s:%d RawKillSignal ioProcessTid=%d failed", __func__, __LINE__, interfacePool->ioProcessTid);
332         }
333     }
334 
335     while (interfacePool->ioProcessStopStatus != USB_POOL_PROCESS_STOPED) {
336         i++;
337         OsalMSleep(USB_IO_SLEEP_MS_TIME);
338         if (i > USB_IO_STOP_WAIT_MAX_TIME) {
339             HDF_LOGD("%{public}s:%d", __func__, __LINE__);
340             break;
341         }
342     }
343 
344     ret = OsalThreadDestroy(&interfacePool->ioSendProcess);
345     if (ret != HDF_SUCCESS) {
346         HDF_LOGE("%{public}s:%d OsalThreadDestroy failed, ret=%d ", __func__, __LINE__, ret);
347         return ret;
348     }
349 
350     ret = OsalThreadDestroy(&interfacePool->ioAsyncReceiveProcess);
351     if (ret != HDF_SUCCESS) {
352         HDF_LOGE("%{public}s:%d OsalThreadDestroy failed, ret=%d ", __func__, __LINE__, ret);
353     }
354 
355     OsalMutexDestroy(&interfacePool->ioStopLock);
356 
357     return ret;
358 }
359 
UsbIoSetRequestCompletionInfo(const void * requestArg)360 void UsbIoSetRequestCompletionInfo(const void *requestArg)
361 {
362     if (requestArg == NULL) {
363         HDF_LOGE("%{public}s:%d parameter error. ", __func__, __LINE__);
364         return;
365     }
366 
367     struct UsbHostRequest *hostRequest = (struct UsbHostRequest *)requestArg;
368     struct UsbIfRequest *requestObj = (struct UsbIfRequest *)hostRequest->privateObj;
369     if (requestObj == NULL) {
370         HDF_LOGE("%{public}s:%d get request error. ", __func__, __LINE__);
371         return;
372     }
373     requestObj->request.compInfo.buffer = hostRequest->buffer;
374     requestObj->request.compInfo.length = hostRequest->length;
375     requestObj->request.compInfo.actualLength = (uint32_t)hostRequest->actualLength;
376     requestObj->request.compInfo.status = hostRequest->status;
377     requestObj->request.compInfo.userData = hostRequest->userData;
378     if ((hostRequest->requestType & USB_DDK_ENDPOINT_XFERTYPE_MASK) == USB_DDK_ENDPOINT_XFER_CONTROL) {
379         requestObj->request.compInfo.buffer = requestObj->request.compInfo.buffer + USB_RAW_CONTROL_SETUP_SIZE;
380     }
381 
382     /* Fill in the request completion information. */
383     /* Call user callback function. */
384     if (hostRequest->userCallback) {
385         hostRequest->userCallback(&requestObj->request);
386     }
387 
388     if (requestObj->isSyncReq) {
389         OsalSemPost(&hostRequest->sem);
390     }
391 }
392