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