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 <balbi@xxxxxx> > Date: Mon Oct 10 10:33:47 2011 +0300 > > usb: gadget: net2272: convert to new style > > > commit 4cf5e00b055ba5e4f3852e477a2a4346730ea283 > Author: Felipe Balbi <balbi@xxxxxx> > Date: Mon Oct 10 10:37:17 2011 +0300 > > usb: gadget: net2280: convert to new style > > > Signed-off-by: Chen Gang <gang.chen@xxxxxxxxxxx> > --- > 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 <balbi@xxxxxx> * * 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