Merge branch 'pm-sleep'
[cascardo/linux.git] / drivers / ntb / ntb_transport.c
index 2ef9d91..d5c5894 100644 (file)
@@ -153,6 +153,7 @@ struct ntb_transport_qp {
        unsigned int rx_index;
        unsigned int rx_max_entry;
        unsigned int rx_max_frame;
+       unsigned int rx_alloc_entry;
        dma_cookie_t last_cookie;
        struct tasklet_struct rxc_db_work;
 
@@ -480,7 +481,9 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count,
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "rx_index - \t%u\n", qp->rx_index);
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
-                              "rx_max_entry - \t%u\n\n", qp->rx_max_entry);
+                              "rx_max_entry - \t%u\n", qp->rx_max_entry);
+       out_offset += snprintf(buf + out_offset, out_count - out_offset,
+                              "rx_alloc_entry - \t%u\n\n", qp->rx_alloc_entry);
 
        out_offset += snprintf(buf + out_offset, out_count - out_offset,
                               "tx_bytes - \t%llu\n", qp->tx_bytes);
@@ -597,9 +600,12 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
 {
        struct ntb_transport_qp *qp = &nt->qp_vec[qp_num];
        struct ntb_transport_mw *mw;
+       struct ntb_dev *ndev = nt->ndev;
+       struct ntb_queue_entry *entry;
        unsigned int rx_size, num_qps_mw;
        unsigned int mw_num, mw_count, qp_count;
        unsigned int i;
+       int node;
 
        mw_count = nt->mw_count;
        qp_count = nt->qp_count;
@@ -626,6 +632,23 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
        qp->rx_max_entry = rx_size / qp->rx_max_frame;
        qp->rx_index = 0;
 
+       /*
+        * Checking to see if we have more entries than the default.
+        * We should add additional entries if that is the case so we
+        * can be in sync with the transport frames.
+        */
+       node = dev_to_node(&ndev->dev);
+       for (i = qp->rx_alloc_entry; i < qp->rx_max_entry; i++) {
+               entry = kzalloc_node(sizeof(*entry), GFP_ATOMIC, node);
+               if (!entry)
+                       return -ENOMEM;
+
+               entry->qp = qp;
+               ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry,
+                            &qp->rx_free_q);
+               qp->rx_alloc_entry++;
+       }
+
        qp->remote_rx_info->entry = qp->rx_max_entry - 1;
 
        /* setup the hdr offsets with 0's */
@@ -1037,6 +1060,13 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
        int node;
        int rc, i;
 
+       mw_count = ntb_mw_count(ndev);
+       if (ntb_spad_count(ndev) < (NUM_MWS + 1 + mw_count * 2)) {
+               dev_err(&ndev->dev, "Not enough scratch pad registers for %s",
+                       NTB_TRANSPORT_NAME);
+               return -EIO;
+       }
+
        if (ntb_db_is_unsafe(ndev))
                dev_dbg(&ndev->dev,
                        "doorbell is unsafe, proceed anyway...\n");
@@ -1052,8 +1082,6 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 
        nt->ndev = ndev;
 
-       mw_count = ntb_mw_count(ndev);
-
        nt->mw_count = mw_count;
 
        nt->mw_vec = kzalloc_node(mw_count * sizeof(*nt->mw_vec),
@@ -1722,8 +1750,9 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
                ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry,
                             &qp->rx_free_q);
        }
+       qp->rx_alloc_entry = NTB_QP_DEF_NUM_ENTRIES;
 
-       for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
+       for (i = 0; i < qp->tx_max_entry; i++) {
                entry = kzalloc_node(sizeof(*entry), GFP_ATOMIC, node);
                if (!entry)
                        goto err2;
@@ -1744,6 +1773,7 @@ err2:
        while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
                kfree(entry);
 err1:
+       qp->rx_alloc_entry = 0;
        while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
                kfree(entry);
        if (qp->tx_dma_chan)