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