From patchwork Thu May 17 17:03:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guido Kiener X-Patchwork-Id: 10407085 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 80BFD60155 for ; Thu, 17 May 2018 16:10:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71936285C9 for ; Thu, 17 May 2018 16:10:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6686E285D2; Thu, 17 May 2018 16:10:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F0A69285C9 for ; Thu, 17 May 2018 16:10:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752588AbeEQQKk (ORCPT ); Thu, 17 May 2018 12:10:40 -0400 Received: from mr01.mx01.tldhost.de ([62.108.36.247]:54012 "EHLO mr01.mx01.tldhost.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752566AbeEQQKg (ORCPT ); Thu, 17 May 2018 12:10:36 -0400 Received: from mx01.tldhost.de (localhost [127.0.0.1]) by mx01.tldhost.de (Postfix) with ESMTP id EE769120DB3 for ; Thu, 17 May 2018 18:05:03 +0200 (CEST) Received: by mx01.tldhost.de (Postfix, from userid 1001) id E0979120DB4; Thu, 17 May 2018 18:05:03 +0200 (CEST) Received: from server12.tldhost.de (server12.tldhost.de [84.19.26.112]) by mx01.tldhost.de (Postfix) with ESMTPS id 5B0B2120DB3; Thu, 17 May 2018 18:04:59 +0200 (CEST) From: Guido Kiener To: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, guido.kiener@rohde-schwarz.com, pankaj.adhikari@ni.com, steve_bayless@keysight.com, dpenkler@gmail.com Cc: Guido Kiener Subject: [PATCH 09/12] usb: usbtmc: Fix ioctl USBTMC_IOCTL_CLEAR Date: Thu, 17 May 2018 19:03:33 +0200 Message-Id: <20180517170336.8426-10-guido@kiener-muenchen.de> In-Reply-To: <20180517170336.8426-1-guido@kiener-muenchen.de> References: <20180517170336.8426-1-guido@kiener-muenchen.de> X-PPP-Message-ID: <20180517160500.4409.72816@server12.tldhost.de> X-PPP-Vhost: kiener-muenchen.de X-POWERED-BY: TLDHost.de - AV:CLEAN SPAM:OK Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Insert a sleep of 50 ms between subsequent CHECK_CLEAR_STATUS control requests to avoid stressing the instrument with repeated requests. Some instruments need time to cleanup internal I/O buffers. Polling and repeated requests slow down the response time of devices. Signed-off-by: Guido Kiener Reviewed-by: Steve Bayless --- drivers/usb/class/usbtmc.c | 46 +++++++++++++++----------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 76b0a7b083a7..165b707991f3 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1643,20 +1643,17 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) { - struct usb_host_interface *current_setting; - struct usb_endpoint_descriptor *desc; struct device *dev; u8 *buffer; int rv; int n; int actual = 0; - int max_size; dev = &data->intf->dev; dev_dbg(dev, "Sending INITIATE_CLEAR request\n"); - buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL); + buffer = kmalloc(USBTMC_BUFSIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; @@ -1664,7 +1661,7 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) usb_rcvctrlpipe(data->usb_dev, 0), USBTMC_REQUEST_INITIATE_CLEAR, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, 0, buffer, 1, USBTMC_TIMEOUT); + 0, 0, buffer, 1, USB_CTRL_GET_TIMEOUT); if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; @@ -1678,22 +1675,6 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) goto exit; } - max_size = 0; - current_setting = data->intf->cur_altsetting; - for (n = 0; n < current_setting->desc.bNumEndpoints; n++) { - desc = ¤t_setting->endpoint[n].desc; - if (desc->bEndpointAddress == data->bulk_in) - max_size = usb_endpoint_maxp(desc); - } - - if (max_size == 0) { - dev_err(dev, "Couldn't get wMaxPacketSize\n"); - rv = -EPERM; - goto exit; - } - - dev_dbg(dev, "wMaxPacketSize is %d\n", max_size); - n = 0; usbtmc_clear_check_status: @@ -1704,7 +1685,7 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) usb_rcvctrlpipe(data->usb_dev, 0), USBTMC_REQUEST_CHECK_CLEAR_STATUS, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, 0, buffer, 2, USBTMC_TIMEOUT); + 0, 0, buffer, 2, USB_CTRL_GET_TIMEOUT); if (rv < 0) { dev_err(dev, "usb_control_msg returned %d\n", rv); goto exit; @@ -1721,15 +1702,19 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) goto exit; } - if (buffer[1] == 1) + if ((buffer[1] & 1) != 0) { do { dev_dbg(dev, "Reading from bulk in EP\n"); rv = usb_bulk_msg(data->usb_dev, usb_rcvbulkpipe(data->usb_dev, data->bulk_in), - buffer, USBTMC_SIZE_IOBUFFER, - &actual, USBTMC_TIMEOUT); + buffer, USBTMC_BUFSIZE, + &actual, USB_CTRL_GET_TIMEOUT); + + print_hex_dump_debug("usbtmc ", DUMP_PREFIX_NONE, + 16, 1, buffer, actual, true); + n++; if (rv < 0) { @@ -1737,10 +1722,15 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) rv); goto exit; } - } while ((actual == max_size) && + } while ((actual == USBTMC_BUFSIZE) && (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); + } else { + /* do not stress device with subsequent requests */ + msleep(50); + n++; + } - if (actual == max_size) { + if (n >= USBTMC_MAX_READS_TO_CLEAR_BULK_IN) { dev_err(dev, "Couldn't clear device buffer within %d cycles\n", USBTMC_MAX_READS_TO_CLEAR_BULK_IN); rv = -EPERM; @@ -1754,7 +1744,7 @@ static int usbtmc_ioctl_clear(struct usbtmc_device_data *data) rv = usb_clear_halt(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out)); if (rv < 0) { - dev_err(dev, "usb_control_msg returned %d\n", rv); + dev_err(dev, "usb_clear_halt returned %d\n", rv); goto exit; } rv = 0;