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