Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
ecba38ab
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
ecba38ab
编写于
6月 23, 2006
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[NET] sunqe: Convert to new SBUS driver layer.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
52a34c7f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
219 addition
and
249 deletion
+219
-249
drivers/net/sunqe.c
drivers/net/sunqe.c
+219
-249
未找到文件。
drivers/net/sunqe.c
浏览文件 @
ecba38ab
/* $Id: sunqe.c,v 1.55 2002/01/15 06:48:55 davem Exp $
/* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver.
* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver.
* Once again I am out to prove that every ethernet
* Once again I am out to prove that every ethernet
* controller out there can be most efficiently programmed
* controller out there can be most efficiently programmed
* if you make it look like a LANCE.
* if you make it look like a LANCE.
*
*
* Copyright (C) 1996, 1999, 2003
David S. Miller (davem@redhat.com
)
* Copyright (C) 1996, 1999, 2003
, 2006 David S. Miller (davem@davemloft.net
)
*/
*/
#include <linux/module.h>
#include <linux/module.h>
...
@@ -41,9 +40,9 @@
...
@@ -41,9 +40,9 @@
#include "sunqe.h"
#include "sunqe.h"
#define DRV_NAME "sunqe"
#define DRV_NAME "sunqe"
#define DRV_VERSION "
3
.0"
#define DRV_VERSION "
4
.0"
#define DRV_RELDATE "
8/24/03
"
#define DRV_RELDATE "
June 23, 2006
"
#define DRV_AUTHOR "David S. Miller (davem@
redhat.com
)"
#define DRV_AUTHOR "David S. Miller (davem@
davemloft.net
)"
static
char
version
[]
=
static
char
version
[]
=
DRV_NAME
".c:v"
DRV_VERSION
" "
DRV_RELDATE
" "
DRV_AUTHOR
"
\n
"
;
DRV_NAME
".c:v"
DRV_VERSION
" "
DRV_RELDATE
" "
DRV_AUTHOR
"
\n
"
;
...
@@ -755,298 +754,269 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
...
@@ -755,298 +754,269 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
qecp
->
gregs
+
GLOB_RSIZE
);
qecp
->
gregs
+
GLOB_RSIZE
);
}
}
/* Four QE's per QEC card. */
static
u8
__init
qec_get_burst
(
struct
device_node
*
dp
)
static
int
__init
qec_ether_init
(
struct
net_device
*
dev
,
struct
sbus_dev
*
sdev
)
{
{
static
unsigned
version_printed
;
struct
net_device
*
qe_devs
[
4
];
struct
sunqe
*
qeps
[
4
];
struct
sbus_dev
*
qesdevs
[
4
];
struct
sbus_dev
*
child
;
struct
sunqec
*
qecp
=
NULL
;
u8
bsizes
,
bsizes_more
;
u8
bsizes
,
bsizes_more
;
int
i
,
j
,
res
=
-
ENOMEM
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* Find and set the burst sizes for the QEC, since it
qe_devs
[
i
]
=
alloc_etherdev
(
sizeof
(
struct
sunqe
));
* does the actual dma for all 4 channels.
if
(
!
qe_devs
[
i
])
*/
goto
out
;
bsizes
=
of_getintprop_default
(
dp
,
"burst-sizes"
,
0xff
);
}
bsizes
&=
0xff
;
bsizes_more
=
of_getintprop_default
(
dp
->
parent
,
"burst-sizes"
,
0xff
);
if
(
version_printed
++
==
0
)
if
(
bsizes_more
!=
0xff
)
printk
(
KERN_INFO
"%s"
,
version
);
bsizes
&=
bsizes_more
;
if
(
bsizes
==
0xff
||
(
bsizes
&
DMA_BURST16
)
==
0
||
(
bsizes
&
DMA_BURST32
)
==
0
)
bsizes
=
(
DMA_BURST32
-
1
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
return
bsizes
;
qeps
[
i
]
=
(
struct
sunqe
*
)
qe_devs
[
i
]
->
priv
;
}
for
(
j
=
0
;
j
<
6
;
j
++
)
qe_devs
[
i
]
->
dev_addr
[
j
]
=
idprom
->
id_ethaddr
[
j
];
qeps
[
i
]
->
channel
=
i
;
spin_lock_init
(
&
qeps
[
i
]
->
lock
);
}
qecp
=
kmalloc
(
sizeof
(
struct
sunqec
),
GFP_KERNEL
);
static
struct
sunqec
*
__init
get_qec
(
struct
sbus_dev
*
child_sdev
)
if
(
qecp
==
NULL
)
{
goto
out1
;
struct
sbus_dev
*
qec_sdev
=
child_sdev
->
parent
;
qecp
->
qec_sdev
=
sdev
;
struct
sunqec
*
qecp
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
for
(
qecp
=
root_qec_dev
;
qecp
;
qecp
=
qecp
->
next_module
)
{
qecp
->
qes
[
i
]
=
qeps
[
i
];
if
(
qecp
->
qec_sdev
==
qec_sdev
)
qeps
[
i
]
->
dev
=
qe_devs
[
i
];
break
;
qeps
[
i
]
->
parent
=
qecp
;
}
}
if
(
!
qecp
)
{
qecp
=
kzalloc
(
sizeof
(
struct
sunqec
),
GFP_KERNEL
);
if
(
qecp
)
{
u32
ctrl
;
qecp
->
qec_sdev
=
qec_sdev
;
qecp
->
gregs
=
sbus_ioremap
(
&
qec_sdev
->
resource
[
0
],
0
,
GLOB_REG_SIZE
,
"QEC Global Registers"
);
if
(
!
qecp
->
gregs
)
goto
fail
;
/* Make sure the QEC is in MACE mode. */
ctrl
=
sbus_readl
(
qecp
->
gregs
+
GLOB_CTRL
);
ctrl
&=
0xf0000000
;
if
(
ctrl
!=
GLOB_CTRL_MMODE
)
{
printk
(
KERN_ERR
"qec: Not in MACE mode!
\n
"
);
goto
fail
;
}
res
=
-
ENODEV
;
if
(
qec_global_reset
(
qecp
->
gregs
))
goto
fail
;
for
(
i
=
0
,
child
=
sdev
->
child
;
i
<
4
;
i
++
,
child
=
child
->
next
)
{
qecp
->
qec_bursts
=
qec_get_burst
(
qec_sdev
->
ofdev
.
node
);
/* Link in channel */
j
=
prom_getintdefault
(
child
->
prom_node
,
"channel#"
,
-
1
);
if
(
j
==
-
1
)
goto
out2
;
qesdevs
[
j
]
=
child
;
}
for
(
i
=
0
;
i
<
4
;
i
++
)
qec_init_once
(
qecp
,
qec_sdev
);
qeps
[
i
]
->
qe_sdev
=
qesdevs
[
i
];
/* Now map in the registers, QEC globals first. */
if
(
request_irq
(
qec_sdev
->
irqs
[
0
],
&
qec_interrupt
,
qecp
->
gregs
=
sbus_ioremap
(
&
sdev
->
resource
[
0
],
0
,
SA_SHIRQ
,
"qec"
,
(
void
*
)
qecp
))
{
GLOB_REG_SIZE
,
"QEC Global Registers"
);
printk
(
KERN_ERR
"qec: Can't register irq.
\n
"
);
if
(
!
qecp
->
gregs
)
{
goto
fail
;
printk
(
KERN_ERR
"QuadEther: Cannot map QEC global registers.
\n
"
);
}
goto
out2
;
}
/* Make sure the QEC is in MACE mode. */
qecp
->
next_module
=
root_qec_dev
;
if
((
sbus_readl
(
qecp
->
gregs
+
GLOB_CTRL
)
&
0xf0000000
)
!=
GLOB_CTRL_MMODE
)
{
root_qec_dev
=
qecp
;
printk
(
KERN_ERR
"QuadEther: AIEEE, QEC is not in MACE mode!
\n
"
);
}
goto
out3
;
}
}
/* Reset the QEC. */
return
qecp
;
if
(
qec_global_reset
(
qecp
->
gregs
))
goto
out3
;
/* Find and set the burst sizes for the QEC, since it does
fail:
* the actual dma for all 4 channels.
if
(
qecp
->
gregs
)
*/
sbus_iounmap
(
qecp
->
gregs
,
GLOB_REG_SIZE
);
bsizes
=
prom_getintdefault
(
sdev
->
prom_node
,
"burst-sizes"
,
0xff
);
kfree
(
qecp
);
bsizes
&=
0xff
;
return
NULL
;
bsizes_more
=
prom_getintdefault
(
sdev
->
bus
->
prom_node
,
"burst-sizes"
,
0xff
);
}
if
(
bsizes_more
!=
0xff
)
static
int
__init
qec_ether_init
(
struct
sbus_dev
*
sdev
)
bsizes
&=
bsizes_more
;
{
if
(
bsizes
==
0xff
||
(
bsizes
&
DMA_BURST16
)
==
0
||
static
unsigned
version_printed
;
(
bsizes
&
DMA_BURST32
)
==
0
)
struct
net_device
*
dev
;
bsizes
=
(
DMA_BURST32
-
1
);
struct
sunqe
*
qe
;
struct
sunqec
*
qecp
;
int
i
,
res
;
qecp
->
qec_bursts
=
bsizes
;
if
(
version_printed
++
==
0
)
printk
(
KERN_INFO
"%s"
,
version
);
/* Perform one time QEC initialization, we never touch the QEC
dev
=
alloc_etherdev
(
sizeof
(
struct
sunqe
));
* globals again after this.
if
(
!
dev
)
*/
return
-
ENOMEM
;
qec_init_once
(
qecp
,
sdev
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
struct
sunqe
*
qe
=
qeps
[
i
];
/* Map in QEC per-channel control registers. */
qe
->
qcregs
=
sbus_ioremap
(
&
qe
->
qe_sdev
->
resource
[
0
],
0
,
CREG_REG_SIZE
,
"QEC Channel Registers"
);
if
(
!
qe
->
qcregs
)
{
printk
(
KERN_ERR
"QuadEther: Cannot map QE %d's channel registers.
\n
"
,
i
);
goto
out4
;
}
/* Map in per-channel AMD MACE registers. */
qe
=
netdev_priv
(
dev
);
qe
->
mregs
=
sbus_ioremap
(
&
qe
->
qe_sdev
->
resource
[
1
],
0
,
MREGS_REG_SIZE
,
"QE MACE Registers"
);
if
(
!
qe
->
mregs
)
{
printk
(
KERN_ERR
"QuadEther: Cannot map QE %d's MACE registers.
\n
"
,
i
);
goto
out4
;
}
qe
->
qe_block
=
sbus_alloc_consistent
(
qe
->
qe_sdev
,
i
=
of_getintprop_default
(
sdev
->
ofdev
.
node
,
"channel#"
,
-
1
);
PAGE_SIZE
,
if
(
i
==
-
1
)
{
&
qe
->
qblock_dvma
);
struct
sbus_dev
*
td
=
sdev
->
parent
->
child
;
qe
->
buffers
=
sbus_alloc_consistent
(
qe
->
qe_sdev
,
i
=
0
;
sizeof
(
struct
sunqe_buffers
),
while
(
td
!=
sdev
)
{
&
qe
->
buffers_dvma
);
td
=
td
->
next
;
if
(
qe
->
qe_block
==
NULL
||
qe
->
qblock_dvma
==
0
||
i
++
;
qe
->
buffers
==
NULL
||
qe
->
buffers_dvma
==
0
)
{
goto
out4
;
}
}
/* Stop this QE. */
qe_stop
(
qe
);
}
}
qe
->
channel
=
i
;
spin_lock_init
(
&
qe
->
lock
);
res
=
-
ENODEV
;
qecp
=
get_qec
(
sdev
);
if
(
!
qecp
)
goto
fail
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
qecp
->
qes
[
qe
->
channel
]
=
qe
;
SET_MODULE_OWNER
(
qe_devs
[
i
]);
qe
->
dev
=
dev
;
qe_devs
[
i
]
->
open
=
qe_open
;
qe
->
parent
=
qecp
;
qe_devs
[
i
]
->
stop
=
qe_close
;
qe
->
qe_sdev
=
sdev
;
qe_devs
[
i
]
->
hard_start_xmit
=
qe_start_xmit
;
qe_devs
[
i
]
->
get_stats
=
qe_get_stats
;
qe_devs
[
i
]
->
set_multicast_list
=
qe_set_multicast
;
qe_devs
[
i
]
->
tx_timeout
=
qe_tx_timeout
;
qe_devs
[
i
]
->
watchdog_timeo
=
5
*
HZ
;
qe_devs
[
i
]
->
irq
=
sdev
->
irqs
[
0
];
qe_devs
[
i
]
->
dma
=
0
;
qe_devs
[
i
]
->
ethtool_ops
=
&
qe_ethtool_ops
;
}
/* QEC receives interrupts from each QE, then it sends the actual
res
=
-
ENOMEM
;
* IRQ to the cpu itself. Since QEC is the single point of
qe
->
qcregs
=
sbus_ioremap
(
&
qe
->
qe_sdev
->
resource
[
0
],
0
,
* interrupt for all QE channels we register the IRQ handler
CREG_REG_SIZE
,
"QEC Channel Registers"
);
* for it now.
if
(
!
qe
->
qcregs
)
{
*/
printk
(
KERN_ERR
"qe: Cannot map channel registers.
\n
"
);
if
(
request_irq
(
sdev
->
irqs
[
0
],
&
qec_interrupt
,
goto
fail
;
SA_SHIRQ
,
"QuadEther"
,
(
void
*
)
qecp
))
{
printk
(
KERN_ERR
"QuadEther: Can't register QEC master irq handler.
\n
"
);
res
=
-
EAGAIN
;
goto
out4
;
}
}
for
(
i
=
0
;
i
<
4
;
i
++
)
{
qe
->
mregs
=
sbus_ioremap
(
&
qe
->
qe_sdev
->
resource
[
1
],
0
,
if
(
register_netdev
(
qe_devs
[
i
])
!=
0
)
MREGS_REG_SIZE
,
"QE MACE Registers"
);
goto
out5
;
if
(
!
qe
->
mregs
)
{
printk
(
KERN_ERR
"qe: Cannot map MACE registers.
\n
"
);
goto
fail
;
}
}
/* Report the QE channels. */
qe
->
qe_block
=
sbus_alloc_consistent
(
qe
->
qe_sdev
,
for
(
i
=
0
;
i
<
4
;
i
++
)
{
PAGE_SIZE
,
printk
(
KERN_INFO
"%s: QuadEthernet channel[%d] "
,
qe_devs
[
i
]
->
name
,
i
);
&
qe
->
qblock_dvma
);
for
(
j
=
0
;
j
<
6
;
j
++
)
qe
->
buffers
=
sbus_alloc_consistent
(
qe
->
qe_sdev
,
printk
(
"%2.2x%c"
,
sizeof
(
struct
sunqe_buffers
),
qe_devs
[
i
]
->
dev_addr
[
j
],
&
qe
->
buffers_dvma
);
j
==
5
?
' '
:
':'
);
if
(
qe
->
qe_block
==
NULL
||
qe
->
qblock_dvma
==
0
||
printk
(
"
\n
"
);
qe
->
buffers
==
NULL
||
qe
->
buffers_dvma
==
0
)
}
goto
fail
;
/* Stop this QE. */
qe_stop
(
qe
);
SET_MODULE_OWNER
(
dev
);
SET_NETDEV_DEV
(
dev
,
&
sdev
->
ofdev
.
dev
);
dev
->
open
=
qe_open
;
dev
->
stop
=
qe_close
;
dev
->
hard_start_xmit
=
qe_start_xmit
;
dev
->
get_stats
=
qe_get_stats
;
dev
->
set_multicast_list
=
qe_set_multicast
;
dev
->
tx_timeout
=
qe_tx_timeout
;
dev
->
watchdog_timeo
=
5
*
HZ
;
dev
->
irq
=
sdev
->
irqs
[
0
];
dev
->
dma
=
0
;
dev
->
ethtool_ops
=
&
qe_ethtool_ops
;
res
=
register_netdev
(
dev
);
if
(
res
)
goto
fail
;
dev_set_drvdata
(
&
sdev
->
ofdev
.
dev
,
qe
);
printk
(
KERN_INFO
"%s: qe channel[%d] "
,
dev
->
name
,
qe
->
channel
);
for
(
i
=
0
;
i
<
6
;
i
++
)
printk
(
"%2.2x%c"
,
dev
->
dev_addr
[
i
],
i
==
5
?
' '
:
':'
);
printk
(
"
\n
"
);
/* We are home free at this point, link the qe's into
* the master list for later driver exit.
*/
qecp
->
next_module
=
root_qec_dev
;
root_qec_dev
=
qecp
;
return
0
;
return
0
;
out5:
fail:
while
(
i
--
)
if
(
qe
->
qcregs
)
unregister_netdev
(
qe_devs
[
i
]);
sbus_iounmap
(
qe
->
qcregs
,
CREG_REG_SIZE
);
free_irq
(
sdev
->
irqs
[
0
],
(
void
*
)
qecp
);
if
(
qe
->
mregs
)
out4:
sbus_iounmap
(
qe
->
mregs
,
MREGS_REG_SIZE
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
qe
->
qe_block
)
struct
sunqe
*
qe
=
(
struct
sunqe
*
)
qe_devs
[
i
]
->
priv
;
sbus_free_consistent
(
qe
->
qe_sdev
,
PAGE_SIZE
,
if
(
qe
->
qcregs
)
qe
->
qe_block
,
sbus_iounmap
(
qe
->
qcregs
,
CREG_REG_SIZE
);
qe
->
qblock_dvma
);
if
(
qe
->
mregs
)
if
(
qe
->
buffers
)
sbus_iounmap
(
qe
->
mregs
,
MREGS_REG_SIZE
);
sbus_free_consistent
(
qe
->
qe_sdev
,
if
(
qe
->
qe_block
)
sizeof
(
struct
sunqe_buffers
),
sbus_free_consistent
(
qe
->
qe_sdev
,
qe
->
buffers
,
PAGE_SIZE
,
qe
->
buffers_dvma
);
qe
->
qe_block
,
qe
->
qblock_dvma
);
free_netdev
(
dev
);
if
(
qe
->
buffers
)
sbus_free_consistent
(
qe
->
qe_sdev
,
sizeof
(
struct
sunqe_buffers
),
qe
->
buffers
,
qe
->
buffers_dvma
);
}
out3:
sbus_iounmap
(
qecp
->
gregs
,
GLOB_REG_SIZE
);
out2:
kfree
(
qecp
);
out1:
i
=
4
;
out:
while
(
i
--
)
free_netdev
(
qe_devs
[
i
]);
return
res
;
return
res
;
}
}
static
int
__
init
qec_match
(
struct
sbus_dev
*
sdev
)
static
int
__
devinit
qec_sbus_probe
(
struct
of_device
*
dev
,
const
struct
of_device_id
*
match
)
{
{
struct
sbus_dev
*
sibling
;
struct
sbus_dev
*
sdev
=
to_sbus_device
(
&
dev
->
dev
);
int
i
;
if
(
strcmp
(
sdev
->
prom_name
,
"qec"
)
!=
0
)
return
0
;
/* QEC can be parent of either QuadEthernet or BigMAC
return
qec_ether_init
(
sdev
);
* children. Do not confuse this with qfe/SUNW,qfe
* which is a quad-happymeal card and handled by
* a different driver.
*/
sibling
=
sdev
->
child
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
sibling
==
NULL
)
return
0
;
if
(
strcmp
(
sibling
->
prom_name
,
"qe"
)
!=
0
)
return
0
;
sibling
=
sibling
->
next
;
}
return
1
;
}
}
static
int
__
init
qec_probe
(
void
)
static
int
__
devexit
qec_sbus_remove
(
struct
of_device
*
dev
)
{
{
struct
net_device
*
dev
=
NULL
;
struct
sunqe
*
qp
=
dev_get_drvdata
(
&
dev
->
dev
);
struct
sbus_bus
*
bus
;
struct
net_device
*
net_dev
=
qp
->
dev
;
struct
sbus_dev
*
sdev
=
NULL
;
static
int
called
;
unregister_netdevice
(
net_dev
);
int
cards
=
0
,
v
;
sbus_iounmap
(
qp
->
qcregs
,
CREG_REG_SIZE
);
root_qec_dev
=
NULL
;
sbus_iounmap
(
qp
->
mregs
,
MREGS_REG_SIZE
);
sbus_free_consistent
(
qp
->
qe_sdev
,
if
(
called
)
PAGE_SIZE
,
return
-
ENODEV
;
qp
->
qe_block
,
called
++
;
qp
->
qblock_dvma
);
sbus_free_consistent
(
qp
->
qe_sdev
,
for_each_sbus
(
bus
)
{
sizeof
(
struct
sunqe_buffers
),
for_each_sbusdev
(
sdev
,
bus
)
{
qp
->
buffers
,
if
(
cards
)
qp
->
buffers_dvma
);
dev
=
NULL
;
free_netdev
(
net_dev
);
if
(
qec_match
(
sdev
))
{
cards
++
;
dev_set_drvdata
(
&
dev
->
dev
,
NULL
);
if
((
v
=
qec_ether_init
(
dev
,
sdev
)))
return
v
;
}
}
}
if
(
!
cards
)
return
-
ENODEV
;
return
0
;
return
0
;
}
}
static
void
__exit
qec_cleanup
(
void
)
static
struct
of_device_id
qec_sbus_match
[]
=
{
{
.
name
=
"qe"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
qec_sbus_match
);
static
struct
of_platform_driver
qec_sbus_driver
=
{
.
name
=
"qec"
,
.
match_table
=
qec_sbus_match
,
.
probe
=
qec_sbus_probe
,
.
remove
=
__devexit_p
(
qec_sbus_remove
),
};
static
int
__init
qec_init
(
void
)
{
return
of_register_driver
(
&
qec_sbus_driver
,
&
sbus_bus_type
);
}
static
void
__exit
qec_exit
(
void
)
{
{
struct
sunqec
*
next_qec
;
of_unregister_driver
(
&
qec_sbus_driver
);
int
i
;
while
(
root_qec_dev
)
{
while
(
root_qec_dev
)
{
next_qec
=
root_qec_dev
->
next_module
;
struct
sunqec
*
next
=
root_qec_dev
->
next_module
;
/* Release all four QE channels, then the QEC itself. */
free_irq
(
root_qec_dev
->
qec_sdev
->
irqs
[
0
],
for
(
i
=
0
;
i
<
4
;
i
++
)
{
(
void
*
)
root_qec_dev
);
unregister_netdev
(
root_qec_dev
->
qes
[
i
]
->
dev
);
sbus_iounmap
(
root_qec_dev
->
qes
[
i
]
->
qcregs
,
CREG_REG_SIZE
);
sbus_iounmap
(
root_qec_dev
->
qes
[
i
]
->
mregs
,
MREGS_REG_SIZE
);
sbus_free_consistent
(
root_qec_dev
->
qes
[
i
]
->
qe_sdev
,
PAGE_SIZE
,
root_qec_dev
->
qes
[
i
]
->
qe_block
,
root_qec_dev
->
qes
[
i
]
->
qblock_dvma
);
sbus_free_consistent
(
root_qec_dev
->
qes
[
i
]
->
qe_sdev
,
sizeof
(
struct
sunqe_buffers
),
root_qec_dev
->
qes
[
i
]
->
buffers
,
root_qec_dev
->
qes
[
i
]
->
buffers_dvma
);
free_netdev
(
root_qec_dev
->
qes
[
i
]
->
dev
);
}
free_irq
(
root_qec_dev
->
qec_sdev
->
irqs
[
0
],
(
void
*
)
root_qec_dev
);
sbus_iounmap
(
root_qec_dev
->
gregs
,
GLOB_REG_SIZE
);
sbus_iounmap
(
root_qec_dev
->
gregs
,
GLOB_REG_SIZE
);
kfree
(
root_qec_dev
);
kfree
(
root_qec_dev
);
root_qec_dev
=
next_qec
;
root_qec_dev
=
next
;
}
}
}
}
module_init
(
qec_
probe
);
module_init
(
qec_
init
);
module_exit
(
qec_
cleanup
);
module_exit
(
qec_
exit
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录