Hi,

On Thu, Feb 28, 2013 at 04:13:01PM +0800, Chen Gang wrote:
> 
>   originally, when deleted the relative code, left some 'another'.
>   need delete 'another', too.
>   the relative patches are:
> 
>     commit 96f8db6a77e3490608e5b5b3f57e7201f8c85496
>     Author: Felipe Balbi <[email protected]>
>     Date:   Mon Oct 10 10:33:47 2011 +0300
> 
>       usb: gadget: net2272: convert to new style
> 
> 
>     commit 4cf5e00b055ba5e4f3852e477a2a4346730ea283
>     Author: Felipe Balbi <[email protected]>
>     Date:   Mon Oct 10 10:37:17 2011 +0300
> 
>       usb: gadget: net2280: convert to new style
> 
> 
> Signed-off-by: Chen Gang <[email protected]>
> ---
>  drivers/usb/gadget/net2272.c |    4 ----
>  drivers/usb/gadget/net2280.c |    4 ----
>  2 files changed, 0 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
> index d226058..22ee57c 100644
> --- a/drivers/usb/gadget/net2272.c
> +++ b/drivers/usb/gadget/net2272.c
> @@ -1484,10 +1484,6 @@ stop_activity(struct net2272 *dev, struct 
> usb_gadget_driver *driver)
>  {
>       int i;
>  
> -     /* don't disconnect if it's not connected */
> -     if (dev->gadget.speed == USB_SPEED_UNKNOWN)
> -             driver = NULL;

this is the wrong fix, I believe. Looks like when I wrote the commits
you mention, I deleted more code then I should. Looks like the real fix
would be to add back:

        /* report disconnect; the driver is already quiesced */
        if (driver) {
                spin_unlock(&dev->lock);
                driver->disconnect(&dev->gadget);
                spin_lock(&dev->lock);
        }

since stop_activity() also gets called from RESET interrupt, and in that
case we need to call driver->disconnect(). Can you make a simple test
that would take current code and issue a device reset to see if that
would break, then apply my suggestion above and run the same test again?

If you want, I have a simple libusb-1.0-based little app which can issue
resets to any device you ask. Currently it will reset a device 10K
times but you can remove the for loop if you want:

8<------------------- cut here -------------------------


/* $(CROSS_COMPILE)gcc -Wall -O2 -g -lusb-1.0 -o device-reset device-reset.c */
/**
 * device-reset.c - Reset a USB device multiple times
 *
 * Copyright (C) 2013 Felipe Balbi <[email protected]>
 *
 * This file is part of the USB Verification Tools Project
 *
 * USB Tools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public Liicense as published by
 * the Free Software Foundation, either version 3 of the license, or
 * (at your option) any later version.
 *
 * USB Tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with USB Tools. If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>

#include <libusb-1.0/libusb.h>

#define OPTION(n, h, v)                 \
{                                       \
        .name           = #n,           \
        .has_arg        = h,            \
        .val            = v,            \
}

static struct option device_reset_opts[] = {
        OPTION("help",          0, 'h'),
        OPTION("device",        1, 'D'),
        {  }    /* Terminating entry */
};

static void usage(char *cmd)
{
        fprintf(stdout, "%s -D VID:PID\n", cmd);
}

int main(int argc, char *argv[])
{
        libusb_context          *context;
        libusb_device_handle    *udevh;

        unsigned                vid = 0;
        unsigned                pid = 0;

        int                     ret = 0;
        int                     i;

        while (1) {
                int             optidx;
                int             opt;

                char            *token;

                opt = getopt_long(argc, argv, "D:h", device_reset_opts, 
&optidx);
                if (opt == -1)
                        break;

                switch (opt) {
                case 'D':
                        token = strtok(optarg, ":");
                        vid = strtoul(token, NULL, 16);
                        token = strtok(NULL, ":");
                        pid = strtoul(token, NULL, 16);
                        break;
                case 'h': /* FALLTHROUGH */
                default:
                        usage(argv[0]);
                        exit(-1);
                }
        }

        libusb_init(&context);

        udevh = libusb_open_device_with_vid_pid(context, vid, pid);
        if (!udevh) {
                perror("open");
                ret = -ENODEV;
                goto out0;
        }

        for (i = 0; i < 10000; i++) {
                ret = libusb_reset_device(udevh);
                printf("Reset #%d: ", i + 1);

                if (ret < 0) {
                        printf("FAILED\n");
                        break;
                } else {
                        printf("PASSED\n");
                }
        }

        libusb_close(udevh);

out0:
        libusb_exit(context);

        return ret;
}


-- 
balbi

Attachment: signature.asc
Description: Digital signature

Reply via email to