.. | .. |
---|
636 | 636 | struct sdma_txreq *tx, |
---|
637 | 637 | int type, |
---|
638 | 638 | dma_addr_t addr, |
---|
639 | | - size_t len) |
---|
| 639 | + size_t len, |
---|
| 640 | + void *pinning_ctx, |
---|
| 641 | + void (*ctx_get)(void *), |
---|
| 642 | + void (*ctx_put)(void *)) |
---|
640 | 643 | { |
---|
641 | 644 | struct sdma_desc *desc = &tx->descp[tx->num_desc]; |
---|
642 | 645 | |
---|
.. | .. |
---|
653 | 656 | << SDMA_DESC0_PHY_ADDR_SHIFT) | |
---|
654 | 657 | (((u64)len & SDMA_DESC0_BYTE_COUNT_MASK) |
---|
655 | 658 | << SDMA_DESC0_BYTE_COUNT_SHIFT); |
---|
| 659 | + |
---|
| 660 | + desc->pinning_ctx = pinning_ctx; |
---|
| 661 | + desc->ctx_put = ctx_put; |
---|
| 662 | + if (pinning_ctx && ctx_get) |
---|
| 663 | + ctx_get(pinning_ctx); |
---|
656 | 664 | } |
---|
657 | 665 | |
---|
658 | 666 | /* helper to extend txreq */ |
---|
.. | .. |
---|
672 | 680 | static inline void _sdma_close_tx(struct hfi1_devdata *dd, |
---|
673 | 681 | struct sdma_txreq *tx) |
---|
674 | 682 | { |
---|
675 | | - tx->descp[tx->num_desc].qw[0] |= |
---|
676 | | - SDMA_DESC0_LAST_DESC_FLAG; |
---|
677 | | - tx->descp[tx->num_desc].qw[1] |= |
---|
678 | | - dd->default_desc1; |
---|
| 683 | + u16 last_desc = tx->num_desc - 1; |
---|
| 684 | + |
---|
| 685 | + tx->descp[last_desc].qw[0] |= SDMA_DESC0_LAST_DESC_FLAG; |
---|
| 686 | + tx->descp[last_desc].qw[1] |= dd->default_desc1; |
---|
679 | 687 | if (tx->flags & SDMA_TXREQ_F_URGENT) |
---|
680 | | - tx->descp[tx->num_desc].qw[1] |= |
---|
681 | | - (SDMA_DESC1_HEAD_TO_HOST_FLAG | |
---|
682 | | - SDMA_DESC1_INT_REQ_FLAG); |
---|
| 688 | + tx->descp[last_desc].qw[1] |= (SDMA_DESC1_HEAD_TO_HOST_FLAG | |
---|
| 689 | + SDMA_DESC1_INT_REQ_FLAG); |
---|
683 | 690 | } |
---|
684 | 691 | |
---|
685 | 692 | static inline int _sdma_txadd_daddr( |
---|
.. | .. |
---|
687 | 694 | int type, |
---|
688 | 695 | struct sdma_txreq *tx, |
---|
689 | 696 | dma_addr_t addr, |
---|
690 | | - u16 len) |
---|
| 697 | + u16 len, |
---|
| 698 | + void *pinning_ctx, |
---|
| 699 | + void (*ctx_get)(void *), |
---|
| 700 | + void (*ctx_put)(void *)) |
---|
691 | 701 | { |
---|
692 | 702 | int rval = 0; |
---|
693 | 703 | |
---|
694 | 704 | make_tx_sdma_desc( |
---|
695 | 705 | tx, |
---|
696 | 706 | type, |
---|
697 | | - addr, len); |
---|
| 707 | + addr, len, |
---|
| 708 | + pinning_ctx, ctx_get, ctx_put); |
---|
698 | 709 | WARN_ON(len > tx->tlen); |
---|
| 710 | + tx->num_desc++; |
---|
699 | 711 | tx->tlen -= len; |
---|
700 | 712 | /* special cases for last */ |
---|
701 | 713 | if (!tx->tlen) { |
---|
.. | .. |
---|
707 | 719 | _sdma_close_tx(dd, tx); |
---|
708 | 720 | } |
---|
709 | 721 | } |
---|
710 | | - tx->num_desc++; |
---|
711 | 722 | return rval; |
---|
712 | 723 | } |
---|
713 | 724 | |
---|
.. | .. |
---|
718 | 729 | * @page: page to map |
---|
719 | 730 | * @offset: offset within the page |
---|
720 | 731 | * @len: length in bytes |
---|
| 732 | + * @pinning_ctx: context to be stored on struct sdma_desc .pinning_ctx. Not |
---|
| 733 | + * added if coalesce buffer is used. E.g. pointer to pinned-page |
---|
| 734 | + * cache entry for the sdma_desc. |
---|
| 735 | + * @ctx_get: optional function to take reference to @pinning_ctx. Not called if |
---|
| 736 | + * @pinning_ctx is NULL. |
---|
| 737 | + * @ctx_put: optional function to release reference to @pinning_ctx after |
---|
| 738 | + * sdma_desc completes. May be called in interrupt context so must |
---|
| 739 | + * not sleep. Not called if @pinning_ctx is NULL. |
---|
721 | 740 | * |
---|
722 | 741 | * This is used to add a page/offset/length descriptor. |
---|
723 | 742 | * |
---|
.. | .. |
---|
732 | 751 | struct sdma_txreq *tx, |
---|
733 | 752 | struct page *page, |
---|
734 | 753 | unsigned long offset, |
---|
735 | | - u16 len) |
---|
| 754 | + u16 len, |
---|
| 755 | + void *pinning_ctx, |
---|
| 756 | + void (*ctx_get)(void *), |
---|
| 757 | + void (*ctx_put)(void *)) |
---|
736 | 758 | { |
---|
737 | 759 | dma_addr_t addr; |
---|
738 | 760 | int rval; |
---|
.. | .. |
---|
756 | 778 | return -ENOSPC; |
---|
757 | 779 | } |
---|
758 | 780 | |
---|
759 | | - return _sdma_txadd_daddr( |
---|
760 | | - dd, SDMA_MAP_PAGE, tx, addr, len); |
---|
| 781 | + return _sdma_txadd_daddr(dd, SDMA_MAP_PAGE, tx, addr, len, |
---|
| 782 | + pinning_ctx, ctx_get, ctx_put); |
---|
761 | 783 | } |
---|
762 | 784 | |
---|
763 | 785 | /** |
---|
.. | .. |
---|
791 | 813 | return rval; |
---|
792 | 814 | } |
---|
793 | 815 | |
---|
794 | | - return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len); |
---|
| 816 | + return _sdma_txadd_daddr(dd, SDMA_MAP_NONE, tx, addr, len, |
---|
| 817 | + NULL, NULL, NULL); |
---|
795 | 818 | } |
---|
796 | 819 | |
---|
797 | 820 | /** |
---|
.. | .. |
---|
837 | 860 | return -ENOSPC; |
---|
838 | 861 | } |
---|
839 | 862 | |
---|
840 | | - return _sdma_txadd_daddr( |
---|
841 | | - dd, SDMA_MAP_SINGLE, tx, addr, len); |
---|
| 863 | + return _sdma_txadd_daddr(dd, SDMA_MAP_SINGLE, tx, addr, len, |
---|
| 864 | + NULL, NULL, NULL); |
---|
842 | 865 | } |
---|
843 | 866 | |
---|
844 | 867 | struct iowait_work; |
---|
.. | .. |
---|
1089 | 1112 | extern uint mod_num_sdma; |
---|
1090 | 1113 | |
---|
1091 | 1114 | void sdma_update_lmc(struct hfi1_devdata *dd, u64 mask, u32 lid); |
---|
1092 | | - |
---|
1093 | 1115 | #endif |
---|