aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/ath3k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/ath3k.c')
-rw-r--r--drivers/bluetooth/ath3k.c80
1 files changed, 25 insertions, 55 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 949ed09c6361..6dcd55a74c0a 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -39,6 +39,11 @@ static struct usb_device_id ath3k_table[] = {
39 /* Atheros AR3011 with sflash firmware*/ 39 /* Atheros AR3011 with sflash firmware*/
40 { USB_DEVICE(0x0CF3, 0x3002) }, 40 { USB_DEVICE(0x0CF3, 0x3002) },
41 41
42 /* Atheros AR9285 Malbec with sflash firmware */
43 { USB_DEVICE(0x03F0, 0x311D) },
44
45 /* Atheros AR5BBU12 with sflash firmware */
46 { USB_DEVICE(0x0489, 0xE02C) },
42 { } /* Terminating entry */ 47 { } /* Terminating entry */
43}; 48};
44 49
@@ -47,46 +52,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
47#define USB_REQ_DFU_DNLOAD 1 52#define USB_REQ_DFU_DNLOAD 1
48#define BULK_SIZE 4096 53#define BULK_SIZE 4096
49 54
50struct ath3k_data { 55static int ath3k_load_firmware(struct usb_device *udev,
51 struct usb_device *udev; 56 const struct firmware *firmware)
52 u8 *fw_data;
53 u32 fw_size;
54 u32 fw_sent;
55};
56
57static int ath3k_load_firmware(struct ath3k_data *data,
58 unsigned char *firmware,
59 int count)
60{ 57{
61 u8 *send_buf; 58 u8 *send_buf;
62 int err, pipe, len, size, sent = 0; 59 int err, pipe, len, size, sent = 0;
60 int count = firmware->size;
63 61
64 BT_DBG("ath3k %p udev %p", data, data->udev); 62 BT_DBG("udev %p", udev);
65 63
66 pipe = usb_sndctrlpipe(data->udev, 0); 64 pipe = usb_sndctrlpipe(udev, 0);
67 65
68 if ((usb_control_msg(data->udev, pipe, 66 send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
67 if (!send_buf) {
68 BT_ERR("Can't allocate memory chunk for firmware");
69 return -ENOMEM;
70 }
71
72 memcpy(send_buf, firmware->data, 20);
73 if ((err = usb_control_msg(udev, pipe,
69 USB_REQ_DFU_DNLOAD, 74 USB_REQ_DFU_DNLOAD,
70 USB_TYPE_VENDOR, 0, 0, 75 USB_TYPE_VENDOR, 0, 0,
71 firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) { 76 send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
72 BT_ERR("Can't change to loading configuration err"); 77 BT_ERR("Can't change to loading configuration err");
73 return -EBUSY; 78 goto error;
74 } 79 }
75 sent += 20; 80 sent += 20;
76 count -= 20; 81 count -= 20;
77 82
78 send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
79 if (!send_buf) {
80 BT_ERR("Can't allocate memory chunk for firmware");
81 return -ENOMEM;
82 }
83
84 while (count) { 83 while (count) {
85 size = min_t(uint, count, BULK_SIZE); 84 size = min_t(uint, count, BULK_SIZE);
86 pipe = usb_sndbulkpipe(data->udev, 0x02); 85 pipe = usb_sndbulkpipe(udev, 0x02);
87 memcpy(send_buf, firmware + sent, size); 86 memcpy(send_buf, firmware->data + sent, size);
88 87
89 err = usb_bulk_msg(data->udev, pipe, send_buf, size, 88 err = usb_bulk_msg(udev, pipe, send_buf, size,
90 &len, 3000); 89 &len, 3000);
91 90
92 if (err || (len != size)) { 91 if (err || (len != size)) {
@@ -112,57 +111,28 @@ static int ath3k_probe(struct usb_interface *intf,
112{ 111{
113 const struct firmware *firmware; 112 const struct firmware *firmware;
114 struct usb_device *udev = interface_to_usbdev(intf); 113 struct usb_device *udev = interface_to_usbdev(intf);
115 struct ath3k_data *data;
116 int size;
117 114
118 BT_DBG("intf %p id %p", intf, id); 115 BT_DBG("intf %p id %p", intf, id);
119 116
120 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 117 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
121 return -ENODEV; 118 return -ENODEV;
122 119
123 data = kzalloc(sizeof(*data), GFP_KERNEL);
124 if (!data)
125 return -ENOMEM;
126
127 data->udev = udev;
128
129 if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { 120 if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
130 kfree(data);
131 return -EIO; 121 return -EIO;
132 } 122 }
133 123
134 size = max_t(uint, firmware->size, 4096); 124 if (ath3k_load_firmware(udev, firmware)) {
135 data->fw_data = kmalloc(size, GFP_KERNEL);
136 if (!data->fw_data) {
137 release_firmware(firmware); 125 release_firmware(firmware);
138 kfree(data);
139 return -ENOMEM;
140 }
141
142 memcpy(data->fw_data, firmware->data, firmware->size);
143 data->fw_size = firmware->size;
144 data->fw_sent = 0;
145 release_firmware(firmware);
146
147 usb_set_intfdata(intf, data);
148 if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
149 usb_set_intfdata(intf, NULL);
150 kfree(data->fw_data);
151 kfree(data);
152 return -EIO; 126 return -EIO;
153 } 127 }
128 release_firmware(firmware);
154 129
155 return 0; 130 return 0;
156} 131}
157 132
158static void ath3k_disconnect(struct usb_interface *intf) 133static void ath3k_disconnect(struct usb_interface *intf)
159{ 134{
160 struct ath3k_data *data = usb_get_intfdata(intf);
161
162 BT_DBG("ath3k_disconnect intf %p", intf); 135 BT_DBG("ath3k_disconnect intf %p", intf);
163
164 kfree(data->fw_data);
165 kfree(data);
166} 136}
167 137
168static struct usb_driver ath3k_driver = { 138static struct usb_driver ath3k_driver = {