struct board_chan *bc; 
struct board_chan __iomem *bc; 
static int pc_ioctl(struct tty_struct *tty, struct file * file,		    unsigned int cmd, unsigned long arg){ /* Begin pc_ioctl */	digiflow_t dflow;	int retval;	unsigned long flags;	unsigned int mflag, mstat;	unsigned char startc, stopc;	struct board_chan *bc;	struct channel *ch = (struct channel *) tty->driver_data;	void __user *argp = (void __user *)arg;		if (ch)		bc = ch->brdchan;	else 		return -EINVAL;	/* -------------------------------------------------------------------		For POSIX compliance we need to add more ioctls.  See tty_ioctl.c		in /usr/src/linux/drivers/char for a good example.  In particular 		think about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS.	---------------------------------------------------------------------- */	switch (cmd) 	{ /* Begin switch cmd */		case TCGETS:			if (copy_to_user(argp, tty->termios, sizeof(struct termios)))				return -EFAULT;			return 0;		case TCGETA:			return get_termio(tty, argp);		case TCSBRK:	/* SVID version: non-zero arg --> no break */			retval = tty_check_change(tty);			if (retval)				return retval;			/* Setup an event to indicate when the transmit buffer empties */			spin_lock_irqsave(&epca_lock, flags);			setup_empty_event(tty,ch);					spin_unlock_irqrestore(&epca_lock, flags);			tty_wait_until_sent(tty, 0);			if (!arg)				digi_send_break(ch, HZ/4);    /* 1/4 second */			return 0;		case TCSBRKP:	/* support for POSIX tcsendbreak() */			retval = tty_check_change(tty);			if (retval)				return retval;			/* Setup an event to indicate when the transmit buffer empties */			spin_lock_irqsave(&epca_lock, flags);			setup_empty_event(tty,ch);					spin_unlock_irqrestore(&epca_lock, flags);			tty_wait_until_sent(tty, 0);			digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);			return 0;		case TIOCGSOFTCAR:			if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))				return -EFAULT;			return 0;		case TIOCSSOFTCAR:		{			unsigned int value;			if (get_user(value, (unsigned __user *)argp))				return -EFAULT;			tty->termios->c_cflag =				((tty->termios->c_cflag & ~CLOCAL) |				 (value ? CLOCAL : 0));			return 0;		}		case TIOCMODG:			mflag = pc_tiocmget(tty, file);			if (put_user(mflag, (unsigned long __user *)argp))				return -EFAULT;			break;		case TIOCMODS:			if (get_user(mstat, (unsigned __user *)argp))				return -EFAULT;			return pc_tiocmset(tty, file, mstat, ~mstat);		case TIOCSDTR:			spin_lock_irqsave(&epca_lock, flags);			ch->omodem |= ch->m_dtr;			globalwinon(ch);			fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);			memoff(ch);			spin_unlock_irqrestore(&epca_lock, flags);			break;		case TIOCCDTR:			spin_lock_irqsave(&epca_lock, flags);			ch->omodem &= ~ch->m_dtr;			globalwinon(ch);			fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);			memoff(ch);			spin_unlock_irqrestore(&epca_lock, flags);			break;		case DIGI_GETA:			if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))				return -EFAULT;			break;		case DIGI_SETAW:		case DIGI_SETAF:			if (cmd == DIGI_SETAW) {				/* Setup an event to indicate when the transmit buffer empties */				spin_lock_irqsave(&epca_lock, flags);				setup_empty_event(tty,ch);						spin_unlock_irqrestore(&epca_lock, flags);				tty_wait_until_sent(tty, 0);			} else 	{				/* ldisc lock already held in ioctl */				if (tty->ldisc.flush_buffer)					tty->ldisc.flush_buffer(tty);			}			/* Fall Thru */		case DIGI_SETA:			if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))				return -EFAULT;						if (ch->digiext.digi_flags & DIGI_ALTPIN)  {				ch->dcd = ch->m_dsr;				ch->dsr = ch->m_dcd;			} else {				ch->dcd = ch->m_dcd;				ch->dsr = ch->m_dsr;			}					spin_lock_irqsave(&epca_lock, flags);			globalwinon(ch);			/* -----------------------------------------------------------------				The below routine generally sets up parity, baud, flow control 				issues, etc.... It effect both control flags and input flags.			------------------------------------------------------------------- */			epcaparam(tty,ch);			memoff(ch);			spin_unlock_irqrestore(&epca_lock, flags);			break;		case DIGI_GETFLOW:		case DIGI_GETAFLOW:			spin_lock_irqsave(&epca_lock, flags);			globalwinon(ch);			if (cmd == DIGI_GETFLOW) {				dflow.startc = readb(&bc->startc);				dflow.stopc = readb(&bc->stopc);			} else {				dflow.startc = readb(&bc->startca);				dflow.stopc = readb(&bc->stopca);			}			memoff(ch);			spin_unlock_irqrestore(&epca_lock, flags);			if (copy_to_user(argp, &dflow, sizeof(dflow)))				return -EFAULT;			break;		case DIGI_SETAFLOW:		case DIGI_SETFLOW:			if (cmd == DIGI_SETFLOW) {				startc = ch->startc;				stopc = ch->stopc;			} else {				startc = ch->startca;				stopc = ch->stopca;			}			if (copy_from_user(&dflow, argp, sizeof(dflow)))				return -EFAULT;			if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin  if setflow toggled */				spin_lock_irqsave(&epca_lock, flags);				globalwinon(ch);				if (cmd == DIGI_SETFLOW) {					ch->fepstartc = ch->startc = dflow.startc;					ch->fepstopc = ch->stopc = dflow.stopc;					fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);				} else {					ch->fepstartca = ch->startca = dflow.startc;					ch->fepstopca  = ch->stopca = dflow.stopc;					fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);				}				if (ch->statusflags & TXSTOPPED)					pc_start(tty);				memoff(ch);				spin_unlock_irqrestore(&epca_lock, flags);			} /* End if setflow toggled */			break;		default:			return -ENOIOCTLCMD;	} /* End switch cmd */	return 0;} /* End pc_ioctl */
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/bc9a5154a24d16d41cc79dbf1442de34454bc7db/epca.c/buggy/drivers/char/epca.c