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