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 if (!HdfSbufWriteUint32(reply, baudRate)) {
620 HDF_LOGE("%s:%d sbuf write buffer failed", __func__, __LINE__);
621 return HDF_ERR_IO;
622 }
623
624 HDF_LOGE("%s:%d baudRate=%d", __func__, __LINE__, baudRate);
625
626 return HDF_SUCCESS;
627 }
628
SerialOpen(struct SerialDevice * port,struct HdfSBuf * data)629 static int32_t SerialOpen(struct SerialDevice *port, struct HdfSBuf *data)
630 {
631 struct AcmDevice *acm = NULL;
632 int32_t ret;
633 int32_t cmdType = HOST_ACM_ASYNC_READ;
634
635 if ((port == NULL) || (data == NULL)) {
636 HDF_LOGE("%s: invalid parma", __func__);
637 return HDF_ERR_INVALID_PARAM;
638 }
639
640 acm = port->acm;
641 if (acm == NULL) {
642 HDF_LOGE("%s: invalid parma", __func__);
643 return HDF_ERR_INVALID_PARAM;
644 }
645
646 if (!HdfSbufReadInt32(data, &cmdType)) {
647 HDF_LOGE("%s:%d sbuf read cmdType failed", __func__, __LINE__);
648 return HDF_ERR_INVALID_PARAM;
649 }
650
651 ret = UsbSerialInit(acm);
652 if (ret != HDF_SUCCESS) {
653 HDF_LOGE("%s:%d UsbSerialInit failed", __func__, __LINE__);
654 return HDF_FAILURE;
655 }
656
657 if (cmdType != HOST_ACM_ASYNC_READ) {
658 HDF_LOGD("%s:%d asyncRead success", __func__, __LINE__);
659 return HDF_SUCCESS;
660 }
661
662 ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE);
663 if (ret != HDF_SUCCESS) {
664 HDF_LOGE("%s: UsbSerialAllocFifo failed", __func__);
665 return HDF_ERR_INVALID_PARAM;
666 }
667 for (int32_t i = 0; i < ACM_NR; i++) {
668 ret = UsbRawSubmitRequest(acm->readReq[i]);
669 if (ret) {
670 HDF_LOGE("%s: UsbRawSubmitRequest failed, ret=%d ", __func__, ret);
671 goto ERR;
672 }
673 }
674 return HDF_SUCCESS;
675
676 ERR:
677 UsbSerialFreeFifo(&port->readFifo);
678 return ret;
679 }
680
SerialClose(struct SerialDevice * port,struct HdfSBuf * data)681 static int32_t SerialClose(struct SerialDevice *port, struct HdfSBuf *data)
682 {
683 int32_t cmdType = HOST_ACM_SYNC_READ;
684
685 if ((port == NULL) || (data == NULL)) {
686 HDF_LOGE("%s:%d invalid parma", __func__, __LINE__);
687 return HDF_ERR_INVALID_PARAM;
688 }
689
690 if (port->acm == NULL) {
691 HDF_LOGE("%s:%d acm is NULL invalid parma", __func__, __LINE__);
692 return HDF_ERR_INVALID_PARAM;
693 }
694
695 if (!HdfSbufReadInt32(data, &cmdType)) {
696 HDF_LOGE("%s:%d sbuf read cmdType failed", __func__, __LINE__);
697 return HDF_ERR_INVALID_PARAM;
698 }
699
700 if ((cmdType == HOST_ACM_SYNC_READ) || (cmdType == HOST_ACM_SYNC_WRITE) || (cmdType == HOST_ACM_ASYNC_WRITE)) {
701 HDF_LOGD("%s:%d cmdType=%d success", __func__, __LINE__, cmdType);
702 return HDF_SUCCESS;
703 }
704
705 OsalMutexLock(&port->acm->readLock);
706 UsbSerialFreeFifo(&port->readFifo);
707 OsalMutexUnlock(&port->acm->readLock);
708
709 UsbSerialRelease(port->acm);
710
711 return HDF_SUCCESS;
712 }
713
SerialWrite(struct SerialDevice * port,struct HdfSBuf * data)714 static int32_t SerialWrite(struct SerialDevice *port, struct HdfSBuf *data)
715 {
716 struct AcmDevice *acm = NULL;
717 struct AcmWb *wb = NULL;
718 const char *tmp = NULL;
719 int32_t size;
720 int32_t wbn;
721
722 if (port == NULL) {
723 HDF_LOGE("%{public}s: port is null", __func__);
724 return HDF_ERR_INVALID_PARAM;
725 }
726 acm = port->acm;
727 if (acm == NULL) {
728 HDF_LOGE("%{public}s: acm is null", __func__);
729 return HDF_ERR_INVALID_PARAM;
730 }
731 if (AcmWbIsAvail(acm)) {
732 wbn = AcmWbAlloc(acm);
733 } else {
734 HDF_LOGE("%{public}s: no write buf", __func__);
735 return HDF_SUCCESS;
736 }
737 if (wbn < 0 || wbn >= ACM_NW) {
738 HDF_LOGE("%{public}s: AcmWbAlloc failed", __func__);
739 return HDF_FAILURE;
740 }
741 wb = &acm->wb[wbn];
742 if (wb == NULL) {
743 return HDF_FAILURE;
744 }
745 tmp = HdfSbufReadString(data);
746 if (tmp == NULL) {
747 HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
748 return HDF_ERR_IO;
749 }
750 size = (int32_t)strlen(tmp) + 1;
751 if (acm->dataOutEp != NULL) {
752 size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size;
753 if (memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size) != EOK) {
754 HDF_LOGE("%{public}s: memcpy_s fail", __func__);
755 }
756 }
757 wb->len = (uint32_t)size;
758
759 if (AcmStartWb(acm, wb) != HDF_SUCCESS) {
760 HDF_LOGE("%{public}s: AcmStartWb failed", __func__);
761 return HDF_FAILURE;
762 }
763 return size;
764 }
765
AcmStartWbSync(struct AcmDevice * acm,struct AcmWb * wb)766 static int32_t AcmStartWbSync(struct AcmDevice *acm, struct AcmWb *wb)
767 {
768 int32_t ret;
769 int32_t size;
770 struct UsbRequestData requestData;
771
772 requestData.endPoint = acm->dataOutEp->addr;
773 requestData.data = wb->buf;
774 requestData.length = wb->len;
775 requestData.requested = &size;
776 requestData.timeout = USB_CTRL_SET_TIMEOUT;
777
778 acm->writeReq = wb->request;
779 ret = UsbRawSendBulkRequest(wb->request, acm->devHandle, &requestData);
780 if (ret) {
781 HDF_LOGE("UsbRawSendBulkRequest failed, ret=%d", ret);
782 }
783
784 wb->use = 0;
785
786 return ret;
787 }
788
SerialWriteSync(const struct SerialDevice * port,const struct HdfSBuf * data)789 static int32_t SerialWriteSync(const struct SerialDevice *port, const struct HdfSBuf *data)
790 {
791 struct AcmDevice *acm = NULL;
792 struct AcmWb *wb = NULL;
793 const char *tmp = NULL;
794 int32_t size;
795 int32_t wbn;
796
797 if (port == NULL) {
798 HDF_LOGE("%{public}s: invalid parma", __func__);
799 return HDF_ERR_INVALID_PARAM;
800 }
801 acm = port->acm;
802 if (acm == NULL) {
803 HDF_LOGE("%{public}s: invalid parma", __func__);
804 return HDF_ERR_INVALID_PARAM;
805 }
806
807 if (AcmWbIsAvail(acm)) {
808 wbn = AcmWbAlloc(acm);
809 } else {
810 HDF_LOGE("%{public}s: no write buf", __func__);
811 return HDF_SUCCESS;
812 }
813
814 if (wbn >= ACM_NW || wbn < 0) {
815 wbn = 0;
816 }
817 wb = &acm->wb[wbn];
818 if ((wb == NULL) || (wb->buf == NULL)) {
819 return HDF_ERR_INVALID_PARAM;
820 }
821 tmp = HdfSbufReadString((struct HdfSBuf *)data);
822 if (tmp == NULL) {
823 HDF_LOGE("%{public}s: sbuf read buffer failed", __func__);
824 return HDF_ERR_IO;
825 }
826 size = (int32_t)strlen(tmp) + 1;
827 if (acm->dataOutEp == NULL) {
828 return HDF_ERR_IO;
829 }
830 size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size;
831 if (memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size) != EOK) {
832 HDF_LOGE("%{public}s: memcpy_s failed", __func__);
833 }
834 wb->len = (uint32_t)size;
835
836 if (AcmStartWbSync(acm, wb) != HDF_SUCCESS) {
837 HDF_LOGE("%{public}s: AcmStartWbSync failed", __func__);
838 return HDF_FAILURE;
839 }
840
841 return size;
842 }
843
UsbSerialReadSync(const struct SerialDevice * port,const struct HdfSBuf * reply)844 static int32_t UsbSerialReadSync(const struct SerialDevice *port, const struct HdfSBuf *reply)
845 {
846 int32_t ret;
847 int32_t size;
848 struct AcmDevice *acm = port->acm;
849 uint8_t *data = NULL;
850 struct UsbRequestData requestData;
851
852 if (g_syncRequest == NULL) {
853 g_syncRequest = UsbRawAllocRequest(acm->devHandle, 0, acm->dataInEp->maxPacketSize);
854 if (g_syncRequest == NULL) {
855 HDF_LOGE("UsbRawAllocRequest g_syncRequest failed\n");
856 return HDF_ERR_MALLOC_FAIL;
857 }
858 }
859 HDF_LOGD("%s:%d g_syncRequest \n", __func__, __LINE__);
860
861 requestData.endPoint = acm->dataInEp->addr;
862 requestData.data = g_syncRequest->buffer;
863 requestData.length = acm->dataInEp->maxPacketSize;
864 requestData.requested = &size;
865 requestData.timeout = USB_CTRL_SET_TIMEOUT;
866
867 ret = UsbRawSendBulkRequest(g_syncRequest, acm->devHandle, &requestData);
868 if (ret) {
869 HDF_LOGE("UsbRawSendBulkRequest failed, ret=%d", ret);
870 return ret;
871 }
872
873 uint32_t count = (uint32_t)g_syncRequest->actualLength;
874 data = (uint8_t *)OsalMemCalloc(count + 1);
875 if (data == NULL) {
876 HDF_LOGE("%s: OsalMemCalloc error", __func__);
877 return HDF_ERR_MALLOC_FAIL;
878 }
879 HDF_LOGD("buffer actualLength:%u", count);
880
881 do {
882 ret = memcpy_s(data, g_syncRequest->actualLength, g_syncRequest->buffer, count);
883 if (ret != EOK) {
884 HDF_LOGE("%{public}s: memcpy_s error", __func__);
885 break;
886 }
887
888 if (!HdfSbufWriteString((struct HdfSBuf *)reply, (char *)data)) {
889 HDF_LOGE("%s: sbuf write buffer failed", __func__);
890 ret = HDF_ERR_IO;
891 break;
892 }
893 } while (0);
894
895 OsalMemFree(data);
896 data = NULL;
897 return ret;
898 }
899
SerialAddOrRemoveInterface(int32_t cmd,const struct SerialDevice * port,const struct HdfSBuf * data)900 static int32_t SerialAddOrRemoveInterface(int32_t cmd, const struct SerialDevice *port, const struct HdfSBuf *data)
901 {
902 (void)cmd;
903 (void)port;
904 (void)data;
905
906 return HDF_SUCCESS;
907 }
908
UsbSerialDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)909 static int32_t UsbSerialDeviceDispatch(
910 struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
911 {
912 struct AcmDevice *acm = NULL;
913 struct SerialDevice *port = NULL;
914
915 if ((client == NULL) || (client->device == NULL)) {
916 HDF_LOGE("%{public}s: client or client->device is NULL", __func__);
917 return HDF_ERR_INVALID_OBJECT;
918 }
919
920 if (client->device->service == NULL) {
921 HDF_LOGE("%{public}s: client->device->service is NULL", __func__);
922 return HDF_ERR_INVALID_OBJECT;
923 }
924
925 if (g_rawAcmReleaseFlag == true) {
926 HDF_LOGE("%{public}s: g_rawAcmReleaseFlag is true", __func__);
927 return HDF_FAILURE;
928 }
929
930 acm = (struct AcmDevice *)client->device->service;
931 port = acm->port;
932 if (port == NULL) {
933 return HDF_FAILURE;
934 }
935 switch (cmd) {
936 case CMD_OPEN_PARM:
937 return SerialOpen(port, data);
938 case CMD_CLOSE_PARM:
939 return SerialClose(port, data);
940 case CMD_WRITE_PARM:
941 return SerialWrite(port, data);
942 case CMD_READ_PARM:
943 return UsbSerialRead(port, reply);
944 case CMD_GET_BAUDRATE:
945 return SerialGetBaudrate(port, reply);
946 case CMD_SET_BAUDRATE:
947 return SerialSetBaudrate(port, data);
948 case CMD_WRITE_DATA_SYNC:
949 return SerialWriteSync(port, data);
950 case CMD_READ_DATA_SYNC:
951 return UsbSerialReadSync(port, reply);
952 case CMD_ADD_INTERFACE:
953 case CMD_REMOVE_INTERFACE:
954 return SerialAddOrRemoveInterface(cmd, port, data);
955 default:
956 return HDF_ERR_NOT_SUPPORT;
957 }
958 }
959
960 /* HdfDriverEntry implementations */
UsbSerialDriverBind(struct HdfDeviceObject * device)961 static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
962 {
963 struct AcmDevice *acm = NULL;
964 struct UsbPnpNotifyServiceInfo *info = NULL;
965 errno_t err;
966
967 if (device == NULL) {
968 HDF_LOGE("%s: device is null", __func__);
969 return HDF_ERR_INVALID_OBJECT;
970 }
971
972 acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
973 if (acm == NULL) {
974 HDF_LOGE("%s: Alloc usb serial device failed", __func__);
975 return HDF_FAILURE;
976 }
977 if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
978 HDF_LOGE("%s:%d OsalMutexInit fail", __func__, __LINE__);
979 goto ERROR;
980 }
981
982 info = (struct UsbPnpNotifyServiceInfo *)device->priv;
983 if (info != NULL) {
984 acm->busNum = (uint8_t)info->busNum;
985 acm->devAddr = (uint8_t)info->devNum;
986 acm->interfaceCnt = info->interfaceLength;
987 err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber,
988 info->interfaceLength);
989 if (err != EOK) {
990 HDF_LOGE("%s:%d memcpy_s failed err=%d", __func__, __LINE__, err);
991 goto LOCK_ERROR;
992 }
993 } else {
994 HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__);
995 goto LOCK_ERROR;
996 }
997
998 device->service = &(acm->service);
999 device->service->Dispatch = UsbSerialDeviceDispatch;
1000 acm->device = device;
1001 HDF_LOGD("UsbSerialDriverBind=========================OK");
1002 return HDF_SUCCESS;
1003
1004 LOCK_ERROR:
1005 if (OsalMutexDestroy(&acm->lock)) {
1006 HDF_LOGE("%s:%d OsalMutexDestroy fail", __func__, __LINE__);
1007 }
1008 ERROR:
1009 OsalMemFree(acm);
1010 acm = NULL;
1011 return HDF_FAILURE;
1012 }
1013
AcmProcessNotification(const struct AcmDevice * acm,const unsigned char * buf)1014 static void AcmProcessNotification(const struct AcmDevice *acm, const unsigned char *buf)
1015 {
1016 (void)acm;
1017 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)buf;
1018
1019 switch (dr->bNotificationType) {
1020 case USB_DDK_CDC_NOTIFY_NETWORK_CONNECTION:
1021 HDF_LOGE("%s - network connection: %d\n", __func__, dr->wValue);
1022 break;
1023 case USB_DDK_CDC_NOTIFY_SERIAL_STATE:
1024 HDF_LOGE("the serial State change\n");
1025 break;
1026 default:
1027 HDF_LOGE("%s-%d received: index %d len %d\n", __func__, dr->bNotificationType, dr->wIndex, dr->wLength);
1028 }
1029 }
1030
AcmNotificationBufferProcess(const struct UsbRawRequest * req,struct AcmDevice * acm,unsigned int currentSize,unsigned int expectedSize)1031 static int32_t AcmNotificationBufferProcess(
1032 const struct UsbRawRequest *req, struct AcmDevice *acm, unsigned int currentSize, unsigned int expectedSize)
1033 {
1034 if (acm->nbSize < expectedSize) {
1035 if (acm->nbSize) {
1036 OsalMemFree(acm->notificationBuffer);
1037 acm->nbSize = 0;
1038 }
1039 unsigned int allocSize = expectedSize;
1040 acm->notificationBuffer = (uint8_t *)OsalMemCalloc(allocSize);
1041 if (!acm->notificationBuffer) {
1042 return HDF_FAILURE;
1043 }
1044 acm->nbSize = allocSize;
1045 }
1046 unsigned int copySize = MIN(currentSize, expectedSize - acm->nbIndex);
1047 int32_t ret = memcpy_s(&acm->notificationBuffer[acm->nbIndex], acm->nbSize - acm->nbIndex, req->buffer, copySize);
1048 if (ret != EOK) {
1049 HDF_LOGE("memcpy_s fail ret=%d", ret);
1050 }
1051 acm->nbIndex += copySize;
1052
1053 return HDF_SUCCESS;
1054 }
1055
AcmNotifyReqCallback(const void * requestArg)1056 static void AcmNotifyReqCallback(const void *requestArg)
1057 {
1058 struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
1059 if (req == NULL) {
1060 HDF_LOGE("%s:%d req is NULL!", __func__, __LINE__);
1061 return;
1062 }
1063 struct AcmDevice *acm = (struct AcmDevice *)req->userData;
1064 if (acm == NULL) {
1065 HDF_LOGE("%s:%d userData(acm) is NULL!", __func__, __LINE__);
1066 return;
1067 }
1068 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)req->buffer;
1069 if (dr == NULL) {
1070 HDF_LOGE("%s:%d req->buffer(dr) is NULL!", __func__, __LINE__);
1071 return;
1072 }
1073 unsigned int currentSize = (unsigned int)req->actualLength;
1074 unsigned int expectedSize = 0;
1075
1076 HDF_LOGD("Irqstatus:%d,actualLength:%u\n", req->status, currentSize);
1077
1078 if (req->status != USB_REQUEST_COMPLETED) {
1079 goto EXIT;
1080 }
1081
1082 if (acm->nbIndex) {
1083 dr = (struct UsbCdcNotification *)acm->notificationBuffer;
1084 }
1085 if (dr != NULL) {
1086 expectedSize = sizeof(struct UsbCdcNotification) + LE16_TO_CPU(dr->wLength);
1087 } else {
1088 HDF_LOGE("%s:%d dr is NULL!", __func__, __LINE__);
1089 return;
1090 }
1091 if (currentSize < expectedSize) {
1092 if (AcmNotificationBufferProcess(req, acm, currentSize, expectedSize) != HDF_SUCCESS) {
1093 goto EXIT;
1094 }
1095 currentSize = acm->nbIndex;
1096 }
1097 if (currentSize >= expectedSize) {
1098 AcmProcessNotification(acm, (unsigned char *)dr);
1099 acm->nbIndex = 0;
1100 }
1101
1102 if (UsbRawSubmitRequest(req) != HDF_SUCCESS) {
1103 HDF_LOGE("%s - UsbRawSubmitRequest failed", __func__);
1104 }
1105
1106 EXIT:
1107 HDF_LOGE("%s:%d exit", __func__, __LINE__);
1108 }
1109
AcmReadBulkCallback(const void * requestArg)1110 static void AcmReadBulkCallback(const void *requestArg)
1111 {
1112 struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg;
1113 if (req == NULL) {
1114 HDF_LOGE("%s:%d req is NULL!", __func__, __LINE__);
1115 return;
1116 }
1117 struct AcmDevice *acm = (struct AcmDevice *)req->userData;
1118 if (acm == NULL || acm->port == NULL) {
1119 HDF_LOGE("%s:%d request userData is NULL!", __func__, __LINE__);
1120 return;
1121 }
1122 size_t size = (size_t)req->actualLength;
1123
1124 if (req->status != USB_REQUEST_COMPLETED) {
1125 HDF_LOGW("%{public}s: the request is failed, status=%d", __func__, req->status);
1126 return;
1127 }
1128 HDF_LOGD("Bulk status: %d+size:%zu", req->status, size);
1129 if (size == 0) {
1130 uint8_t *data = req->buffer;
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("%{public}s: write %u less than expected %zu", __func__, count, size);
1138 }
1139 OsalMutexUnlock(&acm->readLock);
1140 }
1141
1142 if (UsbRawSubmitRequest(req) != HDF_SUCCESS) {
1143 HDF_LOGE("%s UsbRawSubmitRequest failed", __func__);
1144 }
1145 }
1146
UsbAllocReadRequests(struct AcmDevice * acm)1147 static int32_t UsbAllocReadRequests(struct AcmDevice *acm)
1148 {
1149 struct UsbRawFillRequestData reqData;
1150 uint32_t size = acm->dataInEp->maxPacketSize;
1151
1152 for (int32_t i = 0; i < ACM_NR; i++) {
1153 acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size);
1154 if (!acm->readReq[i]) {
1155 HDF_LOGE("readReq request failed\n");
1156 return HDF_ERR_MALLOC_FAIL;
1157 }
1158
1159 reqData.endPoint = acm->dataInEp->addr;
1160 reqData.numIsoPackets = 0;
1161 reqData.callback = AcmReadBulkCallback;
1162 reqData.userData = (void *)acm;
1163 reqData.timeout = USB_CTRL_SET_TIMEOUT;
1164 reqData.length = size;
1165
1166 int32_t ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData);
1167 if (ret != HDF_SUCCESS) {
1168 HDF_LOGE("%s: FillBulkRequest failed, ret=%d\n", __func__, ret);
1169 return HDF_FAILURE;
1170 }
1171 }
1172
1173 return HDF_SUCCESS;
1174 }
1175
UsbFreeReadRequests(struct AcmDevice * acm)1176 static void UsbFreeReadRequests(struct AcmDevice *acm)
1177 {
1178 int32_t i;
1179
1180 if (acm == NULL) {
1181 HDF_LOGE("%s: acm is NULL", __func__);
1182 return;
1183 }
1184
1185 for (i = 0; i < ACM_NR; i++) {
1186 if (acm->readReq[i]) {
1187 UsbRawFreeRequest(acm->readReq[i]);
1188 acm->readReq[i] = NULL;
1189 }
1190 }
1191 }
1192
UsbAllocNotifyRequest(struct AcmDevice * acm)1193 static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm)
1194 {
1195 struct UsbRawFillRequestData fillRequestData;
1196 uint32_t size = acm->notifyEp->maxPacketSize;
1197 int32_t ret;
1198
1199 acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size);
1200 if (!acm->notifyReq) {
1201 HDF_LOGE("notifyReq request fail\n");
1202 return HDF_ERR_MALLOC_FAIL;
1203 }
1204
1205 fillRequestData.endPoint = acm->notifyEp->addr;
1206 fillRequestData.length = size;
1207 fillRequestData.numIsoPackets = 0;
1208 fillRequestData.callback = AcmNotifyReqCallback;
1209 fillRequestData.userData = (void *)acm;
1210 fillRequestData.timeout = USB_CTRL_SET_TIMEOUT;
1211
1212 ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData);
1213 if (ret) {
1214 HDF_LOGE("%s: FillInterruptRequest failed, ret=%d", __func__, ret);
1215 return HDF_FAILURE;
1216 }
1217
1218 return HDF_SUCCESS;
1219 }
1220
UsbFreeNotifyReqeust(struct AcmDevice * acm)1221 static void UsbFreeNotifyReqeust(struct AcmDevice *acm)
1222 {
1223 int32_t ret;
1224
1225 if ((acm == NULL) || (acm->notifyReq == NULL)) {
1226 HDF_LOGE("%s: acm or notifyReq is NULL", __func__);
1227 return;
1228 }
1229
1230 ret = UsbRawFreeRequest(acm->notifyReq);
1231 if (ret == HDF_SUCCESS) {
1232 acm->notifyReq = NULL;
1233 } else {
1234 HDF_LOGE("%s: UsbFreeNotifyReqeust failed, ret=%d", __func__, ret);
1235 }
1236 }
1237
UsbAllocRequests(struct AcmDevice * acm,int32_t ret)1238 static void UsbAllocRequests(struct AcmDevice *acm, int32_t ret)
1239 {
1240 ret = UsbAllocWriteRequests(acm);
1241 if (ret < 0) {
1242 HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__);
1243 ret = HDF_FAILURE;
1244 goto ERR_ALLOC_WRITE_REQS;
1245 }
1246 ret = UsbAllocNotifyRequest(acm);
1247 if (ret) {
1248 HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__);
1249 goto ERR_ALLOC_NOTIFY_REQ;
1250 }
1251 ret = UsbAllocReadRequests(acm);
1252 if (ret) {
1253 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1254 goto ERR_ALLOC_READ_REQS;
1255 }
1256 ret = UsbStartIo(acm);
1257 if (ret) {
1258 HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
1259 goto ERR_START_IO;
1260 }
1261
1262 acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE);
1263 acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
1264 acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
1265 acm->lineCoding.bDataBits = DATA_BITS_LENGTH;
1266
1267 ret = UsbRawSubmitRequest(acm->notifyReq);
1268 if (ret) {
1269 HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__);
1270 goto ERR_SUBMIT_REQ;
1271 }
1272 ret = AcmWriteBufAlloc(acm);
1273 if (ret < 0) {
1274 HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__);
1275 ret = HDF_FAILURE;
1276 goto ERR_ALLOC_WRITE_BUF;
1277 }
1278 ERR_SUBMIT_REQ:
1279 UsbStopIo(acm);
1280 ERR_START_IO:
1281 UsbFreeReadRequests(acm);
1282 ERR_ALLOC_READ_REQS:
1283 UsbFreeNotifyReqeust(acm);
1284 ERR_ALLOC_NOTIFY_REQ:
1285 UsbFreeWriteRequests(acm);
1286 ERR_ALLOC_WRITE_REQS:
1287 AcmWriteBufFree(acm);
1288 ERR_ALLOC_WRITE_BUF:
1289 UsbReleaseInterfaces(acm);
1290 }
1291
UsbSerialInit(struct AcmDevice * acm)1292 static int32_t UsbSerialInit(struct AcmDevice *acm)
1293 {
1294 struct UsbSession *session = NULL;
1295 UsbRawHandle *devHandle = NULL;
1296 int32_t ret;
1297 if (acm->initFlag) {
1298 HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__);
1299 return HDF_SUCCESS;
1300 }
1301 ret = UsbRawInit(NULL);
1302 if (ret) {
1303 HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__);
1304 return HDF_ERR_IO;
1305 }
1306 acm->session = session;
1307 devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr);
1308 if (devHandle == NULL) {
1309 HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__);
1310 ret = HDF_FAILURE;
1311 goto ERR_OPEN_DEVICE;
1312 }
1313 acm->devHandle = devHandle;
1314 ret = UsbGetConfigDescriptor(devHandle, &acm->config);
1315 if (ret) {
1316 HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__);
1317 ret = HDF_FAILURE;
1318 goto ERR_GET_DESC;
1319 }
1320 ret = UsbParseConfigDescriptor(acm, acm->config);
1321 if (ret != HDF_SUCCESS) {
1322 HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__);
1323 ret = HDF_FAILURE;
1324 goto ERR_PARSE_DESC;
1325 }
1326 UsbAllocRequests(acm, ret);
1327 acm->initFlag = true;
1328 HDF_LOGD("%s:%d=========================OK", __func__, __LINE__);
1329 return HDF_SUCCESS;
1330 ERR_PARSE_DESC:
1331 UsbRawFreeConfigDescriptor(acm->config);
1332 acm->config = NULL;
1333 ERR_GET_DESC:
1334 (void)UsbRawCloseDevice(devHandle);
1335 ERR_OPEN_DEVICE:
1336 UsbRawExit(acm->session);
1337 return ret;
1338 }
1339
UsbSerialRelease(struct AcmDevice * acm)1340 static void UsbSerialRelease(struct AcmDevice *acm)
1341 {
1342 if (!(acm->initFlag)) {
1343 HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
1344 return;
1345 }
1346
1347 /* stop io thread and release all resources */
1348 UsbStopIo(acm);
1349 if (g_syncRequest != NULL) {
1350 UsbRawFreeRequest(g_syncRequest);
1351 g_syncRequest = NULL;
1352 }
1353 UsbFreeReadRequests(acm);
1354 UsbFreeNotifyReqeust(acm);
1355 UsbFreeWriteRequests(acm);
1356 AcmWriteBufFree(acm);
1357 UsbReleaseInterfaces(acm);
1358 (void)UsbRawCloseDevice(acm->devHandle);
1359 UsbRawFreeConfigDescriptor(acm->config);
1360 acm->config = NULL;
1361 UsbRawExit(acm->session);
1362
1363 acm->initFlag = false;
1364 }
1365
UsbSerialDriverInit(struct HdfDeviceObject * device)1366 static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
1367 {
1368 struct AcmDevice *acm = NULL;
1369 int32_t ret;
1370
1371 if (device == NULL) {
1372 HDF_LOGE("%s:%d device is null", __func__, __LINE__);
1373 return HDF_ERR_INVALID_OBJECT;
1374 }
1375 acm = (struct AcmDevice *)device->service;
1376 if (acm == NULL) {
1377 return HDF_ERR_INVALID_OBJECT;
1378 }
1379 OsalMutexInit(&acm->readLock);
1380 OsalMutexInit(&acm->writeLock);
1381
1382 ret = UsbSerialDeviceAlloc(acm);
1383 if (ret != HDF_SUCCESS) {
1384 HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__);
1385 }
1386
1387 acm->initFlag = false;
1388 g_rawAcmReleaseFlag = false;
1389
1390 HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
1391
1392 return ret;
1393 }
1394
UsbSerialDriverRelease(struct HdfDeviceObject * device)1395 static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
1396 {
1397 struct AcmDevice *acm = NULL;
1398 if (device == NULL) {
1399 HDF_LOGE("%s: device is null", __func__);
1400 return;
1401 }
1402
1403 acm = (struct AcmDevice *)device->service;
1404 if (acm == NULL) {
1405 HDF_LOGE("%s: acm is null", __func__);
1406 return;
1407 }
1408
1409 g_rawAcmReleaseFlag = true;
1410
1411 if (acm->initFlag) {
1412 HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__);
1413 UsbSerialRelease(acm);
1414 }
1415 UsbSeriaDevicelFree(acm);
1416 OsalMutexDestroy(&acm->writeLock);
1417 OsalMutexDestroy(&acm->readLock);
1418 OsalMutexDestroy(&acm->lock);
1419 OsalMemFree(acm);
1420 acm = NULL;
1421 HDF_LOGD("%s:%d exit", __func__, __LINE__);
1422 }
1423
1424 struct HdfDriverEntry g_usbSerialRawDriverEntry = {
1425 .moduleVersion = 1,
1426 .moduleName = "usbhost_acm_rawapi",
1427 .Bind = UsbSerialDriverBind,
1428 .Init = UsbSerialDriverInit,
1429 .Release = UsbSerialDriverRelease,
1430 };
1431 HDF_INIT(g_usbSerialRawDriverEntry);
1432