Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6614999 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

tty: Introduce some close helpers for ports



Again this is a lot of common code we can unify

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7834909f
Loading
Loading
Loading
Loading
+10 −56
Original line number Original line Diff line number Diff line
@@ -945,76 +945,30 @@ static void isicom_flush_buffer(struct tty_struct *tty)


static void isicom_close(struct tty_struct *tty, struct file *filp)
static void isicom_close(struct tty_struct *tty, struct file *filp)
{
{
	struct isi_port *port = tty->driver_data;
	struct isi_port *ip = tty->driver_data;
	struct tty_port *port = &ip->port;
	struct isi_board *card;
	struct isi_board *card;
	unsigned long flags;
	unsigned long flags;


	if (!port)
	BUG_ON(!ip);
		return;
	card = port->card;
	if (isicom_paranoia_check(port, tty->name, "isicom_close"))
		return;


	pr_dbg("Close start!!!.\n");
	card = ip->card;

	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
	spin_lock_irqsave(&port->port.lock, flags);
	if (tty_hung_up_p(filp)) {
		spin_unlock_irqrestore(&port->port.lock, flags);
		return;
		return;
	}


	if (tty->count == 1 && port->port.count != 1) {
		printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
			"count tty->count = 1 port count = %d.\n",
			card->base, port->port.count);
		port->port.count = 1;
	}
	if (--port->port.count < 0) {
		printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
			"count for channel%d = %d", card->base, port->channel,
			port->port.count);
		port->port.count = 0;
	}

	if (port->port.count) {
		spin_unlock_irqrestore(&port->port.lock, flags);
		return;
	}
	port->port.flags |= ASYNC_CLOSING;
	tty->closing = 1;
	spin_unlock_irqrestore(&port->port.lock, flags);

	if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, port->port.closing_wait);
	/* indicate to the card that no more data can be received
	/* indicate to the card that no more data can be received
	   on this port */
	   on this port */
	spin_lock_irqsave(&card->card_lock, flags);
	spin_lock_irqsave(&card->card_lock, flags);
	if (port->port.flags & ASYNC_INITIALIZED) {
	if (port->flags & ASYNC_INITIALIZED) {
		card->port_status &= ~(1 << port->channel);
		card->port_status &= ~(1 << ip->channel);
		outw(card->port_status, card->base + 0x02);
		outw(card->port_status, card->base + 0x02);
	}
	}
	isicom_shutdown_port(port);
	isicom_shutdown_port(ip);
	spin_unlock_irqrestore(&card->card_lock, flags);
	spin_unlock_irqrestore(&card->card_lock, flags);


	isicom_flush_buffer(tty);
	isicom_flush_buffer(tty);
	tty_ldisc_flush(tty);
	
	
	spin_lock_irqsave(&port->port.lock, flags);
	tty_port_close_end(port, tty);
	tty->closing = 0;

	if (port->port.blocked_open) {
		spin_unlock_irqrestore(&port->port.lock, flags);
		if (port->port.close_delay) {
			pr_dbg("scheduling until time out.\n");
			msleep_interruptible(
				jiffies_to_msecs(port->port.close_delay));
		}
		spin_lock_irqsave(&port->port.lock, flags);
		wake_up_interruptible(&port->port.open_wait);
	}
	port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
	wake_up_interruptible(&port->port.close_wait);
	spin_unlock_irqrestore(&port->port.lock, flags);
}
}


/* write et all */
/* write et all */
+29 −49
Original line number Original line Diff line number Diff line
@@ -767,7 +767,7 @@ static int stli_parsebrd(struct stlconf *confp, char **argp)
			break;
			break;
	}
	}
	if (i == ARRAY_SIZE(stli_brdstr)) {
	if (i == ARRAY_SIZE(stli_brdstr)) {
		printk("STALLION: unknown board name, %s?\n", argp[0]);
		printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]);
		return 0;
		return 0;
	}
	}


@@ -855,21 +855,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
		return;
		return;
	port = &portp->port;
	port = &portp->port;


	spin_lock_irqsave(&port->lock, flags);
	if (tty_port_close_start(port, tty, filp) == 0)
	if (tty_hung_up_p(filp)) {
		spin_unlock_irqrestore(&port->lock, flags);
		return;
	}
	if (tty->count == 1 && port->count != 1)
		port->count = 1;
	if (port->count-- > 1) {
		spin_unlock_irqrestore(&port->lock, flags);
		return;
		return;
	}

	port->flags |= ASYNC_CLOSING;
	tty->closing = 1;
	spin_unlock_irqrestore(&port->lock, flags);


/*
/*
 *	May want to wait for data to drain before closing. The BUSY flag
 *	May want to wait for data to drain before closing. The BUSY flag
@@ -882,6 +869,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
		stli_flushchars(tty);
		stli_flushchars(tty);
	spin_unlock_irqrestore(&stli_lock, flags);
	spin_unlock_irqrestore(&stli_lock, flags);


	/* We end up doing this twice for the moment. This needs looking at
	   eventually. Note we still use portp->closing_wait as a result */
	if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
	if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, portp->closing_wait);
		tty_wait_until_sent(tty, portp->closing_wait);


@@ -905,17 +894,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
	set_bit(ST_DOFLUSHRX, &portp->state);
	set_bit(ST_DOFLUSHRX, &portp->state);
	stli_flushbuffer(tty);
	stli_flushbuffer(tty);


	tty->closing = 0;
	tty_port_close_end(port, tty);
	tty_port_tty_set(&portp->port, NULL);
	tty_port_tty_set(port, NULL);

	if (port->blocked_open) {
		if (portp->close_delay)
			msleep_interruptible(jiffies_to_msecs(portp->close_delay));
		wake_up_interruptible(&port->open_wait);
	}

	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
	wake_up_interruptible(&port->close_wait);
}
}


/*****************************************************************************/
/*****************************************************************************/
@@ -1482,7 +1462,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
	sio.irq = 0;
	sio.irq = 0;
	sio.flags = portp->port.flags;
	sio.flags = portp->port.flags;
	sio.baud_base = portp->baud_base;
	sio.baud_base = portp->baud_base;
	sio.close_delay = portp->close_delay;
	sio.close_delay = portp->port.close_delay;
	sio.closing_wait = portp->closing_wait;
	sio.closing_wait = portp->closing_wait;
	sio.custom_divisor = portp->custom_divisor;
	sio.custom_divisor = portp->custom_divisor;
	sio.xmit_fifo_size = 0;
	sio.xmit_fifo_size = 0;
@@ -1514,7 +1494,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s
		return -EFAULT;
		return -EFAULT;
	if (!capable(CAP_SYS_ADMIN)) {
	if (!capable(CAP_SYS_ADMIN)) {
		if ((sio.baud_base != portp->baud_base) ||
		if ((sio.baud_base != portp->baud_base) ||
		    (sio.close_delay != portp->close_delay) ||
		    (sio.close_delay != portp->port.close_delay) ||
		    ((sio.flags & ~ASYNC_USR_MASK) !=
		    ((sio.flags & ~ASYNC_USR_MASK) !=
		    (portp->port.flags & ~ASYNC_USR_MASK)))
		    (portp->port.flags & ~ASYNC_USR_MASK)))
			return -EPERM;
			return -EPERM;
@@ -1523,7 +1503,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s
	portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
	portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
		(sio.flags & ASYNC_USR_MASK);
		(sio.flags & ASYNC_USR_MASK);
	portp->baud_base = sio.baud_base;
	portp->baud_base = sio.baud_base;
	portp->close_delay = sio.close_delay;
	portp->port.close_delay = sio.close_delay;
	portp->closing_wait = sio.closing_wait;
	portp->closing_wait = sio.closing_wait;
	portp->custom_divisor = sio.custom_divisor;
	portp->custom_divisor = sio.custom_divisor;


@@ -2065,7 +2045,7 @@ static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigne
	unsigned char __iomem *bits;
	unsigned char __iomem *bits;


	if (test_bit(ST_CMDING, &portp->state)) {
	if (test_bit(ST_CMDING, &portp->state)) {
		printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n",
		printk(KERN_ERR "istallion: command already busy, cmd=%x!\n",
				(int) cmd);
				(int) cmd);
		return;
		return;
	}
	}
@@ -2625,7 +2605,7 @@ static int stli_initports(struct stlibrd *brdp)
	for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
	for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
		portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
		portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
		if (!portp) {
		if (!portp) {
			printk("STALLION: failed to allocate port structure\n");
			printk(KERN_WARNING "istallion: failed to allocate port structure\n");
			continue;
			continue;
		}
		}
		tty_port_init(&portp->port);
		tty_port_init(&portp->port);
@@ -2635,7 +2615,7 @@ static int stli_initports(struct stlibrd *brdp)
		portp->brdnr = brdp->brdnr;
		portp->brdnr = brdp->brdnr;
		portp->panelnr = panelnr;
		portp->panelnr = panelnr;
		portp->baud_base = STL_BAUDBASE;
		portp->baud_base = STL_BAUDBASE;
		portp->close_delay = STL_CLOSEDELAY;
		portp->port.close_delay = STL_CLOSEDELAY;
		portp->closing_wait = 30 * HZ;
		portp->closing_wait = 30 * HZ;
		init_waitqueue_head(&portp->port.open_wait);
		init_waitqueue_head(&portp->port.open_wait);
		init_waitqueue_head(&portp->port.close_wait);
		init_waitqueue_head(&portp->port.close_wait);
@@ -2692,7 +2672,7 @@ static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offse
	unsigned char val;
	unsigned char val;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), brd=%d\n",
				"range at line=%d(%d), brd=%d\n",
			(int) offset, line, __LINE__, brdp->brdnr);
			(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -2766,7 +2746,7 @@ static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long off
	unsigned char	val;
	unsigned char	val;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), brd=%d\n",
				"range at line=%d(%d), brd=%d\n",
			(int) offset, line, __LINE__, brdp->brdnr);
			(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -2818,7 +2798,7 @@ static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long off
	unsigned char val;
	unsigned char val;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), brd=%d\n",
				"range at line=%d(%d), brd=%d\n",
			(int) offset, line, __LINE__, brdp->brdnr);
			(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -2863,7 +2843,7 @@ static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long of
	unsigned char	val;
	unsigned char	val;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), board=%d\n",
				"range at line=%d(%d), board=%d\n",
				(int) offset, line, __LINE__, brdp->brdnr);
				(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -2928,7 +2908,7 @@ static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offse
	void __iomem *ptr;
	void __iomem *ptr;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), brd=%d\n",
				"range at line=%d(%d), brd=%d\n",
				(int) offset, line, __LINE__, brdp->brdnr);
				(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -2994,7 +2974,7 @@ static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offs
	unsigned char val;
	unsigned char val;


	if (offset > brdp->memsize) {
	if (offset > brdp->memsize) {
		printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
		printk(KERN_ERR "istallion: shared memory pointer=%x out of "
				"range at line=%d(%d), brd=%d\n",
				"range at line=%d(%d), brd=%d\n",
			(int) offset, line, __LINE__, brdp->brdnr);
			(int) offset, line, __LINE__, brdp->brdnr);
		ptr = NULL;
		ptr = NULL;
@@ -3433,7 +3413,7 @@ static int stli_startbrd(struct stlibrd *brdp)
#endif
#endif


	if (nrdevs < (brdp->nrports + 1)) {
	if (nrdevs < (brdp->nrports + 1)) {
		printk(KERN_ERR "STALLION: slave failed to allocate memory for "
		printk(KERN_ERR "istallion: slave failed to allocate memory for "
				"all devices, devices=%d\n", nrdevs);
				"all devices, devices=%d\n", nrdevs);
		brdp->nrports = nrdevs - 1;
		brdp->nrports = nrdevs - 1;
	}
	}
@@ -3443,13 +3423,13 @@ static int stli_startbrd(struct stlibrd *brdp)
	brdp->bitsize = (nrdevs + 7) / 8;
	brdp->bitsize = (nrdevs + 7) / 8;
	memoff = readl(&hdrp->memp);
	memoff = readl(&hdrp->memp);
	if (memoff > brdp->memsize) {
	if (memoff > brdp->memsize) {
		printk(KERN_ERR "STALLION: corrupted shared memory region?\n");
		printk(KERN_ERR "istallion: corrupted shared memory region?\n");
		rc = -EIO;
		rc = -EIO;
		goto stli_donestartup;
		goto stli_donestartup;
	}
	}
	memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
	memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff);
	if (readw(&memp->dtype) != TYP_ASYNCTRL) {
	if (readw(&memp->dtype) != TYP_ASYNCTRL) {
		printk(KERN_ERR "STALLION: no slave control device found\n");
		printk(KERN_ERR "istallion: no slave control device found\n");
		goto stli_donestartup;
		goto stli_donestartup;
	}
	}
	memp++;
	memp++;
@@ -3534,7 +3514,7 @@ static int __devinit stli_brdinit(struct stlibrd *brdp)
		retval = stli_initonb(brdp);
		retval = stli_initonb(brdp);
		break;
		break;
	default:
	default:
		printk(KERN_ERR "STALLION: board=%d is unknown board "
		printk(KERN_ERR "istallion: board=%d is unknown board "
				"type=%d\n", brdp->brdnr, brdp->brdtype);
				"type=%d\n", brdp->brdnr, brdp->brdtype);
		retval = -ENODEV;
		retval = -ENODEV;
	}
	}
@@ -3543,7 +3523,7 @@ static int __devinit stli_brdinit(struct stlibrd *brdp)
		return retval;
		return retval;


	stli_initports(brdp);
	stli_initports(brdp);
	printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x "
	printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x "
		"nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
		"nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
		brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
		brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
		brdp->nrpanels, brdp->nrports);
		brdp->nrpanels, brdp->nrports);
@@ -3637,7 +3617,7 @@ static int stli_eisamemprobe(struct stlibrd *brdp)
	if (! foundit) {
	if (! foundit) {
		brdp->memaddr = 0;
		brdp->memaddr = 0;
		brdp->membase = NULL;
		brdp->membase = NULL;
		printk(KERN_ERR "STALLION: failed to probe shared memory "
		printk(KERN_ERR "istallion: failed to probe shared memory "
				"region for %s in EISA slot=%d\n",
				"region for %s in EISA slot=%d\n",
			stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
			stli_brdnames[brdp->brdtype], (brdp->iobase >> 12));
		return -ENODEV;
		return -ENODEV;
@@ -3782,7 +3762,7 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev,
	mutex_lock(&stli_brdslock);
	mutex_lock(&stli_brdslock);
	brdnr = stli_getbrdnr();
	brdnr = stli_getbrdnr();
	if (brdnr < 0) {
	if (brdnr < 0) {
		printk(KERN_INFO "STALLION: too many boards found, "
		printk(KERN_INFO "istallion: too many boards found, "
			"maximum supported %d\n", STL_MAXBRDS);
			"maximum supported %d\n", STL_MAXBRDS);
		mutex_unlock(&stli_brdslock);
		mutex_unlock(&stli_brdslock);
		retval = -EIO;
		retval = -EIO;
@@ -3854,7 +3834,7 @@ static struct stlibrd *stli_allocbrd(void)


	brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
	brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
	if (!brdp) {
	if (!brdp) {
		printk(KERN_ERR "STALLION: failed to allocate memory "
		printk(KERN_ERR "istallion: failed to allocate memory "
				"(size=%Zd)\n", sizeof(struct stlibrd));
				"(size=%Zd)\n", sizeof(struct stlibrd));
		return NULL;
		return NULL;
	}
	}
@@ -4493,7 +4473,7 @@ static int __init istallion_module_init(void)


	stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
	stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
	if (!stli_txcookbuf) {
	if (!stli_txcookbuf) {
		printk(KERN_ERR "STALLION: failed to allocate memory "
		printk(KERN_ERR "istallion: failed to allocate memory "
				"(size=%d)\n", STLI_TXBUFSIZE);
				"(size=%d)\n", STLI_TXBUFSIZE);
		retval = -ENOMEM;
		retval = -ENOMEM;
		goto err;
		goto err;
@@ -4518,7 +4498,7 @@ static int __init istallion_module_init(void)


	retval = tty_register_driver(stli_serial);
	retval = tty_register_driver(stli_serial);
	if (retval) {
	if (retval) {
		printk(KERN_ERR "STALLION: failed to register serial driver\n");
		printk(KERN_ERR "istallion: failed to register serial driver\n");
		goto err_ttyput;
		goto err_ttyput;
	}
	}


@@ -4532,7 +4512,7 @@ static int __init istallion_module_init(void)
 */
 */
	retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
	retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
	if (retval) {
	if (retval) {
		printk(KERN_ERR "STALLION: failed to register serial memory "
		printk(KERN_ERR "istallion: failed to register serial memory "
				"device\n");
				"device\n");
		goto err_deinit;
		goto err_deinit;
	}
	}
+9 −47
Original line number Original line Diff line number Diff line
@@ -1080,57 +1080,26 @@ static void mxser_flush_buffer(struct tty_struct *tty)
static void mxser_close(struct tty_struct *tty, struct file *filp)
static void mxser_close(struct tty_struct *tty, struct file *filp)
{
{
	struct mxser_port *info = tty->driver_data;
	struct mxser_port *info = tty->driver_data;
	struct tty_port *port = &info->port;


	unsigned long timeout;
	unsigned long timeout;
	unsigned long flags;


	if (tty->index == MXSER_PORTS)
	if (tty->index == MXSER_PORTS)
		return;
		return;
	if (!info)
	if (!info)
		return;
		return;


	spin_lock_irqsave(&info->port.lock, flags);
	if (tty_port_close_start(port, tty, filp) == 0)

	if (tty_hung_up_p(filp)) {
		spin_unlock_irqrestore(&info->port.lock, flags);
		return;
	}
	if ((tty->count == 1) && (info->port.count != 1)) {
		/*
		 * Uh, oh.  tty->count is 1, which means that the tty
		 * structure will be freed.  Info->port.count should always
		 * be one in these conditions.  If it's greater than
		 * one, we've got real problems, since it means the
		 * serial port won't be shutdown.
		 */
		printk(KERN_ERR "mxser_close: bad serial port count; "
			"tty->count is 1, info->port.count is %d\n", info->port.count);
		info->port.count = 1;
	}
	if (--info->port.count < 0) {
		printk(KERN_ERR "mxser_close: bad serial port count for "
			"ttys%d: %d\n", tty->index, info->port.count);
		info->port.count = 0;
	}
	if (info->port.count) {
		spin_unlock_irqrestore(&info->port.lock, flags);
		return;
		return;
	}

	info->port.flags |= ASYNC_CLOSING;
	spin_unlock_irqrestore(&info->port.lock, flags);
	/*
	/*
	 * Save the termios structure, since this port may have
	 * Save the termios structure, since this port may have
	 * separate termios for callout and dialin.
	 * separate termios for callout and dialin.
	 *
	 * FIXME: Can this go ?
	 */
	 */
	if (info->port.flags & ASYNC_NORMAL_ACTIVE)
	if (info->port.flags & ASYNC_NORMAL_ACTIVE)
		info->normal_termios = *tty->termios;
		info->normal_termios = *tty->termios;
	/*
	 * Now we wait for the transmit buffer to clear; and we notify
	 * the line discipline to only process XON/XOFF characters.
	 */
	tty->closing = 1;
	if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, info->port.closing_wait);
	/*
	/*
	 * At this point we stop accepting input.  To do this, we
	 * At this point we stop accepting input.  To do this, we
	 * disable the receive line status interrupts, and tell the
	 * disable the receive line status interrupts, and tell the
@@ -1156,19 +1125,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
		}
		}
	}
	}
	mxser_shutdown(tty);
	mxser_shutdown(tty);

	mxser_flush_buffer(tty);
	mxser_flush_buffer(tty);
	tty_ldisc_flush(tty);

	tty->closing = 0;
	tty_port_tty_set(&info->port, NULL);
	if (info->port.blocked_open) {
		if (info->port.close_delay)
			schedule_timeout_interruptible(info->port.close_delay);
		wake_up_interruptible(&info->port.open_wait);
	}


	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
	/* Right now the tty_port set is done outside of the close_end helper
	   as we don't yet have everyone using refcounts */	
	tty_port_close_end(port, tty);
	tty_port_tty_set(port, NULL);
}
}


static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
+5 −44
Original line number Original line Diff line number Diff line
@@ -929,35 +929,11 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
	if (!port || rc_paranoia_check(port, tty->name, "close"))
	if (!port || rc_paranoia_check(port, tty->name, "close"))
		return;
		return;


	spin_lock_irqsave(&port->port.lock, flags);
	bp = port_Board(port);
	
	
	if (tty_hung_up_p(filp))
	if (tty_port_close_start(&port->port, tty, filp) == 0)
		goto out;
		return;
	
	
	bp = port_Board(port);
	if ((tty->count == 1) && (port->port.count != 1))  {
		printk(KERN_INFO "rc%d: rc_close: bad port count;"
		       " tty->count is 1, port count is %d\n",
		       board_No(bp), port->port.count);
		port->port.count = 1;
	}
	if (--port->port.count < 0)  {
		printk(KERN_INFO "rc%d: rc_close: bad port count "
				 "for tty%d: %d\n",
		       board_No(bp), port_No(port), port->port.count);
		port->port.count = 0;
	}
	if (port->port.count)
		goto out;
	port->port.flags |= ASYNC_CLOSING;
	/*
	 * Now we wait for the transmit buffer to clear; and we notify
	 * the line discipline to only process XON/XOFF characters.
	 */
	tty->closing = 1;
	spin_unlock_irqrestore(&port->port.lock, flags);
	if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, port->port.closing_wait);
	/*
	/*
	 * At this point we stop accepting input.  To do this, we
	 * At this point we stop accepting input.  To do this, we
	 * disable the receive line status interrupts, and tell the
	 * disable the receive line status interrupts, and tell the
@@ -989,23 +965,8 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
	rc_shutdown_port(tty, bp, port);
	rc_shutdown_port(tty, bp, port);
	rc_flush_buffer(tty);
	rc_flush_buffer(tty);
	spin_unlock_irqrestore(&riscom_lock, flags);
	spin_unlock_irqrestore(&riscom_lock, flags);
	tty_ldisc_flush(tty);

	spin_lock_irqsave(&port->port.lock, flags);
	tty->closing = 0;
	port->port.tty = NULL;
	if (port->port.blocked_open) {
		spin_unlock_irqrestore(&port->port.lock, flags);
		if (port->port.close_delay)
			msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
		wake_up_interruptible(&port->port.open_wait);
		spin_lock_irqsave(&port->port.lock, flags);
	}
	port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
	wake_up_interruptible(&port->port.close_wait);


out:
	tty_port_close_end(&port->port, tty);
	spin_unlock_irqrestore(&riscom_lock, flags);
}
}


static int rc_write(struct tty_struct *tty,
static int rc_write(struct tty_struct *tty,
+4 −35
Original line number Original line Diff line number Diff line
@@ -833,40 +833,20 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);


	portp = tty->driver_data;
	portp = tty->driver_data;
	if (portp == NULL)
	BUG_ON(portp == NULL);
		return;

	port = &portp->port;
	port = &portp->port;


	spin_lock_irqsave(&port->lock, flags);
	if (tty_port_close_start(port, tty, filp) == 0)
	if (tty_hung_up_p(filp)) {
		spin_unlock_irqrestore(&port->lock, flags);
		return;
		return;
	}
	if (tty->count == 1 && port->count != 1)
		port->count = 1;
	if (port->count-- > 1) {
		spin_unlock_irqrestore(&port->lock, flags);
		return;
	}

	port->count = 0;
	port->flags |= ASYNC_CLOSING;

/*
/*
 *	May want to wait for any data to drain before closing. The BUSY
 *	May want to wait for any data to drain before closing. The BUSY
 *	flag keeps track of whether we are still sending or not - it is
 *	flag keeps track of whether we are still sending or not - it is
 *	very accurate for the cd1400, not quite so for the sc26198.
 *	very accurate for the cd1400, not quite so for the sc26198.
 *	(The sc26198 has no "end-of-data" interrupt only empty FIFO)
 *	(The sc26198 has no "end-of-data" interrupt only empty FIFO)
 */
 */
	tty->closing = 1;

	spin_unlock_irqrestore(&port->lock, flags);

	if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
		tty_wait_until_sent(tty, portp->closing_wait);
	stl_waituntilsent(tty, (HZ / 2));
	stl_waituntilsent(tty, (HZ / 2));



	spin_lock_irqsave(&port->lock, flags);
	spin_lock_irqsave(&port->lock, flags);
	portp->port.flags &= ~ASYNC_INITIALIZED;
	portp->port.flags &= ~ASYNC_INITIALIZED;
	spin_unlock_irqrestore(&port->lock, flags);
	spin_unlock_irqrestore(&port->lock, flags);
@@ -883,20 +863,9 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
		portp->tx.head = NULL;
		portp->tx.head = NULL;
		portp->tx.tail = NULL;
		portp->tx.tail = NULL;
	}
	}
	set_bit(TTY_IO_ERROR, &tty->flags);
	tty_ldisc_flush(tty);


	tty->closing = 0;
	tty_port_close_end(port, tty);
	tty_port_tty_set(port, NULL);
	tty_port_tty_set(port, NULL);

	if (port->blocked_open) {
		if (portp->close_delay)
			msleep_interruptible(jiffies_to_msecs(portp->close_delay));
		wake_up_interruptible(&portp->port.open_wait);
	}

	portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
	wake_up_interruptible(&port->close_wait);
}
}


/*****************************************************************************/
/*****************************************************************************/
Loading