compat-wireless: remove ath3k bt workaround
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Wed, 30 Mar 2011 18:22:29 +0000 (11:22 -0700)
committerLuis R. Rodriguez <lrodriguez@atheros.com>
Wed, 30 Mar 2011 18:22:29 +0000 (11:22 -0700)
This should be addressed now upstream properly through this
patch:

commit d9f51b51db2064c9049bf7924318fd8c6ed852cb
Author: Bala Shanmugam <sbalashanmugam@atheros.com>
Date:   Fri Feb 11 15:38:53 2011 +0530

    Bluetooth: Add firmware support for Atheros 3012

    Blacklisted AR3012 PID in btusb and added the same
    in ath3k to load patch and sysconfig files.

Signed-off-by: Bala Shanmugam <sbalashanmugam@atheros.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
crap/0003-btusb-Add-fw-load-support.patch [deleted file]

diff --git a/crap/0003-btusb-Add-fw-load-support.patch b/crap/0003-btusb-Add-fw-load-support.patch
deleted file mode 100644 (file)
index 513f995..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-Reason for this not being merged upstream:
-
-It was first rejected without any alternatives suggested. Then
-an alternative was finally suggested but too late for integration
-upstream.
-
-This is a work around until a new firmware and patch is being worked
-on which is acceptable upstream.
-
-For details refer to:
-
-http://lkml.org/lkml/2010/10/5/195
-
-From 4ac276c14578b380d0c6a27658eeaa364efe6432 Mon Sep 17 00:00:00 2001
-From: Bala Shanmugam <sbalashanmugam@atheros.com>
-Date: Fri, 1 Oct 2010 15:18:02 +0530
-Subject: [PATCH] Added support to load firmware to target RAM from btusb transport driver.
- Each BT device vendor can add their product ID, firmware file, load and unload function
- to btusb_fwcbs array. When the device is inserted btusb will call appropriate
- firmware load function.  This support will significantly reduce cost of
- BT chip because of RAM based firmware.
- Signed-off-by: Bala Shanmugam <sbalashanmugam@atheros.com>
-
----
- drivers/bluetooth/Makefile |    1 +
- drivers/bluetooth/btusb.c  |   67 +++++++++++++++
- drivers/bluetooth/fwload.c |  199 ++++++++++++++++++++++++++++++++++++++++++++
- drivers/bluetooth/fwload.h |   39 +++++++++
- 4 files changed, 306 insertions(+), 0 deletions(-)
- create mode 100644 drivers/bluetooth/fwload.c
- create mode 100644 drivers/bluetooth/fwload.h
-
---- a/drivers/bluetooth/Makefile
-+++ b/drivers/bluetooth/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_BT_HCIBLUECARD) += bluecard
- obj-$(CONFIG_BT_HCIBTUART)    += btuart_cs.o
- obj-$(CONFIG_BT_HCIBTUSB)     += btusb.o
-+obj-$(CONFIG_BT_HCIBTUSB)     += fwload.o
- obj-$(CONFIG_BT_HCIBTSDIO)    += btsdio.o
- obj-$(CONFIG_BT_ATH3K)                += ath3k.o
---- a/drivers/bluetooth/btusb.c
-+++ b/drivers/bluetooth/btusb.c
-@@ -34,6 +34,7 @@
- #include <net/bluetooth/bluetooth.h>
- #include <net/bluetooth/hci_core.h>
-+#include "fwload.h"
- #define VERSION "0.6"
-@@ -55,6 +56,26 @@ static struct usb_driver btusb_driver;
- #define BTUSB_BROKEN_ISOC     0x20
- #define BTUSB_WRONG_SCO_MTU   0x40
-+static struct usb_device_id ath_table[] = {
-+      /* Atheros AR3011 */
-+      { USB_DEVICE(0x0CF3, 0x3002) },
-+      { USB_DEVICE(0x13D3, 0x3304) },
-+      { }     /* Terminating entry */
-+};
-+
-+/* Add firmware file, load and unload function
-+ * to download the firmware to target RAM
-+ */
-+static struct fw_cb_config btusb_fwcbs[] = {
-+      {
-+              .fwfile = "ath3k-1.fw",
-+              .usb_id_table = ath_table,
-+              .fwload = ath_fw_load,
-+              .fwunload = ath_fw_unload
-+      },
-+      {}
-+};
-+
- static struct usb_device_id btusb_table[] = {
-       /* Generic Bluetooth USB device */
-       { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
-@@ -887,6 +908,7 @@ static int btusb_probe(struct usb_interf
-       struct btusb_data *data;
-       struct hci_dev *hdev;
-       int i, err;
-+      const struct usb_device_id *match;
-       BT_DBG("intf %p id %p", intf, id);
-@@ -946,6 +968,19 @@ static int btusb_probe(struct usb_interf
-       data->udev = interface_to_usbdev(intf);
-       data->intf = intf;
-+      for (i = 0; btusb_fwcbs[i].fwfile; i++) {
-+              match = usb_match_id(intf, btusb_fwcbs[i].usb_id_table);
-+              if (match) {
-+                      if (btusb_fwcbs[i].fwload) {
-+                              btusb_fwcbs[i].data =
-+                                      btusb_fwcbs[i].fwload(intf,
-+                                              btusb_fwcbs[i].fwfile,
-+                                              &btusb_fwcbs[i].bsuspend);
-+                      }
-+                      break;
-+              }
-+      }
-+
-       spin_lock_init(&data->lock);
-       INIT_WORK(&data->work, btusb_work);
-@@ -1054,12 +1089,26 @@ static void btusb_disconnect(struct usb_
- {
-       struct btusb_data *data = usb_get_intfdata(intf);
-       struct hci_dev *hdev;
-+      const struct usb_device_id *match;
-+      int i;
-       BT_DBG("intf %p", intf);
-       if (!data)
-               return;
-+      for (i = 0; btusb_fwcbs[i].fwfile; i++) {
-+              match = usb_match_id(intf, btusb_fwcbs[i].usb_id_table);
-+              if (match) {
-+                      if (btusb_fwcbs[i].fwunload) {
-+                              btusb_fwcbs[i].fwunload(btusb_fwcbs[i].data,
-+                                              btusb_fwcbs[i].bsuspend);
-+                              btusb_fwcbs[i].data = NULL;
-+                      }
-+                      break;
-+              }
-+      }
-+
-       hdev = data->hdev;
-       __hci_dev_hold(hdev);
-@@ -1085,12 +1134,22 @@ static void btusb_disconnect(struct usb_
- static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
- {
-       struct btusb_data *data = usb_get_intfdata(intf);
-+      const struct usb_device_id *match;
-+      int i;
-       BT_DBG("intf %p", intf);
-       if (data->suspend_count++)
-               return 0;
-+      for (i = 0; btusb_fwcbs[i].fwfile; i++) {
-+              match = usb_match_id(intf, btusb_fwcbs[i].usb_id_table);
-+              if (match) {
-+                      btusb_fwcbs[i].bsuspend = 1;
-+                      break;
-+              }
-+      }
-+
-       spin_lock_irq(&data->txlock);
-       if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
-               set_bit(BTUSB_SUSPENDING, &data->flags);
-@@ -1203,6 +1262,14 @@ static int __init btusb_init(void)
- static void __exit btusb_exit(void)
- {
-+      int i;
-+      for (i = 0; btusb_fwcbs[i].fwfile; i++) {
-+              if (btusb_fwcbs[i].fwunload && btusb_fwcbs[i].data) {
-+                      btusb_fwcbs[i].fwunload(btusb_fwcbs[i].data,
-+                                      btusb_fwcbs[i].bsuspend);
-+                      btusb_fwcbs[i].data = NULL;
-+              }
-+      }
-       usb_deregister(&btusb_driver);
- }
---- /dev/null
-+++ b/drivers/bluetooth/fwload.c
-@@ -0,0 +1,199 @@
-+/*
-+ *
-+ *  Generic Bluetooth USB DFU driver to download firmware to target RAM
-+ *
-+ *  Copyright (c) 2009-2010 Atheros Communications Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/device.h>
-+#include <linux/firmware.h>
-+#include <linux/usb.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#define USB_REQ_DFU_DNLOAD    1
-+#define USB_REQ_GET_STATE     5
-+#define USB_FIRMWARE_RAM_MODE 11
-+#define USB_FIRMWARE_FLASH_MODE 12
-+#define BULK_SIZE             4096
-+#define VERSION "1.0"
-+
-+struct firmware_data {
-+      struct usb_device *udev;
-+      u8 *fw_data;
-+      u32 fw_size;
-+      u32 fw_sent;
-+};
-+
-+static int load_firmware(struct firmware_data *data,
-+                              unsigned char *firmware,
-+                              int count)
-+{
-+      u8 *send_buf;
-+      int err, pipe, len, size, sent = 0;
-+      char ucFirmware = 0;
-+
-+      BT_DBG("ath3k %p udev %p", data, data->udev);
-+
-+      if ((usb_control_msg(data->udev, usb_rcvctrlpipe(data->udev, 0),
-+                              USB_REQ_GET_STATE,
-+                              USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-+                              &ucFirmware, 1, USB_CTRL_SET_TIMEOUT)) < 0) {
-+              BT_ERR("Can't change to loading configuration err");
-+              return -EBUSY;
-+      }
-+
-+      if (ucFirmware == USB_FIRMWARE_RAM_MODE) {
-+              /* RAM based firmware is available in the target.
-+               * No need to load the firmware to RAM */
-+              BT_DBG("RAM based firmware is available");
-+              return 0;
-+      }
-+
-+      pipe = usb_sndctrlpipe(data->udev, 0);
-+      if ((usb_control_msg(data->udev, pipe,
-+                              USB_REQ_DFU_DNLOAD,
-+                              USB_TYPE_VENDOR, 0, 0,
-+                              firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
-+              BT_ERR("Can't change to loading configuration err");
-+              return -EBUSY;
-+      }
-+      sent += 20;
-+      count -= 20;
-+
-+      send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
-+      if (!send_buf) {
-+              BT_ERR("Can't allocate memory chunk for firmware");
-+              return -ENOMEM;
-+      }
-+
-+      while (count) {
-+              size = min_t(uint, count, BULK_SIZE);
-+              pipe = usb_sndbulkpipe(data->udev, 0x02);
-+              memcpy(send_buf, firmware + sent, size);
-+
-+              err = usb_bulk_msg(data->udev, pipe, send_buf, size,
-+                                      &len, 3000);
-+
-+              if (err || (len != size)) {
-+                      BT_ERR("Error in firmware loading err = %d,"
-+                              "len = %d, size = %d", err, len, size);
-+                      goto error;
-+              }
-+
-+              sent  += size;
-+              count -= size;
-+      }
-+
-+      kfree(send_buf);
-+      return 0;
-+
-+error:
-+      kfree(send_buf);
-+      return err;
-+}
-+
-+void *ath_fw_load(struct usb_interface *intf,
-+                      const char *fwfile, bool *suspend)
-+{
-+      const struct firmware *firmware;
-+      struct usb_device *udev = interface_to_usbdev(intf);
-+      static struct firmware_data *data;
-+      int size;
-+
-+      BT_DBG("\nintf %p suspend %d\n", intf, *suspend);
-+
-+      if (*suspend) {
-+              load_firmware(data, data->fw_data, data->fw_size);
-+              *suspend = 0;
-+              return data;
-+      }
-+
-+      if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
-+              return NULL;
-+
-+      data = kzalloc(sizeof(*data), GFP_KERNEL);
-+      if (!data)
-+              return NULL;
-+      data->udev = udev;
-+
-+      if (request_firmware(&firmware, fwfile, &udev->dev) < 0) {
-+              kfree(data);
-+              return NULL;
-+      }
-+
-+      size = max_t(uint, firmware->size, 4096);
-+      data->fw_data = kmalloc(size, GFP_KERNEL);
-+      if (!data->fw_data) {
-+              release_firmware(firmware);
-+              kfree(data);
-+              return NULL;
-+      }
-+
-+      memcpy(data->fw_data, firmware->data, firmware->size);
-+      data->fw_size = firmware->size;
-+      data->fw_sent = 0;
-+      release_firmware(firmware);
-+
-+      if (load_firmware(data, data->fw_data, data->fw_size)) {
-+              kfree(data->fw_data);
-+              kfree(data);
-+              return NULL;
-+      }
-+      return data;
-+}
-+EXPORT_SYMBOL(ath_fw_load);
-+
-+void ath_fw_unload(void *pdata, bool bsuspend)
-+{
-+      struct firmware_data *data = (struct firmware_data *)pdata;
-+
-+      if (data == NULL)
-+              return;
-+
-+      /* do not free the data on suspend as we will
-+       * use it on resume */
-+      if (!bsuspend) {
-+              kfree(data->fw_data);
-+              kfree(data);
-+      }
-+}
-+EXPORT_SYMBOL(ath_fw_unload);
-+
-+static int __init fwload_init(void)
-+{
-+      BT_INFO("Firmware load driver init. Version:%s", VERSION);
-+      return 0;
-+}
-+
-+static void __exit fwload_deinit(void)
-+{
-+      BT_INFO("Firmware load driver deinit");
-+}
-+
-+module_init(fwload_init);
-+module_exit(fwload_deinit);
-+
-+MODULE_AUTHOR("Atheros Communications");
-+MODULE_DESCRIPTION("Firmware load driver");
-+MODULE_VERSION(VERSION);
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/bluetooth/fwload.h
-@@ -0,0 +1,39 @@
-+/*
-+ *
-+ *  Generic Bluetooth USB DFU driver to download firmware to target RAM
-+ *
-+ *  Copyright (c) 2009-2010 Atheros Communications Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+#ifndef _FWLOAD_H_
-+#define _FWLOAD_H_
-+
-+/* callbacks to load firmware to BT device RAM
-+ * when it is inserted */
-+struct fw_cb_config {
-+      const char *fwfile;
-+      void * (*fwload)(struct usb_interface *intf, const char *fwfile,
-+                       bool *bsuspend);
-+      void (*fwunload)(void *, bool);
-+      const struct usb_device_id *usb_id_table;
-+      void *data;
-+      bool bsuspend;
-+};
-+void *ath_fw_load(struct usb_interface *intf, const char *, bool *);
-+void ath_fw_unload(void *pdata, bool bsuspend);
-+
-+#endif /* _FWLOAD_H_ */