All of lore.kernel.org
 help / color / mirror / Atom feed
From: Henrique Oliveira <henrique.oliveira@cyclades.com>
To: Russell King <rmk+lkml@arm.linux.org.uk>
Cc: linux-kernel@vger.kernel.org, Daniela Squassoni <daniela@cyclades.com>
Subject: Re: [2/3]
Date: Tue, 13 Jan 2004 09:55:23 -0800	[thread overview]
Message-ID: <4004310B.4090802@cyclades.com> (raw)
In-Reply-To: <20040113173352.D7256@flint.arm.linux.org.uk>

Hi,

I am no longer the maintainer of the Cyclades driver (char/cyclades.c). 
Could you please remove my name from that driver and include Daniela as 
the official maintainer <daniela@cyclades.com> ?

Thanks a lot
Henrique

Russell King wrote:

> Here are patches to drivers in the 2.6 kernel which have not been tested
> to correct the tiocmset/tiocmget problem.
> 
> You can find the full thread at the following URL:
> 
> http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=1dvnl-5Pr-1%40gated-at.bofh.it&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3DOutstanding%2Bfixups%26btnG%3DGoogle%2BSearch%26meta%3Dgroup%253Dlinux.kernel
> 
> ===== drivers/char/cyclades.c 1.32 vs edited =====
> --- 1.32/drivers/char/cyclades.c	Tue Sep 30 01:34:28 2003
> +++ edited/drivers/char/cyclades.c	Tue Jan 13 14:01:24 2004
> @@ -3632,8 +3632,9 @@
>  }
>  
>  static int
> -get_modem_info(struct cyclades_port * info, unsigned int *value)
> +cy_tiocmget(struct tty_struct *tty, struct file *file)
>  {
> +  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
>    int card,chip,channel,index;
>    unsigned char *base_addr;
>    unsigned long flags;
> @@ -3645,6 +3646,9 @@
>    struct BOARD_CTRL *board_ctrl;
>    struct CH_CTRL *ch_ctrl;
>  
> +    if (serial_paranoia_check(info, tty->name, __FUNCTION__))
> +	return -ENODEV;
> +
>      card = info->card;
>      channel = (info->line) - (cy_card[card].first_line);
>      if (!IS_CYC_Z(cy_card[card])) {
> @@ -3700,14 +3704,15 @@
>  	}
>  
>      }
> -    return cy_put_user(result, value);
> -} /* get_modem_info */
> +    return result;
> +} /* cy_tiomget */
>  
>  
>  static int
> -set_modem_info(struct cyclades_port * info, unsigned int cmd,
> -                          unsigned int *value)
> +cy_tiocmset(struct tty_struct *tty, struct file *file,
> +            unsigned int set, unsigned int clear)
>  {
> +  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
>    int card,chip,channel,index;
>    unsigned char *base_addr;
>    unsigned long flags;
> @@ -3718,6 +3723,9 @@
>    struct CH_CTRL *ch_ctrl;
>    int retval;
>  
> +    if (serial_paranoia_check(info, tty->name, __FUNCTION__))
> +	return -ENODEV;
> +
>      card = info->card;
>      channel = (info->line) - (cy_card[card].first_line);
>      if (!IS_CYC_Z(cy_card[card])) {
> @@ -3728,66 +3736,7 @@
>  		       (cy_card[card].base_addr
>  		       + (cy_chip_offset[chip]<<index));
>  
> -	switch (cmd) {
> -	case TIOCMBIS:
> -	    if (arg & TIOCM_RTS){
> -		CY_LOCK(info, flags);
> -		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
> -                if (info->rtsdtr_inv) {
> -		    cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
> -                } else {
> -		    cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
> -                }
> -		CY_UNLOCK(info, flags);
> -	    }
> -	    if (arg & TIOCM_DTR){
> -		CY_LOCK(info, flags);
> -		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
> -                if (info->rtsdtr_inv) {
> -		    cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
> -                } else {
> -		    cy_writeb((u_long)base_addr+(CyMSVR2<<index), CyDTR);
> -                }
> -#ifdef CY_DEBUG_DTR
> -		printk("cyc:set_modem_info raising DTR\n");
> -		printk("     status: 0x%x, 0x%x\n",
> -		    cy_readb(base_addr+(CyMSVR1<<index)), 
> -                    cy_readb(base_addr+(CyMSVR2<<index)));
> -#endif
> -		CY_UNLOCK(info, flags);
> -	    }
> -	    break;
> -	case TIOCMBIC:
> -	    if (arg & TIOCM_RTS){
> -		CY_LOCK(info, flags);
> -		cy_writeb((u_long)base_addr+(CyCAR<<index), 
> -                          (u_char)channel);
> -                if (info->rtsdtr_inv) {
> -		    	cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
> -                } else {
> -		    	cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
> -                }
> -		CY_UNLOCK(info, flags);
> -	    }
> -	    if (arg & TIOCM_DTR){
> -		CY_LOCK(info, flags);
> -		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
> -                if (info->rtsdtr_inv) {
> -			cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
> -                } else {
> -			cy_writeb((u_long)base_addr+(CyMSVR2<<index), ~CyDTR);
> -                }
> -#ifdef CY_DEBUG_DTR
> -		printk("cyc:set_modem_info dropping DTR\n");
> -		printk("     status: 0x%x, 0x%x\n",
> -		    cy_readb(base_addr+(CyMSVR1<<index)), 
> -                    cy_readb(base_addr+(CyMSVR2<<index)));
> -#endif
> -		CY_UNLOCK(info, flags);
> -	    }
> -	    break;
> -	case TIOCMSET:
> -	    if (arg & TIOCM_RTS){
> +	if (set & TIOCM_RTS){
>  		CY_LOCK(info, flags);
>  	        cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
>                  if (info->rtsdtr_inv) {
> @@ -3796,7 +3745,8 @@
>  			cy_writeb((u_long)base_addr+(CyMSVR1<<index), CyRTS);
>                  }
>  		CY_UNLOCK(info, flags);
> -	    }else{
> +	}
> +	if (clear & TIOCM_RTS) {
>  		CY_LOCK(info, flags);
>  		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
>                  if (info->rtsdtr_inv) {
> @@ -3805,8 +3755,8 @@
>  			cy_writeb((u_long)base_addr+(CyMSVR1<<index), ~CyRTS);
>                  }
>  		CY_UNLOCK(info, flags);
> -	    }
> -	    if (arg & TIOCM_DTR){
> +	}
> +	if (set & TIOCM_DTR){
>  		CY_LOCK(info, flags);
>  		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
>                  if (info->rtsdtr_inv) {
> @@ -3821,7 +3771,8 @@
>                      cy_readb(base_addr+(CyMSVR2<<index)));
>  #endif
>  		CY_UNLOCK(info, flags);
> -	    }else{
> +	}
> +	if (clear & TIOCM_DTR) {
>  		CY_LOCK(info, flags);
>  		cy_writeb((u_long)base_addr+(CyCAR<<index), (u_char)channel);
>                  if (info->rtsdtr_inv) {
> @@ -3837,10 +3788,6 @@
>                      cy_readb(base_addr+(CyMSVR2<<index)));
>  #endif
>  		CY_UNLOCK(info, flags);
> -	    }
> -	    break;
> -	default:
> -	    return -EINVAL;
>  	}
>      } else {
>  	base_addr = (unsigned char*) (cy_card[card].base_addr);
> @@ -3854,54 +3801,19 @@
>  	    board_ctrl = &zfw_ctrl->board_ctrl;
>  	    ch_ctrl = zfw_ctrl->ch_ctrl;
>  
> -	    switch (cmd) {
> -	    case TIOCMBIS:
> -		if (arg & TIOCM_RTS){
> -		    CY_LOCK(info, flags);
> -		    cy_writel(&ch_ctrl[channel].rs_control,
> -                       cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
> -		    CY_UNLOCK(info, flags);
> -		}
> -		if (arg & TIOCM_DTR){
> -		    CY_LOCK(info, flags);
> -		    cy_writel(&ch_ctrl[channel].rs_control,
> -                       cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
> -#ifdef CY_DEBUG_DTR
> -		    printk("cyc:set_modem_info raising Z DTR\n");
> -#endif
> -		    CY_UNLOCK(info, flags);
> -		}
> -		break;
> -	    case TIOCMBIC:
> -		if (arg & TIOCM_RTS){
> -		    CY_LOCK(info, flags);
> -		    cy_writel(&ch_ctrl[channel].rs_control,
> -                       cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
> -		    CY_UNLOCK(info, flags);
> -		}
> -		if (arg & TIOCM_DTR){
> -		    CY_LOCK(info, flags);
> -		    cy_writel(&ch_ctrl[channel].rs_control,
> -                       cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
> -#ifdef CY_DEBUG_DTR
> -		    printk("cyc:set_modem_info clearing Z DTR\n");
> -#endif
> -		    CY_UNLOCK(info, flags);
> -		}
> -		break;
> -	    case TIOCMSET:
> -		if (arg & TIOCM_RTS){
> +	    if (set & TIOCM_RTS){
>  		    CY_LOCK(info, flags);
>  		    cy_writel(&ch_ctrl[channel].rs_control,
>                         cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
>  		    CY_UNLOCK(info, flags);
> -		}else{
> +	    }
> +	    if (clear & TIOCM_RTS) {
>  		    CY_LOCK(info, flags);
>  		    cy_writel(&ch_ctrl[channel].rs_control,
>                         cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
>  		    CY_UNLOCK(info, flags);
> -		}
> -		if (arg & TIOCM_DTR){
> +	    }
> +	    if (set & TIOCM_DTR){
>  		    CY_LOCK(info, flags);
>  		    cy_writel(&ch_ctrl[channel].rs_control,
>                         cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
> @@ -3909,7 +3821,8 @@
>  		    printk("cyc:set_modem_info raising Z DTR\n");
>  #endif
>  		    CY_UNLOCK(info, flags);
> -		}else{
> +	    }
> +	    if (clear & TIOCM_DTR) {
>  		    CY_LOCK(info, flags);
>  		    cy_writel(&ch_ctrl[channel].rs_control,
>                         cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
> @@ -3917,10 +3830,6 @@
>  		    printk("cyc:set_modem_info clearing Z DTR\n");
>  #endif
>  		    CY_UNLOCK(info, flags);
> -		}
> -		break;
> -	    default:
> -		return -EINVAL;
>  	    }
>  	}else{
>  	    return -ENODEV;
> @@ -3935,7 +3844,7 @@
>  	CY_UNLOCK(info, flags);
>      }
>      return 0;
> -} /* set_modem_info */
> +} /* cy_tiocmset */
>  
>  /*
>   * cy_break() --- routine which turns the break handling on or off
> @@ -4242,14 +4151,6 @@
>  	case CYGETWAIT:
>  	    ret_val = info->closing_wait / (HZ/100);
>  	    break;
> -        case TIOCMGET:
> -            ret_val = get_modem_info(info, (unsigned int *) arg);
> -            break;
> -        case TIOCMBIS:
> -        case TIOCMBIC:
> -        case TIOCMSET:
> -            ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
> -            break;
>          case TIOCGSERIAL:
>              ret_val = get_serial_info(info, (struct serial_struct *) arg);
>              break;
> @@ -5429,6 +5330,8 @@
>      .break_ctl = cy_break,
>      .wait_until_sent = cy_wait_until_sent,
>      .read_proc = cyclades_get_proc_info,
> +    .tiocmget = cy_tiocmget,
> +    .tiocmset = cy_tiocmset,
>  };
>  
>  static int __init
> ===== drivers/char/ip2main.c 1.42 vs edited =====
> --- 1.42/drivers/char/ip2main.c	Tue Sep 30 01:23:52 2003
> +++ edited/drivers/char/ip2main.c	Tue Jan 13 16:06:56 2004
> @@ -186,6 +186,9 @@
>  static void ip2_stop(PTTY);
>  static void ip2_start(PTTY);
>  static void ip2_hangup(PTTY);
> +static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
> +static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
> +			 unsigned int set, unsigned int clear);
>  
>  static void set_irq(int, int);
>  static void ip2_interrupt_bh(i2eBordStrPtr pB);
> @@ -466,6 +469,8 @@
>  	.start           = ip2_start,
>  	.hangup          = ip2_hangup,
>  	.read_proc       = ip2_read_proc,
> +	.tiocmget	 = ip2_tiocmget,
> +	.tiocmset	 = ip2_tiocmset,
>  };
>  
>  /******************************************************************************/
> @@ -1951,6 +1956,80 @@
>  /* Device Ioctl Section                                                       */
>  /******************************************************************************/
>  
> +static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	i2ChanStrPtr pCh = DevTable[tty->index];
> +	wait_queue_t wait;
> +
> +	if (pCh == NULL)
> +		return -ENODEV;
> +
> +/*
> +	FIXME - the following code is causing a NULL pointer dereference in
> +	2.3.51 in an interrupt handler.  It's suppose to prompt the board
> +	to return the DSS signal status immediately.  Why doesn't it do
> +	the same thing in 2.2.14?
> +*/
> +
> +/*	This thing is still busted in the 1.2.12 driver on 2.4.x
> +	and even hoses the serial console so the oops can be trapped.
> +		/\/\|=mhw=|\/\/			*/
> +
> +#ifdef	ENABLE_DSSNOW
> +	i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
> +
> +	init_waitqueue_entry(&wait, current);
> +	add_wait_queue(&pCh->dss_now_wait, &wait);
> +	set_current_state( TASK_INTERRUPTIBLE );
> +
> +	serviceOutgoingFifo( pCh->pMyBord );
> +
> +	schedule();
> +
> +	set_current_state( TASK_RUNNING );
> +	remove_wait_queue(&pCh->dss_now_wait, &wait);
> +
> +	if (signal_pending(current)) {
> +		return -EINTR;
> +	}
> +#endif
> +	return  ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
> +	      | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
> +	      | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
> +	      | ((pCh->dataSetIn  & I2_RI)  ? TIOCM_RNG : 0)
> +	      | ((pCh->dataSetIn  & I2_DSR) ? TIOCM_DSR : 0)
> +	      | ((pCh->dataSetIn  & I2_CTS) ? TIOCM_CTS : 0);
> +}
> +
> +static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
> +			unsigned int set, unsigned int clear)
> +{
> +	i2ChanStrPtr pCh = DevTable[tty->index];
> +
> +	if (pCh == NULL)
> +		return -ENODEV;
> +
> +	if (set & TIOCM_RTS) {
> +		i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
> +		pCh->dataSetOut |= I2_RTS;
> +	}
> +	if (set & TIOCM_DTR) {
> +		i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
> +		pCh->dataSetOut |= I2_DTR;
> +	}
> +
> +	if (clear & TIOCM_RTS) {
> +		i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
> +		pCh->dataSetOut &= ~I2_RTS;
> +	}
> +	if (clear & TIOCM_DTR) {
> +		i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
> +		pCh->dataSetOut &= ~I2_DTR;
> +	}
> +	serviceOutgoingFifo( pCh->pMyBord );
> +	return 0;
> +}
> +
>  /******************************************************************************/
>  /* Function:   ip2_ioctl()                                                    */
>  /* Parameters: Pointer to tty structure                                       */
> @@ -2078,57 +2157,6 @@
>  		
>  		break;
>  
> -	case TIOCMGET:
> -
> -		ip2trace (CHANN, ITRC_IOCTL, 8, 1, rc );
> -
> -/*
> -	FIXME - the following code is causing a NULL pointer dereference in
> -	2.3.51 in an interrupt handler.  It's suppose to prompt the board
> -	to return the DSS signal status immediately.  Why doesn't it do
> -	the same thing in 2.2.14?
> -*/
> -
> -/*	This thing is still busted in the 1.2.12 driver on 2.4.x
> -	and even hoses the serial console so the oops can be trapped.
> -		/\/\|=mhw=|\/\/			*/
> -
> -#ifdef	ENABLE_DSSNOW
> -		i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
> -
> -		init_waitqueue_entry(&wait, current);
> -		add_wait_queue(&pCh->dss_now_wait, &wait);
> -		set_current_state( TASK_INTERRUPTIBLE );
> -
> -		serviceOutgoingFifo( pCh->pMyBord );
> -
> -		schedule();
> -
> -		set_current_state( TASK_RUNNING );
> -		remove_wait_queue(&pCh->dss_now_wait, &wait);
> -
> -		if (signal_pending(current)) {
> -			return -EINTR;
> -		}
> -#endif
> -		rc = put_user(
> -				    ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
> -				  | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
> -				  | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
> -				  | ((pCh->dataSetIn  & I2_RI)  ? TIOCM_RNG : 0)
> -				  | ((pCh->dataSetIn  & I2_DSR) ? TIOCM_DSR : 0)
> -				  | ((pCh->dataSetIn  & I2_CTS) ? TIOCM_CTS : 0),
> -				(unsigned int *) arg);
> -		break;
> -
> -	case TIOCMBIS:
> -	case TIOCMBIC:
> -	case TIOCMSET:
> -		ip2trace (CHANN, ITRC_IOCTL, 9, 0 );
> -
> -		rc = set_modem_info(pCh, cmd, (unsigned int *) arg);
> -		break;
> -
>  	/*
>  	 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
>  	 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
> @@ -2239,70 +2267,6 @@
>  }
>  
>  /******************************************************************************/
> -/* Function:   set_modem_info()                                               */
> -/* Parameters: Pointer to channel structure                                   */
> -/*             Specific ioctl command                                         */
> -/*             Pointer to source for new settings                             */
> -/* Returns:    Nothing                                                        */
> -/*                                                                            */
> -/* Description:                                                               */
> -/* This returns the current settings of the dataset signal inputs to the user */
> -/* program.                                                                   */
> -/******************************************************************************/
> -static int
> -set_modem_info(i2ChanStrPtr pCh, unsigned cmd, unsigned int *value)
> -{
> -	int rc;
> -	unsigned int arg;
> -
> -	rc = get_user(arg,value);
> -	if (rc)
> -		return rc;
> -	switch(cmd) {
> -	case TIOCMBIS:
> -		if (arg & TIOCM_RTS) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
> -			pCh->dataSetOut |= I2_RTS;
> -		}
> -		if (arg & TIOCM_DTR) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
> -			pCh->dataSetOut |= I2_DTR;
> -		}
> -		break;
> -	case TIOCMBIC:
> -		if (arg & TIOCM_RTS) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
> -			pCh->dataSetOut &= ~I2_RTS;
> -		}
> -		if (arg & TIOCM_DTR) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
> -			pCh->dataSetOut &= ~I2_DTR;
> -		}
> -		break;
> -	case TIOCMSET:
> -		if ( (arg & TIOCM_RTS) && !(pCh->dataSetOut & I2_RTS) ) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
> -			pCh->dataSetOut |= I2_RTS;
> -		} else if ( !(arg & TIOCM_RTS) && (pCh->dataSetOut & I2_RTS) ) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
> -			pCh->dataSetOut &= ~I2_RTS;
> -		}
> -		if ( (arg & TIOCM_DTR) && !(pCh->dataSetOut & I2_DTR) ) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
> -			pCh->dataSetOut |= I2_DTR;
> -		} else if ( !(arg & TIOCM_DTR) && (pCh->dataSetOut & I2_DTR) ) {
> -			i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
> -			pCh->dataSetOut &= ~I2_DTR;
> -		}
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -	serviceOutgoingFifo( pCh->pMyBord );
> -	return 0;
> -}
> -
> -/******************************************************************************/
>  /* Function:   GetSerialInfo()                                                */
>  /* Parameters: Pointer to channel structure                                   */
>  /*             Pointer to old termios structure                               */
> @@ -2964,7 +2928,7 @@
>  			rc = put_user(ip2_throttle, pIndex++ );
>  			rc = put_user(ip2_unthrottle, pIndex++ );
>  			rc = put_user(ip2_ioctl, pIndex++ );
> -			rc = put_user(set_modem_info, pIndex++ );
> +			rc = put_user(0, pIndex++ );
>  			rc = put_user(get_serial_info, pIndex++ );
>  			rc = put_user(set_serial_info, pIndex++ );
>  			rc = put_user(ip2_set_termios, pIndex++ );
> ===== drivers/char/istallion.c 1.34 vs edited =====
> --- 1.34/drivers/char/istallion.c	Tue Sep 30 01:34:28 2003
> +++ edited/drivers/char/istallion.c	Tue Jan 13 16:12:50 2004
> @@ -1990,6 +1990,61 @@
>  
>  /*****************************************************************************/
>  
> +static int stli_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	stliport_t *portp = tty->driver_data;
> +	stlibrd_t *brdp;
> +	int rc;
> +
> +	if (portp == (stliport_t *) NULL)
> +		return(-ENODEV);
> +	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
> +		return(0);
> +	brdp = stli_brds[portp->brdnr];
> +	if (brdp == (stlibrd_t *) NULL)
> +		return(0);
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return(-EIO);
> +
> +	if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
> +			       &portp->asig, sizeof(asysigs_t), 1)) < 0)
> +		return(rc);
> +
> +	return stli_mktiocm(portp->asig.sigvalue);
> +}
> +
> +static int stli_tiocmset(struct tty_struct *tty, struct file *file,
> +			 unsigned int set, unsigned int clear)
> +{
> +	stliport_t *portp = tty->driver_data;
> +	stlibrd_t *brdp;
> +	int rts = -1, dtr = -1;
> +
> +	if (portp == (stliport_t *) NULL)
> +		return(-ENODEV);
> +	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
> +		return(0);
> +	brdp = stli_brds[portp->brdnr];
> +	if (brdp == (stlibrd_t *) NULL)
> +		return(0);
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return(-EIO);
> +
> +	if (set & TIOCM_RTS)
> +		rts = 1;
> +	if (set & TIOCM_DTR)
> +		dtr = 1;
> +	if (clear & TIOCM_RTS)
> +		rts = 0;
> +	if (clear & TIOCM_DTR)
> +		dtr = 0;
> +
> +	stli_mkasysigs(&portp->asig, dtr, rts);
> +
> +	return stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
> +			    sizeof(asysigs_t), 0);
> +}
> +
>  static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
>  {
>  	stliport_t	*portp;
> @@ -2033,43 +2088,6 @@
>  				(tty->termios->c_cflag & ~CLOCAL) |
>  				(ival ? CLOCAL : 0);
>  		break;
> -	case TIOCMGET:
> -		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
> -		    sizeof(unsigned int))) == 0) {
> -			if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS,
> -			    &portp->asig, sizeof(asysigs_t), 1)) < 0)
> -				return(rc);
> -			lval = stli_mktiocm(portp->asig.sigvalue);
> -			put_user(lval, (unsigned int *) arg);
> -		}
> -		break;
> -	case TIOCMBIS:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			stli_mkasysigs(&portp->asig,
> -				((ival & TIOCM_DTR) ? 1 : -1),
> -				((ival & TIOCM_RTS) ? 1 : -1));
> -			rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
> -				&portp->asig, sizeof(asysigs_t), 0);
> -		}
> -		break;
> -	case TIOCMBIC:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			stli_mkasysigs(&portp->asig,
> -				((ival & TIOCM_DTR) ? 0 : -1),
> -				((ival & TIOCM_RTS) ? 0 : -1));
> -			rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
> -				&portp->asig, sizeof(asysigs_t), 0);
> -		}
> -		break;
> -	case TIOCMSET:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			stli_mkasysigs(&portp->asig,
> -				((ival & TIOCM_DTR) ? 1 : 0),
> -				((ival & TIOCM_RTS) ? 1 : 0));
> -			rc = stli_cmdwait(brdp, portp, A_SETSIGNALS,
> -				&portp->asig, sizeof(asysigs_t), 0);
> -		}
> -		break;
>  	case TIOCGSERIAL:
>  		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
>  		    sizeof(struct serial_struct))) == 0)
> @@ -5254,6 +5272,8 @@
>  	.wait_until_sent = stli_waituntilsent,
>  	.send_xchar = stli_sendxchar,
>  	.read_proc = stli_readproc,
> +	.tiocmget = stli_tiocmget,
> +	.tiocmset = stli_tiocmset,
>  };
>  
>  /*****************************************************************************/
> ===== drivers/char/rio/rio_linux.c 1.32 vs edited =====
> --- 1.32/drivers/char/rio/rio_linux.c	Tue Sep 30 01:34:28 2003
> +++ edited/drivers/char/rio/rio_linux.c	Tue Jan 13 15:01:40 2004
> @@ -728,6 +728,11 @@
>        rc = gs_setserial(&PortP->gs, (struct serial_struct *) arg);
>      break;
>  #if 0
> +  /*
> +   * note: these IOCTLs no longer reach here.  Use
> +   * tiocmset/tiocmget driver methods instead.  The
> +   * #if 0 disablement predates this comment.
> +   */
>    case TIOCMGET:
>      if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
>                            sizeof(unsigned int))) == 0) {
> ===== drivers/char/rocket.c 1.36 vs edited =====
> --- 1.36/drivers/char/rocket.c	Thu Oct  9 23:13:53 2003
> +++ edited/drivers/char/rocket.c	Tue Jan 13 16:28:49 2004
> @@ -1216,59 +1216,6 @@
>  /********************************************************************************************/
>  /*  Here are the routines used by rp_ioctl.  These are all called from exception handlers.  */
>  
> -static int get_modem_info(struct r_port *info, unsigned int *value)
> -{
> -	unsigned int control, result, ChanStatus;
> -
> -	ChanStatus = sGetChanStatusLo(&info->channel);
> -
> -	control = info->channel.TxControl[3];
> -	result = ((control & SET_RTS) ? TIOCM_RTS : 0) | 
> -		((control & SET_DTR) ?  TIOCM_DTR : 0) |
> -		((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
> -		(sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
> -		((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
> -		((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
> -
> -	if (copy_to_user(value, &result, sizeof (int)))
> -		return -EFAULT;
> -	return 0;
> -}
> -
> -static int set_modem_info(struct r_port *info, unsigned int cmd,
> -			  unsigned int *value)
> -{
> -	unsigned int arg;
> -
> -	if (copy_from_user(&arg, value, sizeof (int)))
> -		return -EFAULT;
> -
> -	switch (cmd) {
> -	case TIOCMBIS:
> -		if (arg & TIOCM_RTS)
> -			info->channel.TxControl[3] |= SET_RTS;
> -		if (arg & TIOCM_DTR)
> -			info->channel.TxControl[3] |= SET_DTR;
> -		break;
> -	case TIOCMBIC:
> -		if (arg & TIOCM_RTS)
> -			info->channel.TxControl[3] &= ~SET_RTS;
> -		if (arg & TIOCM_DTR)
> -			info->channel.TxControl[3] &= ~SET_DTR;
> -		break;
> -	case TIOCMSET:
> -		info->channel.TxControl[3] = ((info->channel.TxControl[3] & ~(SET_RTS | SET_DTR)) | 
> -					      ((arg & TIOCM_RTS) ? SET_RTS : 0) | 
> -					      ((arg & TIOCM_DTR) ? SET_DTR : 0));
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
> -	return 0;
> -}
> -
>  /*
>   *  Returns the state of the serial modem control lines.  These next 2 functions 
>   *  are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
> @@ -1432,12 +1379,6 @@
>  		return -ENXIO;
>  
>  	switch (cmd) {
> -	case TIOCMGET:
> -		return get_modem_info(info, (unsigned int *) arg);
> -	case TIOCMBIS:
> -	case TIOCMBIC:
> -	case TIOCMSET:
> -		return set_modem_info(info, cmd, (unsigned int *) arg);
>  	case RCKP_GET_STRUCT:
>  		if (copy_to_user((void *) arg, info, sizeof (struct r_port)))
>  			return -EFAULT;
> ===== drivers/char/sh-sci.c 1.25 vs edited =====
> --- 1.25/drivers/char/sh-sci.c	Wed Jun 11 20:32:39 2003
> +++ edited/drivers/char/sh-sci.c	Tue Jan 13 15:17:23 2004
> @@ -859,6 +859,31 @@
>  	return retval;
>  }
>  
> +static int sci_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	struct sci_port *port = tty->driver_data;
> +	return sci_getsignals(port);
> +}
> +
> +static int sci_tiocmset(struct tty_struct *tty, struct file *file,
> +			unsigned int set, unsigned int clear)
> +{
> +	struct sci_port *port = tty->driver_data;
> +	int rts = -1, dtr = -1;
> +
> +	if (set & TIOCM_RTS)
> +		rts = 1;
> +	if (set & TIOCM_DTR)
> +		dtr = 1;
> +	if (clear & TIOCM_RTS)
> +		rts = 0;
> +	if (clear & TIOCM_DTR)
> +		dtr = 0;
> +
> +	sci_setsignals(port, dtr, rts);
> +	return 0;
> +}
> +
>  static int sci_ioctl(struct tty_struct * tty, struct file * filp, 
>                       unsigned int cmd, unsigned long arg)
>  {
> @@ -889,25 +914,6 @@
>  			rc = gs_setserial(&port->gs,
>  					  (struct serial_struct *) arg);
>  		break;
> -	case TIOCMGET:
> -		ival = sci_getsignals(port);
> -		rc = put_user(ival, (unsigned int *) arg);
> -		break;
> -	case TIOCMBIS:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
> -			sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1),
> -			                     ((ival & TIOCM_RTS) ? 1 : -1));
> -		break;
> -	case TIOCMBIC:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
> -			sci_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1),
> -			                     ((ival & TIOCM_RTS) ? 0 : -1));
> -		break;
> -	case TIOCMSET:
> -		if ((rc = get_user(ival, (unsigned int *)arg)) == 0)
> -			sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
> -			                     ((ival & TIOCM_RTS) ? 1 : 0));
> -		break;
>  
>  	default:
>  		rc = -ENOIOCTLCMD;
> @@ -991,6 +997,8 @@
>  #ifdef CONFIG_PROC_FS
>  	.read_proc = sci_read_proc,
>  #endif
> +	.tiocmget = sci_tiocmget,
> +	.tiocmset = sci_tiocmset,
>  };
>  
>  /* ********************************************************************** *
> ===== drivers/char/stallion.c 1.37 vs edited =====
> --- 1.37/drivers/char/stallion.c	Tue Sep 30 01:34:28 2003
> +++ edited/drivers/char/stallion.c	Tue Jan 13 15:10:39 2004
> @@ -1514,6 +1514,48 @@
>  
>  /*****************************************************************************/
>  
> +static int stl_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	stlport_t	*portp;
> +
> +	if (tty == (struct tty_struct *) NULL)
> +		return(-ENODEV);
> +	portp = tty->driver_data;
> +	if (portp == (stlport_t *) NULL)
> +		return(-ENODEV);
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return(-EIO);
> +
> +	return stl_getsignals(portp);
> +}
> +
> +static int stl_tiocmset(struct tty_struct *tty, struct file *file,
> +			unsigned int set, unsigned int clear)
> +{
> +	stlport_t	*portp;
> +	int rts = -1, dtr = -1;
> +
> +	if (tty == (struct tty_struct *) NULL)
> +		return(-ENODEV);
> +	portp = tty->driver_data;
> +	if (portp == (stlport_t *) NULL)
> +		return(-ENODEV);
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return(-EIO);
> +
> +	if (set & TIOCM_RTS)
> +		rts = 1;
> +	if (set & TIOCM_DTR)
> +		dtr = 1;
> +	if (clear & TIOCM_RTS)
> +		rts = 0;
> +	if (clear & TIOCM_DTR)
> +		dtr = 0;
> +
> +	stl_setsignals(portp, dtr, rts);
> +	return 0;
> +}
> +
>  static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
>  {
>  	stlport_t	*portp;
> @@ -1553,37 +1595,6 @@
>  				(ival ? CLOCAL : 0);
>  		}
>  		break;
> -	case TIOCMGET:
> -		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
> -		    sizeof(unsigned int))) == 0) {
> -			ival = stl_getsignals(portp);
> -			put_user(ival, (unsigned int *) arg);
> -		}
> -		break;
> -	case TIOCMBIS:
> -		if ((rc = verify_area(VERIFY_READ, (void *) arg,
> -		    sizeof(unsigned int))) == 0) {
> -			get_user(ival, (unsigned int *) arg);
> -			stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : -1),
> -				((ival & TIOCM_RTS) ? 1 : -1));
> -		}
> -		break;
> -	case TIOCMBIC:
> -		if ((rc = verify_area(VERIFY_READ, (void *) arg,
> -		    sizeof(unsigned int))) == 0) {
> -			get_user(ival, (unsigned int *) arg);
> -			stl_setsignals(portp, ((ival & TIOCM_DTR) ? 0 : -1),
> -				((ival & TIOCM_RTS) ? 0 : -1));
> -		}
> -		break;
> -	case TIOCMSET:
> -		if ((rc = verify_area(VERIFY_READ, (void *) arg,
> -		    sizeof(unsigned int))) == 0) {
> -			get_user(ival, (unsigned int *) arg);
> -			stl_setsignals(portp, ((ival & TIOCM_DTR) ? 1 : 0),
> -				((ival & TIOCM_RTS) ? 1 : 0));
> -		}
> -		break;
>  	case TIOCGSERIAL:
>  		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
>  		    sizeof(struct serial_struct))) == 0)
> @@ -3137,6 +3148,8 @@
>  	.wait_until_sent = stl_waituntilsent,
>  	.send_xchar = stl_sendxchar,
>  	.read_proc = stl_readproc,
> +	.tiocmget = stl_tiocmget,
> +	.tiocmset = stl_tiocmset,
>  };
>  
>  /*****************************************************************************/
> ===== drivers/char/sx.c 1.42 vs edited =====
> --- 1.42/drivers/char/sx.c	Tue Dec 30 08:41:41 2003
> +++ edited/drivers/char/sx.c	Tue Jan 13 14:59:30 2004
> @@ -1743,6 +1743,32 @@
>  }
>  
>  
> +static int sx_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	struct sx_port *port = tty->driver_data;
> +	return sx_getsignals(port);
> +}
> +
> +static int sx_tiocmset(struct tty_struct *tty, struct file *file,
> +		       unsigned int set, unsigned int clear)
> +{
> +	struct sx_port *port = tty->driver_data;
> +	int rts = -1, cts = -1;
> +
> +	if (set & TIOCM_RTS)
> +		rts = 1;
> +	if (set & TIOCM_DTR)
> +		dtr = 1;
> +	if (clear & TIOCM_RTS)
> +		rts = 0;
> +	if (clear & TIOCM_DTR)
> +		dtr = 0;
> +
> +	sx_setsignals(port, dtr, rts);
> +	sx_reconfigure_port(port);
> +	return 0;
> +}
> +
>  static int sx_ioctl (struct tty_struct * tty, struct file * filp, 
>                       unsigned int cmd, unsigned long arg)
>  {
> @@ -1775,34 +1801,6 @@
>  		                      sizeof(struct serial_struct))) == 0)
>  			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
>  		break;
> -	case TIOCMGET:
> -		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
> -		                      sizeof(unsigned int))) == 0) {
> -			ival = sx_getsignals(port);
> -			put_user(ival, (unsigned int *) arg);
> -		}
> -		break;
> -	case TIOCMBIS:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			sx_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1),
> -			                     ((ival & TIOCM_RTS) ? 1 : -1));
> -			sx_reconfigure_port(port);
> -		}
> -		break;
> -	case TIOCMBIC:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			sx_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1),
> -			                     ((ival & TIOCM_RTS) ? 0 : -1));
> -			sx_reconfigure_port(port);
> -		}
> -		break;
> -	case TIOCMSET:
> -		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
> -			sx_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
> -			                     ((ival & TIOCM_RTS) ? 1 : 0));
> -			sx_reconfigure_port(port);
> -		}
> -		break;
>  	default:
>  		rc = -ENOIOCTLCMD;
>  		break;
> @@ -2217,6 +2215,8 @@
>  	.stop = gs_stop,
>  	.start = gs_start,
>  	.hangup = gs_hangup,
> +	.tiocmget = sx_tiocmget,
> +	.tiocmset = sx_tiocmset,
>  };
>  
>  static int sx_init_drivers(void)
> ===== drivers/macintosh/macserial.c 1.30 vs edited =====
> --- 1.30/drivers/macintosh/macserial.c	Wed Sep 24 07:15:15 2003
> +++ edited/drivers/macintosh/macserial.c	Tue Jan 13 14:55:37 2004
> @@ -1777,47 +1777,65 @@
>  	return put_user(status,value);
>  }
>  
> -static int get_modem_info(struct mac_serial *info, unsigned int *value)
> +static int rs_tiocmget(struct tty_struct *tty, struct file *file)
>  {
> +	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
>  	unsigned char control, status;
> -	unsigned int result;
>  	unsigned long flags;
>  
> +#ifdef CONFIG_KGDB
> +	if (info->kgdb_channel)
> +		return -ENODEV;
> +#endif
> +	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
> +		return -ENODEV;
> +
> +	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
> +	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT)) {
> +		if (tty->flags & (1 << TTY_IO_ERROR))
> +		    return -EIO;
> +	}
> +
>  	spin_lock_irqsave(&info->lock, flags);
>  	control = info->curregs[5];
>  	status = read_zsreg(info->zs_channel, 0);
>  	spin_unlock_irqrestore(&info->lock, flags);
> -	result =  ((control & RTS) ? TIOCM_RTS: 0)
> +	return    ((control & RTS) ? TIOCM_RTS: 0)
>  		| ((control & DTR) ? TIOCM_DTR: 0)
>  		| ((status  & DCD) ? TIOCM_CAR: 0)
>  		| ((status  & CTS) ? 0: TIOCM_CTS);
> -	return put_user(result,value);
>  }
>  
> -static int set_modem_info(struct mac_serial *info, unsigned int cmd,
> -			  unsigned int *value)
> +static int rs_tiocmset(struct tty_struct *tty, struct file *file,
> +		       unsigned int set, unsigned int clear)
>  {
> +	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
>  	unsigned int arg, bits;
>  	unsigned long flags;
>  
> -	if (get_user(arg, value))
> -		return -EFAULT;
> -	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
> -	spin_lock_irqsave(&info->lock, flags);
> -	switch (cmd) {
> -	case TIOCMBIS:
> -		info->curregs[5] |= bits;
> -		break;
> -	case TIOCMBIC:
> -		info->curregs[5] &= ~bits;
> -		break;
> -	case TIOCMSET:
> -		info->curregs[5] = (info->curregs[5] & ~(DTR | RTS)) | bits;
> -		break;
> -	default:
> -		spin_unlock_irqrestore(&info->lock, flags);
> -		return -EINVAL;
> +#ifdef CONFIG_KGDB
> +	if (info->kgdb_channel)
> +		return -ENODEV;
> +#endif
> +	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
> +		return -ENODEV;
> +
> +	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
> +	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT)) {
> +		if (tty->flags & (1 << TTY_IO_ERROR))
> +		    return -EIO;
>  	}
> +
> +	spin_lock_irqsave(&info->lock, flags);
> +	if (set & TIOCM_RTS)
> +		info->curregs[5] |= RTS;
> +	if (set & TIOCM_DTR)
> +		info->curregs[5] |= DTR;
> +	if (clear & TIOCM_RTS)
> +		info->curregs[5] &= ~RTS;
> +	if (clear & TIOCM_DTR)
> +		info->curregs[5] &= ~DTR;
> +
>  	info->pendregs[5] = info->curregs[5];
>  	write_zsreg(info->zs_channel, 5, info->curregs[5]);
>  	spin_unlock_irqrestore(&info->lock, flags);
> @@ -1863,12 +1881,6 @@
>  	}
>  
>  	switch (cmd) {
> -		case TIOCMGET:
> -			return get_modem_info(info, (unsigned int *) arg);
> -		case TIOCMBIS:
> -		case TIOCMBIC:
> -		case TIOCMSET:
> -			return set_modem_info(info, cmd, (unsigned int *) arg);
>  		case TIOCGSERIAL:
>  			return get_serial_info(info,
>  					(struct serial_struct __user *) arg);
> @@ -2488,6 +2500,8 @@
>  	.break_ctl = rs_break,
>  	.wait_until_sent = rs_wait_until_sent,
>  	.read_proc = macserial_read_proc,
> +	.tiocmget = rs_tiocmget,
> +	.tiocmset = rs_tiocmset,
>  };
>  
>  static int macserial_init(void)
> ===== drivers/s390/net/ctctty.c 1.20 vs edited =====
> --- 1.20/drivers/s390/net/ctctty.c	Mon Oct  6 11:59:26 2003
> +++ edited/drivers/s390/net/ctctty.c	Tue Jan 13 14:51:50 2004
> @@ -655,14 +655,19 @@
>  }
>  
>  
> -static int
> -ctc_tty_get_ctc_tty_info(ctc_tty_info * info, uint * value)
> +static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
>  {
> +	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
>  	u_char control,
>  	 status;
>  	uint result;
>  	ulong flags;
>  
> +	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
> +		return -ENODEV;
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return -EIO;
> +
>  	control = info->mcr;
>  	spin_lock_irqsave(&ctc_tty_lock, flags);
>  	status = info->msr;
> @@ -673,51 +678,31 @@
>  	    | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
>  	    | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
>  	    | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
> -	put_user(result, (uint *) value);
> -	return 0;
> +	return result;
>  }
>  
>  static int
> -ctc_tty_set_ctc_tty_info(ctc_tty_info * info, uint cmd, uint * value)
> +ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
> +		 unsigned int set, unsigned int clear)
>  {
> -	uint arg;
> -	int old_mcr = info->mcr & (UART_MCR_RTS | UART_MCR_DTR);
> +	ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
>  
> -	get_user(arg, (uint *) value);
> -	switch (cmd) {
> -		case TIOCMBIS:
> -#ifdef CTC_DEBUG_MODEM_IOCTL
> -			printk(KERN_DEBUG "%s%d ioctl TIOCMBIS\n", CTC_TTY_NAME,
> -			       info->line);
> -#endif
> -			if (arg & TIOCM_RTS)
> -				info->mcr |= UART_MCR_RTS;
> -			if (arg & TIOCM_DTR)
> -				info->mcr |= UART_MCR_DTR;
> -			break;
> -		case TIOCMBIC:
> -#ifdef CTC_DEBUG_MODEM_IOCTL
> -			printk(KERN_DEBUG "%s%d ioctl TIOCMBIC\n", CTC_TTY_NAME,
> -			       info->line);
> -#endif
> -			if (arg & TIOCM_RTS)
> -				info->mcr &= ~UART_MCR_RTS;
> -			if (arg & TIOCM_DTR)
> -				info->mcr &= ~UART_MCR_DTR;
> -			break;
> -		case TIOCMSET:
> -#ifdef CTC_DEBUG_MODEM_IOCTL
> -			printk(KERN_DEBUG "%s%d ioctl TIOCMSET\n", CTC_TTY_NAME,
> -			       info->line);
> -#endif
> -			info->mcr = ((info->mcr & ~(UART_MCR_RTS | UART_MCR_DTR))
> -				 | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
> -			       | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
> -			break;
> -		default:
> -			return -EINVAL;
> -	}
> -	if ((info->mcr  & (UART_MCR_RTS | UART_MCR_DTR)) != old_mcr)
> +	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
> +		return -ENODEV;
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return -EIO;
> +
> +	if (set & TIOCM_RTS)
> +		info->mcr |= UART_MCR_RTS;
> +	if (set & TIOCM_DTR)
> +		info->mcr |= UART_MCR_DTR;
> +
> +	if (clear & TIOCM_RTS)
> +		info->mcr &= ~UART_MCR_RTS;
> +	if (clear & TIOCM_DTR)
> +		info->mcr &= ~UART_MCR_DTR;
> +
> +	if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
>  		ctc_tty_transmit_status(info);
>  	return 0;
>  }
> @@ -775,22 +760,6 @@
>  			    ((tty->termios->c_cflag & ~CLOCAL) |
>  			     (arg ? CLOCAL : 0));
>  			return 0;
> -		case TIOCMGET:
> -#ifdef CTC_DEBUG_MODEM_IOCTL
> -			printk(KERN_DEBUG "%s%d ioctl TIOCMGET\n", CTC_TTY_NAME,
> -			       info->line);
> -#endif
> -			error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(uint));
> -			if (error)
> -				return error;
> -			return ctc_tty_get_ctc_tty_info(info, (uint *) arg);
> -		case TIOCMBIS:
> -		case TIOCMBIC:
> -		case TIOCMSET:
> -			error = verify_area(VERIFY_READ, (void *) arg, sizeof(uint));
> -			if (error)
> -				return error;
> -			return ctc_tty_set_ctc_tty_info(info, cmd, (uint *) arg);
>  		case TIOCSERGETLSR:	/* Get line status register */
>  #ifdef CTC_DEBUG_MODEM_IOCTL
>  			printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
> @@ -1142,6 +1111,8 @@
>  	.unthrottle = ctc_tty_unthrottle,
>  	.set_termios = ctc_tty_set_termios,
>  	.hangup = ctc_tty_hangup,
> +	.tiocmget = ctc_tty_tiocmget,
> +	.tiocmset = ctc_tty_tiocmset,
>  };
>  
>  int
> ===== drivers/serial/mcfserial.c 1.17 vs edited =====
> --- 1.17/drivers/serial/mcfserial.c	Thu Jul  3 02:18:07 2003
> +++ edited/drivers/serial/mcfserial.c	Tue Jan 13 13:22:09 2004
> @@ -985,6 +985,43 @@
>  	local_irq_restore(flags);
>  }
>  
> +static int mcfrs_tiocmget(struct tty_struct *tty, struct file *file)
> +{
> +	struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
> +
> +	if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl"))
> +		return -ENODEV;
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return -EIO;
> +
> +	return mcfrs_getsignals(info);
> +}
> +
> +static int mcfrs_tiocmset(struct tty_struct *tty, struct file *file,
> +			  unsigned int set, unsigned int clear)
> +{
> +	struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
> +	int rts = -1, dtr = -1;
> +
> +	if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl"))
> +		return -ENODEV;
> +	if (tty->flags & (1 << TTY_IO_ERROR))
> +		return -EIO;
> +
> +	if (set & TIOCM_RTS)
> +		rts = 1;
> +	if (set & TIOCM_DTR)
> +		dtr = 1;
> +	if (clear & TIOCM_RTS)
> +		rts = 0;
> +	if (clear & TIOCM_DTR)
> +		dtr = 0;
> +
> +	mcfrs_setsignals(info, dtr, rts);
> +
> +	return 0;
> +}
> +
>  static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
>  		    unsigned int cmd, unsigned long arg)
>  {
> @@ -1059,45 +1096,6 @@
>  				    info, sizeof(struct mcf_serial));
>  			return 0;
>  			
> -		case TIOCMGET:
> -			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
> -                            sizeof(unsigned int))))
> -                                return(error);
> -			val = mcfrs_getsignals(info);
> -			put_user(val, (unsigned int *) arg);
> -			break;
> -
> -                case TIOCMBIS:
> -			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
> -                            sizeof(unsigned int))))
> -				return(error);
> -
> -			get_user(val, (unsigned int *) arg);
> -			rts = (val & TIOCM_RTS) ? 1 : -1;
> -			dtr = (val & TIOCM_DTR) ? 1 : -1;
> -			mcfrs_setsignals(info, dtr, rts);
> -			break;
> -
> -                case TIOCMBIC:
> -			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
> -                            sizeof(unsigned int))))
> -				return(error);
> -			get_user(val, (unsigned int *) arg);
> -			rts = (val & TIOCM_RTS) ? 0 : -1;
> -			dtr = (val & TIOCM_DTR) ? 0 : -1;
> -			mcfrs_setsignals(info, dtr, rts);
> -			break;
> -
> -                case TIOCMSET:
> -			if ((error = verify_area(VERIFY_WRITE, (void *) arg,
> -                            sizeof(unsigned int))))
> -				return(error);
> -			get_user(val, (unsigned int *) arg);
> -			rts = (val & TIOCM_RTS) ? 1 : 0;
> -			dtr = (val & TIOCM_DTR) ? 1 : 0;
> -			mcfrs_setsignals(info, dtr, rts);
> -			break;
> -
>  #ifdef TIOCSET422
>  		case TIOCSET422:
>  			get_user(val, (unsigned int *) arg);
> @@ -1563,6 +1561,8 @@
>  	.start = mcfrs_start,
>  	.hangup = mcfrs_hangup,
>  	.read_proc = mcfrs_readproc,
> +	.tiocmget = mcfrs_tiocmget,
> +	.tiocmset = mcfrs_tiocmset,
>  };
>  
>  /* mcfrs_init inits the driver */
> ===== drivers/usb/serial/ftdi_sio.c 1.55 vs edited =====
> --- 1.55/drivers/usb/serial/ftdi_sio.c	Tue Oct 28 13:44:01 2003
> +++ edited/drivers/usb/serial/ftdi_sio.c	Tue Jan 13 14:16:51 2004
> @@ -580,6 +580,8 @@
>  static void ftdi_break_ctl		(struct usb_serial_port *port, int break_state );
>  static void ftdi_throttle		(struct usb_serial_port *port);
>  static void ftdi_unthrottle		(struct usb_serial_port *port);
> +static int  ftdi_tiocmget		(struct usb_serial_port *port, struct file * file);
> +static int  ftdi_tiocmset		(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
>  
>  static unsigned short int ftdi_232am_baud_base_to_divisor (int baud, int base);
>  static unsigned short int ftdi_232am_baud_to_divisor (int baud);
> @@ -608,6 +610,8 @@
>  	.break_ctl =		ftdi_break_ctl,
>  	.attach =		ftdi_SIO_startup,
>  	.shutdown =		ftdi_shutdown,
> +	.tiocmget =		ftdi_tiocmget,
> +	.tiocmset =		ftdi_tiocmset,
>  };
>  
>  static struct usb_serial_device_type ftdi_8U232AM_device = {
> @@ -632,6 +636,8 @@
>  	.break_ctl =		ftdi_break_ctl,
>  	.attach =		ftdi_8U232AM_startup,
>  	.shutdown =		ftdi_shutdown,
> +	.tiocmget =		ftdi_tiocmget,
> +	.tiocmset =		ftdi_tiocmset,
>  };
>  
>  static struct usb_serial_device_type ftdi_FT232BM_device = {
> @@ -656,6 +662,8 @@
>  	.break_ctl =		ftdi_break_ctl,
>  	.attach =		ftdi_FT232BM_startup,
>  	.shutdown =		ftdi_shutdown,
> +	.tiocmget =		ftdi_tiocmget,
> +	.tiocmset =		ftdi_tiocmset,
>  };
>  
>  static struct usb_serial_device_type ftdi_USB_UIRT_device = {
> @@ -680,6 +688,8 @@
>  	.break_ctl =		ftdi_break_ctl,
>  	.attach =		ftdi_USB_UIRT_startup,
>  	.shutdown =		ftdi_shutdown,
> +	.tiocmget =		ftdi_tiocmget,
> +	.tiocmset =		ftdi_tiocmset,
>  };
>  
>  /* The TIRA1 is based on a  FT232BM which requires a fixed baud rate of 100000
> @@ -706,6 +716,8 @@
>  	.break_ctl =		ftdi_break_ctl,
>  	.attach =		ftdi_HE_TIRA1_startup,
>  	.shutdown =		ftdi_shutdown,
> +	.tiocmget =		ftdi_tiocmget,
> +	.tiocmset =		ftdi_tiocmset,
>  };
>  
>  
> @@ -1808,119 +1820,94 @@
>  } /* ftdi_termios */
>  
>  
> -static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
> +static int ftdi_tiocmget (struct usb_serial_port *port, struct file * file)
>  {
>  	struct usb_serial *serial = port->serial;
>  	struct ftdi_private *priv = usb_get_serial_port_data(port);
> -
> -	__u16 urb_value=0; /* Will hold the new flags */
>  	char buf[2];
> -	int  ret, mask;
> -	
> -	dbg("%s cmd 0x%04x", __FUNCTION__, cmd);
> -
> -	/* Based on code from acm.c and others */
> -	switch (cmd) {
> +	int  ret;
>  
> -	case TIOCMGET:
> -		dbg("%s TIOCMGET", __FUNCTION__);
> -		switch (priv->chip_type) {
> -		case SIO:
> -			/* Request the status from the device */
> -			if ((ret = usb_control_msg(serial->dev, 
> -						   usb_rcvctrlpipe(serial->dev, 0),
> -						   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
> -						   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
> -						   0, 0, 
> -						   buf, 1, WDR_TIMEOUT)) < 0 ) {
> -				err("%s Could not get modem status of device - err: %d", __FUNCTION__,
> -				    ret);
> -				return(ret);
> -			}
> -			break;
> -		case FT8U232AM:
> -		case FT232BM:
> -			/* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
> -			   format as the data returned from the in point */
> -			if ((ret = usb_control_msg(serial->dev, 
> -						   usb_rcvctrlpipe(serial->dev, 0),
> -						   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
> -						   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
> -						   0, 0, 
> -						   buf, 2, WDR_TIMEOUT)) < 0 ) {
> -				err("%s Could not get modem status of device - err: %d", __FUNCTION__,
> -				    ret);
> -				return(ret);
> -			}
> -			break;
> -		default:
> -			return -EFAULT;
> -			break;
> +	dbg("%s TIOCMGET", __FUNCTION__);
> +	switch (priv->chip_type) {
> +	case SIO:
> +		/* Request the status from the device */
> +		if ((ret = usb_control_msg(serial->dev, 
> +					   usb_rcvctrlpipe(serial->dev, 0),
> +					   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
> +					   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
> +					   0, 0, 
> +					   buf, 1, WDR_TIMEOUT)) < 0 ) {
> +			err("%s Could not get modem status of device - err: %d", __FUNCTION__,
> +			    ret);
> +			return(ret);
>  		}
> -
> -		return put_user((buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
> -				(buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
> -				(buf[0]  & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
> -				(buf[0]  & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0) |
> -				priv->last_dtr_rts,
> -				(unsigned long *) arg);
>  		break;
> +	case FT8U232AM:
> +	case FT232BM:
> +		/* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
> +		   format as the data returned from the in point */
> +		if ((ret = usb_control_msg(serial->dev, 
> +					   usb_rcvctrlpipe(serial->dev, 0),
> +					   FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
> +					   FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
> +					   0, 0, 
> +					   buf, 2, WDR_TIMEOUT)) < 0 ) {
> +			err("%s Could not get modem status of device - err: %d", __FUNCTION__,
> +			    ret);
> +			return(ret);
> +		}
> +		break;
> +	default:
> +		return -EFAULT;
> +		break;
> +	}
> +
> +	return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
> +	       (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
> +	       (buf[0] & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
> +	       (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0) |
> +	       priv->last_dtr_rts;
> +}
> +
> +static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
> +{
> +	struct usb_serial *serial = port->serial;
> +	struct ftdi_private *priv = usb_get_serial_port_data(port);
> +	__u16 urb_value;
> +	int  ret;
> +
> +	dbg("%s TIOCMSET/BIC/BIS", __FUNCTION__);
>  
> -	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
> -		dbg("%s TIOCMSET", __FUNCTION__);
> -		if (get_user(mask, (unsigned long *) arg))
> -			return -EFAULT;
> -		urb_value = ((mask & TIOCM_DTR) ? HIGH : LOW);
> +	if ((set | clear) & TIOCM_DTR) {
> +		urb_value = (set & TIOCM_DTR) ? HIGH : LOW;
>  		if ((ret = set_dtr(port, urb_value)) < 0){
> -			err("Error from DTR set urb (TIOCMSET)");
> +			err("Error from DTR set urb (TIOCM)");
>  			return(ret);
>  		}
> -		urb_value = ((mask & TIOCM_RTS) ? HIGH : LOW);
> +	}
> +	if ((set | clear) & TIOCM_RTS) {
> +		urb_value = (set & TIOCM_RTS) ? HIGH : LOW;
>  		if ((ret = set_rts(port, urb_value)) < 0){
> -			err("Error from RTS set urb (TIOCMSET)");
> +			err("Error from RTS set urb (TIOCM)");
>  			return(ret);
>  		}
> -		return(0);
> -		break;
> -					
> -	case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
> -		dbg("%s TIOCMBIS", __FUNCTION__);
> - 	        if (get_user(mask, (unsigned long *) arg))
> -			return -EFAULT;
> -  	        if (mask & TIOCM_DTR){
> -			if ((ret = set_dtr(port, HIGH)) < 0) {
> -				err("Urb to set DTR failed");
> -				return(ret);
> -			}
> -		}
> -		if (mask & TIOCM_RTS) {
> -			if ((ret = set_rts(port, HIGH)) < 0){
> -				err("Urb to set RTS failed");
> -				return(ret);
> -			}
> -		}
> -		return(0);
> -		break;
> +	}
> +	return(0);
> +}
>  
> -	case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
> -		dbg("%s TIOCMBIC", __FUNCTION__);
> - 	        if (get_user(mask, (unsigned long *) arg))
> -			return -EFAULT;
> -  	        if (mask & TIOCM_DTR){
> -			if ((ret = set_dtr(port, LOW)) < 0){
> -				err("Urb to unset DTR failed");
> -				return(ret);
> -			}
> -		}	
> -		if (mask & TIOCM_RTS) {
> -			if ((ret = set_rts(port, LOW)) < 0){
> -				err("Urb to unset RTS failed");
> -				return(ret);
> -			}
> -		}
> -		return(0);
> -		break;
> +static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
> +{
> +	struct usb_serial *serial = port->serial;
> +	struct ftdi_private *priv = usb_get_serial_port_data(port);
>  
> +	__u16 urb_value=0; /* Will hold the new flags */
> +	char buf[2];
> +	int  ret, mask;
> +	
> +	dbg("%s cmd 0x%04x", __FUNCTION__, cmd);
> +
> +	/* Based on code from acm.c and others */
> +	switch (cmd) {
>  		/*
>  		 * I had originally implemented TCSET{A,S}{,F,W} and
>  		 * TCGET{A,S} here separately, however when testing I
> 

-- 
Henrique Oliveira
Product Marketing Specialist
Cyclades Corporation
http://www.cyclades.com
Phone: 510.771.6205
Fax:   510.771.6200
email: henrique.oliveira@cyclades.com


  reply	other threads:[~2004-01-13 18:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-13 11:00 [PROBLEM] ircomm ioctls Jozef Vesely
2004-01-13 11:36 ` Russell King
2004-01-13 11:49   ` Outstanding fixups (was: Re: [PROBLEM] ircomm ioctls) Russell King
2004-01-13 17:15     ` Russell King
2004-01-13 17:24       ` [1/3] Serial fixups (mostly tested) Russell King
2004-01-24  6:16         ` [lkml] pseudo tty / kernel compile question Karl Tatgenhorst
2004-01-25 21:53           ` David Woodhouse
2004-01-13 17:33       ` [2/3] Russell King
2004-01-13 17:55         ` Henrique Oliveira [this message]
2004-01-13 18:53           ` [2/3] John Stoffel
2004-01-13 22:15         ` [2/3] Paul Mackerras
2004-01-14  7:01           ` [2/3] Benjamin Herrenschmidt
2004-01-16 11:34             ` [2/3] Matthias Urlichs
2004-01-16  0:54         ` [2/3] Greg KH
2004-01-18 12:43         ` [2/3] Greg Ungerer
2004-01-18 15:42           ` [2/3] Russell King
2004-01-18 23:23             ` [2/3] Greg Ungerer
2004-01-13 17:42       ` [3/3] 2.6 broken serial drivers Russell King
2004-01-13 20:21         ` Andrew Morton
2004-01-13 21:10           ` Russell King
2004-01-18 16:16             ` Russell King
2004-01-14 12:42         ` Maciej W. Rozycki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4004310B.4090802@cyclades.com \
    --to=henrique.oliveira@cyclades.com \
    --cc=daniela@cyclades.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rmk+lkml@arm.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.