Re: usbrsa: dead lock usbrsa_write/usbrsa_write_room

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

in regards to the buffering effect I observed -- I am hopeful that I have 
found a fix:
I have now extended the chars_in_buffer function to return the sum of the 
bytes stored in the URB pool awaiting transmission and the bytes in the tx 
buffer of the USB-RSA. Now, the tty layer calls the close function of the 
driver once all URBs are transferred to USB-RSA AND the USB-RSA emptied its tx 
buffer. 

The earlier implementation of chars_in_buffer just returned the number of 
bytes waiting in the URB pool. The close function would be called once all 
URBs were transferred to the USB-RSA.  The close function disables the 
transmit interrupt of the USB-RSA's serial port. If many data was queued, the 
close function would be called before the USB-RSA had finished its 
transmission over serial interface. So much for the hard facts. 

I think what caused the buffering effect is this: The trailing "0d 0a" was 
transferred to the USBRSA's tx buffer, and from there moved to the fifo of 
USBRSA's serial port (The fifo is 16 bytes deep. An ST16C550 implements the 
serial port). The close function shut off the tx interrupt of the serial port 
thereby stopping the transmission on the serial line. The tty layer's next 
call to the open function would reenable the tx interrupt, and the remaining 
data and with it the trailing "0d 0a" held in the fifo would be sent to the 
receiving port.

Here my chars_in_buffer function:

static int usbrsa_chars_in_buffer(struct tty_struct *tty)
{
	struct usb_serial_port*		port = tty->driver_data;
	struct usbrsa_port_private*	priv = usb_get_serial_port_data(port);
	int 				chars = 0;
	int 				i = 0;
	unsigned long			flags;
	long				t;
	int				retval;
	
	dbg("%s() port = %d", __func__, port->number);

	spin_lock_irqsave(&priv->lock, flags);
	//bytes in TX buffer of USBRSA
	chars = priv->nofTxMaxBytes - priv->nofTxBytesFree;

	// account for URBs in the pool and not yet transferred to the USB-RSA
	for (i=0;i<priv->urb_pool_size;i++)
	{
		if (test_bit(i,&priv->write_urb_pool_lock) != 0)
		{
			chars += 
                         priv->write_urb_pool[i]->transfer_buffer_length;
		}
	}

	spin_unlock_irqrestore(&priv->lock, flags);

	chars_in_buffer_exit:
	dbg("%s(): %d", __func__, chars);
	return chars;
}

Cheers Tilman

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux