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 "adapter_if.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <dirent.h> 19094332d3Sopenharmony_ci#include <endian.h> 20094332d3Sopenharmony_ci#include <fcntl.h> 21094332d3Sopenharmony_ci#include <poll.h> 22094332d3Sopenharmony_ci#include <stdarg.h> 23094332d3Sopenharmony_ci#include <stdio.h> 24094332d3Sopenharmony_ci#include <stdlib.h> 25094332d3Sopenharmony_ci#include <string.h> 26094332d3Sopenharmony_ci#include <sys/eventfd.h> 27094332d3Sopenharmony_ci#include <sys/ioctl.h> 28094332d3Sopenharmony_ci#include <sys/stat.h> 29094332d3Sopenharmony_ci#include <sys/types.h> 30094332d3Sopenharmony_ci#include <unistd.h> 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_ci#include "osal_time.h" 33094332d3Sopenharmony_ci#include "usbd_wrapper.h" 34094332d3Sopenharmony_ci 35094332d3Sopenharmony_ci#define HDF_LOG_TAG adapter_if 36094332d3Sopenharmony_ci#define SLEEP_DELAY 100000 37094332d3Sopenharmony_ci#define OPEN_CNT 30 38094332d3Sopenharmony_ci 39094332d3Sopenharmony_cistatic bool IsDirExist(const char *path) 40094332d3Sopenharmony_ci{ 41094332d3Sopenharmony_ci DIR *dir = NULL; 42094332d3Sopenharmony_ci 43094332d3Sopenharmony_ci if (path == NULL) { 44094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d invalid param path.", __func__, __LINE__); 45094332d3Sopenharmony_ci return false; 46094332d3Sopenharmony_ci } 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ci dir = opendir(path); 49094332d3Sopenharmony_ci if (dir == NULL) { 50094332d3Sopenharmony_ci HDF_LOGE("%{public}s: %{public}d: opendir failed!, path is %{public}s, errno is %{public}d", __func__, __LINE__, 51094332d3Sopenharmony_ci path, errno); 52094332d3Sopenharmony_ci return false; 53094332d3Sopenharmony_ci } 54094332d3Sopenharmony_ci closedir(dir); 55094332d3Sopenharmony_ci return true; 56094332d3Sopenharmony_ci} 57094332d3Sopenharmony_ci 58094332d3Sopenharmony_cistatic bool IsDir(const char *path) 59094332d3Sopenharmony_ci{ 60094332d3Sopenharmony_ci struct stat statBuf; 61094332d3Sopenharmony_ci if (lstat(path, &statBuf) == 0) { 62094332d3Sopenharmony_ci return S_ISDIR(statBuf.st_mode) != 0; 63094332d3Sopenharmony_ci } 64094332d3Sopenharmony_ci return false; 65094332d3Sopenharmony_ci} 66094332d3Sopenharmony_ci 67094332d3Sopenharmony_cistatic void GetFilePath(const char *path, const char *fileName, char *filePath) 68094332d3Sopenharmony_ci{ 69094332d3Sopenharmony_ci int32_t ret = strcpy_s(filePath, MAX_PATHLEN - 1, path); 70094332d3Sopenharmony_ci if (ret != EOK) { 71094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcpy_s failed", __func__); 72094332d3Sopenharmony_ci return; 73094332d3Sopenharmony_ci } 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_ci if (strlen(path) > 0 && filePath[strlen(path) - 1] != '/') { 76094332d3Sopenharmony_ci if (strlen(path) + 1 >= MAX_PATHLEN - strlen(fileName)) { 77094332d3Sopenharmony_ci HDF_LOGE("%{public}s: file path too long", __func__); 78094332d3Sopenharmony_ci return; 79094332d3Sopenharmony_ci } 80094332d3Sopenharmony_ci ret = strcat_s(filePath, MAX_PATHLEN - 1, "/"); 81094332d3Sopenharmony_ci if (ret != EOK) { 82094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcat_s failed", __func__); 83094332d3Sopenharmony_ci return; 84094332d3Sopenharmony_ci } 85094332d3Sopenharmony_ci } 86094332d3Sopenharmony_ci 87094332d3Sopenharmony_ci ret = strcat_s(filePath, MAX_PATHLEN - 1, fileName); 88094332d3Sopenharmony_ci if (ret != EOK) { 89094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcat_s failed", __func__); 90094332d3Sopenharmony_ci } 91094332d3Sopenharmony_ci} 92094332d3Sopenharmony_ci 93094332d3Sopenharmony_cistatic bool IsSpecialDir(const char *path) 94094332d3Sopenharmony_ci{ 95094332d3Sopenharmony_ci return (strcmp(path, ".") == 0) || strcmp(path, "..") == 0; 96094332d3Sopenharmony_ci} 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_cistatic void DeleteFile(const char *path) 99094332d3Sopenharmony_ci{ 100094332d3Sopenharmony_ci DIR *dir = NULL; 101094332d3Sopenharmony_ci struct dirent *dirInfo = NULL; 102094332d3Sopenharmony_ci 103094332d3Sopenharmony_ci if (IsDir(path)) { 104094332d3Sopenharmony_ci if ((dir = opendir(path)) == NULL) { 105094332d3Sopenharmony_ci return; 106094332d3Sopenharmony_ci } 107094332d3Sopenharmony_ci char filePath[PATH_MAX]; 108094332d3Sopenharmony_ci while ((dirInfo = readdir(dir)) != NULL) { 109094332d3Sopenharmony_ci GetFilePath(path, dirInfo->d_name, filePath); 110094332d3Sopenharmony_ci if (IsSpecialDir(dirInfo->d_name)) { 111094332d3Sopenharmony_ci continue; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci DeleteFile(filePath); 114094332d3Sopenharmony_ci (void)remove(filePath); 115094332d3Sopenharmony_ci } 116094332d3Sopenharmony_ci closedir(dir); 117094332d3Sopenharmony_ci } 118094332d3Sopenharmony_ci} 119094332d3Sopenharmony_ci 120094332d3Sopenharmony_cistatic bool IsDeviceDirExist(const char *deviceName) 121094332d3Sopenharmony_ci{ 122094332d3Sopenharmony_ci char tmp[MAX_PATHLEN] = {0}; 123094332d3Sopenharmony_ci int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName); 124094332d3Sopenharmony_ci if (ret < 0) { 125094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 126094332d3Sopenharmony_ci return false; 127094332d3Sopenharmony_ci } 128094332d3Sopenharmony_ci 129094332d3Sopenharmony_ci return IsDirExist(tmp); 130094332d3Sopenharmony_ci} 131094332d3Sopenharmony_ci 132094332d3Sopenharmony_cistatic int32_t UsbFnWriteFile(const char *path, const char *str) 133094332d3Sopenharmony_ci{ 134094332d3Sopenharmony_ci size_t ret; 135094332d3Sopenharmony_ci if (strlen(str) == 0) { 136094332d3Sopenharmony_ci return 0; 137094332d3Sopenharmony_ci } 138094332d3Sopenharmony_ci 139094332d3Sopenharmony_ci FILE *fp = fopen(path, "w"); 140094332d3Sopenharmony_ci if (fp == NULL) { 141094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnWriteFile failed", __func__); 142094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 143094332d3Sopenharmony_ci } 144094332d3Sopenharmony_ci 145094332d3Sopenharmony_ci ret = fwrite(str, strlen(str), 1, fp); 146094332d3Sopenharmony_ci if (ret != 1) { 147094332d3Sopenharmony_ci (void)fclose(fp); 148094332d3Sopenharmony_ci return HDF_FAILURE; 149094332d3Sopenharmony_ci } 150094332d3Sopenharmony_ci (void)fclose(fp); 151094332d3Sopenharmony_ci return 0; 152094332d3Sopenharmony_ci} 153094332d3Sopenharmony_ci 154094332d3Sopenharmony_cistatic int32_t UsbFnWriteProp(const char *deviceName, const char *propName, uint32_t propValue) 155094332d3Sopenharmony_ci{ 156094332d3Sopenharmony_ci char tmp[MAX_PATHLEN] = {0}; 157094332d3Sopenharmony_ci char tmpVal[MAX_NAMELEN] = {0}; 158094332d3Sopenharmony_ci int32_t ret; 159094332d3Sopenharmony_ci if (deviceName == NULL || propName == NULL) { 160094332d3Sopenharmony_ci HDF_LOGE("%{public}s: INVALID PARAM", __func__); 161094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 162094332d3Sopenharmony_ci } 163094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/%s", CONFIGFS_DIR, deviceName, propName); 164094332d3Sopenharmony_ci if (ret < 0) { 165094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 166094332d3Sopenharmony_ci return HDF_ERR_IO; 167094332d3Sopenharmony_ci } 168094332d3Sopenharmony_ci 169094332d3Sopenharmony_ci ret = snprintf_s(tmpVal, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", propValue); 170094332d3Sopenharmony_ci if (ret < 0) { 171094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 172094332d3Sopenharmony_ci return HDF_ERR_IO; 173094332d3Sopenharmony_ci } 174094332d3Sopenharmony_ci 175094332d3Sopenharmony_ci return UsbFnWriteFile(tmp, tmpVal); 176094332d3Sopenharmony_ci} 177094332d3Sopenharmony_ci 178094332d3Sopenharmony_cistatic int32_t UsbFnWriteConfString(const char *deviceName, int32_t configVal, uint16_t lang, const char *stringValue) 179094332d3Sopenharmony_ci{ 180094332d3Sopenharmony_ci int32_t ret; 181094332d3Sopenharmony_ci char tmp[MAX_PATHLEN] = {0}; 182094332d3Sopenharmony_ci char tmpPath[MAX_PATHLEN] = {0}; 183094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%d/strings/0x%x", CONFIGFS_DIR, deviceName, 184094332d3Sopenharmony_ci configVal, lang); 185094332d3Sopenharmony_ci if (ret < 0) { 186094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 187094332d3Sopenharmony_ci return HDF_ERR_IO; 188094332d3Sopenharmony_ci } 189094332d3Sopenharmony_ci 190094332d3Sopenharmony_ci if (!IsDirExist(tmp)) { 191094332d3Sopenharmony_ci ret = mkdir(tmp, S_IREAD | S_IWRITE); 192094332d3Sopenharmony_ci if (ret != 0) { 193094332d3Sopenharmony_ci HDF_LOGE("%{public}s: mkdir failed", __func__); 194094332d3Sopenharmony_ci return HDF_ERR_IO; 195094332d3Sopenharmony_ci } 196094332d3Sopenharmony_ci } 197094332d3Sopenharmony_ci 198094332d3Sopenharmony_ci ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/configuration", tmp); 199094332d3Sopenharmony_ci if (ret < 0) { 200094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 201094332d3Sopenharmony_ci return HDF_ERR_IO; 202094332d3Sopenharmony_ci } 203094332d3Sopenharmony_ci 204094332d3Sopenharmony_ci ret = UsbFnWriteFile(tmpPath, stringValue); 205094332d3Sopenharmony_ci return ret; 206094332d3Sopenharmony_ci} 207094332d3Sopenharmony_ci 208094332d3Sopenharmony_cistatic int32_t UsbFnWriteDesString( 209094332d3Sopenharmony_ci const char *deviceName, uint16_t lang, const char *stringName, const char *stringValue) 210094332d3Sopenharmony_ci{ 211094332d3Sopenharmony_ci int32_t ret; 212094332d3Sopenharmony_ci char tmp[MAX_PATHLEN] = {0}; 213094332d3Sopenharmony_ci char tmpPath[MAX_PATHLEN] = {0}; 214094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings/0x%x", CONFIGFS_DIR, deviceName, lang); 215094332d3Sopenharmony_ci if (ret < 0) { 216094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 217094332d3Sopenharmony_ci return HDF_ERR_IO; 218094332d3Sopenharmony_ci } 219094332d3Sopenharmony_ci if (!IsDirExist(tmp)) { 220094332d3Sopenharmony_ci ret = mkdir(tmp, S_IREAD | S_IWRITE); 221094332d3Sopenharmony_ci if (ret != 0) { 222094332d3Sopenharmony_ci HDF_LOGE("%{public}s: mkdir failed", __func__); 223094332d3Sopenharmony_ci return HDF_ERR_IO; 224094332d3Sopenharmony_ci } 225094332d3Sopenharmony_ci } 226094332d3Sopenharmony_ci 227094332d3Sopenharmony_ci ret = snprintf_s(tmpPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", tmp, stringName); 228094332d3Sopenharmony_ci if (ret < 0) { 229094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 230094332d3Sopenharmony_ci return HDF_ERR_IO; 231094332d3Sopenharmony_ci } 232094332d3Sopenharmony_ci 233094332d3Sopenharmony_ci ret = UsbFnWriteFile(tmpPath, stringValue); 234094332d3Sopenharmony_ci return ret; 235094332d3Sopenharmony_ci} 236094332d3Sopenharmony_ci 237094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateFunc(const char *configPath, const char *funcPath) 238094332d3Sopenharmony_ci{ 239094332d3Sopenharmony_ci int32_t ret; 240094332d3Sopenharmony_ci 241094332d3Sopenharmony_ci ret = mkdir(funcPath, S_IREAD | S_IWRITE); 242094332d3Sopenharmony_ci if (ret != 0) { 243094332d3Sopenharmony_ci HDF_LOGE("%{public}s: mkdir failed", __func__); 244094332d3Sopenharmony_ci return HDF_ERR_IO; 245094332d3Sopenharmony_ci } 246094332d3Sopenharmony_ci 247094332d3Sopenharmony_ci ret = symlink(funcPath, configPath); 248094332d3Sopenharmony_ci if (ret != 0) { 249094332d3Sopenharmony_ci HDF_LOGE("%{public}s: symlink failed", __func__); 250094332d3Sopenharmony_ci return HDF_ERR_IO; 251094332d3Sopenharmony_ci } 252094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 253094332d3Sopenharmony_ci return 0; 254094332d3Sopenharmony_ci} 255094332d3Sopenharmony_ci 256094332d3Sopenharmony_cistatic int32_t UsbFnReadFile(const char *path, char *str, uint16_t len) 257094332d3Sopenharmony_ci{ 258094332d3Sopenharmony_ci FILE *fp = fopen(path, "r"); 259094332d3Sopenharmony_ci if (fp == NULL) { 260094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fopen failed", __func__); 261094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 262094332d3Sopenharmony_ci } 263094332d3Sopenharmony_ci if (fread(str, len, 1, fp) != 1) { 264094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fread failed", __func__); 265094332d3Sopenharmony_ci (void)fclose(fp); 266094332d3Sopenharmony_ci return HDF_ERR_IO; 267094332d3Sopenharmony_ci } 268094332d3Sopenharmony_ci (void)fclose(fp); 269094332d3Sopenharmony_ci return 0; 270094332d3Sopenharmony_ci} 271094332d3Sopenharmony_ci 272094332d3Sopenharmony_cistatic int32_t UsbFnAdapterWriteUDC(const char *deviceName, const char *udcName, int32_t enable) 273094332d3Sopenharmony_ci{ 274094332d3Sopenharmony_ci char tmp[MAX_PATHLEN] = {0}; 275094332d3Sopenharmony_ci if (deviceName == NULL || udcName == NULL || IsDeviceDirExist(deviceName) == false) { 276094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 277094332d3Sopenharmony_ci } 278094332d3Sopenharmony_ci 279094332d3Sopenharmony_ci int32_t ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/UDC", CONFIGFS_DIR, deviceName); 280094332d3Sopenharmony_ci if (ret < 0) { 281094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 282094332d3Sopenharmony_ci return HDF_ERR_IO; 283094332d3Sopenharmony_ci } 284094332d3Sopenharmony_ci if (enable != 0) { 285094332d3Sopenharmony_ci (void)UsbFnWriteFile(tmp, udcName); 286094332d3Sopenharmony_ci char udcTmp[MAX_NAMELEN] = {0}; 287094332d3Sopenharmony_ci for (int32_t i = 0; i < OPEN_CNT; i++) { 288094332d3Sopenharmony_ci (void)UsbFnReadFile(tmp, udcTmp, strlen(udcName)); 289094332d3Sopenharmony_ci if (!strcmp(udcName, udcTmp)) { 290094332d3Sopenharmony_ci return 0; 291094332d3Sopenharmony_ci } 292094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 293094332d3Sopenharmony_ci } 294094332d3Sopenharmony_ci if (strcmp(udcName, udcTmp)) { 295094332d3Sopenharmony_ci return HDF_ERR_IO; 296094332d3Sopenharmony_ci } 297094332d3Sopenharmony_ci } else { 298094332d3Sopenharmony_ci (void)UsbFnWriteFile(tmp, "\n"); 299094332d3Sopenharmony_ci } 300094332d3Sopenharmony_ci return 0; 301094332d3Sopenharmony_ci} 302094332d3Sopenharmony_ci 303094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenFn(void) 304094332d3Sopenharmony_ci{ 305094332d3Sopenharmony_ci int32_t i; 306094332d3Sopenharmony_ci int32_t ep = -1; 307094332d3Sopenharmony_ci for (i = 0; i < OPEN_CNT; i++) { 308094332d3Sopenharmony_ci ep = open(USBFN_DEV, O_RDWR); 309094332d3Sopenharmony_ci if (ep > 0) { 310094332d3Sopenharmony_ci break; 311094332d3Sopenharmony_ci } 312094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 313094332d3Sopenharmony_ci } 314094332d3Sopenharmony_ci if (ep < 0) { 315094332d3Sopenharmony_ci HDF_LOGE("func not alloc"); 316094332d3Sopenharmony_ci } 317094332d3Sopenharmony_ci return ep; 318094332d3Sopenharmony_ci} 319094332d3Sopenharmony_ci 320094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosefn(int32_t fd) 321094332d3Sopenharmony_ci{ 322094332d3Sopenharmony_ci if (fd <= 0) { 323094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 324094332d3Sopenharmony_ci } 325094332d3Sopenharmony_ci return close(fd); 326094332d3Sopenharmony_ci} 327094332d3Sopenharmony_ci 328094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreatInterface(const char *interfaceName, int32_t nameLen) 329094332d3Sopenharmony_ci{ 330094332d3Sopenharmony_ci int32_t ret; 331094332d3Sopenharmony_ci int32_t fd; 332094332d3Sopenharmony_ci struct FuncNew fnnew; 333094332d3Sopenharmony_ci if (interfaceName == NULL || nameLen <= 0) { 334094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 335094332d3Sopenharmony_ci } 336094332d3Sopenharmony_ci fd = UsbFnAdapterOpenFn(); 337094332d3Sopenharmony_ci if (fd <= 0) { 338094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterOpenFn failed", __func__); 339094332d3Sopenharmony_ci return HDF_ERR_IO; 340094332d3Sopenharmony_ci } 341094332d3Sopenharmony_ci 342094332d3Sopenharmony_ci fnnew.nameLen = (uint32_t)nameLen; 343094332d3Sopenharmony_ci ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName); 344094332d3Sopenharmony_ci if (ret < 0) { 345094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 346094332d3Sopenharmony_ci UsbFnAdapterClosefn(fd); 347094332d3Sopenharmony_ci return HDF_ERR_IO; 348094332d3Sopenharmony_ci } 349094332d3Sopenharmony_ci ret = ioctl(fd, FUNCTIONFS_NEWFN, &fnnew); 350094332d3Sopenharmony_ci if (ret != 0) { 351094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FUNCTIONFS_NEWFN failed", __func__); 352094332d3Sopenharmony_ci UsbFnAdapterClosefn(fd); 353094332d3Sopenharmony_ci return HDF_ERR_IO; 354094332d3Sopenharmony_ci } 355094332d3Sopenharmony_ci ret = UsbFnAdapterClosefn(fd); 356094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 357094332d3Sopenharmony_ci return ret; 358094332d3Sopenharmony_ci} 359094332d3Sopenharmony_ci 360094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelInterface(const char *interfaceName, int32_t nameLen) 361094332d3Sopenharmony_ci{ 362094332d3Sopenharmony_ci int32_t ret; 363094332d3Sopenharmony_ci struct FuncNew fnnew; 364094332d3Sopenharmony_ci if (interfaceName == NULL || nameLen <= 0) { 365094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 366094332d3Sopenharmony_ci } 367094332d3Sopenharmony_ci 368094332d3Sopenharmony_ci int32_t fd = UsbFnAdapterOpenFn(); 369094332d3Sopenharmony_ci if (fd <= 0) { 370094332d3Sopenharmony_ci return HDF_ERR_IO; 371094332d3Sopenharmony_ci } 372094332d3Sopenharmony_ci 373094332d3Sopenharmony_ci fnnew.nameLen = (uint32_t)nameLen; 374094332d3Sopenharmony_ci ret = snprintf_s(fnnew.name, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", interfaceName); 375094332d3Sopenharmony_ci if (ret < 0) { 376094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 377094332d3Sopenharmony_ci UsbFnAdapterClosefn(fd); 378094332d3Sopenharmony_ci return HDF_ERR_IO; 379094332d3Sopenharmony_ci } 380094332d3Sopenharmony_ci ret = ioctl(fd, FUNCTIONFS_DELFN, &fnnew); 381094332d3Sopenharmony_ci if (ret != 0) { 382094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FUNCTIONFS_DELFN failed", __func__); 383094332d3Sopenharmony_ci UsbFnAdapterClosefn(fd); 384094332d3Sopenharmony_ci return HDF_ERR_IO; 385094332d3Sopenharmony_ci } 386094332d3Sopenharmony_ci ret = UsbFnAdapterClosefn(fd); 387094332d3Sopenharmony_ci return ret; 388094332d3Sopenharmony_ci} 389094332d3Sopenharmony_ci 390094332d3Sopenharmony_cistatic int32_t UsbFnAdapterOpenPipe(const char *interfaceName, int32_t epIndex) 391094332d3Sopenharmony_ci{ 392094332d3Sopenharmony_ci if (interfaceName == NULL || epIndex < 0) { 393094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 394094332d3Sopenharmony_ci } 395094332d3Sopenharmony_ci 396094332d3Sopenharmony_ci char epName[MAX_NAMELEN]; 397094332d3Sopenharmony_ci int32_t ret = snprintf_s(epName, MAX_NAMELEN, MAX_NAMELEN - 1, "/dev/functionfs/%s.ep%d", interfaceName, epIndex); 398094332d3Sopenharmony_ci if (ret < 0) { 399094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 400094332d3Sopenharmony_ci return HDF_ERR_IO; 401094332d3Sopenharmony_ci } 402094332d3Sopenharmony_ci 403094332d3Sopenharmony_ci int32_t ep = -1; 404094332d3Sopenharmony_ci for (int32_t i = 0; i < OPEN_CNT; i++) { 405094332d3Sopenharmony_ci ep = open(epName, O_RDWR); 406094332d3Sopenharmony_ci if (ep > 0) { 407094332d3Sopenharmony_ci break; 408094332d3Sopenharmony_ci } 409094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 410094332d3Sopenharmony_ci } 411094332d3Sopenharmony_ci if (ep < 0) { 412094332d3Sopenharmony_ci HDF_LOGE("unable to open %{public}s", epName); 413094332d3Sopenharmony_ci return HDF_DEV_ERR_NO_DEVICE; 414094332d3Sopenharmony_ci } 415094332d3Sopenharmony_ci return ep; 416094332d3Sopenharmony_ci} 417094332d3Sopenharmony_ci 418094332d3Sopenharmony_cistatic int32_t UsbFnAdapterClosePipe(int32_t ep) 419094332d3Sopenharmony_ci{ 420094332d3Sopenharmony_ci if (ep <= 0) { 421094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 422094332d3Sopenharmony_ci } 423094332d3Sopenharmony_ci 424094332d3Sopenharmony_ci return close(ep); 425094332d3Sopenharmony_ci} 426094332d3Sopenharmony_ci 427094332d3Sopenharmony_cistatic void GetHeaderStr(struct UsbFnStrings ** const strings, struct UsbFunctionfsStringsHead *headerStr) 428094332d3Sopenharmony_ci{ 429094332d3Sopenharmony_ci uint32_t i, j; 430094332d3Sopenharmony_ci uint32_t langCount = 0; 431094332d3Sopenharmony_ci uint32_t strCount = 0; 432094332d3Sopenharmony_ci uint32_t len = 0; 433094332d3Sopenharmony_ci for (i = 0; strings[i] != NULL; i++) { 434094332d3Sopenharmony_ci langCount++; 435094332d3Sopenharmony_ci for (j = 0; strings[i]->strings[j].s; j++) { 436094332d3Sopenharmony_ci len += strlen(strings[i]->strings[j].s) + sizeof(char); 437094332d3Sopenharmony_ci } 438094332d3Sopenharmony_ci strCount = j; 439094332d3Sopenharmony_ci } 440094332d3Sopenharmony_ci headerStr->magic = htole32(FUNCTIONFS_STRINGS_MAGIC); 441094332d3Sopenharmony_ci headerStr->length = htole32(sizeof(struct UsbFunctionfsStringsHead) + langCount * sizeof(uint16_t) + len); 442094332d3Sopenharmony_ci headerStr->strCount = strCount; 443094332d3Sopenharmony_ci headerStr->langCount = langCount; 444094332d3Sopenharmony_ci} 445094332d3Sopenharmony_ci 446094332d3Sopenharmony_cistatic int32_t UsbFnWriteStrings(int32_t ep0, struct UsbFnStrings ** const strings) 447094332d3Sopenharmony_ci{ 448094332d3Sopenharmony_ci uint8_t *str = NULL; 449094332d3Sopenharmony_ci uint8_t *whereDec = NULL; 450094332d3Sopenharmony_ci uint32_t i, j; 451094332d3Sopenharmony_ci int32_t ret; 452094332d3Sopenharmony_ci struct UsbFunctionfsStringsHead headerStr = {0}; 453094332d3Sopenharmony_ci 454094332d3Sopenharmony_ci GetHeaderStr(strings, &headerStr); 455094332d3Sopenharmony_ci str = UsbFnMemCalloc(headerStr.length); 456094332d3Sopenharmony_ci if (str == NULL) { 457094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 458094332d3Sopenharmony_ci } 459094332d3Sopenharmony_ci 460094332d3Sopenharmony_ci whereDec = str; 461094332d3Sopenharmony_ci ret = memcpy_s(whereDec, headerStr.length, &headerStr, sizeof(struct UsbFunctionfsStringsHead)); 462094332d3Sopenharmony_ci if (ret != EOK) { 463094332d3Sopenharmony_ci goto ERR; 464094332d3Sopenharmony_ci } 465094332d3Sopenharmony_ci whereDec += sizeof(struct UsbFunctionfsStringsHead); 466094332d3Sopenharmony_ci 467094332d3Sopenharmony_ci for (i = 0; i < headerStr.langCount; i++) { 468094332d3Sopenharmony_ci ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), &strings[i]->language, sizeof(uint16_t)); 469094332d3Sopenharmony_ci if (ret != EOK) { 470094332d3Sopenharmony_ci goto ERR; 471094332d3Sopenharmony_ci } 472094332d3Sopenharmony_ci whereDec += sizeof(uint16_t); 473094332d3Sopenharmony_ci for (j = 0; j < headerStr.strCount; j++) { 474094332d3Sopenharmony_ci if (strlen(strings[i]->strings[j].s)) { 475094332d3Sopenharmony_ci ret = memcpy_s(whereDec, headerStr.length - (whereDec - str), strings[i]->strings[j].s, 476094332d3Sopenharmony_ci strlen(strings[i]->strings[j].s)); 477094332d3Sopenharmony_ci whereDec += strlen(strings[i]->strings[j].s) + sizeof(char); 478094332d3Sopenharmony_ci } else { 479094332d3Sopenharmony_ci break; 480094332d3Sopenharmony_ci } 481094332d3Sopenharmony_ci if (ret != EOK) { 482094332d3Sopenharmony_ci goto ERR; 483094332d3Sopenharmony_ci } 484094332d3Sopenharmony_ci } 485094332d3Sopenharmony_ci } 486094332d3Sopenharmony_ci 487094332d3Sopenharmony_ci if (write(ep0, str, headerStr.length) < 0) { 488094332d3Sopenharmony_ci goto ERR; 489094332d3Sopenharmony_ci } 490094332d3Sopenharmony_ci UsbFnMemFree(str); 491094332d3Sopenharmony_ci return 0; 492094332d3Sopenharmony_ciERR: 493094332d3Sopenharmony_ci UsbFnMemFree(str); 494094332d3Sopenharmony_ci return HDF_FAILURE; 495094332d3Sopenharmony_ci} 496094332d3Sopenharmony_ci 497094332d3Sopenharmony_cistatic int32_t CopyCount(uint8_t **whereDec, uint32_t fsCount, uint32_t hsCount, uint32_t ssCount) 498094332d3Sopenharmony_ci{ 499094332d3Sopenharmony_ci int32_t ret; 500094332d3Sopenharmony_ci if (fsCount != 0) { 501094332d3Sopenharmony_ci ret = memcpy_s(*whereDec, sizeof(uint32_t), &fsCount, sizeof(uint32_t)); 502094332d3Sopenharmony_ci if (ret != EOK) { 503094332d3Sopenharmony_ci return HDF_FAILURE; 504094332d3Sopenharmony_ci } 505094332d3Sopenharmony_ci *whereDec += sizeof(uint32_t); 506094332d3Sopenharmony_ci } 507094332d3Sopenharmony_ci if (hsCount != 0) { 508094332d3Sopenharmony_ci ret = memcpy_s(*whereDec, sizeof(uint32_t), &hsCount, sizeof(uint32_t)); 509094332d3Sopenharmony_ci if (ret != EOK) { 510094332d3Sopenharmony_ci return HDF_FAILURE; 511094332d3Sopenharmony_ci } 512094332d3Sopenharmony_ci *whereDec += sizeof(uint32_t); 513094332d3Sopenharmony_ci } 514094332d3Sopenharmony_ci if (ssCount != 0) { 515094332d3Sopenharmony_ci ret = memcpy_s(*whereDec, sizeof(uint32_t), &ssCount, sizeof(uint32_t)); 516094332d3Sopenharmony_ci if (ret != EOK) { 517094332d3Sopenharmony_ci return HDF_FAILURE; 518094332d3Sopenharmony_ci } 519094332d3Sopenharmony_ci *whereDec += sizeof(uint32_t); 520094332d3Sopenharmony_ci } 521094332d3Sopenharmony_ci 522094332d3Sopenharmony_ci return 0; 523094332d3Sopenharmony_ci} 524094332d3Sopenharmony_ci 525094332d3Sopenharmony_cistatic int32_t WriteFuncDescriptors(uint8_t ** const whereDec, struct UsbDescriptorHeader ** const headDes) 526094332d3Sopenharmony_ci{ 527094332d3Sopenharmony_ci for (uint32_t i = 0; headDes[i] != NULL; i++) { 528094332d3Sopenharmony_ci if (memcpy_s(*whereDec, headDes[i]->bLength, headDes[i], headDes[i]->bLength) != EOK) { 529094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed", __func__); 530094332d3Sopenharmony_ci return HDF_FAILURE; 531094332d3Sopenharmony_ci } 532094332d3Sopenharmony_ci *whereDec += headDes[i]->bLength; 533094332d3Sopenharmony_ci } 534094332d3Sopenharmony_ci return 0; 535094332d3Sopenharmony_ci} 536094332d3Sopenharmony_ci 537094332d3Sopenharmony_cistatic void GetCountAndHead(struct UsbFunctionfsDescsHeadV2 *header, uint32_t *fsCount, uint32_t *hsCount, 538094332d3Sopenharmony_ci uint32_t *ssCount, const struct UsbFnFunction *func) 539094332d3Sopenharmony_ci{ 540094332d3Sopenharmony_ci int32_t i; 541094332d3Sopenharmony_ci uint32_t lenCount = 0; 542094332d3Sopenharmony_ci uint32_t lenDes = 0; 543094332d3Sopenharmony_ci *fsCount = 0; 544094332d3Sopenharmony_ci *hsCount = 0; 545094332d3Sopenharmony_ci *ssCount = 0; 546094332d3Sopenharmony_ci 547094332d3Sopenharmony_ci for (i = 0; func->fsDescriptors[i] != NULL; i++) { 548094332d3Sopenharmony_ci (*fsCount)++; 549094332d3Sopenharmony_ci lenDes += func->fsDescriptors[i]->bLength; 550094332d3Sopenharmony_ci } 551094332d3Sopenharmony_ci for (i = 0; func->hsDescriptors[i] != NULL; i++) { 552094332d3Sopenharmony_ci (*hsCount)++; 553094332d3Sopenharmony_ci lenDes += func->hsDescriptors[i]->bLength; 554094332d3Sopenharmony_ci } 555094332d3Sopenharmony_ci for (i = 0; func->ssDescriptors[i] != NULL; i++) { 556094332d3Sopenharmony_ci (*ssCount)++; 557094332d3Sopenharmony_ci lenDes += func->ssDescriptors[i]->bLength; 558094332d3Sopenharmony_ci } 559094332d3Sopenharmony_ci 560094332d3Sopenharmony_ci if (*fsCount != 0) { 561094332d3Sopenharmony_ci lenCount += sizeof(uint32_t); 562094332d3Sopenharmony_ci header->flags |= htole32(FUNCTIONFS_HAS_FS_DESC); 563094332d3Sopenharmony_ci } 564094332d3Sopenharmony_ci if (*hsCount != 0) { 565094332d3Sopenharmony_ci lenCount += sizeof(uint32_t); 566094332d3Sopenharmony_ci header->flags |= htole32(FUNCTIONFS_HAS_HS_DESC); 567094332d3Sopenharmony_ci } 568094332d3Sopenharmony_ci if (*ssCount != 0) { 569094332d3Sopenharmony_ci lenCount += sizeof(uint32_t); 570094332d3Sopenharmony_ci header->flags |= htole32(FUNCTIONFS_HAS_SS_DESC); 571094332d3Sopenharmony_ci } 572094332d3Sopenharmony_ci 573094332d3Sopenharmony_ci header->magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2); 574094332d3Sopenharmony_ci header->length = htole32(sizeof(struct UsbFunctionfsDescsHeadV2) + lenCount + lenDes); 575094332d3Sopenharmony_ci} 576094332d3Sopenharmony_ci 577094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreatPipes(int32_t ep0, const struct UsbFnFunction *func) 578094332d3Sopenharmony_ci{ 579094332d3Sopenharmony_ci uint8_t *dec = NULL; 580094332d3Sopenharmony_ci uint8_t *whereDec = NULL; 581094332d3Sopenharmony_ci uint32_t fsCount; 582094332d3Sopenharmony_ci uint32_t hsCount; 583094332d3Sopenharmony_ci uint32_t ssCount; 584094332d3Sopenharmony_ci struct UsbFunctionfsDescsHeadV2 header = {0}; 585094332d3Sopenharmony_ci 586094332d3Sopenharmony_ci GetCountAndHead(&header, &fsCount, &hsCount, &ssCount, func); 587094332d3Sopenharmony_ci 588094332d3Sopenharmony_ci dec = UsbFnMemCalloc(header.length); 589094332d3Sopenharmony_ci if (dec == NULL) { 590094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnMemCalloc failed", __func__); 591094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 592094332d3Sopenharmony_ci } 593094332d3Sopenharmony_ci whereDec = dec; 594094332d3Sopenharmony_ci 595094332d3Sopenharmony_ci int32_t ret = memcpy_s(whereDec, header.length, &header, sizeof(struct UsbFunctionfsDescsHeadV2)); 596094332d3Sopenharmony_ci if (ret != EOK) { 597094332d3Sopenharmony_ci UsbFnMemFree(dec); 598094332d3Sopenharmony_ci return HDF_FAILURE; 599094332d3Sopenharmony_ci } 600094332d3Sopenharmony_ci whereDec += sizeof(struct UsbFunctionfsDescsHeadV2); 601094332d3Sopenharmony_ci 602094332d3Sopenharmony_ci ret = CopyCount(&whereDec, fsCount, hsCount, ssCount); 603094332d3Sopenharmony_ci if (ret != EOK) { 604094332d3Sopenharmony_ci UsbFnMemFree(dec); 605094332d3Sopenharmony_ci return HDF_FAILURE; 606094332d3Sopenharmony_ci } 607094332d3Sopenharmony_ci 608094332d3Sopenharmony_ci ret = WriteFuncDescriptors(&whereDec, func->fsDescriptors); 609094332d3Sopenharmony_ci if (ret != EOK) { 610094332d3Sopenharmony_ci UsbFnMemFree(dec); 611094332d3Sopenharmony_ci return HDF_FAILURE; 612094332d3Sopenharmony_ci } 613094332d3Sopenharmony_ci 614094332d3Sopenharmony_ci ret = WriteFuncDescriptors(&whereDec, func->hsDescriptors); 615094332d3Sopenharmony_ci if (ret != EOK) { 616094332d3Sopenharmony_ci UsbFnMemFree(dec); 617094332d3Sopenharmony_ci return HDF_FAILURE; 618094332d3Sopenharmony_ci } 619094332d3Sopenharmony_ci 620094332d3Sopenharmony_ci ret = WriteFuncDescriptors(&whereDec, func->ssDescriptors); 621094332d3Sopenharmony_ci if (ret != EOK) { 622094332d3Sopenharmony_ci UsbFnMemFree(dec); 623094332d3Sopenharmony_ci return HDF_FAILURE; 624094332d3Sopenharmony_ci } 625094332d3Sopenharmony_ci 626094332d3Sopenharmony_ci if (write(ep0, dec, header.length) < 0) { 627094332d3Sopenharmony_ci HDF_LOGE("unable do write descriptors"); 628094332d3Sopenharmony_ci UsbFnMemFree(dec); 629094332d3Sopenharmony_ci return HDF_ERR_IO; 630094332d3Sopenharmony_ci } 631094332d3Sopenharmony_ci 632094332d3Sopenharmony_ci UsbFnMemFree(dec); 633094332d3Sopenharmony_ci ret = UsbFnWriteStrings(ep0, func->strings); 634094332d3Sopenharmony_ci 635094332d3Sopenharmony_ci usleep(SLEEP_DELAY); 636094332d3Sopenharmony_ci return ret; 637094332d3Sopenharmony_ci} 638094332d3Sopenharmony_ci 639094332d3Sopenharmony_cistatic int32_t WriteDeviceId(const char *devName, const struct UsbDeviceDescriptor *desc) 640094332d3Sopenharmony_ci{ 641094332d3Sopenharmony_ci int32_t ret; 642094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "idVendor", desc->idVendor); 643094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 644094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 645094332d3Sopenharmony_ci } 646094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "idProduct", desc->idProduct); 647094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 648094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 649094332d3Sopenharmony_ci } 650094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bcdUSB", desc->bcdUSB); 651094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 652094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 653094332d3Sopenharmony_ci } 654094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bcdDevice", desc->bcdDevice); 655094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 656094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 657094332d3Sopenharmony_ci } 658094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bDeviceClass", desc->bDeviceClass); 659094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 660094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 661094332d3Sopenharmony_ci } 662094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bDeviceSubClass", desc->bDeviceSubClass); 663094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 664094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 665094332d3Sopenharmony_ci } 666094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bDeviceProtocol", desc->bDeviceProtocol); 667094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 668094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 669094332d3Sopenharmony_ci } 670094332d3Sopenharmony_ci ret = UsbFnWriteProp(devName, "bMaxPacketSize0", desc->bMaxPacketSize0); 671094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 672094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 673094332d3Sopenharmony_ci } 674094332d3Sopenharmony_ci return 0; 675094332d3Sopenharmony_ci} 676094332d3Sopenharmony_ci 677094332d3Sopenharmony_cistatic int32_t WriteDeviceDescriptor( 678094332d3Sopenharmony_ci const char *devName, const struct UsbDeviceDescriptor *desc, struct UsbFnStrings **strings) 679094332d3Sopenharmony_ci{ 680094332d3Sopenharmony_ci int32_t i, ret; 681094332d3Sopenharmony_ci ret = WriteDeviceId(devName, desc); 682094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 683094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 684094332d3Sopenharmony_ci } 685094332d3Sopenharmony_ci 686094332d3Sopenharmony_ci for (i = 0; strings[i] != NULL; i++) { 687094332d3Sopenharmony_ci ret = UsbFnWriteDesString( 688094332d3Sopenharmony_ci devName, strings[i]->language, "manufacturer", strings[i]->strings[desc->iManufacturer].s); 689094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 690094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 691094332d3Sopenharmony_ci } 692094332d3Sopenharmony_ci ret = UsbFnWriteDesString(devName, strings[i]->language, "product", strings[i]->strings[desc->iProduct].s); 693094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 694094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 695094332d3Sopenharmony_ci } 696094332d3Sopenharmony_ci } 697094332d3Sopenharmony_ci return 0; 698094332d3Sopenharmony_ci} 699094332d3Sopenharmony_ci 700094332d3Sopenharmony_cistatic int32_t CreatDeviceDir(const char *devName) 701094332d3Sopenharmony_ci{ 702094332d3Sopenharmony_ci int32_t ret; 703094332d3Sopenharmony_ci char tmp[MAX_PATHLEN]; 704094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 705094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, devName); 706094332d3Sopenharmony_ci if (ret < 0) { 707094332d3Sopenharmony_ci return HDF_ERR_IO; 708094332d3Sopenharmony_ci } 709094332d3Sopenharmony_ci if (!IsDirExist(tmp)) { 710094332d3Sopenharmony_ci ret = mkdir(tmp, S_IREAD | S_IWRITE); 711094332d3Sopenharmony_ci if (ret != 0) { 712094332d3Sopenharmony_ci HDF_LOGE("%{public}s: mkdir failed", __func__); 713094332d3Sopenharmony_ci return HDF_ERR_IO; 714094332d3Sopenharmony_ci } 715094332d3Sopenharmony_ci } 716094332d3Sopenharmony_ci return 0; 717094332d3Sopenharmony_ci} 718094332d3Sopenharmony_ci 719094332d3Sopenharmony_cistatic int32_t WriteConfPowerAttributes(const char *devName, struct UsbFnConfiguration *config, uint8_t confVal) 720094332d3Sopenharmony_ci{ 721094332d3Sopenharmony_ci int32_t ret; 722094332d3Sopenharmony_ci char configName[MAX_PATHLEN]; 723094332d3Sopenharmony_ci char tmp[MAX_PATHLEN], val[MAX_NAMELEN]; 724094332d3Sopenharmony_ci (void)memset_s(configName, MAX_PATHLEN, 0, MAX_PATHLEN); 725094332d3Sopenharmony_ci ret = snprintf_s(configName, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u", CONFIGFS_DIR, devName, confVal); 726094332d3Sopenharmony_ci if (ret < 0) { 727094332d3Sopenharmony_ci return HDF_ERR_IO; 728094332d3Sopenharmony_ci } 729094332d3Sopenharmony_ci if (!IsDirExist(configName)) { 730094332d3Sopenharmony_ci ret = mkdir(configName, S_IREAD | S_IWRITE); 731094332d3Sopenharmony_ci if (ret != 0) { 732094332d3Sopenharmony_ci return HDF_ERR_IO; 733094332d3Sopenharmony_ci } 734094332d3Sopenharmony_ci } 735094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 736094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/MaxPower", configName); 737094332d3Sopenharmony_ci if (ret < 0) { 738094332d3Sopenharmony_ci return HDF_ERR_IO; 739094332d3Sopenharmony_ci } 740094332d3Sopenharmony_ci (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN); 741094332d3Sopenharmony_ci ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "%u", config->maxPower); 742094332d3Sopenharmony_ci if (ret < 0) { 743094332d3Sopenharmony_ci return HDF_ERR_IO; 744094332d3Sopenharmony_ci } 745094332d3Sopenharmony_ci ret = UsbFnWriteFile(tmp, val); 746094332d3Sopenharmony_ci if (ret < 0) { 747094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 748094332d3Sopenharmony_ci } 749094332d3Sopenharmony_ci 750094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 751094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/bmAttributes", configName); 752094332d3Sopenharmony_ci if (ret < 0) { 753094332d3Sopenharmony_ci return HDF_ERR_IO; 754094332d3Sopenharmony_ci } 755094332d3Sopenharmony_ci (void)memset_s(val, MAX_NAMELEN, 0, MAX_NAMELEN); 756094332d3Sopenharmony_ci ret = snprintf_s(val, MAX_NAMELEN, MAX_NAMELEN - 1, "0x%x", config->attributes); 757094332d3Sopenharmony_ci if (ret < 0) { 758094332d3Sopenharmony_ci return HDF_ERR_IO; 759094332d3Sopenharmony_ci } 760094332d3Sopenharmony_ci ret = UsbFnWriteFile(tmp, val); 761094332d3Sopenharmony_ci if (ret < 0) { 762094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 763094332d3Sopenharmony_ci } 764094332d3Sopenharmony_ci return 0; 765094332d3Sopenharmony_ci} 766094332d3Sopenharmony_ci 767094332d3Sopenharmony_cistatic int32_t CreatKernelFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal) 768094332d3Sopenharmony_ci{ 769094332d3Sopenharmony_ci int32_t ret; 770094332d3Sopenharmony_ci char configPath[MAX_PATHLEN]; 771094332d3Sopenharmony_ci char funcPath[MAX_PATHLEN]; 772094332d3Sopenharmony_ci 773094332d3Sopenharmony_ci (void)memset_s(funcPath, MAX_PATHLEN, 0, MAX_PATHLEN); 774094332d3Sopenharmony_ci ret = snprintf_s( 775094332d3Sopenharmony_ci funcPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, functions->funcName); 776094332d3Sopenharmony_ci if (ret < 0) { 777094332d3Sopenharmony_ci return HDF_ERR_IO; 778094332d3Sopenharmony_ci } 779094332d3Sopenharmony_ci 780094332d3Sopenharmony_ci (void)memset_s(configPath, MAX_PATHLEN, 0, MAX_PATHLEN); 781094332d3Sopenharmony_ci ret = snprintf_s(configPath, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.%u/%s", CONFIGFS_DIR, devName, confVal, 782094332d3Sopenharmony_ci functions->funcName); 783094332d3Sopenharmony_ci if (ret < 0) { 784094332d3Sopenharmony_ci return HDF_ERR_IO; 785094332d3Sopenharmony_ci } 786094332d3Sopenharmony_ci ret = UsbFnAdapterCreateFunc(configPath, funcPath); 787094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 788094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterCreateFunc failed", __func__); 789094332d3Sopenharmony_ci return HDF_ERR_IO; 790094332d3Sopenharmony_ci } 791094332d3Sopenharmony_ci return ret; 792094332d3Sopenharmony_ci} 793094332d3Sopenharmony_ci 794094332d3Sopenharmony_cistatic void CleanConfigFs(const char *devName, const char *funcName); 795094332d3Sopenharmony_cistatic int32_t CreatFunc(const char *devName, const struct UsbFnFunction *functions, uint8_t confVal) 796094332d3Sopenharmony_ci{ 797094332d3Sopenharmony_ci int32_t fd, ret; 798094332d3Sopenharmony_ci char interfaceName[MAX_NAMELEN]; 799094332d3Sopenharmony_ci 800094332d3Sopenharmony_ci ret = CreatKernelFunc(devName, functions, confVal); 801094332d3Sopenharmony_ci if (ret < 0) { 802094332d3Sopenharmony_ci return HDF_ERR_IO; 803094332d3Sopenharmony_ci } 804094332d3Sopenharmony_ci 805094332d3Sopenharmony_ci (void)memset_s(interfaceName, MAX_NAMELEN, 0, MAX_NAMELEN); 806094332d3Sopenharmony_ci ret = snprintf_s(interfaceName, MAX_NAMELEN, MAX_NAMELEN - 1, "%s", functions->funcName); 807094332d3Sopenharmony_ci if (ret < 0) { 808094332d3Sopenharmony_ci return HDF_ERR_IO; 809094332d3Sopenharmony_ci } 810094332d3Sopenharmony_ci ret = UsbFnAdapterCreatInterface(interfaceName, strlen(interfaceName)); 811094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 812094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterCreatInterface failed", __func__); 813094332d3Sopenharmony_ci CleanConfigFs(devName, interfaceName); 814094332d3Sopenharmony_ci return HDF_ERR_IO; 815094332d3Sopenharmony_ci } 816094332d3Sopenharmony_ci 817094332d3Sopenharmony_ci fd = UsbFnAdapterOpenPipe(interfaceName, 0); 818094332d3Sopenharmony_ci if (fd <= 0) { 819094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterOpenPipe failed", __func__); 820094332d3Sopenharmony_ci CleanConfigFs(devName, interfaceName); 821094332d3Sopenharmony_ci return HDF_ERR_IO; 822094332d3Sopenharmony_ci } 823094332d3Sopenharmony_ci ret = UsbFnAdapterCreatPipes(fd, functions); 824094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 825094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterCreatPipes failed", __func__); 826094332d3Sopenharmony_ci UsbFnAdapterClosePipe(fd); 827094332d3Sopenharmony_ci return HDF_ERR_IO; 828094332d3Sopenharmony_ci } 829094332d3Sopenharmony_ci ret = UsbFnAdapterClosePipe(fd); 830094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 831094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterClosePipe failed", __func__); 832094332d3Sopenharmony_ci return HDF_ERR_IO; 833094332d3Sopenharmony_ci } 834094332d3Sopenharmony_ci return 0; 835094332d3Sopenharmony_ci} 836094332d3Sopenharmony_ci 837094332d3Sopenharmony_cistatic void DelConfigDevice(const char *deviceName) 838094332d3Sopenharmony_ci{ 839094332d3Sopenharmony_ci int32_t ret; 840094332d3Sopenharmony_ci char tmp[MAX_PATHLEN]; 841094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 842094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs", CONFIGFS_DIR, deviceName); 843094332d3Sopenharmony_ci if (ret < 0) { 844094332d3Sopenharmony_ci return; 845094332d3Sopenharmony_ci } 846094332d3Sopenharmony_ci DeleteFile(tmp); 847094332d3Sopenharmony_ci 848094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 849094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions", CONFIGFS_DIR, deviceName); 850094332d3Sopenharmony_ci if (ret < 0) { 851094332d3Sopenharmony_ci return; 852094332d3Sopenharmony_ci } 853094332d3Sopenharmony_ci DeleteFile(tmp); 854094332d3Sopenharmony_ci 855094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 856094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/strings", CONFIGFS_DIR, deviceName); 857094332d3Sopenharmony_ci if (ret < 0) { 858094332d3Sopenharmony_ci return; 859094332d3Sopenharmony_ci } 860094332d3Sopenharmony_ci DeleteFile(tmp); 861094332d3Sopenharmony_ci 862094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 863094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s", CONFIGFS_DIR, deviceName); 864094332d3Sopenharmony_ci if (ret < 0) { 865094332d3Sopenharmony_ci return; 866094332d3Sopenharmony_ci } 867094332d3Sopenharmony_ci rmdir(tmp); 868094332d3Sopenharmony_ci} 869094332d3Sopenharmony_ci 870094332d3Sopenharmony_cistatic void CleanConfigFs(const char *devName, const char *funcName) 871094332d3Sopenharmony_ci{ 872094332d3Sopenharmony_ci int32_t ret; 873094332d3Sopenharmony_ci char tmp[MAX_PATHLEN]; 874094332d3Sopenharmony_ci 875094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 876094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/configs/b.1/%s", CONFIGFS_DIR, devName, funcName); 877094332d3Sopenharmony_ci if (ret < 0) { 878094332d3Sopenharmony_ci return; 879094332d3Sopenharmony_ci } 880094332d3Sopenharmony_ci (void)remove(tmp); 881094332d3Sopenharmony_ci 882094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 883094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/%s", CONFIGFS_DIR, devName, funcName); 884094332d3Sopenharmony_ci if (ret < 0) { 885094332d3Sopenharmony_ci return; 886094332d3Sopenharmony_ci } 887094332d3Sopenharmony_ci (void)remove(tmp); 888094332d3Sopenharmony_ci} 889094332d3Sopenharmony_ci 890094332d3Sopenharmony_cistatic void CleanFunction(const char *devName, const char *funcName) 891094332d3Sopenharmony_ci{ 892094332d3Sopenharmony_ci int32_t ret; 893094332d3Sopenharmony_ci int32_t nameLength = (int32_t)strlen(funcName); 894094332d3Sopenharmony_ci ret = UsbFnAdapterDelInterface(funcName, nameLength); 895094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 896094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnAdapterDelInterface failed", __func__); 897094332d3Sopenharmony_ci return; 898094332d3Sopenharmony_ci } 899094332d3Sopenharmony_ci CleanConfigFs(devName, funcName); 900094332d3Sopenharmony_ci} 901094332d3Sopenharmony_ci 902094332d3Sopenharmony_cistatic void UsbFnAdapterCleanDevice(const char *devName) 903094332d3Sopenharmony_ci{ 904094332d3Sopenharmony_ci int32_t ret; 905094332d3Sopenharmony_ci char tmp[MAX_PATHLEN]; 906094332d3Sopenharmony_ci DIR *dir = NULL; 907094332d3Sopenharmony_ci struct dirent *ptr = NULL; 908094332d3Sopenharmony_ci 909094332d3Sopenharmony_ci (void)memset_s(tmp, MAX_PATHLEN, 0, MAX_PATHLEN); 910094332d3Sopenharmony_ci ret = snprintf_s(tmp, MAX_PATHLEN, MAX_PATHLEN - 1, "%s/%s/functions/", CONFIGFS_DIR, devName); 911094332d3Sopenharmony_ci if (ret < 0) { 912094332d3Sopenharmony_ci HDF_LOGE("%{public}s: snprintf_s failed", __func__); 913094332d3Sopenharmony_ci return; 914094332d3Sopenharmony_ci } 915094332d3Sopenharmony_ci if ((dir = opendir(tmp)) == NULL) { 916094332d3Sopenharmony_ci return; 917094332d3Sopenharmony_ci } 918094332d3Sopenharmony_ci while ((ptr = readdir(dir)) != NULL) { 919094332d3Sopenharmony_ci if (strncmp(ptr->d_name, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC))) { 920094332d3Sopenharmony_ci continue; 921094332d3Sopenharmony_ci } 922094332d3Sopenharmony_ci CleanFunction(devName, ptr->d_name); 923094332d3Sopenharmony_ci } 924094332d3Sopenharmony_ci closedir(dir); 925094332d3Sopenharmony_ci} 926094332d3Sopenharmony_ci 927094332d3Sopenharmony_cistatic int32_t UsbFnAdapterDelDevice(const char *deviceName, const char *udcName, struct UsbFnDeviceDesc *des) 928094332d3Sopenharmony_ci{ 929094332d3Sopenharmony_ci uint32_t i, j; 930094332d3Sopenharmony_ci int32_t ret; 931094332d3Sopenharmony_ci if (deviceName == NULL) { 932094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 933094332d3Sopenharmony_ci } 934094332d3Sopenharmony_ci ret = UsbFnAdapterWriteUDC(deviceName, udcName, 0); 935094332d3Sopenharmony_ci if (ret < 0) { 936094332d3Sopenharmony_ci return ret; 937094332d3Sopenharmony_ci } 938094332d3Sopenharmony_ci for (i = 0; des->configs[i] != NULL; i++) { 939094332d3Sopenharmony_ci for (j = 0; des->configs[i]->functions[j] != NULL; j++) { 940094332d3Sopenharmony_ci if (des->configs[i]->functions[j]->enable == false) { 941094332d3Sopenharmony_ci continue; 942094332d3Sopenharmony_ci } 943094332d3Sopenharmony_ci if (strncmp(des->configs[i]->functions[j]->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) { 944094332d3Sopenharmony_ci CleanConfigFs(deviceName, des->configs[i]->functions[j]->funcName); 945094332d3Sopenharmony_ci continue; 946094332d3Sopenharmony_ci } 947094332d3Sopenharmony_ci CleanFunction(deviceName, des->configs[i]->functions[j]->funcName); 948094332d3Sopenharmony_ci } 949094332d3Sopenharmony_ci } 950094332d3Sopenharmony_ci 951094332d3Sopenharmony_ci if (strcmp("g1", deviceName) != 0) { 952094332d3Sopenharmony_ci DelConfigDevice(deviceName); 953094332d3Sopenharmony_ci } 954094332d3Sopenharmony_ci return 0; 955094332d3Sopenharmony_ci} 956094332d3Sopenharmony_ci 957094332d3Sopenharmony_cistatic bool CreateFun(struct UsbFnFunction *function, const char *devName, uint8_t *confVal, int32_t *ret) 958094332d3Sopenharmony_ci{ 959094332d3Sopenharmony_ci if (function == NULL || devName == NULL || confVal == NULL || ret == NULL) { 960094332d3Sopenharmony_ci return false; 961094332d3Sopenharmony_ci } 962094332d3Sopenharmony_ci 963094332d3Sopenharmony_ci if (function->enable == false) { 964094332d3Sopenharmony_ci return false; 965094332d3Sopenharmony_ci } 966094332d3Sopenharmony_ci if (strncmp(function->funcName, FUNCTION_GENERIC, strlen(FUNCTION_GENERIC)) != 0) { 967094332d3Sopenharmony_ci *ret = CreatKernelFunc(devName, function, *confVal); 968094332d3Sopenharmony_ci } else { 969094332d3Sopenharmony_ci *ret = CreatFunc(devName, function, *confVal); 970094332d3Sopenharmony_ci } 971094332d3Sopenharmony_ci return true; 972094332d3Sopenharmony_ci} 973094332d3Sopenharmony_ci 974094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCreateDevice(const char *udcName, const char *devName, struct UsbFnDeviceDesc *descriptor) 975094332d3Sopenharmony_ci{ 976094332d3Sopenharmony_ci uint32_t i, j; 977094332d3Sopenharmony_ci int32_t ret; 978094332d3Sopenharmony_ci uint8_t confVal; 979094332d3Sopenharmony_ci 980094332d3Sopenharmony_ci UsbFnAdapterCleanDevice(devName); 981094332d3Sopenharmony_ci 982094332d3Sopenharmony_ci ret = CreatDeviceDir(devName); 983094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 984094332d3Sopenharmony_ci return HDF_ERR_IO; 985094332d3Sopenharmony_ci } 986094332d3Sopenharmony_ci 987094332d3Sopenharmony_ci ret = WriteDeviceDescriptor(devName, descriptor->deviceDesc, descriptor->deviceStrings); 988094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 989094332d3Sopenharmony_ci HDF_LOGE("%{public}s: WriteDeviceDescriptor failed", __func__); 990094332d3Sopenharmony_ci return HDF_ERR_IO; 991094332d3Sopenharmony_ci } 992094332d3Sopenharmony_ci 993094332d3Sopenharmony_ci for (i = 0; descriptor->configs[i] != NULL; i++) { 994094332d3Sopenharmony_ci confVal = descriptor->configs[i]->configurationValue; 995094332d3Sopenharmony_ci ret = WriteConfPowerAttributes(devName, descriptor->configs[i], confVal); 996094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 997094332d3Sopenharmony_ci HDF_LOGE("%{public}s: WriteConfPowerAttributes failed", __func__); 998094332d3Sopenharmony_ci return HDF_ERR_IO; 999094332d3Sopenharmony_ci } 1000094332d3Sopenharmony_ci 1001094332d3Sopenharmony_ci for (j = 0; descriptor->deviceStrings[j] != NULL; j++) { 1002094332d3Sopenharmony_ci ret = UsbFnWriteConfString(devName, confVal, descriptor->deviceStrings[j]->language, 1003094332d3Sopenharmony_ci descriptor->deviceStrings[j]->strings[descriptor->configs[i]->iConfiguration].s); 1004094332d3Sopenharmony_ci if (ret < 0) { 1005094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbFnWriteConfString failed", __func__); 1006094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1007094332d3Sopenharmony_ci } 1008094332d3Sopenharmony_ci } 1009094332d3Sopenharmony_ci 1010094332d3Sopenharmony_ci for (j = 0; descriptor->configs[i]->functions[j] != NULL; j++) { 1011094332d3Sopenharmony_ci if (!CreateFun(descriptor->configs[i]->functions[j], devName, &confVal, &ret)) { 1012094332d3Sopenharmony_ci continue; 1013094332d3Sopenharmony_ci } 1014094332d3Sopenharmony_ci if (ret < 0) { 1015094332d3Sopenharmony_ci HDF_LOGE("%{public}s: CreatFunc failed", __func__); 1016094332d3Sopenharmony_ci (void)UsbFnAdapterWriteUDC(devName, "none", 0); 1017094332d3Sopenharmony_ci (void)UsbFnAdapterWriteUDC(devName, udcName, 1); 1018094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1019094332d3Sopenharmony_ci } 1020094332d3Sopenharmony_ci } 1021094332d3Sopenharmony_ci } 1022094332d3Sopenharmony_ci 1023094332d3Sopenharmony_ci return HDF_SUCCESS; 1024094332d3Sopenharmony_ci} 1025094332d3Sopenharmony_ci 1026094332d3Sopenharmony_cistatic int32_t UsbFnAdapterGetPipeInfo(int32_t ep, struct UsbFnPipeInfo * const pipeInfo) 1027094332d3Sopenharmony_ci{ 1028094332d3Sopenharmony_ci int32_t ret; 1029094332d3Sopenharmony_ci if (ep <= 0 || pipeInfo == NULL) { 1030094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1031094332d3Sopenharmony_ci } 1032094332d3Sopenharmony_ci 1033094332d3Sopenharmony_ci struct UsbEndpointDescriptor desc; 1034094332d3Sopenharmony_ci ret = ioctl(ep, FUNCTIONFS_ENDPOINT_DESC, &desc); 1035094332d3Sopenharmony_ci if (ret != 0) { 1036094332d3Sopenharmony_ci HDF_LOGE("%{public}s: FUNCTIONFS_ENDPOINT_DESC failed", __func__); 1037094332d3Sopenharmony_ci return HDF_ERR_IO; 1038094332d3Sopenharmony_ci } 1039094332d3Sopenharmony_ci 1040094332d3Sopenharmony_ci pipeInfo->type = desc.bmAttributes; 1041094332d3Sopenharmony_ci pipeInfo->dir = USB_PIPE_DIRECTION_OUT; 1042094332d3Sopenharmony_ci if (desc.bEndpointAddress & 0x80) { 1043094332d3Sopenharmony_ci pipeInfo->dir = USB_PIPE_DIRECTION_IN; 1044094332d3Sopenharmony_ci } 1045094332d3Sopenharmony_ci 1046094332d3Sopenharmony_ci pipeInfo->maxPacketSize = desc.wMaxPacketSize; 1047094332d3Sopenharmony_ci pipeInfo->interval = desc.bInterval; 1048094332d3Sopenharmony_ci 1049094332d3Sopenharmony_ci return ret; 1050094332d3Sopenharmony_ci} 1051094332d3Sopenharmony_ci 1052094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueInit(int32_t ep) 1053094332d3Sopenharmony_ci{ 1054094332d3Sopenharmony_ci if (ep <= 0) { 1055094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1056094332d3Sopenharmony_ci } 1057094332d3Sopenharmony_ci return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_INIT, 0); 1058094332d3Sopenharmony_ci} 1059094332d3Sopenharmony_ci 1060094332d3Sopenharmony_cistatic int32_t UsbFnAdapterQueueDel(int32_t ep) 1061094332d3Sopenharmony_ci{ 1062094332d3Sopenharmony_ci if (ep <= 0) { 1063094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1064094332d3Sopenharmony_ci } 1065094332d3Sopenharmony_ci 1066094332d3Sopenharmony_ci return ioctl(ep, FUNCTIONFS_ENDPOINT_QUEUE_DEL, 0); 1067094332d3Sopenharmony_ci} 1068094332d3Sopenharmony_ci 1069094332d3Sopenharmony_cistatic int32_t UsbFnAdapterReleaseBuf(int32_t ep, const struct GenericMemory *mem) 1070094332d3Sopenharmony_ci{ 1071094332d3Sopenharmony_ci if (ep <= 0 || mem == NULL) { 1072094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1073094332d3Sopenharmony_ci } 1074094332d3Sopenharmony_ci 1075094332d3Sopenharmony_ci return ioctl(ep, FUNCTIONFS_ENDPOINT_RELEASE_BUF, mem); 1076094332d3Sopenharmony_ci} 1077094332d3Sopenharmony_ci 1078094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPipeIo(int32_t ep, struct IoData *ioData) 1079094332d3Sopenharmony_ci{ 1080094332d3Sopenharmony_ci int32_t ret; 1081094332d3Sopenharmony_ci if (ep <= 0 || ioData == NULL) { 1082094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param", __func__); 1083094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1084094332d3Sopenharmony_ci } 1085094332d3Sopenharmony_ci 1086094332d3Sopenharmony_ci if (ioData->read) { 1087094332d3Sopenharmony_ci ret = ioctl(ep, FUNCTIONFS_ENDPOINT_READ, ioData); 1088094332d3Sopenharmony_ci } else { 1089094332d3Sopenharmony_ci ret = ioctl(ep, FUNCTIONFS_ENDPOINT_WRITE, ioData); 1090094332d3Sopenharmony_ci } 1091094332d3Sopenharmony_ci 1092094332d3Sopenharmony_ci if (ret < 0) { 1093094332d3Sopenharmony_ci HDF_LOGE("%{public}s: handle endpoint failed errno:%{public}d", __func__, errno); 1094094332d3Sopenharmony_ci } 1095094332d3Sopenharmony_ci 1096094332d3Sopenharmony_ci return ret; 1097094332d3Sopenharmony_ci} 1098094332d3Sopenharmony_ci 1099094332d3Sopenharmony_cistatic int32_t UsbFnAdapterCancelIo(int32_t ep, const struct IoData * const ioData) 1100094332d3Sopenharmony_ci{ 1101094332d3Sopenharmony_ci if (ep <= 0 || ioData == NULL) { 1102094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1103094332d3Sopenharmony_ci } 1104094332d3Sopenharmony_ci return ioctl(ep, FUNCTIONFS_ENDPOINT_RW_CANCEL, ioData); 1105094332d3Sopenharmony_ci} 1106094332d3Sopenharmony_ci 1107094332d3Sopenharmony_cistatic uint8_t *UsbFnAdapterMapAddr(int32_t ep, uint32_t len) 1108094332d3Sopenharmony_ci{ 1109094332d3Sopenharmony_ci if (ep <= 0) { 1110094332d3Sopenharmony_ci return NULL; 1111094332d3Sopenharmony_ci } 1112094332d3Sopenharmony_ci 1113094332d3Sopenharmony_ci return mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, ep, 0); 1114094332d3Sopenharmony_ci} 1115094332d3Sopenharmony_ci 1116094332d3Sopenharmony_cistatic int32_t UsbFnAdapterUnmapAddr(uint8_t * const mapAddr, uint32_t len) 1117094332d3Sopenharmony_ci{ 1118094332d3Sopenharmony_ci if (mapAddr == NULL) { 1119094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1120094332d3Sopenharmony_ci } 1121094332d3Sopenharmony_ci 1122094332d3Sopenharmony_ci return munmap(mapAddr, len); 1123094332d3Sopenharmony_ci} 1124094332d3Sopenharmony_ci 1125094332d3Sopenharmony_cistatic void Ep0Event(struct UsbFnEventAll *event, struct pollfd *pfds) 1126094332d3Sopenharmony_ci{ 1127094332d3Sopenharmony_ci int32_t ret; 1128094332d3Sopenharmony_ci uint8_t i; 1129094332d3Sopenharmony_ci for (i = 0; i < event->ep0Num; i++) { 1130094332d3Sopenharmony_ci if ((uint32_t)pfds[i].revents & POLLIN) { 1131094332d3Sopenharmony_ci ret = read(event->ep0[i], &event->ep0Event[i].ctrlEvent, sizeof(struct UsbFnCtrlEvent)); 1132094332d3Sopenharmony_ci if (!ret) { 1133094332d3Sopenharmony_ci HDF_LOGE("unable to read event from ep0"); 1134094332d3Sopenharmony_ci } 1135094332d3Sopenharmony_ci event->ep0Event[i].type = USB_EP0_CTRL_EVENT; 1136094332d3Sopenharmony_ci } else if ((uint32_t)pfds[i].revents & POLLOUT) { 1137094332d3Sopenharmony_ci ret = ioctl(event->ep0[i], FUNCTIONFS_ENDPOINT_GET_EP0_EVENT, &event->ep0Event[i].reqEvent); 1138094332d3Sopenharmony_ci if (!ret) { 1139094332d3Sopenharmony_ci HDF_LOGE("unable to read reqEvent from ep0"); 1140094332d3Sopenharmony_ci } 1141094332d3Sopenharmony_ci event->ep0Event[i].type = USB_EP0_IO_COMPLETED; 1142094332d3Sopenharmony_ci } 1143094332d3Sopenharmony_ci } 1144094332d3Sopenharmony_ci} 1145094332d3Sopenharmony_ci 1146094332d3Sopenharmony_cistatic void EpEvent(struct UsbFnEventAll *event, struct pollfd *pfds) 1147094332d3Sopenharmony_ci{ 1148094332d3Sopenharmony_ci uint8_t i; 1149094332d3Sopenharmony_ci for (i = 0; i < event->epNum; i++) { 1150094332d3Sopenharmony_ci if ((pfds[i + event->ep0Num].revents & POLLIN)) { 1151094332d3Sopenharmony_ci event->numEvent[i] = read(event->epx[i], event->reqEvent[i], MAX_REQUEST * sizeof(struct UsbFnReqEvent)) / 1152094332d3Sopenharmony_ci sizeof(struct UsbFnReqEvent); 1153094332d3Sopenharmony_ci if (!event->numEvent[i]) { 1154094332d3Sopenharmony_ci HDF_LOGE("unable to read indexBuf from ep#"); 1155094332d3Sopenharmony_ci } 1156094332d3Sopenharmony_ci } 1157094332d3Sopenharmony_ci } 1158094332d3Sopenharmony_ci} 1159094332d3Sopenharmony_ci 1160094332d3Sopenharmony_cistatic int32_t UsbFnAdapterPollEvent(struct UsbFnEventAll *event, int32_t timeout) 1161094332d3Sopenharmony_ci{ 1162094332d3Sopenharmony_ci int32_t ret; 1163094332d3Sopenharmony_ci uint8_t i; 1164094332d3Sopenharmony_ci struct pollfd *pfds = NULL; 1165094332d3Sopenharmony_ci 1166094332d3Sopenharmony_ci if (event == NULL) { 1167094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1168094332d3Sopenharmony_ci } 1169094332d3Sopenharmony_ci if (event->ep0Num + event->epNum == 0) { 1170094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1171094332d3Sopenharmony_ci } 1172094332d3Sopenharmony_ci pfds = UsbFnMemCalloc((event->ep0Num + event->epNum) * sizeof(struct pollfd)); 1173094332d3Sopenharmony_ci if (pfds == NULL) { 1174094332d3Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 1175094332d3Sopenharmony_ci } 1176094332d3Sopenharmony_ci for (i = 0; i < event->ep0Num; i++) { 1177094332d3Sopenharmony_ci if (event->ep0[i] <= 0) { 1178094332d3Sopenharmony_ci UsbFnMemFree(pfds); 1179094332d3Sopenharmony_ci HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->ep0[i]); 1180094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1181094332d3Sopenharmony_ci } 1182094332d3Sopenharmony_ci pfds[i].fd = event->ep0[i]; 1183094332d3Sopenharmony_ci pfds[i].events = POLLIN | POLLOUT; 1184094332d3Sopenharmony_ci } 1185094332d3Sopenharmony_ci for (i = 0; i < event->epNum; i++) { 1186094332d3Sopenharmony_ci if (event->epx[i] <= 0) { 1187094332d3Sopenharmony_ci UsbFnMemFree(pfds); 1188094332d3Sopenharmony_ci HDF_LOGE("%{public}s: ep[%{public}d] = %{public}d", __func__, i, event->epx[i]); 1189094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1190094332d3Sopenharmony_ci } 1191094332d3Sopenharmony_ci pfds[i + event->ep0Num].fd = event->epx[i]; 1192094332d3Sopenharmony_ci pfds[i + event->ep0Num].events = POLLIN; 1193094332d3Sopenharmony_ci } 1194094332d3Sopenharmony_ci ret = poll(pfds, event->ep0Num + event->epNum, timeout); 1195094332d3Sopenharmony_ci if (ret == 0) { 1196094332d3Sopenharmony_ci UsbFnMemFree(pfds); 1197094332d3Sopenharmony_ci return HDF_ERR_TIMEOUT; 1198094332d3Sopenharmony_ci } else if (ret < 0) { 1199094332d3Sopenharmony_ci HDF_LOGE("%{public}s: interrupt", __func__); 1200094332d3Sopenharmony_ci UsbFnMemFree(pfds); 1201094332d3Sopenharmony_ci return HDF_ERR_IO; 1202094332d3Sopenharmony_ci } 1203094332d3Sopenharmony_ci Ep0Event(event, pfds); 1204094332d3Sopenharmony_ci EpEvent(event, pfds); 1205094332d3Sopenharmony_ci UsbFnMemFree(pfds); 1206094332d3Sopenharmony_ci return 0; 1207094332d3Sopenharmony_ci} 1208094332d3Sopenharmony_ci 1209094332d3Sopenharmony_cistatic int32_t UsbFnAdapterRequestGetStatus(int32_t ep, const struct IoData *ioData) 1210094332d3Sopenharmony_ci{ 1211094332d3Sopenharmony_ci if (ep <= 0 || ioData == NULL) { 1212094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 1213094332d3Sopenharmony_ci } 1214094332d3Sopenharmony_ci return ioctl(ep, FUNCTIONFS_ENDPOINT_GET_REQ_STATUS, ioData); 1215094332d3Sopenharmony_ci} 1216094332d3Sopenharmony_ci 1217094332d3Sopenharmony_civoid *UsbFnMemAlloc(size_t size) 1218094332d3Sopenharmony_ci{ 1219094332d3Sopenharmony_ci return UsbFnMemCalloc(size); 1220094332d3Sopenharmony_ci} 1221094332d3Sopenharmony_ci 1222094332d3Sopenharmony_civoid *UsbFnMemCalloc(size_t size) 1223094332d3Sopenharmony_ci{ 1224094332d3Sopenharmony_ci void *buf = OsalMemCalloc(size); 1225094332d3Sopenharmony_ci if (buf == NULL) { 1226094332d3Sopenharmony_ci HDF_LOGE("%{public}s: %{public}d, OsalMemCalloc failed", __func__, __LINE__); 1227094332d3Sopenharmony_ci return NULL; 1228094332d3Sopenharmony_ci } 1229094332d3Sopenharmony_ci return buf; 1230094332d3Sopenharmony_ci} 1231094332d3Sopenharmony_ci 1232094332d3Sopenharmony_civoid UsbFnMemFree(const void *mem) 1233094332d3Sopenharmony_ci{ 1234094332d3Sopenharmony_ci if (mem == NULL) { 1235094332d3Sopenharmony_ci HDF_LOGE("%{public}s:%{public}d invalid param mem.", __func__, __LINE__); 1236094332d3Sopenharmony_ci return; 1237094332d3Sopenharmony_ci } 1238094332d3Sopenharmony_ci OsalMemFree((void *)mem); 1239094332d3Sopenharmony_ci mem = NULL; 1240094332d3Sopenharmony_ci} 1241094332d3Sopenharmony_ci 1242094332d3Sopenharmony_cistatic struct UsbFnAdapterOps g_usbFnAdapter = { 1243094332d3Sopenharmony_ci .createDevice = UsbFnAdapterCreateDevice, 1244094332d3Sopenharmony_ci .delDevice = UsbFnAdapterDelDevice, 1245094332d3Sopenharmony_ci 1246094332d3Sopenharmony_ci .openPipe = UsbFnAdapterOpenPipe, 1247094332d3Sopenharmony_ci .closePipe = UsbFnAdapterClosePipe, 1248094332d3Sopenharmony_ci .getPipeInfo = UsbFnAdapterGetPipeInfo, 1249094332d3Sopenharmony_ci 1250094332d3Sopenharmony_ci .queueInit = UsbFnAdapterQueueInit, 1251094332d3Sopenharmony_ci .queueDel = UsbFnAdapterQueueDel, 1252094332d3Sopenharmony_ci .releaseBuf = UsbFnAdapterReleaseBuf, 1253094332d3Sopenharmony_ci .pipeIo = UsbFnAdapterPipeIo, 1254094332d3Sopenharmony_ci .cancelIo = UsbFnAdapterCancelIo, 1255094332d3Sopenharmony_ci .getReqStatus = UsbFnAdapterRequestGetStatus, 1256094332d3Sopenharmony_ci .mapAddr = UsbFnAdapterMapAddr, 1257094332d3Sopenharmony_ci .unmapAddr = UsbFnAdapterUnmapAddr, 1258094332d3Sopenharmony_ci .pollEvent = UsbFnAdapterPollEvent, 1259094332d3Sopenharmony_ci .writeUDC = UsbFnAdapterWriteUDC, 1260094332d3Sopenharmony_ci .writeProp = UsbFnWriteProp, 1261094332d3Sopenharmony_ci .writeDesString = UsbFnWriteDesString, 1262094332d3Sopenharmony_ci}; 1263094332d3Sopenharmony_ci 1264094332d3Sopenharmony_cistruct UsbFnAdapterOps *UsbFnAdapterGetOps(void) 1265094332d3Sopenharmony_ci{ 1266094332d3Sopenharmony_ci return &g_usbFnAdapter; 1267094332d3Sopenharmony_ci} 1268