diff options
-rw-r--r-- | drivers/usb/serial/omninet.c | 93 |
1 files changed, 17 insertions, 76 deletions
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 558a620d8868..efcd7feed6f4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -1,6 +1,8 @@ /* * USB ZyXEL omni.net LCD PLUS driver * + * Copyright (C) 2013,2017 Johan Hovold <johan@kernel.org> + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. @@ -32,10 +34,8 @@ /* function prototypes */ static void omninet_process_read_urb(struct urb *urb); -static void omninet_write_bulk_callback(struct urb *urb); -static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); -static int omninet_write_room(struct tty_struct *tty); +static int omninet_prepare_write_buffer(struct usb_serial_port *port, + void *buf, size_t count); static int omninet_calc_num_ports(struct usb_serial *serial, struct usb_serial_endpoints *epds); static int omninet_port_probe(struct usb_serial_port *port); @@ -59,10 +59,8 @@ static struct usb_serial_driver zyxel_omninet_device = { .calc_num_ports = omninet_calc_num_ports, .port_probe = omninet_port_probe, .port_remove = omninet_port_remove, - .write = omninet_write, - .write_room = omninet_write_room, - .write_bulk_callback = omninet_write_bulk_callback, .process_read_urb = omninet_process_read_urb, + .prepare_write_buffer = omninet_prepare_write_buffer, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -157,81 +155,24 @@ static void omninet_process_read_urb(struct urb *urb) tty_flip_buffer_push(&port->port); } -static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count) +static int omninet_prepare_write_buffer(struct usb_serial_port *port, + void *buf, size_t count) { struct omninet_data *od = usb_get_serial_port_data(port); - struct omninet_header *header = (struct omninet_header *) - port->write_urb->transfer_buffer; - int result; - - if (count == 0) { - dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__); - return 0; - } - - if (!test_and_clear_bit(0, &port->write_urbs_free)) { - dev_dbg(&port->dev, "%s - already writing\n", __func__); - return 0; - } - - count = (count > OMNINET_PAYLOADSIZE) ? OMNINET_PAYLOADSIZE : count; - - memcpy(port->write_urb->transfer_buffer + OMNINET_HEADERLEN, - buf, count); - - usb_serial_debug_data(&port->dev, __func__, count, - port->write_urb->transfer_buffer); - - header->oh_seq = od->od_outseq++; - header->oh_len = count; - header->oh_xxx = 0x03; - header->oh_pad = 0x00; - - /* send the data out the bulk port, always 64 bytes */ - port->write_urb->transfer_buffer_length = OMNINET_BULKOUTSIZE; - - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) { - set_bit(0, &port->write_urbs_free); - dev_err_console(port, - "%s - failed submitting write urb, error %d\n", - __func__, result); - } else - result = count; - - return result; -} - - -static int omninet_write_room(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - int room = 0; /* Default: no room */ + struct omninet_header *header = buf; - if (test_bit(0, &port->write_urbs_free)) - room = port->bulk_out_size - OMNINET_HEADERLEN; + count = min_t(size_t, count, OMNINET_PAYLOADSIZE); - dev_dbg(&port->dev, "%s - returns %d\n", __func__, room); + count = kfifo_out_locked(&port->write_fifo, buf + OMNINET_HEADERLEN, + count, &port->lock); - return room; -} - -static void omninet_write_bulk_callback(struct urb *urb) -{ -/* struct omninet_header *header = (struct omninet_header *) - urb->transfer_buffer; */ - struct usb_serial_port *port = urb->context; - int status = urb->status; - - set_bit(0, &port->write_urbs_free); - if (status) { - dev_dbg(&port->dev, "%s - nonzero write bulk status received: %d\n", - __func__, status); - return; - } + header->oh_seq = od->od_outseq++; + header->oh_len = count; + header->oh_xxx = 0x03; + header->oh_pad = 0x00; - usb_serial_port_softint(port); + /* always 64 bytes */ + return OMNINET_BULKOUTSIZE; } module_usb_serial_driver(serial_drivers, id_table); |