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 37static bool g_ecmReleaseFlag = false; 38 39static void EcmWriteBulk(struct UsbRequest *req); 40static void EcmAllocWriteReq(struct EcmDevice * const ecm); 41static void EcmFreeWriteReq(struct EcmDevice * const ecm); 42static int32_t EcmAllocIntReq(struct EcmDevice *ecm); 43static void EcmAllocReadReq(struct EcmDevice *ecm); 44static void EcmFreeReadReq(struct EcmDevice *ecm); 45static int32_t EcmInit(struct EcmDevice *ecm); 46static void EcmRelease(struct EcmDevice *ecm); 47static struct UsbInterface *EcmGetUsbInterfaceById(struct EcmDevice *ecm, uint8_t interfaceIndex); 48 49static 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 73static 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 90static 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 103static void EcmFreeFifo(struct DataFifo *fifo) 104{ 105 void *buf = fifo->data; 106 OsalMemFree(buf); 107 DataFifoInit(fifo, 0, NULL); 108} 109 110static 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 122static 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 156static 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 175static 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 188static 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 } 208EXIT: 209 return; 210} 211 212static 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 226static 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 274static 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 } 319OUT: 320 OsalMemFree(buf); 321 return ret; 322} 323 324static 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; 370ERR: 371 EcmFreeFifo(&ecm->readFifo); 372 return ret; 373} 374 375static 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 410static 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 434static 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 487static int32_t EcmGetMac(struct EcmDevice *ecm, struct HdfSBuf *reply) 488{ 489 (void)ecm; 490 (void)reply; 491 return HDF_SUCCESS; 492} 493 494static 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 520static 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 567static struct UsbInterface *EcmGetUsbInterfaceById(struct EcmDevice *ecm, uint8_t interfaceIndex) 568{ 569 return UsbClaimInterface(ecm->session, ecm->busNum, ecm->devAddr, interfaceIndex); 570} 571 572static 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 595static 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 628static 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 649static 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 679ERROR: 680 EcmFreePipes(ecm); 681 return HDF_FAILURE; 682} 683 684static 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 723ERROR: 724 OsalMemFree(ecm); 725 ecm = NULL; 726 return HDF_FAILURE; 727} 728 729static 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 747static 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 760static 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); 806EXIT: 807 HDF_LOGE("%{public}s: exit", __func__); 808} 809 810static 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 847static 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; 865ERR: 866 EcmWriteBufFree(ecm); 867 return; 868} 869 870static 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 882static 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 912static 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 940static 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 } 949ERR: 950 return; 951} 952 953static 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 973static 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 987static 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 1005ERROR: 1006 EcmReleaseInterfaces(ecm); 1007 return HDF_FAILURE; 1008} 1009 1010static 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 1025static 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 1045ERROR: 1046 EcmCloseInterfaces(ecm); 1047 return HDF_FAILURE; 1048} 1049 1050static 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; 1073ERROR_ALLOC_REQ: 1074 EcmFreePipes(ecm); 1075ERROR_GET_PIPES: 1076 UsbFreeNotifyReqeust(ecm); 1077 return ret; 1078} 1079 1080static 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); 1120ERROR_SELECT_SETTING: 1121 EcmCloseInterfaces(ecm); 1122ERROR_OPEN_INTERFACES: 1123 EcmReleaseInterfaces(ecm); 1124ERR_CLAIM_INTERFACES: 1125 UsbExitHostSdk(ecm->session); 1126 ecm->session = NULL; 1127 return ret; 1128} 1129 1130static 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 1146static 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 1170static 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 1200struct HdfDriverEntry g_ecmUsbDriverEntry = { 1201 .moduleVersion = 1, 1202 .moduleName = "usbhost_ecm", 1203 .Bind = EcmDriverBind, 1204 .Init = EcmDriverInit, 1205 .Release = EcmDriverRelease, 1206}; 1207 1208HDF_INIT(g_ecmUsbDriverEntry); 1209