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 "usb_serial_rawapi.h"
17 #include <unistd.h>
18 #include "osal_mem.h"
19 #include "osal_time.h"
20 #include "securec.h"
21 #include "hdf_base.h"
22 #include "hdf_log.h"
23 #include "hdf_usb_pnp_manage.h"
24
25 #define HDF_LOG_TAG USB_HOST_ACM_RAW_API
26 #define USB_CTRL_REQ_SIZE 64
27 #define USB_IO_THREAD_STACK_SIZE 8192
28 #define USB_RAW_IO_SLEEP_MS_TIME 100
29 #define USB_RAW_IO_STOP_WAIT_MAX_TIME 3
30
31 static struct UsbRawRequest *g_syncRequest = NULL;
32 static UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING;
33 struct OsalMutex g_stopIoLock;
34 static bool g_rawAcmReleaseFlag = false;
35
36 static int32_t SerialSendCtrlMsg(struct AcmDevice *acm, uint8_t request,
37 uint16_t value, void *buf, uint16_t len);
38 static void AcmWriteBulkCallback(const void *requestArg);
39 static int32_t UsbSerialInit(struct AcmDevice *acm);
40 static void UsbSerialRelease(struct AcmDevice *acm);
41
UsbIoThread(void * data)42 static int32_t UsbIoThread(void *data)
43 {
44 int32_t ret;
45 struct AcmDevice *acm = (struct AcmDevice *)data;
46
47 for (;;) {
48 if (acm == NULL) {
49 HDF_LOGE("%s:%d acm is NULL", __func__, __LINE__);
50 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
51 continue;
52 }
53
54 if (acm->devHandle == NULL) {
55 HDF_LOGE("%s:%d acm->devHandle is NULL!", __func__, __LINE__);
56 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
57 continue;
58 }
59
60 ret = UsbRawHandleRequests(acm->devHandle);
61 if ((ret < 0) || (g_stopIoStatus != USB_RAW_IO_PROCESS_RUNNING)) {
62 HDF_LOGE("%s:%d UsbIoThread faile, g_stopIoStatus=%d ret=%d ",
63 __func__, __LINE__, g_stopIoStatus, ret);
64 break;
65 }
66 }
67
68 OsalMutexLock(&g_stopIoLock);
69 g_stopIoStatus = USB_RAW_IO_PROCESS_STOPED;
70 OsalMutexUnlock(&g_stopIoLock);
71
72 HDF_LOGD("%s:%d exit", __func__, __LINE__);
73
74 return HDF_SUCCESS;
75 }
76
UsbStartIo(struct AcmDevice * acm)77 static int32_t UsbStartIo(struct AcmDevice *acm)
78 {
79 struct OsalThreadParam threadCfg;
80 int32_t ret;
81
82 HDF_LOGI("%s start", __func__);
83
84 OsalMutexInit(&g_stopIoLock);
85
86 OsalMutexLock(&g_stopIoLock);
87 g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING;
88 OsalMutexUnlock(&g_stopIoLock);
89
90 /* creat Io thread */
91 (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
92 threadCfg.name = "usb io thread";
93 threadCfg.priority = OSAL_THREAD_PRI_LOW;
94 threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE;
95
96 ret = OsalThreadCreate(&acm->ioThread, \
97 (OsalThreadEntry)UsbIoThread, (void *)acm);
98 if (ret != HDF_SUCCESS) {
99 HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ",
100 __func__, __LINE__, ret);
101 return ret;
102 }
103
104 ret = OsalThreadStart(&acm->ioThread, &threadCfg);
105 if (ret != HDF_SUCCESS) {
106 HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ",
107 __func__, __LINE__, ret);
108 return ret;
109 }
110
111 return HDF_SUCCESS;
112 }
113
UsbStopIo(struct AcmDevice * acm)114 static void UsbStopIo(struct AcmDevice *acm)
115 {
116 int32_t ret;
117 int32_t i = 0;
118
119 if (g_stopIoStatus != USB_RAW_IO_PROCESS_STOPED) {
120 HDF_LOGD("%s:%d not stoped", __func__, __LINE__);
121 OsalMutexLock(&g_stopIoLock);
122 g_stopIoStatus = USB_RAW_IO_PROCESS_STOP;
123 OsalMutexUnlock(&g_stopIoLock);
124 } else {
125 HDF_LOGD("%s:%d stoped", __func__, __LINE__);
126 }
127
128 while (g_stopIoStatus != USB_RAW_IO_PROCESS_STOPED) {
129 i++;
130 OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME);
131 if (i > USB_RAW_IO_STOP_WAIT_MAX_TIME) {
132 HDF_LOGD("%s:%d", __func__, __LINE__);
133 break;
134 }
135 }
136
137 ret = OsalThreadDestroy(&acm->ioThread);
138 if (ret != HDF_SUCCESS) {
139 HDF_LOGE("%s:%d OsalThreadDestroy faile, ret=%d ",
140 __func__, __LINE__, ret);
141 }
142
143 OsalMutexDestroy(&g_stopIoLock);
144
145 return;
146 }
147
UsbGetConfigDescriptor(UsbRawHandle * devHandle,struct UsbRawConfigDescriptor ** config)148 static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config)
149 {
150 UsbRawDevice *dev = NULL;
151 int32_t activeConfig;
152 int32_t ret;
153
154 if (devHandle == NULL) {
155 HDF_LOGE("%s:%d devHandle is NULL",
156 __func__, __LINE__);
157 return HDF_ERR_INVALID_PARAM;
158 }
159
160 ret = UsbRawGetConfiguration(devHandle, &activeConfig);
161 if (ret) {
162 HDF_LOGE("%s:%d UsbRawGetConfiguration failed, ret=%d",
163 __func__, __LINE__, ret);
164 return HDF_FAILURE;
165 }
166 HDF_LOGE("%s:%d activeConfig=%d", __func__, __LINE__, activeConfig);
167 dev = UsbRawGetDevice(devHandle);
168 if (dev == NULL) {
169 HDF_LOGE("%s:%d UsbRawGetDevice failed",
170 __func__, __LINE__);
171 return HDF_FAILURE;
172 }
173
174 ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
175 if (ret) {
176 HDF_LOGE("UsbRawGetConfigDescriptor failed, ret=%d\n", ret);
177 return HDF_FAILURE;
178 }
179
180 return HDF_SUCCESS;
181 }
182
UsbGetBulkEndpoint(struct AcmDevice * acm,const struct UsbRawEndpointDescriptor * endPoint)183 static int32_t UsbGetBulkEndpoint(struct AcmDevice *acm, const struct UsbRawEndpointDescriptor *endPoint)
184 {
185 if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
186 /* get bulk in endpoint */
187 acm->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
188 if (acm->dataInEp == NULL) {
189 HDF_LOGE("%s:%d allocate dataInEp failed", __func__, __LINE__);
190 return HDF_FAILURE;
191 }
192 acm->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
193 acm->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
194 acm->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
195 } else {
196 /* get bulk out endpoint */
197 acm->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
198 if (acm->dataOutEp == NULL) {
199 HDF_LOGE("%s:%d allocate dataOutEp failed", __func__, __LINE__);
200 return HDF_FAILURE;
201 }
202 acm->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
203 acm->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
204 acm->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
205 }
206
207 return HDF_SUCCESS;
208 }
209
UsbParseConfigDescriptorProcess(struct AcmDevice * acm,const struct UsbRawInterface * interface,uint8_t interfaceIndex)210 static void UsbParseConfigDescriptorProcess(struct AcmDevice *acm,
211 const struct UsbRawInterface *interface, uint8_t interfaceIndex)
212 {
213 uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass;
214 uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
215
216 switch (ifaceClass) {
217 case USB_DDK_CLASS_COMM:
218 acm->ctrlIface = interfaceIndex;
219 acm->notifyEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
220 if (acm->notifyEp == NULL) {
221 HDF_LOGE("%s:%d allocate endpoint failed", __func__, __LINE__);
222 break;
223 }
224 /* get the first endpoint by default */
225 acm->notifyEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
226 acm->notifyEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
227 acm->notifyEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
228 break;
229 case USB_DDK_CLASS_CDC_DATA:
230 acm->dataIface = interfaceIndex;
231 for (uint8_t j = 0; j < numEndpoints; j++) {
232 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
233 if (UsbGetBulkEndpoint(acm, endPoint) != HDF_SUCCESS) {
234 break;
235 }
236 }
237 break;
238 default:
239 HDF_LOGE("%s:%d wrong descriptor type", __func__, __LINE__);
240 break;
241 }
242 }
243
UsbParseConfigDescriptor(struct AcmDevice * acm,struct UsbRawConfigDescriptor * config)244 static int32_t UsbParseConfigDescriptor(struct AcmDevice *acm, struct UsbRawConfigDescriptor *config)
245 {
246 uint8_t i;
247 int32_t ret;
248
249 if ((acm == NULL) || (config == NULL)) {
250 HDF_LOGE("%s:%d acm or config is NULL",
251 __func__, __LINE__);
252 return HDF_ERR_INVALID_PARAM;
253 }
254
255 for (i = 0; i < acm->interfaceCnt; i++) {
256 uint8_t interfaceIndex = acm->interfaceIndex[i];
257 const struct UsbRawInterface *interface = config->interface[interfaceIndex];
258
259 ret = UsbRawClaimInterface(acm->devHandle, interfaceIndex);
260 if (ret) {
261 HDF_LOGE("%s:%d claim interface %u failed",
262 __func__, __LINE__, i);
263 continue;
264 }
265
266 UsbParseConfigDescriptorProcess(acm, interface, interfaceIndex);
267 }
268
269 return HDF_SUCCESS;
270 }
271
UsbReleaseInterfaces(struct AcmDevice * acm)272 static void UsbReleaseInterfaces(struct AcmDevice *acm)
273 {
274 if ((acm == NULL) || (acm->devHandle == NULL)) {
275 HDF_LOGE("%s:%d acm is NULL",
276 __func__, __LINE__);
277 return;
278 }
279
280 (void)UsbRawReleaseInterface(acm->devHandle, acm->ctrlIface);
281 (void)UsbRawReleaseInterface(acm->devHandle, acm->dataIface);
282
283 if (acm->notifyEp) {
284 OsalMemFree(acm->notifyEp);
285 acm->notifyEp = NULL;
286 }
287 if (acm->dataInEp) {
288 OsalMemFree(acm->dataInEp);
289 acm->dataInEp = NULL;
290 }
291 if (acm->dataOutEp) {
292 OsalMemFree(acm->dataOutEp);
293 acm->dataOutEp = NULL;
294 }
295 }
296
UsbAllocWriteRequests(struct AcmDevice * acm)297 static int32_t UsbAllocWriteRequests(struct AcmDevice *acm)
298 {
299 int32_t i;
300
301 for (i = 0; i < ACM_NW; i++) {
302 struct AcmWb *snd = &acm->wb[i];
303 snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize);
304 snd->instance = acm;
305 if (snd->request == NULL) {
306 HDF_LOGE("%s: UsbRawAllocRequest failed", __func__);
307 return HDF_ERR_MALLOC_FAIL;
308 }
309 }
310
311 return HDF_SUCCESS;
312 }
313
UsbFreeWriteRequests(struct AcmDevice * acm)314 static void UsbFreeWriteRequests(struct AcmDevice *acm)
315 {
316 int32_t i;
317 struct AcmWb *snd = NULL;
318
319 for (i = 0; i < ACM_NW; i++) {
320 snd = &acm->wb[i];
321 if (snd->request != NULL) {
322 UsbRawFreeRequest(snd->request);
323 snd->request = NULL;
324 }
325 }
326 }
327
AcmWbAlloc(const struct AcmDevice * acm)328 static int32_t AcmWbAlloc(const struct AcmDevice *acm)
329 {
330 struct AcmWb *wb = NULL;
331 int32_t i;
332
333 for (i = 0; i < ACM_NW; i++) {
334 wb = (struct AcmWb *)&acm->wb[i];
335 if (!wb->use) {
336 wb->use = 1;
337 wb->len = 0;
338 return i;
339 }
340 }
341 return -1;
342 }
343
UsbSerialAllocFifo(struct DataFifo * fifo,uint32_t size)344 static int32_t UsbSerialAllocFifo(struct DataFifo *fifo, uint32_t size)
345 {
346 if (!DataFifoIsInitialized(fifo)) {
347 void *data = OsalMemAlloc(size);
348 if (data == NULL) {
349 HDF_LOGE("%s:allocate failed", __func__);
350 return HDF_ERR_MALLOC_FAIL;
351 }
352 DataFifoInit(fifo, size, data);
353 }
354 return HDF_SUCCESS;
355 }
356
UsbSerialFreeFifo(const struct DataFifo * fifo)357 static void UsbSerialFreeFifo(const struct DataFifo *fifo)
358 {
359 if (fifo == NULL) {
360 HDF_LOGE("%s:%d fifo is NULL", __func__, __LINE__);
361 return;
362 }
363
364 if (fifo->data != NULL) {
365 OsalMemFree((void *)fifo->data);
366 }
367
368 DataFifoInit((struct DataFifo *)fifo, 0, NULL);
369 }
370
AcmWbIsAvail(const struct AcmDevice * acm)371 static int32_t AcmWbIsAvail(const struct AcmDevice *acm)
372 {
373 int32_t i;
374 int32_t n = ACM_NW;
375
376 OsalMutexLock((struct OsalMutex *)&acm->writeLock);
377 for (i = 0; i < ACM_NW; i++) {
378 n -= acm->wb[i].use;
379 }
380 OsalMutexUnlock((struct OsalMutex *)&acm->writeLock);
381 return n;
382 }
383
AcmStartWb(struct AcmDevice * acm,struct AcmWb * wb)384 static int32_t AcmStartWb(struct AcmDevice *acm, struct AcmWb *wb)
385 {
386 struct UsbRawFillRequestData reqData;
387 int32_t ret;
388 if ((acm == NULL) || (wb == NULL) || (acm->dataOutEp == NULL)
389 || (acm->devHandle == NULL) || (wb->request == NULL)) {
390 return HDF_ERR_INVALID_PARAM;
391 }
392
393 acm->transmitting++;
394
395 reqData.endPoint = acm->dataOutEp->addr;
396 reqData.numIsoPackets = 0;
397 reqData.callback = AcmWriteBulkCallback;
398 reqData.userData = (void *)wb;
399 reqData.timeout = USB_CTRL_SET_TIMEOUT;
400 reqData.buffer = wb->buf;
401 reqData.length = wb->len;
402
403 ret = UsbRawFillBulkRequest(wb->request, acm->devHandle, &reqData);
404 if (ret) {
405 HDF_LOGE("%s: FillInterruptRequest faile, ret=%d", __func__, ret);
406 return HDF_FAILURE;
407 }
408
409 acm->writeReq = wb->request;
410 ret = UsbRawSubmitRequest(wb->request);
411 if (ret) {
412 HDF_LOGE("UsbRawSubmitRequest faile, ret=%d", ret);
413 wb->use = 0;
414 acm->transmitting--;
415 }
416
417 return ret;
418 }
419
AcmWriteBufAlloc(const struct AcmDevice * acm)420 static int32_t AcmWriteBufAlloc(const struct AcmDevice *acm)
421 {
422 struct AcmWb *wb = (struct AcmWb *)&acm->wb[0];
423 int32_t i;
424
425 for (i = 0; i < ACM_NW; i++, wb++) {
426 wb->buf = OsalMemCalloc(acm->dataOutEp->maxPacketSize);
427 if (!wb->buf) {
428 while (i > 0) {
429 --i;
430 --wb;
431 OsalMemFree(wb->buf);
432 wb->buf = NULL;
433 }
434 return -HDF_ERR_MALLOC_FAIL;
435 }
436 }
437 return HDF_SUCCESS;
438 }
439
AcmWriteBufFree(struct AcmDevice * acm)440 static void AcmWriteBufFree(struct AcmDevice *acm)
441 {
442 struct AcmWb *wb = &acm->wb[0];
443 int32_t i;
444
445 for (i = 0; i < ACM_NW; i++, wb++) {
446 if (wb->buf) {
447 OsalMemFree(wb->buf);
448 wb->buf = NULL;
449 }
450 }
451 return;
452 }
453
AcmWriteBulkCallback(const void * requestArg)454 static void AcmWriteBulkCallback(const void *requestArg)
455 {
456 struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
457 if (req == NULL) {
458 HDF_LOGE("%s:%d req is NULL!", __func__, __LINE__);
459 return;
460 }
461 struct AcmWb *wb = (struct AcmWb *)req->userData;
462 if (wb == NULL) {
463 HDF_LOGE("%s:%d userData(wb) is NULL!", __func__, __LINE__);
464 return;
465 }
466
467 if (req->status != USB_REQUEST_COMPLETED) {
468 HDF_LOGE("%s: write req failed, status=%d", __func__, req->status);
469 }
470
471 wb->use = 0;
472 }
473
SerialSendCtrlMsg(struct AcmDevice * acm,uint8_t request,uint16_t value,void * buf,uint16_t len)474 static int32_t SerialSendCtrlMsg(struct AcmDevice *acm, uint8_t request,
475 uint16_t value, void *buf, uint16_t len)
476 {
477 struct UsbControlRequestData ctrlReq;
478 int32_t ret;
479
480 if (acm == NULL || buf == NULL) {
481 HDF_LOGE("%s:invalid param", __func__);
482 return HDF_ERR_INVALID_PARAM;
483 }
484 if (acm->ctrlReq == NULL) {
485 acm->ctrlReq = UsbRawAllocRequest(acm->devHandle, 0, USB_CTRL_REQ_SIZE);
486 if (acm->ctrlReq == NULL) {
487 HDF_LOGE("%s: UsbRawAllocRequest failed", __func__);
488 return HDF_ERR_MALLOC_FAIL;
489 }
490 }
491
492 ctrlReq.requestType = USB_DDK_DIR_OUT | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
493 ctrlReq.requestCmd = request;
494 ctrlReq.value = CpuToLe16(value);
495 ctrlReq.index = 0;
496 ctrlReq.data = buf;
497 ctrlReq.length = len;
498 ctrlReq.timeout = USB_CTRL_SET_TIMEOUT;
499
500 ret = UsbRawSendControlRequest(acm->ctrlReq, acm->devHandle, &ctrlReq);
501 if (ret < HDF_SUCCESS) {
502 HDF_LOGE("%s: UsbRawSendControlRequest failed, ret=%d", __func__, ret);
503 return ret;
504 }
505 if (acm->ctrlReq->status) {
506 HDF_LOGE("%s status=%d ", __func__, acm->ctrlReq->status);
507 }
508 return HDF_SUCCESS;
509 }
510
UsbSerialDeviceAlloc(struct AcmDevice * acm)511 static int32_t UsbSerialDeviceAlloc(struct AcmDevice *acm)
512 {
513 struct SerialDevice *port = NULL;
514
515 if (acm == NULL) {
516 HDF_LOGE("%s: acm null pointer", __func__);
517 return HDF_FAILURE;
518 }
519
520 port = (struct SerialDevice *)OsalMemCalloc(sizeof(*port));
521 if (port == NULL) {
522 HDF_LOGE("%s: Alloc usb serial port failed", __func__);
523 return HDF_FAILURE;
524 }
525 if (OsalMutexInit(&port->lock) != HDF_SUCCESS) {
526 HDF_LOGE("%s: init lock fail!", __func__);
527 return HDF_FAILURE;
528 }
529 port->lineCoding.dwDTERate = CpuToLe32(DATARATE);
530 port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
531 port->lineCoding.bParityType = USB_CDC_NO_PARITY;
532 port->lineCoding.bDataBits = DATA_BITS_LENGTH;
533 acm->lineCoding = port->lineCoding;
534 acm->port = port;
535 port->acm = acm;
536
537 return HDF_SUCCESS;
538 }
539
UsbSeriaDevicelFree(struct AcmDevice * acm)540 static void UsbSeriaDevicelFree(struct AcmDevice *acm)
541 {
542 struct SerialDevice *port = acm->port;
543
544 if (port == NULL) {
545 HDF_LOGE("%s: port is null", __func__);
546 return;
547 }
548 OsalMemFree(port);
549 port = NULL;
550 }
551
UsbSerialRead(struct SerialDevice * port,struct HdfSBuf * reply)552 static int32_t UsbSerialRead(struct SerialDevice *port, struct HdfSBuf *reply)
553 {
554 struct AcmDevice *acm = port->acm;
555 uint8_t *buf = NULL;
556 int32_t ret = HDF_SUCCESS;
557 uint32_t len;
558
559 for (int32_t i = 0; i < ACM_NR; i++) {
560 if(acm->readReq[i]->status != USB_REQUEST_COMPLETED) {
561 HDF_LOGE("%s:%d i=%d status=%d!",
562 __func__, __LINE__, i, acm->readReq[i]->status);
563 return HDF_FAILURE;
564 }
565 }
566
567 if (DataFifoIsEmpty(&port->readFifo)) {
568 if (!HdfSbufWriteString(reply, NULL)) {
569 HDF_LOGE("%s:%d sbuf write buffer failed", __func__, __LINE__);
570 ret = HDF_ERR_IO;
571 }
572 return HDF_SUCCESS;
573 }
574
575 buf = (uint8_t *)OsalMemCalloc(DataFifoLen(&port->readFifo) + 1);
576 if (buf == NULL) {
577 HDF_LOGE("%s:%d OsalMemCalloc error", __func__, __LINE__);
578 return HDF_ERR_MALLOC_FAIL;
579 }
580
581 OsalMutexLock(&acm->readLock);
582 len = DataFifoRead(&port->readFifo, buf, DataFifoLen(&port->readFifo));
583 if (len == 0) {
584 HDF_LOGE("%s:%d no data", __func__, __LINE__);
585 ret = HDF_SUCCESS;
586 OsalMutexUnlock(&acm->readLock);
587 goto OUT;
588 }
589 OsalMutexUnlock(&acm->readLock);
590
591 if (!HdfSbufWriteString(reply, (const char *)buf)) {
592 HDF_LOGE("%s:%d sbuf write buffer failed", __func__, __LINE__);
593 ret = HDF_ERR_IO;
594 }
595
596 OUT:
597 OsalMemFree(buf);
598 return ret;
599 }
600
SerialSetBaudrate(struct SerialDevice * port,const struct HdfSBuf * data)601 static int32_t SerialSetBaudrate(struct SerialDevice *port, const struct HdfSBuf *data)
602 {
603 struct AcmDevice *acm = port->acm;
604 int32_t ret;
605 uint32_t baudRate = 0;
606
607 if (!HdfSbufReadUint32((struct HdfSBuf *)data, &baudRate)) {
608 HDF_LOGE("%s: sbuf read buffer failed", __func__);
609 return HDF_ERR_IO;
610 }
611 port->lineCoding.dwDTERate = CpuToLe32(baudRate);
612 if (memcmp(&acm->lineCoding, &port->lineCoding, sizeof(struct UsbCdcLineCoding))) {
613 ret = memcpy_s(&acm->lineCoding, sizeof(struct UsbCdcLineCoding),
614 &port->lineCoding, sizeof(port->lineCoding));
615 if (ret != EOK) {
616 HDF_LOGE("memcpy_s fail, ret=%d", ret);
617 }
618
619 HDF_LOGE("%s - set line: %d %d %d %d\n",
620 __func__, (port->lineCoding.dwDTERate), port->lineCoding.bCharFormat,
621 port->lineCoding.bParityType, port->lineCoding.bDataBits);
622
623 ret = SerialSendCtrlMsg(acm, USB_DDK_CDC_REQ_SET_LINE_CODING, 0, &acm->lineCoding,
624 sizeof(struct UsbCdcLineCoding));
625 if (ret) {
626 HDF_LOGE("SerialSendCtrlMsg fail\n");
627 return ret;
628 }
629 }
630 return HDF_SUCCESS;
631 }
632
SerialGetBaudrate(struct SerialDevice * port,struct HdfSBuf * reply)633 static int32_t SerialGetBaudrate(struct SerialDevice *port, struct HdfSBuf *reply)
634 {
635 uint32_t baudRate = Le32ToCpu(port->lineCoding.dwDTERate);
636
637 if (!HdfSbufWriteUint32(reply, baudRate)) {
638 HDF_LOGE("%s:%d sbuf write buffer failed", __func__, __LINE__);
639 return HDF_ERR_IO;
640 }
641
642 HDF_LOGE("%s:%d baudRate=%d", __func__, __LINE__, baudRate);
643
644 return HDF_SUCCESS;
645 }
646
SerialOpen(struct SerialDevice * port,struct HdfSBuf * data)647 static int32_t SerialOpen(struct SerialDevice *port, struct HdfSBuf *data)
648 {
649 struct AcmDevice *acm = NULL;
650 int32_t ret;
651 int32_t cmdType = HOST_ACM_ASYNC_READ;
652
653 if ((port == NULL) || (data == NULL)) {
654 HDF_LOGE("%s: invalid parma", __func__);
655 return HDF_ERR_INVALID_PARAM;
656 }
657
658 acm = port->acm;
659 if (acm == NULL) {
660 HDF_LOGE("%s: invalid parma", __func__);
661 return HDF_ERR_INVALID_PARAM;
662 }
663
664 if (!HdfSbufReadInt32(data, &cmdType)) {
665 HDF_LOGE("%s:%d sbuf read cmdType failed", __func__, __LINE__);
666 return HDF_ERR_INVALID_PARAM;
667 }
668
669 ret = UsbSerialInit(acm);
670 if (ret != HDF_SUCCESS) {
671 HDF_LOGE("%s:%d UsbSerialInit failed", __func__, __LINE__);
672 return HDF_FAILURE;
673 }
674
675 if (cmdType != HOST_ACM_ASYNC_READ) {
676 HDF_LOGD("%s:%d asyncRead success", __func__, __LINE__);
677 return HDF_SUCCESS;
678 }
679
680 ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
681 if (ret != HDF_SUCCESS) {
682 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
683 return HDF_ERR_INVALID_PARAM;
684 }
685 for (int32_t i = 0; i < ACM_NR; i++) {
686 ret = UsbRawSubmitRequest(acm->readReq[i]);
687 if (ret) {
688 HDF_LOGE("%s: UsbRawSubmitRequest failed, ret=%d ", __func__, ret);
689 goto ERR;
690 }
691 }
692 return HDF_SUCCESS;
693
694 ERR:
695 UsbSerialFreeFifo(&port->readFifo);
696 return ret;
697 }
698
SerialClose(struct SerialDevice * port,struct HdfSBuf * data)699 static int32_t SerialClose(struct SerialDevice *port, struct HdfSBuf *data)
700 {
701 int32_t cmdType = HOST_ACM_SYNC_READ;
702
703 if ((port == NULL) || (data == NULL)) {
704 HDF_LOGE("%s:%d invalid parma", __func__, __LINE__);
705 return HDF_ERR_INVALID_PARAM;
706 }
707
708 if (port->acm == NULL) {
709 HDF_LOGE("%s:%d acm is NULL invalid parma", __func__, __LINE__);
710 return HDF_ERR_INVALID_PARAM;
711 }
712
713 if (!HdfSbufReadInt32(data, &cmdType)) {
714 HDF_LOGE("%s:%d sbuf read cmdType failed", __func__, __LINE__);
715 return HDF_ERR_INVALID_PARAM;
716 }
717
718 if ((cmdType == HOST_ACM_SYNC_READ) || (cmdType == HOST_ACM_SYNC_WRITE) || (cmdType == HOST_ACM_ASYNC_WRITE)) {
719 HDF_LOGD("%s:%d cmdType=%d success", __func__, __LINE__, cmdType);
720 return HDF_SUCCESS;
721 }
722
723 OsalMutexLock(&port->acm->readLock);
724 UsbSerialFreeFifo(&port->readFifo);
725 OsalMutexUnlock(&port->acm->readLock);
726
727 UsbSerialRelease(port->acm);
728
729 return HDF_SUCCESS;
730 }
731
SerialWrite(struct SerialDevice * port,struct HdfSBuf * data)732 static int32_t SerialWrite(struct SerialDevice *port, struct HdfSBuf *data)
733 {
734 struct AcmDevice *acm = NULL;
735 struct AcmWb *wb = NULL;
736 const char *tmp = NULL;
737 uint32_t size;
738 int32_t ret;
739 int32_t wbn;
740
741 if (port == NULL) {
742 HDF_LOGE("%d: invalid parma", __LINE__);
743 return HDF_ERR_INVALID_PARAM;
744 }
745 acm = port->acm;
746 if (acm == NULL) {
747 HDF_LOGE("%d: invalid parma", __LINE__);
748 return HDF_ERR_INVALID_PARAM;
749 }
750 if (AcmWbIsAvail(acm)) {
751 wbn = AcmWbAlloc(acm);
752 } else {
753 HDF_LOGE("no write buf\n");
754 return HDF_SUCCESS;
755 }
756 if (wbn < 0 || wbn >= ACM_NW) {
757 HDF_LOGE("AcmWbAlloc failed\n");
758 return HDF_FAILURE;
759 }
760 wb = &acm->wb[wbn];
761 if (wb == NULL) {
762 return HDF_FAILURE;
763 }
764 tmp = HdfSbufReadString(data);
765 if (tmp == NULL) {
766 HDF_LOGE("%s: sbuf read buffer failed", __func__);
767 return HDF_ERR_IO;
768 }
769 size = strlen(tmp) + 1;
770 if (acm->dataOutEp != NULL) {
771 size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size;
772 ret = memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size);
773 if (ret != EOK) {
774 HDF_LOGE("%s: memcpy_s fail", __func__);
775 }
776 }
777 wb->len = (int)size;
778 ret = AcmStartWb(acm, wb);
779 return size;
780 }
781
AcmStartWbSync(struct AcmDevice * acm,struct AcmWb * wb)782 static int32_t AcmStartWbSync(struct AcmDevice *acm, struct AcmWb *wb)
783 {
784 int32_t ret;
785 int32_t size;
786 struct UsbRequestData requestData;
787
788 requestData.endPoint = acm->dataOutEp->addr;
789 requestData.data = wb->buf;
790 requestData.length = wb->len;
791 requestData.requested = &size;
792 requestData.timeout = USB_CTRL_SET_TIMEOUT;
793
794 acm->writeReq = wb->request;
795 ret = UsbRawSendBulkRequest(wb->request, acm->devHandle, &requestData);
796 if (ret) {
797 HDF_LOGE("UsbRawSendBulkRequest faile, ret=%d", ret);
798 }
799
800 wb->use = 0;
801
802 return ret;
803 }
804
SerialWriteSync(const struct SerialDevice * port,const struct HdfSBuf * data)805 static int32_t SerialWriteSync(const struct SerialDevice *port, const struct HdfSBuf *data)
806 {
807 struct AcmDevice *acm = NULL;
808 struct AcmWb *wb = NULL;
809 const char *tmp = NULL;
810 uint32_t size;
811 int32_t ret;
812 int32_t wbn;
813
814 if (port == NULL) {
815 HDF_LOGE("%d: invalid parma", __LINE__);
816 return HDF_ERR_INVALID_PARAM;
817 }
818 acm = port->acm;
819 if (acm == NULL) {
820 HDF_LOGE("%d: invalid parma", __LINE__);
821 return HDF_ERR_INVALID_PARAM;
822 }
823
824 if (AcmWbIsAvail(acm)) {
825 wbn = AcmWbAlloc(acm);
826 } else {
827 HDF_LOGE("no write buf\n");
828 return HDF_SUCCESS;
829 }
830
831 if (wbn >= ACM_NW || wbn < 0) {
832 wbn = 0;
833 }
834 wb = &acm->wb[wbn];
835 if ((wb == NULL) || (wb->buf == NULL)) {
836 return HDF_ERR_INVALID_PARAM;
837 }
838 tmp = HdfSbufReadString((struct HdfSBuf *)data);
839 if (tmp == NULL) {
840 HDF_LOGE("%s: sbuf read buffer failed", __func__);
841 return HDF_ERR_IO;
842 }
843 size = strlen(tmp) + 1;
844 if (acm->dataOutEp == NULL) {
845 return HDF_ERR_IO;
846 }
847 size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size;
848 ret = memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size);
849 if (ret != EOK) {
850 HDF_LOGE("%s: memcpy_s fail, ret=%d", __func__, ret);
851 }
852 wb->len = (int)size;
853 ret = AcmStartWbSync(acm, wb);
854
855 return size;
856 }
857
UsbSerialReadSync(const struct SerialDevice * port,const struct HdfSBuf * reply)858 static int32_t UsbSerialReadSync(const struct SerialDevice *port, const struct HdfSBuf *reply)
859 {
860 int32_t ret;
861 int32_t size;
862 struct AcmDevice *acm = port->acm;
863 uint8_t *data = NULL;
864 uint32_t count;
865 struct UsbRequestData requestData;
866
867 if (g_syncRequest == NULL) {
868 g_syncRequest = UsbRawAllocRequest(acm->devHandle, 0, acm->dataInEp->maxPacketSize);
869 if (g_syncRequest == NULL) {
870 HDF_LOGE("UsbRawAllocRequest g_syncRequest failed\n");
871 return HDF_ERR_MALLOC_FAIL;
872 }
873 }
874 HDF_LOGD("%s:%d g_syncRequest \n", __func__, __LINE__);
875
876 requestData.endPoint = acm->dataInEp->addr;
877 requestData.data = g_syncRequest->buffer;
878 requestData.length = acm->dataInEp->maxPacketSize;
879 requestData.requested = &size;
880 requestData.timeout = USB_CTRL_SET_TIMEOUT;
881
882 ret = UsbRawSendBulkRequest(g_syncRequest, acm->devHandle, &requestData);
883 if (ret) {
884 HDF_LOGE("UsbRawSendBulkRequest faile, ret=%d", ret);
885 return ret;
886 }
887
888 count = (uint32_t)g_syncRequest->actualLength;
889 data = (uint8_t *)OsalMemCalloc(count + 1);
890 if (data == NULL) {
891 HDF_LOGE("%s: OsalMemCalloc error", __func__);
892 return HDF_ERR_MALLOC_FAIL;
893 }
894 HDF_LOGD("buffer:%p-%s-actualLength:%d", g_syncRequest->buffer,
895 (uint8_t *)g_syncRequest->buffer, count);
896 ret = memcpy_s(data, g_syncRequest->actualLength, g_syncRequest->buffer, count);
897 if (ret) {
898 HDF_LOGE("memcpy_s error");
899 }
900 if (!HdfSbufWriteString((struct HdfSBuf *)reply, (char *)data)) {
901 HDF_LOGE("%s: sbuf write buffer failed", __func__);
902 ret = HDF_ERR_IO;
903 }
904
905 OsalMemFree(data);
906 data = NULL;
907 return HDF_SUCCESS;
908 }
909
SerialAddOrRemoveInterface(int32_t cmd,const struct SerialDevice * port,const struct HdfSBuf * data)910 static int32_t SerialAddOrRemoveInterface(int32_t cmd, const struct SerialDevice *port, const struct HdfSBuf *data)
911 {
912 UsbInterfaceStatus status;
913 uint32_t index;
914
915 if (!HdfSbufReadUint32((struct HdfSBuf *)data, &index)) {
916 HDF_LOGE("%s:%d sbuf read interfaceNum failed", __func__, __LINE__);
917 return HDF_ERR_INVALID_PARAM;
918 }
919
920 if (cmd == CMD_ADD_INTERFACE) {
921 status = USB_INTERFACE_STATUS_ADD;
922 } else if (cmd == CMD_REMOVE_INTERFACE) {
923 status = USB_INTERFACE_STATUS_REMOVE;
924 } else {
925 HDF_LOGE("%s:%d cmd=% is not define", __func__, __LINE__, cmd);
926 return HDF_ERR_INVALID_PARAM;
927 }
928
929 return HDF_SUCCESS;
930 }
931
UsbSerialDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)932 static int32_t UsbSerialDeviceDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
933 struct HdfSBuf *data, struct HdfSBuf *reply)
934 {
935 struct AcmDevice *acm = NULL;
936 struct SerialDevice *port = NULL;
937
938 if (client == NULL) {
939 HDF_LOGE("%s:%d client is NULL", __func__, __LINE__);
940 return HDF_ERR_INVALID_OBJECT;
941 }
942 if (client->device == NULL) {
943 HDF_LOGE("%s:%d client->device is NULL", __func__, __LINE__);
944 return HDF_ERR_INVALID_OBJECT;
945 }
946 if (client->device->service == NULL) {
947 HDF_LOGE("%s:%d client->device->service is NULL", __func__, __LINE__);
948 return HDF_ERR_INVALID_OBJECT;
949 }
950
951 if (g_rawAcmReleaseFlag == true) {
952 HDF_LOGE("%s:%d g_rawAcmReleaseFlag is true", __func__, __LINE__);
953 return HDF_FAILURE;
954 }
955
956 acm = (struct AcmDevice *)client->device->service;
957 if (acm == NULL) {
958 return HDF_FAILURE;
959 }
960 port = acm->port;
961 if (port == NULL) {
962 return HDF_FAILURE;
963 }
964 switch (cmd) {
965 case CMD_OPEN_PARM:
966 return SerialOpen(port, data);
967 case CMD_CLOSE_PARM:
968 return SerialClose(port, data);
969 case CMD_WRITE_PARM:
970 return SerialWrite(port, data);
971 case CMD_READ_PARM:
972 return UsbSerialRead(port, reply);
973 case CMD_GET_BAUDRATE:
974 return SerialGetBaudrate(port, reply);
975 case CMD_SET_BAUDRATE:
976 return SerialSetBaudrate(port, data);
977 case CMD_WRITE_DATA_SYNC:
978 return SerialWriteSync(port, data);
979 case CMD_READ_DATA_SYNC:
980 return UsbSerialReadSync(port, reply);
981 case CMD_ADD_INTERFACE:
982 case CMD_REMOVE_INTERFACE:
983 return SerialAddOrRemoveInterface(cmd, port, data);
984 default:
985 return HDF_ERR_NOT_SUPPORT;
986 }
987 }
988
989 /* HdfDriverEntry implementations */
UsbSerialDriverBind(struct HdfDeviceObject * device)990 static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
991 {
992 struct AcmDevice *acm = NULL;
993 struct UsbPnpNotifyServiceInfo *info = NULL;
994 errno_t err;
995
996 if (device == NULL) {
997 HDF_LOGE("%s: device is null", __func__);
998 return HDF_ERR_INVALID_OBJECT;
999 }
1000
1001 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
1002 if (acm == NULL) {
1003 HDF_LOGE("%s: Alloc usb serial device failed", __func__);
1004 return HDF_FAILURE;
1005 }
1006 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
1007 HDF_LOGE("%s:%d OsalMutexInit fail", __func__, __LINE__);
1008 goto ERROR;
1009 }
1010
1011 info = (struct UsbPnpNotifyServiceInfo *)device->priv;
1012 if (info != NULL) {
1013 acm->busNum = (uint8_t)info->busNum;
1014 acm->devAddr = (uint8_t)info->devNum;
1015 acm->interfaceCnt = info->interfaceLength;
1016 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES,
1017 (const void*)info->interfaceNumber, info->interfaceLength);
1018 if (err != EOK) {
1019 HDF_LOGE("%s:%d memcpy_s faile err=%d", \
1020 __func__, __LINE__, err);
1021 goto LOCK_ERROR;
1022 }
1023 } else {
1024 HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__);
1025 goto LOCK_ERROR;
1026 }
1027
1028 device->service = &(acm->service);
1029 device->service->Dispatch = UsbSerialDeviceDispatch;
1030 acm->device = device;
1031 HDF_LOGD("UsbSerialDriverBind=========================OK");
1032 return HDF_SUCCESS;
1033
1034 LOCK_ERROR:
1035 if (OsalMutexDestroy(&acm->lock)) {
1036 HDF_LOGE("%s:%d OsalMutexDestroy fail", __func__, __LINE__);
1037 }
1038 ERROR:
1039 OsalMemFree(acm);
1040 acm = NULL;
1041 return HDF_FAILURE;
1042 }
1043
AcmProcessNotification(const struct AcmDevice * acm,const unsigned char * buf)1044 static void AcmProcessNotification(const struct AcmDevice *acm, const unsigned char *buf)
1045 {
1046 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)buf;
1047
1048 switch (dr->bNotificationType) {
1049 case USB_DDK_CDC_NOTIFY_NETWORK_CONNECTION:
1050 HDF_LOGE("%s - network connection: %d\n", __func__, dr->wValue);
1051 break;
1052 case USB_DDK_CDC_NOTIFY_SERIAL_STATE:
1053 HDF_LOGE("the serial State change\n");
1054 break;
1055 default:
1056 HDF_LOGE("%s-%d received: index %d len %d\n",
1057 __func__, dr->bNotificationType, dr->wIndex, dr->wLength);
1058 }
1059 }
1060
AcmNotificationBufferProcess(const struct UsbRawRequest * req,struct AcmDevice * acm,unsigned int currentSize,unsigned int expectedSize)1061 static int32_t AcmNotificationBufferProcess(const struct UsbRawRequest *req,
1062 struct AcmDevice *acm, unsigned int currentSize, unsigned int expectedSize)
1063 {
1064 int32_t ret;
1065 unsigned int copySize;
1066 unsigned int allocSize;
1067
1068 if (acm->nbSize < expectedSize) {
1069 if (acm->nbSize) {
1070 OsalMemFree(acm->notificationBuffer);
1071 acm->nbSize = 0;
1072 }
1073 allocSize = expectedSize;
1074 acm->notificationBuffer = (uint8_t *)OsalMemCalloc(allocSize);
1075 if (!acm->notificationBuffer) {
1076 return HDF_FAILURE;
1077 }
1078 acm->nbSize = allocSize;
1079 }
1080 copySize = MIN(currentSize, expectedSize - acm->nbIndex);
1081 ret = memcpy_s(&acm->notificationBuffer[acm->nbIndex], acm->nbSize - acm->nbIndex,
1082 req->buffer, copySize);
1083 if (ret != EOK) {
1084 HDF_LOGE("memcpy_s fail ret=%d", ret);
1085 }
1086 acm->nbIndex += copySize;
1087
1088 return HDF_SUCCESS;
1089 }
1090
AcmNotifyReqCallback(const void * requestArg)1091 static void AcmNotifyReqCallback(const void *requestArg)
1092 {
1093 struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
1094 if (req == NULL) {
1095 HDF_LOGE("%s:%d req is NULL!", __func__, __LINE__);
1096 return;
1097 }
1098 struct AcmDevice *acm = (struct AcmDevice *)req->userData;
1099 if (acm == NULL) {
1100 HDF_LOGE("%s:%d userData(acm) is NULL!", __func__, __LINE__);
1101 return;
1102 }
1103 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)req->buffer;
1104 if (dr == NULL) {
1105 HDF_LOGE("%s:%d req->buffer(dr) is NULL!", __func__, __LINE__);
1106 return;
1107 }
1108 unsigned int currentSize = (unsigned int)req->actualLength;
1109 unsigned int expectedSize = 0;
1110
1111 HDF_LOGD("Irqstatus:%d,actualLength:%u\n", req->status, currentSize);
1112
1113 if (req->status != USB_REQUEST_COMPLETED) {
1114 goto EXIT;
1115 }
1116
1117 if (acm->nbIndex) {
1118 dr = (struct UsbCdcNotification *)acm->notificationBuffer;
1119 }
1120 if (dr != NULL) {
1121 expectedSize = sizeof(struct UsbCdcNotification) + Le16ToCpu(dr->wLength);
1122 } else {
1123 HDF_LOGE("%s:%d dr is NULL!", __func__, __LINE__);
1124 return;
1125 }
1126 if (currentSize < expectedSize) {
1127 if (AcmNotificationBufferProcess(req, acm, currentSize, expectedSize) != HDF_SUCCESS) {
1128 goto EXIT;
1129 }
1130 currentSize = acm->nbIndex;
1131 }
1132 if (currentSize >= expectedSize) {
1133 AcmProcessNotification(acm, (unsigned char *)dr);
1134 acm->nbIndex = 0;
1135 }
1136
1137 if (UsbRawSubmitRequest(req)) {
1138 HDF_LOGE("%s - UsbRawSubmitRequest failed", __func__);
1139 }
1140
1141 EXIT:
1142 HDF_LOGE("%s:%d exit", __func__, __LINE__);
1143 }
1144
AcmReadBulkCallback(const void * requestArg)1145 static void AcmReadBulkCallback(const void *requestArg)
1146 {
1147 struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
1148 if (req == NULL) {
1149 HDF_LOGE("%s:%d req is NULL!", __func__, __LINE__);
1150 return;
1151 }
1152 struct AcmDevice *acm = (struct AcmDevice *)req->userData;
1153 if (acm == NULL || acm->port == NULL) {
1154 HDF_LOGE("%s:%d userData(acm) is NULL!", __func__, __LINE__);
1155 return;
1156 }
1157 size_t size = (size_t)req->actualLength;
1158
1159 switch (req->status) {
1160 case USB_REQUEST_COMPLETED:
1161 HDF_LOGD("Bulk status: %d+size:%zu", req->status, size);
1162 if (size) {
1163 uint8_t *data = req->buffer;
1164 uint32_t count;
1165
1166 OsalMutexLock(&acm->readLock);
1167 if (DataFifoIsFull(&acm->port->readFifo)) {
1168 DataFifoSkip(&acm->port->readFifo, size);
1169 }
1170 count = DataFifoWrite(&acm->port->readFifo, data, size);
1171 if (count != size) {
1172 HDF_LOGW("%s: write %u less than expected %zu", __func__, count, size);
1173 }
1174 OsalMutexUnlock(&acm->readLock);
1175 }
1176 break;
1177 default:
1178 HDF_LOGW("%s:%d the request is failed, staus=%d",
1179 __func__, __LINE__, req->status);
1180 return;
1181 }
1182
1183 if (UsbRawSubmitRequest(req)) {
1184 HDF_LOGE("%s - UsbRawSubmitRequest failed", __func__);
1185 }
1186 }
1187
UsbAllocReadRequests(struct AcmDevice * acm)1188 static int32_t UsbAllocReadRequests(struct AcmDevice *acm)
1189 {
1190 struct UsbRawFillRequestData reqData;
1191 uint32_t size = acm->dataInEp->maxPacketSize;
1192 int32_t ret;
1193
1194 for (int32_t i = 0; i < ACM_NR; i++) {
1195 acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size);
1196 if (!acm->readReq[i]) {
1197 HDF_LOGE("readReq request failed\n");
1198 return HDF_ERR_MALLOC_FAIL;
1199 }
1200
1201 reqData.endPoint = acm->dataInEp->addr;
1202 reqData.numIsoPackets = 0;
1203 reqData.callback = AcmReadBulkCallback;
1204 reqData.userData = (void *)acm;
1205 reqData.timeout = USB_CTRL_SET_TIMEOUT;
1206 reqData.length = size;
1207
1208 ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData);
1209 if (ret) {
1210 HDF_LOGE("%s: FillBulkRequest faile, ret=%d \n",
1211 __func__, ret);
1212 return HDF_FAILURE;
1213 }
1214 }
1215
1216 return HDF_SUCCESS;
1217 }
1218
UsbFreeReadRequests(struct AcmDevice * acm)1219 static void UsbFreeReadRequests(struct AcmDevice *acm)
1220 {
1221 int32_t i;
1222
1223 if (acm == NULL) {
1224 HDF_LOGE("%s: acm is NULL", __func__);
1225 return;
1226 }
1227
1228 for (i = 0; i < ACM_NR; i++) {
1229 if (acm->readReq[i]) {
1230 UsbRawFreeRequest(acm->readReq[i]);
1231 acm->readReq[i] = NULL;
1232 }
1233 }
1234 }
1235
UsbAllocNotifyRequest(struct AcmDevice * acm)1236 static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm)
1237 {
1238 struct UsbRawFillRequestData fillRequestData;
1239 uint32_t size = acm->notifyEp->maxPacketSize;
1240 int32_t ret;
1241
1242 acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size);
1243 if (!acm->notifyReq) {
1244 HDF_LOGE("notifyReq request fail\n");
1245 return HDF_ERR_MALLOC_FAIL;
1246 }
1247
1248 fillRequestData.endPoint = acm->notifyEp->addr;
1249 fillRequestData.length = size;
1250 fillRequestData.numIsoPackets = 0;
1251 fillRequestData.callback = AcmNotifyReqCallback;
1252 fillRequestData.userData = (void *)acm;
1253 fillRequestData.timeout = USB_CTRL_SET_TIMEOUT;
1254
1255 ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData);
1256 if (ret) {
1257 HDF_LOGE("%s: FillInterruptRequest faile, ret=%d", __func__, ret);
1258 return HDF_FAILURE;
1259 }
1260
1261 return HDF_SUCCESS;
1262 }
1263
UsbFreeNotifyReqeust(struct AcmDevice * acm)1264 static void UsbFreeNotifyReqeust(struct AcmDevice *acm)
1265 {
1266 int32_t ret;
1267
1268 if ((acm == NULL) || (acm->notifyReq == NULL)) {
1269 HDF_LOGE("%s: acm or notifyReq is NULL", __func__);
1270 return;
1271 }
1272
1273 ret = UsbRawFreeRequest(acm->notifyReq);
1274 if (ret == HDF_SUCCESS) {
1275 acm->notifyReq = NULL;
1276 } else {
1277 HDF_LOGE("%s: UsbFreeNotifyReqeust failed, ret=%d",
1278 __func__, ret);
1279 }
1280 }
1281
UsbSerialInit(struct AcmDevice * acm)1282 static int32_t UsbSerialInit(struct AcmDevice *acm)
1283 {
1284 struct UsbSession *session = NULL;
1285 UsbRawHandle *devHandle = NULL;
1286 int32_t ret;
1287
1288 if (acm->initFlag == true) {
1289 HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__);
1290 return HDF_SUCCESS;
1291 }
1292
1293 ret = UsbRawInit(NULL);
1294 if (ret) {
1295 HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__);
1296 return HDF_ERR_IO;
1297 }
1298 acm->session = session;
1299
1300 devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr);
1301 if (devHandle == NULL) {
1302 HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__);
1303 ret = HDF_FAILURE;
1304 goto ERR_OPEN_DEVICE;
1305 }
1306 acm->devHandle = devHandle;
1307 ret = UsbGetConfigDescriptor(devHandle, &acm->config);
1308 if (ret) {
1309 HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__);
1310 ret = HDF_FAILURE;
1311 goto ERR_GET_DESC;
1312 }
1313 ret = UsbParseConfigDescriptor(acm, acm->config);
1314 if (ret != HDF_SUCCESS) {
1315 HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__);
1316 ret = HDF_FAILURE;
1317 goto ERR_PARSE_DESC;
1318 }
1319
1320 ret = AcmWriteBufAlloc(acm);
1321 if (ret < 0) {
1322 HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__);
1323 ret = HDF_FAILURE;
1324 goto ERR_ALLOC_WRITE_BUF;
1325 }
1326 ret = UsbAllocWriteRequests(acm);
1327 if (ret < 0) {
1328 HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__);
1329 ret = HDF_FAILURE;
1330 goto ERR_ALLOC_WRITE_REQS;
1331 }
1332 ret = UsbAllocNotifyRequest(acm);
1333 if (ret) {
1334 HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__);
1335 goto ERR_ALLOC_NOTIFY_REQ;
1336 }
1337 ret = UsbAllocReadRequests(acm);
1338 if (ret) {
1339 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1340 goto ERR_ALLOC_READ_REQS;
1341 }
1342 ret = UsbStartIo(acm);
1343 if (ret) {
1344 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1345 goto ERR_START_IO;
1346 }
1347
1348 acm->lineCoding.dwDTERate = CpuToLe32(DATARATE);
1349 acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
1350 acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
1351 acm->lineCoding.bDataBits = DATA_BITS_LENGTH;
1352
1353 ret = UsbRawSubmitRequest(acm->notifyReq);
1354 if (ret) {
1355 HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__);
1356 goto ERR_SUBMIT_REQ;
1357 }
1358
1359 acm->initFlag = true;
1360
1361 HDF_LOGD("%s:%d=========================OK", __func__, __LINE__);
1362
1363 return HDF_SUCCESS;
1364
1365 ERR_SUBMIT_REQ:
1366 UsbStopIo(acm);
1367 ERR_START_IO:
1368 UsbFreeReadRequests(acm);
1369 ERR_ALLOC_READ_REQS:
1370 UsbFreeNotifyReqeust(acm);
1371 ERR_ALLOC_NOTIFY_REQ:
1372 UsbFreeWriteRequests(acm);
1373 ERR_ALLOC_WRITE_REQS:
1374 AcmWriteBufFree(acm);
1375 ERR_ALLOC_WRITE_BUF:
1376 UsbReleaseInterfaces(acm);
1377 ERR_PARSE_DESC:
1378 UsbRawFreeConfigDescriptor(acm->config);
1379 acm->config = NULL;
1380 ERR_GET_DESC:
1381 (void)UsbRawCloseDevice(devHandle);
1382 ERR_OPEN_DEVICE:
1383 UsbRawExit(acm->session);
1384
1385 return ret;
1386 }
1387
UsbSerialRelease(struct AcmDevice * acm)1388 static void UsbSerialRelease(struct AcmDevice *acm)
1389 {
1390 if (acm->initFlag == false) {
1391 HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
1392 return;
1393 }
1394
1395 /* stop io thread and release all resources */
1396 UsbStopIo(acm);
1397 if (g_syncRequest != NULL) {
1398 UsbRawFreeRequest(g_syncRequest);
1399 g_syncRequest = NULL;
1400 }
1401 UsbFreeReadRequests(acm);
1402 UsbFreeNotifyReqeust(acm);
1403 UsbFreeWriteRequests(acm);
1404 AcmWriteBufFree(acm);
1405 UsbReleaseInterfaces(acm);
1406 (void)UsbRawCloseDevice(acm->devHandle);
1407 UsbRawFreeConfigDescriptor(acm->config);
1408 acm->config = NULL;
1409 UsbRawExit(acm->session);
1410
1411 acm->initFlag = false;
1412 }
1413
UsbSerialDriverInit(struct HdfDeviceObject * device)1414 static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
1415 {
1416 struct AcmDevice *acm = NULL;
1417 int32_t ret;
1418
1419 if (device == NULL) {
1420 HDF_LOGE("%s:%d device is null", __func__, __LINE__);
1421 return HDF_ERR_INVALID_OBJECT;
1422 }
1423 acm = (struct AcmDevice *)device->service;
1424 if (acm == NULL) {
1425 return HDF_ERR_INVALID_OBJECT;
1426 }
1427 OsalMutexInit(&acm->readLock);
1428 OsalMutexInit(&acm->writeLock);
1429
1430 ret = UsbSerialDeviceAlloc(acm);
1431 if (ret != HDF_SUCCESS) {
1432 HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__);
1433 }
1434
1435 acm->initFlag = false;
1436 g_rawAcmReleaseFlag = false;
1437
1438 HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
1439
1440 return ret;
1441 }
1442
UsbSerialDriverRelease(struct HdfDeviceObject * device)1443 static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
1444 {
1445 struct AcmDevice *acm = NULL;
1446 if (device == NULL) {
1447 HDF_LOGE("%s: device is NULL", __func__);
1448 return;
1449 }
1450
1451 acm = (struct AcmDevice *)device->service;
1452 if (acm == NULL) {
1453 HDF_LOGE("%s: acm is null", __func__);
1454 return;
1455 }
1456
1457 g_rawAcmReleaseFlag = true;
1458
1459 if (acm->initFlag == true) {
1460 HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__);
1461 UsbSerialRelease(acm);
1462 }
1463 UsbSeriaDevicelFree(acm);
1464 OsalMutexDestroy(&acm->writeLock);
1465 OsalMutexDestroy(&acm->readLock);
1466 OsalMutexDestroy(&acm->lock);
1467 OsalMemFree(acm);
1468 acm = NULL;
1469 HDF_LOGD("%s:%d exit", __func__, __LINE__);
1470 }
1471
1472 struct HdfDriverEntry g_usbSerialRawDriverEntry = {
1473 .moduleVersion = 1,
1474 .moduleName = "usbhost_acm_rawapi",
1475 .Bind = UsbSerialDriverBind,
1476 .Init = UsbSerialDriverInit,
1477 .Release = UsbSerialDriverRelease,
1478 };
1479 HDF_INIT(g_usbSerialRawDriverEntry);
1480
1481