• 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 <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <dirent.h>
22 #include <sys/ioctl.h>
23 #include <sys/mman.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <sys/time.h>
27 #include <signal.h>
28 #include <sys/mman.h>
29 #include <osal_sem.h>
30 #include <osal_thread.h>
31 #include <errno.h>
32 #include <sys/syscall.h>
33 #include <time.h>
34 #include "usbhost_nosdk_speed.h"
35 #include "osal_time.h"
36 #include "osal_mem.h"
37 #include "implementation/global_implementation.h"
38 #include "signal.h"
39 #include "liteos_ddk_usb.h"
40 #include "usb_pnp_notify.h"
41 
42 #define USB_DEV_FS_PATH "/dev/bus/usb"
43 #define URB_COMPLETE_PROCESS_STACK_SIZE 8196
44 #define ENDPOINT_IN_OFFSET 7
45 static int32_t g_speedFlag = 0;
46 static int32_t g_busNum = 1;
47 static int32_t g_devAddr = 2;
48 static struct OsalSem sem;
49 static struct OsalSem timeSem;
50 
51 static uint64_t g_send_count = 0;
52 static uint64_t g_recv_count = 0;
53 static uint64_t g_byteTotal = 0;
54 static struct UsbAdapterUrbs urb[TEST_CYCLE];
55 static struct urb *sendUrb = NULL;
56 static bool g_printData = false;
57 static unsigned char endNum;
58 static struct OsalSem timeSem;
59 static struct usb_device *fd = NULL;
60 static uint32_t sigCnt = 0;
61 static struct UsbAdapterHostEndpoint *uhe = NULL;
62 static bool g_writeOrRead = TEST_WRITE;
63 static struct AcmDevice *acm = NULL;
64 
CloseDevice()65 static void CloseDevice()
66 {
67     return;
68 }
69 
OpenDevice()70 static int32_t OpenDevice()
71 {
72     struct UsbGetDevicePara paraData;
73     paraData.type = USB_PNP_DEVICE_ADDRESS_TYPE;
74     paraData.busNum = (uint8_t)g_busNum;
75     paraData.devNum = (uint8_t)g_devAddr;
76     fd = UsbPnpNotifyGetUsbDevice(paraData);
77     if (fd == NULL) {
78         printf("err fd\n");
79         return -1;
80     }
81     return 0;
82 }
83 
ClaimInterface(unsigned int iface)84 static int32_t ClaimInterface(unsigned int iface)
85 {
86     printf("claim success: iface=%u\n", iface);
87     return HDF_SUCCESS;
88 }
89 
SpeedPrint()90 void SpeedPrint()
91 {
92     double speed;
93     uint64_t count;
94 
95     sigCnt++;
96     count = sigCnt * TEST_PRINT_TIME;
97     if (count >= TEST_TIME) {
98         g_speedFlag = true;
99     }
100     speed = (g_byteTotal * 1.0) / (sigCnt * TEST_PRINT_TIME  * 1024 * 1024);
101     printf("\nSpeed:%f MB/s\n", speed);
102 }
103 
SendProcess(void * argurb)104 static int32_t SendProcess(void *argurb)
105 {
106     int32_t i;
107     int32_t r;
108     while (!g_speedFlag) {
109         OsalSemWait(&sem, HDF_WAIT_FOREVER);
110         for (i = 0; i < TEST_CYCLE; i++) {
111             if (urb[i].inUse == 0) {
112                 urb[i].inUse = 1;
113                 break;
114             }
115         }
116 
117         if (i == TEST_CYCLE) {
118             i = TEST_CYCLE - 1;
119         }
120         sendUrb = urb[i].urb;
121         r = usb_setup_endpoint(fd, uhe, 1024);
122         if (r) {
123             DPRINTFN(0, "setup failed ret:%d\n", r);
124             return r;
125         }
126         r = usb_submit_urb(sendUrb, 0);
127         if (r < 0) {
128             printf("SubmitBulkRequest: ret:%d\n", r);
129             urb[i].inUse = 0;
130             continue;
131         }
132         g_send_count++;
133     }
134     return 0;
135 }
136 
UrbCompleteHandle(const struct urb * curUrb)137 static void UrbCompleteHandle(const struct urb *curUrb)
138 {
139     if (g_printData == true) {
140         for (int32_t i = 0; i < curUrb->actual_length; i++) {
141             printf("%c", *(((char*)curUrb->transfer_buffer) + i));
142         }
143         fflush(stdout);
144     } else if (g_recv_count % 10000 == 0) {
145         printf("#");
146         fflush(stdout);
147     }
148 }
149 
UrbComplete(struct urb * curUrb)150 static void UrbComplete(struct urb *curUrb)
151 {
152     int32_t i;
153     for (i = 0; i < TEST_CYCLE; i++) {
154         if (urb[i].urb == curUrb) {
155             if (g_byteTotal == 0) {
156                 OsalSemPost(&timeSem);
157             }
158             g_recv_count++;
159             g_byteTotal += curUrb->actual_length;
160             UrbCompleteHandle(curUrb);
161             urb[i].inUse = 0;
162             OsalSemPost(&sem);
163             break;
164         }
165     }
166 }
167 
BeginProcessHandleFirst()168 static int32_t BeginProcessHandleFirst()
169 {
170     char *data = NULL;
171     int32_t i;
172 
173     for (i = 0; i < TEST_CYCLE; i++) {
174         if (urb[i].urb == NULL) {
175             urb[i].urb = OsalMemCalloc(sizeof(struct urb));
176             if (urb[i].urb == NULL) {
177                 printf("urb calloc err\n");
178                 return -1;
179             }
180         }
181         urb[i].inUse = 0;
182         urb[i].urb->dev = fd;
183         urb[i].urb->endpoint = uhe;
184         urb[i].urb->complete = UrbComplete;
185 
186         if (data == NULL) {
187             data = OsalMemCalloc(TEST_LENGTH);
188             if (data == NULL) {
189                 printf("data calloc err\n");
190                 return -1;
191             }
192         }
193 
194         memset_s(data, TEST_LENGTH, 'c', TEST_LENGTH);
195         data[TEST_LENGTH - 1] = '\0';
196         urb[i].urb->transfer_buffer = (void *)data;
197         urb[i].urb->transfer_buffer_length = TEST_LENGTH;
198     }
199 
200     return HDF_SUCCESS;
201 }
202 
BeginProcess(unsigned char endPoint)203 static int32_t BeginProcess(unsigned char endPoint)
204 {
205     int32_t r;
206     const int32_t transNum = 0;
207     int32_t i;
208 
209     if (endPoint <= 0) {
210         printf("parameter error\n");
211         return -1;
212     }
213 
214     uhe = usb_find_host_endpoint(fd, USB_REQUEST_TYPE_BULK, endPoint);
215     if (uhe == NULL) {
216         printf("usb_find_host_endpoint error\n");
217         return -1;
218     }
219     r = BeginProcessHandleFirst();
220     if (r != HDF_SUCCESS) {
221         return r;
222     }
223 
224     printf("test NO SDK endpoint:%u\n", endPoint);
225 
226     for (i = 0; i < TEST_CYCLE; i++) {
227         if (urb[i].inUse == 0) {
228             urb[i].inUse = 1;
229             urb[i].urbNum = transNum;
230             sendUrb = urb[i].urb;
231             r = usb_setup_endpoint(fd, uhe, 1024);
232             if (r) {
233                 DPRINTFN(0, "setup failed ret:%d\n", r);
234                 return r;
235             }
236             r = usb_submit_urb(sendUrb, 0);
237             if (r < 0) {
238                 printf("SubmitBulkRequest: ret:%d\n", r);
239                 urb[i].inUse = 0;
240                 continue;
241             }
242             g_send_count++;
243         }
244     }
245 
246     OsalSemWait(&timeSem, TEST_TIME);
247     while (!g_speedFlag) {
248         OsalSemWait(&timeSem, TEST_PRINT_TIME * TEST_PRINT_TIME_UINT);
249         SpeedPrint();
250     }
251 
252     for (i = 0; i < TEST_CYCLE; i++) {
253         usb_kill_urb(urb[i].urb);
254     }
255 
256     return HDF_SUCCESS;
257 }
258 
ShowHelp(const char * name)259 static void ShowHelp(const char *name)
260 {
261     printf(">> usage:\n");
262     printf(">>      %s [<busNum> <devAddr>]  <ifaceNum> <endpoint> [<printdata>]\n", name);
263     printf("\n");
264 }
265 
UsbGetDevInfo(int32_t * busNum,int32_t * devNum)266 static void UsbGetDevInfo(int32_t *busNum, int32_t *devNum)
267 {
268     struct UsbGetDevicePara paraData;
269     struct usb_device *usbPnpDevice = NULL;
270     paraData.type = USB_PNP_DEVICE_VENDOR_PRODUCT_TYPE;
271     paraData.vendorId = USB_DEVICE_VENDOR_ID;
272     paraData.productId = USB_DEVICE_PRODUCT_ID;
273     usbPnpDevice = UsbPnpNotifyGetUsbDevice(paraData);
274     if (usbPnpDevice == NULL) {
275         printf("%s:%d UsbPnpNotifyGetUsbDevice is NULL!", __func__, __LINE__);
276         return;
277     }
278     *busNum = (int)usbPnpDevice->address;
279     *devNum = (int)usbPnpDevice->port_no;
280     printf("%s:%d busNum=%d devNum=%d!\n", __func__, __LINE__, *busNum, *devNum);
281 }
282 
UsbSerialOpen()283 static int32_t UsbSerialOpen()
284 {
285     return HDF_SUCCESS;
286 }
UsbSerialClose()287 static int32_t UsbSerialClose()
288 {
289     if (!g_speedFlag) {
290         g_speedFlag = true;
291     }
292     return HDF_SUCCESS;
293 }
294 
UsbSerialSpeedInit(const struct UsbSpeedTest * input,int32_t * ifaceNum)295 static int32_t UsbSerialSpeedInit(const struct UsbSpeedTest *input, int32_t *ifaceNum)
296 {
297     int32_t ret = HDF_SUCCESS;
298     if (input == NULL) {
299         return HDF_ERR_INVALID_PARAM;
300     }
301 
302     g_speedFlag = false;
303     g_send_count = 0;
304     g_recv_count = 0;
305     g_byteTotal = 0;
306     g_printData = false;
307     g_writeOrRead = TEST_WRITE;
308     sigCnt = 0;
309     g_busNum = 1;
310     g_devAddr = 2;
311 
312     UsbGetDevInfo(&g_busNum, &g_devAddr);
313     if (input->paramNum == 6) {
314         g_busNum = input->busNum;
315         g_devAddr = input->devAddr;
316         *ifaceNum = input->ifaceNum;
317         endNum = input->writeOrRead;
318         g_writeOrRead = ((endNum >> ENDPOINT_IN_OFFSET) == 0) ? TEST_WRITE : TEST_READ;
319         if (g_writeOrRead == TEST_READ) {
320             g_printData = input->printData;
321         }
322     } else if (input->paramNum == 5) {
323         g_busNum = input->busNum;
324         g_devAddr = input->devAddr;
325         *ifaceNum = input->ifaceNum;
326         endNum = input->writeOrRead;
327         g_writeOrRead = ((endNum >> ENDPOINT_IN_OFFSET) == 0) ? TEST_WRITE : TEST_READ;
328     } else if (input->paramNum == 3) {
329         *ifaceNum = input->ifaceNum;
330         endNum = input->writeOrRead;
331         g_writeOrRead = ((endNum >> ENDPOINT_IN_OFFSET) == 0) ? TEST_WRITE : TEST_READ;
332     } else {
333         printf("Error: parameter error! \n\n");
334         ShowHelp("speedtest");
335         ret = HDF_FAILURE;
336         goto END;
337     }
338     OsalSemInit(&sem, 0);
339     OsalSemInit(&timeSem, 0);
340 END:
341     return ret;
342 }
343 
UsbSerialSpeedThreadCreate()344 static int32_t UsbSerialSpeedThreadCreate()
345 {
346     int32_t ret;
347     struct OsalThread urbSendProcess;
348     struct OsalThreadParam threadCfg;
349 
350     threadCfg.name = "urb send process";
351     threadCfg.priority = OSAL_THREAD_PRI_DEFAULT;
352     threadCfg.stackSize = URB_COMPLETE_PROCESS_STACK_SIZE;
353 
354     ret = OsalThreadCreate(&urbSendProcess, (OsalThreadEntry)SendProcess, NULL);
355     if (ret != HDF_SUCCESS) {
356         printf("OsalThreadCreate fail, ret=%d\n", ret);
357         goto END;
358     }
359 
360     ret = OsalThreadStart(&urbSendProcess, &threadCfg);
361     if (ret != HDF_SUCCESS) {
362         printf("OsalThreadStart fail, ret=%d\n", ret);
363         goto END;
364     }
365 
366 END:
367     return ret;
368 }
369 
UsbSerialSpeed(struct HdfSBuf * data)370 static int32_t UsbSerialSpeed(struct HdfSBuf *data)
371 {
372     int32_t ifaceNum = 3;
373     int32_t ret;
374     struct UsbSpeedTest *input = NULL;
375     uint32_t size = 0;
376     if (acm->busy == true) {
377         printf("%s: speed test busy\n", __func__);
378         ret = HDF_ERR_IO;
379         goto END;
380     } else {
381         acm->busy = true;
382     }
383 
384     (void)HdfSbufReadBuffer(data, (const void **)&input, &size);
385     if ((input == NULL) || (size != sizeof(struct UsbSpeedTest))) {
386         printf("%s: sbuf read buffer failed\n", __func__);
387         ret = HDF_ERR_IO;
388         goto END;
389     }
390 
391     ret = UsbSerialSpeedInit(input, &ifaceNum);
392     if (ret != HDF_SUCCESS) {
393         goto END;
394     }
395 
396     OpenDevice();
397 
398     ret = ClaimInterface(ifaceNum);
399     if (ret != HDF_SUCCESS) {
400         goto END;
401     }
402 
403     ret = UsbSerialSpeedThreadCreate();
404     if (ret != HDF_SUCCESS) {
405         goto END;
406     }
407 
408     ret = BeginProcess(endNum);
409     if (ret != HDF_SUCCESS) {
410         goto END;
411     }
412 
413 END:
414     acm->busy = false;
415     if (ret != HDF_SUCCESS) {
416         printf("please check whether usb drv so is existing or not,like acm, ecm,if not,remove it and test again!\n");
417     }
418     CloseDevice();
419     return ret;
420 }
421 
AcmDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)422 static int32_t AcmDeviceDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
423     struct HdfSBuf *data, struct HdfSBuf *reply)
424 {
425     if (client == NULL) {
426         HDF_LOGE("%s: client is NULL", __func__);
427         return HDF_ERR_INVALID_OBJECT;
428     }
429 
430     if (client->device == NULL) {
431         HDF_LOGE("%s: client->device is NULL", __func__);
432         return HDF_ERR_INVALID_OBJECT;
433     }
434 
435     if (client->device->service == NULL) {
436         HDF_LOGE("%s: client->device->service is NULL", __func__);
437         return HDF_ERR_INVALID_OBJECT;
438     }
439 
440     acm = (struct AcmDevice *)client->device->service;
441 
442     switch (cmd) {
443         case USB_SERIAL_OPEN:
444             return UsbSerialOpen();
445         case USB_SERIAL_CLOSE:
446             return UsbSerialClose();
447         case USB_SERIAL_SPEED:
448             return UsbSerialSpeed(data);
449         default:
450             return HDF_ERR_NOT_SUPPORT;
451     }
452 
453     return HDF_SUCCESS;
454 }
455 
AcmDriverBind(struct HdfDeviceObject * device)456 static int32_t AcmDriverBind(struct HdfDeviceObject *device)
457 {
458     if (device == NULL) {
459         HDF_LOGE("%s: device is null", __func__);
460         return HDF_ERR_INVALID_OBJECT;
461     }
462 
463     acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
464     if (acm == NULL) {
465         HDF_LOGE("%s: Alloc usb acm device failed", __func__);
466         return HDF_FAILURE;
467     }
468 
469     acm->device  = device;
470     device->service = &(acm->service);
471     if (acm->device && acm->device->service) {
472         acm->device->service->Dispatch = AcmDeviceDispatch;
473     }
474     return HDF_SUCCESS;
475 }
476 
AcmDriverInit(struct HdfDeviceObject * device)477 static int32_t AcmDriverInit(struct HdfDeviceObject *device)
478 {
479     return 0;
480 }
481 
AcmDriverRelease(struct HdfDeviceObject * device)482 static void AcmDriverRelease(struct HdfDeviceObject *device)
483 {
484 }
485 
486 struct HdfDriverEntry g_usbNoSdkSpeedDriverEntry = {
487     .moduleVersion = 1,
488     .moduleName    = "usb_nosdkspeed",
489     .Bind          = AcmDriverBind,
490     .Init          = AcmDriverInit,
491     .Release       = AcmDriverRelease,
492 };
493 
494 HDF_INIT(g_usbNoSdkSpeedDriverEntry);
495