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