int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) { struct serial_struct sio; if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return(-EFAULT); if (!capable(CAP_SYS_ADMIN)) { if ((sio.baud_base != port->baud_base) || (sio.close_delay != port->close_delay) || ((sio.flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) return(-EPERM); } port->flags = (port->flags & ~ASYNC_USR_MASK) | (sio.flags & ASYNC_USR_MASK); port->baud_base = sio.baud_base; port->close_delay = sio.close_delay; port->closing_wait = sio.closing_wait; port->custom_divisor = sio.custom_divisor; gs_set_termios (port->tty, NULL); return 0; }
/* Must be called with interrupts enabled */ int gs_init_port(struct gs_port *port) { unsigned long flags; unsigned long page; func_enter (); if (!tmp_buf) { page = get_zeroed_page(GFP_KERNEL); spin_lock_irqsave (&port->driver_lock, flags); /* Don't expect this to make a difference. */ if (tmp_buf) free_page(page); else tmp_buf = (unsigned char *) page; spin_unlock_irqrestore (&port->driver_lock, flags); if (!tmp_buf) { func_exit (); return -ENOMEM; } } if (port->flags & ASYNC_INITIALIZED) { func_exit (); return 0; } if (!port->xmit_buf) { /* We may sleep in get_zeroed_page() */ unsigned long tmp; tmp = get_zeroed_page(GFP_KERNEL); spin_lock_irqsave (&port->driver_lock, flags); if (port->xmit_buf) free_page (tmp); else port->xmit_buf = (unsigned char *) tmp; spin_unlock_irqrestore(&port->driver_lock, flags); if (!port->xmit_buf) { func_exit (); return -ENOMEM; } } spin_lock_irqsave (&port->driver_lock, flags); if (port->tty) clear_bit(TTY_IO_ERROR, &port->tty->flags); init_MUTEX(&port->port_write_sem); port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; spin_unlock_irqrestore(&port->driver_lock, flags); gs_set_termios(port->tty, NULL); spin_lock_irqsave (&port->driver_lock, flags); port->flags |= ASYNC_INITIALIZED; port->flags &= ~GS_TX_INTEN; spin_unlock_irqrestore(&port->driver_lock, flags); func_exit (); return 0; }
/* Must be called with interrupts enabled */ int gs_init_port(struct gs_port *port) { unsigned long flags; unsigned long page; save_flags (flags); if (!tmp_buf) { page = get_zeroed_page(GFP_KERNEL); cli (); /* Don't expect this to make a difference. */ if (tmp_buf) free_page(page); else tmp_buf = (unsigned char *) page; restore_flags (flags); if (!tmp_buf) { return -ENOMEM; } } if (port->flags & ASYNC_INITIALIZED) return 0; if (!port->xmit_buf) { /* We may sleep in get_zeroed_page() */ unsigned long tmp; tmp = get_zeroed_page(GFP_KERNEL); /* Spinlock? */ cli (); if (port->xmit_buf) free_page (tmp); else port->xmit_buf = (unsigned char *) tmp; restore_flags (flags); if (!port->xmit_buf) return -ENOMEM; } cli(); if (port->tty) clear_bit(TTY_IO_ERROR, &port->tty->flags); port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; gs_set_termios(port->tty, NULL); port->flags |= ASYNC_INITIALIZED; port->flags &= ~GS_TX_INTEN; restore_flags(flags); return 0; }
/* Must be called with interrupts enabled */ int gs_init_port(struct gs_port *port) { unsigned long flags; func_enter (); if (port->port.flags & ASYNC_INITIALIZED) { func_exit (); return 0; } if (!port->xmit_buf) { /* We may sleep in get_zeroed_page() */ unsigned long tmp; tmp = get_zeroed_page(GFP_KERNEL); spin_lock_irqsave (&port->driver_lock, flags); if (port->xmit_buf) free_page (tmp); else port->xmit_buf = (unsigned char *) tmp; spin_unlock_irqrestore(&port->driver_lock, flags); if (!port->xmit_buf) { func_exit (); return -ENOMEM; } } spin_lock_irqsave (&port->driver_lock, flags); if (port->port.tty) clear_bit(TTY_IO_ERROR, &port->port.tty->flags); mutex_init(&port->port_write_mutex); port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; spin_unlock_irqrestore(&port->driver_lock, flags); gs_set_termios(port->port.tty, NULL); spin_lock_irqsave (&port->driver_lock, flags); port->port.flags |= ASYNC_INITIALIZED; port->port.flags &= ~GS_TX_INTEN; spin_unlock_irqrestore(&port->driver_lock, flags); func_exit (); return 0; }