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