diff options
| -rw-r--r-- | drivers/usb/serial/oti6858.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index a65be37bf129..e199b0f4f99c 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
| @@ -76,8 +76,6 @@ static struct usb_driver oti6858_driver = { | |||
| 76 | 76 | ||
| 77 | static int debug; | 77 | static int debug; |
| 78 | 78 | ||
| 79 | #define OTI6858_FIFO_SIZE 1024 | ||
| 80 | |||
| 81 | /* requests */ | 79 | /* requests */ |
| 82 | #define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) | 80 | #define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00) |
| 83 | #define OTI6858_REQ_T_GET_STATUS 0x01 | 81 | #define OTI6858_REQ_T_GET_STATUS 0x01 |
| @@ -180,7 +178,6 @@ static struct usb_serial_driver oti6858_device = { | |||
| 180 | struct oti6858_private { | 178 | struct oti6858_private { |
| 181 | spinlock_t lock; | 179 | spinlock_t lock; |
| 182 | 180 | ||
| 183 | struct kfifo write_fifo; | ||
| 184 | struct oti6858_control_pkt status; | 181 | struct oti6858_control_pkt status; |
| 185 | 182 | ||
| 186 | struct { | 183 | struct { |
| @@ -293,9 +290,12 @@ static void send_data(struct work_struct *work) | |||
| 293 | return; | 290 | return; |
| 294 | } | 291 | } |
| 295 | priv->flags.write_urb_in_use = 1; | 292 | priv->flags.write_urb_in_use = 1; |
| 296 | |||
| 297 | count = kfifo_len(&priv->write_fifo); | ||
| 298 | spin_unlock_irqrestore(&priv->lock, flags); | 293 | spin_unlock_irqrestore(&priv->lock, flags); |
| 294 | |||
| 295 | spin_lock_irqsave(&port->lock, flags); | ||
| 296 | count = kfifo_len(&port->write_fifo); | ||
| 297 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 298 | |||
| 299 | if (count > port->bulk_out_size) | 299 | if (count > port->bulk_out_size) |
| 300 | count = port->bulk_out_size; | 300 | count = port->bulk_out_size; |
| 301 | 301 | ||
| @@ -329,9 +329,9 @@ static void send_data(struct work_struct *work) | |||
| 329 | return; | 329 | return; |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | count = kfifo_out_locked(&priv->write_fifo, | 332 | count = kfifo_out_locked(&port->write_fifo, |
| 333 | port->write_urb->transfer_buffer, | 333 | port->write_urb->transfer_buffer, |
| 334 | count, &priv->lock); | 334 | count, &port->lock); |
| 335 | port->write_urb->transfer_buffer_length = count; | 335 | port->write_urb->transfer_buffer_length = count; |
| 336 | port->write_urb->dev = port->serial->dev; | 336 | port->write_urb->dev = port->serial->dev; |
| 337 | result = usb_submit_urb(port->write_urb, GFP_NOIO); | 337 | result = usb_submit_urb(port->write_urb, GFP_NOIO); |
| @@ -354,11 +354,6 @@ static int oti6858_startup(struct usb_serial *serial) | |||
| 354 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); | 354 | priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); |
| 355 | if (!priv) | 355 | if (!priv) |
| 356 | break; | 356 | break; |
| 357 | if (kfifo_alloc(&priv->write_fifo, OTI6858_FIFO_SIZE, | ||
| 358 | GFP_KERNEL)) { | ||
| 359 | kfree(priv); | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | 357 | ||
| 363 | spin_lock_init(&priv->lock); | 358 | spin_lock_init(&priv->lock); |
| 364 | init_waitqueue_head(&priv->intr_wait); | 359 | init_waitqueue_head(&priv->intr_wait); |
| @@ -375,7 +370,6 @@ static int oti6858_startup(struct usb_serial *serial) | |||
| 375 | 370 | ||
| 376 | for (--i; i >= 0; --i) { | 371 | for (--i; i >= 0; --i) { |
| 377 | priv = usb_get_serial_port_data(serial->port[i]); | 372 | priv = usb_get_serial_port_data(serial->port[i]); |
| 378 | kfifo_free(&priv->write_fifo); | ||
| 379 | kfree(priv); | 373 | kfree(priv); |
| 380 | usb_set_serial_port_data(serial->port[i], NULL); | 374 | usb_set_serial_port_data(serial->port[i], NULL); |
| 381 | } | 375 | } |
| @@ -385,14 +379,12 @@ static int oti6858_startup(struct usb_serial *serial) | |||
| 385 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, | 379 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
| 386 | const unsigned char *buf, int count) | 380 | const unsigned char *buf, int count) |
| 387 | { | 381 | { |
| 388 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
| 389 | |||
| 390 | dbg("%s(port = %d, count = %d)", __func__, port->number, count); | 382 | dbg("%s(port = %d, count = %d)", __func__, port->number, count); |
| 391 | 383 | ||
| 392 | if (!count) | 384 | if (!count) |
| 393 | return count; | 385 | return count; |
| 394 | 386 | ||
| 395 | count = kfifo_in_locked(&priv->write_fifo, buf, count, &priv->lock); | 387 | count = kfifo_in_locked(&port->write_fifo, buf, count, &port->lock); |
| 396 | 388 | ||
| 397 | return count; | 389 | return count; |
| 398 | } | 390 | } |
| @@ -400,15 +392,14 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 400 | static int oti6858_write_room(struct tty_struct *tty) | 392 | static int oti6858_write_room(struct tty_struct *tty) |
| 401 | { | 393 | { |
| 402 | struct usb_serial_port *port = tty->driver_data; | 394 | struct usb_serial_port *port = tty->driver_data; |
| 403 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
| 404 | int room = 0; | 395 | int room = 0; |
| 405 | unsigned long flags; | 396 | unsigned long flags; |
| 406 | 397 | ||
| 407 | dbg("%s(port = %d)", __func__, port->number); | 398 | dbg("%s(port = %d)", __func__, port->number); |
| 408 | 399 | ||
| 409 | spin_lock_irqsave(&priv->lock, flags); | 400 | spin_lock_irqsave(&port->lock, flags); |
| 410 | room = kfifo_avail(&priv->write_fifo); | 401 | room = kfifo_avail(&port->write_fifo); |
| 411 | spin_unlock_irqrestore(&priv->lock, flags); | 402 | spin_unlock_irqrestore(&port->lock, flags); |
| 412 | 403 | ||
| 413 | return room; | 404 | return room; |
| 414 | } | 405 | } |
| @@ -416,15 +407,14 @@ static int oti6858_write_room(struct tty_struct *tty) | |||
| 416 | static int oti6858_chars_in_buffer(struct tty_struct *tty) | 407 | static int oti6858_chars_in_buffer(struct tty_struct *tty) |
| 417 | { | 408 | { |
| 418 | struct usb_serial_port *port = tty->driver_data; | 409 | struct usb_serial_port *port = tty->driver_data; |
| 419 | struct oti6858_private *priv = usb_get_serial_port_data(port); | ||
| 420 | int chars = 0; | 410 | int chars = 0; |
| 421 | unsigned long flags; | 411 | unsigned long flags; |
| 422 | 412 | ||
| 423 | dbg("%s(port = %d)", __func__, port->number); | 413 | dbg("%s(port = %d)", __func__, port->number); |
| 424 | 414 | ||
| 425 | spin_lock_irqsave(&priv->lock, flags); | 415 | spin_lock_irqsave(&port->lock, flags); |
| 426 | chars = kfifo_len(&priv->write_fifo); | 416 | chars = kfifo_len(&port->write_fifo); |
| 427 | spin_unlock_irqrestore(&priv->lock, flags); | 417 | spin_unlock_irqrestore(&port->lock, flags); |
| 428 | 418 | ||
| 429 | return chars; | 419 | return chars; |
| 430 | } | 420 | } |
| @@ -615,10 +605,10 @@ static void oti6858_close(struct usb_serial_port *port) | |||
| 615 | 605 | ||
| 616 | dbg("%s(port = %d)", __func__, port->number); | 606 | dbg("%s(port = %d)", __func__, port->number); |
| 617 | 607 | ||
| 618 | spin_lock_irqsave(&priv->lock, flags); | 608 | spin_lock_irqsave(&port->lock, flags); |
| 619 | /* clear out any remaining data in the buffer */ | 609 | /* clear out any remaining data in the buffer */ |
| 620 | kfifo_reset_out(&priv->write_fifo); | 610 | kfifo_reset_out(&port->write_fifo); |
| 621 | spin_unlock_irqrestore(&priv->lock, flags); | 611 | spin_unlock_irqrestore(&port->lock, flags); |
| 622 | 612 | ||
| 623 | dbg("%s(): after buf_clear()", __func__); | 613 | dbg("%s(): after buf_clear()", __func__); |
| 624 | 614 | ||
| @@ -760,18 +750,12 @@ static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | |||
| 760 | 750 | ||
| 761 | static void oti6858_release(struct usb_serial *serial) | 751 | static void oti6858_release(struct usb_serial *serial) |
| 762 | { | 752 | { |
| 763 | struct oti6858_private *priv; | ||
| 764 | int i; | 753 | int i; |
| 765 | 754 | ||
| 766 | dbg("%s()", __func__); | 755 | dbg("%s()", __func__); |
| 767 | 756 | ||
| 768 | for (i = 0; i < serial->num_ports; ++i) { | 757 | for (i = 0; i < serial->num_ports; ++i) |
| 769 | priv = usb_get_serial_port_data(serial->port[i]); | 758 | kfree(usb_get_serial_port_data(serial->port[i])); |
| 770 | if (priv) { | ||
| 771 | kfifo_free(&priv->write_fifo); | ||
| 772 | kfree(priv); | ||
| 773 | } | ||
| 774 | } | ||
| 775 | } | 759 | } |
| 776 | 760 | ||
| 777 | static void oti6858_read_int_callback(struct urb *urb) | 761 | static void oti6858_read_int_callback(struct urb *urb) |
| @@ -864,10 +848,14 @@ static void oti6858_read_int_callback(struct urb *urb) | |||
| 864 | } | 848 | } |
| 865 | } else if (!transient) { | 849 | } else if (!transient) { |
| 866 | unsigned long flags; | 850 | unsigned long flags; |
| 851 | int count; | ||
| 852 | |||
| 853 | spin_lock_irqsave(&port->lock, flags); | ||
| 854 | count = kfifo_len(&port->write_fifo); | ||
| 855 | spin_unlock_irqrestore(&port->lock, flags); | ||
| 867 | 856 | ||
| 868 | spin_lock_irqsave(&priv->lock, flags); | 857 | spin_lock_irqsave(&priv->lock, flags); |
| 869 | if (priv->flags.write_urb_in_use == 0 | 858 | if (priv->flags.write_urb_in_use == 0 && count != 0) { |
| 870 | && kfifo_len(&priv->write_fifo) != 0) { | ||
| 871 | schedule_delayed_work(&priv->delayed_write_work, 0); | 859 | schedule_delayed_work(&priv->delayed_write_work, 0); |
| 872 | resubmit = 0; | 860 | resubmit = 0; |
| 873 | } | 861 | } |
