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
16 #include "usb_protocol.h"
17 #include "usb_io_manage.h"
18 #include "usbd_wrapper.h"
19
20 #define HDF_LOG_TAG USB_PROTOCOL
21
UsbProtocalFillControlSetup(const unsigned char * setup,const struct UsbControlRequest * ctrlReq)22 int32_t UsbProtocalFillControlSetup(const unsigned char *setup, const struct UsbControlRequest *ctrlReq)
23 {
24 struct UsbRawControlSetup *setupData = (struct UsbRawControlSetup *)setup;
25 int32_t ret = HDF_SUCCESS;
26 if ((setup == NULL) || (ctrlReq == NULL)) {
27 HDF_LOGE("%{public}s:%{public}d invalid parameter", __func__, __LINE__);
28 return HDF_ERR_INVALID_PARAM;
29 }
30
31 setupData->requestType = ctrlReq->reqType;
32 setupData->request = ctrlReq->request;
33 setupData->value = CPU_TO_LE16(ctrlReq->value);
34 setupData->index = CPU_TO_LE16(ctrlReq->index);
35 setupData->length = CPU_TO_LE16(ctrlReq->length);
36
37 return ret;
38 }
39
CreateCtrPipe(const struct UsbInterfacePool * pool)40 static int32_t CreateCtrPipe(const struct UsbInterfacePool *pool)
41 {
42 int32_t ret = 0;
43 struct UsbSdkInterface *interfaceObj = NULL;
44 struct UsbPipe *pipe = NULL;
45
46 if (pool == NULL) {
47 HDF_LOGE("%{public}s:%{public}d invalid param pool", __func__, __LINE__);
48 return HDF_ERR_INVALID_PARAM;
49 }
50
51 ret = UsbIfCreatInterfaceObj(pool, &interfaceObj);
52 if (ret != HDF_SUCCESS) {
53 return HDF_ERR_MALLOC_FAIL;
54 }
55 interfaceObj->interface.info.interfaceIndex = USB_CTRL_INTERFACE_ID;
56 interfaceObj->interface.info.pipeNum = 1;
57 interfaceObj->altSettingId = 0;
58 interfaceObj->interface.info.curAltSetting = 0;
59 ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
60 if (ret != HDF_SUCCESS) {
61 return HDF_ERR_IO;
62 }
63
64 pipe->info.pipeId = 0;
65 pipe->info.pipeAddress = 0;
66 pipe->info.pipeDirection = USB_PIPE_DIRECTION_OUT;
67 pipe->info.pipeType = USB_PIPE_TYPE_CONTROL;
68
69 return ret;
70 }
71
UsbInterfaceInit(struct UsbSdkInterface * interfaceObj,const struct UsbRawInterfaceDescriptor * iface,const struct UsbRawInterface * altsettings)72 static int32_t UsbInterfaceInit(struct UsbSdkInterface *interfaceObj,
73 const struct UsbRawInterfaceDescriptor *iface, const struct UsbRawInterface *altsettings)
74 {
75 struct UsbInterfaceInfo *ptr = NULL;
76
77 if ((interfaceObj == NULL) || (iface == NULL)) {
78 HDF_LOGE("%{public}s: invalid parameter", __func__);
79 return HDF_ERR_INVALID_PARAM;
80 }
81 ptr = &interfaceObj->interface.info;
82 ptr->pipeNum = iface->interfaceDescriptor.bNumEndpoints;
83 ptr->interfaceClass = iface->interfaceDescriptor.bInterfaceClass;
84 ptr->interfaceSubClass = iface->interfaceDescriptor.bInterfaceSubClass;
85 ptr->interfaceProtocol = iface->interfaceDescriptor.bInterfaceProtocol;
86 ptr->interfaceIndex = iface->interfaceDescriptor.bInterfaceNumber;
87 ptr->altSettings = altsettings->numAltsetting;
88 ptr->curAltSetting = USB_DEFAULT_ALTSETTING;
89
90 interfaceObj->altSettingId = iface->interfaceDescriptor.bAlternateSetting;
91
92 return HDF_SUCCESS;
93 }
94
UsbPipeInit(struct UsbPipe * pipe,const struct UsbRawEndpointDescriptor * ep)95 static int32_t UsbPipeInit(struct UsbPipe *pipe, const struct UsbRawEndpointDescriptor *ep)
96 {
97 if ((pipe == NULL) || (ep == NULL)) {
98 HDF_LOGE("%{public}s: invalid parameter", __func__);
99 return HDF_ERR_INVALID_PARAM;
100 }
101
102 pipe->info.pipeId = ep->endpointDescriptor.bEndpointAddress;
103 pipe->info.maxPacketSize = ep->endpointDescriptor.wMaxPacketSize;
104 pipe->info.interval = ep->endpointDescriptor.bInterval;
105 pipe->info.pipeType = ep->endpointDescriptor.bmAttributes & USB_DDK_ENDPOINT_XFERTYPE_MASK;
106 pipe->info.pipeAddress = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_NUMBER_MASK;
107 pipe->info.pipeDirection = ep->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK;
108 return HDF_SUCCESS;
109 }
110
UsbGetInterfaceFromConfig(const struct UsbRawConfigDescriptor * config,uint8_t idx)111 static const struct UsbRawInterface *UsbGetInterfaceFromConfig(
112 const struct UsbRawConfigDescriptor *config, uint8_t idx)
113 {
114 if (config == NULL) {
115 HDF_LOGE("%{public}s: invalid param", __func__);
116 return NULL;
117 }
118 if (config->configDescriptor.bNumInterfaces < idx + 1) {
119 HDF_LOGE("%{public}s: invalid param", __func__);
120 return NULL;
121 }
122
123 return config->interface[idx];
124 }
125
126 /* The default AltSetting is 0 */
UsbGetInterfaceDesc(const struct UsbRawInterface * altSetting,uint8_t settingIndex)127 static const struct UsbRawInterfaceDescriptor *UsbGetInterfaceDesc(
128 const struct UsbRawInterface *altSetting, uint8_t settingIndex)
129 {
130 if (altSetting == NULL) {
131 HDF_LOGE("%{public}s:%{public}d invalid param altSetting", __func__, __LINE__);
132 return NULL;
133 }
134
135 return &altSetting->altsetting[settingIndex];
136 }
137
UsbGetEpDesc(const struct UsbRawInterfaceDescriptor * ifDes,uint8_t idx)138 static const struct UsbRawEndpointDescriptor *UsbGetEpDesc(
139 const struct UsbRawInterfaceDescriptor *ifDes, uint8_t idx)
140 {
141 if (ifDes == NULL) {
142 HDF_LOGE("%{public}s:%{public}d invalid param ifDes", __func__, __LINE__);
143 return NULL;
144 }
145 if (ifDes->interfaceDescriptor.bNumEndpoints < (idx + 1)) {
146 HDF_LOGE("%{public}s:invalid param numEp:%{public}d+idx:%{public}hhu",
147 __func__, ifDes->interfaceDescriptor.bNumEndpoints, idx);
148 return NULL;
149 }
150
151 return &ifDes->endPoint[idx];
152 }
153
UsbProtocalCreatePipeObj(const struct UsbRawInterfaceDescriptor * ifDes,const struct UsbSdkInterface * interfaceObj)154 static int32_t UsbProtocalCreatePipeObj(
155 const struct UsbRawInterfaceDescriptor *ifDes, const struct UsbSdkInterface *interfaceObj)
156 {
157 int32_t ret = HDF_SUCCESS;
158 const struct UsbRawEndpointDescriptor *ep = NULL;
159 struct UsbPipe *pipe = NULL;
160
161 for (int32_t cnep = 0; cnep < ifDes->interfaceDescriptor.bNumEndpoints; cnep++) {
162 if (ifDes->interfaceDescriptor.bNumEndpoints > USB_MAXENDPOINTS) {
163 HDF_LOGE("%{public}s:%{public}d bNumEndpoints=%{public}d is error",
164 __func__, __LINE__, ifDes->interfaceDescriptor.bNumEndpoints);
165 ret = HDF_DEV_ERR_NORANGE;
166 break;
167 }
168 ep = UsbGetEpDesc(ifDes, cnep);
169 if (ep == NULL) {
170 ret = HDF_ERR_INVALID_PARAM;
171 break;
172 }
173 ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
174 if (ret != HDF_SUCCESS) {
175 break;
176 }
177 ret = UsbPipeInit(pipe, ep);
178 if (ret != HDF_SUCCESS) {
179 break;
180 }
181 }
182
183 return ret;
184 }
185
UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor * config,const struct UsbInterfacePool * interfacePool)186 static int32_t UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor *config,
187 const struct UsbInterfacePool *interfacePool)
188 {
189 uint8_t j;
190 int32_t ret = HDF_SUCCESS;
191 const struct UsbRawInterface *itface = NULL;
192 const struct UsbRawInterfaceDescriptor *ifDes = NULL;
193 struct UsbSdkInterface *interfaceObj = NULL;
194
195 for (int32_t i = 0; i < config->configDescriptor.bNumInterfaces; i++) {
196 itface = UsbGetInterfaceFromConfig(config, i);
197 if (itface == NULL) {
198 ret = HDF_ERR_INVALID_PARAM;
199 goto ERROR;
200 }
201
202 for (j = 0; j < itface->numAltsetting; j++) {
203 ifDes = UsbGetInterfaceDesc(itface, j);
204 if (ifDes == NULL) {
205 ret = HDF_ERR_INVALID_PARAM;
206 goto ERROR;
207 }
208
209 ret = UsbIfCreatInterfaceObj(interfacePool, &interfaceObj);
210 if (ret != HDF_SUCCESS) {
211 goto ERROR;
212 }
213
214 ret = UsbInterfaceInit(interfaceObj, ifDes, itface);
215 if (ret != 0) {
216 ret = HDF_ERR_IO;
217 goto ERROR;
218 }
219
220 ret = UsbProtocalCreatePipeObj(ifDes, interfaceObj);
221 if (ret != HDF_SUCCESS) {
222 goto ERROR;
223 }
224 }
225 }
226
227 ERROR:
228 return ret;
229 }
230
UsbProtocalParseDescriptor(struct UsbDeviceHandle * devHandle,uint8_t busNum,uint8_t devAddr)231 int32_t UsbProtocalParseDescriptor(struct UsbDeviceHandle *devHandle, uint8_t busNum, uint8_t devAddr)
232 {
233 int32_t ret;
234 int32_t activeConfig = -1;
235 struct UsbInterfacePool *interfacePool = NULL;
236 struct UsbRawConfigDescriptor *config = NULL;
237
238 if ((devHandle == NULL) || (devHandle->dev == NULL) || (devHandle->dev->session == NULL)) {
239 HDF_LOGE("%{public}s:%{public}d invalid param", __func__, __LINE__);
240 return HDF_ERR_INVALID_PARAM;
241 }
242
243 ret = UsbIfCreatInterfacePool(devHandle->dev->session, busNum, devAddr, &interfacePool);
244 if (ret != HDF_SUCCESS) {
245 HDF_LOGE("%{public}s:%{public}d UsbIfCreatInterfacePool error", __func__, __LINE__);
246 return HDF_ERR_IO;
247 }
248 interfacePool->session = devHandle->dev->session;
249 interfacePool->device = devHandle->dev;
250 devHandle->dev->privateObject = (void *)interfacePool;
251
252 ret = CreateCtrPipe(interfacePool);
253 if (ret != HDF_SUCCESS) {
254 goto ERR;
255 }
256
257 ret = RawGetConfiguration(devHandle, &activeConfig);
258 if (ret != HDF_SUCCESS) {
259 goto ERR;
260 }
261
262 ret = RawGetConfigDescriptor(devHandle->dev, activeConfig, &config);
263 if (ret != HDF_SUCCESS) {
264 goto FREE_CONFIG;
265 }
266
267 ret = UsbProtocalCreatInterfaceObj(config, interfacePool);
268 if (ret != HDF_SUCCESS) {
269 goto FREE_CONFIG;
270 }
271
272 FREE_CONFIG:
273 if (config != NULL) {
274 RawClearConfiguration(config);
275 RawUsbMemFree(config);
276 config = NULL;
277 }
278
279 if (ret == HDF_SUCCESS) {
280 return ret;
281 }
282
283 ERR:
284 (void)UsbIfDestroyInterfaceObj(interfacePool, NULL);
285 return ret;
286 }
287
288