Commit 8f1e1742233cd1c3444dfc6c945a2efb2814e157
Committed by
Gustavo F. Padovan
1 parent
29b4433d99
Exists in
master
and in
7 other branches
Bluetooth: HCI devices are either BR/EDR or AMP radios
HCI transport drivers may not know what type of radio an AMP device has so only say whether they're BR/EDR or AMP devices. Signed-off-by: David Vrabel <david.vrabel@csr.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Showing 3 changed files with 5 additions and 5 deletions Inline Diff
drivers/bluetooth/btmrvl_main.c
1 | /** | 1 | /** |
2 | * Marvell Bluetooth driver | 2 | * Marvell Bluetooth driver |
3 | * | 3 | * |
4 | * Copyright (C) 2009, Marvell International Ltd. | 4 | * Copyright (C) 2009, Marvell International Ltd. |
5 | * | 5 | * |
6 | * This software file (the "File") is distributed by Marvell International | 6 | * This software file (the "File") is distributed by Marvell International |
7 | * Ltd. under the terms of the GNU General Public License Version 2, June 1991 | 7 | * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
8 | * (the "License"). You may use, redistribute and/or modify this File in | 8 | * (the "License"). You may use, redistribute and/or modify this File in |
9 | * accordance with the terms and conditions of the License, a copy of which | 9 | * accordance with the terms and conditions of the License, a copy of which |
10 | * is available by writing to the Free Software Foundation, Inc., | 10 | * is available by writing to the Free Software Foundation, Inc., |
11 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the | 11 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the |
12 | * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | 12 | * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. |
13 | * | 13 | * |
14 | * | 14 | * |
15 | * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE | 15 | * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE |
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE | 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
17 | * ARE EXPRESSLY DISCLAIMED. The License provides additional details about | 17 | * ARE EXPRESSLY DISCLAIMED. The License provides additional details about |
18 | * this warranty disclaimer. | 18 | * this warranty disclaimer. |
19 | **/ | 19 | **/ |
20 | 20 | ||
21 | #include <net/bluetooth/bluetooth.h> | 21 | #include <net/bluetooth/bluetooth.h> |
22 | #include <net/bluetooth/hci_core.h> | 22 | #include <net/bluetooth/hci_core.h> |
23 | 23 | ||
24 | #include "btmrvl_drv.h" | 24 | #include "btmrvl_drv.h" |
25 | 25 | ||
26 | #define VERSION "1.0" | 26 | #define VERSION "1.0" |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * This function is called by interface specific interrupt handler. | 29 | * This function is called by interface specific interrupt handler. |
30 | * It updates Power Save & Host Sleep states, and wakes up the main | 30 | * It updates Power Save & Host Sleep states, and wakes up the main |
31 | * thread. | 31 | * thread. |
32 | */ | 32 | */ |
33 | void btmrvl_interrupt(struct btmrvl_private *priv) | 33 | void btmrvl_interrupt(struct btmrvl_private *priv) |
34 | { | 34 | { |
35 | priv->adapter->ps_state = PS_AWAKE; | 35 | priv->adapter->ps_state = PS_AWAKE; |
36 | 36 | ||
37 | priv->adapter->wakeup_tries = 0; | 37 | priv->adapter->wakeup_tries = 0; |
38 | 38 | ||
39 | priv->adapter->int_count++; | 39 | priv->adapter->int_count++; |
40 | 40 | ||
41 | wake_up_interruptible(&priv->main_thread.wait_q); | 41 | wake_up_interruptible(&priv->main_thread.wait_q); |
42 | } | 42 | } |
43 | EXPORT_SYMBOL_GPL(btmrvl_interrupt); | 43 | EXPORT_SYMBOL_GPL(btmrvl_interrupt); |
44 | 44 | ||
45 | void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) | 45 | void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) |
46 | { | 46 | { |
47 | struct hci_event_hdr *hdr = (void *) skb->data; | 47 | struct hci_event_hdr *hdr = (void *) skb->data; |
48 | struct hci_ev_cmd_complete *ec; | 48 | struct hci_ev_cmd_complete *ec; |
49 | u16 opcode, ocf; | 49 | u16 opcode, ocf; |
50 | 50 | ||
51 | if (hdr->evt == HCI_EV_CMD_COMPLETE) { | 51 | if (hdr->evt == HCI_EV_CMD_COMPLETE) { |
52 | ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); | 52 | ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); |
53 | opcode = __le16_to_cpu(ec->opcode); | 53 | opcode = __le16_to_cpu(ec->opcode); |
54 | ocf = hci_opcode_ocf(opcode); | 54 | ocf = hci_opcode_ocf(opcode); |
55 | if (ocf == BT_CMD_MODULE_CFG_REQ && | 55 | if (ocf == BT_CMD_MODULE_CFG_REQ && |
56 | priv->btmrvl_dev.sendcmdflag) { | 56 | priv->btmrvl_dev.sendcmdflag) { |
57 | priv->btmrvl_dev.sendcmdflag = false; | 57 | priv->btmrvl_dev.sendcmdflag = false; |
58 | priv->adapter->cmd_complete = true; | 58 | priv->adapter->cmd_complete = true; |
59 | wake_up_interruptible(&priv->adapter->cmd_wait_q); | 59 | wake_up_interruptible(&priv->adapter->cmd_wait_q); |
60 | } | 60 | } |
61 | } | 61 | } |
62 | } | 62 | } |
63 | EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); | 63 | EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); |
64 | 64 | ||
65 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) | 65 | int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) |
66 | { | 66 | { |
67 | struct btmrvl_adapter *adapter = priv->adapter; | 67 | struct btmrvl_adapter *adapter = priv->adapter; |
68 | struct btmrvl_event *event; | 68 | struct btmrvl_event *event; |
69 | int ret = 0; | 69 | int ret = 0; |
70 | 70 | ||
71 | event = (struct btmrvl_event *) skb->data; | 71 | event = (struct btmrvl_event *) skb->data; |
72 | if (event->ec != 0xff) { | 72 | if (event->ec != 0xff) { |
73 | BT_DBG("Not Marvell Event=%x", event->ec); | 73 | BT_DBG("Not Marvell Event=%x", event->ec); |
74 | ret = -EINVAL; | 74 | ret = -EINVAL; |
75 | goto exit; | 75 | goto exit; |
76 | } | 76 | } |
77 | 77 | ||
78 | switch (event->data[0]) { | 78 | switch (event->data[0]) { |
79 | case BT_CMD_AUTO_SLEEP_MODE: | 79 | case BT_CMD_AUTO_SLEEP_MODE: |
80 | if (!event->data[2]) { | 80 | if (!event->data[2]) { |
81 | if (event->data[1] == BT_PS_ENABLE) | 81 | if (event->data[1] == BT_PS_ENABLE) |
82 | adapter->psmode = 1; | 82 | adapter->psmode = 1; |
83 | else | 83 | else |
84 | adapter->psmode = 0; | 84 | adapter->psmode = 0; |
85 | BT_DBG("PS Mode:%s", | 85 | BT_DBG("PS Mode:%s", |
86 | (adapter->psmode) ? "Enable" : "Disable"); | 86 | (adapter->psmode) ? "Enable" : "Disable"); |
87 | } else { | 87 | } else { |
88 | BT_DBG("PS Mode command failed"); | 88 | BT_DBG("PS Mode command failed"); |
89 | } | 89 | } |
90 | break; | 90 | break; |
91 | 91 | ||
92 | case BT_CMD_HOST_SLEEP_CONFIG: | 92 | case BT_CMD_HOST_SLEEP_CONFIG: |
93 | if (!event->data[3]) | 93 | if (!event->data[3]) |
94 | BT_DBG("gpio=%x, gap=%x", event->data[1], | 94 | BT_DBG("gpio=%x, gap=%x", event->data[1], |
95 | event->data[2]); | 95 | event->data[2]); |
96 | else | 96 | else |
97 | BT_DBG("HSCFG command failed"); | 97 | BT_DBG("HSCFG command failed"); |
98 | break; | 98 | break; |
99 | 99 | ||
100 | case BT_CMD_HOST_SLEEP_ENABLE: | 100 | case BT_CMD_HOST_SLEEP_ENABLE: |
101 | if (!event->data[1]) { | 101 | if (!event->data[1]) { |
102 | adapter->hs_state = HS_ACTIVATED; | 102 | adapter->hs_state = HS_ACTIVATED; |
103 | if (adapter->psmode) | 103 | if (adapter->psmode) |
104 | adapter->ps_state = PS_SLEEP; | 104 | adapter->ps_state = PS_SLEEP; |
105 | wake_up_interruptible(&adapter->cmd_wait_q); | 105 | wake_up_interruptible(&adapter->cmd_wait_q); |
106 | BT_DBG("HS ACTIVATED!"); | 106 | BT_DBG("HS ACTIVATED!"); |
107 | } else { | 107 | } else { |
108 | BT_DBG("HS Enable failed"); | 108 | BT_DBG("HS Enable failed"); |
109 | } | 109 | } |
110 | break; | 110 | break; |
111 | 111 | ||
112 | case BT_CMD_MODULE_CFG_REQ: | 112 | case BT_CMD_MODULE_CFG_REQ: |
113 | if (priv->btmrvl_dev.sendcmdflag && | 113 | if (priv->btmrvl_dev.sendcmdflag && |
114 | event->data[1] == MODULE_BRINGUP_REQ) { | 114 | event->data[1] == MODULE_BRINGUP_REQ) { |
115 | BT_DBG("EVENT:%s", | 115 | BT_DBG("EVENT:%s", |
116 | ((event->data[2] == MODULE_BROUGHT_UP) || | 116 | ((event->data[2] == MODULE_BROUGHT_UP) || |
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 | ||
125 | BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type); | 125 | BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type); |
126 | } else if (priv->btmrvl_dev.sendcmdflag && | 126 | } else if (priv->btmrvl_dev.sendcmdflag && |
127 | event->data[1] == MODULE_SHUTDOWN_REQ) { | 127 | event->data[1] == MODULE_SHUTDOWN_REQ) { |
128 | BT_DBG("EVENT:%s", (event->data[2]) ? | 128 | BT_DBG("EVENT:%s", (event->data[2]) ? |
129 | "Shutdown failed" : "Shutdown succeed"); | 129 | "Shutdown failed" : "Shutdown succeed"); |
130 | } else { | 130 | } else { |
131 | BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP"); | 131 | BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP"); |
132 | ret = -EINVAL; | 132 | ret = -EINVAL; |
133 | } | 133 | } |
134 | break; | 134 | break; |
135 | 135 | ||
136 | case BT_EVENT_POWER_STATE: | 136 | case BT_EVENT_POWER_STATE: |
137 | if (event->data[1] == BT_PS_SLEEP) | 137 | if (event->data[1] == BT_PS_SLEEP) |
138 | adapter->ps_state = PS_SLEEP; | 138 | adapter->ps_state = PS_SLEEP; |
139 | BT_DBG("EVENT:%s", | 139 | BT_DBG("EVENT:%s", |
140 | (adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE"); | 140 | (adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE"); |
141 | break; | 141 | break; |
142 | 142 | ||
143 | default: | 143 | default: |
144 | BT_DBG("Unknown Event=%d", event->data[0]); | 144 | BT_DBG("Unknown Event=%d", event->data[0]); |
145 | ret = -EINVAL; | 145 | ret = -EINVAL; |
146 | break; | 146 | break; |
147 | } | 147 | } |
148 | 148 | ||
149 | exit: | 149 | exit: |
150 | if (!ret) | 150 | if (!ret) |
151 | kfree_skb(skb); | 151 | kfree_skb(skb); |
152 | 152 | ||
153 | return ret; | 153 | return ret; |
154 | } | 154 | } |
155 | EXPORT_SYMBOL_GPL(btmrvl_process_event); | 155 | EXPORT_SYMBOL_GPL(btmrvl_process_event); |
156 | 156 | ||
157 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) | 157 | int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) |
158 | { | 158 | { |
159 | struct sk_buff *skb; | 159 | struct sk_buff *skb; |
160 | struct btmrvl_cmd *cmd; | 160 | struct btmrvl_cmd *cmd; |
161 | int ret = 0; | 161 | int ret = 0; |
162 | 162 | ||
163 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | 163 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); |
164 | if (skb == NULL) { | 164 | if (skb == NULL) { |
165 | BT_ERR("No free skb"); | 165 | BT_ERR("No free skb"); |
166 | return -ENOMEM; | 166 | return -ENOMEM; |
167 | } | 167 | } |
168 | 168 | ||
169 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | 169 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); |
170 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ)); | 170 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ)); |
171 | cmd->length = 1; | 171 | cmd->length = 1; |
172 | cmd->data[0] = subcmd; | 172 | cmd->data[0] = subcmd; |
173 | 173 | ||
174 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | 174 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; |
175 | 175 | ||
176 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | 176 | skb->dev = (void *) priv->btmrvl_dev.hcidev; |
177 | skb_queue_head(&priv->adapter->tx_queue, skb); | 177 | skb_queue_head(&priv->adapter->tx_queue, skb); |
178 | 178 | ||
179 | priv->btmrvl_dev.sendcmdflag = true; | 179 | priv->btmrvl_dev.sendcmdflag = true; |
180 | 180 | ||
181 | priv->adapter->cmd_complete = false; | 181 | priv->adapter->cmd_complete = false; |
182 | 182 | ||
183 | BT_DBG("Queue module cfg Command"); | 183 | BT_DBG("Queue module cfg Command"); |
184 | 184 | ||
185 | wake_up_interruptible(&priv->main_thread.wait_q); | 185 | wake_up_interruptible(&priv->main_thread.wait_q); |
186 | 186 | ||
187 | if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, | 187 | if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, |
188 | priv->adapter->cmd_complete, | 188 | priv->adapter->cmd_complete, |
189 | msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) { | 189 | msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) { |
190 | ret = -ETIMEDOUT; | 190 | ret = -ETIMEDOUT; |
191 | BT_ERR("module_cfg_cmd(%x): timeout: %d", | 191 | BT_ERR("module_cfg_cmd(%x): timeout: %d", |
192 | subcmd, priv->btmrvl_dev.sendcmdflag); | 192 | subcmd, priv->btmrvl_dev.sendcmdflag); |
193 | } | 193 | } |
194 | 194 | ||
195 | BT_DBG("module cfg Command done"); | 195 | BT_DBG("module cfg Command done"); |
196 | 196 | ||
197 | return ret; | 197 | return ret; |
198 | } | 198 | } |
199 | EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); | 199 | EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); |
200 | 200 | ||
201 | int btmrvl_enable_ps(struct btmrvl_private *priv) | 201 | int btmrvl_enable_ps(struct btmrvl_private *priv) |
202 | { | 202 | { |
203 | struct sk_buff *skb; | 203 | struct sk_buff *skb; |
204 | struct btmrvl_cmd *cmd; | 204 | struct btmrvl_cmd *cmd; |
205 | 205 | ||
206 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | 206 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); |
207 | if (skb == NULL) { | 207 | if (skb == NULL) { |
208 | BT_ERR("No free skb"); | 208 | BT_ERR("No free skb"); |
209 | return -ENOMEM; | 209 | return -ENOMEM; |
210 | } | 210 | } |
211 | 211 | ||
212 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | 212 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); |
213 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, | 213 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, |
214 | BT_CMD_AUTO_SLEEP_MODE)); | 214 | BT_CMD_AUTO_SLEEP_MODE)); |
215 | cmd->length = 1; | 215 | cmd->length = 1; |
216 | 216 | ||
217 | if (priv->btmrvl_dev.psmode) | 217 | if (priv->btmrvl_dev.psmode) |
218 | cmd->data[0] = BT_PS_ENABLE; | 218 | cmd->data[0] = BT_PS_ENABLE; |
219 | else | 219 | else |
220 | cmd->data[0] = BT_PS_DISABLE; | 220 | cmd->data[0] = BT_PS_DISABLE; |
221 | 221 | ||
222 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | 222 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; |
223 | 223 | ||
224 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | 224 | skb->dev = (void *) priv->btmrvl_dev.hcidev; |
225 | skb_queue_head(&priv->adapter->tx_queue, skb); | 225 | skb_queue_head(&priv->adapter->tx_queue, skb); |
226 | 226 | ||
227 | BT_DBG("Queue PSMODE Command:%d", cmd->data[0]); | 227 | BT_DBG("Queue PSMODE Command:%d", cmd->data[0]); |
228 | 228 | ||
229 | return 0; | 229 | return 0; |
230 | } | 230 | } |
231 | EXPORT_SYMBOL_GPL(btmrvl_enable_ps); | 231 | EXPORT_SYMBOL_GPL(btmrvl_enable_ps); |
232 | 232 | ||
233 | static int btmrvl_enable_hs(struct btmrvl_private *priv) | 233 | static int btmrvl_enable_hs(struct btmrvl_private *priv) |
234 | { | 234 | { |
235 | struct sk_buff *skb; | 235 | struct sk_buff *skb; |
236 | struct btmrvl_cmd *cmd; | 236 | struct btmrvl_cmd *cmd; |
237 | int ret = 0; | 237 | int ret = 0; |
238 | 238 | ||
239 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | 239 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); |
240 | if (skb == NULL) { | 240 | if (skb == NULL) { |
241 | BT_ERR("No free skb"); | 241 | BT_ERR("No free skb"); |
242 | return -ENOMEM; | 242 | return -ENOMEM; |
243 | } | 243 | } |
244 | 244 | ||
245 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | 245 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); |
246 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE)); | 246 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE)); |
247 | cmd->length = 0; | 247 | cmd->length = 0; |
248 | 248 | ||
249 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | 249 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; |
250 | 250 | ||
251 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | 251 | skb->dev = (void *) priv->btmrvl_dev.hcidev; |
252 | skb_queue_head(&priv->adapter->tx_queue, skb); | 252 | skb_queue_head(&priv->adapter->tx_queue, skb); |
253 | 253 | ||
254 | BT_DBG("Queue hs enable Command"); | 254 | BT_DBG("Queue hs enable Command"); |
255 | 255 | ||
256 | wake_up_interruptible(&priv->main_thread.wait_q); | 256 | wake_up_interruptible(&priv->main_thread.wait_q); |
257 | 257 | ||
258 | if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, | 258 | if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, |
259 | priv->adapter->hs_state, | 259 | priv->adapter->hs_state, |
260 | msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) { | 260 | msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) { |
261 | ret = -ETIMEDOUT; | 261 | ret = -ETIMEDOUT; |
262 | BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state, | 262 | BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state, |
263 | priv->adapter->ps_state, | 263 | priv->adapter->ps_state, |
264 | priv->adapter->wakeup_tries); | 264 | priv->adapter->wakeup_tries); |
265 | } | 265 | } |
266 | 266 | ||
267 | return ret; | 267 | return ret; |
268 | } | 268 | } |
269 | 269 | ||
270 | int btmrvl_prepare_command(struct btmrvl_private *priv) | 270 | int btmrvl_prepare_command(struct btmrvl_private *priv) |
271 | { | 271 | { |
272 | struct sk_buff *skb = NULL; | 272 | struct sk_buff *skb = NULL; |
273 | struct btmrvl_cmd *cmd; | 273 | struct btmrvl_cmd *cmd; |
274 | int ret = 0; | 274 | int ret = 0; |
275 | 275 | ||
276 | if (priv->btmrvl_dev.hscfgcmd) { | 276 | if (priv->btmrvl_dev.hscfgcmd) { |
277 | priv->btmrvl_dev.hscfgcmd = 0; | 277 | priv->btmrvl_dev.hscfgcmd = 0; |
278 | 278 | ||
279 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); | 279 | skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); |
280 | if (skb == NULL) { | 280 | if (skb == NULL) { |
281 | BT_ERR("No free skb"); | 281 | BT_ERR("No free skb"); |
282 | return -ENOMEM; | 282 | return -ENOMEM; |
283 | } | 283 | } |
284 | 284 | ||
285 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); | 285 | cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); |
286 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG)); | 286 | cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG)); |
287 | cmd->length = 2; | 287 | cmd->length = 2; |
288 | cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8; | 288 | cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8; |
289 | cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff); | 289 | cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff); |
290 | 290 | ||
291 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; | 291 | bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; |
292 | 292 | ||
293 | skb->dev = (void *) priv->btmrvl_dev.hcidev; | 293 | skb->dev = (void *) priv->btmrvl_dev.hcidev; |
294 | skb_queue_head(&priv->adapter->tx_queue, skb); | 294 | skb_queue_head(&priv->adapter->tx_queue, skb); |
295 | 295 | ||
296 | BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", | 296 | BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", |
297 | cmd->data[0], cmd->data[1]); | 297 | cmd->data[0], cmd->data[1]); |
298 | } | 298 | } |
299 | 299 | ||
300 | if (priv->btmrvl_dev.pscmd) { | 300 | if (priv->btmrvl_dev.pscmd) { |
301 | priv->btmrvl_dev.pscmd = 0; | 301 | priv->btmrvl_dev.pscmd = 0; |
302 | btmrvl_enable_ps(priv); | 302 | btmrvl_enable_ps(priv); |
303 | } | 303 | } |
304 | 304 | ||
305 | if (priv->btmrvl_dev.hscmd) { | 305 | if (priv->btmrvl_dev.hscmd) { |
306 | priv->btmrvl_dev.hscmd = 0; | 306 | priv->btmrvl_dev.hscmd = 0; |
307 | 307 | ||
308 | if (priv->btmrvl_dev.hsmode) { | 308 | if (priv->btmrvl_dev.hsmode) { |
309 | ret = btmrvl_enable_hs(priv); | 309 | ret = btmrvl_enable_hs(priv); |
310 | } else { | 310 | } else { |
311 | ret = priv->hw_wakeup_firmware(priv); | 311 | ret = priv->hw_wakeup_firmware(priv); |
312 | priv->adapter->hs_state = HS_DEACTIVATED; | 312 | priv->adapter->hs_state = HS_DEACTIVATED; |
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | return ret; | 316 | return ret; |
317 | } | 317 | } |
318 | 318 | ||
319 | static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb) | 319 | static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb) |
320 | { | 320 | { |
321 | int ret = 0; | 321 | int ret = 0; |
322 | 322 | ||
323 | if (!skb || !skb->data) | 323 | if (!skb || !skb->data) |
324 | return -EINVAL; | 324 | return -EINVAL; |
325 | 325 | ||
326 | if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) { | 326 | if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) { |
327 | BT_ERR("Tx Error: Bad skb length %d : %d", | 327 | BT_ERR("Tx Error: Bad skb length %d : %d", |
328 | skb->len, BTM_UPLD_SIZE); | 328 | skb->len, BTM_UPLD_SIZE); |
329 | return -EINVAL; | 329 | return -EINVAL; |
330 | } | 330 | } |
331 | 331 | ||
332 | if (skb_headroom(skb) < BTM_HEADER_LEN) { | 332 | if (skb_headroom(skb) < BTM_HEADER_LEN) { |
333 | struct sk_buff *tmp = skb; | 333 | struct sk_buff *tmp = skb; |
334 | 334 | ||
335 | skb = skb_realloc_headroom(skb, BTM_HEADER_LEN); | 335 | skb = skb_realloc_headroom(skb, BTM_HEADER_LEN); |
336 | if (!skb) { | 336 | if (!skb) { |
337 | BT_ERR("Tx Error: realloc_headroom failed %d", | 337 | BT_ERR("Tx Error: realloc_headroom failed %d", |
338 | BTM_HEADER_LEN); | 338 | BTM_HEADER_LEN); |
339 | skb = tmp; | 339 | skb = tmp; |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | } | 341 | } |
342 | 342 | ||
343 | kfree_skb(tmp); | 343 | kfree_skb(tmp); |
344 | } | 344 | } |
345 | 345 | ||
346 | skb_push(skb, BTM_HEADER_LEN); | 346 | skb_push(skb, BTM_HEADER_LEN); |
347 | 347 | ||
348 | /* header type: byte[3] | 348 | /* header type: byte[3] |
349 | * HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor | 349 | * HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor |
350 | * header length: byte[2][1][0] | 350 | * header length: byte[2][1][0] |
351 | */ | 351 | */ |
352 | 352 | ||
353 | skb->data[0] = (skb->len & 0x0000ff); | 353 | skb->data[0] = (skb->len & 0x0000ff); |
354 | skb->data[1] = (skb->len & 0x00ff00) >> 8; | 354 | skb->data[1] = (skb->len & 0x00ff00) >> 8; |
355 | skb->data[2] = (skb->len & 0xff0000) >> 16; | 355 | skb->data[2] = (skb->len & 0xff0000) >> 16; |
356 | skb->data[3] = bt_cb(skb)->pkt_type; | 356 | skb->data[3] = bt_cb(skb)->pkt_type; |
357 | 357 | ||
358 | if (priv->hw_host_to_card) | 358 | if (priv->hw_host_to_card) |
359 | ret = priv->hw_host_to_card(priv, skb->data, skb->len); | 359 | ret = priv->hw_host_to_card(priv, skb->data, skb->len); |
360 | 360 | ||
361 | return ret; | 361 | return ret; |
362 | } | 362 | } |
363 | 363 | ||
364 | static void btmrvl_init_adapter(struct btmrvl_private *priv) | 364 | static void btmrvl_init_adapter(struct btmrvl_private *priv) |
365 | { | 365 | { |
366 | skb_queue_head_init(&priv->adapter->tx_queue); | 366 | skb_queue_head_init(&priv->adapter->tx_queue); |
367 | 367 | ||
368 | priv->adapter->ps_state = PS_AWAKE; | 368 | priv->adapter->ps_state = PS_AWAKE; |
369 | 369 | ||
370 | init_waitqueue_head(&priv->adapter->cmd_wait_q); | 370 | init_waitqueue_head(&priv->adapter->cmd_wait_q); |
371 | } | 371 | } |
372 | 372 | ||
373 | static void btmrvl_free_adapter(struct btmrvl_private *priv) | 373 | static void btmrvl_free_adapter(struct btmrvl_private *priv) |
374 | { | 374 | { |
375 | skb_queue_purge(&priv->adapter->tx_queue); | 375 | skb_queue_purge(&priv->adapter->tx_queue); |
376 | 376 | ||
377 | kfree(priv->adapter); | 377 | kfree(priv->adapter); |
378 | 378 | ||
379 | priv->adapter = NULL; | 379 | priv->adapter = NULL; |
380 | } | 380 | } |
381 | 381 | ||
382 | static int btmrvl_ioctl(struct hci_dev *hdev, | 382 | static int btmrvl_ioctl(struct hci_dev *hdev, |
383 | unsigned int cmd, unsigned long arg) | 383 | unsigned int cmd, unsigned long arg) |
384 | { | 384 | { |
385 | return -ENOIOCTLCMD; | 385 | return -ENOIOCTLCMD; |
386 | } | 386 | } |
387 | 387 | ||
388 | static void btmrvl_destruct(struct hci_dev *hdev) | 388 | static void btmrvl_destruct(struct hci_dev *hdev) |
389 | { | 389 | { |
390 | } | 390 | } |
391 | 391 | ||
392 | static int btmrvl_send_frame(struct sk_buff *skb) | 392 | static int btmrvl_send_frame(struct sk_buff *skb) |
393 | { | 393 | { |
394 | struct hci_dev *hdev = (struct hci_dev *) skb->dev; | 394 | struct hci_dev *hdev = (struct hci_dev *) skb->dev; |
395 | struct btmrvl_private *priv = NULL; | 395 | struct btmrvl_private *priv = NULL; |
396 | 396 | ||
397 | BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len); | 397 | BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len); |
398 | 398 | ||
399 | if (!hdev || !hdev->driver_data) { | 399 | if (!hdev || !hdev->driver_data) { |
400 | BT_ERR("Frame for unknown HCI device"); | 400 | BT_ERR("Frame for unknown HCI device"); |
401 | return -ENODEV; | 401 | return -ENODEV; |
402 | } | 402 | } |
403 | 403 | ||
404 | priv = (struct btmrvl_private *) hdev->driver_data; | 404 | priv = (struct btmrvl_private *) hdev->driver_data; |
405 | if (!test_bit(HCI_RUNNING, &hdev->flags)) { | 405 | if (!test_bit(HCI_RUNNING, &hdev->flags)) { |
406 | BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags); | 406 | BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags); |
407 | print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET, | 407 | print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET, |
408 | skb->data, skb->len); | 408 | skb->data, skb->len); |
409 | return -EBUSY; | 409 | return -EBUSY; |
410 | } | 410 | } |
411 | 411 | ||
412 | switch (bt_cb(skb)->pkt_type) { | 412 | switch (bt_cb(skb)->pkt_type) { |
413 | case HCI_COMMAND_PKT: | 413 | case HCI_COMMAND_PKT: |
414 | hdev->stat.cmd_tx++; | 414 | hdev->stat.cmd_tx++; |
415 | break; | 415 | break; |
416 | 416 | ||
417 | case HCI_ACLDATA_PKT: | 417 | case HCI_ACLDATA_PKT: |
418 | hdev->stat.acl_tx++; | 418 | hdev->stat.acl_tx++; |
419 | break; | 419 | break; |
420 | 420 | ||
421 | case HCI_SCODATA_PKT: | 421 | case HCI_SCODATA_PKT: |
422 | hdev->stat.sco_tx++; | 422 | hdev->stat.sco_tx++; |
423 | break; | 423 | break; |
424 | } | 424 | } |
425 | 425 | ||
426 | skb_queue_tail(&priv->adapter->tx_queue, skb); | 426 | skb_queue_tail(&priv->adapter->tx_queue, skb); |
427 | 427 | ||
428 | wake_up_interruptible(&priv->main_thread.wait_q); | 428 | wake_up_interruptible(&priv->main_thread.wait_q); |
429 | 429 | ||
430 | return 0; | 430 | return 0; |
431 | } | 431 | } |
432 | 432 | ||
433 | static int btmrvl_flush(struct hci_dev *hdev) | 433 | static int btmrvl_flush(struct hci_dev *hdev) |
434 | { | 434 | { |
435 | struct btmrvl_private *priv = hdev->driver_data; | 435 | struct btmrvl_private *priv = hdev->driver_data; |
436 | 436 | ||
437 | skb_queue_purge(&priv->adapter->tx_queue); | 437 | skb_queue_purge(&priv->adapter->tx_queue); |
438 | 438 | ||
439 | return 0; | 439 | return 0; |
440 | } | 440 | } |
441 | 441 | ||
442 | static int btmrvl_close(struct hci_dev *hdev) | 442 | static int btmrvl_close(struct hci_dev *hdev) |
443 | { | 443 | { |
444 | struct btmrvl_private *priv = hdev->driver_data; | 444 | struct btmrvl_private *priv = hdev->driver_data; |
445 | 445 | ||
446 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) | 446 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) |
447 | return 0; | 447 | return 0; |
448 | 448 | ||
449 | skb_queue_purge(&priv->adapter->tx_queue); | 449 | skb_queue_purge(&priv->adapter->tx_queue); |
450 | 450 | ||
451 | return 0; | 451 | return 0; |
452 | } | 452 | } |
453 | 453 | ||
454 | static int btmrvl_open(struct hci_dev *hdev) | 454 | static int btmrvl_open(struct hci_dev *hdev) |
455 | { | 455 | { |
456 | set_bit(HCI_RUNNING, &hdev->flags); | 456 | set_bit(HCI_RUNNING, &hdev->flags); |
457 | 457 | ||
458 | return 0; | 458 | return 0; |
459 | } | 459 | } |
460 | 460 | ||
461 | /* | 461 | /* |
462 | * This function handles the event generated by firmware, rx data | 462 | * This function handles the event generated by firmware, rx data |
463 | * received from firmware, and tx data sent from kernel. | 463 | * received from firmware, and tx data sent from kernel. |
464 | */ | 464 | */ |
465 | static int btmrvl_service_main_thread(void *data) | 465 | static int btmrvl_service_main_thread(void *data) |
466 | { | 466 | { |
467 | struct btmrvl_thread *thread = data; | 467 | struct btmrvl_thread *thread = data; |
468 | struct btmrvl_private *priv = thread->priv; | 468 | struct btmrvl_private *priv = thread->priv; |
469 | struct btmrvl_adapter *adapter = priv->adapter; | 469 | struct btmrvl_adapter *adapter = priv->adapter; |
470 | wait_queue_t wait; | 470 | wait_queue_t wait; |
471 | struct sk_buff *skb; | 471 | struct sk_buff *skb; |
472 | ulong flags; | 472 | ulong flags; |
473 | 473 | ||
474 | init_waitqueue_entry(&wait, current); | 474 | init_waitqueue_entry(&wait, current); |
475 | 475 | ||
476 | current->flags |= PF_NOFREEZE; | 476 | current->flags |= PF_NOFREEZE; |
477 | 477 | ||
478 | for (;;) { | 478 | for (;;) { |
479 | add_wait_queue(&thread->wait_q, &wait); | 479 | add_wait_queue(&thread->wait_q, &wait); |
480 | 480 | ||
481 | set_current_state(TASK_INTERRUPTIBLE); | 481 | set_current_state(TASK_INTERRUPTIBLE); |
482 | 482 | ||
483 | if (adapter->wakeup_tries || | 483 | if (adapter->wakeup_tries || |
484 | ((!adapter->int_count) && | 484 | ((!adapter->int_count) && |
485 | (!priv->btmrvl_dev.tx_dnld_rdy || | 485 | (!priv->btmrvl_dev.tx_dnld_rdy || |
486 | skb_queue_empty(&adapter->tx_queue)))) { | 486 | skb_queue_empty(&adapter->tx_queue)))) { |
487 | BT_DBG("main_thread is sleeping..."); | 487 | BT_DBG("main_thread is sleeping..."); |
488 | schedule(); | 488 | schedule(); |
489 | } | 489 | } |
490 | 490 | ||
491 | set_current_state(TASK_RUNNING); | 491 | set_current_state(TASK_RUNNING); |
492 | 492 | ||
493 | remove_wait_queue(&thread->wait_q, &wait); | 493 | remove_wait_queue(&thread->wait_q, &wait); |
494 | 494 | ||
495 | BT_DBG("main_thread woke up"); | 495 | BT_DBG("main_thread woke up"); |
496 | 496 | ||
497 | if (kthread_should_stop()) { | 497 | if (kthread_should_stop()) { |
498 | BT_DBG("main_thread: break from main thread"); | 498 | BT_DBG("main_thread: break from main thread"); |
499 | break; | 499 | break; |
500 | } | 500 | } |
501 | 501 | ||
502 | spin_lock_irqsave(&priv->driver_lock, flags); | 502 | spin_lock_irqsave(&priv->driver_lock, flags); |
503 | if (adapter->int_count) { | 503 | if (adapter->int_count) { |
504 | adapter->int_count = 0; | 504 | adapter->int_count = 0; |
505 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 505 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
506 | priv->hw_process_int_status(priv); | 506 | priv->hw_process_int_status(priv); |
507 | } else if (adapter->ps_state == PS_SLEEP && | 507 | } else if (adapter->ps_state == PS_SLEEP && |
508 | !skb_queue_empty(&adapter->tx_queue)) { | 508 | !skb_queue_empty(&adapter->tx_queue)) { |
509 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 509 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
510 | adapter->wakeup_tries++; | 510 | adapter->wakeup_tries++; |
511 | priv->hw_wakeup_firmware(priv); | 511 | priv->hw_wakeup_firmware(priv); |
512 | continue; | 512 | continue; |
513 | } else { | 513 | } else { |
514 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 514 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
515 | } | 515 | } |
516 | 516 | ||
517 | if (adapter->ps_state == PS_SLEEP) | 517 | if (adapter->ps_state == PS_SLEEP) |
518 | continue; | 518 | continue; |
519 | 519 | ||
520 | if (!priv->btmrvl_dev.tx_dnld_rdy) | 520 | if (!priv->btmrvl_dev.tx_dnld_rdy) |
521 | continue; | 521 | continue; |
522 | 522 | ||
523 | skb = skb_dequeue(&adapter->tx_queue); | 523 | skb = skb_dequeue(&adapter->tx_queue); |
524 | if (skb) { | 524 | if (skb) { |
525 | if (btmrvl_tx_pkt(priv, skb)) | 525 | if (btmrvl_tx_pkt(priv, skb)) |
526 | priv->btmrvl_dev.hcidev->stat.err_tx++; | 526 | priv->btmrvl_dev.hcidev->stat.err_tx++; |
527 | else | 527 | else |
528 | priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len; | 528 | priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len; |
529 | 529 | ||
530 | kfree_skb(skb); | 530 | kfree_skb(skb); |
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
534 | return 0; | 534 | return 0; |
535 | } | 535 | } |
536 | 536 | ||
537 | int btmrvl_register_hdev(struct btmrvl_private *priv) | 537 | int btmrvl_register_hdev(struct btmrvl_private *priv) |
538 | { | 538 | { |
539 | struct hci_dev *hdev = NULL; | 539 | struct hci_dev *hdev = NULL; |
540 | int ret; | 540 | int ret; |
541 | 541 | ||
542 | hdev = hci_alloc_dev(); | 542 | hdev = hci_alloc_dev(); |
543 | if (!hdev) { | 543 | if (!hdev) { |
544 | BT_ERR("Can not allocate HCI device"); | 544 | BT_ERR("Can not allocate HCI device"); |
545 | goto err_hdev; | 545 | goto err_hdev; |
546 | } | 546 | } |
547 | 547 | ||
548 | priv->btmrvl_dev.hcidev = hdev; | 548 | priv->btmrvl_dev.hcidev = hdev; |
549 | hdev->driver_data = priv; | 549 | hdev->driver_data = priv; |
550 | 550 | ||
551 | hdev->bus = HCI_SDIO; | 551 | hdev->bus = HCI_SDIO; |
552 | hdev->open = btmrvl_open; | 552 | hdev->open = btmrvl_open; |
553 | hdev->close = btmrvl_close; | 553 | hdev->close = btmrvl_close; |
554 | hdev->flush = btmrvl_flush; | 554 | hdev->flush = btmrvl_flush; |
555 | hdev->send = btmrvl_send_frame; | 555 | hdev->send = btmrvl_send_frame; |
556 | hdev->destruct = btmrvl_destruct; | 556 | hdev->destruct = btmrvl_destruct; |
557 | hdev->ioctl = btmrvl_ioctl; | 557 | hdev->ioctl = btmrvl_ioctl; |
558 | hdev->owner = THIS_MODULE; | 558 | hdev->owner = THIS_MODULE; |
559 | 559 | ||
560 | btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); | 560 | btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); |
561 | 561 | ||
562 | hdev->dev_type = priv->btmrvl_dev.dev_type; | 562 | hdev->dev_type = priv->btmrvl_dev.dev_type; |
563 | 563 | ||
564 | ret = hci_register_dev(hdev); | 564 | ret = hci_register_dev(hdev); |
565 | if (ret < 0) { | 565 | if (ret < 0) { |
566 | BT_ERR("Can not register HCI device"); | 566 | BT_ERR("Can not register HCI device"); |
567 | goto err_hci_register_dev; | 567 | goto err_hci_register_dev; |
568 | } | 568 | } |
569 | 569 | ||
570 | #ifdef CONFIG_DEBUG_FS | 570 | #ifdef CONFIG_DEBUG_FS |
571 | btmrvl_debugfs_init(hdev); | 571 | btmrvl_debugfs_init(hdev); |
572 | #endif | 572 | #endif |
573 | 573 | ||
574 | return 0; | 574 | return 0; |
575 | 575 | ||
576 | err_hci_register_dev: | 576 | err_hci_register_dev: |
577 | hci_free_dev(hdev); | 577 | hci_free_dev(hdev); |
578 | 578 | ||
579 | err_hdev: | 579 | err_hdev: |
580 | /* Stop the thread servicing the interrupts */ | 580 | /* Stop the thread servicing the interrupts */ |
581 | kthread_stop(priv->main_thread.task); | 581 | kthread_stop(priv->main_thread.task); |
582 | 582 | ||
583 | btmrvl_free_adapter(priv); | 583 | btmrvl_free_adapter(priv); |
584 | kfree(priv); | 584 | kfree(priv); |
585 | 585 | ||
586 | return -ENOMEM; | 586 | return -ENOMEM; |
587 | } | 587 | } |
588 | EXPORT_SYMBOL_GPL(btmrvl_register_hdev); | 588 | EXPORT_SYMBOL_GPL(btmrvl_register_hdev); |
589 | 589 | ||
590 | struct btmrvl_private *btmrvl_add_card(void *card) | 590 | struct btmrvl_private *btmrvl_add_card(void *card) |
591 | { | 591 | { |
592 | struct btmrvl_private *priv; | 592 | struct btmrvl_private *priv; |
593 | 593 | ||
594 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 594 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
595 | if (!priv) { | 595 | if (!priv) { |
596 | BT_ERR("Can not allocate priv"); | 596 | BT_ERR("Can not allocate priv"); |
597 | goto err_priv; | 597 | goto err_priv; |
598 | } | 598 | } |
599 | 599 | ||
600 | priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL); | 600 | priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL); |
601 | if (!priv->adapter) { | 601 | if (!priv->adapter) { |
602 | BT_ERR("Allocate buffer for btmrvl_adapter failed!"); | 602 | BT_ERR("Allocate buffer for btmrvl_adapter failed!"); |
603 | goto err_adapter; | 603 | goto err_adapter; |
604 | } | 604 | } |
605 | 605 | ||
606 | btmrvl_init_adapter(priv); | 606 | btmrvl_init_adapter(priv); |
607 | 607 | ||
608 | BT_DBG("Starting kthread..."); | 608 | BT_DBG("Starting kthread..."); |
609 | priv->main_thread.priv = priv; | 609 | priv->main_thread.priv = priv; |
610 | spin_lock_init(&priv->driver_lock); | 610 | spin_lock_init(&priv->driver_lock); |
611 | 611 | ||
612 | init_waitqueue_head(&priv->main_thread.wait_q); | 612 | init_waitqueue_head(&priv->main_thread.wait_q); |
613 | priv->main_thread.task = kthread_run(btmrvl_service_main_thread, | 613 | priv->main_thread.task = kthread_run(btmrvl_service_main_thread, |
614 | &priv->main_thread, "btmrvl_main_service"); | 614 | &priv->main_thread, "btmrvl_main_service"); |
615 | 615 | ||
616 | priv->btmrvl_dev.card = card; | 616 | priv->btmrvl_dev.card = card; |
617 | priv->btmrvl_dev.tx_dnld_rdy = true; | 617 | priv->btmrvl_dev.tx_dnld_rdy = true; |
618 | 618 | ||
619 | return priv; | 619 | return priv; |
620 | 620 | ||
621 | err_adapter: | 621 | err_adapter: |
622 | kfree(priv); | 622 | kfree(priv); |
623 | 623 | ||
624 | err_priv: | 624 | err_priv: |
625 | return NULL; | 625 | return NULL; |
626 | } | 626 | } |
627 | EXPORT_SYMBOL_GPL(btmrvl_add_card); | 627 | EXPORT_SYMBOL_GPL(btmrvl_add_card); |
628 | 628 | ||
629 | int btmrvl_remove_card(struct btmrvl_private *priv) | 629 | int btmrvl_remove_card(struct btmrvl_private *priv) |
630 | { | 630 | { |
631 | struct hci_dev *hdev; | 631 | struct hci_dev *hdev; |
632 | 632 | ||
633 | hdev = priv->btmrvl_dev.hcidev; | 633 | hdev = priv->btmrvl_dev.hcidev; |
634 | 634 | ||
635 | wake_up_interruptible(&priv->adapter->cmd_wait_q); | 635 | wake_up_interruptible(&priv->adapter->cmd_wait_q); |
636 | 636 | ||
637 | kthread_stop(priv->main_thread.task); | 637 | kthread_stop(priv->main_thread.task); |
638 | 638 | ||
639 | #ifdef CONFIG_DEBUG_FS | 639 | #ifdef CONFIG_DEBUG_FS |
640 | btmrvl_debugfs_remove(hdev); | 640 | btmrvl_debugfs_remove(hdev); |
641 | #endif | 641 | #endif |
642 | 642 | ||
643 | hci_unregister_dev(hdev); | 643 | hci_unregister_dev(hdev); |
644 | 644 | ||
645 | hci_free_dev(hdev); | 645 | hci_free_dev(hdev); |
646 | 646 | ||
647 | priv->btmrvl_dev.hcidev = NULL; | 647 | priv->btmrvl_dev.hcidev = NULL; |
648 | 648 | ||
649 | btmrvl_free_adapter(priv); | 649 | btmrvl_free_adapter(priv); |
650 | 650 | ||
651 | kfree(priv); | 651 | kfree(priv); |
652 | 652 | ||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | EXPORT_SYMBOL_GPL(btmrvl_remove_card); | 655 | EXPORT_SYMBOL_GPL(btmrvl_remove_card); |
656 | 656 | ||
657 | MODULE_AUTHOR("Marvell International Ltd."); | 657 | MODULE_AUTHOR("Marvell International Ltd."); |
658 | MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION); | 658 | MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION); |
659 | MODULE_VERSION(VERSION); | 659 | MODULE_VERSION(VERSION); |
660 | MODULE_LICENSE("GPL v2"); | 660 | MODULE_LICENSE("GPL v2"); |
661 | 661 |
include/net/bluetooth/hci.h
1 | /* | 1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux | 2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | 4 | ||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | 6 | ||
7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License version 2 as | 8 | it under the terms of the GNU General Public License version 2 as |
9 | published by the Free Software Foundation; | 9 | published by the Free Software Foundation; |
10 | 10 | ||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 12 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. |
14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | 14 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY |
15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | 15 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES |
16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 16 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 17 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 18 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
19 | 19 | ||
20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | 20 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, |
21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | 21 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS |
22 | SOFTWARE IS DISCLAIMED. | 22 | SOFTWARE IS DISCLAIMED. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifndef __HCI_H | 25 | #ifndef __HCI_H |
26 | #define __HCI_H | 26 | #define __HCI_H |
27 | 27 | ||
28 | #define HCI_MAX_ACL_SIZE 1024 | 28 | #define HCI_MAX_ACL_SIZE 1024 |
29 | #define HCI_MAX_SCO_SIZE 255 | 29 | #define HCI_MAX_SCO_SIZE 255 |
30 | #define HCI_MAX_EVENT_SIZE 260 | 30 | #define HCI_MAX_EVENT_SIZE 260 |
31 | #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) | 31 | #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) |
32 | 32 | ||
33 | /* HCI dev events */ | 33 | /* HCI dev events */ |
34 | #define HCI_DEV_REG 1 | 34 | #define HCI_DEV_REG 1 |
35 | #define HCI_DEV_UNREG 2 | 35 | #define HCI_DEV_UNREG 2 |
36 | #define HCI_DEV_UP 3 | 36 | #define HCI_DEV_UP 3 |
37 | #define HCI_DEV_DOWN 4 | 37 | #define HCI_DEV_DOWN 4 |
38 | #define HCI_DEV_SUSPEND 5 | 38 | #define HCI_DEV_SUSPEND 5 |
39 | #define HCI_DEV_RESUME 6 | 39 | #define HCI_DEV_RESUME 6 |
40 | 40 | ||
41 | /* HCI notify events */ | 41 | /* HCI notify events */ |
42 | #define HCI_NOTIFY_CONN_ADD 1 | 42 | #define HCI_NOTIFY_CONN_ADD 1 |
43 | #define HCI_NOTIFY_CONN_DEL 2 | 43 | #define HCI_NOTIFY_CONN_DEL 2 |
44 | #define HCI_NOTIFY_VOICE_SETTING 3 | 44 | #define HCI_NOTIFY_VOICE_SETTING 3 |
45 | 45 | ||
46 | /* HCI bus types */ | 46 | /* HCI bus types */ |
47 | #define HCI_VIRTUAL 0 | 47 | #define HCI_VIRTUAL 0 |
48 | #define HCI_USB 1 | 48 | #define HCI_USB 1 |
49 | #define HCI_PCCARD 2 | 49 | #define HCI_PCCARD 2 |
50 | #define HCI_UART 3 | 50 | #define HCI_UART 3 |
51 | #define HCI_RS232 4 | 51 | #define HCI_RS232 4 |
52 | #define HCI_PCI 5 | 52 | #define HCI_PCI 5 |
53 | #define HCI_SDIO 6 | 53 | #define HCI_SDIO 6 |
54 | 54 | ||
55 | /* HCI controller types */ | 55 | /* HCI controller types */ |
56 | #define HCI_BREDR 0x00 | 56 | #define HCI_BREDR 0x00 |
57 | #define HCI_80211 0x01 | 57 | #define HCI_AMP 0x01 |
58 | 58 | ||
59 | /* HCI device quirks */ | 59 | /* HCI device quirks */ |
60 | enum { | 60 | enum { |
61 | HCI_QUIRK_NO_RESET, | 61 | HCI_QUIRK_NO_RESET, |
62 | HCI_QUIRK_RAW_DEVICE, | 62 | HCI_QUIRK_RAW_DEVICE, |
63 | HCI_QUIRK_FIXUP_BUFFER_SIZE | 63 | HCI_QUIRK_FIXUP_BUFFER_SIZE |
64 | }; | 64 | }; |
65 | 65 | ||
66 | /* HCI device flags */ | 66 | /* HCI device flags */ |
67 | enum { | 67 | enum { |
68 | HCI_UP, | 68 | HCI_UP, |
69 | HCI_INIT, | 69 | HCI_INIT, |
70 | HCI_RUNNING, | 70 | HCI_RUNNING, |
71 | 71 | ||
72 | HCI_PSCAN, | 72 | HCI_PSCAN, |
73 | HCI_ISCAN, | 73 | HCI_ISCAN, |
74 | HCI_AUTH, | 74 | HCI_AUTH, |
75 | HCI_ENCRYPT, | 75 | HCI_ENCRYPT, |
76 | HCI_INQUIRY, | 76 | HCI_INQUIRY, |
77 | 77 | ||
78 | HCI_RAW, | 78 | HCI_RAW, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* HCI ioctl defines */ | 81 | /* HCI ioctl defines */ |
82 | #define HCIDEVUP _IOW('H', 201, int) | 82 | #define HCIDEVUP _IOW('H', 201, int) |
83 | #define HCIDEVDOWN _IOW('H', 202, int) | 83 | #define HCIDEVDOWN _IOW('H', 202, int) |
84 | #define HCIDEVRESET _IOW('H', 203, int) | 84 | #define HCIDEVRESET _IOW('H', 203, int) |
85 | #define HCIDEVRESTAT _IOW('H', 204, int) | 85 | #define HCIDEVRESTAT _IOW('H', 204, int) |
86 | 86 | ||
87 | #define HCIGETDEVLIST _IOR('H', 210, int) | 87 | #define HCIGETDEVLIST _IOR('H', 210, int) |
88 | #define HCIGETDEVINFO _IOR('H', 211, int) | 88 | #define HCIGETDEVINFO _IOR('H', 211, int) |
89 | #define HCIGETCONNLIST _IOR('H', 212, int) | 89 | #define HCIGETCONNLIST _IOR('H', 212, int) |
90 | #define HCIGETCONNINFO _IOR('H', 213, int) | 90 | #define HCIGETCONNINFO _IOR('H', 213, int) |
91 | #define HCIGETAUTHINFO _IOR('H', 215, int) | 91 | #define HCIGETAUTHINFO _IOR('H', 215, int) |
92 | 92 | ||
93 | #define HCISETRAW _IOW('H', 220, int) | 93 | #define HCISETRAW _IOW('H', 220, int) |
94 | #define HCISETSCAN _IOW('H', 221, int) | 94 | #define HCISETSCAN _IOW('H', 221, int) |
95 | #define HCISETAUTH _IOW('H', 222, int) | 95 | #define HCISETAUTH _IOW('H', 222, int) |
96 | #define HCISETENCRYPT _IOW('H', 223, int) | 96 | #define HCISETENCRYPT _IOW('H', 223, int) |
97 | #define HCISETPTYPE _IOW('H', 224, int) | 97 | #define HCISETPTYPE _IOW('H', 224, int) |
98 | #define HCISETLINKPOL _IOW('H', 225, int) | 98 | #define HCISETLINKPOL _IOW('H', 225, int) |
99 | #define HCISETLINKMODE _IOW('H', 226, int) | 99 | #define HCISETLINKMODE _IOW('H', 226, int) |
100 | #define HCISETACLMTU _IOW('H', 227, int) | 100 | #define HCISETACLMTU _IOW('H', 227, int) |
101 | #define HCISETSCOMTU _IOW('H', 228, int) | 101 | #define HCISETSCOMTU _IOW('H', 228, int) |
102 | 102 | ||
103 | #define HCIBLOCKADDR _IOW('H', 230, int) | 103 | #define HCIBLOCKADDR _IOW('H', 230, int) |
104 | #define HCIUNBLOCKADDR _IOW('H', 231, int) | 104 | #define HCIUNBLOCKADDR _IOW('H', 231, int) |
105 | 105 | ||
106 | #define HCIINQUIRY _IOR('H', 240, int) | 106 | #define HCIINQUIRY _IOR('H', 240, int) |
107 | 107 | ||
108 | /* HCI timeouts */ | 108 | /* HCI timeouts */ |
109 | #define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ | 109 | #define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ |
110 | #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ | 110 | #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ |
111 | #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ | 111 | #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ |
112 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ | 112 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ |
113 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ | 113 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ |
114 | 114 | ||
115 | /* HCI data types */ | 115 | /* HCI data types */ |
116 | #define HCI_COMMAND_PKT 0x01 | 116 | #define HCI_COMMAND_PKT 0x01 |
117 | #define HCI_ACLDATA_PKT 0x02 | 117 | #define HCI_ACLDATA_PKT 0x02 |
118 | #define HCI_SCODATA_PKT 0x03 | 118 | #define HCI_SCODATA_PKT 0x03 |
119 | #define HCI_EVENT_PKT 0x04 | 119 | #define HCI_EVENT_PKT 0x04 |
120 | #define HCI_VENDOR_PKT 0xff | 120 | #define HCI_VENDOR_PKT 0xff |
121 | 121 | ||
122 | /* HCI packet types */ | 122 | /* HCI packet types */ |
123 | #define HCI_DM1 0x0008 | 123 | #define HCI_DM1 0x0008 |
124 | #define HCI_DM3 0x0400 | 124 | #define HCI_DM3 0x0400 |
125 | #define HCI_DM5 0x4000 | 125 | #define HCI_DM5 0x4000 |
126 | #define HCI_DH1 0x0010 | 126 | #define HCI_DH1 0x0010 |
127 | #define HCI_DH3 0x0800 | 127 | #define HCI_DH3 0x0800 |
128 | #define HCI_DH5 0x8000 | 128 | #define HCI_DH5 0x8000 |
129 | 129 | ||
130 | #define HCI_HV1 0x0020 | 130 | #define HCI_HV1 0x0020 |
131 | #define HCI_HV2 0x0040 | 131 | #define HCI_HV2 0x0040 |
132 | #define HCI_HV3 0x0080 | 132 | #define HCI_HV3 0x0080 |
133 | 133 | ||
134 | #define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) | 134 | #define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3) |
135 | #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) | 135 | #define ACL_PTYPE_MASK (~SCO_PTYPE_MASK) |
136 | 136 | ||
137 | /* eSCO packet types */ | 137 | /* eSCO packet types */ |
138 | #define ESCO_HV1 0x0001 | 138 | #define ESCO_HV1 0x0001 |
139 | #define ESCO_HV2 0x0002 | 139 | #define ESCO_HV2 0x0002 |
140 | #define ESCO_HV3 0x0004 | 140 | #define ESCO_HV3 0x0004 |
141 | #define ESCO_EV3 0x0008 | 141 | #define ESCO_EV3 0x0008 |
142 | #define ESCO_EV4 0x0010 | 142 | #define ESCO_EV4 0x0010 |
143 | #define ESCO_EV5 0x0020 | 143 | #define ESCO_EV5 0x0020 |
144 | #define ESCO_2EV3 0x0040 | 144 | #define ESCO_2EV3 0x0040 |
145 | #define ESCO_3EV3 0x0080 | 145 | #define ESCO_3EV3 0x0080 |
146 | #define ESCO_2EV5 0x0100 | 146 | #define ESCO_2EV5 0x0100 |
147 | #define ESCO_3EV5 0x0200 | 147 | #define ESCO_3EV5 0x0200 |
148 | 148 | ||
149 | #define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) | 149 | #define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) |
150 | #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) | 150 | #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) |
151 | 151 | ||
152 | /* ACL flags */ | 152 | /* ACL flags */ |
153 | #define ACL_CONT 0x01 | 153 | #define ACL_CONT 0x01 |
154 | #define ACL_START 0x02 | 154 | #define ACL_START 0x02 |
155 | #define ACL_ACTIVE_BCAST 0x04 | 155 | #define ACL_ACTIVE_BCAST 0x04 |
156 | #define ACL_PICO_BCAST 0x08 | 156 | #define ACL_PICO_BCAST 0x08 |
157 | 157 | ||
158 | /* Baseband links */ | 158 | /* Baseband links */ |
159 | #define SCO_LINK 0x00 | 159 | #define SCO_LINK 0x00 |
160 | #define ACL_LINK 0x01 | 160 | #define ACL_LINK 0x01 |
161 | #define ESCO_LINK 0x02 | 161 | #define ESCO_LINK 0x02 |
162 | 162 | ||
163 | /* LMP features */ | 163 | /* LMP features */ |
164 | #define LMP_3SLOT 0x01 | 164 | #define LMP_3SLOT 0x01 |
165 | #define LMP_5SLOT 0x02 | 165 | #define LMP_5SLOT 0x02 |
166 | #define LMP_ENCRYPT 0x04 | 166 | #define LMP_ENCRYPT 0x04 |
167 | #define LMP_SOFFSET 0x08 | 167 | #define LMP_SOFFSET 0x08 |
168 | #define LMP_TACCURACY 0x10 | 168 | #define LMP_TACCURACY 0x10 |
169 | #define LMP_RSWITCH 0x20 | 169 | #define LMP_RSWITCH 0x20 |
170 | #define LMP_HOLD 0x40 | 170 | #define LMP_HOLD 0x40 |
171 | #define LMP_SNIFF 0x80 | 171 | #define LMP_SNIFF 0x80 |
172 | 172 | ||
173 | #define LMP_PARK 0x01 | 173 | #define LMP_PARK 0x01 |
174 | #define LMP_RSSI 0x02 | 174 | #define LMP_RSSI 0x02 |
175 | #define LMP_QUALITY 0x04 | 175 | #define LMP_QUALITY 0x04 |
176 | #define LMP_SCO 0x08 | 176 | #define LMP_SCO 0x08 |
177 | #define LMP_HV2 0x10 | 177 | #define LMP_HV2 0x10 |
178 | #define LMP_HV3 0x20 | 178 | #define LMP_HV3 0x20 |
179 | #define LMP_ULAW 0x40 | 179 | #define LMP_ULAW 0x40 |
180 | #define LMP_ALAW 0x80 | 180 | #define LMP_ALAW 0x80 |
181 | 181 | ||
182 | #define LMP_CVSD 0x01 | 182 | #define LMP_CVSD 0x01 |
183 | #define LMP_PSCHEME 0x02 | 183 | #define LMP_PSCHEME 0x02 |
184 | #define LMP_PCONTROL 0x04 | 184 | #define LMP_PCONTROL 0x04 |
185 | 185 | ||
186 | #define LMP_ESCO 0x80 | 186 | #define LMP_ESCO 0x80 |
187 | 187 | ||
188 | #define LMP_EV4 0x01 | 188 | #define LMP_EV4 0x01 |
189 | #define LMP_EV5 0x02 | 189 | #define LMP_EV5 0x02 |
190 | 190 | ||
191 | #define LMP_SNIFF_SUBR 0x02 | 191 | #define LMP_SNIFF_SUBR 0x02 |
192 | #define LMP_EDR_ESCO_2M 0x20 | 192 | #define LMP_EDR_ESCO_2M 0x20 |
193 | #define LMP_EDR_ESCO_3M 0x40 | 193 | #define LMP_EDR_ESCO_3M 0x40 |
194 | #define LMP_EDR_3S_ESCO 0x80 | 194 | #define LMP_EDR_3S_ESCO 0x80 |
195 | 195 | ||
196 | #define LMP_SIMPLE_PAIR 0x08 | 196 | #define LMP_SIMPLE_PAIR 0x08 |
197 | 197 | ||
198 | /* Connection modes */ | 198 | /* Connection modes */ |
199 | #define HCI_CM_ACTIVE 0x0000 | 199 | #define HCI_CM_ACTIVE 0x0000 |
200 | #define HCI_CM_HOLD 0x0001 | 200 | #define HCI_CM_HOLD 0x0001 |
201 | #define HCI_CM_SNIFF 0x0002 | 201 | #define HCI_CM_SNIFF 0x0002 |
202 | #define HCI_CM_PARK 0x0003 | 202 | #define HCI_CM_PARK 0x0003 |
203 | 203 | ||
204 | /* Link policies */ | 204 | /* Link policies */ |
205 | #define HCI_LP_RSWITCH 0x0001 | 205 | #define HCI_LP_RSWITCH 0x0001 |
206 | #define HCI_LP_HOLD 0x0002 | 206 | #define HCI_LP_HOLD 0x0002 |
207 | #define HCI_LP_SNIFF 0x0004 | 207 | #define HCI_LP_SNIFF 0x0004 |
208 | #define HCI_LP_PARK 0x0008 | 208 | #define HCI_LP_PARK 0x0008 |
209 | 209 | ||
210 | /* Link modes */ | 210 | /* Link modes */ |
211 | #define HCI_LM_ACCEPT 0x8000 | 211 | #define HCI_LM_ACCEPT 0x8000 |
212 | #define HCI_LM_MASTER 0x0001 | 212 | #define HCI_LM_MASTER 0x0001 |
213 | #define HCI_LM_AUTH 0x0002 | 213 | #define HCI_LM_AUTH 0x0002 |
214 | #define HCI_LM_ENCRYPT 0x0004 | 214 | #define HCI_LM_ENCRYPT 0x0004 |
215 | #define HCI_LM_TRUSTED 0x0008 | 215 | #define HCI_LM_TRUSTED 0x0008 |
216 | #define HCI_LM_RELIABLE 0x0010 | 216 | #define HCI_LM_RELIABLE 0x0010 |
217 | #define HCI_LM_SECURE 0x0020 | 217 | #define HCI_LM_SECURE 0x0020 |
218 | 218 | ||
219 | /* Authentication types */ | 219 | /* Authentication types */ |
220 | #define HCI_AT_NO_BONDING 0x00 | 220 | #define HCI_AT_NO_BONDING 0x00 |
221 | #define HCI_AT_NO_BONDING_MITM 0x01 | 221 | #define HCI_AT_NO_BONDING_MITM 0x01 |
222 | #define HCI_AT_DEDICATED_BONDING 0x02 | 222 | #define HCI_AT_DEDICATED_BONDING 0x02 |
223 | #define HCI_AT_DEDICATED_BONDING_MITM 0x03 | 223 | #define HCI_AT_DEDICATED_BONDING_MITM 0x03 |
224 | #define HCI_AT_GENERAL_BONDING 0x04 | 224 | #define HCI_AT_GENERAL_BONDING 0x04 |
225 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 | 225 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 |
226 | 226 | ||
227 | /* ----- HCI Commands ---- */ | 227 | /* ----- HCI Commands ---- */ |
228 | #define HCI_OP_INQUIRY 0x0401 | 228 | #define HCI_OP_INQUIRY 0x0401 |
229 | struct hci_cp_inquiry { | 229 | struct hci_cp_inquiry { |
230 | __u8 lap[3]; | 230 | __u8 lap[3]; |
231 | __u8 length; | 231 | __u8 length; |
232 | __u8 num_rsp; | 232 | __u8 num_rsp; |
233 | } __packed; | 233 | } __packed; |
234 | 234 | ||
235 | #define HCI_OP_INQUIRY_CANCEL 0x0402 | 235 | #define HCI_OP_INQUIRY_CANCEL 0x0402 |
236 | 236 | ||
237 | #define HCI_OP_EXIT_PERIODIC_INQ 0x0404 | 237 | #define HCI_OP_EXIT_PERIODIC_INQ 0x0404 |
238 | 238 | ||
239 | #define HCI_OP_CREATE_CONN 0x0405 | 239 | #define HCI_OP_CREATE_CONN 0x0405 |
240 | struct hci_cp_create_conn { | 240 | struct hci_cp_create_conn { |
241 | bdaddr_t bdaddr; | 241 | bdaddr_t bdaddr; |
242 | __le16 pkt_type; | 242 | __le16 pkt_type; |
243 | __u8 pscan_rep_mode; | 243 | __u8 pscan_rep_mode; |
244 | __u8 pscan_mode; | 244 | __u8 pscan_mode; |
245 | __le16 clock_offset; | 245 | __le16 clock_offset; |
246 | __u8 role_switch; | 246 | __u8 role_switch; |
247 | } __packed; | 247 | } __packed; |
248 | 248 | ||
249 | #define HCI_OP_DISCONNECT 0x0406 | 249 | #define HCI_OP_DISCONNECT 0x0406 |
250 | struct hci_cp_disconnect { | 250 | struct hci_cp_disconnect { |
251 | __le16 handle; | 251 | __le16 handle; |
252 | __u8 reason; | 252 | __u8 reason; |
253 | } __packed; | 253 | } __packed; |
254 | 254 | ||
255 | #define HCI_OP_ADD_SCO 0x0407 | 255 | #define HCI_OP_ADD_SCO 0x0407 |
256 | struct hci_cp_add_sco { | 256 | struct hci_cp_add_sco { |
257 | __le16 handle; | 257 | __le16 handle; |
258 | __le16 pkt_type; | 258 | __le16 pkt_type; |
259 | } __packed; | 259 | } __packed; |
260 | 260 | ||
261 | #define HCI_OP_CREATE_CONN_CANCEL 0x0408 | 261 | #define HCI_OP_CREATE_CONN_CANCEL 0x0408 |
262 | struct hci_cp_create_conn_cancel { | 262 | struct hci_cp_create_conn_cancel { |
263 | bdaddr_t bdaddr; | 263 | bdaddr_t bdaddr; |
264 | } __packed; | 264 | } __packed; |
265 | 265 | ||
266 | #define HCI_OP_ACCEPT_CONN_REQ 0x0409 | 266 | #define HCI_OP_ACCEPT_CONN_REQ 0x0409 |
267 | struct hci_cp_accept_conn_req { | 267 | struct hci_cp_accept_conn_req { |
268 | bdaddr_t bdaddr; | 268 | bdaddr_t bdaddr; |
269 | __u8 role; | 269 | __u8 role; |
270 | } __packed; | 270 | } __packed; |
271 | 271 | ||
272 | #define HCI_OP_REJECT_CONN_REQ 0x040a | 272 | #define HCI_OP_REJECT_CONN_REQ 0x040a |
273 | struct hci_cp_reject_conn_req { | 273 | struct hci_cp_reject_conn_req { |
274 | bdaddr_t bdaddr; | 274 | bdaddr_t bdaddr; |
275 | __u8 reason; | 275 | __u8 reason; |
276 | } __packed; | 276 | } __packed; |
277 | 277 | ||
278 | #define HCI_OP_LINK_KEY_REPLY 0x040b | 278 | #define HCI_OP_LINK_KEY_REPLY 0x040b |
279 | struct hci_cp_link_key_reply { | 279 | struct hci_cp_link_key_reply { |
280 | bdaddr_t bdaddr; | 280 | bdaddr_t bdaddr; |
281 | __u8 link_key[16]; | 281 | __u8 link_key[16]; |
282 | } __packed; | 282 | } __packed; |
283 | 283 | ||
284 | #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c | 284 | #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c |
285 | struct hci_cp_link_key_neg_reply { | 285 | struct hci_cp_link_key_neg_reply { |
286 | bdaddr_t bdaddr; | 286 | bdaddr_t bdaddr; |
287 | } __packed; | 287 | } __packed; |
288 | 288 | ||
289 | #define HCI_OP_PIN_CODE_REPLY 0x040d | 289 | #define HCI_OP_PIN_CODE_REPLY 0x040d |
290 | struct hci_cp_pin_code_reply { | 290 | struct hci_cp_pin_code_reply { |
291 | bdaddr_t bdaddr; | 291 | bdaddr_t bdaddr; |
292 | __u8 pin_len; | 292 | __u8 pin_len; |
293 | __u8 pin_code[16]; | 293 | __u8 pin_code[16]; |
294 | } __packed; | 294 | } __packed; |
295 | 295 | ||
296 | #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e | 296 | #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e |
297 | struct hci_cp_pin_code_neg_reply { | 297 | struct hci_cp_pin_code_neg_reply { |
298 | bdaddr_t bdaddr; | 298 | bdaddr_t bdaddr; |
299 | } __packed; | 299 | } __packed; |
300 | 300 | ||
301 | #define HCI_OP_CHANGE_CONN_PTYPE 0x040f | 301 | #define HCI_OP_CHANGE_CONN_PTYPE 0x040f |
302 | struct hci_cp_change_conn_ptype { | 302 | struct hci_cp_change_conn_ptype { |
303 | __le16 handle; | 303 | __le16 handle; |
304 | __le16 pkt_type; | 304 | __le16 pkt_type; |
305 | } __packed; | 305 | } __packed; |
306 | 306 | ||
307 | #define HCI_OP_AUTH_REQUESTED 0x0411 | 307 | #define HCI_OP_AUTH_REQUESTED 0x0411 |
308 | struct hci_cp_auth_requested { | 308 | struct hci_cp_auth_requested { |
309 | __le16 handle; | 309 | __le16 handle; |
310 | } __packed; | 310 | } __packed; |
311 | 311 | ||
312 | #define HCI_OP_SET_CONN_ENCRYPT 0x0413 | 312 | #define HCI_OP_SET_CONN_ENCRYPT 0x0413 |
313 | struct hci_cp_set_conn_encrypt { | 313 | struct hci_cp_set_conn_encrypt { |
314 | __le16 handle; | 314 | __le16 handle; |
315 | __u8 encrypt; | 315 | __u8 encrypt; |
316 | } __packed; | 316 | } __packed; |
317 | 317 | ||
318 | #define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 | 318 | #define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 |
319 | struct hci_cp_change_conn_link_key { | 319 | struct hci_cp_change_conn_link_key { |
320 | __le16 handle; | 320 | __le16 handle; |
321 | } __packed; | 321 | } __packed; |
322 | 322 | ||
323 | #define HCI_OP_REMOTE_NAME_REQ 0x0419 | 323 | #define HCI_OP_REMOTE_NAME_REQ 0x0419 |
324 | struct hci_cp_remote_name_req { | 324 | struct hci_cp_remote_name_req { |
325 | bdaddr_t bdaddr; | 325 | bdaddr_t bdaddr; |
326 | __u8 pscan_rep_mode; | 326 | __u8 pscan_rep_mode; |
327 | __u8 pscan_mode; | 327 | __u8 pscan_mode; |
328 | __le16 clock_offset; | 328 | __le16 clock_offset; |
329 | } __packed; | 329 | } __packed; |
330 | 330 | ||
331 | #define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a | 331 | #define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a |
332 | struct hci_cp_remote_name_req_cancel { | 332 | struct hci_cp_remote_name_req_cancel { |
333 | bdaddr_t bdaddr; | 333 | bdaddr_t bdaddr; |
334 | } __packed; | 334 | } __packed; |
335 | 335 | ||
336 | #define HCI_OP_READ_REMOTE_FEATURES 0x041b | 336 | #define HCI_OP_READ_REMOTE_FEATURES 0x041b |
337 | struct hci_cp_read_remote_features { | 337 | struct hci_cp_read_remote_features { |
338 | __le16 handle; | 338 | __le16 handle; |
339 | } __packed; | 339 | } __packed; |
340 | 340 | ||
341 | #define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c | 341 | #define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c |
342 | struct hci_cp_read_remote_ext_features { | 342 | struct hci_cp_read_remote_ext_features { |
343 | __le16 handle; | 343 | __le16 handle; |
344 | __u8 page; | 344 | __u8 page; |
345 | } __packed; | 345 | } __packed; |
346 | 346 | ||
347 | #define HCI_OP_READ_REMOTE_VERSION 0x041d | 347 | #define HCI_OP_READ_REMOTE_VERSION 0x041d |
348 | struct hci_cp_read_remote_version { | 348 | struct hci_cp_read_remote_version { |
349 | __le16 handle; | 349 | __le16 handle; |
350 | } __packed; | 350 | } __packed; |
351 | 351 | ||
352 | #define HCI_OP_SETUP_SYNC_CONN 0x0428 | 352 | #define HCI_OP_SETUP_SYNC_CONN 0x0428 |
353 | struct hci_cp_setup_sync_conn { | 353 | struct hci_cp_setup_sync_conn { |
354 | __le16 handle; | 354 | __le16 handle; |
355 | __le32 tx_bandwidth; | 355 | __le32 tx_bandwidth; |
356 | __le32 rx_bandwidth; | 356 | __le32 rx_bandwidth; |
357 | __le16 max_latency; | 357 | __le16 max_latency; |
358 | __le16 voice_setting; | 358 | __le16 voice_setting; |
359 | __u8 retrans_effort; | 359 | __u8 retrans_effort; |
360 | __le16 pkt_type; | 360 | __le16 pkt_type; |
361 | } __packed; | 361 | } __packed; |
362 | 362 | ||
363 | #define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 | 363 | #define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 |
364 | struct hci_cp_accept_sync_conn_req { | 364 | struct hci_cp_accept_sync_conn_req { |
365 | bdaddr_t bdaddr; | 365 | bdaddr_t bdaddr; |
366 | __le32 tx_bandwidth; | 366 | __le32 tx_bandwidth; |
367 | __le32 rx_bandwidth; | 367 | __le32 rx_bandwidth; |
368 | __le16 max_latency; | 368 | __le16 max_latency; |
369 | __le16 content_format; | 369 | __le16 content_format; |
370 | __u8 retrans_effort; | 370 | __u8 retrans_effort; |
371 | __le16 pkt_type; | 371 | __le16 pkt_type; |
372 | } __packed; | 372 | } __packed; |
373 | 373 | ||
374 | #define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a | 374 | #define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a |
375 | struct hci_cp_reject_sync_conn_req { | 375 | struct hci_cp_reject_sync_conn_req { |
376 | bdaddr_t bdaddr; | 376 | bdaddr_t bdaddr; |
377 | __u8 reason; | 377 | __u8 reason; |
378 | } __packed; | 378 | } __packed; |
379 | 379 | ||
380 | #define HCI_OP_SNIFF_MODE 0x0803 | 380 | #define HCI_OP_SNIFF_MODE 0x0803 |
381 | struct hci_cp_sniff_mode { | 381 | struct hci_cp_sniff_mode { |
382 | __le16 handle; | 382 | __le16 handle; |
383 | __le16 max_interval; | 383 | __le16 max_interval; |
384 | __le16 min_interval; | 384 | __le16 min_interval; |
385 | __le16 attempt; | 385 | __le16 attempt; |
386 | __le16 timeout; | 386 | __le16 timeout; |
387 | } __packed; | 387 | } __packed; |
388 | 388 | ||
389 | #define HCI_OP_EXIT_SNIFF_MODE 0x0804 | 389 | #define HCI_OP_EXIT_SNIFF_MODE 0x0804 |
390 | struct hci_cp_exit_sniff_mode { | 390 | struct hci_cp_exit_sniff_mode { |
391 | __le16 handle; | 391 | __le16 handle; |
392 | } __packed; | 392 | } __packed; |
393 | 393 | ||
394 | #define HCI_OP_ROLE_DISCOVERY 0x0809 | 394 | #define HCI_OP_ROLE_DISCOVERY 0x0809 |
395 | struct hci_cp_role_discovery { | 395 | struct hci_cp_role_discovery { |
396 | __le16 handle; | 396 | __le16 handle; |
397 | } __packed; | 397 | } __packed; |
398 | struct hci_rp_role_discovery { | 398 | struct hci_rp_role_discovery { |
399 | __u8 status; | 399 | __u8 status; |
400 | __le16 handle; | 400 | __le16 handle; |
401 | __u8 role; | 401 | __u8 role; |
402 | } __packed; | 402 | } __packed; |
403 | 403 | ||
404 | #define HCI_OP_SWITCH_ROLE 0x080b | 404 | #define HCI_OP_SWITCH_ROLE 0x080b |
405 | struct hci_cp_switch_role { | 405 | struct hci_cp_switch_role { |
406 | bdaddr_t bdaddr; | 406 | bdaddr_t bdaddr; |
407 | __u8 role; | 407 | __u8 role; |
408 | } __packed; | 408 | } __packed; |
409 | 409 | ||
410 | #define HCI_OP_READ_LINK_POLICY 0x080c | 410 | #define HCI_OP_READ_LINK_POLICY 0x080c |
411 | struct hci_cp_read_link_policy { | 411 | struct hci_cp_read_link_policy { |
412 | __le16 handle; | 412 | __le16 handle; |
413 | } __packed; | 413 | } __packed; |
414 | struct hci_rp_read_link_policy { | 414 | struct hci_rp_read_link_policy { |
415 | __u8 status; | 415 | __u8 status; |
416 | __le16 handle; | 416 | __le16 handle; |
417 | __le16 policy; | 417 | __le16 policy; |
418 | } __packed; | 418 | } __packed; |
419 | 419 | ||
420 | #define HCI_OP_WRITE_LINK_POLICY 0x080d | 420 | #define HCI_OP_WRITE_LINK_POLICY 0x080d |
421 | struct hci_cp_write_link_policy { | 421 | struct hci_cp_write_link_policy { |
422 | __le16 handle; | 422 | __le16 handle; |
423 | __le16 policy; | 423 | __le16 policy; |
424 | } __packed; | 424 | } __packed; |
425 | struct hci_rp_write_link_policy { | 425 | struct hci_rp_write_link_policy { |
426 | __u8 status; | 426 | __u8 status; |
427 | __le16 handle; | 427 | __le16 handle; |
428 | } __packed; | 428 | } __packed; |
429 | 429 | ||
430 | #define HCI_OP_READ_DEF_LINK_POLICY 0x080e | 430 | #define HCI_OP_READ_DEF_LINK_POLICY 0x080e |
431 | struct hci_rp_read_def_link_policy { | 431 | struct hci_rp_read_def_link_policy { |
432 | __u8 status; | 432 | __u8 status; |
433 | __le16 policy; | 433 | __le16 policy; |
434 | } __packed; | 434 | } __packed; |
435 | 435 | ||
436 | #define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f | 436 | #define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f |
437 | struct hci_cp_write_def_link_policy { | 437 | struct hci_cp_write_def_link_policy { |
438 | __le16 policy; | 438 | __le16 policy; |
439 | } __packed; | 439 | } __packed; |
440 | 440 | ||
441 | #define HCI_OP_SNIFF_SUBRATE 0x0811 | 441 | #define HCI_OP_SNIFF_SUBRATE 0x0811 |
442 | struct hci_cp_sniff_subrate { | 442 | struct hci_cp_sniff_subrate { |
443 | __le16 handle; | 443 | __le16 handle; |
444 | __le16 max_latency; | 444 | __le16 max_latency; |
445 | __le16 min_remote_timeout; | 445 | __le16 min_remote_timeout; |
446 | __le16 min_local_timeout; | 446 | __le16 min_local_timeout; |
447 | } __packed; | 447 | } __packed; |
448 | 448 | ||
449 | #define HCI_OP_SET_EVENT_MASK 0x0c01 | 449 | #define HCI_OP_SET_EVENT_MASK 0x0c01 |
450 | struct hci_cp_set_event_mask { | 450 | struct hci_cp_set_event_mask { |
451 | __u8 mask[8]; | 451 | __u8 mask[8]; |
452 | } __packed; | 452 | } __packed; |
453 | 453 | ||
454 | #define HCI_OP_RESET 0x0c03 | 454 | #define HCI_OP_RESET 0x0c03 |
455 | 455 | ||
456 | #define HCI_OP_SET_EVENT_FLT 0x0c05 | 456 | #define HCI_OP_SET_EVENT_FLT 0x0c05 |
457 | struct hci_cp_set_event_flt { | 457 | struct hci_cp_set_event_flt { |
458 | __u8 flt_type; | 458 | __u8 flt_type; |
459 | __u8 cond_type; | 459 | __u8 cond_type; |
460 | __u8 condition[0]; | 460 | __u8 condition[0]; |
461 | } __packed; | 461 | } __packed; |
462 | 462 | ||
463 | /* Filter types */ | 463 | /* Filter types */ |
464 | #define HCI_FLT_CLEAR_ALL 0x00 | 464 | #define HCI_FLT_CLEAR_ALL 0x00 |
465 | #define HCI_FLT_INQ_RESULT 0x01 | 465 | #define HCI_FLT_INQ_RESULT 0x01 |
466 | #define HCI_FLT_CONN_SETUP 0x02 | 466 | #define HCI_FLT_CONN_SETUP 0x02 |
467 | 467 | ||
468 | /* CONN_SETUP Condition types */ | 468 | /* CONN_SETUP Condition types */ |
469 | #define HCI_CONN_SETUP_ALLOW_ALL 0x00 | 469 | #define HCI_CONN_SETUP_ALLOW_ALL 0x00 |
470 | #define HCI_CONN_SETUP_ALLOW_CLASS 0x01 | 470 | #define HCI_CONN_SETUP_ALLOW_CLASS 0x01 |
471 | #define HCI_CONN_SETUP_ALLOW_BDADDR 0x02 | 471 | #define HCI_CONN_SETUP_ALLOW_BDADDR 0x02 |
472 | 472 | ||
473 | /* CONN_SETUP Conditions */ | 473 | /* CONN_SETUP Conditions */ |
474 | #define HCI_CONN_SETUP_AUTO_OFF 0x01 | 474 | #define HCI_CONN_SETUP_AUTO_OFF 0x01 |
475 | #define HCI_CONN_SETUP_AUTO_ON 0x02 | 475 | #define HCI_CONN_SETUP_AUTO_ON 0x02 |
476 | 476 | ||
477 | #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 | 477 | #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 |
478 | struct hci_cp_write_local_name { | 478 | struct hci_cp_write_local_name { |
479 | __u8 name[248]; | 479 | __u8 name[248]; |
480 | } __packed; | 480 | } __packed; |
481 | 481 | ||
482 | #define HCI_OP_READ_LOCAL_NAME 0x0c14 | 482 | #define HCI_OP_READ_LOCAL_NAME 0x0c14 |
483 | struct hci_rp_read_local_name { | 483 | struct hci_rp_read_local_name { |
484 | __u8 status; | 484 | __u8 status; |
485 | __u8 name[248]; | 485 | __u8 name[248]; |
486 | } __packed; | 486 | } __packed; |
487 | 487 | ||
488 | #define HCI_OP_WRITE_CA_TIMEOUT 0x0c16 | 488 | #define HCI_OP_WRITE_CA_TIMEOUT 0x0c16 |
489 | 489 | ||
490 | #define HCI_OP_WRITE_PG_TIMEOUT 0x0c18 | 490 | #define HCI_OP_WRITE_PG_TIMEOUT 0x0c18 |
491 | 491 | ||
492 | #define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a | 492 | #define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a |
493 | #define SCAN_DISABLED 0x00 | 493 | #define SCAN_DISABLED 0x00 |
494 | #define SCAN_INQUIRY 0x01 | 494 | #define SCAN_INQUIRY 0x01 |
495 | #define SCAN_PAGE 0x02 | 495 | #define SCAN_PAGE 0x02 |
496 | 496 | ||
497 | #define HCI_OP_READ_AUTH_ENABLE 0x0c1f | 497 | #define HCI_OP_READ_AUTH_ENABLE 0x0c1f |
498 | 498 | ||
499 | #define HCI_OP_WRITE_AUTH_ENABLE 0x0c20 | 499 | #define HCI_OP_WRITE_AUTH_ENABLE 0x0c20 |
500 | #define AUTH_DISABLED 0x00 | 500 | #define AUTH_DISABLED 0x00 |
501 | #define AUTH_ENABLED 0x01 | 501 | #define AUTH_ENABLED 0x01 |
502 | 502 | ||
503 | #define HCI_OP_READ_ENCRYPT_MODE 0x0c21 | 503 | #define HCI_OP_READ_ENCRYPT_MODE 0x0c21 |
504 | 504 | ||
505 | #define HCI_OP_WRITE_ENCRYPT_MODE 0x0c22 | 505 | #define HCI_OP_WRITE_ENCRYPT_MODE 0x0c22 |
506 | #define ENCRYPT_DISABLED 0x00 | 506 | #define ENCRYPT_DISABLED 0x00 |
507 | #define ENCRYPT_P2P 0x01 | 507 | #define ENCRYPT_P2P 0x01 |
508 | #define ENCRYPT_BOTH 0x02 | 508 | #define ENCRYPT_BOTH 0x02 |
509 | 509 | ||
510 | #define HCI_OP_READ_CLASS_OF_DEV 0x0c23 | 510 | #define HCI_OP_READ_CLASS_OF_DEV 0x0c23 |
511 | struct hci_rp_read_class_of_dev { | 511 | struct hci_rp_read_class_of_dev { |
512 | __u8 status; | 512 | __u8 status; |
513 | __u8 dev_class[3]; | 513 | __u8 dev_class[3]; |
514 | } __packed; | 514 | } __packed; |
515 | 515 | ||
516 | #define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24 | 516 | #define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24 |
517 | struct hci_cp_write_class_of_dev { | 517 | struct hci_cp_write_class_of_dev { |
518 | __u8 dev_class[3]; | 518 | __u8 dev_class[3]; |
519 | } __packed; | 519 | } __packed; |
520 | 520 | ||
521 | #define HCI_OP_READ_VOICE_SETTING 0x0c25 | 521 | #define HCI_OP_READ_VOICE_SETTING 0x0c25 |
522 | struct hci_rp_read_voice_setting { | 522 | struct hci_rp_read_voice_setting { |
523 | __u8 status; | 523 | __u8 status; |
524 | __le16 voice_setting; | 524 | __le16 voice_setting; |
525 | } __packed; | 525 | } __packed; |
526 | 526 | ||
527 | #define HCI_OP_WRITE_VOICE_SETTING 0x0c26 | 527 | #define HCI_OP_WRITE_VOICE_SETTING 0x0c26 |
528 | struct hci_cp_write_voice_setting { | 528 | struct hci_cp_write_voice_setting { |
529 | __le16 voice_setting; | 529 | __le16 voice_setting; |
530 | } __packed; | 530 | } __packed; |
531 | 531 | ||
532 | #define HCI_OP_HOST_BUFFER_SIZE 0x0c33 | 532 | #define HCI_OP_HOST_BUFFER_SIZE 0x0c33 |
533 | struct hci_cp_host_buffer_size { | 533 | struct hci_cp_host_buffer_size { |
534 | __le16 acl_mtu; | 534 | __le16 acl_mtu; |
535 | __u8 sco_mtu; | 535 | __u8 sco_mtu; |
536 | __le16 acl_max_pkt; | 536 | __le16 acl_max_pkt; |
537 | __le16 sco_max_pkt; | 537 | __le16 sco_max_pkt; |
538 | } __packed; | 538 | } __packed; |
539 | 539 | ||
540 | #define HCI_OP_READ_SSP_MODE 0x0c55 | 540 | #define HCI_OP_READ_SSP_MODE 0x0c55 |
541 | struct hci_rp_read_ssp_mode { | 541 | struct hci_rp_read_ssp_mode { |
542 | __u8 status; | 542 | __u8 status; |
543 | __u8 mode; | 543 | __u8 mode; |
544 | } __packed; | 544 | } __packed; |
545 | 545 | ||
546 | #define HCI_OP_WRITE_SSP_MODE 0x0c56 | 546 | #define HCI_OP_WRITE_SSP_MODE 0x0c56 |
547 | struct hci_cp_write_ssp_mode { | 547 | struct hci_cp_write_ssp_mode { |
548 | __u8 mode; | 548 | __u8 mode; |
549 | } __packed; | 549 | } __packed; |
550 | 550 | ||
551 | #define HCI_OP_READ_LOCAL_VERSION 0x1001 | 551 | #define HCI_OP_READ_LOCAL_VERSION 0x1001 |
552 | struct hci_rp_read_local_version { | 552 | struct hci_rp_read_local_version { |
553 | __u8 status; | 553 | __u8 status; |
554 | __u8 hci_ver; | 554 | __u8 hci_ver; |
555 | __le16 hci_rev; | 555 | __le16 hci_rev; |
556 | __u8 lmp_ver; | 556 | __u8 lmp_ver; |
557 | __le16 manufacturer; | 557 | __le16 manufacturer; |
558 | __le16 lmp_subver; | 558 | __le16 lmp_subver; |
559 | } __packed; | 559 | } __packed; |
560 | 560 | ||
561 | #define HCI_OP_READ_LOCAL_COMMANDS 0x1002 | 561 | #define HCI_OP_READ_LOCAL_COMMANDS 0x1002 |
562 | struct hci_rp_read_local_commands { | 562 | struct hci_rp_read_local_commands { |
563 | __u8 status; | 563 | __u8 status; |
564 | __u8 commands[64]; | 564 | __u8 commands[64]; |
565 | } __packed; | 565 | } __packed; |
566 | 566 | ||
567 | #define HCI_OP_READ_LOCAL_FEATURES 0x1003 | 567 | #define HCI_OP_READ_LOCAL_FEATURES 0x1003 |
568 | struct hci_rp_read_local_features { | 568 | struct hci_rp_read_local_features { |
569 | __u8 status; | 569 | __u8 status; |
570 | __u8 features[8]; | 570 | __u8 features[8]; |
571 | } __packed; | 571 | } __packed; |
572 | 572 | ||
573 | #define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004 | 573 | #define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004 |
574 | struct hci_rp_read_local_ext_features { | 574 | struct hci_rp_read_local_ext_features { |
575 | __u8 status; | 575 | __u8 status; |
576 | __u8 page; | 576 | __u8 page; |
577 | __u8 max_page; | 577 | __u8 max_page; |
578 | __u8 features[8]; | 578 | __u8 features[8]; |
579 | } __packed; | 579 | } __packed; |
580 | 580 | ||
581 | #define HCI_OP_READ_BUFFER_SIZE 0x1005 | 581 | #define HCI_OP_READ_BUFFER_SIZE 0x1005 |
582 | struct hci_rp_read_buffer_size { | 582 | struct hci_rp_read_buffer_size { |
583 | __u8 status; | 583 | __u8 status; |
584 | __le16 acl_mtu; | 584 | __le16 acl_mtu; |
585 | __u8 sco_mtu; | 585 | __u8 sco_mtu; |
586 | __le16 acl_max_pkt; | 586 | __le16 acl_max_pkt; |
587 | __le16 sco_max_pkt; | 587 | __le16 sco_max_pkt; |
588 | } __packed; | 588 | } __packed; |
589 | 589 | ||
590 | #define HCI_OP_READ_BD_ADDR 0x1009 | 590 | #define HCI_OP_READ_BD_ADDR 0x1009 |
591 | struct hci_rp_read_bd_addr { | 591 | struct hci_rp_read_bd_addr { |
592 | __u8 status; | 592 | __u8 status; |
593 | bdaddr_t bdaddr; | 593 | bdaddr_t bdaddr; |
594 | } __packed; | 594 | } __packed; |
595 | 595 | ||
596 | /* ---- HCI Events ---- */ | 596 | /* ---- HCI Events ---- */ |
597 | #define HCI_EV_INQUIRY_COMPLETE 0x01 | 597 | #define HCI_EV_INQUIRY_COMPLETE 0x01 |
598 | 598 | ||
599 | #define HCI_EV_INQUIRY_RESULT 0x02 | 599 | #define HCI_EV_INQUIRY_RESULT 0x02 |
600 | struct inquiry_info { | 600 | struct inquiry_info { |
601 | bdaddr_t bdaddr; | 601 | bdaddr_t bdaddr; |
602 | __u8 pscan_rep_mode; | 602 | __u8 pscan_rep_mode; |
603 | __u8 pscan_period_mode; | 603 | __u8 pscan_period_mode; |
604 | __u8 pscan_mode; | 604 | __u8 pscan_mode; |
605 | __u8 dev_class[3]; | 605 | __u8 dev_class[3]; |
606 | __le16 clock_offset; | 606 | __le16 clock_offset; |
607 | } __packed; | 607 | } __packed; |
608 | 608 | ||
609 | #define HCI_EV_CONN_COMPLETE 0x03 | 609 | #define HCI_EV_CONN_COMPLETE 0x03 |
610 | struct hci_ev_conn_complete { | 610 | struct hci_ev_conn_complete { |
611 | __u8 status; | 611 | __u8 status; |
612 | __le16 handle; | 612 | __le16 handle; |
613 | bdaddr_t bdaddr; | 613 | bdaddr_t bdaddr; |
614 | __u8 link_type; | 614 | __u8 link_type; |
615 | __u8 encr_mode; | 615 | __u8 encr_mode; |
616 | } __packed; | 616 | } __packed; |
617 | 617 | ||
618 | #define HCI_EV_CONN_REQUEST 0x04 | 618 | #define HCI_EV_CONN_REQUEST 0x04 |
619 | struct hci_ev_conn_request { | 619 | struct hci_ev_conn_request { |
620 | bdaddr_t bdaddr; | 620 | bdaddr_t bdaddr; |
621 | __u8 dev_class[3]; | 621 | __u8 dev_class[3]; |
622 | __u8 link_type; | 622 | __u8 link_type; |
623 | } __packed; | 623 | } __packed; |
624 | 624 | ||
625 | #define HCI_EV_DISCONN_COMPLETE 0x05 | 625 | #define HCI_EV_DISCONN_COMPLETE 0x05 |
626 | struct hci_ev_disconn_complete { | 626 | struct hci_ev_disconn_complete { |
627 | __u8 status; | 627 | __u8 status; |
628 | __le16 handle; | 628 | __le16 handle; |
629 | __u8 reason; | 629 | __u8 reason; |
630 | } __packed; | 630 | } __packed; |
631 | 631 | ||
632 | #define HCI_EV_AUTH_COMPLETE 0x06 | 632 | #define HCI_EV_AUTH_COMPLETE 0x06 |
633 | struct hci_ev_auth_complete { | 633 | struct hci_ev_auth_complete { |
634 | __u8 status; | 634 | __u8 status; |
635 | __le16 handle; | 635 | __le16 handle; |
636 | } __packed; | 636 | } __packed; |
637 | 637 | ||
638 | #define HCI_EV_REMOTE_NAME 0x07 | 638 | #define HCI_EV_REMOTE_NAME 0x07 |
639 | struct hci_ev_remote_name { | 639 | struct hci_ev_remote_name { |
640 | __u8 status; | 640 | __u8 status; |
641 | bdaddr_t bdaddr; | 641 | bdaddr_t bdaddr; |
642 | __u8 name[248]; | 642 | __u8 name[248]; |
643 | } __packed; | 643 | } __packed; |
644 | 644 | ||
645 | #define HCI_EV_ENCRYPT_CHANGE 0x08 | 645 | #define HCI_EV_ENCRYPT_CHANGE 0x08 |
646 | struct hci_ev_encrypt_change { | 646 | struct hci_ev_encrypt_change { |
647 | __u8 status; | 647 | __u8 status; |
648 | __le16 handle; | 648 | __le16 handle; |
649 | __u8 encrypt; | 649 | __u8 encrypt; |
650 | } __packed; | 650 | } __packed; |
651 | 651 | ||
652 | #define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 | 652 | #define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 |
653 | struct hci_ev_change_link_key_complete { | 653 | struct hci_ev_change_link_key_complete { |
654 | __u8 status; | 654 | __u8 status; |
655 | __le16 handle; | 655 | __le16 handle; |
656 | } __packed; | 656 | } __packed; |
657 | 657 | ||
658 | #define HCI_EV_REMOTE_FEATURES 0x0b | 658 | #define HCI_EV_REMOTE_FEATURES 0x0b |
659 | struct hci_ev_remote_features { | 659 | struct hci_ev_remote_features { |
660 | __u8 status; | 660 | __u8 status; |
661 | __le16 handle; | 661 | __le16 handle; |
662 | __u8 features[8]; | 662 | __u8 features[8]; |
663 | } __packed; | 663 | } __packed; |
664 | 664 | ||
665 | #define HCI_EV_REMOTE_VERSION 0x0c | 665 | #define HCI_EV_REMOTE_VERSION 0x0c |
666 | struct hci_ev_remote_version { | 666 | struct hci_ev_remote_version { |
667 | __u8 status; | 667 | __u8 status; |
668 | __le16 handle; | 668 | __le16 handle; |
669 | __u8 lmp_ver; | 669 | __u8 lmp_ver; |
670 | __le16 manufacturer; | 670 | __le16 manufacturer; |
671 | __le16 lmp_subver; | 671 | __le16 lmp_subver; |
672 | } __packed; | 672 | } __packed; |
673 | 673 | ||
674 | #define HCI_EV_QOS_SETUP_COMPLETE 0x0d | 674 | #define HCI_EV_QOS_SETUP_COMPLETE 0x0d |
675 | struct hci_qos { | 675 | struct hci_qos { |
676 | __u8 service_type; | 676 | __u8 service_type; |
677 | __u32 token_rate; | 677 | __u32 token_rate; |
678 | __u32 peak_bandwidth; | 678 | __u32 peak_bandwidth; |
679 | __u32 latency; | 679 | __u32 latency; |
680 | __u32 delay_variation; | 680 | __u32 delay_variation; |
681 | } __packed; | 681 | } __packed; |
682 | struct hci_ev_qos_setup_complete { | 682 | struct hci_ev_qos_setup_complete { |
683 | __u8 status; | 683 | __u8 status; |
684 | __le16 handle; | 684 | __le16 handle; |
685 | struct hci_qos qos; | 685 | struct hci_qos qos; |
686 | } __packed; | 686 | } __packed; |
687 | 687 | ||
688 | #define HCI_EV_CMD_COMPLETE 0x0e | 688 | #define HCI_EV_CMD_COMPLETE 0x0e |
689 | struct hci_ev_cmd_complete { | 689 | struct hci_ev_cmd_complete { |
690 | __u8 ncmd; | 690 | __u8 ncmd; |
691 | __le16 opcode; | 691 | __le16 opcode; |
692 | } __packed; | 692 | } __packed; |
693 | 693 | ||
694 | #define HCI_EV_CMD_STATUS 0x0f | 694 | #define HCI_EV_CMD_STATUS 0x0f |
695 | struct hci_ev_cmd_status { | 695 | struct hci_ev_cmd_status { |
696 | __u8 status; | 696 | __u8 status; |
697 | __u8 ncmd; | 697 | __u8 ncmd; |
698 | __le16 opcode; | 698 | __le16 opcode; |
699 | } __packed; | 699 | } __packed; |
700 | 700 | ||
701 | #define HCI_EV_ROLE_CHANGE 0x12 | 701 | #define HCI_EV_ROLE_CHANGE 0x12 |
702 | struct hci_ev_role_change { | 702 | struct hci_ev_role_change { |
703 | __u8 status; | 703 | __u8 status; |
704 | bdaddr_t bdaddr; | 704 | bdaddr_t bdaddr; |
705 | __u8 role; | 705 | __u8 role; |
706 | } __packed; | 706 | } __packed; |
707 | 707 | ||
708 | #define HCI_EV_NUM_COMP_PKTS 0x13 | 708 | #define HCI_EV_NUM_COMP_PKTS 0x13 |
709 | struct hci_ev_num_comp_pkts { | 709 | struct hci_ev_num_comp_pkts { |
710 | __u8 num_hndl; | 710 | __u8 num_hndl; |
711 | /* variable length part */ | 711 | /* variable length part */ |
712 | } __packed; | 712 | } __packed; |
713 | 713 | ||
714 | #define HCI_EV_MODE_CHANGE 0x14 | 714 | #define HCI_EV_MODE_CHANGE 0x14 |
715 | struct hci_ev_mode_change { | 715 | struct hci_ev_mode_change { |
716 | __u8 status; | 716 | __u8 status; |
717 | __le16 handle; | 717 | __le16 handle; |
718 | __u8 mode; | 718 | __u8 mode; |
719 | __le16 interval; | 719 | __le16 interval; |
720 | } __packed; | 720 | } __packed; |
721 | 721 | ||
722 | #define HCI_EV_PIN_CODE_REQ 0x16 | 722 | #define HCI_EV_PIN_CODE_REQ 0x16 |
723 | struct hci_ev_pin_code_req { | 723 | struct hci_ev_pin_code_req { |
724 | bdaddr_t bdaddr; | 724 | bdaddr_t bdaddr; |
725 | } __packed; | 725 | } __packed; |
726 | 726 | ||
727 | #define HCI_EV_LINK_KEY_REQ 0x17 | 727 | #define HCI_EV_LINK_KEY_REQ 0x17 |
728 | struct hci_ev_link_key_req { | 728 | struct hci_ev_link_key_req { |
729 | bdaddr_t bdaddr; | 729 | bdaddr_t bdaddr; |
730 | } __packed; | 730 | } __packed; |
731 | 731 | ||
732 | #define HCI_EV_LINK_KEY_NOTIFY 0x18 | 732 | #define HCI_EV_LINK_KEY_NOTIFY 0x18 |
733 | struct hci_ev_link_key_notify { | 733 | struct hci_ev_link_key_notify { |
734 | bdaddr_t bdaddr; | 734 | bdaddr_t bdaddr; |
735 | __u8 link_key[16]; | 735 | __u8 link_key[16]; |
736 | __u8 key_type; | 736 | __u8 key_type; |
737 | } __packed; | 737 | } __packed; |
738 | 738 | ||
739 | #define HCI_EV_CLOCK_OFFSET 0x1c | 739 | #define HCI_EV_CLOCK_OFFSET 0x1c |
740 | struct hci_ev_clock_offset { | 740 | struct hci_ev_clock_offset { |
741 | __u8 status; | 741 | __u8 status; |
742 | __le16 handle; | 742 | __le16 handle; |
743 | __le16 clock_offset; | 743 | __le16 clock_offset; |
744 | } __packed; | 744 | } __packed; |
745 | 745 | ||
746 | #define HCI_EV_PKT_TYPE_CHANGE 0x1d | 746 | #define HCI_EV_PKT_TYPE_CHANGE 0x1d |
747 | struct hci_ev_pkt_type_change { | 747 | struct hci_ev_pkt_type_change { |
748 | __u8 status; | 748 | __u8 status; |
749 | __le16 handle; | 749 | __le16 handle; |
750 | __le16 pkt_type; | 750 | __le16 pkt_type; |
751 | } __packed; | 751 | } __packed; |
752 | 752 | ||
753 | #define HCI_EV_PSCAN_REP_MODE 0x20 | 753 | #define HCI_EV_PSCAN_REP_MODE 0x20 |
754 | struct hci_ev_pscan_rep_mode { | 754 | struct hci_ev_pscan_rep_mode { |
755 | bdaddr_t bdaddr; | 755 | bdaddr_t bdaddr; |
756 | __u8 pscan_rep_mode; | 756 | __u8 pscan_rep_mode; |
757 | } __packed; | 757 | } __packed; |
758 | 758 | ||
759 | #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 | 759 | #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 |
760 | struct inquiry_info_with_rssi { | 760 | struct inquiry_info_with_rssi { |
761 | bdaddr_t bdaddr; | 761 | bdaddr_t bdaddr; |
762 | __u8 pscan_rep_mode; | 762 | __u8 pscan_rep_mode; |
763 | __u8 pscan_period_mode; | 763 | __u8 pscan_period_mode; |
764 | __u8 dev_class[3]; | 764 | __u8 dev_class[3]; |
765 | __le16 clock_offset; | 765 | __le16 clock_offset; |
766 | __s8 rssi; | 766 | __s8 rssi; |
767 | } __packed; | 767 | } __packed; |
768 | struct inquiry_info_with_rssi_and_pscan_mode { | 768 | struct inquiry_info_with_rssi_and_pscan_mode { |
769 | bdaddr_t bdaddr; | 769 | bdaddr_t bdaddr; |
770 | __u8 pscan_rep_mode; | 770 | __u8 pscan_rep_mode; |
771 | __u8 pscan_period_mode; | 771 | __u8 pscan_period_mode; |
772 | __u8 pscan_mode; | 772 | __u8 pscan_mode; |
773 | __u8 dev_class[3]; | 773 | __u8 dev_class[3]; |
774 | __le16 clock_offset; | 774 | __le16 clock_offset; |
775 | __s8 rssi; | 775 | __s8 rssi; |
776 | } __packed; | 776 | } __packed; |
777 | 777 | ||
778 | #define HCI_EV_REMOTE_EXT_FEATURES 0x23 | 778 | #define HCI_EV_REMOTE_EXT_FEATURES 0x23 |
779 | struct hci_ev_remote_ext_features { | 779 | struct hci_ev_remote_ext_features { |
780 | __u8 status; | 780 | __u8 status; |
781 | __le16 handle; | 781 | __le16 handle; |
782 | __u8 page; | 782 | __u8 page; |
783 | __u8 max_page; | 783 | __u8 max_page; |
784 | __u8 features[8]; | 784 | __u8 features[8]; |
785 | } __packed; | 785 | } __packed; |
786 | 786 | ||
787 | #define HCI_EV_SYNC_CONN_COMPLETE 0x2c | 787 | #define HCI_EV_SYNC_CONN_COMPLETE 0x2c |
788 | struct hci_ev_sync_conn_complete { | 788 | struct hci_ev_sync_conn_complete { |
789 | __u8 status; | 789 | __u8 status; |
790 | __le16 handle; | 790 | __le16 handle; |
791 | bdaddr_t bdaddr; | 791 | bdaddr_t bdaddr; |
792 | __u8 link_type; | 792 | __u8 link_type; |
793 | __u8 tx_interval; | 793 | __u8 tx_interval; |
794 | __u8 retrans_window; | 794 | __u8 retrans_window; |
795 | __le16 rx_pkt_len; | 795 | __le16 rx_pkt_len; |
796 | __le16 tx_pkt_len; | 796 | __le16 tx_pkt_len; |
797 | __u8 air_mode; | 797 | __u8 air_mode; |
798 | } __packed; | 798 | } __packed; |
799 | 799 | ||
800 | #define HCI_EV_SYNC_CONN_CHANGED 0x2d | 800 | #define HCI_EV_SYNC_CONN_CHANGED 0x2d |
801 | struct hci_ev_sync_conn_changed { | 801 | struct hci_ev_sync_conn_changed { |
802 | __u8 status; | 802 | __u8 status; |
803 | __le16 handle; | 803 | __le16 handle; |
804 | __u8 tx_interval; | 804 | __u8 tx_interval; |
805 | __u8 retrans_window; | 805 | __u8 retrans_window; |
806 | __le16 rx_pkt_len; | 806 | __le16 rx_pkt_len; |
807 | __le16 tx_pkt_len; | 807 | __le16 tx_pkt_len; |
808 | } __packed; | 808 | } __packed; |
809 | 809 | ||
810 | #define HCI_EV_SNIFF_SUBRATE 0x2e | 810 | #define HCI_EV_SNIFF_SUBRATE 0x2e |
811 | struct hci_ev_sniff_subrate { | 811 | struct hci_ev_sniff_subrate { |
812 | __u8 status; | 812 | __u8 status; |
813 | __le16 handle; | 813 | __le16 handle; |
814 | __le16 max_tx_latency; | 814 | __le16 max_tx_latency; |
815 | __le16 max_rx_latency; | 815 | __le16 max_rx_latency; |
816 | __le16 max_remote_timeout; | 816 | __le16 max_remote_timeout; |
817 | __le16 max_local_timeout; | 817 | __le16 max_local_timeout; |
818 | } __packed; | 818 | } __packed; |
819 | 819 | ||
820 | #define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f | 820 | #define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f |
821 | struct extended_inquiry_info { | 821 | struct extended_inquiry_info { |
822 | bdaddr_t bdaddr; | 822 | bdaddr_t bdaddr; |
823 | __u8 pscan_rep_mode; | 823 | __u8 pscan_rep_mode; |
824 | __u8 pscan_period_mode; | 824 | __u8 pscan_period_mode; |
825 | __u8 dev_class[3]; | 825 | __u8 dev_class[3]; |
826 | __le16 clock_offset; | 826 | __le16 clock_offset; |
827 | __s8 rssi; | 827 | __s8 rssi; |
828 | __u8 data[240]; | 828 | __u8 data[240]; |
829 | } __packed; | 829 | } __packed; |
830 | 830 | ||
831 | #define HCI_EV_IO_CAPA_REQUEST 0x31 | 831 | #define HCI_EV_IO_CAPA_REQUEST 0x31 |
832 | struct hci_ev_io_capa_request { | 832 | struct hci_ev_io_capa_request { |
833 | bdaddr_t bdaddr; | 833 | bdaddr_t bdaddr; |
834 | } __packed; | 834 | } __packed; |
835 | 835 | ||
836 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 | 836 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 |
837 | struct hci_ev_simple_pair_complete { | 837 | struct hci_ev_simple_pair_complete { |
838 | __u8 status; | 838 | __u8 status; |
839 | bdaddr_t bdaddr; | 839 | bdaddr_t bdaddr; |
840 | } __packed; | 840 | } __packed; |
841 | 841 | ||
842 | #define HCI_EV_REMOTE_HOST_FEATURES 0x3d | 842 | #define HCI_EV_REMOTE_HOST_FEATURES 0x3d |
843 | struct hci_ev_remote_host_features { | 843 | struct hci_ev_remote_host_features { |
844 | bdaddr_t bdaddr; | 844 | bdaddr_t bdaddr; |
845 | __u8 features[8]; | 845 | __u8 features[8]; |
846 | } __packed; | 846 | } __packed; |
847 | 847 | ||
848 | /* Internal events generated by Bluetooth stack */ | 848 | /* Internal events generated by Bluetooth stack */ |
849 | #define HCI_EV_STACK_INTERNAL 0xfd | 849 | #define HCI_EV_STACK_INTERNAL 0xfd |
850 | struct hci_ev_stack_internal { | 850 | struct hci_ev_stack_internal { |
851 | __u16 type; | 851 | __u16 type; |
852 | __u8 data[0]; | 852 | __u8 data[0]; |
853 | } __packed; | 853 | } __packed; |
854 | 854 | ||
855 | #define HCI_EV_SI_DEVICE 0x01 | 855 | #define HCI_EV_SI_DEVICE 0x01 |
856 | struct hci_ev_si_device { | 856 | struct hci_ev_si_device { |
857 | __u16 event; | 857 | __u16 event; |
858 | __u16 dev_id; | 858 | __u16 dev_id; |
859 | } __packed; | 859 | } __packed; |
860 | 860 | ||
861 | #define HCI_EV_SI_SECURITY 0x02 | 861 | #define HCI_EV_SI_SECURITY 0x02 |
862 | struct hci_ev_si_security { | 862 | struct hci_ev_si_security { |
863 | __u16 event; | 863 | __u16 event; |
864 | __u16 proto; | 864 | __u16 proto; |
865 | __u16 subproto; | 865 | __u16 subproto; |
866 | __u8 incoming; | 866 | __u8 incoming; |
867 | } __packed; | 867 | } __packed; |
868 | 868 | ||
869 | /* ---- HCI Packet structures ---- */ | 869 | /* ---- HCI Packet structures ---- */ |
870 | #define HCI_COMMAND_HDR_SIZE 3 | 870 | #define HCI_COMMAND_HDR_SIZE 3 |
871 | #define HCI_EVENT_HDR_SIZE 2 | 871 | #define HCI_EVENT_HDR_SIZE 2 |
872 | #define HCI_ACL_HDR_SIZE 4 | 872 | #define HCI_ACL_HDR_SIZE 4 |
873 | #define HCI_SCO_HDR_SIZE 3 | 873 | #define HCI_SCO_HDR_SIZE 3 |
874 | 874 | ||
875 | struct hci_command_hdr { | 875 | struct hci_command_hdr { |
876 | __le16 opcode; /* OCF & OGF */ | 876 | __le16 opcode; /* OCF & OGF */ |
877 | __u8 plen; | 877 | __u8 plen; |
878 | } __packed; | 878 | } __packed; |
879 | 879 | ||
880 | struct hci_event_hdr { | 880 | struct hci_event_hdr { |
881 | __u8 evt; | 881 | __u8 evt; |
882 | __u8 plen; | 882 | __u8 plen; |
883 | } __packed; | 883 | } __packed; |
884 | 884 | ||
885 | struct hci_acl_hdr { | 885 | struct hci_acl_hdr { |
886 | __le16 handle; /* Handle & Flags(PB, BC) */ | 886 | __le16 handle; /* Handle & Flags(PB, BC) */ |
887 | __le16 dlen; | 887 | __le16 dlen; |
888 | } __packed; | 888 | } __packed; |
889 | 889 | ||
890 | struct hci_sco_hdr { | 890 | struct hci_sco_hdr { |
891 | __le16 handle; | 891 | __le16 handle; |
892 | __u8 dlen; | 892 | __u8 dlen; |
893 | } __packed; | 893 | } __packed; |
894 | 894 | ||
895 | #ifdef __KERNEL__ | 895 | #ifdef __KERNEL__ |
896 | #include <linux/skbuff.h> | 896 | #include <linux/skbuff.h> |
897 | static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) | 897 | static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) |
898 | { | 898 | { |
899 | return (struct hci_event_hdr *) skb->data; | 899 | return (struct hci_event_hdr *) skb->data; |
900 | } | 900 | } |
901 | 901 | ||
902 | static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb) | 902 | static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb) |
903 | { | 903 | { |
904 | return (struct hci_acl_hdr *) skb->data; | 904 | return (struct hci_acl_hdr *) skb->data; |
905 | } | 905 | } |
906 | 906 | ||
907 | static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) | 907 | static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) |
908 | { | 908 | { |
909 | return (struct hci_sco_hdr *) skb->data; | 909 | return (struct hci_sco_hdr *) skb->data; |
910 | } | 910 | } |
911 | #endif | 911 | #endif |
912 | 912 | ||
913 | /* Command opcode pack/unpack */ | 913 | /* Command opcode pack/unpack */ |
914 | #define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10)) | 914 | #define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10)) |
915 | #define hci_opcode_ogf(op) (op >> 10) | 915 | #define hci_opcode_ogf(op) (op >> 10) |
916 | #define hci_opcode_ocf(op) (op & 0x03ff) | 916 | #define hci_opcode_ocf(op) (op & 0x03ff) |
917 | 917 | ||
918 | /* ACL handle and flags pack/unpack */ | 918 | /* ACL handle and flags pack/unpack */ |
919 | #define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12)) | 919 | #define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12)) |
920 | #define hci_handle(h) (h & 0x0fff) | 920 | #define hci_handle(h) (h & 0x0fff) |
921 | #define hci_flags(h) (h >> 12) | 921 | #define hci_flags(h) (h >> 12) |
922 | 922 | ||
923 | /* ---- HCI Sockets ---- */ | 923 | /* ---- HCI Sockets ---- */ |
924 | 924 | ||
925 | /* Socket options */ | 925 | /* Socket options */ |
926 | #define HCI_DATA_DIR 1 | 926 | #define HCI_DATA_DIR 1 |
927 | #define HCI_FILTER 2 | 927 | #define HCI_FILTER 2 |
928 | #define HCI_TIME_STAMP 3 | 928 | #define HCI_TIME_STAMP 3 |
929 | 929 | ||
930 | /* CMSG flags */ | 930 | /* CMSG flags */ |
931 | #define HCI_CMSG_DIR 0x0001 | 931 | #define HCI_CMSG_DIR 0x0001 |
932 | #define HCI_CMSG_TSTAMP 0x0002 | 932 | #define HCI_CMSG_TSTAMP 0x0002 |
933 | 933 | ||
934 | struct sockaddr_hci { | 934 | struct sockaddr_hci { |
935 | sa_family_t hci_family; | 935 | sa_family_t hci_family; |
936 | unsigned short hci_dev; | 936 | unsigned short hci_dev; |
937 | }; | 937 | }; |
938 | #define HCI_DEV_NONE 0xffff | 938 | #define HCI_DEV_NONE 0xffff |
939 | 939 | ||
940 | struct hci_filter { | 940 | struct hci_filter { |
941 | unsigned long type_mask; | 941 | unsigned long type_mask; |
942 | unsigned long event_mask[2]; | 942 | unsigned long event_mask[2]; |
943 | __le16 opcode; | 943 | __le16 opcode; |
944 | }; | 944 | }; |
945 | 945 | ||
946 | struct hci_ufilter { | 946 | struct hci_ufilter { |
947 | __u32 type_mask; | 947 | __u32 type_mask; |
948 | __u32 event_mask[2]; | 948 | __u32 event_mask[2]; |
949 | __le16 opcode; | 949 | __le16 opcode; |
950 | }; | 950 | }; |
951 | 951 | ||
952 | #define HCI_FLT_TYPE_BITS 31 | 952 | #define HCI_FLT_TYPE_BITS 31 |
953 | #define HCI_FLT_EVENT_BITS 63 | 953 | #define HCI_FLT_EVENT_BITS 63 |
954 | #define HCI_FLT_OGF_BITS 63 | 954 | #define HCI_FLT_OGF_BITS 63 |
955 | #define HCI_FLT_OCF_BITS 127 | 955 | #define HCI_FLT_OCF_BITS 127 |
956 | 956 | ||
957 | /* ---- HCI Ioctl requests structures ---- */ | 957 | /* ---- HCI Ioctl requests structures ---- */ |
958 | struct hci_dev_stats { | 958 | struct hci_dev_stats { |
959 | __u32 err_rx; | 959 | __u32 err_rx; |
960 | __u32 err_tx; | 960 | __u32 err_tx; |
961 | __u32 cmd_tx; | 961 | __u32 cmd_tx; |
962 | __u32 evt_rx; | 962 | __u32 evt_rx; |
963 | __u32 acl_tx; | 963 | __u32 acl_tx; |
964 | __u32 acl_rx; | 964 | __u32 acl_rx; |
965 | __u32 sco_tx; | 965 | __u32 sco_tx; |
966 | __u32 sco_rx; | 966 | __u32 sco_rx; |
967 | __u32 byte_rx; | 967 | __u32 byte_rx; |
968 | __u32 byte_tx; | 968 | __u32 byte_tx; |
969 | }; | 969 | }; |
970 | 970 | ||
971 | struct hci_dev_info { | 971 | struct hci_dev_info { |
972 | __u16 dev_id; | 972 | __u16 dev_id; |
973 | char name[8]; | 973 | char name[8]; |
974 | 974 | ||
975 | bdaddr_t bdaddr; | 975 | bdaddr_t bdaddr; |
976 | 976 | ||
977 | __u32 flags; | 977 | __u32 flags; |
978 | __u8 type; | 978 | __u8 type; |
979 | 979 | ||
980 | __u8 features[8]; | 980 | __u8 features[8]; |
981 | 981 | ||
982 | __u32 pkt_type; | 982 | __u32 pkt_type; |
983 | __u32 link_policy; | 983 | __u32 link_policy; |
984 | __u32 link_mode; | 984 | __u32 link_mode; |
985 | 985 | ||
986 | __u16 acl_mtu; | 986 | __u16 acl_mtu; |
987 | __u16 acl_pkts; | 987 | __u16 acl_pkts; |
988 | __u16 sco_mtu; | 988 | __u16 sco_mtu; |
989 | __u16 sco_pkts; | 989 | __u16 sco_pkts; |
990 | 990 | ||
991 | struct hci_dev_stats stat; | 991 | struct hci_dev_stats stat; |
992 | }; | 992 | }; |
993 | 993 | ||
994 | struct hci_conn_info { | 994 | struct hci_conn_info { |
995 | __u16 handle; | 995 | __u16 handle; |
996 | bdaddr_t bdaddr; | 996 | bdaddr_t bdaddr; |
997 | __u8 type; | 997 | __u8 type; |
998 | __u8 out; | 998 | __u8 out; |
999 | __u16 state; | 999 | __u16 state; |
1000 | __u32 link_mode; | 1000 | __u32 link_mode; |
1001 | }; | 1001 | }; |
1002 | 1002 | ||
1003 | struct hci_dev_req { | 1003 | struct hci_dev_req { |
1004 | __u16 dev_id; | 1004 | __u16 dev_id; |
1005 | __u32 dev_opt; | 1005 | __u32 dev_opt; |
1006 | }; | 1006 | }; |
1007 | 1007 | ||
1008 | struct hci_dev_list_req { | 1008 | struct hci_dev_list_req { |
1009 | __u16 dev_num; | 1009 | __u16 dev_num; |
1010 | struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ | 1010 | struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ |
1011 | }; | 1011 | }; |
1012 | 1012 | ||
1013 | struct hci_conn_list_req { | 1013 | struct hci_conn_list_req { |
1014 | __u16 dev_id; | 1014 | __u16 dev_id; |
1015 | __u16 conn_num; | 1015 | __u16 conn_num; |
1016 | struct hci_conn_info conn_info[0]; | 1016 | struct hci_conn_info conn_info[0]; |
1017 | }; | 1017 | }; |
1018 | 1018 | ||
1019 | struct hci_conn_info_req { | 1019 | struct hci_conn_info_req { |
1020 | bdaddr_t bdaddr; | 1020 | bdaddr_t bdaddr; |
1021 | __u8 type; | 1021 | __u8 type; |
1022 | struct hci_conn_info conn_info[0]; | 1022 | struct hci_conn_info conn_info[0]; |
1023 | }; | 1023 | }; |
1024 | 1024 | ||
1025 | struct hci_auth_info_req { | 1025 | struct hci_auth_info_req { |
1026 | bdaddr_t bdaddr; | 1026 | bdaddr_t bdaddr; |
1027 | __u8 type; | 1027 | __u8 type; |
1028 | }; | 1028 | }; |
1029 | 1029 | ||
1030 | struct hci_inquiry_req { | 1030 | struct hci_inquiry_req { |
1031 | __u16 dev_id; | 1031 | __u16 dev_id; |
1032 | __u16 flags; | 1032 | __u16 flags; |
1033 | __u8 lap[3]; | 1033 | __u8 lap[3]; |
1034 | __u8 length; | 1034 | __u8 length; |
1035 | __u8 num_rsp; | 1035 | __u8 num_rsp; |
1036 | }; | 1036 | }; |
1037 | #define IREQ_CACHE_FLUSH 0x0001 | 1037 | #define IREQ_CACHE_FLUSH 0x0001 |
1038 | 1038 | ||
1039 | #endif /* __HCI_H */ | 1039 | #endif /* __HCI_H */ |
1040 | 1040 |
net/bluetooth/hci_sysfs.c
1 | /* Bluetooth HCI driver model support. */ | 1 | /* Bluetooth HCI driver model support. */ |
2 | 2 | ||
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
7 | #include <linux/seq_file.h> | 7 | #include <linux/seq_file.h> |
8 | 8 | ||
9 | #include <net/bluetooth/bluetooth.h> | 9 | #include <net/bluetooth/bluetooth.h> |
10 | #include <net/bluetooth/hci_core.h> | 10 | #include <net/bluetooth/hci_core.h> |
11 | 11 | ||
12 | static struct class *bt_class; | 12 | static struct class *bt_class; |
13 | 13 | ||
14 | struct dentry *bt_debugfs = NULL; | 14 | struct dentry *bt_debugfs = NULL; |
15 | EXPORT_SYMBOL_GPL(bt_debugfs); | 15 | EXPORT_SYMBOL_GPL(bt_debugfs); |
16 | 16 | ||
17 | static inline char *link_typetostr(int type) | 17 | static inline char *link_typetostr(int type) |
18 | { | 18 | { |
19 | switch (type) { | 19 | switch (type) { |
20 | case ACL_LINK: | 20 | case ACL_LINK: |
21 | return "ACL"; | 21 | return "ACL"; |
22 | case SCO_LINK: | 22 | case SCO_LINK: |
23 | return "SCO"; | 23 | return "SCO"; |
24 | case ESCO_LINK: | 24 | case ESCO_LINK: |
25 | return "eSCO"; | 25 | return "eSCO"; |
26 | default: | 26 | default: |
27 | return "UNKNOWN"; | 27 | return "UNKNOWN"; |
28 | } | 28 | } |
29 | } | 29 | } |
30 | 30 | ||
31 | static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf) | 31 | static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf) |
32 | { | 32 | { |
33 | struct hci_conn *conn = dev_get_drvdata(dev); | 33 | struct hci_conn *conn = dev_get_drvdata(dev); |
34 | return sprintf(buf, "%s\n", link_typetostr(conn->type)); | 34 | return sprintf(buf, "%s\n", link_typetostr(conn->type)); |
35 | } | 35 | } |
36 | 36 | ||
37 | static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) | 37 | static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) |
38 | { | 38 | { |
39 | struct hci_conn *conn = dev_get_drvdata(dev); | 39 | struct hci_conn *conn = dev_get_drvdata(dev); |
40 | bdaddr_t bdaddr; | 40 | bdaddr_t bdaddr; |
41 | baswap(&bdaddr, &conn->dst); | 41 | baswap(&bdaddr, &conn->dst); |
42 | return sprintf(buf, "%s\n", batostr(&bdaddr)); | 42 | return sprintf(buf, "%s\n", batostr(&bdaddr)); |
43 | } | 43 | } |
44 | 44 | ||
45 | static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) | 45 | static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) |
46 | { | 46 | { |
47 | struct hci_conn *conn = dev_get_drvdata(dev); | 47 | struct hci_conn *conn = dev_get_drvdata(dev); |
48 | 48 | ||
49 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 49 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
50 | conn->features[0], conn->features[1], | 50 | conn->features[0], conn->features[1], |
51 | conn->features[2], conn->features[3], | 51 | conn->features[2], conn->features[3], |
52 | conn->features[4], conn->features[5], | 52 | conn->features[4], conn->features[5], |
53 | conn->features[6], conn->features[7]); | 53 | conn->features[6], conn->features[7]); |
54 | } | 54 | } |
55 | 55 | ||
56 | #define LINK_ATTR(_name,_mode,_show,_store) \ | 56 | #define LINK_ATTR(_name,_mode,_show,_store) \ |
57 | struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store) | 57 | struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store) |
58 | 58 | ||
59 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); | 59 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); |
60 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); | 60 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); |
61 | static LINK_ATTR(features, S_IRUGO, show_link_features, NULL); | 61 | static LINK_ATTR(features, S_IRUGO, show_link_features, NULL); |
62 | 62 | ||
63 | static struct attribute *bt_link_attrs[] = { | 63 | static struct attribute *bt_link_attrs[] = { |
64 | &link_attr_type.attr, | 64 | &link_attr_type.attr, |
65 | &link_attr_address.attr, | 65 | &link_attr_address.attr, |
66 | &link_attr_features.attr, | 66 | &link_attr_features.attr, |
67 | NULL | 67 | NULL |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static struct attribute_group bt_link_group = { | 70 | static struct attribute_group bt_link_group = { |
71 | .attrs = bt_link_attrs, | 71 | .attrs = bt_link_attrs, |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static const struct attribute_group *bt_link_groups[] = { | 74 | static const struct attribute_group *bt_link_groups[] = { |
75 | &bt_link_group, | 75 | &bt_link_group, |
76 | NULL | 76 | NULL |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static void bt_link_release(struct device *dev) | 79 | static void bt_link_release(struct device *dev) |
80 | { | 80 | { |
81 | void *data = dev_get_drvdata(dev); | 81 | void *data = dev_get_drvdata(dev); |
82 | kfree(data); | 82 | kfree(data); |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct device_type bt_link = { | 85 | static struct device_type bt_link = { |
86 | .name = "link", | 86 | .name = "link", |
87 | .groups = bt_link_groups, | 87 | .groups = bt_link_groups, |
88 | .release = bt_link_release, | 88 | .release = bt_link_release, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static void add_conn(struct work_struct *work) | 91 | static void add_conn(struct work_struct *work) |
92 | { | 92 | { |
93 | struct hci_conn *conn = container_of(work, struct hci_conn, work_add); | 93 | struct hci_conn *conn = container_of(work, struct hci_conn, work_add); |
94 | struct hci_dev *hdev = conn->hdev; | 94 | struct hci_dev *hdev = conn->hdev; |
95 | 95 | ||
96 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | 96 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
97 | 97 | ||
98 | dev_set_drvdata(&conn->dev, conn); | 98 | dev_set_drvdata(&conn->dev, conn); |
99 | 99 | ||
100 | if (device_add(&conn->dev) < 0) { | 100 | if (device_add(&conn->dev) < 0) { |
101 | BT_ERR("Failed to register connection device"); | 101 | BT_ERR("Failed to register connection device"); |
102 | return; | 102 | return; |
103 | } | 103 | } |
104 | 104 | ||
105 | hci_dev_hold(hdev); | 105 | hci_dev_hold(hdev); |
106 | } | 106 | } |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * The rfcomm tty device will possibly retain even when conn | 109 | * The rfcomm tty device will possibly retain even when conn |
110 | * is down, and sysfs doesn't support move zombie device, | 110 | * is down, and sysfs doesn't support move zombie device, |
111 | * so we should move the device before conn device is destroyed. | 111 | * so we should move the device before conn device is destroyed. |
112 | */ | 112 | */ |
113 | static int __match_tty(struct device *dev, void *data) | 113 | static int __match_tty(struct device *dev, void *data) |
114 | { | 114 | { |
115 | return !strncmp(dev_name(dev), "rfcomm", 6); | 115 | return !strncmp(dev_name(dev), "rfcomm", 6); |
116 | } | 116 | } |
117 | 117 | ||
118 | static void del_conn(struct work_struct *work) | 118 | static void del_conn(struct work_struct *work) |
119 | { | 119 | { |
120 | struct hci_conn *conn = container_of(work, struct hci_conn, work_del); | 120 | struct hci_conn *conn = container_of(work, struct hci_conn, work_del); |
121 | struct hci_dev *hdev = conn->hdev; | 121 | struct hci_dev *hdev = conn->hdev; |
122 | 122 | ||
123 | if (!device_is_registered(&conn->dev)) | 123 | if (!device_is_registered(&conn->dev)) |
124 | return; | 124 | return; |
125 | 125 | ||
126 | while (1) { | 126 | while (1) { |
127 | struct device *dev; | 127 | struct device *dev; |
128 | 128 | ||
129 | dev = device_find_child(&conn->dev, NULL, __match_tty); | 129 | dev = device_find_child(&conn->dev, NULL, __match_tty); |
130 | if (!dev) | 130 | if (!dev) |
131 | break; | 131 | break; |
132 | device_move(dev, NULL, DPM_ORDER_DEV_LAST); | 132 | device_move(dev, NULL, DPM_ORDER_DEV_LAST); |
133 | put_device(dev); | 133 | put_device(dev); |
134 | } | 134 | } |
135 | 135 | ||
136 | device_del(&conn->dev); | 136 | device_del(&conn->dev); |
137 | put_device(&conn->dev); | 137 | put_device(&conn->dev); |
138 | 138 | ||
139 | hci_dev_put(hdev); | 139 | hci_dev_put(hdev); |
140 | } | 140 | } |
141 | 141 | ||
142 | void hci_conn_init_sysfs(struct hci_conn *conn) | 142 | void hci_conn_init_sysfs(struct hci_conn *conn) |
143 | { | 143 | { |
144 | struct hci_dev *hdev = conn->hdev; | 144 | struct hci_dev *hdev = conn->hdev; |
145 | 145 | ||
146 | BT_DBG("conn %p", conn); | 146 | BT_DBG("conn %p", conn); |
147 | 147 | ||
148 | conn->dev.type = &bt_link; | 148 | conn->dev.type = &bt_link; |
149 | conn->dev.class = bt_class; | 149 | conn->dev.class = bt_class; |
150 | conn->dev.parent = &hdev->dev; | 150 | conn->dev.parent = &hdev->dev; |
151 | 151 | ||
152 | device_initialize(&conn->dev); | 152 | device_initialize(&conn->dev); |
153 | 153 | ||
154 | INIT_WORK(&conn->work_add, add_conn); | 154 | INIT_WORK(&conn->work_add, add_conn); |
155 | INIT_WORK(&conn->work_del, del_conn); | 155 | INIT_WORK(&conn->work_del, del_conn); |
156 | } | 156 | } |
157 | 157 | ||
158 | void hci_conn_add_sysfs(struct hci_conn *conn) | 158 | void hci_conn_add_sysfs(struct hci_conn *conn) |
159 | { | 159 | { |
160 | BT_DBG("conn %p", conn); | 160 | BT_DBG("conn %p", conn); |
161 | 161 | ||
162 | queue_work(conn->hdev->workqueue, &conn->work_add); | 162 | queue_work(conn->hdev->workqueue, &conn->work_add); |
163 | } | 163 | } |
164 | 164 | ||
165 | void hci_conn_del_sysfs(struct hci_conn *conn) | 165 | void hci_conn_del_sysfs(struct hci_conn *conn) |
166 | { | 166 | { |
167 | BT_DBG("conn %p", conn); | 167 | BT_DBG("conn %p", conn); |
168 | 168 | ||
169 | queue_work(conn->hdev->workqueue, &conn->work_del); | 169 | queue_work(conn->hdev->workqueue, &conn->work_del); |
170 | } | 170 | } |
171 | 171 | ||
172 | static inline char *host_bustostr(int bus) | 172 | static inline char *host_bustostr(int bus) |
173 | { | 173 | { |
174 | switch (bus) { | 174 | switch (bus) { |
175 | case HCI_VIRTUAL: | 175 | case HCI_VIRTUAL: |
176 | return "VIRTUAL"; | 176 | return "VIRTUAL"; |
177 | case HCI_USB: | 177 | case HCI_USB: |
178 | return "USB"; | 178 | return "USB"; |
179 | case HCI_PCCARD: | 179 | case HCI_PCCARD: |
180 | return "PCCARD"; | 180 | return "PCCARD"; |
181 | case HCI_UART: | 181 | case HCI_UART: |
182 | return "UART"; | 182 | return "UART"; |
183 | case HCI_RS232: | 183 | case HCI_RS232: |
184 | return "RS232"; | 184 | return "RS232"; |
185 | case HCI_PCI: | 185 | case HCI_PCI: |
186 | return "PCI"; | 186 | return "PCI"; |
187 | case HCI_SDIO: | 187 | case HCI_SDIO: |
188 | return "SDIO"; | 188 | return "SDIO"; |
189 | default: | 189 | default: |
190 | return "UNKNOWN"; | 190 | return "UNKNOWN"; |
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | static inline char *host_typetostr(int type) | 194 | static inline char *host_typetostr(int type) |
195 | { | 195 | { |
196 | switch (type) { | 196 | switch (type) { |
197 | case HCI_BREDR: | 197 | case HCI_BREDR: |
198 | return "BR/EDR"; | 198 | return "BR/EDR"; |
199 | case HCI_80211: | 199 | case HCI_AMP: |
200 | return "802.11"; | 200 | return "AMP"; |
201 | default: | 201 | default: |
202 | return "UNKNOWN"; | 202 | return "UNKNOWN"; |
203 | } | 203 | } |
204 | } | 204 | } |
205 | 205 | ||
206 | static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) | 206 | static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) |
207 | { | 207 | { |
208 | struct hci_dev *hdev = dev_get_drvdata(dev); | 208 | struct hci_dev *hdev = dev_get_drvdata(dev); |
209 | return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); | 209 | return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); |
210 | } | 210 | } |
211 | 211 | ||
212 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) | 212 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) |
213 | { | 213 | { |
214 | struct hci_dev *hdev = dev_get_drvdata(dev); | 214 | struct hci_dev *hdev = dev_get_drvdata(dev); |
215 | return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); | 215 | return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); |
216 | } | 216 | } |
217 | 217 | ||
218 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) | 218 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) |
219 | { | 219 | { |
220 | struct hci_dev *hdev = dev_get_drvdata(dev); | 220 | struct hci_dev *hdev = dev_get_drvdata(dev); |
221 | char name[249]; | 221 | char name[249]; |
222 | int i; | 222 | int i; |
223 | 223 | ||
224 | for (i = 0; i < 248; i++) | 224 | for (i = 0; i < 248; i++) |
225 | name[i] = hdev->dev_name[i]; | 225 | name[i] = hdev->dev_name[i]; |
226 | 226 | ||
227 | name[248] = '\0'; | 227 | name[248] = '\0'; |
228 | return sprintf(buf, "%s\n", name); | 228 | return sprintf(buf, "%s\n", name); |
229 | } | 229 | } |
230 | 230 | ||
231 | static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf) | 231 | static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf) |
232 | { | 232 | { |
233 | struct hci_dev *hdev = dev_get_drvdata(dev); | 233 | struct hci_dev *hdev = dev_get_drvdata(dev); |
234 | return sprintf(buf, "0x%.2x%.2x%.2x\n", | 234 | return sprintf(buf, "0x%.2x%.2x%.2x\n", |
235 | hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); | 235 | hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); |
236 | } | 236 | } |
237 | 237 | ||
238 | static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) | 238 | static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) |
239 | { | 239 | { |
240 | struct hci_dev *hdev = dev_get_drvdata(dev); | 240 | struct hci_dev *hdev = dev_get_drvdata(dev); |
241 | bdaddr_t bdaddr; | 241 | bdaddr_t bdaddr; |
242 | baswap(&bdaddr, &hdev->bdaddr); | 242 | baswap(&bdaddr, &hdev->bdaddr); |
243 | return sprintf(buf, "%s\n", batostr(&bdaddr)); | 243 | return sprintf(buf, "%s\n", batostr(&bdaddr)); |
244 | } | 244 | } |
245 | 245 | ||
246 | static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) | 246 | static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) |
247 | { | 247 | { |
248 | struct hci_dev *hdev = dev_get_drvdata(dev); | 248 | struct hci_dev *hdev = dev_get_drvdata(dev); |
249 | 249 | ||
250 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 250 | return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
251 | hdev->features[0], hdev->features[1], | 251 | hdev->features[0], hdev->features[1], |
252 | hdev->features[2], hdev->features[3], | 252 | hdev->features[2], hdev->features[3], |
253 | hdev->features[4], hdev->features[5], | 253 | hdev->features[4], hdev->features[5], |
254 | hdev->features[6], hdev->features[7]); | 254 | hdev->features[6], hdev->features[7]); |
255 | } | 255 | } |
256 | 256 | ||
257 | static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf) | 257 | static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf) |
258 | { | 258 | { |
259 | struct hci_dev *hdev = dev_get_drvdata(dev); | 259 | struct hci_dev *hdev = dev_get_drvdata(dev); |
260 | return sprintf(buf, "%d\n", hdev->manufacturer); | 260 | return sprintf(buf, "%d\n", hdev->manufacturer); |
261 | } | 261 | } |
262 | 262 | ||
263 | static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) | 263 | static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) |
264 | { | 264 | { |
265 | struct hci_dev *hdev = dev_get_drvdata(dev); | 265 | struct hci_dev *hdev = dev_get_drvdata(dev); |
266 | return sprintf(buf, "%d\n", hdev->hci_ver); | 266 | return sprintf(buf, "%d\n", hdev->hci_ver); |
267 | } | 267 | } |
268 | 268 | ||
269 | static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf) | 269 | static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf) |
270 | { | 270 | { |
271 | struct hci_dev *hdev = dev_get_drvdata(dev); | 271 | struct hci_dev *hdev = dev_get_drvdata(dev); |
272 | return sprintf(buf, "%d\n", hdev->hci_rev); | 272 | return sprintf(buf, "%d\n", hdev->hci_rev); |
273 | } | 273 | } |
274 | 274 | ||
275 | static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) | 275 | static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) |
276 | { | 276 | { |
277 | struct hci_dev *hdev = dev_get_drvdata(dev); | 277 | struct hci_dev *hdev = dev_get_drvdata(dev); |
278 | return sprintf(buf, "%d\n", hdev->idle_timeout); | 278 | return sprintf(buf, "%d\n", hdev->idle_timeout); |
279 | } | 279 | } |
280 | 280 | ||
281 | static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 281 | static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
282 | { | 282 | { |
283 | struct hci_dev *hdev = dev_get_drvdata(dev); | 283 | struct hci_dev *hdev = dev_get_drvdata(dev); |
284 | unsigned long val; | 284 | unsigned long val; |
285 | 285 | ||
286 | if (strict_strtoul(buf, 0, &val) < 0) | 286 | if (strict_strtoul(buf, 0, &val) < 0) |
287 | return -EINVAL; | 287 | return -EINVAL; |
288 | 288 | ||
289 | if (val != 0 && (val < 500 || val > 3600000)) | 289 | if (val != 0 && (val < 500 || val > 3600000)) |
290 | return -EINVAL; | 290 | return -EINVAL; |
291 | 291 | ||
292 | hdev->idle_timeout = val; | 292 | hdev->idle_timeout = val; |
293 | 293 | ||
294 | return count; | 294 | return count; |
295 | } | 295 | } |
296 | 296 | ||
297 | static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf) | 297 | static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf) |
298 | { | 298 | { |
299 | struct hci_dev *hdev = dev_get_drvdata(dev); | 299 | struct hci_dev *hdev = dev_get_drvdata(dev); |
300 | return sprintf(buf, "%d\n", hdev->sniff_max_interval); | 300 | return sprintf(buf, "%d\n", hdev->sniff_max_interval); |
301 | } | 301 | } |
302 | 302 | ||
303 | static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 303 | static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
304 | { | 304 | { |
305 | struct hci_dev *hdev = dev_get_drvdata(dev); | 305 | struct hci_dev *hdev = dev_get_drvdata(dev); |
306 | unsigned long val; | 306 | unsigned long val; |
307 | 307 | ||
308 | if (strict_strtoul(buf, 0, &val) < 0) | 308 | if (strict_strtoul(buf, 0, &val) < 0) |
309 | return -EINVAL; | 309 | return -EINVAL; |
310 | 310 | ||
311 | if (val < 0x0002 || val > 0xFFFE || val % 2) | 311 | if (val < 0x0002 || val > 0xFFFE || val % 2) |
312 | return -EINVAL; | 312 | return -EINVAL; |
313 | 313 | ||
314 | if (val < hdev->sniff_min_interval) | 314 | if (val < hdev->sniff_min_interval) |
315 | return -EINVAL; | 315 | return -EINVAL; |
316 | 316 | ||
317 | hdev->sniff_max_interval = val; | 317 | hdev->sniff_max_interval = val; |
318 | 318 | ||
319 | return count; | 319 | return count; |
320 | } | 320 | } |
321 | 321 | ||
322 | static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf) | 322 | static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf) |
323 | { | 323 | { |
324 | struct hci_dev *hdev = dev_get_drvdata(dev); | 324 | struct hci_dev *hdev = dev_get_drvdata(dev); |
325 | return sprintf(buf, "%d\n", hdev->sniff_min_interval); | 325 | return sprintf(buf, "%d\n", hdev->sniff_min_interval); |
326 | } | 326 | } |
327 | 327 | ||
328 | static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 328 | static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
329 | { | 329 | { |
330 | struct hci_dev *hdev = dev_get_drvdata(dev); | 330 | struct hci_dev *hdev = dev_get_drvdata(dev); |
331 | unsigned long val; | 331 | unsigned long val; |
332 | 332 | ||
333 | if (strict_strtoul(buf, 0, &val) < 0) | 333 | if (strict_strtoul(buf, 0, &val) < 0) |
334 | return -EINVAL; | 334 | return -EINVAL; |
335 | 335 | ||
336 | if (val < 0x0002 || val > 0xFFFE || val % 2) | 336 | if (val < 0x0002 || val > 0xFFFE || val % 2) |
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | 338 | ||
339 | if (val > hdev->sniff_max_interval) | 339 | if (val > hdev->sniff_max_interval) |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | 341 | ||
342 | hdev->sniff_min_interval = val; | 342 | hdev->sniff_min_interval = val; |
343 | 343 | ||
344 | return count; | 344 | return count; |
345 | } | 345 | } |
346 | 346 | ||
347 | static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); | 347 | static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); |
348 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | 348 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); |
349 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 349 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
350 | static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); | 350 | static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); |
351 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | 351 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); |
352 | static DEVICE_ATTR(features, S_IRUGO, show_features, NULL); | 352 | static DEVICE_ATTR(features, S_IRUGO, show_features, NULL); |
353 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); | 353 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); |
354 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); | 354 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); |
355 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); | 355 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); |
356 | 356 | ||
357 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, | 357 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, |
358 | show_idle_timeout, store_idle_timeout); | 358 | show_idle_timeout, store_idle_timeout); |
359 | static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, | 359 | static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, |
360 | show_sniff_max_interval, store_sniff_max_interval); | 360 | show_sniff_max_interval, store_sniff_max_interval); |
361 | static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, | 361 | static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, |
362 | show_sniff_min_interval, store_sniff_min_interval); | 362 | show_sniff_min_interval, store_sniff_min_interval); |
363 | 363 | ||
364 | static struct attribute *bt_host_attrs[] = { | 364 | static struct attribute *bt_host_attrs[] = { |
365 | &dev_attr_bus.attr, | 365 | &dev_attr_bus.attr, |
366 | &dev_attr_type.attr, | 366 | &dev_attr_type.attr, |
367 | &dev_attr_name.attr, | 367 | &dev_attr_name.attr, |
368 | &dev_attr_class.attr, | 368 | &dev_attr_class.attr, |
369 | &dev_attr_address.attr, | 369 | &dev_attr_address.attr, |
370 | &dev_attr_features.attr, | 370 | &dev_attr_features.attr, |
371 | &dev_attr_manufacturer.attr, | 371 | &dev_attr_manufacturer.attr, |
372 | &dev_attr_hci_version.attr, | 372 | &dev_attr_hci_version.attr, |
373 | &dev_attr_hci_revision.attr, | 373 | &dev_attr_hci_revision.attr, |
374 | &dev_attr_idle_timeout.attr, | 374 | &dev_attr_idle_timeout.attr, |
375 | &dev_attr_sniff_max_interval.attr, | 375 | &dev_attr_sniff_max_interval.attr, |
376 | &dev_attr_sniff_min_interval.attr, | 376 | &dev_attr_sniff_min_interval.attr, |
377 | NULL | 377 | NULL |
378 | }; | 378 | }; |
379 | 379 | ||
380 | static struct attribute_group bt_host_group = { | 380 | static struct attribute_group bt_host_group = { |
381 | .attrs = bt_host_attrs, | 381 | .attrs = bt_host_attrs, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | static const struct attribute_group *bt_host_groups[] = { | 384 | static const struct attribute_group *bt_host_groups[] = { |
385 | &bt_host_group, | 385 | &bt_host_group, |
386 | NULL | 386 | NULL |
387 | }; | 387 | }; |
388 | 388 | ||
389 | static void bt_host_release(struct device *dev) | 389 | static void bt_host_release(struct device *dev) |
390 | { | 390 | { |
391 | void *data = dev_get_drvdata(dev); | 391 | void *data = dev_get_drvdata(dev); |
392 | kfree(data); | 392 | kfree(data); |
393 | } | 393 | } |
394 | 394 | ||
395 | static struct device_type bt_host = { | 395 | static struct device_type bt_host = { |
396 | .name = "host", | 396 | .name = "host", |
397 | .groups = bt_host_groups, | 397 | .groups = bt_host_groups, |
398 | .release = bt_host_release, | 398 | .release = bt_host_release, |
399 | }; | 399 | }; |
400 | 400 | ||
401 | static int inquiry_cache_show(struct seq_file *f, void *p) | 401 | static int inquiry_cache_show(struct seq_file *f, void *p) |
402 | { | 402 | { |
403 | struct hci_dev *hdev = f->private; | 403 | struct hci_dev *hdev = f->private; |
404 | struct inquiry_cache *cache = &hdev->inq_cache; | 404 | struct inquiry_cache *cache = &hdev->inq_cache; |
405 | struct inquiry_entry *e; | 405 | struct inquiry_entry *e; |
406 | 406 | ||
407 | hci_dev_lock_bh(hdev); | 407 | hci_dev_lock_bh(hdev); |
408 | 408 | ||
409 | for (e = cache->list; e; e = e->next) { | 409 | for (e = cache->list; e; e = e->next) { |
410 | struct inquiry_data *data = &e->data; | 410 | struct inquiry_data *data = &e->data; |
411 | bdaddr_t bdaddr; | 411 | bdaddr_t bdaddr; |
412 | baswap(&bdaddr, &data->bdaddr); | 412 | baswap(&bdaddr, &data->bdaddr); |
413 | seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | 413 | seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", |
414 | batostr(&bdaddr), | 414 | batostr(&bdaddr), |
415 | data->pscan_rep_mode, data->pscan_period_mode, | 415 | data->pscan_rep_mode, data->pscan_period_mode, |
416 | data->pscan_mode, data->dev_class[2], | 416 | data->pscan_mode, data->dev_class[2], |
417 | data->dev_class[1], data->dev_class[0], | 417 | data->dev_class[1], data->dev_class[0], |
418 | __le16_to_cpu(data->clock_offset), | 418 | __le16_to_cpu(data->clock_offset), |
419 | data->rssi, data->ssp_mode, e->timestamp); | 419 | data->rssi, data->ssp_mode, e->timestamp); |
420 | } | 420 | } |
421 | 421 | ||
422 | hci_dev_unlock_bh(hdev); | 422 | hci_dev_unlock_bh(hdev); |
423 | 423 | ||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int inquiry_cache_open(struct inode *inode, struct file *file) | 427 | static int inquiry_cache_open(struct inode *inode, struct file *file) |
428 | { | 428 | { |
429 | return single_open(file, inquiry_cache_show, inode->i_private); | 429 | return single_open(file, inquiry_cache_show, inode->i_private); |
430 | } | 430 | } |
431 | 431 | ||
432 | static const struct file_operations inquiry_cache_fops = { | 432 | static const struct file_operations inquiry_cache_fops = { |
433 | .open = inquiry_cache_open, | 433 | .open = inquiry_cache_open, |
434 | .read = seq_read, | 434 | .read = seq_read, |
435 | .llseek = seq_lseek, | 435 | .llseek = seq_lseek, |
436 | .release = single_release, | 436 | .release = single_release, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | static int blacklist_show(struct seq_file *f, void *p) | 439 | static int blacklist_show(struct seq_file *f, void *p) |
440 | { | 440 | { |
441 | struct hci_dev *hdev = f->private; | 441 | struct hci_dev *hdev = f->private; |
442 | struct list_head *l; | 442 | struct list_head *l; |
443 | 443 | ||
444 | hci_dev_lock_bh(hdev); | 444 | hci_dev_lock_bh(hdev); |
445 | 445 | ||
446 | list_for_each(l, &hdev->blacklist) { | 446 | list_for_each(l, &hdev->blacklist) { |
447 | struct bdaddr_list *b; | 447 | struct bdaddr_list *b; |
448 | bdaddr_t bdaddr; | 448 | bdaddr_t bdaddr; |
449 | 449 | ||
450 | b = list_entry(l, struct bdaddr_list, list); | 450 | b = list_entry(l, struct bdaddr_list, list); |
451 | 451 | ||
452 | baswap(&bdaddr, &b->bdaddr); | 452 | baswap(&bdaddr, &b->bdaddr); |
453 | 453 | ||
454 | seq_printf(f, "%s\n", batostr(&bdaddr)); | 454 | seq_printf(f, "%s\n", batostr(&bdaddr)); |
455 | } | 455 | } |
456 | 456 | ||
457 | hci_dev_unlock_bh(hdev); | 457 | hci_dev_unlock_bh(hdev); |
458 | 458 | ||
459 | return 0; | 459 | return 0; |
460 | } | 460 | } |
461 | 461 | ||
462 | static int blacklist_open(struct inode *inode, struct file *file) | 462 | static int blacklist_open(struct inode *inode, struct file *file) |
463 | { | 463 | { |
464 | return single_open(file, blacklist_show, inode->i_private); | 464 | return single_open(file, blacklist_show, inode->i_private); |
465 | } | 465 | } |
466 | 466 | ||
467 | static const struct file_operations blacklist_fops = { | 467 | static const struct file_operations blacklist_fops = { |
468 | .open = blacklist_open, | 468 | .open = blacklist_open, |
469 | .read = seq_read, | 469 | .read = seq_read, |
470 | .llseek = seq_lseek, | 470 | .llseek = seq_lseek, |
471 | .release = single_release, | 471 | .release = single_release, |
472 | }; | 472 | }; |
473 | int hci_register_sysfs(struct hci_dev *hdev) | 473 | int hci_register_sysfs(struct hci_dev *hdev) |
474 | { | 474 | { |
475 | struct device *dev = &hdev->dev; | 475 | struct device *dev = &hdev->dev; |
476 | int err; | 476 | int err; |
477 | 477 | ||
478 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 478 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
479 | 479 | ||
480 | dev->type = &bt_host; | 480 | dev->type = &bt_host; |
481 | dev->class = bt_class; | 481 | dev->class = bt_class; |
482 | dev->parent = hdev->parent; | 482 | dev->parent = hdev->parent; |
483 | 483 | ||
484 | dev_set_name(dev, "%s", hdev->name); | 484 | dev_set_name(dev, "%s", hdev->name); |
485 | 485 | ||
486 | dev_set_drvdata(dev, hdev); | 486 | dev_set_drvdata(dev, hdev); |
487 | 487 | ||
488 | err = device_register(dev); | 488 | err = device_register(dev); |
489 | if (err < 0) | 489 | if (err < 0) |
490 | return err; | 490 | return err; |
491 | 491 | ||
492 | if (!bt_debugfs) | 492 | if (!bt_debugfs) |
493 | return 0; | 493 | return 0; |
494 | 494 | ||
495 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); | 495 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); |
496 | if (!hdev->debugfs) | 496 | if (!hdev->debugfs) |
497 | return 0; | 497 | return 0; |
498 | 498 | ||
499 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | 499 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, |
500 | hdev, &inquiry_cache_fops); | 500 | hdev, &inquiry_cache_fops); |
501 | 501 | ||
502 | debugfs_create_file("blacklist", 0444, hdev->debugfs, | 502 | debugfs_create_file("blacklist", 0444, hdev->debugfs, |
503 | hdev, &blacklist_fops); | 503 | hdev, &blacklist_fops); |
504 | 504 | ||
505 | return 0; | 505 | return 0; |
506 | } | 506 | } |
507 | 507 | ||
508 | void hci_unregister_sysfs(struct hci_dev *hdev) | 508 | void hci_unregister_sysfs(struct hci_dev *hdev) |
509 | { | 509 | { |
510 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 510 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
511 | 511 | ||
512 | debugfs_remove_recursive(hdev->debugfs); | 512 | debugfs_remove_recursive(hdev->debugfs); |
513 | 513 | ||
514 | device_del(&hdev->dev); | 514 | device_del(&hdev->dev); |
515 | } | 515 | } |
516 | 516 | ||
517 | int __init bt_sysfs_init(void) | 517 | int __init bt_sysfs_init(void) |
518 | { | 518 | { |
519 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); | 519 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); |
520 | 520 | ||
521 | bt_class = class_create(THIS_MODULE, "bluetooth"); | 521 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
522 | if (IS_ERR(bt_class)) | 522 | if (IS_ERR(bt_class)) |
523 | return PTR_ERR(bt_class); | 523 | return PTR_ERR(bt_class); |
524 | 524 | ||
525 | return 0; | 525 | return 0; |
526 | } | 526 | } |
527 | 527 | ||
528 | void bt_sysfs_cleanup(void) | 528 | void bt_sysfs_cleanup(void) |
529 | { | 529 | { |
530 | class_destroy(bt_class); | 530 | class_destroy(bt_class); |
531 | 531 | ||
532 | debugfs_remove_recursive(bt_debugfs); | 532 | debugfs_remove_recursive(bt_debugfs); |
533 | } | 533 | } |
534 | 534 |