diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-11-08 13:40:14 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-11-09 09:33:26 -0500 |
commit | 744cf19eadcf4de914394e0eb227f94f4318f5e4 (patch) | |
tree | a8c06c43be956e5db8db1bc1e052b773626892c6 /net/bluetooth/mgmt.c | |
parent | 4c659c3976e81f9def48993cd00988d53d7379f2 (diff) |
Bluetooth: Pass full hci_dev struct to mgmt callbacks
The current global pending command list in mgmt.c is racy. Possibly the
simplest way to fix it is to have per-hci dev lists instead of a global
one (all commands that need a pending struct are hci_dev specific).
This way the list can be protected using the already existing per-hci
dev lock. To enable this refactoring the first thing that needs to be
done is to ensure that the mgmt functions have access to the hci_dev
struct (instead of just the dev id).
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 206 |
1 files changed, 106 insertions, 100 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 4cb2f958fb10..2ca7b4427e34 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -255,7 +255,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
255 | return cmd; | 255 | return cmd; |
256 | } | 256 | } |
257 | 257 | ||
258 | static void mgmt_pending_foreach(u16 opcode, int index, | 258 | static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, |
259 | void (*cb)(struct pending_cmd *cmd, void *data), | 259 | void (*cb)(struct pending_cmd *cmd, void *data), |
260 | void *data) | 260 | void *data) |
261 | { | 261 | { |
@@ -269,7 +269,7 @@ static void mgmt_pending_foreach(u16 opcode, int index, | |||
269 | if (opcode > 0 && cmd->opcode != opcode) | 269 | if (opcode > 0 && cmd->opcode != opcode) |
270 | continue; | 270 | continue; |
271 | 271 | ||
272 | if (index >= 0 && cmd->index != index) | 272 | if (hdev && cmd->index != hdev->id) |
273 | continue; | 273 | continue; |
274 | 274 | ||
275 | cb(cmd, data); | 275 | cb(cmd, data); |
@@ -475,8 +475,8 @@ failed: | |||
475 | return err; | 475 | return err; |
476 | } | 476 | } |
477 | 477 | ||
478 | static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | 478 | static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, |
479 | struct sock *skip_sk) | 479 | u16 data_len, struct sock *skip_sk) |
480 | { | 480 | { |
481 | struct sk_buff *skb; | 481 | struct sk_buff *skb; |
482 | struct mgmt_hdr *hdr; | 482 | struct mgmt_hdr *hdr; |
@@ -489,7 +489,10 @@ static int mgmt_event(u16 event, u16 index, void *data, u16 data_len, | |||
489 | 489 | ||
490 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 490 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
491 | hdr->opcode = cpu_to_le16(event); | 491 | hdr->opcode = cpu_to_le16(event); |
492 | hdr->index = cpu_to_le16(index); | 492 | if (hdev) |
493 | hdr->index = cpu_to_le16(hdev->id); | ||
494 | else | ||
495 | hdr->index = cpu_to_le16(MGMT_INDEX_NONE); | ||
493 | hdr->len = cpu_to_le16(data_len); | 496 | hdr->len = cpu_to_le16(data_len); |
494 | 497 | ||
495 | if (data) | 498 | if (data) |
@@ -541,7 +544,7 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
541 | 544 | ||
542 | ev.val = cp->val; | 545 | ev.val = cp->val; |
543 | 546 | ||
544 | err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk); | 547 | err = mgmt_event(MGMT_EV_PAIRABLE, hdev, &ev, sizeof(ev), sk); |
545 | 548 | ||
546 | failed: | 549 | failed: |
547 | hci_dev_unlock_bh(hdev); | 550 | hci_dev_unlock_bh(hdev); |
@@ -1966,18 +1969,18 @@ static void cmd_status_rsp(struct pending_cmd *cmd, void *data) | |||
1966 | mgmt_pending_remove(cmd); | 1969 | mgmt_pending_remove(cmd); |
1967 | } | 1970 | } |
1968 | 1971 | ||
1969 | int mgmt_index_added(u16 index) | 1972 | int mgmt_index_added(struct hci_dev *hdev) |
1970 | { | 1973 | { |
1971 | return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL); | 1974 | return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL); |
1972 | } | 1975 | } |
1973 | 1976 | ||
1974 | int mgmt_index_removed(u16 index) | 1977 | int mgmt_index_removed(struct hci_dev *hdev) |
1975 | { | 1978 | { |
1976 | u8 status = ENODEV; | 1979 | u8 status = ENODEV; |
1977 | 1980 | ||
1978 | mgmt_pending_foreach(0, index, cmd_status_rsp, &status); | 1981 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); |
1979 | 1982 | ||
1980 | return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL); | 1983 | return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL); |
1981 | } | 1984 | } |
1982 | 1985 | ||
1983 | struct cmd_lookup { | 1986 | struct cmd_lookup { |
@@ -2005,22 +2008,22 @@ static void mode_rsp(struct pending_cmd *cmd, void *data) | |||
2005 | mgmt_pending_free(cmd); | 2008 | mgmt_pending_free(cmd); |
2006 | } | 2009 | } |
2007 | 2010 | ||
2008 | int mgmt_powered(u16 index, u8 powered) | 2011 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
2009 | { | 2012 | { |
2010 | struct mgmt_mode ev; | 2013 | struct mgmt_mode ev; |
2011 | struct cmd_lookup match = { powered, NULL }; | 2014 | struct cmd_lookup match = { powered, NULL }; |
2012 | int ret; | 2015 | int ret; |
2013 | 2016 | ||
2014 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | 2017 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, mode_rsp, &match); |
2015 | 2018 | ||
2016 | if (!powered) { | 2019 | if (!powered) { |
2017 | u8 status = ENETDOWN; | 2020 | u8 status = ENETDOWN; |
2018 | mgmt_pending_foreach(0, index, cmd_status_rsp, &status); | 2021 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); |
2019 | } | 2022 | } |
2020 | 2023 | ||
2021 | ev.val = powered; | 2024 | ev.val = powered; |
2022 | 2025 | ||
2023 | ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk); | 2026 | ret = mgmt_event(MGMT_EV_POWERED, hdev, &ev, sizeof(ev), match.sk); |
2024 | 2027 | ||
2025 | if (match.sk) | 2028 | if (match.sk) |
2026 | sock_put(match.sk); | 2029 | sock_put(match.sk); |
@@ -2028,17 +2031,17 @@ int mgmt_powered(u16 index, u8 powered) | |||
2028 | return ret; | 2031 | return ret; |
2029 | } | 2032 | } |
2030 | 2033 | ||
2031 | int mgmt_discoverable(u16 index, u8 discoverable) | 2034 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2032 | { | 2035 | { |
2033 | struct mgmt_mode ev; | 2036 | struct mgmt_mode ev; |
2034 | struct cmd_lookup match = { discoverable, NULL }; | 2037 | struct cmd_lookup match = { discoverable, NULL }; |
2035 | int ret; | 2038 | int ret; |
2036 | 2039 | ||
2037 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match); | 2040 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, mode_rsp, &match); |
2038 | 2041 | ||
2039 | ev.val = discoverable; | 2042 | ev.val = discoverable; |
2040 | 2043 | ||
2041 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev), | 2044 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, hdev, &ev, sizeof(ev), |
2042 | match.sk); | 2045 | match.sk); |
2043 | 2046 | ||
2044 | if (match.sk) | 2047 | if (match.sk) |
@@ -2047,17 +2050,17 @@ int mgmt_discoverable(u16 index, u8 discoverable) | |||
2047 | return ret; | 2050 | return ret; |
2048 | } | 2051 | } |
2049 | 2052 | ||
2050 | int mgmt_connectable(u16 index, u8 connectable) | 2053 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
2051 | { | 2054 | { |
2052 | struct mgmt_mode ev; | 2055 | struct mgmt_mode ev; |
2053 | struct cmd_lookup match = { connectable, NULL }; | 2056 | struct cmd_lookup match = { connectable, NULL }; |
2054 | int ret; | 2057 | int ret; |
2055 | 2058 | ||
2056 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | 2059 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, mode_rsp, &match); |
2057 | 2060 | ||
2058 | ev.val = connectable; | 2061 | ev.val = connectable; |
2059 | 2062 | ||
2060 | ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk); | 2063 | ret = mgmt_event(MGMT_EV_CONNECTABLE, hdev, &ev, sizeof(ev), match.sk); |
2061 | 2064 | ||
2062 | if (match.sk) | 2065 | if (match.sk) |
2063 | sock_put(match.sk); | 2066 | sock_put(match.sk); |
@@ -2065,20 +2068,21 @@ int mgmt_connectable(u16 index, u8 connectable) | |||
2065 | return ret; | 2068 | return ret; |
2066 | } | 2069 | } |
2067 | 2070 | ||
2068 | int mgmt_write_scan_failed(u16 index, u8 scan, u8 status) | 2071 | int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) |
2069 | { | 2072 | { |
2070 | if (scan & SCAN_PAGE) | 2073 | if (scan & SCAN_PAGE) |
2071 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, | 2074 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, |
2072 | cmd_status_rsp, &status); | 2075 | cmd_status_rsp, &status); |
2073 | 2076 | ||
2074 | if (scan & SCAN_INQUIRY) | 2077 | if (scan & SCAN_INQUIRY) |
2075 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, | 2078 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, |
2076 | cmd_status_rsp, &status); | 2079 | cmd_status_rsp, &status); |
2077 | 2080 | ||
2078 | return 0; | 2081 | return 0; |
2079 | } | 2082 | } |
2080 | 2083 | ||
2081 | int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent) | 2084 | int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, |
2085 | u8 persistent) | ||
2082 | { | 2086 | { |
2083 | struct mgmt_ev_new_link_key ev; | 2087 | struct mgmt_ev_new_link_key ev; |
2084 | 2088 | ||
@@ -2090,17 +2094,17 @@ int mgmt_new_link_key(u16 index, struct link_key *key, u8 persistent) | |||
2090 | memcpy(ev.key.val, key->val, 16); | 2094 | memcpy(ev.key.val, key->val, 16); |
2091 | ev.key.pin_len = key->pin_len; | 2095 | ev.key.pin_len = key->pin_len; |
2092 | 2096 | ||
2093 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, index, &ev, sizeof(ev), NULL); | 2097 | return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
2094 | } | 2098 | } |
2095 | 2099 | ||
2096 | int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type) | 2100 | int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type) |
2097 | { | 2101 | { |
2098 | struct mgmt_addr_info ev; | 2102 | struct mgmt_addr_info ev; |
2099 | 2103 | ||
2100 | bacpy(&ev.bdaddr, bdaddr); | 2104 | bacpy(&ev.bdaddr, bdaddr); |
2101 | ev.type = link_to_mgmt(link_type); | 2105 | ev.type = link_to_mgmt(link_type); |
2102 | 2106 | ||
2103 | return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL); | 2107 | return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL); |
2104 | } | 2108 | } |
2105 | 2109 | ||
2106 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | 2110 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) |
@@ -2119,18 +2123,18 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data) | |||
2119 | mgmt_pending_remove(cmd); | 2123 | mgmt_pending_remove(cmd); |
2120 | } | 2124 | } |
2121 | 2125 | ||
2122 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type) | 2126 | int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) |
2123 | { | 2127 | { |
2124 | struct mgmt_addr_info ev; | 2128 | struct mgmt_addr_info ev; |
2125 | struct sock *sk = NULL; | 2129 | struct sock *sk = NULL; |
2126 | int err; | 2130 | int err; |
2127 | 2131 | ||
2128 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | 2132 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); |
2129 | 2133 | ||
2130 | bacpy(&ev.bdaddr, bdaddr); | 2134 | bacpy(&ev.bdaddr, bdaddr); |
2131 | ev.type = link_to_mgmt(type); | 2135 | ev.type = link_to_mgmt(type); |
2132 | 2136 | ||
2133 | err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk); | 2137 | err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk); |
2134 | 2138 | ||
2135 | if (sk) | 2139 | if (sk) |
2136 | sock_put(sk); | 2140 | sock_put(sk); |
@@ -2138,23 +2142,24 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 type) | |||
2138 | return err; | 2142 | return err; |
2139 | } | 2143 | } |
2140 | 2144 | ||
2141 | int mgmt_disconnect_failed(u16 index) | 2145 | int mgmt_disconnect_failed(struct hci_dev *hdev) |
2142 | { | 2146 | { |
2143 | struct pending_cmd *cmd; | 2147 | struct pending_cmd *cmd; |
2144 | int err; | 2148 | int err; |
2145 | 2149 | ||
2146 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index); | 2150 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev->id); |
2147 | if (!cmd) | 2151 | if (!cmd) |
2148 | return -ENOENT; | 2152 | return -ENOENT; |
2149 | 2153 | ||
2150 | err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO); | 2154 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT, EIO); |
2151 | 2155 | ||
2152 | mgmt_pending_remove(cmd); | 2156 | mgmt_pending_remove(cmd); |
2153 | 2157 | ||
2154 | return err; | 2158 | return err; |
2155 | } | 2159 | } |
2156 | 2160 | ||
2157 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status) | 2161 | int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2162 | u8 status) | ||
2158 | { | 2163 | { |
2159 | struct mgmt_ev_connect_failed ev; | 2164 | struct mgmt_ev_connect_failed ev; |
2160 | 2165 | ||
@@ -2162,34 +2167,35 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 type, u8 status) | |||
2162 | ev.addr.type = link_to_mgmt(type); | 2167 | ev.addr.type = link_to_mgmt(type); |
2163 | ev.status = status; | 2168 | ev.status = status; |
2164 | 2169 | ||
2165 | return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL); | 2170 | return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL); |
2166 | } | 2171 | } |
2167 | 2172 | ||
2168 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure) | 2173 | int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure) |
2169 | { | 2174 | { |
2170 | struct mgmt_ev_pin_code_request ev; | 2175 | struct mgmt_ev_pin_code_request ev; |
2171 | 2176 | ||
2172 | bacpy(&ev.bdaddr, bdaddr); | 2177 | bacpy(&ev.bdaddr, bdaddr); |
2173 | ev.secure = secure; | 2178 | ev.secure = secure; |
2174 | 2179 | ||
2175 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev), | 2180 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev), |
2176 | NULL); | 2181 | NULL); |
2177 | } | 2182 | } |
2178 | 2183 | ||
2179 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2184 | int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2185 | u8 status) | ||
2180 | { | 2186 | { |
2181 | struct pending_cmd *cmd; | 2187 | struct pending_cmd *cmd; |
2182 | struct mgmt_rp_pin_code_reply rp; | 2188 | struct mgmt_rp_pin_code_reply rp; |
2183 | int err; | 2189 | int err; |
2184 | 2190 | ||
2185 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | 2191 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev->id); |
2186 | if (!cmd) | 2192 | if (!cmd) |
2187 | return -ENOENT; | 2193 | return -ENOENT; |
2188 | 2194 | ||
2189 | bacpy(&rp.bdaddr, bdaddr); | 2195 | bacpy(&rp.bdaddr, bdaddr); |
2190 | rp.status = status; | 2196 | rp.status = status; |
2191 | 2197 | ||
2192 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp, | 2198 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp, |
2193 | sizeof(rp)); | 2199 | sizeof(rp)); |
2194 | 2200 | ||
2195 | mgmt_pending_remove(cmd); | 2201 | mgmt_pending_remove(cmd); |
@@ -2197,20 +2203,21 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2197 | return err; | 2203 | return err; |
2198 | } | 2204 | } |
2199 | 2205 | ||
2200 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2206 | int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2207 | u8 status) | ||
2201 | { | 2208 | { |
2202 | struct pending_cmd *cmd; | 2209 | struct pending_cmd *cmd; |
2203 | struct mgmt_rp_pin_code_reply rp; | 2210 | struct mgmt_rp_pin_code_reply rp; |
2204 | int err; | 2211 | int err; |
2205 | 2212 | ||
2206 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | 2213 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev->id); |
2207 | if (!cmd) | 2214 | if (!cmd) |
2208 | return -ENOENT; | 2215 | return -ENOENT; |
2209 | 2216 | ||
2210 | bacpy(&rp.bdaddr, bdaddr); | 2217 | bacpy(&rp.bdaddr, bdaddr); |
2211 | rp.status = status; | 2218 | rp.status = status; |
2212 | 2219 | ||
2213 | err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, | 2220 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp, |
2214 | sizeof(rp)); | 2221 | sizeof(rp)); |
2215 | 2222 | ||
2216 | mgmt_pending_remove(cmd); | 2223 | mgmt_pending_remove(cmd); |
@@ -2218,97 +2225,95 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | |||
2218 | return err; | 2225 | return err; |
2219 | } | 2226 | } |
2220 | 2227 | ||
2221 | int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value, | 2228 | int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2222 | u8 confirm_hint) | 2229 | __le32 value, u8 confirm_hint) |
2223 | { | 2230 | { |
2224 | struct mgmt_ev_user_confirm_request ev; | 2231 | struct mgmt_ev_user_confirm_request ev; |
2225 | 2232 | ||
2226 | BT_DBG("hci%u", index); | 2233 | BT_DBG("%s", hdev->name); |
2227 | 2234 | ||
2228 | bacpy(&ev.bdaddr, bdaddr); | 2235 | bacpy(&ev.bdaddr, bdaddr); |
2229 | ev.confirm_hint = confirm_hint; | 2236 | ev.confirm_hint = confirm_hint; |
2230 | put_unaligned_le32(value, &ev.value); | 2237 | put_unaligned_le32(value, &ev.value); |
2231 | 2238 | ||
2232 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev), | 2239 | return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev), |
2233 | NULL); | 2240 | NULL); |
2234 | } | 2241 | } |
2235 | 2242 | ||
2236 | static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status, | 2243 | static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2237 | u8 opcode) | 2244 | u8 status, u8 opcode) |
2238 | { | 2245 | { |
2239 | struct pending_cmd *cmd; | 2246 | struct pending_cmd *cmd; |
2240 | struct mgmt_rp_user_confirm_reply rp; | 2247 | struct mgmt_rp_user_confirm_reply rp; |
2241 | int err; | 2248 | int err; |
2242 | 2249 | ||
2243 | cmd = mgmt_pending_find(opcode, index); | 2250 | cmd = mgmt_pending_find(opcode, hdev->id); |
2244 | if (!cmd) | 2251 | if (!cmd) |
2245 | return -ENOENT; | 2252 | return -ENOENT; |
2246 | 2253 | ||
2247 | bacpy(&rp.bdaddr, bdaddr); | 2254 | bacpy(&rp.bdaddr, bdaddr); |
2248 | rp.status = status; | 2255 | rp.status = status; |
2249 | err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp)); | 2256 | err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp)); |
2250 | 2257 | ||
2251 | mgmt_pending_remove(cmd); | 2258 | mgmt_pending_remove(cmd); |
2252 | 2259 | ||
2253 | return err; | 2260 | return err; |
2254 | } | 2261 | } |
2255 | 2262 | ||
2256 | int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2263 | int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, |
2264 | u8 status) | ||
2257 | { | 2265 | { |
2258 | return confirm_reply_complete(index, bdaddr, status, | 2266 | return confirm_reply_complete(hdev, bdaddr, status, |
2259 | MGMT_OP_USER_CONFIRM_REPLY); | 2267 | MGMT_OP_USER_CONFIRM_REPLY); |
2260 | } | 2268 | } |
2261 | 2269 | ||
2262 | int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | 2270 | int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, |
2271 | bdaddr_t *bdaddr, u8 status) | ||
2263 | { | 2272 | { |
2264 | return confirm_reply_complete(index, bdaddr, status, | 2273 | return confirm_reply_complete(hdev, bdaddr, status, |
2265 | MGMT_OP_USER_CONFIRM_NEG_REPLY); | 2274 | MGMT_OP_USER_CONFIRM_NEG_REPLY); |
2266 | } | 2275 | } |
2267 | 2276 | ||
2268 | int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status) | 2277 | int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status) |
2269 | { | 2278 | { |
2270 | struct mgmt_ev_auth_failed ev; | 2279 | struct mgmt_ev_auth_failed ev; |
2271 | 2280 | ||
2272 | bacpy(&ev.bdaddr, bdaddr); | 2281 | bacpy(&ev.bdaddr, bdaddr); |
2273 | ev.status = status; | 2282 | ev.status = status; |
2274 | 2283 | ||
2275 | return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL); | 2284 | return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); |
2276 | } | 2285 | } |
2277 | 2286 | ||
2278 | int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status) | 2287 | int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) |
2279 | { | 2288 | { |
2280 | struct pending_cmd *cmd; | 2289 | struct pending_cmd *cmd; |
2281 | struct hci_dev *hdev; | ||
2282 | struct mgmt_cp_set_local_name ev; | 2290 | struct mgmt_cp_set_local_name ev; |
2283 | int err; | 2291 | int err; |
2284 | 2292 | ||
2285 | memset(&ev, 0, sizeof(ev)); | 2293 | memset(&ev, 0, sizeof(ev)); |
2286 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2294 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2287 | 2295 | ||
2288 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index); | 2296 | cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev->id); |
2289 | if (!cmd) | 2297 | if (!cmd) |
2290 | goto send_event; | 2298 | goto send_event; |
2291 | 2299 | ||
2292 | if (status) { | 2300 | if (status) { |
2293 | err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO); | 2301 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, |
2302 | EIO); | ||
2294 | goto failed; | 2303 | goto failed; |
2295 | } | 2304 | } |
2296 | 2305 | ||
2297 | hdev = hci_dev_get(index); | 2306 | hci_dev_lock_bh(hdev); |
2298 | if (hdev) { | 2307 | update_eir(hdev); |
2299 | hci_dev_lock_bh(hdev); | 2308 | hci_dev_unlock_bh(hdev); |
2300 | update_eir(hdev); | ||
2301 | hci_dev_unlock_bh(hdev); | ||
2302 | hci_dev_put(hdev); | ||
2303 | } | ||
2304 | 2309 | ||
2305 | err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev, | 2310 | err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev, |
2306 | sizeof(ev)); | 2311 | sizeof(ev)); |
2307 | if (err < 0) | 2312 | if (err < 0) |
2308 | goto failed; | 2313 | goto failed; |
2309 | 2314 | ||
2310 | send_event: | 2315 | send_event: |
2311 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev), | 2316 | err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), |
2312 | cmd ? cmd->sk : NULL); | 2317 | cmd ? cmd->sk : NULL); |
2313 | 2318 | ||
2314 | failed: | 2319 | failed: |
@@ -2317,29 +2322,30 @@ failed: | |||
2317 | return err; | 2322 | return err; |
2318 | } | 2323 | } |
2319 | 2324 | ||
2320 | int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | 2325 | int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, |
2321 | u8 status) | 2326 | u8 *randomizer, u8 status) |
2322 | { | 2327 | { |
2323 | struct pending_cmd *cmd; | 2328 | struct pending_cmd *cmd; |
2324 | int err; | 2329 | int err; |
2325 | 2330 | ||
2326 | BT_DBG("hci%u status %u", index, status); | 2331 | BT_DBG("%s status %u", hdev->name, status); |
2327 | 2332 | ||
2328 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index); | 2333 | cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev->id); |
2329 | if (!cmd) | 2334 | if (!cmd) |
2330 | return -ENOENT; | 2335 | return -ENOENT; |
2331 | 2336 | ||
2332 | if (status) { | 2337 | if (status) { |
2333 | err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2338 | err = cmd_status(cmd->sk, hdev->id, |
2334 | EIO); | 2339 | MGMT_OP_READ_LOCAL_OOB_DATA, EIO); |
2335 | } else { | 2340 | } else { |
2336 | struct mgmt_rp_read_local_oob_data rp; | 2341 | struct mgmt_rp_read_local_oob_data rp; |
2337 | 2342 | ||
2338 | memcpy(rp.hash, hash, sizeof(rp.hash)); | 2343 | memcpy(rp.hash, hash, sizeof(rp.hash)); |
2339 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); | 2344 | memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer)); |
2340 | 2345 | ||
2341 | err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2346 | err = cmd_complete(cmd->sk, hdev->id, |
2342 | &rp, sizeof(rp)); | 2347 | MGMT_OP_READ_LOCAL_OOB_DATA, |
2348 | &rp, sizeof(rp)); | ||
2343 | } | 2349 | } |
2344 | 2350 | ||
2345 | mgmt_pending_remove(cmd); | 2351 | mgmt_pending_remove(cmd); |
@@ -2347,8 +2353,8 @@ int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer, | |||
2347 | return err; | 2353 | return err; |
2348 | } | 2354 | } |
2349 | 2355 | ||
2350 | int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class, | 2356 | int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, |
2351 | s8 rssi, u8 *eir) | 2357 | u8 *dev_class, s8 rssi, u8 *eir) |
2352 | { | 2358 | { |
2353 | struct mgmt_ev_device_found ev; | 2359 | struct mgmt_ev_device_found ev; |
2354 | 2360 | ||
@@ -2364,10 +2370,10 @@ int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 *dev_class, | |||
2364 | if (dev_class) | 2370 | if (dev_class) |
2365 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); | 2371 | memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class)); |
2366 | 2372 | ||
2367 | return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL); | 2373 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL); |
2368 | } | 2374 | } |
2369 | 2375 | ||
2370 | int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | 2376 | int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name) |
2371 | { | 2377 | { |
2372 | struct mgmt_ev_remote_name ev; | 2378 | struct mgmt_ev_remote_name ev; |
2373 | 2379 | ||
@@ -2376,64 +2382,64 @@ int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name) | |||
2376 | bacpy(&ev.bdaddr, bdaddr); | 2382 | bacpy(&ev.bdaddr, bdaddr); |
2377 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); | 2383 | memcpy(ev.name, name, HCI_MAX_NAME_LENGTH); |
2378 | 2384 | ||
2379 | return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL); | 2385 | return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL); |
2380 | } | 2386 | } |
2381 | 2387 | ||
2382 | int mgmt_inquiry_failed(u16 index, u8 status) | 2388 | int mgmt_inquiry_failed(struct hci_dev *hdev, u8 status) |
2383 | { | 2389 | { |
2384 | struct pending_cmd *cmd; | 2390 | struct pending_cmd *cmd; |
2385 | int err; | 2391 | int err; |
2386 | 2392 | ||
2387 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index); | 2393 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); |
2388 | if (!cmd) | 2394 | if (!cmd) |
2389 | return -ENOENT; | 2395 | return -ENOENT; |
2390 | 2396 | ||
2391 | err = cmd_status(cmd->sk, index, cmd->opcode, status); | 2397 | err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status); |
2392 | mgmt_pending_remove(cmd); | 2398 | mgmt_pending_remove(cmd); |
2393 | 2399 | ||
2394 | return err; | 2400 | return err; |
2395 | } | 2401 | } |
2396 | 2402 | ||
2397 | int mgmt_discovering(u16 index, u8 discovering) | 2403 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) |
2398 | { | 2404 | { |
2399 | struct pending_cmd *cmd; | 2405 | struct pending_cmd *cmd; |
2400 | 2406 | ||
2401 | if (discovering) | 2407 | if (discovering) |
2402 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index); | 2408 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev->id); |
2403 | else | 2409 | else |
2404 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, index); | 2410 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev->id); |
2405 | 2411 | ||
2406 | if (cmd != NULL) { | 2412 | if (cmd != NULL) { |
2407 | cmd_complete(cmd->sk, index, cmd->opcode, NULL, 0); | 2413 | cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0); |
2408 | mgmt_pending_remove(cmd); | 2414 | mgmt_pending_remove(cmd); |
2409 | } | 2415 | } |
2410 | 2416 | ||
2411 | return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering, | 2417 | return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering, |
2412 | sizeof(discovering), NULL); | 2418 | sizeof(discovering), NULL); |
2413 | } | 2419 | } |
2414 | 2420 | ||
2415 | int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr) | 2421 | int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2416 | { | 2422 | { |
2417 | struct pending_cmd *cmd; | 2423 | struct pending_cmd *cmd; |
2418 | struct mgmt_ev_device_blocked ev; | 2424 | struct mgmt_ev_device_blocked ev; |
2419 | 2425 | ||
2420 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index); | 2426 | cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev->id); |
2421 | 2427 | ||
2422 | bacpy(&ev.bdaddr, bdaddr); | 2428 | bacpy(&ev.bdaddr, bdaddr); |
2423 | 2429 | ||
2424 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev), | 2430 | return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev), |
2425 | cmd ? cmd->sk : NULL); | 2431 | cmd ? cmd->sk : NULL); |
2426 | } | 2432 | } |
2427 | 2433 | ||
2428 | int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr) | 2434 | int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr) |
2429 | { | 2435 | { |
2430 | struct pending_cmd *cmd; | 2436 | struct pending_cmd *cmd; |
2431 | struct mgmt_ev_device_unblocked ev; | 2437 | struct mgmt_ev_device_unblocked ev; |
2432 | 2438 | ||
2433 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index); | 2439 | cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev->id); |
2434 | 2440 | ||
2435 | bacpy(&ev.bdaddr, bdaddr); | 2441 | bacpy(&ev.bdaddr, bdaddr); |
2436 | 2442 | ||
2437 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev), | 2443 | return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev), |
2438 | cmd ? cmd->sk : NULL); | 2444 | cmd ? cmd->sk : NULL); |
2439 | } | 2445 | } |