aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.name>2006-10-03 04:30:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-10-17 17:46:30 -0400
commit1a2ea1dfc4ee078841cd6406ebf6bf0c5a3d25e9 (patch)
treecba3ced71bc8573e283fe5cd85c2eb532f3e3438
parentfbe2bafcb00b25265c2c869ba4615d6a5324b7f1 (diff)
USB: suspend/resume support for kaweth
this adds support for suspend and resume to the kaweth driver. Signed-off-by: Oliver Neukum <oliver@neukum.name> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/net/kaweth.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index 9ef9075a1680..7c906a43e497 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -76,6 +76,9 @@
76 76
77#define KAWETH_STATUS_BROKEN 0x0000001 77#define KAWETH_STATUS_BROKEN 0x0000001
78#define KAWETH_STATUS_CLOSING 0x0000002 78#define KAWETH_STATUS_CLOSING 0x0000002
79#define KAWETH_STATUS_SUSPENDING 0x0000004
80
81#define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING)
79 82
80#define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01 83#define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01
81#define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02 84#define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02
@@ -102,6 +105,8 @@
102#define STATE_MASK 0x40 105#define STATE_MASK 0x40
103#define STATE_SHIFT 5 106#define STATE_SHIFT 5
104 107
108#define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED)
109
105 110
106MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>"); 111MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>");
107MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); 112MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
@@ -118,6 +123,8 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev,
118 unsigned int pipe, 123 unsigned int pipe,
119 struct usb_ctrlrequest *cmd, void *data, 124 struct usb_ctrlrequest *cmd, void *data,
120 int len, int timeout); 125 int len, int timeout);
126static int kaweth_suspend(struct usb_interface *intf, pm_message_t message);
127static int kaweth_resume(struct usb_interface *intf);
121 128
122/**************************************************************** 129/****************************************************************
123 * usb_device_id 130 * usb_device_id
@@ -169,6 +176,8 @@ static struct usb_driver kaweth_driver = {
169 .name = driver_name, 176 .name = driver_name,
170 .probe = kaweth_probe, 177 .probe = kaweth_probe,
171 .disconnect = kaweth_disconnect, 178 .disconnect = kaweth_disconnect,
179 .suspend = kaweth_suspend,
180 .resume = kaweth_resume,
172 .id_table = usb_klsi_table, 181 .id_table = usb_klsi_table,
173}; 182};
174 183
@@ -212,6 +221,7 @@ struct kaweth_device
212 int suspend_lowmem_rx; 221 int suspend_lowmem_rx;
213 int suspend_lowmem_ctrl; 222 int suspend_lowmem_ctrl;
214 int linkstate; 223 int linkstate;
224 int opened;
215 struct work_struct lowmem_work; 225 struct work_struct lowmem_work;
216 226
217 struct usb_device *dev; 227 struct usb_device *dev;
@@ -524,7 +534,7 @@ static void kaweth_resubmit_tl(void *d)
524{ 534{
525 struct kaweth_device *kaweth = (struct kaweth_device *)d; 535 struct kaweth_device *kaweth = (struct kaweth_device *)d;
526 536
527 if (kaweth->status | KAWETH_STATUS_CLOSING) 537 if (IS_BLOCKED(kaweth->status))
528 return; 538 return;
529 539
530 if (kaweth->suspend_lowmem_rx) 540 if (kaweth->suspend_lowmem_rx)
@@ -591,8 +601,12 @@ static void kaweth_usb_receive(struct urb *urb)
591 return; 601 return;
592 } 602 }
593 603
594 if (kaweth->status & KAWETH_STATUS_CLOSING) 604 spin_lock(&kaweth->device_lock);
605 if (IS_BLOCKED(kaweth->status)) {
606 spin_unlock(&kaweth->device_lock);
595 return; 607 return;
608 }
609 spin_unlock(&kaweth->device_lock);
596 610
597 if(urb->status && urb->status != -EREMOTEIO && count != 1) { 611 if(urb->status && urb->status != -EREMOTEIO && count != 1) {
598 err("%s RX status: %d count: %d packet_len: %d", 612 err("%s RX status: %d count: %d packet_len: %d",
@@ -668,6 +682,7 @@ static int kaweth_open(struct net_device *net)
668 usb_kill_urb(kaweth->rx_urb); 682 usb_kill_urb(kaweth->rx_urb);
669 return -EIO; 683 return -EIO;
670 } 684 }
685 kaweth->opened = 1;
671 686
672 netif_start_queue(net); 687 netif_start_queue(net);
673 688
@@ -678,14 +693,8 @@ static int kaweth_open(struct net_device *net)
678/**************************************************************** 693/****************************************************************
679 * kaweth_close 694 * kaweth_close
680 ****************************************************************/ 695 ****************************************************************/
681static int kaweth_close(struct net_device *net) 696static void kaweth_kill_urbs(struct kaweth_device *kaweth)
682{ 697{
683 struct kaweth_device *kaweth = netdev_priv(net);
684
685 netif_stop_queue(net);
686
687 kaweth->status |= KAWETH_STATUS_CLOSING;
688
689 usb_kill_urb(kaweth->irq_urb); 698 usb_kill_urb(kaweth->irq_urb);
690 usb_kill_urb(kaweth->rx_urb); 699 usb_kill_urb(kaweth->rx_urb);
691 usb_kill_urb(kaweth->tx_urb); 700 usb_kill_urb(kaweth->tx_urb);
@@ -696,6 +705,21 @@ static int kaweth_close(struct net_device *net)
696 we hit them again */ 705 we hit them again */
697 usb_kill_urb(kaweth->irq_urb); 706 usb_kill_urb(kaweth->irq_urb);
698 usb_kill_urb(kaweth->rx_urb); 707 usb_kill_urb(kaweth->rx_urb);
708}
709
710/****************************************************************
711 * kaweth_close
712 ****************************************************************/
713static int kaweth_close(struct net_device *net)
714{
715 struct kaweth_device *kaweth = netdev_priv(net);
716
717 netif_stop_queue(net);
718 kaweth->opened = 0;
719
720 kaweth->status |= KAWETH_STATUS_CLOSING;
721
722 kaweth_kill_urbs(kaweth);
699 723
700 kaweth->status &= ~KAWETH_STATUS_CLOSING; 724 kaweth->status &= ~KAWETH_STATUS_CLOSING;
701 725
@@ -742,6 +766,9 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
742 766
743 kaweth_async_set_rx_mode(kaweth); 767 kaweth_async_set_rx_mode(kaweth);
744 netif_stop_queue(net); 768 netif_stop_queue(net);
769 if (IS_BLOCKED(kaweth->status)) {
770 goto skip;
771 }
745 772
746 /* We now decide whether we can put our special header into the sk_buff */ 773 /* We now decide whether we can put our special header into the sk_buff */
747 if (skb_cloned(skb) || skb_headroom(skb) < 2) { 774 if (skb_cloned(skb) || skb_headroom(skb) < 2) {
@@ -774,6 +801,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
774 if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) 801 if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
775 { 802 {
776 warn("kaweth failed tx_urb %d", res); 803 warn("kaweth failed tx_urb %d", res);
804skip:
777 kaweth->stats.tx_errors++; 805 kaweth->stats.tx_errors++;
778 806
779 netif_start_queue(net); 807 netif_start_queue(net);
@@ -872,6 +900,42 @@ static void kaweth_tx_timeout(struct net_device *net)
872} 900}
873 901
874/**************************************************************** 902/****************************************************************
903 * kaweth_suspend
904 ****************************************************************/
905static int kaweth_suspend(struct usb_interface *intf, pm_message_t message)
906{
907 struct kaweth_device *kaweth = usb_get_intfdata(intf);
908 unsigned long flags;
909
910 spin_lock_irqsave(&kaweth->device_lock, flags);
911 kaweth->status |= KAWETH_STATUS_SUSPENDING;
912 spin_unlock_irqrestore(&kaweth->device_lock, flags);
913
914 kaweth_kill_urbs(kaweth);
915 return 0;
916}
917
918/****************************************************************
919 * kaweth_resume
920 ****************************************************************/
921static int kaweth_resume(struct usb_interface *intf)
922{
923 struct kaweth_device *kaweth = usb_get_intfdata(intf);
924 unsigned long flags;
925
926 spin_lock_irqsave(&kaweth->device_lock, flags);
927 kaweth->status &= ~KAWETH_STATUS_SUSPENDING;
928 spin_unlock_irqrestore(&kaweth->device_lock, flags);
929
930 if (!kaweth->opened)
931 return 0;
932 kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
933 kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
934
935 return 0;
936}
937
938/****************************************************************
875 * kaweth_probe 939 * kaweth_probe
876 ****************************************************************/ 940 ****************************************************************/
877static int kaweth_probe( 941static int kaweth_probe(