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