include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / usb / host / whci / qset.c
index 0828086..141d049 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 #include <linux/uwb/umc.h>
 #include <linux/usb.h>
 
@@ -49,11 +50,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 +71,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 +106,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 +168,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;
 }
@@ -447,16 +466,16 @@ 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;
                                std = qset_new_std(whc, qset, urb, mem_flags);
                                if (std == NULL) {
@@ -469,14 +488,14 @@ 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;
                        }
 
                        std->len += dma_len;