Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ecd2a4c0
Commit
ecd2a4c0
authored
Apr 07, 2003
by
Alan Cox
Committed by
Linus Torvalds
Apr 07, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] first cut at scc.c for 2.5 locking
parent
3ba32a67
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
93 deletions
+81
-93
drivers/net/hamradio/scc.c
drivers/net/hamradio/scc.c
+81
-93
No files found.
drivers/net/hamradio/scc.c
View file @
ecd2a4c0
...
@@ -235,13 +235,14 @@ static io_port Vector_Latch;
...
@@ -235,13 +235,14 @@ static io_port Vector_Latch;
/* These provide interrupt save 2-step access to the Z8530 registers */
/* These provide interrupt save 2-step access to the Z8530 registers */
static
spinlock_t
iolock
;
/* Guards paired accesses */
static
inline
unsigned
char
InReg
(
io_port
port
,
unsigned
char
reg
)
static
inline
unsigned
char
InReg
(
io_port
port
,
unsigned
char
reg
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
char
r
;
unsigned
char
r
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
iolock
,
flags
);
cli
();
#ifdef SCC_LDELAY
#ifdef SCC_LDELAY
Outb
(
port
,
reg
);
Outb
(
port
,
reg
);
udelay
(
SCC_LDELAY
);
udelay
(
SCC_LDELAY
);
...
@@ -251,16 +252,15 @@ static inline unsigned char InReg(io_port port, unsigned char reg)
...
@@ -251,16 +252,15 @@ static inline unsigned char InReg(io_port port, unsigned char reg)
Outb
(
port
,
reg
);
Outb
(
port
,
reg
);
r
=
Inb
(
port
);
r
=
Inb
(
port
);
#endif
#endif
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
iolock
,
flags
);
return
r
;
return
r
;
}
}
static
inline
void
OutReg
(
io_port
port
,
unsigned
char
reg
,
unsigned
char
val
)
static
inline
void
OutReg
(
io_port
port
,
unsigned
char
reg
,
unsigned
char
val
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
iolock
,
flags
);
cli
();
#ifdef SCC_LDELAY
#ifdef SCC_LDELAY
Outb
(
port
,
reg
);
udelay
(
SCC_LDELAY
);
Outb
(
port
,
reg
);
udelay
(
SCC_LDELAY
);
Outb
(
port
,
val
);
udelay
(
SCC_LDELAY
);
Outb
(
port
,
val
);
udelay
(
SCC_LDELAY
);
...
@@ -268,7 +268,7 @@ static inline void OutReg(io_port port, unsigned char reg, unsigned char val)
...
@@ -268,7 +268,7 @@ static inline void OutReg(io_port port, unsigned char reg, unsigned char val)
Outb
(
port
,
reg
);
Outb
(
port
,
reg
);
Outb
(
port
,
val
);
Outb
(
port
,
val
);
#endif
#endif
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
iolock
,
flags
);
}
}
static
inline
void
wr
(
struct
scc_channel
*
scc
,
unsigned
char
reg
,
static
inline
void
wr
(
struct
scc_channel
*
scc
,
unsigned
char
reg
,
...
@@ -295,9 +295,7 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
...
@@ -295,9 +295,7 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
if
(
scc
->
tx_buff
!=
NULL
)
if
(
scc
->
tx_buff
!=
NULL
)
{
{
dev_kfree_skb
(
scc
->
tx_buff
);
dev_kfree_skb
(
scc
->
tx_buff
);
...
@@ -307,7 +305,7 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
...
@@ -307,7 +305,7 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
while
(
skb_queue_len
(
&
scc
->
tx_queue
))
while
(
skb_queue_len
(
&
scc
->
tx_queue
))
dev_kfree_skb
(
skb_dequeue
(
&
scc
->
tx_queue
));
dev_kfree_skb
(
skb_dequeue
(
&
scc
->
tx_queue
));
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
...
@@ -609,6 +607,7 @@ static inline void scc_spint(struct scc_channel *scc)
...
@@ -609,6 +607,7 @@ static inline void scc_spint(struct scc_channel *scc)
static
void
scc_isr_dispatch
(
struct
scc_channel
*
scc
,
int
vector
)
static
void
scc_isr_dispatch
(
struct
scc_channel
*
scc
,
int
vector
)
{
{
spin_lock
(
&
scc
->
lock
);
switch
(
vector
&
VECTOR_MASK
)
switch
(
vector
&
VECTOR_MASK
)
{
{
case
TXINT
:
scc_txint
(
scc
);
break
;
case
TXINT
:
scc_txint
(
scc
);
break
;
...
@@ -616,6 +615,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
...
@@ -616,6 +615,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
case
RXINT
:
scc_rxint
(
scc
);
break
;
case
RXINT
:
scc_rxint
(
scc
);
break
;
case
SPINT
:
scc_spint
(
scc
);
break
;
case
SPINT
:
scc_spint
(
scc
);
break
;
}
}
spin_unlock
(
&
scc
->
lock
);
}
}
/* If the card has a latch for the interrupt vector (like the PA0HZP card)
/* If the card has a latch for the interrupt vector (like the PA0HZP card)
...
@@ -722,12 +722,13 @@ static inline void set_brg(struct scc_channel *scc, unsigned int tc)
...
@@ -722,12 +722,13 @@ static inline void set_brg(struct scc_channel *scc, unsigned int tc)
static
inline
void
set_speed
(
struct
scc_channel
*
scc
)
static
inline
void
set_speed
(
struct
scc_channel
*
scc
)
{
{
disable_irq
(
scc
->
irq
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
if
(
scc
->
modem
.
speed
>
0
)
/* paranoia... */
if
(
scc
->
modem
.
speed
>
0
)
/* paranoia... */
set_brg
(
scc
,
(
unsigned
)
(
scc
->
clock
/
(
scc
->
modem
.
speed
*
64
))
-
2
);
set_brg
(
scc
,
(
unsigned
)
(
scc
->
clock
/
(
scc
->
modem
.
speed
*
64
))
-
2
);
enable_irq
(
scc
->
irq
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
...
@@ -988,14 +989,8 @@ static void scc_key_trx(struct scc_channel *scc, char tx)
...
@@ -988,14 +989,8 @@ static void scc_key_trx(struct scc_channel *scc, char tx)
/* ----> SCC timer interrupt handler and friends. <---- */
/* ----> SCC timer interrupt handler and friends. <---- */
static
void
scc_start_tx_timer
(
struct
scc_channel
*
scc
,
void
(
*
handler
)(
unsigned
long
),
unsigned
long
when
)
static
void
__
scc_start_tx_timer
(
struct
scc_channel
*
scc
,
void
(
*
handler
)(
unsigned
long
),
unsigned
long
when
)
{
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
del_timer
(
&
scc
->
tx_t
);
del_timer
(
&
scc
->
tx_t
);
if
(
when
==
0
)
if
(
when
==
0
)
...
@@ -1009,17 +1004,22 @@ static void scc_start_tx_timer(struct scc_channel *scc, void (*handler)(unsigned
...
@@ -1009,17 +1004,22 @@ static void scc_start_tx_timer(struct scc_channel *scc, void (*handler)(unsigned
scc
->
tx_t
.
expires
=
jiffies
+
(
when
*
HZ
)
/
100
;
scc
->
tx_t
.
expires
=
jiffies
+
(
when
*
HZ
)
/
100
;
add_timer
(
&
scc
->
tx_t
);
add_timer
(
&
scc
->
tx_t
);
}
}
}
static
void
scc_start_tx_timer
(
struct
scc_channel
*
scc
,
void
(
*
handler
)(
unsigned
long
),
unsigned
long
when
)
{
unsigned
long
flags
;
restore_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
__scc_start_tx_timer
(
scc
,
handler
,
when
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
static
void
scc_start_defer
(
struct
scc_channel
*
scc
)
static
void
scc_start_defer
(
struct
scc_channel
*
scc
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
del_timer
(
&
scc
->
tx_wdog
);
del_timer
(
&
scc
->
tx_wdog
);
if
(
scc
->
kiss
.
maxdefer
!=
0
&&
scc
->
kiss
.
maxdefer
!=
TIMER_OFF
)
if
(
scc
->
kiss
.
maxdefer
!=
0
&&
scc
->
kiss
.
maxdefer
!=
TIMER_OFF
)
...
@@ -1029,16 +1029,14 @@ static void scc_start_defer(struct scc_channel *scc)
...
@@ -1029,16 +1029,14 @@ static void scc_start_defer(struct scc_channel *scc)
scc
->
tx_wdog
.
expires
=
jiffies
+
HZ
*
scc
->
kiss
.
maxdefer
;
scc
->
tx_wdog
.
expires
=
jiffies
+
HZ
*
scc
->
kiss
.
maxdefer
;
add_timer
(
&
scc
->
tx_wdog
);
add_timer
(
&
scc
->
tx_wdog
);
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
static
void
scc_start_maxkeyup
(
struct
scc_channel
*
scc
)
static
void
scc_start_maxkeyup
(
struct
scc_channel
*
scc
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
del_timer
(
&
scc
->
tx_wdog
);
del_timer
(
&
scc
->
tx_wdog
);
if
(
scc
->
kiss
.
maxkeyup
!=
0
&&
scc
->
kiss
.
maxkeyup
!=
TIMER_OFF
)
if
(
scc
->
kiss
.
maxkeyup
!=
0
&&
scc
->
kiss
.
maxkeyup
!=
TIMER_OFF
)
...
@@ -1048,8 +1046,7 @@ static void scc_start_maxkeyup(struct scc_channel *scc)
...
@@ -1048,8 +1046,7 @@ static void scc_start_maxkeyup(struct scc_channel *scc)
scc
->
tx_wdog
.
expires
=
jiffies
+
HZ
*
scc
->
kiss
.
maxkeyup
;
scc
->
tx_wdog
.
expires
=
jiffies
+
HZ
*
scc
->
kiss
.
maxkeyup
;
add_timer
(
&
scc
->
tx_wdog
);
add_timer
(
&
scc
->
tx_wdog
);
}
}
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
restore_flags
(
flags
);
}
}
/*
/*
...
@@ -1189,13 +1186,10 @@ static void t_tail(unsigned long channel)
...
@@ -1189,13 +1186,10 @@ static void t_tail(unsigned long channel)
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
del_timer
(
&
scc
->
tx_wdog
);
del_timer
(
&
scc
->
tx_wdog
);
scc_key_trx
(
scc
,
TX_OFF
);
scc_key_trx
(
scc
,
TX_OFF
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
restore_flags
(
flags
);
if
(
scc
->
stat
.
tx_state
==
TXS_TIMEOUT
)
/* we had a timeout? */
if
(
scc
->
stat
.
tx_state
==
TXS_TIMEOUT
)
/* we had a timeout? */
{
{
...
@@ -1242,9 +1236,7 @@ static void t_maxkeyup(unsigned long channel)
...
@@ -1242,9 +1236,7 @@ static void t_maxkeyup(unsigned long channel)
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
/*
/*
* let things settle down before we start to
* let things settle down before we start to
* accept new data.
* accept new data.
...
@@ -1259,7 +1251,7 @@ static void t_maxkeyup(unsigned long channel)
...
@@ -1259,7 +1251,7 @@ static void t_maxkeyup(unsigned long channel)
cl
(
scc
,
R15
,
TxUIE
);
/* count it. */
cl
(
scc
,
R15
,
TxUIE
);
/* count it. */
OutReg
(
scc
->
ctrl
,
R0
,
RES_Tx_P
);
OutReg
(
scc
->
ctrl
,
R0
,
RES_Tx_P
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
scc
->
stat
.
txerrs
++
;
scc
->
stat
.
txerrs
++
;
scc
->
stat
.
tx_state
=
TXS_TIMEOUT
;
scc
->
stat
.
tx_state
=
TXS_TIMEOUT
;
...
@@ -1289,13 +1281,10 @@ static void t_idle(unsigned long channel)
...
@@ -1289,13 +1281,10 @@ static void t_idle(unsigned long channel)
static
void
scc_init_timer
(
struct
scc_channel
*
scc
)
static
void
scc_init_timer
(
struct
scc_channel
*
scc
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
scc
->
stat
.
tx_state
=
TXS_IDLE
;
restore_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
scc
->
stat
.
tx_state
=
TXS_IDLE
;
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
...
@@ -1414,9 +1403,7 @@ static void scc_stop_calibrate(unsigned long channel)
...
@@ -1414,9 +1403,7 @@ static void scc_stop_calibrate(unsigned long channel)
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
struct
scc_channel
*
scc
=
(
struct
scc_channel
*
)
channel
;
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
del_timer
(
&
scc
->
tx_wdog
);
del_timer
(
&
scc
->
tx_wdog
);
scc_key_trx
(
scc
,
TX_OFF
);
scc_key_trx
(
scc
,
TX_OFF
);
wr
(
scc
,
R6
,
0
);
wr
(
scc
,
R6
,
0
);
...
@@ -1425,7 +1412,7 @@ static void scc_stop_calibrate(unsigned long channel)
...
@@ -1425,7 +1412,7 @@ static void scc_stop_calibrate(unsigned long channel)
Outb
(
scc
->
ctrl
,
RES_EXT_INT
);
Outb
(
scc
->
ctrl
,
RES_EXT_INT
);
netif_wake_queue
(
scc
->
dev
);
netif_wake_queue
(
scc
->
dev
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
...
@@ -1434,9 +1421,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
...
@@ -1434,9 +1421,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
{
{
unsigned
long
flags
;
unsigned
long
flags
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
netif_stop_queue
(
scc
->
dev
);
netif_stop_queue
(
scc
->
dev
);
scc_discard_buffers
(
scc
);
scc_discard_buffers
(
scc
);
...
@@ -1460,7 +1445,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
...
@@ -1460,7 +1445,7 @@ scc_start_calibrate(struct scc_channel *scc, int duration, unsigned char pattern
Outb
(
scc
->
ctrl
,
RES_EXT_INT
);
Outb
(
scc
->
ctrl
,
RES_EXT_INT
);
scc_key_trx
(
scc
,
TX_ON
);
scc_key_trx
(
scc
,
TX_ON
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
}
}
/* ******************************************************************* */
/* ******************************************************************* */
...
@@ -1508,16 +1493,14 @@ static void z8530_init(void)
...
@@ -1508,16 +1493,14 @@ static void z8530_init(void)
/* Reset and pre-init Z8530 */
/* Reset and pre-init Z8530 */
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
Outb
(
scc
->
ctrl
,
0
);
Outb
(
scc
->
ctrl
,
0
);
OutReg
(
scc
->
ctrl
,
R9
,
FHWRES
);
/* force hardware reset */
OutReg
(
scc
->
ctrl
,
R9
,
FHWRES
);
/* force hardware reset */
udelay
(
100
);
/* give it 'a bit' more time than required */
udelay
(
100
);
/* give it 'a bit' more time than required */
wr
(
scc
,
R2
,
chip
*
16
);
/* interrupt vector */
wr
(
scc
,
R2
,
chip
*
16
);
/* interrupt vector */
wr
(
scc
,
R9
,
VIS
);
/* vector includes status */
wr
(
scc
,
R9
,
VIS
);
/* vector includes status */
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
restore_flags
(
flags
);
}
}
...
@@ -1548,6 +1531,8 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev
...
@@ -1548,6 +1531,8 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev
dev
->
priv
=
(
void
*
)
scc
;
dev
->
priv
=
(
void
*
)
scc
;
dev
->
init
=
scc_net_init
;
dev
->
init
=
scc_net_init
;
spin_lock_init
(
&
scc
->
lock
);
if
((
addev
?
register_netdevice
(
dev
)
:
register_netdev
(
dev
))
!=
0
)
{
if
((
addev
?
register_netdevice
(
dev
)
:
register_netdev
(
dev
))
!=
0
)
{
kfree
(
dev
);
kfree
(
dev
);
return
-
EIO
;
return
-
EIO
;
...
@@ -1625,17 +1610,14 @@ static int scc_net_close(struct net_device *dev)
...
@@ -1625,17 +1610,14 @@ static int scc_net_close(struct net_device *dev)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
Outb
(
scc
->
ctrl
,
0
);
/* Make sure pointer is written */
Outb
(
scc
->
ctrl
,
0
);
/* Make sure pointer is written */
wr
(
scc
,
R1
,
0
);
/* disable interrupts */
wr
(
scc
,
R1
,
0
);
/* disable interrupts */
wr
(
scc
,
R3
,
0
);
wr
(
scc
,
R3
,
0
);
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
del_timer
(
&
scc
->
tx_t
);
del_timer_sync
(
&
scc
->
tx_t
);
del_timer
(
&
scc
->
tx_wdog
);
del_timer_sync
(
&
scc
->
tx_wdog
);
restore_flags
(
flags
);
scc_discard_buffers
(
scc
);
scc_discard_buffers
(
scc
);
...
@@ -1689,9 +1671,8 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
...
@@ -1689,9 +1671,8 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
return
0
;
return
0
;
}
}
save_flags
(
flags
);
spin_lock_irqsave
(
&
scc
->
lock
,
flags
);
cli
();
if
(
skb_queue_len
(
&
scc
->
tx_queue
)
>
scc
->
dev
->
tx_queue_len
)
{
if
(
skb_queue_len
(
&
scc
->
tx_queue
)
>
scc
->
dev
->
tx_queue_len
)
{
struct
sk_buff
*
skb_del
;
struct
sk_buff
*
skb_del
;
skb_del
=
skb_dequeue
(
&
scc
->
tx_queue
);
skb_del
=
skb_dequeue
(
&
scc
->
tx_queue
);
...
@@ -1710,12 +1691,11 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
...
@@ -1710,12 +1691,11 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
if
(
scc
->
stat
.
tx_state
==
TXS_IDLE
||
scc
->
stat
.
tx_state
==
TXS_IDLE2
)
{
if
(
scc
->
stat
.
tx_state
==
TXS_IDLE
||
scc
->
stat
.
tx_state
==
TXS_IDLE2
)
{
scc
->
stat
.
tx_state
=
TXS_BUSY
;
scc
->
stat
.
tx_state
=
TXS_BUSY
;
if
(
scc
->
kiss
.
fulldup
==
KISS_DUPLEX_HALF
)
if
(
scc
->
kiss
.
fulldup
==
KISS_DUPLEX_HALF
)
scc_start_tx_timer
(
scc
,
t_dwait
,
scc
->
kiss
.
waittime
);
__
scc_start_tx_timer
(
scc
,
t_dwait
,
scc
->
kiss
.
waittime
);
else
else
scc_start_tx_timer
(
scc
,
t_dwait
,
0
);
__
scc_start_tx_timer
(
scc
,
t_dwait
,
0
);
}
}
spin_unlock_irqrestore
(
&
scc
->
lock
,
flags
);
restore_flags
(
flags
);
return
0
;
return
0
;
}
}
...
@@ -1785,19 +1765,23 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
...
@@ -1785,19 +1765,23 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
hwcfg
.
clock
=
SCC_DEFAULT_CLOCK
;
hwcfg
.
clock
=
SCC_DEFAULT_CLOCK
;
#ifndef SCC_DONT_CHECK
#ifndef SCC_DONT_CHECK
disable_irq
(
hwcfg
.
irq
);
check_region
(
scc
->
ctrl
,
1
);
Outb
(
hwcfg
.
ctrl_a
,
0
);
OutReg
(
hwcfg
.
ctrl_a
,
R9
,
FHWRES
);
udelay
(
100
);
OutReg
(
hwcfg
.
ctrl_a
,
R13
,
0x55
);
/* is this chip really there? */
udelay
(
5
);
if
(
InReg
(
hwcfg
.
ctrl_a
,
R13
)
!=
0x55
)
if
(
request_region
(
scc
->
ctrl
,
1
,
"scc-probe"
))
{
disable_irq
(
hwcfg
.
irq
);
Outb
(
hwcfg
.
ctrl_a
,
0
);
OutReg
(
hwcfg
.
ctrl_a
,
R9
,
FHWRES
);
udelay
(
100
);
OutReg
(
hwcfg
.
ctrl_a
,
R13
,
0x55
);
/* is this chip really there? */
udelay
(
5
);
if
(
InReg
(
hwcfg
.
ctrl_a
,
R13
)
!=
0x55
)
found
=
0
;
enable_irq
(
hwcfg
.
irq
);
release_region
(
scc
->
ctrl
,
1
);
}
else
found
=
0
;
found
=
0
;
enable_irq
(
hwcfg
.
irq
);
#endif
#endif
if
(
found
)
if
(
found
)
...
@@ -2111,6 +2095,8 @@ static int __init scc_init_driver (void)
...
@@ -2111,6 +2095,8 @@ static int __init scc_init_driver (void)
printk
(
banner
);
printk
(
banner
);
spin_lock_init
(
&
iolock
);
sprintf
(
devname
,
"%s0"
,
SCC_DriverName
);
sprintf
(
devname
,
"%s0"
,
SCC_DriverName
);
result
=
scc_net_setup
(
SCC_Info
,
devname
,
0
);
result
=
scc_net_setup
(
SCC_Info
,
devname
,
0
);
...
@@ -2127,20 +2113,19 @@ static int __init scc_init_driver (void)
...
@@ -2127,20 +2113,19 @@ static int __init scc_init_driver (void)
static
void
__exit
scc_cleanup_driver
(
void
)
static
void
__exit
scc_cleanup_driver
(
void
)
{
{
unsigned
long
flags
;
io_port
ctrl
;
io_port
ctrl
;
int
k
;
int
k
;
struct
scc_channel
*
scc
;
struct
scc_channel
*
scc
;
save_flags
(
flags
);
cli
();
if
(
Nchips
==
0
)
if
(
Nchips
==
0
)
{
{
unregister_netdev
(
SCC_Info
[
0
].
dev
);
unregister_netdev
(
SCC_Info
[
0
].
dev
);
kfree
(
SCC_Info
[
0
].
dev
);
kfree
(
SCC_Info
[
0
].
dev
);
}
}
/* Guard against chip prattle */
local_irq_disable
();
for
(
k
=
0
;
k
<
Nchips
;
k
++
)
for
(
k
=
0
;
k
<
Nchips
;
k
++
)
if
(
(
ctrl
=
SCC_ctrl
[
k
].
chan_A
)
)
if
(
(
ctrl
=
SCC_ctrl
[
k
].
chan_A
)
)
{
{
...
@@ -2149,6 +2134,13 @@ static void __exit scc_cleanup_driver(void)
...
@@ -2149,6 +2134,13 @@ static void __exit scc_cleanup_driver(void)
udelay
(
50
);
udelay
(
50
);
}
}
/* To unload the port must be closed so no real IRQ pending */
for
(
k
=
0
;
k
<
NR_IRQS
;
k
++
)
if
(
Ivec
[
k
].
used
)
free_irq
(
k
,
NULL
);
local_irq_enable
();
/* Now clean up */
for
(
k
=
0
;
k
<
Nchips
*
2
;
k
++
)
for
(
k
=
0
;
k
<
Nchips
*
2
;
k
++
)
{
{
scc
=
&
SCC_Info
[
k
];
scc
=
&
SCC_Info
[
k
];
...
@@ -2164,14 +2156,10 @@ static void __exit scc_cleanup_driver(void)
...
@@ -2164,14 +2156,10 @@ static void __exit scc_cleanup_driver(void)
}
}
}
}
for
(
k
=
0
;
k
<
NR_IRQS
;
k
++
)
if
(
Ivec
[
k
].
used
)
free_irq
(
k
,
NULL
);
if
(
Vector_Latch
)
if
(
Vector_Latch
)
release_region
(
Vector_Latch
,
1
);
release_region
(
Vector_Latch
,
1
);
restore_flags
(
flags
);
proc_net_remove
(
"z8530drv"
);
proc_net_remove
(
"z8530drv"
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment