USB: serial: add generic wait_until_sent implementation
Add generic wait_until_sent implementation which polls for empty hardware buffers using the new port-operation tx_empty. The generic implementation will be used for all sub-drivers that implement tx_empty but does not define wait_until_sent. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0693196fe7
commit
dcf0105039
|
@ -253,6 +253,37 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
|
||||
|
||||
void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout)
|
||||
{
|
||||
struct usb_serial_port *port = tty->driver_data;
|
||||
unsigned int bps;
|
||||
unsigned long period;
|
||||
unsigned long expire;
|
||||
|
||||
bps = tty_get_baud_rate(tty);
|
||||
if (!bps)
|
||||
bps = 9600; /* B0 */
|
||||
/*
|
||||
* Use a poll-period of roughly the time it takes to send one
|
||||
* character or at least one jiffy.
|
||||
*/
|
||||
period = max_t(unsigned long, (10 * HZ / bps), 1);
|
||||
period = min_t(unsigned long, period, timeout);
|
||||
|
||||
dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n",
|
||||
__func__, jiffies_to_msecs(timeout),
|
||||
jiffies_to_msecs(period));
|
||||
expire = jiffies + timeout;
|
||||
while (!port->serial->type->tx_empty(port)) {
|
||||
schedule_timeout_interruptible(period);
|
||||
if (signal_pending(current))
|
||||
break;
|
||||
if (time_after(jiffies, expire))
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent);
|
||||
|
||||
static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
|
||||
int index, gfp_t mem_flags)
|
||||
{
|
||||
|
|
|
@ -1333,6 +1333,8 @@ static void usb_serial_operations_init(struct usb_serial_driver *device)
|
|||
set_to_generic_if_null(device, close);
|
||||
set_to_generic_if_null(device, write_room);
|
||||
set_to_generic_if_null(device, chars_in_buffer);
|
||||
if (device->tx_empty)
|
||||
set_to_generic_if_null(device, wait_until_sent);
|
||||
set_to_generic_if_null(device, read_bulk_callback);
|
||||
set_to_generic_if_null(device, write_bulk_callback);
|
||||
set_to_generic_if_null(device, process_read_urb);
|
||||
|
|
|
@ -269,6 +269,7 @@ struct usb_serial_driver {
|
|||
void (*break_ctl)(struct tty_struct *tty, int break_state);
|
||||
int (*chars_in_buffer)(struct tty_struct *tty);
|
||||
void (*wait_until_sent)(struct tty_struct *tty, long timeout);
|
||||
bool (*tx_empty)(struct usb_serial_port *port);
|
||||
void (*throttle)(struct tty_struct *tty);
|
||||
void (*unthrottle)(struct tty_struct *tty);
|
||||
int (*tiocmget)(struct tty_struct *tty);
|
||||
|
@ -328,6 +329,8 @@ extern void usb_serial_generic_close(struct usb_serial_port *port);
|
|||
extern int usb_serial_generic_resume(struct usb_serial *serial);
|
||||
extern int usb_serial_generic_write_room(struct tty_struct *tty);
|
||||
extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
|
||||
extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty,
|
||||
long timeout);
|
||||
extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
|
||||
extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
|
||||
extern void usb_serial_generic_throttle(struct tty_struct *tty);
|
||||
|
|
Loading…
Reference in a new issue