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