16
16
#include <linux/etherdevice.h>
17
17
#include <linux/if_arp.h>
18
18
#include <linux/mii.h>
19
+ #include <linux/rtnetlink.h>
19
20
#include <linux/usb.h>
20
21
#include <linux/usb/cdc.h>
21
22
#include <linux/usb/usbnet.h>
@@ -92,7 +93,7 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co
92
93
struct usbnet * dev = netdev_priv (to_net_dev (d ));
93
94
struct qmi_wwan_state * info = (void * )& dev -> data ;
94
95
bool enable ;
95
- int err ;
96
+ int ret ;
96
97
97
98
if (strtobool (buf , & enable ))
98
99
return - EINVAL ;
@@ -101,18 +102,22 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co
101
102
if (enable == (info -> flags & QMI_WWAN_FLAG_RAWIP ))
102
103
return len ;
103
104
105
+ if (!rtnl_trylock ())
106
+ return restart_syscall ();
107
+
104
108
/* we don't want to modify a running netdev */
105
109
if (netif_running (dev -> net )) {
106
110
netdev_err (dev -> net , "Cannot change a running device\n" );
107
- return - EBUSY ;
111
+ ret = - EBUSY ;
112
+ goto err ;
108
113
}
109
114
110
115
/* let other drivers deny the change */
111
- err = call_netdevice_notifiers (NETDEV_PRE_TYPE_CHANGE , dev -> net );
112
- err = notifier_to_errno (err );
113
- if (err ) {
116
+ ret = call_netdevice_notifiers (NETDEV_PRE_TYPE_CHANGE , dev -> net );
117
+ ret = notifier_to_errno (ret );
118
+ if (ret ) {
114
119
netdev_err (dev -> net , "Type change was refused\n" );
115
- return err ;
120
+ goto err ;
116
121
}
117
122
118
123
if (enable )
@@ -121,7 +126,10 @@ static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, co
121
126
info -> flags &= ~QMI_WWAN_FLAG_RAWIP ;
122
127
qmi_wwan_netdev_setup (dev -> net );
123
128
call_netdevice_notifiers (NETDEV_POST_TYPE_CHANGE , dev -> net );
124
- return len ;
129
+ ret = len ;
130
+ err :
131
+ rtnl_unlock ();
132
+ return ret ;
125
133
}
126
134
127
135
static DEVICE_ATTR_RW (raw_ip );
0 commit comments