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 "usbfn_io_mgr.h"
17 #include "usbd_wrapper.h"
18
19 #define HDF_LOG_TAG usbfn_io_mgr
20
ReqToIoData(struct UsbFnRequest * req,struct IoData * ioData,uint32_t aio,uint32_t timeout)21 static int32_t ReqToIoData(struct UsbFnRequest *req, struct IoData *ioData, uint32_t aio, uint32_t timeout)
22 {
23 if (req == NULL || ioData == NULL) {
24 HDF_LOGE("%{public}s invalid param", __func__);
25 return HDF_ERR_INVALID_PARAM;
26 }
27 struct ReqList *reqList = (struct ReqList *)req;
28 ioData->aio = aio;
29 if (req->type == USB_REQUEST_TYPE_PIPE_WRITE) {
30 ioData->read = 0;
31 } else if (req->type == USB_REQUEST_TYPE_PIPE_READ) {
32 ioData->read = 1;
33 }
34 ioData->buf = reqList->buf;
35 ioData->len = req->length;
36 ioData->timeout = timeout;
37
38 return 0;
39 }
40
OpenEp0AndMapAddr(struct UsbFnFuncMgr * funcMgr)41 int32_t OpenEp0AndMapAddr(struct UsbFnFuncMgr *funcMgr)
42 {
43 int32_t ret;
44 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
45 funcMgr->fd = fnOps->openPipe(funcMgr->name, 0);
46 if (funcMgr->fd <= 0) {
47 HDF_LOGE("%{public}s:%{public}d openPipe failed", __func__, __LINE__);
48 return HDF_ERR_IO;
49 }
50
51 ret = fnOps->queueInit(funcMgr->fd);
52 if (ret) {
53 HDF_LOGE("%{public}s:%{public}d queueInit failed", __func__, __LINE__);
54 return HDF_ERR_IO;
55 }
56 return 0;
57 }
58
GetReqType(struct UsbHandleMgr * handle,uint8_t pipe)59 static UsbFnRequestType GetReqType(struct UsbHandleMgr *handle, uint8_t pipe)
60 {
61 struct UsbFnPipeInfo info = {0};
62 UsbFnRequestType type = USB_REQUEST_TYPE_INVALID;
63 if (pipe > 0) {
64 int32_t ret = UsbFnIoMgrInterfaceGetPipeInfo(&(handle->intfMgr->interface), pipe - 1, &info);
65 if (ret) {
66 HDF_LOGE("%{public}s:%{public}d UsbFnMgrInterfaceGetPipeInfo err", __func__, __LINE__);
67 type = USB_REQUEST_TYPE_INVALID;
68 }
69 if (info.dir == USB_PIPE_DIRECTION_IN) {
70 type = USB_REQUEST_TYPE_PIPE_WRITE;
71 } else if (info.dir == USB_PIPE_DIRECTION_OUT) {
72 type = USB_REQUEST_TYPE_PIPE_READ;
73 }
74 }
75 return type;
76 }
77
UsbFnIoMgrRequestAlloc(struct UsbHandleMgr * handle,uint8_t pipe,uint32_t len)78 struct UsbFnRequest *UsbFnIoMgrRequestAlloc(struct UsbHandleMgr *handle, uint8_t pipe, uint32_t len)
79 {
80 int32_t ep;
81 struct UsbFnInterfaceMgr *intfMgr = handle->intfMgr;
82 struct UsbFnFuncMgr *funcMgr = intfMgr->funcMgr;
83 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
84 if (pipe == 0) {
85 if (funcMgr->fd <= 0) {
86 int32_t ret = OpenEp0AndMapAddr(funcMgr);
87 if (ret) {
88 return NULL;
89 }
90 }
91 ep = funcMgr->fd;
92 } else if (pipe <= MAX_EP) {
93 ep = handle->fds[pipe - 1];
94 } else {
95 return NULL;
96 }
97 uint8_t *mapAddr = fnOps->mapAddr(ep, len);
98 if (mapAddr == NULL || mapAddr == (uint8_t *)-1) {
99 HDF_LOGE("%{public}s:%{public}d mapAddr %{public}d failed", __func__, __LINE__, ep);
100 return NULL;
101 }
102
103 struct ReqList *reqList = UsbFnMemCalloc(sizeof(struct ReqList));
104 if (reqList == NULL) {
105 int32_t ret = fnOps->unmapAddr(mapAddr, len);
106 HDF_LOGE("%{public}s:%{public}d UsbFnMemCalloc err, unmap:%{public}d", __func__, __LINE__, ret);
107 return NULL;
108 }
109 struct UsbFnRequest *req = &reqList->req;
110
111 if (pipe == 0) {
112 DListInsertTail(&reqList->entry, &funcMgr->reqEntry);
113 } else {
114 DListInsertTail(&reqList->entry, &handle->reqEntry);
115 }
116 reqList->handle = handle;
117 reqList->fd = ep;
118 reqList->buf = (uintptr_t)mapAddr;
119 reqList->pipe = pipe;
120 reqList->bufLen = len;
121 req->length = len;
122 req->obj = handle->intfMgr->interface.object;
123 req->buf = mapAddr;
124 req->type = GetReqType(handle, pipe);
125
126 return req;
127 }
128
UsbFnIoMgrRequestFree(struct UsbFnRequest * req)129 int32_t UsbFnIoMgrRequestFree(struct UsbFnRequest *req)
130 {
131 struct GenericMemory mem;
132 int32_t ret;
133 if (req == NULL) {
134 HDF_LOGE("%{public}s invalid param", __func__);
135 return HDF_ERR_INVALID_PARAM;
136 }
137
138 struct ReqList *reqList = (struct ReqList *)req;
139 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
140
141 ret = fnOps->unmapAddr(req->buf, reqList->bufLen);
142 if (ret) {
143 HDF_LOGE("%{public}s:%{public}d ummapAddr failed, ret=%{public}d ", __func__, __LINE__, ret);
144 return HDF_ERR_DEVICE_BUSY;
145 }
146 mem.size = reqList->bufLen;
147 mem.buf = (uint64_t)req->buf;
148 ret = fnOps->releaseBuf(reqList->fd, &mem);
149 if (ret) {
150 HDF_LOGE("%{public}s releaseBuf err::%{public}d", __func__, ret);
151 return HDF_ERR_INVALID_PARAM;
152 }
153
154 if (reqList->entry.prev != NULL && reqList->entry.next != NULL) {
155 DListRemove(&reqList->entry);
156 } else {
157 HDF_LOGE("%{public}s: The node prev or next is NULL", __func__);
158 }
159 UsbFnMemFree(reqList);
160 return 0;
161 }
162
UsbFnIoMgrRequestSubmitAsync(struct UsbFnRequest * req)163 int32_t UsbFnIoMgrRequestSubmitAsync(struct UsbFnRequest *req)
164 {
165 int32_t ret;
166 struct IoData ioData = {0};
167 struct ReqList *reqList = NULL;
168 if (req == NULL) {
169 HDF_LOGE("%{public}s invalid param", __func__);
170 return HDF_ERR_INVALID_PARAM;
171 }
172 reqList = (struct ReqList *)req;
173 if (ReqToIoData(req, &ioData, 1, 0)) {
174 return HDF_ERR_IO;
175 }
176
177 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
178 ret = fnOps->pipeIo(reqList->fd, &ioData);
179 if (ret != HDF_SUCCESS) {
180 HDF_LOGE("%{public}s pipeIo failed fd:%{public}d read:%{public}u", __func__, reqList->fd, ioData.read);
181 }
182
183 return ret;
184 }
185
UsbFnIoMgrRequestCancel(struct UsbFnRequest * req)186 int32_t UsbFnIoMgrRequestCancel(struct UsbFnRequest *req)
187 {
188 int32_t ret;
189 struct IoData ioData = {0};
190 struct ReqList *reqList = NULL;
191 if (req == NULL) {
192 HDF_LOGE("%{public}s invalid param", __func__);
193 return HDF_ERR_INVALID_PARAM;
194 }
195 reqList = (struct ReqList *)req;
196 if (ReqToIoData(req, &ioData, 1, 0)) {
197 return HDF_ERR_IO;
198 }
199 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
200 ret = fnOps->cancelIo(reqList->fd, &ioData);
201
202 return ret;
203 }
204
UsbFnIoMgrRequestGetStatus(struct UsbFnRequest * req,UsbRequestStatus * status)205 int32_t UsbFnIoMgrRequestGetStatus(struct UsbFnRequest *req, UsbRequestStatus *status)
206 {
207 struct IoData ioData = {0};
208 struct ReqList *reqList;
209 if (req == NULL) {
210 HDF_LOGE("%{public}s invalid param", __func__);
211 return HDF_ERR_INVALID_PARAM;
212 }
213 reqList = (struct ReqList *)req;
214 if (ReqToIoData(req, &ioData, 1, 0)) {
215 return HDF_ERR_IO;
216 }
217 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
218 *status = -(fnOps->getReqStatus(reqList->fd, &ioData));
219
220 return 0;
221 }
222
UsbFnIoMgrRequestSubmitSync(struct UsbFnRequest * req,uint32_t timeout)223 int32_t UsbFnIoMgrRequestSubmitSync(struct UsbFnRequest *req, uint32_t timeout)
224 {
225 int32_t ret;
226 struct IoData ioData = {0};
227 struct ReqList *reqList;
228
229 if (req == NULL) {
230 HDF_LOGE("%{public}s invalid param", __func__);
231 return HDF_ERR_INVALID_PARAM;
232 }
233 reqList = (struct ReqList *)req;
234 if (ReqToIoData(req, &ioData, 0, timeout)) {
235 return HDF_ERR_IO;
236 }
237 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
238 ret = fnOps->pipeIo(reqList->fd, &ioData);
239 if (ret > 0) {
240 req->status = USB_REQUEST_COMPLETED;
241 req->actual = (uint32_t)ret;
242 return 0;
243 }
244
245 return ret;
246 }
247
HandleInit(struct UsbHandleMgr * handle,struct UsbFnInterfaceMgr * interfaceMgr)248 static int32_t HandleInit(struct UsbHandleMgr *handle, struct UsbFnInterfaceMgr *interfaceMgr)
249 {
250 int32_t ret;
251 uint32_t i, j;
252 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
253
254 DListHeadInit(&handle->reqEntry);
255 handle->numFd = interfaceMgr->interface.info.numPipes;
256 if (handle->numFd > MAX_EP) {
257 HDF_LOGE("%{public}s: Invalid numFd value", __func__);
258 return HDF_ERR_IO;
259 }
260 for (i = 0; i < handle->numFd; i++) {
261 handle->fds[i] = fnOps->openPipe(interfaceMgr->funcMgr->name, interfaceMgr->startEpId + i);
262 if (handle->fds[i] <= 0) {
263 return HDF_ERR_IO;
264 }
265
266 ret = fnOps->queueInit(handle->fds[i]);
267 if (ret) {
268 HDF_LOGE("%{public}s: queueInit failed ret = %{public}d", __func__, ret);
269 return HDF_ERR_IO;
270 }
271
272 handle->reqEvent[i] = UsbFnMemCalloc(sizeof(struct UsbFnReqEvent) * MAX_REQUEST);
273 if (handle->reqEvent[i] == NULL) {
274 HDF_LOGE("%{public}s: UsbFnMemCalloc failed", __func__);
275 goto FREE_EVENT;
276 }
277 }
278 handle->intfMgr = interfaceMgr;
279 return 0;
280
281 FREE_EVENT:
282 for (j = 0; j < i; j++) {
283 UsbFnMemFree(handle->reqEvent[j]);
284 }
285 return HDF_ERR_IO;
286 }
287
UsbFnIoMgrInterfaceOpen(struct UsbFnInterface * interface)288 struct UsbHandleMgr *UsbFnIoMgrInterfaceOpen(struct UsbFnInterface *interface)
289 {
290 int32_t ret;
291 if (interface == NULL) {
292 return NULL;
293 }
294 struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
295 if (interfaceMgr->isOpen) {
296 HDF_LOGE("%{public}s: interface has opened", __func__);
297 return NULL;
298 }
299 struct UsbHandleMgr *handle = UsbFnMemCalloc(sizeof(struct UsbHandleMgr));
300 if (handle == NULL) {
301 HDF_LOGE("%{public}s: malloc UsbHandleMgr failed", __func__);
302 return NULL;
303 }
304
305 ret = HandleInit(handle, interfaceMgr);
306 if (ret) {
307 HDF_LOGE("%{public}s: HandleInit failed", __func__);
308 UsbFnMemFree(handle);
309 return NULL;
310 }
311
312 interfaceMgr->isOpen = true;
313 interfaceMgr->handle = handle;
314 return handle;
315 }
316
UsbFnIoMgrInterfaceClose(struct UsbHandleMgr * handle)317 int32_t UsbFnIoMgrInterfaceClose(struct UsbHandleMgr *handle)
318 {
319 if (handle == NULL) {
320 HDF_LOGE("%{public}s invalid param", __func__);
321 return HDF_ERR_INVALID_PARAM;
322 }
323
324 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
325 struct UsbFnInterfaceMgr *interfaceMgr = handle->intfMgr;
326 if (interfaceMgr == NULL || interfaceMgr->isOpen == false) {
327 HDF_LOGE("%{public}s invalid param", __func__);
328 return HDF_ERR_INVALID_PARAM;
329 }
330 for (uint32_t i = 0; i < handle->numFd; i++) {
331 int32_t ret = fnOps->queueDel(handle->fds[i]);
332 if (ret) {
333 HDF_LOGE("%{public}s:%{public}d queueDel failed, ret=%{public}d ", __func__, __LINE__, ret);
334 return HDF_ERR_DEVICE_BUSY;
335 }
336
337 ret = fnOps->closePipe(handle->fds[i]);
338 if (ret) {
339 HDF_LOGE("%{public}s:%{public}d closePipe failed, ret=%{public}d ", __func__, __LINE__, ret);
340 return HDF_ERR_DEVICE_BUSY;
341 }
342 handle->fds[i] = -1;
343 UsbFnMemFree(handle->reqEvent[i]);
344 handle->reqEvent[i] = NULL;
345 }
346
347 UsbFnMemFree(handle);
348 handle = NULL;
349 interfaceMgr->isOpen = false;
350 interfaceMgr->handle = NULL;
351 return 0;
352 }
353
UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface * interface,uint8_t pipeId,struct UsbFnPipeInfo * info)354 int32_t UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface *interface, uint8_t pipeId, struct UsbFnPipeInfo *info)
355 {
356 int32_t ret;
357 int32_t fd;
358 if (info == NULL || interface == NULL || pipeId >= interface->info.numPipes) {
359 HDF_LOGE("%{public}s invalid param", __func__);
360 return HDF_ERR_INVALID_PARAM;
361 }
362 struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
363 struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
364 if (interfaceMgr->isOpen) {
365 if (pipeId >= MAX_EP) {
366 HDF_LOGE("%{public}s pipeId overflow", __func__);
367 return HDF_ERR_INVALID_PARAM;
368 }
369 fd = interfaceMgr->handle->fds[pipeId];
370 ret = fnOps->getPipeInfo(fd, info);
371 if (ret) {
372 HDF_LOGE("%{public}s: getPipeInfo failed", __func__);
373 return HDF_ERR_DEVICE_BUSY;
374 }
375 } else {
376 fd = fnOps->openPipe(interfaceMgr->funcMgr->name, interfaceMgr->startEpId + pipeId);
377 if (fd <= 0) {
378 HDF_LOGE("%{public}s: openPipe failed", __func__);
379 return HDF_ERR_IO;
380 }
381 ret = fnOps->getPipeInfo(fd, info);
382 if (ret) {
383 fnOps->closePipe(fd);
384 HDF_LOGE("%{public}s: getPipeInfo failed", __func__);
385 return HDF_ERR_DEVICE_BUSY;
386 }
387 fnOps->closePipe(fd);
388 }
389
390 info->id = pipeId;
391 return ret;
392 }
393