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
6d23b118
Commit
6d23b118
authored
Oct 27, 2002
by
Alan Cox
Committed by
Linus Torvalds
Oct 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] drag ATM into the 21st century , part 1
parent
6321043b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
284 additions
and
218 deletions
+284
-218
drivers/atm/Makefile
drivers/atm/Makefile
+1
-1
drivers/atm/iphase.c
drivers/atm/iphase.c
+266
-208
drivers/atm/iphase.h
drivers/atm/iphase.h
+12
-3
drivers/atm/lanai.c
drivers/atm/lanai.c
+1
-2
drivers/atm/zatm.c
drivers/atm/zatm.c
+4
-4
No files found.
drivers/atm/Makefile
View file @
6d23b118
...
...
@@ -40,7 +40,7 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
fore_200e-objs
+=
fore200e_pca_fw.o
# guess the target endianess to choose the right PCA-200E firmware image
ifeq
($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
CONFIG_ATM_FORE200E_PCA_FW
=
$(
shell
if
test
-n
"
`
$(CC)
-E
-dM
$(src)
/../../include/asm/byteorder.h |
grep
' __LITTLE_ENDIAN '
`
"
;
then
echo
pca200e.bin
;
else
echo
pca200e_ecd.bin2
;
fi
)
CONFIG_ATM_FORE200E_PCA_FW
=
$(
shell
if
test
-n
"
`
$(CC)
-E
-dM
$(src)
/../../include/asm/byteorder.h |
grep
' __LITTLE_ENDIAN '
`
"
;
then
echo
$(obj)
/pca200e.bin
;
else
echo
$(obj)
/
pca200e_ecd.bin2
;
fi
)
endif
endif
...
...
drivers/atm/iphase.c
View file @
6d23b118
...
...
@@ -118,7 +118,7 @@ static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data)
}
static
int
ia_enque_rtn_q
(
IARTN_Q
*
que
,
struct
desc_tbl_t
data
)
{
IARTN_Q
*
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_
KERNEL
);
IARTN_Q
*
entry
=
kmalloc
(
sizeof
(
*
entry
),
GFP_
ATOMIC
);
if
(
!
entry
)
return
-
1
;
entry
->
data
=
data
;
entry
->
next
=
NULL
;
...
...
@@ -202,8 +202,7 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
ltimeout
=
dev
->
desc_tbl
[
i
].
iavcc
->
ltimeout
;
delta
=
jiffies
-
dev
->
desc_tbl
[
i
].
timestamp
;
if
(
delta
>=
ltimeout
)
{
IF_ABR
(
printk
(
"RECOVER run!! desc_tbl %d = %d delta = %ld,
time = %ld
\n
"
,
i
,
dev
->
desc_tbl
[
i
].
timestamp
,
delta
,
jiffies
);)
IF_ABR
(
printk
(
"RECOVER run!! desc_tbl %d = %d delta = %ld, time = %ld
\n
"
,
i
,
dev
->
desc_tbl
[
i
].
timestamp
,
delta
,
jiffies
);)
if
(
dev
->
ffL
.
tcq_rd
==
dev
->
ffL
.
tcq_st
)
dev
->
ffL
.
tcq_rd
=
dev
->
ffL
.
tcq_ed
;
else
...
...
@@ -624,6 +623,7 @@ static int ia_que_tx (IADEV *iadev) {
struct
ia_vcc
*
iavcc
;
static
int
ia_pkt_tx
(
struct
atm_vcc
*
vcc
,
struct
sk_buff
*
skb
);
num_desc
=
ia_avail_descs
(
iadev
);
while
(
num_desc
&&
(
skb
=
skb_dequeue
(
&
iadev
->
tx_backlog
)))
{
if
(
!
(
vcc
=
ATM_SKB
(
skb
)
->
vcc
))
{
dev_kfree_skb_any
(
skb
);
...
...
@@ -643,6 +643,7 @@ static int ia_que_tx (IADEV *iadev) {
}
return
0
;
}
void
ia_tx_poll
(
IADEV
*
iadev
)
{
struct
atm_vcc
*
vcc
=
NULL
;
struct
sk_buff
*
skb
=
NULL
,
*
skb1
=
NULL
;
...
...
@@ -1086,6 +1087,7 @@ static int rx_pkt(struct atm_dev *dev)
int
len
;
struct
sk_buff
*
skb
;
u_int
buf_addr
,
dma_addr
;
iadev
=
INPH_IA_DEV
(
dev
);
if
(
iadev
->
rfL
.
pcq_rd
==
(
readw
(
iadev
->
reass_reg
+
PCQ_WR_PTR
)
&
0xffff
))
{
...
...
@@ -1171,7 +1173,8 @@ static int rx_pkt(struct atm_dev *dev)
/* Build the DLE structure */
wr_ptr
=
iadev
->
rx_dle_q
.
write
;
wr_ptr
->
sys_pkt_addr
=
virt_to_bus
(
skb
->
data
);
wr_ptr
->
sys_pkt_addr
=
pci_map_single
(
iadev
->
pci
,
skb
->
data
,
len
,
PCI_DMA_FROMDEVICE
);
wr_ptr
->
local_pkt_addr
=
buf_addr
;
wr_ptr
->
bytes
=
len
;
/* We don't know this do we ?? */
wr_ptr
->
mode
=
DMA_INT_ENABLE
;
...
...
@@ -1290,6 +1293,9 @@ static void rx_dle_intr(struct atm_dev *dev)
struct
cpcs_trailer
*
trailer
;
u_short
length
;
struct
ia_vcc
*
ia_vcc
;
pci_unmap_single
(
iadev
->
pci
,
iadev
->
rx_dle_q
.
write
->
sys_pkt_addr
,
len
,
PCI_DMA_FROMDEVICE
);
/* no VCC related housekeeping done as yet. lets see */
vcc
=
ATM_SKB
(
skb
)
->
vcc
;
if
(
!
vcc
)
{
...
...
@@ -1401,7 +1407,7 @@ static int rx_init(struct atm_dev *dev)
IADEV
*
iadev
;
struct
rx_buf_desc
*
buf_desc_ptr
;
unsigned
long
rx_pkt_start
=
0
;
u32
*
odle_addr
,
*
dle_addr
;
void
*
dle_addr
;
struct
abr_vc_table
*
abr_vc_table
;
u16
*
vc_table
;
u16
*
reass_table
;
...
...
@@ -1412,25 +1418,14 @@ static int rx_init(struct atm_dev *dev)
iadev
=
INPH_IA_DEV
(
dev
);
// spin_lock_init(&iadev->rx_lock);
/* I need to initialize the DLEs somewhere. Lets see what I
need to do for this, hmmm...
- allocate memory for 256 DLEs. make sure that it starts
on a 4k byte address boundary. Program the start address
in Receive List address register. ..... to do for TX also
To make sure that it is a 4k byte boundary - allocate 8k and find
4k byte boundary within.
( (addr + (4k-1)) & ~(4k-1) )
*/
/* allocate 8k bytes */
odle_addr
=
kmalloc
(
2
*
sizeof
(
struct
dle
)
*
DLE_ENTRIES
,
GFP_KERNEL
);
if
(
!
odle_addr
)
{
printk
(
KERN_ERR
DEV_LABEL
"can't allocate DLEs
\n
"
);
return
-
ENOMEM
;
}
/* find 4k byte boundary within the 8k allocated */
dle_addr
=
(
u32
*
)(
((
u32
)
odle_addr
+
(
4096
-
1
))
&
~
(
4096
-
1
)
);
/* Allocate 4k bytes - more aligned than needed (4k boundary) */
dle_addr
=
pci_alloc_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
&
iadev
->
rx_dle_dma
);
if
(
!
dle_addr
)
{
printk
(
KERN_ERR
DEV_LABEL
"can't allocate DLEs
\n
"
);
goto
err_out
;
}
iadev
->
rx_dle_q
.
start
=
(
struct
dle
*
)
dle_addr
;
iadev
->
rx_dle_q
.
read
=
iadev
->
rx_dle_q
.
start
;
iadev
->
rx_dle_q
.
write
=
iadev
->
rx_dle_q
.
start
;
...
...
@@ -1439,7 +1434,8 @@ static int rx_init(struct atm_dev *dev)
DLE that can be used. */
/* write the upper 20 bits of the start address to rx list address register */
writel
(
virt_to_bus
(
dle_addr
)
&
0xfffff000
,
iadev
->
dma
+
IPHASE5575_RX_LIST_ADDR
);
writel
(
iadev
->
rx_dle_dma
&
0xfffff000
,
iadev
->
dma
+
IPHASE5575_RX_LIST_ADDR
);
IF_INIT
(
printk
(
"Tx Dle list addr: 0x%08x value: 0x%0x
\n
"
,
(
u32
)(
iadev
->
dma
+
IPHASE5575_TX_LIST_ADDR
),
*
(
u32
*
)(
iadev
->
dma
+
IPHASE5575_TX_LIST_ADDR
));
...
...
@@ -1613,8 +1609,7 @@ static int rx_init(struct atm_dev *dev)
{
printk
(
KERN_ERR
DEV_LABEL
"itf %d couldn't get free page
\n
"
,
dev
->
number
);
kfree
(
odle_addr
);
return
-
ENOMEM
;
goto
err_free_dle
;
}
memset
(
iadev
->
rx_open
,
0
,
4
*
iadev
->
num_vc
);
iadev
->
rxing
=
1
;
...
...
@@ -1622,6 +1617,12 @@ static int rx_init(struct atm_dev *dev)
/* Mode Register */
writew
(
R_ONLINE
,
iadev
->
reass_reg
+
MODE_REG
);
return
0
;
err_free_dle:
pci_free_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
iadev
->
rx_dle_q
.
start
,
iadev
->
rx_dle_dma
);
err_out:
return
-
ENOMEM
;
}
...
...
@@ -1686,6 +1687,12 @@ static void tx_dle_intr(struct atm_dev *dev)
/* free the DMAed skb */
skb
=
skb_dequeue
(
&
iadev
->
tx_dma_q
);
if
(
!
skb
)
break
;
/* Revenge of the 2 dle (skb + trailer) used in ia_pkt_tx() */
if
(
!
((
dle
-
iadev
->
tx_dle_q
.
start
)
%
(
2
*
sizeof
(
struct
dle
))))
{
pci_unmap_single
(
iadev
->
pci
,
dle
->
sys_pkt_addr
,
skb
->
len
,
PCI_DMA_TODEVICE
);
}
vcc
=
ATM_SKB
(
skb
)
->
vcc
;
if
(
!
vcc
)
{
printk
(
"tx_dle_intr: vcc is null
\n
"
);
...
...
@@ -1878,7 +1885,7 @@ static int tx_init(struct atm_dev *dev)
IADEV
*
iadev
;
struct
tx_buf_desc
*
buf_desc_ptr
;
unsigned
int
tx_pkt_start
;
u32
*
dle_addr
;
void
*
dle_addr
;
int
i
;
u_short
tcq_st_adr
;
u_short
*
tcq_start
;
...
...
@@ -1894,24 +1901,22 @@ static int tx_init(struct atm_dev *dev)
IF_INIT
(
printk
(
"Tx MASK REG: 0x%0x
\n
"
,
readw
(
iadev
->
seg_reg
+
SEG_MASK_REG
));)
/*---------- Initializing Transmit DLEs ----------*/
/* allocating 8k memory for transmit DLEs */
dle_addr
=
kmalloc
(
2
*
sizeof
(
struct
dle
)
*
DLE_ENTRIES
,
GFP_KERNEL
);
if
(
!
dle_addr
)
{
printk
(
KERN_ERR
DEV_LABEL
"can't allocate TX DLEs
\n
"
);
return
-
ENOMEM
;
}
/* find 4k byte boundary within the 8k allocated */
dle_addr
=
(
u32
*
)(((
u32
)
dle_addr
+
(
4096
-
1
))
&
~
(
4096
-
1
));
/* Allocate 4k (boundary aligned) bytes */
dle_addr
=
pci_alloc_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
&
iadev
->
tx_dle_dma
);
if
(
!
dle_addr
)
{
printk
(
KERN_ERR
DEV_LABEL
"can't allocate DLEs
\n
"
);
goto
err_out
;
}
iadev
->
tx_dle_q
.
start
=
(
struct
dle
*
)
dle_addr
;
iadev
->
tx_dle_q
.
read
=
iadev
->
tx_dle_q
.
start
;
iadev
->
tx_dle_q
.
write
=
iadev
->
tx_dle_q
.
start
;
iadev
->
tx_dle_q
.
end
=
(
struct
dle
*
)((
u32
)
dle_addr
+
sizeof
(
struct
dle
)
*
DLE_ENTRIES
);
/* write the upper 20 bits of the start address to tx list address register */
writel
(
virt_to_bus
(
dle_addr
)
&
0xfffff000
,
iadev
->
dma
+
IPHASE5575_TX_LIST_ADDR
);
writel
(
iadev
->
tx_dle_dma
&
0xfffff000
,
iadev
->
dma
+
IPHASE5575_TX_LIST_ADDR
);
writew
(
0xffff
,
iadev
->
seg_reg
+
SEG_MASK_REG
);
writew
(
0
,
iadev
->
seg_reg
+
MODE_REG_0
);
writew
(
RESET_SEG
,
iadev
->
seg_reg
+
SEG_COMMAND_REG
);
...
...
@@ -1955,26 +1960,29 @@ static int tx_init(struct atm_dev *dev)
buf_desc_ptr
++
;
tx_pkt_start
+=
iadev
->
tx_buf_sz
;
}
iadev
->
tx_buf
=
kmalloc
(
iadev
->
num_tx_desc
*
sizeof
(
caddr_t
),
GFP_KERNEL
);
iadev
->
tx_buf
=
kmalloc
(
iadev
->
num_tx_desc
*
sizeof
(
struct
cpcs_trailer_desc
),
GFP_KERNEL
);
if
(
!
iadev
->
tx_buf
)
{
printk
(
KERN_ERR
DEV_LABEL
" couldn't get mem
\n
"
);
return
-
EAGAIN
;
goto
err_free_dle
;
}
for
(
i
=
0
;
i
<
iadev
->
num_tx_desc
;
i
++
)
{
struct
cpcs_trailer
*
cpcs
;
iadev
->
tx_buf
[
i
]
=
kmalloc
(
sizeof
(
struct
cpcs_trailer
),
GFP_KERNEL
|
GFP_DMA
);
if
(
!
iadev
->
tx_buf
[
i
])
{
cpcs
=
kmalloc
(
sizeof
(
*
cpcs
),
GFP_KERNEL
|
GFP_DMA
);
if
(
!
cpcs
)
{
printk
(
KERN_ERR
DEV_LABEL
" couldn't get freepage
\n
"
);
return
-
EAGAIN
;
goto
err_free_tx_bufs
;
}
iadev
->
tx_buf
[
i
].
cpcs
=
cpcs
;
iadev
->
tx_buf
[
i
].
dma_addr
=
pci_map_single
(
iadev
->
pci
,
cpcs
,
sizeof
(
*
cpcs
),
PCI_DMA_TODEVICE
);
}
iadev
->
desc_tbl
=
kmalloc
(
iadev
->
num_tx_desc
*
sizeof
(
struct
desc_tbl_t
),
GFP_KERNEL
);
if
(
!
iadev
->
desc_tbl
)
{
printk
(
KERN_ERR
DEV_LABEL
" couldn't get mem
\n
"
);
return
-
EAGAIN
;
goto
err_free_all_tx_bufs
;
}
/* Communication Queues base address */
...
...
@@ -2103,7 +2111,7 @@ static int tx_init(struct atm_dev *dev)
iadev
->
testTable
=
kmalloc
(
sizeof
(
long
)
*
iadev
->
num_vc
,
GFP_KERNEL
);
if
(
!
iadev
->
testTable
)
{
printk
(
"Get freepage failed
\n
"
);
return
-
EAGAIN
;
goto
err_free_desc_tbl
;
}
for
(
i
=
0
;
i
<
iadev
->
num_vc
;
i
++
)
{
...
...
@@ -2112,7 +2120,7 @@ static int tx_init(struct atm_dev *dev)
iadev
->
testTable
[
i
]
=
kmalloc
(
sizeof
(
struct
testTable_t
),
GFP_KERNEL
);
if
(
!
iadev
->
testTable
[
i
])
return
-
ENOMEM
;
goto
err_free_test_tables
;
iadev
->
testTable
[
i
]
->
lastTime
=
0
;
iadev
->
testTable
[
i
]
->
fract
=
0
;
iadev
->
testTable
[
i
]
->
vc_status
=
VC_UBR
;
...
...
@@ -2163,7 +2171,30 @@ static int tx_init(struct atm_dev *dev)
iadev
->
tx_pkt_cnt
=
0
;
iadev
->
rate_limit
=
iadev
->
LineRate
/
3
;
return
0
;
return
0
;
err_free_test_tables:
while
(
--
i
>=
0
)
kfree
(
iadev
->
testTable
[
i
]);
kfree
(
iadev
->
testTable
);
err_free_desc_tbl:
kfree
(
iadev
->
desc_tbl
);
err_free_all_tx_bufs:
i
=
iadev
->
num_tx_desc
;
err_free_tx_bufs:
while
(
--
i
>=
0
)
{
struct
cpcs_trailer_desc
*
desc
=
iadev
->
tx_buf
+
i
;
pci_unmap_single
(
iadev
->
pci
,
desc
->
dma_addr
,
sizeof
(
*
desc
->
cpcs
),
PCI_DMA_TODEVICE
);
kfree
(
desc
->
cpcs
);
}
kfree
(
iadev
->
tx_buf
);
err_free_dle:
pci_free_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
iadev
->
tx_dle_q
.
start
,
iadev
->
tx_dle_dma
);
err_out:
return
-
ENOMEM
;
}
static
void
ia_int
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
...
...
@@ -2421,10 +2452,37 @@ static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr)
return
readl
(
INPH_IA_DEV
(
dev
)
->
phy
+
addr
);
}
static
void
ia_free_tx
(
IADEV
*
iadev
)
{
int
i
;
kfree
(
iadev
->
desc_tbl
);
for
(
i
=
0
;
i
<
iadev
->
num_vc
;
i
++
)
kfree
(
iadev
->
testTable
[
i
]);
kfree
(
iadev
->
testTable
);
for
(
i
=
0
;
i
<
iadev
->
num_tx_desc
;
i
++
)
{
struct
cpcs_trailer_desc
*
desc
=
iadev
->
tx_buf
+
i
;
pci_unmap_single
(
iadev
->
pci
,
desc
->
dma_addr
,
sizeof
(
*
desc
->
cpcs
),
PCI_DMA_TODEVICE
);
kfree
(
desc
->
cpcs
);
}
kfree
(
iadev
->
tx_buf
);
pci_free_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
iadev
->
tx_dle_q
.
start
,
iadev
->
tx_dle_dma
);
}
static
void
ia_free_rx
(
IADEV
*
iadev
)
{
kfree
(
iadev
->
rx_open
);
pci_free_consistent
(
iadev
->
pci
,
DLE_TOTAL_SIZE
,
iadev
->
rx_dle_q
.
start
,
iadev
->
rx_dle_dma
);
}
static
int
__init
ia_start
(
struct
atm_dev
*
dev
)
{
IADEV
*
iadev
;
int
error
=
1
;
int
error
;
unsigned
char
phy
;
u32
ctrl_reg
;
IF_EVENT
(
printk
(
">ia_start
\n
"
);)
...
...
@@ -2432,7 +2490,8 @@ static int __init ia_start(struct atm_dev *dev)
if
(
request_irq
(
iadev
->
irq
,
&
ia_int
,
SA_SHIRQ
,
DEV_LABEL
,
dev
))
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): IRQ%d is already in use
\n
"
,
dev
->
number
,
iadev
->
irq
);
return
-
EAGAIN
;
error
=
-
EAGAIN
;
goto
err_out
;
}
/* @@@ should release IRQ on error */
/* enabling memory + master */
...
...
@@ -2442,8 +2501,8 @@ static int __init ia_start(struct atm_dev *dev)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't enable memory+"
"master (0x%x)
\n
"
,
dev
->
number
,
error
);
free_irq
(
iadev
->
irq
,
dev
);
return
-
EIO
;
error
=
-
EIO
;
goto
err_free_irq
;
}
udelay
(
10
);
...
...
@@ -2477,15 +2536,11 @@ static int __init ia_start(struct atm_dev *dev)
ia_hw_type
(
iadev
);
error
=
tx_init
(
dev
);
if
(
error
)
{
free_irq
(
iadev
->
irq
,
dev
);
return
error
;
}
if
(
error
)
goto
err_free_irq
;
error
=
rx_init
(
dev
);
if
(
error
)
{
free_irq
(
iadev
->
irq
,
dev
);
return
error
;
}
if
(
error
)
goto
err_free_tx
;
ctrl_reg
=
readl
(
iadev
->
reg
+
IPHASE5575_BUS_CONTROL_REG
);
writel
(
ctrl_reg
|
CTRL_FE_RST
,
iadev
->
reg
+
IPHASE5575_BUS_CONTROL_REG
);
...
...
@@ -2498,35 +2553,38 @@ static int __init ia_start(struct atm_dev *dev)
else
printk
(
"IA: utopia,rev.%0x
\n
"
,
phy
);)
if
(
iadev
->
phy_type
&
FE_25MBIT_PHY
)
{
if
(
iadev
->
phy_type
&
FE_25MBIT_PHY
)
ia_mb25_init
(
iadev
);
return
0
;
}
if
(
iadev
->
phy_type
&
(
FE_DS3_PHY
|
FE_E3_PHY
))
{
else
if
(
iadev
->
phy_type
&
(
FE_DS3_PHY
|
FE_E3_PHY
))
ia_suni_pm7345_init
(
iadev
);
return
0
;
}
error
=
suni_init
(
dev
);
if
(
error
)
{
free_irq
(
iadev
->
irq
,
dev
);
return
error
;
}
/* Enable interrupt on loss of signal SUNI_RSOP_CIE 0x10
SUNI_RSOP_CIE_LOSE - 0x04
*/
ia_phy_put
(
dev
,
ia_phy_get
(
dev
,
0x10
)
|
0x04
,
0x10
);
#if 0
error = dev->phy->start(dev);
if (error) {
free_irq(iadev->irq, dev);
return error;
}
else
{
error
=
suni_init
(
dev
);
if
(
error
)
goto
err_free_rx
;
/*
* Enable interrupt on loss of signal
* SUNI_RSOP_CIE - 0x10
* SUNI_RSOP_CIE_LOSE - 0x04
*/
ia_phy_put
(
dev
,
ia_phy_get
(
dev
,
0x10
)
|
0x04
,
0x10
);
#ifndef MODULE
error
=
dev
->
phy
->
start
(
dev
);
if
(
error
)
goto
err_free_rx
;
#endif
/* Get iadev->carrier_detect status */
IaFrontEndIntr
(
iadev
);
return
0
;
/* Get iadev->carrier_detect status */
IaFrontEndIntr
(
iadev
);
}
return
0
;
err_free_rx:
ia_free_rx
(
iadev
);
err_free_tx:
ia_free_tx
(
iadev
);
err_free_irq:
free_irq
(
iadev
->
irq
,
dev
);
err_out:
return
error
;
}
static
void
ia_close
(
struct
atm_vcc
*
vcc
)
...
...
@@ -2835,10 +2893,10 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
struct
tx_buf_desc
*
buf_desc_ptr
;
int
desc
;
int
comp_code
;
unsigned
int
addr
;
int
total_len
,
pad
,
last
;
struct
cpcs_trailer
*
trailer
;
struct
ia_vcc
*
iavcc
;
iadev
=
INPH_IA_DEV
(
vcc
->
dev
);
iavcc
=
INPH_IA_VCC
(
vcc
);
if
(
!
iavcc
->
txing
)
{
...
...
@@ -2923,13 +2981,9 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
IF_TX
(
printk
(
"ia packet len:%d padding:%d
\n
"
,
total_len
,
pad
);)
/* Put the packet in a tx buffer */
if
(
!
iadev
->
tx_buf
[
desc
-
1
])
printk
(
"couldn't get free page
\n
"
);
trailer
=
iadev
->
tx_buf
[
desc
-
1
].
cpcs
;
IF_TX
(
printk
(
"Sent: skb = 0x%x skb->data: 0x%x len: %d, desc: %d
\n
"
,
(
u32
)
skb
,
(
u32
)
skb
->
data
,
skb
->
len
,
desc
);)
addr
=
virt_to_bus
(
skb
->
data
);
trailer
=
(
struct
cpcs_trailer
*
)
iadev
->
tx_buf
[
desc
-
1
];
trailer
->
control
=
0
;
/*big endian*/
trailer
->
length
=
((
skb
->
len
&
0xff
)
<<
8
)
|
((
skb
->
len
&
0xff00
)
>>
8
);
...
...
@@ -2945,6 +2999,7 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
buf_desc_ptr
=
(
struct
tx_buf_desc
*
)(
iadev
->
seg_ram
+
TX_DESC_BASE
);
buf_desc_ptr
+=
desc
;
/* points to the corresponding entry */
buf_desc_ptr
->
desc_mode
=
AAL5
|
EOM_EN
|
APP_CRC32
|
CMPL_INT
;
/* Huh ? p.115 of users guide describes this as a read-only register */
writew
(
TRANSMIT_DONE
,
iadev
->
seg_reg
+
SEG_INTR_STATUS_REG
);
buf_desc_ptr
->
vc_index
=
vcc
->
vci
;
buf_desc_ptr
->
bytes
=
total_len
;
...
...
@@ -2955,7 +3010,8 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
/* Build the DLE structure */
wr_ptr
=
iadev
->
tx_dle_q
.
write
;
memset
((
caddr_t
)
wr_ptr
,
0
,
sizeof
(
*
wr_ptr
));
wr_ptr
->
sys_pkt_addr
=
addr
;
wr_ptr
->
sys_pkt_addr
=
pci_map_single
(
iadev
->
pci
,
skb
->
data
,
skb
->
len
,
PCI_DMA_TODEVICE
);
wr_ptr
->
local_pkt_addr
=
(
buf_desc_ptr
->
buf_start_hi
<<
16
)
|
buf_desc_ptr
->
buf_start_lo
;
/* wr_ptr->bytes = swap(total_len); didn't seem to affect ?? */
...
...
@@ -2973,7 +3029,7 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
wr_ptr
=
iadev
->
tx_dle_q
.
start
;
/* Build trailer dle */
wr_ptr
->
sys_pkt_addr
=
virt_to_bus
(
iadev
->
tx_buf
[
desc
-
1
])
;
wr_ptr
->
sys_pkt_addr
=
iadev
->
tx_buf
[
desc
-
1
].
dma_addr
;
wr_ptr
->
local_pkt_addr
=
((
buf_desc_ptr
->
buf_start_hi
<<
16
)
|
buf_desc_ptr
->
buf_start_lo
)
+
total_len
-
sizeof
(
struct
cpcs_trailer
);
...
...
@@ -3124,128 +3180,130 @@ static const struct atmdev_ops ops = {
.
owner
=
THIS_MODULE
,
};
static
int
__init
ia_detect
(
void
)
static
int
__devinit
ia_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
struct
atm_dev
*
dev
;
IADEV
*
iadev
;
unsigned
long
flags
;
int
index
=
0
;
struct
pci_dev
*
prev_dev
;
if
(
!
pci_present
())
{
printk
(
KERN_ERR
DEV_LABEL
" driver but no PCI BIOS ?
\n
"
);
return
0
;
}
int
ret
;
iadev
=
kmalloc
(
sizeof
(
*
iadev
),
GFP_KERNEL
);
if
(
!
iadev
)
return
-
ENOMEM
;
memset
((
char
*
)
iadev
,
0
,
sizeof
(
*
iadev
));
prev_dev
=
NULL
;
while
((
iadev
->
pci
=
pci_find_device
(
PCI_VENDOR_ID_IPHASE
,
PCI_DEVICE_ID_IPHASE_5575
,
prev_dev
)))
{
IF_INIT
(
printk
(
"ia detected at bus:%d dev: %d function:%d
\n
"
,
iadev
->
pci
->
bus
->
number
,
PCI_SLOT
(
iadev
->
pci
->
devfn
),
PCI_FUNC
(
iadev
->
pci
->
devfn
));)
if
(
pci_enable_device
(
iadev
->
pci
))
break
;
dev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
NULL
);
if
(
!
dev
)
break
;
IF_INIT
(
printk
(
DEV_LABEL
"registered at (itf :%d)
\n
"
,
dev
->
number
);)
INPH_IA_DEV
(
dev
)
=
iadev
;
// TODO: multi_board using ia_boards logic in cleanup_module
ia_dev
[
index
]
=
iadev
;
_ia_dev
[
index
]
=
dev
;
IF_INIT
(
printk
(
"dev_id = 0x%x iadev->LineRate = %d
\n
"
,
(
u32
)
dev
,
iadev
->
LineRate
);)
iadev_count
++
;
spin_lock_init
(
&
iadev
->
misc_lock
);
spin_lock_irqsave
(
&
iadev
->
misc_lock
,
flags
);
if
(
ia_init
(
dev
)
||
ia_start
(
dev
))
{
atm_dev_deregister
(
dev
);
IF_INIT
(
printk
(
"IA register failed!
\n
"
);)
ia_dev
[
index
]
=
NULL
;
_ia_dev
[
index
]
=
NULL
;
iadev_count
--
;
spin_unlock_irqrestore
(
&
iadev
->
misc_lock
,
flags
);
return
-
EINVAL
;
}
spin_unlock_irqrestore
(
&
iadev
->
misc_lock
,
flags
);
IF_EVENT
(
printk
(
"iadev_count = %d
\n
"
,
iadev_count
);)
prev_dev
=
iadev
->
pci
;
iadev
->
next_board
=
ia_boards
;
ia_boards
=
dev
;
iadev
=
kmalloc
(
sizeof
(
*
iadev
),
GFP_KERNEL
);
if
(
!
iadev
)
break
;
memset
((
char
*
)
iadev
,
0
,
sizeof
(
*
iadev
));
index
++
;
dev
=
NULL
;
}
return
index
;
}
if
(
!
iadev
)
{
ret
=
-
ENOMEM
;
goto
err_out
;
}
memset
(
iadev
,
0
,
sizeof
(
*
iadev
));
iadev
->
pci
=
pdev
;
IF_INIT
(
printk
(
"ia detected at bus:%d dev: %d function:%d
\n
"
,
pdev
->
bus
->
number
,
PCI_SLOT
(
pdev
->
devfn
),
PCI_FUNC
(
pdev
->
devfn
));)
if
(
pci_enable_device
(
pdev
))
{
ret
=
-
ENODEV
;
goto
err_out_free_iadev
;
}
dev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
NULL
);
if
(
!
dev
)
{
ret
=
-
ENOMEM
;
goto
err_out_disable_dev
;
}
INPH_IA_DEV
(
dev
)
=
iadev
;
IF_INIT
(
printk
(
DEV_LABEL
"registered at (itf :%d)
\n
"
,
dev
->
number
);)
IF_INIT
(
printk
(
"dev_id = 0x%x iadev->LineRate = %d
\n
"
,
(
u32
)
dev
,
iadev
->
LineRate
);)
ia_dev
[
iadev_count
]
=
iadev
;
_ia_dev
[
iadev_count
]
=
dev
;
iadev_count
++
;
spin_lock_init
(
&
iadev
->
misc_lock
);
/* First fixes first. I don't want to think about this now. */
spin_lock_irqsave
(
&
iadev
->
misc_lock
,
flags
);
if
(
ia_init
(
dev
)
||
ia_start
(
dev
))
{
IF_INIT
(
printk
(
"IA register failed!
\n
"
);)
iadev_count
--
;
ia_dev
[
iadev_count
]
=
NULL
;
_ia_dev
[
iadev_count
]
=
NULL
;
spin_unlock_irqrestore
(
&
iadev
->
misc_lock
,
flags
);
ret
=
-
EINVAL
;
goto
err_out_deregister_dev
;
}
spin_unlock_irqrestore
(
&
iadev
->
misc_lock
,
flags
);
IF_EVENT
(
printk
(
"iadev_count = %d
\n
"
,
iadev_count
);)
iadev
->
next_board
=
ia_boards
;
ia_boards
=
dev
;
pci_set_drvdata
(
pdev
,
dev
);
return
0
;
err_out_deregister_dev:
atm_dev_deregister
(
dev
);
err_out_disable_dev:
pci_disable_device
(
pdev
);
err_out_free_iadev:
kfree
(
iadev
);
err_out:
return
ret
;
}
static
void
__devexit
ia_remove_one
(
struct
pci_dev
*
pdev
)
{
struct
atm_dev
*
dev
=
pci_get_drvdata
(
pdev
);
IADEV
*
iadev
=
INPH_IA_DEV
(
dev
);
ia_phy_put
(
dev
,
ia_phy_get
(
dev
,
0x10
)
&
~
(
0x4
),
0x10
);
udelay
(
1
);
/* De-register device */
free_irq
(
iadev
->
irq
,
dev
);
iadev_count
--
;
ia_dev
[
iadev_count
]
=
NULL
;
_ia_dev
[
iadev_count
]
=
NULL
;
atm_dev_deregister
(
dev
);
IF_EVENT
(
printk
(
"iav deregistered at (itf:%d)
\n
"
,
dev
->
number
);)
iounmap
((
void
*
)
iadev
->
base
);
pci_disable_device
(
pdev
);
ia_free_rx
(
iadev
);
ia_free_tx
(
iadev
);
kfree
(
iadev
);
}
static
struct
pci_device_id
ia_pci_tbl
[]
__devinitdata
=
{
{
PCI_VENDOR_ID_IPHASE
,
0x0008
,
PCI_ANY_ID
,
PCI_ANY_ID
,
},
{
PCI_VENDOR_ID_IPHASE
,
0x0009
,
PCI_ANY_ID
,
PCI_ANY_ID
,
},
{
0
,}
};
MODULE_DEVICE_TABLE
(
pci
,
ia_pci_tbl
);
static
struct
pci_driver
ia_driver
=
{
.
name
=
DEV_LABEL
,
.
id_table
=
ia_pci_tbl
,
.
probe
=
ia_init_one
,
.
remove
=
ia_remove_one
,
};
static
int
__init
ia_module_init
(
void
)
{
IF_EVENT
(
printk
(
">ia init_module
\n
"
);)
if
(
!
ia_detect
())
{
{
int
ret
;
ret
=
pci_module_init
(
&
ia_driver
);
if
(
ret
>=
0
)
{
ia_timer
.
expires
=
jiffies
+
3
*
HZ
;
add_timer
(
&
ia_timer
);
}
else
printk
(
KERN_ERR
DEV_LABEL
": no adapter found
\n
"
);
return
-
ENXIO
;
}
ia_timer
.
expires
=
jiffies
+
3
*
HZ
;
add_timer
(
&
ia_timer
);
return
0
;
}
return
ret
;
}
static
void
__exit
ia_module_exit
(
void
)
{
struct
atm_dev
*
dev
;
IADEV
*
iadev
;
unsigned
short
command
;
int
i
,
j
=
0
;
IF_EVENT
(
printk
(
">ia cleanup_module
\n
"
);)
if
(
MOD_IN_USE
)
printk
(
"ia: module in use
\n
"
);
{
pci_unregister_driver
(
&
ia_driver
);
del_timer
(
&
ia_timer
);
while
(
ia_dev
[
j
])
{
dev
=
ia_boards
;
iadev
=
INPH_IA_DEV
(
dev
);
ia_boards
=
iadev
->
next_board
;
/* disable interrupt of lost signal */
ia_phy_put
(
dev
,
ia_phy_get
(
dev
,
0x10
)
&
~
(
0x4
),
0x10
);
udelay
(
1
);
/* De-register device */
atm_dev_deregister
(
dev
);
IF_EVENT
(
printk
(
"iav deregistered at (itf:%d)
\n
"
,
dev
->
number
);)
for
(
i
=
0
;
i
<
iadev
->
num_tx_desc
;
i
++
)
kfree
(
iadev
->
tx_buf
[
i
]);
kfree
(
iadev
->
tx_buf
);
/* Disable memory mapping and busmastering */
if
(
pci_read_config_word
(
iadev
->
pci
,
PCI_COMMAND
,
&
command
)
!=
0
)
{
printk
(
"ia: can't read PCI_COMMAND.
\n
"
);
}
command
&=
~
(
PCI_COMMAND_MEMORY
|
PCI_COMMAND_MASTER
);
if
(
pci_write_config_word
(
iadev
->
pci
,
PCI_COMMAND
,
command
)
!=
0
)
{
printk
(
"ia: can't write PCI_COMMAND.
\n
"
);
}
free_irq
(
iadev
->
irq
,
dev
);
iounmap
((
void
*
)
iadev
->
base
);
kfree
(
iadev
);
j
++
;
}
/* and voila whatever we tried seems to work. I don't know if it will
fix suni errors though. Really doubt that. */
for
(
i
=
0
;
i
<
8
;
i
++
)
{
ia_dev
[
i
]
=
NULL
;
_ia_dev
[
i
]
=
NULL
;
}
}
module_init
(
ia_module_init
);
...
...
drivers/atm/iphase.h
View file @
6d23b118
...
...
@@ -200,7 +200,13 @@ struct cpcs_trailer
u_short
length
;
u_int
crc32
;
};
struct
cpcs_trailer_desc
{
struct
cpcs_trailer
*
cpcs
;
dma_addr_t
dma_addr
;
};
struct
ia_vcc
{
int
rxing
;
...
...
@@ -272,6 +278,7 @@ struct ext_vc
#define DLE_ENTRIES 256
#define DMA_INT_ENABLE 0x0002
/* use for both Tx and Rx */
#define TX_DLE_PSI 0x0001
#define DLE_TOTAL_SIZE (sizeof(struct dle)*DLE_ENTRIES)
/* Descriptor List Entries (DLE) */
struct
dle
...
...
@@ -1017,7 +1024,7 @@ typedef struct iadev_t {
struct
wait_queue
*
close_wait
;
struct
wait_queue
*
timeout_wait
;
#endif
caddr_t
*
tx_buf
;
struct
cpcs_trailer_desc
*
tx_buf
;
u16
num_tx_desc
,
tx_buf_sz
,
rate_limit
;
u32
tx_cell_cnt
,
tx_pkt_cnt
;
u32
MAIN_VC_TABLE_ADDR
,
EXT_VC_TABLE_ADDR
,
ABR_SCHED_TABLE_ADDR
;
...
...
@@ -1063,7 +1070,9 @@ typedef struct iadev_t {
struct
desc_tbl_t
*
desc_tbl
;
u_short
host_tcq_wr
;
struct
testTable_t
**
testTable
;
}
IADEV
;
dma_addr_t
tx_dle_dma
;
dma_addr_t
rx_dle_dma
;
}
IADEV
;
#define INPH_IA_DEV(d) ((IADEV *) (d)->dev_data)
...
...
drivers/atm/lanai.c
View file @
6d23b118
...
...
@@ -2108,8 +2108,7 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
}
result
=
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
w
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't read ""
PCI_SUBSYSTEM_ID: %d
\n
"
,
lanai
->
number
,
result
);
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't read PCI_SUBSYSTEM_ID: %d
\n
"
,
lanai
->
number
,
result
);
return
-
EINVAL
;
}
if
((
result
=
check_board_id_and_rev
(
"PCI"
,
w
,
NULL
))
!=
0
)
...
...
drivers/atm/zatm.c
View file @
6d23b118
...
...
@@ -1260,13 +1260,13 @@ static void zatm_int(int irq,void *dev_id,struct pt_regs *regs)
/* don't handle RD */
if
(
reason
&
uPD98401_INT_SPE
)
printk
(
KERN_ALERT
DEV_LABEL
"(itf %d): system parity "
"error at 0x%08x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
"error at 0x%08
l
x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
if
(
reason
&
uPD98401_INT_CPE
)
printk
(
KERN_ALERT
DEV_LABEL
"(itf %d): control memory "
"parity error at 0x%08x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
"parity error at 0x%08
l
x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
if
(
reason
&
uPD98401_INT_SBE
)
{
printk
(
KERN_ALERT
DEV_LABEL
"(itf %d): system bus "
"error at 0x%08x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
"error at 0x%08
l
x
\n
"
,
dev
->
number
,
zin
(
ADDR
));
event_dump
();
}
/* don't handle IND */
...
...
@@ -1448,7 +1448,7 @@ static int __init zatm_init(struct atm_dev *dev)
}
while
(
t0
>
t1
||
t1
>
t2
);
/* loop if wrapping ... */
zatm_dev
->
khz
=
t2
-
2
*
t1
+
t0
;
printk
(
KERN_NOTICE
DEV_LABEL
"(itf %d): uPD98401 %
d.%
d at %d.%03d "
printk
(
KERN_NOTICE
DEV_LABEL
"(itf %d): uPD98401 %
ld.%l
d at %d.%03d "
"MHz
\n
"
,
dev
->
number
,
(
zin
(
VER
)
&
uPD98401_MAJOR
)
>>
uPD98401_MAJOR_SHIFT
,
zin
(
VER
)
&
uPD98401_MINOR
,
zatm_dev
->
khz
/
1000
,
zatm_dev
->
khz
%
1000
);
...
...
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