Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[pandora-kernel.git] / drivers / usb / gadget / printer.c
index 271ef94..a341dde 100644 (file)
@@ -89,8 +89,7 @@ struct printer_dev {
        u8                      config;
        s8                      interface;
        struct usb_ep           *in_ep, *out_ep;
-       const struct usb_endpoint_descriptor
-                               *in, *out;
+
        struct list_head        rx_reqs;        /* List of free RX structs */
        struct list_head        rx_reqs_active; /* List of Active RX xfers */
        struct list_head        rx_buffers;     /* List of completed xfers */
@@ -795,12 +794,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 }
 
 static int
-printer_fsync(struct file *fd, int datasync)
+printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync)
 {
        struct printer_dev      *dev = fd->private_data;
+       struct inode *inode = fd->f_path.dentry->d_inode;
        unsigned long           flags;
        int                     tx_list_empty;
 
+       mutex_lock(&inode->i_mutex);
        spin_lock_irqsave(&dev->lock, flags);
        tx_list_empty = (likely(list_empty(&dev->tx_reqs)));
        spin_unlock_irqrestore(&dev->lock, flags);
@@ -810,6 +811,7 @@ printer_fsync(struct file *fd, int datasync)
                wait_event_interruptible(dev->tx_flush_wait,
                                (likely(list_empty(&dev->tx_reqs_active))));
        }
+       mutex_unlock(&inode->i_mutex);
 
        return 0;
 }
@@ -895,19 +897,20 @@ set_printer_interface(struct printer_dev *dev)
 {
        int                     result = 0;
 
-       dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
+       dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
        dev->in_ep->driver_data = dev;
 
-       dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc);
+       dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc,
+                                   &fs_ep_out_desc);
        dev->out_ep->driver_data = dev;
 
-       result = usb_ep_enable(dev->in_ep, dev->in);
+       result = usb_ep_enable(dev->in_ep);
        if (result != 0) {
                DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
                goto done;
        }
 
-       result = usb_ep_enable(dev->out_ep, dev->out);
+       result = usb_ep_enable(dev->out_ep);
        if (result != 0) {
                DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
                goto done;
@@ -918,8 +921,8 @@ done:
        if (result != 0) {
                (void) usb_ep_disable(dev->in_ep);
                (void) usb_ep_disable(dev->out_ep);
-               dev->in = NULL;
-               dev->out = NULL;
+               dev->in_ep->desc = NULL;
+               dev->out_ep->desc = NULL;
        }
 
        /* caller is responsible for cleanup on error */
@@ -933,12 +936,14 @@ static void printer_reset_interface(struct printer_dev *dev)
 
        DBG(dev, "%s\n", __func__);
 
-       if (dev->in)
+       if (dev->in_ep->desc)
                usb_ep_disable(dev->in_ep);
 
-       if (dev->out)
+       if (dev->out_ep->desc)
                usb_ep_disable(dev->out_ep);
 
+       dev->in_ep->desc = NULL;
+       dev->out_ep->desc = NULL;
        dev->interface = -1;
 }
 
@@ -1104,9 +1109,9 @@ static void printer_soft_reset(struct printer_dev *dev)
                list_add(&req->list, &dev->tx_reqs);
        }
 
-       if (usb_ep_enable(dev->in_ep, dev->in))
+       if (usb_ep_enable(dev->in_ep))
                DBG(dev, "Failed to enable USB in_ep\n");
-       if (usb_ep_enable(dev->out_ep, dev->out))
+       if (usb_ep_enable(dev->out_ep))
                DBG(dev, "Failed to enable USB out_ep\n");
 
        wake_up_interruptible(&dev->rx_wait);
@@ -1146,6 +1151,8 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                        switch (wValue >> 8) {
 
                        case USB_DT_DEVICE:
+                               device_desc.bMaxPacketSize0 =
+                                       gadget->ep0->maxpacket;
                                value = min(wLength, (u16) sizeof device_desc);
                                memcpy(req->buf, &device_desc, value);
                                break;
@@ -1153,6 +1160,12 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
                        case USB_DT_DEVICE_QUALIFIER:
                                if (!gadget->is_dualspeed)
                                        break;
+                               /*
+                                * assumes ep0 uses the same value for both
+                                * speeds
+                                */
+                               dev_qualifier.bMaxPacketSize0 =
+                                       gadget->ep0->maxpacket;
                                value = min(wLength,
                                                (u16) sizeof dev_qualifier);
                                memcpy(req->buf, &dev_qualifier, value);
@@ -1448,15 +1461,11 @@ autoconf_fail:
        out_ep->driver_data = out_ep;   /* claim */
 
 #ifdef CONFIG_USB_GADGET_DUALSPEED
-       /* assumes ep0 uses the same value for both speeds ... */
-       dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
-
-       /* and that all endpoints are dual-speed */
+       /* assumes that all endpoints are dual-speed */
        hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
        hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
 #endif /* DUALSPEED */
 
-       device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
        usb_gadget_set_selfpowered(gadget);
 
        if (gadget->is_otg) {