From bdbef3d696ca83489eb653459b5a7a62ecf5596a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Sep 2008 00:16:35 +0200 Subject: [Bluetooth] Fix I/O errors on MacBooks with Broadcom chips The newer MacBooks contain a Broadcom based Bluetooth chip and to make this work properly, HCI_Reset must be send first. If HCI_Reset is not used then a lot of I/O errors show up and its triggers packets from non-existent ACL links. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6a010681ecf..7665347238c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -104,6 +104,9 @@ static struct usb_device_id blacklist_table[] = { /* Broadcom BCM2046 */ { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, + /* Apple MacBook Pro with Broadcom chip */ + { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET }, + /* IBM/Lenovo ThinkPad with Broadcom chip */ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, -- cgit v1.2.3 From e8c3c3d22b340a406a9aab1b7a9f436636c3de9d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Sep 2008 00:16:36 +0200 Subject: [Bluetooth] Fix wrong URB handling of btusb driver The btusb driver contains two typos that result in some buggy behavior, but the impact is not immediately visible. During initialization the submitting of interrupt URBs might fail and then make sure to remove the correct flag and not one of the hci_dev flags. When closing down the interface make sure to kill the anchor for the ISOC URBs and not kill the interrupt URBs twice. Also cancel any scheduled work when closing down the interface. Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7665347238c..b4756a6a3a6 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -519,7 +519,7 @@ static int btusb_open(struct hci_dev *hdev) err = btusb_submit_intr_urb(hdev); if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &hdev->flags); + clear_bit(BTUSB_INTR_RUNNING, &data->flags); clear_bit(HCI_RUNNING, &hdev->flags); } @@ -535,8 +535,10 @@ static int btusb_close(struct hci_dev *hdev) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; + cancel_work_sync(&data->work); + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->intr_anchor); + usb_kill_anchored_urbs(&data->isoc_anchor); clear_bit(BTUSB_BULK_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->bulk_anchor); -- cgit v1.2.3 From 5fbcd260c2c52f78cd699f65e9c7af2e60b5380c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 23 Sep 2008 00:16:36 +0200 Subject: [Bluetooth] Fix USB disconnect handling of btusb driver The USB transport specification for Bluetooth splits the ACL and SCO handling into two separate interfaces. In Linux it possible to probe and disconnect these interfaces independently. So make sure that both interfaces are tightly bound together. This fixes the suspend regression that some people have expierenced. Signed-off-by: Oliver Neukum Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index b4756a6a3a6..29ae99817c6 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -172,6 +172,7 @@ static struct usb_device_id blacklist_table[] = { struct btusb_data { struct hci_dev *hdev; struct usb_device *udev; + struct usb_interface *intf; struct usb_interface *isoc; spinlock_t lock; @@ -826,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf, } data->udev = interface_to_usbdev(intf); + data->intf = intf; spin_lock_init(&data->lock); @@ -894,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf, if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, - data->isoc, NULL); + data->isoc, data); if (err < 0) { hci_free_dev(hdev); kfree(data); @@ -926,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf) hdev = data->hdev; - if (data->isoc) - usb_driver_release_interface(&btusb_driver, data->isoc); + __hci_dev_hold(hdev); - usb_set_intfdata(intf, NULL); + usb_set_intfdata(data->intf, NULL); + + if (data->isoc) + usb_set_intfdata(data->isoc, NULL); hci_unregister_dev(hdev); + if (intf == data->isoc) + usb_driver_release_interface(&btusb_driver, data->intf); + else if (data->isoc) + usb_driver_release_interface(&btusb_driver, data->isoc); + + __hci_dev_put(hdev); + hci_free_dev(hdev); } -- cgit v1.2.3 From 92cccc2cda9a744326bbd9f16c635187af7f8a09 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 23 Sep 2008 14:28:16 -0700 Subject: ath9k: disable MIB interrupts to fix interrupt storm Enabling the MIB interrupts has proven to cause an interrupt storm after 7 hours of run. We will make use of the MIB interrupt once we have ANI supported added so for now to cure this we disable the interrupt. The interrupt storm can be seen as follows after 7 hours of run as reported by Steven Noonan : 18:28:38 sum 1106.00 18:28:39 sum 1037.62 18:28:40 sum 1069.00 18:28:41 sum 1167.00 18:28:42 sum 1155.00 18:28:43 sum 1339.00 18:28:44 sum 18355.00 18:28:45 sum 17845.45 18:28:46 sum 15285.00 18:28:47 sum 17511.00 18:28:48 sum 17568.69 18:28:49 sum 17704.04 18:28:50 sum 18566.67 18:28:51 sum 18913.13 at 18:28:44 the MIB interrupt kicked off and caused huge latency which can be seen even on a video he submitted: http://www.youtube.com/watch?v=4GeCx1gZMpA Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index c04959357bd..87e37bc3914 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -795,6 +795,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) sc->sc_imask |= ATH9K_INT_CST; + /* Note: We disable MIB interrupts for now as we don't yet + * handle processing ANI, otherwise you will get an interrupt + * storm after about 7 hours of usage making the system unusable + * with huge latency. Once we do have ANI processing included + * we can re-enable this interrupt. */ +#if 0 /* * Enable MIB interrupts when there are hardware phy counters. * Note we only do this (at the moment) for station mode. @@ -802,6 +808,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ath9k_hw_phycounters(ah) && ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) sc->sc_imask |= ATH9K_INT_MIB; +#endif /* * Some hardware processes the TIM IE and fires an * interrupt when the TIM bit is set. For hardware -- cgit v1.2.3 From 8ca31ce52a5cfd03b960fd81a49197ae85d25347 Mon Sep 17 00:00:00 2001 From: Yasuyuki Kozakai Date: Wed, 24 Sep 2008 15:53:39 -0700 Subject: netfilter: ip6t_{hbh,dst}: Rejects not-strict mode on rule insertion The current code ignores rules for internal options in HBH/DST options header in packet processing if 'Not strict' mode is specified (which is not implemented). Clearly it is not expected by user. Kernel should reject HBH/DST rule insertion with 'Not strict' mode in the first place. Signed-off-by: Yasuyuki Kozakai Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6t_hbh.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 62e39ace058..26654b26d7f 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c @@ -97,8 +97,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in, hdrlen -= 2; if (!(optinfo->flags & IP6T_OPTS_OPTS)) { return ret; - } else if (optinfo->flags & IP6T_OPTS_NSTRICT) { - pr_debug("Not strict - not implemented"); } else { pr_debug("Strict "); pr_debug("#%d ", optinfo->optsnr); @@ -177,6 +175,12 @@ hbh_mt6_check(const char *tablename, const void *entry, pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); return false; } + + if (optsinfo->flags & IP6T_OPTS_NSTRICT) { + pr_debug("ip6t_opts: Not strict - not implemented"); + return false; + } + return true; } -- cgit v1.2.3