• 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 "usbhost_sdkraw_speed.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <dirent.h>
23 #include <sys/ioctl.h>
24 #include <sys/mman.h>
25 #include <fcntl.h>
26 #include <stdlib.h>
27 #include <sys/time.h>
28 #include <signal.h>
29 #include <sys/mman.h>
30 #include <osal_thread.h>
31 #include "hdf_base.h"
32 #include "hdf_log.h"
33 #include "hdf_usb_pnp_manage.h"
34 #include "implementation/global_implementation.h"
35 #include "osal_mem.h"
36 #include "osal_time.h"
37 #include "securec.h"
38 #include "signal.h"
39 #include "usb_ddk_interface.h"
40 #include "usb_pnp_notify.h"
41 
42 #define HDF_LOG_TAG                USB_HOST_ACM_RAW_API
43 
44 #define USB_CTRL_REQ_SIZE          64
45 #define USB_IO_THREAD_STACK_SIZE   8192
46 #define USB_RAW_IO_SLEEP_MS_TIME        500
47 #define USB_RAW_IO_STOP_WAIT_MAX_TIME   2
48 #define USB_DEVICE_VENDOR_ID 0x12D1
49 #define USB_DEVICE_PRODUCT_ID 0x5000
50 
51 static struct AcmDevice *g_acm = NULL;
52 static bool g_stopIoThreadFlag = false;
53 static unsigned int g_speedFlag = 0;
54 static uint64_t g_send_count = 0;
55 static uint64_t g_recv_count = 0;
56 static uint64_t g_byteTotal = 0;
57 static bool g_writeOrRead = TEST_WRITE;
58 static bool g_printData = false;
59 static struct OsalSem sem;
60 static struct OsalSem timeSem;
61 static uint32_t sigCnt = 0;
62 static void AcmTestBulkCallback(const void *requestArg);
63 static int32_t SerialBegin(struct AcmDevice *acm);
64 
UsbIoThread(void * data)65 static int32_t UsbIoThread(void *data)
66 {
67     int32_t ret;
68     struct AcmDevice *acm = (struct AcmDevice *)data;
69 
70     while (true) {
71         if (acm == NULL) {
72             printf("%s:%d acm is NULL", __func__, __LINE__);
73             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
74             continue;
75         }
76 
77         if (acm->devHandle == NULL) {
78             printf("%s:%d acm->devHandle is NULL!", __func__, __LINE__);
79             OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
80             continue;
81         }
82 
83         ret = UsbRawHandleRequests(acm->devHandle);
84         if (ret < 0) {
85             printf("%s:%d UsbRawHandleRequests failed, ret=%d ", \
86                 __func__, __LINE__, ret);
87             if (ret == USB_REQUEST_NO_DEVICE) {
88                 printf("%s:%d, ret=%d", __func__, __LINE__, ret);
89                 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
90             }
91         }
92 
93         if (g_stopIoThreadFlag == true) {
94             HDF_LOGD("%s:%d", __func__, __LINE__);
95             g_stopIoThreadFlag = false;
96             break;
97         }
98     }
99 
100     HDF_LOGE("%s:%d exit", __func__, __LINE__);
101 
102     return HDF_SUCCESS;
103 }
104 
UsbIoSendThread(void * data)105 static int32_t UsbIoSendThread(void *data)
106 {
107     struct AcmDevice *acm = (struct AcmDevice *)data;
108 
109     while (!g_stopIoThreadFlag) {
110         OsalSemWait(&sem, HDF_WAIT_FOREVER);
111         if (!g_speedFlag) {
112             if (SerialBegin(acm) != HDF_SUCCESS) {
113                 HDF_LOGW("%s:%d SerialBegin error!", __func__, __LINE__);
114             }
115             g_send_count++;
116         }
117     }
118     return 0;
119 }
120 
UsbStartIo(struct AcmDevice * acm)121 static int32_t UsbStartIo(struct AcmDevice *acm)
122 {
123     struct OsalThreadParam threadCfg;
124     int32_t ret;
125 
126     HDF_LOGI("%s start", __func__);
127     g_stopIoThreadFlag = false;
128 
129     /* creat Io thread */
130     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
131     threadCfg.name      = "usb io thread";
132     threadCfg.priority  = OSAL_THREAD_PRI_DEFAULT;
133     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
134 
135     ret = OsalThreadCreate(&acm->ioThread, (OsalThreadEntry)UsbIoThread, (void *)acm);
136     if (ret != HDF_SUCCESS) {
137         HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ",
138                  __func__, __LINE__, ret);
139         return ret;
140     }
141 
142     ret = OsalThreadStart(&acm->ioThread, &threadCfg);
143     if (ret != HDF_SUCCESS) {
144         HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ",
145                  __func__, __LINE__, ret);
146         return ret;
147     }
148 
149     (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
150     threadCfg.name      = "usb io send thread";
151     threadCfg.priority  = OSAL_THREAD_PRI_DEFAULT;
152     threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
153     ret = OsalThreadCreate(&acm->ioSendThread, (OsalThreadEntry)UsbIoSendThread, (void *)acm);
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ",
156             __func__, __LINE__, ret);
157         return ret;
158     }
159 
160     ret = OsalThreadStart(&acm->ioSendThread, &threadCfg);
161     if (ret != HDF_SUCCESS) {
162         HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ",
163             __func__, __LINE__, ret);
164         return ret;
165     }
166 
167     return HDF_SUCCESS;
168 }
169 
UsbStopIo(struct AcmDevice * acm)170 static int32_t UsbStopIo(struct AcmDevice *acm)
171 {
172     int32_t ret;
173     int32_t i = 0;
174 
175     printf("%s:%d", __func__, __LINE__);
176     if (g_stopIoThreadFlag == false) {
177         printf("%s:%d", __func__, __LINE__);
178         g_stopIoThreadFlag = true;
179     }
180     printf("%s:%d", __func__, __LINE__);
181 
182     while (g_stopIoThreadFlag) {
183         i++;
184         OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
185         if (i > USB_RAW_IO_STOP_WAIT_MAX_TIME) {
186             printf("%s:%d", __func__, __LINE__);
187             g_stopIoThreadFlag = false;
188         }
189     }
190     printf("%s:%d", __func__, __LINE__);
191 
192     ret = OsalThreadDestroy(&acm->ioThread);
193     if (ret != HDF_SUCCESS) {
194         printf("%s:%d OsalThreadDestroy faile, ret=%d", __func__, __LINE__, ret);
195         return ret;
196     }
197 
198     ret = OsalThreadDestroy(&acm->ioSendThread);
199     if (ret != HDF_SUCCESS) {
200         printf("%s:%d OsalThreadDestroy faile, ret=%d ", __func__, __LINE__, ret);
201         return ret;
202     }
203 
204     return HDF_SUCCESS;
205 }
206 
UsbGetConfigDescriptor(UsbRawHandle * devHandle,struct UsbRawConfigDescriptor ** config)207 static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config)
208 {
209     UsbRawDevice *dev = NULL;
210     int32_t activeConfig;
211     int32_t ret;
212 
213     if (devHandle == NULL) {
214         printf("%s:%d devHandle is NULL", __func__, __LINE__);
215         return HDF_ERR_INVALID_PARAM;
216     }
217 
218     ret = UsbRawGetConfiguration(devHandle, &activeConfig);
219     if (ret) {
220         printf("%s:%d UsbRawGetConfiguration failed, ret=%d", __func__, __LINE__, ret);
221         return HDF_FAILURE;
222     }
223     HDF_LOGE("%s:%d activeConfig=%d", __func__, __LINE__, activeConfig);
224     dev = UsbRawGetDevice(devHandle);
225     if (dev == NULL) {
226         printf("%s:%d UsbRawGetDevice failed", __func__, __LINE__);
227         return HDF_FAILURE;
228     }
229 
230     ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
231     if (ret) {
232         printf("UsbRawGetConfigDescriptor failed, ret=%d\n", ret);
233         return HDF_FAILURE;
234     }
235 
236     return HDF_SUCCESS;
237 }
238 
UsbSpeedGetBulkEndpoint(struct AcmDevice * acm,const struct UsbRawEndpointDescriptor * endPoint)239 static int32_t UsbSpeedGetBulkEndpoint(struct AcmDevice *acm, const struct UsbRawEndpointDescriptor *endPoint)
240 {
241     if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
242         /* get bulk in endpoint */
243         acm->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
244         if (acm->dataInEp == NULL) {
245             HDF_LOGE("%s:%d allocate dataInEp failed", __func__, __LINE__);
246             return HDF_FAILURE;
247         }
248         acm->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
249         acm->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
250         acm->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
251     } else {
252         /* get bulk out endpoint */
253         acm->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
254         if (acm->dataOutEp == NULL) {
255             HDF_LOGE("%s:%d allocate dataOutEp failed", __func__, __LINE__);
256             return HDF_FAILURE;
257         }
258         acm->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
259         acm->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
260         acm->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
261     }
262 
263     return HDF_SUCCESS;
264 }
265 
UsbSpeedParaseInterfaceClass(struct AcmDevice * acm,const struct UsbRawInterface * interface,uint8_t interfaceIndex)266 static void UsbSpeedParaseInterfaceClass(
267     struct AcmDevice *acm, const struct UsbRawInterface *interface, uint8_t interfaceIndex)
268 {
269     uint8_t j;
270     uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass;
271     uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
272 
273     switch (ifaceClass) {
274         case USB_DDK_CLASS_COMM:
275             acm->ctrlIface = interfaceIndex;
276             acm->notifyEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
277             if (acm->notifyEp == NULL) {
278                 printf("%s:%d allocate endpoint failed", __func__, __LINE__);
279                 break;
280             }
281             /* get the first endpoint by default */
282             acm->notifyEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
283             acm->notifyEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
284             acm->notifyEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
285             break;
286         case USB_DDK_CLASS_CDC_DATA:
287             acm->dataIface = interfaceIndex;
288             for (j = 0; j < numEndpoints; j++) {
289                 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
290 
291                 if (UsbSpeedGetBulkEndpoint(acm, endPoint) != HDF_SUCCESS) {
292                     break;
293                 }
294             }
295             break;
296         default:
297             printf("%s:%d wrong descriptor type", __func__, __LINE__);
298             break;
299     }
300 }
301 
UsbParseConfigDescriptor(struct AcmDevice * acm,struct UsbRawConfigDescriptor * config)302 static int32_t UsbParseConfigDescriptor(struct AcmDevice *acm, struct UsbRawConfigDescriptor *config)
303 {
304     uint8_t i;
305     int32_t ret;
306 
307     if ((acm == NULL) || (config == NULL)) {
308         printf("%s:%d acm or config is NULL", __func__, __LINE__);
309         return HDF_ERR_INVALID_PARAM;
310     }
311 
312     for (i = 0; i < acm->interfaceCnt; i++) {
313         uint8_t interfaceIndex = acm->interfaceIndex[i];
314         const struct UsbRawInterface *interface = config->interface[interfaceIndex];
315 
316         if (acm->devHandle) {
317             ret = UsbRawClaimInterface(acm->devHandle, interfaceIndex);
318             if (ret) {
319                 printf("%s:%d claim interface %d failed", __func__, __LINE__, i);
320                 return ret;
321             }
322         }
323 
324         UsbSpeedParaseInterfaceClass(acm, interface, interfaceIndex);
325     }
326 
327     return HDF_SUCCESS;
328 }
329 
UsbAllocDataRequests(struct AcmDevice * acm)330 static int32_t UsbAllocDataRequests(struct AcmDevice *acm)
331 {
332     int32_t i;
333     int32_t ret;
334     for (i = 0; i < TEST_CYCLE; i++) {
335         struct AcmDb *snd = &acm->db[i];
336         snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataEp->maxPacketSize);
337         snd->instance = acm;
338         if (snd->request == NULL) {
339             printf("%s: UsbRawAllocRequest failed", __func__);
340             return HDF_ERR_MALLOC_FAIL;
341         }
342         struct UsbRawFillRequestData reqData;
343         reqData.endPoint      = acm->dataEp->addr;
344         reqData.numIsoPackets = 0;
345         reqData.callback      = AcmTestBulkCallback;
346         reqData.userData      = (void *)snd;
347         reqData.timeout       = USB_CTRL_SET_TIMEOUT;
348         reqData.buffer        = snd->buf;
349         reqData.length        = acm->dataSize;
350 
351         ret = UsbRawFillBulkRequest(snd->request, acm->devHandle, &reqData);
352         if (ret) {
353             printf("%s: FillInterruptRequest faile, ret=%d", __func__, ret);
354             return HDF_FAILURE;
355         }
356     }
357 
358     return HDF_SUCCESS;
359 }
360 
UsbFreeDataRequests(struct AcmDevice * acm)361 static int32_t UsbFreeDataRequests(struct AcmDevice *acm)
362 {
363     int32_t i;
364     for (i = 0; i < TEST_CYCLE; i++) {
365         struct AcmDb *snd = &acm->db[i];
366         UsbRawCancelRequest(snd->request);
367         UsbRawFreeRequest(snd->request);
368     }
369     return HDF_SUCCESS;
370 }
371 
AcmDbAlloc(struct AcmDevice * acm)372 static int32_t AcmDbAlloc(struct AcmDevice *acm)
373 {
374     struct AcmDb *db = NULL;
375     int32_t i;
376 
377     for (i = 0; i < TEST_CYCLE; i++) {
378         db = &acm->db[i];
379         if (!db->use) {
380             db->use = 1;
381             db->len = 0;
382             return i;
383         }
384     }
385     return -1;
386 }
387 
AcmDbIsAvail(struct AcmDevice * acm)388 static int32_t AcmDbIsAvail(struct AcmDevice *acm)
389 {
390     int32_t i;
391     int32_t n = TEST_CYCLE;
392 
393     for (i = 0; i < TEST_CYCLE; i++) {
394         n -= acm->db[i].use;
395     }
396     return n;
397 }
398 
AcmStartdb(struct AcmDevice * acm,struct AcmDb * db)399 static int32_t AcmStartdb(struct AcmDevice *acm, struct AcmDb *db)
400 {
401     int32_t ret;
402     ret = UsbRawSubmitRequest(db->request);
403     if (ret) {
404         printf("UsbRawSubmitRequest failed, ret=%d", ret);
405         db->use = 0;
406     }
407     return ret;
408 }
409 
AcmDataBufAlloc(struct AcmDevice * acm)410 static int32_t AcmDataBufAlloc(struct AcmDevice *acm)
411 {
412     struct AcmDb *db = &acm->db[0];
413     int32_t i;
414 
415     for (i = 0; i < TEST_CYCLE; i++, db++) {
416         db->buf = OsalMemCalloc(acm->dataEp->maxPacketSize);
417         if (!db->buf) {
418             while (i != 0) {
419                 --i;
420                 --db;
421                 OsalMemFree(db->buf);
422                 db->buf = NULL;
423             }
424             return -HDF_ERR_MALLOC_FAIL;
425         } else {
426             memset_s(db->buf, acm->dataSize, 'b', acm->dataSize);
427             db->instance = acm;
428         }
429     }
430     return HDF_SUCCESS;
431 }
AcmDataBufFree(const struct AcmDevice * acm)432 static int32_t AcmDataBufFree(const struct AcmDevice *acm)
433 {
434     struct AcmDb *db = (struct AcmDb *)&acm->db[0];
435     int32_t i;
436     for (i = 0; i < TEST_CYCLE; i++, db++) {
437         if (db->buf) {
438             OsalMemFree(db->buf);
439             db->use = 0;
440         }
441     }
442     return 0;
443 }
444 
AcmTestBulkCallback(const void * requestArg)445 static void AcmTestBulkCallback(const void *requestArg)
446 {
447     struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
448     if (req == NULL) {
449         HDF_LOGE("%s:%{pulib}d req is NULL!", __func__, __LINE__);
450         return;
451     }
452     struct AcmDb *db  = (struct AcmDb *)req->userData;
453     if (db == NULL) {
454         HDF_LOGE("%s:%{pulib}d userData(db) is NULL!", __func__, __LINE__);
455         return;
456     }
457 
458     if (req->status == USB_REQUEST_COMPLETED) {
459         if (g_byteTotal == 0) {
460             OsalSemPost(&timeSem);
461         }
462         g_recv_count++;
463         g_byteTotal += (uint64_t)req->actualLength;
464     } else {
465         printf("status error\n");
466     }
467 
468     if (g_printData == true) {
469         for (int32_t i = 0; i < req->actualLength; i++) {
470             printf("%c", req->buffer[i]);
471         }
472         fflush(stdout);
473     } else if (g_recv_count % 10000 == 0) {
474         printf("#");
475         fflush(stdout);
476     }
477 
478     db->use = 0;
479     OsalSemPost(&sem);
480 }
481 
SerialBegin(struct AcmDevice * acm)482 static int32_t SerialBegin(struct AcmDevice *acm)
483 {
484     int32_t ret;
485     struct AcmDb *db = NULL;
486     int32_t dbn;
487     if (AcmDbIsAvail(acm)) {
488         dbn = AcmDbAlloc(acm);
489     } else {
490         printf("no buf\n");
491         return 0;
492     }
493     if (dbn < 0) {
494         printf("AcmDbAlloc failed\n");
495         return HDF_FAILURE;
496     }
497     db = &acm->db[dbn];
498     db->len = acm->dataSize;
499 
500     ret = AcmStartdb(acm, db);
501     return ret;
502 }
503 
SpeedPrint(void)504 static void SpeedPrint(void)
505 {
506     double speed;
507     uint64_t count;
508 
509     sigCnt++;
510     count = sigCnt * TEST_PRINT_TIME;
511     if (count >= TEST_TIME) {
512         g_speedFlag = true;
513     }
514     speed = (g_byteTotal * TEST_FLOAT_COUNT) / (sigCnt * TEST_PRINT_TIME * TEST_BYTE_COUNT * TEST_BYTE_COUNT);
515     printf("\nSpeed:%f MB/s\n", speed);
516 }
517 
ShowHelp(const char * name)518 static void ShowHelp(const char *name)
519 {
520     printf(">> usage:\n");
521     printf(">>      %s [<busNum> <devAddr>]  <ifaceNum> <w>/<r> [printdata]> \n", name);
522     printf("\n");
523 }
524 
UsbGetDevInfo(int32_t * busNum,int32_t * devNum)525 static void UsbGetDevInfo(int32_t *busNum, int32_t *devNum)
526 {
527     struct UsbGetDevicePara paraData;
528     struct usb_device *usbPnpDevice = NULL;
529     paraData.type = USB_PNP_DEVICE_VENDOR_PRODUCT_TYPE;
530     paraData.vendorId = USB_DEVICE_VENDOR_ID;
531     paraData.productId = USB_DEVICE_PRODUCT_ID;
532     usbPnpDevice = UsbPnpNotifyGetUsbDevice(paraData);
533     if (usbPnpDevice == NULL) {
534         printf("%s:%d UsbPnpNotifyGetUsbDevice is NULL!", __func__, __LINE__);
535         return;
536     }
537     *busNum = (int)usbPnpDevice->address;
538     *devNum = (int)usbPnpDevice->port_no;
539     printf("%s:%d busNum=%d devNum=%d!\n", __func__, __LINE__, *busNum, *devNum);
540 }
541 
UsbSerialOpen(void)542 static int32_t UsbSerialOpen(void)
543 {
544     return HDF_SUCCESS;
545 }
UsbSerialClose(void)546 static int32_t UsbSerialClose(void)
547 {
548     if (!g_speedFlag) {
549         g_speedFlag = true;
550     }
551     return HDF_SUCCESS;
552 }
553 
UsbSerialSpeedInit(const struct UsbSpeedTest * input,int32_t * ifaceNum)554 static int32_t UsbSerialSpeedInit(const struct UsbSpeedTest *input, int32_t *ifaceNum)
555 {
556     int32_t ret = HDF_SUCCESS;
557     int32_t busNum = 1;
558     int32_t devAddr = 2;
559     if (input == NULL) {
560         return HDF_ERR_INVALID_PARAM;
561     }
562 
563     g_speedFlag = false;
564     g_send_count = 0;
565     g_recv_count = 0;
566     g_byteTotal = 0;
567     g_printData = false;
568     g_writeOrRead = TEST_WRITE;
569     sigCnt = 0;
570 
571     UsbGetDevInfo(&busNum, &devAddr);
572     if (input->paramNum == TEST_SIX_TYPE) {
573         busNum = input->busNum;
574         devAddr = input->devAddr;
575         *ifaceNum = input->ifaceNum;
576         g_writeOrRead = input->writeOrRead;
577         if (g_writeOrRead == TEST_READ) {
578             g_printData = input->printData;
579         }
580     } else if (input->paramNum == TEST_FIVE_TYPE) {
581         busNum = input->busNum;
582         devAddr = input->devAddr;
583         *ifaceNum = input->ifaceNum;
584         g_writeOrRead = input->writeOrRead;
585     } else if (input->paramNum == TEST_THREE_TYPE) {
586         *ifaceNum = input->ifaceNum;
587         g_writeOrRead = input->writeOrRead;
588     } else {
589         printf("Error: parameter error! \n\n");
590         ShowHelp("speedtest");
591         ret = HDF_FAILURE;
592         goto END;
593     }
594 
595     g_acm->busNum = busNum;
596     g_acm->devAddr = devAddr;
597     g_acm->interfaceCnt = 1;
598     g_acm->interfaceIndex[0] = *ifaceNum;
599     OsalSemInit(&sem, 0);
600     OsalSemInit(&timeSem, 0);
601 
602 END:
603     return ret;
604 }
605 
UsbSpeedDdkInit(const struct UsbSession * session)606 static int32_t UsbSpeedDdkInit(const struct UsbSession *session)
607 {
608     int32_t ret;
609     UsbRawHandle *devHandle = NULL;
610 
611     ret = UsbRawInit((struct UsbSession **)&session);
612     if (ret) {
613         HDF_LOGE("%s: UsbRawInit failed\n", __func__);
614         return HDF_FAILURE;
615     }
616 
617     devHandle = UsbRawOpenDevice(session, g_acm->busNum, g_acm->devAddr);
618     if (devHandle == NULL) {
619         HDF_LOGE("%s: UsbRawOpenDevice failed\n", __func__);
620         return HDF_FAILURE;
621     }
622     g_acm->devHandle = devHandle;
623     ret = UsbGetConfigDescriptor(devHandle, &g_acm->config);
624     if (ret) {
625         HDF_LOGE("%s: UsbGetConfigDescriptor failed\n", __func__);
626         return HDF_FAILURE;
627     }
628     ret = UsbParseConfigDescriptor(g_acm, g_acm->config);
629     if (ret != HDF_SUCCESS) {
630         HDF_LOGE("%s: UsbParseConfigDescriptor failed\n", __func__);
631         return HDF_FAILURE;
632     }
633     g_acm->dataSize = TEST_LENGTH;
634     g_acm->dataEp = (g_writeOrRead == TEST_WRITE) ? g_acm->dataOutEp : g_acm->dataInEp;
635 
636     ret = AcmDataBufAlloc(g_acm);
637     if (ret < 0) {
638         HDF_LOGE("%s: AcmDataBufAlloc failed\n", __func__);
639         AcmDataBufFree(g_acm);
640         return HDF_FAILURE;
641     }
642     ret = UsbAllocDataRequests(g_acm);
643     if (ret < 0) {
644         HDF_LOGE("%s: UsbAllocDataRequests failed\n", __func__);
645         UsbFreeDataRequests(g_acm);
646         return HDF_FAILURE;
647     }
648 
649     ret = UsbStartIo(g_acm);
650     if (ret) {
651         HDF_LOGE("%s: UsbAllocReadRequests failed\n", __func__);
652         return HDF_FAILURE;
653     }
654 
655     return ret;
656 }
657 
UsbSpeedDdkExit(const struct UsbSession * session)658 static void UsbSpeedDdkExit(const struct UsbSession *session)
659 {
660     int32_t i;
661 
662     if (UsbStopIo(g_acm) != HDF_SUCCESS) {
663         HDF_LOGE("%s UsbStopIo error!", __func__);
664     }
665     if (UsbFreeDataRequests(g_acm) != HDF_SUCCESS) {
666         HDF_LOGE("%s UsbFreeDataRequests error!", __func__);
667     }
668     AcmDataBufFree(g_acm);
669     for (i = 0; i < g_acm->interfaceCnt; i++) {
670         uint8_t interfaceIndex = g_acm->interfaceIndex[i];
671         UsbRawReleaseInterface(g_acm->devHandle, interfaceIndex);
672     }
673     UsbRawCloseDevice(g_acm->devHandle);
674     UsbRawExit(session);
675     OsalSemDestroy(&timeSem);
676     OsalSemDestroy(&sem);
677     g_acm->busy = false;
678 }
679 
UsbSerialSpeed(struct HdfSBuf * data)680 static int32_t UsbSerialSpeed(struct HdfSBuf *data)
681 {
682     struct UsbSession *session = NULL;
683     int32_t ret = HDF_SUCCESS;
684     int32_t ifaceNum = 3;
685     uint32_t size;
686     int32_t i;
687     struct UsbSpeedTest *input = NULL;
688 
689     if (g_acm->busy == true) {
690         printf("%s: speed test busy\n", __func__);
691         ret = HDF_ERR_IO;
692         goto END;
693     } else {
694         g_acm->busy = true;
695     }
696 
697     (void)HdfSbufReadBuffer(data, (const void **)&input, &size);
698     if ((input == NULL) || (size != sizeof(struct UsbSpeedTest))) {
699         printf("%s: sbuf read buffer failed\n", __func__);
700         ret = HDF_ERR_IO;
701         goto END;
702     }
703 
704     ret = UsbSerialSpeedInit(input, &ifaceNum);
705     if (ret != HDF_SUCCESS) {
706         goto END;
707     }
708 
709     ret = UsbSpeedDdkInit(session);
710     if (ret != HDF_SUCCESS) {
711         goto END;
712     }
713 
714     printf("test SDK rawAPI [%s]\n", g_writeOrRead ? "write" : "read");
715 
716     for (i = 0; i < TEST_CYCLE; i++) {
717         if (SerialBegin(g_acm) != HDF_SUCCESS) {
718             printf("SerialBegin error!\n");
719         }
720         g_send_count++;
721     }
722 
723     OsalSemWait(&timeSem, TEST_TIME);
724     while (!g_speedFlag) {
725         OsalSemWait(&timeSem, TEST_PRINT_TIME * TEST_PRINT_TIME_UINT);
726         SpeedPrint();
727     }
728 
729     UsbSpeedDdkExit(session);
730 END:
731     if (ret != HDF_SUCCESS) {
732         printf("please check whether usb drv so is existing or not,like acm,ecm,if not,remove it and test again!\n");
733     }
734     return ret;
735 }
736 
AcmDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)737 static int32_t AcmDeviceDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
738     struct HdfSBuf *data, struct HdfSBuf *reply)
739 {
740     if (client == NULL) {
741         HDF_LOGE("%s: client is NULL", __func__);
742         return HDF_ERR_INVALID_OBJECT;
743     }
744 
745     if (client->device == NULL) {
746         HDF_LOGE("%s: client->device is NULL", __func__);
747         return HDF_ERR_INVALID_OBJECT;
748     }
749 
750     if (client->device->service == NULL) {
751         HDF_LOGE("%s: client->device->service is NULL", __func__);
752         return HDF_ERR_INVALID_OBJECT;
753     }
754 
755     g_acm = (struct AcmDevice *)client->device->service;
756 
757     switch (cmd) {
758         case USB_SERIAL_OPEN:
759             return UsbSerialOpen();
760         case USB_SERIAL_CLOSE:
761             return UsbSerialClose();
762         case USB_SERIAL_SPEED:
763             return UsbSerialSpeed(data);
764         default:
765             return HDF_ERR_NOT_SUPPORT;
766     }
767 
768     return HDF_SUCCESS;
769 }
770 
AcmDriverBind(struct HdfDeviceObject * device)771 static int32_t AcmDriverBind(struct HdfDeviceObject *device)
772 {
773     if (device == NULL) {
774         HDF_LOGE("%s: device is null", __func__);
775         return HDF_ERR_INVALID_OBJECT;
776     }
777 
778     g_acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*g_acm));
779     if (g_acm == NULL) {
780         HDF_LOGE("%s: Alloc usb acm device failed", __func__);
781         return HDF_FAILURE;
782     }
783 
784     g_acm->device  = device;
785     device->service = &(g_acm->service);
786     if (g_acm->device && g_acm->device->service) {
787         g_acm->device->service->Dispatch = AcmDeviceDispatch;
788     }
789 
790     return HDF_SUCCESS;
791 }
792 
AcmDriverInit(struct HdfDeviceObject * device)793 static int32_t AcmDriverInit(struct HdfDeviceObject *device)
794 {
795     return 0;
796 }
797 
AcmDriverRelease(struct HdfDeviceObject * device)798 static void AcmDriverRelease(struct HdfDeviceObject *device)
799 {
800 }
801 
802 struct HdfDriverEntry g_usbRawApiSpeedDriverEntry = {
803     .moduleVersion = 1,
804     .moduleName    = "usb_rawapispeed",
805     .Bind          = AcmDriverBind,
806     .Init          = AcmDriverInit,
807     .Release       = AcmDriverRelease,
808 };
809 
810 HDF_INIT(g_usbRawApiSpeedDriverEntry);
811