diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/ntb | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-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.c | 121 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.h | 7 | ||||
-rw-r--r-- | drivers/ntb/ntb_regs.h | 16 | ||||
-rw-r--r-- | drivers/ntb/ntb_transport.c | 163 |
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); |