--- libusb-1.0.19p/libusb/os/aix_usb.c 2017-11-28 03:39:44 -0600 +++ libusb-1.0.19/libusb/os/aix_usb.c 2017-11-29 06:27:29 -0600 @@ -17,7 +17,7 @@ { openlog("LIBUSB", LOG_PID, LOG_USER); - syslog(LOG_DEBUG, "LIBUSB AIX Logging Starts"); + syslog(LOG_DEBUG, "LIBUSB AIX Logging Start"); return 0; } @@ -25,7 +25,7 @@ void aix_exit(void) { - syslog(LOG_DEBUG, "LIBUSB AIX Logging Ends"); + syslog(LOG_DEBUG, "LIBUSB AIX Logging End"); closelog(); } @@ -77,17 +77,23 @@ bus_number = get_busnumber(dep->d_name); if (bus_number == -1) bus_number = 0; - usbi_dbg("\n calling add_hc_device errno:%d\n",errno); + usbi_dbg("\n calling add_hc_device function with errno:%d\n",errno); rc = add_hc_device(fd ,dep->d_name, bus_number, discdevs, ctx); - usbi_dbg("\n done add_hc_device errno:%d\n",errno); + usbi_dbg("\n done add_hc_device function errno:%d\n",errno); if (rc != 0) { usbi_err(ctx, "add_hc_device failed errno = (%d), rc = %d", errno, rc); + closedir(dp); close(fd); return rc; } } } - + if (!dp) { + usbi_dbg("\n dp is NULL, IT SHOULD NOT!\n"); + } + if (!dp->dd_buf) { + usbi_dbg("\n dp->dd_buf is NULL, IT SHOULD NOT!\n"); + } closedir(dp); close(fd); @@ -102,7 +108,7 @@ if (sscanf(hc_name, "usbhc%d", &busnumber) != 1) return 0; - usbi_dbg("get_busnumber: busnumber returned: %d for usbhc: %s",busnumber, hc_name); + usbi_dbg("get_busnumber: busnumber returned value is %d for usbhc: %s",busnumber, hc_name); return busnumber; @@ -116,7 +122,7 @@ int irv; dev32_t devno32; USBENUM ue1; - USBENUM *uep; + USBENUM *uep = NULL; size_t s; usb_device_t *udp; int n, rc = 0; @@ -131,6 +137,7 @@ /* Get the host controller devno. */ errno=0; + /* malloc done in the callee, need to free this */ hcdevpath = aix_usb_concatenate("/dev/",hc_name); if( ! hcdevpath ) { @@ -144,6 +151,7 @@ { printf("stat() failed, irv=%d errno=%d\n",irv,errno); usbi_err(ctx, "add_hc_device: stat() failed, irv=%d errno=%d",irv,errno); + free(hcdevpath); return LIBUSB_ERROR_NOT_FOUND; } @@ -164,11 +172,12 @@ usbi_err(ctx, "ioctl(,USBD_ENUMERATE_ALL,) failed, irv=%d errno=%d\n",irv,errno); if (errno == ENODEV) return LIBUSB_ERROR_NO_DEVICE; + free(hcdevpath); return LIBUSB_ERROR_IO; } - printf("found %d devices\n",ue1.numDevDisc); - usbi_dbg("add_hc_device: found %d devices",ue1.numDevDisc); + printf("found %d device(s)\n",ue1.numDevDisc); + usbi_dbg("add_hc_device: found %d device(s)",ue1.numDevDisc); if( ue1.numDevDisc < 1 ) { @@ -176,6 +185,7 @@ /* if there are no devices connected to hostcontroller, * the count will be zero. hence return zero instead of negative valie */ + free(hcdevpath); return 0; } @@ -187,6 +197,7 @@ { printf("malloc() failed, errno=%d\n",errno); usbi_err(ctx, "add_hc_device: malloc() failed, errno=%d",errno); + free(hcdevpath); return LIBUSB_ERROR_NO_MEM; } @@ -199,6 +210,7 @@ { printf("ioctl(,USBD_ENUMERATE_ALL,) failed, irv=%d errno=%d\n",irv,errno); usbi_err(ctx, "ioctl(,USBD_ENUMERATE_ALL,) failed, irv=%d errno=%d\n",irv,errno); + free(hcdevpath); free(uep); return LIBUSB_ERROR_IO; } @@ -236,7 +248,7 @@ if (dev) { usbi_dbg("session_id %ld already exists", session_id); libusb_unref_device(dev); - return LIBUSB_SUCCESS; + continue; } if (dev == NULL) @@ -248,7 +260,7 @@ { usbi_err(ctx, "add_hc_device: usbi_alloc_device failed \ for session_id: %ld", session_id); - return (LIBUSB_ERROR_NO_MEM); + continue; } dev->bus_number = bus_number; @@ -314,7 +326,7 @@ { printf("malloc() failed, errno=%d\n",errno); usbi_err(ctx, "malloc() failed for dgd.buffer, length=%d errno=%d",dgd.minBuffLength,errno); - return LIBUSB_ERROR_NO_MEM; + continue; } irv=ioctl(usbd_fd, USBD_GET_DESCRIPTORS, &dgd); @@ -324,19 +336,12 @@ { printf("ioctl(USBD_GET_DESCRIPTORS 2) failed, irv=%d errno=%d\n",irv,errno); usbi_err(ctx, "ioctl(USBD_GET_DESCRIPTORS 2) failed, irv=%d errno=%d\n",irv,errno); - free(uep); - return LIBUSB_ERROR_IO; + free(dgd.buffer); + continue; } - priv->descriptors = malloc(dgd.minBuffLength); - if ( ! (priv->descriptors) ) - { - printf("malloc() failed, errno=%d\n",errno); - return LIBUSB_ERROR_NO_MEM; - } - - memcpy((char *)priv->descriptors, (char *)(dgd.buffer), dgd.bufferLength); + priv->descriptors = (PDESCIDX_32)dgd.buffer; priv->desc_size = dgd.bufferLength; @@ -367,13 +372,23 @@ if (ddd == NULL) { usbi_err(ctx, "discovered_devs_append failed"); - return (LIBUSB_ERROR_NO_MEM); + continue; } libusb_unref_device(dev); *discdevs = ddd; } - free(uep); + if (hcdevpath) { + free(hcdevpath); + } else { + usbi_dbg("add_hc_device: hcdevpath is not freed"); + } + + if (uep) { + free(uep); + } else { + usbi_dbg("add_hc_device: uep is not freed"); + } usbi_dbg("add_hc_device: Function return success"); @@ -504,7 +519,6 @@ usbi_dbg("aix_get_config_descriptor: Device: %s len: %d host_endian: %d idx:%d\n", priv->devicename, len, *host_endian,idx); - desc = (PUSBConfigDesc)priv->configdesc; size = LOAD16(desc->wTotalLength); usbi_dbg("aix_get_config_descriptor: length in aix_get_config_descriptor is %d and cdesc_len is %d",size, priv->cdesc_len); @@ -615,7 +629,6 @@ aix_claim_interface(struct libusb_device_handle *handle, int iface) { struct aix_device_priv *priv = _device_priv(handle->dev); - printf("\n in aix_claim_interface\n"); usbi_dbg("aix_claim_interface: Device: %s Interface: %d", priv->devicename, iface); return (LIBUSB_SUCCESS); } @@ -742,10 +755,17 @@ struct aix_device_priv *priv = _device_priv(dev); usbi_dbg("aix_destroy_device: Device: %s",priv->devicename); - if (priv->descriptors) + if (priv->descriptors) { free(priv->descriptors); - if (priv->configdesc) + } + /* + *priv->configdesc is allocated only when + * there is more than 1 configuration. cdesc_len is + * set only then, hence checking before freeing it + */ + if (priv->configdesc && priv->cdesc_len > 1) { free(priv->configdesc); + } } @@ -810,7 +830,7 @@ struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - usbi_dbg("aix_submit_transfer: Transfer Type: %d", transfer->type); + usbi_dbg("aix_submit_transfer: Transfer Type: %d Transfer Timeout: %d", transfer->type, transfer->timeout); switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL: @@ -879,11 +899,23 @@ tpriv->status = SUBMITTED; - usbi_dbg("\n aix_submit_control_transfer errno 6: %d", errno); + usbi_dbg("\n aix_submit_control_transfer errno is: %d", errno); rc = ioctl(dpriv->fd, USBLIB_PIPE_IO, &pipeioargs); usbi_dbg("\n aix_submit_control_transfer rc: %d", rc); - return 0; + if (rc) { + usbi_err(TRANSFER_CTX(transfer), "USBLIB_PIPE_IO control transfer failed with rc: %d errno: %d", rc, errno); + if (errno == ENODEV) { + rc = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submit control failed error %d errno=%d", rc, errno); + rc = LIBUSB_ERROR_IO; + } + tpriv->status = COMPLETED; + } + + return rc; } @@ -1033,7 +1065,7 @@ do { r = aix_get_irp_data(handle); - } while (0); + } while (r == 0); if (r == 1 || r == LIBUSB_ERROR_NO_DEVICE) continue; else if (r < 0) @@ -1061,25 +1093,56 @@ devsel = hpriv->devsel_handle; - usbi_dbg("aix_get_irp_data: printing errno 1:%d",errno); + usbi_dbg("aix_get_irp_data: printing errno 1 is %d",errno); memset(&pipeioargs, 0, sizeof(struct aix_pipeio)); - usbi_dbg("aix_get_irp_data: printing errno 2:%d",errno); + usbi_dbg("aix_get_irp_data: printing errno 2 is %d",errno); pipeioargs.devsel = hpriv->devsel_handle; pipeioargs.endpoint = 0; pipeioargs.pBuffer = (caddr_t)malloc(hpriv->transfer_size); pipeioargs.clientPriv = (void *)itransfer; pipeioargs.transSize = transfer->length; - pipeioargs.status = 0; + /* + * we are setting it to 100 (a random value) + * this is used to differentiate between old AIX level + * and new AIX level. The change is to handle asynchronous way of + * handling completions. The thread requests and send this ioctl until + * all the outstanding I/Os are returned + */ + pipeioargs.status = 100; errno = 0; r = ioctl(hpriv->fd, USBLIB_GETIRP_STATUS, &pipeioargs); - usbi_dbg("aix_get_irp_data: get irp status ioctl returned %d and errno:%d",r,errno); + usbi_dbg("aix_get_irp_data: get irp status ioctl returned %d and pipeioargs.status value is %d",r, pipeioargs.status); + + if (r == -1) { + + /* + * for AIX levels greater than or equal to + * 71TL5SP2 and + * 72TL2SP2 + */ + + if (pipeioargs.status == EAGAIN) { + free(pipeioargs.pBuffer); + return 1; + } - if (r == -1 && errno == EAGAIN) + /* + * for AIX levels less than or equal to + * 71TL5SP1 and + * 72TL2SP1 + */ + + if (pipeioargs.status == 100) { + free(pipeioargs.pBuffer); return 1; + } + + } + if (r < 0) { usbi_err(HANDLE_CTX(handle), "aix_get_irp_data: failed error %d errno=%d", r, errno); @@ -1277,6 +1340,7 @@ if ( rc != 0 ) { usbi_err(NULL, "get_all_config_descriptors: ioctl(USBLIB_GET_CONFIG_DESC 2) failed, rc=%d errno=%d",rc,errno); free(arg.buf); + close(fd); return -1; } @@ -1285,6 +1349,7 @@ if ( ! (priv->configdesc) ) { usbi_err(NULL, "get_all_config_descriptors: malloc() failed, errno=%d",errno); free(arg.buf); + close(fd); return LIBUSB_ERROR_NO_MEM; } @@ -1331,7 +1396,7 @@ usbi_dbg("open_aix_libusb_device: connwhere: %s",connwhere); - sprintf(crit, "PdDvLn = 'generic/usbif/usblibke' and connwhere = '%s'",connwhere); + sprintf(crit, "PdDvLn = 'generic/usbif/usblibke' and connwhere = '%s' and status='1'",connwhere); cudv_ptr = (struct CuDv *)odm_get_first(CuDv_CLASS,crit,&cudv);