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
927f6aaa
Commit
927f6aaa
authored
Jul 27, 2003
by
Chas Williams
Committed by
Stephen Hemminger
Jul 27, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ATM]: Update LANAI driver to modern PCI and DMA APIs (from mitch@sfgoth.com)
parent
d98e960e
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
155 additions
and
158 deletions
+155
-158
drivers/atm/lanai.c
drivers/atm/lanai.c
+155
-158
No files found.
drivers/atm/lanai.c
View file @
927f6aaa
/* lanai.c -- Copyright 1999 by Mitchell Blank Jr <mitch@sfgoth.com>
/* lanai.c -- Copyright 1999
-2003
by Mitchell Blank Jr <mitch@sfgoth.com>
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
...
@@ -55,6 +55,7 @@
...
@@ -55,6 +55,7 @@
*/
*/
/* Version history:
/* Version history:
* v.1.00 -- 26-JUL-2003 -- PCI/DMA updates
* v.0.02 -- 11-JAN-2000 -- Endian fixes
* v.0.02 -- 11-JAN-2000 -- Endian fixes
* v.0.01 -- 30-NOV-1999 -- Initial release
* v.0.01 -- 30-NOV-1999 -- Initial release
*/
*/
...
@@ -178,7 +179,7 @@
...
@@ -178,7 +179,7 @@
printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
#define APRINTK(truth, format, args...) \
#define APRINTK(truth, format, args...) \
do { \
do { \
if (
!(truth
)) \
if (
unlikely(!(truth)
)) \
printk(KERN_ERR DEV_LABEL ": " format, ##args); \
printk(KERN_ERR DEV_LABEL ": " format, ##args); \
} while (0)
} while (0)
...
@@ -215,7 +216,7 @@ struct lanai_buffer {
...
@@ -215,7 +216,7 @@ struct lanai_buffer {
u32
*
start
;
/* From get_free_pages */
u32
*
start
;
/* From get_free_pages */
u32
*
end
;
/* One past last byte */
u32
*
end
;
/* One past last byte */
u32
*
ptr
;
/* Pointer to current host location */
u32
*
ptr
;
/* Pointer to current host location */
int
order
;
/* log2(size/PAGE_SIZE) */
dma_addr_t
dmaaddr
;
};
};
struct
lanai_vcc_stats
{
struct
lanai_vcc_stats
{
...
@@ -373,89 +374,76 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai,
...
@@ -373,89 +374,76 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai,
/*
/*
* Lanai needs DMA buffers aligned to 256 bytes of at least 1024 bytes -
* Lanai needs DMA buffers aligned to 256 bytes of at least 1024 bytes -
*
we assume that any page allocation will do. I'm sure this is
*
usually any page allocation will do. Just to be safe in case
*
never going to be a problem, but it's good to document assumtions
*
PAGE_SIZE is insanely tiny, though...
*/
*/
#if PAGE_SIZE < 1024
#define LANAI_PAGE_SIZE ((PAGE_SIZE >= 1024) ? PAGE_SIZE : 1024)
#error PAGE_SIZE too small to support LANAI chipset
#endif
/*
* We also assume that the maximum buffer size will be some number
* of whole pages, although that wouldn't be too hard to fix
*/
#if PAGE_SIZE > (128 * 1024)
#error PAGE_SIZE too large to support LANAI chipset
#endif
/* Convert a size to "order" for __get_free_pages */
static
int
bytes_to_order
(
int
bytes
)
{
int
order
=
0
;
if
(
bytes
>
(
128
*
1024
))
bytes
=
128
*
1024
;
/* Max buffer size for lanai */
while
((
PAGE_SIZE
<<
order
)
<
bytes
)
order
++
;
return
order
;
}
/*
/*
* Allocate a buffer in host RAM for service list, RX, or TX
* Allocate a buffer in host RAM for service list, RX, or TX
* Returns buf->
order<0
if no memory
* Returns buf->
start==NULL
if no memory
* Note that the size will be rounded up
to an "order" of pag
es, and
* Note that the size will be rounded up
2^n byt
es, and
* if we can't allocate that we'll settle for something smaller
* if we can't allocate that we'll settle for something smaller
* until minbytes
* until minbytes
*
* NOTE: buffer must be 32-bit DMA capable - when linux can
* make distinction, this will need tweaking for this
* to work on BIG memory machines.
*/
*/
static
void
lanai_buf_allocate
(
struct
lanai_buffer
*
buf
,
static
void
lanai_buf_allocate
(
struct
lanai_buffer
*
buf
,
int
bytes
,
int
minbytes
)
size_t
bytes
,
size_t
minbytes
,
struct
pci_dev
*
pci
)
{
{
unsigned
long
address
;
int
size
;
int
order
=
bytes_to_order
(
bytes
);
if
(
bytes
>
(
128
*
1024
))
/* max lanai buffer size */
bytes
=
128
*
1024
;
for
(
size
=
LANAI_PAGE_SIZE
;
size
<
bytes
;
size
*=
2
)
;
if
(
minbytes
<
LANAI_PAGE_SIZE
)
minbytes
=
LANAI_PAGE_SIZE
;
do
{
do
{
address
=
__get_free_pages
(
GFP_KERNEL
,
order
);
/*
if
(
address
!=
0
)
{
/* Success */
* Technically we could use non-consistent mappings for
bytes
=
PAGE_SIZE
<<
order
;
* everything, but the way the lanai uses DMA memory would
buf
->
start
=
buf
->
ptr
=
(
u32
*
)
address
;
* make that a terrific pain. This is much simpler.
buf
->
end
=
(
u32
*
)
(
address
+
bytes
);
*/
memset
((
void
*
)
address
,
0
,
bytes
);
buf
->
start
=
pci_alloc_consistent
(
pci
,
size
,
&
buf
->
dmaaddr
);
if
(
buf
->
start
!=
NULL
)
{
/* Success */
/* Lanai requires 256-byte alignment of DMA bufs */
APRINTK
((
buf
->
dmaaddr
&
~
0xFFFFFF00
)
==
0
,
"bad dmaaddr: 0x%lx
\n
"
,
(
unsigned
long
)
buf
->
dmaaddr
);
buf
->
ptr
=
buf
->
start
;
buf
->
end
=
(
u32
*
)
(
&
((
unsigned
char
*
)
buf
->
start
)[
size
]);
memset
(
buf
->
start
,
0
,
size
);
break
;
break
;
}
}
if
((
PAGE_SIZE
<<
--
order
)
<
minbytes
)
size
/=
2
;
order
=
-
1
;
/* Too small - give up */
}
while
(
size
>=
minbytes
);
}
while
(
order
>=
0
);
buf
->
order
=
order
;
}
static
inline
void
lanai_buf_deallocate
(
struct
lanai_buffer
*
buf
)
{
if
(
buf
->
order
>=
0
)
{
APRINTK
(
buf
->
start
!=
0
,
"lanai_buf_deallocate: start==0!
\n
"
);
free_pages
((
unsigned
long
)
buf
->
start
,
buf
->
order
);
buf
->
start
=
buf
->
end
=
buf
->
ptr
=
0
;
}
}
}
/* size of buffer in bytes */
/* size of buffer in bytes */
static
inline
in
t
lanai_buf_size
(
const
struct
lanai_buffer
*
buf
)
static
inline
size_
t
lanai_buf_size
(
const
struct
lanai_buffer
*
buf
)
{
{
return
((
unsigned
long
)
buf
->
end
)
-
((
unsigned
long
)
buf
->
start
);
return
((
unsigned
long
)
buf
->
end
)
-
((
unsigned
long
)
buf
->
start
);
}
}
/* size of buffer as "card order" (0=1k .. 7=128k) */
static
void
lanai_buf_deallocate
(
struct
lanai_buffer
*
buf
,
static
inline
int
lanai_buf_size_cardorder
(
const
struct
lanai_buffer
*
buf
)
struct
pci_dev
*
pci
)
{
{
return
buf
->
order
+
PAGE_SHIFT
-
10
;
if
(
buf
->
start
!=
NULL
)
{
pci_free_consistent
(
pci
,
lanai_buf_size
(
buf
),
buf
->
start
,
buf
->
dmaaddr
);
buf
->
start
=
buf
->
end
=
buf
->
ptr
=
NULL
;
}
}
}
/*
DMA-able address for this buffer
*/
/*
size of buffer as "card order" (0=1k .. 7=128k)
*/
static
unsigned
long
lanai_buf_dmaadd
r
(
const
struct
lanai_buffer
*
buf
)
static
int
lanai_buf_size_cardorde
r
(
const
struct
lanai_buffer
*
buf
)
{
{
unsigned
long
r
=
virt_to_bus
(
buf
->
start
);
int
order
=
get_order
(
lanai_buf_size
(
buf
))
+
(
PAGE_SHIFT
-
10
);
APRINTK
((
r
&
~
0xFFFFFF00
)
==
0
,
"bad dmaaddr: 0x%lx
\n
"
,
(
long
)
r
);
return
r
;
/* This can only happen if PAGE_SIZE is gigantic, but just in case */
if
(
order
>
7
)
order
=
7
;
return
order
;
}
}
/* -------------------- HANDLE BACKLOG_VCCS BITFIELD: */
/* -------------------- HANDLE BACKLOG_VCCS BITFIELD: */
...
@@ -492,7 +480,7 @@ enum lanai_register {
...
@@ -492,7 +480,7 @@ enum lanai_register {
Reset_Reg
=
0x00
,
/* Reset; read for chip type; bits: */
Reset_Reg
=
0x00
,
/* Reset; read for chip type; bits: */
#define RESET_GET_BOARD_REV(x) (((x)>> 0)&0x03)
/* Board revision */
#define RESET_GET_BOARD_REV(x) (((x)>> 0)&0x03)
/* Board revision */
#define RESET_GET_BOARD_ID(x) (((x)>> 2)&0x03)
/* Board ID */
#define RESET_GET_BOARD_ID(x) (((x)>> 2)&0x03)
/* Board ID */
#define BOARD_ID_LANAI256 (0)
/* 25.6M adapt
o
r card */
#define BOARD_ID_LANAI256 (0)
/* 25.6M adapt
e
r card */
Endian_Reg
=
0x04
,
/* Endian setting */
Endian_Reg
=
0x04
,
/* Endian setting */
IntStatus_Reg
=
0x08
,
/* Interrupt status */
IntStatus_Reg
=
0x08
,
/* Interrupt status */
IntStatusMasked_Reg
=
0x0C
,
/* Interrupt status (masked) */
IntStatusMasked_Reg
=
0x0C
,
/* Interrupt status (masked) */
...
@@ -850,7 +838,7 @@ static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
...
@@ -850,7 +838,7 @@ static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
{
{
u32
addr1
;
u32
addr1
;
if
(
lvcc
->
rx
.
atmvcc
->
qos
.
aal
==
ATM_AAL5
)
{
if
(
lvcc
->
rx
.
atmvcc
->
qos
.
aal
==
ATM_AAL5
)
{
unsigned
long
dmaaddr
=
lanai_buf_dmaaddr
(
&
lvcc
->
rx
.
buf
)
;
dma_addr_t
dmaaddr
=
lvcc
->
rx
.
buf
.
dmaaddr
;
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_rxcrc1
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_rxcrc1
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_rxcrc2
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_rxcrc2
);
cardvcc_write
(
lvcc
,
0
,
vcc_rxwriteptr
);
cardvcc_write
(
lvcc
,
0
,
vcc_rxwriteptr
);
...
@@ -872,7 +860,7 @@ static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
...
@@ -872,7 +860,7 @@ static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
static
void
host_vcc_start_tx
(
const
struct
lanai_vcc
*
lvcc
)
static
void
host_vcc_start_tx
(
const
struct
lanai_vcc
*
lvcc
)
{
{
unsigned
long
dmaaddr
=
lanai_buf_dmaaddr
(
&
lvcc
->
tx
.
buf
)
;
dma_addr_t
dmaaddr
=
lvcc
->
tx
.
buf
.
dmaaddr
;
cardvcc_write
(
lvcc
,
0
,
vcc_txicg
);
cardvcc_write
(
lvcc
,
0
,
vcc_txicg
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_txcrc1
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_txcrc1
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_txcrc2
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_txcrc2
);
...
@@ -971,14 +959,15 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
...
@@ -971,14 +959,15 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
static
inline
int
aal0_buffer_allocate
(
struct
lanai_dev
*
lanai
)
static
inline
int
aal0_buffer_allocate
(
struct
lanai_dev
*
lanai
)
{
{
DPRINTK
(
"aal0_buffer_allocate: allocating AAL0 RX buffer
\n
"
);
DPRINTK
(
"aal0_buffer_allocate: allocating AAL0 RX buffer
\n
"
);
lanai_buf_allocate
(
&
lanai
->
aal0buf
,
AAL0_RX_BUFFER_SIZE
,
80
);
lanai_buf_allocate
(
&
lanai
->
aal0buf
,
AAL0_RX_BUFFER_SIZE
,
80
,
return
(
lanai
->
aal0buf
.
order
<
0
)
?
-
ENOMEM
:
0
;
lanai
->
pci
);
return
(
lanai
->
aal0buf
.
start
==
NULL
)
?
-
ENOMEM
:
0
;
}
}
static
inline
void
aal0_buffer_free
(
struct
lanai_dev
*
lanai
)
static
inline
void
aal0_buffer_free
(
struct
lanai_dev
*
lanai
)
{
{
DPRINTK
(
"aal0_buffer_allocate: freeing AAL0 RX buffer
\n
"
);
DPRINTK
(
"aal0_buffer_allocate: freeing AAL0 RX buffer
\n
"
);
lanai_buf_deallocate
(
&
lanai
->
aal0buf
);
lanai_buf_deallocate
(
&
lanai
->
aal0buf
,
lanai
->
pci
);
}
}
/* -------------------- EEPROM UTILITIES: */
/* -------------------- EEPROM UTILITIES: */
...
@@ -1678,36 +1667,37 @@ static inline struct lanai_vcc *new_lanai_vcc(void)
...
@@ -1678,36 +1667,37 @@ static inline struct lanai_vcc *new_lanai_vcc(void)
return
lvcc
;
return
lvcc
;
}
}
static
int
lanai_get_sized_buffer
(
int
number
,
struct
lanai_buffer
*
buf
,
static
int
lanai_get_sized_buffer
(
struct
lanai_dev
*
lanai
,
int
max_sdu
,
int
multiplier
,
int
min
,
const
char
*
name
)
struct
lanai_buffer
*
buf
,
int
max_sdu
,
int
multiplier
,
int
min
,
const
char
*
name
)
{
{
int
size
;
int
size
;
if
(
max_sdu
<
1
)
if
(
max_sdu
<
1
)
max_sdu
=
1
;
max_sdu
=
1
;
max_sdu
=
aal5_size
(
max_sdu
);
max_sdu
=
aal5_size
(
max_sdu
);
size
=
(
max_sdu
+
16
)
*
multiplier
+
16
;
size
=
(
max_sdu
+
16
)
*
multiplier
+
16
;
lanai_buf_allocate
(
buf
,
size
,
min
);
lanai_buf_allocate
(
buf
,
size
,
min
,
lanai
->
pci
);
if
(
buf
->
order
<
0
)
if
(
buf
->
start
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
lanai_buf_size
(
buf
)
<
size
)
if
(
lanai_buf_size
(
buf
)
<
size
)
printk
(
KERN_WARNING
DEV_LABEL
"(itf %d): wanted %d bytes "
printk
(
KERN_WARNING
DEV_LABEL
"(itf %d): wanted %d bytes "
"for %s buffer, got only %d
\n
"
,
number
,
size
,
name
,
"for %s buffer, got only %d
\n
"
,
lanai
->
number
,
size
,
name
,
lanai_buf_size
(
buf
));
lanai_buf_size
(
buf
));
DPRINTK
(
"Allocated %d byte %s buffer
\n
"
,
lanai_buf_size
(
buf
),
name
);
DPRINTK
(
"Allocated %d byte %s buffer
\n
"
,
lanai_buf_size
(
buf
),
name
);
return
0
;
return
0
;
}
}
/* Setup a RX buffer for a currently unbound AAL5 vci */
/* Setup a RX buffer for a currently unbound AAL5 vci */
static
inline
int
lanai_setup_rx_vci_aal5
(
int
number
,
struct
lanai_vcc
*
lvcc
,
static
inline
int
lanai_setup_rx_vci_aal5
(
struct
lanai_dev
*
lanai
,
const
struct
atm_qos
*
qos
)
struct
lanai_vcc
*
lvcc
,
const
struct
atm_qos
*
qos
)
{
{
return
lanai_get_sized_buffer
(
number
,
&
lvcc
->
rx
.
buf
,
return
lanai_get_sized_buffer
(
lanai
,
&
lvcc
->
rx
.
buf
,
qos
->
rxtp
.
max_sdu
,
AAL5_RX_MULTIPLIER
,
qos
->
rxtp
.
max_sdu
+
32
,
qos
->
rxtp
.
max_sdu
,
AAL5_RX_MULTIPLIER
,
qos
->
rxtp
.
max_sdu
+
32
,
"RX"
);
"RX"
);
}
}
/* Setup a TX buffer for a currently unbound AAL5 vci */
/* Setup a TX buffer for a currently unbound AAL5 vci */
static
int
lanai_setup_tx_vci
(
int
number
,
struct
lanai_vcc
*
lvcc
,
static
int
lanai_setup_tx_vci
(
struct
lanai_dev
*
lanai
,
struct
lanai_vcc
*
lvcc
,
const
struct
atm_qos
*
qos
)
const
struct
atm_qos
*
qos
)
{
{
int
max_sdu
,
multiplier
;
int
max_sdu
,
multiplier
;
...
@@ -1720,7 +1710,7 @@ static int lanai_setup_tx_vci(int number, struct lanai_vcc *lvcc,
...
@@ -1720,7 +1710,7 @@ static int lanai_setup_tx_vci(int number, struct lanai_vcc *lvcc,
max_sdu
=
qos
->
txtp
.
max_sdu
;
max_sdu
=
qos
->
txtp
.
max_sdu
;
multiplier
=
AAL5_TX_MULTIPLIER
;
multiplier
=
AAL5_TX_MULTIPLIER
;
}
}
return
lanai_get_sized_buffer
(
number
,
&
lvcc
->
tx
.
buf
,
max_sdu
,
return
lanai_get_sized_buffer
(
lanai
,
&
lvcc
->
tx
.
buf
,
max_sdu
,
multiplier
,
80
,
"TX"
);
multiplier
,
80
,
"TX"
);
}
}
...
@@ -1781,8 +1771,9 @@ static void lanai_reset(struct lanai_dev *lanai)
...
@@ -1781,8 +1771,9 @@ static void lanai_reset(struct lanai_dev *lanai)
*/
*/
static
int
__init
service_buffer_allocate
(
struct
lanai_dev
*
lanai
)
static
int
__init
service_buffer_allocate
(
struct
lanai_dev
*
lanai
)
{
{
lanai_buf_allocate
(
&
lanai
->
service
,
SERVICE_ENTRIES
*
4
,
0
);
lanai_buf_allocate
(
&
lanai
->
service
,
SERVICE_ENTRIES
*
4
,
8
,
if
(
lanai
->
service
.
order
<
0
)
lanai
->
pci
);
if
(
lanai
->
service
.
start
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
DPRINTK
(
"allocated service buffer at 0x%08lX, size %d(%d)
\n
"
,
DPRINTK
(
"allocated service buffer at 0x%08lX, size %d(%d)
\n
"
,
(
unsigned
long
)
lanai
->
service
.
start
,
(
unsigned
long
)
lanai
->
service
.
start
,
...
@@ -1793,14 +1784,14 @@ static int __init service_buffer_allocate(struct lanai_dev *lanai)
...
@@ -1793,14 +1784,14 @@ static int __init service_buffer_allocate(struct lanai_dev *lanai)
/* ServiceStuff register contains size and address of buffer */
/* ServiceStuff register contains size and address of buffer */
reg_write
(
lanai
,
reg_write
(
lanai
,
SSTUFF_SET_SIZE
(
lanai_buf_size_cardorder
(
&
lanai
->
service
))
|
SSTUFF_SET_SIZE
(
lanai_buf_size_cardorder
(
&
lanai
->
service
))
|
SSTUFF_SET_ADDR
(
lanai
_buf_dmaaddr
(
&
lanai
->
service
)
),
SSTUFF_SET_ADDR
(
lanai
->
service
.
dmaaddr
),
ServiceStuff_Reg
);
ServiceStuff_Reg
);
return
0
;
return
0
;
}
}
static
inline
void
service_buffer_deallocate
(
struct
lanai_dev
*
lanai
)
static
inline
void
service_buffer_deallocate
(
struct
lanai_dev
*
lanai
)
{
{
lanai_buf_deallocate
(
&
lanai
->
service
);
lanai_buf_deallocate
(
&
lanai
->
service
,
lanai
->
pci
);
}
}
/* Bitfields in service list */
/* Bitfields in service list */
...
@@ -2098,11 +2089,28 @@ static int check_board_id_and_rev(const char *name, u32 val, int *revp)
...
@@ -2098,11 +2089,28 @@ static int check_board_id_and_rev(const char *name, u32 val, int *revp)
/* -------------------- PCI INITIALIZATION/SHUTDOWN: */
/* -------------------- PCI INITIALIZATION/SHUTDOWN: */
static
in
line
in
t
__init
lanai_pci_start
(
struct
lanai_dev
*
lanai
)
static
int
__init
lanai_pci_start
(
struct
lanai_dev
*
lanai
)
{
{
struct
pci_dev
*
pci
=
lanai
->
pci
;
struct
pci_dev
*
pci
=
lanai
->
pci
;
int
result
;
int
result
;
u16
w
;
u16
w
;
if
(
pci_enable_device
(
pci
)
!=
0
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't enable "
"PCI device"
,
lanai
->
number
);
return
-
ENXIO
;
}
pci_set_master
(
pci
);
if
(
pci_set_dma_mask
(
pci
,
0xFFFFFFFF
)
!=
0
)
{
printk
(
KERN_WARNING
DEV_LABEL
"(itf %d): No suitable DMA available.
\n
"
,
lanai
->
number
);
return
-
EBUSY
;
}
if
(
pci_set_consistent_dma_mask
(
pci
,
0xFFFFFFFF
)
!=
0
)
{
printk
(
KERN_WARNING
DEV_LABEL
"(itf %d): No suitable DMA available.
\n
"
,
lanai
->
number
);
return
-
EBUSY
;
}
/* Get the pci revision byte */
/* Get the pci revision byte */
result
=
pci_read_config_byte
(
pci
,
PCI_REVISION_ID
,
result
=
pci_read_config_byte
(
pci
,
PCI_REVISION_ID
,
&
lanai
->
pci_revision
);
&
lanai
->
pci_revision
);
...
@@ -2113,7 +2121,8 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
...
@@ -2113,7 +2121,8 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
}
}
result
=
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
w
);
result
=
pci_read_config_word
(
pci
,
PCI_SUBSYSTEM_ID
,
&
w
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
{
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
;
return
-
EINVAL
;
}
}
if
((
result
=
check_board_id_and_rev
(
"PCI"
,
w
,
NULL
))
!=
0
)
if
((
result
=
check_board_id_and_rev
(
"PCI"
,
w
,
NULL
))
!=
0
)
...
@@ -2125,43 +2134,11 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
...
@@ -2125,43 +2134,11 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
"PCI_LATENCY_TIMER: %d
\n
"
,
lanai
->
number
,
result
);
"PCI_LATENCY_TIMER: %d
\n
"
,
lanai
->
number
,
result
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
result
=
pci_read_config_word
(
pci
,
PCI_COMMAND
,
&
w
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't read "
"PCI_COMMAND: %d
\n
"
,
lanai
->
number
,
result
);
return
-
EINVAL
;
}
w
|=
(
PCI_COMMAND_MEMORY
|
PCI_COMMAND_MASTER
|
PCI_COMMAND_SERR
|
PCI_COMMAND_PARITY
);
result
=
pci_write_config_word
(
pci
,
PCI_COMMAND
,
w
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't "
"write PCI_COMMAND: %d
\n
"
,
lanai
->
number
,
result
);
return
-
EINVAL
;
}
pcistatus_check
(
lanai
,
1
);
pcistatus_check
(
lanai
,
1
);
pcistatus_check
(
lanai
,
0
);
pcistatus_check
(
lanai
,
0
);
return
0
;
return
0
;
}
}
static
void
lanai_pci_stop
(
struct
lanai_dev
*
lanai
)
{
struct
pci_dev
*
pci
=
lanai
->
pci
;
int
result
;
u16
pci_command
;
result
=
pci_read_config_word
(
pci
,
PCI_COMMAND
,
&
pci_command
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
{
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't "
"read PCI_COMMAND: %d
\n
"
,
lanai
->
number
,
result
);
return
;
}
pci_command
&=
~
(
PCI_COMMAND_MEMORY
|
PCI_COMMAND_MASTER
);
result
=
pci_write_config_word
(
pci
,
PCI_COMMAND
,
pci_command
);
if
(
result
!=
PCIBIOS_SUCCESSFUL
)
printk
(
KERN_ERR
DEV_LABEL
"(itf %d): can't "
"write PCI_COMMAND: %d
\n
"
,
lanai
->
number
,
result
);
}
/* -------------------- VPI/VCI ALLOCATION: */
/* -------------------- VPI/VCI ALLOCATION: */
/*
/*
...
@@ -2445,7 +2422,7 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
...
@@ -2445,7 +2422,7 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
#endif
#endif
iounmap
((
void
*
)
lanai
->
base
);
iounmap
((
void
*
)
lanai
->
base
);
error_pci:
error_pci:
lanai_pci_stop
(
lana
i
);
pci_disable_device
(
lanai
->
pc
i
);
error:
error:
return
result
;
return
result
;
}
}
...
@@ -2470,7 +2447,7 @@ static void lanai_dev_close(struct atm_dev *atmdev)
...
@@ -2470,7 +2447,7 @@ static void lanai_dev_close(struct atm_dev *atmdev)
lanai
->
conf1
|=
CONFIG1_POWERDOWN
;
lanai
->
conf1
|=
CONFIG1_POWERDOWN
;
conf1_write
(
lanai
);
conf1_write
(
lanai
);
#endif
#endif
lanai_pci_stop
(
lana
i
);
pci_disable_device
(
lanai
->
pc
i
);
vcc_table_deallocate
(
lanai
);
vcc_table_deallocate
(
lanai
);
service_buffer_deallocate
(
lanai
);
service_buffer_deallocate
(
lanai
);
iounmap
((
void
*
)
lanai
->
base
);
iounmap
((
void
*
)
lanai
->
base
);
...
@@ -2493,7 +2470,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
...
@@ -2493,7 +2470,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
if
(
--
lanai
->
naal0
<=
0
)
if
(
--
lanai
->
naal0
<=
0
)
aal0_buffer_free
(
lanai
);
aal0_buffer_free
(
lanai
);
}
else
}
else
lanai_buf_deallocate
(
&
lvcc
->
rx
.
buf
);
lanai_buf_deallocate
(
&
lvcc
->
rx
.
buf
,
lanai
->
pci
);
lvcc
->
rx
.
atmvcc
=
NULL
;
lvcc
->
rx
.
atmvcc
=
NULL
;
}
}
if
(
lvcc
->
tx
.
atmvcc
==
atmvcc
)
{
if
(
lvcc
->
tx
.
atmvcc
==
atmvcc
)
{
...
@@ -2503,7 +2480,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
...
@@ -2503,7 +2480,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
lanai
->
cbrvcc
=
NULL
;
lanai
->
cbrvcc
=
NULL
;
}
}
lanai_shutdown_tx_vci
(
lanai
,
lvcc
);
lanai_shutdown_tx_vci
(
lanai
,
lvcc
);
lanai_buf_deallocate
(
&
lvcc
->
tx
.
buf
);
lanai_buf_deallocate
(
&
lvcc
->
tx
.
buf
,
lanai
->
pci
);
lvcc
->
tx
.
atmvcc
=
NULL
;
lvcc
->
tx
.
atmvcc
=
NULL
;
}
}
if
(
--
lvcc
->
nref
==
0
)
{
if
(
--
lvcc
->
nref
==
0
)
{
...
@@ -2551,7 +2528,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
...
@@ -2551,7 +2528,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
result
=
aal0_buffer_allocate
(
lanai
);
result
=
aal0_buffer_allocate
(
lanai
);
}
else
}
else
result
=
lanai_setup_rx_vci_aal5
(
result
=
lanai_setup_rx_vci_aal5
(
lanai
->
number
,
lvcc
,
&
atmvcc
->
qos
);
lanai
,
lvcc
,
&
atmvcc
->
qos
);
if
(
result
!=
0
)
if
(
result
!=
0
)
goto
out_free
;
goto
out_free
;
lvcc
->
rx
.
atmvcc
=
atmvcc
;
lvcc
->
rx
.
atmvcc
=
atmvcc
;
...
@@ -2566,7 +2543,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
...
@@ -2566,7 +2543,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
if
(
atmvcc
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
if
(
atmvcc
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
APRINTK
(
lvcc
->
tx
.
atmvcc
==
NULL
,
"tx.atmvcc!=NULL, vci=%d
\n
"
,
APRINTK
(
lvcc
->
tx
.
atmvcc
==
NULL
,
"tx.atmvcc!=NULL, vci=%d
\n
"
,
vci
);
vci
);
result
=
lanai_setup_tx_vci
(
lanai
->
number
,
lvcc
,
&
atmvcc
->
qos
);
result
=
lanai_setup_tx_vci
(
lanai
,
lvcc
,
&
atmvcc
->
qos
);
if
(
result
!=
0
)
if
(
result
!=
0
)
goto
out_free
;
goto
out_free
;
lvcc
->
tx
.
atmvcc
=
atmvcc
;
lvcc
->
tx
.
atmvcc
=
atmvcc
;
...
@@ -2849,49 +2826,69 @@ static const struct atmdev_ops ops = {
...
@@ -2849,49 +2826,69 @@ static const struct atmdev_ops ops = {
.
proc_read
=
lanai_proc_read
.
proc_read
=
lanai_proc_read
};
};
/* detect one type of card LANAI2 or LANAIHB */
/* initialize one probed card */
static
int
__init
lanai_detect_1
(
unsigned
int
vendor
,
unsigned
int
device
)
static
int
__devinit
lanai_init_one
(
struct
pci_dev
*
pci
,
const
struct
pci_device_id
*
ident
)
{
{
struct
pci_dev
*
pci
=
NULL
;
struct
lanai_dev
*
lanai
;
struct
lanai_dev
*
lanai
;
struct
atm_dev
*
atmdev
;
struct
atm_dev
*
atmdev
;
int
count
=
0
,
result
;
int
result
;
while
((
pci
=
pci_find_device
(
vendor
,
device
,
pci
))
!=
NULL
)
{
lanai
=
(
struct
lanai_dev
*
)
lanai
=
(
struct
lanai_dev
*
)
kmalloc
(
sizeof
(
*
lanai
),
GFP_KERNEL
);
kmalloc
(
sizeof
*
lanai
,
GFP_KERNEL
);
if
(
lanai
==
NULL
)
{
if
(
lanai
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't allocate "
printk
(
KERN_ERR
DEV_LABEL
"
dev_data structure!
\n
"
);
": couldn't allocate
dev_data structure!
\n
"
);
break
;
return
-
ENOMEM
;
}
}
atmdev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
0
);
atmdev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
0
);
if
(
atmdev
==
NULL
)
{
if
(
atmdev
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't register "
printk
(
KERN_ERR
DEV_LABEL
"
atm device!
\n
"
);
": couldn't register
atm device!
\n
"
);
kfree
(
lanai
);
kfree
(
lanai
);
break
;
return
-
EBUSY
;
}
}
atmdev
->
dev_data
=
lanai
;
atmdev
->
dev_data
=
lanai
;
lanai
->
pci
=
pci
;
lanai
->
pci
=
pci
;
lanai
->
type
=
(
enum
lanai_type
)
device
;
lanai
->
type
=
(
enum
lanai_type
)
ident
->
device
;
if
((
result
=
lanai_dev_open
(
atmdev
))
!=
0
)
{
result
=
lanai_dev_open
(
atmdev
);
if
(
result
!=
0
)
{
DPRINTK
(
"lanai_start() failed, err=%d
\n
"
,
-
result
);
DPRINTK
(
"lanai_start() failed, err=%d
\n
"
,
-
result
);
atm_dev_deregister
(
atmdev
);
atm_dev_deregister
(
atmdev
);
kfree
(
lanai
);
kfree
(
lanai
);
continue
;
}
count
++
;
}
}
return
coun
t
;
return
resul
t
;
}
}
static
struct
pci_device_id
lanai_pci_tbl
[]
__devinitdata
=
{
{
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAI2
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAIHB
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
},
{
0
,
}
/* terminal entry */
};
MODULE_DEVICE_TABLE
(
pci
,
lanai_pci_tbl
);
static
struct
pci_driver
lanai_driver
=
{
.
name
=
DEV_LABEL
,
.
id_table
=
lanai_pci_tbl
,
.
probe
=
lanai_init_one
,
};
static
int
__init
lanai_module_init
(
void
)
static
int
__init
lanai_module_init
(
void
)
{
{
if
(
lanai_detect_1
(
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAI2
)
+
int
x
;
lanai_detect_1
(
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAIHB
))
return
0
;
x
=
pci_module_init
(
&
lanai_driver
);
printk
(
KERN_ERR
DEV_LABEL
": no adaptor found
\n
"
);
if
(
x
!=
0
)
return
-
ENODEV
;
printk
(
KERN_ERR
DEV_LABEL
": no adapter found
\n
"
);
return
x
;
}
}
static
void
__exit
lanai_module_exit
(
void
)
static
void
__exit
lanai_module_exit
(
void
)
...
...
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