Commit 18aeb444 authored by Frederic Danis's avatar Frederic Danis Committed by Marcel Holtmann

Bluetooth: btbcm: Move request/release_firmware()

Move request/release_firmware() out of btbcm_patchram().
This allows a better error management, if request_firmware() returns an
error then the controller will be used without firmware loading and 0 is
returned.
This will imply to change btbcm_patchram() to accept a firmware instead
of firmware name.
Signed-off-by: default avatarFrederic Danis <frederic.danis@linux.intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 133be026
...@@ -89,21 +89,14 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) ...@@ -89,21 +89,14 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
} }
EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
int btbcm_patchram(struct hci_dev *hdev, const char *firmware) int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
{ {
const struct hci_command_hdr *cmd; const struct hci_command_hdr *cmd;
const struct firmware *fw;
const u8 *fw_ptr; const u8 *fw_ptr;
size_t fw_size; size_t fw_size;
struct sk_buff *skb; struct sk_buff *skb;
u16 opcode; u16 opcode;
int err; int err = 0;
err = request_firmware(&fw, firmware, &hdev->dev);
if (err < 0) {
BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware);
return err;
}
/* Start Download */ /* Start Download */
skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
...@@ -129,8 +122,7 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware) ...@@ -129,8 +122,7 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
fw_size -= sizeof(*cmd); fw_size -= sizeof(*cmd);
if (fw_size < cmd->plen) { if (fw_size < cmd->plen) {
BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name, BT_ERR("%s: BCM: Patch is corrupted", hdev->name);
firmware);
err = -EINVAL; err = -EINVAL;
goto done; goto done;
} }
...@@ -156,7 +148,6 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware) ...@@ -156,7 +148,6 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
msleep(250); msleep(250);
done: done:
release_firmware(fw);
return err; return err;
} }
EXPORT_SYMBOL(btbcm_patchram); EXPORT_SYMBOL(btbcm_patchram);
...@@ -265,6 +256,7 @@ static const struct { ...@@ -265,6 +256,7 @@ static const struct {
int btbcm_setup_patchram(struct hci_dev *hdev) int btbcm_setup_patchram(struct hci_dev *hdev)
{ {
char fw_name[64]; char fw_name[64];
const struct firmware *fw;
u16 subver, rev, pid, vid; u16 subver, rev, pid, vid;
const char *hw_name = NULL; const char *hw_name = NULL;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -335,9 +327,15 @@ int btbcm_setup_patchram(struct hci_dev *hdev) ...@@ -335,9 +327,15 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
hw_name ? : "BCM", (subver & 0x7000) >> 13, hw_name ? : "BCM", (subver & 0x7000) >> 13,
(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
err = btbcm_patchram(hdev, fw_name); err = request_firmware(&fw, fw_name, &hdev->dev);
if (err == -ENOENT) if (err < 0) {
BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name);
return 0; return 0;
}
btbcm_patchram(hdev, fw);
release_firmware(fw);
/* Reset */ /* Reset */
err = btbcm_reset(hdev); err = btbcm_reset(hdev);
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
int btbcm_check_bdaddr(struct hci_dev *hdev); int btbcm_check_bdaddr(struct hci_dev *hdev);
int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
int btbcm_patchram(struct hci_dev *hdev, const char *firmware); int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw);
int btbcm_setup_patchram(struct hci_dev *hdev); int btbcm_setup_patchram(struct hci_dev *hdev);
int btbcm_setup_apple(struct hci_dev *hdev); int btbcm_setup_apple(struct hci_dev *hdev);
...@@ -42,7 +42,7 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) ...@@ -42,7 +42,7 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware) static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/firmware.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/firmware.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment