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,uint8_t id)112 static int32_t UsbPipeInit(struct UsbPipe *pipe, const struct UsbRawEndpointDescriptor *ep, uint8_t id)
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 = id;
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 uint8_t id = 0;
176 const struct UsbRawEndpointDescriptor *ep = NULL;
177 struct UsbPipe *pipe = NULL;
178
179 for (int32_t cnep = 0; cnep < ifDes->interfaceDescriptor.bNumEndpoints; cnep++) {
180 if (ifDes->interfaceDescriptor.bNumEndpoints > USB_MAXENDPOINTS) {
181 HDF_LOGE("%{public}s:%d bNumEndpoints=%d is error",
182 __func__, __LINE__, ifDes->interfaceDescriptor.bNumEndpoints);
183 ret = HDF_DEV_ERR_NORANGE;
184 break;
185 }
186 ep = UsbGetEpDesc(ifDes, cnep);
187 if (ep == NULL) {
188 ret = HDF_ERR_INVALID_PARAM;
189 break;
190 }
191 ret = UsbIfCreatPipeObj(interfaceObj, &pipe);
192 if (ret != HDF_SUCCESS) {
193 break;
194 }
195 ret = UsbPipeInit(pipe, ep, ++id);
196 if (ret != HDF_SUCCESS) {
197 break;
198 }
199 }
200
201 return ret;
202 }
203
UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor * config,const struct UsbInterfacePool * interfacePool)204 static int32_t UsbProtocalCreatInterfaceObj(const struct UsbRawConfigDescriptor *config,
205 const struct UsbInterfacePool *interfacePool)
206 {
207 uint8_t j;
208 int32_t ret = HDF_SUCCESS;
209 const struct UsbRawInterface *itface = NULL;
210 const struct UsbRawInterfaceDescriptor *ifDes = NULL;
211 struct UsbSdkInterface *interfaceObj = NULL;
212
213 for (int32_t i = 0; i < config->configDescriptor.bNumInterfaces; i++) {
214 itface = UsbGetInterfaceFromConfig(config, i);
215 if (itface == NULL) {
216 ret = HDF_ERR_INVALID_PARAM;
217 goto ERROR;
218 }
219
220 for (j = 0; j < itface->numAltsetting; j++) {
221 ifDes = UsbGetInterfaceDesc(itface, j);
222 if (ifDes == NULL) {
223 ret = HDF_ERR_INVALID_PARAM;
224 goto ERROR;
225 }
226
227 ret = UsbIfCreatInterfaceObj(interfacePool, &interfaceObj);
228 if (ret != HDF_SUCCESS) {
229 goto ERROR;
230 }
231
232 ret = UsbInterfaceInit(interfaceObj, ifDes, itface);
233 if (ret != 0) {
234 ret = HDF_ERR_IO;
235 goto ERROR;
236 }
237
238 ret = UsbProtocalCreatePipeObj(ifDes, interfaceObj);
239 if (ret != HDF_SUCCESS) {
240 goto ERROR;
241 }
242 }
243 }
244
245 ERROR:
246 return ret;
247 }
248
UsbProtocalParseDescriptor(struct UsbDeviceHandle * devHandle,uint8_t busNum,uint8_t devAddr)249 int32_t UsbProtocalParseDescriptor(struct UsbDeviceHandle *devHandle, uint8_t busNum, uint8_t devAddr)
250 {
251 int32_t ret;
252 int32_t activeConfig = -1;
253 struct UsbInterfacePool *interfacePool = NULL;
254 struct UsbRawConfigDescriptor *config = NULL;
255
256 if ((devHandle == NULL) || (devHandle->dev == NULL) || (devHandle->dev->session == NULL)) {
257 HDF_LOGE("%{public}s:%d invalid param", __func__, __LINE__);
258 return HDF_ERR_INVALID_PARAM;
259 }
260
261 ret = UsbIfCreatInterfacePool(devHandle->dev->session, busNum, devAddr, &interfacePool);
262 if (ret != HDF_SUCCESS) {
263 HDF_LOGE("%{public}s:%d UsbIfCreatInterfacePool error", __func__, __LINE__);
264 return HDF_ERR_IO;
265 }
266 interfacePool->session = devHandle->dev->session;
267 interfacePool->device = devHandle->dev;
268 devHandle->dev->privateObject = (void *)interfacePool;
269
270 ret = CreateCtrPipe(interfacePool);
271 if (ret != HDF_SUCCESS) {
272 goto ERR;
273 }
274
275 ret = RawGetConfiguration(devHandle, &activeConfig);
276 if (ret != HDF_SUCCESS) {
277 goto ERR;
278 }
279
280 ret = RawGetConfigDescriptor(devHandle->dev, activeConfig, &config);
281 if (ret != HDF_SUCCESS) {
282 goto FREE_CONFIG;
283 }
284
285 ret = UsbProtocalCreatInterfaceObj(config, interfacePool);
286 if (ret != HDF_SUCCESS) {
287 goto FREE_CONFIG;
288 }
289
290 FREE_CONFIG:
291 if (config != NULL) {
292 RawClearConfiguration(config);
293 RawUsbMemFree(config);
294 config = NULL;
295 }
296
297 if (ret == HDF_SUCCESS) {
298 return ret;
299 }
300
301 ERR:
302 (void)UsbIfDestroyInterfaceObj(interfacePool, NULL);
303 return ret;
304 }
305
306