USB: fix comments of 2 functions in hcd.c
[firefly-linux-kernel-4.4.55.git] / drivers / usb / core / hcd.c
index 22a098b318c00198210fb18dd9adc601c37599e6..f936de75f44e7fc015fd7afad26ddf43e15e9b17 100644 (file)
 #include <linux/utsname.h>
 #include <linux/mm.h>
 #include <asm/io.h>
-#include <asm/scatterlist.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/mutex.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
 
@@ -132,8 +132,8 @@ static const u8 usb2_rh_dev_descriptor [18] = {
        0x01,       /*  __u8  bDeviceProtocol; [ usb 2.0 single TT ]*/
        0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
-       0x00, 0x00, /*  __le16 idVendor; */
-       0x00, 0x00, /*  __le16 idProduct; */
+       0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+       0x02, 0x00, /*  __le16 idProduct; device 0x0002 */
        KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
        0x03,       /*  __u8  iManufacturer; */
@@ -155,8 +155,8 @@ static const u8 usb11_rh_dev_descriptor [18] = {
        0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
        0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
-       0x00, 0x00, /*  __le16 idVendor; */
-       0x00, 0x00, /*  __le16 idProduct; */
+       0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+       0x01, 0x00, /*  __le16 idProduct; device 0x0001 */
        KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
        0x03,       /*  __u8  iManufacturer; */
@@ -291,7 +291,6 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
  * rh_string - provides manufacturer, product and serial strings for root hub
  * @id: the string ID number (1: serial number, 2: product, 3: vendor)
  * @hcd: the host controller for this root hub
- * @type: string describing our driver 
  * @data: return packet in UTF-16 LE
  * @len: length of the return packet
  *
@@ -532,8 +531,6 @@ error:
 
        /* any errors get returned through the urb completion */
        spin_lock_irq(&hcd_root_hub_lock);
-       if (urb->status == -EINPROGRESS)
-               urb->status = status;
        usb_hcd_unlink_urb_from_ep(hcd, urb);
 
        /* This peculiar use of spinlocks echoes what real HC drivers do.
@@ -541,7 +538,7 @@ error:
         * RT-friendly.
         */
        spin_unlock(&hcd_root_hub_lock);
-       usb_hcd_giveback_urb(hcd, urb);
+       usb_hcd_giveback_urb(hcd, urb, status);
        spin_lock(&hcd_root_hub_lock);
 
        spin_unlock_irq(&hcd_root_hub_lock);
@@ -579,13 +576,12 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
                if (urb) {
                        hcd->poll_pending = 0;
                        hcd->status_urb = NULL;
-                       urb->status = 0;
                        urb->actual_length = length;
                        memcpy(urb->transfer_buffer, buffer, length);
 
                        usb_hcd_unlink_urb_from_ep(hcd, urb);
                        spin_unlock(&hcd_root_hub_lock);
-                       usb_hcd_giveback_urb(hcd, urb);
+                       usb_hcd_giveback_urb(hcd, urb, 0);
                        spin_lock(&hcd_root_hub_lock);
                } else {
                        length = 0;
@@ -678,7 +674,7 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                        usb_hcd_unlink_urb_from_ep(hcd, urb);
 
                        spin_unlock(&hcd_root_hub_lock);
-                       usb_hcd_giveback_urb(hcd, urb);
+                       usb_hcd_giveback_urb(hcd, urb, status);
                        spin_lock(&hcd_root_hub_lock);
                }
        }
@@ -811,13 +807,13 @@ static int usb_register_bus(struct usb_bus *bus)
        }
        set_bit (busnum, busmap.busmap);
        bus->busnum = busnum;
-       bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0),
-                                            bus->controller, "usb_host%d",
-                                            busnum);
-       result = PTR_ERR(bus->class_dev);
-       if (IS_ERR(bus->class_dev))
+
+       bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0),
+                                "usb_host%d", busnum);
+       result = PTR_ERR(bus->dev);
+       if (IS_ERR(bus->dev))
                goto error_create_class_dev;
-       class_set_devdata(bus->class_dev, bus);
+       dev_set_drvdata(bus->dev, bus);
 
        /* Add it to the local list of buses */
        list_add (&bus->bus_list, &usb_bus_list);
@@ -861,7 +857,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
 
        clear_bit (bus->busnum, busmap.busmap);
 
-       class_device_unregister(bus->class_dev);
+       device_unregister(bus->dev);
 }
 
 /**
@@ -974,7 +970,7 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
                return -1;
        }
 }
-EXPORT_SYMBOL (usb_calc_bus_time);
+EXPORT_SYMBOL_GPL(usb_calc_bus_time);
 
 
 /*-------------------------------------------------------------------------*/
@@ -1017,6 +1013,11 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)
                goto done;
        }
 
+       if (unlikely(!urb->dev->can_submit)) {
+               rc = -EHOSTUNREACH;
+               goto done;
+       }
+
        /*
         * Check the host controller's state and add the URB to the
         * endpoint's queue.
@@ -1024,6 +1025,7 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)
        switch (hcd->state) {
        case HC_STATE_RUNNING:
        case HC_STATE_RESUMING:
+               urb->unlinked = 0;
                list_add_tail(&urb->urb_list, &urb->ep->urb_list);
                break;
        default:
@@ -1071,9 +1073,9 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
        /* Any status except -EINPROGRESS means something already started to
         * unlink this URB from the hardware.  So there's no more work to do.
         */
-       if (urb->status != -EINPROGRESS)
+       if (urb->unlinked)
                return -EBUSY;
-       urb->status = status;
+       urb->unlinked = status;
 
        /* IRQ setup can easily be broken so that USB controllers
         * never get completion IRQs ... maybe even the ones we need to
@@ -1110,48 +1112,177 @@ void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep);
 
-static void map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+/*
+ * Some usb host controllers can only perform dma using a small SRAM area.
+ * The usb core itself is however optimized for host controllers that can dma
+ * using regular system memory - like pci devices doing bus mastering.
+ *
+ * To support host controllers with limited dma capabilites we provide dma
+ * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag.
+ * For this to work properly the host controller code must first use the
+ * function dma_declare_coherent_memory() to point out which memory area
+ * that should be used for dma allocations.
+ *
+ * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for
+ * dma using dma_alloc_coherent() which in turn allocates from the memory
+ * area pointed out with dma_declare_coherent_memory().
+ *
+ * So, to summarize...
+ *
+ * - We need "local" memory, canonical example being
+ *   a small SRAM on a discrete controller being the
+ *   only memory that the controller can read ...
+ *   (a) "normal" kernel memory is no good, and
+ *   (b) there's not enough to share
+ *
+ * - The only *portable* hook for such stuff in the
+ *   DMA framework is dma_declare_coherent_memory()
+ *
+ * - So we use that, even though the primary requirement
+ *   is that the memory be "local" (hence addressible
+ *   by that device), not "coherent".
+ *
+ */
+
+static int hcd_alloc_coherent(struct usb_bus *bus,
+                             gfp_t mem_flags, dma_addr_t *dma_handle,
+                             void **vaddr_handle, size_t size,
+                             enum dma_data_direction dir)
 {
+       unsigned char *vaddr;
+
+       vaddr = hcd_buffer_alloc(bus, size + sizeof(vaddr),
+                                mem_flags, dma_handle);
+       if (!vaddr)
+               return -ENOMEM;
+
+       /*
+        * Store the virtual address of the buffer at the end
+        * of the allocated dma buffer. The size of the buffer
+        * may be uneven so use unaligned functions instead
+        * of just rounding up. It makes sense to optimize for
+        * memory footprint over access speed since the amount
+        * of memory available for dma may be limited.
+        */
+       put_unaligned((unsigned long)*vaddr_handle,
+                     (unsigned long *)(vaddr + size));
+
+       if (dir == DMA_TO_DEVICE)
+               memcpy(vaddr, *vaddr_handle, size);
+
+       *vaddr_handle = vaddr;
+       return 0;
+}
+
+static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
+                             void **vaddr_handle, size_t size,
+                             enum dma_data_direction dir)
+{
+       unsigned char *vaddr = *vaddr_handle;
+
+       vaddr = (void *)get_unaligned((unsigned long *)(vaddr + size));
+
+       if (dir == DMA_FROM_DEVICE)
+               memcpy(vaddr, *vaddr_handle, size);
+
+       hcd_buffer_free(bus, size + sizeof(vaddr), *vaddr_handle, *dma_handle);
+
+       *vaddr_handle = vaddr;
+       *dma_handle = 0;
+}
+
+static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+                          gfp_t mem_flags)
+{
+       enum dma_data_direction dir;
+       int ret = 0;
+
        /* Map the URB's buffers for DMA access.
         * Lower level HCD code should use *_dma exclusively,
         * unless it uses pio or talks to another transport.
         */
-       if (hcd->self.uses_dma && !is_root_hub(urb->dev)) {
-               if (usb_endpoint_xfer_control(&urb->ep->desc)
-                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
-                       urb->setup_dma = dma_map_single (
+       if (is_root_hub(urb->dev))
+               return 0;
+
+       if (usb_endpoint_xfer_control(&urb->ep->desc)
+           && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+               if (hcd->self.uses_dma)
+                       urb->setup_dma = dma_map_single(
                                        hcd->self.controller,
                                        urb->setup_packet,
-                                       sizeof (struct usb_ctrlrequest),
+                                       sizeof(struct usb_ctrlrequest),
                                        DMA_TO_DEVICE);
-               if (urb->transfer_buffer_length != 0
-                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+               else if (hcd->driver->flags & HCD_LOCAL_MEM)
+                       ret = hcd_alloc_coherent(
+                                       urb->dev->bus, mem_flags,
+                                       &urb->setup_dma,
+                                       (void **)&urb->setup_packet,
+                                       sizeof(struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+       }
+
+       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+       if (ret == 0 && urb->transfer_buffer_length != 0
+           && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+               if (hcd->self.uses_dma)
                        urb->transfer_dma = dma_map_single (
                                        hcd->self.controller,
                                        urb->transfer_buffer,
                                        urb->transfer_buffer_length,
-                                       usb_urb_dir_in(urb)
-                                           ? DMA_FROM_DEVICE
-                                           : DMA_TO_DEVICE);
+                                       dir);
+               else if (hcd->driver->flags & HCD_LOCAL_MEM) {
+                       ret = hcd_alloc_coherent(
+                                       urb->dev->bus, mem_flags,
+                                       &urb->transfer_dma,
+                                       &urb->transfer_buffer,
+                                       urb->transfer_buffer_length,
+                                       dir);
+
+                       if (ret && usb_endpoint_xfer_control(&urb->ep->desc)
+                           && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+                               hcd_free_coherent(urb->dev->bus,
+                                       &urb->setup_dma,
+                                       (void **)&urb->setup_packet,
+                                       sizeof(struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+               }
        }
+       return ret;
 }
 
 static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
-       if (hcd->self.uses_dma && !is_root_hub(urb->dev)) {
-               if (usb_endpoint_xfer_control(&urb->ep->desc)
-                       && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+       enum dma_data_direction dir;
+
+       if (is_root_hub(urb->dev))
+               return;
+
+       if (usb_endpoint_xfer_control(&urb->ep->desc)
+           && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+               if (hcd->self.uses_dma)
                        dma_unmap_single(hcd->self.controller, urb->setup_dma,
                                        sizeof(struct usb_ctrlrequest),
                                        DMA_TO_DEVICE);
-               if (urb->transfer_buffer_length != 0
-                       && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
+               else if (hcd->driver->flags & HCD_LOCAL_MEM)
+                       hcd_free_coherent(urb->dev->bus, &urb->setup_dma,
+                                       (void **)&urb->setup_packet,
+                                       sizeof(struct usb_ctrlrequest),
+                                       DMA_TO_DEVICE);
+       }
+
+       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+       if (urb->transfer_buffer_length != 0
+           && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+               if (hcd->self.uses_dma)
                        dma_unmap_single(hcd->self.controller,
                                        urb->transfer_dma,
                                        urb->transfer_buffer_length,
-                                       usb_urb_dir_in(urb)
-                                           ? DMA_FROM_DEVICE
-                                           : DMA_TO_DEVICE);
+                                       dir);
+               else if (hcd->driver->flags & HCD_LOCAL_MEM)
+                       hcd_free_coherent(urb->dev->bus, &urb->transfer_dma,
+                                       &urb->transfer_buffer,
+                                       urb->transfer_buffer_length,
+                                       dir);
        }
 }
 
@@ -1173,6 +1304,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
         */
        usb_get_urb(urb);
        atomic_inc(&urb->use_count);
+       atomic_inc(&urb->dev->urbnum);
        usbmon_urb_submit(&hcd->self, urb);
 
        /* NOTE requirements on root-hub callers (usbfs and the hub
@@ -1182,7 +1314,12 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
         * URBs must be submitted in process context with interrupts
         * enabled.
         */
-       map_urb_for_dma(hcd, urb);
+       status = map_urb_for_dma(hcd, urb, mem_flags);
+       if (unlikely(status)) {
+               usbmon_urb_submit_error(&hcd->self, urb, status);
+               goto error;
+       }
+
        if (is_root_hub(urb->dev))
                status = rh_urb_enqueue(hcd, urb);
        else
@@ -1191,9 +1328,11 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
        if (unlikely(status)) {
                usbmon_urb_submit_error(&hcd->self, urb, status);
                unmap_urb_for_dma(hcd, urb);
+ error:
                urb->hcpriv = NULL;
                INIT_LIST_HEAD(&urb->urb_list);
                atomic_dec(&urb->use_count);
+               atomic_dec(&urb->dev->urbnum);
                if (urb->reject)
                        wake_up(&usb_kill_urb_queue);
                usb_put_urb(urb);
@@ -1252,6 +1391,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
  * usb_hcd_giveback_urb - return URB from HCD to device driver
  * @hcd: host controller returning the URB
  * @urb: urb being returned to the USB device driver.
+ * @status: completion status code for the URB.
  * Context: in_interrupt()
  *
  * This hands the URB from HCD to its USB device driver, using its
@@ -1259,54 +1399,59 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
  * (and is done using urb->hcpriv).  It also released all HCD locks;
  * the device driver won't cause problems if it frees, modifies,
  * or resubmits this URB.
+ *
+ * If @urb was unlinked, the value of @status will be overridden by
+ * @urb->unlinked.  Erroneous short transfers are detected in case
+ * the HCD hasn't checked for them.
  */
-void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
+void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-       unmap_urb_for_dma(hcd, urb);
-       usbmon_urb_complete (&hcd->self, urb);
-       usb_unanchor_urb(urb);
        urb->hcpriv = NULL;
-       if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
+       if (unlikely(urb->unlinked))
+               status = urb->unlinked;
+       else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
                        urb->actual_length < urb->transfer_buffer_length &&
-                       !urb->status))
-               urb->status = -EREMOTEIO;
+                       !status))
+               status = -EREMOTEIO;
+
+       unmap_urb_for_dma(hcd, urb);
+       usbmon_urb_complete(&hcd->self, urb, status);
+       usb_unanchor_urb(urb);
 
        /* pass ownership to the completion handler */
+       urb->status = status;
        urb->complete (urb);
        atomic_dec (&urb->use_count);
        if (unlikely (urb->reject))
                wake_up (&usb_kill_urb_queue);
        usb_put_urb (urb);
 }
-EXPORT_SYMBOL (usb_hcd_giveback_urb);
+EXPORT_SYMBOL_GPL(usb_hcd_giveback_urb);
 
 /*-------------------------------------------------------------------------*/
 
-/* disables the endpoint: cancels any pending urbs, then synchronizes with
- * the hcd to make sure all endpoint state is gone from hardware, and then
- * waits until the endpoint's queue is completely drained. use for
- * set_configuration, set_interface, driver removal, physical disconnect.
- *
- * example:  a qh stored in ep->hcpriv, holding state related to endpoint
- * type, maxpacket size, toggle, halt status, and scheduling.
+/* Cancel all URBs pending on this endpoint and wait for the endpoint's
+ * queue to drain completely.  The caller must first insure that no more
+ * URBs can be submitted for this endpoint.
  */
-void usb_hcd_endpoint_disable (struct usb_device *udev,
+void usb_hcd_flush_endpoint(struct usb_device *udev,
                struct usb_host_endpoint *ep)
 {
        struct usb_hcd          *hcd;
        struct urb              *urb;
 
+       if (!ep)
+               return;
        might_sleep();
        hcd = bus_to_hcd(udev->bus);
 
-       /* ep is already gone from udev->ep_{in,out}[]; no more submits */
-rescan:
+       /* No more submits can occur */
        spin_lock_irq(&hcd_urb_list_lock);
+rescan:
        list_for_each_entry (urb, &ep->urb_list, urb_list) {
                int     is_in;
 
-               /* the urb may already have been unlinked */
-               if (urb->status != -EINPROGRESS)
+               if (urb->unlinked)
                        continue;
                usb_get_urb (urb);
                is_in = usb_urb_dir_in(urb);
@@ -1335,22 +1480,12 @@ rescan:
                usb_put_urb (urb);
 
                /* list contents may have changed */
+               spin_lock(&hcd_urb_list_lock);
                goto rescan;
        }
        spin_unlock_irq(&hcd_urb_list_lock);
 
-       /* synchronize with the hardware, so old configuration state
-        * clears out immediately (and will be freed).
-        */
-       if (hcd->driver->endpoint_disable)
-               hcd->driver->endpoint_disable (hcd, ep);
-
-       /* Wait until the endpoint queue is completely empty.  Most HCDs
-        * will have done this already in their endpoint_disable method,
-        * but some might not.  And there could be root-hub control URBs
-        * still pending since they aren't affected by the HCDs'
-        * endpoint_disable methods.
-        */
+       /* Wait until the endpoint queue is completely empty */
        while (!list_empty (&ep->urb_list)) {
                spin_lock_irq(&hcd_urb_list_lock);
 
@@ -1370,6 +1505,25 @@ rescan:
        }
 }
 
+/* Disables the endpoint: synchronizes with the hcd to make sure all
+ * endpoint state is gone from hardware.  usb_hcd_flush_endpoint() must
+ * have been called previously.  Use for set_configuration, set_interface,
+ * driver removal, physical disconnect.
+ *
+ * example:  a qh stored in ep->hcpriv, holding state related to endpoint
+ * type, maxpacket size, toggle, halt status, and scheduling.
+ */
+void usb_hcd_disable_endpoint(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       struct usb_hcd          *hcd;
+
+       might_sleep();
+       hcd = bus_to_hcd(udev->bus);
+       if (hcd->driver->endpoint_disable)
+               hcd->driver->endpoint_disable(hcd, ep);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* called in any context */
@@ -1512,7 +1666,7 @@ int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num)
                mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(10));
        return status;
 }
-EXPORT_SYMBOL (usb_bus_start_enum);
+EXPORT_SYMBOL_GPL(usb_bus_start_enum);
 
 #endif
 
@@ -1522,7 +1676,6 @@ EXPORT_SYMBOL (usb_bus_start_enum);
  * usb_hcd_irq - hook IRQs to HCD framework (bus glue)
  * @irq: the IRQ being raised
  * @__hcd: pointer to the HCD whose IRQ is being signaled
- * @r: saved hardware registers
  *
  * If the controller isn't HALTed, calls the driver's irq handler.
  * Checks whether the controller is now dead.
@@ -1619,7 +1772,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
                        "USB Host Controller";
        return hcd;
 }
-EXPORT_SYMBOL (usb_create_hcd);
+EXPORT_SYMBOL_GPL(usb_create_hcd);
 
 static void hcd_release (struct kref *kref)
 {
@@ -1634,14 +1787,14 @@ struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd)
                kref_get (&hcd->kref);
        return hcd;
 }
-EXPORT_SYMBOL (usb_get_hcd);
+EXPORT_SYMBOL_GPL(usb_get_hcd);
 
 void usb_put_hcd (struct usb_hcd *hcd)
 {
        if (hcd)
                kref_put (&hcd->kref, hcd_release);
 }
-EXPORT_SYMBOL (usb_put_hcd);
+EXPORT_SYMBOL_GPL(usb_put_hcd);
 
 /**
  * usb_add_hcd - finish generic HCD structure initialization and register
@@ -1767,7 +1920,7 @@ err_register_bus:
        hcd_buffer_destroy(hcd);
        return retval;
 } 
-EXPORT_SYMBOL (usb_add_hcd);
+EXPORT_SYMBOL_GPL(usb_add_hcd);
 
 /**
  * usb_remove_hcd - shutdown processing for generic HCDs
@@ -1809,7 +1962,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
        usb_deregister_bus(&hcd->self);
        hcd_buffer_destroy(hcd);
 }
-EXPORT_SYMBOL (usb_remove_hcd);
+EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
 void
 usb_hcd_platform_shutdown(struct platform_device* dev)
@@ -1819,7 +1972,7 @@ usb_hcd_platform_shutdown(struct platform_device* dev)
        if (hcd->driver->shutdown)
                hcd->driver->shutdown(hcd);
 }
-EXPORT_SYMBOL (usb_hcd_platform_shutdown);
+EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown);
 
 /*-------------------------------------------------------------------------*/