1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "liteos_adapter.h"
17094332d3Sopenharmony_ci#include "los_spinlock.h"
18094332d3Sopenharmony_ci#ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
19094332d3Sopenharmony_ci#include "usb_pnp_notify.h"
20094332d3Sopenharmony_ci#endif
21094332d3Sopenharmony_ci#include "usbd_wrapper.h"
22094332d3Sopenharmony_ci
23094332d3Sopenharmony_ci#define HDF_LOG_TAG USB_LITEOS_ADAPTER
24094332d3Sopenharmony_ci
25094332d3Sopenharmony_ci#define PATH_LEN      24
26094332d3Sopenharmony_ci#define DESC_READ_LEN 256
27094332d3Sopenharmony_ci#define EP_NUM_MAX    30
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_cistatic bool g_CompleteExit;
30094332d3Sopenharmony_ci
31094332d3Sopenharmony_cienum UrbState {
32094332d3Sopenharmony_ci    URB_INIT_STATE,
33094332d3Sopenharmony_ci    URB_SUBMIT_STATE,
34094332d3Sopenharmony_ci    URB_REAP_STATE,
35094332d3Sopenharmony_ci};
36094332d3Sopenharmony_ci
37094332d3Sopenharmony_cistruct Async {
38094332d3Sopenharmony_ci    struct DListHead asynclist;
39094332d3Sopenharmony_ci    enum UrbState state;
40094332d3Sopenharmony_ci    struct UsbDevice *dev;
41094332d3Sopenharmony_ci    UsbAdapterUrb urb;
42094332d3Sopenharmony_ci};
43094332d3Sopenharmony_ci
44094332d3Sopenharmony_cistruct OsDev {
45094332d3Sopenharmony_ci    struct DListHead asyncCompleted;
46094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice;
47094332d3Sopenharmony_ci    SPIN_LOCK_S completeLock;
48094332d3Sopenharmony_ci    struct OsalMutex completeMux;
49094332d3Sopenharmony_ci    struct OsalSem cvWait;
50094332d3Sopenharmony_ci};
51094332d3Sopenharmony_ci
52094332d3Sopenharmony_cistatic void *OsAdapterRealloc(void *ptr, size_t oldSize, size_t newSize)
53094332d3Sopenharmony_ci{
54094332d3Sopenharmony_ci    void *mem;
55094332d3Sopenharmony_ci
56094332d3Sopenharmony_ci    mem = RawUsbMemAlloc(newSize);
57094332d3Sopenharmony_ci    if (mem == NULL) {
58094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
59094332d3Sopenharmony_ci        goto OUT;
60094332d3Sopenharmony_ci    }
61094332d3Sopenharmony_ci
62094332d3Sopenharmony_ci    if (oldSize > 0) {
63094332d3Sopenharmony_ci        if (memmove_s(mem, newSize, ptr, oldSize) != HDF_SUCCESS) {
64094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
65094332d3Sopenharmony_ci            RawUsbMemFree(mem);
66094332d3Sopenharmony_ci            mem = NULL;
67094332d3Sopenharmony_ci            goto OUT;
68094332d3Sopenharmony_ci        }
69094332d3Sopenharmony_ci    }
70094332d3Sopenharmony_ci
71094332d3Sopenharmony_ci    RawUsbMemFree(ptr);
72094332d3Sopenharmony_ci    ptr = NULL;
73094332d3Sopenharmony_ciOUT:
74094332d3Sopenharmony_ci    return mem;
75094332d3Sopenharmony_ci}
76094332d3Sopenharmony_ci
77094332d3Sopenharmony_cistatic bool UsbFindUrb(const struct Async *urb, struct DListHead *list)
78094332d3Sopenharmony_ci{
79094332d3Sopenharmony_ci    bool findFlag = false;
80094332d3Sopenharmony_ci    struct OsDev *osDev = CONTAINER_OF(list, struct OsDev, asyncCompleted);
81094332d3Sopenharmony_ci    struct Async *asPos = NULL;
82094332d3Sopenharmony_ci    struct Async *asTemp = NULL;
83094332d3Sopenharmony_ci    if (DListIsEmpty(&osDev->asyncCompleted)) {
84094332d3Sopenharmony_ci        return false;
85094332d3Sopenharmony_ci    }
86094332d3Sopenharmony_ci    DLIST_FOR_EACH_ENTRY_SAFE(asPos, asTemp, list, struct Async, asynclist) {
87094332d3Sopenharmony_ci        if (asPos == urb) {
88094332d3Sopenharmony_ci            findFlag = true;
89094332d3Sopenharmony_ci            break;
90094332d3Sopenharmony_ci        }
91094332d3Sopenharmony_ci    }
92094332d3Sopenharmony_ci    return findFlag;
93094332d3Sopenharmony_ci}
94094332d3Sopenharmony_ci
95094332d3Sopenharmony_cistatic void OsUrbComplete(UsbAdapterUrb *urb)
96094332d3Sopenharmony_ci{
97094332d3Sopenharmony_ci    uint32_t save;
98094332d3Sopenharmony_ci    struct Async *as = CONTAINER_OF(urb, struct Async, urb);
99094332d3Sopenharmony_ci    struct UsbDevice *dev = as->dev;
100094332d3Sopenharmony_ci    if (dev == NULL) {
101094332d3Sopenharmony_ci        DPRINTFN(0, "dev is null\n");
102094332d3Sopenharmony_ci        return;
103094332d3Sopenharmony_ci    }
104094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
105094332d3Sopenharmony_ci    if (osDev == NULL) {
106094332d3Sopenharmony_ci        DPRINTFN(0, "osDev is null\n");
107094332d3Sopenharmony_ci        return;
108094332d3Sopenharmony_ci    }
109094332d3Sopenharmony_ci    as->state = URB_REAP_STATE;
110094332d3Sopenharmony_ci    LOS_SpinLockSave(&osDev->completeLock, &save);
111094332d3Sopenharmony_ci    if (UsbFindUrb(as, &osDev->asyncCompleted) == false) {
112094332d3Sopenharmony_ci        DListInsertTail(&as->asynclist, &osDev->asyncCompleted);
113094332d3Sopenharmony_ci        LOS_SpinUnlockRestore(&osDev->completeLock, save);
114094332d3Sopenharmony_ci        OsalSemPost(&osDev->cvWait);
115094332d3Sopenharmony_ci    } else {
116094332d3Sopenharmony_ci        LOS_SpinUnlockRestore(&osDev->completeLock, save);
117094332d3Sopenharmony_ci    }
118094332d3Sopenharmony_ci}
119094332d3Sopenharmony_ci
120094332d3Sopenharmony_cistatic int32_t OsSubmitUrb(UsbAdapterUrb *urb, UsbAdapterDevice *adapterDevice, UsbAdapterHostEndpoint *uhe)
121094332d3Sopenharmony_ci{
122094332d3Sopenharmony_ci    int32_t err;
123094332d3Sopenharmony_ci
124094332d3Sopenharmony_ci    if ((uhe == NULL) || (urb == NULL) || (adapterDevice == NULL)) {
125094332d3Sopenharmony_ci        DPRINTFN(0, "invalid param\n");
126094332d3Sopenharmony_ci        return (-EINVAL);
127094332d3Sopenharmony_ci    }
128094332d3Sopenharmony_ci
129094332d3Sopenharmony_ci    err = usb_setup_endpoint(adapterDevice, uhe, 1024);
130094332d3Sopenharmony_ci    if (err < 0) {
131094332d3Sopenharmony_ci        DPRINTFN(0, "setup failed err:%d\n", err);
132094332d3Sopenharmony_ci        return (err);
133094332d3Sopenharmony_ci    }
134094332d3Sopenharmony_ci    err = usb_submit_urb(urb, 0);
135094332d3Sopenharmony_ci    return (err);
136094332d3Sopenharmony_ci}
137094332d3Sopenharmony_ci
138094332d3Sopenharmony_cistatic int32_t OsControlMsg(UsbAdapterUrb *urb)
139094332d3Sopenharmony_ci{
140094332d3Sopenharmony_ci    uint16_t actLen = 0;
141094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = urb->dev;
142094332d3Sopenharmony_ci    void *buffer = urb->transfer_buffer;
143094332d3Sopenharmony_ci    UsbAdapterDeviceRequest req;
144094332d3Sopenharmony_ci
145094332d3Sopenharmony_ci    int32_t err = memcpy_s(&req, sizeof(UsbAdapterDeviceRequest), buffer, sizeof(UsbAdapterDeviceRequest));
146094332d3Sopenharmony_ci    if (err != EOK) {
147094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d err=%d\n", __func__, __LINE__, err);
148094332d3Sopenharmony_ci        err = HDF_ERR_IO;
149094332d3Sopenharmony_ci        return err;
150094332d3Sopenharmony_ci    }
151094332d3Sopenharmony_ci    err = usbd_do_request_flags(
152094332d3Sopenharmony_ci        adapterDevice, NULL, &req, (char *)buffer + sizeof(req), USB_SHORT_XFER_OK, &actLen, urb->timeout);
153094332d3Sopenharmony_ci    if (err) {
154094332d3Sopenharmony_ci        DPRINTFN(1, "OsControlMsg!err:%d\n", err);
155094332d3Sopenharmony_ci    }
156094332d3Sopenharmony_ci    urb->actual_length = actLen;
157094332d3Sopenharmony_ci    if (urb->complete) {
158094332d3Sopenharmony_ci        (urb->complete)(urb);
159094332d3Sopenharmony_ci    }
160094332d3Sopenharmony_ci    return err;
161094332d3Sopenharmony_ci}
162094332d3Sopenharmony_ci
163094332d3Sopenharmony_cistatic int32_t OsWaitUrb(struct OsDev *osDev)
164094332d3Sopenharmony_ci{
165094332d3Sopenharmony_ci    if (osDev == NULL) {
166094332d3Sopenharmony_ci        return HDF_FAILURE;
167094332d3Sopenharmony_ci    }
168094332d3Sopenharmony_ci    do {
169094332d3Sopenharmony_ci        OsalSemWait(&osDev->cvWait, HDF_WAIT_FOREVER);
170094332d3Sopenharmony_ci    } while (!g_CompleteExit && DListIsEmpty(&osDev->asyncCompleted));
171094332d3Sopenharmony_ci    return HDF_SUCCESS;
172094332d3Sopenharmony_ci}
173094332d3Sopenharmony_ci
174094332d3Sopenharmony_cistatic int32_t OsReapUrb(const struct UsbDeviceHandle *handle, struct Async **urb)
175094332d3Sopenharmony_ci{
176094332d3Sopenharmony_ci    if ((handle == NULL) || (handle->dev == NULL) || (handle->dev->privateData == NULL)) {
177094332d3Sopenharmony_ci        PRINTK("invalid parmater\n");
178094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
179094332d3Sopenharmony_ci    }
180094332d3Sopenharmony_ci    int32_t err = 0;
181094332d3Sopenharmony_ci    uint32_t save;
182094332d3Sopenharmony_ci    struct Async *as = NULL;
183094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
184094332d3Sopenharmony_ci    if (dev->privateData == NULL) {
185094332d3Sopenharmony_ci        PRINTK("invalid parmater\n");
186094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
187094332d3Sopenharmony_ci    }
188094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
189094332d3Sopenharmony_ci    err = OsWaitUrb(osDev);
190094332d3Sopenharmony_ci    LOS_SpinLockSave(&osDev->completeLock, &save);
191094332d3Sopenharmony_ci    if (!DListIsEmpty(&osDev->asyncCompleted)) {
192094332d3Sopenharmony_ci        as = DLIST_FIRST_ENTRY(&osDev->asyncCompleted, struct Async, asynclist);
193094332d3Sopenharmony_ci        DListRemove(&as->asynclist);
194094332d3Sopenharmony_ci    }
195094332d3Sopenharmony_ci    LOS_SpinUnlockRestore(&osDev->completeLock, save);
196094332d3Sopenharmony_ci    *urb = as;
197094332d3Sopenharmony_ci    return err;
198094332d3Sopenharmony_ci}
199094332d3Sopenharmony_ci
200094332d3Sopenharmony_cistatic bool OsDeviceCompare(struct HdfSListNode *listEntry, uint32_t searchKey)
201094332d3Sopenharmony_ci{
202094332d3Sopenharmony_ci    struct UsbDevice *dev = (struct UsbDevice *)listEntry;
203094332d3Sopenharmony_ci    if (dev == NULL) {
204094332d3Sopenharmony_ci        return false;
205094332d3Sopenharmony_ci    }
206094332d3Sopenharmony_ci
207094332d3Sopenharmony_ci    if ((dev->busNum == (searchKey >> BUS_OFFSET)) && (dev->devAddr == (searchKey & 0xFF))) {
208094332d3Sopenharmony_ci        return true;
209094332d3Sopenharmony_ci    }
210094332d3Sopenharmony_ci
211094332d3Sopenharmony_ci    return false;
212094332d3Sopenharmony_ci}
213094332d3Sopenharmony_ci
214094332d3Sopenharmony_cistatic struct UsbDeviceHandle *OsGetDeviceHandle(struct UsbSession *session, uint8_t busNum, uint8_t usbAddr)
215094332d3Sopenharmony_ci{
216094332d3Sopenharmony_ci    struct UsbDevice *dev = NULL;
217094332d3Sopenharmony_ci    struct UsbDeviceHandle *handle = NULL;
218094332d3Sopenharmony_ci
219094332d3Sopenharmony_ci    if (session == NULL) {
220094332d3Sopenharmony_ci        DPRINTFN(0, "%s:invalid param\n", __func__);
221094332d3Sopenharmony_ci        return NULL;
222094332d3Sopenharmony_ci    }
223094332d3Sopenharmony_ci
224094332d3Sopenharmony_ci    OsalMutexLock(&session->lock);
225094332d3Sopenharmony_ci    dev = (struct UsbDevice *)HdfSListSearch(&session->usbDevs, (busNum << BUS_OFFSET) | usbAddr, OsDeviceCompare);
226094332d3Sopenharmony_ci    if (dev != NULL) {
227094332d3Sopenharmony_ci        handle = dev->devHandle;
228094332d3Sopenharmony_ci        AdapterAtomicInc(&dev->refcnt);
229094332d3Sopenharmony_ci    }
230094332d3Sopenharmony_ci    OsalMutexUnlock(&session->lock);
231094332d3Sopenharmony_ci
232094332d3Sopenharmony_ci    return handle;
233094332d3Sopenharmony_ci}
234094332d3Sopenharmony_ci
235094332d3Sopenharmony_cistatic struct UsbDeviceHandle *OsCallocDeviceHandle(void)
236094332d3Sopenharmony_ci{
237094332d3Sopenharmony_ci    struct UsbDeviceHandle *handle = NULL;
238094332d3Sopenharmony_ci
239094332d3Sopenharmony_ci    handle = RawUsbMemCalloc(sizeof(*handle));
240094332d3Sopenharmony_ci    if (handle == NULL) {
241094332d3Sopenharmony_ci        DPRINTFN(0, "%s: allocate handle failed", __func__);
242094332d3Sopenharmony_ci        return NULL;
243094332d3Sopenharmony_ci    }
244094332d3Sopenharmony_ci
245094332d3Sopenharmony_ci    OsalMutexInit(&handle->lock);
246094332d3Sopenharmony_ci
247094332d3Sopenharmony_ci    return handle;
248094332d3Sopenharmony_ci}
249094332d3Sopenharmony_ci
250094332d3Sopenharmony_cistatic struct UsbDevice *OsAllocDevice(struct UsbSession *session, struct UsbDeviceHandle *handle)
251094332d3Sopenharmony_ci{
252094332d3Sopenharmony_ci    struct UsbDevice *dev = RawUsbMemCalloc(sizeof(*dev));
253094332d3Sopenharmony_ci    if (dev == NULL) {
254094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d no memory", __func__, __LINE__);
255094332d3Sopenharmony_ci        return NULL;
256094332d3Sopenharmony_ci    }
257094332d3Sopenharmony_ci
258094332d3Sopenharmony_ci    dev->session = session;
259094332d3Sopenharmony_ci    dev->devHandle = handle;
260094332d3Sopenharmony_ci
261094332d3Sopenharmony_ci    RawRequestListInit(dev);
262094332d3Sopenharmony_ci
263094332d3Sopenharmony_ci    handle->dev = dev;
264094332d3Sopenharmony_ci    return dev;
265094332d3Sopenharmony_ci}
266094332d3Sopenharmony_ci
267094332d3Sopenharmony_cistatic int32_t OsReadDescriptors(struct UsbDevice *dev)
268094332d3Sopenharmony_ci{
269094332d3Sopenharmony_ci    size_t allocLen = 0;
270094332d3Sopenharmony_ci    int32_t ret;
271094332d3Sopenharmony_ci    if (dev == NULL) {
272094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d dev is NULL!", __func__, __LINE__);
273094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
274094332d3Sopenharmony_ci    }
275094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
276094332d3Sopenharmony_ci    if ((osDev == NULL) || (osDev->adapterDevice == NULL) || (osDev->adapterDevice->cdesc == NULL)) {
277094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d is NULL!", __func__, __LINE__);
278094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
279094332d3Sopenharmony_ci    }
280094332d3Sopenharmony_ci
281094332d3Sopenharmony_ci    do {
282094332d3Sopenharmony_ci        size_t oldLen = allocLen;
283094332d3Sopenharmony_ci        allocLen += DESC_READ_LEN;
284094332d3Sopenharmony_ci        dev->descriptors = OsAdapterRealloc(dev->descriptors, oldLen, allocLen);
285094332d3Sopenharmony_ci        if ((dev->descriptors == NULL) || (dev->descriptorsLength > allocLen)) {
286094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d\n", __func__, __LINE__);
287094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
288094332d3Sopenharmony_ci        }
289094332d3Sopenharmony_ci        uint8_t *ptr = (uint8_t *)dev->descriptors + dev->descriptorsLength;
290094332d3Sopenharmony_ci        if (ptr == NULL) {
291094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d ptr is NULL\n", __func__, __LINE__);
292094332d3Sopenharmony_ci            ret = HDF_ERR_INVALID_PARAM;
293094332d3Sopenharmony_ci            return ret;
294094332d3Sopenharmony_ci        }
295094332d3Sopenharmony_ci        ret = memset_s(ptr, DESC_READ_LEN, 0, DESC_READ_LEN);
296094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
297094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
298094332d3Sopenharmony_ci            return HDF_FAILURE;
299094332d3Sopenharmony_ci        }
300094332d3Sopenharmony_ci
301094332d3Sopenharmony_ci        size_t count = UGETW(osDev->adapterDevice->cdesc->wTotalLength);
302094332d3Sopenharmony_ci        if (count > DESC_READ_LEN) {
303094332d3Sopenharmony_ci            ret = HDF_ERR_IO;
304094332d3Sopenharmony_ci            return ret;
305094332d3Sopenharmony_ci        }
306094332d3Sopenharmony_ci        ret = memcpy_s(ptr, DESC_READ_LEN, osDev->adapterDevice->cdesc, count);
307094332d3Sopenharmony_ci        if (ret != EOK) {
308094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d ret=%d\n", __func__, __LINE__, ret);
309094332d3Sopenharmony_ci            ret = HDF_ERR_IO;
310094332d3Sopenharmony_ci            return ret;
311094332d3Sopenharmony_ci        }
312094332d3Sopenharmony_ci        DPRINTFN(0, "%s:+configdes_size:%d+type:%d\n", __func__, UGETW(osDev->adapterDevice->cdesc->wTotalLength),
313094332d3Sopenharmony_ci            osDev->adapterDevice->cdesc->bDescriptorType);
314094332d3Sopenharmony_ci        dev->descriptorsLength += count;
315094332d3Sopenharmony_ci    } while (dev->descriptorsLength == allocLen);
316094332d3Sopenharmony_ci
317094332d3Sopenharmony_ci    return HDF_SUCCESS;
318094332d3Sopenharmony_ci}
319094332d3Sopenharmony_ci
320094332d3Sopenharmony_cistatic int32_t OsParseConfigDescriptors(struct UsbDevice *dev)
321094332d3Sopenharmony_ci{
322094332d3Sopenharmony_ci    uint8_t i;
323094332d3Sopenharmony_ci    uint8_t *buffer = NULL;
324094332d3Sopenharmony_ci    size_t descLen;
325094332d3Sopenharmony_ci    UsbAdapterDeviceDescriptor *deviceDesc = NULL;
326094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
327094332d3Sopenharmony_ci    deviceDesc = &osDev->adapterDevice->ddesc;
328094332d3Sopenharmony_ci    uint8_t numConfigs = deviceDesc->bNumConfigurations;
329094332d3Sopenharmony_ci    if (numConfigs == 0) {
330094332d3Sopenharmony_ci        return HDF_SUCCESS;
331094332d3Sopenharmony_ci    }
332094332d3Sopenharmony_ci    dev->configDescriptors = RawUsbMemAlloc(numConfigs * sizeof(struct UsbDeviceConfigDescriptor));
333094332d3Sopenharmony_ci    if (dev->configDescriptors == NULL) {
334094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d\n", __func__, __LINE__);
335094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
336094332d3Sopenharmony_ci    }
337094332d3Sopenharmony_ci    buffer = (uint8_t *)dev->descriptors;
338094332d3Sopenharmony_ci    descLen = dev->descriptorsLength;
339094332d3Sopenharmony_ci
340094332d3Sopenharmony_ci    for (i = 0; i < numConfigs; i++) {
341094332d3Sopenharmony_ci        struct UsbConfigDescriptor *configDesc = NULL;
342094332d3Sopenharmony_ci        uint16_t configLen;
343094332d3Sopenharmony_ci
344094332d3Sopenharmony_ci        if (descLen < USB_DDK_DT_CONFIG_SIZE) {
345094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d read %zu", __func__, __LINE__, descLen);
346094332d3Sopenharmony_ci            RawUsbMemFree(dev->configDescriptors);
347094332d3Sopenharmony_ci            return HDF_ERR_IO;
348094332d3Sopenharmony_ci        }
349094332d3Sopenharmony_ci        configDesc = (struct UsbConfigDescriptor *)buffer;
350094332d3Sopenharmony_ci        if ((configDesc->bDescriptorType != USB_DDK_DT_CONFIG) || (configDesc->bLength < USB_DDK_DT_CONFIG_SIZE)) {
351094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d config desc error: type 0x%02x, length %u\n", __func__, __LINE__,
352094332d3Sopenharmony_ci                configDesc->bDescriptorType, configDesc->bLength);
353094332d3Sopenharmony_ci            RawUsbMemFree(dev->configDescriptors);
354094332d3Sopenharmony_ci            return HDF_ERR_IO;
355094332d3Sopenharmony_ci        }
356094332d3Sopenharmony_ci        configLen = LE16_TO_CPU(configDesc->wTotalLength);
357094332d3Sopenharmony_ci        if (configLen < USB_DDK_DT_CONFIG_SIZE) {
358094332d3Sopenharmony_ci            DPRINTFN(0, "invalid wTotalLength value %u\n", configLen);
359094332d3Sopenharmony_ci            RawUsbMemFree(dev->configDescriptors);
360094332d3Sopenharmony_ci            return HDF_ERR_IO;
361094332d3Sopenharmony_ci        }
362094332d3Sopenharmony_ci        if (configLen > descLen) {
363094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d read %zu/%u\n", __func__, __LINE__, descLen, configLen);
364094332d3Sopenharmony_ci            configLen = (uint16_t)descLen;
365094332d3Sopenharmony_ci        }
366094332d3Sopenharmony_ci        dev->configDescriptors[i].desc = configDesc;
367094332d3Sopenharmony_ci        dev->configDescriptors[i].actualLen = configLen;
368094332d3Sopenharmony_ci        buffer += configLen;
369094332d3Sopenharmony_ci        descLen -= configLen;
370094332d3Sopenharmony_ci    }
371094332d3Sopenharmony_ci    return HDF_SUCCESS;
372094332d3Sopenharmony_ci}
373094332d3Sopenharmony_ci
374094332d3Sopenharmony_cistatic struct OsDev *OsDevAllocInit(void)
375094332d3Sopenharmony_ci{
376094332d3Sopenharmony_ci    struct OsDev *osDev = NULL;
377094332d3Sopenharmony_ci    osDev = RawUsbMemCalloc(sizeof(*osDev));
378094332d3Sopenharmony_ci    if (osDev == NULL) {
379094332d3Sopenharmony_ci        return NULL;
380094332d3Sopenharmony_ci    }
381094332d3Sopenharmony_ci    DListHeadInit(&osDev->asyncCompleted);
382094332d3Sopenharmony_ci    OsalSemInit(&osDev->cvWait, 0);
383094332d3Sopenharmony_ci    LOS_SpinInit(&osDev->completeLock);
384094332d3Sopenharmony_ci    OsalMutexInit(&osDev->completeMux);
385094332d3Sopenharmony_ci    return osDev;
386094332d3Sopenharmony_ci}
387094332d3Sopenharmony_ci
388094332d3Sopenharmony_cistatic void OsDevDestory(struct OsDev *osDev)
389094332d3Sopenharmony_ci{
390094332d3Sopenharmony_ci    if (osDev == NULL) {
391094332d3Sopenharmony_ci        DPRINTFN(0, "invalid parma\n");
392094332d3Sopenharmony_ci        return;
393094332d3Sopenharmony_ci    }
394094332d3Sopenharmony_ci    OsalSemDestroy(&osDev->cvWait);
395094332d3Sopenharmony_ci    OsalMutexDestroy(&osDev->completeMux);
396094332d3Sopenharmony_ci    RawUsbMemFree(osDev);
397094332d3Sopenharmony_ci}
398094332d3Sopenharmony_ci
399094332d3Sopenharmony_cistatic int32_t OsInitDevice(struct UsbDevice *dev, uint8_t busNum, uint8_t devAddr)
400094332d3Sopenharmony_ci{
401094332d3Sopenharmony_ci    struct OsDev *osDev = NULL;
402094332d3Sopenharmony_ci    int32_t ret;
403094332d3Sopenharmony_ci
404094332d3Sopenharmony_ci    dev->busNum = busNum;
405094332d3Sopenharmony_ci    dev->devAddr = devAddr;
406094332d3Sopenharmony_ci    osDev = OsDevAllocInit();
407094332d3Sopenharmony_ci    if (osDev == NULL) {
408094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d osDev  is NULL\n", __func__, __LINE__);
409094332d3Sopenharmony_ci        return HDF_DEV_ERR_NO_DEVICE;
410094332d3Sopenharmony_ci    }
411094332d3Sopenharmony_ci    g_CompleteExit = false;
412094332d3Sopenharmony_ci#ifdef LOSCFG_DRIVERS_HDF_USB_PNP_NOTIFY
413094332d3Sopenharmony_ci    struct UsbGetDevicePara paraData;
414094332d3Sopenharmony_ci    paraData.type = USB_PNP_DEVICE_ADDRESS_TYPE;
415094332d3Sopenharmony_ci    paraData.busNum = dev->busNum;
416094332d3Sopenharmony_ci    paraData.devNum = dev->devAddr;
417094332d3Sopenharmony_ci    osDev->adapterDevice = UsbPnpNotifyGetUsbDevice(paraData);
418094332d3Sopenharmony_ci#else
419094332d3Sopenharmony_ci    osDev->adapterDevice = NULL;
420094332d3Sopenharmony_ci#endif
421094332d3Sopenharmony_ci    if (osDev->adapterDevice == NULL) {
422094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d osDev->adapterDevice is NULL\n", __func__, __LINE__);
423094332d3Sopenharmony_ci        return HDF_DEV_ERR_NO_DEVICE;
424094332d3Sopenharmony_ci    }
425094332d3Sopenharmony_ci
426094332d3Sopenharmony_ci    dev->privateData = (void *)osDev;
427094332d3Sopenharmony_ci    dev->descriptorsLength = 0;
428094332d3Sopenharmony_ci    ret = OsReadDescriptors(dev);
429094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
430094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d ret=%d\n", __func__, __LINE__, ret);
431094332d3Sopenharmony_ci        return ret;
432094332d3Sopenharmony_ci    }
433094332d3Sopenharmony_ci    ret = OsParseConfigDescriptors(dev);
434094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
435094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d ret=%d\n", __func__, __LINE__, ret);
436094332d3Sopenharmony_ci        return ret;
437094332d3Sopenharmony_ci    }
438094332d3Sopenharmony_ci    ret = memcpy_s(&dev->deviceDescriptor, sizeof(struct UsbDeviceDescriptor), &osDev->adapterDevice->ddesc,
439094332d3Sopenharmony_ci        USB_DDK_DT_DEVICE_SIZE);
440094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
441094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d ret=%d\n", __func__, __LINE__, ret);
442094332d3Sopenharmony_ci        ret = HDF_ERR_IO;
443094332d3Sopenharmony_ci    }
444094332d3Sopenharmony_ci    return ret;
445094332d3Sopenharmony_ci}
446094332d3Sopenharmony_ci
447094332d3Sopenharmony_cistatic void OsFreeIsoUrbs(struct UsbHostRequest *request)
448094332d3Sopenharmony_ci{
449094332d3Sopenharmony_ci    struct Async *urb = NULL;
450094332d3Sopenharmony_ci
451094332d3Sopenharmony_ci    for (int32_t i = 0; i < request->numUrbs; i++) {
452094332d3Sopenharmony_ci        urb = request->isoUrbs[i];
453094332d3Sopenharmony_ci        if (urb == NULL) {
454094332d3Sopenharmony_ci            break;
455094332d3Sopenharmony_ci        }
456094332d3Sopenharmony_ci        RawUsbMemFree(urb);
457094332d3Sopenharmony_ci        request->isoUrbs[i] = NULL;
458094332d3Sopenharmony_ci    }
459094332d3Sopenharmony_ci
460094332d3Sopenharmony_ci    RawUsbMemFree(request->isoUrbs);
461094332d3Sopenharmony_ci    request->isoUrbs = NULL;
462094332d3Sopenharmony_ci}
463094332d3Sopenharmony_ci
464094332d3Sopenharmony_cistatic void OsDiscardUrbs(const struct UsbHostRequest *request, int32_t first, int32_t last)
465094332d3Sopenharmony_ci{
466094332d3Sopenharmony_ci    UsbAdapterUrb *urb = NULL;
467094332d3Sopenharmony_ci    struct Async *as = NULL;
468094332d3Sopenharmony_ci
469094332d3Sopenharmony_ci    if ((request == NULL) || (request->devHandle == NULL) || (first > URBS_PER_REQUEST) || (first > last)) {
470094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
471094332d3Sopenharmony_ci        return;
472094332d3Sopenharmony_ci    }
473094332d3Sopenharmony_ci
474094332d3Sopenharmony_ci    for (int32_t i = last - 1; i >= first; i--) {
475094332d3Sopenharmony_ci        if (request->requestType == USB_REQUEST_TYPE_ISOCHRONOUS) {
476094332d3Sopenharmony_ci            as = (struct Async *)request->isoUrbs[i];
477094332d3Sopenharmony_ci        } else {
478094332d3Sopenharmony_ci            as = &(((struct Async *)request->urbs)[i]);
479094332d3Sopenharmony_ci        }
480094332d3Sopenharmony_ci        if (as == NULL) {
481094332d3Sopenharmony_ci            DPRINTFN(0, "discard as null\n");
482094332d3Sopenharmony_ci            return;
483094332d3Sopenharmony_ci        }
484094332d3Sopenharmony_ci        urb = &as->urb;
485094332d3Sopenharmony_ci        if (as->state == URB_SUBMIT_STATE) {
486094332d3Sopenharmony_ci            DPRINTFN(0, "usb kill urb\n");
487094332d3Sopenharmony_ci            usb_kill_urb(urb);
488094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d discard request\n", __func__, __LINE__);
489094332d3Sopenharmony_ci        }
490094332d3Sopenharmony_ci    }
491094332d3Sopenharmony_ci}
492094332d3Sopenharmony_ci
493094332d3Sopenharmony_cistatic int32_t OsSubmitControlMsg(
494094332d3Sopenharmony_ci    struct UsbHostRequest * const request, const UsbAdapterDevice *adapterDevice, const struct UsbDevice *dev)
495094332d3Sopenharmony_ci{
496094332d3Sopenharmony_ci    int32_t ret;
497094332d3Sopenharmony_ci    struct Async *as = NULL;
498094332d3Sopenharmony_ci    UsbAdapterUrb *urb = NULL;
499094332d3Sopenharmony_ci    UsbAdapterHostEndpoint *uhe = NULL;
500094332d3Sopenharmony_ci    if ((request == NULL) || (request->length > MAX_BULK_DATA_BUFFER_LENGTH) || (request->buffer == NULL) ||
501094332d3Sopenharmony_ci        (adapterDevice == NULL) || (dev == NULL)) {
502094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
503094332d3Sopenharmony_ci    }
504094332d3Sopenharmony_ci    uhe = usb_find_host_endpoint((UsbAdapterDevice *)adapterDevice, request->requestType, request->endPoint);
505094332d3Sopenharmony_ci    if (uhe == NULL) {
506094332d3Sopenharmony_ci        DPRINTFN(0, "no found endpoint\n");
507094332d3Sopenharmony_ci        return -1;
508094332d3Sopenharmony_ci    }
509094332d3Sopenharmony_ci    if (request->urbs == NULL) {
510094332d3Sopenharmony_ci        as = RawUsbMemCalloc(sizeof(*as));
511094332d3Sopenharmony_ci        request->urbs = (void *)as;
512094332d3Sopenharmony_ci        request->numUrbs = 1;
513094332d3Sopenharmony_ci    }
514094332d3Sopenharmony_ci
515094332d3Sopenharmony_ci    if (request->urbs == NULL) {
516094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d no mem", __func__, __LINE__);
517094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
518094332d3Sopenharmony_ci    }
519094332d3Sopenharmony_ci    as = (struct Async *)request->urbs;
520094332d3Sopenharmony_ci    DListHeadInit(&as->asynclist);
521094332d3Sopenharmony_ci    as->dev = (struct UsbDevice *)dev;
522094332d3Sopenharmony_ci    as->state = URB_SUBMIT_STATE;
523094332d3Sopenharmony_ci    urb = &as->urb;
524094332d3Sopenharmony_ci    ret = memset_s(urb, sizeof(*urb), 0, sizeof(*urb));
525094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
526094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
527094332d3Sopenharmony_ci        return HDF_FAILURE;
528094332d3Sopenharmony_ci    }
529094332d3Sopenharmony_ci
530094332d3Sopenharmony_ci    urb->dev = (UsbAdapterDevice *)adapterDevice;
531094332d3Sopenharmony_ci    urb->endpoint = uhe;
532094332d3Sopenharmony_ci    urb->timeout = 500;
533094332d3Sopenharmony_ci    urb->transfer_buffer = request->buffer;
534094332d3Sopenharmony_ci    urb->context = (void *)request;
535094332d3Sopenharmony_ci    urb->complete = OsUrbComplete;
536094332d3Sopenharmony_ci    ret = OsControlMsg(urb);
537094332d3Sopenharmony_ci    DPRINTFN(0, "OsSubmitControlRequest:ret:%d\n", ret);
538094332d3Sopenharmony_ci    if (ret) {
539094332d3Sopenharmony_ci        DPRINTFN(0, "submiturb failed, errno=%d\n", errno);
540094332d3Sopenharmony_ci        return HDF_ERR_IO;
541094332d3Sopenharmony_ci    }
542094332d3Sopenharmony_ci
543094332d3Sopenharmony_ci    return HDF_SUCCESS;
544094332d3Sopenharmony_ci}
545094332d3Sopenharmony_ci
546094332d3Sopenharmony_cistatic int32_t OsSubmitControlRequest(struct UsbHostRequest *request)
547094332d3Sopenharmony_ci{
548094332d3Sopenharmony_ci    struct OsDev *osDev = NULL;
549094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = NULL;
550094332d3Sopenharmony_ci
551094332d3Sopenharmony_ci    if ((request == NULL) || (request->length > MAX_BULK_DATA_BUFFER_LENGTH) || (request->devHandle == NULL) ||
552094332d3Sopenharmony_ci        (request->buffer == NULL)) {
553094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
554094332d3Sopenharmony_ci    }
555094332d3Sopenharmony_ci    struct UsbDeviceHandle *handle = request->devHandle;
556094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
557094332d3Sopenharmony_ci    if (dev) {
558094332d3Sopenharmony_ci        osDev = (struct OsDev *)dev->privateData;
559094332d3Sopenharmony_ci    }
560094332d3Sopenharmony_ci    if (osDev) {
561094332d3Sopenharmony_ci        adapterDevice = osDev->adapterDevice;
562094332d3Sopenharmony_ci    }
563094332d3Sopenharmony_ci
564094332d3Sopenharmony_ci    return OsSubmitControlMsg(request, adapterDevice, dev);
565094332d3Sopenharmony_ci}
566094332d3Sopenharmony_ci
567094332d3Sopenharmony_cistatic int32_t OsSubmitBulkRequestHandleUrb(
568094332d3Sopenharmony_ci    struct Async *pas, struct UsbHostRequest *request, int32_t bulkBufferLen, int32_t number)
569094332d3Sopenharmony_ci{
570094332d3Sopenharmony_ci    UsbAdapterUrb *urb = NULL;
571094332d3Sopenharmony_ci
572094332d3Sopenharmony_ci    if (bulkBufferLen == 0) {
573094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d bulkBufferLen can not be zero", __func__, __LINE__);
574094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
575094332d3Sopenharmony_ci    }
576094332d3Sopenharmony_ci
577094332d3Sopenharmony_ci    urb = &pas->urb;
578094332d3Sopenharmony_ci    urb->context = (void *)request;
579094332d3Sopenharmony_ci    switch (request->requestType) {
580094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_BULK:
581094332d3Sopenharmony_ci            break;
582094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_INTERRUPT:
583094332d3Sopenharmony_ci            urb->interval = 50;
584094332d3Sopenharmony_ci            break;
585094332d3Sopenharmony_ci        default:
586094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d unknown requestType=%u\n", __func__, __LINE__, request->requestType);
587094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
588094332d3Sopenharmony_ci    }
589094332d3Sopenharmony_ci    urb->transfer_buffer = request->buffer + (number * bulkBufferLen);
590094332d3Sopenharmony_ci    urb->complete = OsUrbComplete;
591094332d3Sopenharmony_ci    if (number == request->numUrbs - 1) {
592094332d3Sopenharmony_ci        uint32_t len = (uint32_t)(request->length % bulkBufferLen);
593094332d3Sopenharmony_ci        urb->transfer_buffer_length = (len == 0) ? (uint32_t)bulkBufferLen : len;
594094332d3Sopenharmony_ci    } else {
595094332d3Sopenharmony_ci        urb->transfer_buffer_length = (uint32_t)bulkBufferLen;
596094332d3Sopenharmony_ci    }
597094332d3Sopenharmony_ci
598094332d3Sopenharmony_ci    return HDF_SUCCESS;
599094332d3Sopenharmony_ci}
600094332d3Sopenharmony_ci
601094332d3Sopenharmony_cistatic int32_t OsSubmitBulkRequestHandle(
602094332d3Sopenharmony_ci    struct UsbHostRequest * const request, struct Async * const as, int32_t bulkBufferLen)
603094332d3Sopenharmony_ci{
604094332d3Sopenharmony_ci    struct Async *pas = NULL;
605094332d3Sopenharmony_ci    int32_t numUrbs = request->numUrbs;
606094332d3Sopenharmony_ci    struct UsbDevice *dev = request->devHandle->dev;
607094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
608094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
609094332d3Sopenharmony_ci    UsbAdapterUrb *urb = NULL;
610094332d3Sopenharmony_ci
611094332d3Sopenharmony_ci    UsbAdapterHostEndpoint *uhe = usb_find_host_endpoint(adapterDevice, request->requestType, request->endPoint);
612094332d3Sopenharmony_ci    if (uhe == NULL) {
613094332d3Sopenharmony_ci        DPRINTFN(0, "no found endpoint\n");
614094332d3Sopenharmony_ci        return HDF_DEV_ERR_NO_DEVICE;
615094332d3Sopenharmony_ci    }
616094332d3Sopenharmony_ci
617094332d3Sopenharmony_ci    int32_t i;
618094332d3Sopenharmony_ci    for (i = 0, pas = as; i < numUrbs; i++, pas++) {
619094332d3Sopenharmony_ci        urb = &pas->urb;
620094332d3Sopenharmony_ci        int32_t ret = memset_s(urb, sizeof(*urb), 0, sizeof(*urb));
621094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
622094332d3Sopenharmony_ci            HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
623094332d3Sopenharmony_ci            return HDF_FAILURE;
624094332d3Sopenharmony_ci        }
625094332d3Sopenharmony_ci
626094332d3Sopenharmony_ci        ret = OsSubmitBulkRequestHandleUrb(pas, request, bulkBufferLen, i);
627094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
628094332d3Sopenharmony_ci            return ret;
629094332d3Sopenharmony_ci        }
630094332d3Sopenharmony_ci        pas->state = URB_SUBMIT_STATE;
631094332d3Sopenharmony_ci        DListHeadInit(&pas->asynclist);
632094332d3Sopenharmony_ci        pas->dev = dev;
633094332d3Sopenharmony_ci        urb->dev = adapterDevice;
634094332d3Sopenharmony_ci        urb->endpoint = uhe;
635094332d3Sopenharmony_ci
636094332d3Sopenharmony_ci        ret = OsSubmitUrb(urb, urb->dev, urb->endpoint);
637094332d3Sopenharmony_ci        if (ret == 0) {
638094332d3Sopenharmony_ci            continue;
639094332d3Sopenharmony_ci        }
640094332d3Sopenharmony_ci        if (i == 0) {
641094332d3Sopenharmony_ci            DPRINTFN(0, "the first urb failed\n");
642094332d3Sopenharmony_ci            return HDF_ERR_IO;
643094332d3Sopenharmony_ci        }
644094332d3Sopenharmony_ci        OsalMutexLock(&request->lock);
645094332d3Sopenharmony_ci        request->numRetired += numUrbs - i;
646094332d3Sopenharmony_ci        if (errno != EREMOTEIO) {
647094332d3Sopenharmony_ci            request->reqStatus = USB_REQUEST_ERROR;
648094332d3Sopenharmony_ci        }
649094332d3Sopenharmony_ci        OsDiscardUrbs(request, 0, i);
650094332d3Sopenharmony_ci        OsalMutexUnlock(&request->lock);
651094332d3Sopenharmony_ci        return HDF_SUCCESS;
652094332d3Sopenharmony_ci    }
653094332d3Sopenharmony_ci
654094332d3Sopenharmony_ci    return HDF_SUCCESS;
655094332d3Sopenharmony_ci}
656094332d3Sopenharmony_ci
657094332d3Sopenharmony_cistatic int32_t OsSubmitBulkRequest(struct UsbHostRequest * const request)
658094332d3Sopenharmony_ci{
659094332d3Sopenharmony_ci    struct Async *as = NULL;
660094332d3Sopenharmony_ci    uint32_t bulkBufferLen;
661094332d3Sopenharmony_ci    int32_t numUrbs;
662094332d3Sopenharmony_ci
663094332d3Sopenharmony_ci    if ((request == NULL) || (request->devHandle == NULL)) {
664094332d3Sopenharmony_ci        DPRINTFN(0, "%s: invalid param", __func__);
665094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
666094332d3Sopenharmony_ci    }
667094332d3Sopenharmony_ci
668094332d3Sopenharmony_ci    if (request->length > MAX_BULK_DATA_BUFFER_LENGTH || request->length <= 0) {
669094332d3Sopenharmony_ci        DPRINTFN(0, "Bulk request size err\n");
670094332d3Sopenharmony_ci        return HDF_FAILURE;
671094332d3Sopenharmony_ci    }
672094332d3Sopenharmony_ci
673094332d3Sopenharmony_ci    if (request->devHandle->caps & USB_ADAPTER_CAP_BULK_SCATTER_GATHER) {
674094332d3Sopenharmony_ci        bulkBufferLen = request->length ? request->length : 1;
675094332d3Sopenharmony_ci    } else {
676094332d3Sopenharmony_ci        bulkBufferLen = MAX_BULK_DATA_BUFFER_LENGTH;
677094332d3Sopenharmony_ci    }
678094332d3Sopenharmony_ci    if (request->length < bulkBufferLen) {
679094332d3Sopenharmony_ci        numUrbs = 1;
680094332d3Sopenharmony_ci    } else {
681094332d3Sopenharmony_ci        numUrbs = (request->length + bulkBufferLen - 1) / bulkBufferLen;
682094332d3Sopenharmony_ci    }
683094332d3Sopenharmony_ci    if (request->urbs == NULL) {
684094332d3Sopenharmony_ci        as = RawUsbMemCalloc(sizeof(*as));
685094332d3Sopenharmony_ci        request->urbs = (void *)as;
686094332d3Sopenharmony_ci    } else if (numUrbs > 1) {
687094332d3Sopenharmony_ci        RawUsbMemFree(request->urbs);
688094332d3Sopenharmony_ci        as = RawUsbMemCalloc(numUrbs * sizeof(*as));
689094332d3Sopenharmony_ci        request->urbs = (void *)as;
690094332d3Sopenharmony_ci    }
691094332d3Sopenharmony_ci    if (request->urbs == NULL) {
692094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d no mem", __func__, __LINE__);
693094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
694094332d3Sopenharmony_ci    }
695094332d3Sopenharmony_ci    as = (struct Async *)request->urbs;
696094332d3Sopenharmony_ci    request->numUrbs = numUrbs;
697094332d3Sopenharmony_ci    request->numRetired = 0;
698094332d3Sopenharmony_ci    request->reqStatus = USB_REQUEST_COMPLETED;
699094332d3Sopenharmony_ci
700094332d3Sopenharmony_ci    return OsSubmitBulkRequestHandle(request, as, bulkBufferLen);
701094332d3Sopenharmony_ci}
702094332d3Sopenharmony_ci
703094332d3Sopenharmony_cistatic int32_t OsAllocIsoUrbs(struct UsbHostRequest *request, int32_t numUrbs, struct Async **ass)
704094332d3Sopenharmony_ci{
705094332d3Sopenharmony_ci    struct Async *as = NULL;
706094332d3Sopenharmony_ci    unsigned char *urbBuffer = request->buffer;
707094332d3Sopenharmony_ci    int32_t numPacketsLeft = request->numIsoPackets;
708094332d3Sopenharmony_ci    int32_t packetIdx = 0;
709094332d3Sopenharmony_ci    int32_t i, j;
710094332d3Sopenharmony_ci
711094332d3Sopenharmony_ci    UsbPipeType pipeType = request->requestType;
712094332d3Sopenharmony_ci    unsigned char endPoint = request->endPoint;
713094332d3Sopenharmony_ci    struct UsbDeviceHandle *handle = request->devHandle;
714094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
715094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
716094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
717094332d3Sopenharmony_ci    UsbAdapterHostEndpoint *uhe = NULL;
718094332d3Sopenharmony_ci    uhe = usb_find_host_endpoint(adapterDevice, pipeType, endPoint);
719094332d3Sopenharmony_ci    if (uhe == NULL) {
720094332d3Sopenharmony_ci        DPRINTFN(0, "no found endpoint\n");
721094332d3Sopenharmony_ci        return HDF_DEV_ERR_NO_DEVICE;
722094332d3Sopenharmony_ci    }
723094332d3Sopenharmony_ci
724094332d3Sopenharmony_ci    for (i = 0; i < numUrbs; i++) {
725094332d3Sopenharmony_ci        UsbAdapterUrb *urb = NULL;
726094332d3Sopenharmony_ci        int32_t numPackets = MIN(numPacketsLeft, MAX_ISO_PACKETS_PER_URB);
727094332d3Sopenharmony_ci        as = RawUsbMemCalloc(sizeof(struct Async));
728094332d3Sopenharmony_ci        if (as == NULL) {
729094332d3Sopenharmony_ci            OsFreeIsoUrbs(request);
730094332d3Sopenharmony_ci            return HDF_ERR_MALLOC_FAIL;
731094332d3Sopenharmony_ci        }
732094332d3Sopenharmony_ci        ass[i] = as;
733094332d3Sopenharmony_ci        urb = &as->urb;
734094332d3Sopenharmony_ci        for (j = 0; j < numPackets; j++) {
735094332d3Sopenharmony_ci            unsigned int packetLen = request->isoPacketDesc[packetIdx++].length;
736094332d3Sopenharmony_ci            urb->transfer_buffer_length += packetLen;
737094332d3Sopenharmony_ci            urb->iso_frame_desc[j].length = packetLen;
738094332d3Sopenharmony_ci        }
739094332d3Sopenharmony_ci        urb->endpoint = uhe;
740094332d3Sopenharmony_ci        urb->number_of_packets = (unsigned int)numPackets;
741094332d3Sopenharmony_ci        urb->transfer_buffer = urbBuffer;
742094332d3Sopenharmony_ci        urb->context = request;
743094332d3Sopenharmony_ci        urbBuffer += urb->transfer_buffer_length;
744094332d3Sopenharmony_ci        numPacketsLeft -= numPackets;
745094332d3Sopenharmony_ci    }
746094332d3Sopenharmony_ci
747094332d3Sopenharmony_ci    return HDF_SUCCESS;
748094332d3Sopenharmony_ci}
749094332d3Sopenharmony_ci
750094332d3Sopenharmony_cistatic int32_t OsSubmitIsoUrbs(struct UsbHostRequest *request, int32_t numUrbs, struct Async **pUrbs)
751094332d3Sopenharmony_ci{
752094332d3Sopenharmony_ci    for (int32_t i = 0; i < numUrbs; i++) {
753094332d3Sopenharmony_ci        UsbAdapterUrb *urb = &(pUrbs[i]->urb);
754094332d3Sopenharmony_ci        int32_t ret = OsSubmitUrb(urb, urb->dev, urb->endpoint);
755094332d3Sopenharmony_ci        DPRINTFN(0, "submitUrb:%d errno=%d\n", ret, errno);
756094332d3Sopenharmony_ci        if (ret == 0) {
757094332d3Sopenharmony_ci            continue;
758094332d3Sopenharmony_ci        }
759094332d3Sopenharmony_ci
760094332d3Sopenharmony_ci        if (errno == ENODEV) {
761094332d3Sopenharmony_ci            ret = HDF_DEV_ERR_NO_DEVICE;
762094332d3Sopenharmony_ci        } else {
763094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d submit iso urb failed errno=%d\n", __func__, __LINE__, errno);
764094332d3Sopenharmony_ci            ret = HDF_ERR_IO;
765094332d3Sopenharmony_ci        }
766094332d3Sopenharmony_ci
767094332d3Sopenharmony_ci        if (i == 0) {
768094332d3Sopenharmony_ci            DPRINTFN(0, "first URB failed");
769094332d3Sopenharmony_ci            OsFreeIsoUrbs(request);
770094332d3Sopenharmony_ci            return ret;
771094332d3Sopenharmony_ci        }
772094332d3Sopenharmony_ci
773094332d3Sopenharmony_ci        OsalMutexLock(&request->lock);
774094332d3Sopenharmony_ci        request->reqStatus = USB_REQUEST_ERROR;
775094332d3Sopenharmony_ci        request->numRetired += numUrbs - i;
776094332d3Sopenharmony_ci        if (request->numRetired == numUrbs) {
777094332d3Sopenharmony_ci            RawUsbMemFree(pUrbs);
778094332d3Sopenharmony_ci            request->isoUrbs = NULL;
779094332d3Sopenharmony_ci        }
780094332d3Sopenharmony_ci        OsalMutexUnlock(&request->lock);
781094332d3Sopenharmony_ci
782094332d3Sopenharmony_ci        break;
783094332d3Sopenharmony_ci    }
784094332d3Sopenharmony_ci
785094332d3Sopenharmony_ci    return HDF_SUCCESS;
786094332d3Sopenharmony_ci}
787094332d3Sopenharmony_ci
788094332d3Sopenharmony_cistatic int32_t OsSubmitIsoRequest(struct UsbHostRequest *request)
789094332d3Sopenharmony_ci{
790094332d3Sopenharmony_ci    unsigned int totalLen = 0;
791094332d3Sopenharmony_ci
792094332d3Sopenharmony_ci    if ((request == NULL) || (request->devHandle == NULL) || (request->numIsoPackets < 1)) {
793094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
794094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
795094332d3Sopenharmony_ci    }
796094332d3Sopenharmony_ci
797094332d3Sopenharmony_ci    if (request->length > MAX_ISO_DATA_BUFFER_LEN) {
798094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d request length exceed the maximum", __func__, __LINE__);
799094332d3Sopenharmony_ci        return HDF_ERR_NOT_SUPPORT;
800094332d3Sopenharmony_ci    }
801094332d3Sopenharmony_ci
802094332d3Sopenharmony_ci    for (int32_t i = 0; i < request->numIsoPackets; i++) {
803094332d3Sopenharmony_ci        unsigned int packetLen = request->isoPacketDesc[i].length;
804094332d3Sopenharmony_ci        if (packetLen > MAX_ISO_DATA_BUFFER_LEN) {
805094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d packet length: %u exceeds maximum: %u\n", __func__, __LINE__, packetLen,
806094332d3Sopenharmony_ci                MAX_ISO_DATA_BUFFER_LEN);
807094332d3Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
808094332d3Sopenharmony_ci        }
809094332d3Sopenharmony_ci        totalLen += packetLen;
810094332d3Sopenharmony_ci    }
811094332d3Sopenharmony_ci    if (request->length < totalLen) {
812094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
813094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
814094332d3Sopenharmony_ci    }
815094332d3Sopenharmony_ci    int32_t numUrbs = (request->numIsoPackets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB;
816094332d3Sopenharmony_ci    struct Async **pUrbs = RawUsbMemCalloc(numUrbs * sizeof(struct Async *));
817094332d3Sopenharmony_ci    if (pUrbs == NULL) {
818094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d RawUsbMemCalloc pUrbs failed", __func__, __LINE__);
819094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
820094332d3Sopenharmony_ci    }
821094332d3Sopenharmony_ci    request->isoUrbs = (void **)pUrbs;
822094332d3Sopenharmony_ci    request->numUrbs = numUrbs;
823094332d3Sopenharmony_ci    request->numRetired = 0;
824094332d3Sopenharmony_ci    request->isoPacketOffset = 0;
825094332d3Sopenharmony_ci    int32_t ret = OsAllocIsoUrbs(request, numUrbs, pUrbs);
826094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
827094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d alloc iso urbs failed", __func__, __LINE__);
828094332d3Sopenharmony_ci        return ret;
829094332d3Sopenharmony_ci    }
830094332d3Sopenharmony_ci
831094332d3Sopenharmony_ci    return OsSubmitIsoUrbs(request, numUrbs, pUrbs);
832094332d3Sopenharmony_ci}
833094332d3Sopenharmony_ci
834094332d3Sopenharmony_cistatic int32_t OsControlCompletion(struct UsbHostRequest *request, struct Async *as)
835094332d3Sopenharmony_ci{
836094332d3Sopenharmony_ci    int32_t status;
837094332d3Sopenharmony_ci    UsbAdapterUrb *urb = &as->urb;
838094332d3Sopenharmony_ci
839094332d3Sopenharmony_ci    OsalMutexLock(&request->lock);
840094332d3Sopenharmony_ci    request->numRetired++;
841094332d3Sopenharmony_ci    request->actualLength += (int)urb->actual_length;
842094332d3Sopenharmony_ci    if (request->reqStatus == USB_REQUEST_CANCELLED) {
843094332d3Sopenharmony_ci        OsalMutexUnlock(&request->lock);
844094332d3Sopenharmony_ci        as->state = URB_INIT_STATE;
845094332d3Sopenharmony_ci        return RawHandleRequestCompletion(request, USB_REQUEST_CANCELLED);
846094332d3Sopenharmony_ci    }
847094332d3Sopenharmony_ci
848094332d3Sopenharmony_ci    switch (urb->status) {
849094332d3Sopenharmony_ci        case 0:
850094332d3Sopenharmony_ci            status = USB_REQUEST_COMPLETED;
851094332d3Sopenharmony_ci            break;
852094332d3Sopenharmony_ci        case -ENOENT:
853094332d3Sopenharmony_ci            status = USB_REQUEST_CANCELLED;
854094332d3Sopenharmony_ci            break;
855094332d3Sopenharmony_ci        case -EPIPE:
856094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d unsupported control request", __func__, __LINE__);
857094332d3Sopenharmony_ci            status = USB_REQUEST_STALL;
858094332d3Sopenharmony_ci            break;
859094332d3Sopenharmony_ci        case -EOVERFLOW:
860094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d overflow actualLength=%d\n", __func__, __LINE__, urb->actual_length);
861094332d3Sopenharmony_ci            status = USB_REQUEST_OVERFLOW;
862094332d3Sopenharmony_ci            break;
863094332d3Sopenharmony_ci        case -ENODEV:
864094332d3Sopenharmony_ci        case -ESHUTDOWN:
865094332d3Sopenharmony_ci            DPRINTFN(0, "device removed");
866094332d3Sopenharmony_ci            status = USB_REQUEST_NO_DEVICE;
867094332d3Sopenharmony_ci            break;
868094332d3Sopenharmony_ci        default:
869094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d urb status=%d\n", __func__, __LINE__, urb->status);
870094332d3Sopenharmony_ci            status = USB_REQUEST_ERROR;
871094332d3Sopenharmony_ci            break;
872094332d3Sopenharmony_ci    }
873094332d3Sopenharmony_ci    OsalMutexUnlock(&request->lock);
874094332d3Sopenharmony_ci    as->state = URB_INIT_STATE;
875094332d3Sopenharmony_ci    return RawHandleRequestCompletion(request, status);
876094332d3Sopenharmony_ci}
877094332d3Sopenharmony_ci
878094332d3Sopenharmony_cistatic void OsIsoRequestDesStatus(struct UsbHostRequest *request, UsbAdapterUrb *urb)
879094332d3Sopenharmony_ci{
880094332d3Sopenharmony_ci    uint32_t i;
881094332d3Sopenharmony_ci    UsbAdapterIsoPacketDescriptor *urbDesc = NULL;
882094332d3Sopenharmony_ci    struct UsbIsoPacketDesc *requestDesc = NULL;
883094332d3Sopenharmony_ci
884094332d3Sopenharmony_ci    for (i = 0; i < urb->number_of_packets; i++) {
885094332d3Sopenharmony_ci        urbDesc = &urb->iso_frame_desc[i];
886094332d3Sopenharmony_ci        requestDesc = &request->isoPacketDesc[request->isoPacketOffset++];
887094332d3Sopenharmony_ci
888094332d3Sopenharmony_ci        switch (urbDesc->status) {
889094332d3Sopenharmony_ci            case HDF_SUCCESS:
890094332d3Sopenharmony_ci                requestDesc->status = USB_REQUEST_COMPLETED;
891094332d3Sopenharmony_ci                break;
892094332d3Sopenharmony_ci            case -ENODEV:
893094332d3Sopenharmony_ci            case -ESHUTDOWN:
894094332d3Sopenharmony_ci                requestDesc->status = USB_REQUEST_NO_DEVICE;
895094332d3Sopenharmony_ci                break;
896094332d3Sopenharmony_ci            case -EPIPE:
897094332d3Sopenharmony_ci                requestDesc->status = USB_REQUEST_STALL;
898094332d3Sopenharmony_ci                break;
899094332d3Sopenharmony_ci            case -EOVERFLOW:
900094332d3Sopenharmony_ci                requestDesc->status = USB_REQUEST_OVERFLOW;
901094332d3Sopenharmony_ci                break;
902094332d3Sopenharmony_ci            default:
903094332d3Sopenharmony_ci                requestDesc->status = USB_REQUEST_ERROR;
904094332d3Sopenharmony_ci                break;
905094332d3Sopenharmony_ci        }
906094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d urb status=%d-%d\n", __func__, __LINE__, i, urbDesc->status);
907094332d3Sopenharmony_ci
908094332d3Sopenharmony_ci        requestDesc->actualLength = urbDesc->actual_length;
909094332d3Sopenharmony_ci    }
910094332d3Sopenharmony_ci}
911094332d3Sopenharmony_ci
912094332d3Sopenharmony_cistatic int32_t OsIsoCompletion(struct UsbHostRequest *request, struct Async *as)
913094332d3Sopenharmony_ci{
914094332d3Sopenharmony_ci    UsbRequestStatus status;
915094332d3Sopenharmony_ci    int32_t urbIndex = 0;
916094332d3Sopenharmony_ci    int32_t numUrbs;
917094332d3Sopenharmony_ci    UsbAdapterUrb *urb = &as->urb;
918094332d3Sopenharmony_ci
919094332d3Sopenharmony_ci    if (request == NULL) {
920094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
921094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
922094332d3Sopenharmony_ci    }
923094332d3Sopenharmony_ci
924094332d3Sopenharmony_ci    numUrbs = request->numUrbs;
925094332d3Sopenharmony_ci    OsalMutexLock(&request->lock);
926094332d3Sopenharmony_ci    for (int32_t i = 0; i < numUrbs; i++) {
927094332d3Sopenharmony_ci        if (urb == request->isoUrbs[i]) {
928094332d3Sopenharmony_ci            urbIndex = i + 1;
929094332d3Sopenharmony_ci            break;
930094332d3Sopenharmony_ci        }
931094332d3Sopenharmony_ci    }
932094332d3Sopenharmony_ci    if (urbIndex == 0) {
933094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d urbIndex is zero", __func__, __LINE__);
934094332d3Sopenharmony_ci        OsalMutexUnlock(&request->lock);
935094332d3Sopenharmony_ci        return HDF_ERR_BAD_FD;
936094332d3Sopenharmony_ci    }
937094332d3Sopenharmony_ci
938094332d3Sopenharmony_ci    OsIsoRequestDesStatus(request, urb);
939094332d3Sopenharmony_ci    request->numRetired++;
940094332d3Sopenharmony_ci    if (request->reqStatus != USB_REQUEST_COMPLETED) {
941094332d3Sopenharmony_ci        if (request->numRetired == numUrbs) {
942094332d3Sopenharmony_ci            OsFreeIsoUrbs(request);
943094332d3Sopenharmony_ci            OsalMutexUnlock(&request->lock);
944094332d3Sopenharmony_ci            return RawHandleRequestCompletion(request, USB_REQUEST_ERROR);
945094332d3Sopenharmony_ci        }
946094332d3Sopenharmony_ci        goto OUT;
947094332d3Sopenharmony_ci    }
948094332d3Sopenharmony_ci
949094332d3Sopenharmony_ci    status = USB_REQUEST_COMPLETED;
950094332d3Sopenharmony_ci    if (urb->status == -ESHUTDOWN) {
951094332d3Sopenharmony_ci        status = USB_REQUEST_NO_DEVICE;
952094332d3Sopenharmony_ci    } else if (!((urb->status == HDF_SUCCESS) || (urb->status == -ENOENT) || (urb->status == -ECONNRESET))) {
953094332d3Sopenharmony_ci        status = USB_REQUEST_ERROR;
954094332d3Sopenharmony_ci    }
955094332d3Sopenharmony_ci
956094332d3Sopenharmony_ci    if (request->numRetired == numUrbs) {
957094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d all URBs reaped for complete", __func__, __LINE__);
958094332d3Sopenharmony_ci        OsFreeIsoUrbs(request);
959094332d3Sopenharmony_ci        OsalMutexUnlock(&request->lock);
960094332d3Sopenharmony_ci        return RawHandleRequestCompletion(request, status);
961094332d3Sopenharmony_ci    }
962094332d3Sopenharmony_ciOUT:
963094332d3Sopenharmony_ci    OsalMutexUnlock(&request->lock);
964094332d3Sopenharmony_ci    return HDF_SUCCESS;
965094332d3Sopenharmony_ci}
966094332d3Sopenharmony_ci
967094332d3Sopenharmony_cistatic int32_t OsProcessAbnormalReap(struct UsbHostRequest *request, const UsbAdapterUrb *urb)
968094332d3Sopenharmony_ci{
969094332d3Sopenharmony_ci    if (urb->actual_length > 0) {
970094332d3Sopenharmony_ci        unsigned char *target = request->buffer + request->actualLength;
971094332d3Sopenharmony_ci        if (urb->transfer_buffer != target) {
972094332d3Sopenharmony_ci            if (memmove_s(target, urb->actual_length, urb->transfer_buffer, urb->actual_length) != EOK) {
973094332d3Sopenharmony_ci                DPRINTFN(0, "%s: memmove_s failed, ret=%d", __func__, ret);
974094332d3Sopenharmony_ci            }
975094332d3Sopenharmony_ci        }
976094332d3Sopenharmony_ci        request->actualLength += urb->actual_length;
977094332d3Sopenharmony_ci    }
978094332d3Sopenharmony_ci    if (request->numRetired == request->numUrbs) {
979094332d3Sopenharmony_ci        return HDF_SUCCESS;
980094332d3Sopenharmony_ci    }
981094332d3Sopenharmony_ci
982094332d3Sopenharmony_ci    return HDF_ERR_IO;
983094332d3Sopenharmony_ci}
984094332d3Sopenharmony_ci
985094332d3Sopenharmony_cistatic int32_t OsUrbStatusToRequestStatus(struct UsbHostRequest *request, const UsbAdapterUrb *urb)
986094332d3Sopenharmony_ci{
987094332d3Sopenharmony_ci    int32_t ret;
988094332d3Sopenharmony_ci
989094332d3Sopenharmony_ci    switch (urb->status) {
990094332d3Sopenharmony_ci        case 0:
991094332d3Sopenharmony_ci            ret = HDF_SUCCESS;
992094332d3Sopenharmony_ci            break;
993094332d3Sopenharmony_ci        case -ESHUTDOWN:
994094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d device is removed", __func__, __LINE__);
995094332d3Sopenharmony_ci            request->reqStatus = USB_REQUEST_NO_DEVICE;
996094332d3Sopenharmony_ci            ret = HDF_DEV_ERR_NO_DEVICE;
997094332d3Sopenharmony_ci            break;
998094332d3Sopenharmony_ci        case -EPIPE:
999094332d3Sopenharmony_ci            if (request->reqStatus == USB_REQUEST_COMPLETED) {
1000094332d3Sopenharmony_ci                request->reqStatus = USB_REQUEST_STALL;
1001094332d3Sopenharmony_ci            }
1002094332d3Sopenharmony_ci            ret = HDF_DEV_ERR_NO_DEVICE;
1003094332d3Sopenharmony_ci            break;
1004094332d3Sopenharmony_ci        case -EOVERFLOW:
1005094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d overflow error, actualLength=%d\n", __func__, __LINE__, urb->actual_length);
1006094332d3Sopenharmony_ci            if (request->reqStatus == USB_REQUEST_COMPLETED) {
1007094332d3Sopenharmony_ci                request->reqStatus = USB_REQUEST_OVERFLOW;
1008094332d3Sopenharmony_ci            }
1009094332d3Sopenharmony_ci            ret = HDF_FAILURE;
1010094332d3Sopenharmony_ci            break;
1011094332d3Sopenharmony_ci        case -ECONNRESET:
1012094332d3Sopenharmony_ci            ret = HDF_DEV_ERR_OP;
1013094332d3Sopenharmony_ci            if (request->reqStatus == USB_REQUEST_COMPLETED) {
1014094332d3Sopenharmony_ci                request->reqStatus = USB_REQUEST_CANCELLED;
1015094332d3Sopenharmony_ci            }
1016094332d3Sopenharmony_ci            break;
1017094332d3Sopenharmony_ci        default:
1018094332d3Sopenharmony_ci            DPRINTFN(0, "unknown urb status %d\n", urb->status);
1019094332d3Sopenharmony_ci            if (request->reqStatus == USB_REQUEST_COMPLETED) {
1020094332d3Sopenharmony_ci                request->reqStatus = USB_REQUEST_ERROR;
1021094332d3Sopenharmony_ci            }
1022094332d3Sopenharmony_ci            ret = HDF_FAILURE;
1023094332d3Sopenharmony_ci            break;
1024094332d3Sopenharmony_ci    }
1025094332d3Sopenharmony_ci
1026094332d3Sopenharmony_ci    return ret;
1027094332d3Sopenharmony_ci}
1028094332d3Sopenharmony_ci
1029094332d3Sopenharmony_cistatic int32_t OsBulkCompletion(struct UsbHostRequest * const request, struct Async * const as)
1030094332d3Sopenharmony_ci{
1031094332d3Sopenharmony_ci    int32_t ret;
1032094332d3Sopenharmony_ci    int32_t urbIdx = as - (struct Async *)request->urbs;
1033094332d3Sopenharmony_ci    const UsbAdapterUrb *urb = &as->urb;
1034094332d3Sopenharmony_ci
1035094332d3Sopenharmony_ci    OsalMutexLock(&request->lock);
1036094332d3Sopenharmony_ci    request->numRetired++;
1037094332d3Sopenharmony_ci    if (request->reqStatus != USB_REQUEST_COMPLETED) {
1038094332d3Sopenharmony_ci        if (OsProcessAbnormalReap(request, urb) == HDF_SUCCESS) {
1039094332d3Sopenharmony_ci            goto COMPLETED;
1040094332d3Sopenharmony_ci        } else {
1041094332d3Sopenharmony_ci            goto OUT;
1042094332d3Sopenharmony_ci        }
1043094332d3Sopenharmony_ci    }
1044094332d3Sopenharmony_ci    request->actualLength += urb->actual_length;
1045094332d3Sopenharmony_ci    ret = OsUrbStatusToRequestStatus(request, urb);
1046094332d3Sopenharmony_ci    if (ret == HDF_DEV_ERR_NO_DEVICE) {
1047094332d3Sopenharmony_ci        goto CANCEL;
1048094332d3Sopenharmony_ci    } else if (ret == HDF_FAILURE) {
1049094332d3Sopenharmony_ci        goto COMPLETED;
1050094332d3Sopenharmony_ci    }
1051094332d3Sopenharmony_ci
1052094332d3Sopenharmony_ci    if (request->numRetired == request->numUrbs) {
1053094332d3Sopenharmony_ci        goto COMPLETED;
1054094332d3Sopenharmony_ci    } else if (urb->actual_length < urb->transfer_buffer_length) {
1055094332d3Sopenharmony_ci        if (request->reqStatus == USB_REQUEST_COMPLETED) {
1056094332d3Sopenharmony_ci            request->reqStatus = USB_REQUEST_COMPLETED_SHORT;
1057094332d3Sopenharmony_ci        }
1058094332d3Sopenharmony_ci    } else {
1059094332d3Sopenharmony_ci        goto OUT;
1060094332d3Sopenharmony_ci    }
1061094332d3Sopenharmony_ci
1062094332d3Sopenharmony_ciCANCEL:
1063094332d3Sopenharmony_ci    if (request->numRetired == request->numUrbs) {
1064094332d3Sopenharmony_ci        goto COMPLETED;
1065094332d3Sopenharmony_ci    }
1066094332d3Sopenharmony_ci    OsDiscardUrbs(request, urbIdx + 1, request->numUrbs);
1067094332d3Sopenharmony_ci
1068094332d3Sopenharmony_ciOUT:
1069094332d3Sopenharmony_ci    OsalMutexUnlock(&request->lock);
1070094332d3Sopenharmony_ci    return HDF_SUCCESS;
1071094332d3Sopenharmony_ci
1072094332d3Sopenharmony_ciCOMPLETED:
1073094332d3Sopenharmony_ci    OsalMutexUnlock(&request->lock);
1074094332d3Sopenharmony_ci    as->state = URB_INIT_STATE;
1075094332d3Sopenharmony_ci    return RawHandleRequestCompletion(request, request->reqStatus);
1076094332d3Sopenharmony_ci}
1077094332d3Sopenharmony_ci
1078094332d3Sopenharmony_cistatic int32_t OsFreeRequest(const struct UsbHostRequest *request)
1079094332d3Sopenharmony_ci{
1080094332d3Sopenharmony_ci    int32_t retry = 0;
1081094332d3Sopenharmony_ci    if (request == NULL) {
1082094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
1083094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1084094332d3Sopenharmony_ci    }
1085094332d3Sopenharmony_ci
1086094332d3Sopenharmony_ci    while (true) {
1087094332d3Sopenharmony_ci        OsalMSleep(20);
1088094332d3Sopenharmony_ci        if (request->numUrbs != request->numRetired) {
1089094332d3Sopenharmony_ci            if (++retry > 10) {
1090094332d3Sopenharmony_ci                DPRINTFN(0, "request busy numUrbs:%d+numretired:%d\n", request->numUrbs, request->numRetired);
1091094332d3Sopenharmony_ci                return HDF_ERR_DEVICE_BUSY;
1092094332d3Sopenharmony_ci            }
1093094332d3Sopenharmony_ci            continue;
1094094332d3Sopenharmony_ci        } else {
1095094332d3Sopenharmony_ci            break;
1096094332d3Sopenharmony_ci        }
1097094332d3Sopenharmony_ci    }
1098094332d3Sopenharmony_ci
1099094332d3Sopenharmony_ci    return HDF_SUCCESS;
1100094332d3Sopenharmony_ci}
1101094332d3Sopenharmony_ci
1102094332d3Sopenharmony_cistatic int32_t AdapterInit(const struct UsbSession *session)
1103094332d3Sopenharmony_ci{
1104094332d3Sopenharmony_ci    (void)session;
1105094332d3Sopenharmony_ci    return HDF_SUCCESS;
1106094332d3Sopenharmony_ci}
1107094332d3Sopenharmony_ci
1108094332d3Sopenharmony_cistatic void AdapterExit(const struct UsbSession *session)
1109094332d3Sopenharmony_ci{
1110094332d3Sopenharmony_ci    (void)session;
1111094332d3Sopenharmony_ci    return;
1112094332d3Sopenharmony_ci}
1113094332d3Sopenharmony_ci
1114094332d3Sopenharmony_cistatic struct UsbDeviceHandle *AdapterOpenDevice(struct UsbSession *session, uint8_t busNum, uint8_t usbAddr)
1115094332d3Sopenharmony_ci{
1116094332d3Sopenharmony_ci    int32_t ret;
1117094332d3Sopenharmony_ci    struct UsbDevice *dev = NULL;
1118094332d3Sopenharmony_ci    struct UsbDeviceHandle *handle = NULL;
1119094332d3Sopenharmony_ci
1120094332d3Sopenharmony_ci    handle = OsGetDeviceHandle(session, busNum, usbAddr);
1121094332d3Sopenharmony_ci    if (handle != NULL) {
1122094332d3Sopenharmony_ci        return handle;
1123094332d3Sopenharmony_ci    }
1124094332d3Sopenharmony_ci    handle = OsCallocDeviceHandle();
1125094332d3Sopenharmony_ci    if (handle == NULL) {
1126094332d3Sopenharmony_ci        DPRINTFN(0, "%s: Calloc Device Handle failed", __func__);
1127094332d3Sopenharmony_ci        return NULL;
1128094332d3Sopenharmony_ci    }
1129094332d3Sopenharmony_ci    dev = OsAllocDevice(session, handle);
1130094332d3Sopenharmony_ci    if (dev == NULL) {
1131094332d3Sopenharmony_ci        DPRINTFN(0, "%s: OsAllocDevice failed\n", __func__);
1132094332d3Sopenharmony_ci        goto ERR;
1133094332d3Sopenharmony_ci    }
1134094332d3Sopenharmony_ci    ret = OsInitDevice(dev, busNum, usbAddr);
1135094332d3Sopenharmony_ci    if (ret) {
1136094332d3Sopenharmony_ci        DPRINTFN(0, "%s: OsInitDevice failed ret=%d\n", __func__, ret);
1137094332d3Sopenharmony_ci        RawUsbMemFree(dev->privateData);
1138094332d3Sopenharmony_ci        RawUsbMemFree(dev);
1139094332d3Sopenharmony_ci        goto ERR;
1140094332d3Sopenharmony_ci    }
1141094332d3Sopenharmony_ci    OsalAtomicSet(&dev->refcnt, 1);
1142094332d3Sopenharmony_ci    OsalMutexLock(&session->lock);
1143094332d3Sopenharmony_ci    HdfSListAdd(&session->usbDevs, &dev->list);
1144094332d3Sopenharmony_ci    OsalMutexUnlock(&session->lock);
1145094332d3Sopenharmony_ci    return handle;
1146094332d3Sopenharmony_ciERR:
1147094332d3Sopenharmony_ci    OsalMutexDestroy(&handle->lock);
1148094332d3Sopenharmony_ci    RawUsbMemFree(handle);
1149094332d3Sopenharmony_ci    return NULL;
1150094332d3Sopenharmony_ci}
1151094332d3Sopenharmony_ci
1152094332d3Sopenharmony_cistatic void AdapterCloseDevice(struct UsbDeviceHandle *handle)
1153094332d3Sopenharmony_ci{
1154094332d3Sopenharmony_ci    struct UsbDevice *dev = NULL;
1155094332d3Sopenharmony_ci
1156094332d3Sopenharmony_ci    if ((handle == NULL) || (handle->dev == NULL)) {
1157094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
1158094332d3Sopenharmony_ci        return;
1159094332d3Sopenharmony_ci    }
1160094332d3Sopenharmony_ci    if (RawKillSignal(handle, 0) != HDF_SUCCESS) {
1161094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d RawKillSignal failed", __func__, __LINE__);
1162094332d3Sopenharmony_ci    }
1163094332d3Sopenharmony_ci    dev = handle->dev;
1164094332d3Sopenharmony_ci    if (AdapterAtomicDec(&dev->refcnt)) {
1165094332d3Sopenharmony_ci        return;
1166094332d3Sopenharmony_ci    }
1167094332d3Sopenharmony_ci    if (dev->session == NULL) {
1168094332d3Sopenharmony_ci        return;
1169094332d3Sopenharmony_ci    }
1170094332d3Sopenharmony_ci    OsalMutexLock(&dev->session->lock);
1171094332d3Sopenharmony_ci    HdfSListRemove(&dev->session->usbDevs, &dev->list);
1172094332d3Sopenharmony_ci    OsalMutexUnlock(&dev->session->lock);
1173094332d3Sopenharmony_ci
1174094332d3Sopenharmony_ci    if (dev->configDescriptors) {
1175094332d3Sopenharmony_ci        RawUsbMemFree(dev->configDescriptors);
1176094332d3Sopenharmony_ci    }
1177094332d3Sopenharmony_ci    if (dev->descriptors) {
1178094332d3Sopenharmony_ci        RawUsbMemFree(dev->descriptors);
1179094332d3Sopenharmony_ci    }
1180094332d3Sopenharmony_ci    if (dev->privateData) {
1181094332d3Sopenharmony_ci        OsDevDestory(dev->privateData);
1182094332d3Sopenharmony_ci        dev->privateData = NULL;
1183094332d3Sopenharmony_ci    }
1184094332d3Sopenharmony_ci    RawUsbMemFree(dev);
1185094332d3Sopenharmony_ci
1186094332d3Sopenharmony_ci    OsalMutexDestroy(&handle->lock);
1187094332d3Sopenharmony_ci    RawUsbMemFree(handle);
1188094332d3Sopenharmony_ci    handle = NULL;
1189094332d3Sopenharmony_ci}
1190094332d3Sopenharmony_ci
1191094332d3Sopenharmony_cistatic int32_t AdapterGetConfigDescriptor(const struct UsbDevice *dev, uint8_t configIndex, void *buffer, size_t len)
1192094332d3Sopenharmony_ci{
1193094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
1194094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
1195094332d3Sopenharmony_ci    size_t count;
1196094332d3Sopenharmony_ci    if ((buffer == NULL) || (len == 0) || (adapterDevice == NULL) || (adapterDevice->cdesc == NULL)) {
1197094332d3Sopenharmony_ci        DPRINTFN(0, "invalid param is NULL");
1198094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1199094332d3Sopenharmony_ci    }
1200094332d3Sopenharmony_ci    count = UGETW(adapterDevice->cdesc->wTotalLength);
1201094332d3Sopenharmony_ci    if (count > len) {
1202094332d3Sopenharmony_ci        DPRINTFN(0, "count length is error");
1203094332d3Sopenharmony_ci        return HDF_ERR_IO;
1204094332d3Sopenharmony_ci    }
1205094332d3Sopenharmony_ci    if (memcpy_s(buffer, len, adapterDevice->cdesc, count) != EOK) {
1206094332d3Sopenharmony_ci        DPRINTFN(0, "memcpy_s fail");
1207094332d3Sopenharmony_ci        return HDF_ERR_IO;
1208094332d3Sopenharmony_ci    }
1209094332d3Sopenharmony_ci    return (int32_t)len;
1210094332d3Sopenharmony_ci}
1211094332d3Sopenharmony_ci
1212094332d3Sopenharmony_cistatic int32_t AdapterGetConfiguration(const struct UsbDeviceHandle *handle, uint8_t *activeConfig)
1213094332d3Sopenharmony_ci{
1214094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
1215094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
1216094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
1217094332d3Sopenharmony_ci
1218094332d3Sopenharmony_ci    if (adapterDevice != NULL) {
1219094332d3Sopenharmony_ci        *activeConfig = adapterDevice->curr_config_index;
1220094332d3Sopenharmony_ci    }
1221094332d3Sopenharmony_ci
1222094332d3Sopenharmony_ci    return HDF_SUCCESS;
1223094332d3Sopenharmony_ci}
1224094332d3Sopenharmony_ci
1225094332d3Sopenharmony_cistatic int32_t AdapterSetConfiguration(struct UsbDeviceHandle *handle, int32_t activeConfig)
1226094332d3Sopenharmony_ci{
1227094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
1228094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
1229094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
1230094332d3Sopenharmony_ci
1231094332d3Sopenharmony_ci    if (adapterDevice->flags.usb_mode != USB_MODE_HOST) {
1232094332d3Sopenharmony_ci        return HDF_DEV_ERR_DEV_INIT_FAIL;
1233094332d3Sopenharmony_ci    }
1234094332d3Sopenharmony_ci    if ((activeConfig < 0) || (activeConfig >= (int)adapterDevice->curr_config_no)) {
1235094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1236094332d3Sopenharmony_ci    }
1237094332d3Sopenharmony_ci    if (activeConfig == adapterDevice->curr_config_index) {
1238094332d3Sopenharmony_ci        return HDF_SUCCESS;
1239094332d3Sopenharmony_ci    }
1240094332d3Sopenharmony_ci    if (usbd_set_config_index(adapterDevice, activeConfig) != 0) {
1241094332d3Sopenharmony_ci        return HDF_ERR_IO;
1242094332d3Sopenharmony_ci    }
1243094332d3Sopenharmony_ci
1244094332d3Sopenharmony_ci    return HDF_SUCCESS;
1245094332d3Sopenharmony_ci}
1246094332d3Sopenharmony_ci
1247094332d3Sopenharmony_cistatic int32_t AdapterClaimInterface(const struct UsbDeviceHandle *handle, unsigned int interfaceNumber)
1248094332d3Sopenharmony_ci{
1249094332d3Sopenharmony_ci    (void)handle;
1250094332d3Sopenharmony_ci    (void)interfaceNumber;
1251094332d3Sopenharmony_ci    return HDF_SUCCESS;
1252094332d3Sopenharmony_ci}
1253094332d3Sopenharmony_ci
1254094332d3Sopenharmony_cistatic int32_t AdapterReleaseInterface(const struct UsbDeviceHandle *handle, unsigned int interfaceNumber)
1255094332d3Sopenharmony_ci{
1256094332d3Sopenharmony_ci    (void)handle;
1257094332d3Sopenharmony_ci    (void)interfaceNumber;
1258094332d3Sopenharmony_ci    return HDF_SUCCESS;
1259094332d3Sopenharmony_ci}
1260094332d3Sopenharmony_ci
1261094332d3Sopenharmony_cistatic int32_t AdapterSetInterface(const struct UsbDeviceHandle *handle, uint8_t interface, uint8_t altSetting)
1262094332d3Sopenharmony_ci{
1263094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
1264094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
1265094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
1266094332d3Sopenharmony_ci
1267094332d3Sopenharmony_ci    if (adapterDevice->flags.usb_mode != USB_MODE_HOST) {
1268094332d3Sopenharmony_ci        return HDF_DEV_ERR_DEV_INIT_FAIL;
1269094332d3Sopenharmony_ci    }
1270094332d3Sopenharmony_ci    DPRINTFN(0, "altSetting interfaceId:%d+altSetting:%d\n", interface, altSetting);
1271094332d3Sopenharmony_ci    if (usb_set_interface(adapterDevice, interface, altSetting)) {
1272094332d3Sopenharmony_ci        return HDF_ERR_IO;
1273094332d3Sopenharmony_ci    }
1274094332d3Sopenharmony_ci
1275094332d3Sopenharmony_ci    return HDF_SUCCESS;
1276094332d3Sopenharmony_ci}
1277094332d3Sopenharmony_ci
1278094332d3Sopenharmony_cistatic int32_t AdapterClearHalt(const struct UsbDeviceHandle *handle, unsigned int endPoint)
1279094332d3Sopenharmony_ci{
1280094332d3Sopenharmony_ci    struct UsbDevice *dev = handle->dev;
1281094332d3Sopenharmony_ci    struct OsDev *osDev = (struct OsDev *)dev->privateData;
1282094332d3Sopenharmony_ci    UsbAdapterDevice *adapterDevice = osDev->adapterDevice;
1283094332d3Sopenharmony_ci    int32_t ret;
1284094332d3Sopenharmony_ci    UsbAdapterHostEndpoint *uhe = usb_find_host_endpoint(adapterDevice, PIPE_BULK, endPoint);
1285094332d3Sopenharmony_ci    if (uhe == NULL) {
1286094332d3Sopenharmony_ci        printf("no found uhe\n");
1287094332d3Sopenharmony_ci        return -1;
1288094332d3Sopenharmony_ci    }
1289094332d3Sopenharmony_ci    ret = usb_clear_halt(adapterDevice, uhe);
1290094332d3Sopenharmony_ci    return ret;
1291094332d3Sopenharmony_ci}
1292094332d3Sopenharmony_ci
1293094332d3Sopenharmony_cistatic int32_t AdapterResetDevice(const struct UsbDeviceHandle *handle)
1294094332d3Sopenharmony_ci{
1295094332d3Sopenharmony_ci    (void)handle;
1296094332d3Sopenharmony_ci    return HDF_SUCCESS;
1297094332d3Sopenharmony_ci}
1298094332d3Sopenharmony_ci
1299094332d3Sopenharmony_cistatic struct UsbHostRequest *AdapterAllocRequest(
1300094332d3Sopenharmony_ci    const struct UsbDeviceHandle *handle, int32_t isoPackets, size_t length)
1301094332d3Sopenharmony_ci{
1302094332d3Sopenharmony_ci    (void)handle;
1303094332d3Sopenharmony_ci    size_t allocSize;
1304094332d3Sopenharmony_ci    struct UsbHostRequest *request = NULL;
1305094332d3Sopenharmony_ci
1306094332d3Sopenharmony_ci    allocSize = sizeof(struct UsbHostRequest) + (sizeof(struct UsbIsoPacketDesc) * (size_t)isoPackets) +
1307094332d3Sopenharmony_ci        (sizeof(unsigned char) * length);
1308094332d3Sopenharmony_ci    request = RawUsbMemCalloc(allocSize);
1309094332d3Sopenharmony_ci    if (request == NULL) {
1310094332d3Sopenharmony_ci        HDF_LOGE("%{public}s RawMemAlloc fail", __func__);
1311094332d3Sopenharmony_ci        return NULL;
1312094332d3Sopenharmony_ci    }
1313094332d3Sopenharmony_ci    request->numIsoPackets = isoPackets;
1314094332d3Sopenharmony_ci    request->buffer = (unsigned char *)request + allocSize - length;
1315094332d3Sopenharmony_ci    request->bufLen = (int)length;
1316094332d3Sopenharmony_ci    return request;
1317094332d3Sopenharmony_ci}
1318094332d3Sopenharmony_ci
1319094332d3Sopenharmony_cistatic int32_t AdapterFreeRequest(struct UsbHostRequest *request)
1320094332d3Sopenharmony_ci{
1321094332d3Sopenharmony_ci    if (request == NULL) {
1322094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d invalid param", __func__, __LINE__);
1323094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1324094332d3Sopenharmony_ci    }
1325094332d3Sopenharmony_ci    if (request->numUrbs > request->numRetired) {
1326094332d3Sopenharmony_ci        OsDiscardUrbs(request, request->numRetired, request->numUrbs);
1327094332d3Sopenharmony_ci        int32_t ret = OsFreeRequest(request);
1328094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
1329094332d3Sopenharmony_ci            return ret;
1330094332d3Sopenharmony_ci        }
1331094332d3Sopenharmony_ci    }
1332094332d3Sopenharmony_ci    if (request->urbs) {
1333094332d3Sopenharmony_ci        RawUsbMemFree(request->urbs);
1334094332d3Sopenharmony_ci        request->urbs = NULL;
1335094332d3Sopenharmony_ci    }
1336094332d3Sopenharmony_ci    RawUsbMemFree((void *)request);
1337094332d3Sopenharmony_ci    return HDF_SUCCESS;
1338094332d3Sopenharmony_ci}
1339094332d3Sopenharmony_ci
1340094332d3Sopenharmony_cistatic int32_t AdapterSubmitRequest(struct UsbHostRequest *request)
1341094332d3Sopenharmony_ci{
1342094332d3Sopenharmony_ci    int32_t ret;
1343094332d3Sopenharmony_ci
1344094332d3Sopenharmony_ci    if (request == NULL) {
1345094332d3Sopenharmony_ci        DPRINTFN(0, "%s:%d request is NULL", __func__, __LINE__);
1346094332d3Sopenharmony_ci        return HDF_FAILURE;
1347094332d3Sopenharmony_ci    }
1348094332d3Sopenharmony_ci    OsalMutexInit(&(request->lock));
1349094332d3Sopenharmony_ci    request->actualLength = 0;
1350094332d3Sopenharmony_ci    request->numRetired = 0;
1351094332d3Sopenharmony_ci    request->numUrbs = 0;
1352094332d3Sopenharmony_ci    switch (request->requestType) {
1353094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_CONTROL:
1354094332d3Sopenharmony_ci            ret = OsSubmitControlRequest(request);
1355094332d3Sopenharmony_ci            break;
1356094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_ISOCHRONOUS:
1357094332d3Sopenharmony_ci            ret = OsSubmitIsoRequest(request);
1358094332d3Sopenharmony_ci            break;
1359094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_BULK:
1360094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_INTERRUPT:
1361094332d3Sopenharmony_ci            ret = OsSubmitBulkRequest(request);
1362094332d3Sopenharmony_ci            break;
1363094332d3Sopenharmony_ci        default:
1364094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d unknown requestType=%u\n", __func__, __LINE__, request->requestType);
1365094332d3Sopenharmony_ci            ret = HDF_ERR_INVALID_PARAM;
1366094332d3Sopenharmony_ci            break;
1367094332d3Sopenharmony_ci    }
1368094332d3Sopenharmony_ci
1369094332d3Sopenharmony_ci    return ret;
1370094332d3Sopenharmony_ci}
1371094332d3Sopenharmony_ci
1372094332d3Sopenharmony_cistatic int32_t AdapterCancelRequest(const struct UsbHostRequest *request)
1373094332d3Sopenharmony_ci{
1374094332d3Sopenharmony_ci    if (!request->urbs) {
1375094332d3Sopenharmony_ci        DPRINTFN(0, "adapter cancel urb null\n");
1376094332d3Sopenharmony_ci        goto END;
1377094332d3Sopenharmony_ci    }
1378094332d3Sopenharmony_ci
1379094332d3Sopenharmony_ci    OsDiscardUrbs(request, 0, request->numUrbs);
1380094332d3Sopenharmony_ciEND:
1381094332d3Sopenharmony_ci    return HDF_SUCCESS;
1382094332d3Sopenharmony_ci}
1383094332d3Sopenharmony_ci
1384094332d3Sopenharmony_cistatic int32_t AdapterUrbCompleteHandle(const struct UsbDeviceHandle *devHandle)
1385094332d3Sopenharmony_ci{
1386094332d3Sopenharmony_ci    int32_t ret;
1387094332d3Sopenharmony_ci    struct UsbDevice *dev = NULL;
1388094332d3Sopenharmony_ci    struct OsDev *osDev = NULL;
1389094332d3Sopenharmony_ci    UsbAdapterUrb *urb = NULL;
1390094332d3Sopenharmony_ci    struct Async *as = NULL;
1391094332d3Sopenharmony_ci    struct UsbHostRequest *request = NULL;
1392094332d3Sopenharmony_ci    if ((devHandle == NULL) || (devHandle->dev == NULL) || (devHandle->dev->privateData == NULL)) {
1393094332d3Sopenharmony_ci        HDF_LOGE("%{public}s:%{public}d invalid parameter", __func__, __LINE__);
1394094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
1395094332d3Sopenharmony_ci    }
1396094332d3Sopenharmony_ci    dev = devHandle->dev;
1397094332d3Sopenharmony_ci    osDev = (struct OsDev *)dev->privateData;
1398094332d3Sopenharmony_ci    ret = OsReapUrb(devHandle, &as);
1399094332d3Sopenharmony_ci    if (as == NULL) {
1400094332d3Sopenharmony_ci        HDF_LOGE("as is null\n");
1401094332d3Sopenharmony_ci        return HDF_FAILURE;
1402094332d3Sopenharmony_ci    }
1403094332d3Sopenharmony_ci    urb = &as->urb;
1404094332d3Sopenharmony_ci    request = urb->context;
1405094332d3Sopenharmony_ci    switch (request->requestType) {
1406094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_CONTROL:
1407094332d3Sopenharmony_ci            ret = OsControlCompletion(request, as);
1408094332d3Sopenharmony_ci            break;
1409094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_ISOCHRONOUS:
1410094332d3Sopenharmony_ci            ret = OsIsoCompletion(request, as);
1411094332d3Sopenharmony_ci            break;
1412094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_BULK:
1413094332d3Sopenharmony_ci        case USB_REQUEST_TYPE_INTERRUPT:
1414094332d3Sopenharmony_ci            ret = OsBulkCompletion(request, as);
1415094332d3Sopenharmony_ci            break;
1416094332d3Sopenharmony_ci        default:
1417094332d3Sopenharmony_ci            DPRINTFN(0, "%s:%d unrecognised requestType %u\n", __func__, __LINE__, request->requestType);
1418094332d3Sopenharmony_ci            ret = HDF_FAILURE;
1419094332d3Sopenharmony_ci            break;
1420094332d3Sopenharmony_ci    }
1421094332d3Sopenharmony_ci    return ret;
1422094332d3Sopenharmony_ci}
1423094332d3Sopenharmony_ci
1424094332d3Sopenharmony_cistatic struct UsbOsAdapterOps g_usbAdapter = {
1425094332d3Sopenharmony_ci    .init = AdapterInit,
1426094332d3Sopenharmony_ci    .exit = AdapterExit,
1427094332d3Sopenharmony_ci    .openDevice = AdapterOpenDevice,
1428094332d3Sopenharmony_ci    .closeDevice = AdapterCloseDevice,
1429094332d3Sopenharmony_ci    .getConfigDescriptor = AdapterGetConfigDescriptor,
1430094332d3Sopenharmony_ci    .getConfiguration = AdapterGetConfiguration,
1431094332d3Sopenharmony_ci    .setConfiguration = AdapterSetConfiguration,
1432094332d3Sopenharmony_ci    .claimInterface = AdapterClaimInterface,
1433094332d3Sopenharmony_ci    .releaseInterface = AdapterReleaseInterface,
1434094332d3Sopenharmony_ci    .setInterfaceAltsetting = AdapterSetInterface,
1435094332d3Sopenharmony_ci    .clearHalt = AdapterClearHalt,
1436094332d3Sopenharmony_ci    .resetDevice = AdapterResetDevice,
1437094332d3Sopenharmony_ci    .allocRequest = AdapterAllocRequest,
1438094332d3Sopenharmony_ci    .freeRequest = AdapterFreeRequest,
1439094332d3Sopenharmony_ci    .submitRequest = AdapterSubmitRequest,
1440094332d3Sopenharmony_ci    .cancelRequest = AdapterCancelRequest,
1441094332d3Sopenharmony_ci    .urbCompleteHandle = AdapterUrbCompleteHandle,
1442094332d3Sopenharmony_ci};
1443094332d3Sopenharmony_ci
1444094332d3Sopenharmony_cistruct UsbOsAdapterOps *UsbAdapterGetOps(void)
1445094332d3Sopenharmony_ci{
1446094332d3Sopenharmony_ci    return &g_usbAdapter;
1447094332d3Sopenharmony_ci}
1448094332d3Sopenharmony_ci
1449094332d3Sopenharmony_ciUsbRawTidType UsbAdapterGetTid(void)
1450094332d3Sopenharmony_ci{
1451094332d3Sopenharmony_ci    return HDF_FAILURE;
1452094332d3Sopenharmony_ci}
1453094332d3Sopenharmony_ci
1454094332d3Sopenharmony_ciint32_t UsbAdapterRegisterSignal(void)
1455094332d3Sopenharmony_ci{
1456094332d3Sopenharmony_ci    return HDF_SUCCESS;
1457094332d3Sopenharmony_ci}
1458094332d3Sopenharmony_ci
1459094332d3Sopenharmony_ciint32_t UsbAdapterKillSignal(struct UsbDeviceHandle *handle, UsbRawTidType tid)
1460094332d3Sopenharmony_ci{
1461094332d3Sopenharmony_ci    if ((handle != NULL) && (handle->dev != NULL)) {
1462094332d3Sopenharmony_ci        struct UsbDevice *dev = handle->dev;
1463094332d3Sopenharmony_ci        struct OsDev *osDev = (struct OsDev *)dev->privateData;
1464094332d3Sopenharmony_ci        if (osDev != NULL) {
1465094332d3Sopenharmony_ci            g_CompleteExit = true;
1466094332d3Sopenharmony_ci            OsalSemPost(&osDev->cvWait);
1467094332d3Sopenharmony_ci            HDF_LOGD("%{public}s:%{public}d signal post", __func__, __LINE__);
1468094332d3Sopenharmony_ci            return HDF_SUCCESS;
1469094332d3Sopenharmony_ci        } else {
1470094332d3Sopenharmony_ci            return HDF_FAILURE;
1471094332d3Sopenharmony_ci        }
1472094332d3Sopenharmony_ci    } else {
1473094332d3Sopenharmony_ci        return HDF_FAILURE;
1474094332d3Sopenharmony_ci    }
1475094332d3Sopenharmony_ci}
1476094332d3Sopenharmony_ci
1477094332d3Sopenharmony_ciint32_t AdapterAtomicInc(OsalAtomic *v)
1478094332d3Sopenharmony_ci{
1479094332d3Sopenharmony_ci    int32_t valOld;
1480094332d3Sopenharmony_ci    int32_t val;
1481094332d3Sopenharmony_ci    uint32_t status = 0;
1482094332d3Sopenharmony_ci    Atomic *p = NULL;
1483094332d3Sopenharmony_ci    if (v) {
1484094332d3Sopenharmony_ci        p = (Atomic *)&(v)->counter;
1485094332d3Sopenharmony_ci    } else {
1486094332d3Sopenharmony_ci        return HDF_FAILURE;
1487094332d3Sopenharmony_ci    }
1488094332d3Sopenharmony_ci    do {
1489094332d3Sopenharmony_ci        __asm__ __volatile__("ldrex   %1, [%4]\n"
1490094332d3Sopenharmony_ci                             "mov   %0, %1\n"
1491094332d3Sopenharmony_ci                             "add   %1, %1, #1\n"
1492094332d3Sopenharmony_ci                             "strex   %2, %1, [%4]"
1493094332d3Sopenharmony_ci                             : "=&r"(valOld), "=&r"(val), "=&r"(status), "+m"(*p)
1494094332d3Sopenharmony_ci                             : "r"(p)
1495094332d3Sopenharmony_ci                             : "cc");
1496094332d3Sopenharmony_ci    } while (__builtin_expect(status != 0, 0));
1497094332d3Sopenharmony_ci
1498094332d3Sopenharmony_ci    return valOld;
1499094332d3Sopenharmony_ci}
1500094332d3Sopenharmony_ci
1501094332d3Sopenharmony_ciint32_t AdapterAtomicDec(OsalAtomic *v)
1502094332d3Sopenharmony_ci{
1503094332d3Sopenharmony_ci    if (v) {
1504094332d3Sopenharmony_ci        return LOS_AtomicDecRet((Atomic *)&(v)->counter);
1505094332d3Sopenharmony_ci    } else {
1506094332d3Sopenharmony_ci        return HDF_FAILURE;
1507094332d3Sopenharmony_ci    }
1508094332d3Sopenharmony_ci}
1509