cdc-wdm.c (18abf874367456540846319574864e6ff32752e2) cdc-wdm.c (cac6fb015f719104e60b1c68c15ca5b734f57b9c)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * cdc-wdm.c
4 *
5 * This driver supports USB CDC WCM Device Management.
6 *
7 * Copyright (c) 2007-2009 Oliver Neukum
8 *

--- 7 unchanged lines hidden (view full) ---

16#include <linux/errno.h>
17#include <linux/ioctl.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/mutex.h>
21#include <linux/uaccess.h>
22#include <linux/bitops.h>
23#include <linux/poll.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * cdc-wdm.c
4 *
5 * This driver supports USB CDC WCM Device Management.
6 *
7 * Copyright (c) 2007-2009 Oliver Neukum
8 *

--- 7 unchanged lines hidden (view full) ---

16#include <linux/errno.h>
17#include <linux/ioctl.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/mutex.h>
21#include <linux/uaccess.h>
22#include <linux/bitops.h>
23#include <linux/poll.h>
24#include <linux/skbuff.h>
24#include <linux/usb.h>
25#include <linux/usb/cdc.h>
25#include <linux/usb.h>
26#include <linux/usb/cdc.h>
27#include <linux/wwan.h>
26#include <asm/byteorder.h>
27#include <asm/unaligned.h>
28#include <linux/usb/cdc-wdm.h>
29
30#define DRIVER_AUTHOR "Oliver Neukum"
31#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
32
33static const struct usb_device_id wdm_ids[] = {

--- 16 unchanged lines hidden (view full) ---

50#define WDM_RESULT 3
51#define WDM_READ 4
52#define WDM_INT_STALL 5
53#define WDM_POLL_RUNNING 6
54#define WDM_RESPONDING 7
55#define WDM_SUSPENDING 8
56#define WDM_RESETTING 9
57#define WDM_OVERFLOW 10
28#include <asm/byteorder.h>
29#include <asm/unaligned.h>
30#include <linux/usb/cdc-wdm.h>
31
32#define DRIVER_AUTHOR "Oliver Neukum"
33#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
34
35static const struct usb_device_id wdm_ids[] = {

--- 16 unchanged lines hidden (view full) ---

52#define WDM_RESULT 3
53#define WDM_READ 4
54#define WDM_INT_STALL 5
55#define WDM_POLL_RUNNING 6
56#define WDM_RESPONDING 7
57#define WDM_SUSPENDING 8
58#define WDM_RESETTING 9
59#define WDM_OVERFLOW 10
60#define WDM_WWAN_IN_USE 11
58
59#define WDM_MAX 16
60
61/* we cannot wait forever at flush() */
62#define WDM_FLUSH_TIMEOUT (30 * HZ)
63
64/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
65#define WDM_DEFAULT_BUFSIZE 256

--- 35 unchanged lines hidden (view full) ---

101 struct work_struct rxwork;
102 struct work_struct service_outs_intr;
103 int werr;
104 int rerr;
105 int resp_count;
106
107 struct list_head device_list;
108 int (*manage_power)(struct usb_interface *, int);
61
62#define WDM_MAX 16
63
64/* we cannot wait forever at flush() */
65#define WDM_FLUSH_TIMEOUT (30 * HZ)
66
67/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
68#define WDM_DEFAULT_BUFSIZE 256

--- 35 unchanged lines hidden (view full) ---

104 struct work_struct rxwork;
105 struct work_struct service_outs_intr;
106 int werr;
107 int rerr;
108 int resp_count;
109
110 struct list_head device_list;
111 int (*manage_power)(struct usb_interface *, int);
112
113 enum wwan_port_type wwanp_type;
114 struct wwan_port *wwanp;
109};
110
111static struct usb_driver wdm_driver;
112
113/* return intfdata if we own the interface, else look up intf in the list */
114static struct wdm_device *wdm_find_device(struct usb_interface *intf)
115{
116 struct wdm_device *desc;

--- 35 unchanged lines hidden (view full) ---

152 desc->werr = urb->status;
153 spin_unlock_irqrestore(&desc->iuspin, flags);
154 kfree(desc->outbuf);
155 desc->outbuf = NULL;
156 clear_bit(WDM_IN_USE, &desc->flags);
157 wake_up_all(&desc->wait);
158}
159
115};
116
117static struct usb_driver wdm_driver;
118
119/* return intfdata if we own the interface, else look up intf in the list */
120static struct wdm_device *wdm_find_device(struct usb_interface *intf)
121{
122 struct wdm_device *desc;

--- 35 unchanged lines hidden (view full) ---

158 desc->werr = urb->status;
159 spin_unlock_irqrestore(&desc->iuspin, flags);
160 kfree(desc->outbuf);
161 desc->outbuf = NULL;
162 clear_bit(WDM_IN_USE, &desc->flags);
163 wake_up_all(&desc->wait);
164}
165
166static void wdm_wwan_rx(struct wdm_device *desc, int length);
167
160static void wdm_in_callback(struct urb *urb)
161{
162 unsigned long flags;
163 struct wdm_device *desc = urb->context;
164 int status = urb->status;
165 int length = urb->actual_length;
166
167 spin_lock_irqsave(&desc->iuspin, flags);

--- 19 unchanged lines hidden (view full) ---

187 break;
188 default:
189 dev_err(&desc->intf->dev,
190 "Unexpected error %d\n", status);
191 break;
192 }
193 }
194
168static void wdm_in_callback(struct urb *urb)
169{
170 unsigned long flags;
171 struct wdm_device *desc = urb->context;
172 int status = urb->status;
173 int length = urb->actual_length;
174
175 spin_lock_irqsave(&desc->iuspin, flags);

--- 19 unchanged lines hidden (view full) ---

195 break;
196 default:
197 dev_err(&desc->intf->dev,
198 "Unexpected error %d\n", status);
199 break;
200 }
201 }
202
203 if (test_bit(WDM_WWAN_IN_USE, &desc->flags)) {
204 wdm_wwan_rx(desc, length);
205 goto out;
206 }
207
195 /*
196 * only set a new error if there is no previous error.
197 * Errors are only cleared during read/open
198 * Avoid propagating -EPIPE (stall) to userspace since it is
199 * better handled as an empty read
200 */
201 if (desc->rerr == 0 && status != -EPIPE)
202 desc->rerr = status;

--- 18 unchanged lines hidden (view full) ---

221 * We should respond to further attempts from the device to send
222 * data, so that we can get unstuck.
223 */
224 schedule_work(&desc->service_outs_intr);
225 } else {
226 set_bit(WDM_READ, &desc->flags);
227 wake_up(&desc->wait);
228 }
208 /*
209 * only set a new error if there is no previous error.
210 * Errors are only cleared during read/open
211 * Avoid propagating -EPIPE (stall) to userspace since it is
212 * better handled as an empty read
213 */
214 if (desc->rerr == 0 && status != -EPIPE)
215 desc->rerr = status;

--- 18 unchanged lines hidden (view full) ---

234 * We should respond to further attempts from the device to send
235 * data, so that we can get unstuck.
236 */
237 schedule_work(&desc->service_outs_intr);
238 } else {
239 set_bit(WDM_READ, &desc->flags);
240 wake_up(&desc->wait);
241 }
242out:
229 spin_unlock_irqrestore(&desc->iuspin, flags);
230}
231
232static void wdm_int_callback(struct urb *urb)
233{
234 unsigned long flags;
235 int rv = 0;
236 int responding;

--- 79 unchanged lines hidden (view full) ---

316 rv = usb_submit_urb(urb, GFP_ATOMIC);
317 if (rv)
318 dev_err(&desc->intf->dev,
319 "%s - usb_submit_urb failed with result %d\n",
320 __func__, rv);
321
322}
323
243 spin_unlock_irqrestore(&desc->iuspin, flags);
244}
245
246static void wdm_int_callback(struct urb *urb)
247{
248 unsigned long flags;
249 int rv = 0;
250 int responding;

--- 79 unchanged lines hidden (view full) ---

330 rv = usb_submit_urb(urb, GFP_ATOMIC);
331 if (rv)
332 dev_err(&desc->intf->dev,
333 "%s - usb_submit_urb failed with result %d\n",
334 __func__, rv);
335
336}
337
324static void poison_urbs(struct wdm_device *desc)
338static void kill_urbs(struct wdm_device *desc)
325{
326 /* the order here is essential */
339{
340 /* the order here is essential */
327 usb_poison_urb(desc->command);
328 usb_poison_urb(desc->validity);
329 usb_poison_urb(desc->response);
341 usb_kill_urb(desc->command);
342 usb_kill_urb(desc->validity);
343 usb_kill_urb(desc->response);
330}
331
344}
345
332static void unpoison_urbs(struct wdm_device *desc)
333{
334 /*
335 * the order here is not essential
336 * it is symmetrical just to be nice
337 */
338 usb_unpoison_urb(desc->response);
339 usb_unpoison_urb(desc->validity);
340 usb_unpoison_urb(desc->command);
341}
342
343static void free_urbs(struct wdm_device *desc)
344{
345 usb_free_urb(desc->validity);
346 usb_free_urb(desc->response);
347 usb_free_urb(desc->command);
348}
349
350static void cleanup(struct wdm_device *desc)

--- 352 unchanged lines hidden (view full) ---

703 if (!desc)
704 goto out;
705
706 intf = desc->intf;
707 if (test_bit(WDM_DISCONNECTING, &desc->flags))
708 goto out;
709 file->private_data = desc;
710
346static void free_urbs(struct wdm_device *desc)
347{
348 usb_free_urb(desc->validity);
349 usb_free_urb(desc->response);
350 usb_free_urb(desc->command);
351}
352
353static void cleanup(struct wdm_device *desc)

--- 352 unchanged lines hidden (view full) ---

706 if (!desc)
707 goto out;
708
709 intf = desc->intf;
710 if (test_bit(WDM_DISCONNECTING, &desc->flags))
711 goto out;
712 file->private_data = desc;
713
714 if (test_bit(WDM_WWAN_IN_USE, &desc->flags)) {
715 rv = -EBUSY;
716 goto out;
717 }
718
711 rv = usb_autopm_get_interface(desc->intf);
712 if (rv < 0) {
713 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
714 goto out;
715 }
716
717 /* using write lock to protect desc->count */
718 mutex_lock(&desc->wlock);

--- 28 unchanged lines hidden (view full) ---

747 /* using write lock to protect desc->count */
748 mutex_lock(&desc->wlock);
749 desc->count--;
750 mutex_unlock(&desc->wlock);
751
752 if (!desc->count) {
753 if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
754 dev_dbg(&desc->intf->dev, "wdm_release: cleanup\n");
719 rv = usb_autopm_get_interface(desc->intf);
720 if (rv < 0) {
721 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
722 goto out;
723 }
724
725 /* using write lock to protect desc->count */
726 mutex_lock(&desc->wlock);

--- 28 unchanged lines hidden (view full) ---

755 /* using write lock to protect desc->count */
756 mutex_lock(&desc->wlock);
757 desc->count--;
758 mutex_unlock(&desc->wlock);
759
760 if (!desc->count) {
761 if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
762 dev_dbg(&desc->intf->dev, "wdm_release: cleanup\n");
755 poison_urbs(desc);
763 kill_urbs(desc);
756 spin_lock_irq(&desc->iuspin);
757 desc->resp_count = 0;
758 spin_unlock_irq(&desc->iuspin);
759 desc->manage_power(desc->intf, 0);
764 spin_lock_irq(&desc->iuspin);
765 desc->resp_count = 0;
766 spin_unlock_irq(&desc->iuspin);
767 desc->manage_power(desc->intf, 0);
760 unpoison_urbs(desc);
761 } else {
762 /* must avoid dev_printk here as desc->intf is invalid */
763 pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__);
764 cleanup(desc);
765 }
766 }
767 mutex_unlock(&wdm_mutex);
768 return 0;

--- 30 unchanged lines hidden (view full) ---

799};
800
801static struct usb_class_driver wdm_class = {
802 .name = "cdc-wdm%d",
803 .fops = &wdm_fops,
804 .minor_base = WDM_MINOR_BASE,
805};
806
768 } else {
769 /* must avoid dev_printk here as desc->intf is invalid */
770 pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__);
771 cleanup(desc);
772 }
773 }
774 mutex_unlock(&wdm_mutex);
775 return 0;

--- 30 unchanged lines hidden (view full) ---

806};
807
808static struct usb_class_driver wdm_class = {
809 .name = "cdc-wdm%d",
810 .fops = &wdm_fops,
811 .minor_base = WDM_MINOR_BASE,
812};
813
814/* --- WWAN framework integration --- */
815#ifdef CONFIG_WWAN
816static int wdm_wwan_port_start(struct wwan_port *port)
817{
818 struct wdm_device *desc = wwan_port_get_drvdata(port);
819
820 /* The interface is both exposed via the WWAN framework and as a
821 * legacy usbmisc chardev. If chardev is already open, just fail
822 * to prevent concurrent usage. Otherwise, switch to WWAN mode.
823 */
824 mutex_lock(&wdm_mutex);
825 if (desc->count) {
826 mutex_unlock(&wdm_mutex);
827 return -EBUSY;
828 }
829 set_bit(WDM_WWAN_IN_USE, &desc->flags);
830 mutex_unlock(&wdm_mutex);
831
832 desc->manage_power(desc->intf, 1);
833
834 /* tx is allowed */
835 wwan_port_txon(port);
836
837 /* Start getting events */
838 return usb_submit_urb(desc->validity, GFP_KERNEL);
839}
840
841static void wdm_wwan_port_stop(struct wwan_port *port)
842{
843 struct wdm_device *desc = wwan_port_get_drvdata(port);
844
845 /* Stop all transfers and disable WWAN mode */
846 kill_urbs(desc);
847 desc->manage_power(desc->intf, 0);
848 clear_bit(WDM_READ, &desc->flags);
849 clear_bit(WDM_WWAN_IN_USE, &desc->flags);
850}
851
852static void wdm_wwan_port_tx_complete(struct urb *urb)
853{
854 struct sk_buff *skb = urb->context;
855 struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
856
857 usb_autopm_put_interface(desc->intf);
858 wwan_port_txon(desc->wwanp);
859 kfree_skb(skb);
860}
861
862static int wdm_wwan_port_tx(struct wwan_port *port, struct sk_buff *skb)
863{
864 struct wdm_device *desc = wwan_port_get_drvdata(port);
865 struct usb_interface *intf = desc->intf;
866 struct usb_ctrlrequest *req = desc->orq;
867 int rv;
868
869 rv = usb_autopm_get_interface(intf);
870 if (rv)
871 return rv;
872
873 usb_fill_control_urb(
874 desc->command,
875 interface_to_usbdev(intf),
876 usb_sndctrlpipe(interface_to_usbdev(intf), 0),
877 (unsigned char *)req,
878 skb->data,
879 skb->len,
880 wdm_wwan_port_tx_complete,
881 skb
882 );
883
884 req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
885 req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
886 req->wValue = 0;
887 req->wIndex = desc->inum;
888 req->wLength = cpu_to_le16(skb->len);
889
890 skb_shinfo(skb)->destructor_arg = desc;
891
892 rv = usb_submit_urb(desc->command, GFP_KERNEL);
893 if (rv)
894 usb_autopm_put_interface(intf);
895 else /* One transfer at a time, stop TX until URB completion */
896 wwan_port_txoff(port);
897
898 return rv;
899}
900
901static struct wwan_port_ops wdm_wwan_port_ops = {
902 .start = wdm_wwan_port_start,
903 .stop = wdm_wwan_port_stop,
904 .tx = wdm_wwan_port_tx,
905};
906
907static void wdm_wwan_init(struct wdm_device *desc)
908{
909 struct usb_interface *intf = desc->intf;
910 struct wwan_port *port;
911
912 /* Only register to WWAN core if protocol/type is known */
913 if (desc->wwanp_type == WWAN_PORT_UNKNOWN) {
914 dev_info(&intf->dev, "Unknown control protocol\n");
915 return;
916 }
917
918 port = wwan_create_port(&intf->dev, desc->wwanp_type, &wdm_wwan_port_ops, desc);
919 if (IS_ERR(port)) {
920 dev_err(&intf->dev, "%s: Unable to create WWAN port\n",
921 dev_name(intf->usb_dev));
922 return;
923 }
924
925 desc->wwanp = port;
926}
927
928static void wdm_wwan_deinit(struct wdm_device *desc)
929{
930 if (!desc->wwanp)
931 return;
932
933 wwan_remove_port(desc->wwanp);
934 desc->wwanp = NULL;
935}
936
937static void wdm_wwan_rx(struct wdm_device *desc, int length)
938{
939 struct wwan_port *port = desc->wwanp;
940 struct sk_buff *skb;
941
942 /* Forward data to WWAN port */
943 skb = alloc_skb(length, GFP_ATOMIC);
944 if (!skb)
945 return;
946
947 memcpy(skb_put(skb, length), desc->inbuf, length);
948 wwan_port_rx(port, skb);
949
950 /* inbuf has been copied, it is safe to check for outstanding data */
951 schedule_work(&desc->service_outs_intr);
952}
953#else /* CONFIG_WWAN */
954static void wdm_wwan_init(struct wdm_device *desc) {}
955static void wdm_wwan_deinit(struct wdm_device *desc) {}
956static void wdm_wwan_rx(struct wdm_device *desc, int length) {}
957#endif /* CONFIG_WWAN */
958
807/* --- error handling --- */
808static void wdm_rxwork(struct work_struct *work)
809{
810 struct wdm_device *desc = container_of(work, struct wdm_device, rxwork);
811 unsigned long flags;
812 int rv = 0;
813 int responding;
814

--- 28 unchanged lines hidden (view full) ---

843 wake_up(&desc->wait);
844 }
845 spin_unlock_irq(&desc->iuspin);
846}
847
848/* --- hotplug --- */
849
850static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep,
959/* --- error handling --- */
960static void wdm_rxwork(struct work_struct *work)
961{
962 struct wdm_device *desc = container_of(work, struct wdm_device, rxwork);
963 unsigned long flags;
964 int rv = 0;
965 int responding;
966

--- 28 unchanged lines hidden (view full) ---

995 wake_up(&desc->wait);
996 }
997 spin_unlock_irq(&desc->iuspin);
998}
999
1000/* --- hotplug --- */
1001
1002static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep,
851 u16 bufsize, int (*manage_power)(struct usb_interface *, int))
1003 u16 bufsize, enum wwan_port_type type,
1004 int (*manage_power)(struct usb_interface *, int))
852{
853 int rv = -ENOMEM;
854 struct wdm_device *desc;
855
856 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
857 if (!desc)
858 goto out;
859 INIT_LIST_HEAD(&desc->device_list);
860 mutex_init(&desc->rlock);
861 mutex_init(&desc->wlock);
862 spin_lock_init(&desc->iuspin);
863 init_waitqueue_head(&desc->wait);
864 desc->wMaxCommand = bufsize;
865 /* this will be expanded and needed in hardware endianness */
866 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
867 desc->intf = intf;
1005{
1006 int rv = -ENOMEM;
1007 struct wdm_device *desc;
1008
1009 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
1010 if (!desc)
1011 goto out;
1012 INIT_LIST_HEAD(&desc->device_list);
1013 mutex_init(&desc->rlock);
1014 mutex_init(&desc->wlock);
1015 spin_lock_init(&desc->iuspin);
1016 init_waitqueue_head(&desc->wait);
1017 desc->wMaxCommand = bufsize;
1018 /* this will be expanded and needed in hardware endianness */
1019 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
1020 desc->intf = intf;
1021 desc->wwanp_type = type;
868 INIT_WORK(&desc->rxwork, wdm_rxwork);
869 INIT_WORK(&desc->service_outs_intr, service_interrupt_work);
870
871 rv = -EINVAL;
872 if (!usb_endpoint_is_int_in(ep))
873 goto err;
874
875 desc->wMaxPacketSize = usb_endpoint_maxp(ep);

--- 64 unchanged lines hidden (view full) ---

940 list_add(&desc->device_list, &wdm_device_list);
941 spin_unlock(&wdm_device_list_lock);
942
943 rv = usb_register_dev(intf, &wdm_class);
944 if (rv < 0)
945 goto err;
946 else
947 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
1022 INIT_WORK(&desc->rxwork, wdm_rxwork);
1023 INIT_WORK(&desc->service_outs_intr, service_interrupt_work);
1024
1025 rv = -EINVAL;
1026 if (!usb_endpoint_is_int_in(ep))
1027 goto err;
1028
1029 desc->wMaxPacketSize = usb_endpoint_maxp(ep);

--- 64 unchanged lines hidden (view full) ---

1094 list_add(&desc->device_list, &wdm_device_list);
1095 spin_unlock(&wdm_device_list_lock);
1096
1097 rv = usb_register_dev(intf, &wdm_class);
1098 if (rv < 0)
1099 goto err;
1100 else
1101 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
1102
1103 wdm_wwan_init(desc);
1104
948out:
949 return rv;
950err:
951 spin_lock(&wdm_device_list_lock);
952 list_del(&desc->device_list);
953 spin_unlock(&wdm_device_list_lock);
954 cleanup(desc);
955 return rv;

--- 28 unchanged lines hidden (view full) ---

984 if (hdr.usb_cdc_dmm_desc)
985 maxcom = le16_to_cpu(hdr.usb_cdc_dmm_desc->wMaxCommand);
986
987 iface = intf->cur_altsetting;
988 if (iface->desc.bNumEndpoints != 1)
989 goto err;
990 ep = &iface->endpoint[0].desc;
991
1105out:
1106 return rv;
1107err:
1108 spin_lock(&wdm_device_list_lock);
1109 list_del(&desc->device_list);
1110 spin_unlock(&wdm_device_list_lock);
1111 cleanup(desc);
1112 return rv;

--- 28 unchanged lines hidden (view full) ---

1141 if (hdr.usb_cdc_dmm_desc)
1142 maxcom = le16_to_cpu(hdr.usb_cdc_dmm_desc->wMaxCommand);
1143
1144 iface = intf->cur_altsetting;
1145 if (iface->desc.bNumEndpoints != 1)
1146 goto err;
1147 ep = &iface->endpoint[0].desc;
1148
992 rv = wdm_create(intf, ep, maxcom, &wdm_manage_power);
1149 rv = wdm_create(intf, ep, maxcom, WWAN_PORT_UNKNOWN, &wdm_manage_power);
993
994err:
995 return rv;
996}
997
998/**
999 * usb_cdc_wdm_register - register a WDM subdriver
1000 * @intf: usb interface the subdriver will associate with
1001 * @ep: interrupt endpoint to monitor for notifications
1002 * @bufsize: maximum message size to support for read/write
1150
1151err:
1152 return rv;
1153}
1154
1155/**
1156 * usb_cdc_wdm_register - register a WDM subdriver
1157 * @intf: usb interface the subdriver will associate with
1158 * @ep: interrupt endpoint to monitor for notifications
1159 * @bufsize: maximum message size to support for read/write
1160 * @type: Type/protocol of the transported data (MBIM, QMI...)
1003 * @manage_power: call-back invoked during open and release to
1004 * manage the device's power
1005 * Create WDM usb class character device and associate it with intf
1006 * without binding, allowing another driver to manage the interface.
1007 *
1008 * The subdriver will manage the given interrupt endpoint exclusively
1009 * and will issue control requests referring to the given intf. It
1010 * will otherwise avoid interferring, and in particular not do
1011 * usb_set_intfdata/usb_get_intfdata on intf.
1012 *
1013 * The return value is a pointer to the subdriver's struct usb_driver.
1014 * The registering driver is responsible for calling this subdriver's
1015 * disconnect, suspend, resume, pre_reset and post_reset methods from
1016 * its own.
1017 */
1018struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf,
1019 struct usb_endpoint_descriptor *ep,
1161 * @manage_power: call-back invoked during open and release to
1162 * manage the device's power
1163 * Create WDM usb class character device and associate it with intf
1164 * without binding, allowing another driver to manage the interface.
1165 *
1166 * The subdriver will manage the given interrupt endpoint exclusively
1167 * and will issue control requests referring to the given intf. It
1168 * will otherwise avoid interferring, and in particular not do
1169 * usb_set_intfdata/usb_get_intfdata on intf.
1170 *
1171 * The return value is a pointer to the subdriver's struct usb_driver.
1172 * The registering driver is responsible for calling this subdriver's
1173 * disconnect, suspend, resume, pre_reset and post_reset methods from
1174 * its own.
1175 */
1176struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf,
1177 struct usb_endpoint_descriptor *ep,
1020 int bufsize,
1178 int bufsize, enum wwan_port_type type,
1021 int (*manage_power)(struct usb_interface *, int))
1022{
1023 int rv;
1024
1179 int (*manage_power)(struct usb_interface *, int))
1180{
1181 int rv;
1182
1025 rv = wdm_create(intf, ep, bufsize, manage_power);
1183 rv = wdm_create(intf, ep, bufsize, type, manage_power);
1026 if (rv < 0)
1027 goto err;
1028
1029 return &wdm_driver;
1030err:
1031 return ERR_PTR(rv);
1032}
1033EXPORT_SYMBOL(usb_cdc_wdm_register);
1034
1035static void wdm_disconnect(struct usb_interface *intf)
1036{
1037 struct wdm_device *desc;
1038 unsigned long flags;
1039
1040 usb_deregister_dev(intf, &wdm_class);
1041 desc = wdm_find_device(intf);
1042 mutex_lock(&wdm_mutex);
1043
1184 if (rv < 0)
1185 goto err;
1186
1187 return &wdm_driver;
1188err:
1189 return ERR_PTR(rv);
1190}
1191EXPORT_SYMBOL(usb_cdc_wdm_register);
1192
1193static void wdm_disconnect(struct usb_interface *intf)
1194{
1195 struct wdm_device *desc;
1196 unsigned long flags;
1197
1198 usb_deregister_dev(intf, &wdm_class);
1199 desc = wdm_find_device(intf);
1200 mutex_lock(&wdm_mutex);
1201
1202 wdm_wwan_deinit(desc);
1203
1044 /* the spinlock makes sure no new urbs are generated in the callbacks */
1045 spin_lock_irqsave(&desc->iuspin, flags);
1046 set_bit(WDM_DISCONNECTING, &desc->flags);
1047 set_bit(WDM_READ, &desc->flags);
1048 spin_unlock_irqrestore(&desc->iuspin, flags);
1049 wake_up_all(&desc->wait);
1050 mutex_lock(&desc->rlock);
1051 mutex_lock(&desc->wlock);
1204 /* the spinlock makes sure no new urbs are generated in the callbacks */
1205 spin_lock_irqsave(&desc->iuspin, flags);
1206 set_bit(WDM_DISCONNECTING, &desc->flags);
1207 set_bit(WDM_READ, &desc->flags);
1208 spin_unlock_irqrestore(&desc->iuspin, flags);
1209 wake_up_all(&desc->wait);
1210 mutex_lock(&desc->rlock);
1211 mutex_lock(&desc->wlock);
1052 poison_urbs(desc);
1053 cancel_work_sync(&desc->rxwork);
1054 cancel_work_sync(&desc->service_outs_intr);
1212 cancel_work_sync(&desc->rxwork);
1213 cancel_work_sync(&desc->service_outs_intr);
1214 kill_urbs(desc);
1055 mutex_unlock(&desc->wlock);
1056 mutex_unlock(&desc->rlock);
1057
1058 /* the desc->intf pointer used as list key is now invalid */
1059 spin_lock(&wdm_device_list_lock);
1060 list_del(&desc->device_list);
1061 spin_unlock(&wdm_device_list_lock);
1062

--- 24 unchanged lines hidden (view full) ---

1087 || test_bit(WDM_RESPONDING, &desc->flags))) {
1088 spin_unlock_irq(&desc->iuspin);
1089 rv = -EBUSY;
1090 } else {
1091
1092 set_bit(WDM_SUSPENDING, &desc->flags);
1093 spin_unlock_irq(&desc->iuspin);
1094 /* callback submits work - order is essential */
1215 mutex_unlock(&desc->wlock);
1216 mutex_unlock(&desc->rlock);
1217
1218 /* the desc->intf pointer used as list key is now invalid */
1219 spin_lock(&wdm_device_list_lock);
1220 list_del(&desc->device_list);
1221 spin_unlock(&wdm_device_list_lock);
1222

--- 24 unchanged lines hidden (view full) ---

1247 || test_bit(WDM_RESPONDING, &desc->flags))) {
1248 spin_unlock_irq(&desc->iuspin);
1249 rv = -EBUSY;
1250 } else {
1251
1252 set_bit(WDM_SUSPENDING, &desc->flags);
1253 spin_unlock_irq(&desc->iuspin);
1254 /* callback submits work - order is essential */
1095 poison_urbs(desc);
1255 kill_urbs(desc);
1096 cancel_work_sync(&desc->rxwork);
1097 cancel_work_sync(&desc->service_outs_intr);
1256 cancel_work_sync(&desc->rxwork);
1257 cancel_work_sync(&desc->service_outs_intr);
1098 unpoison_urbs(desc);
1099 }
1100 if (!PMSG_IS_AUTO(message)) {
1101 mutex_unlock(&desc->wlock);
1102 mutex_unlock(&desc->rlock);
1103 }
1104
1105 return rv;
1106}

--- 41 unchanged lines hidden (view full) ---

1148 set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */
1149 set_bit(WDM_READ, &desc->flags); /* unblock read */
1150 clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */
1151 desc->rerr = -EINTR;
1152 spin_unlock_irq(&desc->iuspin);
1153 wake_up_all(&desc->wait);
1154 mutex_lock(&desc->rlock);
1155 mutex_lock(&desc->wlock);
1258 }
1259 if (!PMSG_IS_AUTO(message)) {
1260 mutex_unlock(&desc->wlock);
1261 mutex_unlock(&desc->rlock);
1262 }
1263
1264 return rv;
1265}

--- 41 unchanged lines hidden (view full) ---

1307 set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */
1308 set_bit(WDM_READ, &desc->flags); /* unblock read */
1309 clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */
1310 desc->rerr = -EINTR;
1311 spin_unlock_irq(&desc->iuspin);
1312 wake_up_all(&desc->wait);
1313 mutex_lock(&desc->rlock);
1314 mutex_lock(&desc->wlock);
1156 poison_urbs(desc);
1315 kill_urbs(desc);
1157 cancel_work_sync(&desc->rxwork);
1158 cancel_work_sync(&desc->service_outs_intr);
1159 return 0;
1160}
1161
1162static int wdm_post_reset(struct usb_interface *intf)
1163{
1164 struct wdm_device *desc = wdm_find_device(intf);
1165 int rv;
1166
1316 cancel_work_sync(&desc->rxwork);
1317 cancel_work_sync(&desc->service_outs_intr);
1318 return 0;
1319}
1320
1321static int wdm_post_reset(struct usb_interface *intf)
1322{
1323 struct wdm_device *desc = wdm_find_device(intf);
1324 int rv;
1325
1167 unpoison_urbs(desc);
1168 clear_bit(WDM_OVERFLOW, &desc->flags);
1169 clear_bit(WDM_RESETTING, &desc->flags);
1170 rv = recover_from_urb_loss(desc);
1171 mutex_unlock(&desc->wlock);
1172 mutex_unlock(&desc->rlock);
1173 return rv;
1174}
1175

--- 21 unchanged lines hidden ---
1326 clear_bit(WDM_OVERFLOW, &desc->flags);
1327 clear_bit(WDM_RESETTING, &desc->flags);
1328 rv = recover_from_urb_loss(desc);
1329 mutex_unlock(&desc->wlock);
1330 mutex_unlock(&desc->rlock);
1331 return rv;
1332}
1333

--- 21 unchanged lines hidden ---