diff options
Diffstat (limited to 'drivers/staging/dgnc')
-rw-r--r-- | drivers/staging/dgnc/Makefile | 3 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_cls.c | 44 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_cls.h | 2 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_driver.c | 558 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_driver.h | 189 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_mgmt.c | 6 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_neo.c | 111 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_neo.h | 58 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_sysfs.c | 703 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_sysfs.h | 40 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_tty.c | 362 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_tty.h | 6 | ||||
-rw-r--r-- | drivers/staging/dgnc/digi.h | 107 |
13 files changed, 628 insertions, 1561 deletions
diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile index 995c874f40eb..40ff0d007695 100644 --- a/drivers/staging/dgnc/Makefile +++ b/drivers/staging/dgnc/Makefile @@ -2,5 +2,4 @@ obj-$(CONFIG_DGNC) += dgnc.o dgnc-objs := dgnc_cls.o dgnc_driver.o\ dgnc_mgmt.o dgnc_neo.o\ - dgnc_tty.o dgnc_sysfs.o\ - dgnc_utils.o + dgnc_tty.o dgnc_utils.o diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index aedca66cbe41..c20ffdd254d8 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -385,9 +385,8 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) ch->ch_rxcount++; } - /* - * Write new final heads to channel structure. - */ + /* Write new final heads to channel structure. */ + ch->ch_r_head = head & RQUEUEMASK; ch->ch_e_head = head & EQUEUEMASK; @@ -666,9 +665,8 @@ static void cls_param(struct tty_struct *tty) if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - /* - * If baud rate is zero, flush queues, and set mval to drop DTR. - */ + /* If baud rate is zero, flush queues, and set mval to drop DTR. */ + if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = 0; ch->ch_r_tail = 0; @@ -887,9 +885,8 @@ static void cls_param(struct tty_struct *tty) cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); } -/* - * Our board poller function. - */ +/* Our board poller function. */ + static void cls_tasklet(unsigned long data) { struct dgnc_board *bd = (struct dgnc_board *)data; @@ -914,9 +911,8 @@ static void cls_tasklet(unsigned long data) */ spin_lock_irqsave(&bd->bd_intr_lock, flags); - /* - * If board is ready, parse deeper to see if there is anything to do. - */ + /* If board is ready, parse deeper to see if there is anything to do. */ + if ((state == BOARD_READY) && (ports > 0)) { /* Loop on each port */ for (i = 0; i < ports; i++) { @@ -938,9 +934,8 @@ static void cls_tasklet(unsigned long data) cls_copy_data_from_queue_to_uart(ch); dgnc_wakeup_writes(ch); - /* - * Check carrier function. - */ + /* Check carrier function. */ + dgnc_carrier(ch); /* @@ -992,9 +987,8 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) for (i = 0; i < brd->nasync; i++) cls_parse_isr(brd, i); - /* - * Schedule tasklet to more in-depth servicing at a better time. - */ + /* Schedule tasklet to more in-depth servicing at a better time. */ + tasklet_schedule(&brd->helper_tasklet); spin_unlock_irqrestore(&brd->bd_intr_lock, flags); @@ -1043,9 +1037,7 @@ static int cls_drain(struct tty_struct *tty, uint seconds) un->un_flags |= UN_EMPTY; spin_unlock_irqrestore(&ch->ch_lock, flags); - /* - * NOTE: Do something with time passed in. - */ + /* NOTE: Do something with time passed in. */ /* If ret is non-zero, user ctrl-c'ed us */ @@ -1112,9 +1104,8 @@ static void cls_uart_init(struct channel_t *ch) readb(&ch->ch_cls_uart->msr); } -/* - * Turns off UART. - */ +/* Turns off UART. */ + static void cls_uart_off(struct channel_t *ch) { writeb(0, &ch->ch_cls_uart->ier); @@ -1160,9 +1151,8 @@ static void cls_send_break(struct channel_t *ch, int msecs) if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - /* - * If we receive a time of 0, this means turn off the break. - */ + /* If we receive a time of 0, this means turn off the break. */ + if (msecs == 0) { /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { diff --git a/drivers/staging/dgnc/dgnc_cls.h b/drivers/staging/dgnc/dgnc_cls.h index 2597e36d38c4..463ad30efb3b 100644 --- a/drivers/staging/dgnc/dgnc_cls.h +++ b/drivers/staging/dgnc/dgnc_cls.h @@ -69,7 +69,7 @@ struct cls_uart_struct { #define UART_EXAR654_EFR_IXON 0x2 /* Receiver compares Xon1/Xoff1 */ #define UART_EXAR654_EFR_IXOFF 0x8 /* Transmit Xon1/Xoff1 */ #define UART_EXAR654_EFR_RTSDTR 0x40 /* Auto RTS/DTR Flow Control Enable */ -#define UART_EXAR654_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow COntrol Enable */ +#define UART_EXAR654_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow Control Enable */ #define UART_EXAR654_IER_XOFF 0x20 /* Xoff Interrupt Enable */ #define UART_EXAR654_IER_RTSDTR 0x40 /* Output Interrupt Enable */ #define UART_EXAR654_IER_CTSDSR 0x80 /* Input Interrupt Enable */ diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index fd372d3afa46..5381dbddd8bb 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -24,31 +24,14 @@ #include "dgnc_tty.h" #include "dgnc_cls.h" #include "dgnc_neo.h" -#include "dgnc_sysfs.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Digi International, http://www.digi.com"); MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_SUPPORTED_DEVICE("dgnc"); -/************************************************************************** - * - * protos for this file - * - */ -static int dgnc_start(void); -static int dgnc_request_irq(struct dgnc_board *brd); -static void dgnc_free_irq(struct dgnc_board *brd); -static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); -static void dgnc_cleanup_board(struct dgnc_board *brd); -static void dgnc_poll_handler(ulong dummy); -static int dgnc_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent); -static int dgnc_do_remap(struct dgnc_board *brd); +/* File operations permitted on Control/Management major. */ -/* - * File operations permitted on Control/Management major. - */ static const struct file_operations dgnc_board_fops = { .owner = THIS_MODULE, .unlocked_ioctl = dgnc_mgmt_ioctl, @@ -56,9 +39,8 @@ static const struct file_operations dgnc_board_fops = { .release = dgnc_mgmt_close }; -/* - * Globals - */ +/* Globals */ + uint dgnc_num_boards; struct dgnc_board *dgnc_board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); @@ -66,14 +48,12 @@ DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ uint dgnc_major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ -/* - * Static vars. - */ +/* Static vars. */ + static struct class *dgnc_class; -/* - * Poller stuff - */ +/* Poller stuff */ + static ulong dgnc_poll_time; /* Time of next poll */ static uint dgnc_poll_stop; /* Used to tell poller to stop */ static struct timer_list dgnc_poll_timer; @@ -93,7 +73,7 @@ struct board_id { unsigned int is_pci_express; }; -static struct board_id dgnc_ids[] = { +static const struct board_id dgnc_ids[] = { { PCI_DEVICE_CLASSIC_4_PCI_NAME, 4, 0 }, { PCI_DEVICE_CLASSIC_4_422_PCI_NAME, 4, 0 }, { PCI_DEVICE_CLASSIC_8_PCI_NAME, 8, 0 }, @@ -114,274 +94,20 @@ static struct board_id dgnc_ids[] = { { NULL, 0, 0 } }; -static struct pci_driver dgnc_driver = { - .name = "dgnc", - .probe = dgnc_init_one, - .id_table = dgnc_pci_tbl, -}; - -/************************************************************************ - * - * Driver load/unload functions - * - ************************************************************************/ - -static void cleanup(bool sysfiles) -{ - int i; - unsigned long flags; - - spin_lock_irqsave(&dgnc_poll_lock, flags); - dgnc_poll_stop = 1; - spin_unlock_irqrestore(&dgnc_poll_lock, flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgnc_poll_timer); - - if (sysfiles) - dgnc_remove_driver_sysfiles(&dgnc_driver); - - device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); - class_destroy(dgnc_class); - unregister_chrdev(dgnc_major, "dgnc"); - - for (i = 0; i < dgnc_num_boards; ++i) { - dgnc_remove_ports_sysfiles(dgnc_board[i]); - dgnc_cleanup_tty(dgnc_board[i]); - dgnc_cleanup_board(dgnc_board[i]); - } - - dgnc_tty_post_uninit(); -} - -/* - * dgnc_cleanup_module() - * - * Module unload. This is where it all ends. - */ -static void __exit dgnc_cleanup_module(void) -{ - cleanup(true); - pci_unregister_driver(&dgnc_driver); -} - -/* - * init_module() - * - * Module load. This is where it all starts. - */ -static int __init dgnc_init_module(void) -{ - int rc; - - /* - * Initialize global stuff - */ - rc = dgnc_start(); - - if (rc < 0) - return rc; - - /* - * Find and configure all the cards - */ - rc = pci_register_driver(&dgnc_driver); - if (rc) { - pr_warn("WARNING: dgnc driver load failed. No Digi Neo or Classic boards found.\n"); - cleanup(false); - return rc; - } - dgnc_create_driver_sysfiles(&dgnc_driver); - - return 0; -} - -module_init(dgnc_init_module); -module_exit(dgnc_cleanup_module); +/* Remap PCI memory. */ -/* - * Start of driver. - */ -static int dgnc_start(void) +static int dgnc_do_remap(struct dgnc_board *brd) { int rc = 0; - unsigned long flags; - struct device *dev; - - /* make sure timer is initialized before we do anything else */ - init_timer(&dgnc_poll_timer); - - /* - * Register our base character device into the kernel. - * This allows the download daemon to connect to the downld device - * before any of the boards are init'ed. - * - * Register management/dpa devices - */ - rc = register_chrdev(0, "dgnc", &dgnc_board_fops); - if (rc < 0) { - pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); - return rc; - } - dgnc_major = rc; - - dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); - if (IS_ERR(dgnc_class)) { - rc = PTR_ERR(dgnc_class); - pr_err(DRVSTR ": Can't create dgnc_mgmt class (%d)\n", rc); - goto failed_class; - } - - dev = device_create(dgnc_class, NULL, - MKDEV(dgnc_major, 0), - NULL, "dgnc_mgmt"); - if (IS_ERR(dev)) { - rc = PTR_ERR(dev); - pr_err(DRVSTR ": Can't create device (%d)\n", rc); - goto failed_device; - } - - /* - * Init any global tty stuff. - */ - rc = dgnc_tty_preinit(); - - if (rc < 0) { - pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc); - goto failed_tty; - } - - /* Start the poller */ - spin_lock_irqsave(&dgnc_poll_lock, flags); - setup_timer(&dgnc_poll_timer, dgnc_poll_handler, 0); - dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); - dgnc_poll_timer.expires = dgnc_poll_time; - spin_unlock_irqrestore(&dgnc_poll_lock, flags); - - add_timer(&dgnc_poll_timer); - - return 0; - -failed_tty: - device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); -failed_device: - class_destroy(dgnc_class); -failed_class: - unregister_chrdev(dgnc_major, "dgnc"); - return rc; -} - -/* returns count (>= 0), or negative on error */ -static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int rc; - struct dgnc_board *brd; - - /* wake up and enable device */ - rc = pci_enable_device(pdev); - - if (rc) - return -EIO; - - brd = dgnc_found_board(pdev, ent->driver_data); - if (IS_ERR(brd)) - return PTR_ERR(brd); - - /* - * Do tty device initialization. - */ - - rc = dgnc_tty_register(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); - goto failed; - } - - rc = dgnc_request_irq(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); - goto unregister_tty; - } - - rc = dgnc_tty_init(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto free_irq; - } - - brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; - dgnc_create_ports_sysfiles(brd); - - dgnc_board[dgnc_num_boards++] = brd; - - return 0; - -free_irq: - dgnc_free_irq(brd); -unregister_tty: - dgnc_tty_unregister(brd); - -failed: - kfree(brd); + brd->re_map_membase = ioremap(brd->membase, 0x1000); + if (!brd->re_map_membase) + rc = -ENOMEM; return rc; } /* - * dgnc_cleanup_board() - * - * Free all the memory associated with a board - */ -static void dgnc_cleanup_board(struct dgnc_board *brd) -{ - int i = 0; - - if (!brd || brd->magic != DGNC_BOARD_MAGIC) - return; - - switch (brd->device) { - case PCI_DEVICE_CLASSIC_4_DID: - case PCI_DEVICE_CLASSIC_8_DID: - case PCI_DEVICE_CLASSIC_4_422_DID: - case PCI_DEVICE_CLASSIC_8_422_DID: - - /* Tell card not to interrupt anymore. */ - outb(0, brd->iobase + 0x4c); - break; - - default: - break; - } - - if (brd->irq) - free_irq(brd->irq, brd); - - tasklet_kill(&brd->helper_tasklet); - - if (brd->re_map_membase) { - iounmap(brd->re_map_membase); - brd->re_map_membase = NULL; - } - - /* Free all allocated channels structs */ - for (i = 0; i < MAXPORTS ; i++) { - if (brd->channels[i]) { - kfree(brd->channels[i]->ch_rqueue); - kfree(brd->channels[i]->ch_equeue); - kfree(brd->channels[i]->ch_wqueue); - kfree(brd->channels[i]); - brd->channels[i] = NULL; - } - } - - dgnc_board[brd->boardnum] = NULL; - - kfree(brd); -} - -/* * dgnc_found_board() * * A board has been found, init it. @@ -587,21 +313,6 @@ static void dgnc_free_irq(struct dgnc_board *brd) } /* - * Remap PCI memory. - */ -static int dgnc_do_remap(struct dgnc_board *brd) -{ - int rc = 0; - - brd->re_map_membase = ioremap(brd->membase, 0x1000); - if (!brd->re_map_membase) - rc = -ENOMEM; - - return rc; -} - -/* - * * Function: * * dgnc_poll_handler @@ -623,7 +334,6 @@ static int dgnc_do_remap(struct dgnc_board *brd) * As each timer expires, it determines (a) whether the "transmit" * waiter needs to be woken up, and (b) whether the poller needs to * be rescheduled. - * */ static void dgnc_poll_handler(ulong dummy) @@ -651,9 +361,8 @@ static void dgnc_poll_handler(ulong dummy) spin_unlock_irqrestore(&brd->bd_lock, flags); } - /* - * Schedule ourself back at the nominal wakeup interval. - */ + /* Schedule ourself back at the nominal wakeup interval. */ + spin_lock_irqsave(&dgnc_poll_lock, flags); dgnc_poll_time += dgnc_jiffies_from_ms(dgnc_poll_tick); @@ -669,3 +378,240 @@ static void dgnc_poll_handler(ulong dummy) if (!dgnc_poll_stop) add_timer(&dgnc_poll_timer); } + +/* returns count (>= 0), or negative on error */ +static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int rc; + struct dgnc_board *brd; + + /* wake up and enable device */ + rc = pci_enable_device(pdev); + + if (rc) + return -EIO; + + brd = dgnc_found_board(pdev, ent->driver_data); + if (IS_ERR(brd)) + return PTR_ERR(brd); + + /* Do tty device initialization. */ + + rc = dgnc_tty_register(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); + goto failed; + } + + rc = dgnc_request_irq(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); + goto unregister_tty; + } + + rc = dgnc_tty_init(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); + goto free_irq; + } + + brd->state = BOARD_READY; + brd->dpastatus = BD_RUNNING; + + dgnc_board[dgnc_num_boards++] = brd; + + return 0; + +free_irq: + dgnc_free_irq(brd); +unregister_tty: + dgnc_tty_unregister(brd); + +failed: + kfree(brd); + + return rc; +} + +static struct pci_driver dgnc_driver = { + .name = "dgnc", + .probe = dgnc_init_one, + .id_table = dgnc_pci_tbl, +}; + +/* Start of driver. */ + +static int dgnc_start(void) +{ + int rc = 0; + unsigned long flags; + struct device *dev; + + /* make sure timer is initialized before we do anything else */ + init_timer(&dgnc_poll_timer); + + /* + * Register our base character device into the kernel. + * This allows the download daemon to connect to the downld device + * before any of the boards are init'ed. + * + * Register management/dpa devices + */ + rc = register_chrdev(0, "dgnc", &dgnc_board_fops); + if (rc < 0) { + pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); + return rc; + } + dgnc_major = rc; + + dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); + if (IS_ERR(dgnc_class)) { + rc = PTR_ERR(dgnc_class); + pr_err(DRVSTR ": Can't create dgnc_mgmt class (%d)\n", rc); + goto failed_class; + } + + dev = device_create(dgnc_class, NULL, + MKDEV(dgnc_major, 0), + NULL, "dgnc_mgmt"); + if (IS_ERR(dev)) { + rc = PTR_ERR(dev); + pr_err(DRVSTR ": Can't create device (%d)\n", rc); + goto failed_device; + } + + /* Start the poller */ + spin_lock_irqsave(&dgnc_poll_lock, flags); + setup_timer(&dgnc_poll_timer, dgnc_poll_handler, 0); + dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); + dgnc_poll_timer.expires = dgnc_poll_time; + spin_unlock_irqrestore(&dgnc_poll_lock, flags); + + add_timer(&dgnc_poll_timer); + + return 0; + +failed_device: + class_destroy(dgnc_class); +failed_class: + unregister_chrdev(dgnc_major, "dgnc"); + return rc; +} + +/* + * dgnc_cleanup_board() + * + * Free all the memory associated with a board + */ +static void dgnc_cleanup_board(struct dgnc_board *brd) +{ + int i = 0; + + if (!brd || brd->magic != DGNC_BOARD_MAGIC) + return; + + switch (brd->device) { + case PCI_DEVICE_CLASSIC_4_DID: + case PCI_DEVICE_CLASSIC_8_DID: + case PCI_DEVICE_CLASSIC_4_422_DID: + case PCI_DEVICE_CLASSIC_8_422_DID: + + /* Tell card not to interrupt anymore. */ + outb(0, brd->iobase + 0x4c); + break; + + default: + break; + } + + if (brd->irq) + free_irq(brd->irq, brd); + + tasklet_kill(&brd->helper_tasklet); + + if (brd->re_map_membase) { + iounmap(brd->re_map_membase); + brd->re_map_membase = NULL; + } + + /* Free all allocated channels structs */ + for (i = 0; i < MAXPORTS ; i++) { + if (brd->channels[i]) { + kfree(brd->channels[i]->ch_rqueue); + kfree(brd->channels[i]->ch_equeue); + kfree(brd->channels[i]->ch_wqueue); + kfree(brd->channels[i]); + brd->channels[i] = NULL; + } + } + + dgnc_board[brd->boardnum] = NULL; + + kfree(brd); +} + +/* Driver load/unload functions */ + +static void cleanup(void) +{ + int i; + unsigned long flags; + + spin_lock_irqsave(&dgnc_poll_lock, flags); + dgnc_poll_stop = 1; + spin_unlock_irqrestore(&dgnc_poll_lock, flags); + + /* Turn off poller right away. */ + del_timer_sync(&dgnc_poll_timer); + + device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); + class_destroy(dgnc_class); + unregister_chrdev(dgnc_major, "dgnc"); + + for (i = 0; i < dgnc_num_boards; ++i) { + dgnc_cleanup_tty(dgnc_board[i]); + dgnc_cleanup_board(dgnc_board[i]); + } +} + +/* + * dgnc_cleanup_module() + * + * Module unload. This is where it all ends. + */ +static void __exit dgnc_cleanup_module(void) +{ + cleanup(); + pci_unregister_driver(&dgnc_driver); +} + +/* + * init_module() + * + * Module load. This is where it all starts. + */ +static int __init dgnc_init_module(void) +{ + int rc; + + /* Initialize global stuff */ + + rc = dgnc_start(); + + if (rc < 0) + return rc; + + /* Find and configure all the cards */ + + rc = pci_register_driver(&dgnc_driver); + if (rc) { + pr_warn("WARNING: dgnc driver load failed. No Digi Neo or Classic boards found.\n"); + cleanup(); + return rc; + } + + return 0; +} + +module_init(dgnc_init_module); +module_exit(dgnc_cleanup_module); diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 879202663a98..c8119f2fe881 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -12,11 +12,8 @@ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - ************************************************************************* - * * Driver includes - * - *************************************************************************/ + */ #ifndef __DGNC_DRIVER_H #define __DGNC_DRIVER_H @@ -26,19 +23,14 @@ #include <linux/interrupt.h> #include "digi.h" /* Digi specific ioctl header */ -#include "dgnc_sysfs.h" /* Support for SYSFS */ -/************************************************************************* - * - * Driver defines - * - *************************************************************************/ +/* Driver defines */ -/* Driver identification and error statments */ -#define PROCSTR "dgnc" /* /proc entries */ -#define DEVSTR "/dev/dg/dgnc" /* /dev entries */ -#define DRVSTR "dgnc" /* Driver name string */ -#define DG_PART "40002369_F" /* RPM part number */ +/* Driver identification and error statements */ +#define PROCSTR "dgnc" /* /proc entries */ +#define DEVSTR "/dev/dg/dgnc" /* /dev entries */ +#define DRVSTR "dgnc" /* Driver name string */ +#define DG_PART "40002369_F" /* RPM part number */ #define TRC_TO_CONSOLE 1 @@ -61,7 +53,8 @@ #define PORT_NUM(dev) ((dev) & 0x7f) #define IS_PRINT(dev) (((dev) & 0xff) >= 0x80) -/* MAX number of stop characters we will send +/* + *MAX number of stop characters we will send * when our read queue is getting full */ #define MAX_STOPS_SENT 5 @@ -88,35 +81,28 @@ #define _POSIX_VDISABLE '\0' #endif -/* - * All the possible states the driver can be while being loaded. - */ +/* All the possible states the driver can be while being loaded. */ + enum { DRIVER_INITIALIZED = 0, DRIVER_READY }; -/* - * All the possible states the board can be while booting up. - */ +/* All the possible states the board can be while booting up. */ + enum { BOARD_FAILED = 0, BOARD_FOUND, BOARD_READY }; -/************************************************************************* - * - * Structures and closely related defines. - * - *************************************************************************/ +/* Structures and closely related defines. */ struct dgnc_board; struct channel_t; -/************************************************************************ - * Per board operations structure * - ************************************************************************/ +/* Per board operations structure */ + struct board_ops { void (*tasklet)(unsigned long data); irqreturn_t (*intr)(int irq, void *voidbrd); @@ -138,16 +124,14 @@ struct board_ops { void (*send_immediate_char)(struct channel_t *ch, unsigned char); }; -/************************************************************************ - * Device flag definitions for bd_flags. - ************************************************************************/ +/* Device flag definitions for bd_flags. */ + #define BD_IS_PCI_EXPRESS 0x0001 /* Is a PCI Express board */ -/* - * Per-board information - */ +/* Per-board information */ + struct dgnc_board { - int magic; /* Board Magic number. */ + int magic; /* Board Magic number. */ int boardnum; /* Board number: 0-32 */ int type; /* Type of board */ @@ -220,62 +204,56 @@ struct dgnc_board { }; -/************************************************************************ - * Unit flag definitions for un_flags. - ************************************************************************/ -#define UN_ISOPEN 0x0001 /* Device is open */ -#define UN_CLOSING 0x0002 /* Line is being closed */ -#define UN_IMM 0x0004 /* Service immediately */ -#define UN_BUSY 0x0008 /* Some work this channel */ -#define UN_BREAKI 0x0010 /* Input break received */ +/* Unit flag definitions for un_flags. */ +#define UN_ISOPEN 0x0001 /* Device is open */ +#define UN_CLOSING 0x0002 /* Line is being closed */ +#define UN_IMM 0x0004 /* Service immediately */ +#define UN_BUSY 0x0008 /* Some work this channel */ +#define UN_BREAKI 0x0010 /* Input break received */ #define UN_PWAIT 0x0020 /* Printer waiting for terminal */ -#define UN_TIME 0x0040 /* Waiting on time */ -#define UN_EMPTY 0x0080 /* Waiting output queue empty */ +#define UN_TIME 0x0040 /* Waiting on time */ +#define UN_EMPTY 0x0080 /* Waiting output queue empty */ #define UN_LOW 0x0100 /* Waiting output low water mark*/ -#define UN_EXCL_OPEN 0x0200 /* Open for exclusive use */ -#define UN_WOPEN 0x0400 /* Device waiting for open */ -#define UN_WIOCTL 0x0800 /* Device waiting for open */ -#define UN_HANGUP 0x8000 /* Carrier lost */ +#define UN_EXCL_OPEN 0x0200 /* Open for exclusive use */ +#define UN_WOPEN 0x0400 /* Device waiting for open */ +#define UN_WIOCTL 0x0800 /* Device waiting for open */ +#define UN_HANGUP 0x8000 /* Carrier lost */ struct device; -/************************************************************************ - * Structure for terminal or printer unit. - ************************************************************************/ +/* Structure for terminal or printer unit. */ struct un_t { - int magic; /* Unit Magic Number. */ + int magic; /* Unit Magic Number. */ struct channel_t *un_ch; ulong un_time; uint un_type; - uint un_open_count; /* Counter of opens to port */ - struct tty_struct *un_tty;/* Pointer to unit tty structure */ - uint un_flags; /* Unit flags */ + uint un_open_count; /* Counter of opens to port */ + struct tty_struct *un_tty; /* Pointer to unit tty structure */ + uint un_flags; /* Unit flags */ wait_queue_head_t un_flags_wait; /* Place to sleep to wait on unit */ - uint un_dev; /* Minor device number */ + uint un_dev; /* Minor device number */ struct device *un_sysfs; }; -/************************************************************************ - * Device flag definitions for ch_flags. - ************************************************************************/ -#define CH_PRON 0x0001 /* Printer on string */ -#define CH_STOP 0x0002 /* Output is stopped */ -#define CH_STOPI 0x0004 /* Input is stopped */ -#define CH_CD 0x0008 /* Carrier is present */ -#define CH_FCAR 0x0010 /* Carrier forced on */ -#define CH_HANGUP 0x0020 /* Hangup received */ - -#define CH_RECEIVER_OFF 0x0040 /* Receiver is off */ -#define CH_OPENING 0x0080 /* Port in fragile open state */ -#define CH_CLOSING 0x0100 /* Port in fragile close state */ -#define CH_FIFO_ENABLED 0x0200 /* Port has FIFOs enabled */ -#define CH_TX_FIFO_EMPTY 0x0400 /* TX Fifo is completely empty */ -#define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */ -#define CH_BREAK_SENDING 0x1000 /* Break is being sent */ -#define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ +/* Device flag definitions for ch_flags. */ +#define CH_PRON 0x0001 /* Printer on string */ +#define CH_STOP 0x0002 /* Output is stopped */ +#define CH_STOPI 0x0004 /* Input is stopped */ +#define CH_CD 0x0008 /* Carrier is present */ +#define CH_FCAR 0x0010 /* Carrier forced on */ +#define CH_HANGUP 0x0020 /* Hangup received */ + +#define CH_RECEIVER_OFF 0x0040 /* Receiver is off */ +#define CH_OPENING 0x0080 /* Port in fragile open state */ +#define CH_CLOSING 0x0100 /* Port in fragile close state */ +#define CH_FIFO_ENABLED 0x0200 /* Port has FIFOs enabled */ +#define CH_TX_FIFO_EMPTY 0x0400 /* TX Fifo is completely empty */ +#define CH_TX_FIFO_LWM 0x0800 /* TX Fifo is below Low Water */ +#define CH_BREAK_SENDING 0x1000 /* Break is being sent */ +#define CH_LOOPBACK 0x2000 /* Channel is in lookback mode */ #define CH_BAUD0 0x08000 /* Used for checking B0 transitions */ -#define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */ -#define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */ +#define CH_FORCED_STOP 0x20000 /* Output is forcibly stopped */ +#define CH_FORCED_STOPI 0x40000 /* Input is forcibly stopped */ /* Our Read/Error/Write queue sizes */ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */ @@ -285,43 +263,41 @@ struct un_t { #define EQUEUESIZE RQUEUESIZE #define WQUEUESIZE (WQUEUEMASK + 1) -/************************************************************************ - * Channel information structure. - ************************************************************************/ +/* Channel information structure. */ struct channel_t { - int magic; /* Channel Magic Number */ - struct dgnc_board *ch_bd; /* Board structure pointer */ + int magic; /* Channel Magic Number */ + struct dgnc_board *ch_bd; /* Board structure pointer */ struct digi_t ch_digi; /* Transparent Print structure */ - struct un_t ch_tun; /* Terminal unit info */ - struct un_t ch_pun; /* Printer unit info */ + struct un_t ch_tun; /* Terminal unit info */ + struct un_t ch_pun; /* Printer unit info */ spinlock_t ch_lock; /* provide for serialization */ wait_queue_head_t ch_flags_wait; - uint ch_portnum; /* Port number, 0 offset. */ - uint ch_open_count; /* open count */ - uint ch_flags; /* Channel flags */ + uint ch_portnum; /* Port number, 0 offset. */ + uint ch_open_count; /* open count */ + uint ch_flags; /* Channel flags */ ulong ch_close_delay; /* How long we should * drop RTS/DTR for */ - ulong ch_cpstime; /* Time for CPS calculations */ + ulong ch_cpstime; /* Time for CPS calculations */ - tcflag_t ch_c_iflag; /* channel iflags */ - tcflag_t ch_c_cflag; /* channel cflags */ - tcflag_t ch_c_oflag; /* channel oflags */ - tcflag_t ch_c_lflag; /* channel lflags */ - unsigned char ch_stopc; /* Stop character */ - unsigned char ch_startc; /* Start character */ + tcflag_t ch_c_iflag; /* channel iflags */ + tcflag_t ch_c_cflag; /* channel cflags */ + tcflag_t ch_c_oflag; /* channel oflags */ + tcflag_t ch_c_lflag; /* channel lflags */ + unsigned char ch_stopc; /* Stop character */ + unsigned char ch_startc; /* Start character */ uint ch_old_baud; /* Cache of the current baud */ uint ch_custom_speed;/* Custom baud, if set */ uint ch_wopen; /* Waiting for open process cnt */ - unsigned char ch_mostat; /* FEP output modem status */ - unsigned char ch_mistat; /* FEP input modem status */ + unsigned char ch_mostat; /* FEP output modem status */ + unsigned char ch_mistat; /* FEP input modem status */ struct neo_uart_struct __iomem *ch_neo_uart; /* Pointer to the * "mapped" UART struct @@ -347,10 +323,10 @@ struct channel_t { ulong ch_rxcount; /* total of data received so far */ ulong ch_txcount; /* total of data transmitted so far */ - unsigned char ch_r_tlevel; /* Receive Trigger level */ - unsigned char ch_t_tlevel; /* Transmit Trigger level */ + unsigned char ch_r_tlevel; /* Receive Trigger level */ + unsigned char ch_t_tlevel; /* Transmit Trigger level */ - unsigned char ch_r_watermark; /* Receive Watermark */ + unsigned char ch_r_watermark; /* Receive Watermark */ ulong ch_stop_sending_break; /* Time we should STOP * sending a break @@ -374,16 +350,15 @@ struct channel_t { }; -/* - * Our Global Variables. - */ +/* Our Global Variables. */ + extern uint dgnc_major; /* Our driver/mgmt major */ extern int dgnc_poll_tick; /* Poll interval - 20 ms */ extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ extern spinlock_t dgnc_poll_lock; /* Poll scheduling lock */ extern uint dgnc_num_boards; /* Total number of boards */ -extern struct dgnc_board *dgnc_board[MAXBOARDS]; /* Array of board - * structs - */ +extern struct dgnc_board *dgnc_board[MAXBOARDS];/* Array of board + * structs + */ #endif diff --git a/drivers/staging/dgnc/dgnc_mgmt.c b/drivers/staging/dgnc/dgnc_mgmt.c index 683c098391d9..9d9b15d6358a 100644 --- a/drivers/staging/dgnc/dgnc_mgmt.c +++ b/drivers/staging/dgnc/dgnc_mgmt.c @@ -13,13 +13,11 @@ * PURPOSE. See the GNU General Public License for more details. */ -/************************************************************************ - * +/* * This file implements the mgmt functionality for the * Neo and ClassicBoard based product lines. - * - ************************************************************************ */ + #include <linux/kernel.h> #include <linux/ctype.h> #include <linux/sched.h> /* For jiffies, task states */ diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 5becb3741b67..3eefefe53174 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -107,7 +107,8 @@ static inline void neo_set_cts_flow_control(struct channel_t *ch) /* Turn off auto Xon flow control */ efr &= ~UART_17158_EFR_IXON; - /* Why? Because Exar's spec says we have to zero it + /* + * Why? Because Exar's spec says we have to zero it * out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -145,7 +146,8 @@ static inline void neo_set_rts_flow_control(struct channel_t *ch) ier &= ~UART_17158_IER_XOFF; efr &= ~UART_17158_EFR_IXOFF; - /* Why? Because Exar's spec says we have to zero it + /* + * Why? Because Exar's spec says we have to zero it * out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -185,7 +187,8 @@ static inline void neo_set_ixon_flow_control(struct channel_t *ch) /* Turn on auto Xon flow control */ efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXON); - /* Why? Because Exar's spec says we have to zero it + /* + * Why? Because Exar's spec says we have to zero it * out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -225,7 +228,8 @@ static inline void neo_set_ixoff_flow_control(struct channel_t *ch) ier |= UART_17158_IER_XOFF; efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXOFF); - /* Why? Because Exar's spec says we have to zero it + /* + * Why? Because Exar's spec says we have to zero it * out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -268,7 +272,8 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch) else efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXOFF); - /* Why? Because Exar's spec says we have to zero + /* + * Why? Because Exar's spec says we have to zero * it out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -308,7 +313,8 @@ static inline void neo_set_no_output_flow_control(struct channel_t *ch) else efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXON); - /* Why? Because Exar's spec says we have to zero it + /* + * Why? Because Exar's spec says we have to zero it * out before setting it */ writeb(0, &ch->ch_neo_uart->efr); @@ -351,9 +357,8 @@ static inline void neo_set_new_start_stop_chars(struct channel_t *ch) neo_pci_posting_flush(ch->ch_bd); } -/* - * No locks are assumed to be held when calling this function. - */ +/* No locks are assumed to be held when calling this function. */ + static inline void neo_clear_break(struct channel_t *ch, int force) { unsigned long flags; @@ -381,9 +386,8 @@ static inline void neo_clear_break(struct channel_t *ch, int force) spin_unlock_irqrestore(&ch->ch_lock, flags); } -/* - * Parse the ISR register. - */ +/* Parse the ISR register. */ + static inline void neo_parse_isr(struct dgnc_board *brd, uint port) { struct channel_t *ch; @@ -412,8 +416,8 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) { /* Read data from uart -> queue */ neo_copy_data_from_uart_to_queue(ch); - - /* Call our tty layer to enforce queue + /* + * Call our tty layer to enforce queue * flow control if needed. */ spin_lock_irqsave(&ch->ch_lock, flags); @@ -438,7 +442,8 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) * one it was, so we can suspend or resume data flow. */ if (cause == UART_17158_XON_DETECT) { - /* Is output stopped right now, if so, + /* + * Is output stopped right now, if so, * resume it */ if (brd->channels[port]->ch_flags & CH_STOP) { @@ -609,9 +614,8 @@ static void neo_param(struct tty_struct *tty) if (!bd || bd->magic != DGNC_BOARD_MAGIC) return; - /* - * If baud rate is zero, flush queues, and set mval to drop DTR. - */ + /* If baud rate is zero, flush queues, and set mval to drop DTR. */ + if ((ch->ch_c_cflag & (CBAUD)) == 0) { ch->ch_r_head = 0; ch->ch_r_tail = 0; @@ -672,7 +676,8 @@ static void neo_param(struct tty_struct *tty) 4800, 9600, 19200, 38400 } }; - /* Only use the TXPrint baud rate if the terminal unit + /* + * Only use the TXPrint baud rate if the terminal unit * is NOT open */ if (!(ch->ch_tun.un_flags & UN_ISOPEN) && @@ -797,7 +802,8 @@ static void neo_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) { neo_set_cts_flow_control(ch); } else if (ch->ch_c_iflag & IXON) { - /* If start/stop is set to disable, then we should + /* + * If start/stop is set to disable, then we should * disable flow control */ if ((ch->ch_startc == _POSIX_VDISABLE) || @@ -812,7 +818,8 @@ static void neo_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) { neo_set_rts_flow_control(ch); } else if (ch->ch_c_iflag & IXOFF) { - /* If start/stop is set to disable, then we should + /* + * If start/stop is set to disable, then we should * disable flow control */ if ((ch->ch_startc == _POSIX_VDISABLE) || @@ -840,9 +847,8 @@ static void neo_param(struct tty_struct *tty) neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); } -/* - * Our board poller function. - */ +/* Our board poller function. */ + static void neo_tasklet(unsigned long data) { struct dgnc_board *bd = (struct dgnc_board *)data; @@ -867,9 +873,8 @@ static void neo_tasklet(unsigned long data) */ spin_lock_irqsave(&bd->bd_intr_lock, flags); - /* - * If board is ready, parse deeper to see if there is anything to do. - */ + /* If board is ready, parse deeper to see if there is anything to do. */ + if ((state == BOARD_READY) && (ports > 0)) { /* Loop on each port */ for (i = 0; i < ports; i++) { @@ -997,9 +1002,9 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) break; case UART_17158_RX_LINE_STATUS: - /* - * RXRDY and RX LINE Status (logic OR of LSR[4:1]) - */ + + /* RXRDY and RX LINE Status (logic OR of LSR[4:1]) */ + neo_parse_lsr(brd, port); break; @@ -1022,9 +1027,9 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) break; case UART_17158_MSR: - /* - * MSR or flow control was seen. - */ + + /* MSR or flow control was seen. */ + neo_parse_isr(brd, port); break; @@ -1041,9 +1046,8 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) port++; } - /* - * Schedule tasklet to more in-depth servicing at a better time. - */ + /* Schedule tasklet to more in-depth servicing at a better time. */ + tasklet_schedule(&brd->helper_tasklet); spin_unlock_irqrestore(&brd->bd_intr_lock, flags); @@ -1238,9 +1242,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); } - /* - * Discard character if we are ignoring the error mask. - */ + /* Discard character if we are ignoring the error mask. */ + if (linestatus & error_mask) { unsigned char discard; @@ -1279,9 +1282,8 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) ch->ch_rxcount++; } - /* - * Write new final heads to channel structure. - */ + /* Write new final heads to channel structure. */ + ch->ch_r_head = head & RQUEUEMASK; ch->ch_e_head = head & EQUEUEMASK; @@ -1412,9 +1414,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) (ch->ch_flags & CH_BREAK_SENDING)) goto exit_unlock; - /* - * If FIFOs are disabled. Send data directly to txrx register - */ + /* If FIFOs are disabled. Send data directly to txrx register */ + if (!(ch->ch_flags & CH_FIFO_ENABLED)) { unsigned char lsrbits = readb(&ch->ch_neo_uart->lsr); @@ -1458,9 +1459,8 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) goto exit_unlock; } - /* - * We have to do it this way, because of the EXAR TXFIFO count bug. - */ + /* We have to do it this way, because of the EXAR TXFIFO count bug. */ + if ((ch->ch_bd->dvid & 0xf0) < UART_XR17E158_DVID) { if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM))) goto exit_unlock; @@ -1645,9 +1645,8 @@ static void neo_send_stop_character(struct channel_t *ch) } } -/* - * neo_uart_init - */ +/* neo_uart_init */ + static void neo_uart_init(struct channel_t *ch) { writeb(0, &ch->ch_neo_uart->ier); @@ -1668,9 +1667,8 @@ static void neo_uart_init(struct channel_t *ch) neo_pci_posting_flush(ch->ch_bd); } -/* - * Make the UART completely turn off. - */ +/* Make the UART completely turn off. */ + static void neo_uart_off(struct channel_t *ch) { /* Turn off UART enhanced bits */ @@ -1705,9 +1703,8 @@ static uint neo_get_uart_bytes_left(struct channel_t *ch) /* Channel lock MUST be held by the calling function! */ static void neo_send_break(struct channel_t *ch, int msecs) { - /* - * If we receive a time of 0, this means turn off the break. - */ + /* If we receive a time of 0, this means turn off the break. */ + if (msecs == 0) { if (ch->ch_flags & CH_BREAK_SENDING) { unsigned char temp = readb(&ch->ch_neo_uart->lcr); diff --git a/drivers/staging/dgnc/dgnc_neo.h b/drivers/staging/dgnc/dgnc_neo.h index abddd48353d0..77ecd9baae45 100644 --- a/drivers/staging/dgnc/dgnc_neo.h +++ b/drivers/staging/dgnc/dgnc_neo.h @@ -18,37 +18,38 @@ #include "dgnc_driver.h" -/************************************************************************ - * Per channel/port NEO UART structure * - ************************************************************************ - * Base Structure Entries Usage Meanings to Host * - * * - * W = read write R = read only * - * U = Unused. * - ************************************************************************/ +/* + * Per channel/port NEO UART structure + * Base Structure Entries Usage Meanings to Host + * + * W = read write R = read only + * U = Unused. + */ struct neo_uart_struct { - u8 txrx; /* WR RHR/THR - Holding Reg */ + u8 txrx; /* WR RHR/THR - Holding Reg */ u8 ier; /* WR IER - Interrupt Enable Reg */ - u8 isr_fcr; /* WR ISR/FCR - Interrupt Status Reg/Fifo Control Reg */ + u8 isr_fcr; /* WR ISR/FCR - Interrupt Status Reg/Fifo + * Control Reg + */ u8 lcr; /* WR LCR - Line Control Reg */ u8 mcr; /* WR MCR - Modem Control Reg */ u8 lsr; /* WR LSR - Line Status Reg */ u8 msr; /* WR MSR - Modem Status Reg */ u8 spr; /* WR SPR - Scratch Pad Reg */ - u8 fctr; /* WR FCTR - Feature Control Reg */ + u8 fctr; /* WR FCTR - Feature Control Reg */ u8 efr; /* WR EFR - Enhanced Function Reg */ - u8 tfifo; /* WR TXCNT/TXTRG - Transmit FIFO Reg */ - u8 rfifo; /* WR RXCNT/RXTRG - Receive FIFO Reg */ + u8 tfifo; /* WR TXCNT/TXTRG - Transmit FIFO Reg */ + u8 rfifo; /* WR RXCNT/RXTRG - Receive FIFO Reg */ u8 xoffchar1; /* WR XOFF 1 - XOff Character 1 Reg */ u8 xoffchar2; /* WR XOFF 2 - XOff Character 2 Reg */ u8 xonchar1; /* WR XON 1 - Xon Character 1 Reg */ u8 xonchar2; /* WR XON 2 - XOn Character 2 Reg */ u8 reserved1[0x2ff - 0x200]; /* U Reserved by Exar */ - u8 txrxburst[64]; /* RW 64 bytes of RX/TX FIFO Data */ + u8 txrxburst[64]; /* RW 64 bytes of RX/TX FIFO Data */ u8 reserved2[0x37f - 0x340]; /* U Reserved by Exar */ - u8 rxburst_with_errors[64]; /* R 64 bytes of RX FIFO Data + LSR */ + u8 rxburst_with_errors[64]; /* R 64 bytes of RX FIFO Data + LSR */ }; /* Where to read the extended interrupt register (32bits instead of 8bits) */ @@ -108,7 +109,9 @@ struct neo_uart_struct { /* 17158 Extended IIR's */ #define UART_17158_IIR_RDI_TIMEOUT 0x0C /* Receiver data TIMEOUT */ #define UART_17158_IIR_XONXOFF 0x10 /* Received an XON/XOFF char */ -#define UART_17158_IIR_HWFLOW_STATE_CHANGE 0x20 /* CTS/DSR or RTS/DTR state change */ +#define UART_17158_IIR_HWFLOW_STATE_CHANGE 0x20 /* CTS/DSR or RTS/DTR + * state change + */ #define UART_17158_IIR_FIFO_ENABLED 0xC0 /* 16550 FIFOs are Enabled */ /* @@ -119,8 +122,12 @@ struct neo_uart_struct { #define UART_17158_RXRDY_TIMEOUT 0x2 /* RX Ready Timeout */ #define UART_17158_TXRDY 0x3 /* TX Ready */ #define UART_17158_MSR 0x4 /* Modem State Change */ -#define UART_17158_TX_AND_FIFO_CLR 0x40 /* Transmitter Holding Reg Empty */ -#define UART_17158_RX_FIFO_DATA_ERROR 0x80 /* UART detected an RX FIFO Data error */ +#define UART_17158_TX_AND_FIFO_CLR 0x40 /* Transmitter Holding + * Reg Empty + */ +#define UART_17158_RX_FIFO_DATA_ERROR 0x80 /* UART detected an RX FIFO + * Data error + */ /* * These are the EXTENDED definitions for the 17C158's Interrupt @@ -130,19 +137,22 @@ struct neo_uart_struct { #define UART_17158_EFR_IXON 0x2 /* Receiver compares Xon1/Xoff1 */ #define UART_17158_EFR_IXOFF 0x8 /* Transmit Xon1/Xoff1 */ #define UART_17158_EFR_RTSDTR 0x40 /* Auto RTS/DTR Flow Control Enable */ -#define UART_17158_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow COntrol Enable */ +#define UART_17158_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow Control Enable */ -#define UART_17158_XOFF_DETECT 0x1 /* Indicates whether chip saw an incoming XOFF char */ -#define UART_17158_XON_DETECT 0x2 /* Indicates whether chip saw an incoming XON char */ +#define UART_17158_XOFF_DETECT 0x1 /* Indicates whether chip saw an + * incoming XOFF char + */ +#define UART_17158_XON_DETECT 0x2 /* Indicates whether chip saw an + * incoming XON char + */ #define UART_17158_IER_RSVD1 0x10 /* Reserved by Exar */ #define UART_17158_IER_XOFF 0x20 /* Xoff Interrupt Enable */ #define UART_17158_IER_RTSDTR 0x40 /* Output Interrupt Enable */ #define UART_17158_IER_CTSDSR 0x80 /* Input Interrupt Enable */ -/* - * Our Global Variables - */ +/* Our Global Variables */ + extern struct board_ops dgnc_neo_ops; #endif diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c deleted file mode 100644 index 290bf6e226ac..000000000000 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * Copyright 2004 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/ctype.h> -#include <linux/string.h> -#include <linux/serial_reg.h> -#include <linux/device.h> -#include <linux/pci.h> -#include <linux/kdev_t.h> - -#include "dgnc_driver.h" -#include "dgnc_mgmt.h" - -static ssize_t version_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", DG_PART); -} -static DRIVER_ATTR_RO(version); - -static ssize_t boards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dgnc_num_boards); -} -static DRIVER_ATTR_RO(boards); - -static ssize_t maxboards_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", MAXBOARDS); -} -static DRIVER_ATTR_RO(maxboards); - -static ssize_t pollrate_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%dms\n", dgnc_poll_tick); -} - -static ssize_t pollrate_store(struct device_driver *ddp, - const char *buf, size_t count) -{ - unsigned long flags; - int tick; - int ret; - - ret = sscanf(buf, "%d\n", &tick); - if (ret != 1) - return -EINVAL; - - spin_lock_irqsave(&dgnc_poll_lock, flags); - dgnc_poll_tick = tick; - spin_unlock_irqrestore(&dgnc_poll_lock, flags); - - return count; -} -static DRIVER_ATTR_RW(pollrate); - -void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) -{ - int rc = 0; - struct device_driver *driverfs = &dgnc_driver->driver; - - rc |= driver_create_file(driverfs, &driver_attr_version); - rc |= driver_create_file(driverfs, &driver_attr_boards); - rc |= driver_create_file(driverfs, &driver_attr_maxboards); - rc |= driver_create_file(driverfs, &driver_attr_pollrate); - if (rc) - pr_err("DGNC: sysfs driver_create_file failed!\n"); -} - -void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) -{ - struct device_driver *driverfs = &dgnc_driver->driver; - - driver_remove_file(driverfs, &driver_attr_version); - driver_remove_file(driverfs, &driver_attr_boards); - driver_remove_file(driverfs, &driver_attr_maxboards); - driver_remove_file(driverfs, &driver_attr_pollrate); -} - -#define DGNC_VERIFY_BOARD(p, bd) \ - do { \ - if (!p) \ - return 0; \ - \ - bd = dev_get_drvdata(p); \ - if (!bd || bd->magic != DGNC_BOARD_MAGIC) \ - return 0; \ - if (bd->state != BOARD_READY) \ - return 0; \ - } while (0) - -static ssize_t vpd_show(struct device *p, struct device_attribute *attr, - char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - count += sprintf(buf + count, - "\n 0 1 2 3 4 5 6 7 8 9 A B C D E F"); - for (i = 0; i < 0x40 * 2; i++) { - if (!(i % 16)) - count += sprintf(buf + count, "\n%04X ", i * 2); - count += sprintf(buf + count, "%02X ", bd->vpd[i]); - } - count += sprintf(buf + count, "\n"); - - return count; -} -static DEVICE_ATTR_RO(vpd); - -static ssize_t serial_number_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - - DGNC_VERIFY_BOARD(p, bd); - - if (bd->serial_num[0] == '\0') - count += sprintf(buf + count, "<UNKNOWN>\n"); - else - count += sprintf(buf + count, "%s\n", bd->serial_num); - - return count; -} -static DEVICE_ATTR_RO(serial_number); - -static ssize_t ports_state_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, - "%d %s\n", bd->channels[i]->ch_portnum, - bd->channels[i]->ch_open_count ? "Open" : "Closed"); - } - return count; -} -static DEVICE_ATTR_RO(ports_state); - -static ssize_t ports_baud_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, - "%d %d\n", bd->channels[i]->ch_portnum, - bd->channels[i]->ch_old_baud); - } - return count; -} -static DEVICE_ATTR_RO(ports_baud); - -static ssize_t ports_msignals_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - struct channel_t *ch = bd->channels[i]; - - if (ch->ch_open_count) { - count += snprintf(buf + count, PAGE_SIZE - count, - "%d %s %s %s %s %s %s\n", - ch->ch_portnum, - (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "", - (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "", - (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "", - (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "", - (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "", - (ch->ch_mistat & UART_MSR_RI) ? "RI" : ""); - } else { - count += snprintf(buf + count, PAGE_SIZE - count, - "%d\n", ch->ch_portnum); - } - } - return count; -} -static DEVICE_ATTR_RO(ports_msignals); - -static ssize_t ports_iflag_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_c_iflag); - } - return count; -} -static DEVICE_ATTR_RO(ports_iflag); - -static ssize_t ports_cflag_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_c_cflag); - } - return count; -} -static DEVICE_ATTR_RO(ports_cflag); - -static ssize_t ports_oflag_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_c_oflag); - } - return count; -} -static DEVICE_ATTR_RO(ports_oflag); - -static ssize_t ports_lflag_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_c_lflag); - } - return count; -} -static DEVICE_ATTR_RO(ports_lflag); - -static ssize_t ports_digi_flag_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %x\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_digi.digi_flags); - } - return count; -} -static DEVICE_ATTR_RO(ports_digi_flag); - -static ssize_t ports_rxcount_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_rxcount); - } - return count; -} -static DEVICE_ATTR_RO(ports_rxcount); - -static ssize_t ports_txcount_show(struct device *p, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - int count = 0; - int i = 0; - - DGNC_VERIFY_BOARD(p, bd); - - for (i = 0; i < bd->nasync; i++) { - count += snprintf(buf + count, PAGE_SIZE - count, "%d %ld\n", - bd->channels[i]->ch_portnum, - bd->channels[i]->ch_txcount); - } - return count; -} -static DEVICE_ATTR_RO(ports_txcount); - -/* this function creates the sys files that will export each signal status - * to sysfs each value will be put in a separate filename - */ -void dgnc_create_ports_sysfiles(struct dgnc_board *bd) -{ - int rc = 0; - - dev_set_drvdata(&bd->pdev->dev, bd); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_state); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_baud); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_msignals); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_iflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_cflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_oflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_lflag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_digi_flag); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_rxcount); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_ports_txcount); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_vpd); - rc |= device_create_file(&bd->pdev->dev, &dev_attr_serial_number); - if (rc) - dev_err(&bd->pdev->dev, "dgnc: sysfs device_create_file failed!\n"); -} - -/* removes all the sys files created for that port */ -void dgnc_remove_ports_sysfiles(struct dgnc_board *bd) -{ - device_remove_file(&bd->pdev->dev, &dev_attr_ports_state); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_baud); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_msignals); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_iflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_cflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_oflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_lflag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_digi_flag); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_rxcount); - device_remove_file(&bd->pdev->dev, &dev_attr_ports_txcount); - device_remove_file(&bd->pdev->dev, &dev_attr_vpd); - device_remove_file(&bd->pdev->dev, &dev_attr_serial_number); -} - -static ssize_t tty_state_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - un->un_open_count ? "Open" : "Closed"); -} -static DEVICE_ATTR_RO(tty_state); - -static ssize_t tty_baud_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud); -} -static DEVICE_ATTR_RO(tty_baud); - -static ssize_t tty_msignals_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - if (ch->ch_open_count) { - return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n", - (ch->ch_mostat & UART_MCR_RTS) ? "RTS" : "", - (ch->ch_mistat & UART_MSR_CTS) ? "CTS" : "", - (ch->ch_mostat & UART_MCR_DTR) ? "DTR" : "", - (ch->ch_mistat & UART_MSR_DSR) ? "DSR" : "", - (ch->ch_mistat & UART_MSR_DCD) ? "DCD" : "", - (ch->ch_mistat & UART_MSR_RI) ? "RI" : ""); - } - return 0; -} -static DEVICE_ATTR_RO(tty_msignals); - -static ssize_t tty_iflag_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag); -} -static DEVICE_ATTR_RO(tty_iflag); - -static ssize_t tty_cflag_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag); -} -static DEVICE_ATTR_RO(tty_cflag); - -static ssize_t tty_oflag_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag); -} -static DEVICE_ATTR_RO(tty_oflag); - -static ssize_t tty_lflag_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag); -} -static DEVICE_ATTR_RO(tty_lflag); - -static ssize_t tty_digi_flag_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags); -} -static DEVICE_ATTR_RO(tty_digi_flag); - -static ssize_t tty_rxcount_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount); -} -static DEVICE_ATTR_RO(tty_rxcount); - -static ssize_t tty_txcount_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount); -} -static DEVICE_ATTR_RO(tty_txcount); - -static ssize_t tty_custom_name_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!d) - return 0; - un = dev_get_drvdata(d); - if (!un || un->magic != DGNC_UNIT_MAGIC) - return 0; - ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return 0; - bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return 0; - if (bd->state != BOARD_READY) - return 0; - - return snprintf(buf, PAGE_SIZE, "%sn%d%c\n", - (un->un_type == DGNC_PRINT) ? "pr" : "tty", - bd->boardnum + 1, 'a' + ch->ch_portnum); -} -static DEVICE_ATTR_RO(tty_custom_name); - -static struct attribute *dgnc_sysfs_tty_entries[] = { - &dev_attr_tty_state.attr, - &dev_attr_tty_baud.attr, - &dev_attr_tty_msignals.attr, - &dev_attr_tty_iflag.attr, - &dev_attr_tty_cflag.attr, - &dev_attr_tty_oflag.attr, - &dev_attr_tty_lflag.attr, - &dev_attr_tty_digi_flag.attr, - &dev_attr_tty_rxcount.attr, - &dev_attr_tty_txcount.attr, - &dev_attr_tty_custom_name.attr, - NULL -}; - -static const struct attribute_group dgnc_tty_attribute_group = { - .name = NULL, - .attrs = dgnc_sysfs_tty_entries, -}; - -void dgnc_create_tty_sysfs(struct un_t *un, struct device *c) -{ - int ret; - - ret = sysfs_create_group(&c->kobj, &dgnc_tty_attribute_group); - if (ret) { - dev_err(c, "dgnc: failed to create sysfs tty device attributes.\n"); - sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group); - return; - } - - dev_set_drvdata(c, un); -} - -void dgnc_remove_tty_sysfs(struct device *c) -{ - sysfs_remove_group(&c->kobj, &dgnc_tty_attribute_group); -} - diff --git a/drivers/staging/dgnc/dgnc_sysfs.h b/drivers/staging/dgnc/dgnc_sysfs.h deleted file mode 100644 index 7be7d55bc49e..000000000000 --- a/drivers/staging/dgnc/dgnc_sysfs.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#ifndef __DGNC_SYSFS_H -#define __DGNC_SYSFS_H - -#include <linux/device.h> -#include "dgnc_driver.h" - -struct dgnc_board; -struct channel_t; -struct un_t; -struct pci_driver; -struct class_device; - -void dgnc_create_ports_sysfiles(struct dgnc_board *bd); -void dgnc_remove_ports_sysfiles(struct dgnc_board *bd); - -void dgnc_create_driver_sysfiles(struct pci_driver *); -void dgnc_remove_driver_sysfiles(struct pci_driver *); - -int dgnc_tty_class_init(void); -int dgnc_tty_class_destroy(void); - -void dgnc_create_tty_sysfs(struct un_t *un, struct device *c); -void dgnc_remove_tty_sysfs(struct device *c); - -#endif diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 953d9310fa74..1e10c0fe4745 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -13,13 +13,9 @@ * PURPOSE. See the GNU General Public License for more details. */ -/************************************************************************ - * +/* * This file implements the tty driver functionality for the * Neo and ClassicBoard PCI based product lines. - * - ************************************************************************ - * */ #include <linux/kernel.h> @@ -39,27 +35,20 @@ #include "dgnc_tty.h" #include "dgnc_neo.h" #include "dgnc_cls.h" -#include "dgnc_sysfs.h" #include "dgnc_utils.h" -/* - * internal variables - */ -static unsigned char *dgnc_TmpWriteBuf; - -/* - * Default transparent print information. - */ -static struct digi_t dgnc_digi_init = { - .digi_flags = DIGI_COOK, /* Flags */ - .digi_maxcps = 100, /* Max CPS */ - .digi_maxchar = 50, /* Max chars in print queue */ - .digi_bufsize = 100, /* Printer buffer size */ - .digi_onlen = 4, /* size of printer on string */ - .digi_offlen = 4, /* size of printer off string */ - .digi_onstr = "\033[5i", /* ANSI printer on string ] */ - .digi_offstr = "\033[4i", /* ANSI printer off string ] */ - .digi_term = "ansi" /* default terminal type */ +/* Default transparent print information. */ + +static const struct digi_t dgnc_digi_init = { + .digi_flags = DIGI_COOK, /* Flags */ + .digi_maxcps = 100, /* Max CPS */ + .digi_maxchar = 50, /* Max chars in print queue */ + .digi_bufsize = 100, /* Printer buffer size */ + .digi_onlen = 4, /* size of printer on string */ + .digi_offlen = 4, /* size of printer off string */ + .digi_onstr = "\033[5i", /* ANSI printer on string ] */ + .digi_offstr = "\033[4i", /* ANSI printer off string ] */ + .digi_term = "ansi" /* default terminal type */ }; /* @@ -69,7 +58,7 @@ static struct digi_t dgnc_digi_init = { * This defines a raw port at 9600 baud, 8 data bits, no parity, * 1 stop bit. */ -static struct ktermios DgncDefaultTermios = { +static struct ktermios default_termios = { .c_iflag = (DEFAULT_IFLAGS), /* iflags */ .c_oflag = (DEFAULT_OFLAGS), /* oflags */ .c_cflag = (DEFAULT_CFLAGS), /* cflags */ @@ -113,6 +102,8 @@ static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf, static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios); static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch); +static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char line); +static void dgnc_wake_up_unit(struct un_t *unit); static const struct tty_operations dgnc_tty_ops = { .open = dgnc_tty_open, @@ -137,36 +128,7 @@ static const struct tty_operations dgnc_tty_ops = { .send_xchar = dgnc_tty_send_xchar }; -/************************************************************************ - * - * TTY Initialization/Cleanup Functions - * - ************************************************************************/ - -/* - * dgnc_tty_preinit() - * - * Initialize any global tty related data before we download any boards. - */ -int dgnc_tty_preinit(void) -{ - /* - * Allocate a buffer for doing the copy from user space to - * kernel space in dgnc_write(). We only use one buffer and - * control access to it with a semaphore. If we are paging, we - * are already in trouble so one buffer won't hurt much anyway. - * - * We are okay to sleep in the malloc, as this routine - * is only called during module load, (not in interrupt context), - * and with no locks held. - */ - dgnc_TmpWriteBuf = kmalloc(WRITEBUFLEN, GFP_KERNEL); - - if (!dgnc_TmpWriteBuf) - return -ENOMEM; - - return 0; -} +/* TTY Initialization/Cleanup Functions */ /* * dgnc_tty_register() @@ -194,7 +156,7 @@ int dgnc_tty_register(struct dgnc_board *brd) brd->serial_driver->minor_start = 0; brd->serial_driver->type = TTY_DRIVER_TYPE_SERIAL; brd->serial_driver->subtype = SERIAL_TYPE_NORMAL; - brd->serial_driver->init_termios = DgncDefaultTermios; + brd->serial_driver->init_termios = default_termios; brd->serial_driver->driver_name = DRVSTR; /* @@ -233,7 +195,7 @@ int dgnc_tty_register(struct dgnc_board *brd) brd->print_driver->minor_start = 0x80; brd->print_driver->type = TTY_DRIVER_TYPE_SERIAL; brd->print_driver->subtype = SERIAL_TYPE_NORMAL; - brd->print_driver->init_termios = DgncDefaultTermios; + brd->print_driver->init_termios = default_termios; brd->print_driver->driver_name = DRVSTR; /* @@ -285,9 +247,7 @@ int dgnc_tty_init(struct dgnc_board *brd) if (!brd) return -ENXIO; - /* - * Initialize board structure elements. - */ + /* Initialize board structure elements. */ vaddr = brd->re_map_membase; @@ -345,12 +305,10 @@ int dgnc_tty_init(struct dgnc_board *brd) classp = tty_register_device(brd->serial_driver, i, &ch->ch_bd->pdev->dev); ch->ch_tun.un_sysfs = classp; - dgnc_create_tty_sysfs(&ch->ch_tun, classp); classp = tty_register_device(brd->print_driver, i, &ch->ch_bd->pdev->dev); ch->ch_pun.un_sysfs = classp; - dgnc_create_tty_sysfs(&ch->ch_pun, classp); } } @@ -365,17 +323,6 @@ err_free_channels: } /* - * dgnc_tty_post_uninit() - * - * UnInitialize any global tty related data. - */ -void dgnc_tty_post_uninit(void) -{ - kfree(dgnc_TmpWriteBuf); - dgnc_TmpWriteBuf = NULL; -} - -/* * dgnc_cleanup_tty() * * Uninitialize the TTY portion of this driver. Free all memory and @@ -385,20 +332,14 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_tun.un_sysfs); + for (i = 0; i < brd->nasync; i++) tty_unregister_device(brd->serial_driver, i); - } + tty_unregister_driver(brd->serial_driver); - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_pun.un_sysfs); + for (i = 0; i < brd->nasync; i++) tty_unregister_device(brd->print_driver, i); - } + tty_unregister_driver(brd->print_driver); put_tty_driver(brd->serial_driver); @@ -437,9 +378,7 @@ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n) } if (n > 0) { - /* - * Move rest of data. - */ + /* Move rest of data. */ remain = n; memcpy(ch->ch_wqueue + head, buf, remain); head += remain; @@ -509,9 +448,8 @@ void dgnc_input(struct channel_t *ch) goto exit_unlock; } - /* - * If we are throttled, simply don't read any data. - */ + /* If we are throttled, simply don't read any data. */ + if (ch->ch_flags & CH_FORCED_STOPI) goto exit_unlock; @@ -624,10 +562,10 @@ exit_unlock: tty_ldisc_deref(ld); } -/************************************************************************ +/* * Determines when CARRIER changes state and takes appropriate * action. - ************************************************************************/ + */ void dgnc_carrier(struct channel_t *ch) { int virt_carrier = 0; @@ -645,28 +583,24 @@ void dgnc_carrier(struct channel_t *ch) if (ch->ch_c_cflag & CLOCAL) virt_carrier = 1; - /* - * Test for a VIRTUAL carrier transition to HIGH. - */ + /* Test for a VIRTUAL carrier transition to HIGH. */ + if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) { /* * When carrier rises, wake any threads waiting * for carrier in the open routine. */ - if (waitqueue_active(&ch->ch_flags_wait)) wake_up_interruptible(&ch->ch_flags_wait); } - /* - * Test for a PHYSICAL carrier transition to HIGH. - */ + /* Test for a PHYSICAL carrier transition to HIGH. */ + if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) { /* * When carrier rises, wake any threads waiting * for carrier in the open routine. */ - if (waitqueue_active(&ch->ch_flags_wait)) wake_up_interruptible(&ch->ch_flags_wait); } @@ -704,9 +638,8 @@ void dgnc_carrier(struct channel_t *ch) tty_hangup(ch->ch_pun.un_tty); } - /* - * Make sure that our cached values reflect the current reality. - */ + /* Make sure that our cached values reflect the current reality. */ + if (virt_carrier == 1) ch->ch_flags |= CH_FCAR; else @@ -718,9 +651,8 @@ void dgnc_carrier(struct channel_t *ch) ch->ch_flags &= ~CH_CD; } -/* - * Assign the custom baud rate to the channel structure - */ +/* Assign the custom baud rate to the channel structure */ + static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate) { int testdiv; @@ -854,6 +786,12 @@ void dgnc_check_queue_flow_control(struct channel_t *ch) } } +static void dgnc_set_signal_low(struct channel_t *ch, const unsigned char sig) +{ + ch->ch_mostat &= ~(sig); + ch->ch_bd->bd_ops->assert_modem_signals(ch); +} + void dgnc_wakeup_writes(struct channel_t *ch) { int qlen = 0; @@ -864,9 +802,8 @@ void dgnc_wakeup_writes(struct channel_t *ch) spin_lock_irqsave(&ch->ch_lock, flags); - /* - * If channel now has space, wake up anyone waiting on the condition. - */ + /* If channel now has space, wake up anyone waiting on the condition. */ + qlen = ch->ch_w_head - ch->ch_w_tail; if (qlen < 0) qlen += WQUEUESIZE; @@ -892,19 +829,15 @@ void dgnc_wakeup_writes(struct channel_t *ch) * If RTS Toggle mode is on, whenever * the queue and UART is empty, keep RTS low. */ - if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) { - ch->ch_mostat &= ~(UART_MCR_RTS); - ch->ch_bd->bd_ops->assert_modem_signals(ch); - } + if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) + dgnc_set_signal_low(ch, UART_MCR_RTS); /* * If DTR Toggle mode is on, whenever * the queue and UART is empty, keep DTR low. */ - if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) { - ch->ch_mostat &= ~(UART_MCR_DTR); - ch->ch_bd->bd_ops->assert_modem_signals(ch); - } + if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) + dgnc_set_signal_low(ch, UART_MCR_DTR); } } @@ -930,7 +863,7 @@ void dgnc_wakeup_writes(struct channel_t *ch) spin_unlock_irqrestore(&ch->ch_lock, flags); } -struct dgnc_board *find_board_by_major(unsigned int major) +static struct dgnc_board *find_board_by_major(unsigned int major) { int i; @@ -948,16 +881,10 @@ struct dgnc_board *find_board_by_major(unsigned int major) return NULL; } -/************************************************************************ - * - * TTY Entry points and helper functions - * - ************************************************************************/ +/* TTY Entry points and helper functions */ + +/* dgnc_tty_open() */ -/* - * dgnc_tty_open() - * - */ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) { struct dgnc_board *brd; @@ -1045,8 +972,8 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) * ch_flags_wait to wake us back up. */ rc = wait_event_interruptible(ch->ch_flags_wait, - (((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & - UN_CLOSING) == 0)); + (((ch->ch_tun.un_flags | + ch->ch_pun.un_flags) & UN_CLOSING) == 0)); /* If ret is non-zero, user ctrl-c'ed us */ if (rc) @@ -1057,9 +984,8 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) /* Store our unit into driver_data, so we always have it available. */ tty->driver_data = un; - /* - * Initialize tty's - */ + /* Initialize tty's */ + if (!(un->un_flags & UN_ISOPEN)) { /* Store important variables. */ un->un_tty = tty; @@ -1096,13 +1022,10 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) ch->ch_flags &= ~(CH_OPENING); wake_up_interruptible(&ch->ch_flags_wait); - /* - * Initialize if neither terminal or printer is open. - */ + /* Initialize if neither terminal or printer is open. */ + if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) { - /* - * Flush input queues. - */ + /* Flush input queues. */ ch->ch_r_head = 0; ch->ch_r_tail = 0; ch->ch_e_head = 0; @@ -1138,16 +1061,13 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) brd->bd_ops->uart_init(ch); } - /* - * Run param in case we changed anything - */ + /* Run param in case we changed anything */ + brd->bd_ops->param(tty); dgnc_carrier(ch); - /* - * follow protocol for opening port - */ + /* follow protocol for opening port */ spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -1248,9 +1168,8 @@ static int dgnc_block_til_ready(struct tty_struct *tty, break; } - /* - * Store the flags before we let go of channel lock - */ + /* Store the flags before we let go of channel lock */ + if (sleep_on_un_flags) old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags; else @@ -1269,12 +1188,13 @@ static int dgnc_block_til_ready(struct tty_struct *tty, * from the current value. */ if (sleep_on_un_flags) - retval = wait_event_interruptible(un->un_flags_wait, - (old_flags != (ch->ch_tun.un_flags | - ch->ch_pun.un_flags))); + retval = wait_event_interruptible + (un->un_flags_wait, + (old_flags != (ch->ch_tun.un_flags | + ch->ch_pun.un_flags))); else retval = wait_event_interruptible(ch->ch_flags_wait, - (old_flags != ch->ch_flags)); + (old_flags != ch->ch_flags)); /* * We got woken up for some reason. @@ -1304,10 +1224,8 @@ static void dgnc_tty_hangup(struct tty_struct *tty) dgnc_tty_flush_buffer(tty); } -/* - * dgnc_tty_close() - * - */ +/* dgnc_tty_close() */ + static void dgnc_tty_close(struct tty_struct *tty, struct file *file) { struct dgnc_board *bd; @@ -1377,9 +1295,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) !(ch->ch_digi.digi_flags & DIGI_PRINTER)) { ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI); - /* - * turn off print device when closing print device. - */ + /* turn off print device when closing print device. */ + if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) { dgnc_wmove(ch, ch->ch_digi.digi_offstr, (int)ch->ch_digi.digi_offlen); @@ -1399,9 +1316,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) tty->closing = 0; - /* - * If we have HUPCL set, lower DTR and RTS - */ + /* If we have HUPCL set, lower DTR and RTS */ + if (ch->ch_c_cflag & HUPCL) { /* Drop RTS/DTR */ ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS); @@ -1424,9 +1340,8 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) /* Turn off UART interrupts for this port */ ch->ch_bd->bd_ops->uart_off(ch); } else { - /* - * turn off print device when closing print device. - */ + /* turn off print device when closing print device. */ + if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) { dgnc_wmove(ch, ch->ch_digi.digi_offstr, (int)ch->ch_digi.digi_offlen); @@ -1543,7 +1458,7 @@ static int dgnc_tty_write_room(struct tty_struct *tty) int ret = 0; unsigned long flags; - if (!tty || !dgnc_TmpWriteBuf) + if (!tty) return 0; un = tty->driver_data; @@ -1598,9 +1513,8 @@ static int dgnc_tty_write_room(struct tty_struct *tty) */ static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c) { - /* - * Simply call tty_write. - */ + /* Simply call tty_write. */ + dgnc_tty_write(tty, &c, 1); return 1; } @@ -1623,7 +1537,7 @@ static int dgnc_tty_write(struct tty_struct *tty, ushort tmask; uint remain; - if (!tty || !dgnc_TmpWriteBuf) + if (!tty) return 0; un = tty->driver_data; @@ -1667,9 +1581,8 @@ static int dgnc_tty_write(struct tty_struct *tty, */ count = min(count, bufcount); - /* - * Bail if no space left. - */ + /* Bail if no space left. */ + if (count <= 0) goto exit_retry; @@ -1712,9 +1625,7 @@ static int dgnc_tty_write(struct tty_struct *tty, } if (n > 0) { - /* - * Move rest of data. - */ + /* Move rest of data. */ remain = n; memcpy(ch->ch_wqueue + head, buf, remain); head += remain; @@ -1749,9 +1660,7 @@ exit_retry: return 0; } -/* - * Return modem signals to ld. - */ +/* Return modem signals to ld. */ static int dgnc_tty_tiocmget(struct tty_struct *tty) { @@ -1960,9 +1869,8 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c) dev_dbg(tty->dev, "dgnc_tty_send_xchar finish\n"); } -/* - * Return modem signals to ld. - */ +/* Return modem signals to ld. */ + static inline int dgnc_get_mstat(struct channel_t *ch) { unsigned char mstat; @@ -1994,9 +1902,8 @@ static inline int dgnc_get_mstat(struct channel_t *ch) return result; } -/* - * Return modem signals to ld. - */ +/* Return modem signals to ld. */ + static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value) { @@ -2070,9 +1977,6 @@ static int dgnc_set_modem_info(struct channel_t *ch, * dgnc_tty_digigeta() * * Ioctl to get the information for ditty. - * - * - * */ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retinfo) @@ -2112,9 +2016,6 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, * dgnc_tty_digiseta() * * Ioctl to set the information for ditty. - * - * - * */ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info) @@ -2145,9 +2046,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, spin_lock_irqsave(&ch->ch_lock, flags); - /* - * Handle transistions to and from RTS Toggle. - */ + /* Handle transitions to and from RTS Toggle. */ + if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) && (new_digi.digi_flags & DIGI_RTS_TOGGLE)) ch->ch_mostat &= ~(UART_MCR_RTS); @@ -2155,9 +2055,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, !(new_digi.digi_flags & DIGI_RTS_TOGGLE)) ch->ch_mostat |= (UART_MCR_RTS); - /* - * Handle transistions to and from DTR Toggle. - */ + /* Handle transitions to and from DTR Toggle. */ + if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && (new_digi.digi_flags & DIGI_DTR_TOGGLE)) ch->ch_mostat &= ~(UART_MCR_DTR); @@ -2195,9 +2094,8 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, return 0; } -/* - * dgnc_set_termios() - */ +/* dgnc_set_termios() */ + static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { @@ -2428,11 +2326,18 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty) spin_unlock_irqrestore(&ch->ch_lock, flags); } -/***************************************************************************** - * - * The IOCTL function and all of its helpers +/* + * dgnc_wake_up_unit() * - *****************************************************************************/ + * Wakes up processes waiting in the unit's (teminal/printer) wait queue + */ +static void dgnc_wake_up_unit(struct un_t *unit) +{ + unit->un_flags &= ~(UN_LOW | UN_EMPTY); + wake_up_interruptible(&unit->un_flags_wait); +} + +/* The IOCTL function and all of its helpers */ /* * dgnc_tty_ioctl() @@ -2506,7 +2411,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return 0; case TCSBRKP: - /* support for POSIX tcsendbreak() + /* + * support for POSIX tcsendbreak() * According to POSIX.1 spec (7.2.2.1.2) breaks should be * between 0.25 and 0.5 seconds so we'll ask for something * in the middle: 0.375 seconds. @@ -2583,9 +2489,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_unlock_irqrestore(&ch->ch_lock, flags); return dgnc_set_modem_info(ch, cmd, uarg); - /* - * Here are any additional ioctl's that we want to implement - */ + /* Here are any additional ioctl's that we want to implement */ case TCFLSH: /* @@ -2615,17 +2519,11 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, ch->ch_w_head = ch->ch_w_tail; ch_bd_ops->flush_uart_write(ch); - if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) { - ch->ch_tun.un_flags &= - ~(UN_LOW | UN_EMPTY); - wake_up_interruptible(&ch->ch_tun.un_flags_wait); - } - - if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) { - ch->ch_pun.un_flags &= - ~(UN_LOW | UN_EMPTY); - wake_up_interruptible(&ch->ch_pun.un_flags_wait); - } + if (ch->ch_tun.un_flags & (UN_LOW | UN_EMPTY)) + dgnc_wake_up_unit(&ch->ch_tun); + + if (ch->ch_pun.un_flags & (UN_LOW | UN_EMPTY)) + dgnc_wake_up_unit(&ch->ch_pun); } } @@ -2705,9 +2603,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case DIGI_LOOPBACK: { uint loopback = 0; - /* Let go of locks when accessing user space, + /* + * Let go of locks when accessing user space, * could sleep - */ + */ spin_unlock_irqrestore(&ch->ch_lock, flags); rc = get_user(loopback, (unsigned int __user *)arg); if (rc) @@ -2749,7 +2648,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, * This ioctl allows insertion of a character into the front * of any pending data to be transmitted. * - * This ioctl is to satify the "Send Character Immediate" + * This ioctl is to satisfy the "Send Character Immediate" * call that the RealPort protocol spec requires. */ case DIGI_REALPORT_SENDIMMEDIATE: @@ -2769,7 +2668,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* * This ioctl returns all the current counts for the port. * - * This ioctl is to satify the "Line Error Counters" + * This ioctl is to satisfy the "Line Error Counters" * call that the RealPort protocol spec requires. */ case DIGI_REALPORT_GETCOUNTERS: @@ -2795,7 +2694,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* * This ioctl returns all current events. * - * This ioctl is to satify the "Event Reporting" + * This ioctl is to satisfy the "Event Reporting" * call that the RealPort protocol spec requires. */ case DIGI_REALPORT_GETEVENTS: @@ -2831,23 +2730,23 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_unlock_irqrestore(&ch->ch_lock, flags); - /* - * Get data from user first. - */ + /* Get data from user first. */ + if (copy_from_user(&buf, uarg, sizeof(buf))) return -EFAULT; spin_lock_irqsave(&ch->ch_lock, flags); - /* - * Figure out how much data is in our RX and TX queues. - */ + /* Figure out how much data is in our RX and TX queues. */ + buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK; buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK; /* - * Is the UART empty? Add that value to whats in our TX queue. + * Is the UART empty? + * Add that value to whats in our TX queue. */ + count = buf.txbuf + ch_bd_ops->get_uart_bytes_left(ch); /* @@ -2867,9 +2766,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (buf.txbuf > tdist) buf.txbuf = tdist; - /* - * Report whether our queue and UART TX are completely empty. - */ + /* Report whether our queue and UART TX are completely empty. */ + if (count) buf.txdone = 0; else diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 24c9a412211e..1ee0eeeb4730 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -21,11 +21,9 @@ int dgnc_tty_register(struct dgnc_board *brd); void dgnc_tty_unregister(struct dgnc_board *brd); -int dgnc_tty_preinit(void); -int dgnc_tty_init(struct dgnc_board *); +int dgnc_tty_init(struct dgnc_board *brd); -void dgnc_tty_post_uninit(void); -void dgnc_cleanup_tty(struct dgnc_board *); +void dgnc_cleanup_tty(struct dgnc_board *brd); void dgnc_input(struct channel_t *ch); void dgnc_carrier(struct channel_t *ch); diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h index 5b983e6f5ee2..ec2e3dda6119 100644 --- a/drivers/staging/dgnc/digi.h +++ b/drivers/staging/dgnc/digi.h @@ -17,16 +17,16 @@ #define __DIGI_H #ifndef TIOCM_LE -#define TIOCM_LE 0x01 /* line enable */ -#define TIOCM_DTR 0x02 /* data terminal ready */ -#define TIOCM_RTS 0x04 /* request to send */ -#define TIOCM_ST 0x08 /* secondary transmit */ -#define TIOCM_SR 0x10 /* secondary receive */ -#define TIOCM_CTS 0x20 /* clear to send */ -#define TIOCM_CAR 0x40 /* carrier detect */ -#define TIOCM_RNG 0x80 /* ring indicator */ -#define TIOCM_DSR 0x100 /* data set ready */ -#define TIOCM_RI TIOCM_RNG /* ring (alternate) */ +#define TIOCM_LE 0x01 /* line enable */ +#define TIOCM_DTR 0x02 /* data terminal ready */ +#define TIOCM_RTS 0x04 /* request to send */ +#define TIOCM_ST 0x08 /* secondary transmit */ +#define TIOCM_SR 0x10 /* secondary receive */ +#define TIOCM_CTS 0x20 /* clear to send */ +#define TIOCM_CAR 0x40 /* carrier detect */ +#define TIOCM_RNG 0x80 /* ring indicator */ +#define TIOCM_DSR 0x100 /* data set ready */ +#define TIOCM_RI TIOCM_RNG /* ring (alternate) */ #define TIOCM_CD TIOCM_CAR /* carrier detect (alt) */ #endif @@ -40,72 +40,71 @@ #define TIOCMBIS (('d' << 8) | 255) /* set modem ctrl state */ #endif -#define DIGI_GETA (('e' << 8) | 94) /* Read params */ -#define DIGI_SETA (('e' << 8) | 95) /* Set params */ -#define DIGI_SETAW (('e' << 8) | 96) /* Drain & set params */ +#define DIGI_GETA (('e' << 8) | 94) /* Read params */ +#define DIGI_SETA (('e' << 8) | 95) /* Set params */ +#define DIGI_SETAW (('e' << 8) | 96) /* Drain & set params */ #define DIGI_SETAF (('e' << 8) | 97) /* Drain, flush & set params */ -#define DIGI_GET_NI_INFO (('d' << 8) | 250) /* Non-intelligent state info */ -#define DIGI_LOOPBACK (('d' << 8) | 252) /* - * Enable/disable UART - * internal loopback - */ -#define DIGI_FAST 0x0002 /* Fast baud rates */ -#define RTSPACE 0x0004 /* RTS input flow control */ -#define CTSPACE 0x0008 /* CTS output flow control */ +#define DIGI_GET_NI_INFO (('d' << 8) | 250) /* Non-intelligent state info */ +#define DIGI_LOOPBACK (('d' << 8) | 252) /* + * Enable/disable UART + * internal loopback + */ +#define DIGI_FAST 0x0002 /* Fast baud rates */ +#define RTSPACE 0x0004 /* RTS input flow control */ +#define CTSPACE 0x0008 /* CTS output flow control */ #define DIGI_COOK 0x0080 /* Cooked processing done in FEP */ -#define DIGI_FORCEDCD 0x0100 /* Force carrier */ -#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ +#define DIGI_FORCEDCD 0x0100 /* Force carrier */ +#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ #define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl*/ -#define DIGI_DTR_TOGGLE 0x2000 /* Support DTR Toggle */ -#define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */ -#define DIGI_PLEN 28 /* String length */ -#define DIGI_TSIZ 10 /* Terminal string len */ +#define DIGI_DTR_TOGGLE 0x2000 /* Support DTR Toggle */ +#define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */ +#define DIGI_PLEN 28 /* String length */ +#define DIGI_TSIZ 10 /* Terminal string len */ -/************************************************************************ +/* * Structure used with ioctl commands for DIGI parameters. - ************************************************************************/ + */ struct digi_t { - unsigned short digi_flags; /* Flags (see above) */ - unsigned short digi_maxcps; /* Max printer CPS */ + unsigned short digi_flags; /* Flags (see above) */ + unsigned short digi_maxcps; /* Max printer CPS */ unsigned short digi_maxchar; /* Max chars in print queue */ - unsigned short digi_bufsize; /* Buffer size */ - unsigned char digi_onlen; /* Length of ON string */ + unsigned short digi_bufsize; /* Buffer size */ + unsigned char digi_onlen; /* Length of ON string */ unsigned char digi_offlen; /* Length of OFF string */ - char digi_onstr[DIGI_PLEN]; /* Printer on string */ - char digi_offstr[DIGI_PLEN]; /* Printer off string */ - char digi_term[DIGI_TSIZ]; /* terminal string */ + char digi_onstr[DIGI_PLEN]; /* Printer on string */ + char digi_offstr[DIGI_PLEN]; /* Printer off string */ + char digi_term[DIGI_TSIZ]; /* terminal string */ }; -/************************************************************************ - * Structure to get driver status information - ************************************************************************/ +/* Structure to get driver status information */ + struct digi_dinfo { - unsigned int dinfo_nboards; /* # boards configured */ + unsigned int dinfo_nboards; /* # boards configured */ char dinfo_reserved[12]; /* for future expansion */ - char dinfo_version[16]; /* driver version */ + char dinfo_version[16]; /* driver version */ }; -#define DIGI_GETDD (('d' << 8) | 248) /* get driver info */ +#define DIGI_GETDD (('d' << 8) | 248) /* get driver info */ -/************************************************************************ +/* * Structure used with ioctl commands for per-board information * * physsize and memsize differ when board has "windowed" memory - ************************************************************************/ + */ struct digi_info { - unsigned int info_bdnum; /* Board number (0 based) */ - unsigned int info_ioport; /* io port address */ - unsigned int info_physaddr; /* memory address */ + unsigned int info_bdnum; /* Board number (0 based) */ + unsigned int info_ioport; /* io port address */ + unsigned int info_physaddr; /* memory address */ unsigned int info_physsize; /* Size of host mem window */ unsigned int info_memsize; /* Amount of dual-port mem */ - /* on board */ - unsigned short info_bdtype; /* Board type */ - unsigned short info_nports; /* number of ports */ - char info_bdstate; /* board state */ - char info_reserved[7]; /* for future expansion */ + /* on board */ + unsigned short info_bdtype; /* Board type */ + unsigned short info_nports; /* number of ports */ + char info_bdstate; /* board state */ + char info_reserved[7]; /* for future expansion */ }; -#define DIGI_GETBD (('d' << 8) | 249) /* get board info */ +#define DIGI_GETBD (('d' << 8) | 249) /* get board info */ struct digi_getbuffer /* Struct for holding buffer use counts */ { @@ -139,7 +138,7 @@ struct digi_getcounter { #define DIGI_REALPORT_GETEVENTS (('e' << 8) | 111) #define EV_OPU 0x0001 /* !<Output paused by client */ -#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */ +#define EV_OPS 0x0002 /* !<Output paused by regular sw flowctrl */ #define EV_IPU 0x0010 /* !<Input paused unconditionally by user */ #define EV_IPS 0x0020 /* !<Input paused by high/low water marks */ #define EV_TXB 0x0040 /* !<Transmit break pending */ |