diff --git a/[refs] b/[refs] index cc6753ae2013..d5772d36e2f4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e21b9d031fa184632c373eedc12e3c296e1aa65b +refs/heads/master: 48856286b64e4b66ec62b94e504d0b29c1ade664 diff --git a/trunk/drivers/bcma/bcma_private.h b/trunk/drivers/bcma/bcma_private.h index cb0c45488572..19e3fbfd5757 100644 --- a/trunk/drivers/bcma/bcma_private.h +++ b/trunk/drivers/bcma/bcma_private.h @@ -94,16 +94,11 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); #ifdef CONFIG_BCMA_DRIVER_GPIO /* driver_gpio.c */ int bcma_gpio_init(struct bcma_drv_cc *cc); -int bcma_gpio_unregister(struct bcma_drv_cc *cc); #else static inline int bcma_gpio_init(struct bcma_drv_cc *cc) { return -ENOTSUPP; } -static inline int bcma_gpio_unregister(struct bcma_drv_cc *cc) -{ - return 0; -} #endif /* CONFIG_BCMA_DRIVER_GPIO */ #endif diff --git a/trunk/drivers/bcma/driver_gpio.c b/trunk/drivers/bcma/driver_gpio.c index 71f755c06fc6..9a6f585da2d9 100644 --- a/trunk/drivers/bcma/driver_gpio.c +++ b/trunk/drivers/bcma/driver_gpio.c @@ -96,8 +96,3 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) return gpiochip_add(chip); } - -int bcma_gpio_unregister(struct bcma_drv_cc *cc) -{ - return gpiochip_remove(&cc->gpio); -} diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index 324f9debda88..4a92f647b58b 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -268,13 +268,6 @@ int bcma_bus_register(struct bcma_bus *bus) void bcma_bus_unregister(struct bcma_bus *bus) { struct bcma_device *cores[3]; - int err; - - err = bcma_gpio_unregister(&bus->drv_cc); - if (err == -EBUSY) - bcma_err(bus, "Some GPIOs are still in use.\n"); - else if (err) - bcma_err(bus, "Can not unregister GPIO driver: %i\n", err); cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index 00d3b2d37828..9197b2c72ca3 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -1215,9 +1215,6 @@ static const struct usb_device_id cdc_devs[] = { { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), .driver_info = (unsigned long)&wwan_info, }, - { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), - .driver_info = (unsigned long)&wwan_info, - }, /* Infineon(now Intel) HSPA Modem platform */ { USB_DEVICE_AND_INTERFACE_INFO(0x1519, 0x0443, diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index c8e05e27f38c..2ca7f8ea2dca 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -351,10 +351,6 @@ static const struct usb_device_id products[] = { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), .driver_info = (unsigned long)&qmi_wwan_info, }, - { /* HUAWEI_INTERFACE_NDIS_CONTROL_QUALCOMM */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x69), - .driver_info = (unsigned long)&qmi_wwan_info, - }, /* 2. Combined interface devices matching on class+protocol */ { /* Huawei E367 and possibly others in "Windows mode" */ @@ -365,14 +361,6 @@ static const struct usb_device_id products[] = { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), .driver_info = (unsigned long)&qmi_wwan_info, }, - { /* HUAWEI_NDIS_SINGLE_INTERFACE_VDF */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x37), - .driver_info = (unsigned long)&qmi_wwan_info, - }, - { /* HUAWEI_INTERFACE_NDIS_HW_QUALCOMM */ - USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 0x01, 0x67), - .driver_info = (unsigned long)&qmi_wwan_info, - }, { /* Pantech UML290, P4200 and more */ USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), .driver_info = (unsigned long)&qmi_wwan_info, diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index e5fd20994bec..0f71d1d4339d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -36,7 +36,6 @@ #include "debug.h" #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ -#define BRCMS_FLUSH_TIMEOUT 500 /* msec */ /* Flags we support */ #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ @@ -709,29 +708,16 @@ static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw) wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); } -static bool brcms_tx_flush_completed(struct brcms_info *wl) -{ - bool result; - - spin_lock_bh(&wl->lock); - result = brcms_c_tx_flush_completed(wl->wlc); - spin_unlock_bh(&wl->lock); - return result; -} - static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) { struct brcms_info *wl = hw->priv; - int ret; no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); - ret = wait_event_timeout(wl->tx_flush_wq, - brcms_tx_flush_completed(wl), - msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT)); - - brcms_dbg_mac80211(wl->wlc->hw->d11core, - "ret=%d\n", jiffies_to_msecs(ret)); + /* wait for packet queue and dma fifos to run empty */ + spin_lock_bh(&wl->lock); + brcms_c_wait_for_tx_completion(wl->wlc, drop); + spin_unlock_bh(&wl->lock); } static const struct ieee80211_ops brcms_ops = { @@ -786,7 +772,6 @@ void brcms_dpc(unsigned long data) done: spin_unlock_bh(&wl->lock); - wake_up(&wl->tx_flush_wq); } /* @@ -1035,8 +1020,6 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) atomic_set(&wl->callbacks, 0); - init_waitqueue_head(&wl->tx_flush_wq); - /* setup the bottom half handler */ tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); @@ -1626,3 +1609,13 @@ bool brcms_rfkill_set_hw_state(struct brcms_info *wl) spin_lock_bh(&wl->lock); return blocked; } + +/* + * precondition: perimeter lock has been acquired + */ +void brcms_msleep(struct brcms_info *wl, uint ms) +{ + spin_unlock_bh(&wl->lock); + msleep(ms); + spin_lock_bh(&wl->lock); +} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 947ccacf43e6..9358bd5ebd35 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -68,8 +68,6 @@ struct brcms_info { spinlock_t lock; /* per-device perimeter lock */ spinlock_t isr_lock; /* per-device ISR synchronization lock */ - /* tx flush */ - wait_queue_head_t tx_flush_wq; /* timer related fields */ atomic_t callbacks; /* # outstanding callback functions */ @@ -102,6 +100,7 @@ extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, extern void brcms_free_timer(struct brcms_timer *timer); extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); extern bool brcms_del_timer(struct brcms_timer *timer); +extern void brcms_msleep(struct brcms_info *wl, uint ms); extern void brcms_dpc(unsigned long data); extern void brcms_timer(struct brcms_timer *t); extern void brcms_fatal_error(struct brcms_info *wl); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index 8b5839008af3..9f3d7e9f3bb5 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -7511,16 +7511,25 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) return wlc->band->bandunit; } -bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc) +void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { + int timeout = 20; int i; /* Kick DMA to send any pending AMPDU */ for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) if (wlc->hw->di[i]) - dma_kick_tx(wlc->hw->di[i]); + dma_txflush(wlc->hw->di[i]); - return !brcms_txpktpendtot(wlc); + /* wait for queue and DMA fifos to run dry */ + while (brcms_txpktpendtot(wlc) > 0) { + brcms_msleep(wlc->wl, 1); + + if (--timeout == 0) + break; + } + + WARN_ON_ONCE(timeout == 0); } void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h index b0f14b7b8616..4fb2834f4e64 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -314,6 +314,8 @@ extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); extern void brcms_c_scan_start(struct brcms_c_info *wlc); extern void brcms_c_scan_stop(struct brcms_c_info *wlc); extern int brcms_c_get_curband(struct brcms_c_info *wlc); +extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, + bool drop); extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, @@ -330,6 +332,5 @@ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); -extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); #endif /* _BRCM_PUB_H_ */ diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index 0f8b05185eda..4494d130b37c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -1004,8 +1004,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) is_tx ? "Tx" : "Rx"); if (is_tx) { - schedule_work(&rtlpriv-> - works.lps_leave_work); + rtl_lps_leave(hw); ppsc->last_delaylps_stamp_jiffies = jiffies; } @@ -1015,7 +1014,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) } } else if (ETH_P_ARP == ether_type) { if (is_tx) { - schedule_work(&rtlpriv->works.lps_leave_work); + rtl_lps_leave(hw); ppsc->last_delaylps_stamp_jiffies = jiffies; } @@ -1025,7 +1024,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { - schedule_work(&rtlpriv->works.lps_leave_work); + rtl_lps_leave(hw); ppsc->last_delaylps_stamp_jiffies = jiffies; } diff --git a/trunk/drivers/net/xen-netback/common.h b/trunk/drivers/net/xen-netback/common.h index 94b79c3338c4..9d7f1723dd8f 100644 --- a/trunk/drivers/net/xen-netback/common.h +++ b/trunk/drivers/net/xen-netback/common.h @@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb); /* Notify xenvif that ring now has space to send an skb to the frontend */ void xenvif_notify_tx_completion(struct xenvif *vif); +/* Prevent the device from generating any further traffic. */ +void xenvif_carrier_off(struct xenvif *vif); + /* Returns number of ring slots required to send an skb to the frontend */ unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); diff --git a/trunk/drivers/net/xen-netback/interface.c b/trunk/drivers/net/xen-netback/interface.c index b7d41f8c338a..b8c5193bd420 100644 --- a/trunk/drivers/net/xen-netback/interface.c +++ b/trunk/drivers/net/xen-netback/interface.c @@ -343,17 +343,22 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, return err; } -void xenvif_disconnect(struct xenvif *vif) +void xenvif_carrier_off(struct xenvif *vif) { struct net_device *dev = vif->dev; - if (netif_carrier_ok(dev)) { - rtnl_lock(); - netif_carrier_off(dev); /* discard queued packets */ - if (netif_running(dev)) - xenvif_down(vif); - rtnl_unlock(); - xenvif_put(vif); - } + + rtnl_lock(); + netif_carrier_off(dev); /* discard queued packets */ + if (netif_running(dev)) + xenvif_down(vif); + rtnl_unlock(); + xenvif_put(vif); +} + +void xenvif_disconnect(struct xenvif *vif) +{ + if (netif_carrier_ok(vif->dev)) + xenvif_carrier_off(vif); atomic_dec(&vif->refcnt); wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); diff --git a/trunk/drivers/net/xen-netback/netback.c b/trunk/drivers/net/xen-netback/netback.c index f2d6b78d901d..c2e3336b4f98 100644 --- a/trunk/drivers/net/xen-netback/netback.c +++ b/trunk/drivers/net/xen-netback/netback.c @@ -888,6 +888,13 @@ static void netbk_tx_err(struct xenvif *vif, xenvif_put(vif); } +static void netbk_fatal_tx_err(struct xenvif *vif) +{ + netdev_err(vif->dev, "fatal error; disabling device\n"); + xenvif_carrier_off(vif); + xenvif_put(vif); +} + static int netbk_count_requests(struct xenvif *vif, struct xen_netif_tx_request *first, struct xen_netif_tx_request *txp, @@ -901,19 +908,22 @@ static int netbk_count_requests(struct xenvif *vif, do { if (frags >= work_to_do) { - netdev_dbg(vif->dev, "Need more frags\n"); + netdev_err(vif->dev, "Need more frags\n"); + netbk_fatal_tx_err(vif); return -frags; } if (unlikely(frags >= MAX_SKB_FRAGS)) { - netdev_dbg(vif->dev, "Too many frags\n"); + netdev_err(vif->dev, "Too many frags\n"); + netbk_fatal_tx_err(vif); return -frags; } memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), sizeof(*txp)); if (txp->size > first->size) { - netdev_dbg(vif->dev, "Frags galore\n"); + netdev_err(vif->dev, "Frag is bigger than frame.\n"); + netbk_fatal_tx_err(vif); return -frags; } @@ -921,8 +931,9 @@ static int netbk_count_requests(struct xenvif *vif, frags++; if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { - netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", + netdev_err(vif->dev, "txp->offset: %x, size: %u\n", txp->offset, txp->size); + netbk_fatal_tx_err(vif); return -frags; } } while ((txp++)->flags & XEN_NETTXF_more_data); @@ -1095,7 +1106,8 @@ static int xen_netbk_get_extras(struct xenvif *vif, do { if (unlikely(work_to_do-- <= 0)) { - netdev_dbg(vif->dev, "Missing extra info\n"); + netdev_err(vif->dev, "Missing extra info\n"); + netbk_fatal_tx_err(vif); return -EBADR; } @@ -1104,8 +1116,9 @@ static int xen_netbk_get_extras(struct xenvif *vif, if (unlikely(!extra.type || extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { vif->tx.req_cons = ++cons; - netdev_dbg(vif->dev, + netdev_err(vif->dev, "Invalid extra type: %d\n", extra.type); + netbk_fatal_tx_err(vif); return -EINVAL; } @@ -1121,13 +1134,15 @@ static int netbk_set_skb_gso(struct xenvif *vif, struct xen_netif_extra_info *gso) { if (!gso->u.gso.size) { - netdev_dbg(vif->dev, "GSO size must not be zero.\n"); + netdev_err(vif->dev, "GSO size must not be zero.\n"); + netbk_fatal_tx_err(vif); return -EINVAL; } /* Currently only TCPv4 S.O. is supported. */ if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { - netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); + netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); + netbk_fatal_tx_err(vif); return -EINVAL; } @@ -1264,9 +1279,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) /* Get a netif from the list with work to do. */ vif = poll_net_schedule_list(netbk); + /* This can sometimes happen because the test of + * list_empty(net_schedule_list) at the top of the + * loop is unlocked. Just go back and have another + * look. + */ if (!vif) continue; + if (vif->tx.sring->req_prod - vif->tx.req_cons > + XEN_NETIF_TX_RING_SIZE) { + netdev_err(vif->dev, + "Impossible number of requests. " + "req_prod %d, req_cons %d, size %ld\n", + vif->tx.sring->req_prod, vif->tx.req_cons, + XEN_NETIF_TX_RING_SIZE); + netbk_fatal_tx_err(vif); + continue; + } + RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); if (!work_to_do) { xenvif_put(vif); @@ -1294,17 +1325,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) work_to_do = xen_netbk_get_extras(vif, extras, work_to_do); idx = vif->tx.req_cons; - if (unlikely(work_to_do < 0)) { - netbk_tx_err(vif, &txreq, idx); + if (unlikely(work_to_do < 0)) continue; - } } ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); - if (unlikely(ret < 0)) { - netbk_tx_err(vif, &txreq, idx - ret); + if (unlikely(ret < 0)) continue; - } + idx += ret; if (unlikely(txreq.size < ETH_HLEN)) { @@ -1316,11 +1344,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) /* No crossing a page as the payload mustn't fragment. */ if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { - netdev_dbg(vif->dev, + netdev_err(vif->dev, "txreq.offset: %x, size: %u, end: %lu\n", txreq.offset, txreq.size, (txreq.offset&~PAGE_MASK) + txreq.size); - netbk_tx_err(vif, &txreq, idx); + netbk_fatal_tx_err(vif); continue; } @@ -1348,8 +1376,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; if (netbk_set_skb_gso(vif, skb, gso)) { + /* Failure in netbk_set_skb_gso is fatal. */ kfree_skb(skb); - netbk_tx_err(vif, &txreq, idx); continue; } } diff --git a/trunk/drivers/ssb/driver_gpio.c b/trunk/drivers/ssb/driver_gpio.c index eb2753008ef0..97ac0a38e3d0 100644 --- a/trunk/drivers/ssb/driver_gpio.c +++ b/trunk/drivers/ssb/driver_gpio.c @@ -174,15 +174,3 @@ int ssb_gpio_init(struct ssb_bus *bus) return -1; } - -int ssb_gpio_unregister(struct ssb_bus *bus) -{ - if (ssb_chipco_available(&bus->chipco) || - ssb_extif_available(&bus->extif)) { - return gpiochip_remove(&bus->gpio); - } else { - SSB_WARN_ON(1); - } - - return -1; -} diff --git a/trunk/drivers/ssb/main.c b/trunk/drivers/ssb/main.c index 24dc331b4701..772ad9b5c304 100644 --- a/trunk/drivers/ssb/main.c +++ b/trunk/drivers/ssb/main.c @@ -443,15 +443,6 @@ static void ssb_devices_unregister(struct ssb_bus *bus) void ssb_bus_unregister(struct ssb_bus *bus) { - int err; - - err = ssb_gpio_unregister(bus); - if (err == -EBUSY) - ssb_dprintk(KERN_ERR PFX "Some GPIOs are still in use.\n"); - else if (err) - ssb_dprintk(KERN_ERR PFX - "Can not unregister GPIO driver: %i\n", err); - ssb_buses_lock(); ssb_devices_unregister(bus); list_del(&bus->list); diff --git a/trunk/drivers/ssb/ssb_private.h b/trunk/drivers/ssb/ssb_private.h index da38305a2d22..6c10b66c796c 100644 --- a/trunk/drivers/ssb/ssb_private.h +++ b/trunk/drivers/ssb/ssb_private.h @@ -252,16 +252,11 @@ static inline void ssb_extif_init(struct ssb_extif *extif) #ifdef CONFIG_SSB_DRIVER_GPIO extern int ssb_gpio_init(struct ssb_bus *bus); -extern int ssb_gpio_unregister(struct ssb_bus *bus); #else /* CONFIG_SSB_DRIVER_GPIO */ static inline int ssb_gpio_init(struct ssb_bus *bus) { return -ENOTSUPP; } -static inline int ssb_gpio_unregister(struct ssb_bus *bus) -{ - return 0; -} #endif /* CONFIG_SSB_DRIVER_GPIO */ #endif /* LINUX_SSB_PRIVATE_H_ */ diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 4925a02ae7e4..25bfce0666eb 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -249,12 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn) __u8 reason = hci_proto_disconn_ind(conn); switch (conn->type) { + case ACL_LINK: + hci_acl_disconn(conn, reason); + break; case AMP_LINK: hci_amp_disconn(conn, reason); break; - default: - hci_acl_disconn(conn, reason); - break; } } diff --git a/trunk/net/bluetooth/smp.c b/trunk/net/bluetooth/smp.c index 5abefb12891d..68a9587c9694 100644 --- a/trunk/net/bluetooth/smp.c +++ b/trunk/net/bluetooth/smp.c @@ -859,19 +859,6 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) skb_pull(skb, sizeof(code)); - /* - * The SMP context must be initialized for all other PDUs except - * pairing and security requests. If we get any other PDU when - * not initialized simply disconnect (done if this function - * returns an error). - */ - if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && - !conn->smp_chan) { - BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); - kfree_skb(skb); - return -ENOTSUPP; - } - switch (code) { case SMP_CMD_PAIRING_REQ: reason = smp_cmd_pairing_req(conn, skb); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index ad70a962c20e..680c4224ed96 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -3484,7 +3484,8 @@ static bool tcp_process_frto(struct sock *sk, int flag) ((tp->frto_counter >= 2) && (flag & FLAG_RETRANS_DATA_ACKED))) tp->undo_marker = 0; - if (!before(tp->snd_una, tp->frto_highmark)) { + if (!before(tp->snd_una, tp->frto_highmark) || + !tcp_packets_in_flight(tp)) { tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), flag); return true; } @@ -3504,11 +3505,6 @@ static bool tcp_process_frto(struct sock *sk, int flag) } } else { if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) { - if (!tcp_packets_in_flight(tp)) { - tcp_enter_frto_loss(sk, 2, flag); - return true; - } - /* Prevent sending of new data. */ tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)); diff --git a/trunk/net/ipv6/ip6_gre.c b/trunk/net/ipv6/ip6_gre.c index 131dd097736d..c727e4712751 100644 --- a/trunk/net/ipv6/ip6_gre.c +++ b/trunk/net/ipv6/ip6_gre.c @@ -960,7 +960,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb, int ret; if (!ip6_tnl_xmit_ctl(t)) - goto tx_err; + return -1; switch (skb->protocol) { case htons(ETH_P_IP):