forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: tty_port,usb-console: Fix usb serial console open/close regression tty: cpm_uart: use resource_size() tty_buffer: Fix distinct type warning hvc_console: Fix race between hvc_close and hvc_remove uartlite: Fix build on sparc. tty: Take a 256 byte padding into account when buffering below sub-page units Revert "tty: Add a new VT mode which is like VT_PROCESS but doesn't require a VT_RELDISP ioctl call"
This commit is contained in:
commit
8dba8f9494
@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
|
||||
spin_lock_irqsave(&hp->lock, flags);
|
||||
/* Check and then increment for fast path open. */
|
||||
if (hp->count++ > 0) {
|
||||
tty_kref_get(tty);
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
hvc_kick();
|
||||
return 0;
|
||||
@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
|
||||
|
||||
tty->driver_data = hp;
|
||||
|
||||
hp->tty = tty;
|
||||
hp->tty = tty_kref_get(tty);
|
||||
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
|
||||
@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
|
||||
spin_lock_irqsave(&hp->lock, flags);
|
||||
hp->tty = NULL;
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
tty_kref_put(tty);
|
||||
tty->driver_data = NULL;
|
||||
kref_put(&hp->kref, destroy_hvc_struct);
|
||||
printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
|
||||
@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
|
||||
return;
|
||||
|
||||
hp = tty->driver_data;
|
||||
|
||||
spin_lock_irqsave(&hp->lock, flags);
|
||||
tty_kref_get(tty);
|
||||
|
||||
if (--hp->count == 0) {
|
||||
/* We are done with the tty pointer now. */
|
||||
hp->tty = NULL;
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
|
||||
/* Put the ref obtained in hvc_open() */
|
||||
tty_kref_put(tty);
|
||||
|
||||
if (hp->ops->notifier_del)
|
||||
hp->ops->notifier_del(hp, hp->data);
|
||||
|
||||
@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
}
|
||||
|
||||
tty_kref_put(tty);
|
||||
kref_put(&hp->kref, destroy_hvc_struct);
|
||||
}
|
||||
|
||||
@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty)
|
||||
spin_unlock_irqrestore(&hp->lock, flags);
|
||||
|
||||
if (hp->ops->notifier_hangup)
|
||||
hp->ops->notifier_hangup(hp, hp->data);
|
||||
hp->ops->notifier_hangup(hp, hp->data);
|
||||
|
||||
while(temp_open_count) {
|
||||
--temp_open_count;
|
||||
tty_kref_put(tty);
|
||||
kref_put(&hp->kref, destroy_hvc_struct);
|
||||
}
|
||||
}
|
||||
@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
|
||||
}
|
||||
|
||||
/* No tty attached, just skip */
|
||||
tty = hp->tty;
|
||||
tty = tty_kref_get(hp->tty);
|
||||
if (tty == NULL)
|
||||
goto bail;
|
||||
|
||||
@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)
|
||||
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
if (tty)
|
||||
tty_kref_put(tty);
|
||||
|
||||
return poll_mask;
|
||||
}
|
||||
@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)
|
||||
struct tty_struct *tty;
|
||||
|
||||
spin_lock_irqsave(&hp->lock, flags);
|
||||
tty = hp->tty;
|
||||
tty = tty_kref_get(hp->tty);
|
||||
|
||||
if (hp->index < MAX_NR_HVC_CONSOLES)
|
||||
vtermnos[hp->index] = -1;
|
||||
@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp)
|
||||
/*
|
||||
* We 'put' the instance that was grabbed when the kref instance
|
||||
* was initialized using kref_init(). Let the last holder of this
|
||||
* kref cause it to be removed, which will probably be the tty_hangup
|
||||
* kref cause it to be removed, which will probably be the tty_vhangup
|
||||
* below.
|
||||
*/
|
||||
kref_put(&hp->kref, destroy_hvc_struct);
|
||||
|
||||
/*
|
||||
* This function call will auto chain call hvc_hangup. The tty should
|
||||
* always be valid at this time unless a simultaneous tty close already
|
||||
* cleaned up the hvc_struct.
|
||||
* This function call will auto chain call hvc_hangup.
|
||||
*/
|
||||
if (tty)
|
||||
tty_hangup(tty);
|
||||
if (tty) {
|
||||
tty_vhangup(tty);
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hvc_remove);
|
||||
|
@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
|
||||
{
|
||||
int copied = 0;
|
||||
do {
|
||||
int goal = min(size - copied, TTY_BUFFER_PAGE);
|
||||
int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
|
||||
int space = tty_buffer_request_room(tty, goal);
|
||||
struct tty_buffer *tb = tty->buf.tail;
|
||||
/* If there is no space then tb may be NULL */
|
||||
@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
|
||||
{
|
||||
int copied = 0;
|
||||
do {
|
||||
int goal = min(size - copied, TTY_BUFFER_PAGE);
|
||||
int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
|
||||
int space = tty_buffer_request_room(tty, goal);
|
||||
struct tty_buffer *tb = tty->buf.tail;
|
||||
/* If there is no space then tb may be NULL */
|
||||
|
@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set);
|
||||
static void tty_port_shutdown(struct tty_port *port)
|
||||
{
|
||||
mutex_lock(&port->mutex);
|
||||
if (port->ops->shutdown &&
|
||||
if (port->ops->shutdown && !port->console &&
|
||||
test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
|
||||
port->ops->shutdown(port);
|
||||
mutex_unlock(&port->mutex);
|
||||
|
@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) {
|
||||
if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc)
|
||||
* telling it that it has acquired. Also check if it has died and
|
||||
* clean up (similar to logic employed in change_console())
|
||||
*/
|
||||
if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
|
||||
if (vc->vt_mode.mode == VT_PROCESS) {
|
||||
/*
|
||||
* Send the signal as privileged - kill_pid() will
|
||||
* tell us if the process has gone or something else
|
||||
@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc)
|
||||
* vt to auto control.
|
||||
*/
|
||||
vc = vc_cons[fg_console].d;
|
||||
if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) {
|
||||
if (vc->vt_mode.mode == VT_PROCESS) {
|
||||
/*
|
||||
* Send the signal as privileged - kill_pid() will
|
||||
* tell us if the process has gone or something else
|
||||
@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc)
|
||||
*/
|
||||
vc->vt_newvt = new_vc->vc_num;
|
||||
if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
|
||||
if(vc->vt_mode.mode == VT_PROCESS)
|
||||
/*
|
||||
* It worked. Mark the vt to switch to and
|
||||
* return. The process needs to send us a
|
||||
* VT_RELDISP ioctl to complete the switch.
|
||||
*/
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* The controlling process has died, so we revert back to
|
||||
* normal operation. In this case, we'll also change back
|
||||
* to KD_TEXT mode. I'm not sure if this is strictly correct
|
||||
* but it saves the agony when the X server dies and the screen
|
||||
* remains blanked due to KD_GRAPHICS! It would be nice to do
|
||||
* this outside of VT_PROCESS but there is no single process
|
||||
* to account for and tracking tty count may be undesirable.
|
||||
* It worked. Mark the vt to switch to and
|
||||
* return. The process needs to send us a
|
||||
* VT_RELDISP ioctl to complete the switch.
|
||||
*/
|
||||
reset_vc(vc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch...
|
||||
* The controlling process has died, so we revert back to
|
||||
* normal operation. In this case, we'll also change back
|
||||
* to KD_TEXT mode. I'm not sure if this is strictly correct
|
||||
* but it saves the agony when the X server dies and the screen
|
||||
* remains blanked due to KD_GRAPHICS! It would be nice to do
|
||||
* this outside of VT_PROCESS but there is no single process
|
||||
* to account for and tracking tty count may be undesirable.
|
||||
*/
|
||||
reset_vc(vc);
|
||||
|
||||
/*
|
||||
* Fall through to normal (VT_AUTO) handling of the switch...
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
|
||||
void __iomem *pram;
|
||||
unsigned long offset;
|
||||
struct resource res;
|
||||
unsigned long len;
|
||||
resource_size_t len;
|
||||
|
||||
/* Don't remap parameter RAM if it has already been initialized
|
||||
* during console setup.
|
||||
@ -74,7 +74,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port,
|
||||
if (of_address_to_resource(np, 1, &res))
|
||||
return NULL;
|
||||
|
||||
len = 1 + res.end - res.start;
|
||||
len = resource_size(&res);
|
||||
pram = ioremap(res.start, len);
|
||||
if (!pram)
|
||||
return NULL;
|
||||
|
@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options)
|
||||
/* The console is special in terms of closing the device so
|
||||
* indicate this port is now acting as a system console. */
|
||||
port->console = 1;
|
||||
port->port.console = 1;
|
||||
|
||||
mutex_unlock(&serial->disc_mutex);
|
||||
return retval;
|
||||
|
@ -70,12 +70,13 @@ struct tty_buffer {
|
||||
|
||||
/*
|
||||
* We default to dicing tty buffer allocations to this many characters
|
||||
* in order to avoid multiple page allocations. We assume tty_buffer itself
|
||||
* is under 256 bytes. See tty_buffer_find for the allocation logic this
|
||||
* must match
|
||||
* in order to avoid multiple page allocations. We know the size of
|
||||
* tty_buffer itself but it must also be taken into account that the
|
||||
* the buffer is 256 byte aligned. See tty_buffer_find for the allocation
|
||||
* logic this must match
|
||||
*/
|
||||
|
||||
#define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2)
|
||||
#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
|
||||
|
||||
|
||||
struct tty_bufhead {
|
||||
@ -223,6 +224,7 @@ struct tty_port {
|
||||
wait_queue_head_t close_wait; /* Close waiters */
|
||||
wait_queue_head_t delta_msr_wait; /* Modem status change */
|
||||
unsigned long flags; /* TTY flags ASY_*/
|
||||
unsigned char console:1; /* port is a console */
|
||||
struct mutex mutex; /* Locking */
|
||||
struct mutex buf_mutex; /* Buffer alloc lock */
|
||||
unsigned char *xmit_buf; /* Optional buffer */
|
||||
|
@ -27,7 +27,7 @@ struct vt_mode {
|
||||
#define VT_SETMODE 0x5602 /* set mode of active vt */
|
||||
#define VT_AUTO 0x00 /* auto vt switching */
|
||||
#define VT_PROCESS 0x01 /* process controls switching */
|
||||
#define VT_PROCESS_AUTO 0x02 /* process is notified of switching */
|
||||
#define VT_ACKACQ 0x02 /* acknowledge switch */
|
||||
|
||||
struct vt_stat {
|
||||
unsigned short v_active; /* active vt */
|
||||
@ -38,7 +38,6 @@ struct vt_stat {
|
||||
#define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */
|
||||
|
||||
#define VT_RELDISP 0x5605 /* release display */
|
||||
#define VT_ACKACQ 0x02 /* acknowledge switch */
|
||||
|
||||
#define VT_ACTIVATE 0x5606 /* make vt active */
|
||||
#define VT_WAITACTIVE 0x5607 /* wait for vt active */
|
||||
|
Loading…
Reference in New Issue
Block a user