• 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 "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 int ReqToIoData(struct UsbFnRequest *req, struct IoData *ioData,
21     uint32_t aio, uint32_t timeout)
22 {
23     if (req == NULL || ioData == NULL) {
24         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
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 int OpenEp0AndMapAddr(struct UsbFnFuncMgr *funcMgr)
42 {
43     int ret;
44     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
45     funcMgr->fd = fnOps->openPipe(funcMgr->name, 0);
46     if (funcMgr->fd <= 0) {
47         HDF_LOGE("%s:%d openPipe failed", __func__, __LINE__);
48         return HDF_ERR_IO;
49     }
50 
51     ret = fnOps->queueInit(funcMgr->fd);
52     if (ret) {
53         HDF_LOGE("%s:%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     int ret;
62     struct UsbFnPipeInfo info;
63     UsbFnRequestType type = USB_REQUEST_TYPE_INVALID;
64     if (pipe > 0) {
65         ret = UsbFnIoMgrInterfaceGetPipeInfo(&(handle->intfMgr->interface), pipe - 1, &info);
66         if (ret) {
67             HDF_LOGE("%s:%d UsbFnMgrInterfaceGetPipeInfo err", __func__, __LINE__);
68             type = USB_REQUEST_TYPE_INVALID;
69         }
70         if (info.dir == USB_PIPE_DIRECTION_IN) {
71             type = USB_REQUEST_TYPE_PIPE_WRITE;
72         } else if (info.dir == USB_PIPE_DIRECTION_OUT) {
73             type = USB_REQUEST_TYPE_PIPE_READ;
74         }
75     }
76     return type;
77 }
78 
UsbFnIoMgrRequestAlloc(struct UsbHandleMgr * handle,uint8_t pipe,uint32_t len)79 struct UsbFnRequest *UsbFnIoMgrRequestAlloc(struct UsbHandleMgr *handle, uint8_t pipe, uint32_t len)
80 {
81     int ret;
82     int ep;
83     uint8_t *mapAddr = NULL;
84     struct UsbFnRequest *req = NULL;
85     struct ReqList *reqList = NULL;
86     struct UsbFnInterfaceMgr *intfMgr = handle->intfMgr;
87     struct UsbFnFuncMgr *funcMgr = intfMgr->funcMgr;
88     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
89     if (pipe == 0) {
90         if (funcMgr->fd <= 0) {
91             ret = OpenEp0AndMapAddr(funcMgr);
92             if (ret) {
93                 return NULL;
94             }
95         }
96         ep = funcMgr->fd;
97     } else {
98         ep = handle->fds[pipe - 1];
99     }
100     mapAddr = fnOps->mapAddr(ep, len);
101     if (mapAddr == NULL) {
102         HDF_LOGE("%s:%d mapAddr failed", __func__, __LINE__);
103         return NULL;
104     }
105 
106     reqList = UsbFnMemCalloc(sizeof(struct ReqList));
107     if (reqList == NULL) {
108         HDF_LOGE("%s:%d UsbFnMemCalloc err", __func__, __LINE__);
109         return NULL;
110     }
111     req = &reqList->req;
112 
113     if (pipe == 0) {
114         DListInsertTail(&reqList->entry, &funcMgr->reqEntry);
115     } else {
116         DListInsertTail(&reqList->entry, &handle->reqEntry);
117     }
118     reqList->handle = handle;
119     reqList->fd = ep;
120     reqList->buf = (uint32_t)mapAddr;
121     reqList->pipe = pipe;
122     reqList->bufLen = len;
123     req->length = len;
124     req->obj = handle->intfMgr->interface.object;
125     req->buf = mapAddr;
126     req->type = GetReqType(handle, pipe);
127 
128     return req;
129 }
130 
UsbFnIoMgrRequestFree(struct UsbFnRequest * req)131 int UsbFnIoMgrRequestFree(struct UsbFnRequest *req)
132 {
133     struct GenericMemory mem;
134     int ret;
135     if (req == NULL) {
136         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
137         return HDF_ERR_INVALID_PARAM;
138     }
139 
140     struct ReqList *reqList = (struct ReqList *) req;
141     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
142 
143     ret = fnOps->unmapAddr(req->buf, reqList->bufLen);
144     if (ret) {
145         HDF_LOGE("%s:%d ummapAddr failed, ret=%d ", __func__, __LINE__, ret);
146         return HDF_ERR_DEVICE_BUSY;
147     }
148     mem.size = reqList->bufLen;
149     mem.buf = (uint32_t)req->buf;
150     ret = fnOps->releaseBuf(reqList->fd, &mem);
151     if (ret) {
152         HDF_LOGE("%s:%d releaseBuf err", __func__, __LINE__);
153         return HDF_ERR_INVALID_PARAM;
154     }
155 
156     DListRemove(&reqList->entry);
157     UsbFnMemFree(reqList);
158     return 0;
159 }
160 
UsbFnIoMgrRequestSubmitAsync(struct UsbFnRequest * req)161 int UsbFnIoMgrRequestSubmitAsync(struct UsbFnRequest *req)
162 {
163     int ret;
164     struct IoData ioData = {0};
165     struct ReqList *reqList = NULL;
166     if (req == NULL) {
167         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
168         return HDF_ERR_INVALID_PARAM;
169     }
170     reqList = (struct ReqList *) req;
171     if (ReqToIoData(req, &ioData, 1, 0)) {
172         return HDF_ERR_IO;
173     }
174     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
175     ret = fnOps->pipeIo(reqList->fd, &ioData);
176 
177     return ret;
178 }
179 
UsbFnIoMgrRequestCancel(struct UsbFnRequest * req)180 int UsbFnIoMgrRequestCancel(struct UsbFnRequest *req)
181 {
182     int ret;
183     struct IoData ioData = {0};
184     struct ReqList *reqList = NULL;
185     if (req == NULL) {
186         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
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 int UsbFnIoMgrRequestGetStatus(struct UsbFnRequest *req, UsbRequestStatus *status)
200 {
201     struct IoData ioData = {0};
202     struct ReqList *reqList;
203     if (req == NULL) {
204         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
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 int UsbFnIoMgrRequestSubmitSync(struct UsbFnRequest *req, uint32_t timeout)
218 {
219     int ret;
220     struct IoData ioData = {0};
221     struct ReqList *reqList;
222 
223     if (req == NULL) {
224         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
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 = ret;
236         return 0;
237     }
238 
239     return ret;
240 }
241 
HandleInit(struct UsbHandleMgr * handle,struct UsbFnInterfaceMgr * interfaceMgr)242 static int HandleInit(struct UsbHandleMgr *handle, struct UsbFnInterfaceMgr *interfaceMgr)
243 {
244     int ret;
245     uint32_t i, j;
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("%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("%s: UsbFnMemCalloc failed", __func__);
265             goto FREE_EVENT;
266         }
267     }
268     handle->intfMgr = interfaceMgr;
269     return 0;
270 
271 FREE_EVENT:
272    for (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     int ret;
281     if (interface == NULL) {
282         return NULL;
283     }
284     struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
285     if (interfaceMgr->isOpen) {
286         HDF_LOGE("%s: interface has opened", __func__);
287         return NULL;
288     }
289     struct UsbHandleMgr *handle = UsbFnMemCalloc(sizeof(struct UsbHandleMgr));
290     if (handle == NULL) {
291         return NULL;
292     }
293 
294     ret = HandleInit(handle, interfaceMgr);
295     if (ret) {
296         HDF_LOGE("%s: HandleInit failed", __func__);
297         UsbFnMemFree(handle);
298         return NULL;
299     }
300 
301     interfaceMgr->isOpen = true;
302     interfaceMgr->handle = handle;
303     return handle;
304 }
305 
UsbFnIoMgrInterfaceClose(struct UsbHandleMgr * handle)306 int UsbFnIoMgrInterfaceClose(struct UsbHandleMgr *handle)
307 {
308     int ret;
309     uint32_t i;
310     if (handle == NULL) {
311         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
312         return HDF_ERR_INVALID_PARAM;
313     }
314     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
315     struct UsbFnInterfaceMgr *interfaceMgr = handle->intfMgr;
316 
317     if (interfaceMgr == NULL || interfaceMgr->isOpen == false) {
318         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
319         return HDF_ERR_INVALID_PARAM;
320     }
321     for (i = 0; i < handle->numFd; i++) {
322         ret = fnOps->queueDel(handle->fds[i]);
323         if (ret) {
324             HDF_LOGE("%s:%d queueDel failed, ret=%d ", __func__, __LINE__, ret);
325             return HDF_ERR_DEVICE_BUSY;
326         }
327 
328         ret = fnOps->closePipe(handle->fds[i]);
329         if (ret) {
330             HDF_LOGE("%s:%d closePipe failed, ret=%d ", __func__, __LINE__, ret);
331             return HDF_ERR_DEVICE_BUSY;
332         }
333         handle->fds[i] = -1;
334         UsbFnMemFree(handle->reqEvent[i]);
335     }
336 
337     UsbFnMemFree(handle);
338     interfaceMgr->isOpen = false;
339     interfaceMgr->handle = NULL;
340     return 0;
341 }
342 
UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface * interface,uint8_t pipeId,struct UsbFnPipeInfo * info)343 int UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface *interface,
344     uint8_t pipeId, struct UsbFnPipeInfo *info)
345 {
346     int ret;
347     int fd;
348     if (info == NULL || interface == NULL || pipeId >= interface->info.numPipes) {
349         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
350         return HDF_ERR_INVALID_PARAM;
351     }
352     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
353     struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
354     if (interfaceMgr->isOpen) {
355         fd = interfaceMgr->handle->fds[pipeId];
356         ret = fnOps->getPipeInfo(fd, info);
357         if (ret) {
358             HDF_LOGE("%s: getPipeInfo failed", __func__);
359             return HDF_ERR_DEVICE_BUSY;
360         }
361     } else {
362         fd = fnOps->openPipe(interfaceMgr->funcMgr->name, interfaceMgr->startEpId + pipeId);
363         if (fd <= 0) {
364             HDF_LOGE("%s: openPipe failed", __func__);
365             return HDF_ERR_IO;
366         }
367         ret = fnOps->getPipeInfo(fd, info);
368         if (ret) {
369             fnOps->closePipe(fd);
370             HDF_LOGE("%s: getPipeInfo failed", __func__);
371             return HDF_ERR_DEVICE_BUSY;
372         }
373         fnOps->closePipe(fd);
374     }
375 
376     info->id = pipeId;
377     return ret;
378 }
379