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