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