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