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