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