Commit 59e89646 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] tty_driver refcounting

drivers/char/pcxx.c converted to dynamic allocation
parent d7e68f44
...@@ -140,7 +140,7 @@ int pcxx_nbios=sizeof(pcxx_bios); ...@@ -140,7 +140,7 @@ int pcxx_nbios=sizeof(pcxx_bios);
#define SERIAL_TYPE_NORMAL 1 #define SERIAL_TYPE_NORMAL 1
#define PCXE_EVENT_HANGUP 1 #define PCXE_EVENT_HANGUP 1
struct tty_driver pcxe_driver; static struct tty_driver *pcxe_driver;
static struct timer_list pcxx_timer; static struct timer_list pcxx_timer;
...@@ -232,9 +232,10 @@ void cleanup_module() ...@@ -232,9 +232,10 @@ void cleanup_module()
del_timer_sync(&pcxx_timer); del_timer_sync(&pcxx_timer);
remove_bh(DIGI_BH); remove_bh(DIGI_BH);
if ((e1 = tty_unregister_driver(&pcxe_driver))) if ((e1 = tty_unregister_driver(pcxe_driver)))
printk("SERIAL: failed to unregister serial driver (%d)\n", e1); printk("SERIAL: failed to unregister serial driver (%d)\n", e1);
put_tty_driver(pcxe_driver);
cleanup_board_resources(); cleanup_board_resources();
kfree(digi_channels); kfree(digi_channels);
restore_flags(flags); restore_flags(flags);
...@@ -1026,6 +1027,24 @@ void __init pcxx_setup(char *str, int *ints) ...@@ -1026,6 +1027,24 @@ void __init pcxx_setup(char *str, int *ints)
} }
#endif #endif
static struct tty_operations pcxe_ops = {
.open = pcxe_open,
.close = pcxe_close,
.write = pcxe_write,
.put_char = pcxe_put_char,
.flush_chars = pcxe_flush_chars,
.write_room = pcxe_write_room,
.chars_in_buffer = pcxe_chars_in_buffer,
.flush_buffer = pcxe_flush_buffer,
.ioctl = pcxe_ioctl,
.throttle = pcxe_throttle,
.unthrottle = pcxe_unthrottle,
.set_termios = pcxe_set_termios,
.stop = pcxe_stop,
.start = pcxe_start,
.hangup = pcxe_hangup,
};
/* /*
* function to initialize the driver with the given parameters, which are either * function to initialize the driver with the given parameters, which are either
* the default values from this file or the parameters given at boot. * the default values from this file or the parameters given at boot.
...@@ -1119,6 +1138,10 @@ int __init pcxe_init(void) ...@@ -1119,6 +1138,10 @@ int __init pcxe_init(void)
return -EIO; return -EIO;
} }
pcxe_driver = alloc_tty_driver(nbdevs);
if (!pcxe_driver)
return -ENOMEM;
/* /*
* this turns out to be more memory efficient, as there are no * this turns out to be more memory efficient, as there are no
* unused spaces. * unused spaces.
...@@ -1126,6 +1149,7 @@ int __init pcxe_init(void) ...@@ -1126,6 +1149,7 @@ int __init pcxe_init(void)
digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL); digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL);
if (!digi_channels) { if (!digi_channels) {
printk(KERN_ERR "Unable to allocate digi_channel struct\n"); printk(KERN_ERR "Unable to allocate digi_channel struct\n");
put_tty_driver(pcxe_driver);
return -ENOMEM; return -ENOMEM;
} }
memset(digi_channels, 0, sizeof(struct channel) * nbdevs); memset(digi_channels, 0, sizeof(struct channel) * nbdevs);
...@@ -1135,36 +1159,16 @@ int __init pcxe_init(void) ...@@ -1135,36 +1159,16 @@ int __init pcxe_init(void)
init_timer(&pcxx_timer); init_timer(&pcxx_timer);
pcxx_timer.function = pcxxpoll; pcxx_timer.function = pcxxpoll;
memset(&pcxe_driver, 0, sizeof(struct tty_driver)); pcxe_driver->owner = THIS_MODULE;
pcxe_driver.magic = TTY_DRIVER_MAGIC; pcxe_driver->name = "ttyD";
pcxe_driver.owner = THIS_MODULE; pcxe_driver->major = DIGI_MAJOR;
pcxe_driver.name = "ttyD"; pcxe_driver->minor_start = 0;
pcxe_driver.major = DIGI_MAJOR; pcxe_driver->type = TTY_DRIVER_TYPE_SERIAL;
pcxe_driver.minor_start = 0; pcxe_driver->subtype = SERIAL_TYPE_NORMAL;
pcxe_driver->init_termios = tty_std_termios;
pcxe_driver.num = nbdevs; pcxe_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
pcxe_driver->flags = TTY_DRIVER_REAL_RAW;
pcxe_driver.type = TTY_DRIVER_TYPE_SERIAL; tty_set_operations(pcxe_driver, &pcxe_ops);
pcxe_driver.subtype = SERIAL_TYPE_NORMAL;
pcxe_driver.init_termios = tty_std_termios;
pcxe_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
pcxe_driver.flags = TTY_DRIVER_REAL_RAW;
pcxe_driver.open = pcxe_open;
pcxe_driver.close = pcxe_close;
pcxe_driver.write = pcxe_write;
pcxe_driver.put_char = pcxe_put_char;
pcxe_driver.flush_chars = pcxe_flush_chars;
pcxe_driver.write_room = pcxe_write_room;
pcxe_driver.chars_in_buffer = pcxe_chars_in_buffer;
pcxe_driver.flush_buffer = pcxe_flush_buffer;
pcxe_driver.ioctl = pcxe_ioctl;
pcxe_driver.throttle = pcxe_throttle;
pcxe_driver.unthrottle = pcxe_unthrottle;
pcxe_driver.set_termios = pcxe_set_termios;
pcxe_driver.stop = pcxe_stop;
pcxe_driver.start = pcxe_start;
pcxe_driver.hangup = pcxe_hangup;
for(crd=0; crd < numcards; crd++) { for(crd=0; crd < numcards; crd++) {
bd = &boards[crd]; bd = &boards[crd];
...@@ -1546,7 +1550,7 @@ int __init pcxe_init(void) ...@@ -1546,7 +1550,7 @@ int __init pcxe_init(void)
goto cleanup_boards; goto cleanup_boards;
} }
ret = tty_register_driver(&pcxe_driver); ret = tty_register_driver(pcxe_driver);
if(ret) { if(ret) {
printk(KERN_ERR "Couldn't register PC/Xe driver\n"); printk(KERN_ERR "Couldn't register PC/Xe driver\n");
goto cleanup_boards; goto cleanup_boards;
...@@ -1561,9 +1565,10 @@ int __init pcxe_init(void) ...@@ -1561,9 +1565,10 @@ int __init pcxe_init(void)
printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.\n", enabled_cards); printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.\n", enabled_cards);
return 0; return 0;
cleanup_pcxe_driver: tty_unregister_driver(&pcxe_driver); cleanup_boards:
cleanup_boards: cleanup_board_resources(); cleanup_board_resources();
kfree(digi_channels); kfree(digi_channels);
put_tty_driver(pcxe_driver);
return ret; return ret;
} }
......
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