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 "cdc_ether.h"
19 #include "hdf_base.h"
20 #include "hdf_log.h"
21 #include "hdf_usb_pnp_manage.h"
22 #include "osal_mem.h"
23 #include "osal_time.h"
24 #include "securec.h"
25 #include "usb_ddk_interface.h"
26 #ifndef USBD_WRAPPER_H
27 #define USBD_WRAPPER_H
28 // define Domain ID
29 #ifdef LOG_DOMAIN
30 #undef LOG_DOMAIN
31 #endif
32 #define LOG_DOMAIN 0xD002518
33 #endif // USBD_WRAPPER_H
34
35 #define HDF_LOG_TAG USB_HOST_ECM
36
37 static bool g_ecmReleaseFlag = false;
38
39 static void EcmWriteBulk(struct UsbRequest *req);
40 static void EcmAllocWriteReq(struct EcmDevice * const ecm);
41 static void EcmFreeWriteReq(struct EcmDevice * const ecm);
42 static int32_t EcmAllocIntReq(struct EcmDevice *ecm);
43 static void EcmAllocReadReq(struct EcmDevice *ecm);
44 static void EcmFreeReadReq(struct EcmDevice *ecm);
45 static int32_t EcmInit(struct EcmDevice *ecm);
46 static void EcmRelease(struct EcmDevice *ecm);
47 static struct UsbInterface *EcmGetUsbInterfaceById(struct EcmDevice *ecm, uint8_t interfaceIndex);
48
EcmWbAlloc(struct EcmDevice * ecm)49 static int32_t EcmWbAlloc(struct EcmDevice *ecm)
50 {
51 int32_t i, wbn;
52 struct EcmWb *wb = NULL;
53 wbn = 0;
54 i = 0;
55 OsalMutexLock(&ecm->writeLock);
56 for (;;) {
57 wb = &ecm->wb[wbn];
58 if (!wb->use) {
59 wb->use = 1;
60 wb->len = 0;
61 OsalMutexUnlock(&ecm->writeLock);
62 return wbn;
63 }
64 wbn = (wbn + 1) % ECM_NW;
65 if (++i >= ECM_NW) {
66 OsalMutexUnlock(&ecm->writeLock);
67 return 0;
68 }
69 }
70 OsalMutexUnlock(&ecm->writeLock);
71 }
72
InterfaceIdToHandle(const struct EcmDevice * ecm,uint8_t id)73 static UsbInterfaceHandle *InterfaceIdToHandle(const struct EcmDevice *ecm, uint8_t id)
74 {
75 UsbInterfaceHandle *devHandle = NULL;
76
77 if (id == 0xFF) {
78 devHandle = ecm->ctrDevHandle;
79 } else {
80 for (int32_t i = 0; i < ecm->interfaceCnt; i++) {
81 if (ecm->iface[i]->info.interfaceIndex == id) {
82 devHandle = ecm->devHandle[i];
83 break;
84 }
85 }
86 }
87 return devHandle;
88 }
89
EcmAllocFifo(struct DataFifo * fifo,uint32_t size)90 static int32_t EcmAllocFifo(struct DataFifo *fifo, uint32_t size)
91 {
92 if (!DataFifoIsInitialized(fifo)) {
93 void *data = OsalMemAlloc(size);
94 if (data == NULL) {
95 HDF_LOGE("%{public}s: allocate fifo data buffer failed", __func__);
96 return HDF_ERR_MALLOC_FAIL;
97 }
98 DataFifoInit(fifo, size, data);
99 }
100 return HDF_SUCCESS;
101 }
102
EcmFreeFifo(struct DataFifo * fifo)103 static void EcmFreeFifo(struct DataFifo *fifo)
104 {
105 void *buf = fifo->data;
106 OsalMemFree(buf);
107 DataFifoInit(fifo, 0, NULL);
108 }
109
EcmWbIsAvail(struct EcmDevice * ecm)110 static int32_t EcmWbIsAvail(struct EcmDevice *ecm)
111 {
112 int32_t i, n;
113 n = ECM_NW;
114 OsalMutexLock(&ecm->writeLock);
115 for (i = 0; i < ECM_NW; i++) {
116 n -= ecm->wb[i].use;
117 }
118 OsalMutexUnlock(&ecm->writeLock);
119 return n;
120 }
121
EcmStartWb(struct EcmDevice * ecm,struct EcmWb * wb)122 static int32_t EcmStartWb(struct EcmDevice *ecm, struct EcmWb *wb)
123 {
124 int32_t rc;
125 struct UsbRequestParams parmas = {};
126 ecm->transmitting++;
127 parmas.interfaceId = ecm->dataOutPipe->interfaceId;
128 parmas.pipeAddress = ecm->dataOutPipe->pipeAddress;
129 parmas.pipeId = ecm->dataOutPipe->pipeId;
130 parmas.callback = EcmWriteBulk;
131 parmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
132 parmas.timeout = USB_CTRL_SET_TIMEOUT;
133 parmas.dataReq.numIsoPackets = 0;
134 parmas.userData = (void *)wb;
135 parmas.dataReq.length = (uint32_t)wb->len;
136 parmas.dataReq.buffer = wb->buf;
137 rc = UsbFillRequest(wb->request, InterfaceIdToHandle(ecm, ecm->dataOutPipe->interfaceId), &parmas);
138 if (rc != HDF_SUCCESS) {
139 HDF_LOGE("%{public}s: UsbFillRequest failed, ret=%{public}d", __func__, rc);
140 return rc;
141 }
142 ecm->writeReq = wb->request;
143 rc = UsbSubmitRequestAsync(wb->request);
144 if (rc < 0) {
145 HDF_LOGE("UsbRequestSubmitSync failed, ret=%{public}d", rc);
146 OsalMutexLock(&ecm->writeLock);
147 wb->use = 0;
148 OsalMutexUnlock(&ecm->writeLock);
149 ecm->transmitting--;
150 } else {
151 ecm->writeReqNum++;
152 }
153 return rc;
154 }
155
EcmWriteBufAlloc(struct EcmDevice * ecm)156 static int32_t EcmWriteBufAlloc(struct EcmDevice *ecm)
157 {
158 int32_t i;
159 struct EcmWb *wb;
160 for (wb = &ecm->wb[0], i = 0; i < ECM_NW; i++, wb++) {
161 wb->buf = OsalMemCalloc(ecm->writeSize);
162 if (!wb->buf) {
163 while (i != 0) {
164 --i;
165 --wb;
166 OsalMemFree(wb->buf);
167 wb->buf = NULL;
168 }
169 return -HDF_ERR_MALLOC_FAIL;
170 }
171 }
172 return 0;
173 }
174
EcmWriteBufFree(struct EcmDevice * ecm)175 static int32_t EcmWriteBufFree(struct EcmDevice *ecm)
176 {
177 int32_t i;
178 struct EcmWb *wb;
179 for (wb = &ecm->wb[0], i = 0; i < ECM_NW; i++, wb++) {
180 if (wb->buf) {
181 OsalMemFree(wb->buf);
182 wb->buf = NULL;
183 }
184 }
185 return 0;
186 }
187
EcmWriteBulk(struct UsbRequest * req)188 static void EcmWriteBulk(struct UsbRequest *req)
189 {
190 int32_t status = req->compInfo.status;
191 struct EcmWb *wb = (struct EcmWb *)req->compInfo.userData;
192 struct EcmDevice *ecm = wb->ecm;
193 ecm->writeReqNum--;
194
195 switch (status) {
196 case USB_REQUEST_COMPLETED:
197 OsalMutexLock(&ecm->writeLock);
198 wb->use = 0;
199 OsalMutexUnlock(&ecm->writeLock);
200 break;
201 case -ECONNRESET:
202 case -ENOENT:
203 case -ESHUTDOWN:
204 return;
205 default:
206 goto EXIT;
207 }
208 EXIT:
209 return;
210 }
211
EcmUsbControlMsg(const struct EcmControlParams * const controlParams)212 static struct UsbControlRequest EcmUsbControlMsg(const struct EcmControlParams * const controlParams)
213 {
214 struct UsbControlRequest dr;
215 dr.target = controlParams->requestType & TARGET_MASK;
216 dr.reqType = (controlParams->requestType >> USB_TYPE_OFFSET) & REQUEST_TYPE_MASK;
217 dr.directon = (controlParams->requestType >> USB_DIR_OFFSET) & DIRECTION_MASK;
218 dr.request = controlParams->request;
219 dr.value = CPU_TO_LE16(controlParams->value);
220 dr.index = CPU_TO_LE16(controlParams->index);
221 dr.buffer = controlParams->data;
222 dr.length = CPU_TO_LE16(controlParams->size);
223 return dr;
224 }
225
EcmCtrlMsg(struct EcmDevice * ecm,uint8_t request,uint16_t value,void * buf,uint16_t len)226 static int32_t EcmCtrlMsg(struct EcmDevice *ecm, uint8_t request, uint16_t value, void *buf, uint16_t len)
227 {
228 int32_t ret;
229 const uint16_t index = 0;
230 struct UsbRequest *usbRequest = NULL;
231 struct EcmControlParams controlParams;
232 struct UsbRequestParams parmas = {};
233 if (ecm == NULL) {
234 HDF_LOGE("%{public}s:invalid param", __func__);
235 return HDF_ERR_IO;
236 }
237 usbRequest = UsbAllocRequest(ecm->ctrDevHandle, 0, len);
238 if (usbRequest == NULL) {
239 HDF_LOGE("%{public}s: UsbAllocRequest failed", __func__);
240 return HDF_ERR_IO;
241 }
242 ecm->ctrlReq = usbRequest;
243
244 controlParams.request = request;
245 controlParams.requestType = USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
246 controlParams.value = value;
247 controlParams.index = index;
248 controlParams.data = buf;
249 controlParams.size = len;
250
251 parmas.interfaceId = USB_CTRL_INTERFACE_ID;
252 parmas.pipeAddress = ecm->ctrPipe->pipeAddress;
253 parmas.pipeId = ecm->ctrPipe->pipeId;
254 parmas.requestType = USB_REQUEST_PARAMS_CTRL_TYPE;
255 parmas.timeout = USB_CTRL_SET_TIMEOUT;
256 parmas.ctrlReq = EcmUsbControlMsg(&controlParams);
257
258 ret = UsbFillRequest(ecm->ctrlReq, ecm->ctrDevHandle, &parmas);
259 if (ret != HDF_SUCCESS) {
260 HDF_LOGE("%{public}s: failed, ret=%{public}d ", __func__, ret);
261 return ret;
262 }
263 ret = UsbSubmitRequestAsync(ecm->ctrlReq);
264 if (ret != HDF_SUCCESS) {
265 HDF_LOGE("UsbRequestSubmitSync failed, ret=%{public}d ", ret);
266 return ret;
267 }
268 if (!ecm->ctrlReq->compInfo.status) {
269 HDF_LOGE("%{public}s status=%{public}d ", __func__, ecm->ctrlReq->compInfo.status);
270 }
271 return HDF_SUCCESS;
272 }
273
EcmRead(struct EcmDevice * ecm,struct HdfSBuf * reply)274 static int32_t EcmRead(struct EcmDevice *ecm, struct HdfSBuf *reply)
275 {
276 uint32_t len;
277 int32_t ret = HDF_SUCCESS;
278 uint8_t *buf = NULL;
279 if (ecm == NULL) {
280 HDF_LOGE("%{public}d: invalid parma", __LINE__);
281 return HDF_ERR_INVALID_PARAM;
282 }
283 if (!(ecm->openFlag)) {
284 return HDF_ERR_BAD_FD;
285 }
286
287 for (int32_t i = 0; i < ECM_NR; i++) {
288 if (ecm->readReq[i]->compInfo.status != USB_REQUEST_COMPLETED) {
289 HDF_LOGE("%{public}s:%{public}d i=%{public}d status=%{public}d!",
290 __func__, __LINE__, i, ecm->readReq[i]->compInfo.status);
291 return HDF_FAILURE;
292 }
293 }
294 OsalMutexLock(&ecm->readLock);
295 if (DataFifoIsEmpty(&ecm->readFifo)) {
296 OsalMutexUnlock(&ecm->readLock);
297 return 0;
298 }
299 OsalMutexUnlock(&ecm->readLock);
300 buf = (uint8_t *)OsalMemCalloc(DataFifoLen(&ecm->readFifo) + sizeof(uint32_t));
301 if (buf == NULL) {
302 HDF_LOGE("%{public}s: OsalMemCalloc error", __func__);
303 return HDF_ERR_MALLOC_FAIL;
304 }
305 OsalMutexLock(&ecm->readLock);
306 len = DataFifoRead(&ecm->readFifo, buf, DataFifoLen(&ecm->readFifo));
307 if (len == 0) {
308 HDF_LOGE("%{public}s: no data", __func__);
309 ret = 0;
310 OsalMutexUnlock(&ecm->readLock);
311 goto OUT;
312 }
313 OsalMutexUnlock(&ecm->readLock);
314 bool bufok = HdfSbufWriteBuffer(reply, (const void *)buf, len);
315 if (!bufok) {
316 HDF_LOGE("EcmRead HdfSbufWriteBuffer err");
317 ret = HDF_ERR_IO;
318 }
319 OUT:
320 OsalMemFree(buf);
321 return ret;
322 }
323
EcmOpen(struct EcmDevice * ecm,struct HdfSBuf * data)324 static int32_t EcmOpen(struct EcmDevice *ecm, struct HdfSBuf *data)
325 {
326 int32_t ret;
327 int32_t cmdType = HOST_ECM_ADD_INTERFACE;
328
329 if ((ecm == NULL) || (data == NULL)) {
330 HDF_LOGE("%{public}s: invalid parma", __func__);
331 return HDF_ERR_INVALID_PARAM;
332 }
333
334 if (!HdfSbufReadInt32(data, &cmdType)) {
335 HDF_LOGE("%{public}s:%{public}d sbuf read cmdType failed", __func__, __LINE__);
336 return HDF_ERR_INVALID_PARAM;
337 }
338
339 ret = EcmInit(ecm);
340 if (ret != HDF_SUCCESS) {
341 HDF_LOGE("%{public}s:%{public}d EcmInit failed", __func__, __LINE__);
342 return HDF_FAILURE;
343 }
344
345 if ((cmdType == HOST_ECM_ADD_INTERFACE) || (cmdType == HOST_ECM_REMOVE_INTERFACE)) {
346 HDF_LOGD("%{public}s:%{public}d add or remove interface success", __func__, __LINE__);
347 return HDF_SUCCESS;
348 }
349
350 ret = EcmAllocFifo(&ecm->readFifo, READ_BUF_SIZE);
351 if (ret != HDF_SUCCESS) {
352 HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__);
353 return HDF_ERR_INVALID_PARAM;
354 }
355 ecm->openFlag = true;
356 ecm->readReqNum = 0;
357 ecm->writeReqNum = 0;
358 EcmAllocWriteReq(ecm);
359 EcmAllocReadReq(ecm);
360 for (int32_t i = 0; i < ECM_NR; i++) {
361 ret = UsbSubmitRequestAsync(ecm->readReq[i]);
362 if (ret != HDF_SUCCESS) {
363 HDF_LOGE("UsbSubmitRequestAsync failed, ret=%{public}d ", ret);
364 goto ERR;
365 } else {
366 ecm->readReqNum++;
367 }
368 }
369 return HDF_SUCCESS;
370 ERR:
371 EcmFreeFifo(&ecm->readFifo);
372 return ret;
373 }
374
EcmClostRelease(struct EcmDevice * ecm)375 static void EcmClostRelease(struct EcmDevice *ecm)
376 {
377 int32_t ret;
378 int32_t cnt = 0;
379 const int32_t temp = 20;
380
381 if (!(ecm->openFlag)) {
382 HDF_LOGE("%{public}s:%{public}d: openFlag is false", __func__, __LINE__);
383 return;
384 }
385
386 for (int32_t i = 0; i < ECM_NR; i++) {
387 ret = UsbCancelRequest(ecm->readReq[i]);
388 if (ret != HDF_SUCCESS) {
389 HDF_LOGE("UsbCancelRequest rd failed, ret=%{public}d ", ret);
390 }
391 }
392 for (int32_t i = 0; i < ECM_NW; i++) {
393 struct EcmWb *snd = &(ecm->wb[i]);
394 ret = UsbCancelRequest(snd->request);
395 if (ret != HDF_SUCCESS) {
396 HDF_LOGE("UsbCancelRequest wr failed, ret=%{public}d ", ret);
397 }
398 }
399
400 while ((cnt < temp) && ((ecm->readReqNum != 0) || (ecm->writeReqNum != 0))) {
401 cnt++;
402 }
403
404 EcmFreeWriteReq(ecm);
405 EcmFreeReadReq(ecm);
406 EcmFreeFifo(&ecm->readFifo);
407 ecm->openFlag = false;
408 }
409
EcmClose(struct EcmDevice * ecm,struct HdfSBuf * data)410 static int32_t EcmClose(struct EcmDevice *ecm, struct HdfSBuf *data)
411 {
412 int32_t cmdType = HOST_ECM_REMOVE_INTERFACE;
413
414 if ((ecm == NULL) || (data == NULL)) {
415 HDF_LOGE("%{public}s: invalid parma", __func__);
416 return HDF_ERR_INVALID_PARAM;
417 }
418
419 if (!HdfSbufReadInt32(data, &cmdType)) {
420 HDF_LOGE("%{public}s:%{public}d sbuf read cmdType failed", __func__, __LINE__);
421 return HDF_ERR_INVALID_PARAM;
422 }
423
424 if ((cmdType == HOST_ECM_ADD_INTERFACE) || (cmdType == HOST_ECM_REMOVE_INTERFACE)) {
425 HDF_LOGD("%{public}s:%{public}d cmdType=%{public}d success", __func__, __LINE__, cmdType);
426 return HDF_SUCCESS;
427 }
428
429 EcmClostRelease(ecm);
430 EcmRelease(ecm);
431 return HDF_SUCCESS;
432 }
433
EcmWrite(struct EcmDevice * ecm,struct HdfSBuf * data)434 static int32_t EcmWrite(struct EcmDevice *ecm, struct HdfSBuf *data)
435 {
436 uint32_t size;
437 uint32_t totalSize = 0;
438 int32_t ret;
439 uint8_t *tmp = NULL;
440 int32_t wbn;
441 uint32_t len;
442 struct EcmWb *wb = NULL;
443
444 if (ecm == NULL || ecm->openFlag == false) {
445 return HDF_ERR_BAD_FD;
446 }
447 if (!HdfSbufReadBuffer(data, (const void **)&tmp, &totalSize)) {
448 return HDF_ERR_IO;
449 }
450 size = totalSize;
451 while (size != 0) {
452 if (EcmWbIsAvail(ecm)) {
453 wbn = EcmWbAlloc(ecm);
454 } else {
455 return (int32_t)size;
456 }
457 if (wbn < ECM_NW && wbn >= 0) {
458 wb = &ecm->wb[wbn];
459 }
460 if (wb == NULL) {
461 return HDF_ERR_INVALID_PARAM;
462 }
463 if (size > ecm->writeSize) {
464 len = ecm->writeSize;
465 size -= ecm->writeSize;
466 } else {
467 len = size;
468 size = 0;
469 }
470 if (wb->buf) {
471 ret = memcpy_s(wb->buf, ecm->writeSize, tmp, len);
472 if (ret != EOK) {
473 return (int32_t)size;
474 }
475 tmp += len;
476 wb->len = (int)len;
477 wb->ecm = ecm;
478 ret = EcmStartWb(ecm, wb);
479 if (ret != HDF_SUCCESS) {
480 return HDF_FAILURE;
481 }
482 }
483 }
484 return totalSize;
485 }
486
EcmGetMac(struct EcmDevice * ecm,struct HdfSBuf * reply)487 static int32_t EcmGetMac(struct EcmDevice *ecm, struct HdfSBuf *reply)
488 {
489 (void)ecm;
490 (void)reply;
491 return HDF_SUCCESS;
492 }
493
EcmAddOrRemoveInterface(int32_t cmd,struct EcmDevice * ecm,struct HdfSBuf * data)494 static int32_t EcmAddOrRemoveInterface(int32_t cmd, struct EcmDevice *ecm, struct HdfSBuf *data)
495 {
496 UsbInterfaceStatus status = USB_INTERFACE_STATUS_NORMAL;
497 uint32_t index = 0;
498 if (ecm == NULL) {
499 HDF_LOGE("%{public}d: invalid param", __LINE__);
500 return HDF_ERR_INVALID_PARAM;
501 }
502
503 if (!HdfSbufReadUint32(data, &index)) {
504 HDF_LOGE("%{public}s:%{public}d sbuf read interfaceNum failed", __func__, __LINE__);
505 return HDF_ERR_INVALID_PARAM;
506 }
507
508 if (cmd == CMD_ECM_ADD_INTERFACE) {
509 status = USB_INTERFACE_STATUS_ADD;
510 } else if (cmd == CMD_ECM_REMOVE_INTERFACE) {
511 status = USB_INTERFACE_STATUS_REMOVE;
512 } else {
513 HDF_LOGE("%{public}s:%{public}d cmd=%{public}d is not define", __func__, __LINE__, cmd);
514 return HDF_ERR_INVALID_PARAM;
515 }
516
517 return UsbAddOrRemoveInterface(ecm->session, ecm->busNum, ecm->devAddr, index, status);
518 }
519
EcmDeviceDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)520 static int32_t EcmDeviceDispatch(
521 struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
522 {
523 struct EcmDevice *ecm = NULL;
524 if (client == NULL) {
525 HDF_LOGE("%{public}s: client is null", __func__);
526 return HDF_ERR_INVALID_OBJECT;
527 }
528
529 if (client->device == NULL) {
530 HDF_LOGE("%{public}s: client->device is null", __func__);
531 return HDF_ERR_INVALID_OBJECT;
532 }
533
534 if (client->device->service == NULL) {
535 HDF_LOGE("%{public}s: client->device->service is null", __func__);
536 return HDF_ERR_INVALID_OBJECT;
537 }
538
539 if (g_ecmReleaseFlag) {
540 HDF_LOGE("%{public}s:%{public}d g_ecmReleaseFlag is true", __func__, __LINE__);
541 return HDF_ERR_DEVICE_BUSY;
542 }
543
544 ecm = (struct EcmDevice *)client->device->service;
545
546 switch (cmd) {
547 case CMD_ECM_OPEN:
548 return EcmOpen(ecm, data);
549 case CMD_ECM_CLOSE:
550 return EcmClose(ecm, data);
551 case CMD_ECM_READ:
552 return EcmRead(ecm, reply);
553 case CMD_ECM_WRITE:
554 return EcmWrite(ecm, data);
555 case CMD_ECM_GET_MAC:
556 return EcmGetMac(ecm, reply);
557 case CMD_ECM_ADD_INTERFACE:
558 case CMD_ECM_REMOVE_INTERFACE:
559 return EcmAddOrRemoveInterface(cmd, ecm, data);
560 default:
561 return HDF_ERR_NOT_SUPPORT;
562 }
563
564 return HDF_SUCCESS;
565 }
566
EcmGetUsbInterfaceById(struct EcmDevice * ecm,uint8_t interfaceIndex)567 static struct UsbInterface *EcmGetUsbInterfaceById(struct EcmDevice *ecm, uint8_t interfaceIndex)
568 {
569 return UsbClaimInterface(ecm->session, ecm->busNum, ecm->devAddr, interfaceIndex);
570 }
571
EcmFreePipes(struct EcmDevice * ecm)572 static void EcmFreePipes(struct EcmDevice *ecm)
573 {
574 if (ecm == NULL) {
575 return;
576 }
577 if (ecm->ctrPipe) {
578 OsalMemFree(ecm->ctrPipe);
579 ecm->ctrPipe = NULL;
580 }
581 if (ecm->intPipe) {
582 OsalMemFree(ecm->intPipe);
583 ecm->intPipe = NULL;
584 }
585 if (ecm->dataInPipe) {
586 OsalMemFree(ecm->dataInPipe);
587 ecm->dataInPipe = NULL;
588 }
589 if (ecm->dataOutPipe) {
590 OsalMemFree(ecm->dataOutPipe);
591 ecm->dataOutPipe = NULL;
592 }
593 }
594
EcmEnumePipe(struct EcmDevice * ecm,uint8_t interfaceIndex,UsbPipeType pipeType,UsbPipeDirection pipeDirection)595 static struct UsbPipeInfo *EcmEnumePipe(
596 struct EcmDevice *ecm, uint8_t interfaceIndex, UsbPipeType pipeType, UsbPipeDirection pipeDirection)
597 {
598 struct UsbInterfaceInfo *info = NULL;
599 UsbInterfaceHandle *interfaceHandle = NULL;
600 if (pipeType == USB_PIPE_TYPE_CONTROL) {
601 info = &ecm->ctrIface->info;
602 interfaceHandle = ecm->ctrDevHandle;
603 } else {
604 info = &ecm->iface[interfaceIndex]->info;
605 interfaceHandle = ecm->devHandle[interfaceIndex];
606 }
607
608 for (uint8_t i = 0; i <= info->pipeNum; i++) {
609 struct UsbPipeInfo p;
610 int32_t ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p);
611 if (ret < HDF_SUCCESS) {
612 continue;
613 }
614 if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) {
615 struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi));
616 if (pi == NULL) {
617 HDF_LOGE("%{public}s: Alloc pipe failed", __func__);
618 return NULL;
619 }
620 p.interfaceId = info->interfaceIndex;
621 *pi = p;
622 return pi;
623 }
624 }
625 return NULL;
626 }
627
EcmGetPipe(struct EcmDevice * ecm,UsbPipeType pipeType,UsbPipeDirection pipeDirection)628 static struct UsbPipeInfo *EcmGetPipe(struct EcmDevice *ecm, UsbPipeType pipeType, UsbPipeDirection pipeDirection)
629 {
630 uint8_t i;
631 if (ecm == NULL) {
632 HDF_LOGE("%{public}s: invalid parmas", __func__);
633 return NULL;
634 }
635 for (i = 0; i < ecm->interfaceCnt; i++) {
636 struct UsbPipeInfo *p = NULL;
637 if (ecm->iface[i] == NULL) {
638 continue;
639 }
640 p = EcmEnumePipe(ecm, i, pipeType, pipeDirection);
641 if (p == NULL) {
642 continue;
643 }
644 return p;
645 }
646 return NULL;
647 }
648
EcmGetPipes(struct EcmDevice * ecm)649 static int32_t EcmGetPipes(struct EcmDevice *ecm)
650 {
651 ecm->dataInPipe = EcmGetPipe(ecm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN);
652 if (ecm->dataInPipe == NULL) {
653 HDF_LOGE("dataInPipe is NULL");
654 goto ERROR;
655 }
656 ecm->dataOutPipe = EcmGetPipe(ecm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT);
657 if (ecm->dataOutPipe == NULL) {
658 HDF_LOGE("dataOutPipe is NULL");
659 goto ERROR;
660 }
661 ecm->ctrPipe = EcmEnumePipe(ecm, ecm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT);
662 if (ecm->ctrPipe == NULL) {
663 HDF_LOGE("ctrPipe is NULL");
664 goto ERROR;
665 }
666 ecm->intPipe = EcmGetPipe(ecm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN);
667 if (ecm->intPipe == NULL) {
668 HDF_LOGE("intPipe is NULL");
669 goto ERROR;
670 }
671
672 ecm->readSize = ecm->dataInPipe->maxPacketSize;
673 ecm->writeSize = ecm->dataOutPipe->maxPacketSize;
674 ecm->ctrlSize = ecm->ctrPipe->maxPacketSize;
675 ecm->intSize = ecm->intPipe->maxPacketSize;
676
677 return HDF_SUCCESS;
678
679 ERROR:
680 EcmFreePipes(ecm);
681 return HDF_FAILURE;
682 }
683
EcmDriverBind(struct HdfDeviceObject * device)684 static int32_t EcmDriverBind(struct HdfDeviceObject *device)
685 {
686 struct UsbPnpNotifyServiceInfo *info = NULL;
687 errno_t err;
688 struct EcmDevice *ecm = NULL;
689 if (device == NULL) {
690 HDF_LOGE("%{public}s: device is null", __func__);
691 return HDF_ERR_INVALID_OBJECT;
692 }
693 ecm = (struct EcmDevice *)OsalMemCalloc(sizeof(*ecm));
694 if (ecm == NULL) {
695 HDF_LOGE("%{public}s: Alloc usb serial device failed", __func__);
696 return HDF_FAILURE;
697 }
698
699 info = (struct UsbPnpNotifyServiceInfo *)device->priv;
700 if (info != NULL) {
701 HDF_LOGD("bus:%{public}d+dev:%{public}d", info->busNum, info->devNum);
702 HDF_LOGD("interfaceLength:%{public}d", info->interfaceLength);
703 ecm->busNum = (uint8_t)info->busNum;
704 ecm->devAddr = (uint8_t)info->devNum;
705 ecm->interfaceCnt = info->interfaceLength;
706 err = memcpy_s((void *)(ecm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber,
707 info->interfaceLength);
708 if (err != EOK) {
709 HDF_LOGE("%{public}s:%{public}d memcpy_s failed err=%{public}d", __func__, __LINE__, err);
710 goto ERROR;
711 }
712 } else {
713 HDF_LOGE("%{public}s:%{public}d info is NULL!", __func__, __LINE__);
714 goto ERROR;
715 }
716
717 ecm->device = device;
718 device->service = &(ecm->service);
719 ecm->device->service->Dispatch = EcmDeviceDispatch;
720 HDF_LOGD("EcmDriverBind=========================OK");
721 return HDF_SUCCESS;
722
723 ERROR:
724 OsalMemFree(ecm);
725 ecm = NULL;
726 return HDF_FAILURE;
727 }
728
EcmProcessNotification(struct EcmDevice * ecm,unsigned char * buf)729 static void EcmProcessNotification(struct EcmDevice *ecm, unsigned char *buf)
730 {
731 (void)ecm;
732 if (buf == NULL) {
733 HDF_LOGE("%{public}s - invalid buffer", __func__);
734 return;
735 }
736 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)buf;
737 switch (dr->bNotificationType) {
738 case USB_DDK_CDC_NOTIFY_NETWORK_CONNECTION:
739 HDF_LOGE("%{public}s - network connection: %{public}s", __func__, (dr->wValue ? "on" : "off"));
740 break;
741 case USB_DDK_CDC_NOTIFY_SPEED_CHANGE:
742 HDF_LOGE("%{public}s - speed change wLength: %{public}d", __func__, dr->wLength);
743 break;
744 default:
745 HDF_LOGE("%{public}s-%{public}d received: index %{public}d len %{public}d",
746 __func__, dr->bNotificationType, dr->wIndex, dr->wLength);
747 }
748 return;
749 }
750
EcmNotificationAndRequest(struct UsbRequest * req,struct EcmDevice * ecm,struct UsbCdcNotification * dr,unsigned int currentSize,uint32_t expectedSize)751 static void EcmNotificationAndRequest(struct UsbRequest *req, struct EcmDevice *ecm, struct UsbCdcNotification *dr,
752 unsigned int currentSize, uint32_t expectedSize)
753 {
754 if (currentSize >= expectedSize) {
755 EcmProcessNotification(ecm, (unsigned char *)dr);
756 ecm->nbIndex = 0;
757 }
758
759 if ((UsbSubmitRequestAsync(req) != HDF_SUCCESS) && (UsbSubmitRequestAsync(req) != -EPERM)) {
760 HDF_LOGE("%{public}s: usb_submit_urb failed", __func__);
761 }
762 }
763
EcmCtrlIrq(struct UsbRequest * req)764 static void EcmCtrlIrq(struct UsbRequest *req)
765 {
766 struct EcmDevice *ecm = (struct EcmDevice *)req->compInfo.userData;
767 int32_t status = (int32_t)req->compInfo.status;
768 struct UsbCdcNotification *dr = (struct UsbCdcNotification *)req->compInfo.buffer;
769 unsigned int currentSize = req->compInfo.actualLength;
770 switch (status) {
771 case 0:
772 break;
773 case -ECONNRESET:
774 case -ENOENT:
775 case -ESHUTDOWN:
776 return;
777 default:
778 goto EXIT;
779 }
780 if (ecm->nbIndex) {
781 dr = (struct UsbCdcNotification *)ecm->notificationBuffer;
782 }
783 uint32_t expectedSize = sizeof(struct UsbCdcNotification) + LE16_TO_CPU(dr->wLength);
784 if (currentSize < expectedSize) {
785 if (ecm->nbSize < expectedSize) {
786 if (ecm->nbSize) {
787 OsalMemFree(ecm->notificationBuffer);
788 ecm->nbSize = 0;
789 }
790 uint32_t allocSize = expectedSize;
791 ecm->notificationBuffer = OsalMemCalloc(allocSize);
792 dr = (struct UsbCdcNotification *)ecm->notificationBuffer;
793 if (!ecm->notificationBuffer) {
794 goto EXIT;
795 }
796 ecm->nbSize = allocSize;
797 }
798 uint32_t copySize = MIN(currentSize, expectedSize - ecm->nbIndex);
799 int32_t ret = memcpy_s(
800 &ecm->notificationBuffer[ecm->nbIndex], ecm->nbSize - ecm->nbIndex, req->compInfo.buffer, copySize);
801 if (ret != EOK) {
802 HDF_LOGE("%{public}s: memcpy_s failed", __func__);
803 OsalMemFree(ecm->notificationBuffer);
804 ecm->notificationBuffer = NULL;
805 return;
806 }
807 ecm->nbIndex += copySize;
808 currentSize = ecm->nbIndex;
809 }
810 EcmNotificationAndRequest(req, ecm, dr, currentSize, expectedSize);
811 EXIT:
812 HDF_LOGE("%{public}s: exit", __func__);
813 }
814
EcmReadBulk(struct UsbRequest * req)815 static void EcmReadBulk(struct UsbRequest *req)
816 {
817 int32_t status = req->compInfo.status;
818 size_t size = req->compInfo.actualLength;
819 struct EcmDevice *ecm = (struct EcmDevice *)req->compInfo.userData;
820 ecm->readReqNum--;
821 switch (status) {
822 case USB_REQUEST_COMPLETED:
823 OsalMutexLock(&ecm->readLock);
824 if (size) {
825 uint8_t *data = req->compInfo.buffer;
826 if (DataFifoIsFull(&ecm->readFifo)) {
827 HDF_LOGD("%{public}s:%{public}d fifo is full", __func__, __LINE__);
828 DataFifoSkip(&ecm->readFifo, size);
829 }
830 uint32_t count = DataFifoWrite(&ecm->readFifo, data, size);
831 if (count != size) {
832 HDF_LOGW("%{public}s: write %{public}u less than expected %{public}zu", __func__, count, size);
833 }
834 }
835 OsalMutexUnlock(&ecm->readLock);
836 break;
837 default:
838 HDF_LOGE("%{public}s:%{public}d status=%{public}d", __func__, __LINE__, status);
839 return;
840 }
841
842 if (ecm->openFlag) {
843 int32_t retval = UsbSubmitRequestAsync(req);
844 if (retval && retval != -EPERM) {
845 HDF_LOGE("%{public}s - usb_submit_urb failed: %{public}d", __func__, retval);
846 } else {
847 ecm->readReqNum++;
848 }
849 }
850 }
851
EcmAllocWriteReq(struct EcmDevice * const ecm)852 static void EcmAllocWriteReq(struct EcmDevice * const ecm)
853 {
854 if (EcmWriteBufAlloc(ecm) < 0) {
855 HDF_LOGE("EcmAllocWriteReq buf alloc failed");
856 return;
857 }
858
859 for (int32_t i = 0; i < ECM_NW; i++) {
860 struct EcmWb *snd = &(ecm->wb[i]);
861 snd->request = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->dataOutPipe->interfaceId), 0, ecm->writeSize);
862 snd->instance = ecm;
863 snd->use = 0;
864 if (snd->request == NULL) {
865 HDF_LOGE("snd request fail");
866 goto ERR;
867 }
868 }
869 return;
870 ERR:
871 EcmWriteBufFree(ecm);
872 return;
873 }
874
EcmFreeWriteReq(struct EcmDevice * const ecm)875 static void EcmFreeWriteReq(struct EcmDevice * const ecm)
876 {
877 OsalMutexLock(&ecm->writeLock);
878 for (int32_t i = 0; i < ECM_NW; i++) {
879 struct EcmWb *snd = &(ecm->wb[i]);
880 snd->use = 0;
881 UsbFreeRequest(snd->request);
882 }
883 OsalMutexUnlock(&ecm->writeLock);
884 EcmWriteBufFree(ecm);
885 }
886
EcmAllocIntReq(struct EcmDevice * ecm)887 static int32_t EcmAllocIntReq(struct EcmDevice *ecm)
888 {
889 int32_t ret;
890 struct UsbRequestParams intParmas = {};
891 if (ecm == NULL || ecm->intPipe == NULL) {
892 return HDF_FAILURE;
893 }
894 ecm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->intPipe->interfaceId), 0, ecm->intSize);
895 if (!ecm->notifyReq) {
896 HDF_LOGE("notifyReq request fail");
897 return HDF_ERR_MALLOC_FAIL;
898 }
899 intParmas.userData = (void *)ecm;
900 intParmas.pipeAddress = ecm->intPipe->pipeAddress;
901 intParmas.pipeId = ecm->intPipe->pipeId;
902 intParmas.interfaceId = ecm->intPipe->interfaceId;
903 intParmas.callback = EcmCtrlIrq;
904 intParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
905 intParmas.timeout = USB_CTRL_SET_TIMEOUT;
906 intParmas.dataReq.numIsoPackets = 0;
907 intParmas.dataReq.directon = (((uint32_t)(ecm->intPipe->pipeDirection)) >> USB_DIR_OFFSET) & 0x1;
908 intParmas.dataReq.length = ecm->intSize;
909 ret = UsbFillRequest(ecm->notifyReq, InterfaceIdToHandle(ecm, ecm->intPipe->interfaceId), &intParmas);
910 if (ret != HDF_SUCCESS) {
911 HDF_LOGE("%{public}s: UsbFillRequest failed, ret=%{public}d ", __func__, ret);
912 return ret;
913 }
914 return HDF_SUCCESS;
915 }
916
EcmAllocReadReq(struct EcmDevice * ecm)917 static void EcmAllocReadReq(struct EcmDevice *ecm)
918 {
919 struct UsbRequestParams readParmas = {};
920 for (int32_t i = 0; i < ECM_NR; i++) {
921 ecm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->dataInPipe->interfaceId), 0, ecm->readSize);
922 if (!ecm->readReq[i]) {
923 HDF_LOGE("readReq request failed");
924 return;
925 }
926 readParmas.userData = (void *)ecm;
927 readParmas.pipeAddress = ecm->dataInPipe->pipeAddress;
928 readParmas.pipeId = ecm->dataInPipe->pipeId;
929 readParmas.interfaceId = ecm->dataInPipe->interfaceId;
930 readParmas.callback = EcmReadBulk;
931 readParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
932 readParmas.timeout = USB_CTRL_SET_TIMEOUT;
933 readParmas.dataReq.numIsoPackets = 0;
934 readParmas.dataReq.directon = (((uint32_t)(ecm->dataInPipe->pipeDirection)) >> USB_DIR_OFFSET) & 0x1;
935 readParmas.dataReq.length = ecm->readSize;
936 int32_t ret =
937 UsbFillRequest(ecm->readReq[i], InterfaceIdToHandle(ecm, ecm->dataInPipe->interfaceId), &readParmas);
938 if (ret != HDF_SUCCESS) {
939 HDF_LOGE("%{public}s: UsbFillRequest failed, ret=%{public}d ", __func__, ret);
940 return;
941 }
942 }
943 }
944
EcmFreeReadReq(struct EcmDevice * ecm)945 static void EcmFreeReadReq(struct EcmDevice *ecm)
946 {
947 int32_t ret;
948 for (int32_t i = 0; i < ECM_NR; i++) {
949 ret = UsbFreeRequest(ecm->readReq[i]);
950 if (ret) {
951 goto ERR;
952 }
953 }
954 ERR:
955 return;
956 }
957
UsbFreeNotifyReqeust(struct EcmDevice * ecm)958 static void UsbFreeNotifyReqeust(struct EcmDevice *ecm)
959 {
960 int32_t ret;
961
962 if ((ecm == NULL) || (ecm->notifyReq == NULL)) {
963 HDF_LOGE("%{public}s: ecm or notifyReq is NULL", __func__);
964 return;
965 }
966 ret = UsbCancelRequest(ecm->notifyReq);
967 if (ret != HDF_SUCCESS) {
968 HDF_LOGE("UsbCancelRequest rd failed, ret=%{public}d ", ret);
969 }
970 ret = UsbFreeRequest(ecm->notifyReq);
971 if (ret == HDF_SUCCESS) {
972 ecm->notifyReq = NULL;
973 } else {
974 HDF_LOGE("%{public}s: UsbFreeNotifyReqeust failed, ret=%{public}d", __func__, ret);
975 }
976 }
977
EcmReleaseInterfaces(struct EcmDevice * ecm)978 static void EcmReleaseInterfaces(struct EcmDevice *ecm)
979 {
980 for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
981 if (ecm->iface[i]) {
982 UsbReleaseInterface(ecm->iface[i]);
983 ecm->iface[i] = NULL;
984 }
985 }
986 if (ecm->ctrIface) {
987 UsbReleaseInterface(ecm->ctrIface);
988 ecm->ctrIface = NULL;
989 }
990 }
991
EcmClaimInterfaces(struct EcmDevice * ecm)992 static int32_t EcmClaimInterfaces(struct EcmDevice *ecm)
993 {
994 for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
995 ecm->iface[i] = EcmGetUsbInterfaceById(ecm, ecm->interfaceIndex[i]);
996 if (ecm->iface[i] == NULL) {
997 HDF_LOGE("interface%{public}d is null", ecm->interfaceIndex[i]);
998 goto ERROR;
999 }
1000 }
1001
1002 ecm->ctrIface = EcmGetUsbInterfaceById(ecm, USB_CTRL_INTERFACE_ID);
1003 if (ecm->ctrIface == NULL) {
1004 HDF_LOGE("%{public}d: UsbClaimInterface null", __LINE__);
1005 goto ERROR;
1006 }
1007
1008 return HDF_SUCCESS;
1009
1010 ERROR:
1011 EcmReleaseInterfaces(ecm);
1012 return HDF_FAILURE;
1013 }
1014
EcmCloseInterfaces(struct EcmDevice * ecm)1015 static void EcmCloseInterfaces(struct EcmDevice *ecm)
1016 {
1017 for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
1018 if (ecm->devHandle[i]) {
1019 UsbCloseInterface(ecm->devHandle[i], false);
1020 ecm->devHandle[i] = NULL;
1021 }
1022 }
1023
1024 if (ecm->ctrDevHandle) {
1025 UsbCloseInterface(ecm->ctrDevHandle, false);
1026 ecm->ctrDevHandle = NULL;
1027 }
1028 }
1029
EcmOpenInterfaces(struct EcmDevice * ecm)1030 static int32_t EcmOpenInterfaces(struct EcmDevice *ecm)
1031 {
1032 for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
1033 if (ecm->iface[i]) {
1034 ecm->devHandle[i] = UsbOpenInterface(ecm->iface[i]);
1035 if (ecm->devHandle[i] == NULL) {
1036 HDF_LOGE("%{public}s: UsbOpenInterface null", __func__);
1037 goto ERROR;
1038 }
1039 }
1040 }
1041
1042 ecm->ctrDevHandle = UsbOpenInterface(ecm->ctrIface);
1043 if (ecm->ctrDevHandle == NULL) {
1044 HDF_LOGE("%{public}s: ctrDevHandle UsbOpenInterface null", __func__);
1045 goto ERROR;
1046 }
1047
1048 return HDF_SUCCESS;
1049
1050 ERROR:
1051 EcmCloseInterfaces(ecm);
1052 return HDF_FAILURE;
1053 }
1054
EcmGetPipesAndRequest(struct EcmDevice * ecm,int32_t ret)1055 static int32_t EcmGetPipesAndRequest(struct EcmDevice *ecm, int32_t ret)
1056 {
1057 ret = EcmGetPipes(ecm);
1058 if (ret != HDF_SUCCESS) {
1059 HDF_LOGE("%{public}s: EcmGetPipes failed", __func__);
1060 goto ERROR_GET_PIPES;
1061 }
1062
1063 ret = EcmAllocIntReq(ecm);
1064 if (ret != HDF_SUCCESS) {
1065 HDF_LOGE("%{public}s: EcmAllocIntReq failed", __func__);
1066 goto ERROR_ALLOC_REQ;
1067 }
1068 if (false) {
1069 EcmCtrlMsg(ecm, USB_DDK_CDC_SET_ETHERNET_PACKET_FILTER,
1070 USB_DDK_CDC_PACKET_TYPE_DIRECTED | USB_DDK_CDC_PACKET_TYPE_BROADCAST, NULL, 0);
1071 ret = UsbSubmitRequestAsync(ecm->notifyReq);
1072 if (ret != HDF_SUCCESS) {
1073 return ret;
1074 }
1075 }
1076 ecm->initFlag = true;
1077 return HDF_SUCCESS;
1078 ERROR_ALLOC_REQ:
1079 EcmFreePipes(ecm);
1080 ERROR_GET_PIPES:
1081 UsbFreeNotifyReqeust(ecm);
1082 return ret;
1083 }
1084
EcmInit(struct EcmDevice * ecm)1085 static int32_t EcmInit(struct EcmDevice *ecm)
1086 {
1087 int32_t ret;
1088 const uint8_t altsetting = 1;
1089
1090 if (ecm->initFlag == true) {
1091 HDF_LOGE("%{public}s: initFlag is true", __func__);
1092 return HDF_SUCCESS;
1093 }
1094
1095 if (UsbInitHostSdk(NULL) != HDF_SUCCESS) {
1096 HDF_LOGE("%{public}s: UsbInitHostSdk failed", __func__);
1097 return HDF_ERR_IO;
1098 }
1099 ecm->session = NULL;
1100
1101 ret = EcmClaimInterfaces(ecm);
1102 if (ret != HDF_SUCCESS) {
1103 HDF_LOGE("%{public}s: EcmClaimInterfaces failed", __func__);
1104 goto ERR_CLAIM_INTERFACES;
1105 }
1106
1107 ret = EcmOpenInterfaces(ecm);
1108 if (ret != HDF_SUCCESS) {
1109 HDF_LOGE("%{public}s: EcmOpenInterfaces failed", __func__);
1110 goto ERROR_OPEN_INTERFACES;
1111 }
1112
1113 if (ecm->interfaceCnt > USB_MAX_INTERFACES) {
1114 HDF_LOGE("interfaceCnt invalid : %{public}u", ecm->interfaceCnt);
1115 goto ERROR_OPEN_INTERFACES;
1116 }
1117
1118 ret = UsbSelectInterfaceSetting(
1119 ecm->devHandle[ecm->interfaceCnt - 1], altsetting, &ecm->iface[ecm->interfaceCnt - 1]); // set altsetting
1120 if (ret != HDF_SUCCESS) {
1121 HDF_LOGE("UsbSelectInterfaceSetting fail");
1122 goto ERROR_SELECT_SETTING;
1123 }
1124 EcmGetPipesAndRequest(ecm, ret);
1125 ERROR_SELECT_SETTING:
1126 EcmCloseInterfaces(ecm);
1127 ERROR_OPEN_INTERFACES:
1128 EcmReleaseInterfaces(ecm);
1129 ERR_CLAIM_INTERFACES:
1130 UsbExitHostSdk(ecm->session);
1131 ecm->session = NULL;
1132 return ret;
1133 }
1134
EcmRelease(struct EcmDevice * ecm)1135 static void EcmRelease(struct EcmDevice *ecm)
1136 {
1137 if (!(ecm->initFlag)) {
1138 HDF_LOGE("%{public}s:%{public}d: initFlag is false", __func__, __LINE__);
1139 return;
1140 }
1141
1142 EcmCloseInterfaces(ecm);
1143 EcmReleaseInterfaces(ecm);
1144 UsbFreeNotifyReqeust(ecm);
1145 EcmFreePipes(ecm);
1146 UsbExitHostSdk(ecm->session);
1147
1148 ecm->initFlag = false;
1149 }
1150
EcmDriverInit(struct HdfDeviceObject * device)1151 static int32_t EcmDriverInit(struct HdfDeviceObject *device)
1152 {
1153 struct EcmDevice *ecm = NULL;
1154
1155 if (device == NULL) {
1156 HDF_LOGE("%{public}s: device is null", __func__);
1157 return HDF_ERR_INVALID_OBJECT;
1158 }
1159 ecm = (struct EcmDevice *)device->service;
1160 if (ecm == NULL) {
1161 HDF_LOGE("%{public}s: ecm is null", __func__);
1162 return HDF_FAILURE;
1163 }
1164
1165 OsalMutexInit(&ecm->readLock);
1166 OsalMutexInit(&ecm->writeLock);
1167 ecm->openFlag = false;
1168 ecm->initFlag = false;
1169 g_ecmReleaseFlag = false;
1170
1171 HDF_LOGE("%{public}s:%{public}d EcmDriverInit OK", __func__, __LINE__);
1172 return HDF_SUCCESS;
1173 }
1174
EcmDriverRelease(struct HdfDeviceObject * device)1175 static void EcmDriverRelease(struct HdfDeviceObject *device)
1176 {
1177 struct EcmDevice *ecm = NULL;
1178 if (device == NULL) {
1179 HDF_LOGE("%{public}s: device is NULL", __func__);
1180 return;
1181 }
1182 ecm = (struct EcmDevice *)device->service;
1183 if (ecm == NULL) {
1184 HDF_LOGE("%{public}s: ecm is null", __func__);
1185 return;
1186 }
1187
1188 g_ecmReleaseFlag = true;
1189
1190 if (ecm->openFlag) {
1191 HDF_LOGD("%{public}s:%{public}d EcmClostRelease", __func__, __LINE__);
1192 EcmClostRelease(ecm);
1193 }
1194 if (ecm->initFlag) {
1195 HDF_LOGD("%{public}s:%{public}d EcmRelease", __func__, __LINE__);
1196 EcmRelease(ecm);
1197 }
1198 OsalMutexDestroy(&ecm->writeLock);
1199 OsalMutexDestroy(&ecm->readLock);
1200 OsalMemFree(ecm);
1201 ecm = NULL;
1202 HDF_LOGD("%{public}s:%{public}d exit", __func__, __LINE__);
1203 }
1204
1205 struct HdfDriverEntry g_ecmUsbDriverEntry = {
1206 .moduleVersion = 1,
1207 .moduleName = "usbhost_ecm",
1208 .Bind = EcmDriverBind,
1209 .Init = EcmDriverInit,
1210 .Release = EcmDriverRelease,
1211 };
1212
1213 HDF_INIT(g_ecmUsbDriverEntry);
1214