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
92133ef4
Commit
92133ef4
authored
Jun 14, 2003
by
Stephen Hemminger
Committed by
David S. Miller
Jun 14, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NET]: Convert SLIP driver to alloc_netdev.
parent
760bddfb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
94 deletions
+124
-94
drivers/net/slip.c
drivers/net/slip.c
+124
-94
No files found.
drivers/net/slip.c
View file @
92133ef4
...
...
@@ -83,12 +83,7 @@
#define SLIP_VERSION "0.8.4-NET3.019-NEWTTY"
typedef
struct
slip_ctrl
{
struct
slip
ctrl
;
/* SLIP things */
struct
net_device
dev
;
/* the device */
}
slip_ctrl_t
;
static
slip_ctrl_t
**
slip_ctrls
;
static
struct
net_device
**
slip_devs
;
int
slip_maxdev
=
SL_NRUNIT
;
/* Can be overridden with insmod! */
MODULE_PARM
(
slip_maxdev
,
"i"
);
...
...
@@ -624,32 +619,45 @@ static int sl_init(struct net_device *dev)
*/
dev
->
mtu
=
sl
->
mtu
;
dev
->
hard_start_xmit
=
sl_xmit
;
dev
->
type
=
ARPHRD_SLIP
+
sl
->
mode
;
#ifdef SL_CHECK_TRANSMIT
dev
->
tx_timeout
=
sl_tx_timeout
;
dev
->
watchdog_timeo
=
20
*
HZ
;
#endif
return
0
;
}
static
void
sl_uninit
(
struct
net_device
*
dev
)
{
struct
slip
*
sl
=
(
struct
slip
*
)(
dev
->
priv
);
sl_free_bufs
(
sl
);
}
static
void
sl_setup
(
struct
net_device
*
dev
)
{
dev
->
init
=
sl_init
;
dev
->
uninit
=
sl_uninit
;
dev
->
open
=
sl_open
;
dev
->
destructor
=
(
void
(
*
)(
struct
net_device
*
))
kfree
;
dev
->
stop
=
sl_close
;
dev
->
get_stats
=
sl_get_stats
;
dev
->
change_mtu
=
sl_change_mtu
;
dev
->
hard_start_xmit
=
sl_xmit
;
#ifdef CONFIG_SLIP_SMART
dev
->
do_ioctl
=
sl_ioctl
;
#endif
dev
->
hard_header_len
=
0
;
dev
->
addr_len
=
0
;
dev
->
type
=
ARPHRD_SLIP
+
sl
->
mode
;
dev
->
tx_queue_len
=
10
;
SET_MODULE_OWNER
(
dev
);
/* New-style flags. */
dev
->
flags
=
IFF_NOARP
|
IFF_POINTOPOINT
|
IFF_MULTICAST
;
return
0
;
}
/******************************************
Routines looking at TTY side.
******************************************/
...
...
@@ -702,52 +710,57 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch
static
void
sl_sync
(
void
)
{
int
i
;
struct
net_device
*
dev
;
struct
slip
*
sl
;
for
(
i
=
0
;
i
<
slip_maxdev
;
i
++
)
{
slip_ctrl_t
*
slp
=
slip_ctrls
[
i
];
if
(
slp
==
NULL
)
if
((
dev
=
slip_devs
[
i
])
==
NULL
)
break
;
if
(
slp
->
ctrl
.
tty
||
slp
->
ctrl
.
leased
)
sl
=
dev
->
priv
;
if
(
sl
->
tty
||
sl
->
leased
)
continue
;
if
(
slp
->
dev
.
flags
&
IFF_UP
)
dev_close
(
&
slp
->
dev
);
if
(
dev
->
flags
&
IFF_UP
)
dev_close
(
dev
);
}
}
/* Find a free SLIP channel, and link in this `tty' line. */
static
struct
slip
*
sl_alloc
(
dev_t
line
)
{
struct
slip
*
sl
;
slip_ctrl_t
*
slp
=
NULL
;
int
i
;
int
sel
=
-
1
;
int
score
=
-
1
;
struct
net_device
*
dev
=
NULL
;
struct
slip
*
sl
;
if
(
slip_
ctrls
==
NULL
)
if
(
slip_
devs
==
NULL
)
return
NULL
;
/* Master array missing ! */
for
(
i
=
0
;
i
<
slip_maxdev
;
i
++
)
{
slp
=
slip_ctrl
s
[
i
];
if
(
slp
==
NULL
)
dev
=
slip_dev
s
[
i
];
if
(
dev
==
NULL
)
break
;
if
(
slp
->
ctrl
.
leased
)
{
if
(
slp
->
ctrl
.
line
!=
line
)
sl
=
dev
->
priv
;
if
(
sl
->
leased
)
{
if
(
sl
->
line
!=
line
)
continue
;
if
(
sl
p
->
ctrl
.
tty
)
if
(
sl
->
tty
)
return
NULL
;
/* Clear ESCAPE & ERROR flags */
sl
p
->
ctrl
.
flags
&=
(
1
<<
SLF_INUSE
);
return
&
slp
->
ctr
l
;
sl
->
flags
&=
(
1
<<
SLF_INUSE
);
return
s
l
;
}
if
(
sl
p
->
ctrl
.
tty
)
if
(
sl
->
tty
)
continue
;
if
(
current
->
pid
==
sl
p
->
ctrl
.
pid
)
{
if
(
sl
p
->
ctrl
.
line
==
line
&&
score
<
3
)
{
if
(
current
->
pid
==
sl
->
pid
)
{
if
(
sl
->
line
==
line
&&
score
<
3
)
{
sel
=
i
;
score
=
3
;
continue
;
...
...
@@ -758,7 +771,7 @@ sl_alloc(dev_t line)
}
continue
;
}
if
(
sl
p
->
ctrl
.
line
==
line
&&
score
<
1
)
{
if
(
sl
->
line
==
line
&&
score
<
1
)
{
sel
=
i
;
score
=
1
;
continue
;
...
...
@@ -771,10 +784,11 @@ sl_alloc(dev_t line)
if
(
sel
>=
0
)
{
i
=
sel
;
slp
=
slip_ctrl
s
[
i
];
dev
=
slip_dev
s
[
i
];
if
(
score
>
1
)
{
slp
->
ctrl
.
flags
&=
(
1
<<
SLF_INUSE
);
return
&
slp
->
ctrl
;
sl
=
dev
->
priv
;
sl
->
flags
&=
(
1
<<
SLF_INUSE
);
return
sl
;
}
}
...
...
@@ -782,26 +796,32 @@ sl_alloc(dev_t line)
if
(
i
>=
slip_maxdev
)
return
NULL
;
if
(
slp
)
{
if
(
test_bit
(
SLF_INUSE
,
&
slp
->
ctrl
.
flags
))
{
unregister_netdevice
(
&
slp
->
dev
);
sl_free_bufs
(
&
slp
->
ctrl
);
if
(
dev
)
{
sl
=
dev
->
priv
;
if
(
test_bit
(
SLF_INUSE
,
&
sl
->
flags
))
{
unregister_netdevice
(
dev
);
dev
=
NULL
;
slip_devs
[
i
]
=
NULL
;
}
}
else
if
((
slp
=
(
slip_ctrl_t
*
)
kmalloc
(
sizeof
(
slip_ctrl_t
),
GFP_KERNEL
))
==
NULL
)
return
NULL
;
}
if
(
!
dev
)
{
char
name
[
IFNAMSIZ
];
sprintf
(
name
,
"sl%d"
,
i
);
dev
=
alloc_netdev
(
sizeof
(
*
sl
),
name
,
sl_setup
);
if
(
!
dev
)
return
NULL
;
dev
->
base_addr
=
i
;
}
memset
(
slp
,
0
,
sizeof
(
slip_ctrl_t
))
;
sl
=
dev
->
priv
;
sl
=
&
slp
->
ctrl
;
/* Initialize channel control data */
sl
->
magic
=
SLIP_MAGIC
;
sl
->
dev
=
&
slp
->
dev
;
sl
->
dev
=
dev
;
spin_lock_init
(
&
sl
->
lock
);
sl
->
mode
=
SL_MODE_DEFAULT
;
sprintf
(
slp
->
dev
.
name
,
"sl%d"
,
i
);
slp
->
dev
.
base_addr
=
i
;
slp
->
dev
.
priv
=
(
void
*
)
sl
;
slp
->
dev
.
init
=
sl_init
;
#ifdef CONFIG_SLIP_SMART
init_timer
(
&
sl
->
keepalive_timer
);
/* initialize timer_list struct */
sl
->
keepalive_timer
.
data
=
(
unsigned
long
)
sl
;
...
...
@@ -810,8 +830,9 @@ sl_alloc(dev_t line)
sl
->
outfill_timer
.
data
=
(
unsigned
long
)
sl
;
sl
->
outfill_timer
.
function
=
sl_outfill
;
#endif
slip_ctrls
[
i
]
=
slp
;
return
&
slp
->
ctrl
;
slip_devs
[
i
]
=
dev
;
return
sl
;
}
/*
...
...
@@ -865,12 +886,10 @@ slip_open(struct tty_struct *tty)
if
((
err
=
sl_alloc_bufs
(
sl
,
SL_MTU
))
!=
0
)
goto
err_free_chan
;
if
(
register_netdevice
(
sl
->
dev
))
{
sl_free_bufs
(
sl
);
goto
err_free_chan
;
}
set_bit
(
SLF_INUSE
,
&
sl
->
flags
);
if
((
err
=
register_netdevice
(
sl
->
dev
)))
goto
err_free_bufs
;
}
#ifdef CONFIG_SLIP_SMART
...
...
@@ -888,6 +907,9 @@ slip_open(struct tty_struct *tty)
rtnl_unlock
();
return
sl
->
dev
->
base_addr
;
err_free_bufs:
sl_free_bufs
(
sl
);
err_free_chan:
sl
->
tty
=
NULL
;
tty
->
disc_data
=
NULL
;
...
...
@@ -1335,14 +1357,14 @@ static int __init slip_init(void)
printk
(
KERN_INFO
"SLIP linefill/keepalive option.
\n
"
);
#endif
slip_
ctrls
=
kmalloc
(
sizeof
(
void
*
)
*
slip_maxdev
,
GFP_KERNEL
);
if
(
!
slip_
ctrl
s
)
{
printk
(
KERN_ERR
"SLIP: Can't allocate slip
_ctrls[]
array! Uaargh! (-> No SLIP available)
\n
"
);
slip_
devs
=
kmalloc
(
sizeof
(
struct
net_device
*
)
*
slip_maxdev
,
GFP_KERNEL
);
if
(
!
slip_
dev
s
)
{
printk
(
KERN_ERR
"SLIP: Can't allocate slip
devices
array! Uaargh! (-> No SLIP available)
\n
"
);
return
-
ENOMEM
;
}
/* Clear the pointer array, we allocate devices when we need them */
memset
(
slip_
ctrls
,
0
,
sizeof
(
void
*
)
*
slip_maxdev
);
/* Pointers */
memset
(
slip_
devs
,
0
,
sizeof
(
struct
net_device
*
)
*
slip_maxdev
);
/* Fill in our line protocol discipline, and register it */
if
((
status
=
tty_register_ldisc
(
N_SLIP
,
&
sl_ldisc
))
!=
0
)
{
...
...
@@ -1354,51 +1376,59 @@ static int __init slip_init(void)
static
void
__exit
slip_exit
(
void
)
{
int
i
;
struct
net_device
*
dev
;
struct
slip
*
sl
;
unsigned
long
timeout
=
jiffies
+
HZ
;
int
busy
=
0
;
if
(
slip_ctrls
!=
NULL
)
{
unsigned
long
timeout
=
jiffies
+
HZ
;
int
busy
=
0
;
if
(
slip_devs
==
NULL
)
return
;
/* First of all: check for active disciplines and hangup them.
*/
do
{
if
(
busy
)
yield
();
busy
=
0
;
local_bh_disable
();
for
(
i
=
0
;
i
<
slip_maxdev
;
i
++
)
{
struct
slip_ctrl
*
slc
=
slip_ctrls
[
i
];
if
(
!
slc
)
continue
;
spin_lock
(
&
slc
->
ctrl
.
lock
);
if
(
slc
->
ctrl
.
tty
)
{
busy
++
;
tty_hangup
(
slc
->
ctrl
.
tty
);
}
spin_unlock
(
&
slc
->
ctrl
.
lock
);
}
local_bh_enable
();
}
while
(
busy
&&
time_before
(
jiffies
,
timeout
));
/* First of all: check for active disciplines and hangup them.
*/
do
{
if
(
busy
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
HZ
/
10
);
current
->
state
=
TASK_RUNNING
;
}
busy
=
0
;
for
(
i
=
0
;
i
<
slip_maxdev
;
i
++
)
{
struct
slip_ctrl
*
slc
=
slip_ctrls
[
i
];
if
(
slc
)
{
unregister_netdev
(
&
slc
->
dev
);
if
(
slc
->
ctrl
.
tty
)
{
printk
(
KERN_ERR
"%s: tty discipline is still running
\n
"
,
slc
->
dev
.
name
);
/* Intentionally leak the control block. */
}
else
{
sl_free_bufs
(
&
slc
->
ctrl
);
kfree
(
slc
);
}
slip_ctrls
[
i
]
=
NULL
;
dev
=
slip_devs
[
i
];
if
(
!
dev
)
continue
;
sl
=
dev
->
priv
;
spin_lock_bh
(
&
sl
->
lock
);
if
(
sl
->
tty
)
{
busy
++
;
tty_hangup
(
sl
->
tty
);
}
spin_unlock_bh
(
&
sl
->
lock
);
}
}
while
(
busy
&&
time_before
(
jiffies
,
timeout
));
for
(
i
=
0
;
i
<
slip_maxdev
;
i
++
)
{
dev
=
slip_devs
[
i
];
if
(
!
dev
)
continue
;
slip_devs
[
i
]
=
NULL
;
sl
=
dev
->
priv
;
if
(
sl
->
tty
)
{
printk
(
KERN_ERR
"%s: tty discipline still running
\n
"
,
dev
->
name
);
/* Intentionally leak the control block. */
dev
->
destructor
=
NULL
;
}
kfree
(
slip_ctrls
);
slip_ctrls
=
NULL
;
unregister_netdev
(
dev
);
}
kfree
(
slip_devs
);
slip_devs
=
NULL
;
if
((
i
=
tty_register_ldisc
(
N_SLIP
,
NULL
)))
{
printk
(
KERN_ERR
"SLIP: can't unregister line discipline (err = %d)
\n
"
,
i
);
...
...
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