forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (42 commits) netpoll: fix incorrect access to skb data in __netpoll_rx cassini: init before use in cas_interruptN. can: ti_hecc: Fix uninitialized spinlock in probe can: ti_hecc: Fix unintialized variable net: sh_eth: fix the compile error net/phy: fix DP83865 phy interrupt handler sendmmsg/sendmsg: fix unsafe user pointer access ibmveth: Fix leak when recycling skb and hypervisor returns error arp: fix rcu lockdep splat in arp_process() bridge: fix a possible use after free bridge: Pseudo-header required for the checksum of ICMPv6 mcast: Fix source address selection for multicast listener report MAINTAINERS: Update GIT trees for network development ath9k: Fix PS wrappers in ath9k_set_coverage_class carl9170: Fix mismatch in carl9170_op_set_key mutex lock-unlock wl12xx: add max_sched_scan_ssids value to the hw description wl12xx: Fix validation of pm_runtime_get_sync return value wl12xx: Remove obsolete testmode NVS push command bcma: add uevent to the bus, to autoload drivers ath9k_hw: Fix STA (AR9485) bringup issue due to incorrect MAC address ...
This commit is contained in:
commit
0f43dd546d
@ -4450,8 +4450,8 @@ M: "David S. Miller" <davem@davemloft.net>
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.linuxfoundation.org/en/Net
|
||||
W: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
|
||||
S: Maintained
|
||||
F: net/
|
||||
F: include/net/
|
||||
|
@ -15,6 +15,7 @@ MODULE_LICENSE("GPL");
|
||||
static int bcma_bus_match(struct device *dev, struct device_driver *drv);
|
||||
static int bcma_device_probe(struct device *dev);
|
||||
static int bcma_device_remove(struct device *dev);
|
||||
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -49,6 +50,7 @@ static struct bus_type bcma_bus_type = {
|
||||
.match = bcma_bus_match,
|
||||
.probe = bcma_device_probe,
|
||||
.remove = bcma_device_remove,
|
||||
.uevent = bcma_device_uevent,
|
||||
.dev_attrs = bcma_device_attrs,
|
||||
};
|
||||
|
||||
@ -227,6 +229,16 @@ static int bcma_device_remove(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
|
||||
|
||||
return add_uevent_var(env,
|
||||
"MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
|
||||
core->id.manuf, core->id.id,
|
||||
core->id.rev, core->id.class);
|
||||
}
|
||||
|
||||
static int __init bcma_modinit(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = {
|
||||
/* Atheros AR3011 with sflash firmware*/
|
||||
{ USB_DEVICE(0x0CF3, 0x3002) },
|
||||
{ USB_DEVICE(0x13d3, 0x3304) },
|
||||
{ USB_DEVICE(0x0930, 0x0215) },
|
||||
|
||||
/* Atheros AR9285 Malbec with sflash firmware */
|
||||
{ USB_DEVICE(0x03F0, 0x311D) },
|
||||
|
@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = {
|
||||
/* Atheros 3011 with sflash firmware */
|
||||
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
|
||||
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
|
||||
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
|
||||
|
||||
/* Atheros AR9285 Malbec with sflash firmware */
|
||||
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
|
||||
@ -256,7 +257,9 @@ static void btusb_intr_complete(struct urb *urb)
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
if (err != -EPERM)
|
||||
/* -EPERM: urb is being killed;
|
||||
* -ENODEV: device got disconnected */
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
BT_ERR("%s urb %p failed to resubmit (%d)",
|
||||
hdev->name, urb, -err);
|
||||
usb_unanchor_urb(urb);
|
||||
@ -341,7 +344,9 @@ static void btusb_bulk_complete(struct urb *urb)
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
if (err != -EPERM)
|
||||
/* -EPERM: urb is being killed;
|
||||
* -ENODEV: device got disconnected */
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
BT_ERR("%s urb %p failed to resubmit (%d)",
|
||||
hdev->name, urb, -err);
|
||||
usb_unanchor_urb(urb);
|
||||
@ -431,7 +436,9 @@ static void btusb_isoc_complete(struct urb *urb)
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
if (err != -EPERM)
|
||||
/* -EPERM: urb is being killed;
|
||||
* -ENODEV: device got disconnected */
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
BT_ERR("%s urb %p failed to resubmit (%d)",
|
||||
hdev->name, urb, -err);
|
||||
usb_unanchor_urb(urb);
|
||||
|
@ -503,9 +503,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
spin_unlock_irqrestore(&priv->mbx_lock, flags);
|
||||
|
||||
/* Prepare mailbox for transmission */
|
||||
data = cf->can_dlc | (get_tx_head_prio(priv) << 8);
|
||||
if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
|
||||
data |= HECC_CANMCF_RTR;
|
||||
data |= get_tx_head_prio(priv) << 8;
|
||||
hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);
|
||||
|
||||
if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
|
||||
@ -923,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
||||
priv->can.do_get_state = ti_hecc_get_state;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
|
||||
|
||||
spin_lock_init(&priv->mbx_lock);
|
||||
ndev->irq = irq->start;
|
||||
ndev->flags |= IFF_ECHO;
|
||||
platform_set_drvdata(pdev, ndev);
|
||||
|
@ -2452,14 +2452,13 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id)
|
||||
struct net_device *dev = dev_id;
|
||||
struct cas *cp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
int ring;
|
||||
int ring = (irq == cp->pci_irq_INTC) ? 2 : 3;
|
||||
u32 status = readl(cp->regs + REG_PLUS_INTRN_STATUS(ring));
|
||||
|
||||
/* check for shared irq */
|
||||
if (status == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
ring = (irq == cp->pci_irq_INTC) ? 2 : 3;
|
||||
spin_lock_irqsave(&cp->lock, flags);
|
||||
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
|
||||
#ifdef USE_NAPI
|
||||
|
@ -395,7 +395,7 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada
|
||||
}
|
||||
|
||||
/* recycle the current buffer on the rx queue */
|
||||
static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
|
||||
static int ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
|
||||
{
|
||||
u32 q_index = adapter->rx_queue.index;
|
||||
u64 correlator = adapter->rx_queue.queue_addr[q_index].correlator;
|
||||
@ -403,6 +403,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
|
||||
unsigned int index = correlator & 0xffffffffUL;
|
||||
union ibmveth_buf_desc desc;
|
||||
unsigned long lpar_rc;
|
||||
int ret = 1;
|
||||
|
||||
BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS);
|
||||
BUG_ON(index >= adapter->rx_buff_pool[pool].size);
|
||||
@ -410,7 +411,7 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
|
||||
if (!adapter->rx_buff_pool[pool].active) {
|
||||
ibmveth_rxq_harvest_buffer(adapter);
|
||||
ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
desc.fields.flags_len = IBMVETH_BUF_VALID |
|
||||
@ -423,12 +424,16 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter)
|
||||
netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed "
|
||||
"during recycle rc=%ld", lpar_rc);
|
||||
ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) {
|
||||
adapter->rx_queue.index = 0;
|
||||
adapter->rx_queue.toggle = !adapter->rx_queue.toggle;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter)
|
||||
@ -1084,8 +1089,9 @@ restart_poll:
|
||||
if (rx_flush)
|
||||
ibmveth_flush_buffer(skb->data,
|
||||
length + offset);
|
||||
if (!ibmveth_rxq_recycle_buffer(adapter))
|
||||
kfree_skb(skb);
|
||||
skb = new_skb;
|
||||
ibmveth_rxq_recycle_buffer(adapter);
|
||||
} else {
|
||||
ibmveth_rxq_harvest_buffer(adapter);
|
||||
skb_reserve(skb, offset);
|
||||
|
@ -25,8 +25,9 @@
|
||||
/* DP83865 phy identifier values */
|
||||
#define DP83865_PHY_ID 0x20005c7a
|
||||
|
||||
#define DP83865_INT_MASK_REG 0x15
|
||||
#define DP83865_INT_MASK_STATUS 0x14
|
||||
#define DP83865_INT_STATUS 0x14
|
||||
#define DP83865_INT_MASK 0x15
|
||||
#define DP83865_INT_CLEAR 0x17
|
||||
|
||||
#define DP83865_INT_REMOTE_FAULT 0x0008
|
||||
#define DP83865_INT_ANE_COMPLETED 0x0010
|
||||
@ -68,21 +69,25 @@ static int ns_config_intr(struct phy_device *phydev)
|
||||
int err;
|
||||
|
||||
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
||||
err = phy_write(phydev, DP83865_INT_MASK_REG,
|
||||
err = phy_write(phydev, DP83865_INT_MASK,
|
||||
DP83865_INT_MASK_DEFAULT);
|
||||
else
|
||||
err = phy_write(phydev, DP83865_INT_MASK_REG, 0);
|
||||
err = phy_write(phydev, DP83865_INT_MASK, 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ns_ack_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
int ret = phy_read(phydev, DP83865_INT_MASK_STATUS);
|
||||
int ret = phy_read(phydev, DP83865_INT_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
/* Clear the interrupt status bit by writing a “1”
|
||||
* to the corresponding bit in INT_CLEAR (2:0 are reserved) */
|
||||
ret = phy_write(phydev, DP83865_INT_CLEAR, ret & ~0x7);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ns_giga_speed_fallback(struct phy_device *phydev, int mode)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <linux/phy.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x,
|
||||
static const struct ar9300_eeprom ar9300_default = {
|
||||
.eepromVersion = 2,
|
||||
.templateVersion = 2,
|
||||
.macAddr = {1, 2, 3, 4, 5, 6},
|
||||
.macAddr = {0, 2, 3, 4, 5, 6},
|
||||
.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
.baseEepHeader = {
|
||||
|
@ -2283,7 +2283,11 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
ah->coverage_class = coverage_class;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_init_global_settings(ah);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
|
@ -1066,8 +1066,10 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
* the high througput speed in 802.11n networks.
|
||||
*/
|
||||
|
||||
if (!is_main_vif(ar, vif))
|
||||
if (!is_main_vif(ar, vif)) {
|
||||
mutex_lock(&ar->mutex);
|
||||
goto err_softw;
|
||||
}
|
||||
|
||||
/*
|
||||
* While the hardware supports *catch-all* key, for offloading
|
||||
|
@ -871,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
|
||||
{
|
||||
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
int retval;
|
||||
|
||||
retval = rt2x00lib_suspend(rt2x00dev, state);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Decrease usbdev refcount.
|
||||
*/
|
||||
usb_put_dev(interface_to_usbdev(usb_intf));
|
||||
|
||||
return 0;
|
||||
return rt2x00lib_suspend(rt2x00dev, state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_suspend);
|
||||
|
||||
@ -891,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
|
||||
struct ieee80211_hw *hw = usb_get_intfdata(usb_intf);
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
||||
usb_get_dev(interface_to_usbdev(usb_intf));
|
||||
|
||||
return rt2x00lib_resume(rt2x00dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00usb_resume);
|
||||
|
@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
|
||||
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
|
||||
wl->hw->wiphy->max_scan_ssids = 1;
|
||||
wl->hw->wiphy->max_sched_scan_ssids = 1;
|
||||
/*
|
||||
* Maximum length of elements in scanning probe request templates
|
||||
* should be the maximum length possible for a template, without
|
||||
|
@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)
|
||||
/* If enabled, tell runtime PM not to power off the card */
|
||||
if (pm_runtime_enabled(&func->dev)) {
|
||||
ret = pm_runtime_get_sync(&func->dev);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
} else {
|
||||
/* Runtime PM is disabled: power up the card manually */
|
||||
|
@ -36,7 +36,6 @@ enum wl1271_tm_commands {
|
||||
WL1271_TM_CMD_TEST,
|
||||
WL1271_TM_CMD_INTERROGATE,
|
||||
WL1271_TM_CMD_CONFIGURE,
|
||||
WL1271_TM_CMD_NVS_PUSH,
|
||||
WL1271_TM_CMD_SET_PLT_MODE,
|
||||
WL1271_TM_CMD_RECOVER,
|
||||
|
||||
@ -190,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
|
||||
{
|
||||
int ret = 0;
|
||||
size_t len;
|
||||
void *buf;
|
||||
|
||||
wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");
|
||||
|
||||
if (!tb[WL1271_TM_ATTR_DATA])
|
||||
return -EINVAL;
|
||||
|
||||
buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
|
||||
len = nla_len(tb[WL1271_TM_ATTR_DATA]);
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
kfree(wl->nvs);
|
||||
|
||||
if ((wl->chip.id == CHIP_ID_1283_PG20) &&
|
||||
(len != sizeof(struct wl128x_nvs_file)))
|
||||
return -EINVAL;
|
||||
else if (len != sizeof(struct wl1271_nvs_file))
|
||||
return -EINVAL;
|
||||
|
||||
wl->nvs = kzalloc(len, GFP_KERNEL);
|
||||
if (!wl->nvs) {
|
||||
wl1271_error("could not allocate memory for the nvs file");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(wl->nvs, buf, len);
|
||||
wl->nvs_len = len;
|
||||
|
||||
wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
|
||||
{
|
||||
u32 val;
|
||||
@ -288,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
|
||||
return wl1271_tm_cmd_interrogate(wl, tb);
|
||||
case WL1271_TM_CMD_CONFIGURE:
|
||||
return wl1271_tm_cmd_configure(wl, tb);
|
||||
case WL1271_TM_CMD_NVS_PUSH:
|
||||
return wl1271_tm_cmd_nvs_push(wl, tb);
|
||||
case WL1271_TM_CMD_SET_PLT_MODE:
|
||||
return wl1271_tm_cmd_set_plt_mode(wl, tb);
|
||||
case WL1271_TM_CMD_RECOVER:
|
||||
|
@ -1865,6 +1865,9 @@ struct wiphy {
|
||||
* you need use set_wiphy_dev() (see below) */
|
||||
struct device dev;
|
||||
|
||||
/* protects ->resume, ->suspend sysfs callbacks against unregister hw */
|
||||
bool registered;
|
||||
|
||||
/* dir in debugfs: ieee80211/<wiphyname> */
|
||||
struct dentry *debugfsdir;
|
||||
|
||||
|
@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
|
||||
BT_DBG("sk %p", sk);
|
||||
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
while (sk->sk_state != state) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
if (!timeo) {
|
||||
err = -EINPROGRESS;
|
||||
break;
|
||||
@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
err = sock_error(sk);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
return err;
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ struct bnep_session {
|
||||
unsigned int role;
|
||||
unsigned long state;
|
||||
unsigned long flags;
|
||||
atomic_t terminate;
|
||||
struct task_struct *task;
|
||||
|
||||
struct ethhdr eh;
|
||||
|
@ -484,9 +484,11 @@ static int bnep_session(void *arg)
|
||||
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
while (!kthread_should_stop()) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
if (atomic_read(&s->terminate))
|
||||
break;
|
||||
/* RX */
|
||||
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
|
||||
skb_orphan(skb);
|
||||
@ -504,7 +506,7 @@ static int bnep_session(void *arg)
|
||||
|
||||
schedule();
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
/* Cleanup session */
|
||||
@ -640,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req)
|
||||
down_read(&bnep_session_sem);
|
||||
|
||||
s = __bnep_get_session(req->dst);
|
||||
if (s)
|
||||
kthread_stop(s->task);
|
||||
else
|
||||
if (s) {
|
||||
atomic_inc(&s->terminate);
|
||||
wake_up_process(s->task);
|
||||
} else
|
||||
err = -ENOENT;
|
||||
|
||||
up_read(&bnep_session_sem);
|
||||
|
@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
|
||||
|
||||
capi_ctr_down(ctrl);
|
||||
|
||||
kthread_stop(session->task);
|
||||
atomic_inc(&session->terminate);
|
||||
wake_up_process(session->task);
|
||||
}
|
||||
|
||||
static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
|
||||
|
@ -81,6 +81,7 @@ struct cmtp_session {
|
||||
|
||||
char name[BTNAMSIZ];
|
||||
|
||||
atomic_t terminate;
|
||||
struct task_struct *task;
|
||||
|
||||
wait_queue_head_t wait;
|
||||
|
@ -292,9 +292,11 @@ static int cmtp_session(void *arg)
|
||||
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
while (!kthread_should_stop()) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
if (atomic_read(&session->terminate))
|
||||
break;
|
||||
if (sk->sk_state != BT_CONNECTED)
|
||||
break;
|
||||
|
||||
@ -307,7 +309,7 @@ static int cmtp_session(void *arg)
|
||||
|
||||
schedule();
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
down_write(&cmtp_session_sem);
|
||||
@ -380,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
|
||||
|
||||
if (!(session->flags & (1 << CMTP_LOOPBACK))) {
|
||||
err = cmtp_attach_device(session);
|
||||
if (err < 0)
|
||||
goto detach;
|
||||
if (err < 0) {
|
||||
atomic_inc(&session->terminate);
|
||||
wake_up_process(session->task);
|
||||
up_write(&cmtp_session_sem);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
up_write(&cmtp_session_sem);
|
||||
return 0;
|
||||
|
||||
detach:
|
||||
cmtp_detach_device(session);
|
||||
|
||||
unlink:
|
||||
__cmtp_unlink_session(session);
|
||||
|
||||
@ -414,7 +417,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req)
|
||||
skb_queue_purge(&session->transmit);
|
||||
|
||||
/* Stop session thread */
|
||||
kthread_stop(session->task);
|
||||
atomic_inc(&session->terminate);
|
||||
wake_up_process(session->task);
|
||||
} else
|
||||
err = -ENOENT;
|
||||
|
||||
|
@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg)
|
||||
|
||||
BT_ERR("%s command tx timeout", hdev->name);
|
||||
atomic_set(&hdev->cmd_cnt, 1);
|
||||
clear_bit(HCI_RESET, &hdev->flags);
|
||||
tasklet_schedule(&hdev->cmd_task);
|
||||
}
|
||||
|
||||
@ -1327,7 +1326,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr)
|
||||
|
||||
entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL);
|
||||
if (!entry) {
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg)
|
||||
if (hdev->sent_cmd) {
|
||||
atomic_dec(&hdev->cmd_cnt);
|
||||
hci_send_frame(skb);
|
||||
mod_timer(&hdev->cmd_timer,
|
||||
if (test_bit(HCI_RESET, &hdev->flags))
|
||||
del_timer(&hdev->cmd_timer);
|
||||
else
|
||||
mod_timer(&hdev->cmd_timer,
|
||||
jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
|
||||
} else {
|
||||
skb_queue_head(&hdev->cmd_q, skb);
|
||||
|
@ -764,6 +764,7 @@ static int hidp_session(void *arg)
|
||||
|
||||
up_write(&hidp_session_sem);
|
||||
|
||||
kfree(session->rd_data);
|
||||
kfree(session);
|
||||
return 0;
|
||||
}
|
||||
@ -841,7 +842,8 @@ static int hidp_setup_input(struct hidp_session *session,
|
||||
|
||||
err = input_register_device(input);
|
||||
if (err < 0) {
|
||||
hci_conn_put_device(session->conn);
|
||||
input_free_device(input);
|
||||
session->input = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1044,8 +1046,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
|
||||
}
|
||||
|
||||
err = hid_add_device(session->hid);
|
||||
if (err < 0)
|
||||
goto err_add_device;
|
||||
if (err < 0) {
|
||||
atomic_inc(&session->terminate);
|
||||
wake_up_process(session->task);
|
||||
up_write(&hidp_session_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (session->input) {
|
||||
hidp_send_ctrl_message(session,
|
||||
@ -1059,12 +1065,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
|
||||
up_write(&hidp_session_sem);
|
||||
return 0;
|
||||
|
||||
err_add_device:
|
||||
hid_destroy_device(session->hid);
|
||||
session->hid = NULL;
|
||||
atomic_inc(&session->terminate);
|
||||
wake_up_process(session->task);
|
||||
|
||||
unlink:
|
||||
hidp_del_timer(session);
|
||||
|
||||
@ -1090,7 +1090,6 @@ purge:
|
||||
failed:
|
||||
up_write(&hidp_session_sem);
|
||||
|
||||
input_free_device(session->input);
|
||||
kfree(session);
|
||||
return err;
|
||||
}
|
||||
|
@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk)
|
||||
int timeo = HZ/5;
|
||||
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
while ((chan->unacked_frames > 0 && chan->conn)) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
while (chan->unacked_frames > 0 && chan->conn) {
|
||||
if (!timeo)
|
||||
timeo = HZ/5;
|
||||
|
||||
@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk)
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
err = sock_error(sk);
|
||||
if (err)
|
||||
|
@ -235,39 +235,39 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
|
||||
|
||||
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
goto done;
|
||||
}
|
||||
|
||||
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
|
||||
|
||||
BT_DBG("sk %p timeo %ld", sk, timeo);
|
||||
|
||||
/* Wait for an incoming connection. (wake-one). */
|
||||
add_wait_queue_exclusive(sk_sleep(sk), &wait);
|
||||
while (!(nsk = bt_accept_dequeue(sk, newsock))) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
break;
|
||||
}
|
||||
|
||||
nsk = bt_accept_dequeue(sk, newsock);
|
||||
if (nsk)
|
||||
break;
|
||||
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
err = sock_intr_errno(timeo);
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
if (err)
|
||||
@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
|
||||
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
|
||||
|
||||
sk->sk_destruct = l2cap_sock_destruct;
|
||||
sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
|
||||
sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
|
||||
|
||||
sock_reset_flag(sk, SOCK_ZAPPED);
|
||||
|
||||
|
@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
|
||||
#define rfcomm_lock() mutex_lock(&rfcomm_mutex)
|
||||
#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
|
||||
|
||||
static unsigned long rfcomm_event;
|
||||
|
||||
static LIST_HEAD(session_list);
|
||||
|
||||
@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void)
|
||||
{
|
||||
if (!rfcomm_thread)
|
||||
return;
|
||||
set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
|
||||
wake_up_process(rfcomm_thread);
|
||||
}
|
||||
|
||||
@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused)
|
||||
|
||||
rfcomm_add_listener(BDADDR_ANY);
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
|
||||
/* No pending events. Let's sleep.
|
||||
* Incoming connections and data will wake us up. */
|
||||
schedule();
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
|
||||
/* Process stuff */
|
||||
clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
|
||||
rfcomm_process_sessions();
|
||||
|
||||
schedule();
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
rfcomm_kill_listener();
|
||||
|
||||
|
@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sk->sk_type != SOCK_STREAM) {
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
@ -501,28 +496,33 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
|
||||
|
||||
/* Wait for an incoming connection. (wake-one). */
|
||||
add_wait_queue_exclusive(sk_sleep(sk), &wait);
|
||||
while (!(nsk = bt_accept_dequeue(sk, newsock))) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
break;
|
||||
}
|
||||
|
||||
nsk = bt_accept_dequeue(sk, newsock);
|
||||
if (nsk)
|
||||
break;
|
||||
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
err = sock_intr_errno(timeo);
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
if (err)
|
||||
|
@ -564,39 +564,39 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
goto done;
|
||||
}
|
||||
|
||||
timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
|
||||
|
||||
BT_DBG("sk %p timeo %ld", sk, timeo);
|
||||
|
||||
/* Wait for an incoming connection. (wake-one). */
|
||||
add_wait_queue_exclusive(sk_sleep(sk), &wait);
|
||||
while (!(ch = bt_accept_dequeue(sk, newsock))) {
|
||||
while (1) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
|
||||
if (sk->sk_state != BT_LISTEN) {
|
||||
err = -EBADFD;
|
||||
break;
|
||||
}
|
||||
|
||||
ch = bt_accept_dequeue(sk, newsock);
|
||||
if (ch)
|
||||
break;
|
||||
|
||||
if (!timeo) {
|
||||
err = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
err = sock_intr_errno(timeo);
|
||||
break;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
timeo = schedule_timeout(timeo);
|
||||
lock_sock(sk);
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
if (err)
|
||||
|
@ -1456,7 +1456,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
|
||||
{
|
||||
struct sk_buff *skb2;
|
||||
const struct ipv6hdr *ip6h;
|
||||
struct icmp6hdr *icmp6h;
|
||||
u8 icmp6_type;
|
||||
u8 nexthdr;
|
||||
unsigned len;
|
||||
int offset;
|
||||
@ -1502,9 +1502,9 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
|
||||
__skb_pull(skb2, offset);
|
||||
skb_reset_transport_header(skb2);
|
||||
|
||||
icmp6h = icmp6_hdr(skb2);
|
||||
icmp6_type = icmp6_hdr(skb2)->icmp6_type;
|
||||
|
||||
switch (icmp6h->icmp6_type) {
|
||||
switch (icmp6_type) {
|
||||
case ICMPV6_MGM_QUERY:
|
||||
case ICMPV6_MGM_REPORT:
|
||||
case ICMPV6_MGM_REDUCTION:
|
||||
@ -1520,16 +1520,23 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
|
||||
err = pskb_trim_rcsum(skb2, len);
|
||||
if (err)
|
||||
goto out;
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
ip6h = ipv6_hdr(skb2);
|
||||
|
||||
switch (skb2->ip_summed) {
|
||||
case CHECKSUM_COMPLETE:
|
||||
if (!csum_fold(skb2->csum))
|
||||
if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, skb2->len,
|
||||
IPPROTO_ICMPV6, skb2->csum))
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case CHECKSUM_NONE:
|
||||
skb2->csum = 0;
|
||||
if (skb_checksum_complete(skb2))
|
||||
skb2->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
|
||||
&ip6h->daddr,
|
||||
skb2->len,
|
||||
IPPROTO_ICMPV6, 0));
|
||||
if (__skb_checksum_complete(skb2))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1537,7 +1544,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
|
||||
|
||||
BR_INPUT_SKB_CB(skb)->igmp = 1;
|
||||
|
||||
switch (icmp6h->icmp6_type) {
|
||||
switch (icmp6_type) {
|
||||
case ICMPV6_MGM_REPORT:
|
||||
{
|
||||
struct mld_msg *mld;
|
||||
|
@ -1319,11 +1319,15 @@ static void neigh_proxy_process(unsigned long arg)
|
||||
|
||||
if (tdif <= 0) {
|
||||
struct net_device *dev = skb->dev;
|
||||
|
||||
__skb_unlink(skb, &tbl->proxy_queue);
|
||||
if (tbl->proxy_redo && netif_running(dev))
|
||||
if (tbl->proxy_redo && netif_running(dev)) {
|
||||
rcu_read_lock();
|
||||
tbl->proxy_redo(skb);
|
||||
else
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
dev_put(dev);
|
||||
} else if (!sched_next || tdif < sched_next)
|
||||
|
@ -558,13 +558,14 @@ int __netpoll_rx(struct sk_buff *skb)
|
||||
if (skb_shared(skb))
|
||||
goto out;
|
||||
|
||||
iph = (struct iphdr *)skb->data;
|
||||
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
|
||||
goto out;
|
||||
iph = (struct iphdr *)skb->data;
|
||||
if (iph->ihl < 5 || iph->version != 4)
|
||||
goto out;
|
||||
if (!pskb_may_pull(skb, iph->ihl*4))
|
||||
goto out;
|
||||
iph = (struct iphdr *)skb->data;
|
||||
if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
|
||||
goto out;
|
||||
|
||||
@ -579,6 +580,7 @@ int __netpoll_rx(struct sk_buff *skb)
|
||||
if (pskb_trim_rcsum(skb, len))
|
||||
goto out;
|
||||
|
||||
iph = (struct iphdr *)skb->data;
|
||||
if (iph->protocol != IPPROTO_UDP)
|
||||
goto out;
|
||||
|
||||
|
@ -767,7 +767,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
|
||||
break;
|
||||
for (i=0; i<nsrcs; i++) {
|
||||
/* skip inactive filters */
|
||||
if (pmc->sfcount[MCAST_INCLUDE] ||
|
||||
if (psf->sf_count[MCAST_INCLUDE] ||
|
||||
pmc->sfcount[MCAST_EXCLUDE] !=
|
||||
psf->sf_count[MCAST_EXCLUDE])
|
||||
continue;
|
||||
|
@ -1059,7 +1059,7 @@ static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
|
||||
break;
|
||||
for (i=0; i<nsrcs; i++) {
|
||||
/* skip inactive filters */
|
||||
if (pmc->mca_sfcount[MCAST_INCLUDE] ||
|
||||
if (psf->sf_count[MCAST_INCLUDE] ||
|
||||
pmc->mca_sfcount[MCAST_EXCLUDE] !=
|
||||
psf->sf_count[MCAST_EXCLUDE])
|
||||
continue;
|
||||
|
@ -1012,7 +1012,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||
cancel_work_sync(&local->reconfig_filter);
|
||||
|
||||
ieee80211_clear_tx_pending(local);
|
||||
sta_info_stop(local);
|
||||
rate_control_deinitialize(local);
|
||||
|
||||
if (skb_queue_len(&local->skb_queue) ||
|
||||
@ -1024,6 +1023,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||
|
||||
destroy_workqueue(local->workqueue);
|
||||
wiphy_unregister(local->hw.wiphy);
|
||||
sta_info_stop(local);
|
||||
ieee80211_wep_free(local);
|
||||
ieee80211_led_exit(local);
|
||||
kfree(local->int_scan_req);
|
||||
|
10
net/socket.c
10
net/socket.c
@ -1965,8 +1965,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
* used_address->name_len is initialized to UINT_MAX so that the first
|
||||
* destination address never matches.
|
||||
*/
|
||||
if (used_address && used_address->name_len == msg_sys->msg_namelen &&
|
||||
!memcmp(&used_address->name, msg->msg_name,
|
||||
if (used_address && msg_sys->msg_name &&
|
||||
used_address->name_len == msg_sys->msg_namelen &&
|
||||
!memcmp(&used_address->name, msg_sys->msg_name,
|
||||
used_address->name_len)) {
|
||||
err = sock_sendmsg_nosec(sock, msg_sys, total_len);
|
||||
goto out_freectl;
|
||||
@ -1978,8 +1979,9 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
|
||||
*/
|
||||
if (used_address && err >= 0) {
|
||||
used_address->name_len = msg_sys->msg_namelen;
|
||||
memcpy(&used_address->name, msg->msg_name,
|
||||
used_address->name_len);
|
||||
if (msg_sys->msg_name)
|
||||
memcpy(&used_address->name, msg_sys->msg_name,
|
||||
used_address->name_len);
|
||||
}
|
||||
|
||||
out_freectl:
|
||||
|
@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
if (res)
|
||||
goto out_rm_dev;
|
||||
|
||||
rtnl_lock();
|
||||
rdev->wiphy.registered = true;
|
||||
rtnl_unlock();
|
||||
return 0;
|
||||
|
||||
out_rm_dev:
|
||||
@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
|
||||
|
||||
rtnl_lock();
|
||||
rdev->wiphy.registered = false;
|
||||
rtnl_unlock();
|
||||
|
||||
rfkill_unregister(rdev->rfkill);
|
||||
|
||||
/* protect the device list */
|
||||
|
@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
|
||||
|
||||
if (rdev->ops->suspend) {
|
||||
rtnl_lock();
|
||||
ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
|
||||
if (rdev->wiphy.registered)
|
||||
ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev)
|
||||
|
||||
if (rdev->ops->resume) {
|
||||
rtnl_lock();
|
||||
ret = rdev->ops->resume(&rdev->wiphy);
|
||||
if (rdev->wiphy.registered)
|
||||
ret = rdev->ops->resume(&rdev->wiphy);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user