Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
35c2221b
Commit
35c2221b
authored
Jan 29, 2009
by
David Woodhouse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
solos: Clean up handling of card->tx_mask a little
Signed-off-by:
David Woodhouse
<
David.Woodhouse@intel.com
>
parent
c6428e52
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
28 additions
and
25 deletions
+28
-25
drivers/atm/solos-pci.c
drivers/atm/solos-pci.c
+28
-25
No files found.
drivers/atm/solos-pci.c
View file @
35c2221b
...
...
@@ -140,7 +140,7 @@ module_param(fpga_upgrade, int, 0444);
static
void
fpga_queue
(
struct
solos_card
*
card
,
int
port
,
struct
sk_buff
*
skb
,
struct
atm_vcc
*
vcc
);
static
in
t
fpga_tx
(
struct
solos_card
*
);
static
uint32_
t
fpga_tx
(
struct
solos_card
*
);
static
irqreturn_t
solos_irq
(
int
irq
,
void
*
dev_id
);
static
struct
atm_vcc
*
find_vcc
(
struct
atm_dev
*
dev
,
short
vpi
,
int
vci
);
static
int
list_vccs
(
int
vci
);
...
...
@@ -438,8 +438,6 @@ static int send_command(struct solos_card *card, int dev, const char *buf, size_
struct
sk_buff
*
skb
;
struct
pkt_hdr
*
header
;
// dev_dbg(&card->dev->dev, "size: %d\n", size);
if
(
size
>
(
BUF_SIZE
-
sizeof
(
*
header
)))
{
dev_dbg
(
&
card
->
dev
->
dev
,
"Command is too big. Dropping request
\n
"
);
return
0
;
...
...
@@ -574,9 +572,9 @@ static irqreturn_t solos_irq(int irq, void *dev_id)
struct
solos_card
*
card
=
dev_id
;
int
handled
=
1
;
//ACK IRQ
iowrite32
(
0
,
card
->
config_regs
+
IRQ_CLEAR
);
/* If we're up and running, just kick the tasklet to process TX/RX */
if
(
card
->
atmdev
[
0
])
tasklet_schedule
(
&
card
->
tlet
);
else
...
...
@@ -588,16 +586,16 @@ static irqreturn_t solos_irq(int irq, void *dev_id)
void
solos_bh
(
unsigned
long
card_arg
)
{
struct
solos_card
*
card
=
(
void
*
)
card_arg
;
int
port
;
uint32_t
card_flags
;
uint32_t
rx_done
=
0
;
int
port
;
card_flags
=
ioread32
(
card
->
config_regs
+
FLAGS_ADDR
);
/* The TX bits are set if the channel is busy; clear if not. We want to
invoke fpga_tx() unless _all_ the bits for active channels are set */
if
((
card_flags
&
card
->
tx_mask
)
!=
card
->
tx_mask
)
fpga_tx
(
card
);
/*
* Since fpga_tx() is going to need to read the flags under its lock,
* it can return them to us so that we don't have to hit PCI MMIO
* again for the same information
*/
card_flags
=
fpga_tx
(
card
);
for
(
port
=
0
;
port
<
card
->
nr_ports
;
port
++
)
{
if
(
card_flags
&
(
0x10
<<
port
))
{
...
...
@@ -892,9 +890,8 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
spin_lock_irqsave
(
&
card
->
tx_queue_lock
,
flags
);
old_len
=
skb_queue_len
(
&
card
->
tx_queue
[
port
]);
skb_queue_tail
(
&
card
->
tx_queue
[
port
],
skb
);
if
(
!
old_len
)
{
if
(
!
old_len
)
card
->
tx_mask
|=
(
1
<<
port
);
}
spin_unlock_irqrestore
(
&
card
->
tx_queue_lock
,
flags
);
/* Theoretically we could just schedule the tasklet here, but
...
...
@@ -903,9 +900,9 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
fpga_tx
(
card
);
}
static
in
t
fpga_tx
(
struct
solos_card
*
card
)
static
uint32_
t
fpga_tx
(
struct
solos_card
*
card
)
{
uint32_t
tx_pending
;
uint32_t
tx_pending
,
card_flags
;
uint32_t
tx_started
=
0
;
struct
sk_buff
*
skb
;
struct
atm_vcc
*
vcc
;
...
...
@@ -913,19 +910,24 @@ static int fpga_tx(struct solos_card *card)
unsigned
long
flags
;
spin_lock_irqsave
(
&
card
->
tx_lock
,
flags
);
tx_pending
=
ioread32
(
card
->
config_regs
+
FLAGS_ADDR
)
&
card
->
tx_mask
;
dev_vdbg
(
&
card
->
dev
->
dev
,
"TX Flags are %X
\n
"
,
tx_pending
);
for
(
port
=
0
;
port
<
card
->
nr_ports
;
port
++
)
{
if
(
card
->
atmdev
[
port
]
&&
!
(
tx_pending
&
(
1
<<
port
)))
{
card_flags
=
ioread32
(
card
->
config_regs
+
FLAGS_ADDR
);
/*
* The queue lock is required for _writing_ to tx_mask, but we're
* OK to read it here without locking. The only potential update
* that we could race with is in fpga_queue() where it sets a bit
* for a new port... but it's going to call this function again if
* it's doing that, anyway.
*/
tx_pending
=
card
->
tx_mask
&
~
card_flags
;
for
(
port
=
0
;
tx_pending
;
tx_pending
>>=
1
,
port
++
)
{
if
(
tx_pending
&
1
)
{
struct
sk_buff
*
oldskb
=
card
->
tx_skb
[
port
];
if
(
oldskb
)
pci_unmap_single
(
card
->
dev
,
SKB_CB
(
oldskb
)
->
dma_addr
,
oldskb
->
len
,
PCI_DMA_TODEVICE
);
spin_lock
(
&
card
->
tx_queue_lock
);
skb
=
skb_dequeue
(
&
card
->
tx_queue
[
port
]);
if
(
!
skb
)
...
...
@@ -966,8 +968,9 @@ static int fpga_tx(struct solos_card *card)
if
(
tx_started
)
iowrite32
(
tx_started
,
card
->
config_regs
+
FLAGS_ADDR
);
out:
spin_unlock_irqrestore
(
&
card
->
tx_lock
,
flags
);
return
0
;
return
card_flags
;
}
static
int
psend
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
)
...
...
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