]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/usb/host/whci/qset.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[mv-sheeva.git] / drivers / usb / host / whci / qset.c
index 88e51ea8620bb7a350ffccadd1e955aef62966db..7d4204db0f61c7ce18bb9e897700b22335094139 100644 (file)
@@ -49,11 +49,13 @@ struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags)
  *        state
  * @urb:  an urb for a transfer to this endpoint
  */
-static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
+static void qset_fill_qh(struct whc *whc, struct whc_qset *qset, struct urb *urb)
 {
        struct usb_device *usb_dev = urb->dev;
+       struct wusb_dev *wusb_dev = usb_dev->wusb_dev;
        struct usb_wireless_ep_comp_descriptor *epcd;
        bool is_out;
+       uint8_t phy_rate;
 
        is_out = usb_pipeout(urb->pipe);
 
@@ -68,6 +70,22 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
                qset->max_burst = 1;
        }
 
+       /*
+        * Initial PHY rate is 53.3 Mbit/s for control endpoints or
+        * the maximum supported by the device for other endpoints
+        * (unless limited by the user).
+        */
+       if (usb_pipecontrol(urb->pipe))
+               phy_rate = UWB_PHY_RATE_53;
+       else {
+               uint16_t phy_rates;
+
+               phy_rates = le16_to_cpu(wusb_dev->wusb_cap_descr->wPHYRates);
+               phy_rate = fls(phy_rates) - 1;
+               if (phy_rate > whc->wusbhc.phy_rate)
+                       phy_rate = whc->wusbhc.phy_rate;
+       }
+
        qset->qh.info1 = cpu_to_le32(
                QH_INFO1_EP(usb_pipeendpoint(urb->pipe))
                | (is_out ? QH_INFO1_DIR_OUT : QH_INFO1_DIR_IN)
@@ -87,7 +105,7 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb)
         * strength and can presumably guess the Tx power required
         * from that? */
        qset->qh.info3 = cpu_to_le32(
-               QH_INFO3_TX_RATE_53_3
+               QH_INFO3_TX_RATE(phy_rate)
                | QH_INFO3_TX_PWR(0) /* 0 == max power */
                );
 
@@ -149,7 +167,7 @@ struct whc_qset *get_qset(struct whc *whc, struct urb *urb,
 
                qset->ep = urb->ep;
                urb->ep->hcpriv = qset;
-               qset_fill_qh(qset, urb);
+               qset_fill_qh(whc, qset, urb);
        }
        return qset;
 }
@@ -422,8 +440,6 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
        size_t pl_len;
        int p = 0;
 
-       dev_dbg(&whc->umc->dev, "adding urb w/ sg of length %d\n", urb->transfer_buffer_length);
-
        remaining = urb->transfer_buffer_length;
 
        for_each_sg(urb->sg->sg, sg, urb->num_sgs, i) {
@@ -437,10 +453,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                }
 
                dma_addr = sg_dma_address(sg);
-               dma_remaining = min(sg_dma_len(sg), remaining);
-
-               dev_dbg(&whc->umc->dev, "adding sg[%d] %08x %d\n", i, (unsigned)dma_addr,
-                       dma_remaining);
+               dma_remaining = min_t(size_t, sg_dma_len(sg), remaining);
 
                while (dma_remaining) {
                        size_t dma_len;
@@ -452,18 +465,17 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                         * - the previous one isn't full.
                         *
                         * If a new std is needed but the previous one
-                        * did not end on a wMaxPacketSize boundary
-                        * then this sg list cannot be mapped onto
-                        * multiple qTDs.  Return an error and let the
-                        * caller sort it out.
+                        * was not a whole number of packets then this
+                        * sg list cannot be mapped onto multiple
+                        * qTDs.  Return an error and let the caller
+                        * sort it out.
                         */
                        if (!std
                            || (prev_end & (WHCI_PAGE_SIZE-1))
                            || (dma_addr & (WHCI_PAGE_SIZE-1))
                            || std->len + WHCI_PAGE_SIZE > QTD_MAX_XFER_SIZE) {
-                               if (prev_end % qset->max_packet != 0)
+                               if (std->len % qset->max_packet != 0)
                                        return -EINVAL;
-                               dev_dbg(&whc->umc->dev, "need new std\n");
                                std = qset_new_std(whc, qset, urb, mem_flags);
                                if (std == NULL) {
                                        return -ENOMEM;
@@ -475,18 +487,16 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                        dma_len = dma_remaining;
 
                        /*
-                        * If the remainder in this element doesn't
-                        * fit in a single qTD, end the qTD on a
-                        * wMaxPacketSize boundary.
+                        * If the remainder of this element doesn't
+                        * fit in a single qTD, limit the qTD to a
+                        * whole number of packets.  This allows the
+                        * remainder to go into the next qTD.
                         */
                        if (std->len + dma_len > QTD_MAX_XFER_SIZE) {
-                               dma_len = QTD_MAX_XFER_SIZE - std->len;
-                               ep = ((dma_addr + dma_len) / qset->max_packet) * qset->max_packet;
-                               dma_len = ep - dma_addr;
+                               dma_len = (QTD_MAX_XFER_SIZE / qset->max_packet)
+                                       * qset->max_packet - std->len;
                        }
 
-                       dev_dbg(&whc->umc->dev, "adding %d\n", dma_len);
-
                        std->len += dma_len;
                        std->ntds_remaining = -1; /* filled in later */
 
@@ -495,9 +505,6 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                        num_pointers = DIV_ROUND_UP(ep - sp, WHCI_PAGE_SIZE);
                        std->num_pointers += num_pointers;
 
-                       dev_dbg(&whc->umc->dev, "need %d more (%d total) page pointers\n",
-                               num_pointers, std->num_pointers);
-
                        pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
 
                        std->pl_virt = krealloc(std->pl_virt, pl_len, mem_flags);
@@ -506,7 +513,6 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                        }
 
                        for (;p < std->num_pointers; p++, entry++) {
-                               dev_dbg(&whc->umc->dev, "e[%d] %08x\n", p, dma_addr);
                                std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
                                dma_addr = (dma_addr + WHCI_PAGE_SIZE) & ~(WHCI_PAGE_SIZE-1);
                        }
@@ -517,8 +523,6 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
                }
        }
 
-       dev_dbg(&whc->umc->dev, "used %d tds\n", ntds);
-
        /* Now the number of stds is know, go back and fill in
           std->ntds_remaining. */
        list_for_each_entry(std, &qset->stds, list_node) {
@@ -565,14 +569,11 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
                        break;
                }
 
-               sg_remaining = min(remaining, sg->length);
+               sg_remaining = min_t(size_t, remaining, sg->length);
                orig = sg_virt(sg);
 
-               dev_dbg(&whc->umc->dev, "adding sg[%d] %d\n", i, sg_remaining);
-
                while (sg_remaining) {
                        if (!std || std->len == max_std_len) {
-                               dev_dbg(&whc->umc->dev, "need new std\n");
                                std = qset_new_std(whc, qset, urb, mem_flags);
                                if (std == NULL)
                                        return -ENOMEM;
@@ -587,9 +588,6 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
 
                        len = min(sg_remaining, max_std_len - std->len);
 
-                       dev_dbg(&whc->umc->dev, "added %d from sg[%d] @ offset %d\n",
-                               len, i, orig - sg_virt(sg));
-
                        if (is_out)
                                memcpy(bounce, orig, len);
 
@@ -650,8 +648,6 @@ int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb,
        if (urb->sg) {
                ret = qset_add_urb_sg(whc, qset, urb, mem_flags);
                if (ret == -EINVAL) {
-                       dev_dbg(&whc->umc->dev, "linearizing %d octet urb\n",
-                               urb->transfer_buffer_length);
                        qset_free_stds(qset, urb);
                        ret = qset_add_urb_sg_linearize(whc, qset, urb, mem_flags);
                }