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
Hide 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
* modify it under the terms of the GNU General Public License
...
...
@@ -55,6 +55,7 @@
*/
/* Version history:
* v.1.00 -- 26-JUL-2003 -- PCI/DMA updates
* v.0.02 -- 11-JAN-2000 -- Endian fixes
* v.0.01 -- 30-NOV-1999 -- Initial release
*/
...
...
@@ -178,7 +179,7 @@
printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
#define APRINTK(truth, format, args...) \
do { \
if (
!(truth
)) \
if (
unlikely(!(truth)
)) \
printk(KERN_ERR DEV_LABEL ": " format, ##args); \
} while (0)
...
...
@@ -215,7 +216,7 @@ struct lanai_buffer {
u32
*
start
;
/* From get_free_pages */
u32
*
end
;
/* One past last byte */
u32
*
ptr
;
/* Pointer to current host location */
int
order
;
/* log2(size/PAGE_SIZE) */
dma_addr_t
dmaaddr
;
};
struct
lanai_vcc_stats
{
...
...
@@ -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 -
*
we assume that any page allocation will do. I'm sure this is
*
never going to be a problem, but it's good to document assumtions
*
usually any page allocation will do. Just to be safe in case
*
PAGE_SIZE is insanely tiny, though...
*/
#if 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
;
}
#define LANAI_PAGE_SIZE ((PAGE_SIZE >= 1024) ? PAGE_SIZE : 1024)
/*
* Allocate a buffer in host RAM for service list, RX, or TX
* Returns buf->
order<0
if no memory
* Note that the size will be rounded up
to an "order" of pag
es, and
* Returns buf->
start==NULL
if no memory
* 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
* 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
,
int
bytes
,
int
minbytes
)
size_t
bytes
,
size_t
minbytes
,
struct
pci_dev
*
pci
)
{
unsigned
long
address
;
int
order
=
bytes_to_order
(
bytes
);
int
size
;
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
{
address
=
__get_free_pages
(
GFP_KERNEL
,
order
);
if
(
address
!=
0
)
{
/* Success */
bytes
=
PAGE_SIZE
<<
order
;
buf
->
start
=
buf
->
ptr
=
(
u32
*
)
address
;
buf
->
end
=
(
u32
*
)
(
address
+
bytes
);
memset
((
void
*
)
address
,
0
,
bytes
);
/*
* Technically we could use non-consistent mappings for
* everything, but the way the lanai uses DMA memory would
* make that a terrific pain. This is much simpler.
*/
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
;
}
if
((
PAGE_SIZE
<<
--
order
)
<
minbytes
)
order
=
-
1
;
/* Too small - give up */
}
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
/=
2
;
}
while
(
size
>=
minbytes
);
}
/* 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
);
}
/* size of buffer as "card order" (0=1k .. 7=128k) */
static
inline
int
lanai_buf_size_cardorder
(
const
struct
lanai_buffer
*
buf
)
static
void
lanai_buf_deallocate
(
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
*/
static
unsigned
long
lanai_buf_dmaadd
r
(
const
struct
lanai_buffer
*
buf
)
/*
size of buffer as "card order" (0=1k .. 7=128k)
*/
static
int
lanai_buf_size_cardorde
r
(
const
struct
lanai_buffer
*
buf
)
{
unsigned
long
r
=
virt_to_bus
(
buf
->
start
);
APRINTK
((
r
&
~
0xFFFFFF00
)
==
0
,
"bad dmaaddr: 0x%lx
\n
"
,
(
long
)
r
);
return
r
;
int
order
=
get_order
(
lanai_buf_size
(
buf
))
+
(
PAGE_SHIFT
-
10
);
/* This can only happen if PAGE_SIZE is gigantic, but just in case */
if
(
order
>
7
)
order
=
7
;
return
order
;
}
/* -------------------- HANDLE BACKLOG_VCCS BITFIELD: */
...
...
@@ -492,7 +480,7 @@ enum lanai_register {
Reset_Reg
=
0x00
,
/* Reset; read for chip type; bits: */
#define RESET_GET_BOARD_REV(x) (((x)>> 0)&0x03)
/* Board revision */
#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 */
IntStatus_Reg
=
0x08
,
/* Interrupt status */
IntStatusMasked_Reg
=
0x0C
,
/* Interrupt status (masked) */
...
...
@@ -850,7 +838,7 @@ static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
{
u32
addr1
;
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_rxcrc2
);
cardvcc_write
(
lvcc
,
0
,
vcc_rxwriteptr
);
...
...
@@ -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
)
{
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
,
0xFFFF
,
vcc_txcrc1
);
cardvcc_write
(
lvcc
,
0xFFFF
,
vcc_txcrc2
);
...
...
@@ -971,14 +959,15 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
static
inline
int
aal0_buffer_allocate
(
struct
lanai_dev
*
lanai
)
{
DPRINTK
(
"aal0_buffer_allocate: allocating AAL0 RX buffer
\n
"
);
lanai_buf_allocate
(
&
lanai
->
aal0buf
,
AAL0_RX_BUFFER_SIZE
,
80
);
return
(
lanai
->
aal0buf
.
order
<
0
)
?
-
ENOMEM
:
0
;
lanai_buf_allocate
(
&
lanai
->
aal0buf
,
AAL0_RX_BUFFER_SIZE
,
80
,
lanai
->
pci
);
return
(
lanai
->
aal0buf
.
start
==
NULL
)
?
-
ENOMEM
:
0
;
}
static
inline
void
aal0_buffer_free
(
struct
lanai_dev
*
lanai
)
{
DPRINTK
(
"aal0_buffer_allocate: freeing AAL0 RX buffer
\n
"
);
lanai_buf_deallocate
(
&
lanai
->
aal0buf
);
lanai_buf_deallocate
(
&
lanai
->
aal0buf
,
lanai
->
pci
);
}
/* -------------------- EEPROM UTILITIES: */
...
...
@@ -1678,36 +1667,37 @@ static inline struct lanai_vcc *new_lanai_vcc(void)
return
lvcc
;
}
static
int
lanai_get_sized_buffer
(
int
number
,
struct
lanai_buffer
*
buf
,
int
max_sdu
,
int
multiplier
,
int
min
,
const
char
*
name
)
static
int
lanai_get_sized_buffer
(
struct
lanai_dev
*
lanai
,
struct
lanai_buffer
*
buf
,
int
max_sdu
,
int
multiplier
,
int
min
,
const
char
*
name
)
{
int
size
;
if
(
max_sdu
<
1
)
max_sdu
=
1
;
max_sdu
=
aal5_size
(
max_sdu
);
size
=
(
max_sdu
+
16
)
*
multiplier
+
16
;
lanai_buf_allocate
(
buf
,
size
,
min
);
if
(
buf
->
order
<
0
)
lanai_buf_allocate
(
buf
,
size
,
min
,
lanai
->
pci
);
if
(
buf
->
start
==
NULL
)
return
-
ENOMEM
;
if
(
lanai_buf_size
(
buf
)
<
size
)
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
));
DPRINTK
(
"Allocated %d byte %s buffer
\n
"
,
lanai_buf_size
(
buf
),
name
);
return
0
;
}
/* Setup a RX buffer for a currently unbound AAL5 vci */
static
inline
int
lanai_setup_rx_vci_aal5
(
int
number
,
struct
lanai_vcc
*
lvcc
,
const
struct
atm_qos
*
qos
)
static
inline
int
lanai_setup_rx_vci_aal5
(
struct
lanai_dev
*
lanai
,
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
,
"RX"
);
}
/* 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
)
{
int
max_sdu
,
multiplier
;
...
...
@@ -1720,7 +1710,7 @@ static int lanai_setup_tx_vci(int number, struct lanai_vcc *lvcc,
max_sdu
=
qos
->
txtp
.
max_sdu
;
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"
);
}
...
...
@@ -1781,8 +1771,9 @@ static void lanai_reset(struct lanai_dev *lanai)
*/
static
int
__init
service_buffer_allocate
(
struct
lanai_dev
*
lanai
)
{
lanai_buf_allocate
(
&
lanai
->
service
,
SERVICE_ENTRIES
*
4
,
0
);
if
(
lanai
->
service
.
order
<
0
)
lanai_buf_allocate
(
&
lanai
->
service
,
SERVICE_ENTRIES
*
4
,
8
,
lanai
->
pci
);
if
(
lanai
->
service
.
start
==
NULL
)
return
-
ENOMEM
;
DPRINTK
(
"allocated service buffer at 0x%08lX, size %d(%d)
\n
"
,
(
unsigned
long
)
lanai
->
service
.
start
,
...
...
@@ -1793,14 +1784,14 @@ static int __init service_buffer_allocate(struct lanai_dev *lanai)
/* ServiceStuff register contains size and address of buffer */
reg_write
(
lanai
,
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
);
return
0
;
}
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 */
...
...
@@ -2098,11 +2089,28 @@ static int check_board_id_and_rev(const char *name, u32 val, int *revp)
/* -------------------- 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
;
int
result
;
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 */
result
=
pci_read_config_byte
(
pci
,
PCI_REVISION_ID
,
&
lanai
->
pci_revision
);
...
...
@@ -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
);
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
)
...
...
@@ -2125,43 +2134,11 @@ static inline int __init lanai_pci_start(struct lanai_dev *lanai)
"PCI_LATENCY_TIMER: %d
\n
"
,
lanai
->
number
,
result
);
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
,
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: */
/*
...
...
@@ -2445,7 +2422,7 @@ static int __init lanai_dev_open(struct atm_dev *atmdev)
#endif
iounmap
((
void
*
)
lanai
->
base
);
error_pci:
lanai_pci_stop
(
lana
i
);
pci_disable_device
(
lanai
->
pc
i
);
error:
return
result
;
}
...
...
@@ -2470,7 +2447,7 @@ static void lanai_dev_close(struct atm_dev *atmdev)
lanai
->
conf1
|=
CONFIG1_POWERDOWN
;
conf1_write
(
lanai
);
#endif
lanai_pci_stop
(
lana
i
);
pci_disable_device
(
lanai
->
pc
i
);
vcc_table_deallocate
(
lanai
);
service_buffer_deallocate
(
lanai
);
iounmap
((
void
*
)
lanai
->
base
);
...
...
@@ -2493,7 +2470,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
if
(
--
lanai
->
naal0
<=
0
)
aal0_buffer_free
(
lanai
);
}
else
lanai_buf_deallocate
(
&
lvcc
->
rx
.
buf
);
lanai_buf_deallocate
(
&
lvcc
->
rx
.
buf
,
lanai
->
pci
);
lvcc
->
rx
.
atmvcc
=
NULL
;
}
if
(
lvcc
->
tx
.
atmvcc
==
atmvcc
)
{
...
...
@@ -2503,7 +2480,7 @@ static void lanai_close(struct atm_vcc *atmvcc)
lanai
->
cbrvcc
=
NULL
;
}
lanai_shutdown_tx_vci
(
lanai
,
lvcc
);
lanai_buf_deallocate
(
&
lvcc
->
tx
.
buf
);
lanai_buf_deallocate
(
&
lvcc
->
tx
.
buf
,
lanai
->
pci
);
lvcc
->
tx
.
atmvcc
=
NULL
;
}
if
(
--
lvcc
->
nref
==
0
)
{
...
...
@@ -2551,7 +2528,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
result
=
aal0_buffer_allocate
(
lanai
);
}
else
result
=
lanai_setup_rx_vci_aal5
(
lanai
->
number
,
lvcc
,
&
atmvcc
->
qos
);
lanai
,
lvcc
,
&
atmvcc
->
qos
);
if
(
result
!=
0
)
goto
out_free
;
lvcc
->
rx
.
atmvcc
=
atmvcc
;
...
...
@@ -2566,7 +2543,7 @@ static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
if
(
atmvcc
->
qos
.
txtp
.
traffic_class
!=
ATM_NONE
)
{
APRINTK
(
lvcc
->
tx
.
atmvcc
==
NULL
,
"tx.atmvcc!=NULL, vci=%d
\n
"
,
vci
);
result
=
lanai_setup_tx_vci
(
lanai
->
number
,
lvcc
,
&
atmvcc
->
qos
);
result
=
lanai_setup_tx_vci
(
lanai
,
lvcc
,
&
atmvcc
->
qos
);
if
(
result
!=
0
)
goto
out_free
;
lvcc
->
tx
.
atmvcc
=
atmvcc
;
...
...
@@ -2849,49 +2826,69 @@ static const struct atmdev_ops ops = {
.
proc_read
=
lanai_proc_read
};
/* detect one type of card LANAI2 or LANAIHB */
static
int
__init
lanai_detect_1
(
unsigned
int
vendor
,
unsigned
int
device
)
/* initialize one probed card */
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
atm_dev
*
atmdev
;
int
count
=
0
,
result
;
while
((
pci
=
pci_find_device
(
vendor
,
device
,
pci
))
!=
NULL
)
{
lanai
=
(
struct
lanai_dev
*
)
kmalloc
(
sizeof
*
lanai
,
GFP_KERNEL
);
if
(
lanai
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't allocate "
"dev_data structure!
\n
"
)
;
break
;
}
atmdev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
0
);
if
(
atmdev
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't register "
"
atm device!
\n
"
);
kfree
(
lanai
);
break
;
}
atmdev
->
dev_data
=
lanai
;
lanai
->
pci
=
pc
i
;
lanai
->
type
=
(
enum
lanai_type
)
device
;
if
((
result
=
lanai_dev_open
(
atmdev
))
!=
0
)
{
DPRINTK
(
"lanai_start() failed, err=%d
\n
"
,
-
result
);
atm_dev_deregister
(
atmdev
);
kfree
(
lanai
);
continue
;
}
count
++
;
int
result
;
lanai
=
(
struct
lanai_dev
*
)
kmalloc
(
sizeof
(
*
lanai
),
GFP_KERNEL
);
if
(
lanai
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't allocate dev_data structure!
\n
"
);
return
-
ENOMEM
;
}
atmdev
=
atm_dev_register
(
DEV_LABEL
,
&
ops
,
-
1
,
0
);
if
(
atmdev
==
NULL
)
{
printk
(
KERN_ERR
DEV_LABEL
": couldn't register
atm device!
\n
"
);
kfree
(
lanai
);
return
-
EBUSY
;
}
atmdev
->
dev_data
=
lana
i
;
lanai
->
pci
=
pci
;
lanai
->
type
=
(
enum
lanai_type
)
ident
->
device
;
result
=
lanai_dev_open
(
atmdev
);
if
(
result
!=
0
)
{
DPRINTK
(
"lanai_start() failed, err=%d
\n
"
,
-
result
)
;
atm_dev_deregister
(
atmdev
);
kfree
(
lanai
)
;
}
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
)
{
if
(
lanai_detect_1
(
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAI2
)
+
lanai_detect_1
(
PCI_VENDOR_ID_EF
,
PCI_VENDOR_ID_EF_ATM_LANAIHB
))
return
0
;
printk
(
KERN_ERR
DEV_LABEL
": no adaptor found
\n
"
);
return
-
ENODEV
;
int
x
;
x
=
pci_module_init
(
&
lanai_driver
);
if
(
x
!=
0
)
printk
(
KERN_ERR
DEV_LABEL
": no adapter found
\n
"
);
return
x
;
}
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