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
nexedi
linux
Commits
19177750
Commit
19177750
authored
Nov 25, 2002
by
Alan Cox
Committed by
Linus Torvalds
Nov 25, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] locking for dmascc
parent
bc66f155
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
34 deletions
+33
-34
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/dmascc.c
+33
-34
No files found.
drivers/net/hamradio/dmascc.c
View file @
19177750
...
@@ -235,6 +235,8 @@ struct scc_priv {
...
@@ -235,6 +235,8 @@ struct scc_priv {
int
state
;
int
state
;
unsigned
long
tx_start
;
unsigned
long
tx_start
;
int
rr0
;
int
rr0
;
spinlock_t
*
register_lock
;
/* Per scc_info */
spinlock_t
ring_lock
;
};
};
struct
scc_info
{
struct
scc_info
{
...
@@ -243,6 +245,7 @@ struct scc_info {
...
@@ -243,6 +245,7 @@ struct scc_info {
struct
net_device
dev
[
2
];
struct
net_device
dev
[
2
];
struct
scc_priv
priv
[
2
];
struct
scc_priv
priv
[
2
];
struct
scc_info
*
next
;
struct
scc_info
*
next
;
spinlock_t
register_lock
;
/* Per device register lock */
};
};
...
@@ -371,7 +374,7 @@ int __init dmascc_init(void) {
...
@@ -371,7 +374,7 @@ int __init dmascc_init(void) {
/* Cards found = 0 */
/* Cards found = 0 */
n
=
0
;
n
=
0
;
/* Warning message */
/* Warning message */
if
(
!
io
[
0
])
printk
(
"dmascc: autoprobing (dangerous)
\n
"
);
if
(
!
io
[
0
])
printk
(
KERN_INFO
"dmascc: autoprobing (dangerous)
\n
"
);
/* Run autodetection for each card type */
/* Run autodetection for each card type */
for
(
h
=
0
;
h
<
NUM_TYPES
;
h
++
)
{
for
(
h
=
0
;
h
<
NUM_TYPES
;
h
++
)
{
...
@@ -456,7 +459,7 @@ int __init dmascc_init(void) {
...
@@ -456,7 +459,7 @@ int __init dmascc_init(void) {
if
(
n
)
return
0
;
if
(
n
)
return
0
;
/* If no adapter found, return error */
/* If no adapter found, return error */
printk
(
"dmascc: no adapters found
\n
"
);
printk
(
KERN_INFO
"dmascc: no adapters found
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -475,18 +478,21 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -475,18 +478,21 @@ int __init setup_adapter(int card_base, int type, int n) {
/* Allocate memory */
/* Allocate memory */
info
=
kmalloc
(
sizeof
(
struct
scc_info
),
GFP_KERNEL
|
GFP_DMA
);
info
=
kmalloc
(
sizeof
(
struct
scc_info
),
GFP_KERNEL
|
GFP_DMA
);
if
(
!
info
)
{
if
(
!
info
)
{
printk
(
"dmascc: could not allocate memory for %s at %#3x
\n
"
,
printk
(
KERN_ERR
"dmascc: could not allocate memory for %s at %#3x
\n
"
,
hw
[
type
].
name
,
card_base
);
hw
[
type
].
name
,
card_base
);
return
-
1
;
return
-
1
;
}
}
/* Initialize what is necessary for write_scc and write_scc_data */
/* Initialize what is necessary for write_scc and write_scc_data */
memset
(
info
,
0
,
sizeof
(
struct
scc_info
));
memset
(
info
,
0
,
sizeof
(
struct
scc_info
));
spin_lock_init
(
&
info
->
register_lock
);
priv
=
&
info
->
priv
[
0
];
priv
=
&
info
->
priv
[
0
];
priv
->
type
=
type
;
priv
->
type
=
type
;
priv
->
card_base
=
card_base
;
priv
->
card_base
=
card_base
;
priv
->
scc_cmd
=
scc_base
+
SCCA_CMD
;
priv
->
scc_cmd
=
scc_base
+
SCCA_CMD
;
priv
->
scc_data
=
scc_base
+
SCCA_DATA
;
priv
->
scc_data
=
scc_base
+
SCCA_DATA
;
priv
->
register_lock
=
&
info
->
register_lock
;
/* Reset SCC */
/* Reset SCC */
write_scc
(
priv
,
R9
,
FHWRES
|
MIE
|
NV
);
write_scc
(
priv
,
R9
,
FHWRES
|
MIE
|
NV
);
...
@@ -510,7 +516,6 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -510,7 +516,6 @@ int __init setup_adapter(int card_base, int type, int n) {
write_scc
(
priv
,
R15
,
0
);
write_scc
(
priv
,
R15
,
0
);
/* Start IRQ auto-detection */
/* Start IRQ auto-detection */
sti
();
irqs
=
probe_irq_on
();
irqs
=
probe_irq_on
();
/* Enable interrupts */
/* Enable interrupts */
...
@@ -543,7 +548,7 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -543,7 +548,7 @@ int __init setup_adapter(int card_base, int type, int n) {
}
}
if
(
irq
<=
0
)
{
if
(
irq
<=
0
)
{
printk
(
"dmascc: could not find irq of %s at %#3x (irq=%d)
\n
"
,
printk
(
KERN_ERR
"dmascc: could not find irq of %s at %#3x (irq=%d)
\n
"
,
hw
[
type
].
name
,
card_base
,
irq
);
hw
[
type
].
name
,
card_base
,
irq
);
kfree
(
info
);
kfree
(
info
);
return
-
1
;
return
-
1
;
...
@@ -558,6 +563,8 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -558,6 +563,8 @@ int __init setup_adapter(int card_base, int type, int n) {
priv
->
dev
=
dev
;
priv
->
dev
=
dev
;
priv
->
info
=
info
;
priv
->
info
=
info
;
priv
->
channel
=
i
;
priv
->
channel
=
i
;
spin_lock_init
(
&
priv
->
ring_lock
);
priv
->
register_lock
=
&
info
->
register_lock
;
priv
->
card_base
=
card_base
;
priv
->
card_base
=
card_base
;
priv
->
scc_cmd
=
scc_base
+
(
i
?
SCCB_CMD
:
SCCA_CMD
);
priv
->
scc_cmd
=
scc_base
+
(
i
?
SCCB_CMD
:
SCCA_CMD
);
priv
->
scc_data
=
scc_base
+
(
i
?
SCCB_DATA
:
SCCA_DATA
);
priv
->
scc_data
=
scc_base
+
(
i
?
SCCB_DATA
:
SCCA_DATA
);
...
@@ -594,7 +601,7 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -594,7 +601,7 @@ int __init setup_adapter(int card_base, int type, int n) {
memcpy
(
dev
->
dev_addr
,
ax25_test
,
7
);
memcpy
(
dev
->
dev_addr
,
ax25_test
,
7
);
rtnl_lock
();
rtnl_lock
();
if
(
register_netdevice
(
dev
))
{
if
(
register_netdevice
(
dev
))
{
printk
(
"dmascc: could not register %s
\n
"
,
dev
->
name
);
printk
(
KERN_ERR
"dmascc: could not register %s
\n
"
,
dev
->
name
);
}
}
rtnl_unlock
();
rtnl_unlock
();
}
}
...
@@ -603,7 +610,7 @@ int __init setup_adapter(int card_base, int type, int n) {
...
@@ -603,7 +610,7 @@ int __init setup_adapter(int card_base, int type, int n) {
info
->
next
=
first
;
info
->
next
=
first
;
first
=
info
;
first
=
info
;
printk
(
"dmascc: found %s (%s) at %#3x, irq %d
\n
"
,
hw
[
type
].
name
,
printk
(
KERN_INFO
"dmascc: found %s (%s) at %#3x, irq %d
\n
"
,
hw
[
type
].
name
,
chipnames
[
chip
],
card_base
,
irq
);
chipnames
[
chip
],
card_base
,
irq
);
return
0
;
return
0
;
}
}
...
@@ -623,13 +630,12 @@ static void write_scc(struct scc_priv *priv, int reg, int val) {
...
@@ -623,13 +630,12 @@ static void write_scc(struct scc_priv *priv, int reg, int val) {
outb_p
(
val
,
priv
->
scc_cmd
);
outb_p
(
val
,
priv
->
scc_cmd
);
return
;
return
;
default:
default:
save_flags
(
flags
);
spin_lock_irqsave
(
priv
->
register_lock
,
flags
);
cli
();
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
outb_p
(
val
,
priv
->
scc_cmd
);
outb_p
(
val
,
priv
->
scc_cmd
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
priv
->
register_lock
,
flags
);
return
;
return
;
}
}
}
}
...
@@ -647,12 +653,11 @@ static void write_scc_data(struct scc_priv *priv, int val, int fast) {
...
@@ -647,12 +653,11 @@ static void write_scc_data(struct scc_priv *priv, int val, int fast) {
default:
default:
if
(
fast
)
outb_p
(
val
,
priv
->
scc_data
);
if
(
fast
)
outb_p
(
val
,
priv
->
scc_data
);
else
{
else
{
save_flags
(
flags
);
spin_lock_irqsave
(
priv
->
register_lock
,
flags
);
cli
();
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb_p
(
val
,
priv
->
scc_data
);
outb_p
(
val
,
priv
->
scc_data
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
priv
->
register_lock
,
flags
);
}
}
return
;
return
;
}
}
...
@@ -670,13 +675,12 @@ static int read_scc(struct scc_priv *priv, int reg) {
...
@@ -670,13 +675,12 @@ static int read_scc(struct scc_priv *priv, int reg) {
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
return
inb_p
(
priv
->
scc_cmd
);
return
inb_p
(
priv
->
scc_cmd
);
default:
default:
save_flags
(
flags
);
spin_lock_irqsave
(
&
priv
->
register_lock
,
flags
);
cli
();
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
if
(
reg
)
outb_p
(
reg
,
priv
->
scc_cmd
);
rc
=
inb_p
(
priv
->
scc_cmd
);
rc
=
inb_p
(
priv
->
scc_cmd
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
priv
->
register_lock
,
flags
);
return
rc
;
return
rc
;
}
}
}
}
...
@@ -691,12 +695,11 @@ static int read_scc_data(struct scc_priv *priv) {
...
@@ -691,12 +695,11 @@ static int read_scc_data(struct scc_priv *priv) {
case
TYPE_TWIN
:
case
TYPE_TWIN
:
return
inb_p
(
priv
->
scc_data
);
return
inb_p
(
priv
->
scc_data
);
default:
default:
save_flags
(
flags
);
spin_lock_irqsave
(
priv
->
register_lock
,
flags
);
cli
();
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb_p
(
0
,
priv
->
card_base
+
PI_DREQ_MASK
);
rc
=
inb_p
(
priv
->
scc_data
);
rc
=
inb_p
(
priv
->
scc_data
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
outb
(
1
,
priv
->
card_base
+
PI_DREQ_MASK
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
priv
->
register_lock
,
flags
);
return
rc
;
return
rc
;
}
}
}
}
...
@@ -905,9 +908,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
...
@@ -905,9 +908,8 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
priv
->
tx_len
[
i
]
=
skb
->
len
-
1
;
priv
->
tx_len
[
i
]
=
skb
->
len
-
1
;
/* Clear interrupts while we touch our circular buffers */
/* Clear interrupts while we touch our circular buffers */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
priv
->
ring_lock
,
flags
);
/* Move the ring buffer's head */
/* Move the ring buffer's head */
priv
->
tx_head
=
(
i
+
1
)
%
NUM_TX_BUF
;
priv
->
tx_head
=
(
i
+
1
)
%
NUM_TX_BUF
;
priv
->
tx_count
++
;
priv
->
tx_count
++
;
...
@@ -928,7 +930,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
...
@@ -928,7 +930,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
}
}
/* Turn interrupts back on and free buffer */
/* Turn interrupts back on and free buffer */
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
priv
->
ring_lock
,
flags
);
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
return
0
;
return
0
;
...
@@ -951,6 +953,7 @@ static int scc_set_mac_address(struct net_device *dev, void *sa) {
...
@@ -951,6 +953,7 @@ static int scc_set_mac_address(struct net_device *dev, void *sa) {
static
void
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
static
void
scc_isr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
struct
scc_info
*
info
=
dev_id
;
struct
scc_info
*
info
=
dev_id
;
spin_lock
(
info
->
priv
[
0
].
register_lock
);
/* At this point interrupts are enabled, and the interrupt under service
/* At this point interrupts are enabled, and the interrupt under service
is already acknowledged, but masked off.
is already acknowledged, but masked off.
...
@@ -978,6 +981,7 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs * regs) {
...
@@ -978,6 +981,7 @@ static void scc_isr(int irq, void *dev_id, struct pt_regs * regs) {
}
}
}
}
}
else
z8530_isr
(
info
);
}
else
z8530_isr
(
info
);
spin_unlock
(
info
->
priv
[
0
].
register_lock
);
}
}
...
@@ -1002,7 +1006,7 @@ static inline void z8530_isr(struct scc_info *info) {
...
@@ -1002,7 +1006,7 @@ static inline void z8530_isr(struct scc_info *info) {
i
++
;
i
++
;
}
}
if
(
i
<
0
)
{
if
(
i
<
0
)
{
printk
(
"dmascc: stuck in ISR with RR3=0x%02x.
\n
"
,
is
);
printk
(
KERN_ERR
"dmascc: stuck in ISR with RR3=0x%02x.
\n
"
,
is
);
}
}
/* Ok, no interrupts pending from this 8530. The INT line should
/* Ok, no interrupts pending from this 8530. The INT line should
be inactive now. */
be inactive now. */
...
@@ -1099,11 +1103,9 @@ static void rx_bh(void *arg) {
...
@@ -1099,11 +1103,9 @@ static void rx_bh(void *arg) {
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
char
*
data
;
unsigned
char
*
data
;
save_flags
(
flags
);
spin_lock_irqsave
(
&
priv
->
ring_lock
,
flags
);
cli
();
while
(
priv
->
rx_count
)
{
while
(
priv
->
rx_count
)
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
priv
->
ring_lock
,
flags
);
cb
=
priv
->
rx_len
[
i
];
cb
=
priv
->
rx_len
[
i
];
/* Allocate buffer */
/* Allocate buffer */
skb
=
dev_alloc_skb
(
cb
+
1
);
skb
=
dev_alloc_skb
(
cb
+
1
);
...
@@ -1123,14 +1125,12 @@ static void rx_bh(void *arg) {
...
@@ -1123,14 +1125,12 @@ static void rx_bh(void *arg) {
priv
->
stats
.
rx_packets
++
;
priv
->
stats
.
rx_packets
++
;
priv
->
stats
.
rx_bytes
+=
cb
;
priv
->
stats
.
rx_bytes
+=
cb
;
}
}
save_flags
(
flags
);
spin_lock_irqsave
(
&
priv
->
ring_lock
,
flags
);
cli
();
/* Move tail */
/* Move tail */
priv
->
rx_tail
=
i
=
(
i
+
1
)
%
NUM_RX_BUF
;
priv
->
rx_tail
=
i
=
(
i
+
1
)
%
NUM_RX_BUF
;
priv
->
rx_count
--
;
priv
->
rx_count
--
;
}
}
spin_unlock_irqrestore
(
&
priv
->
ring_lock
,
flags
);
restore_flags
(
flags
);
}
}
...
@@ -1319,12 +1319,11 @@ static inline void tx_on(struct scc_priv *priv) {
...
@@ -1319,12 +1319,11 @@ static inline void tx_on(struct scc_priv *priv) {
else
else
write_scc
(
priv
,
R1
,
EXT_INT_ENAB
|
WT_FN_RDYFN
|
WT_RDY_ENAB
);
write_scc
(
priv
,
R1
,
EXT_INT_ENAB
|
WT_FN_RDYFN
|
WT_RDY_ENAB
);
/* Write first byte(s) */
/* Write first byte(s) */
save_flags
(
flags
);
spin_lock_irqsave
(
priv
->
register_lock
,
flags
);
cli
();
for
(
i
=
0
;
i
<
n
;
i
++
)
for
(
i
=
0
;
i
<
n
;
i
++
)
write_scc_data
(
priv
,
priv
->
tx_buf
[
priv
->
tx_tail
][
i
],
1
);
write_scc_data
(
priv
,
priv
->
tx_buf
[
priv
->
tx_tail
][
i
],
1
);
enable_dma
(
priv
->
param
.
dma
);
enable_dma
(
priv
->
param
.
dma
);
restore_flags
(
flags
);
spin_unlock_irqrestore
(
priv
->
register_lock
,
flags
);
}
else
{
}
else
{
write_scc
(
priv
,
R15
,
TxUIE
);
write_scc
(
priv
,
R15
,
TxUIE
);
write_scc
(
priv
,
R1
,
EXT_INT_ENAB
|
WT_FN_RDYFN
|
TxINT_ENAB
);
write_scc
(
priv
,
R1
,
EXT_INT_ENAB
|
WT_FN_RDYFN
|
TxINT_ENAB
);
...
...
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