• 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,
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 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("%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     int32_t ret;
62     struct UsbFnPipeInfo info = {0};
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     int32_t ret;
82     int32_t 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 if (pipe <= MAX_EP) {
98         ep = handle->fds[pipe - 1];
99     } else {
100         return NULL;
101     }
102     mapAddr = fnOps->mapAddr(ep, len);
103     if (mapAddr == NULL) {
104         HDF_LOGE("%s:%d mapAddr failed", __func__, __LINE__);
105         return NULL;
106     }
107 
108     reqList = UsbFnMemCalloc(sizeof(struct ReqList));
109     if (reqList == NULL) {
110         HDF_LOGE("%s:%d UsbFnMemCalloc err", __func__, __LINE__);
111         return NULL;
112     }
113     req = &reqList->req;
114 
115     if (pipe == 0) {
116         DListInsertTail(&reqList->entry, &funcMgr->reqEntry);
117     } else {
118         DListInsertTail(&reqList->entry, &handle->reqEntry);
119     }
120     reqList->handle = handle;
121     reqList->fd = ep;
122     reqList->buf = (uintptr_t)mapAddr;
123     reqList->pipe = pipe;
124     reqList->bufLen = len;
125     req->length = len;
126     req->obj = handle->intfMgr->interface.object;
127     req->buf = mapAddr;
128     req->type = GetReqType(handle, pipe);
129 
130     return req;
131 }
132 
UsbFnIoMgrRequestFree(struct UsbFnRequest * req)133 int32_t UsbFnIoMgrRequestFree(struct UsbFnRequest *req)
134 {
135     struct GenericMemory mem;
136     int32_t ret;
137     if (req == NULL) {
138         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
139         return HDF_ERR_INVALID_PARAM;
140     }
141 
142     struct ReqList *reqList = (struct ReqList *) req;
143     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
144 
145     ret = fnOps->unmapAddr(req->buf, reqList->bufLen);
146     if (ret) {
147         HDF_LOGE("%s:%d ummapAddr failed, ret=%d ", __func__, __LINE__, ret);
148         return HDF_ERR_DEVICE_BUSY;
149     }
150     mem.size = reqList->bufLen;
151     mem.buf = (uintptr_t)req->buf;
152     ret = fnOps->releaseBuf(reqList->fd, &mem);
153     if (ret) {
154         HDF_LOGE("%s:%d releaseBuf err", __func__, __LINE__);
155         return HDF_ERR_INVALID_PARAM;
156     }
157 
158     DListRemove(&reqList->entry);
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("%s:%d INVALID_PARAM", __func__, __LINE__);
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     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
177     ret = fnOps->pipeIo(reqList->fd, &ioData);
178 
179     return ret;
180 }
181 
UsbFnIoMgrRequestCancel(struct UsbFnRequest * req)182 int32_t UsbFnIoMgrRequestCancel(struct UsbFnRequest *req)
183 {
184     int32_t ret;
185     struct IoData ioData = {0};
186     struct ReqList *reqList = NULL;
187     if (req == NULL) {
188         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
189         return HDF_ERR_INVALID_PARAM;
190     }
191     reqList = (struct ReqList *) req;
192     if (ReqToIoData(req, &ioData, 1, 0)) {
193         return HDF_ERR_IO;
194     }
195     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
196     ret = fnOps->cancelIo(reqList->fd, &ioData);
197 
198     return ret;
199 }
200 
UsbFnIoMgrRequestGetStatus(struct UsbFnRequest * req,UsbRequestStatus * status)201 int32_t UsbFnIoMgrRequestGetStatus(struct UsbFnRequest *req, UsbRequestStatus *status)
202 {
203     struct IoData ioData = {0};
204     struct ReqList *reqList;
205     if (req == NULL) {
206         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
207         return HDF_ERR_INVALID_PARAM;
208     }
209     reqList = (struct ReqList *) req;
210     if (ReqToIoData(req, &ioData, 1, 0)) {
211         return HDF_ERR_IO;
212     }
213     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
214     *status = -(fnOps->getReqStatus(reqList->fd, &ioData));
215 
216     return 0;
217 }
218 
UsbFnIoMgrRequestSubmitSync(struct UsbFnRequest * req,uint32_t timeout)219 int32_t UsbFnIoMgrRequestSubmitSync(struct UsbFnRequest *req, uint32_t timeout)
220 {
221     int32_t ret;
222     struct IoData ioData = {0};
223     struct ReqList *reqList;
224 
225     if (req == NULL) {
226         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
227         return HDF_ERR_INVALID_PARAM;
228     }
229     reqList = (struct ReqList *) req;
230     if (ReqToIoData(req, &ioData, 0, timeout)) {
231         return HDF_ERR_IO;
232     }
233     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
234     ret = fnOps->pipeIo(reqList->fd, &ioData);
235     if (ret > 0) {
236         req->status = USB_REQUEST_COMPLETED;
237         req->actual = (uint32_t)ret;
238         return 0;
239     }
240 
241     return ret;
242 }
243 
HandleInit(struct UsbHandleMgr * handle,struct UsbFnInterfaceMgr * interfaceMgr)244 static int32_t HandleInit(struct UsbHandleMgr *handle, struct UsbFnInterfaceMgr *interfaceMgr)
245 {
246     int32_t ret;
247     uint32_t i, j;
248     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
249 
250     DListHeadInit(&handle->reqEntry);
251     handle->numFd = interfaceMgr->interface.info.numPipes;
252     for (i = 0; i < handle->numFd; i++) {
253         handle->fds[i] = fnOps->openPipe(interfaceMgr->funcMgr->name, interfaceMgr->startEpId + i);
254         if (handle->fds[i] <= 0) {
255             return HDF_ERR_IO;
256         }
257 
258         ret = fnOps->queueInit(handle->fds[i]);
259         if (ret) {
260             HDF_LOGE("%s: queueInit failed ret = %d", __func__, ret);
261             return HDF_ERR_IO;
262         }
263 
264         handle->reqEvent[i] = UsbFnMemCalloc(sizeof(struct UsbFnReqEvent) * MAX_REQUEST);
265         if (handle->reqEvent[i] == NULL) {
266             HDF_LOGE("%s: UsbFnMemCalloc failed", __func__);
267             goto FREE_EVENT;
268         }
269     }
270     handle->intfMgr = interfaceMgr;
271     return 0;
272 
273 FREE_EVENT:
274    for (j = 0; j < i; j++) {
275         UsbFnMemFree(handle->reqEvent[j]);
276     }
277     return HDF_ERR_IO;
278 }
279 
UsbFnIoMgrInterfaceOpen(struct UsbFnInterface * interface)280 struct UsbHandleMgr *UsbFnIoMgrInterfaceOpen(struct UsbFnInterface *interface)
281 {
282     int32_t ret;
283     if (interface == NULL) {
284         return NULL;
285     }
286     struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
287     if (interfaceMgr->isOpen) {
288         HDF_LOGE("%s: interface has opened", __func__);
289         return NULL;
290     }
291     struct UsbHandleMgr *handle = UsbFnMemCalloc(sizeof(struct UsbHandleMgr));
292     if (handle == NULL) {
293         return NULL;
294     }
295 
296     ret = HandleInit(handle, interfaceMgr);
297     if (ret) {
298         HDF_LOGE("%s: HandleInit failed", __func__);
299         UsbFnMemFree(handle);
300         return NULL;
301     }
302 
303     interfaceMgr->isOpen = true;
304     interfaceMgr->handle = handle;
305     return handle;
306 }
307 
UsbFnIoMgrInterfaceClose(struct UsbHandleMgr * handle)308 int32_t UsbFnIoMgrInterfaceClose(struct UsbHandleMgr *handle)
309 {
310     int32_t ret;
311     uint32_t i;
312     if (handle == NULL) {
313         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
314         return HDF_ERR_INVALID_PARAM;
315     }
316     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
317     struct UsbFnInterfaceMgr *interfaceMgr = handle->intfMgr;
318 
319     if (interfaceMgr == NULL || interfaceMgr->isOpen == false) {
320         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
321         return HDF_ERR_INVALID_PARAM;
322     }
323     for (i = 0; i < handle->numFd; i++) {
324         ret = fnOps->queueDel(handle->fds[i]);
325         if (ret) {
326             HDF_LOGE("%s:%d queueDel failed, ret=%d ", __func__, __LINE__, ret);
327             return HDF_ERR_DEVICE_BUSY;
328         }
329 
330         ret = fnOps->closePipe(handle->fds[i]);
331         if (ret) {
332             HDF_LOGE("%s:%d closePipe failed, ret=%d ", __func__, __LINE__, ret);
333             return HDF_ERR_DEVICE_BUSY;
334         }
335         handle->fds[i] = -1;
336         UsbFnMemFree(handle->reqEvent[i]);
337     }
338 
339     UsbFnMemFree(handle);
340     interfaceMgr->isOpen = false;
341     interfaceMgr->handle = NULL;
342     return 0;
343 }
344 
UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface * interface,uint8_t pipeId,struct UsbFnPipeInfo * info)345 int32_t UsbFnIoMgrInterfaceGetPipeInfo(struct UsbFnInterface *interface,
346     uint8_t pipeId, struct UsbFnPipeInfo *info)
347 {
348     int32_t ret;
349     int32_t fd;
350     if (info == NULL || interface == NULL || pipeId >= interface->info.numPipes) {
351         HDF_LOGE("%s:%d INVALID_PARAM", __func__, __LINE__);
352         return HDF_ERR_INVALID_PARAM;
353     }
354     struct UsbFnAdapterOps *fnOps = UsbFnAdapterGetOps();
355     struct UsbFnInterfaceMgr *interfaceMgr = (struct UsbFnInterfaceMgr *)interface;
356     if (interfaceMgr->isOpen) {
357         fd = interfaceMgr->handle->fds[pipeId];
358         ret = fnOps->getPipeInfo(fd, info);
359         if (ret) {
360             HDF_LOGE("%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("%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("%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