Message ID | 1466498831-10227-1-git-send-email-jesse.sung@canonical.com |
---|---|
State | New |
Headers | show |
On 06/21/2016 02:47 AM, Wen-chien Jesse Sung wrote: > BugLink: https://launchpad.net/bugs/1512999 > > This commit reverts 8b6d64a7ef7967b9bcab363261ae48edb2986f79. > > Although the BT LED works with the patch, it introduces a new regression > that causes HCI stops responding after LED-on command is issued. > > Tested with the latest master-next head with this revert patch, HCI > works, and both Marvell wireless driver update and WiFi LED work without > problem. > > Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> > --- > drivers/bluetooth/btusb.c | 92 +++-------------------------------------------- > 1 file changed, 5 insertions(+), 87 deletions(-) > > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index a529d8e..7910759 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -24,7 +24,6 @@ > #include <linux/module.h> > #include <linux/usb.h> > #include <linux/firmware.h> > -#include <linux/dmi.h> > #include <asm/unaligned.h> > > #include <net/bluetooth/bluetooth.h> > @@ -64,8 +63,6 @@ static struct usb_driver btusb_driver; > #define BTUSB_BCM2045 0x40000 > #define BTUSB_IFNUM_2 0x80000 > > -#define BTUSB_MARVELL_LED_COMMAND 0xfc77 > - > static const struct usb_device_id btusb_table[] = { > /* Generic Bluetooth USB device */ > { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, > @@ -407,11 +404,6 @@ struct btusb_data { > int suspend_count; > > int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb); > - > - bool is_edge_gateway; > - int marvell_cmd_in_progress; > - wait_queue_head_t marvell_wait_q; > - > int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); > > int (*setup_on_usb)(struct hci_dev *hdev); > @@ -617,31 +609,10 @@ static void btusb_intr_complete(struct urb *urb) > if (urb->status == 0) { > hdev->stat.byte_rx += urb->actual_length; > > - if (data->is_edge_gateway && data->marvell_cmd_in_progress) { > - struct hci_ev_cmd_complete *ev; > - struct hci_event_hdr *hdr; > - bool consume_ev = false; > - > - hdr = urb->transfer_buffer; > - if (hdr->evt == HCI_EV_CMD_COMPLETE) { > - ev = (void *)((u8 *)hdr + HCI_EVENT_HDR_SIZE); > - if (__le16_to_cpu(ev->opcode) == BTUSB_MARVELL_LED_COMMAND) { > - consume_ev = true; > - data->marvell_cmd_in_progress = false; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - } > - > - if (!consume_ev && btusb_recv_intr(data, urb->transfer_buffer, urb->actual_length) < 0) { > - BT_ERR("%s corrupted event packet", hdev->name); > - hdev->stat.err_rx++; > - } > - } else { > - if (btusb_recv_intr(data, urb->transfer_buffer, > - urb->actual_length) < 0) { > - BT_ERR("%s corrupted event packet", hdev->name); > - hdev->stat.err_rx++; > - } > + if (btusb_recv_intr(data, urb->transfer_buffer, > + urb->actual_length) < 0) { > + BT_ERR("%s corrupted event packet", hdev->name); > + hdev->stat.err_rx++; > } > } else if (urb->status == -ENOENT) { > /* Avoid suspend failed when usb_kill_urb */ > @@ -1056,38 +1027,6 @@ done: > kfree_skb(skb); > } > > -static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb); > - > -static void btusb_marvell_config_led(struct hci_dev *hdev, bool status) > -{ > - u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 }; > - int len = HCI_COMMAND_HDR_SIZE + sizeof(config_led); > - struct hci_command_hdr *hdr; > - struct sk_buff *skb; > - struct btusb_data *data = hci_get_drvdata(hdev); > - > - if ((!data->is_edge_gateway) || data->marvell_cmd_in_progress) > - return; > - > - skb = bt_skb_alloc(len, GFP_ATOMIC); > - if (!skb) > - return; > - > - hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); > - hdr->opcode = cpu_to_le16(BTUSB_MARVELL_LED_COMMAND); > - hdr->plen = sizeof(config_led); > - > - if (status) > - config_led[1] = 0x01; > - > - memcpy(skb_put(skb, sizeof(config_led)), config_led, sizeof(config_led)); > - bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; > - > - data->marvell_cmd_in_progress = true; > - btusb_send_frame(hdev, skb); > - wait_event_interruptible_timeout(data->marvell_wait_q, !data->marvell_cmd_in_progress, HZ); > -} > - > static int btusb_open(struct hci_dev *hdev) > { > struct btusb_data *data = hci_get_drvdata(hdev); > @@ -1133,9 +1072,6 @@ static int btusb_open(struct hci_dev *hdev) > > done: > usb_autopm_put_interface(data->intf); > - > - if (data->is_edge_gateway) > - btusb_marvell_config_led(hdev, true); > return 0; > > failed: > @@ -1159,14 +1095,6 @@ static int btusb_close(struct hci_dev *hdev) > > BT_DBG("%s", hdev->name); > > - if (data->is_edge_gateway && usb_get_intfdata(data->intf)) > - btusb_marvell_config_led(hdev, false); > - > - if (data->is_edge_gateway) { > - data->marvell_cmd_in_progress = false; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - > cancel_work_sync(&data->work); > cancel_work_sync(&data->waker); > > @@ -3016,13 +2944,8 @@ static int btusb_probe(struct usb_interface *intf, > set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); > } > > - if (id->driver_info & BTUSB_MARVELL) { > + if (id->driver_info & BTUSB_MARVELL) > hdev->set_bdaddr = btusb_set_bdaddr_marvell; > - if (dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5000") || > - dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5100")) > - data->is_edge_gateway = true; > - init_waitqueue_head(&data->marvell_wait_q); > - } > > if (id->driver_info & BTUSB_SWAVE) { > set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks); > @@ -3205,11 +3128,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) > return -EBUSY; > } > > - if (data->is_edge_gateway) { > - data->marvell_cmd_in_progress = 0; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - > cancel_work_sync(&data->work); > > btusb_stop_traffic(data); >
On Tue, Jun 21, 2016 at 04:47:11PM +0800, Wen-chien Jesse Sung wrote: > BugLink: https://launchpad.net/bugs/1512999 > > This commit reverts 8b6d64a7ef7967b9bcab363261ae48edb2986f79. > > Although the BT LED works with the patch, it introduces a new regression > that causes HCI stops responding after LED-on command is issued. > > Tested with the latest master-next head with this revert patch, HCI > works, and both Marvell wireless driver update and WiFi LED work without > problem. > > Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> > --- > drivers/bluetooth/btusb.c | 92 +++-------------------------------------------- > 1 file changed, 5 insertions(+), 87 deletions(-) > > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index a529d8e..7910759 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -24,7 +24,6 @@ > #include <linux/module.h> > #include <linux/usb.h> > #include <linux/firmware.h> > -#include <linux/dmi.h> > #include <asm/unaligned.h> > > #include <net/bluetooth/bluetooth.h> > @@ -64,8 +63,6 @@ static struct usb_driver btusb_driver; > #define BTUSB_BCM2045 0x40000 > #define BTUSB_IFNUM_2 0x80000 > > -#define BTUSB_MARVELL_LED_COMMAND 0xfc77 > - > static const struct usb_device_id btusb_table[] = { > /* Generic Bluetooth USB device */ > { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, > @@ -407,11 +404,6 @@ struct btusb_data { > int suspend_count; > > int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb); > - > - bool is_edge_gateway; > - int marvell_cmd_in_progress; > - wait_queue_head_t marvell_wait_q; > - > int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); > > int (*setup_on_usb)(struct hci_dev *hdev); > @@ -617,31 +609,10 @@ static void btusb_intr_complete(struct urb *urb) > if (urb->status == 0) { > hdev->stat.byte_rx += urb->actual_length; > > - if (data->is_edge_gateway && data->marvell_cmd_in_progress) { > - struct hci_ev_cmd_complete *ev; > - struct hci_event_hdr *hdr; > - bool consume_ev = false; > - > - hdr = urb->transfer_buffer; > - if (hdr->evt == HCI_EV_CMD_COMPLETE) { > - ev = (void *)((u8 *)hdr + HCI_EVENT_HDR_SIZE); > - if (__le16_to_cpu(ev->opcode) == BTUSB_MARVELL_LED_COMMAND) { > - consume_ev = true; > - data->marvell_cmd_in_progress = false; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - } > - > - if (!consume_ev && btusb_recv_intr(data, urb->transfer_buffer, urb->actual_length) < 0) { > - BT_ERR("%s corrupted event packet", hdev->name); > - hdev->stat.err_rx++; > - } > - } else { > - if (btusb_recv_intr(data, urb->transfer_buffer, > - urb->actual_length) < 0) { > - BT_ERR("%s corrupted event packet", hdev->name); > - hdev->stat.err_rx++; > - } > + if (btusb_recv_intr(data, urb->transfer_buffer, > + urb->actual_length) < 0) { > + BT_ERR("%s corrupted event packet", hdev->name); > + hdev->stat.err_rx++; > } > } else if (urb->status == -ENOENT) { > /* Avoid suspend failed when usb_kill_urb */ > @@ -1056,38 +1027,6 @@ done: > kfree_skb(skb); > } > > -static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb); > - > -static void btusb_marvell_config_led(struct hci_dev *hdev, bool status) > -{ > - u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 }; > - int len = HCI_COMMAND_HDR_SIZE + sizeof(config_led); > - struct hci_command_hdr *hdr; > - struct sk_buff *skb; > - struct btusb_data *data = hci_get_drvdata(hdev); > - > - if ((!data->is_edge_gateway) || data->marvell_cmd_in_progress) > - return; > - > - skb = bt_skb_alloc(len, GFP_ATOMIC); > - if (!skb) > - return; > - > - hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); > - hdr->opcode = cpu_to_le16(BTUSB_MARVELL_LED_COMMAND); > - hdr->plen = sizeof(config_led); > - > - if (status) > - config_led[1] = 0x01; > - > - memcpy(skb_put(skb, sizeof(config_led)), config_led, sizeof(config_led)); > - bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; > - > - data->marvell_cmd_in_progress = true; > - btusb_send_frame(hdev, skb); > - wait_event_interruptible_timeout(data->marvell_wait_q, !data->marvell_cmd_in_progress, HZ); > -} > - > static int btusb_open(struct hci_dev *hdev) > { > struct btusb_data *data = hci_get_drvdata(hdev); > @@ -1133,9 +1072,6 @@ static int btusb_open(struct hci_dev *hdev) > > done: > usb_autopm_put_interface(data->intf); > - > - if (data->is_edge_gateway) > - btusb_marvell_config_led(hdev, true); > return 0; > > failed: > @@ -1159,14 +1095,6 @@ static int btusb_close(struct hci_dev *hdev) > > BT_DBG("%s", hdev->name); > > - if (data->is_edge_gateway && usb_get_intfdata(data->intf)) > - btusb_marvell_config_led(hdev, false); > - > - if (data->is_edge_gateway) { > - data->marvell_cmd_in_progress = false; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - > cancel_work_sync(&data->work); > cancel_work_sync(&data->waker); > > @@ -3016,13 +2944,8 @@ static int btusb_probe(struct usb_interface *intf, > set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); > } > > - if (id->driver_info & BTUSB_MARVELL) { > + if (id->driver_info & BTUSB_MARVELL) > hdev->set_bdaddr = btusb_set_bdaddr_marvell; > - if (dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5000") || > - dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5100")) > - data->is_edge_gateway = true; > - init_waitqueue_head(&data->marvell_wait_q); > - } > > if (id->driver_info & BTUSB_SWAVE) { > set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks); > @@ -3205,11 +3128,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) > return -EBUSY; > } > > - if (data->is_edge_gateway) { > - data->marvell_cmd_in_progress = 0; > - wake_up_interruptible(&data->marvell_wait_q); > - } > - > cancel_work_sync(&data->work); > > btusb_stop_traffic(data); > -- > 2.7.4 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team Acked-by: Andy Whitcroft <apw@canonical.com> -apw
On Tue, Jun 21, 2016 at 04:47:11PM +0800, Wen-chien Jesse Sung wrote: > BugLink: https://launchpad.net/bugs/1512999 > > This commit reverts 8b6d64a7ef7967b9bcab363261ae48edb2986f79. > > Although the BT LED works with the patch, it introduces a new regression > that causes HCI stops responding after LED-on command is issued. > > Tested with the latest master-next head with this revert patch, HCI > works, and both Marvell wireless driver update and WiFi LED work without > problem. > > Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> Applied to Xenial. Thanks for sorting this out, Jesse -- the Xenial respin for this fix (4.4.0-27.46) should appear in -proposed by tomorrow. -Kamal
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a529d8e..7910759 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -24,7 +24,6 @@ #include <linux/module.h> #include <linux/usb.h> #include <linux/firmware.h> -#include <linux/dmi.h> #include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> @@ -64,8 +63,6 @@ static struct usb_driver btusb_driver; #define BTUSB_BCM2045 0x40000 #define BTUSB_IFNUM_2 0x80000 -#define BTUSB_MARVELL_LED_COMMAND 0xfc77 - static const struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, @@ -407,11 +404,6 @@ struct btusb_data { int suspend_count; int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb); - - bool is_edge_gateway; - int marvell_cmd_in_progress; - wait_queue_head_t marvell_wait_q; - int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); int (*setup_on_usb)(struct hci_dev *hdev); @@ -617,31 +609,10 @@ static void btusb_intr_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; - if (data->is_edge_gateway && data->marvell_cmd_in_progress) { - struct hci_ev_cmd_complete *ev; - struct hci_event_hdr *hdr; - bool consume_ev = false; - - hdr = urb->transfer_buffer; - if (hdr->evt == HCI_EV_CMD_COMPLETE) { - ev = (void *)((u8 *)hdr + HCI_EVENT_HDR_SIZE); - if (__le16_to_cpu(ev->opcode) == BTUSB_MARVELL_LED_COMMAND) { - consume_ev = true; - data->marvell_cmd_in_progress = false; - wake_up_interruptible(&data->marvell_wait_q); - } - } - - if (!consume_ev && btusb_recv_intr(data, urb->transfer_buffer, urb->actual_length) < 0) { - BT_ERR("%s corrupted event packet", hdev->name); - hdev->stat.err_rx++; - } - } else { - if (btusb_recv_intr(data, urb->transfer_buffer, - urb->actual_length) < 0) { - BT_ERR("%s corrupted event packet", hdev->name); - hdev->stat.err_rx++; - } + if (btusb_recv_intr(data, urb->transfer_buffer, + urb->actual_length) < 0) { + BT_ERR("%s corrupted event packet", hdev->name); + hdev->stat.err_rx++; } } else if (urb->status == -ENOENT) { /* Avoid suspend failed when usb_kill_urb */ @@ -1056,38 +1027,6 @@ done: kfree_skb(skb); } -static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb); - -static void btusb_marvell_config_led(struct hci_dev *hdev, bool status) -{ - u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 }; - int len = HCI_COMMAND_HDR_SIZE + sizeof(config_led); - struct hci_command_hdr *hdr; - struct sk_buff *skb; - struct btusb_data *data = hci_get_drvdata(hdev); - - if ((!data->is_edge_gateway) || data->marvell_cmd_in_progress) - return; - - skb = bt_skb_alloc(len, GFP_ATOMIC); - if (!skb) - return; - - hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); - hdr->opcode = cpu_to_le16(BTUSB_MARVELL_LED_COMMAND); - hdr->plen = sizeof(config_led); - - if (status) - config_led[1] = 0x01; - - memcpy(skb_put(skb, sizeof(config_led)), config_led, sizeof(config_led)); - bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; - - data->marvell_cmd_in_progress = true; - btusb_send_frame(hdev, skb); - wait_event_interruptible_timeout(data->marvell_wait_q, !data->marvell_cmd_in_progress, HZ); -} - static int btusb_open(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -1133,9 +1072,6 @@ static int btusb_open(struct hci_dev *hdev) done: usb_autopm_put_interface(data->intf); - - if (data->is_edge_gateway) - btusb_marvell_config_led(hdev, true); return 0; failed: @@ -1159,14 +1095,6 @@ static int btusb_close(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - if (data->is_edge_gateway && usb_get_intfdata(data->intf)) - btusb_marvell_config_led(hdev, false); - - if (data->is_edge_gateway) { - data->marvell_cmd_in_progress = false; - wake_up_interruptible(&data->marvell_wait_q); - } - cancel_work_sync(&data->work); cancel_work_sync(&data->waker); @@ -3016,13 +2944,8 @@ static int btusb_probe(struct usb_interface *intf, set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); } - if (id->driver_info & BTUSB_MARVELL) { + if (id->driver_info & BTUSB_MARVELL) hdev->set_bdaddr = btusb_set_bdaddr_marvell; - if (dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5000") || - dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5100")) - data->is_edge_gateway = true; - init_waitqueue_head(&data->marvell_wait_q); - } if (id->driver_info & BTUSB_SWAVE) { set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks); @@ -3205,11 +3128,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) return -EBUSY; } - if (data->is_edge_gateway) { - data->marvell_cmd_in_progress = 0; - wake_up_interruptible(&data->marvell_wait_q); - } - cancel_work_sync(&data->work); btusb_stop_traffic(data);
BugLink: https://launchpad.net/bugs/1512999 This commit reverts 8b6d64a7ef7967b9bcab363261ae48edb2986f79. Although the BT LED works with the patch, it introduces a new regression that causes HCI stops responding after LED-on command is issued. Tested with the latest master-next head with this revert patch, HCI works, and both Marvell wireless driver update and WiFi LED work without problem. Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> --- drivers/bluetooth/btusb.c | 92 +++-------------------------------------------- 1 file changed, 5 insertions(+), 87 deletions(-)