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