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
f4861b30
Commit
f4861b30
authored
Jun 11, 2003
by
Alexander Viro
Committed by
Linus Torvalds
Jun 11, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] tty_driver refcounting
drivers/char/epca.c converted to dynamic allocation
parent
5d85b66a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
146 deletions
+146
-146
drivers/char/epca.c
drivers/char/epca.c
+146
-146
No files found.
drivers/char/epca.c
View file @
f4861b30
...
@@ -97,8 +97,8 @@ static struct board_info boards[MAXBOARDS];
...
@@ -97,8 +97,8 @@ static struct board_info boards[MAXBOARDS];
/* ------------- Begin structures used for driver registeration ---------- */
/* ------------- Begin structures used for driver registeration ---------- */
st
ruct
tty_driver
pc_driver
;
st
atic
struct
tty_driver
*
pc_driver
;
st
ruct
tty_driver
pc_info
;
st
atic
struct
tty_driver
*
pc_info
;
/* ------------------ Begin Digi specific structures -------------------- */
/* ------------------ Begin Digi specific structures -------------------- */
...
@@ -204,6 +204,8 @@ static void epcaparam(struct tty_struct *, struct channel *);
...
@@ -204,6 +204,8 @@ static void epcaparam(struct tty_struct *, struct channel *);
static
void
receive_data
(
struct
channel
*
);
static
void
receive_data
(
struct
channel
*
);
static
int
pc_ioctl
(
struct
tty_struct
*
,
struct
file
*
,
static
int
pc_ioctl
(
struct
tty_struct
*
,
struct
file
*
,
unsigned
int
,
unsigned
long
);
unsigned
int
,
unsigned
long
);
static
int
info_ioctl
(
struct
tty_struct
*
,
struct
file
*
,
unsigned
int
,
unsigned
long
);
static
void
pc_set_termios
(
struct
tty_struct
*
,
struct
termios
*
);
static
void
pc_set_termios
(
struct
tty_struct
*
,
struct
termios
*
);
static
void
do_softint
(
void
*
);
static
void
do_softint
(
void
*
);
static
void
pc_stop
(
struct
tty_struct
*
);
static
void
pc_stop
(
struct
tty_struct
*
);
...
@@ -491,12 +493,6 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
...
@@ -491,12 +493,6 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
struct
channel
*
ch
;
struct
channel
*
ch
;
unsigned
long
flags
;
unsigned
long
flags
;
if
(
tty
->
driver
->
subtype
==
SERIAL_TYPE_INFO
)
{
return
;
}
/* ---------------------------------------------------------
/* ---------------------------------------------------------
verifyChannel returns the channel from the tty struct
verifyChannel returns the channel from the tty struct
if it is valid. This serves as a sanity check.
if it is valid. This serves as a sanity check.
...
@@ -704,13 +700,6 @@ static int pc_write(struct tty_struct * tty, int from_user,
...
@@ -704,13 +700,6 @@ static int pc_write(struct tty_struct * tty, int from_user,
brought into the driver.
brought into the driver.
------------------------------------------------------------------- */
------------------------------------------------------------------- */
/* Stop users from hurting themselves on control minor */
if
(
tty
->
driver
->
subtype
==
SERIAL_TYPE_INFO
)
{
return
(
0
)
;
}
/* ---------------------------------------------------------
/* ---------------------------------------------------------
verifyChannel returns the channel from the tty struct
verifyChannel returns the channel from the tty struct
if it is valid. This serves as a sanity check.
if it is valid. This serves as a sanity check.
...
@@ -1306,13 +1295,6 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
...
@@ -1306,13 +1295,6 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
volatile
struct
board_chan
*
bc
;
volatile
struct
board_chan
*
bc
;
volatile
unsigned
int
head
;
volatile
unsigned
int
head
;
/* Nothing "real" happens in open of control device */
if
(
tty
->
driver
->
subtype
==
SERIAL_TYPE_INFO
)
{
return
(
0
)
;
}
line
=
tty
->
index
;
line
=
tty
->
index
;
if
(
line
<
0
||
line
>=
nbdevs
)
if
(
line
<
0
||
line
>=
nbdevs
)
{
{
...
@@ -1485,13 +1467,15 @@ static void __exit epca_module_exit(void)
...
@@ -1485,13 +1467,15 @@ static void __exit epca_module_exit(void)
save_flags
(
flags
);
save_flags
(
flags
);
cli
();
cli
();
if
((
tty_unregister_driver
(
&
pc_driver
))
||
if
((
tty_unregister_driver
(
pc_driver
))
||
(
tty_unregister_driver
(
&
pc_info
)))
(
tty_unregister_driver
(
pc_info
)))
{
{
printk
(
KERN_WARNING
"<Error> - DIGI : cleanup_module failed to un-register tty driver
\n
"
);
printk
(
KERN_WARNING
"<Error> - DIGI : cleanup_module failed to un-register tty driver
\n
"
);
restore_flags
(
flags
);
restore_flags
(
flags
);
return
;
return
;
}
}
put_tty_driver
(
pc_driver
);
put_tty_driver
(
pc_info
);
for
(
crd
=
0
;
crd
<
num_cards
;
crd
++
)
for
(
crd
=
0
;
crd
<
num_cards
;
crd
++
)
{
/* Begin for each card */
{
/* Begin for each card */
...
@@ -1529,6 +1513,34 @@ static void __exit epca_module_exit(void)
...
@@ -1529,6 +1513,34 @@ static void __exit epca_module_exit(void)
module_exit
(
epca_module_exit
);
module_exit
(
epca_module_exit
);
#endif
/* MODULE */
#endif
/* MODULE */
static
struct
tty_operations
pc_ops
=
{
.
open
=
pc_open
,
.
close
=
pc_close
,
.
write
=
pc_write
,
.
write_room
=
pc_write_room
,
.
flush_buffer
=
pc_flush_buffer
,
.
chars_in_buffer
=
pc_chars_in_buffer
,
.
flush_chars
=
pc_flush_chars
,
.
put_char
=
pc_put_char
,
.
ioctl
=
pc_ioctl
,
.
set_termios
=
pc_set_termios
,
.
stop
=
pc_stop
,
.
start
=
pc_start
,
.
throttle
=
pc_throttle
,
.
unthrottle
=
pc_unthrottle
,
.
hangup
=
pc_hangup
,
};
static
int
info_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
return
0
;
}
static
struct
tty_operations
info_ops
=
{
.
open
=
info_open
,
.
ioctl
=
info_ioctl
,
};
/* ------------------ Begin pc_init ---------------------- */
/* ------------------ Begin pc_init ---------------------- */
int
__init
pc_init
(
void
)
int
__init
pc_init
(
void
)
...
@@ -1553,7 +1565,6 @@ int __init pc_init(void)
...
@@ -1553,7 +1565,6 @@ int __init pc_init(void)
int
crd
;
int
crd
;
struct
board_info
*
bd
;
struct
board_info
*
bd
;
unsigned
char
board_id
=
0
;
unsigned
char
board_id
=
0
;
#ifdef ENABLE_PCI
#ifdef ENABLE_PCI
int
pci_boards_found
,
pci_count
;
int
pci_boards_found
,
pci_count
;
...
@@ -1561,6 +1572,16 @@ int __init pc_init(void)
...
@@ -1561,6 +1572,16 @@ int __init pc_init(void)
pci_count
=
0
;
pci_count
=
0
;
#endif
/* ENABLE_PCI */
#endif
/* ENABLE_PCI */
pc_driver
=
alloc_tty_driver
(
MAX_ALLOC
);
if
(
!
pc_driver
)
return
-
ENOMEM
;
pc_info
=
alloc_tty_driver
(
MAX_ALLOC
);
if
(
!
pc_info
)
{
put_tty_driver
(
pc_driver
);
return
-
ENOMEM
;
}
/* -----------------------------------------------------------------------
/* -----------------------------------------------------------------------
If epca_setup has not been ran by LILO set num_cards to defaults; copy
If epca_setup has not been ran by LILO set num_cards to defaults; copy
board structure defined by digiConfig into drivers board structure.
board structure defined by digiConfig into drivers board structure.
...
@@ -1620,53 +1641,33 @@ int __init pc_init(void)
...
@@ -1620,53 +1641,33 @@ int __init pc_init(void)
#endif
/* ENABLE_PCI */
#endif
/* ENABLE_PCI */
memset
(
&
pc_driver
,
0
,
sizeof
(
struct
tty_driver
));
pc_driver
->
owner
=
THIS_MODULE
;
memset
(
&
pc_info
,
0
,
sizeof
(
struct
tty_driver
));
pc_driver
->
name
=
"ttyD"
;
pc_driver
->
major
=
DIGI_MAJOR
;
pc_driver
.
magic
=
TTY_DRIVER_MAGIC
;
pc_driver
->
minor_start
=
0
;
pc_driver
.
owner
=
THIS_MODULE
;
pc_driver
->
type
=
TTY_DRIVER_TYPE_SERIAL
;
pc_driver
.
name
=
"ttyD"
;
pc_driver
->
subtype
=
SERIAL_TYPE_NORMAL
;
pc_driver
.
major
=
DIGI_MAJOR
;
pc_driver
->
init_termios
=
tty_std_termios
;
pc_driver
.
minor_start
=
0
;
pc_driver
->
init_termios
.
c_iflag
=
0
;
pc_driver
.
num
=
MAX_ALLOC
;
pc_driver
->
init_termios
.
c_oflag
=
0
;
pc_driver
.
type
=
TTY_DRIVER_TYPE_SERIAL
;
pc_driver
->
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
CLOCAL
|
HUPCL
;
pc_driver
.
subtype
=
SERIAL_TYPE_NORMAL
;
pc_driver
->
init_termios
.
c_lflag
=
0
;
pc_driver
.
init_termios
=
tty_std_termios
;
pc_driver
->
flags
=
TTY_DRIVER_REAL_RAW
;
pc_driver
.
init_termios
.
c_iflag
=
0
;
tty_set_operations
(
pc_driver
,
&
pc_ops
);
pc_driver
.
init_termios
.
c_oflag
=
0
;
pc_info
->
owner
=
THIS_MODULE
;
pc_driver
.
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
CLOCAL
|
HUPCL
;
pc_info
->
name
=
"digi_ctl"
;
pc_driver
.
init_termios
.
c_lflag
=
0
;
pc_info
->
major
=
DIGIINFOMAJOR
;
pc_driver
.
flags
=
TTY_DRIVER_REAL_RAW
;
pc_info
->
minor_start
=
0
;
pc_info
->
type
=
TTY_DRIVER_TYPE_SERIAL
;
/* ------------------------------------------------------------------
pc_info
->
subtype
=
SERIAL_TYPE_INFO
;
Setup entry points for the driver. These are primarily called by
pc_info
->
init_termios
=
tty_std_termios
;
the kernel in tty_io.c and n_tty.c
pc_info
->
init_termios
.
c_iflag
=
0
;
--------------------------------------------------------------------- */
pc_info
->
init_termios
.
c_oflag
=
0
;
pc_info
->
init_termios
.
c_lflag
=
0
;
pc_driver
.
open
=
pc_open
;
pc_info
->
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
;
pc_driver
.
close
=
pc_close
;
pc_info
->
flags
=
TTY_DRIVER_REAL_RAW
;
pc_driver
.
write
=
pc_write
;
tty_set_operations
(
pc_info
,
&
info_ops
);
pc_driver
.
write_room
=
pc_write_room
;
pc_driver
.
flush_buffer
=
pc_flush_buffer
;
pc_driver
.
chars_in_buffer
=
pc_chars_in_buffer
;
pc_driver
.
flush_chars
=
pc_flush_chars
;
pc_driver
.
put_char
=
pc_put_char
;
pc_driver
.
ioctl
=
pc_ioctl
;
pc_driver
.
set_termios
=
pc_set_termios
;
pc_driver
.
stop
=
pc_stop
;
pc_driver
.
start
=
pc_start
;
pc_driver
.
throttle
=
pc_throttle
;
pc_driver
.
unthrottle
=
pc_unthrottle
;
pc_driver
.
hangup
=
pc_hangup
;
pc_info
=
pc_driver
;
pc_info
.
name
=
"digi_ctl"
;
pc_info
.
major
=
DIGIINFOMAJOR
;
pc_info
.
minor_start
=
0
;
pc_info
.
num
=
1
;
pc_info
.
init_termios
.
c_cflag
=
B9600
|
CS8
|
CREAD
|
HUPCL
;
pc_info
.
subtype
=
SERIAL_TYPE_INFO
;
save_flags
(
flags
);
save_flags
(
flags
);
...
@@ -1791,10 +1792,10 @@ int __init pc_init(void)
...
@@ -1791,10 +1792,10 @@ int __init pc_init(void)
}
/* End for each card */
}
/* End for each card */
if
(
tty_register_driver
(
&
pc_driver
))
if
(
tty_register_driver
(
pc_driver
))
panic
(
"Couldn't register Digi PC/ driver"
);
panic
(
"Couldn't register Digi PC/ driver"
);
if
(
tty_register_driver
(
&
pc_info
))
if
(
tty_register_driver
(
pc_info
))
panic
(
"Couldn't register Digi PC/ info "
);
panic
(
"Couldn't register Digi PC/ info "
);
/* -------------------------------------------------------------------
/* -------------------------------------------------------------------
...
@@ -2845,103 +2846,102 @@ static void receive_data(struct channel *ch)
...
@@ -2845,103 +2846,102 @@ static void receive_data(struct channel *ch)
}
/* End receive_data */
}
/* End receive_data */
/* --------------------- Begin pc_ioctl ----------------------- */
static
int
info_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
static
int
pc_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
unsigned
int
cmd
,
unsigned
long
arg
)
{
/* Begin pc_ioctl */
{
int
error
;
digiflow_t
dflow
;
int
retval
,
error
;
unsigned
long
flags
;
unsigned
int
mflag
,
mstat
;
unsigned
char
startc
,
stopc
;
volatile
struct
board_chan
*
bc
;
struct
channel
*
ch
=
(
struct
channel
*
)
tty
->
driver_data
;
/* The control device has it's own set of commands */
switch
(
cmd
)
if
(
tty
->
driver
->
subtype
==
SERIAL_TYPE_INFO
)
{
/* Begin switch cmd */
{
/* Begin if subtype is the control device */
switch
(
cmd
)
{
/* Begin switch cmd */
case
DIGI_GETINFO
:
case
DIGI_GETINFO
:
{
/* Begin case DIGI_GETINFO */
{
/* Begin case DIGI_GETINFO */
struct
digi_info
di
;
struct
digi_info
di
;
int
brd
;
int
brd
;
getUser
(
brd
,
(
unsigned
int
*
)
arg
);
getUser
(
brd
,
(
unsigned
int
*
)
arg
);
if
((
error
=
verify_area
(
VERIFY_WRITE
,
(
char
*
)
arg
,
sizeof
(
di
))))
if
((
error
=
verify_area
(
VERIFY_WRITE
,
(
char
*
)
arg
,
sizeof
(
di
))))
{
{
printk
(
KERN_ERR
"DIGI_GETINFO : verify area size 0x%x failed
\n
"
,
sizeof
(
di
));
printk
(
KERN_ERR
"DIGI_GETINFO : verify area size 0x%x failed
\n
"
,
sizeof
(
di
));
return
(
error
);
return
(
error
);
}
}
if
((
brd
<
0
)
||
(
brd
>=
num_cards
)
||
(
num_cards
==
0
))
if
((
brd
<
0
)
||
(
brd
>=
num_cards
)
||
(
num_cards
==
0
))
return
(
-
ENODEV
);
return
(
-
ENODEV
);
memset
(
&
di
,
0
,
sizeof
(
di
));
memset
(
&
di
,
0
,
sizeof
(
di
));
di
.
board
=
brd
;
di
.
board
=
brd
;
di
.
status
=
boards
[
brd
].
status
;
di
.
status
=
boards
[
brd
].
status
;
di
.
type
=
boards
[
brd
].
type
;
di
.
type
=
boards
[
brd
].
type
;
di
.
numports
=
boards
[
brd
].
numports
;
di
.
numports
=
boards
[
brd
].
numports
;
di
.
port
=
boards
[
brd
].
port
;
di
.
port
=
boards
[
brd
].
port
;
di
.
membase
=
boards
[
brd
].
membase
;
di
.
membase
=
boards
[
brd
].
membase
;
if
(
copy_to_user
((
char
*
)
arg
,
&
di
,
sizeof
(
di
)))
if
(
copy_to_user
((
char
*
)
arg
,
&
di
,
sizeof
(
di
)))
return
-
EFAULT
;
return
-
EFAULT
;
break
;
break
;
}
/* End case DIGI_GETINFO */
}
/* End case DIGI_GETINFO */
case
DIGI_POLLER
:
case
DIGI_POLLER
:
{
/* Begin case DIGI_POLLER */
{
/* Begin case DIGI_POLLER */
int
brd
=
arg
&
0xff000000
>>
16
;
int
brd
=
arg
&
0xff000000
>>
16
;
unsigned
char
state
=
arg
&
0xff
;
unsigned
char
state
=
arg
&
0xff
;
if
((
brd
<
0
)
||
(
brd
>=
num_cards
))
if
((
brd
<
0
)
||
(
brd
>=
num_cards
))
{
{
printk
(
KERN_ERR
"<Error> - DIGI POLLER : brd not valid!
\n
"
);
printk
(
KERN_ERR
"<Error> - DIGI POLLER : brd not valid!
\n
"
);
return
(
-
ENODEV
);
return
(
-
ENODEV
);
}
}
digi_poller_inhibited
=
state
;
digi_poller_inhibited
=
state
;
break
;
break
;
}
/* End case DIGI_POLLER */
}
/* End case DIGI_POLLER */
case
DIGI_INIT
:
case
DIGI_INIT
:
{
/* Begin case DIGI_INIT */
{
/* Begin case DIGI_INIT */
/* ------------------------------------------------------------
/* ------------------------------------------------------------
This call is made by the apps to complete the initilization
This call is made by the apps to complete the initilization
of the board(s). This routine is responsible for setting
of the board(s). This routine is responsible for setting
the card to its initial state and setting the drivers control
the card to its initial state and setting the drivers control
fields to the sutianle settings for the card in question.
fields to the sutianle settings for the card in question.
---------------------------------------------------------------- */
---------------------------------------------------------------- */
int
crd
;
int
crd
;
for
(
crd
=
0
;
crd
<
num_cards
;
crd
++
)
for
(
crd
=
0
;
crd
<
num_cards
;
crd
++
)
post_fep_init
(
crd
);
post_fep_init
(
crd
);
break
;
break
;
}
/* End case DIGI_INIT */
}
/* End case DIGI_INIT */
default:
default:
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
}
/* End switch cmd */
}
/* End switch cmd */
return
(
0
)
;
return
(
0
)
;
}
/* --------------------- Begin pc_ioctl ----------------------- */
}
/* End if subtype is the control device */
static
int
pc_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
/* Begin pc_ioctl */
digiflow_t
dflow
;
int
retval
,
error
;
unsigned
long
flags
;
unsigned
int
mflag
,
mstat
;
unsigned
char
startc
,
stopc
;
volatile
struct
board_chan
*
bc
;
struct
channel
*
ch
=
(
struct
channel
*
)
tty
->
driver_data
;
if
(
ch
)
if
(
ch
)
bc
=
ch
->
brdchan
;
bc
=
ch
->
brdchan
;
else
else
...
...
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