1 /* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "device_resource_if.h" 17 #include "hdf_base.h" 18 #include "hdf_device_desc.h" 19 #include "hdf_device_object.h" 20 #include "hdf_log.h" 21 #include "osal_mem.h" 22 #include "osal_time.h" 23 #include "securec.h" 24 #include "usbfn_device.h" 25 #include "usbfn_interface.h" 26 #include "usbfn_request.h" 27 28 #define HDF_LOG_TAG dev_usbfn 29 #define UDC_NAME "invalid_udc_name" 30 31 enum DevUsbFnCmd { 32 DEV_USBFN_INIT = 0x1, 33 DEV_USBFN_RELEASE, 34 }; 35 36 struct DevUsbFnMgr { 37 struct IDeviceIoService service; 38 struct UsbFnDescriptorData descData; 39 struct HdfDeviceObject *device; 40 const char *udcName; 41 }; 42 43 struct UsbFnDevice *g_fnDev = NULL; UsbFnReleaseFuncDevice(void)44 static int32_t UsbFnReleaseFuncDevice(void) 45 { 46 int32_t ret; 47 if (g_fnDev == NULL) { 48 HDF_LOGE("%{public}s: fnDev is null", __func__); 49 return HDF_FAILURE; 50 } 51 ret = UsbFnRemoveDevice(g_fnDev); 52 if (ret == HDF_SUCCESS) { 53 g_fnDev = NULL; 54 } else { 55 HDF_LOGE("%{public}s: remove usb function device failed", __func__); 56 } 57 58 return ret; 59 } 60 UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)61 static int32_t UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) 62 { 63 struct HdfDeviceObject *device = client->device; 64 struct DevUsbFnMgr *devMgr = NULL; 65 struct UsbFnDevice *fnDev = NULL; 66 uint8_t value; 67 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 68 69 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) { 70 HDF_LOGE("%{public}s: iface is invalid", __func__); 71 return HDF_FAILURE; 72 } 73 devMgr = (struct DevUsbFnMgr *)device->service; 74 if (HdfSbufReadUint8(data, &value) != true) { 75 HDF_LOGE("%{public}s: read sbuf failed", __func__); 76 return HDF_FAILURE; 77 } 78 HDF_LOGI("%{public}s: data=%{public}d, descriptor in %{public}s", __func__, value, 79 (devMgr->descData.type == USBFN_DESC_DATA_TYPE_DESC ? "code" : "hcs")); 80 devMgr->descData.functionMask = value; 81 fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData); 82 if (fnDev == NULL) { 83 HDF_LOGE("%{public}s: create usb function device failed", __func__); 84 if (!HdfSbufWriteInt8(reply, 0)) { 85 HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__); 86 } 87 return HDF_FAILURE; 88 } 89 g_fnDev = fnDev; 90 if (!HdfSbufWriteInt8(reply, value)) { 91 HDF_LOGE("%{public}s: fn_usbfn sbuf write error", __func__); 92 return HDF_FAILURE; 93 } 94 HDF_LOGI("%{public}s: create device done, reply: %{public}d", __func__, value); 95 return HDF_SUCCESS; 96 } 97 UsbFnDispatch(struct HdfDeviceIoClient * client,int32_t cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)98 static int32_t UsbFnDispatch( 99 struct HdfDeviceIoClient *client, int32_t cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 100 { 101 int32_t ret; 102 if (client == NULL) { 103 HDF_LOGE("%{public}s: client is NULL", __func__); 104 return HDF_FAILURE; 105 } 106 107 if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) { 108 HDF_LOGE("%{public}s: check interface desc fail", __func__); 109 return HDF_ERR_INVALID_PARAM; 110 } 111 112 switch (cmdId) { 113 case DEV_USBFN_INIT: 114 ret = UsbFnRegistUsbfnDevice(client, data, reply); 115 if (ret != HDF_SUCCESS) { 116 HDF_LOGE("%{public}s: create usbfn device failed", __func__); 117 } 118 break; 119 case DEV_USBFN_RELEASE: 120 ret = UsbFnReleaseFuncDevice(); 121 break; 122 default: 123 ret = HDF_ERR_INVALID_OBJECT; 124 HDF_LOGE("%{public}s: unknown cmd id %{public}d", __func__, cmdId); 125 break; 126 } 127 return ret; 128 } 129 130 /* HdfDriverEntry implementations */ UsbFnDriverBind(struct HdfDeviceObject * device)131 static int32_t UsbFnDriverBind(struct HdfDeviceObject *device) 132 { 133 struct DevUsbFnMgr *devMgr = NULL; 134 if (device == NULL) { 135 HDF_LOGE("%{public}s: device is null", __func__); 136 return HDF_FAILURE; 137 } 138 devMgr = (struct DevUsbFnMgr *)OsalMemCalloc(sizeof(*devMgr)); 139 if (devMgr == NULL) { 140 HDF_LOGE("%{public}s: usbfn Alloc usb devMgr failed", __func__); 141 return HDF_FAILURE; 142 } 143 144 if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) { 145 HDF_LOGE("%{public}s: Set Desc fail!", __func__); 146 OsalMemFree(devMgr); 147 return HDF_FAILURE; 148 } 149 150 devMgr->device = device; 151 device->service = &(devMgr->service); 152 devMgr->device->service->Dispatch = UsbFnDispatch; 153 return HDF_SUCCESS; 154 } 155 UsbFnDriverInit(struct HdfDeviceObject * device)156 static int32_t UsbFnDriverInit(struct HdfDeviceObject *device) 157 { 158 struct DevUsbFnMgr *devMgr = NULL; 159 uint8_t useHcs; 160 161 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 162 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) { 163 HDF_LOGE("%{public}s: iface is invalid", __func__); 164 return HDF_FAILURE; 165 } 166 devMgr = (struct DevUsbFnMgr *)device->service; 167 if (iface->GetString(device->property, "udc_name", &devMgr->udcName, UDC_NAME) != HDF_SUCCESS) { 168 HDF_LOGE("%{public}s: read udc_name failed, use default: %{public}s", __func__, UDC_NAME); 169 return HDF_FAILURE; 170 } 171 HDF_LOGI("%{public}s: udcName=%{public}s", __func__, devMgr->udcName); 172 if (iface->GetUint8(device->property, "use_hcs", &useHcs, 0) != HDF_SUCCESS) { 173 HDF_LOGE("%{public}s: read use_hcs fail, use default", __func__); 174 } 175 HDF_LOGI("%{public}s: use descriptor in %{public}s", __func__, (useHcs == 1) ? "hcs" : "code"); 176 /* force use descripto in hcs, refer to sample for use descriptor in code */ 177 devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP; 178 devMgr->descData.property = device->property; 179 return HDF_SUCCESS; 180 } 181 UsbFnDriverRelease(struct HdfDeviceObject * device)182 static void UsbFnDriverRelease(struct HdfDeviceObject *device) 183 { 184 struct DevUsbFnMgr *devMgr = NULL; 185 devMgr = (struct DevUsbFnMgr *)device->service; 186 if (devMgr == NULL) { 187 HDF_LOGE("%{public}s: descriptor is NULL", __func__); 188 return; 189 } 190 OsalMemFree(devMgr); 191 } 192 193 struct HdfDriverEntry g_usbFnDriverEntry = { 194 .moduleVersion = 1, 195 .moduleName = "usbfn", 196 .Bind = UsbFnDriverBind, 197 .Init = UsbFnDriverInit, 198 .Release = UsbFnDriverRelease, 199 }; 200 201 HDF_INIT(g_usbFnDriverEntry); 202