if (o_tp) kfree(o_tp); 
kfree(o_tp); 
static int init_dev(struct tty_driver *driver, int idx,	struct tty_struct **ret_tty){	struct tty_struct *tty, *o_tty;	struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;	int retval=0;	/* check whether we're reopening an existing tty */	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {		tty = devpts_get_tty(idx);		if (tty && driver->subtype == PTY_TYPE_MASTER)			tty = tty->link;	} else {		tty = driver->ttys[idx];	}	if (tty) goto fast_track;	/*	 * First time open is complex, especially for PTY devices.	 * This code guarantees that either everything succeeds and the	 * TTY is ready for operation, or else the table slots are vacated	 * and the allocated memory released.  (Except that the termios 	 * and locked termios may be retained.)	 */	if (!try_module_get(driver->owner)) {		retval = -ENODEV;		goto end_init;	}	o_tty = NULL;	tp = o_tp = NULL;	ltp = o_ltp = NULL;	tty = alloc_tty_struct();	if(!tty)		goto fail_no_mem;	initialize_tty_struct(tty);	tty->driver = driver;	tty->index = idx;	tty_line_name(driver, idx, tty->name);	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {		tp_loc = &tty->termios;		ltp_loc = &tty->termios_locked;	} else {		tp_loc = &driver->termios[idx];		ltp_loc = &driver->termios_locked[idx];	}	if (!*tp_loc) {		tp = (struct termios *) kmalloc(sizeof(struct termios),						GFP_KERNEL);		if (!tp)			goto free_mem_out;		*tp = driver->init_termios;	}	if (!*ltp_loc) {		ltp = (struct termios *) kmalloc(sizeof(struct termios),						 GFP_KERNEL);		if (!ltp)			goto free_mem_out;		memset(ltp, 0, sizeof(struct termios));	}	if (driver->type == TTY_DRIVER_TYPE_PTY) {		o_tty = alloc_tty_struct();		if (!o_tty)			goto free_mem_out;		initialize_tty_struct(o_tty);		o_tty->driver = driver->other;		o_tty->index = idx;		tty_line_name(driver->other, idx, o_tty->name);		if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {			o_tp_loc = &o_tty->termios;			o_ltp_loc = &o_tty->termios_locked;		} else {			o_tp_loc = &driver->other->termios[idx];			o_ltp_loc = &driver->other->termios_locked[idx];		}		if (!*o_tp_loc) {			o_tp = (struct termios *)				kmalloc(sizeof(struct termios), GFP_KERNEL);			if (!o_tp)				goto free_mem_out;			*o_tp = driver->other->init_termios;		}		if (!*o_ltp_loc) {			o_ltp = (struct termios *)				kmalloc(sizeof(struct termios), GFP_KERNEL);			if (!o_ltp)				goto free_mem_out;			memset(o_ltp, 0, sizeof(struct termios));		}		/*		 * Everything allocated ... set up the o_tty structure.		 */		if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM)) {			driver->other->ttys[idx] = o_tty;		}		if (!*o_tp_loc)			*o_tp_loc = o_tp;		if (!*o_ltp_loc)			*o_ltp_loc = o_ltp;		o_tty->termios = *o_tp_loc;		o_tty->termios_locked = *o_ltp_loc;		driver->other->refcount++;		if (driver->subtype == PTY_TYPE_MASTER)			o_tty->count++;		/* Establish the links in both directions */		tty->link   = o_tty;		o_tty->link = tty;	}	/* 	 * All structures have been allocated, so now we install them.	 * Failures after this point use release_mem to clean up, so 	 * there's no need to null out the local pointers.	 */	if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) {		driver->ttys[idx] = tty;	}		if (!*tp_loc)		*tp_loc = tp;	if (!*ltp_loc)		*ltp_loc = ltp;	tty->termios = *tp_loc;	tty->termios_locked = *ltp_loc;	driver->refcount++;	tty->count++;	/* 	 * Structures all installed ... call the ldisc open routines.	 * If we fail here just call release_mem to clean up.  No need	 * to decrement the use counts, as release_mem doesn't care.	 */	if (tty->ldisc.open) {		retval = (tty->ldisc.open)(tty);		if (retval)			goto release_mem_out;	}	if (o_tty && o_tty->ldisc.open) {		retval = (o_tty->ldisc.open)(o_tty);		if (retval) {			if (tty->ldisc.close)				(tty->ldisc.close)(tty);			goto release_mem_out;		}		tty_ldisc_enable(o_tty);	}	tty_ldisc_enable(tty);	goto success;	/*	 * This fast open can be used if the tty is already open.	 * No memory is allocated, and the only failures are from	 * attempting to open a closing tty or attempting multiple	 * opens on a pty master.	 */fast_track:	if (test_bit(TTY_CLOSING, &tty->flags)) {		retval = -EIO;		goto end_init;	}	if (driver->type == TTY_DRIVER_TYPE_PTY &&	    driver->subtype == PTY_TYPE_MASTER) {		/*		 * special case for PTY masters: only one open permitted, 		 * and the slave side open count is incremented as well.		 */		if (tty->count) {			retval = -EIO;			goto end_init;		}		tty->link->count++;	}	tty->count++;	tty->driver = driver; /* N.B. why do this every time?? */	/* FIXME */	if(!test_bit(TTY_LDISC, &tty->flags))		printk(KERN_ERR "init_dev but no ldisc\n");success:	*ret_tty = tty;		/* All paths come through here to release the semaphore */end_init:	return retval;	/* Release locally allocated memory ... nothing placed in slots */free_mem_out:	if (o_tp)		kfree(o_tp);	if (o_tty)		free_tty_struct(o_tty);	if (ltp)		kfree(ltp);	if (tp)		kfree(tp);	free_tty_struct(tty);fail_no_mem:	module_put(driver->owner);	retval = -ENOMEM;	goto end_init;	/* call the tty release_mem routine to clean out this slot */release_mem_out:	printk(KERN_INFO "init_dev: ldisc open failed, "			 "clearing slot %d\n", idx);	release_mem(tty, idx);	goto end_init;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/735d5661d5c5f023a78fbe68e771e261040ff1b7/tty_io.c/clean/drivers/char/tty_io.c