summaryrefslogtreecommitdiff
path: root/drivers/ntb
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/ntb
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/ntb')
-rw-r--r--drivers/ntb/ntb_hw.c121
-rw-r--r--drivers/ntb/ntb_hw.h7
-rw-r--r--drivers/ntb/ntb_regs.h16
-rw-r--r--drivers/ntb/ntb_transport.c163
4 files changed, 95 insertions, 212 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c
index 170e8e6..1cb6e51 100644
--- a/drivers/ntb/ntb_hw.c
+++ b/drivers/ntb/ntb_hw.c
@@ -141,24 +141,6 @@ void ntb_unregister_event_callback(struct ntb_device *ndev)
ndev->event_cb = NULL;
}
-static void ntb_irq_work(unsigned long data)
-{
- struct ntb_db_cb *db_cb = (struct ntb_db_cb *)data;
- int rc;
-
- rc = db_cb->callback(db_cb->data, db_cb->db_num);
- if (rc)
- tasklet_schedule(&db_cb->irq_work);
- else {
- struct ntb_device *ndev = db_cb->ndev;
- unsigned long mask;
-
- mask = readw(ndev->reg_ofs.ldb_mask);
- clear_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
- writew(mask, ndev->reg_ofs.ldb_mask);
- }
-}
-
/**
* ntb_register_db_callback() - register a callback for doorbell interrupt
* @ndev: pointer to ntb_device instance
@@ -173,7 +155,7 @@ static void ntb_irq_work(unsigned long data)
* RETURNS: An appropriate -ERRNO error value on error, or zero for success.
*/
int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
- void *data, int (*func)(void *data, int db_num))
+ void *data, void (*func)(void *data, int db_num))
{
unsigned long mask;
@@ -184,10 +166,6 @@ int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
ndev->db_cb[idx].callback = func;
ndev->db_cb[idx].data = data;
- ndev->db_cb[idx].ndev = ndev;
-
- tasklet_init(&ndev->db_cb[idx].irq_work, ntb_irq_work,
- (unsigned long) &ndev->db_cb[idx]);
/* unmask interrupt */
mask = readw(ndev->reg_ofs.ldb_mask);
@@ -216,8 +194,6 @@ void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx)
set_bit(idx * ndev->bits_per_vector, &mask);
writew(mask, ndev->reg_ofs.ldb_mask);
- tasklet_disable(&ndev->db_cb[idx].irq_work);
-
ndev->db_cb[idx].callback = NULL;
}
@@ -702,7 +678,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
return -EINVAL;
ndev->limits.max_mw = SNB_ERRATA_MAX_MW;
- ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->reg_ofs.spad_write = ndev->mw[1].vbase +
SNB_SPAD_OFFSET;
ndev->reg_ofs.rdb = ndev->mw[1].vbase +
@@ -713,21 +688,8 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
*/
writeq(ndev->mw[1].bar_sz + 0x1000, ndev->reg_base +
SNB_PBAR4LMT_OFFSET);
- /* HW errata on the Limit registers. They can only be
- * written when the base register is 4GB aligned and
- * < 32bit. This should already be the case based on the
- * driver defaults, but write the Limit registers first
- * just in case.
- */
} else {
ndev->limits.max_mw = SNB_MAX_MW;
-
- /* HW Errata on bit 14 of b2bdoorbell register. Writes
- * will not be mirrored to the remote system. Shrink
- * the number of bits by one, since bit 14 is the last
- * bit.
- */
- ndev->limits.max_db_bits = SNB_MAX_DB_BITS - 1;
ndev->reg_ofs.spad_write = ndev->reg_base +
SNB_B2B_SPAD_OFFSET;
ndev->reg_ofs.rdb = ndev->reg_base +
@@ -737,12 +699,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
* something silly
*/
writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET);
- /* HW errata on the Limit registers. They can only be
- * written when the base register is 4GB aligned and
- * < 32bit. This should already be the case based on the
- * driver defaults, but write the Limit registers first
- * just in case.
- */
}
/* The Xeon errata workaround requires setting SBAR Base
@@ -813,7 +769,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
* have an equal amount.
*/
ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
- ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
/* Note: The SDOORBELL is the cause of the errata. You REALLY
* don't want to touch it.
*/
@@ -838,7 +793,6 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
* have an equal amount.
*/
ndev->limits.max_spads = SNB_MAX_COMPAT_SPADS / 2;
- ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->reg_ofs.rdb = ndev->reg_base + SNB_PDOORBELL_OFFSET;
ndev->reg_ofs.ldb = ndev->reg_base + SNB_SDOORBELL_OFFSET;
ndev->reg_ofs.ldb_mask = ndev->reg_base + SNB_SDBMSK_OFFSET;
@@ -865,6 +819,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev)
ndev->reg_ofs.lnk_stat = ndev->reg_base + SNB_SLINK_STATUS_OFFSET;
ndev->reg_ofs.spci_cmd = ndev->reg_base + SNB_PCICMD_OFFSET;
+ ndev->limits.max_db_bits = SNB_MAX_DB_BITS;
ndev->limits.msix_cnt = SNB_MSIX_CNT;
ndev->bits_per_vector = SNB_DB_BITS_PER_VEC;
@@ -979,16 +934,12 @@ static irqreturn_t bwd_callback_msix_irq(int irq, void *data)
{
struct ntb_db_cb *db_cb = data;
struct ntb_device *ndev = db_cb->ndev;
- unsigned long mask;
dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
db_cb->db_num);
- mask = readw(ndev->reg_ofs.ldb_mask);
- set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
- writew(mask, ndev->reg_ofs.ldb_mask);
-
- tasklet_schedule(&db_cb->irq_work);
+ if (db_cb->callback)
+ db_cb->callback(db_cb->data, db_cb->db_num);
/* No need to check for the specific HB irq, any interrupt means
* we're connected.
@@ -1004,16 +955,12 @@ static irqreturn_t xeon_callback_msix_irq(int irq, void *data)
{
struct ntb_db_cb *db_cb = data;
struct ntb_device *ndev = db_cb->ndev;
- unsigned long mask;
dev_dbg(&ndev->pdev->dev, "MSI-X irq %d received for DB %d\n", irq,
db_cb->db_num);
- mask = readw(ndev->reg_ofs.ldb_mask);
- set_bit(db_cb->db_num * ndev->bits_per_vector, &mask);
- writew(mask, ndev->reg_ofs.ldb_mask);
-
- tasklet_schedule(&db_cb->irq_work);
+ if (db_cb->callback)
+ db_cb->callback(db_cb->data, db_cb->db_num);
/* On Sandybridge, there are 16 bits in the interrupt register
* but only 4 vectors. So, 5 bits are assigned to the first 3
@@ -1039,7 +986,7 @@ static irqreturn_t xeon_event_msix_irq(int irq, void *dev)
dev_err(&ndev->pdev->dev, "Error determining link status\n");
/* bit 15 is always the link bit */
- writew(1 << SNB_LINK_DB, ndev->reg_ofs.ldb);
+ writew(1 << ndev->limits.max_db_bits, ndev->reg_ofs.ldb);
return IRQ_HANDLED;
}
@@ -1128,10 +1075,6 @@ static int ntb_setup_msix(struct ntb_device *ndev)
"Only %d MSI-X vectors. Limiting the number of queues to that number.\n",
rc);
msix_entries = rc;
-
- rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries);
- if (rc)
- goto err1;
}
for (i = 0; i < msix_entries; i++) {
@@ -1233,10 +1176,9 @@ static int ntb_setup_interrupts(struct ntb_device *ndev)
*/
if (ndev->hw_type == BWD_HW)
writeq(~0, ndev->reg_ofs.ldb_mask);
- else {
- u16 var = 1 << SNB_LINK_DB;
- writew(~var, ndev->reg_ofs.ldb_mask);
- }
+ else
+ writew(~(1 << ndev->limits.max_db_bits),
+ ndev->reg_ofs.ldb_mask);
rc = ntb_setup_msix(ndev);
if (!rc)
@@ -1344,39 +1286,6 @@ static void ntb_free_debugfs(struct ntb_device *ndev)
}
}
-static void ntb_hw_link_up(struct ntb_device *ndev)
-{
- if (ndev->conn_type == NTB_CONN_TRANSPARENT)
- ntb_link_event(ndev, NTB_LINK_UP);
- else {
- u32 ntb_cntl;
-
- /* Let's bring the NTB link up */
- ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
- ntb_cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK);
- ntb_cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP;
- ntb_cntl |= NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP;
- writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
- }
-}
-
-static void ntb_hw_link_down(struct ntb_device *ndev)
-{
- u32 ntb_cntl;
-
- if (ndev->conn_type == NTB_CONN_TRANSPARENT) {
- ntb_link_event(ndev, NTB_LINK_DOWN);
- return;
- }
-
- /* Bring NTB link down */
- ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
- ntb_cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP);
- ntb_cntl &= ~(NTB_CNTL_P2S_BAR45_SNOOP | NTB_CNTL_S2P_BAR45_SNOOP);
- ntb_cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK;
- writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
-}
-
static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct ntb_device *ndev;
@@ -1465,7 +1374,9 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
goto err6;
- ntb_hw_link_up(ndev);
+ /* Let's bring the NTB link up */
+ writel(NTB_CNTL_BAR23_SNOOP | NTB_CNTL_BAR45_SNOOP,
+ ndev->reg_ofs.lnk_cntl);
return 0;
@@ -1495,8 +1406,12 @@ static void ntb_pci_remove(struct pci_dev *pdev)
{
struct ntb_device *ndev = pci_get_drvdata(pdev);
int i;
+ u32 ntb_cntl;
- ntb_hw_link_down(ndev);
+ /* Bring NTB link down */
+ ntb_cntl = readl(ndev->reg_ofs.lnk_cntl);
+ ntb_cntl |= NTB_CNTL_LINK_DISABLE;
+ writel(ntb_cntl, ndev->reg_ofs.lnk_cntl);
ntb_transport_free(ndev->ntb_transport);
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h
index bbdb7ed..0a31ced 100644
--- a/drivers/ntb/ntb_hw.h
+++ b/drivers/ntb/ntb_hw.h
@@ -106,11 +106,10 @@ struct ntb_mw {
};
struct ntb_db_cb {
- int (*callback)(void *data, int db_num);
+ void (*callback) (void *data, int db_num);
unsigned int db_num;
void *data;
struct ntb_device *ndev;
- struct tasklet_struct irq_work;
};
struct ntb_device {
@@ -229,8 +228,8 @@ struct ntb_device *ntb_register_transport(struct pci_dev *pdev,
void ntb_unregister_transport(struct ntb_device *ndev);
void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr);
int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx,
- void *data, int (*db_cb_func)(void *data,
- int db_num));
+ void *data, void (*db_cb_func) (void *data,
+ int db_num));
void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx);
int ntb_register_event_callback(struct ntb_device *ndev,
void (*event_cb_func) (void *handle,
diff --git a/drivers/ntb/ntb_regs.h b/drivers/ntb/ntb_regs.h
index 9774506..aa4bdd3 100644
--- a/drivers/ntb/ntb_regs.h
+++ b/drivers/ntb/ntb_regs.h
@@ -55,7 +55,6 @@
#define SNB_MAX_COMPAT_SPADS 16
/* Reserve the uppermost bit for link interrupt */
#define SNB_MAX_DB_BITS 15
-#define SNB_LINK_DB 15
#define SNB_DB_BITS_PER_VEC 5
#define SNB_MAX_MW 2
#define SNB_ERRATA_MAX_MW 1
@@ -76,6 +75,9 @@
#define SNB_SBAR2XLAT_OFFSET 0x0030
#define SNB_SBAR4XLAT_OFFSET 0x0038
#define SNB_SBAR0BASE_OFFSET 0x0040
+#define SNB_SBAR0BASE_OFFSET 0x0040
+#define SNB_SBAR2BASE_OFFSET 0x0048
+#define SNB_SBAR4BASE_OFFSET 0x0050
#define SNB_SBAR2BASE_OFFSET 0x0048
#define SNB_SBAR4BASE_OFFSET 0x0050
#define SNB_NTBCNTL_OFFSET 0x0058
@@ -143,13 +145,11 @@
#define BWD_LTSSMSTATEJMP_FORCEDETECT (1 << 2)
#define BWD_IBIST_ERR_OFLOW 0x7FFF7FFF
-#define NTB_CNTL_CFG_LOCK (1 << 0)
-#define NTB_CNTL_LINK_DISABLE (1 << 1)
-#define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2)
-#define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4)
-#define NTB_CNTL_S2P_BAR45_SNOOP (1 << 6)
-#define NTB_CNTL_P2S_BAR45_SNOOP (1 << 8)
-#define BWD_CNTL_LINK_DOWN (1 << 16)
+#define NTB_CNTL_CFG_LOCK (1 << 0)
+#define NTB_CNTL_LINK_DISABLE (1 << 1)
+#define NTB_CNTL_BAR23_SNOOP (1 << 2)
+#define NTB_CNTL_BAR45_SNOOP (1 << 6)
+#define BWD_CNTL_LINK_DOWN (1 << 16)
#define NTB_PPD_OFFSET 0x00D4
#define SNB_PPD_CONN_TYPE 0x0003
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 3217f39..12a9e83 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -119,6 +119,7 @@ struct ntb_transport_qp {
void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data,
void *data, int len);
+ struct tasklet_struct rx_work;
struct list_head rx_pend_q;
struct list_head rx_free_q;
spinlock_t ntb_rx_pend_q_lock;
@@ -583,8 +584,11 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size)
return 0;
}
-static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
+static void ntb_qp_link_cleanup(struct work_struct *work)
{
+ struct ntb_transport_qp *qp = container_of(work,
+ struct ntb_transport_qp,
+ link_cleanup);
struct ntb_transport *nt = qp->transport;
struct pci_dev *pdev = ntb_query_pdev(nt->ndev);
@@ -598,16 +602,6 @@ static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
dev_info(&pdev->dev, "qp %d: Link Down\n", qp->qp_num);
qp->qp_link = NTB_LINK_DOWN;
-}
-
-static void ntb_qp_link_cleanup_work(struct work_struct *work)
-{
- struct ntb_transport_qp *qp = container_of(work,
- struct ntb_transport_qp,
- link_cleanup);
- struct ntb_transport *nt = qp->transport;
-
- ntb_qp_link_cleanup(qp);
if (nt->transport_link == NTB_LINK_UP)
schedule_delayed_work(&qp->link_work,
@@ -619,20 +613,22 @@ static void ntb_qp_link_down(struct ntb_transport_qp *qp)
schedule_work(&qp->link_cleanup);
}
-static void ntb_transport_link_cleanup(struct ntb_transport *nt)
+static void ntb_transport_link_cleanup(struct work_struct *work)
{
+ struct ntb_transport *nt = container_of(work, struct ntb_transport,
+ link_cleanup);
int i;
- /* Pass along the info to any clients */
- for (i = 0; i < nt->max_qps; i++)
- if (!test_bit(i, &nt->qp_bitmap))
- ntb_qp_link_cleanup(&nt->qps[i]);
-
if (nt->transport_link == NTB_LINK_DOWN)
cancel_delayed_work_sync(&nt->link_work);
else
nt->transport_link = NTB_LINK_DOWN;
+ /* Pass along the info to any clients */
+ for (i = 0; i < nt->max_qps; i++)
+ if (!test_bit(i, &nt->qp_bitmap))
+ ntb_qp_link_down(&nt->qps[i]);
+
/* The scratchpad registers keep the values if the remote side
* goes down, blast them now to give them a sane value the next
* time they are accessed
@@ -641,14 +637,6 @@ static void ntb_transport_link_cleanup(struct ntb_transport *nt)
ntb_write_local_spad(nt->ndev, i, 0);
}
-static void ntb_transport_link_cleanup_work(struct work_struct *work)
-{
- struct ntb_transport *nt = container_of(work, struct ntb_transport,
- link_cleanup);
-
- ntb_transport_link_cleanup(nt);
-}
-
static void ntb_transport_event_callback(void *data, enum ntb_hw_event event)
{
struct ntb_transport *nt = data;
@@ -892,7 +880,7 @@ static int ntb_transport_init_queue(struct ntb_transport *nt,
}
INIT_DELAYED_WORK(&qp->link_work, ntb_qp_link_work);
- INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup_work);
+ INIT_WORK(&qp->link_cleanup, ntb_qp_link_cleanup);
spin_lock_init(&qp->ntb_rx_pend_q_lock);
spin_lock_init(&qp->ntb_rx_free_q_lock);
@@ -948,7 +936,7 @@ int ntb_transport_init(struct pci_dev *pdev)
}
INIT_DELAYED_WORK(&nt->link_work, ntb_transport_link_work);
- INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup_work);
+ INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup);
rc = ntb_register_event_callback(nt->ndev,
ntb_transport_event_callback);
@@ -984,7 +972,7 @@ void ntb_transport_free(void *transport)
struct ntb_device *ndev = nt->ndev;
int i;
- ntb_transport_link_cleanup(nt);
+ nt->transport_link = NTB_LINK_DOWN;
/* verify that all the qp's are freed */
for (i = 0; i < nt->max_qps; i++) {
@@ -1046,9 +1034,10 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset,
struct dma_chan *chan = qp->dma_chan;
struct dma_device *device;
size_t pay_off, buff_off;
- struct dmaengine_unmap_data *unmap;
+ dma_addr_t src, dest;
dma_cookie_t cookie;
void *buf = entry->buf;
+ unsigned long flags;
entry->len = len;
@@ -1056,49 +1045,35 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset,
goto err;
if (len < copy_bytes)
- goto err_wait;
+ goto err1;
device = chan->device;
pay_off = (size_t) offset & ~PAGE_MASK;
buff_off = (size_t) buf & ~PAGE_MASK;
if (!is_dma_copy_aligned(device, pay_off, buff_off, len))
- goto err_wait;
-
- unmap = dmaengine_get_unmap_data(device->dev, 2, GFP_NOWAIT);
- if (!unmap)
- goto err_wait;
-
- unmap->len = len;
- unmap->addr[0] = dma_map_page(device->dev, virt_to_page(offset),
- pay_off, len, DMA_TO_DEVICE);
- if (dma_mapping_error(device->dev, unmap->addr[0]))
- goto err_get_unmap;
-
- unmap->to_cnt = 1;
+ goto err1;
- unmap->addr[1] = dma_map_page(device->dev, virt_to_page(buf),
- buff_off, len, DMA_FROM_DEVICE);
- if (dma_mapping_error(device->dev, unmap->addr[1]))
- goto err_get_unmap;
+ dest = dma_map_single(device->dev, buf, len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(device->dev, dest))
+ goto err1;
- unmap->from_cnt = 1;
+ src = dma_map_single(device->dev, offset, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(device->dev, src))
+ goto err2;
- txd = device->device_prep_dma_memcpy(chan, unmap->addr[1],
- unmap->addr[0], len,
- DMA_PREP_INTERRUPT);
+ flags = DMA_COMPL_DEST_UNMAP_SINGLE | DMA_COMPL_SRC_UNMAP_SINGLE |
+ DMA_PREP_INTERRUPT;
+ txd = device->device_prep_dma_memcpy(chan, dest, src, len, flags);
if (!txd)
- goto err_get_unmap;
+ goto err3;
txd->callback = ntb_rx_copy_callback;
txd->callback_param = entry;
- dma_set_unmap(txd, unmap);
cookie = dmaengine_submit(txd);
if (dma_submit_error(cookie))
- goto err_set_unmap;
-
- dmaengine_unmap_put(unmap);
+ goto err3;
qp->last_cookie = cookie;
@@ -1106,11 +1081,11 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset,
return;
-err_set_unmap:
- dmaengine_unmap_put(unmap);
-err_get_unmap:
- dmaengine_unmap_put(unmap);
-err_wait:
+err3:
+ dma_unmap_single(device->dev, src, len, DMA_TO_DEVICE);
+err2:
+ dma_unmap_single(device->dev, dest, len, DMA_FROM_DEVICE);
+err1:
/* If the callbacks come out of order, the writing of the index to the
* last completed will be out of order. This may result in the
* receive stalling forever.
@@ -1200,14 +1175,11 @@ err:
goto out;
}
-static int ntb_transport_rxc_db(void *data, int db_num)
+static void ntb_transport_rx(unsigned long data)
{
- struct ntb_transport_qp *qp = data;
+ struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data;
int rc, i;
- dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
- __func__, db_num);
-
/* Limit the number of packets processed in a single interrupt to
* provide fairness to others
*/
@@ -1219,8 +1191,16 @@ static int ntb_transport_rxc_db(void *data, int db_num)
if (qp->dma_chan)
dma_async_issue_pending(qp->dma_chan);
+}
+
+static void ntb_transport_rxc_db(void *data, int db_num)
+{
+ struct ntb_transport_qp *qp = data;
+
+ dev_dbg(&ntb_query_pdev(qp->ndev)->dev, "%s: doorbell %d received\n",
+ __func__, db_num);
- return i;
+ tasklet_schedule(&qp->rx_work);
}
static void ntb_tx_copy_callback(void *data)
@@ -1265,12 +1245,12 @@ static void ntb_async_tx(struct ntb_transport_qp *qp,
struct dma_chan *chan = qp->dma_chan;
struct dma_device *device;
size_t dest_off, buff_off;
- struct dmaengine_unmap_data *unmap;
- dma_addr_t dest;
+ dma_addr_t src, dest;
dma_cookie_t cookie;
void __iomem *offset;
size_t len = entry->len;
void *buf = entry->buf;
+ unsigned long flags;
offset = qp->tx_mw + qp->tx_max_frame * qp->tx_index;
hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header);
@@ -1293,41 +1273,28 @@ static void ntb_async_tx(struct ntb_transport_qp *qp,
if (!is_dma_copy_aligned(device, buff_off, dest_off, len))
goto err;
- unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
- if (!unmap)
+ src = dma_map_single(device->dev, buf, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(device->dev, src))
goto err;
- unmap->len = len;
- unmap->addr[0] = dma_map_page(device->dev, virt_to_page(buf),
- buff_off, len, DMA_TO_DEVICE);
- if (dma_mapping_error(device->dev, unmap->addr[0]))
- goto err_get_unmap;
-
- unmap->to_cnt = 1;
-
- txd = device->device_prep_dma_memcpy(chan, dest, unmap->addr[0], len,
- DMA_PREP_INTERRUPT);
+ flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_PREP_INTERRUPT;
+ txd = device->device_prep_dma_memcpy(chan, dest, src, len, flags);
if (!txd)
- goto err_get_unmap;
+ goto err1;
txd->callback = ntb_tx_copy_callback;
txd->callback_param = entry;
- dma_set_unmap(txd, unmap);
cookie = dmaengine_submit(txd);
if (dma_submit_error(cookie))
- goto err_set_unmap;
-
- dmaengine_unmap_put(unmap);
+ goto err1;
dma_async_issue_pending(chan);
qp->tx_async++;
return;
-err_set_unmap:
- dmaengine_unmap_put(unmap);
-err_get_unmap:
- dmaengine_unmap_put(unmap);
+err1:
+ dma_unmap_single(device->dev, src, len, DMA_TO_DEVICE);
err:
ntb_memcpy_tx(entry, offset);
qp->tx_memcpy++;
@@ -1439,12 +1406,11 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev,
qp->tx_handler = handlers->tx_handler;
qp->event_handler = handlers->event_handler;
- dmaengine_get();
qp->dma_chan = dma_find_channel(DMA_MEMCPY);
- if (!qp->dma_chan) {
- dmaengine_put();
+ if (!qp->dma_chan)
dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n");
- }
+ else
+ dmaengine_get();
for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
entry = kzalloc(sizeof(struct ntb_queue_entry), GFP_ATOMIC);
@@ -1466,23 +1432,25 @@ ntb_transport_create_queue(void *data, struct pci_dev *pdev,
&qp->tx_free_q);
}
+ tasklet_init(&qp->rx_work, ntb_transport_rx, (unsigned long) qp);
+
rc = ntb_register_db_callback(qp->ndev, free_queue, qp,
ntb_transport_rxc_db);
if (rc)
- goto err2;
+ goto err3;
dev_info(&pdev->dev, "NTB Transport QP %d created\n", qp->qp_num);
return qp;
+err3:
+ tasklet_disable(&qp->rx_work);
err2:
while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q)))
kfree(entry);
err1:
while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
kfree(entry);
- if (qp->dma_chan)
- dmaengine_put();
set_bit(free_queue, &nt->qp_bitmap);
err:
return NULL;
@@ -1521,6 +1489,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
}
ntb_unregister_db_callback(qp->ndev, qp->qp_num);
+ tasklet_disable(&qp->rx_work);
cancel_delayed_work_sync(&qp->link_work);