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
					
				
			
		
					 3 changed files with 36 additions and 0 deletions
				
			
		| 
						 | 
					@ -253,6 +253,37 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer);
 | 
					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,
 | 
					static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port,
 | 
				
			||||||
						int index, gfp_t mem_flags)
 | 
											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, close);
 | 
				
			||||||
	set_to_generic_if_null(device, write_room);
 | 
						set_to_generic_if_null(device, write_room);
 | 
				
			||||||
	set_to_generic_if_null(device, chars_in_buffer);
 | 
						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, read_bulk_callback);
 | 
				
			||||||
	set_to_generic_if_null(device, write_bulk_callback);
 | 
						set_to_generic_if_null(device, write_bulk_callback);
 | 
				
			||||||
	set_to_generic_if_null(device, process_read_urb);
 | 
						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);
 | 
						void (*break_ctl)(struct tty_struct *tty, int break_state);
 | 
				
			||||||
	int  (*chars_in_buffer)(struct tty_struct *tty);
 | 
						int  (*chars_in_buffer)(struct tty_struct *tty);
 | 
				
			||||||
	void (*wait_until_sent)(struct tty_struct *tty, long timeout);
 | 
						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 (*throttle)(struct tty_struct *tty);
 | 
				
			||||||
	void (*unthrottle)(struct tty_struct *tty);
 | 
						void (*unthrottle)(struct tty_struct *tty);
 | 
				
			||||||
	int  (*tiocmget)(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_resume(struct usb_serial *serial);
 | 
				
			||||||
extern int usb_serial_generic_write_room(struct tty_struct *tty);
 | 
					extern int usb_serial_generic_write_room(struct tty_struct *tty);
 | 
				
			||||||
extern int usb_serial_generic_chars_in_buffer(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_read_bulk_callback(struct urb *urb);
 | 
				
			||||||
extern void usb_serial_generic_write_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);
 | 
					extern void usb_serial_generic_throttle(struct tty_struct *tty);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue