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