• 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 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