Commit f4861b30 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] tty_driver refcounting

drivers/char/epca.c converted to dynamic allocation
parent 5d85b66a
......@@ -97,8 +97,8 @@ static struct board_info boards[MAXBOARDS];
/* ------------- Begin structures used for driver registeration ---------- */
struct tty_driver pc_driver;
struct tty_driver pc_info;
static struct tty_driver *pc_driver;
static struct tty_driver *pc_info;
/* ------------------ Begin Digi specific structures -------------------- */
......@@ -204,6 +204,8 @@ static void epcaparam(struct tty_struct *, struct channel *);
static void receive_data(struct channel *);
static int pc_ioctl(struct tty_struct *, struct file *,
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 do_softint(void *);
static void pc_stop(struct tty_struct *);
......@@ -491,12 +493,6 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
struct channel *ch;
unsigned long flags;
if (tty->driver->subtype == SERIAL_TYPE_INFO)
{
return;
}
/* ---------------------------------------------------------
verifyChannel returns the channel from the tty struct
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,
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
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)
volatile struct board_chan *bc;
volatile unsigned int head;
/* Nothing "real" happens in open of control device */
if (tty->driver->subtype == SERIAL_TYPE_INFO)
{
return (0) ;
}
line = tty->index;
if (line < 0 || line >= nbdevs)
{
......@@ -1485,13 +1467,15 @@ static void __exit epca_module_exit(void)
save_flags(flags);
cli();
if ((tty_unregister_driver(&pc_driver)) ||
(tty_unregister_driver(&pc_info)))
if ((tty_unregister_driver(pc_driver)) ||
(tty_unregister_driver(pc_info)))
{
printk(KERN_WARNING "<Error> - DIGI : cleanup_module failed to un-register tty driver\n");
restore_flags(flags);
return;
}
put_tty_driver(pc_driver);
put_tty_driver(pc_info);
for (crd = 0; crd < num_cards; crd++)
{ /* Begin for each card */
......@@ -1529,6 +1513,34 @@ static void __exit epca_module_exit(void)
module_exit(epca_module_exit);
#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 ---------------------- */
int __init pc_init(void)
......@@ -1554,13 +1566,22 @@ int __init pc_init(void)
struct board_info *bd;
unsigned char board_id = 0;
#ifdef ENABLE_PCI
int pci_boards_found, pci_count;
pci_count = 0;
#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
board structure defined by digiConfig into drivers board structure.
......@@ -1620,53 +1641,33 @@ int __init pc_init(void)
#endif /* ENABLE_PCI */
memset(&pc_driver, 0, sizeof(struct tty_driver));
memset(&pc_info, 0, sizeof(struct tty_driver));
pc_driver.magic = TTY_DRIVER_MAGIC;
pc_driver.owner = THIS_MODULE;
pc_driver.name = "ttyD";
pc_driver.major = DIGI_MAJOR;
pc_driver.minor_start = 0;
pc_driver.num = MAX_ALLOC;
pc_driver.type = TTY_DRIVER_TYPE_SERIAL;
pc_driver.subtype = SERIAL_TYPE_NORMAL;
pc_driver.init_termios = tty_std_termios;
pc_driver.init_termios.c_iflag = 0;
pc_driver.init_termios.c_oflag = 0;
pc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
pc_driver.init_termios.c_lflag = 0;
pc_driver.flags = TTY_DRIVER_REAL_RAW;
/* ------------------------------------------------------------------
Setup entry points for the driver. These are primarily called by
the kernel in tty_io.c and n_tty.c
--------------------------------------------------------------------- */
pc_driver.open = pc_open;
pc_driver.close = pc_close;
pc_driver.write = pc_write;
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;
pc_driver->owner = THIS_MODULE;
pc_driver->name = "ttyD";
pc_driver->major = DIGI_MAJOR;
pc_driver->minor_start = 0;
pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
pc_driver->subtype = SERIAL_TYPE_NORMAL;
pc_driver->init_termios = tty_std_termios;
pc_driver->init_termios.c_iflag = 0;
pc_driver->init_termios.c_oflag = 0;
pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
pc_driver->init_termios.c_lflag = 0;
pc_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(pc_driver, &pc_ops);
pc_info->owner = THIS_MODULE;
pc_info->name = "digi_ctl";
pc_info->major = DIGIINFOMAJOR;
pc_info->minor_start = 0;
pc_info->type = TTY_DRIVER_TYPE_SERIAL;
pc_info->subtype = SERIAL_TYPE_INFO;
pc_info->init_termios = tty_std_termios;
pc_info->init_termios.c_iflag = 0;
pc_info->init_termios.c_oflag = 0;
pc_info->init_termios.c_lflag = 0;
pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
pc_info->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(pc_info, &info_ops);
save_flags(flags);
......@@ -1791,10 +1792,10 @@ int __init pc_init(void)
} /* End for each card */
if (tty_register_driver(&pc_driver))
if (tty_register_driver(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 ");
/* -------------------------------------------------------------------
......@@ -2845,23 +2846,10 @@ static void receive_data(struct channel *ch)
} /* End receive_data */
/* --------------------- Begin pc_ioctl ----------------------- */
static int pc_ioctl(struct tty_struct *tty, struct file * file,
static int info_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;
/* The control device has it's own set of commands */
if (tty->driver->subtype == SERIAL_TYPE_INFO)
{ /* Begin if subtype is the control device */
{
int error;
switch (cmd)
{ /* Begin switch cmd */
......@@ -2939,8 +2927,20 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
} /* End switch cmd */
return (0) ;
}
/* --------------------- Begin pc_ioctl ----------------------- */
static int pc_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{ /* Begin pc_ioctl */
} /* End if subtype is the control device */
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)
bc = ch->brdchan;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment