Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
dma
ioat
dma.h
Go to the documentation of this file.
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_H
22
#define IOATDMA_H
23
24
#include <
linux/dmaengine.h
>
25
#include "
hw.h
"
26
#include "
registers.h
"
27
#include <
linux/init.h
>
28
#include <
linux/dmapool.h
>
29
#include <
linux/cache.h
>
30
#include <
linux/pci_ids.h
>
31
#include <
net/tcp.h
>
32
33
#define IOAT_DMA_VERSION "4.00"
34
35
#define IOAT_LOW_COMPLETION_MASK 0xffffffc0
36
#define IOAT_DMA_DCA_ANY_CPU ~0
37
38
#define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common)
39
#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
40
#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, txd)
41
#define to_dev(ioat_chan) (&(ioat_chan)->device->pdev->dev)
42
43
#define chan_num(ch) ((int)((ch)->reg_base - (ch)->device->reg_base) / 0x80)
44
45
/*
46
* workaround for IOAT ver.3.0 null descriptor issue
47
* (channel returns error when size is 0)
48
*/
49
#define NULL_DESC_BUFFER_SIZE 1
50
70
struct
ioatdma_device
{
71
struct
pci_dev
*
pdev
;
72
void
__iomem
*
reg_base
;
73
struct
pci_pool *
dma_pool
;
74
struct
pci_pool *
completion_pool
;
75
struct
dma_device
common
;
76
u8
version
;
77
struct
msix_entry
msix_entries
[4];
78
struct
ioat_chan_common
*
idx
[4];
79
struct
dca_provider
*
dca
;
80
void
(*
intr_quirk
)(
struct
ioatdma_device
*
device
);
81
int
(*
enumerate_channels
)(
struct
ioatdma_device
*
device
);
82
int
(*
reset_hw
)(
struct
ioat_chan_common
*
chan
);
83
void
(*
cleanup_fn
)(
unsigned
long
data
);
84
void
(*
timer_fn
)(
unsigned
long
data
);
85
int
(*
self_test
)(
struct
ioatdma_device
*
device
);
86
};
87
88
struct
ioat_chan_common
{
89
struct
dma_chan
common
;
90
void
__iomem
*
reg_base
;
91
dma_addr_t
last_completion
;
92
spinlock_t
cleanup_lock
;
93
unsigned
long
state
;
94
#define IOAT_COMPLETION_PENDING 0
95
#define IOAT_COMPLETION_ACK 1
96
#define IOAT_RESET_PENDING 2
97
#define IOAT_KOBJ_INIT_FAIL 3
98
#define IOAT_RESHAPE_PENDING 4
99
#define IOAT_RUN 5
100
struct
timer_list
timer
;
101
#define COMPLETION_TIMEOUT msecs_to_jiffies(100)
102
#define IDLE_TIMEOUT msecs_to_jiffies(2000)
103
#define RESET_DELAY msecs_to_jiffies(100)
104
struct
ioatdma_device
*
device
;
105
dma_addr_t
completion_dma
;
106
u64
*
completion
;
107
struct
tasklet_struct
cleanup_task
;
108
struct
kobject
kobj
;
109
};
110
111
struct
ioat_sysfs_entry
{
112
struct
attribute
attr
;
113
ssize_t
(*
show
)(
struct
dma_chan
*,
char
*);
114
};
115
119
struct
ioat_dma_chan
{
120
struct
ioat_chan_common
base
;
121
122
size_t
xfercap
;
/* XFERCAP register value expanded out */
123
124
spinlock_t
desc_lock
;
125
struct
list_head
free_desc
;
126
struct
list_head
used_desc
;
127
128
int
pending
;
129
u16
desccount
;
130
u16
active
;
131
};
132
133
static
inline
struct
ioat_chan_common
*to_chan_common(
struct
dma_chan
*
c
)
134
{
135
return
container_of
(c,
struct
ioat_chan_common
,
common
);
136
}
137
138
static
inline
struct
ioat_dma_chan
*to_ioat_chan(
struct
dma_chan
*
c
)
139
{
140
struct
ioat_chan_common
*
chan
= to_chan_common(c);
141
142
return
container_of
(chan,
struct
ioat_dma_chan
, base);
143
}
144
145
/* wrapper around hardware descriptor format + additional software fields */
146
155
struct
ioat_desc_sw
{
156
struct
ioat_dma_descriptor
*
hw
;
157
struct
list_head
node
;
158
size_t
len
;
159
struct
list_head
tx_list
;
160
struct
dma_async_tx_descriptor
txd
;
161
#ifdef DEBUG
162
int
id
;
163
#endif
164
};
165
166
#ifdef DEBUG
167
#define set_desc_id(desc, i) ((desc)->id = (i))
168
#define desc_id(desc) ((desc)->id)
169
#else
170
#define set_desc_id(desc, i)
171
#define desc_id(desc) (0)
172
#endif
173
174
static
inline
void
175
__dump_desc_dbg(
struct
ioat_chan_common
*
chan
,
struct
ioat_dma_descriptor
*
hw
,
176
struct
dma_async_tx_descriptor
*
tx
,
int
id
)
177
{
178
struct
device
*
dev
=
to_dev
(chan);
179
180
dev_dbg
(dev,
"desc[%d]: (%#llx->%#llx) cookie: %d flags: %#x"
181
" ctl: %#x (op: %d int_en: %d compl: %d)\n"
,
id
,
182
(
unsigned
long
long
) tx->
phys
,
183
(
unsigned
long
long
) hw->
next
, tx->
cookie
, tx->
flags
,
184
hw->
ctl
, hw->
ctl_f
.op, hw->
ctl_f
.int_en, hw->
ctl_f
.compl_write);
185
}
186
187
#define dump_desc_dbg(c, d) \
188
({ if (d) __dump_desc_dbg(&c->base, d->hw, &d->txd, desc_id(d)); 0; })
189
190
static
inline
void
ioat_set_tcp_copy_break(
unsigned
long
copybreak
)
191
{
192
#ifdef CONFIG_NET_DMA
193
sysctl_tcp_dma_copybreak
=
copybreak
;
194
#endif
195
}
196
197
static
inline
struct
ioat_chan_common
*
198
ioat_chan_by_index(
struct
ioatdma_device
*
device
,
int
index
)
199
{
200
return
device->
idx
[
index
];
201
}
202
203
static
inline
u64
ioat_chansts(
struct
ioat_chan_common
*
chan
)
204
{
205
u8
ver
= chan->
device
->version;
206
u64
status
;
207
u32
status_lo;
208
209
/* We need to read the low address first as this causes the
210
* chipset to latch the upper bits for the subsequent read
211
*/
212
status_lo =
readl
(chan->
reg_base
+
IOAT_CHANSTS_OFFSET_LOW
(ver));
213
status =
readl
(chan->
reg_base
+
IOAT_CHANSTS_OFFSET_HIGH
(ver));
214
status <<= 32;
215
status |= status_lo;
216
217
return
status
;
218
}
219
220
static
inline
void
ioat_start(
struct
ioat_chan_common
*chan)
221
{
222
u8
ver = chan->
device
->version;
223
224
writeb
(
IOAT_CHANCMD_START
, chan->
reg_base
+
IOAT_CHANCMD_OFFSET
(ver));
225
}
226
227
static
inline
u64
ioat_chansts_to_addr(
u64
status)
228
{
229
return
status &
IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR
;
230
}
231
232
static
inline
u32
ioat_chanerr(
struct
ioat_chan_common
*chan)
233
{
234
return
readl
(chan->
reg_base
+
IOAT_CHANERR_OFFSET
);
235
}
236
237
static
inline
void
ioat_suspend(
struct
ioat_chan_common
*chan)
238
{
239
u8
ver = chan->
device
->version;
240
241
writeb
(
IOAT_CHANCMD_SUSPEND
, chan->
reg_base
+
IOAT_CHANCMD_OFFSET
(ver));
242
}
243
244
static
inline
void
ioat_reset(
struct
ioat_chan_common
*chan)
245
{
246
u8
ver = chan->
device
->version;
247
248
writeb
(
IOAT_CHANCMD_RESET
, chan->
reg_base
+
IOAT_CHANCMD_OFFSET
(ver));
249
}
250
251
static
inline
bool
ioat_reset_pending(
struct
ioat_chan_common
*chan)
252
{
253
u8
ver = chan->
device
->version;
254
u8
cmd
;
255
256
cmd =
readb
(chan->
reg_base
+
IOAT_CHANCMD_OFFSET
(ver));
257
return
(cmd &
IOAT_CHANCMD_RESET
) ==
IOAT_CHANCMD_RESET
;
258
}
259
260
static
inline
void
ioat_set_chainaddr(
struct
ioat_dma_chan
*ioat,
u64
addr
)
261
{
262
struct
ioat_chan_common
*chan = &ioat->
base
;
263
264
writel
(addr & 0x00000000FFFFFFFF,
265
chan->
reg_base
+
IOAT1_CHAINADDR_OFFSET_LOW
);
266
writel
(addr >> 32,
267
chan->
reg_base
+
IOAT1_CHAINADDR_OFFSET_HIGH
);
268
}
269
270
static
inline
bool
is_ioat_active(
unsigned
long
status)
271
{
272
return
((status &
IOAT_CHANSTS_STATUS
) ==
IOAT_CHANSTS_ACTIVE
);
273
}
274
275
static
inline
bool
is_ioat_idle(
unsigned
long
status)
276
{
277
return
((status &
IOAT_CHANSTS_STATUS
) ==
IOAT_CHANSTS_DONE
);
278
}
279
280
static
inline
bool
is_ioat_halted(
unsigned
long
status)
281
{
282
return
((status &
IOAT_CHANSTS_STATUS
) ==
IOAT_CHANSTS_HALTED
);
283
}
284
285
static
inline
bool
is_ioat_suspended(
unsigned
long
status)
286
{
287
return
((status &
IOAT_CHANSTS_STATUS
) ==
IOAT_CHANSTS_SUSPENDED
);
288
}
289
290
/* channel was fatally programmed */
291
static
inline
bool
is_ioat_bug(
unsigned
long
err
)
292
{
293
return
!!
err
;
294
}
295
296
static
inline
void
ioat_unmap(
struct
pci_dev
*pdev,
dma_addr_t
addr
,
size_t
len,
297
int
direction
,
enum
dma_ctrl_flags
flags
,
bool
dst
)
298
{
299
if
((dst && (flags &
DMA_COMPL_DEST_UNMAP_SINGLE
)) ||
300
(!dst && (flags &
DMA_COMPL_SRC_UNMAP_SINGLE
)))
301
pci_unmap_single(pdev, addr, len, direction);
302
else
303
pci_unmap_page(pdev, addr, len, direction);
304
}
305
306
int
__devinit
ioat_probe
(
struct
ioatdma_device
*
device
);
307
int
__devinit
ioat_register
(
struct
ioatdma_device
*
device
);
308
int
__devinit
ioat1_dma_probe
(
struct
ioatdma_device
*
dev
,
int
dca);
309
int
__devinit
ioat_dma_self_test
(
struct
ioatdma_device
*
device
);
310
void
__devexit
ioat_dma_remove
(
struct
ioatdma_device
*
device
);
311
struct
dca_provider
*
__devinit
ioat_dca_init
(
struct
pci_dev
*pdev,
312
void
__iomem
*
iobase
);
313
dma_addr_t
ioat_get_current_completion
(
struct
ioat_chan_common
*chan);
314
void
ioat_init_channel
(
struct
ioatdma_device
*
device
,
315
struct
ioat_chan_common
*chan,
int
idx
);
316
enum
dma_status
ioat_dma_tx_status
(
struct
dma_chan
*
c
,
dma_cookie_t
cookie
,
317
struct
dma_tx_state
*txstate);
318
void
ioat_dma_unmap
(
struct
ioat_chan_common
*chan,
enum
dma_ctrl_flags
flags,
319
size_t
len,
struct
ioat_dma_descriptor
*
hw
);
320
bool
ioat_cleanup_preamble
(
struct
ioat_chan_common
*chan,
321
dma_addr_t
*phys_complete);
322
void
ioat_kobject_add
(
struct
ioatdma_device
*
device
,
struct
kobj_type
*
type
);
323
void
ioat_kobject_del
(
struct
ioatdma_device
*
device
);
324
extern
const
struct
sysfs_ops
ioat_sysfs_ops
;
325
extern
struct
ioat_sysfs_entry
ioat_version_attr
;
326
extern
struct
ioat_sysfs_entry
ioat_cap_attr
;
327
#endif
/* IOATDMA_H */
Generated on Thu Jan 10 2013 12:49:31 for Linux Kernel by
1.8.2