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