On Thu, 27 Jun 2013, Tim Sander wrote: > Hi Alan > > > I have just written a ehci testing driver which enables the testing modes > > > used for hw testing via a file in debugfs. This patch is for 3.4.47 not > > > any usb branch. But if this driver is ready for mainline i will be happy > > > to port it to whatever branch you wish. > > > > It's not clear why this patch is needed. Why can't the existing code > > do what you want? > > > > > The only problem with the patch is that it is currently working on hw > > > registers as the usb control msg in this patch is not working. For the > > > time beeing i just commented out the usb_control_msg call and fiddled > > > with the registers directly. This is one thing which might not be > > > mainline compatible? > > > > Why do you want to have a debugfs file in the first place? What's > > wrong with using usbfs or libusb? > Uhm, we came from a vendor bsp where this functionality was available for the What's a bsp? > Freescale I.Mx35. After we where using the mainline kernel this functionality > was missing and i was not aware how to trigger this stuff via libusb or usbfs? > Also skimming over the library documentation i couldn't find any function to > trigger the test modes. > > Besides having an easy way with a shell and a running kernel to trigger test > modes is good to have hw vendors test their stuff? Having a standard test program should be about as good as using a shell. > > As far as I can see, there is no reason for this to be merged because > > it doesn't do anything that can't be done already, using the existing > > facilities. > Do you have any pointer for me? If i would have found an easier way i would > have choosen this one. Attached is a simple "porttest.c" program I just wrote. I haven't tried it out, but any problems should be easy to find and fix. After compiling it, you use the program by giving it the name of the hub's device file, the port number, and the test mode number. For example, if the hub is device 2 on bus 1, and you want to put port 3 into test mode 5, you would type: ./porttest /dev/bus/usb/001/002 3 5 A big advantage of using this program is that it will work with external hubs as well as with root hubs. And of course, it doesn't require any changes to the kernel. > As for the referenced driver: > http://code.google.com/p/bricked/source/browse/drivers/usb/misc/ehset.c > This is functionality which is not available within the kernel in a way that > an external test device plugged triggers some test which in some cases even > need interaction from the driver? Triggering particular behaviors when a device is plugged in is what udev does. Alan Stern
/* porttest -- put a USB hub port into TEST mode */ /* To build: gcc -o testport testport.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/ioctl.h> #include <linux/usbdevice_fs.h> #include <linux/usb/ch9.h> #define USB_MAXCHILDREN 31 #include <linux/usb/ch11.h> char *mode_names[] = { "Reserved", /* 0 */ "Test_J", /* 1 */ "Test_K", /* 2 */ "Test_SE0_NAK", /* 3 */ "Test_Packet", /* 4 */ "Test_Force_Enable", /* 5 */ /* Remaining values are reserved */ }; #define MAX_TEST_MODE 5 int main(int argc, char **argv) { const char *filename; int portnum, testmode; int fd; int rc; struct usbdevfs_ctrltransfer ctl; if (argc != 4) { fprintf(stderr, "Usage: porttest device-filename portnum testmode\n"); return 1; } filename = argv[1]; portnum = atoi(argv[2]); if (portnum <= 0 || portnum > USB_MAXCHILDREN) { fprintf(stderr, "Invalid port number: %d\n", portnum); return 1; } testmode = atoi(argv[3]); if (testmode <= 0 || testmode > MAX_TEST_MODE) { fprintf(stderr, "Invalid test mode: %d\n", testmode); return 1; } fd = open(filename, O_WRONLY); if (fd < 0) { perror("Error opening device file"); return 1; } printf("Setting port %d to test mode %d (%s)\n", portnum, testmode, mode_names[testmode]); ctl.bRequestType = USB_DIR_OUT | USB_RT_PORT; ctl.bRequest = USB_REQ_SET_FEATURE; ctl.wValue = USB_PORT_FEAT_TEST; ctl.wIndex = (testmode << 8) | portnum; ctl.wLength = 0; rc = ioctl(fd, USBDEVFS_CONTROL, &ctl); if (rc < 0) { perror("Error in ioctl"); return 1; } printf("Test mode successful\n"); close(fd); return 0; }