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
signature.asc
Description: Digital signature
