1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 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 "device_resource_if.h" 17094332d3Sopenharmony_ci#include "hdf_base.h" 18094332d3Sopenharmony_ci#include "hdf_device_desc.h" 19094332d3Sopenharmony_ci#include "hdf_device_object.h" 20094332d3Sopenharmony_ci#include "hdf_log.h" 21094332d3Sopenharmony_ci#include "osal_mem.h" 22094332d3Sopenharmony_ci#include "osal_time.h" 23094332d3Sopenharmony_ci#include "securec.h" 24094332d3Sopenharmony_ci#include "usbfn_device.h" 25094332d3Sopenharmony_ci#include "usbfn_interface.h" 26094332d3Sopenharmony_ci#include "usbfn_request.h" 27094332d3Sopenharmony_ci 28094332d3Sopenharmony_ci#define HDF_LOG_TAG dev_usbfn 29094332d3Sopenharmony_ci#define UDC_NAME "invalid_udc_name" 30094332d3Sopenharmony_ci 31094332d3Sopenharmony_cienum DevUsbFnCmd { 32094332d3Sopenharmony_ci DEV_USBFN_INIT = 0x1, 33094332d3Sopenharmony_ci DEV_USBFN_RELEASE, 34094332d3Sopenharmony_ci}; 35094332d3Sopenharmony_ci 36094332d3Sopenharmony_cistruct DevUsbFnMgr { 37094332d3Sopenharmony_ci struct IDeviceIoService service; 38094332d3Sopenharmony_ci struct UsbFnDescriptorData descData; 39094332d3Sopenharmony_ci struct HdfDeviceObject *device; 40094332d3Sopenharmony_ci const char *udcName; 41094332d3Sopenharmony_ci}; 42094332d3Sopenharmony_ci 43094332d3Sopenharmony_cistruct UsbFnDevice *g_fnDev = NULL; 44094332d3Sopenharmony_cistatic int32_t UsbFnReleaseFuncDevice(void) 45094332d3Sopenharmony_ci{ 46094332d3Sopenharmony_ci int32_t ret; 47094332d3Sopenharmony_ci if (g_fnDev == NULL) { 48094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fnDev is null", __func__); 49094332d3Sopenharmony_ci return HDF_FAILURE; 50094332d3Sopenharmony_ci } 51094332d3Sopenharmony_ci ret = UsbFnRemoveDevice(g_fnDev); 52094332d3Sopenharmony_ci if (ret == HDF_SUCCESS) { 53094332d3Sopenharmony_ci g_fnDev = NULL; 54094332d3Sopenharmony_ci } else { 55094332d3Sopenharmony_ci HDF_LOGE("%{public}s: remove usb function device failed", __func__); 56094332d3Sopenharmony_ci } 57094332d3Sopenharmony_ci 58094332d3Sopenharmony_ci return ret; 59094332d3Sopenharmony_ci} 60094332d3Sopenharmony_ci 61094332d3Sopenharmony_cistatic int32_t UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) 62094332d3Sopenharmony_ci{ 63094332d3Sopenharmony_ci struct HdfDeviceObject *device = client->device; 64094332d3Sopenharmony_ci struct DevUsbFnMgr *devMgr = NULL; 65094332d3Sopenharmony_ci struct UsbFnDevice *fnDev = NULL; 66094332d3Sopenharmony_ci uint8_t value; 67094332d3Sopenharmony_ci struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 68094332d3Sopenharmony_ci 69094332d3Sopenharmony_ci if (iface == NULL || iface->GetUint32 == NULL || device == NULL) { 70094332d3Sopenharmony_ci HDF_LOGE("%{public}s: iface is invalid", __func__); 71094332d3Sopenharmony_ci return HDF_FAILURE; 72094332d3Sopenharmony_ci } 73094332d3Sopenharmony_ci devMgr = (struct DevUsbFnMgr *)device->service; 74094332d3Sopenharmony_ci if (HdfSbufReadUint8(data, &value) != true) { 75094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read sbuf failed", __func__); 76094332d3Sopenharmony_ci return HDF_FAILURE; 77094332d3Sopenharmony_ci } 78094332d3Sopenharmony_ci HDF_LOGI("%{public}s: data=%{public}d, descriptor in %{public}s", __func__, value, 79094332d3Sopenharmony_ci (devMgr->descData.type == USBFN_DESC_DATA_TYPE_DESC ? "code" : "hcs")); 80094332d3Sopenharmony_ci devMgr->descData.functionMask = value; 81094332d3Sopenharmony_ci fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData); 82094332d3Sopenharmony_ci if (fnDev == NULL) { 83094332d3Sopenharmony_ci HDF_LOGE("%{public}s: create usb function device failed", __func__); 84094332d3Sopenharmony_ci if (!HdfSbufWriteInt8(reply, 0)) { 85094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__); 86094332d3Sopenharmony_ci } 87094332d3Sopenharmony_ci return HDF_FAILURE; 88094332d3Sopenharmony_ci } 89094332d3Sopenharmony_ci g_fnDev = fnDev; 90094332d3Sopenharmony_ci if (!HdfSbufWriteInt8(reply, value)) { 91094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__); 92094332d3Sopenharmony_ci return HDF_FAILURE; 93094332d3Sopenharmony_ci } 94094332d3Sopenharmony_ci HDF_LOGI("%{public}s: create device done, reply: %{public}d", __func__, value); 95094332d3Sopenharmony_ci return HDF_SUCCESS; 96094332d3Sopenharmony_ci} 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_cistatic int32_t UsbFnDispatch( 99094332d3Sopenharmony_ci struct HdfDeviceIoClient *client, int32_t cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 100094332d3Sopenharmony_ci{ 101094332d3Sopenharmony_ci int32_t ret; 102094332d3Sopenharmony_ci if (client == NULL) { 103094332d3Sopenharmony_ci HDF_LOGE("%{public}s: client is NULL", __func__); 104094332d3Sopenharmony_ci return HDF_FAILURE; 105094332d3Sopenharmony_ci } 106094332d3Sopenharmony_ci 107094332d3Sopenharmony_ci if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) { 108094332d3Sopenharmony_ci HDF_LOGE("%{public}s: check interface desc fail", __func__); 109094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 110094332d3Sopenharmony_ci } 111094332d3Sopenharmony_ci 112094332d3Sopenharmony_ci switch (cmdId) { 113094332d3Sopenharmony_ci case DEV_USBFN_INIT: 114094332d3Sopenharmony_ci ret = UsbFnRegistUsbfnDevice(client, data, reply); 115094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 116094332d3Sopenharmony_ci HDF_LOGE("%{public}s: create usbfn device failed", __func__); 117094332d3Sopenharmony_ci } 118094332d3Sopenharmony_ci break; 119094332d3Sopenharmony_ci case DEV_USBFN_RELEASE: 120094332d3Sopenharmony_ci ret = UsbFnReleaseFuncDevice(); 121094332d3Sopenharmony_ci break; 122094332d3Sopenharmony_ci default: 123094332d3Sopenharmony_ci ret = HDF_ERR_INVALID_OBJECT; 124094332d3Sopenharmony_ci HDF_LOGE("%{public}s: unknown cmd id %{public}d", __func__, cmdId); 125094332d3Sopenharmony_ci break; 126094332d3Sopenharmony_ci } 127094332d3Sopenharmony_ci return ret; 128094332d3Sopenharmony_ci} 129094332d3Sopenharmony_ci 130094332d3Sopenharmony_ci/* HdfDriverEntry implementations */ 131094332d3Sopenharmony_cistatic int32_t UsbFnDriverBind(struct HdfDeviceObject *device) 132094332d3Sopenharmony_ci{ 133094332d3Sopenharmony_ci struct DevUsbFnMgr *devMgr = NULL; 134094332d3Sopenharmony_ci if (device == NULL) { 135094332d3Sopenharmony_ci HDF_LOGE("%{public}s: device is null", __func__); 136094332d3Sopenharmony_ci return HDF_FAILURE; 137094332d3Sopenharmony_ci } 138094332d3Sopenharmony_ci devMgr = (struct DevUsbFnMgr *)OsalMemCalloc(sizeof(*devMgr)); 139094332d3Sopenharmony_ci if (devMgr == NULL) { 140094332d3Sopenharmony_ci HDF_LOGE("%{public}s: usbfn Alloc usb devMgr failed", __func__); 141094332d3Sopenharmony_ci return HDF_FAILURE; 142094332d3Sopenharmony_ci } 143094332d3Sopenharmony_ci 144094332d3Sopenharmony_ci if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) { 145094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Set Desc fail!", __func__); 146094332d3Sopenharmony_ci OsalMemFree(devMgr); 147094332d3Sopenharmony_ci return HDF_FAILURE; 148094332d3Sopenharmony_ci } 149094332d3Sopenharmony_ci 150094332d3Sopenharmony_ci devMgr->device = device; 151094332d3Sopenharmony_ci device->service = &(devMgr->service); 152094332d3Sopenharmony_ci devMgr->device->service->Dispatch = UsbFnDispatch; 153094332d3Sopenharmony_ci return HDF_SUCCESS; 154094332d3Sopenharmony_ci} 155094332d3Sopenharmony_ci 156094332d3Sopenharmony_cistatic int32_t UsbFnDriverInit(struct HdfDeviceObject *device) 157094332d3Sopenharmony_ci{ 158094332d3Sopenharmony_ci struct DevUsbFnMgr *devMgr = NULL; 159094332d3Sopenharmony_ci uint8_t useHcs; 160094332d3Sopenharmony_ci 161094332d3Sopenharmony_ci struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 162094332d3Sopenharmony_ci if (iface == NULL || iface->GetUint32 == NULL || device == NULL) { 163094332d3Sopenharmony_ci HDF_LOGE("%{public}s: iface is invalid", __func__); 164094332d3Sopenharmony_ci return HDF_FAILURE; 165094332d3Sopenharmony_ci } 166094332d3Sopenharmony_ci devMgr = (struct DevUsbFnMgr *)device->service; 167094332d3Sopenharmony_ci if (iface->GetString(device->property, "udc_name", &devMgr->udcName, UDC_NAME) != HDF_SUCCESS) { 168094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read udc_name failed, use default: %{public}s", __func__, UDC_NAME); 169094332d3Sopenharmony_ci return HDF_FAILURE; 170094332d3Sopenharmony_ci } 171094332d3Sopenharmony_ci HDF_LOGI("%{public}s: udcName=%{public}s", __func__, devMgr->udcName); 172094332d3Sopenharmony_ci if (iface->GetUint8(device->property, "use_hcs", &useHcs, 0) != HDF_SUCCESS) { 173094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read use_hcs fail, use default", __func__); 174094332d3Sopenharmony_ci } 175094332d3Sopenharmony_ci HDF_LOGI("%{public}s: use descriptor in %{public}s", __func__, (useHcs == 1) ? "hcs" : "code"); 176094332d3Sopenharmony_ci /* force use descripto in hcs, refer to sample for use descriptor in code */ 177094332d3Sopenharmony_ci devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP; 178094332d3Sopenharmony_ci devMgr->descData.property = device->property; 179094332d3Sopenharmony_ci return HDF_SUCCESS; 180094332d3Sopenharmony_ci} 181094332d3Sopenharmony_ci 182094332d3Sopenharmony_cistatic void UsbFnDriverRelease(struct HdfDeviceObject *device) 183094332d3Sopenharmony_ci{ 184094332d3Sopenharmony_ci struct DevUsbFnMgr *devMgr = NULL; 185094332d3Sopenharmony_ci devMgr = (struct DevUsbFnMgr *)device->service; 186094332d3Sopenharmony_ci if (devMgr == NULL) { 187094332d3Sopenharmony_ci HDF_LOGE("%{public}s: descriptor is NULL", __func__); 188094332d3Sopenharmony_ci return; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci OsalMemFree(devMgr); 191094332d3Sopenharmony_ci} 192094332d3Sopenharmony_ci 193094332d3Sopenharmony_cistruct HdfDriverEntry g_usbFnDriverEntry = { 194094332d3Sopenharmony_ci .moduleVersion = 1, 195094332d3Sopenharmony_ci .moduleName = "usbfn", 196094332d3Sopenharmony_ci .Bind = UsbFnDriverBind, 197094332d3Sopenharmony_ci .Init = UsbFnDriverInit, 198094332d3Sopenharmony_ci .Release = UsbFnDriverRelease, 199094332d3Sopenharmony_ci}; 200094332d3Sopenharmony_ci 201094332d3Sopenharmony_ciHDF_INIT(g_usbFnDriverEntry); 202