diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Kconfig | 14 | ||||
-rw-r--r-- | drivers/bluetooth/Makefile | 1 | ||||
-rw-r--r-- | drivers/bluetooth/ath3k.c | 361 | ||||
-rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 14 | ||||
-rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 66 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_debugfs.c | 22 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 124 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.h | 68 | ||||
-rw-r--r-- | drivers/bluetooth/btsdio.c | 8 | ||||
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 64 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 55 | ||||
-rw-r--r-- | drivers/bluetooth/btwilink.c | 395 | ||||
-rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 29 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ath.c | 33 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h4.c | 7 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 16 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ll.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 1 |
19 files changed, 1026 insertions, 258 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 02deef424926..11b41fd40c27 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -188,7 +188,7 @@ config BT_MRVL | |||
188 | The core driver to support Marvell Bluetooth devices. | 188 | The core driver to support Marvell Bluetooth devices. |
189 | 189 | ||
190 | This driver is required if you want to support | 190 | This driver is required if you want to support |
191 | Marvell Bluetooth devices, such as 8688. | 191 | Marvell Bluetooth devices, such as 8688/8787. |
192 | 192 | ||
193 | Say Y here to compile Marvell Bluetooth driver | 193 | Say Y here to compile Marvell Bluetooth driver |
194 | into the kernel or say M to compile it as module. | 194 | into the kernel or say M to compile it as module. |
@@ -201,7 +201,7 @@ config BT_MRVL_SDIO | |||
201 | The driver for Marvell Bluetooth chipsets with SDIO interface. | 201 | The driver for Marvell Bluetooth chipsets with SDIO interface. |
202 | 202 | ||
203 | This driver is required if you want to use Marvell Bluetooth | 203 | This driver is required if you want to use Marvell Bluetooth |
204 | devices with SDIO interface. Currently only SD8688 chipset is | 204 | devices with SDIO interface. Currently SD8688/SD8787 chipsets are |
205 | supported. | 205 | supported. |
206 | 206 | ||
207 | Say Y here to compile support for Marvell BT-over-SDIO driver | 207 | Say Y here to compile support for Marvell BT-over-SDIO driver |
@@ -219,4 +219,14 @@ config BT_ATH3K | |||
219 | Say Y here to compile support for "Atheros firmware download driver" | 219 | Say Y here to compile support for "Atheros firmware download driver" |
220 | into the kernel or say M to compile it as module (ath3k). | 220 | into the kernel or say M to compile it as module (ath3k). |
221 | 221 | ||
222 | config BT_WILINK | ||
223 | tristate "Texas Instruments WiLink7 driver" | ||
224 | depends on TI_ST | ||
225 | help | ||
226 | This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS | ||
227 | combo devices. This makes use of shared transport line discipline | ||
228 | core driver to communicate with the BT core of the combo chip. | ||
229 | |||
230 | Say Y here to compile support for Texas Instrument's WiLink7 driver | ||
231 | into the kernel or say M to compile it as module. | ||
222 | endmenu | 232 | endmenu |
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 71bdf13287c4..f4460f4f4b78 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o | |||
18 | obj-$(CONFIG_BT_ATH3K) += ath3k.o | 18 | obj-$(CONFIG_BT_ATH3K) += ath3k.o |
19 | obj-$(CONFIG_BT_MRVL) += btmrvl.o | 19 | obj-$(CONFIG_BT_MRVL) += btmrvl.o |
20 | obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o | 20 | obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o |
21 | obj-$(CONFIG_BT_WILINK) += btwilink.o | ||
21 | 22 | ||
22 | btmrvl-y := btmrvl_main.o | 23 | btmrvl-y := btmrvl_main.o |
23 | btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o | 24 | btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 128cae4e8629..6bacef368fab 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -31,76 +31,326 @@ | |||
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 */ |
37 | { USB_DEVICE(0x0CF3, 0x3000) }, | 61 | { USB_DEVICE(0x0CF3, 0x3000) }, |
62 | |||
63 | /* Atheros AR3011 with sflash firmware*/ | ||
64 | { USB_DEVICE(0x0CF3, 0x3002) }, | ||
65 | { USB_DEVICE(0x13d3, 0x3304) }, | ||
66 | |||
67 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
68 | { USB_DEVICE(0x03F0, 0x311D) }, | ||
69 | |||
70 | /* Atheros AR3012 with sflash firmware*/ | ||
71 | { USB_DEVICE(0x0CF3, 0x3004) }, | ||
72 | |||
73 | /* Atheros AR5BBU12 with sflash firmware */ | ||
74 | { USB_DEVICE(0x0489, 0xE02C) }, | ||
75 | |||
38 | { } /* Terminating entry */ | 76 | { } /* Terminating entry */ |
39 | }; | 77 | }; |
40 | 78 | ||
41 | MODULE_DEVICE_TABLE(usb, ath3k_table); | 79 | MODULE_DEVICE_TABLE(usb, ath3k_table); |
42 | 80 | ||
43 | #define USB_REQ_DFU_DNLOAD 1 | 81 | #define BTUSB_ATH3012 0x80 |
44 | #define BULK_SIZE 4096 | 82 | /* This table is to load patch and sysconfig files |
83 | * for AR3012 */ | ||
84 | static struct usb_device_id ath3k_blist_tbl[] = { | ||
45 | 85 | ||
46 | struct ath3k_data { | 86 | /* Atheros AR3012 with sflash firmware*/ |
47 | struct usb_device *udev; | 87 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, |
48 | u8 *fw_data; | 88 | |
49 | u32 fw_size; | 89 | { } /* Terminating entry */ |
50 | u32 fw_sent; | ||
51 | }; | 90 | }; |
52 | 91 | ||
53 | static int ath3k_load_firmware(struct ath3k_data *data, | 92 | #define USB_REQ_DFU_DNLOAD 1 |
54 | unsigned char *firmware, | 93 | #define BULK_SIZE 4096 |
55 | int count) | 94 | #define FW_HDR_SIZE 20 |
95 | |||
96 | static int ath3k_load_firmware(struct usb_device *udev, | ||
97 | const struct firmware *firmware) | ||
56 | { | 98 | { |
57 | u8 *send_buf; | 99 | u8 *send_buf; |
58 | int err, pipe, len, size, sent = 0; | 100 | int err, pipe, len, size, sent = 0; |
101 | int count = firmware->size; | ||
102 | |||
103 | BT_DBG("udev %p", udev); | ||
59 | 104 | ||
60 | BT_DBG("ath3k %p udev %p", data, data->udev); | 105 | pipe = usb_sndctrlpipe(udev, 0); |
61 | 106 | ||
62 | pipe = usb_sndctrlpipe(data->udev, 0); | 107 | send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); |
108 | if (!send_buf) { | ||
109 | BT_ERR("Can't allocate memory chunk for firmware"); | ||
110 | return -ENOMEM; | ||
111 | } | ||
63 | 112 | ||
64 | if ((usb_control_msg(data->udev, pipe, | 113 | memcpy(send_buf, firmware->data, 20); |
114 | if ((err = usb_control_msg(udev, pipe, | ||
65 | USB_REQ_DFU_DNLOAD, | 115 | USB_REQ_DFU_DNLOAD, |
66 | USB_TYPE_VENDOR, 0, 0, | 116 | USB_TYPE_VENDOR, 0, 0, |
67 | firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) { | 117 | send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) { |
68 | BT_ERR("Can't change to loading configuration err"); | 118 | BT_ERR("Can't change to loading configuration err"); |
69 | return -EBUSY; | 119 | goto error; |
70 | } | 120 | } |
71 | sent += 20; | 121 | sent += 20; |
72 | count -= 20; | 122 | count -= 20; |
73 | 123 | ||
124 | while (count) { | ||
125 | size = min_t(uint, count, BULK_SIZE); | ||
126 | pipe = usb_sndbulkpipe(udev, 0x02); | ||
127 | memcpy(send_buf, firmware->data + sent, size); | ||
128 | |||
129 | err = usb_bulk_msg(udev, pipe, send_buf, size, | ||
130 | &len, 3000); | ||
131 | |||
132 | if (err || (len != size)) { | ||
133 | BT_ERR("Error in firmware loading err = %d," | ||
134 | "len = %d, size = %d", err, len, size); | ||
135 | goto error; | ||
136 | } | ||
137 | |||
138 | sent += size; | ||
139 | count -= size; | ||
140 | } | ||
141 | |||
142 | error: | ||
143 | kfree(send_buf); | ||
144 | return err; | ||
145 | } | ||
146 | |||
147 | static int ath3k_get_state(struct usb_device *udev, unsigned char *state) | ||
148 | { | ||
149 | int pipe = 0; | ||
150 | |||
151 | pipe = usb_rcvctrlpipe(udev, 0); | ||
152 | return usb_control_msg(udev, pipe, ATH3K_GETSTATE, | ||
153 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | ||
154 | state, 0x01, USB_CTRL_SET_TIMEOUT); | ||
155 | } | ||
156 | |||
157 | static int ath3k_get_version(struct usb_device *udev, | ||
158 | struct ath3k_version *version) | ||
159 | { | ||
160 | int pipe = 0; | ||
161 | |||
162 | pipe = usb_rcvctrlpipe(udev, 0); | ||
163 | return usb_control_msg(udev, pipe, ATH3K_GETVERSION, | ||
164 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, | ||
165 | sizeof(struct ath3k_version), | ||
166 | USB_CTRL_SET_TIMEOUT); | ||
167 | } | ||
168 | |||
169 | static int ath3k_load_fwfile(struct usb_device *udev, | ||
170 | const struct firmware *firmware) | ||
171 | { | ||
172 | u8 *send_buf; | ||
173 | int err, pipe, len, size, count, sent = 0; | ||
174 | int ret; | ||
175 | |||
176 | count = firmware->size; | ||
177 | |||
74 | send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); | 178 | send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); |
75 | if (!send_buf) { | 179 | if (!send_buf) { |
76 | BT_ERR("Can't allocate memory chunk for firmware"); | 180 | BT_ERR("Can't allocate memory chunk for firmware"); |
77 | return -ENOMEM; | 181 | return -ENOMEM; |
78 | } | 182 | } |
79 | 183 | ||
184 | size = min_t(uint, count, FW_HDR_SIZE); | ||
185 | memcpy(send_buf, firmware->data, size); | ||
186 | |||
187 | pipe = usb_sndctrlpipe(udev, 0); | ||
188 | ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD, | ||
189 | USB_TYPE_VENDOR, 0, 0, send_buf, | ||
190 | size, USB_CTRL_SET_TIMEOUT); | ||
191 | if (ret < 0) { | ||
192 | BT_ERR("Can't change to loading configuration err"); | ||
193 | kfree(send_buf); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | sent += size; | ||
198 | count -= size; | ||
199 | |||
80 | while (count) { | 200 | while (count) { |
81 | size = min_t(uint, count, BULK_SIZE); | 201 | size = min_t(uint, count, BULK_SIZE); |
82 | pipe = usb_sndbulkpipe(data->udev, 0x02); | 202 | pipe = usb_sndbulkpipe(udev, 0x02); |
83 | memcpy(send_buf, firmware + sent, size); | ||
84 | 203 | ||
85 | err = usb_bulk_msg(data->udev, pipe, send_buf, size, | 204 | memcpy(send_buf, firmware->data + sent, size); |
86 | &len, 3000); | ||
87 | 205 | ||
206 | err = usb_bulk_msg(udev, pipe, send_buf, size, | ||
207 | &len, 3000); | ||
88 | if (err || (len != size)) { | 208 | if (err || (len != size)) { |
89 | BT_ERR("Error in firmware loading err = %d," | 209 | BT_ERR("Error in firmware loading err = %d," |
90 | "len = %d, size = %d", err, len, size); | 210 | "len = %d, size = %d", err, len, size); |
91 | goto error; | 211 | kfree(send_buf); |
212 | return err; | ||
92 | } | 213 | } |
93 | |||
94 | sent += size; | 214 | sent += size; |
95 | count -= size; | 215 | count -= size; |
96 | } | 216 | } |
97 | 217 | ||
98 | kfree(send_buf); | 218 | kfree(send_buf); |
99 | return 0; | 219 | return 0; |
220 | } | ||
100 | 221 | ||
101 | error: | 222 | static int ath3k_switch_pid(struct usb_device *udev) |
102 | kfree(send_buf); | 223 | { |
103 | return err; | 224 | int pipe = 0; |
225 | |||
226 | pipe = usb_sndctrlpipe(udev, 0); | ||
227 | return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID, | ||
228 | USB_TYPE_VENDOR, 0, 0, | ||
229 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
230 | } | ||
231 | |||
232 | static int ath3k_set_normal_mode(struct usb_device *udev) | ||
233 | { | ||
234 | unsigned char fw_state; | ||
235 | int pipe = 0, ret; | ||
236 | |||
237 | ret = ath3k_get_state(udev, &fw_state); | ||
238 | if (ret < 0) { | ||
239 | BT_ERR("Can't get state to change to normal mode err"); | ||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { | ||
244 | BT_DBG("firmware was already in normal mode"); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | pipe = usb_sndctrlpipe(udev, 0); | ||
249 | return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE, | ||
250 | USB_TYPE_VENDOR, 0, 0, | ||
251 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
252 | } | ||
253 | |||
254 | static int ath3k_load_patch(struct usb_device *udev) | ||
255 | { | ||
256 | unsigned char fw_state; | ||
257 | char filename[ATH3K_NAME_LEN] = {0}; | ||
258 | const struct firmware *firmware; | ||
259 | struct ath3k_version fw_version, pt_version; | ||
260 | int ret; | ||
261 | |||
262 | ret = ath3k_get_state(udev, &fw_state); | ||
263 | if (ret < 0) { | ||
264 | BT_ERR("Can't get state to change to load ram patch err"); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | if (fw_state & ATH3K_PATCH_UPDATE) { | ||
269 | BT_DBG("Patch was already downloaded"); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | ret = ath3k_get_version(udev, &fw_version); | ||
274 | if (ret < 0) { | ||
275 | BT_ERR("Can't get version to change to load ram patch err"); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", | ||
280 | fw_version.rom_version); | ||
281 | |||
282 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
283 | if (ret < 0) { | ||
284 | BT_ERR("Patch file not found %s", filename); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); | ||
289 | pt_version.build_version = *(int *) | ||
290 | (firmware->data + firmware->size - 4); | ||
291 | |||
292 | if ((pt_version.rom_version != fw_version.rom_version) || | ||
293 | (pt_version.build_version <= fw_version.build_version)) { | ||
294 | BT_ERR("Patch file version did not match with firmware"); | ||
295 | release_firmware(firmware); | ||
296 | return -EINVAL; | ||
297 | } | ||
298 | |||
299 | ret = ath3k_load_fwfile(udev, firmware); | ||
300 | release_firmware(firmware); | ||
301 | |||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | static int ath3k_load_syscfg(struct usb_device *udev) | ||
306 | { | ||
307 | unsigned char fw_state; | ||
308 | char filename[ATH3K_NAME_LEN] = {0}; | ||
309 | const struct firmware *firmware; | ||
310 | struct ath3k_version fw_version; | ||
311 | int clk_value, ret; | ||
312 | |||
313 | ret = ath3k_get_state(udev, &fw_state); | ||
314 | if (ret < 0) { | ||
315 | BT_ERR("Can't get state to change to load configration err"); | ||
316 | return -EBUSY; | ||
317 | } | ||
318 | |||
319 | ret = ath3k_get_version(udev, &fw_version); | ||
320 | if (ret < 0) { | ||
321 | BT_ERR("Can't get version to change to load ram patch err"); | ||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | switch (fw_version.ref_clock) { | ||
326 | |||
327 | case ATH3K_XTAL_FREQ_26M: | ||
328 | clk_value = 26; | ||
329 | break; | ||
330 | case ATH3K_XTAL_FREQ_40M: | ||
331 | clk_value = 40; | ||
332 | break; | ||
333 | case ATH3K_XTAL_FREQ_19P2: | ||
334 | clk_value = 19; | ||
335 | break; | ||
336 | default: | ||
337 | clk_value = 0; | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", | ||
342 | fw_version.rom_version, clk_value, ".dfu"); | ||
343 | |||
344 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
345 | if (ret < 0) { | ||
346 | BT_ERR("Configuration file not found %s", filename); | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | ret = ath3k_load_fwfile(udev, firmware); | ||
351 | release_firmware(firmware); | ||
352 | |||
353 | return ret; | ||
104 | } | 354 | } |
105 | 355 | ||
106 | static int ath3k_probe(struct usb_interface *intf, | 356 | static int ath3k_probe(struct usb_interface *intf, |
@@ -108,57 +358,56 @@ static int ath3k_probe(struct usb_interface *intf, | |||
108 | { | 358 | { |
109 | const struct firmware *firmware; | 359 | const struct firmware *firmware; |
110 | struct usb_device *udev = interface_to_usbdev(intf); | 360 | struct usb_device *udev = interface_to_usbdev(intf); |
111 | struct ath3k_data *data; | 361 | int ret; |
112 | int size; | ||
113 | 362 | ||
114 | BT_DBG("intf %p id %p", intf, id); | 363 | BT_DBG("intf %p id %p", intf, id); |
115 | 364 | ||
116 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | 365 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) |
117 | return -ENODEV; | 366 | return -ENODEV; |
118 | 367 | ||
119 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 368 | /* match device ID in ath3k blacklist table */ |
120 | if (!data) | 369 | if (!id->driver_info) { |
121 | return -ENOMEM; | 370 | const struct usb_device_id *match; |
371 | match = usb_match_id(intf, ath3k_blist_tbl); | ||
372 | if (match) | ||
373 | id = match; | ||
374 | } | ||
122 | 375 | ||
123 | data->udev = udev; | 376 | /* load patch and sysconfig files for AR3012 */ |
377 | if (id->driver_info & BTUSB_ATH3012) { | ||
378 | ret = ath3k_load_patch(udev); | ||
379 | if (ret < 0) { | ||
380 | BT_ERR("Loading patch file failed"); | ||
381 | return ret; | ||
382 | } | ||
383 | ret = ath3k_load_syscfg(udev); | ||
384 | if (ret < 0) { | ||
385 | BT_ERR("Loading sysconfig file failed"); | ||
386 | return ret; | ||
387 | } | ||
388 | ret = ath3k_set_normal_mode(udev); | ||
389 | if (ret < 0) { | ||
390 | BT_ERR("Set normal mode failed"); | ||
391 | return ret; | ||
392 | } | ||
393 | ath3k_switch_pid(udev); | ||
394 | return 0; | ||
395 | } | ||
124 | 396 | ||
125 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | 397 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { |
126 | kfree(data); | 398 | BT_ERR("Error loading firmware"); |
127 | return -EIO; | 399 | return -EIO; |
128 | } | 400 | } |
129 | 401 | ||
130 | size = max_t(uint, firmware->size, 4096); | 402 | ret = ath3k_load_firmware(udev, firmware); |
131 | data->fw_data = kmalloc(size, GFP_KERNEL); | ||
132 | if (!data->fw_data) { | ||
133 | release_firmware(firmware); | ||
134 | kfree(data); | ||
135 | return -ENOMEM; | ||
136 | } | ||
137 | |||
138 | memcpy(data->fw_data, firmware->data, firmware->size); | ||
139 | data->fw_size = firmware->size; | ||
140 | data->fw_sent = 0; | ||
141 | release_firmware(firmware); | 403 | release_firmware(firmware); |
142 | 404 | ||
143 | usb_set_intfdata(intf, data); | 405 | return ret; |
144 | if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) { | ||
145 | usb_set_intfdata(intf, NULL); | ||
146 | kfree(data->fw_data); | ||
147 | kfree(data); | ||
148 | return -EIO; | ||
149 | } | ||
150 | |||
151 | return 0; | ||
152 | } | 406 | } |
153 | 407 | ||
154 | static void ath3k_disconnect(struct usb_interface *intf) | 408 | static void ath3k_disconnect(struct usb_interface *intf) |
155 | { | 409 | { |
156 | struct ath3k_data *data = usb_get_intfdata(intf); | ||
157 | |||
158 | BT_DBG("ath3k_disconnect intf %p", intf); | 410 | BT_DBG("ath3k_disconnect intf %p", intf); |
159 | |||
160 | kfree(data->fw_data); | ||
161 | kfree(data); | ||
162 | } | 411 | } |
163 | 412 | ||
164 | static struct usb_driver ath3k_driver = { | 413 | static struct usb_driver ath3k_driver = { |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index d52e90a5a617..aed1904ea67b 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/io.h> | 40 | #include <linux/io.h> |
41 | 41 | ||
42 | #include <pcmcia/cs.h> | ||
43 | #include <pcmcia/cistpl.h> | 42 | #include <pcmcia/cistpl.h> |
44 | #include <pcmcia/ciscode.h> | 43 | #include <pcmcia/ciscode.h> |
45 | #include <pcmcia/ds.h> | 44 | #include <pcmcia/ds.h> |
@@ -865,8 +864,7 @@ static int bluecard_probe(struct pcmcia_device *link) | |||
865 | info->p_dev = link; | 864 | info->p_dev = link; |
866 | link->priv = info; | 865 | link->priv = info; |
867 | 866 | ||
868 | link->conf.Attributes = CONF_ENABLE_IRQ; | 867 | link->config_flags |= CONF_ENABLE_IRQ; |
869 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
870 | 868 | ||
871 | return bluecard_config(link); | 869 | return bluecard_config(link); |
872 | } | 870 | } |
@@ -886,7 +884,7 @@ static int bluecard_config(struct pcmcia_device *link) | |||
886 | bluecard_info_t *info = link->priv; | 884 | bluecard_info_t *info = link->priv; |
887 | int i, n; | 885 | int i, n; |
888 | 886 | ||
889 | link->conf.ConfigIndex = 0x20; | 887 | link->config_index = 0x20; |
890 | 888 | ||
891 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 889 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
892 | link->resource[0]->end = 64; | 890 | link->resource[0]->end = 64; |
@@ -906,7 +904,7 @@ static int bluecard_config(struct pcmcia_device *link) | |||
906 | if (i != 0) | 904 | if (i != 0) |
907 | goto failed; | 905 | goto failed; |
908 | 906 | ||
909 | i = pcmcia_request_configuration(link, &link->conf); | 907 | i = pcmcia_enable_device(link); |
910 | if (i != 0) | 908 | if (i != 0) |
911 | goto failed; | 909 | goto failed; |
912 | 910 | ||
@@ -932,7 +930,7 @@ static void bluecard_release(struct pcmcia_device *link) | |||
932 | pcmcia_disable_device(link); | 930 | pcmcia_disable_device(link); |
933 | } | 931 | } |
934 | 932 | ||
935 | static struct pcmcia_device_id bluecard_ids[] = { | 933 | static const struct pcmcia_device_id bluecard_ids[] = { |
936 | PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e), | 934 | PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e), |
937 | PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c), | 935 | PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c), |
938 | PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab), | 936 | PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab), |
@@ -942,9 +940,7 @@ MODULE_DEVICE_TABLE(pcmcia, bluecard_ids); | |||
942 | 940 | ||
943 | static struct pcmcia_driver bluecard_driver = { | 941 | static struct pcmcia_driver bluecard_driver = { |
944 | .owner = THIS_MODULE, | 942 | .owner = THIS_MODULE, |
945 | .drv = { | 943 | .name = "bluecard_cs", |
946 | .name = "bluecard_cs", | ||
947 | }, | ||
948 | .probe = bluecard_probe, | 944 | .probe = bluecard_probe, |
949 | .remove = bluecard_detach, | 945 | .remove = bluecard_detach, |
950 | .id_table = bluecard_ids, | 946 | .id_table = bluecard_ids, |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 7ab8f29d5e0d..4fc01949d399 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <linux/device.h> | 45 | #include <linux/device.h> |
46 | #include <linux/firmware.h> | 46 | #include <linux/firmware.h> |
47 | 47 | ||
48 | #include <pcmcia/cs.h> | ||
49 | #include <pcmcia/cistpl.h> | 48 | #include <pcmcia/cistpl.h> |
50 | #include <pcmcia/ciscode.h> | 49 | #include <pcmcia/ciscode.h> |
51 | #include <pcmcia/ds.h> | 50 | #include <pcmcia/ds.h> |
@@ -657,11 +656,8 @@ static int bt3c_probe(struct pcmcia_device *link) | |||
657 | info->p_dev = link; | 656 | info->p_dev = link; |
658 | link->priv = info; | 657 | link->priv = info; |
659 | 658 | ||
660 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 659 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | |
661 | link->resource[0]->end = 8; | 660 | CONF_AUTO_SET_IO; |
662 | |||
663 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
664 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
665 | 661 | ||
666 | return bt3c_config(link); | 662 | return bt3c_config(link); |
667 | } | 663 | } |
@@ -675,43 +671,41 @@ static void bt3c_detach(struct pcmcia_device *link) | |||
675 | kfree(info); | 671 | kfree(info); |
676 | } | 672 | } |
677 | 673 | ||
678 | static int bt3c_check_config(struct pcmcia_device *p_dev, | 674 | static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data) |
679 | cistpl_cftable_entry_t *cf, | ||
680 | cistpl_cftable_entry_t *dflt, | ||
681 | unsigned int vcc, | ||
682 | void *priv_data) | ||
683 | { | 675 | { |
684 | unsigned long try = (unsigned long) priv_data; | 676 | int *try = priv_data; |
685 | 677 | ||
686 | p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; | 678 | if (try == 0) |
679 | p_dev->io_lines = 16; | ||
687 | 680 | ||
688 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 681 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) |
689 | p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 682 | return -EINVAL; |
690 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && | 683 | |
691 | (cf->io.win[0].base != 0)) { | 684 | p_dev->resource[0]->end = 8; |
692 | p_dev->resource[0]->start = cf->io.win[0].base; | 685 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
693 | if (!pcmcia_request_io(p_dev)) | 686 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
694 | return 0; | 687 | |
695 | } | 688 | return pcmcia_request_io(p_dev); |
696 | return -ENODEV; | ||
697 | } | 689 | } |
698 | 690 | ||
699 | static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, | 691 | static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, |
700 | cistpl_cftable_entry_t *cf, | ||
701 | cistpl_cftable_entry_t *dflt, | ||
702 | unsigned int vcc, | ||
703 | void *priv_data) | 692 | void *priv_data) |
704 | { | 693 | { |
705 | static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; | 694 | static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
706 | int j; | 695 | int j; |
707 | 696 | ||
708 | if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 697 | if (p_dev->io_lines > 3) |
709 | for (j = 0; j < 5; j++) { | 698 | return -ENODEV; |
710 | p_dev->resource[0]->start = base[j]; | 699 | |
711 | p_dev->io_lines = base[j] ? 16 : 3; | 700 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
712 | if (!pcmcia_request_io(p_dev)) | 701 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
713 | return 0; | 702 | p_dev->resource[0]->end = 8; |
714 | } | 703 | |
704 | for (j = 0; j < 5; j++) { | ||
705 | p_dev->resource[0]->start = base[j]; | ||
706 | p_dev->io_lines = base[j] ? 16 : 3; | ||
707 | if (!pcmcia_request_io(p_dev)) | ||
708 | return 0; | ||
715 | } | 709 | } |
716 | return -ENODEV; | 710 | return -ENODEV; |
717 | } | 711 | } |
@@ -742,7 +736,7 @@ found_port: | |||
742 | if (i != 0) | 736 | if (i != 0) |
743 | goto failed; | 737 | goto failed; |
744 | 738 | ||
745 | i = pcmcia_request_configuration(link, &link->conf); | 739 | i = pcmcia_enable_device(link); |
746 | if (i != 0) | 740 | if (i != 0) |
747 | goto failed; | 741 | goto failed; |
748 | 742 | ||
@@ -767,7 +761,7 @@ static void bt3c_release(struct pcmcia_device *link) | |||
767 | } | 761 | } |
768 | 762 | ||
769 | 763 | ||
770 | static struct pcmcia_device_id bt3c_ids[] = { | 764 | static const struct pcmcia_device_id bt3c_ids[] = { |
771 | PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02), | 765 | PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02), |
772 | PCMCIA_DEVICE_NULL | 766 | PCMCIA_DEVICE_NULL |
773 | }; | 767 | }; |
@@ -775,9 +769,7 @@ MODULE_DEVICE_TABLE(pcmcia, bt3c_ids); | |||
775 | 769 | ||
776 | static struct pcmcia_driver bt3c_driver = { | 770 | static struct pcmcia_driver bt3c_driver = { |
777 | .owner = THIS_MODULE, | 771 | .owner = THIS_MODULE, |
778 | .drv = { | 772 | .name = "bt3c_cs", |
779 | .name = "bt3c_cs", | ||
780 | }, | ||
781 | .probe = bt3c_probe, | 773 | .probe = bt3c_probe, |
782 | .remove = bt3c_detach, | 774 | .remove = bt3c_detach, |
783 | .id_table = bt3c_ids, | 775 | .id_table = bt3c_ids, |
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index 54739b08c308..8ecf4c6c2874 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c | |||
@@ -64,6 +64,8 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file, | |||
64 | return -EFAULT; | 64 | return -EFAULT; |
65 | 65 | ||
66 | ret = strict_strtol(buf, 10, &result); | 66 | ret = strict_strtol(buf, 10, &result); |
67 | if (ret) | ||
68 | return ret; | ||
67 | 69 | ||
68 | priv->btmrvl_dev.hscfgcmd = result; | 70 | priv->btmrvl_dev.hscfgcmd = result; |
69 | 71 | ||
@@ -92,6 +94,7 @@ static const struct file_operations btmrvl_hscfgcmd_fops = { | |||
92 | .read = btmrvl_hscfgcmd_read, | 94 | .read = btmrvl_hscfgcmd_read, |
93 | .write = btmrvl_hscfgcmd_write, | 95 | .write = btmrvl_hscfgcmd_write, |
94 | .open = btmrvl_open_generic, | 96 | .open = btmrvl_open_generic, |
97 | .llseek = default_llseek, | ||
95 | }; | 98 | }; |
96 | 99 | ||
97 | static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, | 100 | static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, |
@@ -107,6 +110,8 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf, | |||
107 | return -EFAULT; | 110 | return -EFAULT; |
108 | 111 | ||
109 | ret = strict_strtol(buf, 10, &result); | 112 | ret = strict_strtol(buf, 10, &result); |
113 | if (ret) | ||
114 | return ret; | ||
110 | 115 | ||
111 | priv->btmrvl_dev.psmode = result; | 116 | priv->btmrvl_dev.psmode = result; |
112 | 117 | ||
@@ -130,6 +135,7 @@ static const struct file_operations btmrvl_psmode_fops = { | |||
130 | .read = btmrvl_psmode_read, | 135 | .read = btmrvl_psmode_read, |
131 | .write = btmrvl_psmode_write, | 136 | .write = btmrvl_psmode_write, |
132 | .open = btmrvl_open_generic, | 137 | .open = btmrvl_open_generic, |
138 | .llseek = default_llseek, | ||
133 | }; | 139 | }; |
134 | 140 | ||
135 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, | 141 | static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, |
@@ -145,6 +151,8 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf, | |||
145 | return -EFAULT; | 151 | return -EFAULT; |
146 | 152 | ||
147 | ret = strict_strtol(buf, 10, &result); | 153 | ret = strict_strtol(buf, 10, &result); |
154 | if (ret) | ||
155 | return ret; | ||
148 | 156 | ||
149 | priv->btmrvl_dev.pscmd = result; | 157 | priv->btmrvl_dev.pscmd = result; |
150 | 158 | ||
@@ -173,6 +181,7 @@ static const struct file_operations btmrvl_pscmd_fops = { | |||
173 | .read = btmrvl_pscmd_read, | 181 | .read = btmrvl_pscmd_read, |
174 | .write = btmrvl_pscmd_write, | 182 | .write = btmrvl_pscmd_write, |
175 | .open = btmrvl_open_generic, | 183 | .open = btmrvl_open_generic, |
184 | .llseek = default_llseek, | ||
176 | }; | 185 | }; |
177 | 186 | ||
178 | static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, | 187 | static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, |
@@ -188,6 +197,8 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf, | |||
188 | return -EFAULT; | 197 | return -EFAULT; |
189 | 198 | ||
190 | ret = strict_strtol(buf, 16, &result); | 199 | ret = strict_strtol(buf, 16, &result); |
200 | if (ret) | ||
201 | return ret; | ||
191 | 202 | ||
192 | priv->btmrvl_dev.gpio_gap = result; | 203 | priv->btmrvl_dev.gpio_gap = result; |
193 | 204 | ||
@@ -211,6 +222,7 @@ static const struct file_operations btmrvl_gpiogap_fops = { | |||
211 | .read = btmrvl_gpiogap_read, | 222 | .read = btmrvl_gpiogap_read, |
212 | .write = btmrvl_gpiogap_write, | 223 | .write = btmrvl_gpiogap_write, |
213 | .open = btmrvl_open_generic, | 224 | .open = btmrvl_open_generic, |
225 | .llseek = default_llseek, | ||
214 | }; | 226 | }; |
215 | 227 | ||
216 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | 228 | static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, |
@@ -226,6 +238,8 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf, | |||
226 | return -EFAULT; | 238 | return -EFAULT; |
227 | 239 | ||
228 | ret = strict_strtol(buf, 10, &result); | 240 | ret = strict_strtol(buf, 10, &result); |
241 | if (ret) | ||
242 | return ret; | ||
229 | 243 | ||
230 | priv->btmrvl_dev.hscmd = result; | 244 | priv->btmrvl_dev.hscmd = result; |
231 | if (priv->btmrvl_dev.hscmd) { | 245 | if (priv->btmrvl_dev.hscmd) { |
@@ -252,6 +266,7 @@ static const struct file_operations btmrvl_hscmd_fops = { | |||
252 | .read = btmrvl_hscmd_read, | 266 | .read = btmrvl_hscmd_read, |
253 | .write = btmrvl_hscmd_write, | 267 | .write = btmrvl_hscmd_write, |
254 | .open = btmrvl_open_generic, | 268 | .open = btmrvl_open_generic, |
269 | .llseek = default_llseek, | ||
255 | }; | 270 | }; |
256 | 271 | ||
257 | static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, | 272 | static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, |
@@ -267,6 +282,8 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf, | |||
267 | return -EFAULT; | 282 | return -EFAULT; |
268 | 283 | ||
269 | ret = strict_strtol(buf, 10, &result); | 284 | ret = strict_strtol(buf, 10, &result); |
285 | if (ret) | ||
286 | return ret; | ||
270 | 287 | ||
271 | priv->btmrvl_dev.hsmode = result; | 288 | priv->btmrvl_dev.hsmode = result; |
272 | 289 | ||
@@ -289,6 +306,7 @@ static const struct file_operations btmrvl_hsmode_fops = { | |||
289 | .read = btmrvl_hsmode_read, | 306 | .read = btmrvl_hsmode_read, |
290 | .write = btmrvl_hsmode_write, | 307 | .write = btmrvl_hsmode_write, |
291 | .open = btmrvl_open_generic, | 308 | .open = btmrvl_open_generic, |
309 | .llseek = default_llseek, | ||
292 | }; | 310 | }; |
293 | 311 | ||
294 | static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, | 312 | static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, |
@@ -306,6 +324,7 @@ static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, | |||
306 | static const struct file_operations btmrvl_curpsmode_fops = { | 324 | static const struct file_operations btmrvl_curpsmode_fops = { |
307 | .read = btmrvl_curpsmode_read, | 325 | .read = btmrvl_curpsmode_read, |
308 | .open = btmrvl_open_generic, | 326 | .open = btmrvl_open_generic, |
327 | .llseek = default_llseek, | ||
309 | }; | 328 | }; |
310 | 329 | ||
311 | static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, | 330 | static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, |
@@ -323,6 +342,7 @@ static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, | |||
323 | static const struct file_operations btmrvl_psstate_fops = { | 342 | static const struct file_operations btmrvl_psstate_fops = { |
324 | .read = btmrvl_psstate_read, | 343 | .read = btmrvl_psstate_read, |
325 | .open = btmrvl_open_generic, | 344 | .open = btmrvl_open_generic, |
345 | .llseek = default_llseek, | ||
326 | }; | 346 | }; |
327 | 347 | ||
328 | static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, | 348 | static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, |
@@ -340,6 +360,7 @@ static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, | |||
340 | static const struct file_operations btmrvl_hsstate_fops = { | 360 | static const struct file_operations btmrvl_hsstate_fops = { |
341 | .read = btmrvl_hsstate_read, | 361 | .read = btmrvl_hsstate_read, |
342 | .open = btmrvl_open_generic, | 362 | .open = btmrvl_open_generic, |
363 | .llseek = default_llseek, | ||
343 | }; | 364 | }; |
344 | 365 | ||
345 | static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, | 366 | static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, |
@@ -358,6 +379,7 @@ static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, | |||
358 | static const struct file_operations btmrvl_txdnldready_fops = { | 379 | static const struct file_operations btmrvl_txdnldready_fops = { |
359 | .read = btmrvl_txdnldready_read, | 380 | .read = btmrvl_txdnldready_read, |
360 | .open = btmrvl_open_generic, | 381 | .open = btmrvl_open_generic, |
382 | .llseek = default_llseek, | ||
361 | }; | 383 | }; |
362 | 384 | ||
363 | void btmrvl_debugfs_init(struct hci_dev *hdev) | 385 | void btmrvl_debugfs_init(struct hci_dev *hdev) |
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 0d32ec82e9bf..548d1d9e4dda 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
@@ -117,8 +117,8 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) | |||
117 | (event->data[2] == MODULE_ALREADY_UP)) ? | 117 | (event->data[2] == MODULE_ALREADY_UP)) ? |
118 | "Bring-up succeed" : "Bring-up failed"); | 118 | "Bring-up succeed" : "Bring-up failed"); |
119 | 119 | ||
120 | if (event->length > 3) | 120 | if (event->length > 3 && event->data[3]) |
121 | priv->btmrvl_dev.dev_type = event->data[3]; | 121 | priv->btmrvl_dev.dev_type = HCI_AMP; |
122 | else | 122 | else |
123 | priv->btmrvl_dev.dev_type = HCI_BREDR; | 123 | priv->btmrvl_dev.dev_type = HCI_BREDR; |
124 | 124 | ||
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index dcc2a6ec23f0..7f521d4ac657 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -49,15 +49,59 @@ | |||
49 | static u8 user_rmmod; | 49 | static u8 user_rmmod; |
50 | static u8 sdio_ireg; | 50 | static u8 sdio_ireg; |
51 | 51 | ||
52 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { | ||
53 | .cfg = 0x03, | ||
54 | .host_int_mask = 0x04, | ||
55 | .host_intstatus = 0x05, | ||
56 | .card_status = 0x20, | ||
57 | .sq_read_base_addr_a0 = 0x10, | ||
58 | .sq_read_base_addr_a1 = 0x11, | ||
59 | .card_fw_status0 = 0x40, | ||
60 | .card_fw_status1 = 0x41, | ||
61 | .card_rx_len = 0x42, | ||
62 | .card_rx_unit = 0x43, | ||
63 | .io_port_0 = 0x00, | ||
64 | .io_port_1 = 0x01, | ||
65 | .io_port_2 = 0x02, | ||
66 | }; | ||
67 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { | ||
68 | .cfg = 0x00, | ||
69 | .host_int_mask = 0x02, | ||
70 | .host_intstatus = 0x03, | ||
71 | .card_status = 0x30, | ||
72 | .sq_read_base_addr_a0 = 0x40, | ||
73 | .sq_read_base_addr_a1 = 0x41, | ||
74 | .card_revision = 0x5c, | ||
75 | .card_fw_status0 = 0x60, | ||
76 | .card_fw_status1 = 0x61, | ||
77 | .card_rx_len = 0x62, | ||
78 | .card_rx_unit = 0x63, | ||
79 | .io_port_0 = 0x78, | ||
80 | .io_port_1 = 0x79, | ||
81 | .io_port_2 = 0x7a, | ||
82 | }; | ||
83 | |||
52 | static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { | 84 | static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = { |
53 | .helper = "sd8688_helper.bin", | 85 | .helper = "sd8688_helper.bin", |
54 | .firmware = "sd8688.bin", | 86 | .firmware = "sd8688.bin", |
87 | .reg = &btmrvl_reg_8688, | ||
88 | .sd_blksz_fw_dl = 64, | ||
89 | }; | ||
90 | |||
91 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { | ||
92 | .helper = NULL, | ||
93 | .firmware = "mrvl/sd8787_uapsta.bin", | ||
94 | .reg = &btmrvl_reg_8787, | ||
95 | .sd_blksz_fw_dl = 256, | ||
55 | }; | 96 | }; |
56 | 97 | ||
57 | static const struct sdio_device_id btmrvl_sdio_ids[] = { | 98 | static const struct sdio_device_id btmrvl_sdio_ids[] = { |
58 | /* Marvell SD8688 Bluetooth device */ | 99 | /* Marvell SD8688 Bluetooth device */ |
59 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), | 100 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), |
60 | .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, | 101 | .driver_data = (unsigned long) &btmrvl_sdio_sd6888 }, |
102 | /* Marvell SD8787 Bluetooth device */ | ||
103 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), | ||
104 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, | ||
61 | 105 | ||
62 | { } /* Terminating entry */ | 106 | { } /* Terminating entry */ |
63 | }; | 107 | }; |
@@ -69,7 +113,7 @@ static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card) | |||
69 | u8 reg; | 113 | u8 reg; |
70 | int ret; | 114 | int ret; |
71 | 115 | ||
72 | reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret); | 116 | reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret); |
73 | if (!ret) | 117 | if (!ret) |
74 | card->rx_unit = reg; | 118 | card->rx_unit = reg; |
75 | 119 | ||
@@ -83,11 +127,11 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat) | |||
83 | 127 | ||
84 | *dat = 0; | 128 | *dat = 0; |
85 | 129 | ||
86 | fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret); | 130 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); |
87 | if (ret) | 131 | if (ret) |
88 | return -EIO; | 132 | return -EIO; |
89 | 133 | ||
90 | fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret); | 134 | fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret); |
91 | if (ret) | 135 | if (ret) |
92 | return -EIO; | 136 | return -EIO; |
93 | 137 | ||
@@ -101,7 +145,7 @@ static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat) | |||
101 | u8 reg; | 145 | u8 reg; |
102 | int ret; | 146 | int ret; |
103 | 147 | ||
104 | reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret); | 148 | reg = sdio_readb(card->func, card->reg->card_rx_len, &ret); |
105 | if (!ret) | 149 | if (!ret) |
106 | *dat = (u16) reg << card->rx_unit; | 150 | *dat = (u16) reg << card->rx_unit; |
107 | 151 | ||
@@ -113,7 +157,7 @@ static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card, | |||
113 | { | 157 | { |
114 | int ret; | 158 | int ret; |
115 | 159 | ||
116 | sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret); | 160 | sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret); |
117 | if (ret) { | 161 | if (ret) { |
118 | BT_ERR("Unable to enable the host interrupt!"); | 162 | BT_ERR("Unable to enable the host interrupt!"); |
119 | ret = -EIO; | 163 | ret = -EIO; |
@@ -128,13 +172,13 @@ static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card, | |||
128 | u8 host_int_mask; | 172 | u8 host_int_mask; |
129 | int ret; | 173 | int ret; |
130 | 174 | ||
131 | host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret); | 175 | host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret); |
132 | if (ret) | 176 | if (ret) |
133 | return -EIO; | 177 | return -EIO; |
134 | 178 | ||
135 | host_int_mask &= ~mask; | 179 | host_int_mask &= ~mask; |
136 | 180 | ||
137 | sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret); | 181 | sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret); |
138 | if (ret < 0) { | 182 | if (ret < 0) { |
139 | BT_ERR("Unable to disable the host interrupt!"); | 183 | BT_ERR("Unable to disable the host interrupt!"); |
140 | return -EIO; | 184 | return -EIO; |
@@ -150,7 +194,7 @@ static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits) | |||
150 | int ret; | 194 | int ret; |
151 | 195 | ||
152 | for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { | 196 | for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) { |
153 | status = sdio_readb(card->func, CARD_STATUS_REG, &ret); | 197 | status = sdio_readb(card->func, card->reg->card_status, &ret); |
154 | if (ret) | 198 | if (ret) |
155 | goto failed; | 199 | goto failed; |
156 | if ((status & bits) == bits) | 200 | if ((status & bits) == bits) |
@@ -299,7 +343,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
299 | u8 base0, base1; | 343 | u8 base0, base1; |
300 | void *tmpfwbuf = NULL; | 344 | void *tmpfwbuf = NULL; |
301 | u8 *fwbuf; | 345 | u8 *fwbuf; |
302 | u16 len; | 346 | u16 len, blksz_dl = card->sd_blksz_fw_dl; |
303 | int txlen = 0, tx_blocks = 0, count = 0; | 347 | int txlen = 0, tx_blocks = 0, count = 0; |
304 | 348 | ||
305 | ret = request_firmware(&fw_firmware, card->firmware, | 349 | ret = request_firmware(&fw_firmware, card->firmware, |
@@ -345,7 +389,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
345 | 389 | ||
346 | for (tries = 0; tries < MAX_POLL_TRIES; tries++) { | 390 | for (tries = 0; tries < MAX_POLL_TRIES; tries++) { |
347 | base0 = sdio_readb(card->func, | 391 | base0 = sdio_readb(card->func, |
348 | SQ_READ_BASE_ADDRESS_A0_REG, &ret); | 392 | card->reg->sq_read_base_addr_a0, &ret); |
349 | if (ret) { | 393 | if (ret) { |
350 | BT_ERR("BASE0 register read failed:" | 394 | BT_ERR("BASE0 register read failed:" |
351 | " base0 = 0x%04X(%d)." | 395 | " base0 = 0x%04X(%d)." |
@@ -355,7 +399,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
355 | goto done; | 399 | goto done; |
356 | } | 400 | } |
357 | base1 = sdio_readb(card->func, | 401 | base1 = sdio_readb(card->func, |
358 | SQ_READ_BASE_ADDRESS_A1_REG, &ret); | 402 | card->reg->sq_read_base_addr_a1, &ret); |
359 | if (ret) { | 403 | if (ret) { |
360 | BT_ERR("BASE1 register read failed:" | 404 | BT_ERR("BASE1 register read failed:" |
361 | " base1 = 0x%04X(%d)." | 405 | " base1 = 0x%04X(%d)." |
@@ -403,20 +447,19 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card) | |||
403 | if (firmwarelen - offset < txlen) | 447 | if (firmwarelen - offset < txlen) |
404 | txlen = firmwarelen - offset; | 448 | txlen = firmwarelen - offset; |
405 | 449 | ||
406 | tx_blocks = | 450 | tx_blocks = (txlen + blksz_dl - 1) / blksz_dl; |
407 | (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE; | ||
408 | 451 | ||
409 | memcpy(fwbuf, &firmware[offset], txlen); | 452 | memcpy(fwbuf, &firmware[offset], txlen); |
410 | } | 453 | } |
411 | 454 | ||
412 | ret = sdio_writesb(card->func, card->ioport, fwbuf, | 455 | ret = sdio_writesb(card->func, card->ioport, fwbuf, |
413 | tx_blocks * SDIO_BLOCK_SIZE); | 456 | tx_blocks * blksz_dl); |
414 | 457 | ||
415 | if (ret < 0) { | 458 | if (ret < 0) { |
416 | BT_ERR("FW download, writesb(%d) failed @%d", | 459 | BT_ERR("FW download, writesb(%d) failed @%d", |
417 | count, offset); | 460 | count, offset); |
418 | sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG, | 461 | sdio_writeb(card->func, HOST_CMD53_FIN, |
419 | &ret); | 462 | card->reg->cfg, &ret); |
420 | if (ret) | 463 | if (ret) |
421 | BT_ERR("writeb failed (CFG)"); | 464 | BT_ERR("writeb failed (CFG)"); |
422 | } | 465 | } |
@@ -597,7 +640,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) | |||
597 | 640 | ||
598 | priv = card->priv; | 641 | priv = card->priv; |
599 | 642 | ||
600 | ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); | 643 | ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); |
601 | if (ret) { | 644 | if (ret) { |
602 | BT_ERR("sdio_readb: read int status register failed"); | 645 | BT_ERR("sdio_readb: read int status register failed"); |
603 | return; | 646 | return; |
@@ -613,7 +656,7 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func) | |||
613 | 656 | ||
614 | sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | | 657 | sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS | |
615 | UP_LD_HOST_INT_STATUS), | 658 | UP_LD_HOST_INT_STATUS), |
616 | HOST_INTSTATUS_REG, &ret); | 659 | card->reg->host_intstatus, &ret); |
617 | if (ret) { | 660 | if (ret) { |
618 | BT_ERR("sdio_writeb: clear int status register failed"); | 661 | BT_ERR("sdio_writeb: clear int status register failed"); |
619 | return; | 662 | return; |
@@ -664,7 +707,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
664 | goto release_irq; | 707 | goto release_irq; |
665 | } | 708 | } |
666 | 709 | ||
667 | reg = sdio_readb(func, IO_PORT_0_REG, &ret); | 710 | reg = sdio_readb(func, card->reg->io_port_0, &ret); |
668 | if (ret < 0) { | 711 | if (ret < 0) { |
669 | ret = -EIO; | 712 | ret = -EIO; |
670 | goto release_irq; | 713 | goto release_irq; |
@@ -672,7 +715,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
672 | 715 | ||
673 | card->ioport = reg; | 716 | card->ioport = reg; |
674 | 717 | ||
675 | reg = sdio_readb(func, IO_PORT_1_REG, &ret); | 718 | reg = sdio_readb(func, card->reg->io_port_1, &ret); |
676 | if (ret < 0) { | 719 | if (ret < 0) { |
677 | ret = -EIO; | 720 | ret = -EIO; |
678 | goto release_irq; | 721 | goto release_irq; |
@@ -680,7 +723,7 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card) | |||
680 | 723 | ||
681 | card->ioport |= (reg << 8); | 724 | card->ioport |= (reg << 8); |
682 | 725 | ||
683 | reg = sdio_readb(func, IO_PORT_2_REG, &ret); | 726 | reg = sdio_readb(func, card->reg->io_port_2, &ret); |
684 | if (ret < 0) { | 727 | if (ret < 0) { |
685 | ret = -EIO; | 728 | ret = -EIO; |
686 | goto release_irq; | 729 | goto release_irq; |
@@ -815,6 +858,8 @@ exit: | |||
815 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | 858 | static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) |
816 | { | 859 | { |
817 | int ret = 0; | 860 | int ret = 0; |
861 | u8 fws0; | ||
862 | int pollnum = MAX_POLL_TRIES; | ||
818 | 863 | ||
819 | if (!card || !card->func) { | 864 | if (!card || !card->func) { |
820 | BT_ERR("card or function is NULL!"); | 865 | BT_ERR("card or function is NULL!"); |
@@ -827,20 +872,36 @@ static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card) | |||
827 | goto done; | 872 | goto done; |
828 | } | 873 | } |
829 | 874 | ||
830 | ret = btmrvl_sdio_download_helper(card); | 875 | /* Check if other function driver is downloading the firmware */ |
876 | fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret); | ||
831 | if (ret) { | 877 | if (ret) { |
832 | BT_ERR("Failed to download helper!"); | 878 | BT_ERR("Failed to read FW downloading status!"); |
833 | ret = -EIO; | 879 | ret = -EIO; |
834 | goto done; | 880 | goto done; |
835 | } | 881 | } |
882 | if (fws0) { | ||
883 | BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0); | ||
884 | |||
885 | /* Give other function more time to download the firmware */ | ||
886 | pollnum *= 10; | ||
887 | } else { | ||
888 | if (card->helper) { | ||
889 | ret = btmrvl_sdio_download_helper(card); | ||
890 | if (ret) { | ||
891 | BT_ERR("Failed to download helper!"); | ||
892 | ret = -EIO; | ||
893 | goto done; | ||
894 | } | ||
895 | } | ||
836 | 896 | ||
837 | if (btmrvl_sdio_download_fw_w_helper(card)) { | 897 | if (btmrvl_sdio_download_fw_w_helper(card)) { |
838 | BT_ERR("Failed to download firmware!"); | 898 | BT_ERR("Failed to download firmware!"); |
839 | ret = -EIO; | 899 | ret = -EIO; |
840 | goto done; | 900 | goto done; |
901 | } | ||
841 | } | 902 | } |
842 | 903 | ||
843 | if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) { | 904 | if (btmrvl_sdio_verify_fw_download(card, pollnum)) { |
844 | BT_ERR("FW failed to be active in time!"); | 905 | BT_ERR("FW failed to be active in time!"); |
845 | ret = -ETIMEDOUT; | 906 | ret = -ETIMEDOUT; |
846 | goto done; | 907 | goto done; |
@@ -864,7 +925,7 @@ static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv) | |||
864 | 925 | ||
865 | sdio_claim_host(card->func); | 926 | sdio_claim_host(card->func); |
866 | 927 | ||
867 | sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret); | 928 | sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret); |
868 | 929 | ||
869 | sdio_release_host(card->func); | 930 | sdio_release_host(card->func); |
870 | 931 | ||
@@ -893,8 +954,10 @@ static int btmrvl_sdio_probe(struct sdio_func *func, | |||
893 | 954 | ||
894 | if (id->driver_data) { | 955 | if (id->driver_data) { |
895 | struct btmrvl_sdio_device *data = (void *) id->driver_data; | 956 | struct btmrvl_sdio_device *data = (void *) id->driver_data; |
896 | card->helper = data->helper; | 957 | card->helper = data->helper; |
897 | card->firmware = data->firmware; | 958 | card->firmware = data->firmware; |
959 | card->reg = data->reg; | ||
960 | card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; | ||
898 | } | 961 | } |
899 | 962 | ||
900 | if (btmrvl_sdio_register_dev(card) < 0) { | 963 | if (btmrvl_sdio_register_dev(card) < 0) { |
@@ -1011,3 +1074,4 @@ MODULE_VERSION(VERSION); | |||
1011 | MODULE_LICENSE("GPL v2"); | 1074 | MODULE_LICENSE("GPL v2"); |
1012 | MODULE_FIRMWARE("sd8688_helper.bin"); | 1075 | MODULE_FIRMWARE("sd8688_helper.bin"); |
1013 | MODULE_FIRMWARE("sd8688.bin"); | 1076 | MODULE_FIRMWARE("sd8688.bin"); |
1077 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); | ||
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h index 27329f107e5a..43d35a609ca9 100644 --- a/drivers/bluetooth/btmrvl_sdio.h +++ b/drivers/bluetooth/btmrvl_sdio.h | |||
@@ -47,44 +47,46 @@ | |||
47 | /* Max retry number of CMD53 write */ | 47 | /* Max retry number of CMD53 write */ |
48 | #define MAX_WRITE_IOMEM_RETRY 2 | 48 | #define MAX_WRITE_IOMEM_RETRY 2 |
49 | 49 | ||
50 | /* Host Control Registers */ | 50 | /* register bitmasks */ |
51 | #define IO_PORT_0_REG 0x00 | 51 | #define HOST_POWER_UP BIT(1) |
52 | #define IO_PORT_1_REG 0x01 | 52 | #define HOST_CMD53_FIN BIT(2) |
53 | #define IO_PORT_2_REG 0x02 | 53 | |
54 | 54 | #define HIM_DISABLE 0xff | |
55 | #define CONFIG_REG 0x03 | 55 | #define HIM_ENABLE (BIT(0) | BIT(1)) |
56 | #define HOST_POWER_UP BIT(1) | 56 | |
57 | #define HOST_CMD53_FIN BIT(2) | 57 | #define UP_LD_HOST_INT_STATUS BIT(0) |
58 | 58 | #define DN_LD_HOST_INT_STATUS BIT(1) | |
59 | #define HOST_INT_MASK_REG 0x04 | 59 | |
60 | #define HIM_DISABLE 0xff | 60 | #define DN_LD_CARD_RDY BIT(0) |
61 | #define HIM_ENABLE (BIT(0) | BIT(1)) | 61 | #define CARD_IO_READY BIT(3) |
62 | 62 | ||
63 | #define HOST_INTSTATUS_REG 0x05 | 63 | #define FIRMWARE_READY 0xfedc |
64 | #define UP_LD_HOST_INT_STATUS BIT(0) | 64 | |
65 | #define DN_LD_HOST_INT_STATUS BIT(1) | 65 | |
66 | 66 | struct btmrvl_sdio_card_reg { | |
67 | /* Card Control Registers */ | 67 | u8 cfg; |
68 | #define SQ_READ_BASE_ADDRESS_A0_REG 0x10 | 68 | u8 host_int_mask; |
69 | #define SQ_READ_BASE_ADDRESS_A1_REG 0x11 | 69 | u8 host_intstatus; |
70 | 70 | u8 card_status; | |
71 | #define CARD_STATUS_REG 0x20 | 71 | u8 sq_read_base_addr_a0; |
72 | #define DN_LD_CARD_RDY BIT(0) | 72 | u8 sq_read_base_addr_a1; |
73 | #define CARD_IO_READY BIT(3) | 73 | u8 card_revision; |
74 | 74 | u8 card_fw_status0; | |
75 | #define CARD_FW_STATUS0_REG 0x40 | 75 | u8 card_fw_status1; |
76 | #define CARD_FW_STATUS1_REG 0x41 | 76 | u8 card_rx_len; |
77 | #define FIRMWARE_READY 0xfedc | 77 | u8 card_rx_unit; |
78 | 78 | u8 io_port_0; | |
79 | #define CARD_RX_LEN_REG 0x42 | 79 | u8 io_port_1; |
80 | #define CARD_RX_UNIT_REG 0x43 | 80 | u8 io_port_2; |
81 | 81 | }; | |
82 | 82 | ||
83 | struct btmrvl_sdio_card { | 83 | struct btmrvl_sdio_card { |
84 | struct sdio_func *func; | 84 | struct sdio_func *func; |
85 | u32 ioport; | 85 | u32 ioport; |
86 | const char *helper; | 86 | const char *helper; |
87 | const char *firmware; | 87 | const char *firmware; |
88 | const struct btmrvl_sdio_card_reg *reg; | ||
89 | u16 sd_blksz_fw_dl; | ||
88 | u8 rx_unit; | 90 | u8 rx_unit; |
89 | struct btmrvl_private *priv; | 91 | struct btmrvl_private *priv; |
90 | }; | 92 | }; |
@@ -92,6 +94,8 @@ struct btmrvl_sdio_card { | |||
92 | struct btmrvl_sdio_device { | 94 | struct btmrvl_sdio_device { |
93 | const char *helper; | 95 | const char *helper; |
94 | const char *firmware; | 96 | const char *firmware; |
97 | const struct btmrvl_sdio_card_reg *reg; | ||
98 | u16 sd_blksz_fw_dl; | ||
95 | }; | 99 | }; |
96 | 100 | ||
97 | 101 | ||
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 76e5127884f0..792e32d29a1d 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c | |||
@@ -46,6 +46,9 @@ static const struct sdio_device_id btsdio_table[] = { | |||
46 | /* Generic Bluetooth Type-B SDIO device */ | 46 | /* Generic Bluetooth Type-B SDIO device */ |
47 | { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, | 47 | { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, |
48 | 48 | ||
49 | /* Generic Bluetooth AMP controller */ | ||
50 | { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) }, | ||
51 | |||
49 | { } /* Terminating entry */ | 52 | { } /* Terminating entry */ |
50 | }; | 53 | }; |
51 | 54 | ||
@@ -329,6 +332,11 @@ static int btsdio_probe(struct sdio_func *func, | |||
329 | hdev->bus = HCI_SDIO; | 332 | hdev->bus = HCI_SDIO; |
330 | hdev->driver_data = data; | 333 | hdev->driver_data = data; |
331 | 334 | ||
335 | if (id->class == SDIO_CLASS_BT_AMP) | ||
336 | hdev->dev_type = HCI_AMP; | ||
337 | else | ||
338 | hdev->dev_type = HCI_BREDR; | ||
339 | |||
332 | data->hdev = hdev; | 340 | data->hdev = hdev; |
333 | 341 | ||
334 | SET_HCIDEV_DEV(hdev, &func->dev); | 342 | SET_HCIDEV_DEV(hdev, &func->dev); |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 1c4f5e863b03..526b61807d94 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
43 | 43 | ||
44 | #include <pcmcia/cs.h> | ||
45 | #include <pcmcia/cistpl.h> | 44 | #include <pcmcia/cistpl.h> |
46 | #include <pcmcia/ciscode.h> | 45 | #include <pcmcia/ciscode.h> |
47 | #include <pcmcia/ds.h> | 46 | #include <pcmcia/ds.h> |
@@ -586,11 +585,8 @@ static int btuart_probe(struct pcmcia_device *link) | |||
586 | info->p_dev = link; | 585 | info->p_dev = link; |
587 | link->priv = info; | 586 | link->priv = info; |
588 | 587 | ||
589 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 588 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | |
590 | link->resource[0]->end = 8; | 589 | CONF_AUTO_SET_IO; |
591 | |||
592 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
593 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
594 | 590 | ||
595 | return btuart_config(link); | 591 | return btuart_config(link); |
596 | } | 592 | } |
@@ -604,43 +600,41 @@ static void btuart_detach(struct pcmcia_device *link) | |||
604 | kfree(info); | 600 | kfree(info); |
605 | } | 601 | } |
606 | 602 | ||
607 | static int btuart_check_config(struct pcmcia_device *p_dev, | 603 | static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data) |
608 | cistpl_cftable_entry_t *cf, | ||
609 | cistpl_cftable_entry_t *dflt, | ||
610 | unsigned int vcc, | ||
611 | void *priv_data) | ||
612 | { | 604 | { |
613 | int *try = priv_data; | 605 | int *try = priv_data; |
614 | 606 | ||
615 | p_dev->io_lines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; | 607 | if (try == 0) |
608 | p_dev->io_lines = 16; | ||
616 | 609 | ||
617 | if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) | 610 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) |
618 | p_dev->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 611 | return -EINVAL; |
619 | if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && | 612 | |
620 | (cf->io.win[0].base != 0)) { | 613 | p_dev->resource[0]->end = 8; |
621 | p_dev->resource[0]->start = cf->io.win[0].base; | 614 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
622 | if (!pcmcia_request_io(p_dev)) | 615 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
623 | return 0; | 616 | |
624 | } | 617 | return pcmcia_request_io(p_dev); |
625 | return -ENODEV; | ||
626 | } | 618 | } |
627 | 619 | ||
628 | static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, | 620 | static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, |
629 | cistpl_cftable_entry_t *cf, | ||
630 | cistpl_cftable_entry_t *dflt, | ||
631 | unsigned int vcc, | ||
632 | void *priv_data) | 621 | void *priv_data) |
633 | { | 622 | { |
634 | static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; | 623 | static unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
635 | int j; | 624 | int j; |
636 | 625 | ||
637 | if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { | 626 | if (p_dev->io_lines > 3) |
638 | for (j = 0; j < 5; j++) { | 627 | return -ENODEV; |
639 | p_dev->resource[0]->start = base[j]; | 628 | |
640 | p_dev->io_lines = base[j] ? 16 : 3; | 629 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
641 | if (!pcmcia_request_io(p_dev)) | 630 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
642 | return 0; | 631 | p_dev->resource[0]->end = 8; |
643 | } | 632 | |
633 | for (j = 0; j < 5; j++) { | ||
634 | p_dev->resource[0]->start = base[j]; | ||
635 | p_dev->io_lines = base[j] ? 16 : 3; | ||
636 | if (!pcmcia_request_io(p_dev)) | ||
637 | return 0; | ||
644 | } | 638 | } |
645 | return -ENODEV; | 639 | return -ENODEV; |
646 | } | 640 | } |
@@ -671,7 +665,7 @@ found_port: | |||
671 | if (i != 0) | 665 | if (i != 0) |
672 | goto failed; | 666 | goto failed; |
673 | 667 | ||
674 | i = pcmcia_request_configuration(link, &link->conf); | 668 | i = pcmcia_enable_device(link); |
675 | if (i != 0) | 669 | if (i != 0) |
676 | goto failed; | 670 | goto failed; |
677 | 671 | ||
@@ -695,7 +689,7 @@ static void btuart_release(struct pcmcia_device *link) | |||
695 | pcmcia_disable_device(link); | 689 | pcmcia_disable_device(link); |
696 | } | 690 | } |
697 | 691 | ||
698 | static struct pcmcia_device_id btuart_ids[] = { | 692 | static const struct pcmcia_device_id btuart_ids[] = { |
699 | /* don't use this driver. Use serial_cs + hci_uart instead */ | 693 | /* don't use this driver. Use serial_cs + hci_uart instead */ |
700 | PCMCIA_DEVICE_NULL | 694 | PCMCIA_DEVICE_NULL |
701 | }; | 695 | }; |
@@ -703,9 +697,7 @@ MODULE_DEVICE_TABLE(pcmcia, btuart_ids); | |||
703 | 697 | ||
704 | static struct pcmcia_driver btuart_driver = { | 698 | static struct pcmcia_driver btuart_driver = { |
705 | .owner = THIS_MODULE, | 699 | .owner = THIS_MODULE, |
706 | .drv = { | 700 | .name = "btuart_cs", |
707 | .name = "btuart_cs", | ||
708 | }, | ||
709 | .probe = btuart_probe, | 701 | .probe = btuart_probe, |
710 | .remove = btuart_detach, | 702 | .remove = btuart_detach, |
711 | .id_table = btuart_ids, | 703 | .id_table = btuart_ids, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d22ce3cc611e..c2de8951e3fb 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -59,9 +59,21 @@ static struct usb_device_id btusb_table[] = { | |||
59 | /* Generic Bluetooth USB device */ | 59 | /* Generic Bluetooth USB device */ |
60 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 60 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
61 | 61 | ||
62 | /* Apple MacBookPro 7,1 */ | ||
63 | { USB_DEVICE(0x05ac, 0x8213) }, | ||
64 | |||
62 | /* Apple iMac11,1 */ | 65 | /* Apple iMac11,1 */ |
63 | { USB_DEVICE(0x05ac, 0x8215) }, | 66 | { USB_DEVICE(0x05ac, 0x8215) }, |
64 | 67 | ||
68 | /* Apple MacBookPro6,2 */ | ||
69 | { USB_DEVICE(0x05ac, 0x8218) }, | ||
70 | |||
71 | /* Apple MacBookAir3,1, MacBookAir3,2 */ | ||
72 | { USB_DEVICE(0x05ac, 0x821b) }, | ||
73 | |||
74 | /* Apple MacBookPro8,2 */ | ||
75 | { USB_DEVICE(0x05ac, 0x821a) }, | ||
76 | |||
65 | /* AVM BlueFRITZ! USB v2.0 */ | 77 | /* AVM BlueFRITZ! USB v2.0 */ |
66 | { USB_DEVICE(0x057c, 0x3800) }, | 78 | { USB_DEVICE(0x057c, 0x3800) }, |
67 | 79 | ||
@@ -90,6 +102,19 @@ static struct usb_device_id blacklist_table[] = { | |||
90 | /* Broadcom BCM2033 without firmware */ | 102 | /* Broadcom BCM2033 without firmware */ |
91 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | 103 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, |
92 | 104 | ||
105 | /* Atheros 3011 with sflash firmware */ | ||
106 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | ||
107 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, | ||
108 | |||
109 | /* Atheros AR9285 Malbec with sflash firmware */ | ||
110 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | ||
111 | |||
112 | /* Atheros 3012 with sflash firmware */ | ||
113 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE }, | ||
114 | |||
115 | /* Atheros AR5BBU12 with sflash firmware */ | ||
116 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | ||
117 | |||
93 | /* Broadcom BCM2035 */ | 118 | /* Broadcom BCM2035 */ |
94 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 119 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
95 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 120 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
@@ -230,7 +255,8 @@ static void btusb_intr_complete(struct urb *urb) | |||
230 | 255 | ||
231 | err = usb_submit_urb(urb, GFP_ATOMIC); | 256 | err = usb_submit_urb(urb, GFP_ATOMIC); |
232 | if (err < 0) { | 257 | if (err < 0) { |
233 | BT_ERR("%s urb %p failed to resubmit (%d)", | 258 | if (err != -EPERM) |
259 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
234 | hdev->name, urb, -err); | 260 | hdev->name, urb, -err); |
235 | usb_unanchor_urb(urb); | 261 | usb_unanchor_urb(urb); |
236 | } | 262 | } |
@@ -314,7 +340,8 @@ static void btusb_bulk_complete(struct urb *urb) | |||
314 | 340 | ||
315 | err = usb_submit_urb(urb, GFP_ATOMIC); | 341 | err = usb_submit_urb(urb, GFP_ATOMIC); |
316 | if (err < 0) { | 342 | if (err < 0) { |
317 | BT_ERR("%s urb %p failed to resubmit (%d)", | 343 | if (err != -EPERM) |
344 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
318 | hdev->name, urb, -err); | 345 | hdev->name, urb, -err); |
319 | usb_unanchor_urb(urb); | 346 | usb_unanchor_urb(urb); |
320 | } | 347 | } |
@@ -403,13 +430,14 @@ static void btusb_isoc_complete(struct urb *urb) | |||
403 | 430 | ||
404 | err = usb_submit_urb(urb, GFP_ATOMIC); | 431 | err = usb_submit_urb(urb, GFP_ATOMIC); |
405 | if (err < 0) { | 432 | if (err < 0) { |
406 | BT_ERR("%s urb %p failed to resubmit (%d)", | 433 | if (err != -EPERM) |
434 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
407 | hdev->name, urb, -err); | 435 | hdev->name, urb, -err); |
408 | usb_unanchor_urb(urb); | 436 | usb_unanchor_urb(urb); |
409 | } | 437 | } |
410 | } | 438 | } |
411 | 439 | ||
412 | static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu) | 440 | static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu) |
413 | { | 441 | { |
414 | int i, offset = 0; | 442 | int i, offset = 0; |
415 | 443 | ||
@@ -666,7 +694,8 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
666 | break; | 694 | break; |
667 | 695 | ||
668 | case HCI_ACLDATA_PKT: | 696 | case HCI_ACLDATA_PKT: |
669 | if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1) | 697 | if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 && |
698 | hdev->conn_hash.le_num < 1)) | ||
670 | return -ENODEV; | 699 | return -ENODEV; |
671 | 700 | ||
672 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 701 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
@@ -693,15 +722,11 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
693 | pipe = usb_sndisocpipe(data->udev, | 722 | pipe = usb_sndisocpipe(data->udev, |
694 | data->isoc_tx_ep->bEndpointAddress); | 723 | data->isoc_tx_ep->bEndpointAddress); |
695 | 724 | ||
696 | urb->dev = data->udev; | 725 | usb_fill_int_urb(urb, data->udev, pipe, |
697 | urb->pipe = pipe; | 726 | skb->data, skb->len, btusb_isoc_tx_complete, |
698 | urb->context = skb; | 727 | skb, data->isoc_tx_ep->bInterval); |
699 | urb->complete = btusb_isoc_tx_complete; | ||
700 | urb->interval = data->isoc_tx_ep->bInterval; | ||
701 | 728 | ||
702 | urb->transfer_flags = URB_ISO_ASAP; | 729 | urb->transfer_flags = URB_ISO_ASAP; |
703 | urb->transfer_buffer = skb->data; | ||
704 | urb->transfer_buffer_length = skb->len; | ||
705 | 730 | ||
706 | __fill_isoc_descriptor(urb, skb->len, | 731 | __fill_isoc_descriptor(urb, skb->len, |
707 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); | 732 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); |
@@ -760,7 +785,7 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt) | |||
760 | } | 785 | } |
761 | } | 786 | } |
762 | 787 | ||
763 | static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting) | 788 | static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting) |
764 | { | 789 | { |
765 | struct btusb_data *data = hdev->driver_data; | 790 | struct btusb_data *data = hdev->driver_data; |
766 | struct usb_interface *intf = data->isoc; | 791 | struct usb_interface *intf = data->isoc; |
@@ -811,7 +836,7 @@ static void btusb_work(struct work_struct *work) | |||
811 | 836 | ||
812 | if (hdev->conn_hash.sco_num > 0) { | 837 | if (hdev->conn_hash.sco_num > 0) { |
813 | if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { | 838 | if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { |
814 | err = usb_autopm_get_interface(data->isoc); | 839 | err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf); |
815 | if (err < 0) { | 840 | if (err < 0) { |
816 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); | 841 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); |
817 | usb_kill_anchored_urbs(&data->isoc_anchor); | 842 | usb_kill_anchored_urbs(&data->isoc_anchor); |
@@ -840,7 +865,7 @@ static void btusb_work(struct work_struct *work) | |||
840 | 865 | ||
841 | __set_isoc_interface(hdev, 0); | 866 | __set_isoc_interface(hdev, 0); |
842 | if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) | 867 | if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) |
843 | usb_autopm_put_interface(data->isoc); | 868 | usb_autopm_put_interface(data->isoc ? data->isoc : data->intf); |
844 | } | 869 | } |
845 | } | 870 | } |
846 | 871 | ||
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c new file mode 100644 index 000000000000..65d27aff553a --- /dev/null +++ b/drivers/bluetooth/btwilink.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * Texas Instrument's Bluetooth Driver For Shared Transport. | ||
3 | * | ||
4 | * Bluetooth Driver acts as interface between HCI core and | ||
5 | * TI Shared Transport Layer. | ||
6 | * | ||
7 | * Copyright (C) 2009-2010 Texas Instruments | ||
8 | * Author: Raja Mani <raja_mani@ti.com> | ||
9 | * Pavan Savoy <pavan_savoy@ti.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | */ | ||
25 | #define DEBUG | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <net/bluetooth/bluetooth.h> | ||
28 | #include <net/bluetooth/hci_core.h> | ||
29 | #include <net/bluetooth/hci.h> | ||
30 | |||
31 | #include <linux/ti_wilink_st.h> | ||
32 | |||
33 | /* Bluetooth Driver Version */ | ||
34 | #define VERSION "1.0" | ||
35 | #define MAX_BT_CHNL_IDS 3 | ||
36 | |||
37 | /* Number of seconds to wait for registration completion | ||
38 | * when ST returns PENDING status. | ||
39 | */ | ||
40 | #define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ | ||
41 | |||
42 | /** | ||
43 | * struct ti_st - driver operation structure | ||
44 | * @hdev: hci device pointer which binds to bt driver | ||
45 | * @reg_status: ST registration callback status | ||
46 | * @st_write: write function provided by the ST driver | ||
47 | * to be used by the driver during send_frame. | ||
48 | * @wait_reg_completion - completion sync between ti_st_open | ||
49 | * and st_reg_completion_cb. | ||
50 | */ | ||
51 | struct ti_st { | ||
52 | struct hci_dev *hdev; | ||
53 | char reg_status; | ||
54 | long (*st_write) (struct sk_buff *); | ||
55 | struct completion wait_reg_completion; | ||
56 | }; | ||
57 | |||
58 | /* Increments HCI counters based on pocket ID (cmd,acl,sco) */ | ||
59 | static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) | ||
60 | { | ||
61 | struct hci_dev *hdev = hst->hdev; | ||
62 | |||
63 | /* Update HCI stat counters */ | ||
64 | switch (pkt_type) { | ||
65 | case HCI_COMMAND_PKT: | ||
66 | hdev->stat.cmd_tx++; | ||
67 | break; | ||
68 | |||
69 | case HCI_ACLDATA_PKT: | ||
70 | hdev->stat.acl_tx++; | ||
71 | break; | ||
72 | |||
73 | case HCI_SCODATA_PKT: | ||
74 | hdev->stat.sco_tx++; | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /* ------- Interfaces to Shared Transport ------ */ | ||
80 | |||
81 | /* Called by ST layer to indicate protocol registration completion | ||
82 | * status.ti_st_open() function will wait for signal from this | ||
83 | * API when st_register() function returns ST_PENDING. | ||
84 | */ | ||
85 | static void st_reg_completion_cb(void *priv_data, char data) | ||
86 | { | ||
87 | struct ti_st *lhst = priv_data; | ||
88 | |||
89 | /* Save registration status for use in ti_st_open() */ | ||
90 | lhst->reg_status = data; | ||
91 | /* complete the wait in ti_st_open() */ | ||
92 | complete(&lhst->wait_reg_completion); | ||
93 | } | ||
94 | |||
95 | /* Called by Shared Transport layer when receive data is | ||
96 | * available */ | ||
97 | static long st_receive(void *priv_data, struct sk_buff *skb) | ||
98 | { | ||
99 | struct ti_st *lhst = priv_data; | ||
100 | int err; | ||
101 | |||
102 | if (!skb) | ||
103 | return -EFAULT; | ||
104 | |||
105 | if (!lhst) { | ||
106 | kfree_skb(skb); | ||
107 | return -EFAULT; | ||
108 | } | ||
109 | |||
110 | skb->dev = (void *) lhst->hdev; | ||
111 | |||
112 | /* Forward skb to HCI core layer */ | ||
113 | err = hci_recv_frame(skb); | ||
114 | if (err < 0) { | ||
115 | BT_ERR("Unable to push skb to HCI core(%d)", err); | ||
116 | return err; | ||
117 | } | ||
118 | |||
119 | lhst->hdev->stat.byte_rx += skb->len; | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* ------- Interfaces to HCI layer ------ */ | ||
125 | /* protocol structure registered with shared transport */ | ||
126 | static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { | ||
127 | { | ||
128 | .chnl_id = HCI_ACLDATA_PKT, /* ACL */ | ||
129 | .hdr_len = sizeof(struct hci_acl_hdr), | ||
130 | .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen), | ||
131 | .len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */ | ||
132 | .reserve = 8, | ||
133 | }, | ||
134 | { | ||
135 | .chnl_id = HCI_SCODATA_PKT, /* SCO */ | ||
136 | .hdr_len = sizeof(struct hci_sco_hdr), | ||
137 | .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen), | ||
138 | .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ | ||
139 | .reserve = 8, | ||
140 | }, | ||
141 | { | ||
142 | .chnl_id = HCI_EVENT_PKT, /* HCI Events */ | ||
143 | .hdr_len = sizeof(struct hci_event_hdr), | ||
144 | .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), | ||
145 | .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ | ||
146 | .reserve = 8, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | /* Called from HCI core to initialize the device */ | ||
151 | static int ti_st_open(struct hci_dev *hdev) | ||
152 | { | ||
153 | unsigned long timeleft; | ||
154 | struct ti_st *hst; | ||
155 | int err, i; | ||
156 | |||
157 | BT_DBG("%s %p", hdev->name, hdev); | ||
158 | |||
159 | if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) | ||
160 | return -EBUSY; | ||
161 | |||
162 | /* provide contexts for callbacks from ST */ | ||
163 | hst = hdev->driver_data; | ||
164 | |||
165 | for (i = 0; i < MAX_BT_CHNL_IDS; i++) { | ||
166 | ti_st_proto[i].priv_data = hst; | ||
167 | ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE; | ||
168 | ti_st_proto[i].recv = st_receive; | ||
169 | ti_st_proto[i].reg_complete_cb = st_reg_completion_cb; | ||
170 | |||
171 | /* Prepare wait-for-completion handler */ | ||
172 | init_completion(&hst->wait_reg_completion); | ||
173 | /* Reset ST registration callback status flag, | ||
174 | * this value will be updated in | ||
175 | * st_reg_completion_cb() | ||
176 | * function whenever it called from ST driver. | ||
177 | */ | ||
178 | hst->reg_status = -EINPROGRESS; | ||
179 | |||
180 | err = st_register(&ti_st_proto[i]); | ||
181 | if (!err) | ||
182 | goto done; | ||
183 | |||
184 | if (err != -EINPROGRESS) { | ||
185 | clear_bit(HCI_RUNNING, &hdev->flags); | ||
186 | BT_ERR("st_register failed %d", err); | ||
187 | return err; | ||
188 | } | ||
189 | |||
190 | /* ST is busy with either protocol | ||
191 | * registration or firmware download. | ||
192 | */ | ||
193 | BT_DBG("waiting for registration " | ||
194 | "completion signal from ST"); | ||
195 | timeleft = wait_for_completion_timeout | ||
196 | (&hst->wait_reg_completion, | ||
197 | msecs_to_jiffies(BT_REGISTER_TIMEOUT)); | ||
198 | if (!timeleft) { | ||
199 | clear_bit(HCI_RUNNING, &hdev->flags); | ||
200 | BT_ERR("Timeout(%d sec),didn't get reg " | ||
201 | "completion signal from ST", | ||
202 | BT_REGISTER_TIMEOUT / 1000); | ||
203 | return -ETIMEDOUT; | ||
204 | } | ||
205 | |||
206 | /* Is ST registration callback | ||
207 | * called with ERROR status? */ | ||
208 | if (hst->reg_status != 0) { | ||
209 | clear_bit(HCI_RUNNING, &hdev->flags); | ||
210 | BT_ERR("ST registration completed with invalid " | ||
211 | "status %d", hst->reg_status); | ||
212 | return -EAGAIN; | ||
213 | } | ||
214 | |||
215 | done: | ||
216 | hst->st_write = ti_st_proto[i].write; | ||
217 | if (!hst->st_write) { | ||
218 | BT_ERR("undefined ST write function"); | ||
219 | clear_bit(HCI_RUNNING, &hdev->flags); | ||
220 | for (i = 0; i < MAX_BT_CHNL_IDS; i++) { | ||
221 | /* Undo registration with ST */ | ||
222 | err = st_unregister(&ti_st_proto[i]); | ||
223 | if (err) | ||
224 | BT_ERR("st_unregister() failed with " | ||
225 | "error %d", err); | ||
226 | hst->st_write = NULL; | ||
227 | } | ||
228 | return -EIO; | ||
229 | } | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | /* Close device */ | ||
235 | static int ti_st_close(struct hci_dev *hdev) | ||
236 | { | ||
237 | int err, i; | ||
238 | struct ti_st *hst = hdev->driver_data; | ||
239 | |||
240 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) | ||
241 | return 0; | ||
242 | |||
243 | for (i = 0; i < MAX_BT_CHNL_IDS; i++) { | ||
244 | err = st_unregister(&ti_st_proto[i]); | ||
245 | if (err) | ||
246 | BT_ERR("st_unregister(%d) failed with error %d", | ||
247 | ti_st_proto[i].chnl_id, err); | ||
248 | } | ||
249 | |||
250 | hst->st_write = NULL; | ||
251 | |||
252 | return err; | ||
253 | } | ||
254 | |||
255 | static int ti_st_send_frame(struct sk_buff *skb) | ||
256 | { | ||
257 | struct hci_dev *hdev; | ||
258 | struct ti_st *hst; | ||
259 | long len; | ||
260 | |||
261 | hdev = (struct hci_dev *)skb->dev; | ||
262 | |||
263 | if (!test_bit(HCI_RUNNING, &hdev->flags)) | ||
264 | return -EBUSY; | ||
265 | |||
266 | hst = hdev->driver_data; | ||
267 | |||
268 | /* Prepend skb with frame type */ | ||
269 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | ||
270 | |||
271 | BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, | ||
272 | skb->len); | ||
273 | |||
274 | /* Insert skb to shared transport layer's transmit queue. | ||
275 | * Freeing skb memory is taken care in shared transport layer, | ||
276 | * so don't free skb memory here. | ||
277 | */ | ||
278 | len = hst->st_write(skb); | ||
279 | if (len < 0) { | ||
280 | kfree_skb(skb); | ||
281 | BT_ERR("ST write failed (%ld)", len); | ||
282 | /* Try Again, would only fail if UART has gone bad */ | ||
283 | return -EAGAIN; | ||
284 | } | ||
285 | |||
286 | /* ST accepted our skb. So, Go ahead and do rest */ | ||
287 | hdev->stat.byte_tx += len; | ||
288 | ti_st_tx_complete(hst, bt_cb(skb)->pkt_type); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static void ti_st_destruct(struct hci_dev *hdev) | ||
294 | { | ||
295 | BT_DBG("%s", hdev->name); | ||
296 | /* do nothing here, since platform remove | ||
297 | * would free the hdev->driver_data | ||
298 | */ | ||
299 | } | ||
300 | |||
301 | static int bt_ti_probe(struct platform_device *pdev) | ||
302 | { | ||
303 | static struct ti_st *hst; | ||
304 | struct hci_dev *hdev; | ||
305 | int err; | ||
306 | |||
307 | hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL); | ||
308 | if (!hst) | ||
309 | return -ENOMEM; | ||
310 | |||
311 | /* Expose "hciX" device to user space */ | ||
312 | hdev = hci_alloc_dev(); | ||
313 | if (!hdev) { | ||
314 | kfree(hst); | ||
315 | return -ENOMEM; | ||
316 | } | ||
317 | |||
318 | BT_DBG("hdev %p", hdev); | ||
319 | |||
320 | hst->hdev = hdev; | ||
321 | hdev->bus = HCI_UART; | ||
322 | hdev->driver_data = hst; | ||
323 | hdev->open = ti_st_open; | ||
324 | hdev->close = ti_st_close; | ||
325 | hdev->flush = NULL; | ||
326 | hdev->send = ti_st_send_frame; | ||
327 | hdev->destruct = ti_st_destruct; | ||
328 | hdev->owner = THIS_MODULE; | ||
329 | |||
330 | err = hci_register_dev(hdev); | ||
331 | if (err < 0) { | ||
332 | BT_ERR("Can't register HCI device error %d", err); | ||
333 | kfree(hst); | ||
334 | hci_free_dev(hdev); | ||
335 | return err; | ||
336 | } | ||
337 | |||
338 | BT_DBG("HCI device registered (hdev %p)", hdev); | ||
339 | |||
340 | dev_set_drvdata(&pdev->dev, hst); | ||
341 | return err; | ||
342 | } | ||
343 | |||
344 | static int bt_ti_remove(struct platform_device *pdev) | ||
345 | { | ||
346 | struct hci_dev *hdev; | ||
347 | struct ti_st *hst = dev_get_drvdata(&pdev->dev); | ||
348 | |||
349 | if (!hst) | ||
350 | return -EFAULT; | ||
351 | |||
352 | BT_DBG("%s", hst->hdev->name); | ||
353 | |||
354 | hdev = hst->hdev; | ||
355 | ti_st_close(hdev); | ||
356 | hci_unregister_dev(hdev); | ||
357 | |||
358 | hci_free_dev(hdev); | ||
359 | kfree(hst); | ||
360 | |||
361 | dev_set_drvdata(&pdev->dev, NULL); | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static struct platform_driver btwilink_driver = { | ||
366 | .probe = bt_ti_probe, | ||
367 | .remove = bt_ti_remove, | ||
368 | .driver = { | ||
369 | .name = "btwilink", | ||
370 | .owner = THIS_MODULE, | ||
371 | }, | ||
372 | }; | ||
373 | |||
374 | /* ------- Module Init/Exit interfaces ------ */ | ||
375 | static int __init btwilink_init(void) | ||
376 | { | ||
377 | BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION); | ||
378 | |||
379 | return platform_driver_register(&btwilink_driver); | ||
380 | } | ||
381 | |||
382 | static void __exit btwilink_exit(void) | ||
383 | { | ||
384 | platform_driver_unregister(&btwilink_driver); | ||
385 | } | ||
386 | |||
387 | module_init(btwilink_init); | ||
388 | module_exit(btwilink_exit); | ||
389 | |||
390 | /* ------ Module Info ------ */ | ||
391 | |||
392 | MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>"); | ||
393 | MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); | ||
394 | MODULE_VERSION(VERSION); | ||
395 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index db7c8db695fc..5e4c2de9fc3f 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
43 | 43 | ||
44 | #include <pcmcia/cs.h> | ||
45 | #include <pcmcia/cistpl.h> | 44 | #include <pcmcia/cistpl.h> |
46 | #include <pcmcia/ciscode.h> | 45 | #include <pcmcia/ciscode.h> |
47 | #include <pcmcia/ds.h> | 46 | #include <pcmcia/ds.h> |
@@ -572,11 +571,7 @@ static int dtl1_probe(struct pcmcia_device *link) | |||
572 | info->p_dev = link; | 571 | info->p_dev = link; |
573 | link->priv = info; | 572 | link->priv = info; |
574 | 573 | ||
575 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 574 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
576 | link->resource[0]->end = 8; | ||
577 | |||
578 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
579 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
580 | 575 | ||
581 | return dtl1_config(link); | 576 | return dtl1_config(link); |
582 | } | 577 | } |
@@ -591,18 +586,14 @@ static void dtl1_detach(struct pcmcia_device *link) | |||
591 | kfree(info); | 586 | kfree(info); |
592 | } | 587 | } |
593 | 588 | ||
594 | static int dtl1_confcheck(struct pcmcia_device *p_dev, | 589 | static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) |
595 | cistpl_cftable_entry_t *cf, | ||
596 | cistpl_cftable_entry_t *dflt, | ||
597 | unsigned int vcc, | ||
598 | void *priv_data) | ||
599 | { | 590 | { |
600 | if ((cf->io.nwin != 1) || (cf->io.win[0].len <= 8)) | 591 | if ((p_dev->resource[1]->end) || (p_dev->resource[1]->end < 8)) |
601 | return -ENODEV; | 592 | return -ENODEV; |
602 | 593 | ||
603 | p_dev->resource[0]->start = cf->io.win[0].base; | 594 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
604 | p_dev->resource[0]->end = cf->io.win[0].len; /*yo */ | 595 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
605 | p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK; | 596 | |
606 | return pcmcia_request_io(p_dev); | 597 | return pcmcia_request_io(p_dev); |
607 | } | 598 | } |
608 | 599 | ||
@@ -620,7 +611,7 @@ static int dtl1_config(struct pcmcia_device *link) | |||
620 | if (i != 0) | 611 | if (i != 0) |
621 | goto failed; | 612 | goto failed; |
622 | 613 | ||
623 | i = pcmcia_request_configuration(link, &link->conf); | 614 | i = pcmcia_enable_device(link); |
624 | if (i != 0) | 615 | if (i != 0) |
625 | goto failed; | 616 | goto failed; |
626 | 617 | ||
@@ -645,7 +636,7 @@ static void dtl1_release(struct pcmcia_device *link) | |||
645 | } | 636 | } |
646 | 637 | ||
647 | 638 | ||
648 | static struct pcmcia_device_id dtl1_ids[] = { | 639 | static const struct pcmcia_device_id dtl1_ids[] = { |
649 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), | 640 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d), |
650 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82), | 641 | PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82), |
651 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), | 642 | PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), |
@@ -656,9 +647,7 @@ MODULE_DEVICE_TABLE(pcmcia, dtl1_ids); | |||
656 | 647 | ||
657 | static struct pcmcia_driver dtl1_driver = { | 648 | static struct pcmcia_driver dtl1_driver = { |
658 | .owner = THIS_MODULE, | 649 | .owner = THIS_MODULE, |
659 | .drv = { | 650 | .name = "dtl1_cs", |
660 | .name = "dtl1_cs", | ||
661 | }, | ||
662 | .probe = dtl1_probe, | 651 | .probe = dtl1_probe, |
663 | .remove = dtl1_detach, | 652 | .remove = dtl1_detach, |
664 | .id_table = dtl1_ids, | 653 | .id_table = dtl1_ids, |
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 6a160c17ea94..4093935ddf42 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c | |||
@@ -51,32 +51,32 @@ struct ath_struct { | |||
51 | 51 | ||
52 | static int ath_wakeup_ar3k(struct tty_struct *tty) | 52 | static int ath_wakeup_ar3k(struct tty_struct *tty) |
53 | { | 53 | { |
54 | struct termios settings; | 54 | struct ktermios ktermios; |
55 | int status = tty->driver->ops->tiocmget(tty, NULL); | 55 | int status = tty->driver->ops->tiocmget(tty); |
56 | 56 | ||
57 | if (status & TIOCM_CTS) | 57 | if (status & TIOCM_CTS) |
58 | return status; | 58 | return status; |
59 | 59 | ||
60 | /* Disable Automatic RTSCTS */ | 60 | /* Disable Automatic RTSCTS */ |
61 | n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); | 61 | memcpy(&ktermios, tty->termios, sizeof(ktermios)); |
62 | settings.c_cflag &= ~CRTSCTS; | 62 | ktermios.c_cflag &= ~CRTSCTS; |
63 | n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); | 63 | tty_set_termios(tty, &ktermios); |
64 | 64 | ||
65 | /* Clear RTS first */ | 65 | /* Clear RTS first */ |
66 | status = tty->driver->ops->tiocmget(tty, NULL); | 66 | status = tty->driver->ops->tiocmget(tty); |
67 | tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS); | 67 | tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS); |
68 | mdelay(20); | 68 | mdelay(20); |
69 | 69 | ||
70 | /* Set RTS, wake up board */ | 70 | /* Set RTS, wake up board */ |
71 | status = tty->driver->ops->tiocmget(tty, NULL); | 71 | status = tty->driver->ops->tiocmget(tty); |
72 | tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00); | 72 | tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00); |
73 | mdelay(20); | 73 | mdelay(20); |
74 | 74 | ||
75 | status = tty->driver->ops->tiocmget(tty, NULL); | 75 | status = tty->driver->ops->tiocmget(tty); |
76 | 76 | ||
77 | n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); | 77 | /* Disable Automatic RTSCTS */ |
78 | settings.c_cflag |= CRTSCTS; | 78 | ktermios.c_cflag |= CRTSCTS; |
79 | n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); | 79 | status = tty_set_termios(tty, &ktermios); |
80 | 80 | ||
81 | return status; | 81 | return status; |
82 | } | 82 | } |
@@ -201,8 +201,13 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu) | |||
201 | /* Recv data */ | 201 | /* Recv data */ |
202 | static int ath_recv(struct hci_uart *hu, void *data, int count) | 202 | static int ath_recv(struct hci_uart *hu, void *data, int count) |
203 | { | 203 | { |
204 | if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | 204 | int ret; |
205 | |||
206 | ret = hci_recv_stream_fragment(hu->hdev, data, count); | ||
207 | if (ret < 0) { | ||
205 | BT_ERR("Frame Reassembly Failed"); | 208 | BT_ERR("Frame Reassembly Failed"); |
209 | return ret; | ||
210 | } | ||
206 | 211 | ||
207 | return count; | 212 | return count; |
208 | } | 213 | } |
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 7b8ad93e2c36..2fcd8b387d69 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c | |||
@@ -151,8 +151,13 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
151 | /* Recv data */ | 151 | /* Recv data */ |
152 | static int h4_recv(struct hci_uart *hu, void *data, int count) | 152 | static int h4_recv(struct hci_uart *hu, void *data, int count) |
153 | { | 153 | { |
154 | if (hci_recv_stream_fragment(hu->hdev, data, count) < 0) | 154 | int ret; |
155 | |||
156 | ret = hci_recv_stream_fragment(hu->hdev, data, count); | ||
157 | if (ret < 0) { | ||
155 | BT_ERR("Frame Reassembly Failed"); | 158 | BT_ERR("Frame Reassembly Failed"); |
159 | return ret; | ||
160 | } | ||
156 | 161 | ||
157 | return count; | 162 | return count; |
158 | } | 163 | } |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 998833d93c13..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -101,7 +101,7 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) | |||
101 | break; | 101 | break; |
102 | 102 | ||
103 | case HCI_SCODATA_PKT: | 103 | case HCI_SCODATA_PKT: |
104 | hdev->stat.cmd_tx++; | 104 | hdev->stat.sco_tx++; |
105 | break; | 105 | break; |
106 | } | 106 | } |
107 | } | 107 | } |
@@ -256,9 +256,16 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
256 | 256 | ||
257 | BT_DBG("tty %p", tty); | 257 | BT_DBG("tty %p", tty); |
258 | 258 | ||
259 | /* FIXME: This btw is bogus, nothing requires the old ldisc to clear | ||
260 | the pointer */ | ||
259 | if (hu) | 261 | if (hu) |
260 | return -EEXIST; | 262 | return -EEXIST; |
261 | 263 | ||
264 | /* Error if the tty has no write op instead of leaving an exploitable | ||
265 | hole */ | ||
266 | if (tty->ops->write == NULL) | ||
267 | return -EOPNOTSUPP; | ||
268 | |||
262 | if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { | 269 | if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { |
263 | BT_ERR("Can't allocate control structure"); | 270 | BT_ERR("Can't allocate control structure"); |
264 | return -ENFILE; | 271 | return -ENFILE; |
@@ -304,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty) | |||
304 | 311 | ||
305 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { | 312 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { |
306 | hu->proto->close(hu); | 313 | hu->proto->close(hu); |
307 | hci_unregister_dev(hdev); | 314 | if (hdev) { |
308 | hci_free_dev(hdev); | 315 | hci_unregister_dev(hdev); |
316 | hci_free_dev(hdev); | ||
317 | } | ||
309 | } | 318 | } |
310 | } | 319 | } |
311 | } | 320 | } |
@@ -389,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
389 | hdev->flush = hci_uart_flush; | 398 | hdev->flush = hci_uart_flush; |
390 | hdev->send = hci_uart_send_frame; | 399 | hdev->send = hci_uart_send_frame; |
391 | hdev->destruct = hci_uart_destruct; | 400 | hdev->destruct = hci_uart_destruct; |
401 | hdev->parent = hu->tty->dev; | ||
392 | 402 | ||
393 | hdev->owner = THIS_MODULE; | 403 | hdev->owner = THIS_MODULE; |
394 | 404 | ||
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 38595e782d02..7e4b435f79f0 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c | |||
@@ -207,7 +207,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) | |||
207 | /* | 207 | /* |
208 | * This state means that both the host and the BRF chip | 208 | * This state means that both the host and the BRF chip |
209 | * have simultaneously sent a wake-up-indication packet. | 209 | * have simultaneously sent a wake-up-indication packet. |
210 | * Traditionaly, in this case, receiving a wake-up-indication | 210 | * Traditionally, in this case, receiving a wake-up-indication |
211 | * was enough and an additional wake-up-ack wasn't needed. | 211 | * was enough and an additional wake-up-ack wasn't needed. |
212 | * This has changed with the BRF6350, which does require an | 212 | * This has changed with the BRF6350, which does require an |
213 | * explicit wake-up-ack. Other BRF versions, which do not | 213 | * explicit wake-up-ack. Other BRF versions, which do not |
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 3aa7b2a54b6f..67c180c2c1e0 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -282,6 +282,7 @@ static const struct file_operations vhci_fops = { | |||
282 | .poll = vhci_poll, | 282 | .poll = vhci_poll, |
283 | .open = vhci_open, | 283 | .open = vhci_open, |
284 | .release = vhci_release, | 284 | .release = vhci_release, |
285 | .llseek = no_llseek, | ||
285 | }; | 286 | }; |
286 | 287 | ||
287 | static struct miscdevice vhci_miscdev= { | 288 | static struct miscdevice vhci_miscdev= { |