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