• 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 
EcmNotificationAndRequest(struct UsbRequest * req,struct EcmDevice * ecm,struct UsbCdcNotification * dr,unsigned int currentSize,uint32_t expectedSize)737 static void EcmNotificationAndRequest(struct UsbRequest *req, struct EcmDevice *ecm, struct UsbCdcNotification *dr,
738     unsigned int currentSize, uint32_t expectedSize)
739 {
740     if (currentSize >= expectedSize) {
741         EcmProcessNotification(ecm, (unsigned char *)dr);
742         ecm->nbIndex = 0;
743     }
744 
745     if ((UsbSubmitRequestAsync(req) != HDF_SUCCESS) && (UsbSubmitRequestAsync(req) != -EPERM)) {
746         HDF_LOGE("%{public}s: usb_submit_urb failed", __func__);
747     }
748 }
749 
EcmCtrlIrq(struct UsbRequest * req)750 static void EcmCtrlIrq(struct UsbRequest *req)
751 {
752     struct EcmDevice *ecm = (struct EcmDevice *)req->compInfo.userData;
753     int32_t status = (int32_t)req->compInfo.status;
754     struct UsbCdcNotification *dr = (struct UsbCdcNotification *)req->compInfo.buffer;
755     unsigned int currentSize = req->compInfo.actualLength;
756     switch (status) {
757         case 0:
758             break;
759         case -ECONNRESET:
760         case -ENOENT:
761         case -ESHUTDOWN:
762             return;
763         default:
764             goto EXIT;
765     }
766     if (ecm->nbIndex) {
767         dr = (struct UsbCdcNotification *)ecm->notificationBuffer;
768     }
769     uint32_t expectedSize = sizeof(struct UsbCdcNotification) + LE16_TO_CPU(dr->wLength);
770     if (currentSize < expectedSize) {
771         if (ecm->nbSize < expectedSize) {
772             if (ecm->nbSize) {
773                 OsalMemFree(ecm->notificationBuffer);
774                 ecm->nbSize = 0;
775             }
776             uint32_t allocSize = expectedSize;
777             ecm->notificationBuffer = OsalMemCalloc(allocSize);
778             if (!ecm->notificationBuffer) {
779                 goto EXIT;
780             }
781             ecm->nbSize = allocSize;
782         }
783         uint32_t copySize = MIN(currentSize, expectedSize - ecm->nbIndex);
784         int32_t ret = memcpy_s(
785             &ecm->notificationBuffer[ecm->nbIndex], ecm->nbSize - ecm->nbIndex, req->compInfo.buffer, copySize);
786         if (ret != EOK) {
787             HDF_LOGE("%{public}s: memcpy_s failed", __func__);
788             return;
789         }
790         ecm->nbIndex += copySize;
791         currentSize = ecm->nbIndex;
792     }
793     EcmNotificationAndRequest(req, ecm, dr, currentSize, expectedSize);
794 EXIT:
795     HDF_LOGE("%{public}s: exit", __func__);
796 }
797 
EcmReadBulk(struct UsbRequest * req)798 static void EcmReadBulk(struct UsbRequest *req)
799 {
800     int32_t status = req->compInfo.status;
801     size_t size = req->compInfo.actualLength;
802     struct EcmDevice *ecm = (struct EcmDevice *)req->compInfo.userData;
803     ecm->readReqNum--;
804     switch (status) {
805         case USB_REQUEST_COMPLETED:
806             OsalMutexLock(&ecm->readLock);
807             if (size) {
808                 uint8_t *data = req->compInfo.buffer;
809                 if (DataFifoIsFull(&ecm->readFifo)) {
810                     HDF_LOGD("%s:%d fifo is full", __func__, __LINE__);
811                     DataFifoSkip(&ecm->readFifo, size);
812                 }
813                 uint32_t count = DataFifoWrite(&ecm->readFifo, data, size);
814                 if (count != size) {
815                     HDF_LOGW("%s: write %u less than expected %zu", __func__, count, size);
816                 }
817             }
818             OsalMutexUnlock(&ecm->readLock);
819             break;
820         default:
821             HDF_LOGE("%s:%d status=%d", __func__, __LINE__, status);
822             return;
823     }
824 
825     if (ecm->openFlag) {
826         int32_t retval = UsbSubmitRequestAsync(req);
827         if (retval && retval != -EPERM) {
828             HDF_LOGE("%s - usb_submit_urb failed: %d\n", __func__, retval);
829         } else {
830             ecm->readReqNum++;
831         }
832     }
833 }
834 
EcmAllocWriteReq(struct EcmDevice * const ecm)835 static void EcmAllocWriteReq(struct EcmDevice * const ecm)
836 {
837     if (EcmWriteBufAlloc(ecm) < 0) {
838         HDF_LOGE("EcmAllocWriteReq buf alloc failed\n");
839         return;
840     }
841 
842     for (int32_t i = 0; i < ECM_NW; i++) {
843         struct EcmWb *snd = &(ecm->wb[i]);
844         snd->request = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->dataOutPipe->interfaceId), 0, ecm->writeSize);
845         snd->instance = ecm;
846         snd->use = 0;
847         if (snd->request == NULL) {
848             HDF_LOGE("snd request fail\n");
849             goto ERR;
850         }
851     }
852     return;
853 ERR:
854     EcmWriteBufFree(ecm);
855     return;
856 }
857 
EcmFreeWriteReq(struct EcmDevice * const ecm)858 static void EcmFreeWriteReq(struct EcmDevice * const ecm)
859 {
860     OsalMutexLock(&ecm->writeLock);
861     for (int32_t i = 0; i < ECM_NW; i++) {
862         struct EcmWb *snd = &(ecm->wb[i]);
863         snd->use = 0;
864         UsbFreeRequest(snd->request);
865     }
866     OsalMutexUnlock(&ecm->writeLock);
867     EcmWriteBufFree(ecm);
868 }
869 
EcmAllocIntReq(struct EcmDevice * ecm)870 static int32_t EcmAllocIntReq(struct EcmDevice *ecm)
871 {
872     int32_t ret;
873     struct UsbRequestParams intParmas = {};
874     if (ecm == NULL || ecm->intPipe == NULL) {
875         return HDF_FAILURE;
876     }
877     ecm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->intPipe->interfaceId), 0, ecm->intSize);
878     if (!ecm->notifyReq) {
879         HDF_LOGE("notifyReq request fail\n");
880         return HDF_ERR_MALLOC_FAIL;
881     }
882     intParmas.userData = (void *)ecm;
883     intParmas.pipeAddress = ecm->intPipe->pipeAddress;
884     intParmas.pipeId = ecm->intPipe->pipeId;
885     intParmas.interfaceId = ecm->intPipe->interfaceId;
886     intParmas.callback = EcmCtrlIrq;
887     intParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
888     intParmas.timeout = USB_CTRL_SET_TIMEOUT;
889     intParmas.dataReq.numIsoPackets = 0;
890     intParmas.dataReq.directon = (((uint32_t)(ecm->intPipe->pipeDirection)) >> USB_DIR_OFFSET) & 0x1;
891     intParmas.dataReq.length = ecm->intSize;
892     ret = UsbFillRequest(ecm->notifyReq, InterfaceIdToHandle(ecm, ecm->intPipe->interfaceId), &intParmas);
893     if (ret != HDF_SUCCESS) {
894         HDF_LOGE("%s: UsbFillRequest failed, ret=%d \n", __func__, ret);
895         return ret;
896     }
897     return HDF_SUCCESS;
898 }
899 
EcmAllocReadReq(struct EcmDevice * ecm)900 static void EcmAllocReadReq(struct EcmDevice *ecm)
901 {
902     struct UsbRequestParams readParmas = {};
903     for (int32_t i = 0; i < ECM_NR; i++) {
904         ecm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(ecm, ecm->dataInPipe->interfaceId), 0, ecm->readSize);
905         if (!ecm->readReq[i]) {
906             HDF_LOGE("readReq request failed\n");
907             return;
908         }
909         readParmas.userData = (void *)ecm;
910         readParmas.pipeAddress = ecm->dataInPipe->pipeAddress;
911         readParmas.pipeId = ecm->dataInPipe->pipeId;
912         readParmas.interfaceId = ecm->dataInPipe->interfaceId;
913         readParmas.callback = EcmReadBulk;
914         readParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
915         readParmas.timeout = USB_CTRL_SET_TIMEOUT;
916         readParmas.dataReq.numIsoPackets = 0;
917         readParmas.dataReq.directon = (((uint32_t)(ecm->dataInPipe->pipeDirection)) >> USB_DIR_OFFSET) & 0x1;
918         readParmas.dataReq.length = ecm->readSize;
919         int32_t ret =
920             UsbFillRequest(ecm->readReq[i], InterfaceIdToHandle(ecm, ecm->dataInPipe->interfaceId), &readParmas);
921         if (ret != HDF_SUCCESS) {
922             HDF_LOGE("%s: UsbFillRequest failed, ret=%d \n", __func__, ret);
923             return;
924         }
925     }
926 }
927 
EcmFreeReadReq(struct EcmDevice * ecm)928 static void EcmFreeReadReq(struct EcmDevice *ecm)
929 {
930     int32_t ret;
931     for (int32_t i = 0; i < ECM_NR; i++) {
932         ret = UsbFreeRequest(ecm->readReq[i]);
933         if (ret) {
934             goto ERR;
935         }
936     }
937 ERR:
938     return;
939 }
940 
UsbFreeNotifyReqeust(struct EcmDevice * ecm)941 static void UsbFreeNotifyReqeust(struct EcmDevice *ecm)
942 {
943     int32_t ret;
944 
945     if ((ecm == NULL) || (ecm->notifyReq == NULL)) {
946         HDF_LOGE("%s: ecm or notifyReq is NULL", __func__);
947         return;
948     }
949     ret = UsbCancelRequest(ecm->notifyReq);
950     if (ret != HDF_SUCCESS) {
951         HDF_LOGE("UsbCancelRequest rd failed, ret=%d ", ret);
952     }
953     ret = UsbFreeRequest(ecm->notifyReq);
954     if (ret == HDF_SUCCESS) {
955         ecm->notifyReq = NULL;
956     } else {
957         HDF_LOGE("%s: UsbFreeNotifyReqeust failed, ret=%d", __func__, ret);
958     }
959 }
960 
EcmReleaseInterfaces(struct EcmDevice * ecm)961 static void EcmReleaseInterfaces(struct EcmDevice *ecm)
962 {
963     for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
964         if (ecm->iface[i]) {
965             UsbReleaseInterface(ecm->iface[i]);
966             ecm->iface[i] = NULL;
967         }
968     }
969     if (ecm->ctrIface) {
970         UsbReleaseInterface(ecm->ctrIface);
971         ecm->ctrIface = NULL;
972     }
973 }
974 
EcmClaimInterfaces(struct EcmDevice * ecm)975 static int32_t EcmClaimInterfaces(struct EcmDevice *ecm)
976 {
977     for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
978         ecm->iface[i] = EcmGetUsbInterfaceById(ecm, ecm->interfaceIndex[i]);
979         if (ecm->iface[i] == NULL) {
980             HDF_LOGE("interface%d is null", ecm->interfaceIndex[i]);
981             goto ERROR;
982         }
983     }
984 
985     ecm->ctrIface = EcmGetUsbInterfaceById(ecm, USB_CTRL_INTERFACE_ID);
986     if (ecm->ctrIface == NULL) {
987         HDF_LOGE("%d: UsbClaimInterface null", __LINE__);
988         goto ERROR;
989     }
990 
991     return HDF_SUCCESS;
992 
993 ERROR:
994     EcmReleaseInterfaces(ecm);
995     return HDF_FAILURE;
996 }
997 
EcmCloseInterfaces(struct EcmDevice * ecm)998 static void EcmCloseInterfaces(struct EcmDevice *ecm)
999 {
1000     for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
1001         if (ecm->devHandle[i]) {
1002             UsbCloseInterface(ecm->devHandle[i]);
1003             ecm->devHandle[i] = NULL;
1004         }
1005     }
1006 
1007     if (ecm->ctrDevHandle) {
1008         UsbCloseInterface(ecm->ctrDevHandle);
1009         ecm->ctrDevHandle = NULL;
1010     }
1011 }
1012 
EcmOpenInterfaces(struct EcmDevice * ecm)1013 static int32_t EcmOpenInterfaces(struct EcmDevice *ecm)
1014 {
1015     for (uint8_t i = 0; i < ecm->interfaceCnt; i++) {
1016         if (ecm->iface[i]) {
1017             ecm->devHandle[i] = UsbOpenInterface(ecm->iface[i]);
1018             if (ecm->devHandle[i] == NULL) {
1019                 HDF_LOGE("%s: UsbOpenInterface null", __func__);
1020                 goto ERROR;
1021             }
1022         }
1023     }
1024 
1025     ecm->ctrDevHandle = UsbOpenInterface(ecm->ctrIface);
1026     if (ecm->ctrDevHandle == NULL) {
1027         HDF_LOGE("%s: ctrDevHandle UsbOpenInterface null", __func__);
1028         goto ERROR;
1029     }
1030 
1031     return HDF_SUCCESS;
1032 
1033 ERROR:
1034     EcmCloseInterfaces(ecm);
1035     return HDF_FAILURE;
1036 }
1037 
EcmGetPipesAndRequest(struct EcmDevice * ecm,int32_t ret)1038 static int32_t EcmGetPipesAndRequest(struct EcmDevice *ecm, int32_t ret)
1039 {
1040     ret = EcmGetPipes(ecm);
1041     if (ret != HDF_SUCCESS) {
1042         HDF_LOGE("%{public}s: EcmGetPipes failed", __func__);
1043         goto ERROR_GET_PIPES;
1044     }
1045 
1046     ret = EcmAllocIntReq(ecm);
1047     if (ret != HDF_SUCCESS) {
1048         HDF_LOGE("%{public}s: EcmAllocIntReq failed", __func__);
1049         goto ERROR_ALLOC_REQ;
1050     }
1051     if (false) {
1052         EcmCtrlMsg(ecm, USB_DDK_CDC_SET_ETHERNET_PACKET_FILTER,
1053             USB_DDK_CDC_PACKET_TYPE_DIRECTED | USB_DDK_CDC_PACKET_TYPE_BROADCAST, NULL, 0);
1054         ret = UsbSubmitRequestAsync(ecm->notifyReq);
1055         if (ret != HDF_SUCCESS) {
1056             return ret;
1057         }
1058     }
1059     ecm->initFlag = true;
1060     return HDF_SUCCESS;
1061 ERROR_ALLOC_REQ:
1062     EcmFreePipes(ecm);
1063 ERROR_GET_PIPES:
1064     UsbFreeNotifyReqeust(ecm);
1065     return ret;
1066 }
1067 
EcmInit(struct EcmDevice * ecm)1068 static int32_t EcmInit(struct EcmDevice *ecm)
1069 {
1070     int32_t ret;
1071     const uint8_t altsetting = 1;
1072 
1073     if (ecm->initFlag == true) {
1074         HDF_LOGE("%{public}s: initFlag is true", __func__);
1075         return HDF_SUCCESS;
1076     }
1077 
1078     if (UsbInitHostSdk(NULL) != HDF_SUCCESS) {
1079         HDF_LOGE("%{public}s: UsbInitHostSdk failed", __func__);
1080         return HDF_ERR_IO;
1081     }
1082     ecm->session = NULL;
1083 
1084     ret = EcmClaimInterfaces(ecm);
1085     if (ret != HDF_SUCCESS) {
1086         HDF_LOGE("%{public}s: EcmClaimInterfaces failed", __func__);
1087         goto ERR_CLAIM_INTERFACES;
1088     }
1089 
1090     ret = EcmOpenInterfaces(ecm);
1091     if (ret != HDF_SUCCESS) {
1092         HDF_LOGE("%{public}s: EcmOpenInterfaces failed", __func__);
1093         goto ERROR_OPEN_INTERFACES;
1094     }
1095 
1096     if (ecm->interfaceCnt > USB_MAX_INTERFACES) {
1097         HDF_LOGE("interfaceCnt invalid : %u\n", ecm->interfaceCnt);
1098         goto ERROR_OPEN_INTERFACES;
1099     }
1100 
1101     ret = UsbSelectInterfaceSetting(
1102         ecm->devHandle[ecm->interfaceCnt - 1], altsetting, &ecm->iface[ecm->interfaceCnt - 1]); // set altsetting
1103     if (ret != HDF_SUCCESS) {
1104         HDF_LOGE("UsbSelectInterfaceSetting fail\n");
1105         goto ERROR_SELECT_SETTING;
1106     }
1107     EcmGetPipesAndRequest(ecm, ret);
1108 ERROR_SELECT_SETTING:
1109     EcmCloseInterfaces(ecm);
1110 ERROR_OPEN_INTERFACES:
1111     EcmReleaseInterfaces(ecm);
1112 ERR_CLAIM_INTERFACES:
1113     UsbExitHostSdk(ecm->session);
1114     ecm->session = NULL;
1115     return ret;
1116 }
1117 
EcmRelease(struct EcmDevice * ecm)1118 static void EcmRelease(struct EcmDevice *ecm)
1119 {
1120     if (!(ecm->initFlag)) {
1121         HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
1122         return;
1123     }
1124 
1125     EcmCloseInterfaces(ecm);
1126     EcmReleaseInterfaces(ecm);
1127     UsbFreeNotifyReqeust(ecm);
1128     EcmFreePipes(ecm);
1129     UsbExitHostSdk(ecm->session);
1130 
1131     ecm->initFlag = false;
1132 }
1133 
EcmDriverInit(struct HdfDeviceObject * device)1134 static int32_t EcmDriverInit(struct HdfDeviceObject *device)
1135 {
1136     struct EcmDevice *ecm = NULL;
1137 
1138     if (device == NULL) {
1139         HDF_LOGE("%s: device is null", __func__);
1140         return HDF_ERR_INVALID_OBJECT;
1141     }
1142     ecm = (struct EcmDevice *)device->service;
1143     if (ecm == NULL) {
1144         HDF_LOGE("%s: ecm is null", __func__);
1145         return HDF_FAILURE;
1146     }
1147 
1148     OsalMutexInit(&ecm->readLock);
1149     OsalMutexInit(&ecm->writeLock);
1150     ecm->openFlag = false;
1151     ecm->initFlag = false;
1152     g_ecmReleaseFlag = false;
1153 
1154     HDF_LOGE("%s:%d EcmDriverInit OK", __func__, __LINE__);
1155     return HDF_SUCCESS;
1156 }
1157 
EcmDriverRelease(struct HdfDeviceObject * device)1158 static void EcmDriverRelease(struct HdfDeviceObject *device)
1159 {
1160     struct EcmDevice *ecm = NULL;
1161     if (device == NULL) {
1162         HDF_LOGE("%s: device is NULL", __func__);
1163         return;
1164     }
1165     ecm = (struct EcmDevice *)device->service;
1166     if (ecm == NULL) {
1167         HDF_LOGE("%s: ecm is null", __func__);
1168         return;
1169     }
1170 
1171     g_ecmReleaseFlag = true;
1172 
1173     if (ecm->openFlag) {
1174         HDF_LOGD("%s:%d EcmClostRelease", __func__, __LINE__);
1175         EcmClostRelease(ecm);
1176     }
1177     if (ecm->initFlag) {
1178         HDF_LOGD("%s:%d EcmRelease", __func__, __LINE__);
1179         EcmRelease(ecm);
1180     }
1181     OsalMutexDestroy(&ecm->writeLock);
1182     OsalMutexDestroy(&ecm->readLock);
1183     OsalMemFree(ecm);
1184     ecm = NULL;
1185     HDF_LOGD("%s:%d exit", __func__, __LINE__);
1186 }
1187 
1188 struct HdfDriverEntry g_ecmUsbDriverEntry = {
1189     .moduleVersion = 1,
1190     .moduleName = "usbhost_ecm",
1191     .Bind = EcmDriverBind,
1192     .Init = EcmDriverInit,
1193     .Release = EcmDriverRelease,
1194 };
1195 
1196 HDF_INIT(g_ecmUsbDriverEntry);
1197