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