Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
9ee1bea4
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9ee1bea4
编写于
10月 04, 2007
作者:
J
Jens Axboe
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
x86-64: update pci-gart iommu to sg helpers
Signed-off-by:
N
Jens Axboe
<
jens.axboe@oracle.com
>
上级
b922f53b
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
36 addition
and
29 deletion
+36
-29
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pci-gart_64.c
+36
-29
未找到文件。
arch/x86/kernel/pci-gart_64.c
浏览文件 @
9ee1bea4
...
...
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/kdebug.h>
#include <linux/scatterlist.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
...
...
@@ -278,10 +279,10 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
*/
static
void
gart_unmap_sg
(
struct
device
*
dev
,
struct
scatterlist
*
sg
,
int
nents
,
int
dir
)
{
struct
scatterlist
*
s
;
int
i
;
for
(
i
=
0
;
i
<
nents
;
i
++
)
{
struct
scatterlist
*
s
=
&
sg
[
i
];
for_each_sg
(
sg
,
s
,
nents
,
i
)
{
if
(
!
s
->
dma_length
||
!
s
->
length
)
break
;
gart_unmap_single
(
dev
,
s
->
dma_address
,
s
->
dma_length
,
dir
);
...
...
@@ -292,14 +293,14 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
static
int
dma_map_sg_nonforce
(
struct
device
*
dev
,
struct
scatterlist
*
sg
,
int
nents
,
int
dir
)
{
struct
scatterlist
*
s
;
int
i
;
#ifdef CONFIG_IOMMU_DEBUG
printk
(
KERN_DEBUG
"dma_map_sg overflow
\n
"
);
#endif
for
(
i
=
0
;
i
<
nents
;
i
++
)
{
struct
scatterlist
*
s
=
&
sg
[
i
];
for_each_sg
(
sg
,
s
,
nents
,
i
)
{
unsigned
long
addr
=
page_to_phys
(
s
->
page
)
+
s
->
offset
;
if
(
nonforced_iommu
(
dev
,
addr
,
s
->
length
))
{
addr
=
dma_map_area
(
dev
,
addr
,
s
->
length
,
dir
);
...
...
@@ -319,23 +320,23 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
}
/* Map multiple scatterlist entries continuous into the first. */
static
int
__dma_map_cont
(
struct
scatterlist
*
s
g
,
int
start
,
int
stopat
,
static
int
__dma_map_cont
(
struct
scatterlist
*
s
tart
,
int
nelems
,
struct
scatterlist
*
sout
,
unsigned
long
pages
)
{
unsigned
long
iommu_start
=
alloc_iommu
(
pages
);
unsigned
long
iommu_page
=
iommu_start
;
struct
scatterlist
*
s
;
int
i
;
if
(
iommu_start
==
-
1
)
return
-
1
;
for
(
i
=
start
;
i
<
stopat
;
i
++
)
{
struct
scatterlist
*
s
=
&
sg
[
i
];
for_each_sg
(
start
,
s
,
nelems
,
i
)
{
unsigned
long
pages
,
addr
;
unsigned
long
phys_addr
=
s
->
dma_address
;
BUG_ON
(
i
>
start
&&
s
->
offset
);
if
(
i
==
start
)
{
BUG_ON
(
s
!=
start
&&
s
->
offset
);
if
(
s
==
start
)
{
*
sout
=
*
s
;
sout
->
dma_address
=
iommu_bus_base
;
sout
->
dma_address
+=
iommu_page
*
PAGE_SIZE
+
s
->
offset
;
...
...
@@ -357,17 +358,17 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
return
0
;
}
static
inline
int
dma_map_cont
(
struct
scatterlist
*
s
g
,
int
start
,
int
stopat
,
static
inline
int
dma_map_cont
(
struct
scatterlist
*
s
tart
,
int
nelems
,
struct
scatterlist
*
sout
,
unsigned
long
pages
,
int
need
)
{
if
(
!
need
)
{
BUG_ON
(
stopat
-
start
!=
1
);
*
sout
=
sg
[
start
];
sout
->
dma_length
=
s
g
[
start
].
length
;
if
(
!
need
)
{
BUG_ON
(
nelems
!=
1
);
*
sout
=
*
start
;
sout
->
dma_length
=
s
tart
->
length
;
return
0
;
}
return
__dma_map_cont
(
s
g
,
start
,
stopat
,
sout
,
pages
);
}
return
__dma_map_cont
(
s
tart
,
nelems
,
sout
,
pages
);
}
/*
...
...
@@ -381,6 +382,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
int
start
;
unsigned
long
pages
=
0
;
int
need
=
0
,
nextneed
;
struct
scatterlist
*
s
,
*
ps
,
*
start_sg
,
*
sgmap
;
if
(
nents
==
0
)
return
0
;
...
...
@@ -390,8 +392,9 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
out
=
0
;
start
=
0
;
for
(
i
=
0
;
i
<
nents
;
i
++
)
{
struct
scatterlist
*
s
=
&
sg
[
i
];
start_sg
=
sgmap
=
sg
;
ps
=
NULL
;
/* shut up gcc */
for_each_sg
(
sg
,
s
,
nents
,
i
)
{
dma_addr_t
addr
=
page_to_phys
(
s
->
page
)
+
s
->
offset
;
s
->
dma_address
=
addr
;
BUG_ON
(
s
->
length
==
0
);
...
...
@@ -400,29 +403,33 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
/* Handle the previous not yet processed entries */
if
(
i
>
start
)
{
struct
scatterlist
*
ps
=
&
sg
[
i
-
1
];
/* Can only merge when the last chunk ends on a page
boundary and the new one doesn't have an offset. */
if
(
!
iommu_merge
||
!
nextneed
||
!
need
||
s
->
offset
||
(
ps
->
offset
+
ps
->
length
)
%
PAGE_SIZE
)
{
if
(
dma_map_cont
(
s
g
,
start
,
i
,
sg
+
out
,
pages
,
need
)
<
0
)
(
ps
->
offset
+
ps
->
length
)
%
PAGE_SIZE
)
{
if
(
dma_map_cont
(
s
tart_sg
,
i
-
start
,
sgmap
,
pages
,
need
)
<
0
)
goto
error
;
out
++
;
sgmap
=
sg_next
(
sgmap
);
pages
=
0
;
start
=
i
;
start
=
i
;
start_sg
=
s
;
}
}
need
=
nextneed
;
pages
+=
to_pages
(
s
->
offset
,
s
->
length
);
ps
=
s
;
}
if
(
dma_map_cont
(
s
g
,
start
,
i
,
sg
+
out
,
pages
,
need
)
<
0
)
if
(
dma_map_cont
(
s
tart_sg
,
i
-
start
,
sgmap
,
pages
,
need
)
<
0
)
goto
error
;
out
++
;
flush_gart
();
if
(
out
<
nents
)
sg
[
out
].
dma_length
=
0
;
if
(
out
<
nents
)
{
sgmap
=
sg_next
(
sgmap
);
sgmap
->
dma_length
=
0
;
}
return
out
;
error:
...
...
@@ -437,8 +444,8 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
if
(
panic_on_overflow
)
panic
(
"dma_map_sg: overflow on %lu pages
\n
"
,
pages
);
iommu_full
(
dev
,
pages
<<
PAGE_SHIFT
,
dir
);
for
(
i
=
0
;
i
<
nents
;
i
++
)
s
g
[
i
].
dma_address
=
bad_dma_address
;
for
_each_sg
(
sg
,
s
,
nents
,
i
)
s
->
dma_address
=
bad_dma_address
;
return
0
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录