diff options
Diffstat (limited to 'drivers/staging/dgnc')
-rw-r--r-- | drivers/staging/dgnc/TODO | 3 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_cls.c | 154 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_cls.h | 42 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_driver.c | 109 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_driver.h | 340 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_mgmt.c | 67 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_mgmt.h | 7 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_neo.c | 228 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_neo.h | 85 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_pci.h | 13 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_tty.c | 577 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_tty.h | 6 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_utils.c | 9 | ||||
-rw-r--r-- | drivers/staging/dgnc/dgnc_utils.h | 6 | ||||
-rw-r--r-- | drivers/staging/dgnc/digi.h | 134 |
15 files changed, 715 insertions, 1065 deletions
diff --git a/drivers/staging/dgnc/TODO b/drivers/staging/dgnc/TODO index e26d1d6..d4cc657 100644 --- a/drivers/staging/dgnc/TODO +++ b/drivers/staging/dgnc/TODO @@ -1,7 +1,4 @@ * remove unnecessary comments -* remove unnecessary error messages. Example kzalloc() has its - own error message. Adding an extra one is useless. -* use goto statements for error handling when appropriate * there is a lot of unnecessary code in the driver. It was originally a standalone driver. Remove unneeded code. diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index c20ffdd..9639035 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -14,15 +14,15 @@ */ #include <linux/kernel.h> -#include <linux/sched.h> /* For jiffies, task states */ -#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */ -#include <linux/delay.h> /* For udelay */ -#include <linux/io.h> /* For read[bwl]/write[bwl] */ -#include <linux/serial.h> /* For struct async_serial */ -#include <linux/serial_reg.h> /* For the various UART offsets */ +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/serial.h> +#include <linux/serial_reg.h> #include <linux/pci.h> -#include "dgnc_driver.h" /* Driver main header file */ +#include "dgnc_driver.h" #include "dgnc_cls.h" #include "dgnc_tty.h" @@ -273,7 +273,6 @@ static inline void cls_set_no_input_flow_control(struct channel_t *ch) } /* - * cls_clear_break. * Determines whether its time to shut off break condition. * * No locks are assumed to be held when calling this function. @@ -283,12 +282,11 @@ static inline void cls_clear_break(struct channel_t *ch, int force) { unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* Bail if we aren't currently sending a break. */ if (!ch->ch_stop_sending_break) { spin_unlock_irqrestore(&ch->ch_lock, flags); return; @@ -316,16 +314,14 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) ushort tail; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* cache head and tail of queue */ head = ch->ch_r_head; tail = ch->ch_r_tail; - /* Store how much space we have left in the queue */ qleft = tail - head - 1; if (qleft < 0) qleft += RQUEUEMASK + 1; @@ -343,9 +339,7 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) if (!(linestatus & (UART_LSR_DR))) break; - /* - * Discard character if we are ignoring the error mask. - */ + /* Discard character if we are ignoring the error mask. */ if (linestatus & error_mask) { linestatus = 0; readb(&ch->ch_cls_uart->txrx); @@ -356,9 +350,6 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) * If our queue is full, we have no choice but to drop some * data. The assumption is that HWFLOW or SWFLOW should have * stopped things way way before we got to this point. - * - * I decided that I wanted to ditch the oldest data first, - * I hope thats okay with everyone? Yes? Good. */ while (qleft < 1) { tail = (tail + 1) & RQUEUEMASK; @@ -380,13 +371,10 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) if (ch->ch_equeue[head] & UART_LSR_FE) ch->ch_err_frame++; - /* Add to, and flip head if needed */ head = (head + 1) & RQUEUEMASK; ch->ch_rxcount++; } - /* Write new final heads to channel structure. */ - ch->ch_r_head = head & RQUEUEMASK; ch->ch_e_head = head & EQUEUEMASK; @@ -398,7 +386,7 @@ static void cls_assert_modem_signals(struct channel_t *ch) { unsigned char out; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; out = ch->ch_mostat; @@ -421,12 +409,11 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) uint len_written = 0; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* No data to write to the UART */ if (ch->ch_w_tail == ch->ch_w_head) goto exit_unlock; @@ -440,12 +427,10 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) n = 32; - /* cache head and tail of queue */ head = ch->ch_w_head & WQUEUEMASK; tail = ch->ch_w_tail & WQUEUEMASK; qlen = (head - tail) & WQUEUEMASK; - /* Find minimum of the FIFO space, versus queue length */ n = min(n, qlen); while (n > 0) { @@ -494,7 +479,7 @@ static void cls_parse_modem(struct channel_t *ch, unsigned char signals) unsigned char msignals = signals; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; /* @@ -524,10 +509,7 @@ static void cls_parse_modem(struct channel_t *ch, unsigned char signals) } spin_unlock_irqrestore(&ch->ch_lock, flags); - /* - * Scrub off lower bits. They signify delta's, which I don't - * care about - */ + /* Scrub off lower bits. They signify delta's */ signals &= 0xf0; spin_lock_irqsave(&ch->ch_lock, flags); @@ -569,34 +551,28 @@ static inline void cls_parse_isr(struct dgnc_board *brd, uint port) return; ch = brd->channels[port]; - if (ch->magic != DGNC_CHANNEL_MAGIC) - return; /* Here we try to figure out what caused the interrupt to happen */ while (1) { isr = readb(&ch->ch_cls_uart->isr_fcr); - /* Bail if no pending interrupt on port */ if (isr & UART_IIR_NO_INT) break; /* Receive Interrupt pending */ if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) { - /* Read data from uart -> queue */ cls_copy_data_from_uart_to_queue(ch); dgnc_check_queue_flow_control(ch); } /* Transmit Hold register empty pending */ if (isr & UART_IIR_THRI) { - /* Transfer data (if any) from Write Queue -> UART. */ spin_lock_irqsave(&ch->ch_lock, flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, flags); cls_copy_data_from_queue_to_uart(ch); } - /* Parse any modem signal changes */ cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); } } @@ -604,12 +580,14 @@ static inline void cls_parse_isr(struct dgnc_board *brd, uint port) /* Channel lock MUST be held before calling this function! */ static void cls_flush_uart_write(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), &ch->ch_cls_uart->isr_fcr); - usleep_range(10, 20); + + /* Must use *delay family functions in atomic context */ + udelay(10); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); } @@ -617,7 +595,7 @@ static void cls_flush_uart_write(struct channel_t *ch) /* Channel lock MUST be held before calling this function! */ static void cls_flush_uart_read(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; /* @@ -634,10 +612,7 @@ static void cls_flush_uart_read(struct channel_t *ch) udelay(10); } -/* - * cls_param() - * Send any/all changes to the line to the UART. - */ +/* Send any/all changes to the line to the UART. */ static void cls_param(struct tty_struct *tty) { unsigned char lcr = 0; @@ -650,23 +625,22 @@ static void cls_param(struct tty_struct *tty) struct channel_t *ch; struct un_t *un; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = (struct un_t *)tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; /* 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; @@ -776,10 +750,6 @@ static void cls_param(struct tty_struct *tty) if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; - /* - * Not all platforms support mark/space parity, - * so this will hide behind an ifdef. - */ #ifdef CMSPAR if (ch->ch_c_cflag & CMSPAR) lcr |= UART_LCR_SPAR; @@ -850,10 +820,6 @@ static void cls_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) { cls_set_cts_flow_control(ch); } else if (ch->ch_c_iflag & IXON) { - /* - * If start/stop is set to disable, then we should - * disable flow control - */ if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) cls_set_no_output_flow_control(ch); @@ -866,10 +832,6 @@ static void cls_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) { cls_set_rts_flow_control(ch); } else if (ch->ch_c_iflag & IXOFF) { - /* - * If start/stop is set to disable, then we should disable - * flow control - */ if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) cls_set_no_input_flow_control(ch); @@ -881,12 +843,10 @@ static void cls_param(struct tty_struct *tty) cls_assert_modem_signals(ch); - /* Get current status of the modem signals now */ cls_parse_modem(ch, readb(&ch->ch_cls_uart->msr)); } -/* Our board poller function. */ - +/* Board poller function. */ static void cls_tasklet(unsigned long data) { struct dgnc_board *bd = (struct dgnc_board *)data; @@ -896,10 +856,9 @@ static void cls_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; - /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); state = bd->state; ports = bd->nasync; @@ -911,10 +870,7 @@ 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 ((state == BOARD_READY) && (ports > 0)) { - /* Loop on each port */ for (i = 0; i < ports; i++) { ch = bd->channels[i]; @@ -934,8 +890,6 @@ static void cls_tasklet(unsigned long data) cls_copy_data_from_queue_to_uart(ch); dgnc_wakeup_writes(ch); - /* Check carrier function. */ - dgnc_carrier(ch); /* @@ -950,11 +904,7 @@ static void cls_tasklet(unsigned long data) spin_unlock_irqrestore(&bd->bd_intr_lock, flags); } -/* - * cls_intr() - * - * Classic specific interrupt handler. - */ +/* Classic specific interrupt handler. */ static irqreturn_t cls_intr(int irq, void *voidbrd) { struct dgnc_board *brd = voidbrd; @@ -962,33 +912,20 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) unsigned char poll_reg; unsigned long flags; - /* - * Check to make sure it didn't receive interrupt with a null board - * associated or a board pointer that wasn't ours. - */ - if (!brd || brd->magic != DGNC_BOARD_MAGIC) + if (!brd) return IRQ_NONE; spin_lock_irqsave(&brd->bd_intr_lock, flags); - /* - * Check the board's global interrupt offset to see if we - * we actually do have an interrupt pending for us. - */ poll_reg = readb(brd->re_map_membase + UART_CLASSIC_POLL_ADDR_OFFSET); - - /* If 0, no interrupts pending */ if (!poll_reg) { spin_unlock_irqrestore(&brd->bd_intr_lock, flags); return IRQ_NONE; } - /* Parse each port to find out what caused the interrupt */ for (i = 0; i < brd->nasync; i++) cls_parse_isr(brd, i); - /* Schedule tasklet to more in-depth servicing at a better time. */ - tasklet_schedule(&brd->helper_tasklet); spin_unlock_irqrestore(&brd->bd_intr_lock, flags); @@ -1013,7 +950,7 @@ static void cls_enable_receiver(struct channel_t *ch) } /* - * This function basically goes to sleep for secs, or until + * This function basically goes to sleep for seconds, or until * it gets signalled that the port has fully drained. */ static int cls_drain(struct tty_struct *tty, uint seconds) @@ -1022,15 +959,15 @@ static int cls_drain(struct tty_struct *tty, uint seconds) struct channel_t *ch; struct un_t *un; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return -ENXIO; un = (struct un_t *)tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return -ENXIO; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -ENXIO; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1047,7 +984,7 @@ static int cls_drain(struct tty_struct *tty, uint seconds) static void cls_send_start_character(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; if (ch->ch_startc != _POSIX_VDISABLE) { @@ -1058,7 +995,7 @@ static void cls_send_start_character(struct channel_t *ch) static void cls_send_stop_character(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; if (ch->ch_stopc != _POSIX_VDISABLE) { @@ -1067,7 +1004,6 @@ static void cls_send_stop_character(struct channel_t *ch) } } -/* Inits UART */ static void cls_uart_init(struct channel_t *ch) { unsigned char lcrb = readb(&ch->ch_cls_uart->lcr); @@ -1096,7 +1032,7 @@ static void cls_uart_init(struct channel_t *ch) writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, &ch->ch_cls_uart->isr_fcr); - udelay(10); + usleep_range(10, 20); ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); @@ -1104,25 +1040,21 @@ static void cls_uart_init(struct channel_t *ch) readb(&ch->ch_cls_uart->msr); } -/* Turns off UART. */ - static void cls_uart_off(struct channel_t *ch) { writeb(0, &ch->ch_cls_uart->ier); } /* - * cls_get_uarts_bytes_left. - * Returns 0 is nothing left in the FIFO, returns 1 otherwise. - * * The channel lock MUST be held by the calling function. + * Returns 0 is nothing left in the FIFO, returns 1 otherwise. */ static uint cls_get_uart_bytes_left(struct channel_t *ch) { unsigned char left = 0; unsigned char lsr = 0; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return 0; lsr = readb(&ch->ch_cls_uart->lsr); @@ -1141,20 +1073,16 @@ static uint cls_get_uart_bytes_left(struct channel_t *ch) } /* - * cls_send_break. * Starts sending a break thru the UART. - * * The channel lock MUST be held by the calling function. */ static void cls_send_break(struct channel_t *ch, int msecs) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; /* 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) { unsigned char temp = readb(&ch->ch_cls_uart->lcr); @@ -1182,7 +1110,6 @@ static void cls_send_break(struct channel_t *ch, int msecs) } /* - * cls_send_immediate_char. * Sends a specific character as soon as possible to the UART, * jumping over any bytes that might be in the write queue. * @@ -1190,7 +1117,7 @@ static void cls_send_break(struct channel_t *ch, int msecs) */ static void cls_send_immediate_char(struct channel_t *ch, unsigned char c) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; writeb(c, &ch->ch_cls_uart->txrx); @@ -1203,8 +1130,6 @@ static void cls_vpd(struct dgnc_board *brd) int i = 0; vpdbase = pci_resource_start(brd->pdev, 3); - - /* No VPD */ if (!vpdbase) return; @@ -1213,7 +1138,6 @@ static void cls_vpd(struct dgnc_board *brd) if (!re_map_vpdbase) return; - /* Store the VPD into our buffer */ for (i = 0; i < 0x40; i++) { brd->vpd[i] = readb(re_map_vpdbase + i); pr_info("%x ", brd->vpd[i]); diff --git a/drivers/staging/dgnc/dgnc_cls.h b/drivers/staging/dgnc/dgnc_cls.h index 463ad30..9dfa968 100644 --- a/drivers/staging/dgnc/dgnc_cls.h +++ b/drivers/staging/dgnc/dgnc_cls.h @@ -13,27 +13,24 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DGNC_CLS_H -#define __DGNC_CLS_H +#ifndef _DGNC_CLS_H +#define _DGNC_CLS_H -/************************************************************************ - * Per channel/port Classic UART structure * - ************************************************************************ - * Base Structure Entries Usage Meanings to Host * - * * - * W = read write R = read only * - * U = Unused. * - ************************************************************************/ - -/* - * txrx : WR RHR/THR - Holding reg - * ier : WR IER - Interrupt Enable Reg - * isr_fcr : WR ISR/FCR - Interrupt Status Reg/Fifo Control Reg - * lcr : WR LCR - Line Control Reg - * mcr : WR MCR - Modem Control Reg - * lsr : WR LSR - Line Status Reg - * msr : WR MSG - Modem Status Reg - * spr : WR SPR - Scratch pad Reg +/** + * struct cls_uart_struct - Per channel/port Classic UART. + * + * key - W = read write + * - R = read only + * - U = unused + * + * @txrx: (WR) Holding Register. + * @ier: (WR) Interrupt Enable Register. + * @isr_fcr: (WR) Interrupt Status Register/Fifo Control Register. + * @lcr: (WR) Line Control Register. + * @mcr: (WR) Modem Control Register. + * @lsr: (WR) Line Status Register. + * @msr: (WR) Modem Status Register. + * @spr: (WR) Scratch Pad Register. */ struct cls_uart_struct { u8 txrx; @@ -74,9 +71,6 @@ struct cls_uart_struct { #define UART_EXAR654_IER_RTSDTR 0x40 /* Output Interrupt Enable */ #define UART_EXAR654_IER_CTSDSR 0x80 /* Input Interrupt Enable */ -/* - * Our Global Variables - */ extern struct board_ops dgnc_cls_ops; -#endif +#endif /* _DGNC_CLS_H */ diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 5381dbd..253f38b 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -30,8 +30,6 @@ 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"); -/* File operations permitted on Control/Management major. */ - static const struct file_operations dgnc_board_fops = { .owner = THIS_MODULE, .unlocked_ioctl = dgnc_mgmt_ioctl, @@ -39,8 +37,6 @@ static const struct file_operations dgnc_board_fops = { .release = dgnc_mgmt_close }; -/* Globals */ - uint dgnc_num_boards; struct dgnc_board *dgnc_board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); @@ -48,12 +44,8 @@ DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ uint dgnc_major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ -/* Static vars. */ - static struct class *dgnc_class; -/* 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; @@ -95,23 +87,17 @@ static const struct board_id dgnc_ids[] = { }; /* 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 -ENOMEM; - return rc; + return 0; } -/* - * dgnc_found_board() - * - * A board has been found, init it. - */ + +/* A board has been found, initialize it. */ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) { struct dgnc_board *brd; @@ -119,13 +105,11 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) int i = 0; int rc = 0; - /* get the board structure and prep it */ brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) return ERR_PTR(-ENOMEM); /* store the info for the board we've found */ - brd->magic = DGNC_BOARD_MAGIC; brd->boardnum = dgnc_num_boards; brd->vendor = dgnc_pci_tbl[id].vendor; brd->device = dgnc_pci_tbl[id].device; @@ -170,7 +154,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) * 4 Memory Mapped UARTs and Status */ - /* get the PCI Base Address Registers */ brd->membase = pci_resource_start(pdev, 4); if (!brd->membase) { @@ -191,14 +174,12 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) brd->iobase_end = pci_resource_end(pdev, 1); brd->iobase = ((unsigned int)(brd->iobase)) & 0xFFFE; - /* Assign the board_ops struct */ brd->bd_ops = &dgnc_cls_ops; brd->bd_uart_offset = 0x8; brd->bd_dividend = 921600; rc = dgnc_do_remap(brd); - if (rc < 0) goto failed; @@ -237,7 +218,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) else brd->dpatype = T_NEO | T_PCIBUS; - /* get the PCI Base Address Registers */ brd->membase = pci_resource_start(pdev, 0); brd->membase_end = pci_resource_end(pdev, 0); @@ -246,7 +226,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) else brd->membase &= ~15; - /* Assign the board_ops struct */ brd->bd_ops = &dgnc_neo_ops; brd->bd_uart_offset = 0x200; @@ -272,7 +251,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) goto failed; } - /* init our poll helper tasklet */ tasklet_init(&brd->helper_tasklet, brd->bd_ops->tasklet, (unsigned long)brd); @@ -289,21 +267,18 @@ failed: static int dgnc_request_irq(struct dgnc_board *brd) { - int rc = 0; - if (brd->irq) { - rc = request_irq(brd->irq, brd->bd_ops->intr, + int rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "DGNC", brd); - if (rc) { dev_err(&brd->pdev->dev, "Failed to hook IRQ %d\n", brd->irq); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; - rc = -ENODEV; + return -ENODEV; } } - return rc; + return 0; } static void dgnc_free_irq(struct dgnc_board *brd) @@ -312,30 +287,12 @@ static void dgnc_free_irq(struct dgnc_board *brd) free_irq(brd->irq, brd); } -/* - * Function: - * - * dgnc_poll_handler - * - * Author: - * - * Scott H Kilau - * - * Parameters: - * - * dummy -- ignored - * - * Return Values: - * - * none - * - * Description: - * - * 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. - */ + /* + * 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) { struct dgnc_board *brd; @@ -343,19 +300,16 @@ static void dgnc_poll_handler(ulong dummy) int i; unsigned long new_time; - /* Go thru each board, kicking off a tasklet for each if needed */ for (i = 0; i < dgnc_num_boards; i++) { brd = dgnc_board[i]; spin_lock_irqsave(&brd->bd_lock, flags); - /* If board is in a failed state don't schedule a tasklet */ if (brd->state == BOARD_FAILED) { spin_unlock_irqrestore(&brd->bd_lock, flags); continue; } - /* Schedule a poll helper task */ tasklet_schedule(&brd->helper_tasklet); spin_unlock_irqrestore(&brd->bd_lock, flags); @@ -385,9 +339,7 @@ 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; @@ -395,8 +347,6 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 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); @@ -426,7 +376,6 @@ free_irq: dgnc_free_irq(brd); unregister_tty: dgnc_tty_unregister(brd); - failed: kfree(brd); @@ -439,24 +388,14 @@ static struct pci_driver dgnc_driver = { .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); @@ -495,19 +434,16 @@ 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 - */ +/* 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) + if (!brd) return; switch (brd->device) { @@ -534,7 +470,6 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) 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); @@ -574,42 +509,28 @@ static void cleanup(void) } } -/* - * 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; } diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index c8119f2..980410f 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -11,12 +11,10 @@ * 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. - * - * Driver includes */ -#ifndef __DGNC_DRIVER_H -#define __DGNC_DRIVER_H +#ifndef _DGNC_DRIVER_H +#define _DGNC_DRIVER_H #include <linux/types.h> #include <linux/tty.h> @@ -24,8 +22,6 @@ #include "digi.h" /* Digi specific ioctl header */ -/* Driver defines */ - /* Driver identification and error statements */ #define PROCSTR "dgnc" /* /proc entries */ #define DEVSTR "/dev/dg/dgnc" /* /dev entries */ @@ -39,11 +35,6 @@ #define MAXPORTS 8 #define MAXTTYNAMELEN 200 -/* Our 3 magic numbers for our board, channel and unit structs */ -#define DGNC_BOARD_MAGIC 0x5c6df104 -#define DGNC_CHANNEL_MAGIC 0x6c6df104 -#define DGNC_UNIT_MAGIC 0x7c6df104 - /* Serial port types */ #define DGNC_SERIAL 0 #define DGNC_PRINT 1 @@ -53,10 +44,7 @@ #define PORT_NUM(dev) ((dev) & 0x7f) #define IS_PRINT(dev) (((dev) & 0xff) >= 0x80) -/* - *MAX number of stop characters we will send - * when our read queue is getting full - */ +/* MAX number of stop characters sent when our read queue is getting full */ #define MAX_STOPS_SENT 5 /* 4 extra for alignment play space */ @@ -82,27 +70,24 @@ #endif /* 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. */ - enum { BOARD_FAILED = 0, BOARD_FOUND, BOARD_READY }; -/* Structures and closely related defines. */ - struct dgnc_board; struct channel_t; -/* Per board operations structure */ - +/** + * struct board_ops - Per board operations. + */ struct board_ops { void (*tasklet)(unsigned long data); irqreturn_t (*intr)(int irq, void *voidbrd); @@ -128,77 +113,107 @@ struct board_ops { #define BD_IS_PCI_EXPRESS 0x0001 /* Is a PCI Express board */ -/* Per-board information */ - +/** + * struct dgnc_board - Per board information. + * @boardnum: Board number (0 - 32). + * + * @type: Type of board. + * @name: Product name. + * @pdev: Pointer to the pci_dev structure. + * @bd_flags: Board flags. + * @vendor: PCI vendor ID. + * @device: PCI device ID. + * @subvendor: PCI subsystem vendor ID. + * @subdevice: PCI subsystem device ID. + * @rev: PCI revision ID. + * @pci_bus: PCI bus value. + * @pci_slot: PCI slot value. + * @maxports: Maximum ports this board can handle. + * @dvid: Board specific device ID. + * @vpd: VPD of this board, if found. + * @serial_num: Serial number of this board, if found in VPD. + * @bd_lock: Used to protect board. + * @bd_intr_lock: Protect poller tasklet and interrupt routine from each other. + * @state: State of the card. + * @state_wait: Queue to sleep on for state change. + * @helper_tasklet: Poll helper tasklet. + * @nasync: Number of ports on card. + * @irq: Interrupt request number. + * @membase: Start of base memory of the card. + * @membase_end: End of base memory of the card. + * @iobase: Start of IO base of the card. + * @iobase_end: End of IO base of the card. + * @bd_uart_offset: Space between each UART. + * @channels: array of pointers to our channels. + * @serial_driver: Pointer to the serial driver. + * @serial_name: Serial driver name. + * @print_dirver: Pointer to the print driver. + * @print_name: Print driver name. + * @dpatype: Board type as defined by DPA. + * @dpastatus: Board status as defined by DPA. + * @bd_dividend: Board/UART's specific dividend. + * @bd_ops: Pointer to board operations structure. + * @proc_entry_pointer: Proc/<board> entry + * @dgnc_board_table: Proc/<board> entry + */ struct dgnc_board { - int magic; /* Board Magic number. */ - int boardnum; /* Board number: 0-32 */ + int boardnum; - int type; /* Type of board */ - char *name; /* Product Name */ - struct pci_dev *pdev; /* Pointer to the pci_dev struct */ - unsigned long bd_flags; /* Board flags */ - u16 vendor; /* PCI vendor ID */ - u16 device; /* PCI device ID */ - u16 subvendor; /* PCI subsystem vendor ID */ - u16 subdevice; /* PCI subsystem device ID */ - unsigned char rev; /* PCI revision ID */ - uint pci_bus; /* PCI bus value */ - uint pci_slot; /* PCI slot value */ - uint maxports; /* MAX ports this board can handle */ - unsigned char dvid; /* Board specific device id */ - unsigned char vpd[128]; /* VPD of board, if found */ - unsigned char serial_num[20]; /* Serial number of board, - * if found in VPD - */ + int type; + char *name; + struct pci_dev *pdev; + unsigned long bd_flags; + u16 vendor; + u16 device; + u16 subvendor; + u16 subdevice; + unsigned char rev; + uint pci_bus; + uint pci_slot; + uint maxports; + unsigned char dvid; + unsigned char vpd[128]; + unsigned char serial_num[20]; - spinlock_t bd_lock; /* Used to protect board */ + /* used to protect the board */ + spinlock_t bd_lock; - spinlock_t bd_intr_lock; /* Used to protect the poller tasklet - * and the interrupt routine from each - * other. - */ + /* Protect poller tasklet and interrupt routine from each other. */ + spinlock_t bd_intr_lock; - uint state; /* State of card. */ - wait_queue_head_t state_wait; /* Place to sleep on for state change */ + uint state; + wait_queue_head_t state_wait; - struct tasklet_struct helper_tasklet; /* Poll helper tasklet */ + struct tasklet_struct helper_tasklet; - uint nasync; /* Number of ports on card */ + uint nasync; - uint irq; /* Interrupt request number */ + uint irq; - ulong membase; /* Start of base memory of the card */ - ulong membase_end; /* End of base memory of the card */ + ulong membase; + ulong membase_end; - u8 __iomem *re_map_membase; /* Remapped memory of the card */ + u8 __iomem *re_map_membase; - ulong iobase; /* Start of io base of the card */ - ulong iobase_end; /* End of io base of the card */ + ulong iobase; + ulong iobase_end; - uint bd_uart_offset; /* Space between each UART */ + uint bd_uart_offset; - struct channel_t *channels[MAXPORTS]; /* array of pointers - * to our channels. - */ + struct channel_t *channels[MAXPORTS]; struct tty_driver *serial_driver; char serial_name[200]; struct tty_driver *print_driver; char print_name[200]; - u16 dpatype; /* The board "type", - * as defined by DPA - */ - u16 dpastatus; /* The board "status", - * as defined by DPA - */ + u16 dpatype; + u16 dpastatus; - uint bd_dividend; /* Board/UARTs specific dividend */ + uint bd_dividend; struct board_ops *bd_ops; - /* /proc/<board> entries */ struct proc_dir_entry *proc_entry_pointer; struct dgnc_proc_entry *dgnc_board_table; @@ -221,17 +236,23 @@ struct dgnc_board { struct device; -/* Structure for terminal or printer unit. */ +/** + * struct un_t - terminal or printer unit + * @un_open_count: Counter of opens to port. + * @un_tty: Pointer to unit tty structure. + * @un_flags: Unit flags. + * @un_flags_wait: Place to sleep to wait on unit. + * @un_dev: Minor device number. + */ struct un_t { - 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 */ - wait_queue_head_t un_flags_wait; /* Place to sleep to wait on unit */ - uint un_dev; /* Minor device number */ + uint un_open_count; + struct tty_struct *un_tty; + uint un_flags; + wait_queue_head_t un_flags_wait; + uint un_dev; struct device *un_sysfs; }; @@ -263,102 +284,137 @@ struct un_t { #define EQUEUESIZE RQUEUESIZE #define WQUEUESIZE (WQUEUEMASK + 1) -/* Channel information structure. */ +/** + * struct channel_t - Channel information. + * @dgnc_board: Pointer to board structure. + * @ch_bd: Transparent print structure. + * @ch_tun: Terminal unit information. + * @ch_pun: Printer unit information. + * @ch_lock: Provide for serialization. + * @ch_flags_wait: Channel flags wait queue. + * @ch_portnum: Port number, 0 offset. + * @ch_open_count: Open count. + * @ch_flags: Channel flags. + * @ch_close_delay: How long we should drop RTS/DTR for. + * @ch_cpstime: Time for CPS calculations. + * @ch_c_iflag: Channel iflags. + * @ch_c_cflag: Channel cflags. + * @ch_c_oflag: Channel oflags. + * @ch_c_lflag: Channel lflags. + * @ch_stopc: Stop character. + * @ch_startc: Start character. + * @ch_old_baud: Cache of the current baud rate. + * @ch_custom_speed: Custom baud rate, if set. + * @ch_wopen: Waiting for open process count. + * @ch_mostat: FEP output modem status. + * @ch_mistat: FEP input modem status. + * @chc_neo_uart: Pointer to the mapped neo UART struct + * @ch_cls_uart: Pointer to the mapped cls UART struct + * @ch_cached_lsr: Cached value of the LSR register. + * @ch_rqueue: Read queue buffer, malloc'ed. + * @ch_r_head: Head location of the read queue. + * @ch_r_tail: Tail location of the read queue. + * @ch_equeue: Error queue buffer, malloc'ed. + * @ch_e_head: Head location of the error queue. + * @ch_e_tail: Tail location of the error queue. + * @ch_wqueue: Write queue buffer, malloc'ed. + * @ch_w_head: Head location of the write queue. + * @ch_w_tail: Tail location of the write queue. + * @ch_rxcount: Total of data received so far. + * @ch_txcount: Total of data transmitted so far. + * @ch_r_tlevel: Receive trigger level. + * @ch_t_tlevel: Transmit trigger level. + * @ch_r_watermark: Receive water mark. + * @ch_stop_sending_break: Time we should STOP sending a break. + * @ch_stops_sent: How many times I have send a stop character to try + * to stop the other guy sending. + * @ch_err_parity: Count of parity + * @ch_err_frame: Count of framing errors on channel. + * @ch_err_break: Count of breaks on channel. + * @ch_err_overrun: Count of overruns on channel. + * @ch_xon_sends: Count of xons transmitted. + * @ch_xoff_sends: Count of xoffs transmitted. + * @proc_entry_pointer: Proc/<board>/<channel> entry. + * @dgnc_channel_table: Proc/<board>/<channel> entry. + */ struct channel_t { - 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 dgnc_board *ch_bd; + struct digi_t ch_digi; + struct un_t ch_tun; + struct un_t ch_pun; - spinlock_t ch_lock; /* provide for serialization */ + 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; + uint ch_open_count; + uint ch_flags; - ulong ch_close_delay; /* How long we should - * drop RTS/DTR for - */ + ulong ch_close_delay; - ulong ch_cpstime; /* Time for CPS calculations */ + ulong ch_cpstime; - 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; + tcflag_t ch_c_cflag; + tcflag_t ch_c_oflag; + tcflag_t ch_c_lflag; + unsigned char ch_stopc; + unsigned char ch_startc; - uint ch_old_baud; /* Cache of the current baud */ - uint ch_custom_speed;/* Custom baud, if set */ + uint ch_old_baud; + uint ch_custom_speed; - uint ch_wopen; /* Waiting for open process cnt */ + uint ch_wopen; - unsigned char ch_mostat; /* FEP output modem status */ - unsigned char ch_mistat; /* FEP input modem status */ + unsigned char ch_mostat; + unsigned char ch_mistat; - struct neo_uart_struct __iomem *ch_neo_uart; /* Pointer to the - * "mapped" UART struct - */ - struct cls_uart_struct __iomem *ch_cls_uart; /* Pointer to the - * "mapped" UART struct - */ + struct neo_uart_struct __iomem *ch_neo_uart; + struct cls_uart_struct __iomem *ch_cls_uart; - unsigned char ch_cached_lsr; /* Cached value of the LSR register */ + unsigned char ch_cached_lsr; - unsigned char *ch_rqueue; /* Our read queue buffer - malloc'ed */ - ushort ch_r_head; /* Head location of the read queue */ - ushort ch_r_tail; /* Tail location of the read queue */ + unsigned char *ch_rqueue; + ushort ch_r_head; + ushort ch_r_tail; - unsigned char *ch_equeue; /* Our error queue buffer - malloc'ed */ - ushort ch_e_head; /* Head location of the error queue */ - ushort ch_e_tail; /* Tail location of the error queue */ + unsigned char *ch_equeue; + ushort ch_e_head; + ushort ch_e_tail; - unsigned char *ch_wqueue; /* Our write queue buffer - malloc'ed */ - ushort ch_w_head; /* Head location of the write queue */ - ushort ch_w_tail; /* Tail location of the write queue */ + unsigned char *ch_wqueue; + ushort ch_w_head; + ushort ch_w_tail; - ulong ch_rxcount; /* total of data received so far */ - ulong ch_txcount; /* total of data transmitted so far */ + ulong ch_rxcount; + ulong ch_txcount; - unsigned char ch_r_tlevel; /* Receive Trigger level */ - unsigned char ch_t_tlevel; /* Transmit Trigger level */ + unsigned char ch_r_tlevel; + unsigned char ch_t_tlevel; - unsigned char ch_r_watermark; /* Receive Watermark */ + unsigned char ch_r_watermark; - ulong ch_stop_sending_break; /* Time we should STOP - * sending a break - */ + ulong ch_stop_sending_break; + uint ch_stops_sent; - uint ch_stops_sent; /* How many times I have sent a stop - * character to try to stop the other - * guy sending. - */ - ulong ch_err_parity; /* Count of parity errors on channel */ - ulong ch_err_frame; /* Count of framing errors on channel */ - ulong ch_err_break; /* Count of breaks on channel */ - ulong ch_err_overrun; /* Count of overruns on channel */ + ulong ch_err_parity; + ulong ch_err_frame; + ulong ch_err_break; + ulong ch_err_overrun; - ulong ch_xon_sends; /* Count of xons transmitted */ - ulong ch_xoff_sends; /* Count of xoffs transmitted */ + ulong ch_xon_sends; + ulong ch_xoff_sends; - /* /proc/<board>/<channel> entries */ struct proc_dir_entry *proc_entry_pointer; struct dgnc_proc_entry *dgnc_channel_table; }; -/* 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 boards */ -#endif +#endif /* _DGNC_DRIVER_H */ diff --git a/drivers/staging/dgnc/dgnc_mgmt.c b/drivers/staging/dgnc/dgnc_mgmt.c index 9d9b15d..3ca473b4 100644 --- a/drivers/staging/dgnc/dgnc_mgmt.c +++ b/drivers/staging/dgnc/dgnc_mgmt.c @@ -20,11 +20,11 @@ #include <linux/kernel.h> #include <linux/ctype.h> -#include <linux/sched.h> /* For jiffies, task states */ -#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */ +#include <linux/sched.h> +#include <linux/interrupt.h> #include <linux/serial_reg.h> #include <linux/termios.h> -#include <linux/uaccess.h> /* For copy_from_user/copy_to_user */ +#include <linux/uaccess.h> #include "dgnc_driver.h" #include "dgnc_pci.h" @@ -33,64 +33,60 @@ /* Our "in use" variables, to enforce 1 open only */ static int dgnc_mgmt_in_use[MAXMGMTDEVICES]; -/* - * dgnc_mgmt_open() - * - * Open the mgmt/downld/dpa device +/** + * dgnc_mgmt_open() - Open the mgmt/downld/dpa device. */ int dgnc_mgmt_open(struct inode *inode, struct file *file) { unsigned long flags; unsigned int minor = iminor(inode); + int rc = 0; spin_lock_irqsave(&dgnc_global_lock, flags); - /* mgmt device */ - if (minor < MAXMGMTDEVICES) { - /* Only allow 1 open at a time on mgmt device */ - if (dgnc_mgmt_in_use[minor]) { - spin_unlock_irqrestore(&dgnc_global_lock, flags); - return -EBUSY; - } - dgnc_mgmt_in_use[minor]++; - } else { - spin_unlock_irqrestore(&dgnc_global_lock, flags); - return -ENXIO; + if (minor >= MAXMGMTDEVICES) { + rc = -ENXIO; + goto out; } + /* Only allow 1 open at a time on mgmt device */ + if (dgnc_mgmt_in_use[minor]) { + rc = -EBUSY; + goto out; + } + dgnc_mgmt_in_use[minor]++; +out: spin_unlock_irqrestore(&dgnc_global_lock, flags); - return 0; + return rc; } -/* - * dgnc_mgmt_close() - * - * Open the mgmt/dpa device +/** + * dgnc_mgmt_close() - Close the mgmt/dpa device */ int dgnc_mgmt_close(struct inode *inode, struct file *file) { unsigned long flags; unsigned int minor = iminor(inode); + int rc = 0; spin_lock_irqsave(&dgnc_global_lock, flags); - /* mgmt device */ - if (minor < MAXMGMTDEVICES) { - if (dgnc_mgmt_in_use[minor]) - dgnc_mgmt_in_use[minor] = 0; + if (minor >= MAXMGMTDEVICES) { + rc = -ENXIO; + goto out; } + dgnc_mgmt_in_use[minor] = 0; + +out: spin_unlock_irqrestore(&dgnc_global_lock, flags); - return 0; + return rc; } -/* - * dgnc_mgmt_ioctl() - * - * ioctl the mgmt/dpa device +/** + * dgnc_mgmt_ioctl() - Ioctl the mgmt/dpa device. */ - long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; @@ -171,17 +167,15 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) board = ni.board; channel = ni.channel; - /* Verify boundaries on board */ if (board >= dgnc_num_boards) return -ENODEV; - /* Verify boundaries on channel */ if (channel >= dgnc_board[board]->nasync) return -ENODEV; ch = dgnc_board[board]->channels[channel]; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -ENODEV; memset(&ni, 0, sizeof(ni)); @@ -250,6 +244,5 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } } - return 0; } diff --git a/drivers/staging/dgnc/dgnc_mgmt.h b/drivers/staging/dgnc/dgnc_mgmt.h index 708abe9..a7a5770 100644 --- a/drivers/staging/dgnc/dgnc_mgmt.h +++ b/drivers/staging/dgnc/dgnc_mgmt.h @@ -13,13 +13,14 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DGNC_MGMT_H -#define __DGNC_MGMT_H +#ifndef _DGNC_MGMT_H +#define _DGNC_MGMT_H #define MAXMGMTDEVICES 8 int dgnc_mgmt_open(struct inode *inode, struct file *file); int dgnc_mgmt_close(struct inode *inode, struct file *file); long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -#endif + +#endif /* _DGNC_MGMT_H */ diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 3eefefe..1943e66 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -14,15 +14,15 @@ */ #include <linux/kernel.h> -#include <linux/sched.h> /* For jiffies, task states */ -#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */ -#include <linux/delay.h> /* For udelay */ -#include <linux/io.h> /* For read[bwl]/write[bwl] */ -#include <linux/serial.h> /* For struct async_serial */ -#include <linux/serial_reg.h> /* For the various UART offsets */ - -#include "dgnc_driver.h" /* Driver main header file */ -#include "dgnc_neo.h" /* Our header file */ +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/serial.h> +#include <linux/serial_reg.h> + +#include "dgnc_driver.h" +#include "dgnc_neo.h" #include "dgnc_tty.h" static inline void neo_parse_lsr(struct dgnc_board *brd, uint port); @@ -96,12 +96,7 @@ static inline void neo_set_cts_flow_control(struct channel_t *ch) unsigned char efr = readb(&ch->ch_neo_uart->efr); /* Turn on auto CTS flow control */ -#if 1 ier |= UART_17158_IER_CTSDSR; -#else - ier &= ~(UART_17158_IER_CTSDSR); -#endif - efr |= (UART_17158_EFR_ECB | UART_17158_EFR_CTSDSR); /* Turn off auto Xon flow control */ @@ -135,11 +130,7 @@ static inline void neo_set_rts_flow_control(struct channel_t *ch) unsigned char efr = readb(&ch->ch_neo_uart->efr); /* Turn on auto RTS flow control */ -#if 1 ier |= UART_17158_IER_RTSDTR; -#else - ier &= ~(UART_17158_IER_RTSDTR); -#endif efr |= (UART_17158_EFR_ECB | UART_17158_EFR_RTSDTR); /* Turn off auto Xoff flow control */ @@ -358,20 +349,17 @@ static inline void neo_set_new_start_stop_chars(struct channel_t *ch) } /* 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; spin_lock_irqsave(&ch->ch_lock, flags); - /* Bail if we aren't currently sending a break. */ if (!ch->ch_stop_sending_break) { spin_unlock_irqrestore(&ch->ch_lock, flags); return; } - /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { if (force || time_after_eq(jiffies, ch->ch_stop_sending_break)) { @@ -387,7 +375,6 @@ static inline void neo_clear_break(struct channel_t *ch, int force) } /* Parse the ISR register. */ - static inline void neo_parse_isr(struct dgnc_board *brd, uint port) { struct channel_t *ch; @@ -396,14 +383,13 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) unsigned long flags; ch = brd->channels[port]; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; /* Here we try to figure out what caused the interrupt to happen */ while (1) { isr = readb(&ch->ch_neo_uart->isr_fcr); - /* Bail if no pending interrupt */ if (isr & UART_IIR_NO_INT) break; @@ -426,7 +412,6 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) } if (isr & UART_IIR_THRI) { - /* Transfer data (if any) from Write Queue -> UART. */ spin_lock_irqsave(&ch->ch_lock, flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -442,10 +427,7 @@ 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, - * resume it - */ + /* resume output if stopped */ if (brd->channels[port]->ch_flags & CH_STOP) { spin_lock_irqsave(&ch->ch_lock, flags); @@ -504,7 +486,6 @@ static inline void neo_parse_isr(struct dgnc_board *brd, uint port) } } - /* Parse any modem signal changes */ neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); } } @@ -515,18 +496,14 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) int linestatus; unsigned long flags; - /* - * Check to make sure it didn't receive interrupt with a null board - * associated or a board pointer that wasn't ours. - */ - if (!brd || brd->magic != DGNC_BOARD_MAGIC) + if (!brd) return; if (port >= brd->maxports) return; ch = brd->channels[port]; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; linestatus = readb(&ch->ch_neo_uart->lsr); @@ -534,7 +511,6 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) ch->ch_cached_lsr |= linestatus; if (ch->ch_cached_lsr & UART_LSR_DR) { - /* Read data from uart -> queue */ neo_copy_data_from_uart_to_queue(ch); spin_lock_irqsave(&ch->ch_lock, flags); dgnc_check_queue_flow_control(ch); @@ -571,22 +547,17 @@ static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, flags); - /* Transfer data (if any) from Write Queue -> UART. */ neo_copy_data_from_queue_to_uart(ch); } else if (linestatus & UART_17158_TX_AND_FIFO_CLR) { spin_lock_irqsave(&ch->ch_lock, flags); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); spin_unlock_irqrestore(&ch->ch_lock, flags); - /* Transfer data (if any) from Write Queue -> UART. */ neo_copy_data_from_queue_to_uart(ch); } } -/* - * neo_param() - * Send any/all changes to the line to the UART. - */ +/* Send any/all changes to the line to the UART. */ static void neo_param(struct tty_struct *tty) { unsigned char lcr = 0; @@ -599,23 +570,22 @@ static void neo_param(struct tty_struct *tty) struct channel_t *ch; struct un_t *un; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = (struct un_t *)tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; /* 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; @@ -724,10 +694,6 @@ static void neo_param(struct tty_struct *tty) if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; - /* - * Not all platforms support mark/space parity, - * so this will hide behind an ifdef. - */ #ifdef CMSPAR if (ch->ch_c_cflag & CMSPAR) lcr |= UART_LCR_SPAR; @@ -796,16 +762,11 @@ static void neo_param(struct tty_struct *tty) if (ier != uart_ier) writeb(ier, &ch->ch_neo_uart->ier); - /* Set new start/stop chars */ neo_set_new_start_stop_chars(ch); 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 - * disable flow control - */ if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) neo_set_no_output_flow_control(ch); @@ -818,10 +779,6 @@ 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 - * disable flow control - */ if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) neo_set_no_input_flow_control(ch); @@ -843,12 +800,10 @@ static void neo_param(struct tty_struct *tty) neo_assert_modem_signals(ch); - /* Get current status of the modem signals now */ neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); } -/* Our board poller function. */ - +/* Board poller function. */ static void neo_tasklet(unsigned long data) { struct dgnc_board *bd = (struct dgnc_board *)data; @@ -858,10 +813,9 @@ static void neo_tasklet(unsigned long data) int state = 0; int ports = 0; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; - /* Cache a couple board values */ spin_lock_irqsave(&bd->bd_lock, flags); state = bd->state; ports = bd->nasync; @@ -873,15 +827,10 @@ 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 ((state == BOARD_READY) && (ports > 0)) { - /* Loop on each port */ for (i = 0; i < ports; i++) { ch = bd->channels[i]; - - /* Just being careful... */ - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) continue; /* @@ -903,10 +852,6 @@ static void neo_tasklet(unsigned long data) neo_copy_data_from_queue_to_uart(ch); dgnc_wakeup_writes(ch); - /* - * Call carrier carrier function, in case something - * has changed. - */ dgnc_carrier(ch); /* @@ -918,15 +863,10 @@ static void neo_tasklet(unsigned long data) } } - /* Allow interrupt routine to access the interrupt register again */ spin_unlock_irqrestore(&bd->bd_intr_lock, flags); } -/* - * dgnc_neo_intr() - * - * Neo specific interrupt handler. - */ +/* Neo specific interrupt handler. */ static irqreturn_t neo_intr(int irq, void *voidbrd) { struct dgnc_board *brd = voidbrd; @@ -937,11 +877,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) unsigned long flags; unsigned long flags2; - /* - * Check to make sure it didn't receive interrupt with a null board - * associated or a board pointer that wasn't ours. - */ - if (!brd || brd->magic != DGNC_BOARD_MAGIC) + if (!brd) return IRQ_NONE; /* Lock out the slow poller from running on this board. */ @@ -964,19 +900,12 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) return IRQ_NONE; } - /* - * At this point, we have at least SOMETHING to service, dig - * further... - */ - - /* Loop on each port */ while ((uart_poll & 0xff) != 0) { type = uart_poll >> (8 + (port * 3)); type &= 0x7; uart_poll &= ~(0x01 << port); - /* Switch on type of interrupt we have */ switch (type) { case UART_17158_RXRDY_TIMEOUT: /* @@ -984,7 +913,6 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) * RX FIFO until it falls below the trigger level. */ - /* Verify the port is in range. */ if (port >= brd->nasync) break; @@ -1027,27 +955,17 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) break; case UART_17158_MSR: - /* MSR or flow control was seen. */ - neo_parse_isr(brd, port); break; default: - /* - * The UART triggered us with a bogus interrupt type. - * It appears the Exar chip, when REALLY bogged down, - * will throw these once and awhile. - * Its harmless, just ignore it and move on. - */ break; } port++; } - /* Schedule tasklet to more in-depth servicing at a better time. */ - tasklet_schedule(&brd->helper_tasklet); spin_unlock_irqrestore(&brd->bd_intr_lock, flags); @@ -1094,32 +1012,23 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) ushort tail; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* cache head and tail of queue */ head = ch->ch_r_head & RQUEUEMASK; tail = ch->ch_r_tail & RQUEUEMASK; - /* Get our cached LSR */ linestatus = ch->ch_cached_lsr; ch->ch_cached_lsr = 0; - /* Store how much space we have left in the queue */ qleft = tail - head - 1; if (qleft < 0) qleft += RQUEUEMASK + 1; - /* - * If the UART is not in FIFO mode, force the FIFO copy to - * NOT be run, by setting total to 0. - * - * On the other hand, if the UART IS in FIFO mode, then ask - * the UART to give us an approximation of data it has RX'ed. - */ if (!(ch->ch_flags & CH_FIFO_ENABLED)) { + /* force the FIFO copy to NOT be run */ total = 0; } else { total = readb(&ch->ch_neo_uart->rfifo); @@ -1138,26 +1047,11 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) total -= 3; } - /* - * Finally, bound the copy to make sure we don't overflow - * our own queue... - * The byte by byte copy loop below this loop this will - * deal with the queue overflow possibility. - */ total = min(total, qleft); while (total > 0) { - /* - * Grab the linestatus register, we need to check - * to see if there are any errors in the FIFO. - */ linestatus = readb(&ch->ch_neo_uart->lsr); - /* - * Break out if there is a FIFO error somewhere. - * This will allow us to go byte by byte down below, - * finding the exact location of the error. - */ if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) break; @@ -1182,7 +1076,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) linestatus = 0; - /* Copy data from uart to the queue */ memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, n); @@ -1193,7 +1086,6 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) */ memset(ch->ch_equeue + head, 0, n); - /* Add to and flip head if needed */ head = (head + n) & RQUEUEMASK; total -= n; qleft -= n; @@ -1242,8 +1134,6 @@ 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. */ - if (linestatus & error_mask) { unsigned char discard; @@ -1253,13 +1143,10 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) } /* - * If our queue is full, we have no choice but to drop some - * data. - * The assumption is that HWFLOW or SWFLOW should have stopped - * things way way before we got to this point. - * - * I decided that I wanted to ditch the oldest data first, - * I hope thats okay with everyone? Yes? Good. + * If our queue is full, we have no choice but to drop + * some data. The assumption is that HWFLOW or SWFLOW + * should have stopped things way way before we got to + * this point. */ while (qleft < 1) { tail = (tail + 1) & RQUEUEMASK; @@ -1272,18 +1159,14 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) &ch->ch_neo_uart->txrxburst, 1); ch->ch_equeue[head] = (unsigned char)linestatus; - /* Ditch any remaining linestatus value. */ linestatus = 0; - /* Add to and flip head if needed */ head = (head + 1) & RQUEUEMASK; qleft--; ch->ch_rxcount++; } - /* Write new final heads to channel structure. */ - ch->ch_r_head = head & RQUEUEMASK; ch->ch_e_head = head & EQUEUEMASK; @@ -1301,25 +1184,21 @@ static int neo_drain(struct tty_struct *tty, uint seconds) struct un_t *un; int rc = 0; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return -ENXIO; un = (struct un_t *)tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return -ENXIO; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -ENXIO; spin_lock_irqsave(&ch->ch_lock, flags); un->un_flags |= UN_EMPTY; spin_unlock_irqrestore(&ch->ch_lock, flags); - /* - * Go to sleep waiting for the tty layer to wake me back up when - * the empty flag goes away. - */ rc = wait_event_interruptible_timeout(un->un_flags_wait, ((un->un_flags & UN_EMPTY) == 0), msecs_to_jiffies(seconds * 1000)); @@ -1330,15 +1209,14 @@ static int neo_drain(struct tty_struct *tty, uint seconds) /* * Flush the WRITE FIFO on the Neo. - * - * NOTE: Channel lock MUST be held before calling this function! + * Channel lock MUST be held before calling this function! */ static void neo_flush_uart_write(struct channel_t *ch) { unsigned char tmp = 0; int i = 0; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), @@ -1347,7 +1225,7 @@ static void neo_flush_uart_write(struct channel_t *ch) for (i = 0; i < 10; i++) { /* - * Check to see if the UART feels it completely flushed the + * Check to see if the UART completely flushed the FIFO * FIFO. */ tmp = readb(&ch->ch_neo_uart->isr_fcr); @@ -1362,15 +1240,14 @@ static void neo_flush_uart_write(struct channel_t *ch) /* * Flush the READ FIFO on the Neo. - * - * NOTE: Channel lock MUST be held before calling this function! + * Channel lock MUST be held before calling this function! */ static void neo_flush_uart_read(struct channel_t *ch) { unsigned char tmp = 0; int i = 0; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR, @@ -1400,12 +1277,11 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) uint len_written = 0; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* No data to write to the UART */ if (ch->ch_w_tail == ch->ch_w_head) goto exit_unlock; @@ -1414,12 +1290,10 @@ 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 (!(ch->ch_flags & CH_FIFO_ENABLED)) { + /* Send data directly to txrx register */ unsigned char lsrbits = readb(&ch->ch_neo_uart->lsr); - /* Cache the LSR bits for later parsing */ ch->ch_cached_lsr |= lsrbits; if (ch->ch_cached_lsr & UART_LSR_THRE) { ch->ch_cached_lsr &= ~(UART_LSR_THRE); @@ -1477,12 +1351,10 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) n = UART_17158_TX_FIFOSIZE - readb(&ch->ch_neo_uart->tfifo); } - /* cache head and tail of queue */ head = ch->ch_w_head & WQUEUEMASK; tail = ch->ch_w_tail & WQUEUEMASK; qlen = (head - tail) & WQUEUEMASK; - /* Find minimum of the FIFO space, versus queue length */ n = min(n, qlen); while (n > 0) { @@ -1521,14 +1393,12 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); - /* Add and flip queue if needed */ tail = (tail + s) & WQUEUEMASK; n -= s; ch->ch_txcount += s; len_written += s; } - /* Update the final tail */ ch->ch_w_tail = tail & WQUEUEMASK; if (len_written > 0) { @@ -1544,7 +1414,7 @@ static void neo_parse_modem(struct channel_t *ch, unsigned char signals) { unsigned char msignals = signals; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; /* @@ -1572,10 +1442,7 @@ static void neo_parse_modem(struct channel_t *ch, unsigned char signals) } } - /* - * Scrub off lower bits. They signify delta's, which I don't care - * about - */ + /* Scrub off lower bits. They signify delta's */ msignals &= 0xf0; if (msignals & UART_MSR_DCD) @@ -1604,7 +1471,7 @@ static void neo_assert_modem_signals(struct channel_t *ch) { unsigned char out; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; out = ch->ch_mostat; @@ -1621,7 +1488,7 @@ static void neo_assert_modem_signals(struct channel_t *ch) static void neo_send_start_character(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; if (ch->ch_startc != _POSIX_VDISABLE) { @@ -1634,7 +1501,7 @@ static void neo_send_start_character(struct channel_t *ch) static void neo_send_stop_character(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; if (ch->ch_stopc != _POSIX_VDISABLE) { @@ -1668,7 +1535,6 @@ static void neo_uart_init(struct channel_t *ch) } /* Make the UART completely turn off. */ - static void neo_uart_off(struct channel_t *ch) { /* Turn off UART enhanced bits */ @@ -1735,8 +1601,6 @@ static void neo_send_break(struct channel_t *ch, int msecs) } /* - * neo_send_immediate_char. - * * Sends a specific character as soon as possible to the UART, * jumping over any bytes that might be in the write queue. * @@ -1744,7 +1608,7 @@ static void neo_send_break(struct channel_t *ch, int msecs) */ static void neo_send_immediate_char(struct channel_t *ch, unsigned char c) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; writeb(c, &ch->ch_neo_uart->txrx); @@ -1797,7 +1661,7 @@ static void neo_vpd(struct dgnc_board *brd) unsigned int i = 0; unsigned int a; - if (!brd || brd->magic != DGNC_BOARD_MAGIC) + if (!brd) return; if (!brd->re_map_membase) diff --git a/drivers/staging/dgnc/dgnc_neo.h b/drivers/staging/dgnc/dgnc_neo.h index 77ecd9b..c30a2c2 100644 --- a/drivers/staging/dgnc/dgnc_neo.h +++ b/drivers/staging/dgnc/dgnc_neo.h @@ -13,43 +13,62 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DGNC_NEO_H -#define __DGNC_NEO_H +#ifndef _DGNC_NEO_H +#define _DGNC_NEO_H #include "dgnc_driver.h" -/* - * Per channel/port NEO UART structure - * Base Structure Entries Usage Meanings to Host +/** + * struct neo_uart_struct - Per channel/port NEO UART structure + * + * key - W = read write + * - R = read only + * - U = unused * - * W = read write R = read only - * U = Unused. + * @txrx: (RW) Holding Register. + * @ier: (RW) Interrupt Enable Register. + * @isr_fcr: (RW) Interrupt Status Reg/Fifo Control Register. + * @lcr: (RW) Line Control Register. + * @mcr: (RW) Modem Control Register. + * @lsr: (RW) Line Status Register. + * @msr: (RW) Modem Status Register. + * @spr: (RW) Scratch Pad Register. + * @fctr: (RW) Feature Control Register. + * @efr: (RW) Enhanced Function Register. + * @tfifo: (RW) Transmit FIFO Register. + * @rfifo: (RW) Receive FIFO Register. + * @xoffchar1: (RW) XOff Character 1 Register. + * @xoffchar2: (RW) XOff Character 2 Register. + * @xonchar1: (RW) Xon Character 1 Register. + * @xonchar2: (RW) XOn Character 2 Register. + * @reserved1: (U) Reserved by Exar. + * @txrxburst: (RW) 64 bytes of RX/TX FIFO Data. + * @reserved2: (U) Reserved by Exar. + * @rxburst_with_errors: (R) bytes of RX FIFO Data + LSR. */ - struct neo_uart_struct { - 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 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 efr; /* WR EFR - Enhanced Function 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 reserved2[0x37f - 0x340]; /* U Reserved by Exar */ - u8 rxburst_with_errors[64]; /* R 64 bytes of RX FIFO Data + LSR */ + u8 txrx; + u8 ier; + u8 isr_fcr; + + u8 lcr; + u8 mcr; + u8 lsr; + u8 msr; + u8 spr; + u8 fctr; + u8 efr; + u8 tfifo; + u8 rfifo; + u8 xoffchar1; + u8 xoffchar2; + u8 xonchar1; + u8 xonchar2; + + u8 reserved1[0x2ff - 0x200]; + u8 txrxburst[64]; + u8 reserved2[0x37f - 0x340]; + u8 rxburst_with_errors[64]; }; /* Where to read the extended interrupt register (32bits instead of 8bits) */ @@ -151,8 +170,6 @@ struct neo_uart_struct { #define UART_17158_IER_RTSDTR 0x40 /* Output Interrupt Enable */ #define UART_17158_IER_CTSDSR 0x80 /* Input Interrupt Enable */ -/* Our Global Variables */ - extern struct board_ops dgnc_neo_ops; -#endif +#endif /* _DGNC_NEO_H */ diff --git a/drivers/staging/dgnc/dgnc_pci.h b/drivers/staging/dgnc/dgnc_pci.h index 4e170c4..5984591 100644 --- a/drivers/staging/dgnc/dgnc_pci.h +++ b/drivers/staging/dgnc/dgnc_pci.h @@ -13,10 +13,11 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DGNC_PCI_H -#define __DGNC_PCI_H +#ifndef _DGNC_PCI_H +#define _DGNC_PCI_H -#define PCIMAX 32 /* maximum number of PCI boards */ +/* Maximum number of PCI boards */ +#define PCIMAX 32 #define DIGI_VID 0x114F @@ -59,10 +60,10 @@ #define PCI_DEVICE_NEO_EXPRESS_8RJ45_PCI_NAME "Neo 8 PCI Express RJ45" #define PCI_DEVICE_NEO_EXPRESS_4_IBM_PCI_NAME "Neo 4 PCI Express IBM" -/* Size of Memory and I/O for PCI (4 K) */ +/* Size of memory and I/O for PCI (4 K) */ #define PCI_RAM_SIZE 0x1000 -/* Size of Memory (2MB) */ +/* Size of memory (2MB) */ #define PCI_MEM_SIZE 0x1000 -#endif +#endif /* _DGNC_PCI_H */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index c3b8fc5..9e98781 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -58,16 +58,15 @@ static const 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 default_termios = { - .c_iflag = (DEFAULT_IFLAGS), /* iflags */ - .c_oflag = (DEFAULT_OFLAGS), /* oflags */ - .c_cflag = (DEFAULT_CFLAGS), /* cflags */ - .c_lflag = (DEFAULT_LFLAGS), /* lflags */ +static const struct ktermios default_termios = { + .c_iflag = (DEFAULT_IFLAGS), + .c_oflag = (DEFAULT_OFLAGS), + .c_cflag = (DEFAULT_CFLAGS), + .c_lflag = (DEFAULT_LFLAGS), .c_cc = INIT_C_CC, .c_line = 0, }; -/* Our function prototypes */ static int dgnc_tty_open(struct tty_struct *tty, struct file *file); static void dgnc_tty_close(struct tty_struct *tty, struct file *file); static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, @@ -130,10 +129,8 @@ static const struct tty_operations dgnc_tty_ops = { /* TTY Initialization/Cleanup Functions */ -/* - * dgnc_tty_register() - * - * Init the tty subsystem for this board. +/** + * dgnc_tty_register() - Init the tty subsystem for this board. */ int dgnc_tty_register(struct dgnc_board *brd) { @@ -143,7 +140,6 @@ int dgnc_tty_register(struct dgnc_board *brd) TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); - if (IS_ERR(brd->serial_driver)) return PTR_ERR(brd->serial_driver); @@ -181,7 +177,6 @@ int dgnc_tty_register(struct dgnc_board *brd) TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); - if (IS_ERR(brd->print_driver)) { rc = PTR_ERR(brd->print_driver); goto unregister_serial_driver; @@ -232,15 +227,15 @@ void dgnc_tty_unregister(struct dgnc_board *brd) put_tty_driver(brd->serial_driver); } -/* - * dgnc_tty_init() +/** + * dgnc_tty_init() - Initialize the tty subsystem. * - * Init the tty subsystem. Called once per board after board has been - * downloaded and init'ed. + * Called once per board after board has been downloaded and initialized. */ int dgnc_tty_init(struct dgnc_board *brd) { int i; + int rc; void __iomem *vaddr; struct channel_t *ch; @@ -254,14 +249,12 @@ int dgnc_tty_init(struct dgnc_board *brd) brd->nasync = brd->maxports; for (i = 0; i < brd->nasync; i++) { - /* - * Okay to malloc with GFP_KERNEL, we are not at - * interrupt context, and there are no locks held. - */ brd->channels[i] = kzalloc(sizeof(*brd->channels[i]), GFP_KERNEL); - if (!brd->channels[i]) + if (!brd->channels[i]) { + rc = -ENOMEM; goto err_free_channels; + } } ch = brd->channels[0]; @@ -271,14 +264,10 @@ int dgnc_tty_init(struct dgnc_board *brd) for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) { spin_lock_init(&ch->ch_lock); - /* Store all our magic numbers */ - ch->magic = DGNC_CHANNEL_MAGIC; - ch->ch_tun.magic = DGNC_UNIT_MAGIC; ch->ch_tun.un_ch = ch; ch->ch_tun.un_type = DGNC_SERIAL; ch->ch_tun.un_dev = i; - ch->ch_pun.magic = DGNC_UNIT_MAGIC; ch->ch_pun.un_ch = ch; ch->ch_pun.un_type = DGNC_PRINT; ch->ch_pun.un_dev = i + 128; @@ -319,11 +308,12 @@ err_free_channels: kfree(brd->channels[i]); brd->channels[i] = NULL; } - return -ENOMEM; + + return rc; } -/* - * dgnc_cleanup_tty() +/** + * dgnc_cleanup_tty() - Cleanup driver. * * Uninitialize the TTY portion of this driver. Free all memory and * resources. @@ -346,19 +336,18 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) put_tty_driver(brd->print_driver); } -/* - * dgnc_wmove - Write data to transmit queue. - * - * ch - Pointer to channel structure. - * buf - Pointer to characters to be moved. - * n - Number of characters to move. +/** + * dgnc_wmove() - Write data to transmit queue. + * @ch: Pointer to channel structure. + * @buf: Pointer to characters to be moved. + * @n: Number of characters to move. */ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n) { int remain; uint head; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; head = ch->ch_w_head & WQUEUEMASK; @@ -388,10 +377,9 @@ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n) ch->ch_w_head = head; } -/* - * dgnc_input - Process received data. - * - * ch - Pointer to channel structure. +/** + * dgnc_input() - Process received data. + * @ch: Pointer to channel structure. */ void dgnc_input(struct channel_t *ch) { @@ -409,21 +397,17 @@ void dgnc_input(struct channel_t *ch) int s = 0; int i = 0; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; tp = ch->ch_tun.un_tty; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); - /* - * Figure the number of characters in the buffer. - * Exit immediately if none. - */ rmask = RQUEUEMASK; head = ch->ch_r_head & rmask; tail = ch->ch_r_tail & rmask; @@ -436,7 +420,7 @@ void dgnc_input(struct channel_t *ch) * If the device is not open, or CREAD is off, * flush input data and return immediately. */ - if (!tp || (tp->magic != TTY_MAGIC) || + if (!tp || !(ch->ch_tun.un_flags & UN_ISOPEN) || !C_CREAD(tp) || (ch->ch_tun.un_flags & UN_CLOSING)) { @@ -448,32 +432,18 @@ void dgnc_input(struct channel_t *ch) goto exit_unlock; } - /* If we are throttled, simply don't read any data. */ - if (ch->ch_flags & CH_FORCED_STOPI) goto exit_unlock; flip_len = TTY_FLIPBUF_SIZE; - /* Chop down the length, if needed */ len = min(data_len, flip_len); len = min(len, (N_TTY_BUF_SIZE - 1)); ld = tty_ldisc_ref(tp); - - /* - * If we were unable to get a reference to the ld, - * don't flush our buffer, and act like the ld doesn't - * have any space to put the data right now. - */ if (!ld) { len = 0; } else { - /* - * If ld doesn't have a pointer to a receive_buf function, - * flush the data, then act like the ld doesn't have any - * space to put the data right now. - */ if (!ld->ops->receive_buf) { ch->ch_r_head = ch->ch_r_tail; len = 0; @@ -562,7 +532,9 @@ exit_unlock: tty_ldisc_deref(ld); } -/* +/** + * dgnc_carrier() + * * Determines when CARRIER changes state and takes appropriate * action. */ @@ -571,7 +543,7 @@ void dgnc_carrier(struct channel_t *ch) int virt_carrier = 0; int phys_carrier = 0; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; if (ch->ch_mistat & UART_MSR_DCD) @@ -652,7 +624,6 @@ void dgnc_carrier(struct channel_t *ch) } /* Assign the custom baud rate to the channel structure */ - static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate) { int testdiv; @@ -716,7 +687,6 @@ void dgnc_check_queue_flow_control(struct channel_t *ch) { int qleft; - /* Store how much space we have left in the queue */ qleft = ch->ch_r_tail - ch->ch_r_head - 1; if (qleft < 0) qleft += RQUEUEMASK + 1; @@ -797,7 +767,7 @@ void dgnc_wakeup_writes(struct channel_t *ch) int qlen = 0; unsigned long flags; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -883,8 +853,6 @@ static struct dgnc_board *find_board_by_major(unsigned int major) /* TTY Entry points and helper functions */ -/* dgnc_tty_open() */ - static int dgnc_tty_open(struct tty_struct *tty, struct file *file) { struct dgnc_board *brd; @@ -903,39 +871,30 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) if (major > 255) return -ENXIO; - /* Get board pointer from our array of majors we have allocated */ brd = find_board_by_major(major); if (!brd) return -ENXIO; - /* - * If board is not yet up to a state of READY, go to - * sleep waiting for it to happen or they cancel the open. - */ rc = wait_event_interruptible(brd->state_wait, (brd->state & BOARD_READY)); - if (rc) return rc; spin_lock_irqsave(&brd->bd_lock, flags); - /* If opened device is greater than our number of ports, bail. */ if (PORT_NUM(minor) >= brd->nasync) { - spin_unlock_irqrestore(&brd->bd_lock, flags); - return -ENXIO; + rc = -ENXIO; + goto err_brd_unlock; } ch = brd->channels[PORT_NUM(minor)]; if (!ch) { - spin_unlock_irqrestore(&brd->bd_lock, flags); - return -ENXIO; + rc = -ENXIO; + goto err_brd_unlock; } - /* Drop board lock */ spin_unlock_irqrestore(&brd->bd_lock, flags); - /* Grab channel lock */ spin_lock_irqsave(&ch->ch_lock, flags); /* Figure out our type */ @@ -946,8 +905,8 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) un = &brd->channels[PORT_NUM(minor)]->ch_pun; un->un_type = DGNC_PRINT; } else { - spin_unlock_irqrestore(&ch->ch_lock, flags); - return -ENXIO; + rc = -ENXIO; + goto err_ch_unlock; } /* @@ -959,7 +918,6 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) rc = wait_event_interruptible(ch->ch_flags_wait, ((ch->ch_flags & CH_OPENING) == 0)); - /* If ret is non-zero, user ctrl-c'ed us */ if (rc) return -EINTR; @@ -975,21 +933,18 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) ch->ch_flags_wait, (((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) return -EINTR; spin_lock_irqsave(&ch->ch_lock, flags); - /* Store our unit into driver_data, so we always have it available. */ tty->driver_data = un; /* Initialize tty's */ if (!(un->un_flags & UN_ISOPEN)) { - /* Store important variables. */ - un->un_tty = tty; + un->un_tty = tty; /* Maybe do something here to the TTY struct as well? */ } @@ -1000,7 +955,6 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) */ ch->ch_flags |= (CH_OPENING); - /* Drop locks, as malloc with GFP_KERNEL can sleep */ spin_unlock_irqrestore(&ch->ch_lock, flags); if (!ch->ch_rqueue) @@ -1014,7 +968,6 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) kfree(ch->ch_rqueue); kfree(ch->ch_equeue); kfree(ch->ch_wqueue); - return -ENOMEM; } @@ -1062,19 +1015,14 @@ 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 */ - brd->bd_ops->param(tty); dgnc_carrier(ch); - /* follow protocol for opening port */ - spin_unlock_irqrestore(&ch->ch_lock, flags); rc = dgnc_block_til_ready(tty, file, ch); - /* No going back now, increment our unit and channel counters */ spin_lock_irqsave(&ch->ch_lock, flags); ch->ch_open_count++; un->un_open_count++; @@ -1082,18 +1030,23 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) spin_unlock_irqrestore(&ch->ch_lock, flags); return rc; + +err_brd_unlock: + spin_unlock_irqrestore(&brd->bd_lock, flags); + + return rc; +err_ch_unlock: + spin_unlock_irqrestore(&ch->ch_lock, flags); + + return rc; } -/* - * dgnc_block_til_ready() - * - * Wait for DCD, if needed. - */ +/* Wait for DCD, if needed. */ static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch) { - int retval = 0; + int rc = 0; struct un_t *un = tty->driver_data; unsigned long flags; uint old_flags = 0; @@ -1106,22 +1059,16 @@ static int dgnc_block_til_ready(struct tty_struct *tty, ch->ch_wopen++; - /* Loop forever */ while (1) { sleep_on_un_flags = 0; - /* - * If board has failed somehow during our sleep, - * bail with error. - */ if (ch->ch_bd->state == BOARD_FAILED) { - retval = -ENXIO; + rc = -ENXIO; break; } - /* If tty was hung up, break out of loop and set error. */ if (tty_hung_up_p(file)) { - retval = -EAGAIN; + rc = -EAGAIN; break; } @@ -1146,7 +1093,7 @@ static int dgnc_block_til_ready(struct tty_struct *tty, break; if (tty_io_error(tty)) { - retval = -EIO; + rc = -EIO; break; } @@ -1162,15 +1109,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, /* * If there is a signal pending, the user probably * interrupted (ctrl-c) us. - * Leave loop with error set. */ if (signal_pending(current)) { - retval = -ERESTARTSYS; + rc = -ERESTARTSYS; break; } - /* 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 @@ -1189,12 +1133,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, * from the current value. */ if (sleep_on_un_flags) - retval = wait_event_interruptible + rc = wait_event_interruptible (un->un_flags_wait, (old_flags != (ch->ch_tun.un_flags | ch->ch_pun.un_flags))); else - retval = wait_event_interruptible( + rc = wait_event_interruptible( ch->ch_flags_wait, (old_flags != ch->ch_flags)); @@ -1209,25 +1153,19 @@ static int dgnc_block_til_ready(struct tty_struct *tty, spin_unlock_irqrestore(&ch->ch_lock, flags); - return retval; + return rc; } -/* - * dgnc_tty_hangup() - * - * Hangup the port. Like a close, but don't wait for output to drain. - */ +/* Hangup the port. Like a close, but don't wait for output to drain. */ static void dgnc_tty_hangup(struct tty_struct *tty) { - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; /* flush the transmit queues */ dgnc_tty_flush_buffer(tty); } -/* dgnc_tty_close() */ - static void dgnc_tty_close(struct tty_struct *tty, struct file *file) { struct dgnc_board *bd; @@ -1235,19 +1173,19 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1361,8 +1299,6 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) } /* - * dgnc_tty_chars_in_buffer() - * * Return number of characters that have not been transmitted yet. * * This routine is used by the line discipline to determine if there @@ -1375,18 +1311,18 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty) ushort thead; ushort ttail; uint tmask; - uint chars = 0; + uint chars; unsigned long flags; if (!tty) return 0; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return 0; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return 0; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1397,21 +1333,17 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty) spin_unlock_irqrestore(&ch->ch_lock, flags); - if (ttail == thead) { + if (ttail == thead) chars = 0; - } else { - if (thead >= ttail) - chars = thead - ttail; - else - chars = thead - ttail + WQUEUESIZE; - } + else if (thead > ttail) + chars = thead - ttail; + else + chars = thead - ttail + WQUEUESIZE; return chars; } /* - * dgnc_maxcps_room - * * Reduces bytes_available to the max number of characters * that can be sent currently given the maxcps value, and * returns the new bytes_available. This only affects printer @@ -1419,6 +1351,8 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty) */ static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available) { + int rc = bytes_available; + if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) { int cps_limit = 0; unsigned long current_time = jiffies; @@ -1439,17 +1373,13 @@ static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available) cps_limit = 0; } - bytes_available = min(cps_limit, bytes_available); + rc = min(cps_limit, bytes_available); } - return bytes_available; + return rc; } -/* - * dgnc_tty_write_room() - * - * Return space available in Tx buffer - */ +/* Return room available in Tx buffer */ static int dgnc_tty_write_room(struct tty_struct *tty) { struct channel_t *ch = NULL; @@ -1457,18 +1387,18 @@ static int dgnc_tty_write_room(struct tty_struct *tty) ushort head; ushort tail; ushort tmask; - int ret = 0; + int room = 0; unsigned long flags; if (!tty) return 0; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return 0; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return 0; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1477,53 +1407,45 @@ static int dgnc_tty_write_room(struct tty_struct *tty) head = (ch->ch_w_head) & tmask; tail = (ch->ch_w_tail) & tmask; - ret = tail - head - 1; - if (ret < 0) - ret += WQUEUESIZE; + room = tail - head - 1; + if (room < 0) + room += WQUEUESIZE; /* Limit printer to maxcps */ if (un->un_type != DGNC_PRINT) - ret = dgnc_maxcps_room(ch, ret); + room = dgnc_maxcps_room(ch, room); /* - * If we are printer device, leave space for + * If we are printer device, leave room for * possibly both the on and off strings. */ if (un->un_type == DGNC_PRINT) { if (!(ch->ch_flags & CH_PRON)) - ret -= ch->ch_digi.digi_onlen; - ret -= ch->ch_digi.digi_offlen; + room -= ch->ch_digi.digi_onlen; + room -= ch->ch_digi.digi_offlen; } else { if (ch->ch_flags & CH_PRON) - ret -= ch->ch_digi.digi_offlen; + room -= ch->ch_digi.digi_offlen; } - if (ret < 0) - ret = 0; + if (room < 0) + room = 0; spin_unlock_irqrestore(&ch->ch_lock, flags); - - return ret; + return room; } /* - * dgnc_tty_put_char() - * * Put a character into ch->ch_buf - * - * - used by the line discipline for OPOST processing + * Used by the line discipline for OPOST processing */ static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c) { - /* Simply call tty_write. */ - dgnc_tty_write(tty, &c, 1); return 1; } /* - * dgnc_tty_write() - * * Take data from the user or kernel and send it out to the FEP. * In here exists all the Transparent Print magic as well. */ @@ -1543,11 +1465,11 @@ static int dgnc_tty_write(struct tty_struct *tty, return 0; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return 0; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return 0; if (!count) @@ -1561,7 +1483,6 @@ static int dgnc_tty_write(struct tty_struct *tty, spin_lock_irqsave(&ch->ch_lock, flags); - /* Get our space available for the channel from the board */ tmask = WQUEUEMASK; head = (ch->ch_w_head) & tmask; tail = (ch->ch_w_tail) & tmask; @@ -1577,14 +1498,7 @@ static int dgnc_tty_write(struct tty_struct *tty, if (un->un_type != DGNC_PRINT) bufcount = dgnc_maxcps_room(ch, bufcount); - /* - * Take minimum of what the user wants to send, and the - * space available in the FEP buffer. - */ count = min(count, bufcount); - - /* Bail if no space left. */ - if (count <= 0) goto exit_retry; @@ -1646,42 +1560,36 @@ static int dgnc_tty_write(struct tty_struct *tty, spin_unlock_irqrestore(&ch->ch_lock, flags); - if (count) { - /* - * Channel lock is grabbed and then released - * inside this routine. - */ + if (count) ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch); - } return count; exit_retry: - spin_unlock_irqrestore(&ch->ch_lock, flags); + return 0; } /* Return modem signals to ld. */ - static int dgnc_tty_tiocmget(struct tty_struct *tty) { struct channel_t *ch; struct un_t *un; - int result = -EIO; + int rc; unsigned char mstat = 0; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) - return result; + if (!tty) + return -EIO; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) - return result; + if (!un) + return -EIO; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return result; + if (!ch) + return -EIO; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1689,53 +1597,47 @@ static int dgnc_tty_tiocmget(struct tty_struct *tty) spin_unlock_irqrestore(&ch->ch_lock, flags); - result = 0; + rc = 0; if (mstat & UART_MCR_DTR) - result |= TIOCM_DTR; + rc |= TIOCM_DTR; if (mstat & UART_MCR_RTS) - result |= TIOCM_RTS; + rc |= TIOCM_RTS; if (mstat & UART_MSR_CTS) - result |= TIOCM_CTS; + rc |= TIOCM_CTS; if (mstat & UART_MSR_DSR) - result |= TIOCM_DSR; + rc |= TIOCM_DSR; if (mstat & UART_MSR_RI) - result |= TIOCM_RI; + rc |= TIOCM_RI; if (mstat & UART_MSR_DCD) - result |= TIOCM_CD; + rc |= TIOCM_CD; - return result; + return rc; } -/* - * dgnc_tty_tiocmset() - * - * Set modem signals, called by ld. - */ - +/* Set modem signals, called by ld. */ static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct dgnc_board *bd; struct channel_t *ch; struct un_t *un; - int ret = -EIO; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) - return ret; + if (!tty) + return -EIO; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) - return ret; + if (!un) + return -EIO; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return ret; + if (!ch) + return -EIO; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return ret; + if (!bd) + return -EIO; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1751,95 +1653,74 @@ static int dgnc_tty_tiocmset(struct tty_struct *tty, if (clear & TIOCM_DTR) ch->ch_mostat &= ~(UART_MCR_DTR); - ch->ch_bd->bd_ops->assert_modem_signals(ch); + bd->bd_ops->assert_modem_signals(ch); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } -/* - * dgnc_tty_send_break() - * - * Send a Break, called by ld. - */ +/* Send a Break, called by ld. */ static int dgnc_tty_send_break(struct tty_struct *tty, int msec) { struct dgnc_board *bd; struct channel_t *ch; struct un_t *un; - int ret = -EIO; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) - return ret; + if (!tty) + return -EIO; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) - return ret; + if (!un) + return -EIO; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) - return ret; + if (!ch) + return -EIO; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) - return ret; + if (!bd) + return -EIO; - switch (msec) { - case -1: + if (msec < 0) msec = 0xFFFF; - break; - case 0: - msec = 0; - break; - default: - break; - } spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_bd->bd_ops->send_break(ch, msec); + bd->bd_ops->send_break(ch, msec); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } -/* - * dgnc_tty_wait_until_sent() - * - * wait until data has been transmitted, called by ld. - */ +/* wait until data has been transmitted, called by ld. */ static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout) { struct dgnc_board *bd; struct channel_t *ch; struct un_t *un; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; bd->bd_ops->drain(tty, 0); } -/* - * dgnc_send_xchar() - * - * send a high priority character, called by ld. - */ +/* send a high priority character, called by ld. */ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c) { struct dgnc_board *bd; @@ -1847,39 +1728,34 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; - dev_dbg(tty->dev, "dgnc_tty_send_xchar start\n"); - spin_lock_irqsave(&ch->ch_lock, flags); bd->bd_ops->send_immediate_char(ch, c); spin_unlock_irqrestore(&ch->ch_lock, flags); - - dev_dbg(tty->dev, "dgnc_tty_send_xchar finish\n"); } /* Return modem signals to ld. */ - static inline int dgnc_get_mstat(struct channel_t *ch) { unsigned char mstat; - int result = 0; unsigned long flags; + int rc; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -ENXIO; spin_lock_irqsave(&ch->ch_lock, flags); @@ -1888,46 +1764,43 @@ static inline int dgnc_get_mstat(struct channel_t *ch) spin_unlock_irqrestore(&ch->ch_lock, flags); + rc = 0; + if (mstat & UART_MCR_DTR) - result |= TIOCM_DTR; + rc |= TIOCM_DTR; if (mstat & UART_MCR_RTS) - result |= TIOCM_RTS; + rc |= TIOCM_RTS; if (mstat & UART_MSR_CTS) - result |= TIOCM_CTS; + rc |= TIOCM_CTS; if (mstat & UART_MSR_DSR) - result |= TIOCM_DSR; + rc |= TIOCM_DSR; if (mstat & UART_MSR_RI) - result |= TIOCM_RI; + rc |= TIOCM_RI; if (mstat & UART_MSR_DCD) - result |= TIOCM_CD; + rc |= TIOCM_CD; - return result; + return rc; } /* Return modem signals to ld. */ - static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value) { return put_user(dgnc_get_mstat(ch), value); } -/* - * dgnc_set_modem_info() - * - * Set modem signals, called by ld. - */ +/* Set modem signals, called by ld. */ static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command, unsigned int __user *value) { - int ret = -ENXIO; + int rc; unsigned int arg = 0; unsigned long flags; - ret = get_user(arg, value); - if (ret) - return ret; + rc = get_user(arg, value); + if (rc) + return rc; switch (command) { case TIOCMBIS: @@ -1975,11 +1848,7 @@ static int dgnc_set_modem_info(struct channel_t *ch, return 0; } -/* - * dgnc_tty_digigeta() - * - * Ioctl to get the information for ditty. - */ +/* Ioctl to get the information for ditty. */ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retinfo) { @@ -1991,15 +1860,15 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, if (!retinfo) return -EFAULT; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return -EFAULT; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return -EFAULT; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -EFAULT; memset(&tmp, 0, sizeof(tmp)); @@ -2014,11 +1883,7 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, return 0; } -/* - * dgnc_tty_digiseta() - * - * Ioctl to set the information for ditty. - */ +/* Ioctl to set the information for ditty. */ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info) { @@ -2028,19 +1893,19 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t new_digi; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return -EFAULT; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return -EFAULT; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -EFAULT; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return -EFAULT; if (copy_from_user(&new_digi, new_info, sizeof(new_digi))) @@ -2089,15 +1954,13 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, if (ch->ch_digi.digi_offlen > DIGI_PLEN) ch->ch_digi.digi_offlen = DIGI_PLEN; - ch->ch_bd->bd_ops->param(tty); + bd->bd_ops->param(tty); spin_unlock_irqrestore(&ch->ch_lock, flags); return 0; } -/* dgnc_set_termios() */ - static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { @@ -2106,19 +1969,19 @@ static void dgnc_tty_set_termios(struct tty_struct *tty, struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2130,7 +1993,7 @@ static void dgnc_tty_set_termios(struct tty_struct *tty, ch->ch_startc = tty->termios.c_cc[VSTART]; ch->ch_stopc = tty->termios.c_cc[VSTOP]; - ch->ch_bd->bd_ops->param(tty); + bd->bd_ops->param(tty); dgnc_carrier(ch); spin_unlock_irqrestore(&ch->ch_lock, flags); @@ -2142,15 +2005,15 @@ static void dgnc_tty_throttle(struct tty_struct *tty) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2166,15 +2029,15 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2191,19 +2054,19 @@ static void dgnc_tty_start(struct tty_struct *tty) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2220,19 +2083,19 @@ static void dgnc_tty_stop(struct tty_struct *tty) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2243,8 +2106,6 @@ static void dgnc_tty_stop(struct tty_struct *tty) } /* - * dgnc_tty_flush_chars() - * * Flush the cook buffer * * Note to self, and any other poor souls who venture here: @@ -2262,19 +2123,19 @@ static void dgnc_tty_flush_chars(struct tty_struct *tty) struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2284,26 +2145,22 @@ static void dgnc_tty_flush_chars(struct tty_struct *tty) spin_unlock_irqrestore(&ch->ch_lock, flags); } -/* - * dgnc_tty_flush_buffer() - * - * Flush Tx buffer (make in == out) - */ +/* Flush Tx buffer (make in == out) */ static void dgnc_tty_flush_buffer(struct tty_struct *tty) { struct channel_t *ch; struct un_t *un; unsigned long flags; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return; spin_lock_irqsave(&ch->ch_lock, flags); @@ -2328,11 +2185,7 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty) spin_unlock_irqrestore(&ch->ch_lock, flags); } -/* - * dgnc_wake_up_unit() - * - * Wakes up processes waiting in the unit's (teminal/printer) wait queue - */ +/* 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); @@ -2341,11 +2194,7 @@ static void dgnc_wake_up_unit(struct un_t *unit) /* The IOCTL function and all of its helpers */ -/* - * dgnc_tty_ioctl() - * - * The usual assortment of ioctl's - */ +/* The usual assortment of ioctl's */ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -2357,19 +2206,19 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long flags; void __user *uarg = (void __user *)arg; - if (!tty || tty->magic != TTY_MAGIC) + if (!tty) return -ENODEV; un = tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) + if (!un) return -ENODEV; ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) + if (!ch) return -ENODEV; bd = ch->ch_bd; - if (!bd || bd->magic != DGNC_BOARD_MAGIC) + if (!bd) return -ENODEV; ch_bd_ops = bd->bd_ops; @@ -2377,8 +2226,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_lock_irqsave(&ch->ch_lock, flags); if (un->un_open_count <= 0) { - spin_unlock_irqrestore(&ch->ch_lock, flags); - return -EIO; + rc = -EIO; + goto err_unlock; } switch (cmd) { @@ -2399,7 +2248,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return rc; rc = ch_bd_ops->drain(tty, 0); - if (rc) return -EINTR; @@ -2504,10 +2352,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, * also. */ rc = tty_check_change(tty); - if (rc) { - spin_unlock_irqrestore(&ch->ch_lock, flags); - return rc; - } + if (rc) + goto err_unlock; if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) { ch->ch_r_head = ch->ch_r_tail; @@ -2588,7 +2434,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (cmd == (DIGI_SETAW)) { spin_unlock_irqrestore(&ch->ch_lock, flags); rc = ch_bd_ops->drain(tty, 0); - if (rc) return -EINTR; @@ -2634,7 +2479,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case DIGI_SETCUSTOMBAUD: { int new_rate; - /* Let go of locks when accessing user space, could sleep */ + spin_unlock_irqrestore(&ch->ch_lock, flags); rc = get_user(new_rate, (int __user *)arg); if (rc) @@ -2732,8 +2577,6 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, spin_unlock_irqrestore(&ch->ch_lock, flags); - /* Get data from user first. */ - if (copy_from_user(&buf, uarg, sizeof(buf))) return -EFAULT; @@ -2787,4 +2630,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return -ENOIOCTLCMD; } +err_unlock: + spin_unlock_irqrestore(&ch->ch_lock, flags); + + return rc; } diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 1ee0eee..6c58f1b 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -13,8 +13,8 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DGNC_TTY_H -#define __DGNC_TTY_H +#ifndef _DGNC_TTY_H +#define _DGNC_TTY_H #include "dgnc_driver.h" @@ -30,4 +30,4 @@ void dgnc_carrier(struct channel_t *ch); void dgnc_wakeup_writes(struct channel_t *ch); void dgnc_check_queue_flow_control(struct channel_t *ch); -#endif +#endif /* _DGNC_TTY_H */ diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c index 6f592400..e07ff8d2 100644 --- a/drivers/staging/dgnc/dgnc_utils.c +++ b/drivers/staging/dgnc/dgnc_utils.c @@ -2,12 +2,11 @@ #include <linux/sched/signal.h> #include "dgnc_utils.h" -/* - * dgnc_ms_sleep() +/** + * dgnc_ms_sleep - Put the driver to sleep + * @ms - milliseconds to sleep * - * Put the driver to sleep for x ms's - * - * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal. + * Return: 0 if timed out, if interrupted by a signal return signal. */ int dgnc_ms_sleep(ulong ms) { diff --git a/drivers/staging/dgnc/dgnc_utils.h b/drivers/staging/dgnc/dgnc_utils.h index 1164c3a..d1f07a5 100644 --- a/drivers/staging/dgnc/dgnc_utils.h +++ b/drivers/staging/dgnc/dgnc_utils.h @@ -1,6 +1,6 @@ -#ifndef __DGNC_UTILS_H -#define __DGNC_UTILS_H +#ifndef _DGNC_UTILS_H +#define _DGNC_UTILS_H int dgnc_ms_sleep(ulong ms); -#endif +#endif /* _DGNC_UTILS_H */ diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h index ec2e3dd..46b06b0 100644 --- a/drivers/staging/dgnc/digi.h +++ b/drivers/staging/dgnc/digi.h @@ -13,8 +13,8 @@ * PURPOSE. See the GNU General Public License for more details. */ -#ifndef __DIGI_H -#define __DIGI_H +#ifndef _DIGI_H +#define _DIGI_H #ifndef TIOCM_LE #define TIOCM_LE 0x01 /* line enable */ @@ -45,8 +45,7 @@ #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 +#define DIGI_LOOPBACK (('d' << 8) | 252) /* Enable/disable UART * internal loopback */ #define DIGI_FAST 0x0002 /* Fast baud rates */ @@ -64,50 +63,77 @@ /* * Structure used with ioctl commands for DIGI parameters. */ +/** + * struct digi_t - Ioctl commands for DIGI parameters. + * @digi_flags: Flags. + * @digi_maxcps: Maximum printer CPS. + * @digi_maxchar: Maximum characters in the print queue. + * @digi_bufsize: Buffer size. + * @digi_onlen: Length of ON string. + * @digi_offlen: Length of OFF string. + * @digi_onstr: Printer ON string. + * @digi_offstr: Printer OFF string. + * @digi_term: Terminal string. + */ struct digi_t { - 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 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 */ + unsigned short digi_flags; + unsigned short digi_maxcps; + unsigned short digi_maxchar; + unsigned short digi_bufsize; + unsigned char digi_onlen; + unsigned char digi_offlen; + char digi_onstr[DIGI_PLEN]; + char digi_offstr[DIGI_PLEN]; + char digi_term[DIGI_TSIZ]; }; -/* Structure to get driver status information */ - +/** + * struct digi_dinfo - Driver status information. + * @dinfo_nboards: Number of boards configured. + * @dinfo_reserved: Not used, for future expansion. + * @dinfio_version: Driver version. + */ struct digi_dinfo { - unsigned int dinfo_nboards; /* # boards configured */ - char dinfo_reserved[12]; /* for future expansion */ - char dinfo_version[16]; /* driver version */ + unsigned int dinfo_nboards; + char dinfo_reserved[12]; + char dinfo_version[16]; }; #define DIGI_GETDD (('d' << 8) | 248) /* get driver info */ -/* - * Structure used with ioctl commands for per-board information +/** + * struct digi_info - Ioctl commands for per board information. + * + * Physsize and memsize differ when board has "windowed" memory. * - * physsize and memsize differ when board has "windowed" memory + * @info_bdnum: Board number (0 based). + * @info_ioport: IO port address. + * @indo_physaddr: Memory address. + * @info_physize: Size of host memory window. + * @info_memsize: Amount of dual-port memory on board. + * @info_bdtype: Board type. + * @info_nports: Number of ports. + * @info_bdstate: Board state. + * @info_reserved: Not used, for future expansion. */ 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_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 */ + unsigned int info_bdnum; + unsigned int info_ioport; + unsigned int info_physaddr; + unsigned int info_physsize; + unsigned int info_memsize; + unsigned short info_bdtype; + unsigned short info_nports; + char info_bdstate; + char info_reserved[7]; }; #define DIGI_GETBD (('d' << 8) | 249) /* get board info */ -struct digi_getbuffer /* Struct for holding buffer use counts */ -{ +/** + * struct digi_getbuffer - Holds buffer use counts. + */ +struct digi_getbuffer { unsigned long tx_in; unsigned long tx_out; unsigned long rxbuf; @@ -115,14 +141,24 @@ struct digi_getbuffer /* Struct for holding buffer use counts */ unsigned long txdone; }; +/** + * struct digi_getcounter + * @norun: Number of UART overrun errors. + * @noflow: Number of buffer overflow errors. + * @nframe: Number of framing errors. + * @nparity: Number of parity errors. + * @nbreak: Number of breaks received. + * @rbytes: Number of received bytes. + * @tbytes: Number of transmitted bytes. + */ struct digi_getcounter { - unsigned long norun; /* number of UART overrun errors */ - unsigned long noflow; /* number of buffer overflow errors */ - unsigned long nframe; /* number of framing errors */ - unsigned long nparity; /* number of parity errors */ - unsigned long nbreak; /* number of breaks received */ - unsigned long rbytes; /* number of received bytes */ - unsigned long tbytes; /* number of bytes transmitted fully */ + unsigned long norun; + unsigned long noflow; + unsigned long nframe; + unsigned long nparity; + unsigned long nbreak; + unsigned long rbytes; + unsigned long tbytes; }; /* Board State Definitions */ @@ -137,15 +173,14 @@ struct digi_getcounter { #define DIGI_REALPORT_GETCOUNTERS (('e' << 8) | 110) #define DIGI_REALPORT_GETEVENTS (('e' << 8) | 111) -#define EV_OPU 0x0001 /* !<Output paused by client */ -#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 */ +#define EV_OPU 0x0001 /* Output paused by client */ +#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 */ -/* - * This structure holds data needed for the intelligent <--> nonintelligent - * DPA translation +/** + * struct ni_info - intelligent <--> non-intelligent DPA translation. */ struct ni_info { int board; @@ -175,4 +210,5 @@ struct ni_info { #define T_NEO 0000 #define TTY_FLIPBUF_SIZE 512 -#endif /* DIGI_H */ + +#endif /* _DIGI_H */ |