• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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