Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: tcp: Fix tcp_hybla zero congestion window growth with small rho and large cwnd. net: Fix netdev_run_todo dead-lock tcp: Fix possible double-ack w/ user dma net: only invoke dev->change_rx_flags when device is UP netrom: Fix sock_orphan() use in nr_release ax25: Quick fix for making sure unaccepted sockets get destroyed. Revert "ax25: Fix std timer socket destroy handling." [Bluetooth] Add reset quirk for A-Link BlueUSB21 dongle [Bluetooth] Add reset quirk for new Targus and Belkin dongles [Bluetooth] Fix double frees on error paths of btusb and bpa10x drivers
This commit is contained in:
commit
392eaef2e9
@ -256,7 +256,6 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
|
|||||||
BT_ERR("%s urb %p submission failed (%d)",
|
BT_ERR("%s urb %p submission failed (%d)",
|
||||||
hdev->name, urb, -err);
|
hdev->name, urb, -err);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
@ -298,7 +297,6 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
|
|||||||
BT_ERR("%s urb %p submission failed (%d)",
|
BT_ERR("%s urb %p submission failed (%d)",
|
||||||
hdev->name, urb, -err);
|
hdev->name, urb, -err);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
|
@ -102,6 +102,7 @@ static struct usb_device_id blacklist_table[] = {
|
|||||||
{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
||||||
|
|
||||||
/* Broadcom BCM2046 */
|
/* Broadcom BCM2046 */
|
||||||
|
{ USB_DEVICE(0x0a5c, 0x2146), .driver_info = BTUSB_RESET },
|
||||||
{ USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
|
{ USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
|
||||||
|
|
||||||
/* Apple MacBook Pro with Broadcom chip */
|
/* Apple MacBook Pro with Broadcom chip */
|
||||||
@ -113,6 +114,7 @@ static struct usb_device_id blacklist_table[] = {
|
|||||||
|
|
||||||
/* Targus ACB10US */
|
/* Targus ACB10US */
|
||||||
{ USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET },
|
{ USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET },
|
||||||
|
{ USB_DEVICE(0x0a5c, 0x2154), .driver_info = BTUSB_RESET },
|
||||||
|
|
||||||
/* ANYCOM Bluetooth USB-200 and USB-250 */
|
/* ANYCOM Bluetooth USB-200 and USB-250 */
|
||||||
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET },
|
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET },
|
||||||
@ -150,6 +152,9 @@ static struct usb_device_id blacklist_table[] = {
|
|||||||
{ USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
{ USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
||||||
{ USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
{ USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
|
||||||
|
|
||||||
|
/* Belkin F8T016 device */
|
||||||
|
{ USB_DEVICE(0x050d, 0x016a), .driver_info = BTUSB_RESET },
|
||||||
|
|
||||||
/* Digianswer devices */
|
/* Digianswer devices */
|
||||||
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
|
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
|
||||||
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
|
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
|
||||||
@ -271,7 +276,6 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev)
|
|||||||
BT_ERR("%s urb %p submission failed (%d)",
|
BT_ERR("%s urb %p submission failed (%d)",
|
||||||
hdev->name, urb, -err);
|
hdev->name, urb, -err);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
@ -354,7 +358,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev)
|
|||||||
BT_ERR("%s urb %p submission failed (%d)",
|
BT_ERR("%s urb %p submission failed (%d)",
|
||||||
hdev->name, urb, -err);
|
hdev->name, urb, -err);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
@ -475,7 +478,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev)
|
|||||||
BT_ERR("%s urb %p submission failed (%d)",
|
BT_ERR("%s urb %p submission failed (%d)",
|
||||||
hdev->name, urb, -err);
|
hdev->name, urb, -err);
|
||||||
usb_unanchor_urb(urb);
|
usb_unanchor_urb(urb);
|
||||||
kfree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
|
@ -317,6 +317,9 @@ void ax25_destroy_socket(ax25_cb *ax25)
|
|||||||
/* Queue the unaccepted socket for death */
|
/* Queue the unaccepted socket for death */
|
||||||
sock_orphan(skb->sk);
|
sock_orphan(skb->sk);
|
||||||
|
|
||||||
|
/* 9A4GL: hack to release unaccepted sockets */
|
||||||
|
skb->sk->sk_state = TCP_LISTEN;
|
||||||
|
|
||||||
ax25_start_heartbeat(sax25);
|
ax25_start_heartbeat(sax25);
|
||||||
sax25->state = AX25_STATE_0;
|
sax25->state = AX25_STATE_0;
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,11 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
|
|||||||
|
|
||||||
switch (ax25->state) {
|
switch (ax25->state) {
|
||||||
case AX25_STATE_0:
|
case AX25_STATE_0:
|
||||||
if (!sk ||
|
/* Magic here: If we listen() and a new link dies before it
|
||||||
sock_flag(sk, SOCK_DESTROY) ||
|
is accepted() it isn't 'dead' so doesn't get removed. */
|
||||||
sock_flag(sk, SOCK_DEAD)) {
|
if (!sk || sock_flag(sk, SOCK_DESTROY) ||
|
||||||
|
(sk->sk_state == TCP_LISTEN &&
|
||||||
|
sock_flag(sk, SOCK_DEAD))) {
|
||||||
if (sk) {
|
if (sk) {
|
||||||
sock_hold(sk);
|
sock_hold(sk);
|
||||||
ax25_destroy_socket(ax25);
|
ax25_destroy_socket(ax25);
|
||||||
|
@ -2918,6 +2918,12 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dev_change_rx_flags(struct net_device *dev, int flags)
|
||||||
|
{
|
||||||
|
if (dev->flags & IFF_UP && dev->change_rx_flags)
|
||||||
|
dev->change_rx_flags(dev, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static int __dev_set_promiscuity(struct net_device *dev, int inc)
|
static int __dev_set_promiscuity(struct net_device *dev, int inc)
|
||||||
{
|
{
|
||||||
unsigned short old_flags = dev->flags;
|
unsigned short old_flags = dev->flags;
|
||||||
@ -2955,8 +2961,7 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
|
|||||||
current->uid, current->gid,
|
current->uid, current->gid,
|
||||||
audit_get_sessionid(current));
|
audit_get_sessionid(current));
|
||||||
|
|
||||||
if (dev->change_rx_flags)
|
dev_change_rx_flags(dev, IFF_PROMISC);
|
||||||
dev->change_rx_flags(dev, IFF_PROMISC);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3022,8 +3027,7 @@ int dev_set_allmulti(struct net_device *dev, int inc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dev->flags ^ old_flags) {
|
if (dev->flags ^ old_flags) {
|
||||||
if (dev->change_rx_flags)
|
dev_change_rx_flags(dev, IFF_ALLMULTI);
|
||||||
dev->change_rx_flags(dev, IFF_ALLMULTI);
|
|
||||||
dev_set_rx_mode(dev);
|
dev_set_rx_mode(dev);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -3347,8 +3351,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
|
|||||||
* Load in the correct multicast list now the flags have changed.
|
* Load in the correct multicast list now the flags have changed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (dev->change_rx_flags && (old_flags ^ flags) & IFF_MULTICAST)
|
if ((old_flags ^ flags) & IFF_MULTICAST)
|
||||||
dev->change_rx_flags(dev, IFF_MULTICAST);
|
dev_change_rx_flags(dev, IFF_MULTICAST);
|
||||||
|
|
||||||
dev_set_rx_mode(dev);
|
dev_set_rx_mode(dev);
|
||||||
|
|
||||||
@ -3808,14 +3812,11 @@ static int dev_new_index(struct net *net)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delayed registration/unregisteration */
|
/* Delayed registration/unregisteration */
|
||||||
static DEFINE_SPINLOCK(net_todo_list_lock);
|
|
||||||
static LIST_HEAD(net_todo_list);
|
static LIST_HEAD(net_todo_list);
|
||||||
|
|
||||||
static void net_set_todo(struct net_device *dev)
|
static void net_set_todo(struct net_device *dev)
|
||||||
{
|
{
|
||||||
spin_lock(&net_todo_list_lock);
|
|
||||||
list_add_tail(&dev->todo_list, &net_todo_list);
|
list_add_tail(&dev->todo_list, &net_todo_list);
|
||||||
spin_unlock(&net_todo_list_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rollback_registered(struct net_device *dev)
|
static void rollback_registered(struct net_device *dev)
|
||||||
@ -4142,33 +4143,24 @@ static void netdev_wait_allrefs(struct net_device *dev)
|
|||||||
* free_netdev(y1);
|
* free_netdev(y1);
|
||||||
* free_netdev(y2);
|
* free_netdev(y2);
|
||||||
*
|
*
|
||||||
* We are invoked by rtnl_unlock() after it drops the semaphore.
|
* We are invoked by rtnl_unlock().
|
||||||
* This allows us to deal with problems:
|
* This allows us to deal with problems:
|
||||||
* 1) We can delete sysfs objects which invoke hotplug
|
* 1) We can delete sysfs objects which invoke hotplug
|
||||||
* without deadlocking with linkwatch via keventd.
|
* without deadlocking with linkwatch via keventd.
|
||||||
* 2) Since we run with the RTNL semaphore not held, we can sleep
|
* 2) Since we run with the RTNL semaphore not held, we can sleep
|
||||||
* safely in order to wait for the netdev refcnt to drop to zero.
|
* safely in order to wait for the netdev refcnt to drop to zero.
|
||||||
|
*
|
||||||
|
* We must not return until all unregister events added during
|
||||||
|
* the interval the lock was held have been completed.
|
||||||
*/
|
*/
|
||||||
static DEFINE_MUTEX(net_todo_run_mutex);
|
|
||||||
void netdev_run_todo(void)
|
void netdev_run_todo(void)
|
||||||
{
|
{
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
/* Need to guard against multiple cpu's getting out of order. */
|
|
||||||
mutex_lock(&net_todo_run_mutex);
|
|
||||||
|
|
||||||
/* Not safe to do outside the semaphore. We must not return
|
|
||||||
* until all unregister events invoked by the local processor
|
|
||||||
* have been completed (either by this todo run, or one on
|
|
||||||
* another cpu).
|
|
||||||
*/
|
|
||||||
if (list_empty(&net_todo_list))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Snapshot list, allow later requests */
|
/* Snapshot list, allow later requests */
|
||||||
spin_lock(&net_todo_list_lock);
|
|
||||||
list_replace_init(&net_todo_list, &list);
|
list_replace_init(&net_todo_list, &list);
|
||||||
spin_unlock(&net_todo_list_lock);
|
|
||||||
|
__rtnl_unlock();
|
||||||
|
|
||||||
while (!list_empty(&list)) {
|
while (!list_empty(&list)) {
|
||||||
struct net_device *dev
|
struct net_device *dev
|
||||||
@ -4200,9 +4192,6 @@ void netdev_run_todo(void)
|
|||||||
/* Free network device */
|
/* Free network device */
|
||||||
kobject_put(&dev->dev.kobj);
|
kobject_put(&dev->dev.kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&net_todo_run_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_device_stats *internal_stats(struct net_device *dev)
|
static struct net_device_stats *internal_stats(struct net_device *dev)
|
||||||
|
@ -73,7 +73,7 @@ void __rtnl_unlock(void)
|
|||||||
|
|
||||||
void rtnl_unlock(void)
|
void rtnl_unlock(void)
|
||||||
{
|
{
|
||||||
mutex_unlock(&rtnl_mutex);
|
/* This fellow will unlock it for us. */
|
||||||
netdev_run_todo();
|
netdev_run_todo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,11 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
|
|||||||
ca->snd_cwnd_cents -= 128;
|
ca->snd_cwnd_cents -= 128;
|
||||||
tp->snd_cwnd_cnt = 0;
|
tp->snd_cwnd_cnt = 0;
|
||||||
}
|
}
|
||||||
|
/* check when cwnd has not been incremented for a while */
|
||||||
|
if (increment == 0 && odd == 0 && tp->snd_cwnd_cnt >= tp->snd_cwnd) {
|
||||||
|
tp->snd_cwnd++;
|
||||||
|
tp->snd_cwnd_cnt = 0;
|
||||||
|
}
|
||||||
/* clamp down slowstart cwnd to ssthresh value. */
|
/* clamp down slowstart cwnd to ssthresh value. */
|
||||||
if (is_slowstart)
|
if (is_slowstart)
|
||||||
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
||||||
|
@ -4879,7 +4879,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
|
|||||||
goto no_ack;
|
goto no_ack;
|
||||||
}
|
}
|
||||||
|
|
||||||
__tcp_ack_snd_check(sk, 0);
|
if (!copied_early || tp->rcv_nxt != tp->rcv_wup)
|
||||||
|
__tcp_ack_snd_check(sk, 0);
|
||||||
no_ack:
|
no_ack:
|
||||||
#ifdef CONFIG_NET_DMA
|
#ifdef CONFIG_NET_DMA
|
||||||
if (copied_early)
|
if (copied_early)
|
||||||
|
@ -525,6 +525,7 @@ static int nr_release(struct socket *sock)
|
|||||||
if (sk == NULL) return 0;
|
if (sk == NULL) return 0;
|
||||||
|
|
||||||
sock_hold(sk);
|
sock_hold(sk);
|
||||||
|
sock_orphan(sk);
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
nr = nr_sk(sk);
|
nr = nr_sk(sk);
|
||||||
|
|
||||||
@ -548,7 +549,6 @@ static int nr_release(struct socket *sock)
|
|||||||
sk->sk_state = TCP_CLOSE;
|
sk->sk_state = TCP_CLOSE;
|
||||||
sk->sk_shutdown |= SEND_SHUTDOWN;
|
sk->sk_shutdown |= SEND_SHUTDOWN;
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
sock_orphan(sk);
|
|
||||||
sock_set_flag(sk, SOCK_DESTROY);
|
sock_set_flag(sk, SOCK_DESTROY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user