Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
ab1f5e49
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ab1f5e49
编写于
8月 28, 2009
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
上级
3161e453
11ebd1bf
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
67 addition
and
53 deletion
+67
-53
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/ipw2200.c
+67
-53
未找到文件。
drivers/net/wireless/ipw2x00/ipw2200.c
浏览文件 @
ab1f5e49
...
...
@@ -2874,45 +2874,27 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
return
0
;
}
static
int
ipw_fw_dma_add_buffer
(
struct
ipw_priv
*
priv
,
u32
src_phys
,
u32
dest_address
,
u32
length
)
static
int
ipw_fw_dma_add_buffer
(
struct
ipw_priv
*
priv
,
dma_addr_t
*
src_address
,
int
nr
,
u32
dest_address
,
u32
len
)
{
u32
bytes_left
=
length
;
u32
src_offset
=
0
;
u32
dest_offset
=
0
;
int
status
=
0
;
int
ret
,
i
;
u32
size
;
IPW_DEBUG_FW
(
">>
\n
"
);
IPW_DEBUG_FW_INFO
(
"src_phys=0x%x dest_address=0x%x length=0x%x
\n
"
,
src_phys
,
dest_address
,
length
);
while
(
bytes_left
>
CB_MAX_LENGTH
)
{
status
=
ipw_fw_dma_add_command_block
(
priv
,
src_phys
+
src_offset
,
dest_address
+
dest_offset
,
CB_MAX_LENGTH
,
0
,
0
);
if
(
status
)
{
IPW_DEBUG_FW_INFO
(
"nr=%d dest_address=0x%x len=0x%x
\n
"
,
nr
,
dest_address
,
len
);
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
size
=
min_t
(
u32
,
len
-
i
*
CB_MAX_LENGTH
,
CB_MAX_LENGTH
);
ret
=
ipw_fw_dma_add_command_block
(
priv
,
src_address
[
i
],
dest_address
+
i
*
CB_MAX_LENGTH
,
size
,
0
,
0
);
if
(
ret
)
{
IPW_DEBUG_FW_INFO
(
": Failed
\n
"
);
return
-
1
;
}
else
IPW_DEBUG_FW_INFO
(
": Added new cb
\n
"
);
src_offset
+=
CB_MAX_LENGTH
;
dest_offset
+=
CB_MAX_LENGTH
;
bytes_left
-=
CB_MAX_LENGTH
;
}
/* add the buffer tail */
if
(
bytes_left
>
0
)
{
status
=
ipw_fw_dma_add_command_block
(
priv
,
src_phys
+
src_offset
,
dest_address
+
dest_offset
,
bytes_left
,
0
,
0
);
if
(
status
)
{
IPW_DEBUG_FW_INFO
(
": Failed on the buffer tail
\n
"
);
return
-
1
;
}
else
IPW_DEBUG_FW_INFO
(
": Adding new cb - the buffer tail
\n
"
);
}
IPW_DEBUG_FW
(
"<<
\n
"
);
...
...
@@ -3160,59 +3142,91 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
static
int
ipw_load_firmware
(
struct
ipw_priv
*
priv
,
u8
*
data
,
size_t
len
)
{
int
r
c
=
-
1
;
int
r
et
=
-
1
;
int
offset
=
0
;
struct
fw_chunk
*
chunk
;
dma_addr_t
shared_phys
;
u8
*
shared_virt
;
int
total_nr
=
0
;
int
i
;
struct
pci_pool
*
pool
;
u32
*
virts
[
CB_NUMBER_OF_ELEMENTS_SMALL
];
dma_addr_t
phys
[
CB_NUMBER_OF_ELEMENTS_SMALL
];
IPW_DEBUG_TRACE
(
"<< :
\n
"
);
shared_virt
=
pci_alloc_consistent
(
priv
->
pci_dev
,
len
,
&
shared_phys
);
if
(
!
shared_virt
)
pool
=
pci_pool_create
(
"ipw2200"
,
priv
->
pci_dev
,
CB_MAX_LENGTH
,
0
,
0
);
if
(
!
pool
)
{
IPW_ERROR
(
"pci_pool_create failed
\n
"
);
return
-
ENOMEM
;
memmove
(
shared_virt
,
data
,
len
);
}
/* Start the Dma */
r
c
=
ipw_fw_dma_enable
(
priv
);
r
et
=
ipw_fw_dma_enable
(
priv
);
/* the DMA is already ready this would be a bug. */
BUG_ON
(
priv
->
sram_desc
.
last_cb_index
>
0
);
do
{
u32
chunk_len
;
u8
*
start
;
int
size
;
int
nr
=
0
;
chunk
=
(
struct
fw_chunk
*
)(
data
+
offset
);
offset
+=
sizeof
(
struct
fw_chunk
);
chunk_len
=
le32_to_cpu
(
chunk
->
length
);
start
=
data
+
offset
;
nr
=
(
chunk_len
+
CB_MAX_LENGTH
-
1
)
/
CB_MAX_LENGTH
;
for
(
i
=
0
;
i
<
nr
;
i
++
)
{
virts
[
total_nr
]
=
pci_pool_alloc
(
pool
,
GFP_KERNEL
,
&
phys
[
total_nr
]);
if
(
!
virts
[
total_nr
])
{
ret
=
-
ENOMEM
;
goto
out
;
}
size
=
min_t
(
u32
,
chunk_len
-
i
*
CB_MAX_LENGTH
,
CB_MAX_LENGTH
);
memcpy
(
virts
[
total_nr
],
start
,
size
);
start
+=
size
;
total_nr
++
;
/* We don't support fw chunk larger than 64*8K */
BUG_ON
(
total_nr
>
CB_NUMBER_OF_ELEMENTS_SMALL
);
}
/* build DMA packet and queue up for sending */
/* dma to chunk->address, the chunk->length bytes from data +
* offeset*/
/* Dma loading */
r
c
=
ipw_fw_dma_add_buffer
(
priv
,
shared_phys
+
offset
,
le32_to_cpu
(
chunk
->
address
),
le32_to_cpu
(
chunk
->
length
)
);
if
(
r
c
)
{
r
et
=
ipw_fw_dma_add_buffer
(
priv
,
&
phys
[
total_nr
-
nr
]
,
nr
,
le32_to_cpu
(
chunk
->
address
),
chunk_len
);
if
(
r
et
)
{
IPW_DEBUG_INFO
(
"dmaAddBuffer Failed
\n
"
);
goto
out
;
}
offset
+=
le32_to_cpu
(
chunk
->
length
)
;
offset
+=
chunk_len
;
}
while
(
offset
<
len
);
/* Run the DMA and wait for the answer */
r
c
=
ipw_fw_dma_kick
(
priv
);
if
(
r
c
)
{
r
et
=
ipw_fw_dma_kick
(
priv
);
if
(
r
et
)
{
IPW_ERROR
(
"dmaKick Failed
\n
"
);
goto
out
;
}
r
c
=
ipw_fw_dma_wait
(
priv
);
if
(
r
c
)
{
r
et
=
ipw_fw_dma_wait
(
priv
);
if
(
r
et
)
{
IPW_ERROR
(
"dmaWaitSync Failed
\n
"
);
goto
out
;
}
out:
pci_free_consistent
(
priv
->
pci_dev
,
len
,
shared_virt
,
shared_phys
);
return
rc
;
out:
for
(
i
=
0
;
i
<
total_nr
;
i
++
)
pci_pool_free
(
pool
,
virts
[
i
],
phys
[
i
]);
pci_pool_destroy
(
pool
);
return
ret
;
}
/* stop nic */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录