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 "../include/cdcacm.h"
17 #include "hdf_base.h"
18 #include "hdf_device_object.h"
19 #include "device_resource_if.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "osal_time.h"
23 #include "securec.h"
24 #include "usbfn_device.h"
25 #include "usbfn_interface.h"
26 #include "usbfn_request.h"
27 #include "default_config.h"
28
29 #define HDF_LOG_TAG hdf_cdc_acm
30
31 #define PENDING_FLAG 0
32 #define CTRL_REQUEST_NUM 2
33 #define QUEUE_SIZE 8
34 #define WRITE_BUF_SIZE 8192
35 #define READ_BUF_SIZE 8192
36
37 #define PORT_RATE 9600
38 #define DATA_BIT 8
39 static int32_t g_inFifo = 0;
40 /* Usb Serial Related Functions */
41
42 static int32_t UsbSerialInit(struct UsbAcmDevice *acm);
43 static int32_t UsbSerialRelease(struct UsbAcmDevice *acm);
UsbSerialStartTx(struct UsbSerial * port)44 static int32_t UsbSerialStartTx(struct UsbSerial *port)
45 {
46 if (port == NULL) {
47 return HDF_FAILURE;
48 }
49 struct DListHead *pool = &port->writePool;
50 int32_t ret = HDF_FAILURE;
51 if (port->acm == NULL) {
52 return HDF_SUCCESS;
53 }
54 while (!port->writeBusy && !DListIsEmpty(pool)) {
55 struct UsbFnRequest *req = NULL;
56 uint32_t len;
57 if (port->writeStarted >= QUEUE_SIZE) {
58 break;
59 }
60 req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
61 if (req == NULL) {
62 break;
63 }
64 len = DataFifoRead(&port->writeFifo, req->buf, port->acm->dataInPipe.maxPacketSize);
65 if (len == 0) {
66 break;
67 }
68 req->length = len;
69 DListRemove(&req->list);
70 port->writeBusy = true;
71 ret = UsbFnSubmitRequestAsync(req);
72 port->writeBusy = false;
73 if (ret != HDF_SUCCESS) {
74 HDF_LOGD("%s: send request erro %d", __func__, ret);
75 DListInsertTail(&req->list, pool);
76 break;
77 }
78 port->writeStarted++;
79 /* if acm is disconnect, abort immediately */
80 if (port->acm == NULL) {
81 break;
82 }
83 }
84 return ret;
85 }
86
UsbSerialStartRx(struct UsbSerial * port)87 static uint32_t UsbSerialStartRx(struct UsbSerial *port)
88 {
89 struct DListHead *pool = &port->readPool;
90 struct UsbAcmPipe *out = &port->acm->dataOutPipe;
91 while (!DListIsEmpty(pool)) {
92 struct UsbFnRequest *req = NULL;
93 int32_t ret;
94
95 if (port->readStarted >= QUEUE_SIZE) {
96 break;
97 }
98
99 req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
100 DListRemove(&req->list);
101 req->length = out->maxPacketSize;
102 ret = UsbFnSubmitRequestAsync(req);
103 if (ret != HDF_SUCCESS) {
104 HDF_LOGD("%s: send request erro %d", __func__, ret);
105 DListInsertTail(&req->list, pool);
106 break;
107 }
108 port->readStarted++;
109 /* if acm is disconnect, abort immediately */
110 if (port->acm == NULL) {
111 break;
112 }
113 }
114 return port->readStarted;
115 }
116
UsbSerialRxPush(struct UsbSerial * port)117 static void UsbSerialRxPush(struct UsbSerial *port)
118 {
119 struct DListHead *queue = &port->readQueue;
120 bool disconnect = false;
121 while (!DListIsEmpty(queue)) {
122 struct UsbFnRequest *req;
123
124 req = DLIST_FIRST_ENTRY(queue, struct UsbFnRequest, list);
125 switch (req->status) {
126 case USB_REQUEST_NO_DEVICE:
127 disconnect = true;
128 HDF_LOGV("%s: the device is disconnected", __func__);
129 break;
130 case USB_REQUEST_COMPLETED:
131 break;
132 default:
133 HDF_LOGV("%s: unexpected status %d", __func__, req->status);
134 break;
135 }
136
137 if (g_inFifo && req->actual) {
138 uint32_t size = req->actual;
139 uint8_t *data = req->buf;
140 uint32_t count;
141
142 if (DataFifoIsFull(&port->readFifo)) {
143 DataFifoSkip(&port->readFifo, size);
144 }
145 count = DataFifoWrite(&port->readFifo, data, size);
146 if (count != size) {
147 HDF_LOGW("%s: write %u less than expected %u", __func__, count, size);
148 }
149 }
150
151 DListRemove(&req->list);
152 DListInsertTail(&req->list, &port->readPool);
153 port->readStarted--;
154 }
155
156 if (!disconnect && port->acm) {
157 UsbSerialStartRx(port);
158 }
159 }
160
UsbSerialFreeRequests(struct DListHead * head,int32_t * allocated)161 static void UsbSerialFreeRequests(struct DListHead *head, int32_t *allocated)
162 {
163 struct UsbFnRequest *req = NULL;
164 while (!DListIsEmpty(head)) {
165 req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
166 DListRemove(&req->list);
167 (void)UsbFnFreeRequest(req);
168 if (allocated) {
169 (*allocated)--;
170 }
171 }
172 }
173
174 static bool g_isStartRead = false;
175 static bool g_isReadDone = false;
176 static uint64_t g_readCnt = 0;
177 struct timeval g_readTimeStart, g_readTimeEnd;
178 static float g_readSpeed = 0;
179 static bool isGetReadTimeStart = false;
UsbSerialReadComplete(uint8_t pipe,struct UsbFnRequest * req)180 static void UsbSerialReadComplete(uint8_t pipe, struct UsbFnRequest *req)
181 {
182 struct UsbSerial *port = (struct UsbSerial *)req->context;
183 if (g_isReadDone != true && g_isStartRead == true && req->status == USB_REQUEST_COMPLETED) {
184 g_readCnt += req->actual;
185 if (isGetReadTimeStart == false) {
186 isGetReadTimeStart = true;
187 gettimeofday(&g_readTimeStart, NULL);
188 }
189 }
190 OsalMutexLock(&port->lock);
191 DListInsertTail(&req->list, &port->readQueue);
192 UsbSerialRxPush(port);
193 OsalMutexUnlock(&port->lock);
194 }
195
SpeedReadThread(void * arg)196 static int32_t SpeedReadThread(void *arg)
197 {
198 g_readCnt = 0;
199 g_isReadDone = false;
200 g_readSpeed = 0;
201 isGetReadTimeStart = false;
202 double timeUse;
203 double usec = 1000000;
204 double k = 1024;
205 struct timeval timeTmp;
206 while (!g_isReadDone) {
207 if (g_readCnt == 0) {
208 OsalSleep(1);
209 continue;
210 } else {
211 OsalSleep(1);
212 }
213 gettimeofday(&timeTmp, NULL);
214 timeUse = (double)(timeTmp.tv_sec - g_readTimeStart.tv_sec) +
215 (double)timeTmp.tv_usec / usec - (double)g_readTimeStart.tv_usec / usec;
216 g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
217 }
218 timeUse = (double)(g_readTimeEnd.tv_sec - g_readTimeStart.tv_sec) +
219 (double)g_readTimeEnd.tv_usec / usec - (double)g_readTimeStart.tv_usec / usec;
220 HDF_LOGD("timeUse = %lf\n", timeUse);
221 g_readSpeed = (float)((double)g_readCnt / k / k / timeUse);
222 HDF_LOGD("%s: g_speed = %f MB/s", __func__, g_readSpeed);
223 return HDF_SUCCESS;
224 }
225
226 #define HDF_PROCESS_STACK_SIZE 10000
227 struct OsalThread g_threadRead;
StartThreadReadSpeed(struct UsbSerial * port)228 static int32_t StartThreadReadSpeed(struct UsbSerial *port)
229 {
230 int32_t ret;
231 struct OsalThreadParam threadCfg;
232 ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
233 if (ret != HDF_SUCCESS) {
234 HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
235 return ret;
236 }
237
238 threadCfg.name = "speed read process";
239 threadCfg.priority = OSAL_THREAD_PRI_LOW;
240 threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
241
242 ret = OsalThreadCreate(&g_threadRead, (OsalThreadEntry)SpeedReadThread, port);
243 if (HDF_SUCCESS != ret) {
244 HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ", __func__, __LINE__, ret);
245 return HDF_ERR_DEVICE_BUSY;
246 }
247
248 ret = OsalThreadStart(&g_threadRead, &threadCfg);
249 if (HDF_SUCCESS != ret) {
250 HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ", __func__, __LINE__, ret);
251 return HDF_ERR_DEVICE_BUSY;
252 }
253 return HDF_SUCCESS;
254 }
255
UsbSerialGetTempReadSpeed(struct UsbSerial * port,struct HdfSBuf * reply)256 static int32_t UsbSerialGetTempReadSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
257 {
258 if (!HdfSbufWriteFloat(reply, g_readSpeed)) {
259 HDF_LOGE("%s: HdfSbufWriteFloat failed", __func__);
260 return HDF_FAILURE;
261 }
262 return HDF_SUCCESS;
263 }
264
UsbSerialGetTempReadSpeedInt(struct UsbSerial * port,struct HdfSBuf * reply)265 static int32_t UsbSerialGetTempReadSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
266 {
267 uint32_t calc = 10000;
268 if (!HdfSbufWriteUint32(reply, (uint32_t)(g_readSpeed * calc))) {
269 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
270 return HDF_FAILURE;
271 }
272 return HDF_SUCCESS;
273 }
274
UsbSerialReadSpeedDone(struct UsbSerial * port)275 static int32_t UsbSerialReadSpeedDone(struct UsbSerial *port)
276 {
277 gettimeofday(&g_readTimeEnd, NULL);
278 g_isReadDone = true;
279 g_isStartRead = false;
280 return HDF_SUCCESS;
281 }
282
UsbSerialReadSpeedStart(struct UsbSerial * port)283 static int32_t UsbSerialReadSpeedStart(struct UsbSerial *port)
284 {
285 g_inFifo = 0;
286 g_isStartRead = true;
287 return StartThreadReadSpeed(port);
288 }
289
UsbSerialWriteComplete(uint8_t pipe,struct UsbFnRequest * req)290 static void UsbSerialWriteComplete(uint8_t pipe, struct UsbFnRequest *req)
291 {
292 struct UsbSerial *port = (struct UsbSerial *)req->context;
293
294 OsalMutexLock(&port->lock);
295 DListInsertTail(&req->list, &port->writePool);
296 port->writeStarted--;
297
298 switch (req->status) {
299 case USB_REQUEST_COMPLETED:
300 UsbSerialStartTx(port);
301 break;
302 case USB_REQUEST_NO_DEVICE:
303 HDF_LOGV("%s: acm device was disconnected", __func__);
304 break;
305 default:
306 HDF_LOGV("%s: unexpected status %d", __func__, req->status);
307 break;
308 }
309 OsalMutexUnlock(&port->lock);
310 }
311
UsbSerialAllocReadRequests(struct UsbSerial * port,int32_t num)312 static int32_t UsbSerialAllocReadRequests(struct UsbSerial *port, int32_t num)
313 {
314 struct UsbAcmDevice *acm = port->acm;
315 struct DListHead *head = &port->readPool;
316 struct UsbFnRequest *req = NULL;
317 int32_t i;
318
319 for (i = 0; i < num; i++) {
320 req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataOutPipe.id,
321 acm->dataOutPipe.maxPacketSize);
322 if (!req) {
323 return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
324 }
325
326 req->complete = UsbSerialReadComplete;
327 req->context = port;
328 DListInsertTail(&req->list, head);
329 port->readAllocated++;
330 }
331 return HDF_SUCCESS;
332 }
333
UsbSerialAllocWriteRequests(struct UsbSerial * port,int32_t num)334 static int32_t UsbSerialAllocWriteRequests(struct UsbSerial *port, int32_t num)
335 {
336 struct UsbAcmDevice *acm = port->acm;
337 struct DListHead *head = &port->writePool;
338 struct UsbFnRequest *req = NULL;
339 int32_t i;
340
341 for (i = 0; i < num; i++) {
342 req = UsbFnAllocRequest(acm->dataIface.handle, acm->dataInPipe.id,
343 acm->dataInPipe.maxPacketSize);
344 if (!req) {
345 return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
346 }
347
348 req->complete = UsbSerialWriteComplete;
349 req->context = port;
350 DListInsertTail(&req->list, head);
351 port->writeAllocated++;
352 }
353 return HDF_SUCCESS;
354 }
355
UsbSerialStartIo(struct UsbSerial * port)356 static int32_t UsbSerialStartIo(struct UsbSerial *port)
357 {
358 struct DListHead *head = &port->readPool;
359 int32_t ret = HDF_SUCCESS;
360 uint32_t started;
361
362 /* allocate requests for read/write */
363 if (port->readAllocated == 0) {
364 ret = UsbSerialAllocReadRequests(port, QUEUE_SIZE);
365 if (ret != HDF_SUCCESS) {
366 return ret;
367 }
368 }
369 if (port->writeAllocated == 0) {
370 ret = UsbSerialAllocWriteRequests(port, QUEUE_SIZE);
371 if (ret != HDF_SUCCESS) {
372 UsbSerialFreeRequests(head, &port->readAllocated);
373 return ret;
374 }
375 }
376
377 started = UsbSerialStartRx(port);
378 if (started) {
379 UsbSerialStartTx(port);
380 } else {
381 UsbSerialFreeRequests(head, &port->readAllocated);
382 UsbSerialFreeRequests(&port->writePool, &port->writeAllocated);
383 ret = HDF_ERR_IO;
384 }
385
386 return ret;
387 }
388
UsbSerialAllocFifo(struct DataFifo * fifo,uint32_t size)389 static int32_t UsbSerialAllocFifo(struct DataFifo *fifo, uint32_t size)
390 {
391 if (!DataFifoIsInitialized(fifo)) {
392 void *data = OsalMemAlloc(size);
393 if (data == NULL) {
394 HDF_LOGE("%s: allocate fifo data buffer failed", __func__);
395 return HDF_ERR_MALLOC_FAIL;
396 }
397 DataFifoInit(fifo, size, data);
398 }
399 return HDF_SUCCESS;
400 }
401
UsbSerialFreeFifo(struct DataFifo * fifo)402 static void UsbSerialFreeFifo(struct DataFifo *fifo)
403 {
404 void *buf = fifo->data;
405 OsalMemFree(buf);
406 DataFifoInit(fifo, 0, NULL);
407 }
408
UsbSerialOpen(struct UsbSerial * port)409 int32_t UsbSerialOpen(struct UsbSerial *port)
410 {
411 int32_t ret;
412
413 if (port == NULL) {
414 return HDF_ERR_INVALID_PARAM;
415 }
416 g_inFifo = 1;
417 OsalMutexLock(&port->lock);
418 ret = UsbSerialAllocFifo(&port->writeFifo, WRITE_BUF_SIZE);
419 if (ret != HDF_SUCCESS) {
420 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
421 goto OUT;
422 }
423 ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
424 if (ret != HDF_SUCCESS) {
425 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
426 goto OUT;
427 }
428
429 /* the acm is enabled, start the io stream */
430 if (port->acm) {
431 if (!port->suspended) {
432 struct UsbAcmDevice *acm = port->acm;
433 HDF_LOGD("%s: start usb serial", __func__);
434 ret = UsbSerialStartIo(port);
435 if (ret != HDF_SUCCESS) {
436 goto OUT;
437 }
438 if (acm->notify && acm->notify->Connect) {
439 acm->notify->Connect(acm);
440 }
441 } else {
442 HDF_LOGD("%s: delay start usb serial", __func__);
443 port->startDelayed = true;
444 }
445 }
446
447 OUT:
448 OsalMutexUnlock(&port->lock);
449 return HDF_SUCCESS;
450 }
451
UsbSerialClose(struct UsbSerial * port)452 int32_t UsbSerialClose(struct UsbSerial *port)
453 {
454 struct UsbAcmDevice *acm = NULL;
455
456 if (port == NULL) {
457 return HDF_ERR_INVALID_PARAM;
458 }
459
460 OsalMutexLock(&port->lock);
461
462 HDF_LOGD("%s: close usb serial", __func__);
463 acm = port->acm;
464 if (acm && !port->suspended) {
465 if (acm->notify && acm->notify->Disconnect) {
466 acm->notify->Disconnect(acm);
467 }
468 }
469 DataFifoReset(&port->writeFifo);
470 DataFifoReset(&port->readFifo);
471 port->startDelayed = false;
472
473 OsalMutexUnlock(&port->lock);
474 return HDF_SUCCESS;
475 }
476
477 #define WRITE_SPEED_REQ_NUM 8
478 struct UsbFnRequest *g_req[WRITE_SPEED_REQ_NUM] = {NULL};
479 static bool g_isWriteDone = false;
480 static uint64_t g_writeCnt = 0;
481 struct timeval g_timeStart, g_timeEnd;
482 static float g_speed = 0;
483 static bool isGetWriteTimeStart = false;
UsbSerialWriteSpeedComplete(uint8_t pipe,struct UsbFnRequest * req)484 static void UsbSerialWriteSpeedComplete(uint8_t pipe, struct UsbFnRequest *req)
485 {
486 int32_t ret;
487 switch (req->status) {
488 case USB_REQUEST_COMPLETED:
489 g_writeCnt += req->actual;
490 if (isGetWriteTimeStart == false) {
491 isGetWriteTimeStart = true;
492 gettimeofday(&g_timeStart, NULL);
493 }
494 if (g_isWriteDone) {
495 UsbFnFreeRequest(req);
496 } else {
497 ret = memset_s(req->buf, req->length, 'a', req->length);
498 if (ret != HDF_SUCCESS) {
499 HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
500 return;
501 }
502 UsbFnSubmitRequestAsync(req);
503 }
504 break;
505 case USB_REQUEST_NO_DEVICE:
506 HDF_LOGV("%s: acm device was disconnected", __func__);
507 break;
508 default:
509 HDF_LOGD("%s: req->status = %d", __func__, req->status);
510 break;
511 }
512 }
513
SpeedThread(void * arg)514 static int32_t SpeedThread(void *arg)
515 {
516 int32_t i;
517 int32_t ret;
518 g_writeCnt = 0;
519 g_isWriteDone = false;
520 isGetWriteTimeStart = false;
521 g_speed = 0;
522 double timeUse;
523 double usec = 1000000;
524 double k = 1024;
525 struct timeval timeTmp;
526 struct UsbSerial *port = (struct UsbSerial *)arg;
527
528 for (i = 0; i < WRITE_SPEED_REQ_NUM; i++) {
529 g_req[i] = UsbFnAllocRequest(port->acm->dataIface.handle, port->acm->dataInPipe.id,
530 port->acm->dataInPipe.maxPacketSize);
531 if (g_req[i] == NULL) {
532 return HDF_FAILURE;
533 }
534 g_req[i]->complete = UsbSerialWriteSpeedComplete;
535 g_req[i]->context = port;
536 g_req[i]->length = port->acm->dataInPipe.maxPacketSize;
537 ret = memset_s(g_req[i]->buf, port->acm->dataInPipe.maxPacketSize, 'a', port->acm->dataInPipe.maxPacketSize);
538 if (ret != HDF_SUCCESS) {
539 HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
540 return ret;
541 }
542 UsbFnSubmitRequestAsync(g_req[i]);
543 }
544 while (!g_isWriteDone) {
545 if (g_writeCnt == 0) {
546 OsalSleep(1);
547 continue;
548 } else {
549 OsalSleep(1);
550 }
551 gettimeofday(&timeTmp, NULL);
552 timeUse = (double)(timeTmp.tv_sec - g_timeStart.tv_sec) +
553 (double)timeTmp.tv_usec / usec - (double)g_timeStart.tv_usec / usec;
554 g_speed = (float)((double)g_writeCnt / k / k / timeUse);
555 }
556 timeUse = (double)(g_timeEnd.tv_sec - g_timeStart.tv_sec) +
557 (double)g_timeEnd.tv_usec / usec - (double)g_timeStart.tv_usec / usec;
558 HDF_LOGE("timeUse = %lf\n", timeUse);
559 g_speed = (float)((double)g_writeCnt / k / k / timeUse);
560 HDF_LOGD("%s: g_speed = %f MB/s", __func__, g_speed);
561 return HDF_SUCCESS;
562 }
563
564 struct OsalThread g_thread;
StartThreadSpeed(struct UsbSerial * port)565 static int32_t StartThreadSpeed(struct UsbSerial *port)
566 {
567 int32_t ret;
568
569 struct OsalThreadParam threadCfg;
570 ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
571 if (ret != HDF_SUCCESS) {
572 HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
573 return ret;
574 }
575 threadCfg.name = "speed test process";
576 threadCfg.priority = OSAL_THREAD_PRI_LOW;
577 threadCfg.stackSize = HDF_PROCESS_STACK_SIZE;
578
579 ret = OsalThreadCreate(&g_thread, (OsalThreadEntry)SpeedThread, port);
580 if (HDF_SUCCESS != ret) {
581 HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ", __func__, __LINE__, ret);
582 return HDF_ERR_DEVICE_BUSY;
583 }
584
585 ret = OsalThreadStart(&g_thread, &threadCfg);
586 if (HDF_SUCCESS != ret) {
587 HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ", __func__, __LINE__, ret);
588 return HDF_ERR_DEVICE_BUSY;
589 }
590 return 0;
591 }
592
UsbSerialGetTempSpeed(struct UsbSerial * port,struct HdfSBuf * reply)593 static int32_t UsbSerialGetTempSpeed(struct UsbSerial *port, struct HdfSBuf *reply)
594 {
595 if (!HdfSbufWriteFloat(reply, g_speed)) {
596 HDF_LOGE("%s: HdfSbufWriteFloat failed", __func__);
597 return HDF_FAILURE;
598 }
599 return HDF_SUCCESS;
600 }
601
UsbSerialGetTempSpeedInt(struct UsbSerial * port,struct HdfSBuf * reply)602 static int32_t UsbSerialGetTempSpeedInt(struct UsbSerial *port, struct HdfSBuf *reply)
603 {
604 uint32_t calc = 10000;
605 if (!HdfSbufWriteUint32(reply, (uint32_t)(g_speed * calc))) {
606 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
607 return HDF_FAILURE;
608 }
609 return HDF_SUCCESS;
610 }
611
UsbSerialSpeedDone(struct UsbSerial * port)612 static int32_t UsbSerialSpeedDone(struct UsbSerial *port)
613 {
614 gettimeofday(&g_timeEnd, NULL);
615 g_isWriteDone = true;
616 return HDF_SUCCESS;
617 }
618
UsbSerialSpeed(struct UsbSerial * port)619 static int32_t UsbSerialSpeed(struct UsbSerial *port)
620 {
621 StartThreadSpeed(port);
622 return HDF_SUCCESS;
623 }
624
UsbSerialRead(struct UsbSerial * port,struct HdfSBuf * reply)625 static int32_t UsbSerialRead(struct UsbSerial *port, struct HdfSBuf *reply)
626 {
627 uint32_t len, fifoLen;
628 int32_t ret = HDF_SUCCESS;
629 uint8_t *buf = NULL;
630 uint32_t i;
631 OsalMutexLock(&port->lock);
632 if (DataFifoIsEmpty(&port->readFifo)) {
633 OsalMutexUnlock(&port->lock);
634 return 0;
635 }
636 fifoLen = DataFifoLen(&port->readFifo);
637 buf = (uint8_t *)OsalMemCalloc(fifoLen + 1);
638 if (buf == NULL) {
639 HDF_LOGE("%s: OsalMemCalloc error", __func__);
640 OsalMutexUnlock(&port->lock);
641 return HDF_ERR_MALLOC_FAIL;
642 }
643 for (i = 0; i < fifoLen; i++) {
644 len = DataFifoRead(&port->readFifo, buf + i, 1);
645 if (len == 0) {
646 HDF_LOGE("%s: no data", __func__);
647 ret = HDF_ERR_IO;
648 goto OUT;
649 }
650 if (*(buf + i) == 0) {
651 if (i == 0) {
652 goto OUT;
653 }
654 break;
655 }
656 }
657
658 if (!HdfSbufWriteString(reply, (const char *)buf)) {
659 HDF_LOGE("%s: sbuf write buffer failed", __func__);
660 ret = HDF_ERR_IO;
661 }
662 OUT:
663 if (port->acm) {
664 UsbSerialStartRx(port);
665 }
666 OsalMemFree(buf);
667 OsalMutexUnlock(&port->lock);
668 return ret;
669 }
670
UsbSerialWrite(struct UsbSerial * port,struct HdfSBuf * data)671 static int32_t UsbSerialWrite(struct UsbSerial *port, struct HdfSBuf *data)
672 {
673 uint32_t size;
674 const char *tmp = NULL;
675
676 OsalMutexLock(&port->lock);
677
678 tmp = HdfSbufReadString(data);
679 if (tmp == NULL) {
680 HDF_LOGE("%s: sbuf read buffer failed", __func__);
681 return HDF_ERR_IO;
682 }
683 char *buf = OsalMemCalloc(strlen(tmp) + 1);
684 if (buf == NULL) {
685 HDF_LOGE("%s: OsalMemCalloc failed", __func__);
686 return HDF_ERR_IO;
687 }
688
689 int32_t ret = strcpy_s(buf, strlen(tmp) + 1, tmp);
690 if (ret != EOK) {
691 HDF_LOGE("%s: strcpy_s failed", __func__);
692 OsalMemFree(buf);
693 return HDF_ERR_IO;
694 }
695
696 size = DataFifoWrite(&port->writeFifo, (uint8_t *)buf, strlen(buf));
697
698 if (port->acm) {
699 UsbSerialStartTx(port);
700 }
701 OsalMutexUnlock(&port->lock);
702 OsalMemFree(buf);
703 return size;
704 }
705
UsbSerialGetBaudrate(struct UsbSerial * port,struct HdfSBuf * reply)706 static int32_t UsbSerialGetBaudrate(struct UsbSerial *port, struct HdfSBuf *reply)
707 {
708 uint32_t baudRate = Le32ToCpu(port->lineCoding.dwDTERate);
709 if (!HdfSbufWriteBuffer(reply, &baudRate, sizeof(baudRate))) {
710 HDF_LOGE("%s: sbuf write buffer failed", __func__);
711 return HDF_ERR_IO;
712 }
713 return HDF_SUCCESS;
714 }
715
UsbSerialSetBaudrate(struct UsbSerial * port,struct HdfSBuf * data)716 static int32_t UsbSerialSetBaudrate(struct UsbSerial *port, struct HdfSBuf *data)
717 {
718 uint32_t size;
719 uint32_t *baudRate = NULL;
720
721 if (!HdfSbufReadBuffer(data, (const void **)&baudRate, &size)) {
722 HDF_LOGE("%s: sbuf read buffer failed", __func__);
723 return HDF_ERR_IO;
724 }
725 port->lineCoding.dwDTERate = CpuToLe32(*baudRate);
726 if (port->acm) {
727 port->acm->lineCoding.dwDTERate = CpuToLe32(*baudRate);
728 }
729 return HDF_SUCCESS;
730 }
731
UsbSerialGetProp(struct UsbAcmDevice * acmDevice,struct HdfSBuf * data,struct HdfSBuf * reply)732 static int32_t UsbSerialGetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data,
733 struct HdfSBuf *reply)
734 {
735 struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
736 const char *propName = NULL;
737 char propValue[USB_MAX_PACKET_SIZE] = {0};
738 int32_t ret;
739
740 propName = HdfSbufReadString(data);
741 if (propName == NULL) {
742 return HDF_ERR_IO;
743 }
744 ret = UsbFnGetInterfaceProp(intf, propName, propValue);
745 if (ret) {
746 return HDF_ERR_IO;
747 }
748 if (!HdfSbufWriteString(reply, propValue)) {
749 HDF_LOGE("%s:failed to write result", __func__);
750 return HDF_ERR_IO;
751 }
752 return HDF_SUCCESS;
753 }
754
UsbSerialSetProp(struct UsbAcmDevice * acmDevice,struct HdfSBuf * data)755 static int32_t UsbSerialSetProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
756 {
757 struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
758 int32_t ret;
759 char tmp[USB_MAX_PACKET_SIZE] = {0};
760
761 const char *propName = HdfSbufReadString(data);
762 if (propName == NULL) {
763 return HDF_ERR_IO;
764 }
765 const char *propValue = HdfSbufReadString(data);
766 if (propValue == NULL) {
767 return HDF_ERR_IO;
768 }
769 (void)memset_s(&tmp, sizeof(tmp), 0, sizeof(tmp));
770 ret = snprintf_s(tmp, USB_MAX_PACKET_SIZE, USB_MAX_PACKET_SIZE - 1, "%s", propValue);
771 if (ret < 0) {
772 HDF_LOGE("%s: snprintf_s failed", __func__);
773 return HDF_FAILURE;
774 }
775 ret = UsbFnSetInterfaceProp(intf, propName, tmp);
776 if (ret) {
777 HDF_LOGE("%s: UsbFnInterfaceSetProp failed", __func__);
778 return HDF_ERR_IO;
779 }
780 return HDF_SUCCESS;
781 }
782
UsbSerialRegistPropAGet(const struct UsbFnInterface * intf,const char * name,const char * value)783 static int32_t UsbSerialRegistPropAGet(const struct UsbFnInterface *intf, const char *name, const char *value)
784 {
785 HDF_LOGE("%s: name = %s", __func__, name);
786 HDF_LOGE("%s: value = %s", __func__, value);
787
788 return 0;
789 }
790
UsbSerialRegistPropASet(const struct UsbFnInterface * intf,const char * name,const char * value)791 static int32_t UsbSerialRegistPropASet(const struct UsbFnInterface *intf, const char *name, const char *value)
792 {
793 HDF_LOGE("%s: name = %s", __func__, name);
794 HDF_LOGE("%s: value = %s", __func__, value);
795
796 return 0;
797 }
798
UsbSerialRegistProp(struct UsbAcmDevice * acmDevice,struct HdfSBuf * data)799 static int32_t UsbSerialRegistProp(struct UsbAcmDevice *acmDevice, struct HdfSBuf *data)
800 {
801 struct UsbFnInterface *intf = acmDevice->ctrlIface.fn;
802 struct UsbFnRegistInfo registInfo;
803 int32_t ret;
804
805 const char *propName = HdfSbufReadString(data);
806 if (propName == NULL) {
807 return HDF_ERR_IO;
808 }
809 const char *propValue = HdfSbufReadString(data);
810 if (propValue == NULL) {
811 return HDF_ERR_IO;
812 }
813 registInfo.name = propName;
814 registInfo.value = propValue;
815 registInfo.getProp = UsbSerialRegistPropAGet;
816 registInfo.setProp = UsbSerialRegistPropASet;
817 ret = UsbFnRegistInterfaceProp(intf, ®istInfo);
818 if (ret) {
819 HDF_LOGE("%s: UsbFnInterfaceSetProp failed", __func__);
820 return HDF_ERR_IO;
821 }
822 return HDF_SUCCESS;
823 }
824
AcmSerialCmd(struct UsbAcmDevice * acm,int32_t cmd,struct UsbSerial * port,struct HdfSBuf * data,struct HdfSBuf * reply)825 static int32_t AcmSerialCmd(struct UsbAcmDevice *acm, int32_t cmd, struct UsbSerial *port,
826 struct HdfSBuf *data, struct HdfSBuf *reply)
827 {
828 switch (cmd) {
829 case USB_SERIAL_OPEN:
830 return UsbSerialOpen(port);
831 case USB_SERIAL_CLOSE:
832 return UsbSerialClose(port);
833 case USB_SERIAL_READ:
834 return UsbSerialRead(port, reply);
835 case USB_SERIAL_WRITE:
836 return UsbSerialWrite(port, data);
837 case USB_SERIAL_GET_BAUDRATE:
838 return UsbSerialGetBaudrate(port, reply);
839 case USB_SERIAL_SET_BAUDRATE:
840 return UsbSerialSetBaudrate(port, data);
841 case USB_SERIAL_SET_PROP:
842 return UsbSerialSetProp(acm, data);
843 case USB_SERIAL_GET_PROP:
844 return UsbSerialGetProp(acm, data, reply);
845 case USB_SERIAL_REGIST_PROP:
846 return UsbSerialRegistProp(acm, data);
847 case USB_SERIAL_WRITE_SPEED:
848 return UsbSerialSpeed(port);
849 case USB_SERIAL_WRITE_GET_TEMP_SPEED:
850 return UsbSerialGetTempSpeed(port, reply);
851 case USB_SERIAL_WRITE_SPEED_DONE:
852 return UsbSerialSpeedDone(port);
853 case USB_SERIAL_WRITE_GET_TEMP_SPEED_UINT32:
854 return UsbSerialGetTempSpeedInt(port, reply);
855 case USB_SERIAL_READ_SPEED:
856 return UsbSerialReadSpeedStart(port);
857 case USB_SERIAL_READ_GET_TEMP_SPEED:
858 return UsbSerialGetTempReadSpeed(port, reply);
859 case USB_SERIAL_READ_SPEED_DONE:
860 return UsbSerialReadSpeedDone(port);
861 case USB_SERIAL_READ_GET_TEMP_SPEED_UINT32:
862 return UsbSerialGetTempReadSpeedInt(port, reply);
863 default:
864 return HDF_ERR_NOT_SUPPORT;
865 }
866 return HDF_SUCCESS;
867 }
868
AcmDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)869 static int32_t AcmDeviceDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
870 struct HdfSBuf *data, struct HdfSBuf *reply)
871 {
872 struct UsbAcmDevice *acm = NULL;
873 struct UsbSerial *port = NULL;
874
875 if (client == NULL || client->device == NULL || client->device->service == NULL) {
876 HDF_LOGE("%s: client is NULL", __func__);
877 return HDF_ERR_INVALID_OBJECT;
878 }
879
880 acm = (struct UsbAcmDevice *)client->device->service;
881 if (acm == NULL) {
882 return HDF_ERR_IO;
883 }
884
885 if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) {
886 HDF_LOGE("%{public}s:%{public}d check interface desc fail", __func__, __LINE__);
887 return HDF_ERR_INVALID_PARAM;
888 }
889
890 switch (cmd) {
891 case USB_SERIAL_INIT:
892 return UsbSerialInit(acm);
893 case USB_SERIAL_RELEASE:
894 return UsbSerialRelease(acm);
895 default:
896 HDF_LOGE("%s: unknown cmd %d", __func__, cmd);
897 break;
898 }
899 port = acm->port;
900 if (port == NULL) {
901 return HDF_ERR_IO;
902 }
903
904 return AcmSerialCmd(acm, cmd, port, data, reply);
905 }
906
AcmDeviceDestroy(struct UsbAcmDevice * acm)907 static void AcmDeviceDestroy(struct UsbAcmDevice *acm)
908 {
909 if (acm == NULL) {
910 return;
911 }
912 OsalMemFree(acm);
913 }
914
AcmCtrlComplete(uint8_t pipe,struct UsbFnRequest * req)915 static void AcmCtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
916 {
917 if (req == NULL) {
918 return;
919 }
920 struct CtrlInfo *ctrlInfo = (struct CtrlInfo *)req->context;
921 if (ctrlInfo == NULL) {
922 return;
923 }
924 struct UsbAcmDevice *acm = ctrlInfo->acm;
925 if (req->status != USB_REQUEST_COMPLETED) {
926 HDF_LOGD("%s: ctrl completion error %d", __func__, req->status);
927 goto OUT;
928 }
929
930 if (ctrlInfo->request == USB_DDK_CDC_REQ_SET_LINE_CODING) {
931 struct UsbCdcLineCoding *value = req->buf;
932 if (req->actual == sizeof(*value)) {
933 acm->lineCoding = *value;
934 HDF_LOGD("dwDTERate = %d", acm->lineCoding.dwDTERate);
935 HDF_LOGD("bCharFormat = %d", acm->lineCoding.bCharFormat);
936 HDF_LOGD("bParityType = %d", acm->lineCoding.bParityType);
937 HDF_LOGD("bDataBits = %d", acm->lineCoding.bDataBits);
938 }
939 }
940
941 OUT:
942 DListInsertTail(&req->list, &acm->ctrlPool);
943 }
944
AcmAllocCtrlRequests(struct UsbAcmDevice * acm,int32_t num)945 static int32_t AcmAllocCtrlRequests(struct UsbAcmDevice *acm, int32_t num)
946 {
947 struct DListHead *head = &acm->ctrlPool;
948 struct UsbFnRequest *req = NULL;
949 struct CtrlInfo *ctrlInfo = NULL;
950 int32_t i;
951
952 DListHeadInit(&acm->ctrlPool);
953 acm->ctrlReqNum = 0;
954
955 for (i = 0; i < num; i++) {
956 ctrlInfo = (struct CtrlInfo *)OsalMemCalloc(sizeof(*ctrlInfo));
957 if (ctrlInfo == NULL) {
958 HDF_LOGE("%s: Allocate ctrlInfo failed", __func__);
959 goto OUT;
960 }
961 ctrlInfo->acm = acm;
962 req = UsbFnAllocCtrlRequest(acm->ctrlIface.handle,
963 sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));
964 if (req == NULL) {
965 goto OUT;
966 }
967 req->complete = AcmCtrlComplete;
968 req->context = ctrlInfo;
969 DListInsertTail(&req->list, head);
970 acm->ctrlReqNum++;
971 }
972 return HDF_SUCCESS;
973
974 OUT:
975 return DListIsEmpty(head) ? HDF_FAILURE : HDF_SUCCESS;
976 }
977
AcmFreeCtrlRequests(struct UsbAcmDevice * acm)978 static void AcmFreeCtrlRequests(struct UsbAcmDevice *acm)
979 {
980 struct DListHead *head = &acm->ctrlPool;
981 struct UsbFnRequest *req = NULL;
982
983 while (!DListIsEmpty(head)) {
984 req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
985 DListRemove(&req->list);
986 OsalMemFree(req->context);
987 (void)UsbFnFreeRequest(req);
988 acm->ctrlReqNum--;
989 }
990 }
991
992 static int32_t AcmNotifySerialState(struct UsbAcmDevice *acm);
AcmNotifyComplete(uint8_t pipe,struct UsbFnRequest * req)993 static void AcmNotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
994 {
995 struct UsbAcmDevice *acm = (struct UsbAcmDevice *)req->context;
996 bool pending = false;
997
998 if (acm == NULL) {
999 HDF_LOGE("%s: acm is null", __func__);
1000 return;
1001 }
1002
1003 OsalMutexLock(&acm->lock);
1004 /* estimate pending */
1005 if (req->status == PENDING_FLAG) {
1006 pending = acm->pending;
1007 }
1008 acm->notifyReq = req;
1009 OsalMutexUnlock(&acm->lock);
1010 if (pending) {
1011 AcmNotifySerialState(acm);
1012 }
1013 }
1014
AcmAllocNotifyRequest(struct UsbAcmDevice * acm)1015 static int32_t AcmAllocNotifyRequest(struct UsbAcmDevice *acm)
1016 {
1017 /* allocate notification request */
1018 acm->notifyReq = UsbFnAllocRequest(acm->ctrlIface.handle, acm->notifyPipe.id,
1019 sizeof(struct UsbCdcNotification) * 2);
1020 if (acm->notifyReq == NULL) {
1021 HDF_LOGE("%s: allocate notify request failed", __func__);
1022 return HDF_FAILURE;
1023 }
1024 acm->notifyReq->complete = AcmNotifyComplete;
1025 acm->notifyReq->context = acm;
1026
1027 return HDF_SUCCESS;
1028 }
1029
AcmFreeNotifyRequest(struct UsbAcmDevice * acm)1030 static void AcmFreeNotifyRequest(struct UsbAcmDevice *acm)
1031 {
1032 int32_t ret;
1033
1034 /* free notification request */
1035 ret = UsbFnFreeRequest(acm->notifyReq);
1036 if (ret != HDF_SUCCESS) {
1037 HDF_LOGE("%s: free notify request failed", __func__);
1038 return;
1039 }
1040 acm->notifyReq = NULL;
1041 }
1042
AcmEnable(struct UsbAcmDevice * acm)1043 static uint32_t AcmEnable(struct UsbAcmDevice *acm)
1044 {
1045 int32_t ret;
1046 struct UsbSerial *port = acm->port;
1047
1048 if (port == NULL) {
1049 HDF_LOGE("%s: port is null", __func__);
1050 return HDF_FAILURE;
1051 }
1052
1053 OsalMutexLock(&port->lock);
1054 port->acm = acm;
1055 acm->lineCoding = port->lineCoding;
1056
1057 ret = UsbSerialAllocFifo(&port->writeFifo, WRITE_BUF_SIZE);
1058 if (ret != HDF_SUCCESS) {
1059 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
1060 return HDF_FAILURE;
1061 }
1062 ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
1063 if (ret != HDF_SUCCESS) {
1064 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
1065 return HDF_FAILURE;
1066 }
1067
1068 ret = UsbSerialStartIo(port);
1069 if (ret != HDF_SUCCESS) {
1070 HDF_LOGE("%s: UsbSerialStartIo failed", __func__);
1071 }
1072 if (acm->notify && acm->notify->Connect) {
1073 acm->notify->Connect(acm);
1074 }
1075
1076 OsalMutexUnlock(&port->lock);
1077
1078 return HDF_SUCCESS;
1079 }
1080
AcmDisable(struct UsbAcmDevice * acm)1081 static uint32_t AcmDisable(struct UsbAcmDevice *acm)
1082 {
1083 struct UsbSerial *port = acm->port;
1084
1085 if (port == NULL) {
1086 HDF_LOGE("%s: port is null", __func__);
1087 return HDF_FAILURE;
1088 }
1089
1090 OsalMutexLock(&port->lock);
1091 port->lineCoding = acm->lineCoding;
1092
1093 UsbSerialFreeFifo(&port->writeFifo);
1094 UsbSerialFreeFifo(&port->readFifo);
1095
1096 OsalMutexUnlock(&port->lock);
1097
1098 return HDF_SUCCESS;
1099 }
1100
AcmGetCtrlReq(struct UsbAcmDevice * acm)1101 static struct UsbFnRequest *AcmGetCtrlReq(struct UsbAcmDevice *acm)
1102 {
1103 struct UsbFnRequest *req = NULL;
1104 struct DListHead *pool = &acm->ctrlPool;
1105
1106 if (!DListIsEmpty(pool)) {
1107 req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
1108 DListRemove(&req->list);
1109 }
1110 return req;
1111 }
1112
AcmSetup(struct UsbAcmDevice * acm,struct UsbFnCtrlRequest * setup)1113 static void AcmSetup(struct UsbAcmDevice *acm, struct UsbFnCtrlRequest *setup)
1114 {
1115 if (acm == NULL || setup == NULL) {
1116 return;
1117 }
1118 struct UsbFnRequest *req = NULL;
1119 struct CtrlInfo *ctrlInfo = NULL;
1120 uint16_t value = Le16ToCpu(setup->value);
1121 uint16_t length = Le16ToCpu(setup->length);
1122 int32_t ret = 0;
1123
1124 req = AcmGetCtrlReq(acm);
1125 if (req == NULL) {
1126 HDF_LOGE("%s: control request pool is empty", __func__);
1127 return;
1128 }
1129
1130 switch (setup->request) {
1131 case USB_DDK_CDC_REQ_SET_LINE_CODING:
1132 if (length != sizeof(struct UsbCdcLineCoding)) {
1133 goto OUT;
1134 }
1135 ret = (int)length;
1136 break;
1137 case USB_DDK_CDC_REQ_GET_LINE_CODING:
1138 ret = (int)MIN(length, sizeof(struct UsbCdcLineCoding));
1139 if (acm->lineCoding.dwDTERate == 0) {
1140 acm->lineCoding = acm->port->lineCoding;
1141 }
1142 if (memcpy_s(req->buf, ret, &acm->lineCoding, ret) != EOK) {
1143 return;
1144 }
1145 break;
1146 case USB_DDK_CDC_REQ_SET_CONTROL_LINE_STATE:
1147 ret = 0;
1148 acm->handshakeBits = value;
1149 break;
1150 default:
1151 HDF_LOGE("%s: setup request is not supported", __func__);
1152 break;
1153 }
1154
1155 OUT:
1156 ctrlInfo = (struct CtrlInfo *)req->context;
1157 ctrlInfo->request = setup->request;
1158 req->length = ret;
1159 ret = UsbFnSubmitRequestAsync(req);
1160 if (ret != HDF_SUCCESS) {
1161 HDF_LOGE("%s: acm send setup response error", __func__);
1162 }
1163 }
1164
AcmSuspend(struct UsbAcmDevice * acm)1165 static void AcmSuspend(struct UsbAcmDevice *acm)
1166 {
1167 struct UsbSerial *port = acm->port;
1168
1169 if (port == NULL) {
1170 HDF_LOGE("%s: port is null", __func__);
1171 return;
1172 }
1173
1174 OsalMutexLock(&port->lock);
1175 port->suspended = true;
1176 OsalMutexUnlock(&port->lock);
1177 }
1178
AcmResume(struct UsbAcmDevice * acm)1179 static void AcmResume(struct UsbAcmDevice *acm)
1180 {
1181 int32_t ret;
1182 struct UsbSerial *port = acm->port;
1183 if (port == NULL) {
1184 HDF_LOGE("%s: port is null", __func__);
1185 return;
1186 }
1187
1188 OsalMutexLock(&port->lock);
1189 port->suspended = false;
1190 if (!port->startDelayed) {
1191 OsalMutexUnlock(&port->lock);
1192 return;
1193 }
1194 ret = UsbSerialStartIo(port);
1195 if (ret != HDF_SUCCESS) {
1196 HDF_LOGE("%s: UsbSerialStartIo failed", __func__);
1197 }
1198 if (acm->notify && acm->notify->Connect) {
1199 acm->notify->Connect(acm);
1200 }
1201 port->startDelayed = false;
1202 OsalMutexUnlock(&port->lock);
1203 }
1204
UsbAcmEventCallback(struct UsbFnEvent * event)1205 static void UsbAcmEventCallback(struct UsbFnEvent *event)
1206 {
1207 struct UsbAcmDevice *acm = NULL;
1208
1209 if (event == NULL || event->context == NULL) {
1210 HDF_LOGE("%s: event is null", __func__);
1211 return;
1212 }
1213
1214 acm = (struct UsbAcmDevice *)event->context;
1215 switch (event->type) {
1216 case USBFN_STATE_BIND:
1217 HDF_LOGI("%s: receive bind event", __func__);
1218 break;
1219 case USBFN_STATE_UNBIND:
1220 HDF_LOGI("%s: receive unbind event", __func__);
1221 break;
1222 case USBFN_STATE_ENABLE:
1223 HDF_LOGI("%s: receive enable event", __func__);
1224 AcmEnable(acm);
1225 break;
1226 case USBFN_STATE_DISABLE:
1227 HDF_LOGI("%s: receive disable event", __func__);
1228 AcmDisable(acm);
1229 acm->enableEvtCnt = 0;
1230 break;
1231 case USBFN_STATE_SETUP:
1232 HDF_LOGI("%s: receive setup event", __func__);
1233 if (event->setup != NULL) {
1234 AcmSetup(acm, event->setup);
1235 }
1236 break;
1237 case USBFN_STATE_SUSPEND:
1238 HDF_LOGI("%s: receive suspend event", __func__);
1239 AcmSuspend(acm);
1240 break;
1241 case USBFN_STATE_RESUME:
1242 HDF_LOGI("%s: receive resume event", __func__);
1243 AcmResume(acm);
1244 break;
1245 default:
1246 break;
1247 }
1248 }
1249
AcmSendNotifyRequest(struct UsbAcmDevice * acm,uint8_t type,uint16_t value,const void * data,uint32_t length)1250 static int32_t AcmSendNotifyRequest(struct UsbAcmDevice *acm, uint8_t type,
1251 uint16_t value, const void *data, uint32_t length)
1252 {
1253 struct UsbFnRequest *req = acm->notifyReq;
1254 struct UsbCdcNotification *notify = NULL;
1255 int32_t ret;
1256
1257 if (req == NULL || req->buf == NULL) {
1258 HDF_LOGE("%s: req is null", __func__);
1259 return HDF_FAILURE;
1260 }
1261
1262 acm->notifyReq = NULL;
1263 acm->pending = false;
1264 req->length = sizeof(*notify) + length;
1265
1266 notify = (struct UsbCdcNotification *)req->buf;
1267 notify->bmRequestType = USB_DDK_DIR_IN | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
1268 notify->bNotificationType = type;
1269 notify->wValue = CpuToLe16(value);
1270 notify->wIndex = CpuToLe16(acm->ctrlIface.fn->info.index);
1271 notify->wLength = CpuToLe16(length);
1272 ret = memcpy_s((void *)(notify + 1), length, data, length);
1273 if (ret != EOK) {
1274 HDF_LOGE("%s: memcpy_s failed", __func__);
1275 return HDF_FAILURE;
1276 }
1277
1278 ret = UsbFnSubmitRequestAsync(req);
1279 if (ret != HDF_SUCCESS) {
1280 HDF_LOGE("%s: send notify request failed", __func__);
1281 acm->notifyReq = req;
1282 }
1283
1284 return ret;
1285 }
1286
AcmNotifySerialState(struct UsbAcmDevice * acm)1287 static int32_t AcmNotifySerialState(struct UsbAcmDevice *acm)
1288 {
1289 int32_t ret = 0;
1290 uint16_t serialState;
1291
1292 OsalMutexLock(&acm->lock);
1293 if (acm->notifyReq) {
1294 HDF_LOGD("acm serial state %04x\n", acm->serialState);
1295 serialState = CpuToLe16(acm->serialState);
1296 ret = AcmSendNotifyRequest(acm, USB_DDK_CDC_NOTIFY_SERIAL_STATE,
1297 0, &serialState, sizeof(acm->serialState));
1298 } else {
1299 acm->pending = true;
1300 }
1301 OsalMutexUnlock(&acm->lock);
1302
1303 return ret;
1304 }
1305
AcmConnect(struct UsbAcmDevice * acm)1306 static void AcmConnect(struct UsbAcmDevice *acm)
1307 {
1308 if (acm == NULL) {
1309 HDF_LOGE("%s: acm is null", __func__);
1310 return;
1311 }
1312 acm->serialState |= SERIAL_STATE_DSR | SERIAL_STATE_DCD;
1313 AcmNotifySerialState(acm);
1314 }
1315
AcmDisconnect(struct UsbAcmDevice * acm)1316 static void AcmDisconnect(struct UsbAcmDevice *acm)
1317 {
1318 if (acm == NULL) {
1319 HDF_LOGE("%s: acm is null", __func__);
1320 return;
1321 }
1322 acm->serialState &= ~(SERIAL_STATE_DSR | SERIAL_STATE_DCD);
1323 AcmNotifySerialState(acm);
1324 }
1325
AcmSendBreak(struct UsbAcmDevice * acm,int32_t duration)1326 static int32_t AcmSendBreak(struct UsbAcmDevice *acm, int32_t duration)
1327 {
1328 uint16_t state;
1329
1330 if (acm == NULL) {
1331 HDF_LOGE("%s: acm is null", __func__);
1332 return HDF_FAILURE;
1333 }
1334
1335 state = acm->serialState;
1336 state &= ~SERIAL_STATE_BREAK;
1337 if (duration)
1338 state |= SERIAL_STATE_BREAK;
1339
1340 acm->serialState = state;
1341 return AcmNotifySerialState(acm);
1342 }
1343
1344 static struct AcmNotifyMethod g_acmNotifyMethod = {
1345 .Connect = AcmConnect,
1346 .Disconnect = AcmDisconnect,
1347 .SendBreak = AcmSendBreak,
1348 };
1349
AcmParseEachPipe(struct UsbAcmDevice * acm,struct UsbAcmInterface * iface)1350 static int32_t AcmParseEachPipe(struct UsbAcmDevice *acm, struct UsbAcmInterface *iface)
1351 {
1352 struct UsbFnInterface *fnIface = iface->fn;
1353 int32_t ret;
1354 uint32_t i;
1355
1356 for (i = 0; i < fnIface->info.numPipes; i++) {
1357 struct UsbFnPipeInfo pipeInfo;
1358 (void)memset_s(&pipeInfo, sizeof(pipeInfo), 0, sizeof(pipeInfo));
1359 ret = UsbFnGetInterfacePipeInfo(fnIface, i, &pipeInfo);
1360 if (ret != HDF_SUCCESS) {
1361 HDF_LOGE("%s: get pipe info error", __func__);
1362 return ret;
1363 }
1364 switch (pipeInfo.type) {
1365 case USB_PIPE_TYPE_INTERRUPT:
1366 acm->notifyPipe.id = pipeInfo.id;
1367 acm->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
1368 acm->ctrlIface = *iface;
1369 break;
1370 case USB_PIPE_TYPE_BULK:
1371 if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
1372 acm->dataInPipe.id = pipeInfo.id;
1373 acm->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
1374 acm->dataIface = *iface;
1375 } else {
1376 acm->dataOutPipe.id = pipeInfo.id;
1377 acm->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
1378 }
1379 break;
1380 default:
1381 HDF_LOGE("%s: pipe type %d don't support",
1382 __func__, pipeInfo.type);
1383 break;
1384 }
1385 }
1386
1387 return HDF_SUCCESS;
1388 }
1389
AcmParseAcmIface(struct UsbAcmDevice * acm,struct UsbFnInterface * fnIface)1390 static int32_t AcmParseAcmIface(struct UsbAcmDevice *acm, struct UsbFnInterface *fnIface)
1391 {
1392 int32_t ret;
1393 struct UsbAcmInterface iface;
1394 UsbFnInterfaceHandle handle = UsbFnOpenInterface(fnIface);
1395 if (handle == NULL) {
1396 HDF_LOGE("%s: open interface failed", __func__);
1397 return HDF_FAILURE;
1398 }
1399 iface.fn = fnIface;
1400 iface.handle = handle;
1401
1402 ret = AcmParseEachPipe(acm, &iface);
1403 if (ret != HDF_SUCCESS) {
1404 return HDF_FAILURE;
1405 }
1406 return HDF_SUCCESS;
1407 }
1408
AcmParseEachIface(struct UsbAcmDevice * acm,struct UsbFnDevice * fnDev)1409 static int32_t AcmParseEachIface(struct UsbAcmDevice *acm, struct UsbFnDevice *fnDev)
1410 {
1411 struct UsbFnInterface *fnIface = NULL;
1412 uint32_t i;
1413 if (fnDev == NULL) {
1414 return HDF_FAILURE;
1415 }
1416 for (i = 0; i < fnDev->numInterfaces; i++) {
1417 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i);
1418 if (fnIface == NULL) {
1419 HDF_LOGE("%s: get interface failed", __func__);
1420 return HDF_FAILURE;
1421 }
1422
1423 if (fnIface->info.subclass == USB_DDK_CDC_SUBCLASS_ACM) {
1424 (void)AcmParseAcmIface(acm, fnIface);
1425 fnIface = (struct UsbFnInterface *)UsbFnGetInterface(fnDev, i + 1);
1426 if (fnIface == NULL) {
1427 HDF_LOGE("%s: get interface failed", __func__);
1428 return HDF_FAILURE;
1429 }
1430 (void)AcmParseAcmIface(acm, fnIface);
1431 return HDF_SUCCESS;
1432 }
1433 }
1434 return HDF_FAILURE;
1435 }
1436
AcmCreateFuncDevice(struct UsbAcmDevice * acm,struct DeviceResourceIface * iface)1437 static int32_t AcmCreateFuncDevice(struct UsbAcmDevice *acm,
1438 struct DeviceResourceIface *iface)
1439 {
1440 int32_t ret;
1441 struct UsbFnDevice *fnDev = NULL;
1442
1443 if (iface->GetString(acm->device->property, "udc_name",
1444 (const char **)&acm->udcName, UDC_NAME) != HDF_SUCCESS) {
1445 HDF_LOGE("%s: read udc_name failed, use default", __func__);
1446 }
1447
1448 fnDev = (struct UsbFnDevice *)UsbFnGetDevice(acm->udcName);
1449 if (fnDev == NULL) {
1450 HDF_LOGE("%s: create usb function device failed", __func__);
1451 return HDF_FAILURE;
1452 }
1453
1454 ret = AcmParseEachIface(acm, fnDev);
1455 if (ret != HDF_SUCCESS) {
1456 HDF_LOGE("%s: get pipes failed", __func__);
1457 return HDF_FAILURE;
1458 }
1459
1460 acm->fnDev = fnDev;
1461 return HDF_SUCCESS;
1462 }
1463
AcmReleaseFuncDevice(struct UsbAcmDevice * acm)1464 static int32_t AcmReleaseFuncDevice(struct UsbAcmDevice *acm)
1465 {
1466 int32_t ret = HDF_SUCCESS;
1467 if (acm->fnDev == NULL) {
1468 HDF_LOGE("%s: fnDev is null", __func__);
1469 return HDF_FAILURE;
1470 }
1471 AcmFreeCtrlRequests(acm);
1472 AcmFreeNotifyRequest(acm);
1473 (void)UsbFnCloseInterface(acm->ctrlIface.handle);
1474 (void)UsbFnCloseInterface(acm->dataIface.handle);
1475 (void)UsbFnStopRecvInterfaceEvent(acm->ctrlIface.fn);
1476 return ret;
1477 }
1478
UsbSerialAlloc(struct UsbAcmDevice * acm)1479 static int32_t UsbSerialAlloc(struct UsbAcmDevice *acm)
1480 {
1481 struct UsbSerial *port = NULL;
1482
1483 port = (struct UsbSerial *)OsalMemCalloc(sizeof(*port));
1484 if (port == NULL) {
1485 HDF_LOGE("%s: Alloc usb serial port failed", __func__);
1486 return HDF_FAILURE;
1487 }
1488
1489 if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
1490 HDF_LOGE("%s: init lock fail!", __func__);
1491 return HDF_FAILURE;
1492 }
1493
1494 DListHeadInit(&port->readPool);
1495 DListHeadInit(&port->readQueue);
1496 DListHeadInit(&port->writePool);
1497
1498 port->lineCoding.dwDTERate = CpuToLe32(PORT_RATE);
1499 port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
1500 port->lineCoding.bParityType = USB_CDC_NO_PARITY;
1501 port->lineCoding.bDataBits = DATA_BIT;
1502
1503 acm->port = port;
1504 return HDF_SUCCESS;
1505 }
1506
UsbSerialFree(struct UsbAcmDevice * acm)1507 static void UsbSerialFree(struct UsbAcmDevice *acm)
1508 {
1509 struct UsbSerial *port = acm->port;
1510
1511 if (port == NULL) {
1512 HDF_LOGE("%s: port is null", __func__);
1513 return;
1514 }
1515 OsalMemFree(port);
1516 }
1517
1518 /* HdfDriverEntry implementations */
AcmDriverBind(struct HdfDeviceObject * device)1519 static int32_t AcmDriverBind(struct HdfDeviceObject *device)
1520 {
1521 struct UsbAcmDevice *acm = NULL;
1522
1523 if (device == NULL) {
1524 HDF_LOGE("%s: device is null", __func__);
1525 return HDF_ERR_INVALID_OBJECT;
1526 }
1527
1528 acm = (struct UsbAcmDevice *)OsalMemCalloc(sizeof(*acm));
1529 if (acm == NULL) {
1530 HDF_LOGE("%s: Alloc usb acm device failed", __func__);
1531 return HDF_FAILURE;
1532 }
1533
1534 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
1535 HDF_LOGE("%s: init lock fail!", __func__);
1536 OsalMemFree(acm);
1537 return HDF_FAILURE;
1538 }
1539
1540 if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
1541 HDF_LOGE(" Set Desc fail!");
1542 OsalMemFree(acm);
1543 return HDF_FAILURE;
1544 }
1545
1546 acm->device = device;
1547 device->service = &(acm->service);
1548 acm->device->service->Dispatch = AcmDeviceDispatch;
1549 acm->notify = NULL;
1550 acm->initFlag = false;
1551 return HDF_SUCCESS;
1552 }
1553
UsbSerialInit(struct UsbAcmDevice * acm)1554 static int32_t UsbSerialInit(struct UsbAcmDevice *acm)
1555 {
1556 struct DeviceResourceIface *iface = NULL;
1557 int32_t ret;
1558
1559 if (acm == NULL || acm->initFlag) {
1560 HDF_LOGE("%s: acm is null", __func__);
1561 return HDF_FAILURE;
1562 }
1563 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
1564 if (iface == NULL || iface->GetUint32 == NULL) {
1565 HDF_LOGE("%s: face is invalid", __func__);
1566 return HDF_FAILURE;
1567 }
1568
1569 ret = AcmCreateFuncDevice(acm, iface);
1570 if (ret != HDF_SUCCESS) {
1571 HDF_LOGE("%s: AcmCreateFuncDevice failed", __func__);
1572 return HDF_FAILURE;
1573 }
1574
1575 ret = UsbSerialAlloc(acm);
1576 if (ret != HDF_SUCCESS) {
1577 HDF_LOGE("%s: UsbSerialAlloc failed", __func__);
1578 goto ERR;
1579 }
1580
1581 ret = AcmAllocCtrlRequests(acm, CTRL_REQUEST_NUM);
1582 if (ret != HDF_SUCCESS) {
1583 HDF_LOGE("%s: AcmAllocCtrlRequests failed", __func__);
1584 goto ERR;
1585 }
1586
1587 ret = AcmAllocNotifyRequest(acm);
1588 if (ret != HDF_SUCCESS) {
1589 HDF_LOGE("%s: AcmAllocNotifyRequest failed", __func__);
1590 goto ERR;
1591 }
1592
1593 ret = UsbFnStartRecvInterfaceEvent(acm->ctrlIface.fn, 0xff, UsbAcmEventCallback, acm);
1594 if (ret != HDF_SUCCESS) {
1595 HDF_LOGE("%s: register event callback failed", __func__);
1596 goto ERR;
1597 }
1598
1599 acm->notify = &g_acmNotifyMethod;
1600 acm->initFlag = true;
1601 return HDF_SUCCESS;
1602
1603 ERR:
1604 UsbSerialFree(acm);
1605 (void)AcmReleaseFuncDevice(acm);
1606 return ret;
1607 }
1608
UsbSerialRelease(struct UsbAcmDevice * acm)1609 static int32_t UsbSerialRelease(struct UsbAcmDevice *acm)
1610 {
1611 if (acm == NULL || acm->initFlag == false) {
1612 HDF_LOGE("%s: acm is null", __func__);
1613 return HDF_FAILURE;
1614 }
1615 (void)AcmReleaseFuncDevice(acm);
1616 UsbSerialFree(acm);
1617 acm->initFlag = false;
1618 return 0;
1619 }
1620
AcmDriverInit(struct HdfDeviceObject * device)1621 static int32_t AcmDriverInit(struct HdfDeviceObject *device)
1622 {
1623 HDF_LOGI("%s: do nothing...", __func__);
1624 return 0;
1625 }
1626
AcmDriverRelease(struct HdfDeviceObject * device)1627 static void AcmDriverRelease(struct HdfDeviceObject *device)
1628 {
1629 struct UsbAcmDevice *acm = NULL;
1630 if (device == NULL) {
1631 HDF_LOGE("%s: device is NULL", __func__);
1632 return;
1633 }
1634
1635 acm = (struct UsbAcmDevice *)device->service;
1636 if (acm == NULL) {
1637 HDF_LOGE("%s: acm is null", __func__);
1638 return;
1639 }
1640 (void)OsalMutexDestroy(&acm->lock);
1641 AcmDeviceDestroy(acm);
1642 }
1643
1644 struct HdfDriverEntry g_acmDriverEntry = {
1645 .moduleVersion = 1,
1646 .moduleName = "usbfn_cdcacm",
1647 .Bind = AcmDriverBind,
1648 .Init = AcmDriverInit,
1649 .Release = AcmDriverRelease,
1650 };
1651
1652 HDF_INIT(g_acmDriverEntry);
1653