Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
[linux-2.6.git] / drivers / usb / core / message.c
index 95a49d8..c021af3 100644 (file)
@@ -59,8 +59,8 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
                dev_dbg(&urb->dev->dev,
                        "%s timed out on ep%d%s len=%d/%d\n",
                        current->comm,
-                       usb_pipeendpoint(urb->pipe),
-                       usb_pipein(urb->pipe) ? "in" : "out",
+                       usb_endpoint_num(&urb->ep->desc),
+                       usb_urb_dir_in(urb) ? "in" : "out",
                        urb->actual_length,
                        urb->transfer_buffer_length);
        } else
@@ -250,7 +250,8 @@ static void sg_clean (struct usb_sg_request *io)
                io->urbs = NULL;
        }
        if (io->dev->dev.dma_mask != NULL)
-               usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
+               usb_buffer_unmap_sg (io->dev, usb_pipein(io->pipe),
+                               io->sg, io->nents);
        io->dev = NULL;
 }
 
@@ -278,8 +279,8 @@ static void sg_complete (struct urb *urb)
                dev_err (io->dev->bus->controller,
                        "dev %s ep%d%s scatterlist error %d/%d\n",
                        io->dev->devpath,
-                       usb_pipeendpoint (urb->pipe),
-                       usb_pipein (urb->pipe) ? "in" : "out",
+                       usb_endpoint_num(&urb->ep->desc),
+                       usb_urb_dir_in(urb) ? "in" : "out",
                        status, io->status);
                // BUG ();
        }
@@ -379,7 +380,8 @@ int usb_sg_init (
         */
        dma = (dev->dev.dma_mask != NULL);
        if (dma)
-               io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
+               io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe),
+                               sg, nents);
        else
                io->entries = nents;
 
@@ -1013,8 +1015,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
                ep = dev->ep_in[epnum];
                dev->ep_in[epnum] = NULL;
        }
-       if (ep && dev->bus)
-               usb_hcd_endpoint_disable(dev, ep);
+       if (ep) {
+               ep->enabled = 0;
+               usb_hcd_flush_endpoint(dev, ep);
+               usb_hcd_disable_endpoint(dev, ep);
+       }
 }
 
 /**
@@ -1096,23 +1101,21 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
  * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
  * For control endpoints, both the input and output sides are handled.
  */
-static void
-usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
+void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
 {
-       unsigned int epaddr = ep->desc.bEndpointAddress;
-       unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
-       int is_control;
+       int epnum = usb_endpoint_num(&ep->desc);
+       int is_out = usb_endpoint_dir_out(&ep->desc);
+       int is_control = usb_endpoint_xfer_control(&ep->desc);
 
-       is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                       == USB_ENDPOINT_XFER_CONTROL);
-       if (usb_endpoint_out(epaddr) || is_control) {
+       if (is_out || is_control) {
                usb_settoggle(dev, epnum, 1, 0);
                dev->ep_out[epnum] = ep;
        }
-       if (!usb_endpoint_out(epaddr) || is_control) {
+       if (!is_out || is_control) {
                usb_settoggle(dev, epnum, 0, 0);
                dev->ep_in[epnum] = ep;
        }
+       ep->enabled = 1;
 }
 
 /*
@@ -1171,6 +1174,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
        struct usb_host_interface *alt;
        int ret;
        int manual = 0;
+       int changed;
 
        if (dev->state == USB_STATE_SUSPENDED)
                return -EHOSTUNREACH;
@@ -1210,7 +1214,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
         */
 
        /* prevent submissions using previous endpoint settings */
-       if (device_is_registered(&iface->dev))
+       changed = (iface->cur_altsetting != alt);
+       if (changed && device_is_registered(&iface->dev))
                usb_remove_sysfs_intf_files(iface);
        usb_disable_interface(dev, iface);
 
@@ -1247,7 +1252,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
         * (Likewise, EP0 never "halts" on well designed devices.)
         */
        usb_enable_interface(dev, iface);
-       if (device_is_registered(&iface->dev))
+       if (changed && device_is_registered(&iface->dev))
                usb_create_sysfs_intf_files(iface);
 
        return 0;
@@ -1328,7 +1333,7 @@ int usb_reset_configuration(struct usb_device *dev)
        return 0;
 }
 
-void usb_release_interface(struct device *dev)
+static void usb_release_interface(struct device *dev)
 {
        struct usb_interface *intf = to_usb_interface(dev);
        struct usb_interface_cache *intfc =
@@ -1467,6 +1472,9 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
  * channels are available independently; and choosing between open
  * standard device protocols (like CDC) or proprietary ones.
  *
+ * Note that a non-authorized device (dev->authorized == 0) will only
+ * be put in unconfigured mode.
+ *
  * Note that USB has an additional level of device configurability,
  * associated with interfaces.  That configurability is accessed using
  * usb_set_interface().
@@ -1488,7 +1496,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
        struct usb_interface **new_interfaces = NULL;
        int n, nintf;
 
-       if (configuration == -1)
+       if (dev->authorized == 0 || configuration == -1)
                configuration = 0;
        else {
                for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {