Re: Support for Quatech ESU2-100 USB 2.0 8-port serial adaptor

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

 



> +	qt2_box_flush(serial, port->number, QT2_FLUSH_TX); /* flush tx buffer */
> +	qt2_box_flush(serial, port->number, QT2_FLUSH_RX); /* flush rx buffer */
> +	/* now wait for the flags to magically go back to being true */
> +	jift = jiffies + (10 * HZ);
> +	do {
> +		if ((port_extra->rcv_flush == true) &&

Horkkkk...


Use wait_event and wakeup not busy loops.

Also btw if you implement the chars_in_buffer() method the kernel will
wait for that to report 0 before closing. That is the correct way to
handle it as the functionality is also needed for things like break
handling.

> +	jift = jiffies + (10 * HZ);	/* 10 sec timeout */
> +	do {
> +		status = qt2_box_get_register(serial, port->number,
> +			QT2_LINE_STATUS_REGISTER, &lsr_value);
> +		if (status < 0) {
> +			dbg("%s(): qt2_box_get_register failed", __func__);
> +			break;
> +		}
> +		if ((lsr_value & QT2_LSR_TEMT)) {
> +			dbg("UART done sending");
> +			break;
> +		}
> +		schedule();

If you have to poll then it might be a good idea to sleep between polls
so you don't jam up the USB bus.


> +/* called to deliver writes from the next layer up to the device */
> +static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port,
> +		const unsigned char *buf, int count)
> +{
> +	struct usb_serial *serial;	/* parent device struct */
> +	__u8 header_array[5];	/* header used to direct writes to the correct

You will save yourself an enormous amount of pain if you ignore the
existing USB drivers on this one (as they mostly suck rocks) and
implement a proper 4K or so FIFO. That cleans up so much its unbelievable
(especially as we have the kfifo API ...). At that point you get proper
buffering and you just empty the fifo into an URB every time you get a
completion for the last one.

> +static int qt2_write_room(struct tty_struct *tty)
> +{
> +	struct usb_serial_port *port = tty->driver_data;
> +		/* parent usb_serial_port pointer */
> +	struct quatech2_port *port_extra;	/* extra data for this port */
> +	int room = 0;
> +	port_extra = qt2_get_port_private(port);
> +
> +	if (port_extra->close_pending == true) {
> +		dbg("%s(): port_extra->close_pending == true", __func__);
> +		return -ENODEV;
> +	}
> +
> +	dbg("%s(): port %d", __func__, port->number);
> +	if ((port->write_urb->status != -EINPROGRESS) &&
> +		(port_extra->tx_pending_bytes == 0))
> +		room = port->bulk_out_size - QT2_TX_HEADER_LENGTH;
> +	return room;

This value must never go down by more than bytes written - its a promise
which a lot of USB drivers don't properly keep causing lost chars etc

> +static int qt2_ioctl(struct tty_struct *tty, struct file *file,
> +		     unsigned int cmd, unsigned long arg)

This looks pretty bogus.

TIOCMGET/TIOCMSET are not passed to the driver ioctl method but to your
mget and mset operators so you can dump that lot in favour of the code
you have later.


>
> +	} else if (cmd == TIOCMIWAIT) {
> +		dbg("%s() port %d, cmd == TIOCMIWAIT enter",
> +			__func__, port->number);

This one if provided does need to be in the ioctl handler.

> +		prev_msr_value = port_extra->shadowMSR  & SERIAL_MSR_MASK;
> +		while (1) {
> +			add_wait_queue(&port_extra->wait, &wait);
> +			set_current_state(TASK_INTERRUPTIBLE);
> +			schedule();
> +			dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
> +				__func__, port->number);
> +			remove_wait_queue(&port_extra->wait, &wait);
> +			/* see if a signal woke us up */
> +			if (signal_pending(current))
> +				return -ERESTARTSYS;
> +			msr_value = port_extra->shadowMSR & SERIAL_MSR_MASK;
> +			if (msr_value == prev_msr_value)
> +				return -EIO;  /* no change - error */

Why is this an error and not just a spurious wake up ?

What about disconnecting the adapter btw - shouldn't that break out of
the loop with an error ?


>
--
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