ChangeSet 1.855.9.8, 2002/11/05 11:07:55-08:00, [EMAIL PROTECTED]

[PATCH] usbtest, Kconfig and misc

Minor patches:

- resend of the Config.in patch, updated to Kconfig,
   plus makes 'usbtest' modular when usb is;

- hmm, "usbfs" isn't locking here.  protect.  fix
   is basically from martin:  add/use a semaphore.

- that one-liner to make sure get_configuration is
   called correctly (with funkier test firmware).

- new 'realworld' module param can be used to turn
   off the real-world accomodations and be stricter
   about what device failures make ch9 tests fail.


diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig  Tue Nov  5 16:10:32 2002
+++ b/drivers/usb/misc/Kconfig  Tue Nov  5 16:10:32 2002
@@ -99,10 +99,13 @@
 
 config USB_TEST
        tristate "USB testing driver (DEVELOPMENT)"
-       depends on USB_DEVICEFS && EXPERIMENTAL
+       depends on USB && USB_DEVICEFS && EXPERIMENTAL
        help
 
          This driver is for testing host controller software.  It is used
          with specialized device firmware for regression and stress testing,
          to help prevent problems from cropping up with "real" drivers.
+
+         See <http://www.linux-usb.org/usbtest> for more information,
+         including sample test device firmware and "how to use it".
 
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c        Tue Nov  5 16:10:32 2002
+++ b/drivers/usb/misc/usbtest.c        Tue Nov  5 16:10:32 2002
@@ -51,14 +51,10 @@
 };
 
 /* this is accessed only through usbfs ioctl calls.
- * one ioctl to issue a test ... no locking needed!!!
+ * one ioctl to issue a test ... one lock per device.
  * tests create other threads if they need them.
  * urbs and buffers are allocated dynamically,
  * and data generated deterministically.
- *
- * there's a minor complication on rmmod, since
- * usbfs.disconnect() waits till our ioctl completes.
- * unplug works fine since we'll see real i/o errors.
  */
 struct usbtest_dev {
        struct usb_interface    *intf;
@@ -66,6 +62,7 @@
        char                    id [32];
        int                     in_pipe;
        int                     out_pipe;
+       struct semaphore        sem;
 
 #define TBUF_SIZE      256
        u8                      *buf;
@@ -282,6 +279,10 @@
  * or remote wakeup (which needs human interaction).
  */
 
+static int realworld = 1;
+MODULE_PARM (realworld, "i");
+MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance");
+
 static int get_altsetting (struct usbtest_dev *dev)
 {
        struct usb_interface    *iface = dev->intf;
@@ -366,13 +367,11 @@
        case USB_DT_OTHER_SPEED_CONFIG:
                if (config->bLength != 9)
                        return 0;
-#if 0
                /* this bit 'must be 1' but often isn't */
-               if (!(config->bmAttributes & 0x80)) {
+               if (!realworld && !(config->bmAttributes & 0x80)) {
                        dbg ("high bit of config attributes not set");
                        return 0;
                }
-#endif
                if (config->bmAttributes & 0x1f)        /* reserved == 0 */
                        return 0;
                break;
@@ -424,7 +423,7 @@
                }
 
                /* [real world] get/set unimplemented if there's only one */
-               if (iface->num_altsetting == 1)
+               if (realworld && iface->num_altsetting == 1)
                        continue;
 
                /* [9.4.10] set_interface */
@@ -446,7 +445,7 @@
        }
 
        /* [real world] get_config unimplemented if there's only one */
-       if (udev->descriptor.bNumConfigurations != 1) {
+       if (!realworld || udev->descriptor.bNumConfigurations != 1) {
                int     expected = udev->actconfig->desc.bConfigurationValue;
 
                /* [9.4.2] get_configuration always works
@@ -454,7 +453,8 @@
                 * won't return config descriptors except before set_config.
                 */
                retval = usb_control_msg (udev, usb_rcvctrlpipe (udev, 0),
-                               USB_REQ_GET_CONFIGURATION, USB_RECIP_DEVICE,
+                               USB_REQ_GET_CONFIGURATION,
+                               USB_DIR_IN | USB_RECIP_DEVICE,
                                0, 0, dev->buf, 1, HZ * USB_CTRL_GET_TIMEOUT);
                if (retval != 1 || dev->buf [0] != expected) {
                        dbg ("%s get config --> %d (%d)", dev->id, retval,
@@ -563,7 +563,8 @@
  * threads and request completion.
  */
 
-static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
+static int
+usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
 {
        struct usbtest_dev      *dev = dev_get_drvdata (&intf->dev);
        struct usb_device       *udev = testdev_to_usbdev (dev);
@@ -584,6 +585,9 @@
                        || param->sglen < 0 || param->vary < 0)
                return -EINVAL;
 
+       if (down_interruptible (&dev->sem))
+               return -ERESTARTSYS;
+
        /* some devices, like ez-usb default devices, need a non-default
         * altsetting to have any active endpoints.  some tests change
         * altsettings; force a default so most tests don't need to check.
@@ -591,12 +595,15 @@
        if (dev->info->alt >= 0) {
                int     res;
 
-               if (intf->altsetting->desc.bInterfaceNumber)
+               if (intf->altsetting->desc.bInterfaceNumber) {
+                       up (&dev->sem);
                        return -ENODEV;
+               }
                res = set_altsetting (dev, dev->info->alt);
                if (res) {
                        err ("%s: set altsetting to %d failed, %d",
                                        dev->id, dev->info->alt, res);
+                       up (&dev->sem);
                        return res;
                }
        }
@@ -770,6 +777,7 @@
                param->duration.tv_usec += 1000 * 1000;
                param->duration.tv_sec -= 1;
        }
+       up (&dev->sem);
        return retval;
 }
 
@@ -819,6 +827,7 @@
        memset (dev, 0, sizeof *dev);
        info = (struct usbtest_info *) id->driver_info;
        dev->info = info;
+       init_MUTEX (&dev->sem);
 
        /* use the same kind of id the hid driver shows */
        snprintf (dev->id, sizeof dev->id, "%s-%s:%d",
@@ -873,6 +882,8 @@
 static void usbtest_disconnect (struct usb_interface *intf)
 {
        struct usbtest_dev      *dev = dev_get_drvdata (&intf->dev);
+
+       down (&dev->sem);
 
        dev_set_drvdata (&intf->dev, 0);
        info ("unbound %s", dev->id);


-------------------------------------------------------
This sf.net email is sponsored by: See the NEW Palm 
Tungsten T handheld. Power & Color in a compact size!
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0001en
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to