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 --- |