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