LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (http://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   self written usb driver: received data is retransmitted (http://www.linuxquestions.org/questions/linux-kernel-70/self-written-usb-driver-received-data-is-retransmitted-927957/)

tilman1 02-06-2012 04:13 PM

self written usb driver: received data is retransmitted
 
Hi,

I am writting a driver for a serial converter.
In principle, receiving and sending data already works.
Data that is received is however echoed and thereby retransmitted on the tx feed. I suspect the tty layer, but know to little about it to really pinpoint it to that.

Looking at other postings, this question might be too detailed and too close to the kernel for the forum. If so, I would appreciate information on where to sent this question to.

Thank you and best regards

Tilman



Debug message from /var/log/messages
Code:

[ 7357.548188] usbrsa ttyUSB1: usbrsa_read_callback - length = 4, data = 41 42 43 44
[ 7357.548200] drivers/usb/serial/usbrsa.c: usbrsa_write_room(): 640
[ 7357.548203] drivers/usb/serial/usbrsa.c: usbrsa_write - port 1
[ 7357.548238] usbrsa ttyUSB1: usbrsa_write - length = 1, data = 42
[ 7357.548247] drivers/usb/serial/usbrsa.c: usbrsa_write_room(): 512
[ 7357.548261] usbrsa ttyUSB1: usbrsa_write - length = 1, data = 43
[ 7357.548270] drivers/usb/serial/usbrsa.c: usbrsa_write_room(): 448
[ 7357.548281] drivers/usb/serial/usbrsa.c: usbrsa_write - port 1{  [ 7357.548283] usbrsa ttyUSB1: usbrsa_write - length = 1, data = 44


Here a code fragment from the completion handler that processes the received data from the usb-to-serial-convertor. The received data is stored in a transfer buffer to which data points.
Am I doing this correctly ?
Code:

        data = urb->transfer_buffer;
        tty = tty_port_tty_get(&port->port);
        if (tty != NULL && urb->actual_length > 0) {
                tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
        tty_kref_put(tty);


vedasolutions 02-07-2012 03:46 AM

Your read call back code is okay. Based on some conditions received characters are echoed in the tty layer.
Check the function n_tty_receive_char() in drivers/tty/n_tty.c. This function echoes the charactors on the tx
using the process_echoes() function. You can put the printk's in the n_tty_recieve_char() and check which condition
is met to make the characters echoed on tx. You can even use stty command on your device file and check the condtions.

tilman1 02-07-2012 03:25 PM

stty -F /dev/ttyUSB1 -echo prevents the characters being echoed.

The tty flags are however only persisted if the device is opened:
stty -F /dev/ttyUSB1 -echo is only persisted if I keep the device opened by cat /dev/ttyUSB1.
I guess that set_termios function is lacking something. But what ?

Code:

static void usbrsa_set_termios(struct tty_struct *tty,
        struct usb_serial_port *port, struct ktermios *old_termios)
{
        struct usbrsa_port_private*        priv = usb_get_serial_port_data(port);
        unsigned int                        cflag;
        speed_t                                baud_rate;
        unsigned long                        flags;
        int                                retval;
        int                                retries = 3;
       
        dbg("%s - port %d", __func__, port->number);
       
       
        if (!tty)
        {
                dbg("%s(): no tty structures", __func__);
                return;
        }
       
        if (I_IXOFF(tty) || I_IXON(tty))
        {
                priv->xon = START_CHAR(tty);
                priv->xoff = STOP_CHAR(tty);
                dbg("%s - XON = %2x, XOFF = %2x",
                                __func__, priv->xon, priv->xoff );
        }
        cflag = tty->termios->c_cflag;
       
        /* get the baud rate wanted */
        baud_rate        = tty_get_baud_rate(tty);
        dbg("%s - baudrate = %u",__func__, baud_rate );
       
        // compute values for baud rate counter and LCR. Then sent to USB-RSA
        while(retries > 0)
        {
                spin_lock_irqsave(&priv->lock, flags);
                if (!(test_bit(LOCK_BAUDRATE_LCR,&priv->urb_lock)))
                {       
                        prepare_baudrate_lcr_urb(cflag,
                                        baud_rate,
                                        priv->baudrate_lcr_urb->transfer_buffer);
                       
                        set_bit(LOCK_BAUDRATE_LCR,&priv->urb_lock);
                        spin_unlock_irqrestore(&priv->lock, flags);
                       
                        retval = usb_submit_urb(priv->baudrate_lcr_urb,GFP_KERNEL);
                       
                        if (retval != 0)
                        {
                                dev_err(&port->dev, "%s(): usb_submit_urb() failed"
                                                    " with error %d\n", __func__, retval);
                                spin_lock_irqsave(&priv->lock, flags);
                                clear_bit(LOCK_BAUDRATE_LCR,&priv->urb_lock);
                                spin_unlock_irqrestore(&priv->lock, flags);
                                retries--;
                        }
                }
                else
                {
                        spin_unlock_irqrestore(&priv->lock, flags);
                        retries--;
                }
        }
       
}


tilman1 02-08-2012 07:22 AM

Found it. Actually, there is nothing lacking but too much:
I had set usb_serial_driver.init_termios to an init function assuming that it is only called if the driver initializes, i.e. when the function assigned to the attach-hook (usb_serial_driver.attach) is called by the usb system. I wonder what the init_termios hook is normally used for ?

Thanks
Tilman


All times are GMT -5. The time now is 01:35 PM.