Merge branch 'wireless'
John W. Linville says: ==================== This batch of fixes is intended for 3.8... Included is a Bluetooth pull. Gustavo says: "A few fixes for 3.8. Five of them are just new devices ids addition. Apart from the that there is fix to a kernel memory leak to userspace from Anderson Lizardo, two interoperability fixes from Jaganath Kanakkassery and Szymon Janc. And a crash fix by me." Along with that, Amitkumar Karwar brings a pair of mwifiex fixes for problems related to handling of band information within the driver. These problems can lead to association failures. Sujith Manoharan fixes a memory leak in the ath9k_htc code (originally reported by Larry Finger). The big hero this round is Felix Fietkau. Felix gives us seven ath9k fixes, including a fix for a race condition, the removal of a double-free, and a fix for a deadlock, among others. These have all been in linux-next for at least a couple of days, with no complaints so far. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
be05e45a0f
|
@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||
{ USB_DEVICE(0x13d3, 0x3362) },
|
||||
{ USB_DEVICE(0x0CF3, 0xE004) },
|
||||
{ USB_DEVICE(0x0930, 0x0219) },
|
||||
{ USB_DEVICE(0x0489, 0xe057) },
|
||||
{ USB_DEVICE(0x13d3, 0x3393) },
|
||||
{ USB_DEVICE(0x0489, 0xe04e) },
|
||||
{ USB_DEVICE(0x0489, 0xe056) },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE02C) },
|
||||
|
@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
|
@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
|
||||
|
|
|
@ -317,7 +317,6 @@ struct ath_rx {
|
|||
u32 *rxlink;
|
||||
u32 num_pkts;
|
||||
unsigned int rxfilter;
|
||||
spinlock_t rxbuflock;
|
||||
struct list_head rxbuf;
|
||||
struct ath_descdma rxdma;
|
||||
struct ath_buf *rx_bufptr;
|
||||
|
@ -328,7 +327,6 @@ struct ath_rx {
|
|||
|
||||
int ath_startrecv(struct ath_softc *sc);
|
||||
bool ath_stoprecv(struct ath_softc *sc);
|
||||
void ath_flushrecv(struct ath_softc *sc);
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc);
|
||||
int ath_rx_init(struct ath_softc *sc, int nbufs);
|
||||
void ath_rx_cleanup(struct ath_softc *sc);
|
||||
|
@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
|
|||
enum sc_op_flags {
|
||||
SC_OP_INVALID,
|
||||
SC_OP_BEACONS,
|
||||
SC_OP_RXFLUSH,
|
||||
SC_OP_ANI_RUN,
|
||||
SC_OP_PRIM_STA_VIF,
|
||||
SC_OP_HW_RESET,
|
||||
|
|
|
@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
|
|||
skb->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb_any(skb);
|
||||
bf->bf_buf_addr = 0;
|
||||
bf->bf_mpdu = NULL;
|
||||
}
|
||||
|
||||
skb = ieee80211_beacon_get(hw, vif);
|
||||
|
@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)
|
|||
return;
|
||||
|
||||
bf = ath9k_beacon_generate(sc->hw, vif);
|
||||
WARN_ON(!bf);
|
||||
|
||||
if (sc->beacon.bmisscnt != 0) {
|
||||
ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
|
||||
|
|
|
@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
|
|||
RXS_ERR("RX-LENGTH-ERR", rx_len_err);
|
||||
RXS_ERR("RX-OOM-ERR", rx_oom_err);
|
||||
RXS_ERR("RX-RATE-ERR", rx_rate_err);
|
||||
RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
|
||||
RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);
|
||||
|
||||
PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
|
||||
|
|
|
@ -216,7 +216,6 @@ struct ath_tx_stats {
|
|||
* @rx_oom_err: No. of frames dropped due to OOM issues.
|
||||
* @rx_rate_err: No. of frames dropped due to rate errors.
|
||||
* @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
|
||||
* @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
|
||||
* @rx_beacons: No. of beacons received.
|
||||
* @rx_frags: No. of rx-fragements received.
|
||||
*/
|
||||
|
@ -235,7 +234,6 @@ struct ath_rx_stats {
|
|||
u32 rx_oom_err;
|
||||
u32 rx_rate_err;
|
||||
u32 rx_too_many_frags_err;
|
||||
u32 rx_drop_rxflush;
|
||||
u32 rx_beacons;
|
||||
u32 rx_frags;
|
||||
};
|
||||
|
|
|
@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
|
|||
endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
|
||||
skb, htc_hdr->endpoint_id,
|
||||
txok);
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)
|
|||
ath_start_ani(sc);
|
||||
}
|
||||
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
bool ret = true;
|
||||
|
@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
|||
if (!ath_drain_all_txq(sc, retry_tx))
|
||||
ret = false;
|
||||
|
||||
if (!flush) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
} else {
|
||||
ath_flushrecv(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
|||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = NULL;
|
||||
bool fastcc = true;
|
||||
bool flush = false;
|
||||
int r;
|
||||
|
||||
__ath_cancel_work(sc);
|
||||
|
||||
tasklet_disable(&sc->intr_tq);
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
|
||||
|
@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
|||
|
||||
if (!hchan) {
|
||||
fastcc = false;
|
||||
flush = true;
|
||||
hchan = ah->curchan;
|
||||
}
|
||||
|
||||
if (!ath_prepare_reset(sc, retry_tx, flush))
|
||||
if (!ath_prepare_reset(sc, retry_tx))
|
||||
fastcc = false;
|
||||
|
||||
ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
|
||||
|
@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
|||
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
tasklet_enable(&sc->intr_tq);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
|||
ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
|
||||
}
|
||||
|
||||
ath_prepare_reset(sc, false, true);
|
||||
ath_prepare_reset(sc, false);
|
||||
|
||||
if (sc->rx.frag) {
|
||||
dev_kfree_skb_any(sc->rx.frag);
|
||||
|
|
|
@ -254,8 +254,6 @@ rx_init_fail:
|
|||
|
||||
static void ath_edma_start_recv(struct ath_softc *sc)
|
||||
{
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
ath9k_hw_rxena(sc->sc_ah);
|
||||
|
||||
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
|
||||
|
@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
|
|||
ath_opmode_init(sc);
|
||||
|
||||
ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
}
|
||||
|
||||
static void ath_edma_stop_recv(struct ath_softc *sc)
|
||||
|
@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
|
|||
int error = 0;
|
||||
|
||||
spin_lock_init(&sc->sc_pcu_lock);
|
||||
spin_lock_init(&sc->rx.rxbuflock);
|
||||
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
|
||||
common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
|
||||
sc->sc_ah->caps.rx_status_len;
|
||||
|
@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
|
||||
|
@ -468,26 +461,31 @@ start_recv:
|
|||
ath_opmode_init(sc);
|
||||
ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
}
|
||||
|
||||
bool ath_stoprecv(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
bool stopped, reset = false;
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
ath9k_hw_abortpcurecv(ah);
|
||||
ath9k_hw_setrxfilter(ah, 0);
|
||||
stopped = ath9k_hw_stopdmarecv(ah, &reset);
|
||||
|
||||
ath_flushrecv(sc);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_edma_stop_recv(sc);
|
||||
else
|
||||
sc->rx.rxlink = NULL;
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
if (!(ah->ah_flags & AH_UNPLUGGED) &&
|
||||
unlikely(!stopped)) {
|
||||
|
@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
|
|||
return stopped && !reset;
|
||||
}
|
||||
|
||||
void ath_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
|
||||
}
|
||||
|
||||
static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
|
||||
{
|
||||
/* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
|
||||
|
@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
list_del(&bf->list);
|
||||
if (!bf->bf_mpdu)
|
||||
return bf;
|
||||
|
||||
|
@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|||
dma_type = DMA_FROM_DEVICE;
|
||||
|
||||
qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
tsf_lower = tsf & 0xffffffff;
|
||||
|
||||
do {
|
||||
bool decrypt_error = false;
|
||||
/* If handling rx interrupt and flush is in progress => exit */
|
||||
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
|
||||
break;
|
||||
|
||||
memset(&rs, 0, sizeof(rs));
|
||||
if (edma)
|
||||
|
@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|||
|
||||
ath_debug_stat_rx(sc, &rs);
|
||||
|
||||
/*
|
||||
* If we're asked to flush receive queue, directly
|
||||
* chain it back at the queue without processing it.
|
||||
*/
|
||||
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
|
||||
RX_STAT_INC(rx_drop_rxflush);
|
||||
goto requeue_drop_frag;
|
||||
}
|
||||
|
||||
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
|
||||
|
||||
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
|
||||
|
@ -1254,19 +1231,18 @@ requeue_drop_frag:
|
|||
sc->rx.frag = NULL;
|
||||
}
|
||||
requeue:
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
if (flush)
|
||||
continue;
|
||||
|
||||
if (edma) {
|
||||
list_add_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
} else {
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
if (!flush)
|
||||
ath9k_hw_rxena(ah);
|
||||
ath9k_hw_rxena(ah);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
spin_unlock_bh(&sc->rx.rxbuflock);
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_RXEOL)) {
|
||||
ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
|
|
|
@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
|
|||
#endif
|
||||
t->ms = ms;
|
||||
t->periodic = (bool) periodic;
|
||||
t->set = true;
|
||||
|
||||
atomic_inc(&t->wl->callbacks);
|
||||
if (!t->set) {
|
||||
t->set = true;
|
||||
atomic_inc(&t->wl->callbacks);
|
||||
}
|
||||
|
||||
ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
|
||||
}
|
||||
|
|
|
@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
|
|||
struct cfg80211_ssid req_ssid;
|
||||
int ret, auth_type = 0;
|
||||
struct cfg80211_bss *bss = NULL;
|
||||
u8 is_scanning_required = 0, config_bands = 0;
|
||||
u8 is_scanning_required = 0;
|
||||
|
||||
memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));
|
||||
|
||||
|
@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
|
|||
/* disconnect before try to associate */
|
||||
mwifiex_deauthenticate(priv, NULL);
|
||||
|
||||
if (channel) {
|
||||
if (mode == NL80211_IFTYPE_STATION) {
|
||||
if (channel->band == IEEE80211_BAND_2GHZ)
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
else
|
||||
config_bands = BAND_A | BAND_AN;
|
||||
|
||||
if (!((config_bands | priv->adapter->fw_bands) &
|
||||
~priv->adapter->fw_bands))
|
||||
priv->adapter->config_bands = config_bands;
|
||||
}
|
||||
}
|
||||
|
||||
/* As this is new association, clear locally stored
|
||||
* keys and security related flags */
|
||||
priv->sec_info.wpa_enabled = false;
|
||||
|
@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
|
|||
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) !=
|
||||
NL80211_CHAN_NO_HT)
|
||||
config_bands |= BAND_GN;
|
||||
config_bands |= BAND_G | BAND_GN;
|
||||
} else {
|
||||
if (cfg80211_get_chandef_type(¶ms->chandef) ==
|
||||
NL80211_CHAN_NO_HT)
|
||||
|
|
|
@ -283,6 +283,20 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
|||
if (ret)
|
||||
goto done;
|
||||
|
||||
if (bss_desc) {
|
||||
u8 config_bands = 0;
|
||||
|
||||
if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
|
||||
== HostCmd_SCAN_RADIO_TYPE_BG)
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
else
|
||||
config_bands = BAND_A | BAND_AN;
|
||||
|
||||
if (!((config_bands | adapter->fw_bands) &
|
||||
~adapter->fw_bands))
|
||||
adapter->config_bands = config_bands;
|
||||
}
|
||||
|
||||
ret = mwifiex_check_network_compatibility(priv, bss_desc);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
|
|
@ -2810,14 +2810,6 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (conn) {
|
||||
hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
|
||||
mgmt_device_connected(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, 0, NULL, 0,
|
||||
conn->dev_class);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
/* Send to upper protocol */
|
||||
l2cap_recv_acldata(conn, skb, flags);
|
||||
return;
|
||||
|
|
|
@ -2688,7 +2688,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (ev->opcode != HCI_OP_NOP)
|
||||
del_timer(&hdev->cmd_timer);
|
||||
|
||||
if (ev->ncmd) {
|
||||
if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
|
||||
atomic_set(&hdev->cmd_cnt, 1);
|
||||
if (!skb_queue_empty(&hdev->cmd_q))
|
||||
queue_work(hdev->workqueue, &hdev->cmd_work);
|
||||
|
|
|
@ -931,7 +931,7 @@ static int hidp_setup_hid(struct hidp_session *session,
|
|||
hid->version = req->version;
|
||||
hid->country = req->country;
|
||||
|
||||
strncpy(hid->name, req->name, 128);
|
||||
strncpy(hid->name, req->name, sizeof(req->name) - 1);
|
||||
|
||||
snprintf(hid->phys, sizeof(hid->phys), "%pMR",
|
||||
&bt_sk(session->ctrl_sock->sk)->src);
|
||||
|
|
|
@ -3727,6 +3727,17 @@ sendresp:
|
|||
static int l2cap_connect_req(struct l2cap_conn *conn,
|
||||
struct l2cap_cmd_hdr *cmd, u8 *data)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hcon->hdev;
|
||||
struct hci_conn *hcon = conn->hcon;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
|
||||
mgmt_device_connected(hdev, &hcon->dst, hcon->type,
|
||||
hcon->dst_type, 0, NULL, 0,
|
||||
hcon->dev_class);
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ static void __sco_sock_close(struct sock *sk)
|
|||
|
||||
case BT_CONNECTED:
|
||||
case BT_CONFIG:
|
||||
if (sco_pi(sk)->conn) {
|
||||
if (sco_pi(sk)->conn->hcon) {
|
||||
sk->sk_state = BT_DISCONN;
|
||||
sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT);
|
||||
hci_conn_put(sco_pi(sk)->conn->hcon);
|
||||
|
|
Загрузка…
Ссылка в новой задаче