aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2012-03-22 11:50:55 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-10 16:32:07 -0400
commit5c0c7582a618e843bdcf9c4b20d019d8ffd176ee (patch)
tree79429a3d1e56e3ba960f600bd85a495c20a25dce /drivers/usb
parenta6765cbafa1570617fd68e4ff5fa525329c72e66 (diff)
USB: whiteheat: reimplement using generic framework
Kill custom list-based read and write implementations and reimplement using the generic framework. Compile-only tested. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/whiteheat.c539
1 files changed, 8 insertions, 531 deletions
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 522bf850a05d..c141b472b6a2 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -95,10 +95,6 @@ static void whiteheat_release(struct usb_serial *serial);
95static int whiteheat_open(struct tty_struct *tty, 95static int whiteheat_open(struct tty_struct *tty,
96 struct usb_serial_port *port); 96 struct usb_serial_port *port);
97static void whiteheat_close(struct usb_serial_port *port); 97static void whiteheat_close(struct usb_serial_port *port);
98static int whiteheat_write(struct tty_struct *tty,
99 struct usb_serial_port *port,
100 const unsigned char *buf, int count);
101static int whiteheat_write_room(struct tty_struct *tty);
102static int whiteheat_ioctl(struct tty_struct *tty, 98static int whiteheat_ioctl(struct tty_struct *tty,
103 unsigned int cmd, unsigned long arg); 99 unsigned int cmd, unsigned long arg);
104static void whiteheat_set_termios(struct tty_struct *tty, 100static void whiteheat_set_termios(struct tty_struct *tty,
@@ -107,11 +103,6 @@ static int whiteheat_tiocmget(struct tty_struct *tty);
107static int whiteheat_tiocmset(struct tty_struct *tty, 103static int whiteheat_tiocmset(struct tty_struct *tty,
108 unsigned int set, unsigned int clear); 104 unsigned int set, unsigned int clear);
109static void whiteheat_break_ctl(struct tty_struct *tty, int break_state); 105static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
110static int whiteheat_chars_in_buffer(struct tty_struct *tty);
111static void whiteheat_throttle(struct tty_struct *tty);
112static void whiteheat_unthrottle(struct tty_struct *tty);
113static void whiteheat_read_callback(struct urb *urb);
114static void whiteheat_write_callback(struct urb *urb);
115 106
116static struct usb_serial_driver whiteheat_fake_device = { 107static struct usb_serial_driver whiteheat_fake_device = {
117 .driver = { 108 .driver = {
@@ -137,18 +128,13 @@ static struct usb_serial_driver whiteheat_device = {
137 .release = whiteheat_release, 128 .release = whiteheat_release,
138 .open = whiteheat_open, 129 .open = whiteheat_open,
139 .close = whiteheat_close, 130 .close = whiteheat_close,
140 .write = whiteheat_write,
141 .write_room = whiteheat_write_room,
142 .ioctl = whiteheat_ioctl, 131 .ioctl = whiteheat_ioctl,
143 .set_termios = whiteheat_set_termios, 132 .set_termios = whiteheat_set_termios,
144 .break_ctl = whiteheat_break_ctl, 133 .break_ctl = whiteheat_break_ctl,
145 .tiocmget = whiteheat_tiocmget, 134 .tiocmget = whiteheat_tiocmget,
146 .tiocmset = whiteheat_tiocmset, 135 .tiocmset = whiteheat_tiocmset,
147 .chars_in_buffer = whiteheat_chars_in_buffer, 136 .throttle = usb_serial_generic_throttle,
148 .throttle = whiteheat_throttle, 137 .unthrottle = usb_serial_generic_unthrottle,
149 .unthrottle = whiteheat_unthrottle,
150 .read_bulk_callback = whiteheat_read_callback,
151 .write_bulk_callback = whiteheat_write_callback,
152}; 138};
153 139
154static struct usb_serial_driver * const serial_drivers[] = { 140static struct usb_serial_driver * const serial_drivers[] = {
@@ -165,29 +151,8 @@ struct whiteheat_command_private {
165 __u8 result_buffer[64]; 151 __u8 result_buffer[64];
166}; 152};
167 153
168
169#define THROTTLED 0x01
170#define ACTUALLY_THROTTLED 0x02
171
172static int urb_pool_size = 8;
173
174struct whiteheat_urb_wrap {
175 struct list_head list;
176 struct urb *urb;
177};
178
179struct whiteheat_private { 154struct whiteheat_private {
180 spinlock_t lock;
181 __u8 flags;
182 __u8 mcr; /* FIXME: no locking on mcr */ 155 __u8 mcr; /* FIXME: no locking on mcr */
183 struct list_head rx_urbs_free;
184 struct list_head rx_urbs_submitted;
185 struct list_head rx_urb_q;
186 struct work_struct rx_work;
187 struct usb_serial_port *port;
188 struct list_head tx_urbs_free;
189 struct list_head tx_urbs_submitted;
190 struct mutex deathwarrant;
191}; 156};
192 157
193 158
@@ -197,12 +162,6 @@ static void stop_command_port(struct usb_serial *serial);
197static void command_port_write_callback(struct urb *urb); 162static void command_port_write_callback(struct urb *urb);
198static void command_port_read_callback(struct urb *urb); 163static void command_port_read_callback(struct urb *urb);
199 164
200static int start_port_read(struct usb_serial_port *port);
201static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
202 struct list_head *head);
203static struct list_head *list_first(struct list_head *head);
204static void rx_data_softint(struct work_struct *work);
205
206static int firm_send_command(struct usb_serial_port *port, __u8 command, 165static int firm_send_command(struct usb_serial_port *port, __u8 command,
207 __u8 *data, __u8 datasize); 166 __u8 *data, __u8 datasize);
208static int firm_open(struct usb_serial_port *port); 167static int firm_open(struct usb_serial_port *port);
@@ -348,11 +307,6 @@ static int whiteheat_attach(struct usb_serial *serial)
348 __u8 *command; 307 __u8 *command;
349 __u8 *result; 308 __u8 *result;
350 int i; 309 int i;
351 int j;
352 struct urb *urb;
353 int buf_size;
354 struct whiteheat_urb_wrap *wrap;
355 struct list_head *tmp;
356 310
357 command_port = serial->port[COMMAND_PORT]; 311 command_port = serial->port[COMMAND_PORT];
358 312
@@ -422,72 +376,7 @@ static int whiteheat_attach(struct usb_serial *serial)
422 goto no_private; 376 goto no_private;
423 } 377 }
424 378
425 spin_lock_init(&info->lock);
426 mutex_init(&info->deathwarrant);
427 info->flags = 0;
428 info->mcr = 0; 379 info->mcr = 0;
429 INIT_WORK(&info->rx_work, rx_data_softint);
430 info->port = port;
431
432 INIT_LIST_HEAD(&info->rx_urbs_free);
433 INIT_LIST_HEAD(&info->rx_urbs_submitted);
434 INIT_LIST_HEAD(&info->rx_urb_q);
435 INIT_LIST_HEAD(&info->tx_urbs_free);
436 INIT_LIST_HEAD(&info->tx_urbs_submitted);
437
438 for (j = 0; j < urb_pool_size; j++) {
439 urb = usb_alloc_urb(0, GFP_KERNEL);
440 if (!urb) {
441 dev_err(&port->dev, "No free urbs available\n");
442 goto no_rx_urb;
443 }
444 buf_size = port->read_urb->transfer_buffer_length;
445 urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
446 if (!urb->transfer_buffer) {
447 dev_err(&port->dev,
448 "Couldn't allocate urb buffer\n");
449 goto no_rx_buf;
450 }
451 wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
452 if (!wrap) {
453 dev_err(&port->dev,
454 "Couldn't allocate urb wrapper\n");
455 goto no_rx_wrap;
456 }
457 usb_fill_bulk_urb(urb, serial->dev,
458 usb_rcvbulkpipe(serial->dev,
459 port->bulk_in_endpointAddress),
460 urb->transfer_buffer, buf_size,
461 whiteheat_read_callback, port);
462 wrap->urb = urb;
463 list_add(&wrap->list, &info->rx_urbs_free);
464
465 urb = usb_alloc_urb(0, GFP_KERNEL);
466 if (!urb) {
467 dev_err(&port->dev, "No free urbs available\n");
468 goto no_tx_urb;
469 }
470 buf_size = port->write_urb->transfer_buffer_length;
471 urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
472 if (!urb->transfer_buffer) {
473 dev_err(&port->dev,
474 "Couldn't allocate urb buffer\n");
475 goto no_tx_buf;
476 }
477 wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
478 if (!wrap) {
479 dev_err(&port->dev,
480 "Couldn't allocate urb wrapper\n");
481 goto no_tx_wrap;
482 }
483 usb_fill_bulk_urb(urb, serial->dev,
484 usb_sndbulkpipe(serial->dev,
485 port->bulk_out_endpointAddress),
486 urb->transfer_buffer, buf_size,
487 whiteheat_write_callback, port);
488 wrap->urb = urb;
489 list_add(&wrap->list, &info->tx_urbs_free);
490 }
491 380
492 usb_set_serial_port_data(port, info); 381 usb_set_serial_port_data(port, info);
493 } 382 }
@@ -530,29 +419,6 @@ no_command_private:
530 for (i = serial->num_ports - 1; i >= 0; i--) { 419 for (i = serial->num_ports - 1; i >= 0; i--) {
531 port = serial->port[i]; 420 port = serial->port[i];
532 info = usb_get_serial_port_data(port); 421 info = usb_get_serial_port_data(port);
533 for (j = urb_pool_size - 1; j >= 0; j--) {
534 tmp = list_first(&info->tx_urbs_free);
535 list_del(tmp);
536 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
537 urb = wrap->urb;
538 kfree(wrap);
539no_tx_wrap:
540 kfree(urb->transfer_buffer);
541no_tx_buf:
542 usb_free_urb(urb);
543no_tx_urb:
544 tmp = list_first(&info->rx_urbs_free);
545 list_del(tmp);
546 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
547 urb = wrap->urb;
548 kfree(wrap);
549no_rx_wrap:
550 kfree(urb->transfer_buffer);
551no_rx_buf:
552 usb_free_urb(urb);
553no_rx_urb:
554 ;
555 }
556 kfree(info); 422 kfree(info);
557no_private: 423no_private:
558 ; 424 ;
@@ -568,12 +434,7 @@ no_command_buffer:
568static void whiteheat_release(struct usb_serial *serial) 434static void whiteheat_release(struct usb_serial *serial)
569{ 435{
570 struct usb_serial_port *command_port; 436 struct usb_serial_port *command_port;
571 struct usb_serial_port *port;
572 struct whiteheat_private *info; 437 struct whiteheat_private *info;
573 struct whiteheat_urb_wrap *wrap;
574 struct urb *urb;
575 struct list_head *tmp;
576 struct list_head *tmp2;
577 int i; 438 int i;
578 439
579 dbg("%s", __func__); 440 dbg("%s", __func__);
@@ -583,31 +444,14 @@ static void whiteheat_release(struct usb_serial *serial)
583 kfree(usb_get_serial_port_data(command_port)); 444 kfree(usb_get_serial_port_data(command_port));
584 445
585 for (i = 0; i < serial->num_ports; i++) { 446 for (i = 0; i < serial->num_ports; i++) {
586 port = serial->port[i]; 447 info = usb_get_serial_port_data(serial->port[i]);
587 info = usb_get_serial_port_data(port);
588 list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
589 list_del(tmp);
590 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
591 urb = wrap->urb;
592 kfree(wrap);
593 kfree(urb->transfer_buffer);
594 usb_free_urb(urb);
595 }
596 list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) {
597 list_del(tmp);
598 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
599 urb = wrap->urb;
600 kfree(wrap);
601 kfree(urb->transfer_buffer);
602 usb_free_urb(urb);
603 }
604 kfree(info); 448 kfree(info);
605 } 449 }
606} 450}
607 451
608static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) 452static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
609{ 453{
610 int retval = 0; 454 int retval;
611 455
612 dbg("%s - port %d", __func__, port->number); 456 dbg("%s - port %d", __func__, port->number);
613 457
@@ -615,9 +459,6 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
615 if (retval) 459 if (retval)
616 goto exit; 460 goto exit;
617 461
618 if (tty)
619 tty->low_latency = 1;
620
621 /* send an open port command */ 462 /* send an open port command */
622 retval = firm_open(port); 463 retval = firm_open(port);
623 if (retval) { 464 if (retval) {
@@ -639,17 +480,12 @@ static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
639 usb_clear_halt(port->serial->dev, port->read_urb->pipe); 480 usb_clear_halt(port->serial->dev, port->read_urb->pipe);
640 usb_clear_halt(port->serial->dev, port->write_urb->pipe); 481 usb_clear_halt(port->serial->dev, port->write_urb->pipe);
641 482
642 /* Start reading from the device */ 483 retval = usb_serial_generic_open(tty, port);
643 retval = start_port_read(port);
644 if (retval) { 484 if (retval) {
645 dev_err(&port->dev,
646 "%s - failed submitting read urb, error %d\n",
647 __func__, retval);
648 firm_close(port); 485 firm_close(port);
649 stop_command_port(port->serial); 486 stop_command_port(port->serial);
650 goto exit; 487 goto exit;
651 } 488 }
652
653exit: 489exit:
654 dbg("%s - exit, retval = %d", __func__, retval); 490 dbg("%s - exit, retval = %d", __func__, retval);
655 return retval; 491 return retval;
@@ -658,125 +494,14 @@ exit:
658 494
659static void whiteheat_close(struct usb_serial_port *port) 495static void whiteheat_close(struct usb_serial_port *port)
660{ 496{
661 struct whiteheat_private *info = usb_get_serial_port_data(port);
662 struct whiteheat_urb_wrap *wrap;
663 struct urb *urb;
664 struct list_head *tmp;
665 struct list_head *tmp2;
666
667 dbg("%s - port %d", __func__, port->number); 497 dbg("%s - port %d", __func__, port->number);
668 498
669 firm_report_tx_done(port); 499 firm_report_tx_done(port);
670 firm_close(port); 500 firm_close(port);
671 501
672 /* shutdown our bulk reads and writes */ 502 usb_serial_generic_close(port);
673 mutex_lock(&info->deathwarrant);
674 spin_lock_irq(&info->lock);
675 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
676 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
677 urb = wrap->urb;
678 list_del(tmp);
679 spin_unlock_irq(&info->lock);
680 usb_kill_urb(urb);
681 spin_lock_irq(&info->lock);
682 list_add(tmp, &info->rx_urbs_free);
683 }
684 list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
685 list_move(tmp, &info->rx_urbs_free);
686 list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
687 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
688 urb = wrap->urb;
689 list_del(tmp);
690 spin_unlock_irq(&info->lock);
691 usb_kill_urb(urb);
692 spin_lock_irq(&info->lock);
693 list_add(tmp, &info->tx_urbs_free);
694 }
695 spin_unlock_irq(&info->lock);
696 mutex_unlock(&info->deathwarrant);
697 stop_command_port(port->serial);
698}
699
700
701static int whiteheat_write(struct tty_struct *tty,
702 struct usb_serial_port *port, const unsigned char *buf, int count)
703{
704 struct whiteheat_private *info = usb_get_serial_port_data(port);
705 struct whiteheat_urb_wrap *wrap;
706 struct urb *urb;
707 int result;
708 int bytes;
709 int sent = 0;
710 unsigned long flags;
711 struct list_head *tmp;
712
713 dbg("%s - port %d", __func__, port->number);
714
715 if (count == 0) {
716 dbg("%s - write request of 0 bytes", __func__);
717 return (0);
718 }
719
720 while (count) {
721 spin_lock_irqsave(&info->lock, flags);
722 if (list_empty(&info->tx_urbs_free)) {
723 spin_unlock_irqrestore(&info->lock, flags);
724 break;
725 }
726 tmp = list_first(&info->tx_urbs_free);
727 list_del(tmp);
728 spin_unlock_irqrestore(&info->lock, flags);
729
730 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
731 urb = wrap->urb;
732 bytes = (count > port->bulk_out_size) ?
733 port->bulk_out_size : count;
734 memcpy(urb->transfer_buffer, buf + sent, bytes);
735
736 usb_serial_debug_data(debug, &port->dev,
737 __func__, bytes, urb->transfer_buffer);
738
739 urb->transfer_buffer_length = bytes;
740 result = usb_submit_urb(urb, GFP_ATOMIC);
741 if (result) {
742 dev_err_console(port,
743 "%s - failed submitting write urb, error %d\n",
744 __func__, result);
745 sent = result;
746 spin_lock_irqsave(&info->lock, flags);
747 list_add(tmp, &info->tx_urbs_free);
748 spin_unlock_irqrestore(&info->lock, flags);
749 break;
750 } else {
751 sent += bytes;
752 count -= bytes;
753 spin_lock_irqsave(&info->lock, flags);
754 list_add(tmp, &info->tx_urbs_submitted);
755 spin_unlock_irqrestore(&info->lock, flags);
756 }
757 }
758 503
759 return sent; 504 stop_command_port(port->serial);
760}
761
762static int whiteheat_write_room(struct tty_struct *tty)
763{
764 struct usb_serial_port *port = tty->driver_data;
765 struct whiteheat_private *info = usb_get_serial_port_data(port);
766 struct list_head *tmp;
767 int room = 0;
768 unsigned long flags;
769
770 dbg("%s - port %d", __func__, port->number);
771
772 spin_lock_irqsave(&info->lock, flags);
773 list_for_each(tmp, &info->tx_urbs_free)
774 room++;
775 spin_unlock_irqrestore(&info->lock, flags);
776 room *= port->bulk_out_size;
777
778 dbg("%s - returns %d", __func__, room);
779 return (room);
780} 505}
781 506
782static int whiteheat_tiocmget(struct tty_struct *tty) 507static int whiteheat_tiocmget(struct tty_struct *tty)
@@ -836,7 +561,7 @@ static int whiteheat_ioctl(struct tty_struct *tty,
836 serstruct.line = port->serial->minor; 561 serstruct.line = port->serial->minor;
837 serstruct.port = port->number; 562 serstruct.port = port->number;
838 serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; 563 serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
839 serstruct.xmit_fifo_size = port->bulk_out_size; 564 serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
840 serstruct.custom_divisor = 0; 565 serstruct.custom_divisor = 0;
841 serstruct.baud_base = 460800; 566 serstruct.baud_base = 460800;
842 serstruct.close_delay = CLOSING_DELAY; 567 serstruct.close_delay = CLOSING_DELAY;
@@ -866,60 +591,6 @@ static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
866} 591}
867 592
868 593
869static int whiteheat_chars_in_buffer(struct tty_struct *tty)
870{
871 struct usb_serial_port *port = tty->driver_data;
872 struct whiteheat_private *info = usb_get_serial_port_data(port);
873 struct list_head *tmp;
874 struct whiteheat_urb_wrap *wrap;
875 int chars = 0;
876 unsigned long flags;
877
878 dbg("%s - port %d", __func__, port->number);
879
880 spin_lock_irqsave(&info->lock, flags);
881 list_for_each(tmp, &info->tx_urbs_submitted) {
882 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
883 chars += wrap->urb->transfer_buffer_length;
884 }
885 spin_unlock_irqrestore(&info->lock, flags);
886
887 dbg("%s - returns %d", __func__, chars);
888 return chars;
889}
890
891
892static void whiteheat_throttle(struct tty_struct *tty)
893{
894 struct usb_serial_port *port = tty->driver_data;
895 struct whiteheat_private *info = usb_get_serial_port_data(port);
896
897 dbg("%s - port %d", __func__, port->number);
898
899 spin_lock_irq(&info->lock);
900 info->flags |= THROTTLED;
901 spin_unlock_irq(&info->lock);
902}
903
904
905static void whiteheat_unthrottle(struct tty_struct *tty)
906{
907 struct usb_serial_port *port = tty->driver_data;
908 struct whiteheat_private *info = usb_get_serial_port_data(port);
909 int actually_throttled;
910
911 dbg("%s - port %d", __func__, port->number);
912
913 spin_lock_irq(&info->lock);
914 actually_throttled = info->flags & ACTUALLY_THROTTLED;
915 info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
916 spin_unlock_irq(&info->lock);
917
918 if (actually_throttled)
919 rx_data_softint(&info->rx_work);
920}
921
922
923/***************************************************************************** 594/*****************************************************************************
924 * Connect Tech's White Heat callback routines 595 * Connect Tech's White Heat callback routines
925 *****************************************************************************/ 596 *****************************************************************************/
@@ -988,80 +659,6 @@ static void command_port_read_callback(struct urb *urb)
988} 659}
989 660
990 661
991static void whiteheat_read_callback(struct urb *urb)
992{
993 struct usb_serial_port *port = urb->context;
994 struct whiteheat_urb_wrap *wrap;
995 unsigned char *data = urb->transfer_buffer;
996 struct whiteheat_private *info = usb_get_serial_port_data(port);
997 int status = urb->status;
998
999 dbg("%s - port %d", __func__, port->number);
1000
1001 spin_lock(&info->lock);
1002 wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
1003 if (!wrap) {
1004 spin_unlock(&info->lock);
1005 dev_err(&port->dev, "%s - Not my urb!\n", __func__);
1006 return;
1007 }
1008 list_del(&wrap->list);
1009 spin_unlock(&info->lock);
1010
1011 if (status) {
1012 dbg("%s - nonzero read bulk status received: %d",
1013 __func__, status);
1014 spin_lock(&info->lock);
1015 list_add(&wrap->list, &info->rx_urbs_free);
1016 spin_unlock(&info->lock);
1017 return;
1018 }
1019
1020 usb_serial_debug_data(debug, &port->dev,
1021 __func__, urb->actual_length, data);
1022
1023 spin_lock(&info->lock);
1024 list_add_tail(&wrap->list, &info->rx_urb_q);
1025 if (info->flags & THROTTLED) {
1026 info->flags |= ACTUALLY_THROTTLED;
1027 spin_unlock(&info->lock);
1028 return;
1029 }
1030 spin_unlock(&info->lock);
1031
1032 schedule_work(&info->rx_work);
1033}
1034
1035
1036static void whiteheat_write_callback(struct urb *urb)
1037{
1038 struct usb_serial_port *port = urb->context;
1039 struct whiteheat_private *info = usb_get_serial_port_data(port);
1040 struct whiteheat_urb_wrap *wrap;
1041 int status = urb->status;
1042
1043 dbg("%s - port %d", __func__, port->number);
1044
1045 spin_lock(&info->lock);
1046 wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
1047 if (!wrap) {
1048 spin_unlock(&info->lock);
1049 dev_err(&port->dev, "%s - Not my urb!\n", __func__);
1050 return;
1051 }
1052 list_move(&wrap->list, &info->tx_urbs_free);
1053 spin_unlock(&info->lock);
1054
1055 if (status) {
1056 dbg("%s - nonzero write bulk status received: %d",
1057 __func__, status);
1058 return;
1059 }
1060
1061 usb_serial_port_softint(port);
1062}
1063
1064
1065/***************************************************************************** 662/*****************************************************************************
1066 * Connect Tech's White Heat firmware interface 663 * Connect Tech's White Heat firmware interface
1067 *****************************************************************************/ 664 *****************************************************************************/
@@ -1336,123 +933,6 @@ static void stop_command_port(struct usb_serial *serial)
1336 mutex_unlock(&command_info->mutex); 933 mutex_unlock(&command_info->mutex);
1337} 934}
1338 935
1339
1340static int start_port_read(struct usb_serial_port *port)
1341{
1342 struct whiteheat_private *info = usb_get_serial_port_data(port);
1343 struct whiteheat_urb_wrap *wrap;
1344 struct urb *urb;
1345 int retval = 0;
1346 unsigned long flags;
1347 struct list_head *tmp;
1348 struct list_head *tmp2;
1349
1350 spin_lock_irqsave(&info->lock, flags);
1351
1352 list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
1353 list_del(tmp);
1354 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1355 urb = wrap->urb;
1356 spin_unlock_irqrestore(&info->lock, flags);
1357 retval = usb_submit_urb(urb, GFP_KERNEL);
1358 if (retval) {
1359 spin_lock_irqsave(&info->lock, flags);
1360 list_add(tmp, &info->rx_urbs_free);
1361 list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
1362 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1363 urb = wrap->urb;
1364 list_del(tmp);
1365 spin_unlock_irqrestore(&info->lock, flags);
1366 usb_kill_urb(urb);
1367 spin_lock_irqsave(&info->lock, flags);
1368 list_add(tmp, &info->rx_urbs_free);
1369 }
1370 break;
1371 }
1372 spin_lock_irqsave(&info->lock, flags);
1373 list_add(tmp, &info->rx_urbs_submitted);
1374 }
1375
1376 spin_unlock_irqrestore(&info->lock, flags);
1377
1378 return retval;
1379}
1380
1381
1382static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
1383 struct list_head *head)
1384{
1385 struct whiteheat_urb_wrap *wrap;
1386 struct list_head *tmp;
1387
1388 list_for_each(tmp, head) {
1389 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1390 if (wrap->urb == urb)
1391 return wrap;
1392 }
1393
1394 return NULL;
1395}
1396
1397
1398static struct list_head *list_first(struct list_head *head)
1399{
1400 return head->next;
1401}
1402
1403
1404static void rx_data_softint(struct work_struct *work)
1405{
1406 struct whiteheat_private *info =
1407 container_of(work, struct whiteheat_private, rx_work);
1408 struct usb_serial_port *port = info->port;
1409 struct tty_struct *tty = tty_port_tty_get(&port->port);
1410 struct whiteheat_urb_wrap *wrap;
1411 struct urb *urb;
1412 unsigned long flags;
1413 struct list_head *tmp;
1414 struct list_head *tmp2;
1415 int result;
1416 int sent = 0;
1417
1418 spin_lock_irqsave(&info->lock, flags);
1419 if (info->flags & THROTTLED) {
1420 spin_unlock_irqrestore(&info->lock, flags);
1421 goto out;
1422 }
1423
1424 list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
1425 list_del(tmp);
1426 spin_unlock_irqrestore(&info->lock, flags);
1427
1428 wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
1429 urb = wrap->urb;
1430
1431 if (tty && urb->actual_length)
1432 sent += tty_insert_flip_string(tty,
1433 urb->transfer_buffer, urb->actual_length);
1434
1435 result = usb_submit_urb(urb, GFP_ATOMIC);
1436 if (result) {
1437 dev_err(&port->dev,
1438 "%s - failed resubmitting read urb, error %d\n",
1439 __func__, result);
1440 spin_lock_irqsave(&info->lock, flags);
1441 list_add(tmp, &info->rx_urbs_free);
1442 continue;
1443 }
1444
1445 spin_lock_irqsave(&info->lock, flags);
1446 list_add(tmp, &info->rx_urbs_submitted);
1447 }
1448 spin_unlock_irqrestore(&info->lock, flags);
1449
1450 if (sent)
1451 tty_flip_buffer_push(tty);
1452out:
1453 tty_kref_put(tty);
1454}
1455
1456module_usb_serial_driver(whiteheat_driver, serial_drivers); 936module_usb_serial_driver(whiteheat_driver, serial_drivers);
1457 937
1458MODULE_AUTHOR(DRIVER_AUTHOR); 938MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -1462,8 +942,5 @@ MODULE_LICENSE("GPL");
1462MODULE_FIRMWARE("whiteheat.fw"); 942MODULE_FIRMWARE("whiteheat.fw");
1463MODULE_FIRMWARE("whiteheat_loader.fw"); 943MODULE_FIRMWARE("whiteheat_loader.fw");
1464 944
1465module_param(urb_pool_size, int, 0);
1466MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
1467
1468module_param(debug, bool, S_IRUGO | S_IWUSR); 945module_param(debug, bool, S_IRUGO | S_IWUSR);
1469MODULE_PARM_DESC(debug, "Debug enabled or not"); 946MODULE_PARM_DESC(debug, "Debug enabled or not");