]>
Commit | Line | Data |
---|---|---|
5cbafa65 DW |
1 | /* |
2 | * Copyright(c) 2004 - 2009 Intel Corporation. All rights reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify it | |
5 | * under the terms of the GNU General Public License as published by the Free | |
6 | * Software Foundation; either version 2 of the License, or (at your option) | |
7 | * any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along with | |
15 | * this program; if not, write to the Free Software Foundation, Inc., 59 | |
16 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 | * | |
18 | * The full GNU General Public License is included in this distribution in the | |
19 | * file called COPYING. | |
20 | */ | |
21 | #ifndef IOATDMA_V2_H | |
22 | #define IOATDMA_V2_H | |
23 | ||
24 | #include <linux/dmaengine.h> | |
25 | #include "dma.h" | |
26 | #include "hw.h" | |
27 | ||
28 | ||
29 | extern int ioat_pending_level; | |
30 | ||
31 | /* | |
32 | * workaround for IOAT ver.3.0 null descriptor issue | |
33 | * (channel returns error when size is 0) | |
34 | */ | |
35 | #define NULL_DESC_BUFFER_SIZE 1 | |
36 | ||
37 | #define IOAT_MAX_ORDER 16 | |
38 | #define ioat_get_alloc_order() \ | |
39 | (min(ioat_ring_alloc_order, IOAT_MAX_ORDER)) | |
a309218a DW |
40 | #define ioat_get_max_alloc_order() \ |
41 | (min(ioat_ring_max_alloc_order, IOAT_MAX_ORDER)) | |
5cbafa65 DW |
42 | |
43 | /* struct ioat2_dma_chan - ioat v2 / v3 channel attributes | |
44 | * @base: common ioat channel parameters | |
45 | * @xfercap_log; log2 of channel max transfer length (for fast division) | |
46 | * @head: allocated index | |
47 | * @issued: hardware notification point | |
48 | * @tail: cleanup index | |
49 | * @pending: lock free indicator for issued != head | |
50 | * @dmacount: identical to 'head' except for occasionally resetting to zero | |
51 | * @alloc_order: log2 of the number of allocated descriptors | |
52 | * @ring: software ring buffer implementation of hardware ring | |
53 | * @ring_lock: protects ring attributes | |
54 | */ | |
55 | struct ioat2_dma_chan { | |
56 | struct ioat_chan_common base; | |
57 | size_t xfercap_log; | |
58 | u16 head; | |
59 | u16 issued; | |
60 | u16 tail; | |
61 | u16 dmacount; | |
62 | u16 alloc_order; | |
63 | int pending; | |
64 | struct ioat_ring_ent **ring; | |
65 | spinlock_t ring_lock; | |
66 | }; | |
67 | ||
68 | static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) | |
69 | { | |
70 | struct ioat_chan_common *chan = to_chan_common(c); | |
71 | ||
72 | return container_of(chan, struct ioat2_dma_chan, base); | |
73 | } | |
74 | ||
75 | static inline u16 ioat2_ring_mask(struct ioat2_dma_chan *ioat) | |
76 | { | |
77 | return (1 << ioat->alloc_order) - 1; | |
78 | } | |
79 | ||
80 | /* count of descriptors in flight with the engine */ | |
81 | static inline u16 ioat2_ring_active(struct ioat2_dma_chan *ioat) | |
82 | { | |
83 | return (ioat->head - ioat->tail) & ioat2_ring_mask(ioat); | |
84 | } | |
85 | ||
86 | /* count of descriptors pending submission to hardware */ | |
87 | static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat) | |
88 | { | |
89 | return (ioat->head - ioat->issued) & ioat2_ring_mask(ioat); | |
90 | } | |
91 | ||
92 | static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) | |
93 | { | |
94 | u16 num_descs = ioat2_ring_mask(ioat) + 1; | |
95 | u16 active = ioat2_ring_active(ioat); | |
96 | ||
97 | BUG_ON(active > num_descs); | |
98 | ||
99 | return num_descs - active; | |
100 | } | |
101 | ||
102 | /* assumes caller already checked space */ | |
103 | static inline u16 ioat2_desc_alloc(struct ioat2_dma_chan *ioat, u16 len) | |
104 | { | |
105 | ioat->head += len; | |
106 | return ioat->head - len; | |
107 | } | |
108 | ||
109 | static inline u16 ioat2_xferlen_to_descs(struct ioat2_dma_chan *ioat, size_t len) | |
110 | { | |
111 | u16 num_descs = len >> ioat->xfercap_log; | |
112 | ||
113 | num_descs += !!(len & ((1 << ioat->xfercap_log) - 1)); | |
114 | return num_descs; | |
115 | } | |
116 | ||
117 | struct ioat_ring_ent { | |
118 | struct ioat_dma_descriptor *hw; | |
119 | struct dma_async_tx_descriptor txd; | |
120 | size_t len; | |
6df9183a DW |
121 | #ifdef DEBUG |
122 | int id; | |
123 | #endif | |
5cbafa65 DW |
124 | }; |
125 | ||
126 | static inline struct ioat_ring_ent * | |
127 | ioat2_get_ring_ent(struct ioat2_dma_chan *ioat, u16 idx) | |
128 | { | |
129 | return ioat->ring[idx & ioat2_ring_mask(ioat)]; | |
130 | } | |
131 | ||
09c8a5b8 DW |
132 | static inline void ioat2_set_chainaddr(struct ioat2_dma_chan *ioat, u64 addr) |
133 | { | |
134 | struct ioat_chan_common *chan = &ioat->base; | |
135 | ||
136 | writel(addr & 0x00000000FFFFFFFF, | |
137 | chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW); | |
138 | writel(addr >> 32, | |
139 | chan->reg_base + IOAT2_CHAINADDR_OFFSET_HIGH); | |
140 | } | |
141 | ||
345d8523 DW |
142 | int __devinit ioat2_dma_probe(struct ioatdma_device *dev, int dca); |
143 | int __devinit ioat3_dma_probe(struct ioatdma_device *dev, int dca); | |
144 | struct dca_provider * __devinit ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase); | |
145 | struct dca_provider * __devinit ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase); | |
5cbafa65 | 146 | #endif /* IOATDMA_V2_H */ |