usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL
[pandora-kernel.git] / drivers / usb / host / xhci-mem.c
index 0e4b25f..1e3912b 100644 (file)
@@ -178,8 +178,15 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
                struct xhci_segment     *next;
 
                next = xhci_segment_alloc(xhci, flags);
-               if (!next)
+               if (!next) {
+                       prev = ring->first_seg;
+                       while (prev) {
+                               next = prev->next;
+                               xhci_segment_free(xhci, prev);
+                               prev = next;
+                       }
                        goto fail;
+               }
                xhci_link_segments(xhci, prev, next, link_trbs, isoc);
 
                prev = next;
@@ -199,7 +206,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
        return ring;
 
 fail:
-       xhci_ring_free(xhci, ring);
+       kfree(ring);
        return NULL;
 }
 
@@ -264,6 +271,10 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci
                ctx->size += CTX_SIZE(xhci->hcc_params);
 
        ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma);
+       if (!ctx->bytes) {
+               kfree(ctx);
+               return NULL;
+       }
        memset(ctx->bytes, 0, ctx->size);
        return ctx;
 }
@@ -693,10 +704,9 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
                struct xhci_virt_device *virt_dev,
                int slot_id)
 {
-       struct list_head *tt;
        struct list_head *tt_list_head;
-       struct list_head *tt_next;
-       struct xhci_tt_bw_info *tt_info;
+       struct xhci_tt_bw_info *tt_info, *next;
+       bool slot_found = false;
 
        /* If the device never made it past the Set Address stage,
         * it may not have the real_port set correctly.
@@ -708,34 +718,16 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
        }
 
        tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts);
-       if (list_empty(tt_list_head))
-               return;
-
-       list_for_each(tt, tt_list_head) {
-               tt_info = list_entry(tt, struct xhci_tt_bw_info, tt_list);
-               if (tt_info->slot_id == slot_id)
+       list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
+               /* Multi-TT hubs will have more than one entry */
+               if (tt_info->slot_id == slot_id) {
+                       slot_found = true;
+                       list_del(&tt_info->tt_list);
+                       kfree(tt_info);
+               } else if (slot_found) {
                        break;
+               }
        }
-       /* Cautionary measure in case the hub was disconnected before we
-        * stored the TT information.
-        */
-       if (tt_info->slot_id != slot_id)
-               return;
-
-       tt_next = tt->next;
-       tt_info = list_entry(tt, struct xhci_tt_bw_info,
-                       tt_list);
-       /* Multi-TT hubs will have more than one entry */
-       do {
-               list_del(tt);
-               kfree(tt_info);
-               tt = tt_next;
-               if (list_empty(tt_list_head))
-                       break;
-               tt_next = tt->next;
-               tt_info = list_entry(tt, struct xhci_tt_bw_info,
-                               tt_list);
-       } while (tt_info->slot_id == slot_id);
 }
 
 int xhci_alloc_tt_info(struct xhci_hcd *xhci,
@@ -1140,26 +1132,44 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
 }
 
 /*
- * Convert bInterval expressed in frames (in 1-255 range) to exponent of
+ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
  * microframes, rounded down to nearest power of 2.
  */
-static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
-               struct usb_host_endpoint *ep)
+static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
+               struct usb_host_endpoint *ep, unsigned int desc_interval,
+               unsigned int min_exponent, unsigned int max_exponent)
 {
        unsigned int interval;
 
-       interval = fls(8 * ep->desc.bInterval) - 1;
-       interval = clamp_val(interval, 3, 10);
-       if ((1 << interval) != 8 * ep->desc.bInterval)
+       interval = fls(desc_interval) - 1;
+       interval = clamp_val(interval, min_exponent, max_exponent);
+       if ((1 << interval) != desc_interval)
                dev_warn(&udev->dev,
                         "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
                         ep->desc.bEndpointAddress,
                         1 << interval,
-                        8 * ep->desc.bInterval);
+                        desc_interval);
 
        return interval;
 }
 
+static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       if (ep->desc.bInterval == 0)
+               return 0;
+       return xhci_microframes_to_exponent(udev, ep,
+                       ep->desc.bInterval, 0, 15);
+}
+
+
+static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       return xhci_microframes_to_exponent(udev, ep,
+                       ep->desc.bInterval * 8, 3, 10);
+}
+
 /* Return the polling or NAK interval.
  *
  * The polling interval is expressed in "microframes".  If xHCI's Interval field
@@ -1178,7 +1188,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
                /* Max NAK rate */
                if (usb_endpoint_xfer_control(&ep->desc) ||
                    usb_endpoint_xfer_bulk(&ep->desc)) {
-                       interval = ep->desc.bInterval;
+                       interval = xhci_parse_microframe_interval(udev, ep);
                        break;
                }
                /* Fall through - SS and HS isoc/int have same decoding */
@@ -1320,10 +1330,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                /* Attempt to use the ring cache */
                if (virt_dev->num_rings_cached == 0)
                        return -ENOMEM;
+               virt_dev->num_rings_cached--;
                virt_dev->eps[ep_index].new_ring =
                        virt_dev->ring_cache[virt_dev->num_rings_cached];
                virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
-               virt_dev->num_rings_cached--;
                xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
                        usb_endpoint_xfer_isoc(&ep->desc) ? true : false);
        }
@@ -1347,15 +1357,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep));
 
        /* Set the max packet size and max burst */
+       max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
+       max_burst = 0;
        switch (udev->speed) {
        case USB_SPEED_SUPER:
-               max_packet = usb_endpoint_maxp(&ep->desc);
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                /* dig out max burst from ep companion desc */
-               max_packet = ep->ss_ep_comp.bMaxBurst;
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
+               max_burst = ep->ss_ep_comp.bMaxBurst;
                break;
        case USB_SPEED_HIGH:
+               /* Some devices get this wrong */
+               if (usb_endpoint_xfer_bulk(&ep->desc))
+                       max_packet = 512;
                /* bits 11:12 specify the number of additional transaction
                 * opportunities per microframe (USB 2.0, section 9.6.6)
                 */
@@ -1363,17 +1375,16 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                                usb_endpoint_xfer_int(&ep->desc)) {
                        max_burst = (usb_endpoint_maxp(&ep->desc)
                                     & 0x1800) >> 11;
-                       ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst));
                }
-               /* Fall through */
+               break;
        case USB_SPEED_FULL:
        case USB_SPEED_LOW:
-               max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
-               ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
                break;
        default:
                BUG();
        }
+       ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
+                       MAX_BURST(max_burst));
        max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
        ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
 
@@ -1392,10 +1403,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
         * use Event Data TRBs, and we don't chain in a link TRB on short
         * transfers, we're basically dividing by 1.
         *
-        * xHCI 1.0 specification indicates that the Average TRB Length should
-        * be set to 8 for control endpoints.
+        * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length
+        * should be set to 8 for control endpoints.
         */
-       if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version == 0x100)
+       if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
                ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8));
        else
                ep_ctx->tx_info |=
@@ -1683,16 +1694,12 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 {
        struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
        struct dev_info *dev_info, *next;
+       struct xhci_cd  *cur_cd, *next_cd;
        unsigned long   flags;
        int size;
-       int i;
+       int i, j, num_ports;
 
        /* Free the Event Ring Segment Table and the actual Event Ring */
-       if (xhci->ir_set) {
-               xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
-               xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
-               xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
-       }
        size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
        if (xhci->erst.entries)
                dma_free_coherent(&pdev->dev, size,
@@ -1704,11 +1711,26 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->event_ring = NULL;
        xhci_dbg(xhci, "Freed event ring\n");
 
-       xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
+       xhci->cmd_ring_reserved_trbs = 0;
        if (xhci->cmd_ring)
                xhci_ring_free(xhci, xhci->cmd_ring);
        xhci->cmd_ring = NULL;
        xhci_dbg(xhci, "Freed command ring\n");
+       list_for_each_entry_safe(cur_cd, next_cd,
+                       &xhci->cancel_cmd_list, cancel_cmd_list) {
+               list_del(&cur_cd->cancel_cmd_list);
+               kfree(cur_cd);
+       }
+
+       num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+       for (i = 0; i < num_ports && xhci->rh_bw; i++) {
+               struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
+               for (j = 0; j < XHCI_MAX_INTERVAL; j++) {
+                       struct list_head *ep = &bwt->interval_bw[j].endpoints;
+                       while (!list_empty(ep))
+                               list_del_init(ep->next);
+               }
+       }
 
        for (i = 1; i < MAX_HC_SLOTS; ++i)
                xhci_free_virt_device(xhci, i);
@@ -1733,7 +1755,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->medium_streams_pool = NULL;
        xhci_dbg(xhci, "Freed medium stream array pool\n");
 
-       xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
        if (xhci->dcbaa)
                dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
                                xhci->dcbaa, xhci->dcbaa->dma);
@@ -1748,13 +1769,31 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        }
        spin_unlock_irqrestore(&xhci->lock, flags);
 
+       if (!xhci->rh_bw)
+               goto no_bw;
+
+       for (i = 0; i < num_ports; i++) {
+               struct xhci_tt_bw_info *tt, *n;
+               list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) {
+                       list_del(&tt->tt_list);
+                       kfree(tt);
+               }
+       }
+
+no_bw:
        xhci->num_usb2_ports = 0;
        xhci->num_usb3_ports = 0;
+       xhci->num_active_eps = 0;
        kfree(xhci->usb2_ports);
        kfree(xhci->usb3_ports);
        kfree(xhci->port_array);
        kfree(xhci->rh_bw);
 
+       xhci->usb2_ports = NULL;
+       xhci->usb3_ports = NULL;
+       xhci->port_array = NULL;
+       xhci->rh_bw = NULL;
+
        xhci->page_size = 0;
        xhci->page_shift = 0;
        xhci->bus_state[0].bus_suspended = 0;
@@ -2158,6 +2197,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        u32 page_size;
        int i;
 
+       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
+
        page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
        xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
        for (i = 0; i < 16; i++) {
@@ -2192,7 +2234,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
         * "physically contiguous and 64-byte (cache line) aligned".
         */
        xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma,
-                       GFP_KERNEL);
+                       flags);
        if (!xhci->dcbaa)
                goto fail;
        memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
@@ -2273,7 +2315,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
        xhci->erst.entries = dma_alloc_coherent(dev,
                        sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS, &dma,
-                       GFP_KERNEL);
+                       flags);
        if (!xhci->erst.entries)
                goto fail;
        xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n",
@@ -2336,12 +2378,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
        if (xhci_setup_port_arrays(xhci, flags))
                goto fail;
 
-       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
-
        return 0;
 
 fail:
        xhci_warn(xhci, "Couldn't initialize memory\n");
+       xhci_halt(xhci);
+       xhci_reset(xhci);
        xhci_mem_cleanup(xhci);
        return -ENOMEM;
 }