1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include <unistd.h> 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include "hdf_base.h" 19094332d3Sopenharmony_ci#include "hdf_log.h" 20094332d3Sopenharmony_ci#include "hdf_usb_pnp_manage.h" 21094332d3Sopenharmony_ci#include "osal_mem.h" 22094332d3Sopenharmony_ci#include "osal_time.h" 23094332d3Sopenharmony_ci#include "securec.h" 24094332d3Sopenharmony_ci#include "usb_serial_rawapi.h" 25094332d3Sopenharmony_ci 26094332d3Sopenharmony_ci#define HDF_LOG_TAG USB_HOST_ACM_RAW_API 27094332d3Sopenharmony_ci#define USB_CTRL_REQ_SIZE 64 28094332d3Sopenharmony_ci#define USB_IO_THREAD_STACK_SIZE 8192 29094332d3Sopenharmony_ci#define USB_RAW_IO_SLEEP_MS_TIME 100 30094332d3Sopenharmony_ci#define USB_RAW_IO_STOP_WAIT_MAX_TIME 3 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_cistatic struct UsbRawRequest *g_syncRequest = NULL; 33094332d3Sopenharmony_cistatic UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING; 34094332d3Sopenharmony_cistruct OsalMutex g_stopIoLock; 35094332d3Sopenharmony_cistatic bool g_rawAcmReleaseFlag = false; 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_cistatic int32_t SerialSendCtrlMsg(struct AcmDevice *acm, uint8_t request, uint16_t value, void *buf, uint16_t len); 38094332d3Sopenharmony_cistatic void AcmWriteBulkCallback(const void *requestArg); 39094332d3Sopenharmony_cistatic int32_t UsbSerialInit(struct AcmDevice *acm); 40094332d3Sopenharmony_cistatic void UsbSerialRelease(struct AcmDevice *acm); 41094332d3Sopenharmony_ci 42094332d3Sopenharmony_cistatic int32_t UsbIoThread(void *data) 43094332d3Sopenharmony_ci{ 44094332d3Sopenharmony_ci int32_t ret; 45094332d3Sopenharmony_ci struct AcmDevice *acm = (struct AcmDevice *)data; 46094332d3Sopenharmony_ci 47094332d3Sopenharmony_ci for (;;) { 48094332d3Sopenharmony_ci if (acm == NULL) { 49094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d acm is null", __func__, __LINE__); 50094332d3Sopenharmony_ci OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME); 51094332d3Sopenharmony_ci continue; 52094332d3Sopenharmony_ci } 53094332d3Sopenharmony_ci 54094332d3Sopenharmony_ci if (acm->devHandle == NULL) { 55094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d acm->devHandle is null", __func__, __LINE__); 56094332d3Sopenharmony_ci OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME); 57094332d3Sopenharmony_ci continue; 58094332d3Sopenharmony_ci } 59094332d3Sopenharmony_ci 60094332d3Sopenharmony_ci ret = UsbRawHandleRequests(acm->devHandle); 61094332d3Sopenharmony_ci if ((ret < 0) || (g_stopIoStatus != USB_RAW_IO_PROCESS_RUNNING)) { 62094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbIoThread failed, g_stopIoStatus=%{public}d ret=%{public}d ", 63094332d3Sopenharmony_ci __func__, __LINE__, g_stopIoStatus, ret); 64094332d3Sopenharmony_ci break; 65094332d3Sopenharmony_ci } 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci 68094332d3Sopenharmony_ci OsalMutexLock(&g_stopIoLock); 69094332d3Sopenharmony_ci g_stopIoStatus = USB_RAW_IO_PROCESS_STOPED; 70094332d3Sopenharmony_ci OsalMutexUnlock(&g_stopIoLock); 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d exit", __func__, __LINE__); 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_ci return HDF_SUCCESS; 75094332d3Sopenharmony_ci} 76094332d3Sopenharmony_ci 77094332d3Sopenharmony_cistatic int32_t UsbStartIo(struct AcmDevice *acm) 78094332d3Sopenharmony_ci{ 79094332d3Sopenharmony_ci struct OsalThreadParam threadCfg; 80094332d3Sopenharmony_ci int32_t ret; 81094332d3Sopenharmony_ci 82094332d3Sopenharmony_ci HDF_LOGI("%{public}s start", __func__); 83094332d3Sopenharmony_ci 84094332d3Sopenharmony_ci OsalMutexInit(&g_stopIoLock); 85094332d3Sopenharmony_ci 86094332d3Sopenharmony_ci OsalMutexLock(&g_stopIoLock); 87094332d3Sopenharmony_ci g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING; 88094332d3Sopenharmony_ci OsalMutexUnlock(&g_stopIoLock); 89094332d3Sopenharmony_ci 90094332d3Sopenharmony_ci /* create Io thread */ 91094332d3Sopenharmony_ci (void)memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg)); 92094332d3Sopenharmony_ci threadCfg.name = "usb io thread"; 93094332d3Sopenharmony_ci threadCfg.priority = OSAL_THREAD_PRI_LOW; 94094332d3Sopenharmony_ci threadCfg.stackSize = USB_IO_THREAD_STACK_SIZE; 95094332d3Sopenharmony_ci 96094332d3Sopenharmony_ci ret = OsalThreadCreate(&acm->ioThread, (OsalThreadEntry)UsbIoThread, (void *)acm); 97094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 98094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalThreadCreate failed, ret = %{public}d", __func__, __LINE__, ret); 99094332d3Sopenharmony_ci return ret; 100094332d3Sopenharmony_ci } 101094332d3Sopenharmony_ci 102094332d3Sopenharmony_ci ret = OsalThreadStart(&acm->ioThread, &threadCfg); 103094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 104094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalThreadStart failed, ret = %{public}d", __func__, __LINE__, ret); 105094332d3Sopenharmony_ci return ret; 106094332d3Sopenharmony_ci } 107094332d3Sopenharmony_ci 108094332d3Sopenharmony_ci return HDF_SUCCESS; 109094332d3Sopenharmony_ci} 110094332d3Sopenharmony_ci 111094332d3Sopenharmony_cistatic void UsbStopIo(struct AcmDevice *acm) 112094332d3Sopenharmony_ci{ 113094332d3Sopenharmony_ci int32_t ret; 114094332d3Sopenharmony_ci int32_t i = 0; 115094332d3Sopenharmony_ci 116094332d3Sopenharmony_ci if (g_stopIoStatus != USB_RAW_IO_PROCESS_STOPED) { 117094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d not stopped", __func__, __LINE__); 118094332d3Sopenharmony_ci OsalMutexLock(&g_stopIoLock); 119094332d3Sopenharmony_ci g_stopIoStatus = USB_RAW_IO_PROCESS_STOP; 120094332d3Sopenharmony_ci OsalMutexUnlock(&g_stopIoLock); 121094332d3Sopenharmony_ci } else { 122094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d stopped", __func__, __LINE__); 123094332d3Sopenharmony_ci } 124094332d3Sopenharmony_ci 125094332d3Sopenharmony_ci while (g_stopIoStatus != USB_RAW_IO_PROCESS_STOPED) { 126094332d3Sopenharmony_ci i++; 127094332d3Sopenharmony_ci OsalMSleep(USB_RAW_IO_SLEEP_MS_TIME); 128094332d3Sopenharmony_ci if (i > USB_RAW_IO_STOP_WAIT_MAX_TIME) { 129094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d", __func__, __LINE__); 130094332d3Sopenharmony_ci break; 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci } 133094332d3Sopenharmony_ci 134094332d3Sopenharmony_ci ret = OsalThreadDestroy(&acm->ioThread); 135094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 136094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalThreadDestroy failed, ret = %{public}d", __func__, __LINE__, ret); 137094332d3Sopenharmony_ci } 138094332d3Sopenharmony_ci 139094332d3Sopenharmony_ci OsalMutexDestroy(&g_stopIoLock); 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ci return; 142094332d3Sopenharmony_ci} 143094332d3Sopenharmony_ci 144094332d3Sopenharmony_cistatic int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config) 145094332d3Sopenharmony_ci{ 146094332d3Sopenharmony_ci UsbRawDevice *dev = NULL; 147094332d3Sopenharmony_ci int32_t activeConfig; 148094332d3Sopenharmony_ci int32_t ret; 149094332d3Sopenharmony_ci 150094332d3Sopenharmony_ci if (devHandle == NULL) { 151094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d devHandle is null", __func__, __LINE__); 152094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 153094332d3Sopenharmony_ci } 154094332d3Sopenharmony_ci 155094332d3Sopenharmony_ci ret = UsbRawGetConfiguration(devHandle, &activeConfig); 156094332d3Sopenharmony_ci if (ret) { 157094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbRawGetConfiguration failed, ret = %{public}d", __func__, __LINE__, ret); 158094332d3Sopenharmony_ci return HDF_FAILURE; 159094332d3Sopenharmony_ci } 160094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d activeConfig = %{public}d", __func__, __LINE__, activeConfig); 161094332d3Sopenharmony_ci dev = UsbRawGetDevice(devHandle); 162094332d3Sopenharmony_ci if (dev == NULL) { 163094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbRawGetDevice failed", __func__, __LINE__); 164094332d3Sopenharmony_ci return HDF_FAILURE; 165094332d3Sopenharmony_ci } 166094332d3Sopenharmony_ci 167094332d3Sopenharmony_ci ret = UsbRawGetConfigDescriptor(dev, activeConfig, config); 168094332d3Sopenharmony_ci if (ret) { 169094332d3Sopenharmony_ci HDF_LOGE("UsbRawGetConfigDescriptor failed, ret = %{public}d", ret); 170094332d3Sopenharmony_ci return HDF_FAILURE; 171094332d3Sopenharmony_ci } 172094332d3Sopenharmony_ci 173094332d3Sopenharmony_ci return HDF_SUCCESS; 174094332d3Sopenharmony_ci} 175094332d3Sopenharmony_ci 176094332d3Sopenharmony_cistatic int32_t UsbGetBulkEndpoint(struct AcmDevice *acm, const struct UsbRawEndpointDescriptor *endPoint) 177094332d3Sopenharmony_ci{ 178094332d3Sopenharmony_ci if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) { 179094332d3Sopenharmony_ci /* get bulk in endpoint */ 180094332d3Sopenharmony_ci acm->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint)); 181094332d3Sopenharmony_ci if (acm->dataInEp == NULL) { 182094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d allocate dataInEp failed", __func__, __LINE__); 183094332d3Sopenharmony_ci return HDF_FAILURE; 184094332d3Sopenharmony_ci } 185094332d3Sopenharmony_ci acm->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress; 186094332d3Sopenharmony_ci acm->dataInEp->interval = endPoint->endpointDescriptor.bInterval; 187094332d3Sopenharmony_ci acm->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize; 188094332d3Sopenharmony_ci } else { 189094332d3Sopenharmony_ci /* get bulk out endpoint */ 190094332d3Sopenharmony_ci acm->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint)); 191094332d3Sopenharmony_ci if (acm->dataOutEp == NULL) { 192094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d allocate dataOutEp failed", __func__, __LINE__); 193094332d3Sopenharmony_ci return HDF_FAILURE; 194094332d3Sopenharmony_ci } 195094332d3Sopenharmony_ci acm->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress; 196094332d3Sopenharmony_ci acm->dataOutEp->interval = endPoint->endpointDescriptor.bInterval; 197094332d3Sopenharmony_ci acm->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize; 198094332d3Sopenharmony_ci } 199094332d3Sopenharmony_ci 200094332d3Sopenharmony_ci return HDF_SUCCESS; 201094332d3Sopenharmony_ci} 202094332d3Sopenharmony_ci 203094332d3Sopenharmony_cistatic void UsbParseConfigDescriptorProcess( 204094332d3Sopenharmony_ci struct AcmDevice *acm, const struct UsbRawInterface *interface, uint8_t interfaceIndex) 205094332d3Sopenharmony_ci{ 206094332d3Sopenharmony_ci uint8_t ifaceClass = interface->altsetting->interfaceDescriptor.bInterfaceClass; 207094332d3Sopenharmony_ci uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints; 208094332d3Sopenharmony_ci 209094332d3Sopenharmony_ci switch (ifaceClass) { 210094332d3Sopenharmony_ci case USB_DDK_CLASS_COMM: 211094332d3Sopenharmony_ci acm->ctrlIface = interfaceIndex; 212094332d3Sopenharmony_ci acm->notifyEp = OsalMemAlloc(sizeof(struct UsbEndpoint)); 213094332d3Sopenharmony_ci if (acm->notifyEp == NULL) { 214094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d allocate endpoint failed", __func__, __LINE__); 215094332d3Sopenharmony_ci break; 216094332d3Sopenharmony_ci } 217094332d3Sopenharmony_ci /* get the first endpoint by default */ 218094332d3Sopenharmony_ci acm->notifyEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress; 219094332d3Sopenharmony_ci acm->notifyEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval; 220094332d3Sopenharmony_ci acm->notifyEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize; 221094332d3Sopenharmony_ci break; 222094332d3Sopenharmony_ci case USB_DDK_CLASS_CDC_DATA: 223094332d3Sopenharmony_ci acm->dataIface = interfaceIndex; 224094332d3Sopenharmony_ci for (uint8_t j = 0; j < numEndpoints; j++) { 225094332d3Sopenharmony_ci const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j]; 226094332d3Sopenharmony_ci if (UsbGetBulkEndpoint(acm, endPoint) != HDF_SUCCESS) { 227094332d3Sopenharmony_ci break; 228094332d3Sopenharmony_ci } 229094332d3Sopenharmony_ci } 230094332d3Sopenharmony_ci break; 231094332d3Sopenharmony_ci default: 232094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d wrong descriptor type", __func__, __LINE__); 233094332d3Sopenharmony_ci break; 234094332d3Sopenharmony_ci } 235094332d3Sopenharmony_ci} 236094332d3Sopenharmony_ci 237094332d3Sopenharmony_cistatic int32_t UsbParseConfigDescriptor(struct AcmDevice *acm, struct UsbRawConfigDescriptor *config) 238094332d3Sopenharmony_ci{ 239094332d3Sopenharmony_ci if ((acm == NULL) || (config == NULL)) { 240094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d acm or config is null", __func__, __LINE__); 241094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 242094332d3Sopenharmony_ci } 243094332d3Sopenharmony_ci 244094332d3Sopenharmony_ci for (uint8_t i = 0; i < acm->interfaceCnt; i++) { 245094332d3Sopenharmony_ci uint8_t interfaceIndex = acm->interfaceIndex[i]; 246094332d3Sopenharmony_ci const struct UsbRawInterface *interface = config->interface[interfaceIndex]; 247094332d3Sopenharmony_ci 248094332d3Sopenharmony_ci int32_t ret = UsbRawClaimInterface(acm->devHandle, interfaceIndex); 249094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 250094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d claim interface %{public}hhu failed", __func__, __LINE__, i); 251094332d3Sopenharmony_ci continue; 252094332d3Sopenharmony_ci } 253094332d3Sopenharmony_ci 254094332d3Sopenharmony_ci UsbParseConfigDescriptorProcess(acm, interface, interfaceIndex); 255094332d3Sopenharmony_ci } 256094332d3Sopenharmony_ci 257094332d3Sopenharmony_ci return HDF_SUCCESS; 258094332d3Sopenharmony_ci} 259094332d3Sopenharmony_ci 260094332d3Sopenharmony_cistatic void UsbReleaseInterfaces(struct AcmDevice *acm) 261094332d3Sopenharmony_ci{ 262094332d3Sopenharmony_ci if ((acm == NULL) || (acm->devHandle == NULL)) { 263094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d acm is null", __func__, __LINE__); 264094332d3Sopenharmony_ci return; 265094332d3Sopenharmony_ci } 266094332d3Sopenharmony_ci 267094332d3Sopenharmony_ci (void)UsbRawReleaseInterface(acm->devHandle, acm->ctrlIface); 268094332d3Sopenharmony_ci (void)UsbRawReleaseInterface(acm->devHandle, acm->dataIface); 269094332d3Sopenharmony_ci 270094332d3Sopenharmony_ci if (acm->notifyEp) { 271094332d3Sopenharmony_ci OsalMemFree(acm->notifyEp); 272094332d3Sopenharmony_ci acm->notifyEp = NULL; 273094332d3Sopenharmony_ci } 274094332d3Sopenharmony_ci if (acm->dataInEp) { 275094332d3Sopenharmony_ci OsalMemFree(acm->dataInEp); 276094332d3Sopenharmony_ci acm->dataInEp = NULL; 277094332d3Sopenharmony_ci } 278094332d3Sopenharmony_ci if (acm->dataOutEp) { 279094332d3Sopenharmony_ci OsalMemFree(acm->dataOutEp); 280094332d3Sopenharmony_ci acm->dataOutEp = NULL; 281094332d3Sopenharmony_ci } 282094332d3Sopenharmony_ci} 283094332d3Sopenharmony_ci 284094332d3Sopenharmony_cistatic int32_t UsbAllocWriteRequests(struct AcmDevice *acm) 285094332d3Sopenharmony_ci{ 286094332d3Sopenharmony_ci int32_t i; 287094332d3Sopenharmony_ci 288094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++) { 289094332d3Sopenharmony_ci struct AcmWb *snd = &acm->wb[i]; 290094332d3Sopenharmony_ci snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize); 291094332d3Sopenharmony_ci snd->instance = acm; 292094332d3Sopenharmony_ci if (snd->request == NULL) { 293094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbRawAllocRequest failed", __func__); 294094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 295094332d3Sopenharmony_ci } 296094332d3Sopenharmony_ci } 297094332d3Sopenharmony_ci 298094332d3Sopenharmony_ci return HDF_SUCCESS; 299094332d3Sopenharmony_ci} 300094332d3Sopenharmony_ci 301094332d3Sopenharmony_cistatic void UsbFreeWriteRequests(struct AcmDevice *acm) 302094332d3Sopenharmony_ci{ 303094332d3Sopenharmony_ci int32_t i; 304094332d3Sopenharmony_ci struct AcmWb *snd = NULL; 305094332d3Sopenharmony_ci 306094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++) { 307094332d3Sopenharmony_ci snd = &acm->wb[i]; 308094332d3Sopenharmony_ci if (snd->request != NULL) { 309094332d3Sopenharmony_ci UsbRawFreeRequest(snd->request); 310094332d3Sopenharmony_ci snd->request = NULL; 311094332d3Sopenharmony_ci } 312094332d3Sopenharmony_ci } 313094332d3Sopenharmony_ci} 314094332d3Sopenharmony_ci 315094332d3Sopenharmony_cistatic int32_t AcmWbAlloc(const struct AcmDevice *acm) 316094332d3Sopenharmony_ci{ 317094332d3Sopenharmony_ci struct AcmWb *wb = NULL; 318094332d3Sopenharmony_ci int32_t i; 319094332d3Sopenharmony_ci 320094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++) { 321094332d3Sopenharmony_ci wb = (struct AcmWb *)&acm->wb[i]; 322094332d3Sopenharmony_ci if (!wb->use) { 323094332d3Sopenharmony_ci wb->use = 1; 324094332d3Sopenharmony_ci wb->len = 0; 325094332d3Sopenharmony_ci return i; 326094332d3Sopenharmony_ci } 327094332d3Sopenharmony_ci } 328094332d3Sopenharmony_ci return -1; 329094332d3Sopenharmony_ci} 330094332d3Sopenharmony_ci 331094332d3Sopenharmony_cistatic int32_t UsbSerialAllocFifo(struct DataFifo *fifo, uint32_t size) 332094332d3Sopenharmony_ci{ 333094332d3Sopenharmony_ci if (!DataFifoIsInitialized(fifo)) { 334094332d3Sopenharmony_ci void *data = OsalMemAlloc(size); 335094332d3Sopenharmony_ci if (data == NULL) { 336094332d3Sopenharmony_ci HDF_LOGE("%{public}s:allocate failed", __func__); 337094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 338094332d3Sopenharmony_ci } 339094332d3Sopenharmony_ci DataFifoInit(fifo, size, data); 340094332d3Sopenharmony_ci } 341094332d3Sopenharmony_ci return HDF_SUCCESS; 342094332d3Sopenharmony_ci} 343094332d3Sopenharmony_ci 344094332d3Sopenharmony_cistatic void UsbSerialFreeFifo(const struct DataFifo *fifo) 345094332d3Sopenharmony_ci{ 346094332d3Sopenharmony_ci if (fifo == NULL) { 347094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d fifo is null", __func__, __LINE__); 348094332d3Sopenharmony_ci return; 349094332d3Sopenharmony_ci } 350094332d3Sopenharmony_ci 351094332d3Sopenharmony_ci if (fifo->data != NULL) { 352094332d3Sopenharmony_ci OsalMemFree((void *)fifo->data); 353094332d3Sopenharmony_ci } 354094332d3Sopenharmony_ci 355094332d3Sopenharmony_ci DataFifoInit((struct DataFifo *)fifo, 0, NULL); 356094332d3Sopenharmony_ci} 357094332d3Sopenharmony_ci 358094332d3Sopenharmony_cistatic int32_t AcmWbIsAvail(const struct AcmDevice *acm) 359094332d3Sopenharmony_ci{ 360094332d3Sopenharmony_ci int32_t i; 361094332d3Sopenharmony_ci int32_t n = ACM_NW; 362094332d3Sopenharmony_ci 363094332d3Sopenharmony_ci OsalMutexLock((struct OsalMutex *)&acm->writeLock); 364094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++) { 365094332d3Sopenharmony_ci n -= acm->wb[i].use; 366094332d3Sopenharmony_ci } 367094332d3Sopenharmony_ci OsalMutexUnlock((struct OsalMutex *)&acm->writeLock); 368094332d3Sopenharmony_ci return n; 369094332d3Sopenharmony_ci} 370094332d3Sopenharmony_ci 371094332d3Sopenharmony_cistatic int32_t AcmStartWb(struct AcmDevice *acm, struct AcmWb *wb) 372094332d3Sopenharmony_ci{ 373094332d3Sopenharmony_ci struct UsbRawFillRequestData reqData; 374094332d3Sopenharmony_ci int32_t ret; 375094332d3Sopenharmony_ci if ((acm == NULL) || (wb == NULL) || (acm->dataOutEp == NULL) || (acm->devHandle == NULL) || 376094332d3Sopenharmony_ci (wb->request == NULL)) { 377094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 378094332d3Sopenharmony_ci } 379094332d3Sopenharmony_ci 380094332d3Sopenharmony_ci acm->transmitting++; 381094332d3Sopenharmony_ci 382094332d3Sopenharmony_ci reqData.endPoint = acm->dataOutEp->addr; 383094332d3Sopenharmony_ci reqData.numIsoPackets = 0; 384094332d3Sopenharmony_ci reqData.callback = AcmWriteBulkCallback; 385094332d3Sopenharmony_ci reqData.userData = (void *)wb; 386094332d3Sopenharmony_ci reqData.timeout = USB_CTRL_SET_TIMEOUT; 387094332d3Sopenharmony_ci reqData.buffer = wb->buf; 388094332d3Sopenharmony_ci reqData.length = wb->len; 389094332d3Sopenharmony_ci 390094332d3Sopenharmony_ci ret = UsbRawFillBulkRequest(wb->request, acm->devHandle, &reqData); 391094332d3Sopenharmony_ci if (ret) { 392094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FillInterruptRequest failed, ret = %{public}d", __func__, ret); 393094332d3Sopenharmony_ci return HDF_FAILURE; 394094332d3Sopenharmony_ci } 395094332d3Sopenharmony_ci 396094332d3Sopenharmony_ci acm->writeReq = wb->request; 397094332d3Sopenharmony_ci ret = UsbRawSubmitRequest(wb->request); 398094332d3Sopenharmony_ci if (ret) { 399094332d3Sopenharmony_ci HDF_LOGE("UsbRawSubmitRequest failed, ret = %{public}d", ret); 400094332d3Sopenharmony_ci wb->use = 0; 401094332d3Sopenharmony_ci acm->transmitting--; 402094332d3Sopenharmony_ci } 403094332d3Sopenharmony_ci 404094332d3Sopenharmony_ci return ret; 405094332d3Sopenharmony_ci} 406094332d3Sopenharmony_ci 407094332d3Sopenharmony_cistatic int32_t AcmWriteBufAlloc(const struct AcmDevice *acm) 408094332d3Sopenharmony_ci{ 409094332d3Sopenharmony_ci struct AcmWb *wb = (struct AcmWb *)&acm->wb[0]; 410094332d3Sopenharmony_ci int32_t i; 411094332d3Sopenharmony_ci 412094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++, wb++) { 413094332d3Sopenharmony_ci wb->buf = OsalMemCalloc(acm->dataOutEp->maxPacketSize); 414094332d3Sopenharmony_ci if (!wb->buf) { 415094332d3Sopenharmony_ci while (i > 0) { 416094332d3Sopenharmony_ci --i; 417094332d3Sopenharmony_ci --wb; 418094332d3Sopenharmony_ci OsalMemFree(wb->buf); 419094332d3Sopenharmony_ci wb->buf = NULL; 420094332d3Sopenharmony_ci } 421094332d3Sopenharmony_ci return -HDF_ERR_MALLOC_FAIL; 422094332d3Sopenharmony_ci } 423094332d3Sopenharmony_ci } 424094332d3Sopenharmony_ci return HDF_SUCCESS; 425094332d3Sopenharmony_ci} 426094332d3Sopenharmony_ci 427094332d3Sopenharmony_cistatic void AcmWriteBufFree(struct AcmDevice *acm) 428094332d3Sopenharmony_ci{ 429094332d3Sopenharmony_ci struct AcmWb *wb = &acm->wb[0]; 430094332d3Sopenharmony_ci int32_t i; 431094332d3Sopenharmony_ci 432094332d3Sopenharmony_ci for (i = 0; i < ACM_NW; i++, wb++) { 433094332d3Sopenharmony_ci if (wb->buf) { 434094332d3Sopenharmony_ci OsalMemFree(wb->buf); 435094332d3Sopenharmony_ci wb->buf = NULL; 436094332d3Sopenharmony_ci } 437094332d3Sopenharmony_ci } 438094332d3Sopenharmony_ci return; 439094332d3Sopenharmony_ci} 440094332d3Sopenharmony_ci 441094332d3Sopenharmony_cistatic void AcmWriteBulkCallback(const void *requestArg) 442094332d3Sopenharmony_ci{ 443094332d3Sopenharmony_ci struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg; 444094332d3Sopenharmony_ci if (req == NULL) { 445094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d req is null!", __func__, __LINE__); 446094332d3Sopenharmony_ci return; 447094332d3Sopenharmony_ci } 448094332d3Sopenharmony_ci struct AcmWb *wb = (struct AcmWb *)req->userData; 449094332d3Sopenharmony_ci if (wb == NULL) { 450094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d userData(wb) is null!", __func__, __LINE__); 451094332d3Sopenharmony_ci return; 452094332d3Sopenharmony_ci } 453094332d3Sopenharmony_ci 454094332d3Sopenharmony_ci if (req->status != USB_REQUEST_COMPLETED) { 455094332d3Sopenharmony_ci HDF_LOGE("%{public}s: write req failed, status = %{public}d", __func__, req->status); 456094332d3Sopenharmony_ci } 457094332d3Sopenharmony_ci 458094332d3Sopenharmony_ci wb->use = 0; 459094332d3Sopenharmony_ci} 460094332d3Sopenharmony_ci 461094332d3Sopenharmony_cistatic int32_t SerialSendCtrlMsg(struct AcmDevice *acm, uint8_t request, uint16_t value, void *buf, uint16_t len) 462094332d3Sopenharmony_ci{ 463094332d3Sopenharmony_ci struct UsbControlRequestData ctrlReq; 464094332d3Sopenharmony_ci int32_t ret; 465094332d3Sopenharmony_ci 466094332d3Sopenharmony_ci if (acm == NULL || buf == NULL) { 467094332d3Sopenharmony_ci HDF_LOGE("%{public}s:invalid param", __func__); 468094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 469094332d3Sopenharmony_ci } 470094332d3Sopenharmony_ci if (acm->ctrlReq == NULL) { 471094332d3Sopenharmony_ci acm->ctrlReq = UsbRawAllocRequest(acm->devHandle, 0, USB_CTRL_REQ_SIZE); 472094332d3Sopenharmony_ci if (acm->ctrlReq == NULL) { 473094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbRawAllocRequest failed", __func__); 474094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 475094332d3Sopenharmony_ci } 476094332d3Sopenharmony_ci } 477094332d3Sopenharmony_ci 478094332d3Sopenharmony_ci ctrlReq.requestType = USB_DDK_DIR_OUT | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE; 479094332d3Sopenharmony_ci ctrlReq.requestCmd = request; 480094332d3Sopenharmony_ci ctrlReq.value = CPU_TO_LE16(value); 481094332d3Sopenharmony_ci ctrlReq.index = 0; 482094332d3Sopenharmony_ci ctrlReq.data = buf; 483094332d3Sopenharmony_ci ctrlReq.length = len; 484094332d3Sopenharmony_ci ctrlReq.timeout = USB_CTRL_SET_TIMEOUT; 485094332d3Sopenharmony_ci 486094332d3Sopenharmony_ci ret = UsbRawSendControlRequest(acm->ctrlReq, acm->devHandle, &ctrlReq); 487094332d3Sopenharmony_ci if (ret < HDF_SUCCESS) { 488094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbRawSendControlRequest failed, ret=%{public}d", __func__, ret); 489094332d3Sopenharmony_ci return ret; 490094332d3Sopenharmony_ci } 491094332d3Sopenharmony_ci if (acm->ctrlReq->status) { 492094332d3Sopenharmony_ci HDF_LOGE("%{public}s status=%{public}d ", __func__, acm->ctrlReq->status); 493094332d3Sopenharmony_ci } 494094332d3Sopenharmony_ci return HDF_SUCCESS; 495094332d3Sopenharmony_ci} 496094332d3Sopenharmony_ci 497094332d3Sopenharmony_cistatic int32_t UsbSerialDeviceAlloc(struct AcmDevice *acm) 498094332d3Sopenharmony_ci{ 499094332d3Sopenharmony_ci struct SerialDevice *port = NULL; 500094332d3Sopenharmony_ci 501094332d3Sopenharmony_ci if (acm == NULL) { 502094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm null pointer", __func__); 503094332d3Sopenharmony_ci return HDF_FAILURE; 504094332d3Sopenharmony_ci } 505094332d3Sopenharmony_ci 506094332d3Sopenharmony_ci port = (struct SerialDevice *)OsalMemCalloc(sizeof(*port)); 507094332d3Sopenharmony_ci if (port == NULL) { 508094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Alloc usb serial port failed", __func__); 509094332d3Sopenharmony_ci return HDF_FAILURE; 510094332d3Sopenharmony_ci } 511094332d3Sopenharmony_ci if (OsalMutexInit(&port->lock) != HDF_SUCCESS) { 512094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init lock fail!", __func__); 513094332d3Sopenharmony_ci OsalMemFree(port); 514094332d3Sopenharmony_ci return HDF_FAILURE; 515094332d3Sopenharmony_ci } 516094332d3Sopenharmony_ci port->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE); 517094332d3Sopenharmony_ci port->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; 518094332d3Sopenharmony_ci port->lineCoding.bParityType = USB_CDC_NO_PARITY; 519094332d3Sopenharmony_ci port->lineCoding.bDataBits = DATA_BITS_LENGTH; 520094332d3Sopenharmony_ci acm->lineCoding = port->lineCoding; 521094332d3Sopenharmony_ci acm->port = port; 522094332d3Sopenharmony_ci port->acm = acm; 523094332d3Sopenharmony_ci 524094332d3Sopenharmony_ci return HDF_SUCCESS; 525094332d3Sopenharmony_ci} 526094332d3Sopenharmony_ci 527094332d3Sopenharmony_cistatic void UsbSeriaDevicelFree(struct AcmDevice *acm) 528094332d3Sopenharmony_ci{ 529094332d3Sopenharmony_ci struct SerialDevice *port = acm->port; 530094332d3Sopenharmony_ci 531094332d3Sopenharmony_ci if (port == NULL) { 532094332d3Sopenharmony_ci HDF_LOGE("%{public}s: port is null", __func__); 533094332d3Sopenharmony_ci return; 534094332d3Sopenharmony_ci } 535094332d3Sopenharmony_ci OsalMemFree(port); 536094332d3Sopenharmony_ci port = NULL; 537094332d3Sopenharmony_ci} 538094332d3Sopenharmony_ci 539094332d3Sopenharmony_cistatic int32_t UsbSerialRead(struct SerialDevice *port, struct HdfSBuf *reply) 540094332d3Sopenharmony_ci{ 541094332d3Sopenharmony_ci struct AcmDevice *acm = port->acm; 542094332d3Sopenharmony_ci uint8_t *buf = NULL; 543094332d3Sopenharmony_ci int32_t ret = HDF_SUCCESS; 544094332d3Sopenharmony_ci uint32_t len; 545094332d3Sopenharmony_ci 546094332d3Sopenharmony_ci for (int32_t i = 0; i < ACM_NR; i++) { 547094332d3Sopenharmony_ci if (acm->readReq[i]->status != USB_REQUEST_COMPLETED) { 548094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d i=%{public}d status=%{public}d!", 549094332d3Sopenharmony_ci __func__, __LINE__, i, acm->readReq[i]->status); 550094332d3Sopenharmony_ci return HDF_FAILURE; 551094332d3Sopenharmony_ci } 552094332d3Sopenharmony_ci } 553094332d3Sopenharmony_ci 554094332d3Sopenharmony_ci if (DataFifoIsEmpty(&port->readFifo)) { 555094332d3Sopenharmony_ci if (!HdfSbufWriteString(reply, NULL)) { 556094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d sbuf write buffer failed", __func__, __LINE__); 557094332d3Sopenharmony_ci return HDF_ERR_IO; 558094332d3Sopenharmony_ci } 559094332d3Sopenharmony_ci return HDF_SUCCESS; 560094332d3Sopenharmony_ci } 561094332d3Sopenharmony_ci 562094332d3Sopenharmony_ci buf = (uint8_t *)OsalMemCalloc(DataFifoLen(&port->readFifo) + 1); 563094332d3Sopenharmony_ci if (buf == NULL) { 564094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalMemCalloc error", __func__, __LINE__); 565094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 566094332d3Sopenharmony_ci } 567094332d3Sopenharmony_ci 568094332d3Sopenharmony_ci OsalMutexLock(&acm->readLock); 569094332d3Sopenharmony_ci len = DataFifoRead(&port->readFifo, buf, DataFifoLen(&port->readFifo)); 570094332d3Sopenharmony_ci if (len == 0) { 571094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d no data", __func__, __LINE__); 572094332d3Sopenharmony_ci ret = HDF_SUCCESS; 573094332d3Sopenharmony_ci OsalMutexUnlock(&acm->readLock); 574094332d3Sopenharmony_ci goto OUT; 575094332d3Sopenharmony_ci } 576094332d3Sopenharmony_ci OsalMutexUnlock(&acm->readLock); 577094332d3Sopenharmony_ci 578094332d3Sopenharmony_ci if (!HdfSbufWriteString(reply, (const char *)buf)) { 579094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d sbuf write buffer failed", __func__, __LINE__); 580094332d3Sopenharmony_ci ret = HDF_ERR_IO; 581094332d3Sopenharmony_ci } 582094332d3Sopenharmony_ci 583094332d3Sopenharmony_ciOUT: 584094332d3Sopenharmony_ci OsalMemFree(buf); 585094332d3Sopenharmony_ci return ret; 586094332d3Sopenharmony_ci} 587094332d3Sopenharmony_ci 588094332d3Sopenharmony_cistatic int32_t SerialSetBaudrate(struct SerialDevice *port, const struct HdfSBuf *data) 589094332d3Sopenharmony_ci{ 590094332d3Sopenharmony_ci struct AcmDevice *acm = port->acm; 591094332d3Sopenharmony_ci uint32_t baudRate = 0; 592094332d3Sopenharmony_ci 593094332d3Sopenharmony_ci if (!HdfSbufReadUint32((struct HdfSBuf *)data, &baudRate)) { 594094332d3Sopenharmony_ci HDF_LOGE("%{public}s: sbuf read buffer failed", __func__); 595094332d3Sopenharmony_ci return HDF_ERR_IO; 596094332d3Sopenharmony_ci } 597094332d3Sopenharmony_ci port->lineCoding.dwDTERate = CPU_TO_LE32(baudRate); 598094332d3Sopenharmony_ci if (memcmp(&acm->lineCoding, &port->lineCoding, sizeof(struct UsbCdcLineCoding))) { 599094332d3Sopenharmony_ci int32_t ret = 600094332d3Sopenharmony_ci memcpy_s(&acm->lineCoding, sizeof(struct UsbCdcLineCoding), &port->lineCoding, sizeof(port->lineCoding)); 601094332d3Sopenharmony_ci if (ret != EOK) { 602094332d3Sopenharmony_ci HDF_LOGE("memcpy_s fail, ret=%{public}d", ret); 603094332d3Sopenharmony_ci return ret; 604094332d3Sopenharmony_ci } 605094332d3Sopenharmony_ci 606094332d3Sopenharmony_ci HDF_LOGE("%{public}s - set line: %{public}d %{public}d %{public}d %{public}d", 607094332d3Sopenharmony_ci __func__, (port->lineCoding.dwDTERate), port->lineCoding.bCharFormat, 608094332d3Sopenharmony_ci port->lineCoding.bParityType, port->lineCoding.bDataBits); 609094332d3Sopenharmony_ci 610094332d3Sopenharmony_ci ret = SerialSendCtrlMsg( 611094332d3Sopenharmony_ci acm, USB_DDK_CDC_REQ_SET_LINE_CODING, 0, &acm->lineCoding, sizeof(struct UsbCdcLineCoding)); 612094332d3Sopenharmony_ci if (ret) { 613094332d3Sopenharmony_ci HDF_LOGE("SerialSendCtrlMsg fail"); 614094332d3Sopenharmony_ci return ret; 615094332d3Sopenharmony_ci } 616094332d3Sopenharmony_ci } 617094332d3Sopenharmony_ci return HDF_SUCCESS; 618094332d3Sopenharmony_ci} 619094332d3Sopenharmony_ci 620094332d3Sopenharmony_cistatic int32_t SerialGetBaudrate(struct SerialDevice *port, struct HdfSBuf *reply) 621094332d3Sopenharmony_ci{ 622094332d3Sopenharmony_ci uint32_t baudRate = LE32_TO_CPU(port->lineCoding.dwDTERate); 623094332d3Sopenharmony_ci 624094332d3Sopenharmony_ci if (!HdfSbufWriteUint32(reply, baudRate)) { 625094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d sbuf write buffer failed", __func__, __LINE__); 626094332d3Sopenharmony_ci return HDF_ERR_IO; 627094332d3Sopenharmony_ci } 628094332d3Sopenharmony_ci 629094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d baudRate=%{public}d", __func__, __LINE__, baudRate); 630094332d3Sopenharmony_ci 631094332d3Sopenharmony_ci return HDF_SUCCESS; 632094332d3Sopenharmony_ci} 633094332d3Sopenharmony_ci 634094332d3Sopenharmony_cistatic int32_t SerialOpen(struct SerialDevice *port, struct HdfSBuf *data) 635094332d3Sopenharmony_ci{ 636094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 637094332d3Sopenharmony_ci int32_t ret; 638094332d3Sopenharmony_ci int32_t cmdType = HOST_ACM_ASYNC_READ; 639094332d3Sopenharmony_ci 640094332d3Sopenharmony_ci if ((port == NULL) || (data == NULL)) { 641094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid parma", __func__); 642094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 643094332d3Sopenharmony_ci } 644094332d3Sopenharmony_ci 645094332d3Sopenharmony_ci acm = port->acm; 646094332d3Sopenharmony_ci if (acm == NULL) { 647094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid parma", __func__); 648094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 649094332d3Sopenharmony_ci } 650094332d3Sopenharmony_ci 651094332d3Sopenharmony_ci if (!HdfSbufReadInt32(data, &cmdType)) { 652094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d sbuf read cmdType failed", __func__, __LINE__); 653094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 654094332d3Sopenharmony_ci } 655094332d3Sopenharmony_ci 656094332d3Sopenharmony_ci ret = UsbSerialInit(acm); 657094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 658094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbSerialInit failed", __func__, __LINE__); 659094332d3Sopenharmony_ci return HDF_FAILURE; 660094332d3Sopenharmony_ci } 661094332d3Sopenharmony_ci 662094332d3Sopenharmony_ci if (cmdType != HOST_ACM_ASYNC_READ) { 663094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d asyncRead success", __func__, __LINE__); 664094332d3Sopenharmony_ci return HDF_SUCCESS; 665094332d3Sopenharmony_ci } 666094332d3Sopenharmony_ci 667094332d3Sopenharmony_ci ret = UsbSerialAllocFifo(&port->readFifo, READ_BUF_SIZE); 668094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 669094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbSerialAllocFifo failed", __func__); 670094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 671094332d3Sopenharmony_ci } 672094332d3Sopenharmony_ci for (int32_t i = 0; i < ACM_NR; i++) { 673094332d3Sopenharmony_ci ret = UsbRawSubmitRequest(acm->readReq[i]); 674094332d3Sopenharmony_ci if (ret) { 675094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbRawSubmitRequest failed, ret=%{public}d ", __func__, ret); 676094332d3Sopenharmony_ci goto ERR; 677094332d3Sopenharmony_ci } 678094332d3Sopenharmony_ci } 679094332d3Sopenharmony_ci return HDF_SUCCESS; 680094332d3Sopenharmony_ci 681094332d3Sopenharmony_ciERR: 682094332d3Sopenharmony_ci UsbSerialFreeFifo(&port->readFifo); 683094332d3Sopenharmony_ci return ret; 684094332d3Sopenharmony_ci} 685094332d3Sopenharmony_ci 686094332d3Sopenharmony_cistatic int32_t SerialClose(struct SerialDevice *port, struct HdfSBuf *data) 687094332d3Sopenharmony_ci{ 688094332d3Sopenharmony_ci int32_t cmdType = HOST_ACM_SYNC_READ; 689094332d3Sopenharmony_ci 690094332d3Sopenharmony_ci if ((port == NULL) || (data == NULL)) { 691094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d invalid parma", __func__, __LINE__); 692094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 693094332d3Sopenharmony_ci } 694094332d3Sopenharmony_ci 695094332d3Sopenharmony_ci if (port->acm == NULL) { 696094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d acm is NULL invalid parma", __func__, __LINE__); 697094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 698094332d3Sopenharmony_ci } 699094332d3Sopenharmony_ci 700094332d3Sopenharmony_ci if (!HdfSbufReadInt32(data, &cmdType)) { 701094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d sbuf read cmdType failed", __func__, __LINE__); 702094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 703094332d3Sopenharmony_ci } 704094332d3Sopenharmony_ci 705094332d3Sopenharmony_ci if ((cmdType == HOST_ACM_SYNC_READ) || (cmdType == HOST_ACM_SYNC_WRITE) || (cmdType == HOST_ACM_ASYNC_WRITE)) { 706094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d cmdType=%{public}d success", __func__, __LINE__, cmdType); 707094332d3Sopenharmony_ci return HDF_SUCCESS; 708094332d3Sopenharmony_ci } 709094332d3Sopenharmony_ci 710094332d3Sopenharmony_ci OsalMutexLock(&port->acm->readLock); 711094332d3Sopenharmony_ci UsbSerialFreeFifo(&port->readFifo); 712094332d3Sopenharmony_ci OsalMutexUnlock(&port->acm->readLock); 713094332d3Sopenharmony_ci 714094332d3Sopenharmony_ci UsbSerialRelease(port->acm); 715094332d3Sopenharmony_ci 716094332d3Sopenharmony_ci return HDF_SUCCESS; 717094332d3Sopenharmony_ci} 718094332d3Sopenharmony_ci 719094332d3Sopenharmony_cistatic int32_t SerialWrite(struct SerialDevice *port, struct HdfSBuf *data) 720094332d3Sopenharmony_ci{ 721094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 722094332d3Sopenharmony_ci struct AcmWb *wb = NULL; 723094332d3Sopenharmony_ci const char *tmp = NULL; 724094332d3Sopenharmony_ci int32_t size; 725094332d3Sopenharmony_ci int32_t wbn; 726094332d3Sopenharmony_ci 727094332d3Sopenharmony_ci if (port == NULL) { 728094332d3Sopenharmony_ci HDF_LOGE("%{public}s: port is null", __func__); 729094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 730094332d3Sopenharmony_ci } 731094332d3Sopenharmony_ci acm = port->acm; 732094332d3Sopenharmony_ci if (acm == NULL) { 733094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm is null", __func__); 734094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 735094332d3Sopenharmony_ci } 736094332d3Sopenharmony_ci if (AcmWbIsAvail(acm)) { 737094332d3Sopenharmony_ci wbn = AcmWbAlloc(acm); 738094332d3Sopenharmony_ci } else { 739094332d3Sopenharmony_ci HDF_LOGE("%{public}s: no write buf", __func__); 740094332d3Sopenharmony_ci return HDF_SUCCESS; 741094332d3Sopenharmony_ci } 742094332d3Sopenharmony_ci if (wbn < 0 || wbn >= ACM_NW) { 743094332d3Sopenharmony_ci HDF_LOGE("%{public}s: AcmWbAlloc failed", __func__); 744094332d3Sopenharmony_ci return HDF_FAILURE; 745094332d3Sopenharmony_ci } 746094332d3Sopenharmony_ci wb = &acm->wb[wbn]; 747094332d3Sopenharmony_ci if (wb == NULL) { 748094332d3Sopenharmony_ci return HDF_FAILURE; 749094332d3Sopenharmony_ci } 750094332d3Sopenharmony_ci tmp = HdfSbufReadString(data); 751094332d3Sopenharmony_ci if (tmp == NULL) { 752094332d3Sopenharmony_ci HDF_LOGE("%{public}s: sbuf read buffer failed", __func__); 753094332d3Sopenharmony_ci return HDF_ERR_IO; 754094332d3Sopenharmony_ci } 755094332d3Sopenharmony_ci size = (int32_t)strlen(tmp) + 1; 756094332d3Sopenharmony_ci if (acm->dataOutEp != NULL) { 757094332d3Sopenharmony_ci size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size; 758094332d3Sopenharmony_ci if (memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size) != EOK) { 759094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s fail", __func__); 760094332d3Sopenharmony_ci } 761094332d3Sopenharmony_ci } 762094332d3Sopenharmony_ci wb->len = (uint32_t)size; 763094332d3Sopenharmony_ci 764094332d3Sopenharmony_ci if (AcmStartWb(acm, wb) != HDF_SUCCESS) { 765094332d3Sopenharmony_ci HDF_LOGE("%{public}s: AcmStartWb failed", __func__); 766094332d3Sopenharmony_ci return HDF_FAILURE; 767094332d3Sopenharmony_ci } 768094332d3Sopenharmony_ci return size; 769094332d3Sopenharmony_ci} 770094332d3Sopenharmony_ci 771094332d3Sopenharmony_cistatic int32_t AcmStartWbSync(struct AcmDevice *acm, struct AcmWb *wb) 772094332d3Sopenharmony_ci{ 773094332d3Sopenharmony_ci int32_t ret; 774094332d3Sopenharmony_ci int32_t size; 775094332d3Sopenharmony_ci struct UsbRequestData requestData; 776094332d3Sopenharmony_ci 777094332d3Sopenharmony_ci requestData.endPoint = acm->dataOutEp->addr; 778094332d3Sopenharmony_ci requestData.data = wb->buf; 779094332d3Sopenharmony_ci requestData.length = wb->len; 780094332d3Sopenharmony_ci requestData.requested = &size; 781094332d3Sopenharmony_ci requestData.timeout = USB_CTRL_SET_TIMEOUT; 782094332d3Sopenharmony_ci 783094332d3Sopenharmony_ci acm->writeReq = wb->request; 784094332d3Sopenharmony_ci ret = UsbRawSendBulkRequest(wb->request, acm->devHandle, &requestData); 785094332d3Sopenharmony_ci if (ret) { 786094332d3Sopenharmony_ci HDF_LOGE("UsbRawSendBulkRequest failed, ret=%{public}d", ret); 787094332d3Sopenharmony_ci } 788094332d3Sopenharmony_ci 789094332d3Sopenharmony_ci wb->use = 0; 790094332d3Sopenharmony_ci 791094332d3Sopenharmony_ci return ret; 792094332d3Sopenharmony_ci} 793094332d3Sopenharmony_ci 794094332d3Sopenharmony_cistatic int32_t SerialWriteSync(const struct SerialDevice *port, const struct HdfSBuf *data) 795094332d3Sopenharmony_ci{ 796094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 797094332d3Sopenharmony_ci struct AcmWb *wb = NULL; 798094332d3Sopenharmony_ci const char *tmp = NULL; 799094332d3Sopenharmony_ci int32_t size; 800094332d3Sopenharmony_ci int32_t wbn; 801094332d3Sopenharmony_ci 802094332d3Sopenharmony_ci if (port == NULL) { 803094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid parma", __func__); 804094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 805094332d3Sopenharmony_ci } 806094332d3Sopenharmony_ci acm = port->acm; 807094332d3Sopenharmony_ci if (acm == NULL) { 808094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid parma", __func__); 809094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 810094332d3Sopenharmony_ci } 811094332d3Sopenharmony_ci 812094332d3Sopenharmony_ci if (AcmWbIsAvail(acm)) { 813094332d3Sopenharmony_ci wbn = AcmWbAlloc(acm); 814094332d3Sopenharmony_ci } else { 815094332d3Sopenharmony_ci HDF_LOGE("%{public}s: no write buf", __func__); 816094332d3Sopenharmony_ci return HDF_SUCCESS; 817094332d3Sopenharmony_ci } 818094332d3Sopenharmony_ci 819094332d3Sopenharmony_ci if (wbn >= ACM_NW || wbn < 0) { 820094332d3Sopenharmony_ci wbn = 0; 821094332d3Sopenharmony_ci } 822094332d3Sopenharmony_ci wb = &acm->wb[wbn]; 823094332d3Sopenharmony_ci if ((wb == NULL) || (wb->buf == NULL)) { 824094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 825094332d3Sopenharmony_ci } 826094332d3Sopenharmony_ci tmp = HdfSbufReadString((struct HdfSBuf *)data); 827094332d3Sopenharmony_ci if (tmp == NULL) { 828094332d3Sopenharmony_ci HDF_LOGE("%{public}s: sbuf read buffer failed", __func__); 829094332d3Sopenharmony_ci return HDF_ERR_IO; 830094332d3Sopenharmony_ci } 831094332d3Sopenharmony_ci size = (int32_t)strlen(tmp) + 1; 832094332d3Sopenharmony_ci if (acm->dataOutEp == NULL) { 833094332d3Sopenharmony_ci return HDF_ERR_IO; 834094332d3Sopenharmony_ci } 835094332d3Sopenharmony_ci size = (size > acm->dataOutEp->maxPacketSize) ? acm->dataOutEp->maxPacketSize : size; 836094332d3Sopenharmony_ci if (memcpy_s(wb->buf, acm->dataOutEp->maxPacketSize, tmp, size) != EOK) { 837094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed", __func__); 838094332d3Sopenharmony_ci } 839094332d3Sopenharmony_ci wb->len = (uint32_t)size; 840094332d3Sopenharmony_ci 841094332d3Sopenharmony_ci if (AcmStartWbSync(acm, wb) != HDF_SUCCESS) { 842094332d3Sopenharmony_ci HDF_LOGE("%{public}s: AcmStartWbSync failed", __func__); 843094332d3Sopenharmony_ci return HDF_FAILURE; 844094332d3Sopenharmony_ci } 845094332d3Sopenharmony_ci 846094332d3Sopenharmony_ci return size; 847094332d3Sopenharmony_ci} 848094332d3Sopenharmony_ci 849094332d3Sopenharmony_cistatic int32_t UsbSerialReadSync(const struct SerialDevice *port, const struct HdfSBuf *reply) 850094332d3Sopenharmony_ci{ 851094332d3Sopenharmony_ci int32_t ret; 852094332d3Sopenharmony_ci int32_t size; 853094332d3Sopenharmony_ci struct AcmDevice *acm = port->acm; 854094332d3Sopenharmony_ci uint8_t *data = NULL; 855094332d3Sopenharmony_ci struct UsbRequestData requestData; 856094332d3Sopenharmony_ci 857094332d3Sopenharmony_ci if (g_syncRequest == NULL) { 858094332d3Sopenharmony_ci g_syncRequest = UsbRawAllocRequest(acm->devHandle, 0, acm->dataInEp->maxPacketSize); 859094332d3Sopenharmony_ci if (g_syncRequest == NULL) { 860094332d3Sopenharmony_ci HDF_LOGE("UsbRawAllocRequest g_syncRequest failed"); 861094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 862094332d3Sopenharmony_ci } 863094332d3Sopenharmony_ci } 864094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d g_syncRequest ", __func__, __LINE__); 865094332d3Sopenharmony_ci 866094332d3Sopenharmony_ci requestData.endPoint = acm->dataInEp->addr; 867094332d3Sopenharmony_ci requestData.data = g_syncRequest->buffer; 868094332d3Sopenharmony_ci requestData.length = acm->dataInEp->maxPacketSize; 869094332d3Sopenharmony_ci requestData.requested = &size; 870094332d3Sopenharmony_ci requestData.timeout = USB_CTRL_SET_TIMEOUT; 871094332d3Sopenharmony_ci 872094332d3Sopenharmony_ci ret = UsbRawSendBulkRequest(g_syncRequest, acm->devHandle, &requestData); 873094332d3Sopenharmony_ci if (ret) { 874094332d3Sopenharmony_ci HDF_LOGE("UsbRawSendBulkRequest failed, ret=%{public}d", ret); 875094332d3Sopenharmony_ci return ret; 876094332d3Sopenharmony_ci } 877094332d3Sopenharmony_ci 878094332d3Sopenharmony_ci uint32_t count = (uint32_t)g_syncRequest->actualLength; 879094332d3Sopenharmony_ci data = (uint8_t *)OsalMemCalloc(count + 1); 880094332d3Sopenharmony_ci if (data == NULL) { 881094332d3Sopenharmony_ci HDF_LOGE("%{public}s: OsalMemCalloc error", __func__); 882094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 883094332d3Sopenharmony_ci } 884094332d3Sopenharmony_ci HDF_LOGD("buffer actualLength:%{public}u", count); 885094332d3Sopenharmony_ci 886094332d3Sopenharmony_ci do { 887094332d3Sopenharmony_ci ret = memcpy_s(data, g_syncRequest->actualLength, g_syncRequest->buffer, count); 888094332d3Sopenharmony_ci if (ret != EOK) { 889094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s error", __func__); 890094332d3Sopenharmony_ci break; 891094332d3Sopenharmony_ci } 892094332d3Sopenharmony_ci 893094332d3Sopenharmony_ci if (!HdfSbufWriteString((struct HdfSBuf *)reply, (char *)data)) { 894094332d3Sopenharmony_ci HDF_LOGE("%{public}s: sbuf write buffer failed", __func__); 895094332d3Sopenharmony_ci ret = HDF_ERR_IO; 896094332d3Sopenharmony_ci break; 897094332d3Sopenharmony_ci } 898094332d3Sopenharmony_ci } while (0); 899094332d3Sopenharmony_ci 900094332d3Sopenharmony_ci OsalMemFree(data); 901094332d3Sopenharmony_ci data = NULL; 902094332d3Sopenharmony_ci return ret; 903094332d3Sopenharmony_ci} 904094332d3Sopenharmony_ci 905094332d3Sopenharmony_cistatic int32_t SerialAddOrRemoveInterface(int32_t cmd, const struct SerialDevice *port, const struct HdfSBuf *data) 906094332d3Sopenharmony_ci{ 907094332d3Sopenharmony_ci (void)cmd; 908094332d3Sopenharmony_ci (void)port; 909094332d3Sopenharmony_ci (void)data; 910094332d3Sopenharmony_ci 911094332d3Sopenharmony_ci return HDF_SUCCESS; 912094332d3Sopenharmony_ci} 913094332d3Sopenharmony_ci 914094332d3Sopenharmony_cistatic int32_t UsbSerialDeviceDispatch( 915094332d3Sopenharmony_ci struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) 916094332d3Sopenharmony_ci{ 917094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 918094332d3Sopenharmony_ci struct SerialDevice *port = NULL; 919094332d3Sopenharmony_ci 920094332d3Sopenharmony_ci if ((client == NULL) || (client->device == NULL)) { 921094332d3Sopenharmony_ci HDF_LOGE("%{public}s: client or client->device is NULL", __func__); 922094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 923094332d3Sopenharmony_ci } 924094332d3Sopenharmony_ci 925094332d3Sopenharmony_ci if (client->device->service == NULL) { 926094332d3Sopenharmony_ci HDF_LOGE("%{public}s: client->device->service is NULL", __func__); 927094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 928094332d3Sopenharmony_ci } 929094332d3Sopenharmony_ci 930094332d3Sopenharmony_ci if (g_rawAcmReleaseFlag == true) { 931094332d3Sopenharmony_ci HDF_LOGE("%{public}s: g_rawAcmReleaseFlag is true", __func__); 932094332d3Sopenharmony_ci return HDF_FAILURE; 933094332d3Sopenharmony_ci } 934094332d3Sopenharmony_ci 935094332d3Sopenharmony_ci acm = (struct AcmDevice *)client->device->service; 936094332d3Sopenharmony_ci port = acm->port; 937094332d3Sopenharmony_ci if (port == NULL) { 938094332d3Sopenharmony_ci return HDF_FAILURE; 939094332d3Sopenharmony_ci } 940094332d3Sopenharmony_ci switch (cmd) { 941094332d3Sopenharmony_ci case CMD_OPEN_PARM: 942094332d3Sopenharmony_ci return SerialOpen(port, data); 943094332d3Sopenharmony_ci case CMD_CLOSE_PARM: 944094332d3Sopenharmony_ci return SerialClose(port, data); 945094332d3Sopenharmony_ci case CMD_WRITE_PARM: 946094332d3Sopenharmony_ci return SerialWrite(port, data); 947094332d3Sopenharmony_ci case CMD_READ_PARM: 948094332d3Sopenharmony_ci return UsbSerialRead(port, reply); 949094332d3Sopenharmony_ci case CMD_GET_BAUDRATE: 950094332d3Sopenharmony_ci return SerialGetBaudrate(port, reply); 951094332d3Sopenharmony_ci case CMD_SET_BAUDRATE: 952094332d3Sopenharmony_ci return SerialSetBaudrate(port, data); 953094332d3Sopenharmony_ci case CMD_WRITE_DATA_SYNC: 954094332d3Sopenharmony_ci return SerialWriteSync(port, data); 955094332d3Sopenharmony_ci case CMD_READ_DATA_SYNC: 956094332d3Sopenharmony_ci return UsbSerialReadSync(port, reply); 957094332d3Sopenharmony_ci case CMD_ADD_INTERFACE: 958094332d3Sopenharmony_ci case CMD_REMOVE_INTERFACE: 959094332d3Sopenharmony_ci return SerialAddOrRemoveInterface(cmd, port, data); 960094332d3Sopenharmony_ci default: 961094332d3Sopenharmony_ci return HDF_ERR_NOT_SUPPORT; 962094332d3Sopenharmony_ci } 963094332d3Sopenharmony_ci} 964094332d3Sopenharmony_ci 965094332d3Sopenharmony_ci/* HdfDriverEntry implementations */ 966094332d3Sopenharmony_cistatic int32_t UsbSerialDriverBind(struct HdfDeviceObject *device) 967094332d3Sopenharmony_ci{ 968094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 969094332d3Sopenharmony_ci struct UsbPnpNotifyServiceInfo *info = NULL; 970094332d3Sopenharmony_ci errno_t err; 971094332d3Sopenharmony_ci 972094332d3Sopenharmony_ci if (device == NULL) { 973094332d3Sopenharmony_ci HDF_LOGE("%{public}s: device is null", __func__); 974094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 975094332d3Sopenharmony_ci } 976094332d3Sopenharmony_ci 977094332d3Sopenharmony_ci acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm)); 978094332d3Sopenharmony_ci if (acm == NULL) { 979094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Alloc usb serial device failed", __func__); 980094332d3Sopenharmony_ci return HDF_FAILURE; 981094332d3Sopenharmony_ci } 982094332d3Sopenharmony_ci if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) { 983094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalMutexInit fail", __func__, __LINE__); 984094332d3Sopenharmony_ci goto ERROR; 985094332d3Sopenharmony_ci } 986094332d3Sopenharmony_ci 987094332d3Sopenharmony_ci info = (struct UsbPnpNotifyServiceInfo *)device->priv; 988094332d3Sopenharmony_ci if (info != NULL) { 989094332d3Sopenharmony_ci acm->busNum = (uint8_t)info->busNum; 990094332d3Sopenharmony_ci acm->devAddr = (uint8_t)info->devNum; 991094332d3Sopenharmony_ci acm->interfaceCnt = info->interfaceLength; 992094332d3Sopenharmony_ci err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber, 993094332d3Sopenharmony_ci info->interfaceLength); 994094332d3Sopenharmony_ci if (err != EOK) { 995094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d memcpy_s failed err=%{public}d", __func__, __LINE__, err); 996094332d3Sopenharmony_ci goto LOCK_ERROR; 997094332d3Sopenharmony_ci } 998094332d3Sopenharmony_ci } else { 999094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d info is NULL!", __func__, __LINE__); 1000094332d3Sopenharmony_ci goto LOCK_ERROR; 1001094332d3Sopenharmony_ci } 1002094332d3Sopenharmony_ci 1003094332d3Sopenharmony_ci device->service = &(acm->service); 1004094332d3Sopenharmony_ci device->service->Dispatch = UsbSerialDeviceDispatch; 1005094332d3Sopenharmony_ci acm->device = device; 1006094332d3Sopenharmony_ci HDF_LOGD("UsbSerialDriverBind=========================OK"); 1007094332d3Sopenharmony_ci return HDF_SUCCESS; 1008094332d3Sopenharmony_ci 1009094332d3Sopenharmony_ciLOCK_ERROR: 1010094332d3Sopenharmony_ci if (OsalMutexDestroy(&acm->lock)) { 1011094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d OsalMutexDestroy fail", __func__, __LINE__); 1012094332d3Sopenharmony_ci } 1013094332d3Sopenharmony_ciERROR: 1014094332d3Sopenharmony_ci OsalMemFree(acm); 1015094332d3Sopenharmony_ci acm = NULL; 1016094332d3Sopenharmony_ci return HDF_FAILURE; 1017094332d3Sopenharmony_ci} 1018094332d3Sopenharmony_ci 1019094332d3Sopenharmony_cistatic void AcmProcessNotification(const struct AcmDevice *acm, const unsigned char *buf) 1020094332d3Sopenharmony_ci{ 1021094332d3Sopenharmony_ci (void)acm; 1022094332d3Sopenharmony_ci struct UsbCdcNotification *dr = (struct UsbCdcNotification *)buf; 1023094332d3Sopenharmony_ci 1024094332d3Sopenharmony_ci switch (dr->bNotificationType) { 1025094332d3Sopenharmony_ci case USB_DDK_CDC_NOTIFY_NETWORK_CONNECTION: 1026094332d3Sopenharmony_ci HDF_LOGE("%{public}s - network connection: %{public}d", __func__, dr->wValue); 1027094332d3Sopenharmony_ci break; 1028094332d3Sopenharmony_ci case USB_DDK_CDC_NOTIFY_SERIAL_STATE: 1029094332d3Sopenharmony_ci HDF_LOGE("the serial State change"); 1030094332d3Sopenharmony_ci break; 1031094332d3Sopenharmony_ci default: 1032094332d3Sopenharmony_ci HDF_LOGE("%{public}s-%{public}d received: index %{public}d len %{public}d", 1033094332d3Sopenharmony_ci __func__, dr->bNotificationType, dr->wIndex, dr->wLength); 1034094332d3Sopenharmony_ci } 1035094332d3Sopenharmony_ci} 1036094332d3Sopenharmony_ci 1037094332d3Sopenharmony_cistatic int32_t AcmNotificationBufferProcess( 1038094332d3Sopenharmony_ci const struct UsbRawRequest *req, struct AcmDevice *acm, unsigned int currentSize, unsigned int expectedSize) 1039094332d3Sopenharmony_ci{ 1040094332d3Sopenharmony_ci if (acm->nbSize < expectedSize) { 1041094332d3Sopenharmony_ci if (acm->nbSize) { 1042094332d3Sopenharmony_ci OsalMemFree(acm->notificationBuffer); 1043094332d3Sopenharmony_ci acm->nbSize = 0; 1044094332d3Sopenharmony_ci } 1045094332d3Sopenharmony_ci unsigned int allocSize = expectedSize; 1046094332d3Sopenharmony_ci acm->notificationBuffer = (uint8_t *)OsalMemCalloc(allocSize); 1047094332d3Sopenharmony_ci if (!acm->notificationBuffer) { 1048094332d3Sopenharmony_ci return HDF_FAILURE; 1049094332d3Sopenharmony_ci } 1050094332d3Sopenharmony_ci acm->nbSize = allocSize; 1051094332d3Sopenharmony_ci } 1052094332d3Sopenharmony_ci unsigned int copySize = MIN(currentSize, expectedSize - acm->nbIndex); 1053094332d3Sopenharmony_ci int32_t ret = memcpy_s(&acm->notificationBuffer[acm->nbIndex], acm->nbSize - acm->nbIndex, req->buffer, copySize); 1054094332d3Sopenharmony_ci if (ret != EOK) { 1055094332d3Sopenharmony_ci HDF_LOGE("memcpy_s fail ret=%{public}d", ret); 1056094332d3Sopenharmony_ci } 1057094332d3Sopenharmony_ci acm->nbIndex += copySize; 1058094332d3Sopenharmony_ci 1059094332d3Sopenharmony_ci return HDF_SUCCESS; 1060094332d3Sopenharmony_ci} 1061094332d3Sopenharmony_ci 1062094332d3Sopenharmony_cistatic void AcmNotifyReqCallback(const void *requestArg) 1063094332d3Sopenharmony_ci{ 1064094332d3Sopenharmony_ci struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg; 1065094332d3Sopenharmony_ci if (req == NULL) { 1066094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d req is NULL!", __func__, __LINE__); 1067094332d3Sopenharmony_ci return; 1068094332d3Sopenharmony_ci } 1069094332d3Sopenharmony_ci struct AcmDevice *acm = (struct AcmDevice *)req->userData; 1070094332d3Sopenharmony_ci if (acm == NULL) { 1071094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d userData(acm) is NULL!", __func__, __LINE__); 1072094332d3Sopenharmony_ci return; 1073094332d3Sopenharmony_ci } 1074094332d3Sopenharmony_ci struct UsbCdcNotification *dr = (struct UsbCdcNotification *)req->buffer; 1075094332d3Sopenharmony_ci if (dr == NULL) { 1076094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d req->buffer(dr) is NULL!", __func__, __LINE__); 1077094332d3Sopenharmony_ci return; 1078094332d3Sopenharmony_ci } 1079094332d3Sopenharmony_ci unsigned int currentSize = (unsigned int)req->actualLength; 1080094332d3Sopenharmony_ci unsigned int expectedSize = 0; 1081094332d3Sopenharmony_ci 1082094332d3Sopenharmony_ci HDF_LOGD("Irqstatus:%{public}d,actualLength:%{public}u", req->status, currentSize); 1083094332d3Sopenharmony_ci 1084094332d3Sopenharmony_ci if (req->status != USB_REQUEST_COMPLETED) { 1085094332d3Sopenharmony_ci goto EXIT; 1086094332d3Sopenharmony_ci } 1087094332d3Sopenharmony_ci 1088094332d3Sopenharmony_ci if (acm->nbIndex) { 1089094332d3Sopenharmony_ci dr = (struct UsbCdcNotification *)acm->notificationBuffer; 1090094332d3Sopenharmony_ci } 1091094332d3Sopenharmony_ci if (dr != NULL) { 1092094332d3Sopenharmony_ci expectedSize = sizeof(struct UsbCdcNotification) + LE16_TO_CPU(dr->wLength); 1093094332d3Sopenharmony_ci } else { 1094094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d dr is NULL!", __func__, __LINE__); 1095094332d3Sopenharmony_ci return; 1096094332d3Sopenharmony_ci } 1097094332d3Sopenharmony_ci if (currentSize < expectedSize) { 1098094332d3Sopenharmony_ci if (AcmNotificationBufferProcess(req, acm, currentSize, expectedSize) != HDF_SUCCESS) { 1099094332d3Sopenharmony_ci goto EXIT; 1100094332d3Sopenharmony_ci } 1101094332d3Sopenharmony_ci currentSize = acm->nbIndex; 1102094332d3Sopenharmony_ci } 1103094332d3Sopenharmony_ci if (currentSize >= expectedSize) { 1104094332d3Sopenharmony_ci AcmProcessNotification(acm, (unsigned char *)dr); 1105094332d3Sopenharmony_ci acm->nbIndex = 0; 1106094332d3Sopenharmony_ci } 1107094332d3Sopenharmony_ci 1108094332d3Sopenharmony_ci if (UsbRawSubmitRequest(req) != HDF_SUCCESS) { 1109094332d3Sopenharmony_ci HDF_LOGE("%{public}s - UsbRawSubmitRequest failed", __func__); 1110094332d3Sopenharmony_ci } 1111094332d3Sopenharmony_ci 1112094332d3Sopenharmony_ciEXIT: 1113094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d exit", __func__, __LINE__); 1114094332d3Sopenharmony_ci} 1115094332d3Sopenharmony_ci 1116094332d3Sopenharmony_cistatic void AcmReadBulkCallback(const void *requestArg) 1117094332d3Sopenharmony_ci{ 1118094332d3Sopenharmony_ci struct UsbRawRequest *req = (struct UsbRawRequest *)requestArg; 1119094332d3Sopenharmony_ci if (req == NULL) { 1120094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d req is NULL!", __func__, __LINE__); 1121094332d3Sopenharmony_ci return; 1122094332d3Sopenharmony_ci } 1123094332d3Sopenharmony_ci struct AcmDevice *acm = (struct AcmDevice *)req->userData; 1124094332d3Sopenharmony_ci if (acm == NULL || acm->port == NULL) { 1125094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d request userData is NULL!", __func__, __LINE__); 1126094332d3Sopenharmony_ci return; 1127094332d3Sopenharmony_ci } 1128094332d3Sopenharmony_ci size_t size = (size_t)req->actualLength; 1129094332d3Sopenharmony_ci 1130094332d3Sopenharmony_ci if (req->status != USB_REQUEST_COMPLETED) { 1131094332d3Sopenharmony_ci HDF_LOGW("%{public}s: the request is failed, status=%{public}d", __func__, req->status); 1132094332d3Sopenharmony_ci return; 1133094332d3Sopenharmony_ci } 1134094332d3Sopenharmony_ci HDF_LOGD("Bulk status: %{public}d+size:%{public}zu", req->status, size); 1135094332d3Sopenharmony_ci if (size == 0) { 1136094332d3Sopenharmony_ci uint8_t *data = req->buffer; 1137094332d3Sopenharmony_ci OsalMutexLock(&acm->readLock); 1138094332d3Sopenharmony_ci if (DataFifoIsFull(&acm->port->readFifo)) { 1139094332d3Sopenharmony_ci DataFifoSkip(&acm->port->readFifo, size); 1140094332d3Sopenharmony_ci } 1141094332d3Sopenharmony_ci uint32_t count = DataFifoWrite(&acm->port->readFifo, data, size); 1142094332d3Sopenharmony_ci if (count != size) { 1143094332d3Sopenharmony_ci HDF_LOGW("%{public}s: write %{public}u less than expected %{public}zu", __func__, count, size); 1144094332d3Sopenharmony_ci } 1145094332d3Sopenharmony_ci OsalMutexUnlock(&acm->readLock); 1146094332d3Sopenharmony_ci } 1147094332d3Sopenharmony_ci 1148094332d3Sopenharmony_ci if (UsbRawSubmitRequest(req) != HDF_SUCCESS) { 1149094332d3Sopenharmony_ci HDF_LOGE("%{public}s UsbRawSubmitRequest failed", __func__); 1150094332d3Sopenharmony_ci } 1151094332d3Sopenharmony_ci} 1152094332d3Sopenharmony_ci 1153094332d3Sopenharmony_cistatic int32_t UsbAllocReadRequests(struct AcmDevice *acm) 1154094332d3Sopenharmony_ci{ 1155094332d3Sopenharmony_ci struct UsbRawFillRequestData reqData; 1156094332d3Sopenharmony_ci uint32_t size = acm->dataInEp->maxPacketSize; 1157094332d3Sopenharmony_ci 1158094332d3Sopenharmony_ci for (int32_t i = 0; i < ACM_NR; i++) { 1159094332d3Sopenharmony_ci acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size); 1160094332d3Sopenharmony_ci if (!acm->readReq[i]) { 1161094332d3Sopenharmony_ci HDF_LOGE("readReq request failed"); 1162094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 1163094332d3Sopenharmony_ci } 1164094332d3Sopenharmony_ci 1165094332d3Sopenharmony_ci reqData.endPoint = acm->dataInEp->addr; 1166094332d3Sopenharmony_ci reqData.numIsoPackets = 0; 1167094332d3Sopenharmony_ci reqData.callback = AcmReadBulkCallback; 1168094332d3Sopenharmony_ci reqData.userData = (void *)acm; 1169094332d3Sopenharmony_ci reqData.timeout = USB_CTRL_SET_TIMEOUT; 1170094332d3Sopenharmony_ci reqData.length = size; 1171094332d3Sopenharmony_ci 1172094332d3Sopenharmony_ci int32_t ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData); 1173094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 1174094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FillBulkRequest failed, ret=%{public}d", __func__, ret); 1175094332d3Sopenharmony_ci return HDF_FAILURE; 1176094332d3Sopenharmony_ci } 1177094332d3Sopenharmony_ci } 1178094332d3Sopenharmony_ci 1179094332d3Sopenharmony_ci return HDF_SUCCESS; 1180094332d3Sopenharmony_ci} 1181094332d3Sopenharmony_ci 1182094332d3Sopenharmony_cistatic void UsbFreeReadRequests(struct AcmDevice *acm) 1183094332d3Sopenharmony_ci{ 1184094332d3Sopenharmony_ci int32_t i; 1185094332d3Sopenharmony_ci 1186094332d3Sopenharmony_ci if (acm == NULL) { 1187094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm is NULL", __func__); 1188094332d3Sopenharmony_ci return; 1189094332d3Sopenharmony_ci } 1190094332d3Sopenharmony_ci 1191094332d3Sopenharmony_ci for (i = 0; i < ACM_NR; i++) { 1192094332d3Sopenharmony_ci if (acm->readReq[i]) { 1193094332d3Sopenharmony_ci UsbRawFreeRequest(acm->readReq[i]); 1194094332d3Sopenharmony_ci acm->readReq[i] = NULL; 1195094332d3Sopenharmony_ci } 1196094332d3Sopenharmony_ci } 1197094332d3Sopenharmony_ci} 1198094332d3Sopenharmony_ci 1199094332d3Sopenharmony_cistatic int32_t UsbAllocNotifyRequest(struct AcmDevice *acm) 1200094332d3Sopenharmony_ci{ 1201094332d3Sopenharmony_ci struct UsbRawFillRequestData fillRequestData; 1202094332d3Sopenharmony_ci if ((acm == NULL) || (acm->notifyEp == NULL)) { 1203094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm or notifyEp is NULL", __func__); 1204094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 1205094332d3Sopenharmony_ci } 1206094332d3Sopenharmony_ci uint32_t size = acm->notifyEp->maxPacketSize; 1207094332d3Sopenharmony_ci int32_t ret; 1208094332d3Sopenharmony_ci 1209094332d3Sopenharmony_ci acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size); 1210094332d3Sopenharmony_ci if (!acm->notifyReq) { 1211094332d3Sopenharmony_ci HDF_LOGE("notifyReq request fail"); 1212094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 1213094332d3Sopenharmony_ci } 1214094332d3Sopenharmony_ci 1215094332d3Sopenharmony_ci fillRequestData.endPoint = acm->notifyEp->addr; 1216094332d3Sopenharmony_ci fillRequestData.length = size; 1217094332d3Sopenharmony_ci fillRequestData.numIsoPackets = 0; 1218094332d3Sopenharmony_ci fillRequestData.callback = AcmNotifyReqCallback; 1219094332d3Sopenharmony_ci fillRequestData.userData = (void *)acm; 1220094332d3Sopenharmony_ci fillRequestData.timeout = USB_CTRL_SET_TIMEOUT; 1221094332d3Sopenharmony_ci 1222094332d3Sopenharmony_ci ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData); 1223094332d3Sopenharmony_ci if (ret) { 1224094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FillInterruptRequest failed, ret=%{public}d", __func__, ret); 1225094332d3Sopenharmony_ci return HDF_FAILURE; 1226094332d3Sopenharmony_ci } 1227094332d3Sopenharmony_ci 1228094332d3Sopenharmony_ci return HDF_SUCCESS; 1229094332d3Sopenharmony_ci} 1230094332d3Sopenharmony_ci 1231094332d3Sopenharmony_cistatic void UsbFreeNotifyReqeust(struct AcmDevice *acm) 1232094332d3Sopenharmony_ci{ 1233094332d3Sopenharmony_ci int32_t ret; 1234094332d3Sopenharmony_ci 1235094332d3Sopenharmony_ci if ((acm == NULL) || (acm->notifyReq == NULL)) { 1236094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm or notifyReq is NULL", __func__); 1237094332d3Sopenharmony_ci return; 1238094332d3Sopenharmony_ci } 1239094332d3Sopenharmony_ci 1240094332d3Sopenharmony_ci ret = UsbRawFreeRequest(acm->notifyReq); 1241094332d3Sopenharmony_ci if (ret == HDF_SUCCESS) { 1242094332d3Sopenharmony_ci acm->notifyReq = NULL; 1243094332d3Sopenharmony_ci } else { 1244094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFreeNotifyReqeust failed, ret=%{public}d", __func__, ret); 1245094332d3Sopenharmony_ci } 1246094332d3Sopenharmony_ci} 1247094332d3Sopenharmony_ci 1248094332d3Sopenharmony_cistatic void UsbAllocRequests(struct AcmDevice *acm, int32_t ret) 1249094332d3Sopenharmony_ci{ 1250094332d3Sopenharmony_ci ret = UsbAllocWriteRequests(acm); 1251094332d3Sopenharmony_ci if (ret < 0) { 1252094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbAllocWriteRequests failed", __func__, __LINE__); 1253094332d3Sopenharmony_ci ret = HDF_FAILURE; 1254094332d3Sopenharmony_ci goto ERR_ALLOC_WRITE_REQS; 1255094332d3Sopenharmony_ci } 1256094332d3Sopenharmony_ci ret = UsbAllocNotifyRequest(acm); 1257094332d3Sopenharmony_ci if (ret) { 1258094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbAllocNotifyRequests failed", __func__, __LINE__); 1259094332d3Sopenharmony_ci goto ERR_ALLOC_NOTIFY_REQ; 1260094332d3Sopenharmony_ci } 1261094332d3Sopenharmony_ci ret = UsbAllocReadRequests(acm); 1262094332d3Sopenharmony_ci if (ret) { 1263094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbAllocReadRequests failed", __func__, __LINE__); 1264094332d3Sopenharmony_ci goto ERR_ALLOC_READ_REQS; 1265094332d3Sopenharmony_ci } 1266094332d3Sopenharmony_ci ret = UsbStartIo(acm); 1267094332d3Sopenharmony_ci if (ret) { 1268094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbAllocReadRequests failed", __func__, __LINE__); 1269094332d3Sopenharmony_ci goto ERR_START_IO; 1270094332d3Sopenharmony_ci } 1271094332d3Sopenharmony_ci 1272094332d3Sopenharmony_ci acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE); 1273094332d3Sopenharmony_ci acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS; 1274094332d3Sopenharmony_ci acm->lineCoding.bParityType = USB_CDC_NO_PARITY; 1275094332d3Sopenharmony_ci acm->lineCoding.bDataBits = DATA_BITS_LENGTH; 1276094332d3Sopenharmony_ci 1277094332d3Sopenharmony_ci ret = UsbRawSubmitRequest(acm->notifyReq); 1278094332d3Sopenharmony_ci if (ret) { 1279094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbRawSubmitRequest failed", __func__, __LINE__); 1280094332d3Sopenharmony_ci goto ERR_SUBMIT_REQ; 1281094332d3Sopenharmony_ci } 1282094332d3Sopenharmony_ci ret = AcmWriteBufAlloc(acm); 1283094332d3Sopenharmony_ci if (ret < 0) { 1284094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d AcmWriteBufAlloc failed", __func__, __LINE__); 1285094332d3Sopenharmony_ci ret = HDF_FAILURE; 1286094332d3Sopenharmony_ci goto ERR_ALLOC_WRITE_BUF; 1287094332d3Sopenharmony_ci } 1288094332d3Sopenharmony_ciERR_SUBMIT_REQ: 1289094332d3Sopenharmony_ci UsbStopIo(acm); 1290094332d3Sopenharmony_ciERR_START_IO: 1291094332d3Sopenharmony_ci UsbFreeReadRequests(acm); 1292094332d3Sopenharmony_ciERR_ALLOC_READ_REQS: 1293094332d3Sopenharmony_ci UsbFreeNotifyReqeust(acm); 1294094332d3Sopenharmony_ciERR_ALLOC_NOTIFY_REQ: 1295094332d3Sopenharmony_ci UsbFreeWriteRequests(acm); 1296094332d3Sopenharmony_ciERR_ALLOC_WRITE_REQS: 1297094332d3Sopenharmony_ci AcmWriteBufFree(acm); 1298094332d3Sopenharmony_ciERR_ALLOC_WRITE_BUF: 1299094332d3Sopenharmony_ci UsbReleaseInterfaces(acm); 1300094332d3Sopenharmony_ci} 1301094332d3Sopenharmony_ci 1302094332d3Sopenharmony_cistatic int32_t UsbSerialInit(struct AcmDevice *acm) 1303094332d3Sopenharmony_ci{ 1304094332d3Sopenharmony_ci struct UsbSession *session = NULL; 1305094332d3Sopenharmony_ci UsbRawHandle *devHandle = NULL; 1306094332d3Sopenharmony_ci int32_t ret; 1307094332d3Sopenharmony_ci if (acm->initFlag) { 1308094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d: initFlag is true", __func__, __LINE__); 1309094332d3Sopenharmony_ci return HDF_SUCCESS; 1310094332d3Sopenharmony_ci } 1311094332d3Sopenharmony_ci ret = UsbRawInit(NULL); 1312094332d3Sopenharmony_ci if (ret) { 1313094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbRawInit failed", __func__, __LINE__); 1314094332d3Sopenharmony_ci return HDF_ERR_IO; 1315094332d3Sopenharmony_ci } 1316094332d3Sopenharmony_ci acm->session = session; 1317094332d3Sopenharmony_ci devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr); 1318094332d3Sopenharmony_ci if (devHandle == NULL) { 1319094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbRawOpenDevice failed", __func__, __LINE__); 1320094332d3Sopenharmony_ci ret = HDF_FAILURE; 1321094332d3Sopenharmony_ci goto ERR_OPEN_DEVICE; 1322094332d3Sopenharmony_ci } 1323094332d3Sopenharmony_ci acm->devHandle = devHandle; 1324094332d3Sopenharmony_ci ret = UsbGetConfigDescriptor(devHandle, &acm->config); 1325094332d3Sopenharmony_ci if (ret) { 1326094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbGetConfigDescriptor failed", __func__, __LINE__); 1327094332d3Sopenharmony_ci ret = HDF_FAILURE; 1328094332d3Sopenharmony_ci goto ERR_GET_DESC; 1329094332d3Sopenharmony_ci } 1330094332d3Sopenharmony_ci ret = UsbParseConfigDescriptor(acm, acm->config); 1331094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 1332094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbParseConfigDescriptor failed", __func__, __LINE__); 1333094332d3Sopenharmony_ci ret = HDF_FAILURE; 1334094332d3Sopenharmony_ci goto ERR_PARSE_DESC; 1335094332d3Sopenharmony_ci } 1336094332d3Sopenharmony_ci UsbAllocRequests(acm, ret); 1337094332d3Sopenharmony_ci acm->initFlag = true; 1338094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d=========================OK", __func__, __LINE__); 1339094332d3Sopenharmony_ci return HDF_SUCCESS; 1340094332d3Sopenharmony_ciERR_PARSE_DESC: 1341094332d3Sopenharmony_ci UsbRawFreeConfigDescriptor(acm->config); 1342094332d3Sopenharmony_ci acm->config = NULL; 1343094332d3Sopenharmony_ciERR_GET_DESC: 1344094332d3Sopenharmony_ci (void)UsbRawCloseDevice(devHandle); 1345094332d3Sopenharmony_ciERR_OPEN_DEVICE: 1346094332d3Sopenharmony_ci UsbRawExit(acm->session); 1347094332d3Sopenharmony_ci return ret; 1348094332d3Sopenharmony_ci} 1349094332d3Sopenharmony_ci 1350094332d3Sopenharmony_cistatic void UsbSerialRelease(struct AcmDevice *acm) 1351094332d3Sopenharmony_ci{ 1352094332d3Sopenharmony_ci if (!(acm->initFlag)) { 1353094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d: initFlag is false", __func__, __LINE__); 1354094332d3Sopenharmony_ci return; 1355094332d3Sopenharmony_ci } 1356094332d3Sopenharmony_ci 1357094332d3Sopenharmony_ci /* stop io thread and release all resources */ 1358094332d3Sopenharmony_ci UsbStopIo(acm); 1359094332d3Sopenharmony_ci if (g_syncRequest != NULL) { 1360094332d3Sopenharmony_ci UsbRawFreeRequest(g_syncRequest); 1361094332d3Sopenharmony_ci g_syncRequest = NULL; 1362094332d3Sopenharmony_ci } 1363094332d3Sopenharmony_ci UsbFreeReadRequests(acm); 1364094332d3Sopenharmony_ci UsbFreeNotifyReqeust(acm); 1365094332d3Sopenharmony_ci UsbFreeWriteRequests(acm); 1366094332d3Sopenharmony_ci AcmWriteBufFree(acm); 1367094332d3Sopenharmony_ci UsbReleaseInterfaces(acm); 1368094332d3Sopenharmony_ci (void)UsbRawCloseDevice(acm->devHandle); 1369094332d3Sopenharmony_ci UsbRawFreeConfigDescriptor(acm->config); 1370094332d3Sopenharmony_ci acm->config = NULL; 1371094332d3Sopenharmony_ci UsbRawExit(acm->session); 1372094332d3Sopenharmony_ci 1373094332d3Sopenharmony_ci acm->initFlag = false; 1374094332d3Sopenharmony_ci} 1375094332d3Sopenharmony_ci 1376094332d3Sopenharmony_cistatic int32_t UsbSerialDriverInit(struct HdfDeviceObject *device) 1377094332d3Sopenharmony_ci{ 1378094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 1379094332d3Sopenharmony_ci int32_t ret; 1380094332d3Sopenharmony_ci 1381094332d3Sopenharmony_ci if (device == NULL) { 1382094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d device is null", __func__, __LINE__); 1383094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 1384094332d3Sopenharmony_ci } 1385094332d3Sopenharmony_ci acm = (struct AcmDevice *)device->service; 1386094332d3Sopenharmony_ci if (acm == NULL) { 1387094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 1388094332d3Sopenharmony_ci } 1389094332d3Sopenharmony_ci OsalMutexInit(&acm->readLock); 1390094332d3Sopenharmony_ci OsalMutexInit(&acm->writeLock); 1391094332d3Sopenharmony_ci 1392094332d3Sopenharmony_ci ret = UsbSerialDeviceAlloc(acm); 1393094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 1394094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbSerialDeviceAlloc failed", __func__, __LINE__); 1395094332d3Sopenharmony_ci } 1396094332d3Sopenharmony_ci 1397094332d3Sopenharmony_ci acm->initFlag = false; 1398094332d3Sopenharmony_ci g_rawAcmReleaseFlag = false; 1399094332d3Sopenharmony_ci 1400094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d init ok!", __func__, __LINE__); 1401094332d3Sopenharmony_ci 1402094332d3Sopenharmony_ci return ret; 1403094332d3Sopenharmony_ci} 1404094332d3Sopenharmony_ci 1405094332d3Sopenharmony_cistatic void UsbSerialDriverRelease(struct HdfDeviceObject *device) 1406094332d3Sopenharmony_ci{ 1407094332d3Sopenharmony_ci struct AcmDevice *acm = NULL; 1408094332d3Sopenharmony_ci if (device == NULL) { 1409094332d3Sopenharmony_ci HDF_LOGE("%{public}s: device is null", __func__); 1410094332d3Sopenharmony_ci return; 1411094332d3Sopenharmony_ci } 1412094332d3Sopenharmony_ci 1413094332d3Sopenharmony_ci acm = (struct AcmDevice *)device->service; 1414094332d3Sopenharmony_ci if (acm == NULL) { 1415094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm is null", __func__); 1416094332d3Sopenharmony_ci return; 1417094332d3Sopenharmony_ci } 1418094332d3Sopenharmony_ci 1419094332d3Sopenharmony_ci g_rawAcmReleaseFlag = true; 1420094332d3Sopenharmony_ci 1421094332d3Sopenharmony_ci if (acm->initFlag) { 1422094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d UsbSerialRelease", __func__, __LINE__); 1423094332d3Sopenharmony_ci UsbSerialRelease(acm); 1424094332d3Sopenharmony_ci } 1425094332d3Sopenharmony_ci UsbSeriaDevicelFree(acm); 1426094332d3Sopenharmony_ci OsalMutexDestroy(&acm->writeLock); 1427094332d3Sopenharmony_ci OsalMutexDestroy(&acm->readLock); 1428094332d3Sopenharmony_ci OsalMutexDestroy(&acm->lock); 1429094332d3Sopenharmony_ci OsalMemFree(acm); 1430094332d3Sopenharmony_ci acm = NULL; 1431094332d3Sopenharmony_ci device->service = NULL; 1432094332d3Sopenharmony_ci HDF_LOGD("%{public}s:%{public}d exit", __func__, __LINE__); 1433094332d3Sopenharmony_ci} 1434094332d3Sopenharmony_ci 1435094332d3Sopenharmony_cistruct HdfDriverEntry g_usbSerialRawDriverEntry = { 1436094332d3Sopenharmony_ci .moduleVersion = 1, 1437094332d3Sopenharmony_ci .moduleName = "usbhost_acm_rawapi", 1438094332d3Sopenharmony_ci .Bind = UsbSerialDriverBind, 1439094332d3Sopenharmony_ci .Init = UsbSerialDriverInit, 1440094332d3Sopenharmony_ci .Release = UsbSerialDriverRelease, 1441094332d3Sopenharmony_ci}; 1442094332d3Sopenharmony_ciHDF_INIT(g_usbSerialRawDriverEntry); 1443