1 /* 2 * Copyright (C) 2021 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 #ifndef HDC_USBFFS_H 16 #define HDC_USBFFS_H 17 // clang-format off 18 #include <linux/usb/functionfs.h> 19 #include "daemon_common.h" 20 // clang-format on 21 22 namespace Hdc { 23 constexpr auto HDC_USBDR_SND = 0x0; 24 constexpr auto HDC_USBDR_RCV = 0x80; 25 constexpr auto HDC_USBMD_BLK = 0X02; 26 constexpr auto HDC_USBMD_RCV = 0X03; 27 constexpr auto HDC_CLASS = 0xff; 28 constexpr auto HDC_SUBCLASS = 0x50; 29 constexpr auto HDC_FSPKT_SIZE_MAX = 64; 30 constexpr auto HDC_HSPKT_SIZE_MAX = 512; 31 constexpr uint16_t HDC_SSPKT_SIZE_MAX = 1024; 32 constexpr auto USB_FFS_BASE = "/dev/usb-ffs/"; 33 constexpr auto HDC_USBTF_DEV = 0x01; 34 constexpr auto HDC_USBTF_CFG = 0x02; 35 constexpr auto HDC_USBTF_STR = 0x03; 36 constexpr auto HDC_USBTF_ITF = 0x04; 37 constexpr auto HDC_USBTF_EPS = 0x05; 38 39 #define SHORT_LE(x) htole16(x) 40 #define LONG_LE(x) htole32(x) 41 #define HDC_INTERFACE_NAME "HDC Interface" 42 43 struct UsbFunctionDesc { 44 struct usb_interface_descriptor ifDesc; 45 struct usb_endpoint_descriptor_no_audio from; 46 struct usb_endpoint_descriptor_no_audio to; 47 } __attribute__((packed)); 48 49 static const struct { 50 struct usb_functionfs_strings_head head; 51 struct { 52 __le16 code; 53 const char name[sizeof(HDC_INTERFACE_NAME)]; 54 } __attribute__((packed)) firstItem; 55 } __attribute__((packed)) USB_FFS_VALUE = { 56 .head = 57 { 58 .magic = LONG_LE(FUNCTIONFS_STRINGS_MAGIC), 59 .length = LONG_LE(sizeof(USB_FFS_VALUE)), 60 .str_count = LONG_LE(1), 61 .lang_count = LONG_LE(1), 62 }, 63 .firstItem = 64 { 65 SHORT_LE(0x0409), 66 HDC_INTERFACE_NAME, 67 }, 68 }; 69 70 struct UsbFunctionfsDescsHeadOld { 71 __le32 magic; 72 __le32 length; 73 __le32 config1Count; 74 __le32 config2Count; 75 } __attribute__((packed)); 76 77 struct UsbFuncConfig { 78 struct usb_interface_descriptor ifDesc; 79 struct usb_endpoint_descriptor_no_audio from; 80 struct usb_ss_ep_comp_descriptor pairFrom; 81 struct usb_endpoint_descriptor_no_audio to; 82 struct usb_ss_ep_comp_descriptor pairTo; 83 } __attribute__((packed)); 84 85 static struct UsbFuncConfig config3 = { 86 .ifDesc = { 87 .bLength = sizeof(config3.ifDesc), 88 .bDescriptorType = USB_DT_INTERFACE, 89 .bInterfaceNumber = 0, 90 .bNumEndpoints = 2, 91 .bInterfaceClass = HDC_CLASS, 92 .bInterfaceSubClass = HDC_SUBCLASS, 93 .bInterfaceProtocol = VER_PROTOCOL, 94 .iInterface = 1 95 }, 96 .from = { 97 .bLength = sizeof(config3.from), 98 .bDescriptorType = USB_DT_ENDPOINT, 99 .bEndpointAddress = 1 | USB_DIR_OUT, 100 .bmAttributes = USB_ENDPOINT_XFER_BULK, 101 .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, 102 }, 103 .pairFrom = { 104 .bLength = sizeof(config3.pairFrom), 105 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 106 .bMaxBurst = 4, 107 }, 108 .to = { 109 .bLength = sizeof(config3.to), 110 .bDescriptorType = USB_DT_ENDPOINT, 111 .bEndpointAddress = 2 | USB_DIR_IN, 112 .bmAttributes = USB_ENDPOINT_XFER_BULK, 113 .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, 114 }, 115 .pairTo = { 116 .bLength = sizeof(config3.pairTo), 117 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 118 .bMaxBurst = 4, 119 }, 120 }; 121 122 static struct UsbFunctionDesc config1 = { 123 .ifDesc = { 124 .bLength = sizeof(config1.ifDesc), 125 .bDescriptorType = USB_DT_INTERFACE, 126 .bInterfaceNumber = 0, 127 .bNumEndpoints = 2, 128 .bInterfaceClass = HDC_CLASS, 129 .bInterfaceSubClass = HDC_SUBCLASS, 130 .bInterfaceProtocol = VER_PROTOCOL, 131 .iInterface = 1 132 }, 133 .from = { 134 .bLength = sizeof(config1.from), 135 .bDescriptorType = USB_DT_ENDPOINT, 136 .bEndpointAddress = 1 | USB_DIR_OUT, 137 .bmAttributes = USB_ENDPOINT_XFER_BULK, 138 .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, 139 }, 140 .to = { 141 .bLength = sizeof(config1.to), 142 .bDescriptorType = USB_DT_ENDPOINT, 143 .bEndpointAddress = 2 | USB_DIR_IN, 144 .bmAttributes = USB_ENDPOINT_XFER_BULK, 145 .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, 146 }, 147 }; 148 149 static struct UsbFunctionDesc config2 = { 150 .ifDesc = { 151 .bLength = sizeof(config2.ifDesc), 152 .bDescriptorType = USB_DT_INTERFACE, 153 .bInterfaceNumber = 0, 154 .bNumEndpoints = 2, 155 .bInterfaceClass = HDC_CLASS, 156 .bInterfaceSubClass = HDC_SUBCLASS, 157 .bInterfaceProtocol = VER_PROTOCOL, 158 .iInterface = 1 159 }, 160 .from = { 161 .bLength = sizeof(config2.from), 162 .bDescriptorType = USB_DT_ENDPOINT, 163 .bEndpointAddress = 1 | USB_DIR_OUT, 164 .bmAttributes = USB_ENDPOINT_XFER_BULK, 165 .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, 166 }, 167 .to = { 168 .bLength = sizeof(config2.to), 169 .bDescriptorType = USB_DT_ENDPOINT, 170 .bEndpointAddress = 2 | USB_DIR_IN, 171 .bmAttributes = USB_ENDPOINT_XFER_BULK, 172 .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, 173 }, 174 }; 175 176 struct usb_functionfs_desc_v2 { 177 struct usb_functionfs_descs_head_v2 head; 178 __le32 config1Count; 179 __le32 config2Count; 180 __le32 config3Count; 181 __le32 configWosCount; 182 struct UsbFunctionDesc config1Desc, config2Desc; 183 struct UsbFuncConfig config3Desc; 184 struct usb_os_desc_header wosHead; 185 struct usb_ext_compat_desc wosDesc; 186 } __attribute__((packed)); 187 188 } // namespace Hdc 189 #endif 190