diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 19:29:25 -0400 |
commit | 7a6362800cb7d1d618a697a650c7aaed3eb39320 (patch) | |
tree | 087f9bc6c13ef1fad4b392c5cf9325cd28fa8523 /drivers/bluetooth | |
parent | 6445ced8670f37cfc2c5e24a9de9b413dbfc788d (diff) | |
parent | ceda86a108671294052cbf51660097b6534672f5 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1480 commits)
bonding: enable netpoll without checking link status
xfrm: Refcount destination entry on xfrm_lookup
net: introduce rx_handler results and logic around that
bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag
bonding: wrap slave state work
net: get rid of multiple bond-related netdevice->priv_flags
bonding: register slave pointer for rx_handler
be2net: Bump up the version number
be2net: Copyright notice change. Update to Emulex instead of ServerEngines
e1000e: fix kconfig for crc32 dependency
netfilter ebtables: fix xt_AUDIT to work with ebtables
xen network backend driver
bonding: Improve syslog message at device creation time
bonding: Call netif_carrier_off after register_netdevice
bonding: Incorrect TX queue offset
net_sched: fix ip_tos2prio
xfrm: fix __xfrm_route_forward()
be2net: Fix UDP packet detected status in RX compl
Phonet: fix aligned-mode pipe socket buffer header reserve
netxen: support for GbE port settings
...
Fix up conflicts in drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
with the staging updates.
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/ath3k.c | 287 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 13 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 1 |
3 files changed, 289 insertions, 12 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 6dcd55a74c0a..5577ed656e2f 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -31,6 +31,30 @@ | |||
31 | 31 | ||
32 | #define VERSION "1.0" | 32 | #define VERSION "1.0" |
33 | 33 | ||
34 | #define ATH3K_DNLOAD 0x01 | ||
35 | #define ATH3K_GETSTATE 0x05 | ||
36 | #define ATH3K_SET_NORMAL_MODE 0x07 | ||
37 | #define ATH3K_GETVERSION 0x09 | ||
38 | #define USB_REG_SWITCH_VID_PID 0x0a | ||
39 | |||
40 | #define ATH3K_MODE_MASK 0x3F | ||
41 | #define ATH3K_NORMAL_MODE 0x0E | ||
42 | |||
43 | #define ATH3K_PATCH_UPDATE 0x80 | ||
44 | #define ATH3K_SYSCFG_UPDATE 0x40 | ||
45 | |||
46 | #define ATH3K_XTAL_FREQ_26M 0x00 | ||
47 | #define ATH3K_XTAL_FREQ_40M 0x01 | ||
48 | #define ATH3K_XTAL_FREQ_19P2 0x02 | ||
49 | #define ATH3K_NAME_LEN 0xFF | ||
50 | |||
51 | struct ath3k_version { | ||
52 | unsigned int rom_version; | ||
53 | unsigned int build_version; | ||
54 | unsigned int ram_version; | ||
55 | unsigned char ref_clock; | ||
56 | unsigned char reserved[0x07]; | ||
57 | }; | ||
34 | 58 | ||
35 | static struct usb_device_id ath3k_table[] = { | 59 | static struct usb_device_id ath3k_table[] = { |
36 | /* Atheros AR3011 */ | 60 | /* Atheros AR3011 */ |
@@ -42,15 +66,31 @@ static struct usb_device_id ath3k_table[] = { | |||
42 | /* Atheros AR9285 Malbec with sflash firmware */ | 66 | /* Atheros AR9285 Malbec with sflash firmware */ |
43 | { USB_DEVICE(0x03F0, 0x311D) }, | 67 | { USB_DEVICE(0x03F0, 0x311D) }, |
44 | 68 | ||
69 | /* Atheros AR3012 with sflash firmware*/ | ||
70 | { USB_DEVICE(0x0CF3, 0x3004) }, | ||
71 | |||
45 | /* Atheros AR5BBU12 with sflash firmware */ | 72 | /* Atheros AR5BBU12 with sflash firmware */ |
46 | { USB_DEVICE(0x0489, 0xE02C) }, | 73 | { USB_DEVICE(0x0489, 0xE02C) }, |
74 | |||
47 | { } /* Terminating entry */ | 75 | { } /* Terminating entry */ |
48 | }; | 76 | }; |
49 | 77 | ||
50 | MODULE_DEVICE_TABLE(usb, ath3k_table); | 78 | MODULE_DEVICE_TABLE(usb, ath3k_table); |
51 | 79 | ||
80 | #define BTUSB_ATH3012 0x80 | ||
81 | /* This table is to load patch and sysconfig files | ||
82 | * for AR3012 */ | ||
83 | static struct usb_device_id ath3k_blist_tbl[] = { | ||
84 | |||
85 | /* Atheros AR3012 with sflash firmware*/ | ||
86 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | ||
87 | |||
88 | { } /* Terminating entry */ | ||
89 | }; | ||
90 | |||
52 | #define USB_REQ_DFU_DNLOAD 1 | 91 | #define USB_REQ_DFU_DNLOAD 1 |
53 | #define BULK_SIZE 4096 | 92 | #define BULK_SIZE 4096 |
93 | #define FW_HDR_SIZE 20 | ||
54 | 94 | ||
55 | static int ath3k_load_firmware(struct usb_device *udev, | 95 | static int ath3k_load_firmware(struct usb_device *udev, |
56 | const struct firmware *firmware) | 96 | const struct firmware *firmware) |
@@ -106,28 +146,265 @@ error: | |||
106 | return err; | 146 | return err; |
107 | } | 147 | } |
108 | 148 | ||
149 | static int ath3k_get_state(struct usb_device *udev, unsigned char *state) | ||
150 | { | ||
151 | int pipe = 0; | ||
152 | |||
153 | pipe = usb_rcvctrlpipe(udev, 0); | ||
154 | return usb_control_msg(udev, pipe, ATH3K_GETSTATE, | ||
155 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | ||
156 | state, 0x01, USB_CTRL_SET_TIMEOUT); | ||
157 | } | ||
158 | |||
159 | static int ath3k_get_version(struct usb_device *udev, | ||
160 | struct ath3k_version *version) | ||
161 | { | ||
162 | int pipe = 0; | ||
163 | |||
164 | pipe = usb_rcvctrlpipe(udev, 0); | ||
165 | return usb_control_msg(udev, pipe, ATH3K_GETVERSION, | ||
166 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, | ||
167 | sizeof(struct ath3k_version), | ||
168 | USB_CTRL_SET_TIMEOUT); | ||
169 | } | ||
170 | |||
171 | static int ath3k_load_fwfile(struct usb_device *udev, | ||
172 | const struct firmware *firmware) | ||
173 | { | ||
174 | u8 *send_buf; | ||
175 | int err, pipe, len, size, count, sent = 0; | ||
176 | int ret; | ||
177 | |||
178 | count = firmware->size; | ||
179 | |||
180 | send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); | ||
181 | if (!send_buf) { | ||
182 | BT_ERR("Can't allocate memory chunk for firmware"); | ||
183 | return -ENOMEM; | ||
184 | } | ||
185 | |||
186 | size = min_t(uint, count, FW_HDR_SIZE); | ||
187 | memcpy(send_buf, firmware->data, size); | ||
188 | |||
189 | pipe = usb_sndctrlpipe(udev, 0); | ||
190 | ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD, | ||
191 | USB_TYPE_VENDOR, 0, 0, send_buf, | ||
192 | size, USB_CTRL_SET_TIMEOUT); | ||
193 | if (ret < 0) { | ||
194 | BT_ERR("Can't change to loading configuration err"); | ||
195 | kfree(send_buf); | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | sent += size; | ||
200 | count -= size; | ||
201 | |||
202 | while (count) { | ||
203 | size = min_t(uint, count, BULK_SIZE); | ||
204 | pipe = usb_sndbulkpipe(udev, 0x02); | ||
205 | |||
206 | memcpy(send_buf, firmware->data + sent, size); | ||
207 | |||
208 | err = usb_bulk_msg(udev, pipe, send_buf, size, | ||
209 | &len, 3000); | ||
210 | if (err || (len != size)) { | ||
211 | BT_ERR("Error in firmware loading err = %d," | ||
212 | "len = %d, size = %d", err, len, size); | ||
213 | kfree(send_buf); | ||
214 | return err; | ||
215 | } | ||
216 | sent += size; | ||
217 | count -= size; | ||
218 | } | ||
219 | |||
220 | kfree(send_buf); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int ath3k_switch_pid(struct usb_device *udev) | ||
225 | { | ||
226 | int pipe = 0; | ||
227 | |||
228 | pipe = usb_sndctrlpipe(udev, 0); | ||
229 | return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID, | ||
230 | USB_TYPE_VENDOR, 0, 0, | ||
231 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
232 | } | ||
233 | |||
234 | static int ath3k_set_normal_mode(struct usb_device *udev) | ||
235 | { | ||
236 | unsigned char fw_state; | ||
237 | int pipe = 0, ret; | ||
238 | |||
239 | ret = ath3k_get_state(udev, &fw_state); | ||
240 | if (ret < 0) { | ||
241 | BT_ERR("Can't get state to change to normal mode err"); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { | ||
246 | BT_DBG("firmware was already in normal mode"); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | pipe = usb_sndctrlpipe(udev, 0); | ||
251 | return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE, | ||
252 | USB_TYPE_VENDOR, 0, 0, | ||
253 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
254 | } | ||
255 | |||
256 | static int ath3k_load_patch(struct usb_device *udev) | ||
257 | { | ||
258 | unsigned char fw_state; | ||
259 | char filename[ATH3K_NAME_LEN] = {0}; | ||
260 | const struct firmware *firmware; | ||
261 | struct ath3k_version fw_version, pt_version; | ||
262 | int ret; | ||
263 | |||
264 | ret = ath3k_get_state(udev, &fw_state); | ||
265 | if (ret < 0) { | ||
266 | BT_ERR("Can't get state to change to load ram patch err"); | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | if (fw_state & ATH3K_PATCH_UPDATE) { | ||
271 | BT_DBG("Patch was already downloaded"); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | ret = ath3k_get_version(udev, &fw_version); | ||
276 | if (ret < 0) { | ||
277 | BT_ERR("Can't get version to change to load ram patch err"); | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", | ||
282 | fw_version.rom_version); | ||
283 | |||
284 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
285 | if (ret < 0) { | ||
286 | BT_ERR("Patch file not found %s", filename); | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); | ||
291 | pt_version.build_version = *(int *) | ||
292 | (firmware->data + firmware->size - 4); | ||
293 | |||
294 | if ((pt_version.rom_version != fw_version.rom_version) || | ||
295 | (pt_version.build_version <= fw_version.build_version)) { | ||
296 | BT_ERR("Patch file version did not match with firmware"); | ||
297 | release_firmware(firmware); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | |||
301 | ret = ath3k_load_fwfile(udev, firmware); | ||
302 | release_firmware(firmware); | ||
303 | |||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | static int ath3k_load_syscfg(struct usb_device *udev) | ||
308 | { | ||
309 | unsigned char fw_state; | ||
310 | char filename[ATH3K_NAME_LEN] = {0}; | ||
311 | const struct firmware *firmware; | ||
312 | struct ath3k_version fw_version; | ||
313 | int clk_value, ret; | ||
314 | |||
315 | ret = ath3k_get_state(udev, &fw_state); | ||
316 | if (ret < 0) { | ||
317 | BT_ERR("Can't get state to change to load configration err"); | ||
318 | return -EBUSY; | ||
319 | } | ||
320 | |||
321 | ret = ath3k_get_version(udev, &fw_version); | ||
322 | if (ret < 0) { | ||
323 | BT_ERR("Can't get version to change to load ram patch err"); | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | switch (fw_version.ref_clock) { | ||
328 | |||
329 | case ATH3K_XTAL_FREQ_26M: | ||
330 | clk_value = 26; | ||
331 | break; | ||
332 | case ATH3K_XTAL_FREQ_40M: | ||
333 | clk_value = 40; | ||
334 | break; | ||
335 | case ATH3K_XTAL_FREQ_19P2: | ||
336 | clk_value = 19; | ||
337 | break; | ||
338 | default: | ||
339 | clk_value = 0; | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", | ||
344 | fw_version.rom_version, clk_value, ".dfu"); | ||
345 | |||
346 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
347 | if (ret < 0) { | ||
348 | BT_ERR("Configuration file not found %s", filename); | ||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | ret = ath3k_load_fwfile(udev, firmware); | ||
353 | release_firmware(firmware); | ||
354 | |||
355 | return ret; | ||
356 | } | ||
357 | |||
109 | static int ath3k_probe(struct usb_interface *intf, | 358 | static int ath3k_probe(struct usb_interface *intf, |
110 | const struct usb_device_id *id) | 359 | const struct usb_device_id *id) |
111 | { | 360 | { |
112 | const struct firmware *firmware; | 361 | const struct firmware *firmware; |
113 | struct usb_device *udev = interface_to_usbdev(intf); | 362 | struct usb_device *udev = interface_to_usbdev(intf); |
363 | int ret; | ||
114 | 364 | ||
115 | BT_DBG("intf %p id %p", intf, id); | 365 | BT_DBG("intf %p id %p", intf, id); |
116 | 366 | ||
117 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | 367 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) |
118 | return -ENODEV; | 368 | return -ENODEV; |
119 | 369 | ||
120 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | 370 | /* match device ID in ath3k blacklist table */ |
121 | return -EIO; | 371 | if (!id->driver_info) { |
372 | const struct usb_device_id *match; | ||
373 | match = usb_match_id(intf, ath3k_blist_tbl); | ||
374 | if (match) | ||
375 | id = match; | ||
122 | } | 376 | } |
123 | 377 | ||
124 | if (ath3k_load_firmware(udev, firmware)) { | 378 | /* load patch and sysconfig files for AR3012 */ |
125 | release_firmware(firmware); | 379 | if (id->driver_info & BTUSB_ATH3012) { |
380 | ret = ath3k_load_patch(udev); | ||
381 | if (ret < 0) { | ||
382 | BT_ERR("Loading patch file failed"); | ||
383 | return ret; | ||
384 | } | ||
385 | ret = ath3k_load_syscfg(udev); | ||
386 | if (ret < 0) { | ||
387 | BT_ERR("Loading sysconfig file failed"); | ||
388 | return ret; | ||
389 | } | ||
390 | ret = ath3k_set_normal_mode(udev); | ||
391 | if (ret < 0) { | ||
392 | BT_ERR("Set normal mode failed"); | ||
393 | return ret; | ||
394 | } | ||
395 | ath3k_switch_pid(udev); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | ||
400 | BT_ERR("Error loading firmware"); | ||
126 | return -EIO; | 401 | return -EIO; |
127 | } | 402 | } |
403 | |||
404 | ret = ath3k_load_firmware(udev, firmware); | ||
128 | release_firmware(firmware); | 405 | release_firmware(firmware); |
129 | 406 | ||
130 | return 0; | 407 | return ret; |
131 | } | 408 | } |
132 | 409 | ||
133 | static void ath3k_disconnect(struct usb_interface *intf) | 410 | static void ath3k_disconnect(struct usb_interface *intf) |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 700a3840fddc..7e0ebd4a1a74 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = { | |||
105 | /* Atheros AR9285 Malbec with sflash firmware */ | 105 | /* Atheros AR9285 Malbec with sflash firmware */ |
106 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | 106 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
107 | 107 | ||
108 | /* Atheros 3012 with sflash firmware */ | ||
109 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE }, | ||
110 | |||
108 | /* Atheros AR5BBU12 with sflash firmware */ | 111 | /* Atheros AR5BBU12 with sflash firmware */ |
109 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 112 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
110 | 113 | ||
@@ -714,15 +717,11 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
714 | pipe = usb_sndisocpipe(data->udev, | 717 | pipe = usb_sndisocpipe(data->udev, |
715 | data->isoc_tx_ep->bEndpointAddress); | 718 | data->isoc_tx_ep->bEndpointAddress); |
716 | 719 | ||
717 | urb->dev = data->udev; | 720 | usb_fill_int_urb(urb, data->udev, pipe, |
718 | urb->pipe = pipe; | 721 | skb->data, skb->len, btusb_isoc_tx_complete, |
719 | urb->context = skb; | 722 | skb, data->isoc_tx_ep->bInterval); |
720 | urb->complete = btusb_isoc_tx_complete; | ||
721 | urb->interval = data->isoc_tx_ep->bInterval; | ||
722 | 723 | ||
723 | urb->transfer_flags = URB_ISO_ASAP; | 724 | urb->transfer_flags = URB_ISO_ASAP; |
724 | urb->transfer_buffer = skb->data; | ||
725 | urb->transfer_buffer_length = skb->len; | ||
726 | 725 | ||
727 | __fill_isoc_descriptor(urb, skb->len, | 726 | __fill_isoc_descriptor(urb, skb->len, |
728 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); | 727 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 3c6cabcb7d84..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
398 | hdev->flush = hci_uart_flush; | 398 | hdev->flush = hci_uart_flush; |
399 | hdev->send = hci_uart_send_frame; | 399 | hdev->send = hci_uart_send_frame; |
400 | hdev->destruct = hci_uart_destruct; | 400 | hdev->destruct = hci_uart_destruct; |
401 | hdev->parent = hu->tty->dev; | ||
401 | 402 | ||
402 | hdev->owner = THIS_MODULE; | 403 | hdev->owner = THIS_MODULE; |
403 | 404 | ||