diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-27 23:13:32 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-03-01 16:55:58 -0500 |
commit | bdb6d97154b7b7e98867e9b71bae0f47ec70b1d7 (patch) | |
tree | 73d3cc5c3204ec55164c8f111ba58d1004b63627 /net/bluetooth | |
parent | 75fb0e324daa48ec458fb5c2960eb07b80cfad9d (diff) |
Bluetooth: mgmt: Refactor hci_dev lookup for commands
Almost all mgmt commands need to lookup a struct hci_dev based on the
index received within the mgmt headers. It makese therefore sense to
look this up in a single place and then just pass the hdev pointer to
each command handler function.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/mgmt.c | 764 |
1 files changed, 274 insertions, 490 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 3fcccad75453..cc9fb64def90 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -624,17 +624,11 @@ static void mgmt_init_hdev(struct hci_dev *hdev) | |||
624 | } | 624 | } |
625 | } | 625 | } |
626 | 626 | ||
627 | static int read_controller_info(struct sock *sk, u16 index) | 627 | static int read_controller_info(struct sock *sk, struct hci_dev *hdev) |
628 | { | 628 | { |
629 | struct mgmt_rp_read_info rp; | 629 | struct mgmt_rp_read_info rp; |
630 | struct hci_dev *hdev; | ||
631 | |||
632 | BT_DBG("sock %p hci%u", sk, index); | ||
633 | 630 | ||
634 | hdev = hci_dev_get(index); | 631 | BT_DBG("sock %p %s", sk, hdev->name); |
635 | if (!hdev) | ||
636 | return cmd_status(sk, index, MGMT_OP_READ_INFO, | ||
637 | MGMT_STATUS_INVALID_PARAMS); | ||
638 | 632 | ||
639 | hci_dev_lock(hdev); | 633 | hci_dev_lock(hdev); |
640 | 634 | ||
@@ -658,9 +652,9 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
658 | memcpy(rp.short_name, hdev->short_name, sizeof(hdev->short_name)); | 652 | memcpy(rp.short_name, hdev->short_name, sizeof(hdev->short_name)); |
659 | 653 | ||
660 | hci_dev_unlock(hdev); | 654 | hci_dev_unlock(hdev); |
661 | hci_dev_put(hdev); | ||
662 | 655 | ||
663 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, 0, &rp, sizeof(rp)); | 656 | return cmd_complete(sk, hdev->id, MGMT_OP_READ_INFO, 0, &rp, |
657 | sizeof(rp)); | ||
664 | } | 658 | } |
665 | 659 | ||
666 | static void mgmt_pending_free(struct pending_cmd *cmd) | 660 | static void mgmt_pending_free(struct pending_cmd *cmd) |
@@ -744,22 +738,17 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) | |||
744 | sizeof(settings)); | 738 | sizeof(settings)); |
745 | } | 739 | } |
746 | 740 | ||
747 | static int set_powered(struct sock *sk, u16 index, void *data, u16 len) | 741 | static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data, |
742 | u16 len) | ||
748 | { | 743 | { |
749 | struct mgmt_mode *cp = data; | 744 | struct mgmt_mode *cp = data; |
750 | struct hci_dev *hdev; | ||
751 | struct pending_cmd *cmd; | 745 | struct pending_cmd *cmd; |
752 | int err; | 746 | int err; |
753 | 747 | ||
754 | BT_DBG("request for hci%u", index); | 748 | BT_DBG("request for %s", hdev->name); |
755 | 749 | ||
756 | if (len != sizeof(*cp)) | 750 | if (len != sizeof(*cp)) |
757 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, | 751 | return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, |
758 | MGMT_STATUS_INVALID_PARAMS); | ||
759 | |||
760 | hdev = hci_dev_get(index); | ||
761 | if (!hdev) | ||
762 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, | ||
763 | MGMT_STATUS_INVALID_PARAMS); | 752 | MGMT_STATUS_INVALID_PARAMS); |
764 | 753 | ||
765 | hci_dev_lock(hdev); | 754 | hci_dev_lock(hdev); |
@@ -780,7 +769,7 @@ static int set_powered(struct sock *sk, u16 index, void *data, u16 len) | |||
780 | } | 769 | } |
781 | 770 | ||
782 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { | 771 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) { |
783 | err = cmd_status(sk, index, MGMT_OP_SET_POWERED, | 772 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED, |
784 | MGMT_STATUS_BUSY); | 773 | MGMT_STATUS_BUSY); |
785 | goto failed; | 774 | goto failed; |
786 | } | 775 | } |
@@ -800,7 +789,6 @@ static int set_powered(struct sock *sk, u16 index, void *data, u16 len) | |||
800 | 789 | ||
801 | failed: | 790 | failed: |
802 | hci_dev_unlock(hdev); | 791 | hci_dev_unlock(hdev); |
803 | hci_dev_put(hdev); | ||
804 | return err; | 792 | return err; |
805 | } | 793 | } |
806 | 794 | ||
@@ -843,48 +831,43 @@ static int new_settings(struct hci_dev *hdev, struct sock *skip) | |||
843 | return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip); | 831 | return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip); |
844 | } | 832 | } |
845 | 833 | ||
846 | static int set_discoverable(struct sock *sk, u16 index, void *data, u16 len) | 834 | static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, |
835 | u16 len) | ||
847 | { | 836 | { |
848 | struct mgmt_cp_set_discoverable *cp = data; | 837 | struct mgmt_cp_set_discoverable *cp = data; |
849 | struct hci_dev *hdev; | ||
850 | struct pending_cmd *cmd; | 838 | struct pending_cmd *cmd; |
851 | u16 timeout; | 839 | u16 timeout; |
852 | u8 scan; | 840 | u8 scan; |
853 | int err; | 841 | int err; |
854 | 842 | ||
855 | BT_DBG("request for hci%u", index); | 843 | BT_DBG("request for %s", hdev->name); |
856 | 844 | ||
857 | if (len != sizeof(*cp)) | 845 | if (len != sizeof(*cp)) |
858 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 846 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
859 | MGMT_STATUS_INVALID_PARAMS); | 847 | MGMT_STATUS_INVALID_PARAMS); |
860 | 848 | ||
861 | timeout = get_unaligned_le16(&cp->timeout); | 849 | timeout = get_unaligned_le16(&cp->timeout); |
862 | if (!cp->val && timeout > 0) | 850 | if (!cp->val && timeout > 0) |
863 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 851 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
864 | MGMT_STATUS_INVALID_PARAMS); | ||
865 | |||
866 | hdev = hci_dev_get(index); | ||
867 | if (!hdev) | ||
868 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | ||
869 | MGMT_STATUS_INVALID_PARAMS); | 852 | MGMT_STATUS_INVALID_PARAMS); |
870 | 853 | ||
871 | hci_dev_lock(hdev); | 854 | hci_dev_lock(hdev); |
872 | 855 | ||
873 | if (!hdev_is_powered(hdev) && timeout > 0) { | 856 | if (!hdev_is_powered(hdev) && timeout > 0) { |
874 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 857 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
875 | MGMT_STATUS_NOT_POWERED); | 858 | MGMT_STATUS_NOT_POWERED); |
876 | goto failed; | 859 | goto failed; |
877 | } | 860 | } |
878 | 861 | ||
879 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || | 862 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
880 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { | 863 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
881 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 864 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
882 | MGMT_STATUS_BUSY); | 865 | MGMT_STATUS_BUSY); |
883 | goto failed; | 866 | goto failed; |
884 | } | 867 | } |
885 | 868 | ||
886 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) { | 869 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) { |
887 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 870 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, |
888 | MGMT_STATUS_REJECTED); | 871 | MGMT_STATUS_REJECTED); |
889 | goto failed; | 872 | goto failed; |
890 | } | 873 | } |
@@ -945,28 +928,21 @@ static int set_discoverable(struct sock *sk, u16 index, void *data, u16 len) | |||
945 | 928 | ||
946 | failed: | 929 | failed: |
947 | hci_dev_unlock(hdev); | 930 | hci_dev_unlock(hdev); |
948 | hci_dev_put(hdev); | ||
949 | |||
950 | return err; | 931 | return err; |
951 | } | 932 | } |
952 | 933 | ||
953 | static int set_connectable(struct sock *sk, u16 index, void *data, u16 len) | 934 | static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, |
935 | u16 len) | ||
954 | { | 936 | { |
955 | struct mgmt_mode *cp = data; | 937 | struct mgmt_mode *cp = data; |
956 | struct hci_dev *hdev; | ||
957 | struct pending_cmd *cmd; | 938 | struct pending_cmd *cmd; |
958 | u8 scan; | 939 | u8 scan; |
959 | int err; | 940 | int err; |
960 | 941 | ||
961 | BT_DBG("request for hci%u", index); | 942 | BT_DBG("request for %s", hdev->name); |
962 | 943 | ||
963 | if (len != sizeof(*cp)) | 944 | if (len != sizeof(*cp)) |
964 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, | 945 | return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, |
965 | MGMT_STATUS_INVALID_PARAMS); | ||
966 | |||
967 | hdev = hci_dev_get(index); | ||
968 | if (!hdev) | ||
969 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, | ||
970 | MGMT_STATUS_INVALID_PARAMS); | 946 | MGMT_STATUS_INVALID_PARAMS); |
971 | 947 | ||
972 | hci_dev_lock(hdev); | 948 | hci_dev_lock(hdev); |
@@ -996,7 +972,7 @@ static int set_connectable(struct sock *sk, u16 index, void *data, u16 len) | |||
996 | 972 | ||
997 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || | 973 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || |
998 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { | 974 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { |
999 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, | 975 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, |
1000 | MGMT_STATUS_BUSY); | 976 | MGMT_STATUS_BUSY); |
1001 | goto failed; | 977 | goto failed; |
1002 | } | 978 | } |
@@ -1028,26 +1004,19 @@ static int set_connectable(struct sock *sk, u16 index, void *data, u16 len) | |||
1028 | 1004 | ||
1029 | failed: | 1005 | failed: |
1030 | hci_dev_unlock(hdev); | 1006 | hci_dev_unlock(hdev); |
1031 | hci_dev_put(hdev); | ||
1032 | |||
1033 | return err; | 1007 | return err; |
1034 | } | 1008 | } |
1035 | 1009 | ||
1036 | static int set_pairable(struct sock *sk, u16 index, void *data, u16 len) | 1010 | static int set_pairable(struct sock *sk, struct hci_dev *hdev, void *data, |
1011 | u16 len) | ||
1037 | { | 1012 | { |
1038 | struct mgmt_mode *cp = data; | 1013 | struct mgmt_mode *cp = data; |
1039 | struct hci_dev *hdev; | ||
1040 | int err; | 1014 | int err; |
1041 | 1015 | ||
1042 | BT_DBG("request for hci%u", index); | 1016 | BT_DBG("request for %s", hdev->name); |
1043 | 1017 | ||
1044 | if (len != sizeof(*cp)) | 1018 | if (len != sizeof(*cp)) |
1045 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, | 1019 | return cmd_status(sk, hdev->id, MGMT_OP_SET_PAIRABLE, |
1046 | MGMT_STATUS_INVALID_PARAMS); | ||
1047 | |||
1048 | hdev = hci_dev_get(index); | ||
1049 | if (!hdev) | ||
1050 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, | ||
1051 | MGMT_STATUS_INVALID_PARAMS); | 1020 | MGMT_STATUS_INVALID_PARAMS); |
1052 | 1021 | ||
1053 | hci_dev_lock(hdev); | 1022 | hci_dev_lock(hdev); |
@@ -1065,28 +1034,21 @@ static int set_pairable(struct sock *sk, u16 index, void *data, u16 len) | |||
1065 | 1034 | ||
1066 | failed: | 1035 | failed: |
1067 | hci_dev_unlock(hdev); | 1036 | hci_dev_unlock(hdev); |
1068 | hci_dev_put(hdev); | ||
1069 | |||
1070 | return err; | 1037 | return err; |
1071 | } | 1038 | } |
1072 | 1039 | ||
1073 | static int set_link_security(struct sock *sk, u16 index, void *data, u16 len) | 1040 | static int set_link_security(struct sock *sk, struct hci_dev *hdev, |
1041 | void *data, u16 len) | ||
1074 | { | 1042 | { |
1075 | struct mgmt_mode *cp = data; | 1043 | struct mgmt_mode *cp = data; |
1076 | struct pending_cmd *cmd; | 1044 | struct pending_cmd *cmd; |
1077 | struct hci_dev *hdev; | ||
1078 | u8 val; | 1045 | u8 val; |
1079 | int err; | 1046 | int err; |
1080 | 1047 | ||
1081 | BT_DBG("request for hci%u", index); | 1048 | BT_DBG("request for %s", hdev->name); |
1082 | 1049 | ||
1083 | if (len != sizeof(*cp)) | 1050 | if (len != sizeof(*cp)) |
1084 | return cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY, | 1051 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, |
1085 | MGMT_STATUS_INVALID_PARAMS); | ||
1086 | |||
1087 | hdev = hci_dev_get(index); | ||
1088 | if (!hdev) | ||
1089 | return cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY, | ||
1090 | MGMT_STATUS_INVALID_PARAMS); | 1052 | MGMT_STATUS_INVALID_PARAMS); |
1091 | 1053 | ||
1092 | hci_dev_lock(hdev); | 1054 | hci_dev_lock(hdev); |
@@ -1111,7 +1073,7 @@ static int set_link_security(struct sock *sk, u16 index, void *data, u16 len) | |||
1111 | } | 1073 | } |
1112 | 1074 | ||
1113 | if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) { | 1075 | if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) { |
1114 | err = cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY, | 1076 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, |
1115 | MGMT_STATUS_BUSY); | 1077 | MGMT_STATUS_BUSY); |
1116 | goto failed; | 1078 | goto failed; |
1117 | } | 1079 | } |
@@ -1137,34 +1099,26 @@ static int set_link_security(struct sock *sk, u16 index, void *data, u16 len) | |||
1137 | 1099 | ||
1138 | failed: | 1100 | failed: |
1139 | hci_dev_unlock(hdev); | 1101 | hci_dev_unlock(hdev); |
1140 | hci_dev_put(hdev); | ||
1141 | |||
1142 | return err; | 1102 | return err; |
1143 | } | 1103 | } |
1144 | 1104 | ||
1145 | static int set_ssp(struct sock *sk, u16 index, void *data, u16 len) | 1105 | static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) |
1146 | { | 1106 | { |
1147 | struct mgmt_mode *cp = data; | 1107 | struct mgmt_mode *cp = data; |
1148 | struct pending_cmd *cmd; | 1108 | struct pending_cmd *cmd; |
1149 | struct hci_dev *hdev; | ||
1150 | u8 val; | 1109 | u8 val; |
1151 | int err; | 1110 | int err; |
1152 | 1111 | ||
1153 | BT_DBG("request for hci%u", index); | 1112 | BT_DBG("request for %s", hdev->name); |
1154 | 1113 | ||
1155 | if (len != sizeof(*cp)) | 1114 | if (len != sizeof(*cp)) |
1156 | return cmd_status(sk, index, MGMT_OP_SET_SSP, | 1115 | return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, |
1157 | MGMT_STATUS_INVALID_PARAMS); | ||
1158 | |||
1159 | hdev = hci_dev_get(index); | ||
1160 | if (!hdev) | ||
1161 | return cmd_status(sk, index, MGMT_OP_SET_SSP, | ||
1162 | MGMT_STATUS_INVALID_PARAMS); | 1116 | MGMT_STATUS_INVALID_PARAMS); |
1163 | 1117 | ||
1164 | hci_dev_lock(hdev); | 1118 | hci_dev_lock(hdev); |
1165 | 1119 | ||
1166 | if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { | 1120 | if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { |
1167 | err = cmd_status(sk, index, MGMT_OP_SET_SSP, | 1121 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, |
1168 | MGMT_STATUS_NOT_SUPPORTED); | 1122 | MGMT_STATUS_NOT_SUPPORTED); |
1169 | goto failed; | 1123 | goto failed; |
1170 | } | 1124 | } |
@@ -1190,7 +1144,8 @@ static int set_ssp(struct sock *sk, u16 index, void *data, u16 len) | |||
1190 | } | 1144 | } |
1191 | 1145 | ||
1192 | if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { | 1146 | if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) { |
1193 | err = cmd_status(sk, index, MGMT_OP_SET_SSP, MGMT_STATUS_BUSY); | 1147 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, |
1148 | MGMT_STATUS_BUSY); | ||
1194 | goto failed; | 1149 | goto failed; |
1195 | } | 1150 | } |
1196 | 1151 | ||
@@ -1213,70 +1168,49 @@ static int set_ssp(struct sock *sk, u16 index, void *data, u16 len) | |||
1213 | 1168 | ||
1214 | failed: | 1169 | failed: |
1215 | hci_dev_unlock(hdev); | 1170 | hci_dev_unlock(hdev); |
1216 | hci_dev_put(hdev); | ||
1217 | |||
1218 | return err; | 1171 | return err; |
1219 | } | 1172 | } |
1220 | 1173 | ||
1221 | static int set_hs(struct sock *sk, u16 index, void *data, u16 len) | 1174 | static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) |
1222 | { | 1175 | { |
1223 | struct mgmt_mode *cp = data; | 1176 | struct mgmt_mode *cp = data; |
1224 | struct hci_dev *hdev; | ||
1225 | int err; | ||
1226 | 1177 | ||
1227 | BT_DBG("request for hci%u", index); | 1178 | BT_DBG("request for %s", hdev->name); |
1228 | 1179 | ||
1229 | if (len != sizeof(*cp)) | 1180 | if (len != sizeof(*cp)) |
1230 | return cmd_status(sk, index, MGMT_OP_SET_HS, | 1181 | return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, |
1231 | MGMT_STATUS_INVALID_PARAMS); | 1182 | MGMT_STATUS_INVALID_PARAMS); |
1232 | 1183 | ||
1233 | hdev = hci_dev_get(index); | 1184 | if (!enable_hs) |
1234 | if (!hdev) | 1185 | return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, |
1235 | return cmd_status(sk, index, MGMT_OP_SET_HS, | 1186 | MGMT_STATUS_NOT_SUPPORTED); |
1236 | MGMT_STATUS_INVALID_PARAMS); | ||
1237 | |||
1238 | if (!enable_hs) { | ||
1239 | err = cmd_status(sk, index, MGMT_OP_SET_HS, | ||
1240 | MGMT_STATUS_NOT_SUPPORTED); | ||
1241 | goto failed; | ||
1242 | } | ||
1243 | 1187 | ||
1244 | if (cp->val) | 1188 | if (cp->val) |
1245 | set_bit(HCI_HS_ENABLED, &hdev->dev_flags); | 1189 | set_bit(HCI_HS_ENABLED, &hdev->dev_flags); |
1246 | else | 1190 | else |
1247 | clear_bit(HCI_HS_ENABLED, &hdev->dev_flags); | 1191 | clear_bit(HCI_HS_ENABLED, &hdev->dev_flags); |
1248 | 1192 | ||
1249 | err = send_settings_rsp(sk, MGMT_OP_SET_HS, hdev); | 1193 | return send_settings_rsp(sk, MGMT_OP_SET_HS, hdev); |
1250 | |||
1251 | failed: | ||
1252 | hci_dev_put(hdev); | ||
1253 | return err; | ||
1254 | } | 1194 | } |
1255 | 1195 | ||
1256 | static int set_le(struct sock *sk, u16 index, void *data, u16 len) | 1196 | static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) |
1257 | { | 1197 | { |
1258 | struct mgmt_mode *cp = data; | 1198 | struct mgmt_mode *cp = data; |
1259 | struct hci_cp_write_le_host_supported hci_cp; | 1199 | struct hci_cp_write_le_host_supported hci_cp; |
1260 | struct pending_cmd *cmd; | 1200 | struct pending_cmd *cmd; |
1261 | struct hci_dev *hdev; | ||
1262 | int err; | 1201 | int err; |
1263 | u8 val, enabled; | 1202 | u8 val, enabled; |
1264 | 1203 | ||
1265 | BT_DBG("request for hci%u", index); | 1204 | BT_DBG("request for %s", hdev->name); |
1266 | 1205 | ||
1267 | if (len != sizeof(*cp)) | 1206 | if (len != sizeof(*cp)) |
1268 | return cmd_status(sk, index, MGMT_OP_SET_LE, | 1207 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LE, |
1269 | MGMT_STATUS_INVALID_PARAMS); | ||
1270 | |||
1271 | hdev = hci_dev_get(index); | ||
1272 | if (!hdev) | ||
1273 | return cmd_status(sk, index, MGMT_OP_SET_LE, | ||
1274 | MGMT_STATUS_INVALID_PARAMS); | 1208 | MGMT_STATUS_INVALID_PARAMS); |
1275 | 1209 | ||
1276 | hci_dev_lock(hdev); | 1210 | hci_dev_lock(hdev); |
1277 | 1211 | ||
1278 | if (!enable_le || !(hdev->features[4] & LMP_LE)) { | 1212 | if (!enable_le || !(hdev->features[4] & LMP_LE)) { |
1279 | err = cmd_status(sk, index, MGMT_OP_SET_LE, | 1213 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, |
1280 | MGMT_STATUS_NOT_SUPPORTED); | 1214 | MGMT_STATUS_NOT_SUPPORTED); |
1281 | goto unlock; | 1215 | goto unlock; |
1282 | } | 1216 | } |
@@ -1303,7 +1237,8 @@ static int set_le(struct sock *sk, u16 index, void *data, u16 len) | |||
1303 | } | 1237 | } |
1304 | 1238 | ||
1305 | if (mgmt_pending_find(MGMT_OP_SET_LE, hdev)) { | 1239 | if (mgmt_pending_find(MGMT_OP_SET_LE, hdev)) { |
1306 | err = cmd_status(sk, index, MGMT_OP_SET_LE, MGMT_STATUS_BUSY); | 1240 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, |
1241 | MGMT_STATUS_BUSY); | ||
1307 | goto unlock; | 1242 | goto unlock; |
1308 | } | 1243 | } |
1309 | 1244 | ||
@@ -1329,33 +1264,26 @@ static int set_le(struct sock *sk, u16 index, void *data, u16 len) | |||
1329 | 1264 | ||
1330 | unlock: | 1265 | unlock: |
1331 | hci_dev_unlock(hdev); | 1266 | hci_dev_unlock(hdev); |
1332 | hci_dev_put(hdev); | ||
1333 | return err; | 1267 | return err; |
1334 | } | 1268 | } |
1335 | 1269 | ||
1336 | static int add_uuid(struct sock *sk, u16 index, void *data, u16 len) | 1270 | static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) |
1337 | { | 1271 | { |
1338 | struct mgmt_cp_add_uuid *cp = data; | 1272 | struct mgmt_cp_add_uuid *cp = data; |
1339 | struct pending_cmd *cmd; | 1273 | struct pending_cmd *cmd; |
1340 | struct hci_dev *hdev; | ||
1341 | struct bt_uuid *uuid; | 1274 | struct bt_uuid *uuid; |
1342 | int err; | 1275 | int err; |
1343 | 1276 | ||
1344 | BT_DBG("request for hci%u", index); | 1277 | BT_DBG("request for %s", hdev->name); |
1345 | 1278 | ||
1346 | if (len != sizeof(*cp)) | 1279 | if (len != sizeof(*cp)) |
1347 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, | 1280 | return cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID, |
1348 | MGMT_STATUS_INVALID_PARAMS); | ||
1349 | |||
1350 | hdev = hci_dev_get(index); | ||
1351 | if (!hdev) | ||
1352 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, | ||
1353 | MGMT_STATUS_INVALID_PARAMS); | 1281 | MGMT_STATUS_INVALID_PARAMS); |
1354 | 1282 | ||
1355 | hci_dev_lock(hdev); | 1283 | hci_dev_lock(hdev); |
1356 | 1284 | ||
1357 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1285 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1358 | err = cmd_status(sk, index, MGMT_OP_ADD_UUID, | 1286 | err = cmd_status(sk, hdev->id, MGMT_OP_ADD_UUID, |
1359 | MGMT_STATUS_BUSY); | 1287 | MGMT_STATUS_BUSY); |
1360 | goto failed; | 1288 | goto failed; |
1361 | } | 1289 | } |
@@ -1380,7 +1308,7 @@ static int add_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1380 | goto failed; | 1308 | goto failed; |
1381 | 1309 | ||
1382 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1310 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1383 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, 0, | 1311 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0, |
1384 | hdev->dev_class, 3); | 1312 | hdev->dev_class, 3); |
1385 | goto failed; | 1313 | goto failed; |
1386 | } | 1314 | } |
@@ -1393,8 +1321,6 @@ static int add_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1393 | 1321 | ||
1394 | failed: | 1322 | failed: |
1395 | hci_dev_unlock(hdev); | 1323 | hci_dev_unlock(hdev); |
1396 | hci_dev_put(hdev); | ||
1397 | |||
1398 | return err; | 1324 | return err; |
1399 | } | 1325 | } |
1400 | 1326 | ||
@@ -1412,30 +1338,25 @@ static bool enable_service_cache(struct hci_dev *hdev) | |||
1412 | return false; | 1338 | return false; |
1413 | } | 1339 | } |
1414 | 1340 | ||
1415 | static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len) | 1341 | static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, |
1342 | u16 len) | ||
1416 | { | 1343 | { |
1417 | struct mgmt_cp_remove_uuid *cp = data; | 1344 | struct mgmt_cp_remove_uuid *cp = data; |
1418 | struct pending_cmd *cmd; | 1345 | struct pending_cmd *cmd; |
1419 | struct list_head *p, *n; | 1346 | struct list_head *p, *n; |
1420 | struct hci_dev *hdev; | ||
1421 | u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | 1347 | u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
1422 | int err, found; | 1348 | int err, found; |
1423 | 1349 | ||
1424 | BT_DBG("request for hci%u", index); | 1350 | BT_DBG("request for %s", hdev->name); |
1425 | 1351 | ||
1426 | if (len != sizeof(*cp)) | 1352 | if (len != sizeof(*cp)) |
1427 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | 1353 | return cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, |
1428 | MGMT_STATUS_INVALID_PARAMS); | ||
1429 | |||
1430 | hdev = hci_dev_get(index); | ||
1431 | if (!hdev) | ||
1432 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | ||
1433 | MGMT_STATUS_INVALID_PARAMS); | 1354 | MGMT_STATUS_INVALID_PARAMS); |
1434 | 1355 | ||
1435 | hci_dev_lock(hdev); | 1356 | hci_dev_lock(hdev); |
1436 | 1357 | ||
1437 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1358 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1438 | err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | 1359 | err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, |
1439 | MGMT_STATUS_BUSY); | 1360 | MGMT_STATUS_BUSY); |
1440 | goto unlock; | 1361 | goto unlock; |
1441 | } | 1362 | } |
@@ -1444,8 +1365,8 @@ static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1444 | err = hci_uuids_clear(hdev); | 1365 | err = hci_uuids_clear(hdev); |
1445 | 1366 | ||
1446 | if (enable_service_cache(hdev)) { | 1367 | if (enable_service_cache(hdev)) { |
1447 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, 0, | 1368 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, |
1448 | hdev->dev_class, 3); | 1369 | 0, hdev->dev_class, 3); |
1449 | goto unlock; | 1370 | goto unlock; |
1450 | } | 1371 | } |
1451 | 1372 | ||
@@ -1465,7 +1386,7 @@ static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len) | |||
1465 | } | 1386 | } |
1466 | 1387 | ||
1467 | if (found == 0) { | 1388 | if (found == 0) { |
1468 | err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | 1389 | err = cmd_status(sk, hdev->id, MGMT_OP_REMOVE_UUID, |
1469 | MGMT_STATUS_INVALID_PARAMS); | 1390 | MGMT_STATUS_INVALID_PARAMS); |
1470 | goto unlock; | 1391 | goto unlock; |
1471 | } | 1392 | } |
@@ -1480,7 +1401,7 @@ update_class: | |||
1480 | goto unlock; | 1401 | goto unlock; |
1481 | 1402 | ||
1482 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1403 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1483 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, 0, | 1404 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0, |
1484 | hdev->dev_class, 3); | 1405 | hdev->dev_class, 3); |
1485 | goto unlock; | 1406 | goto unlock; |
1486 | } | 1407 | } |
@@ -1493,33 +1414,26 @@ update_class: | |||
1493 | 1414 | ||
1494 | unlock: | 1415 | unlock: |
1495 | hci_dev_unlock(hdev); | 1416 | hci_dev_unlock(hdev); |
1496 | hci_dev_put(hdev); | ||
1497 | |||
1498 | return err; | 1417 | return err; |
1499 | } | 1418 | } |
1500 | 1419 | ||
1501 | static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len) | 1420 | static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, |
1421 | u16 len) | ||
1502 | { | 1422 | { |
1503 | struct hci_dev *hdev; | ||
1504 | struct mgmt_cp_set_dev_class *cp = data; | 1423 | struct mgmt_cp_set_dev_class *cp = data; |
1505 | struct pending_cmd *cmd; | 1424 | struct pending_cmd *cmd; |
1506 | int err; | 1425 | int err; |
1507 | 1426 | ||
1508 | BT_DBG("request for hci%u", index); | 1427 | BT_DBG("request for %s", hdev->name); |
1509 | 1428 | ||
1510 | if (len != sizeof(*cp)) | 1429 | if (len != sizeof(*cp)) |
1511 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, | 1430 | return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, |
1512 | MGMT_STATUS_INVALID_PARAMS); | ||
1513 | |||
1514 | hdev = hci_dev_get(index); | ||
1515 | if (!hdev) | ||
1516 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, | ||
1517 | MGMT_STATUS_INVALID_PARAMS); | 1431 | MGMT_STATUS_INVALID_PARAMS); |
1518 | 1432 | ||
1519 | hci_dev_lock(hdev); | 1433 | hci_dev_lock(hdev); |
1520 | 1434 | ||
1521 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1435 | if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1522 | err = cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, | 1436 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, |
1523 | MGMT_STATUS_BUSY); | 1437 | MGMT_STATUS_BUSY); |
1524 | goto unlock; | 1438 | goto unlock; |
1525 | } | 1439 | } |
@@ -1528,7 +1442,7 @@ static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len) | |||
1528 | hdev->minor_class = cp->minor; | 1442 | hdev->minor_class = cp->minor; |
1529 | 1443 | ||
1530 | if (!hdev_is_powered(hdev)) { | 1444 | if (!hdev_is_powered(hdev)) { |
1531 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, 0, | 1445 | err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, |
1532 | hdev->dev_class, 3); | 1446 | hdev->dev_class, 3); |
1533 | goto unlock; | 1447 | goto unlock; |
1534 | } | 1448 | } |
@@ -1545,7 +1459,7 @@ static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len) | |||
1545 | goto unlock; | 1459 | goto unlock; |
1546 | 1460 | ||
1547 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { | 1461 | if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { |
1548 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, 0, | 1462 | err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0, |
1549 | hdev->dev_class, 3); | 1463 | hdev->dev_class, 3); |
1550 | goto unlock; | 1464 | goto unlock; |
1551 | } | 1465 | } |
@@ -1558,20 +1472,18 @@ static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len) | |||
1558 | 1472 | ||
1559 | unlock: | 1473 | unlock: |
1560 | hci_dev_unlock(hdev); | 1474 | hci_dev_unlock(hdev); |
1561 | hci_dev_put(hdev); | ||
1562 | |||
1563 | return err; | 1475 | return err; |
1564 | } | 1476 | } |
1565 | 1477 | ||
1566 | static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len) | 1478 | static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, |
1479 | u16 len) | ||
1567 | { | 1480 | { |
1568 | struct hci_dev *hdev; | ||
1569 | struct mgmt_cp_load_link_keys *cp = data; | 1481 | struct mgmt_cp_load_link_keys *cp = data; |
1570 | u16 key_count, expected_len; | 1482 | u16 key_count, expected_len; |
1571 | int i; | 1483 | int i; |
1572 | 1484 | ||
1573 | if (len < sizeof(*cp)) | 1485 | if (len < sizeof(*cp)) |
1574 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, | 1486 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, |
1575 | MGMT_STATUS_INVALID_PARAMS); | 1487 | MGMT_STATUS_INVALID_PARAMS); |
1576 | 1488 | ||
1577 | key_count = get_unaligned_le16(&cp->key_count); | 1489 | key_count = get_unaligned_le16(&cp->key_count); |
@@ -1581,16 +1493,11 @@ static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len) | |||
1581 | if (expected_len != len) { | 1493 | if (expected_len != len) { |
1582 | BT_ERR("load_link_keys: expected %u bytes, got %u bytes", | 1494 | BT_ERR("load_link_keys: expected %u bytes, got %u bytes", |
1583 | len, expected_len); | 1495 | len, expected_len); |
1584 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, | 1496 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, |
1585 | MGMT_STATUS_INVALID_PARAMS); | 1497 | MGMT_STATUS_INVALID_PARAMS); |
1586 | } | 1498 | } |
1587 | 1499 | ||
1588 | hdev = hci_dev_get(index); | 1500 | BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, |
1589 | if (!hdev) | ||
1590 | return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS, | ||
1591 | MGMT_STATUS_INVALID_PARAMS); | ||
1592 | |||
1593 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | ||
1594 | key_count); | 1501 | key_count); |
1595 | 1502 | ||
1596 | hci_dev_lock(hdev); | 1503 | hci_dev_lock(hdev); |
@@ -1611,10 +1518,9 @@ static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len) | |||
1611 | key->type, key->pin_len); | 1518 | key->type, key->pin_len); |
1612 | } | 1519 | } |
1613 | 1520 | ||
1614 | cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0); | 1521 | cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0); |
1615 | 1522 | ||
1616 | hci_dev_unlock(hdev); | 1523 | hci_dev_unlock(hdev); |
1617 | hci_dev_put(hdev); | ||
1618 | 1524 | ||
1619 | return 0; | 1525 | return 0; |
1620 | } | 1526 | } |
@@ -1631,9 +1537,9 @@ static int device_unpaired(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
1631 | skip_sk); | 1537 | skip_sk); |
1632 | } | 1538 | } |
1633 | 1539 | ||
1634 | static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | 1540 | static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, |
1541 | u16 len) | ||
1635 | { | 1542 | { |
1636 | struct hci_dev *hdev; | ||
1637 | struct mgmt_cp_unpair_device *cp = data; | 1543 | struct mgmt_cp_unpair_device *cp = data; |
1638 | struct mgmt_rp_unpair_device rp; | 1544 | struct mgmt_rp_unpair_device rp; |
1639 | struct hci_cp_disconnect dc; | 1545 | struct hci_cp_disconnect dc; |
@@ -1642,12 +1548,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
1642 | int err; | 1548 | int err; |
1643 | 1549 | ||
1644 | if (len != sizeof(*cp)) | 1550 | if (len != sizeof(*cp)) |
1645 | return cmd_status(sk, index, MGMT_OP_UNPAIR_DEVICE, | 1551 | return cmd_status(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, |
1646 | MGMT_STATUS_INVALID_PARAMS); | ||
1647 | |||
1648 | hdev = hci_dev_get(index); | ||
1649 | if (!hdev) | ||
1650 | return cmd_status(sk, index, MGMT_OP_UNPAIR_DEVICE, | ||
1651 | MGMT_STATUS_INVALID_PARAMS); | 1552 | MGMT_STATUS_INVALID_PARAMS); |
1652 | 1553 | ||
1653 | hci_dev_lock(hdev); | 1554 | hci_dev_lock(hdev); |
@@ -1657,7 +1558,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
1657 | rp.addr.type = cp->addr.type; | 1558 | rp.addr.type = cp->addr.type; |
1658 | 1559 | ||
1659 | if (!hdev_is_powered(hdev)) { | 1560 | if (!hdev_is_powered(hdev)) { |
1660 | err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, | 1561 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, |
1661 | MGMT_STATUS_NOT_POWERED, | 1562 | MGMT_STATUS_NOT_POWERED, |
1662 | &rp, sizeof(rp)); | 1563 | &rp, sizeof(rp)); |
1663 | goto unlock; | 1564 | goto unlock; |
@@ -1669,7 +1570,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
1669 | err = hci_remove_ltk(hdev, &cp->addr.bdaddr); | 1570 | err = hci_remove_ltk(hdev, &cp->addr.bdaddr); |
1670 | 1571 | ||
1671 | if (err < 0) { | 1572 | if (err < 0) { |
1672 | err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, | 1573 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, |
1673 | MGMT_STATUS_NOT_PAIRED, | 1574 | MGMT_STATUS_NOT_PAIRED, |
1674 | &rp, sizeof(rp)); | 1575 | &rp, sizeof(rp)); |
1675 | goto unlock; | 1576 | goto unlock; |
@@ -1687,7 +1588,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
1687 | } | 1588 | } |
1688 | 1589 | ||
1689 | if (!conn) { | 1590 | if (!conn) { |
1690 | err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, 0, | 1591 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 0, |
1691 | &rp, sizeof(rp)); | 1592 | &rp, sizeof(rp)); |
1692 | device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk); | 1593 | device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk); |
1693 | goto unlock; | 1594 | goto unlock; |
@@ -1708,14 +1609,12 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
1708 | 1609 | ||
1709 | unlock: | 1610 | unlock: |
1710 | hci_dev_unlock(hdev); | 1611 | hci_dev_unlock(hdev); |
1711 | hci_dev_put(hdev); | ||
1712 | |||
1713 | return err; | 1612 | return err; |
1714 | } | 1613 | } |
1715 | 1614 | ||
1716 | static int disconnect(struct sock *sk, u16 index, void *data, u16 len) | 1615 | static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, |
1616 | u16 len) | ||
1717 | { | 1617 | { |
1718 | struct hci_dev *hdev; | ||
1719 | struct mgmt_cp_disconnect *cp = data; | 1618 | struct mgmt_cp_disconnect *cp = data; |
1720 | struct hci_cp_disconnect dc; | 1619 | struct hci_cp_disconnect dc; |
1721 | struct pending_cmd *cmd; | 1620 | struct pending_cmd *cmd; |
@@ -1725,24 +1624,19 @@ static int disconnect(struct sock *sk, u16 index, void *data, u16 len) | |||
1725 | BT_DBG(""); | 1624 | BT_DBG(""); |
1726 | 1625 | ||
1727 | if (len != sizeof(*cp)) | 1626 | if (len != sizeof(*cp)) |
1728 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1627 | return cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, |
1729 | MGMT_STATUS_INVALID_PARAMS); | ||
1730 | |||
1731 | hdev = hci_dev_get(index); | ||
1732 | if (!hdev) | ||
1733 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, | ||
1734 | MGMT_STATUS_INVALID_PARAMS); | 1628 | MGMT_STATUS_INVALID_PARAMS); |
1735 | 1629 | ||
1736 | hci_dev_lock(hdev); | 1630 | hci_dev_lock(hdev); |
1737 | 1631 | ||
1738 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1632 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1739 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1633 | err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, |
1740 | MGMT_STATUS_NOT_POWERED); | 1634 | MGMT_STATUS_NOT_POWERED); |
1741 | goto failed; | 1635 | goto failed; |
1742 | } | 1636 | } |
1743 | 1637 | ||
1744 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { | 1638 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { |
1745 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1639 | err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, |
1746 | MGMT_STATUS_BUSY); | 1640 | MGMT_STATUS_BUSY); |
1747 | goto failed; | 1641 | goto failed; |
1748 | } | 1642 | } |
@@ -1753,7 +1647,7 @@ static int disconnect(struct sock *sk, u16 index, void *data, u16 len) | |||
1753 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); | 1647 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); |
1754 | 1648 | ||
1755 | if (!conn) { | 1649 | if (!conn) { |
1756 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1650 | err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, |
1757 | MGMT_STATUS_NOT_CONNECTED); | 1651 | MGMT_STATUS_NOT_CONNECTED); |
1758 | goto failed; | 1652 | goto failed; |
1759 | } | 1653 | } |
@@ -1773,8 +1667,6 @@ static int disconnect(struct sock *sk, u16 index, void *data, u16 len) | |||
1773 | 1667 | ||
1774 | failed: | 1668 | failed: |
1775 | hci_dev_unlock(hdev); | 1669 | hci_dev_unlock(hdev); |
1776 | hci_dev_put(hdev); | ||
1777 | |||
1778 | return err; | 1670 | return err; |
1779 | } | 1671 | } |
1780 | 1672 | ||
@@ -1797,10 +1689,9 @@ static u8 link_to_mgmt(u8 link_type, u8 addr_type) | |||
1797 | } | 1689 | } |
1798 | } | 1690 | } |
1799 | 1691 | ||
1800 | static int get_connections(struct sock *sk, u16 index) | 1692 | static int get_connections(struct sock *sk, struct hci_dev *hdev) |
1801 | { | 1693 | { |
1802 | struct mgmt_rp_get_connections *rp; | 1694 | struct mgmt_rp_get_connections *rp; |
1803 | struct hci_dev *hdev; | ||
1804 | struct hci_conn *c; | 1695 | struct hci_conn *c; |
1805 | size_t rp_len; | 1696 | size_t rp_len; |
1806 | int err; | 1697 | int err; |
@@ -1808,15 +1699,10 @@ static int get_connections(struct sock *sk, u16 index) | |||
1808 | 1699 | ||
1809 | BT_DBG(""); | 1700 | BT_DBG(""); |
1810 | 1701 | ||
1811 | hdev = hci_dev_get(index); | ||
1812 | if (!hdev) | ||
1813 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, | ||
1814 | MGMT_STATUS_INVALID_PARAMS); | ||
1815 | |||
1816 | hci_dev_lock(hdev); | 1702 | hci_dev_lock(hdev); |
1817 | 1703 | ||
1818 | if (!hdev_is_powered(hdev)) { | 1704 | if (!hdev_is_powered(hdev)) { |
1819 | err = cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, | 1705 | err = cmd_status(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, |
1820 | MGMT_STATUS_NOT_POWERED); | 1706 | MGMT_STATUS_NOT_POWERED); |
1821 | goto unlock; | 1707 | goto unlock; |
1822 | } | 1708 | } |
@@ -1850,18 +1736,18 @@ static int get_connections(struct sock *sk, u16 index) | |||
1850 | /* Recalculate length in case of filtered SCO connections, etc */ | 1736 | /* Recalculate length in case of filtered SCO connections, etc */ |
1851 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); | 1737 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); |
1852 | 1738 | ||
1853 | err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, 0, rp, rp_len); | 1739 | err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONNECTIONS, 0, rp, |
1740 | rp_len); | ||
1854 | 1741 | ||
1855 | kfree(rp); | 1742 | kfree(rp); |
1856 | 1743 | ||
1857 | unlock: | 1744 | unlock: |
1858 | hci_dev_unlock(hdev); | 1745 | hci_dev_unlock(hdev); |
1859 | hci_dev_put(hdev); | ||
1860 | return err; | 1746 | return err; |
1861 | } | 1747 | } |
1862 | 1748 | ||
1863 | static int send_pin_code_neg_reply(struct sock *sk, u16 index, | 1749 | static int send_pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev, |
1864 | struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp) | 1750 | struct mgmt_cp_pin_code_neg_reply *cp) |
1865 | { | 1751 | { |
1866 | struct pending_cmd *cmd; | 1752 | struct pending_cmd *cmd; |
1867 | int err; | 1753 | int err; |
@@ -1879,9 +1765,9 @@ static int send_pin_code_neg_reply(struct sock *sk, u16 index, | |||
1879 | return err; | 1765 | return err; |
1880 | } | 1766 | } |
1881 | 1767 | ||
1882 | static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len) | 1768 | static int pin_code_reply(struct sock *sk, struct hci_dev *hdev, void *data, |
1769 | u16 len) | ||
1883 | { | 1770 | { |
1884 | struct hci_dev *hdev; | ||
1885 | struct hci_conn *conn; | 1771 | struct hci_conn *conn; |
1886 | struct mgmt_cp_pin_code_reply *cp = data; | 1772 | struct mgmt_cp_pin_code_reply *cp = data; |
1887 | struct hci_cp_pin_code_reply reply; | 1773 | struct hci_cp_pin_code_reply reply; |
@@ -1891,25 +1777,20 @@ static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len) | |||
1891 | BT_DBG(""); | 1777 | BT_DBG(""); |
1892 | 1778 | ||
1893 | if (len != sizeof(*cp)) | 1779 | if (len != sizeof(*cp)) |
1894 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1780 | return cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, |
1895 | MGMT_STATUS_INVALID_PARAMS); | ||
1896 | |||
1897 | hdev = hci_dev_get(index); | ||
1898 | if (!hdev) | ||
1899 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | ||
1900 | MGMT_STATUS_INVALID_PARAMS); | 1781 | MGMT_STATUS_INVALID_PARAMS); |
1901 | 1782 | ||
1902 | hci_dev_lock(hdev); | 1783 | hci_dev_lock(hdev); |
1903 | 1784 | ||
1904 | if (!hdev_is_powered(hdev)) { | 1785 | if (!hdev_is_powered(hdev)) { |
1905 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1786 | err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, |
1906 | MGMT_STATUS_NOT_POWERED); | 1787 | MGMT_STATUS_NOT_POWERED); |
1907 | goto failed; | 1788 | goto failed; |
1908 | } | 1789 | } |
1909 | 1790 | ||
1910 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); | 1791 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); |
1911 | if (!conn) { | 1792 | if (!conn) { |
1912 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1793 | err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, |
1913 | MGMT_STATUS_NOT_CONNECTED); | 1794 | MGMT_STATUS_NOT_CONNECTED); |
1914 | goto failed; | 1795 | goto failed; |
1915 | } | 1796 | } |
@@ -1921,9 +1802,9 @@ static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len) | |||
1921 | 1802 | ||
1922 | BT_ERR("PIN code is not 16 bytes long"); | 1803 | BT_ERR("PIN code is not 16 bytes long"); |
1923 | 1804 | ||
1924 | err = send_pin_code_neg_reply(sk, index, hdev, &ncp); | 1805 | err = send_pin_code_neg_reply(sk, hdev, &ncp); |
1925 | if (err >= 0) | 1806 | if (err >= 0) |
1926 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1807 | err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, |
1927 | MGMT_STATUS_INVALID_PARAMS); | 1808 | MGMT_STATUS_INVALID_PARAMS); |
1928 | 1809 | ||
1929 | goto failed; | 1810 | goto failed; |
@@ -1945,59 +1826,45 @@ static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len) | |||
1945 | 1826 | ||
1946 | failed: | 1827 | failed: |
1947 | hci_dev_unlock(hdev); | 1828 | hci_dev_unlock(hdev); |
1948 | hci_dev_put(hdev); | ||
1949 | |||
1950 | return err; | 1829 | return err; |
1951 | } | 1830 | } |
1952 | 1831 | ||
1953 | static int pin_code_neg_reply(struct sock *sk, u16 index, void *data, u16 len) | 1832 | static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev, |
1833 | void *data, u16 len) | ||
1954 | { | 1834 | { |
1955 | struct hci_dev *hdev; | ||
1956 | struct mgmt_cp_pin_code_neg_reply *cp = data; | 1835 | struct mgmt_cp_pin_code_neg_reply *cp = data; |
1957 | int err; | 1836 | int err; |
1958 | 1837 | ||
1959 | BT_DBG(""); | 1838 | BT_DBG(""); |
1960 | 1839 | ||
1961 | if (len != sizeof(*cp)) | 1840 | if (len != sizeof(*cp)) |
1962 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1841 | return cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, |
1963 | MGMT_STATUS_INVALID_PARAMS); | ||
1964 | |||
1965 | hdev = hci_dev_get(index); | ||
1966 | if (!hdev) | ||
1967 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | ||
1968 | MGMT_STATUS_INVALID_PARAMS); | 1842 | MGMT_STATUS_INVALID_PARAMS); |
1969 | 1843 | ||
1970 | hci_dev_lock(hdev); | 1844 | hci_dev_lock(hdev); |
1971 | 1845 | ||
1972 | if (!hdev_is_powered(hdev)) { | 1846 | if (!hdev_is_powered(hdev)) { |
1973 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1847 | err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, |
1974 | MGMT_STATUS_NOT_POWERED); | 1848 | MGMT_STATUS_NOT_POWERED); |
1975 | goto failed; | 1849 | goto failed; |
1976 | } | 1850 | } |
1977 | 1851 | ||
1978 | err = send_pin_code_neg_reply(sk, index, hdev, cp); | 1852 | err = send_pin_code_neg_reply(sk, hdev, cp); |
1979 | 1853 | ||
1980 | failed: | 1854 | failed: |
1981 | hci_dev_unlock(hdev); | 1855 | hci_dev_unlock(hdev); |
1982 | hci_dev_put(hdev); | ||
1983 | |||
1984 | return err; | 1856 | return err; |
1985 | } | 1857 | } |
1986 | 1858 | ||
1987 | static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len) | 1859 | static int set_io_capability(struct sock *sk, struct hci_dev *hdev, |
1860 | void *data, u16 len) | ||
1988 | { | 1861 | { |
1989 | struct hci_dev *hdev; | ||
1990 | struct mgmt_cp_set_io_capability *cp = data; | 1862 | struct mgmt_cp_set_io_capability *cp = data; |
1991 | 1863 | ||
1992 | BT_DBG(""); | 1864 | BT_DBG(""); |
1993 | 1865 | ||
1994 | if (len != sizeof(*cp)) | 1866 | if (len != sizeof(*cp)) |
1995 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, | 1867 | return cmd_status(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, |
1996 | MGMT_STATUS_INVALID_PARAMS); | ||
1997 | |||
1998 | hdev = hci_dev_get(index); | ||
1999 | if (!hdev) | ||
2000 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, | ||
2001 | MGMT_STATUS_INVALID_PARAMS); | 1868 | MGMT_STATUS_INVALID_PARAMS); |
2002 | 1869 | ||
2003 | hci_dev_lock(hdev); | 1870 | hci_dev_lock(hdev); |
@@ -2008,9 +1875,9 @@ static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len) | |||
2008 | hdev->io_capability); | 1875 | hdev->io_capability); |
2009 | 1876 | ||
2010 | hci_dev_unlock(hdev); | 1877 | hci_dev_unlock(hdev); |
2011 | hci_dev_put(hdev); | ||
2012 | 1878 | ||
2013 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, 0, NULL, 0); | 1879 | return cmd_complete(sk, hdev->id, MGMT_OP_SET_IO_CAPABILITY, 0, |
1880 | NULL, 0); | ||
2014 | } | 1881 | } |
2015 | 1882 | ||
2016 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) | 1883 | static inline struct pending_cmd *find_pairing(struct hci_conn *conn) |
@@ -2065,9 +1932,9 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) | |||
2065 | pairing_complete(cmd, mgmt_status(status)); | 1932 | pairing_complete(cmd, mgmt_status(status)); |
2066 | } | 1933 | } |
2067 | 1934 | ||
2068 | static int pair_device(struct sock *sk, u16 index, void *data, u16 len) | 1935 | static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, |
1936 | u16 len) | ||
2069 | { | 1937 | { |
2070 | struct hci_dev *hdev; | ||
2071 | struct mgmt_cp_pair_device *cp = data; | 1938 | struct mgmt_cp_pair_device *cp = data; |
2072 | struct mgmt_rp_pair_device rp; | 1939 | struct mgmt_rp_pair_device rp; |
2073 | struct pending_cmd *cmd; | 1940 | struct pending_cmd *cmd; |
@@ -2078,18 +1945,13 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2078 | BT_DBG(""); | 1945 | BT_DBG(""); |
2079 | 1946 | ||
2080 | if (len != sizeof(*cp)) | 1947 | if (len != sizeof(*cp)) |
2081 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, | 1948 | return cmd_status(sk, hdev->id, MGMT_OP_PAIR_DEVICE, |
2082 | MGMT_STATUS_INVALID_PARAMS); | ||
2083 | |||
2084 | hdev = hci_dev_get(index); | ||
2085 | if (!hdev) | ||
2086 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, | ||
2087 | MGMT_STATUS_INVALID_PARAMS); | 1949 | MGMT_STATUS_INVALID_PARAMS); |
2088 | 1950 | ||
2089 | hci_dev_lock(hdev); | 1951 | hci_dev_lock(hdev); |
2090 | 1952 | ||
2091 | if (!hdev_is_powered(hdev)) { | 1953 | if (!hdev_is_powered(hdev)) { |
2092 | err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, | 1954 | err = cmd_status(sk, hdev->id, MGMT_OP_PAIR_DEVICE, |
2093 | MGMT_STATUS_NOT_POWERED); | 1955 | MGMT_STATUS_NOT_POWERED); |
2094 | goto unlock; | 1956 | goto unlock; |
2095 | } | 1957 | } |
@@ -2112,7 +1974,7 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2112 | rp.addr.type = cp->addr.type; | 1974 | rp.addr.type = cp->addr.type; |
2113 | 1975 | ||
2114 | if (IS_ERR(conn)) { | 1976 | if (IS_ERR(conn)) { |
2115 | err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE, | 1977 | err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, |
2116 | MGMT_STATUS_CONNECT_FAILED, | 1978 | MGMT_STATUS_CONNECT_FAILED, |
2117 | &rp, sizeof(rp)); | 1979 | &rp, sizeof(rp)); |
2118 | goto unlock; | 1980 | goto unlock; |
@@ -2120,7 +1982,7 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2120 | 1982 | ||
2121 | if (conn->connect_cfm_cb) { | 1983 | if (conn->connect_cfm_cb) { |
2122 | hci_conn_put(conn); | 1984 | hci_conn_put(conn); |
2123 | err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE, | 1985 | err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, |
2124 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); | 1986 | MGMT_STATUS_BUSY, &rp, sizeof(rp)); |
2125 | goto unlock; | 1987 | goto unlock; |
2126 | } | 1988 | } |
@@ -2149,16 +2011,13 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2149 | 2011 | ||
2150 | unlock: | 2012 | unlock: |
2151 | hci_dev_unlock(hdev); | 2013 | hci_dev_unlock(hdev); |
2152 | hci_dev_put(hdev); | ||
2153 | |||
2154 | return err; | 2014 | return err; |
2155 | } | 2015 | } |
2156 | 2016 | ||
2157 | static int cancel_pair_device(struct sock *sk, u16 index, | 2017 | static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, |
2158 | unsigned char *data, u16 len) | 2018 | unsigned char *data, u16 len) |
2159 | { | 2019 | { |
2160 | struct mgmt_addr_info *addr = (void *) data; | 2020 | struct mgmt_addr_info *addr = (void *) data; |
2161 | struct hci_dev *hdev; | ||
2162 | struct pending_cmd *cmd; | 2021 | struct pending_cmd *cmd; |
2163 | struct hci_conn *conn; | 2022 | struct hci_conn *conn; |
2164 | int err; | 2023 | int err; |
@@ -2166,25 +2025,20 @@ static int cancel_pair_device(struct sock *sk, u16 index, | |||
2166 | BT_DBG(""); | 2025 | BT_DBG(""); |
2167 | 2026 | ||
2168 | if (len != sizeof(*addr)) | 2027 | if (len != sizeof(*addr)) |
2169 | return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, | 2028 | return cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, |
2170 | MGMT_STATUS_INVALID_PARAMS); | ||
2171 | |||
2172 | hdev = hci_dev_get(index); | ||
2173 | if (!hdev) | ||
2174 | return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, | ||
2175 | MGMT_STATUS_INVALID_PARAMS); | 2029 | MGMT_STATUS_INVALID_PARAMS); |
2176 | 2030 | ||
2177 | hci_dev_lock(hdev); | 2031 | hci_dev_lock(hdev); |
2178 | 2032 | ||
2179 | if (!hdev_is_powered(hdev)) { | 2033 | if (!hdev_is_powered(hdev)) { |
2180 | err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, | 2034 | err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, |
2181 | MGMT_STATUS_NOT_POWERED); | 2035 | MGMT_STATUS_NOT_POWERED); |
2182 | goto unlock; | 2036 | goto unlock; |
2183 | } | 2037 | } |
2184 | 2038 | ||
2185 | cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev); | 2039 | cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev); |
2186 | if (!cmd) { | 2040 | if (!cmd) { |
2187 | err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, | 2041 | err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, |
2188 | MGMT_STATUS_INVALID_PARAMS); | 2042 | MGMT_STATUS_INVALID_PARAMS); |
2189 | goto unlock; | 2043 | goto unlock; |
2190 | } | 2044 | } |
@@ -2192,40 +2046,33 @@ static int cancel_pair_device(struct sock *sk, u16 index, | |||
2192 | conn = cmd->user_data; | 2046 | conn = cmd->user_data; |
2193 | 2047 | ||
2194 | if (bacmp(&addr->bdaddr, &conn->dst) != 0) { | 2048 | if (bacmp(&addr->bdaddr, &conn->dst) != 0) { |
2195 | err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, | 2049 | err = cmd_status(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, |
2196 | MGMT_STATUS_INVALID_PARAMS); | 2050 | MGMT_STATUS_INVALID_PARAMS); |
2197 | goto unlock; | 2051 | goto unlock; |
2198 | } | 2052 | } |
2199 | 2053 | ||
2200 | pairing_complete(cmd, MGMT_STATUS_CANCELLED); | 2054 | pairing_complete(cmd, MGMT_STATUS_CANCELLED); |
2201 | 2055 | ||
2202 | err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, 0, addr, | 2056 | err = cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0, |
2203 | sizeof(*addr)); | 2057 | addr, sizeof(*addr)); |
2204 | unlock: | 2058 | unlock: |
2205 | hci_dev_unlock(hdev); | 2059 | hci_dev_unlock(hdev); |
2206 | hci_dev_put(hdev); | ||
2207 | |||
2208 | return err; | 2060 | return err; |
2209 | } | 2061 | } |
2210 | 2062 | ||
2211 | static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | 2063 | static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev, |
2212 | u8 type, u16 mgmt_op, u16 hci_op, | 2064 | bdaddr_t *bdaddr, u8 type, u16 mgmt_op, |
2213 | __le32 passkey) | 2065 | u16 hci_op, __le32 passkey) |
2214 | { | 2066 | { |
2215 | struct pending_cmd *cmd; | 2067 | struct pending_cmd *cmd; |
2216 | struct hci_dev *hdev; | ||
2217 | struct hci_conn *conn; | 2068 | struct hci_conn *conn; |
2218 | int err; | 2069 | int err; |
2219 | 2070 | ||
2220 | hdev = hci_dev_get(index); | ||
2221 | if (!hdev) | ||
2222 | return cmd_status(sk, index, mgmt_op, | ||
2223 | MGMT_STATUS_INVALID_PARAMS); | ||
2224 | |||
2225 | hci_dev_lock(hdev); | 2071 | hci_dev_lock(hdev); |
2226 | 2072 | ||
2227 | if (!hdev_is_powered(hdev)) { | 2073 | if (!hdev_is_powered(hdev)) { |
2228 | err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED); | 2074 | err = cmd_status(sk, hdev->id, mgmt_op, |
2075 | MGMT_STATUS_NOT_POWERED); | ||
2229 | goto done; | 2076 | goto done; |
2230 | } | 2077 | } |
2231 | 2078 | ||
@@ -2235,7 +2082,7 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
2235 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); | 2082 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr); |
2236 | 2083 | ||
2237 | if (!conn) { | 2084 | if (!conn) { |
2238 | err = cmd_status(sk, index, mgmt_op, | 2085 | err = cmd_status(sk, hdev->id, mgmt_op, |
2239 | MGMT_STATUS_NOT_CONNECTED); | 2086 | MGMT_STATUS_NOT_CONNECTED); |
2240 | goto done; | 2087 | goto done; |
2241 | } | 2088 | } |
@@ -2245,10 +2092,10 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
2245 | err = smp_user_confirm_reply(conn, mgmt_op, passkey); | 2092 | err = smp_user_confirm_reply(conn, mgmt_op, passkey); |
2246 | 2093 | ||
2247 | if (!err) | 2094 | if (!err) |
2248 | err = cmd_status(sk, index, mgmt_op, | 2095 | err = cmd_status(sk, hdev->id, mgmt_op, |
2249 | MGMT_STATUS_SUCCESS); | 2096 | MGMT_STATUS_SUCCESS); |
2250 | else | 2097 | else |
2251 | err = cmd_status(sk, index, mgmt_op, | 2098 | err = cmd_status(sk, hdev->id, mgmt_op, |
2252 | MGMT_STATUS_FAILED); | 2099 | MGMT_STATUS_FAILED); |
2253 | 2100 | ||
2254 | goto done; | 2101 | goto done; |
@@ -2275,92 +2122,86 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
2275 | 2122 | ||
2276 | done: | 2123 | done: |
2277 | hci_dev_unlock(hdev); | 2124 | hci_dev_unlock(hdev); |
2278 | hci_dev_put(hdev); | ||
2279 | |||
2280 | return err; | 2125 | return err; |
2281 | } | 2126 | } |
2282 | 2127 | ||
2283 | static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len) | 2128 | static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, |
2129 | void *data, u16 len) | ||
2284 | { | 2130 | { |
2285 | struct mgmt_cp_user_confirm_reply *cp = data; | 2131 | struct mgmt_cp_user_confirm_reply *cp = data; |
2286 | 2132 | ||
2287 | BT_DBG(""); | 2133 | BT_DBG(""); |
2288 | 2134 | ||
2289 | if (len != sizeof(*cp)) | 2135 | if (len != sizeof(*cp)) |
2290 | return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY, | 2136 | return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_REPLY, |
2291 | MGMT_STATUS_INVALID_PARAMS); | 2137 | MGMT_STATUS_INVALID_PARAMS); |
2292 | 2138 | ||
2293 | return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type, | 2139 | return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, |
2294 | MGMT_OP_USER_CONFIRM_REPLY, | 2140 | MGMT_OP_USER_CONFIRM_REPLY, |
2295 | HCI_OP_USER_CONFIRM_REPLY, 0); | 2141 | HCI_OP_USER_CONFIRM_REPLY, 0); |
2296 | } | 2142 | } |
2297 | 2143 | ||
2298 | static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data, | 2144 | static int user_confirm_neg_reply(struct sock *sk, struct hci_dev *hdev, |
2299 | u16 len) | 2145 | void *data, u16 len) |
2300 | { | 2146 | { |
2301 | struct mgmt_cp_user_confirm_neg_reply *cp = data; | 2147 | struct mgmt_cp_user_confirm_neg_reply *cp = data; |
2302 | 2148 | ||
2303 | BT_DBG(""); | 2149 | BT_DBG(""); |
2304 | 2150 | ||
2305 | if (len != sizeof(*cp)) | 2151 | if (len != sizeof(*cp)) |
2306 | return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY, | 2152 | return cmd_status(sk, hdev->id, MGMT_OP_USER_CONFIRM_NEG_REPLY, |
2307 | MGMT_STATUS_INVALID_PARAMS); | 2153 | MGMT_STATUS_INVALID_PARAMS); |
2308 | 2154 | ||
2309 | return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type, | 2155 | return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, |
2310 | MGMT_OP_USER_CONFIRM_NEG_REPLY, | 2156 | MGMT_OP_USER_CONFIRM_NEG_REPLY, |
2311 | HCI_OP_USER_CONFIRM_NEG_REPLY, 0); | 2157 | HCI_OP_USER_CONFIRM_NEG_REPLY, 0); |
2312 | } | 2158 | } |
2313 | 2159 | ||
2314 | static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len) | 2160 | static int user_passkey_reply(struct sock *sk, struct hci_dev *hdev, |
2161 | void *data, u16 len) | ||
2315 | { | 2162 | { |
2316 | struct mgmt_cp_user_passkey_reply *cp = data; | 2163 | struct mgmt_cp_user_passkey_reply *cp = data; |
2317 | 2164 | ||
2318 | BT_DBG(""); | 2165 | BT_DBG(""); |
2319 | 2166 | ||
2320 | if (len != sizeof(*cp)) | 2167 | if (len != sizeof(*cp)) |
2321 | return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY, | 2168 | return cmd_status(sk, hdev->id, MGMT_OP_USER_PASSKEY_REPLY, |
2322 | EINVAL); | 2169 | EINVAL); |
2323 | 2170 | ||
2324 | return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type, | 2171 | return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, |
2325 | MGMT_OP_USER_PASSKEY_REPLY, | 2172 | MGMT_OP_USER_PASSKEY_REPLY, |
2326 | HCI_OP_USER_PASSKEY_REPLY, | 2173 | HCI_OP_USER_PASSKEY_REPLY, |
2327 | cp->passkey); | 2174 | cp->passkey); |
2328 | } | 2175 | } |
2329 | 2176 | ||
2330 | static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data, | 2177 | static int user_passkey_neg_reply(struct sock *sk, struct hci_dev *hdev, |
2331 | u16 len) | 2178 | void *data, u16 len) |
2332 | { | 2179 | { |
2333 | struct mgmt_cp_user_passkey_neg_reply *cp = data; | 2180 | struct mgmt_cp_user_passkey_neg_reply *cp = data; |
2334 | 2181 | ||
2335 | BT_DBG(""); | 2182 | BT_DBG(""); |
2336 | 2183 | ||
2337 | if (len != sizeof(*cp)) | 2184 | if (len != sizeof(*cp)) |
2338 | return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY, | 2185 | return cmd_status(sk, hdev->id, MGMT_OP_USER_PASSKEY_NEG_REPLY, |
2339 | EINVAL); | 2186 | EINVAL); |
2340 | 2187 | ||
2341 | return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type, | 2188 | return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, |
2342 | MGMT_OP_USER_PASSKEY_NEG_REPLY, | 2189 | MGMT_OP_USER_PASSKEY_NEG_REPLY, |
2343 | HCI_OP_USER_PASSKEY_NEG_REPLY, 0); | 2190 | HCI_OP_USER_PASSKEY_NEG_REPLY, 0); |
2344 | } | 2191 | } |
2345 | 2192 | ||
2346 | static int set_local_name(struct sock *sk, u16 index, void *data, | 2193 | static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data, |
2347 | u16 len) | 2194 | u16 len) |
2348 | { | 2195 | { |
2349 | struct mgmt_cp_set_local_name *mgmt_cp = data; | 2196 | struct mgmt_cp_set_local_name *mgmt_cp = data; |
2350 | struct hci_cp_write_local_name hci_cp; | 2197 | struct hci_cp_write_local_name hci_cp; |
2351 | struct hci_dev *hdev; | ||
2352 | struct pending_cmd *cmd; | 2198 | struct pending_cmd *cmd; |
2353 | int err; | 2199 | int err; |
2354 | 2200 | ||
2355 | BT_DBG(""); | 2201 | BT_DBG(""); |
2356 | 2202 | ||
2357 | if (len != sizeof(*mgmt_cp)) | 2203 | if (len != sizeof(*mgmt_cp)) |
2358 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, | 2204 | return cmd_status(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, |
2359 | MGMT_STATUS_INVALID_PARAMS); | ||
2360 | |||
2361 | hdev = hci_dev_get(index); | ||
2362 | if (!hdev) | ||
2363 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, | ||
2364 | MGMT_STATUS_INVALID_PARAMS); | 2205 | MGMT_STATUS_INVALID_PARAMS); |
2365 | 2206 | ||
2366 | hci_dev_lock(hdev); | 2207 | hci_dev_lock(hdev); |
@@ -2396,40 +2237,32 @@ static int set_local_name(struct sock *sk, u16 index, void *data, | |||
2396 | 2237 | ||
2397 | failed: | 2238 | failed: |
2398 | hci_dev_unlock(hdev); | 2239 | hci_dev_unlock(hdev); |
2399 | hci_dev_put(hdev); | ||
2400 | |||
2401 | return err; | 2240 | return err; |
2402 | } | 2241 | } |
2403 | 2242 | ||
2404 | static int read_local_oob_data(struct sock *sk, u16 index) | 2243 | static int read_local_oob_data(struct sock *sk, struct hci_dev *hdev) |
2405 | { | 2244 | { |
2406 | struct hci_dev *hdev; | ||
2407 | struct pending_cmd *cmd; | 2245 | struct pending_cmd *cmd; |
2408 | int err; | 2246 | int err; |
2409 | 2247 | ||
2410 | BT_DBG("hci%u", index); | 2248 | BT_DBG("%s", hdev->name); |
2411 | |||
2412 | hdev = hci_dev_get(index); | ||
2413 | if (!hdev) | ||
2414 | return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | ||
2415 | MGMT_STATUS_INVALID_PARAMS); | ||
2416 | 2249 | ||
2417 | hci_dev_lock(hdev); | 2250 | hci_dev_lock(hdev); |
2418 | 2251 | ||
2419 | if (!hdev_is_powered(hdev)) { | 2252 | if (!hdev_is_powered(hdev)) { |
2420 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2253 | err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
2421 | MGMT_STATUS_NOT_POWERED); | 2254 | MGMT_STATUS_NOT_POWERED); |
2422 | goto unlock; | 2255 | goto unlock; |
2423 | } | 2256 | } |
2424 | 2257 | ||
2425 | if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { | 2258 | if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) { |
2426 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2259 | err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
2427 | MGMT_STATUS_NOT_SUPPORTED); | 2260 | MGMT_STATUS_NOT_SUPPORTED); |
2428 | goto unlock; | 2261 | goto unlock; |
2429 | } | 2262 | } |
2430 | 2263 | ||
2431 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { | 2264 | if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) { |
2432 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 2265 | err = cmd_status(sk, hdev->id, MGMT_OP_READ_LOCAL_OOB_DATA, |
2433 | MGMT_STATUS_BUSY); | 2266 | MGMT_STATUS_BUSY); |
2434 | goto unlock; | 2267 | goto unlock; |
2435 | } | 2268 | } |
@@ -2446,35 +2279,26 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
2446 | 2279 | ||
2447 | unlock: | 2280 | unlock: |
2448 | hci_dev_unlock(hdev); | 2281 | hci_dev_unlock(hdev); |
2449 | hci_dev_put(hdev); | ||
2450 | |||
2451 | return err; | 2282 | return err; |
2452 | } | 2283 | } |
2453 | 2284 | ||
2454 | static int add_remote_oob_data(struct sock *sk, u16 index, void *data, | 2285 | static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, |
2455 | u16 len) | 2286 | void *data, u16 len) |
2456 | { | 2287 | { |
2457 | struct hci_dev *hdev; | ||
2458 | struct mgmt_cp_add_remote_oob_data *cp = data; | 2288 | struct mgmt_cp_add_remote_oob_data *cp = data; |
2459 | u8 status; | 2289 | u8 status; |
2460 | int err; | 2290 | int err; |
2461 | 2291 | ||
2462 | BT_DBG("hci%u ", index); | 2292 | BT_DBG("%s ", hdev->name); |
2463 | 2293 | ||
2464 | if (len != sizeof(*cp)) | 2294 | if (len != sizeof(*cp)) |
2465 | return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, | 2295 | return cmd_status(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, |
2466 | MGMT_STATUS_INVALID_PARAMS); | 2296 | MGMT_STATUS_INVALID_PARAMS); |
2467 | 2297 | ||
2468 | hdev = hci_dev_get(index); | ||
2469 | if (!hdev) | ||
2470 | return cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, | ||
2471 | MGMT_STATUS_INVALID_PARAMS, | ||
2472 | &cp->addr, sizeof(cp->addr)); | ||
2473 | |||
2474 | hci_dev_lock(hdev); | 2298 | hci_dev_lock(hdev); |
2475 | 2299 | ||
2476 | if (!hdev_is_powered(hdev)) { | 2300 | if (!hdev_is_powered(hdev)) { |
2477 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, | 2301 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, |
2478 | MGMT_STATUS_NOT_POWERED, | 2302 | MGMT_STATUS_NOT_POWERED, |
2479 | &cp->addr, sizeof(cp->addr)); | 2303 | &cp->addr, sizeof(cp->addr)); |
2480 | goto unlock; | 2304 | goto unlock; |
@@ -2487,42 +2311,34 @@ static int add_remote_oob_data(struct sock *sk, u16 index, void *data, | |||
2487 | else | 2311 | else |
2488 | status = 0; | 2312 | status = 0; |
2489 | 2313 | ||
2490 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, status, | 2314 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status, |
2491 | &cp->addr, sizeof(cp->addr)); | 2315 | &cp->addr, sizeof(cp->addr)); |
2492 | 2316 | ||
2493 | unlock: | 2317 | unlock: |
2494 | hci_dev_unlock(hdev); | 2318 | hci_dev_unlock(hdev); |
2495 | hci_dev_put(hdev); | ||
2496 | |||
2497 | return err; | 2319 | return err; |
2498 | } | 2320 | } |
2499 | 2321 | ||
2500 | static int remove_remote_oob_data(struct sock *sk, u16 index, | 2322 | static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, |
2501 | void *data, u16 len) | 2323 | void *data, u16 len) |
2502 | { | 2324 | { |
2503 | struct hci_dev *hdev; | ||
2504 | struct mgmt_cp_remove_remote_oob_data *cp = data; | 2325 | struct mgmt_cp_remove_remote_oob_data *cp = data; |
2505 | u8 status; | 2326 | u8 status; |
2506 | int err; | 2327 | int err; |
2507 | 2328 | ||
2508 | BT_DBG("hci%u ", index); | 2329 | BT_DBG("%s", hdev->name); |
2509 | 2330 | ||
2510 | if (len != sizeof(*cp)) | 2331 | if (len != sizeof(*cp)) |
2511 | return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 2332 | return cmd_status(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
2512 | MGMT_STATUS_INVALID_PARAMS); | 2333 | MGMT_STATUS_INVALID_PARAMS); |
2513 | 2334 | ||
2514 | hdev = hci_dev_get(index); | ||
2515 | if (!hdev) | ||
2516 | return cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | ||
2517 | MGMT_STATUS_INVALID_PARAMS, | ||
2518 | &cp->addr, sizeof(cp->addr)); | ||
2519 | |||
2520 | hci_dev_lock(hdev); | 2335 | hci_dev_lock(hdev); |
2521 | 2336 | ||
2522 | if (!hdev_is_powered(hdev)) { | 2337 | if (!hdev_is_powered(hdev)) { |
2523 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 2338 | err = cmd_complete(sk, hdev->id, |
2524 | MGMT_STATUS_NOT_POWERED, | 2339 | MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
2525 | &cp->addr, sizeof(cp->addr)); | 2340 | MGMT_STATUS_NOT_POWERED, |
2341 | &cp->addr, sizeof(cp->addr)); | ||
2526 | goto unlock; | 2342 | goto unlock; |
2527 | } | 2343 | } |
2528 | 2344 | ||
@@ -2532,13 +2348,11 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
2532 | else | 2348 | else |
2533 | status = 0; | 2349 | status = 0; |
2534 | 2350 | ||
2535 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, status, | 2351 | err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
2536 | &cp->addr, sizeof(cp->addr)); | 2352 | status, &cp->addr, sizeof(cp->addr)); |
2537 | 2353 | ||
2538 | unlock: | 2354 | unlock: |
2539 | hci_dev_unlock(hdev); | 2355 | hci_dev_unlock(hdev); |
2540 | hci_dev_put(hdev); | ||
2541 | |||
2542 | return err; | 2356 | return err; |
2543 | } | 2357 | } |
2544 | 2358 | ||
@@ -2559,36 +2373,30 @@ int mgmt_interleaved_discovery(struct hci_dev *hdev) | |||
2559 | return err; | 2373 | return err; |
2560 | } | 2374 | } |
2561 | 2375 | ||
2562 | static int start_discovery(struct sock *sk, u16 index, | 2376 | static int start_discovery(struct sock *sk, struct hci_dev *hdev, |
2563 | void *data, u16 len) | 2377 | void *data, u16 len) |
2564 | { | 2378 | { |
2565 | struct mgmt_cp_start_discovery *cp = data; | 2379 | struct mgmt_cp_start_discovery *cp = data; |
2566 | struct pending_cmd *cmd; | 2380 | struct pending_cmd *cmd; |
2567 | struct hci_dev *hdev; | ||
2568 | int err; | 2381 | int err; |
2569 | 2382 | ||
2570 | BT_DBG("hci%u", index); | 2383 | BT_DBG("%s", hdev->name); |
2571 | 2384 | ||
2572 | if (len != sizeof(*cp)) | 2385 | if (len != sizeof(*cp)) |
2573 | return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | 2386 | return cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2574 | MGMT_STATUS_INVALID_PARAMS); | ||
2575 | |||
2576 | hdev = hci_dev_get(index); | ||
2577 | if (!hdev) | ||
2578 | return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | ||
2579 | MGMT_STATUS_INVALID_PARAMS); | 2387 | MGMT_STATUS_INVALID_PARAMS); |
2580 | 2388 | ||
2581 | hci_dev_lock(hdev); | 2389 | hci_dev_lock(hdev); |
2582 | 2390 | ||
2583 | if (!hdev_is_powered(hdev)) { | 2391 | if (!hdev_is_powered(hdev)) { |
2584 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | 2392 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2585 | MGMT_STATUS_NOT_POWERED); | 2393 | MGMT_STATUS_NOT_POWERED); |
2586 | goto failed; | 2394 | goto failed; |
2587 | } | 2395 | } |
2588 | 2396 | ||
2589 | if (hdev->discovery.state != DISCOVERY_STOPPED) { | 2397 | if (hdev->discovery.state != DISCOVERY_STOPPED) { |
2590 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | 2398 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2591 | MGMT_STATUS_BUSY); | 2399 | MGMT_STATUS_BUSY); |
2592 | goto failed; | 2400 | goto failed; |
2593 | } | 2401 | } |
2594 | 2402 | ||
@@ -2635,42 +2443,35 @@ static int start_discovery(struct sock *sk, u16 index, | |||
2635 | 2443 | ||
2636 | failed: | 2444 | failed: |
2637 | hci_dev_unlock(hdev); | 2445 | hci_dev_unlock(hdev); |
2638 | hci_dev_put(hdev); | ||
2639 | |||
2640 | return err; | 2446 | return err; |
2641 | } | 2447 | } |
2642 | 2448 | ||
2643 | static int stop_discovery(struct sock *sk, u16 index, void *data, u16 len) | 2449 | static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, |
2450 | u16 len) | ||
2644 | { | 2451 | { |
2645 | struct mgmt_cp_stop_discovery *mgmt_cp = data; | 2452 | struct mgmt_cp_stop_discovery *mgmt_cp = data; |
2646 | struct hci_dev *hdev; | ||
2647 | struct pending_cmd *cmd; | 2453 | struct pending_cmd *cmd; |
2648 | struct hci_cp_remote_name_req_cancel cp; | 2454 | struct hci_cp_remote_name_req_cancel cp; |
2649 | struct inquiry_entry *e; | 2455 | struct inquiry_entry *e; |
2650 | int err; | 2456 | int err; |
2651 | 2457 | ||
2652 | BT_DBG("hci%u", index); | 2458 | BT_DBG("%s", hdev->name); |
2653 | 2459 | ||
2654 | if (len != sizeof(*mgmt_cp)) | 2460 | if (len != sizeof(*mgmt_cp)) |
2655 | return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, | 2461 | return cmd_status(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, |
2656 | MGMT_STATUS_INVALID_PARAMS); | ||
2657 | |||
2658 | hdev = hci_dev_get(index); | ||
2659 | if (!hdev) | ||
2660 | return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, | ||
2661 | MGMT_STATUS_INVALID_PARAMS); | 2462 | MGMT_STATUS_INVALID_PARAMS); |
2662 | 2463 | ||
2663 | hci_dev_lock(hdev); | 2464 | hci_dev_lock(hdev); |
2664 | 2465 | ||
2665 | if (!hci_discovery_active(hdev)) { | 2466 | if (!hci_discovery_active(hdev)) { |
2666 | err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, | 2467 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, |
2667 | MGMT_STATUS_REJECTED, | 2468 | MGMT_STATUS_REJECTED, |
2668 | &mgmt_cp->type, sizeof(mgmt_cp->type)); | 2469 | &mgmt_cp->type, sizeof(mgmt_cp->type)); |
2669 | goto unlock; | 2470 | goto unlock; |
2670 | } | 2471 | } |
2671 | 2472 | ||
2672 | if (hdev->discovery.type != mgmt_cp->type) { | 2473 | if (hdev->discovery.type != mgmt_cp->type) { |
2673 | err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, | 2474 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, |
2674 | MGMT_STATUS_INVALID_PARAMS, | 2475 | MGMT_STATUS_INVALID_PARAMS, |
2675 | &mgmt_cp->type, sizeof(mgmt_cp->type)); | 2476 | &mgmt_cp->type, sizeof(mgmt_cp->type)); |
2676 | goto unlock; | 2477 | goto unlock; |
@@ -2694,7 +2495,7 @@ static int stop_discovery(struct sock *sk, u16 index, void *data, u16 len) | |||
2694 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING); | 2495 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING); |
2695 | if (!e) { | 2496 | if (!e) { |
2696 | mgmt_pending_remove(cmd); | 2497 | mgmt_pending_remove(cmd); |
2697 | err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, 0, | 2498 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0, |
2698 | &mgmt_cp->type, sizeof(mgmt_cp->type)); | 2499 | &mgmt_cp->type, sizeof(mgmt_cp->type)); |
2699 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | 2500 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
2700 | goto unlock; | 2501 | goto unlock; |
@@ -2710,41 +2511,34 @@ static int stop_discovery(struct sock *sk, u16 index, void *data, u16 len) | |||
2710 | 2511 | ||
2711 | unlock: | 2512 | unlock: |
2712 | hci_dev_unlock(hdev); | 2513 | hci_dev_unlock(hdev); |
2713 | hci_dev_put(hdev); | ||
2714 | |||
2715 | return err; | 2514 | return err; |
2716 | } | 2515 | } |
2717 | 2516 | ||
2718 | static int confirm_name(struct sock *sk, u16 index, void *data, u16 len) | 2517 | static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data, |
2518 | u16 len) | ||
2719 | { | 2519 | { |
2720 | struct mgmt_cp_confirm_name *cp = data; | 2520 | struct mgmt_cp_confirm_name *cp = data; |
2721 | struct inquiry_entry *e; | 2521 | struct inquiry_entry *e; |
2722 | struct hci_dev *hdev; | ||
2723 | int err; | 2522 | int err; |
2724 | 2523 | ||
2725 | BT_DBG("hci%u", index); | 2524 | BT_DBG("%s", hdev->name); |
2726 | 2525 | ||
2727 | if (len != sizeof(*cp)) | 2526 | if (len != sizeof(*cp)) |
2728 | return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME, | 2527 | return cmd_status(sk, hdev->id, MGMT_OP_CONFIRM_NAME, |
2729 | MGMT_STATUS_INVALID_PARAMS); | 2528 | MGMT_STATUS_INVALID_PARAMS); |
2730 | |||
2731 | hdev = hci_dev_get(index); | ||
2732 | if (!hdev) | ||
2733 | return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME, | ||
2734 | MGMT_STATUS_INVALID_PARAMS); | ||
2735 | 2529 | ||
2736 | hci_dev_lock(hdev); | 2530 | hci_dev_lock(hdev); |
2737 | 2531 | ||
2738 | if (!hci_discovery_active(hdev)) { | 2532 | if (!hci_discovery_active(hdev)) { |
2739 | err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME, | 2533 | err = cmd_status(sk, hdev->id, MGMT_OP_CONFIRM_NAME, |
2740 | MGMT_STATUS_FAILED); | 2534 | MGMT_STATUS_FAILED); |
2741 | goto failed; | 2535 | goto failed; |
2742 | } | 2536 | } |
2743 | 2537 | ||
2744 | e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr); | 2538 | e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr); |
2745 | if (!e) { | 2539 | if (!e) { |
2746 | err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME, | 2540 | err = cmd_status(sk, hdev->id, MGMT_OP_CONFIRM_NAME, |
2747 | MGMT_STATUS_INVALID_PARAMS); | 2541 | MGMT_STATUS_INVALID_PARAMS); |
2748 | goto failed; | 2542 | goto failed; |
2749 | } | 2543 | } |
2750 | 2544 | ||
@@ -2760,29 +2554,22 @@ static int confirm_name(struct sock *sk, u16 index, void *data, u16 len) | |||
2760 | 2554 | ||
2761 | failed: | 2555 | failed: |
2762 | hci_dev_unlock(hdev); | 2556 | hci_dev_unlock(hdev); |
2763 | |||
2764 | return err; | 2557 | return err; |
2765 | } | 2558 | } |
2766 | 2559 | ||
2767 | static int block_device(struct sock *sk, u16 index, void *data, u16 len) | 2560 | static int block_device(struct sock *sk, struct hci_dev *hdev, void *data, |
2561 | u16 len) | ||
2768 | { | 2562 | { |
2769 | struct hci_dev *hdev; | ||
2770 | struct mgmt_cp_block_device *cp = data; | 2563 | struct mgmt_cp_block_device *cp = data; |
2771 | u8 status; | 2564 | u8 status; |
2772 | int err; | 2565 | int err; |
2773 | 2566 | ||
2774 | BT_DBG("hci%u", index); | 2567 | BT_DBG("%s", hdev->name); |
2775 | 2568 | ||
2776 | if (len != sizeof(*cp)) | 2569 | if (len != sizeof(*cp)) |
2777 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | 2570 | return cmd_status(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, |
2778 | MGMT_STATUS_INVALID_PARAMS); | 2571 | MGMT_STATUS_INVALID_PARAMS); |
2779 | 2572 | ||
2780 | hdev = hci_dev_get(index); | ||
2781 | if (!hdev) | ||
2782 | return cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | ||
2783 | MGMT_STATUS_INVALID_PARAMS, | ||
2784 | &cp->addr, sizeof(cp->addr)); | ||
2785 | |||
2786 | hci_dev_lock(hdev); | 2573 | hci_dev_lock(hdev); |
2787 | 2574 | ||
2788 | err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type); | 2575 | err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type); |
@@ -2791,34 +2578,27 @@ static int block_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2791 | else | 2578 | else |
2792 | status = 0; | 2579 | status = 0; |
2793 | 2580 | ||
2794 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, status, | 2581 | err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status, |
2795 | &cp->addr, sizeof(cp->addr)); | 2582 | &cp->addr, sizeof(cp->addr)); |
2796 | 2583 | ||
2797 | hci_dev_unlock(hdev); | 2584 | hci_dev_unlock(hdev); |
2798 | hci_dev_put(hdev); | ||
2799 | 2585 | ||
2800 | return err; | 2586 | return err; |
2801 | } | 2587 | } |
2802 | 2588 | ||
2803 | static int unblock_device(struct sock *sk, u16 index, void *data, u16 len) | 2589 | static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data, |
2590 | u16 len) | ||
2804 | { | 2591 | { |
2805 | struct hci_dev *hdev; | ||
2806 | struct mgmt_cp_unblock_device *cp = data; | 2592 | struct mgmt_cp_unblock_device *cp = data; |
2807 | u8 status; | 2593 | u8 status; |
2808 | int err; | 2594 | int err; |
2809 | 2595 | ||
2810 | BT_DBG("hci%u", index); | 2596 | BT_DBG("%s", hdev->name); |
2811 | 2597 | ||
2812 | if (len != sizeof(*cp)) | 2598 | if (len != sizeof(*cp)) |
2813 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | 2599 | return cmd_status(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, |
2814 | MGMT_STATUS_INVALID_PARAMS); | 2600 | MGMT_STATUS_INVALID_PARAMS); |
2815 | 2601 | ||
2816 | hdev = hci_dev_get(index); | ||
2817 | if (!hdev) | ||
2818 | return cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | ||
2819 | MGMT_STATUS_INVALID_PARAMS, | ||
2820 | &cp->addr, sizeof(cp->addr)); | ||
2821 | |||
2822 | hci_dev_lock(hdev); | 2602 | hci_dev_lock(hdev); |
2823 | 2603 | ||
2824 | err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type); | 2604 | err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type); |
@@ -2827,41 +2607,35 @@ static int unblock_device(struct sock *sk, u16 index, void *data, u16 len) | |||
2827 | else | 2607 | else |
2828 | status = 0; | 2608 | status = 0; |
2829 | 2609 | ||
2830 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, status, | 2610 | err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status, |
2831 | &cp->addr, sizeof(cp->addr)); | 2611 | &cp->addr, sizeof(cp->addr)); |
2832 | 2612 | ||
2833 | hci_dev_unlock(hdev); | 2613 | hci_dev_unlock(hdev); |
2834 | hci_dev_put(hdev); | ||
2835 | 2614 | ||
2836 | return err; | 2615 | return err; |
2837 | } | 2616 | } |
2838 | 2617 | ||
2839 | static int set_fast_connectable(struct sock *sk, u16 index, | 2618 | static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, |
2840 | void *data, u16 len) | 2619 | void *data, u16 len) |
2841 | { | 2620 | { |
2842 | struct hci_dev *hdev; | ||
2843 | struct mgmt_mode *cp = data; | 2621 | struct mgmt_mode *cp = data; |
2844 | struct hci_cp_write_page_scan_activity acp; | 2622 | struct hci_cp_write_page_scan_activity acp; |
2845 | u8 type; | 2623 | u8 type; |
2846 | int err; | 2624 | int err; |
2847 | 2625 | ||
2848 | BT_DBG("hci%u", index); | 2626 | BT_DBG("%s", hdev->name); |
2849 | 2627 | ||
2850 | if (len != sizeof(*cp)) | 2628 | if (len != sizeof(*cp)) |
2851 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | 2629 | return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
2852 | MGMT_STATUS_INVALID_PARAMS); | 2630 | MGMT_STATUS_INVALID_PARAMS); |
2853 | 2631 | ||
2854 | hdev = hci_dev_get(index); | ||
2855 | if (!hdev) | ||
2856 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | ||
2857 | MGMT_STATUS_INVALID_PARAMS); | ||
2858 | if (!hdev_is_powered(hdev)) | 2632 | if (!hdev_is_powered(hdev)) |
2859 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | 2633 | return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
2860 | MGMT_STATUS_NOT_POWERED); | 2634 | MGMT_STATUS_NOT_POWERED); |
2861 | 2635 | ||
2862 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) | 2636 | if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) |
2863 | return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | 2637 | return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
2864 | MGMT_STATUS_REJECTED); | 2638 | MGMT_STATUS_REJECTED); |
2865 | 2639 | ||
2866 | hci_dev_lock(hdev); | 2640 | hci_dev_lock(hdev); |
2867 | 2641 | ||
@@ -2878,37 +2652,34 @@ static int set_fast_connectable(struct sock *sk, u16 index, | |||
2878 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, | 2652 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, |
2879 | sizeof(acp), &acp); | 2653 | sizeof(acp), &acp); |
2880 | if (err < 0) { | 2654 | if (err < 0) { |
2881 | err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | 2655 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
2882 | MGMT_STATUS_FAILED); | 2656 | MGMT_STATUS_FAILED); |
2883 | goto done; | 2657 | goto done; |
2884 | } | 2658 | } |
2885 | 2659 | ||
2886 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); | 2660 | err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); |
2887 | if (err < 0) { | 2661 | if (err < 0) { |
2888 | err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, | 2662 | err = cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, |
2889 | MGMT_STATUS_FAILED); | 2663 | MGMT_STATUS_FAILED); |
2890 | goto done; | 2664 | goto done; |
2891 | } | 2665 | } |
2892 | 2666 | ||
2893 | err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, 0, | 2667 | err = cmd_complete(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 0, |
2894 | NULL, 0); | 2668 | NULL, 0); |
2895 | done: | 2669 | done: |
2896 | hci_dev_unlock(hdev); | 2670 | hci_dev_unlock(hdev); |
2897 | hci_dev_put(hdev); | ||
2898 | |||
2899 | return err; | 2671 | return err; |
2900 | } | 2672 | } |
2901 | 2673 | ||
2902 | static int load_long_term_keys(struct sock *sk, u16 index, | 2674 | static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, |
2903 | void *cp_data, u16 len) | 2675 | void *cp_data, u16 len) |
2904 | { | 2676 | { |
2905 | struct hci_dev *hdev; | ||
2906 | struct mgmt_cp_load_long_term_keys *cp = cp_data; | 2677 | struct mgmt_cp_load_long_term_keys *cp = cp_data; |
2907 | u16 key_count, expected_len; | 2678 | u16 key_count, expected_len; |
2908 | int i; | 2679 | int i; |
2909 | 2680 | ||
2910 | if (len < sizeof(*cp)) | 2681 | if (len < sizeof(*cp)) |
2911 | return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS, | 2682 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, |
2912 | EINVAL); | 2683 | EINVAL); |
2913 | 2684 | ||
2914 | key_count = get_unaligned_le16(&cp->key_count); | 2685 | key_count = get_unaligned_le16(&cp->key_count); |
@@ -2918,16 +2689,11 @@ static int load_long_term_keys(struct sock *sk, u16 index, | |||
2918 | if (expected_len != len) { | 2689 | if (expected_len != len) { |
2919 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | 2690 | BT_ERR("load_keys: expected %u bytes, got %u bytes", |
2920 | len, expected_len); | 2691 | len, expected_len); |
2921 | return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS, | 2692 | return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, |
2922 | EINVAL); | 2693 | EINVAL); |
2923 | } | 2694 | } |
2924 | 2695 | ||
2925 | hdev = hci_dev_get(index); | 2696 | BT_DBG("%s key_count %u", hdev->name, key_count); |
2926 | if (!hdev) | ||
2927 | return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS, | ||
2928 | ENODEV); | ||
2929 | |||
2930 | BT_DBG("hci%u key_count %u", index, key_count); | ||
2931 | 2697 | ||
2932 | hci_dev_lock(hdev); | 2698 | hci_dev_lock(hdev); |
2933 | 2699 | ||
@@ -2948,7 +2714,6 @@ static int load_long_term_keys(struct sock *sk, u16 index, | |||
2948 | } | 2714 | } |
2949 | 2715 | ||
2950 | hci_dev_unlock(hdev); | 2716 | hci_dev_unlock(hdev); |
2951 | hci_dev_put(hdev); | ||
2952 | 2717 | ||
2953 | return 0; | 2718 | return 0; |
2954 | } | 2719 | } |
@@ -2959,6 +2724,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2959 | u8 *cp; | 2724 | u8 *cp; |
2960 | struct mgmt_hdr *hdr; | 2725 | struct mgmt_hdr *hdr; |
2961 | u16 opcode, index, len; | 2726 | u16 opcode, index, len; |
2727 | struct hci_dev *hdev = NULL; | ||
2962 | int err; | 2728 | int err; |
2963 | 2729 | ||
2964 | BT_DBG("got %zu bytes", msglen); | 2730 | BT_DBG("got %zu bytes", msglen); |
@@ -2985,6 +2751,21 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2985 | goto done; | 2751 | goto done; |
2986 | } | 2752 | } |
2987 | 2753 | ||
2754 | if (opcode < MGMT_OP_READ_INFO) { | ||
2755 | if (index != MGMT_INDEX_NONE) { | ||
2756 | err = cmd_status(sk, index, opcode, | ||
2757 | MGMT_STATUS_INVALID_PARAMS); | ||
2758 | goto done; | ||
2759 | } | ||
2760 | } else { | ||
2761 | hdev = hci_dev_get(index); | ||
2762 | if (!hdev) { | ||
2763 | err = cmd_status(sk, index, opcode, | ||
2764 | MGMT_STATUS_INVALID_PARAMS); | ||
2765 | goto done; | ||
2766 | } | ||
2767 | } | ||
2768 | |||
2988 | cp = buf + sizeof(*hdr); | 2769 | cp = buf + sizeof(*hdr); |
2989 | 2770 | ||
2990 | switch (opcode) { | 2771 | switch (opcode) { |
@@ -2998,112 +2779,112 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2998 | err = read_index_list(sk); | 2779 | err = read_index_list(sk); |
2999 | break; | 2780 | break; |
3000 | case MGMT_OP_READ_INFO: | 2781 | case MGMT_OP_READ_INFO: |
3001 | err = read_controller_info(sk, index); | 2782 | err = read_controller_info(sk, hdev); |
3002 | break; | 2783 | break; |
3003 | case MGMT_OP_SET_POWERED: | 2784 | case MGMT_OP_SET_POWERED: |
3004 | err = set_powered(sk, index, cp, len); | 2785 | err = set_powered(sk, hdev, cp, len); |
3005 | break; | 2786 | break; |
3006 | case MGMT_OP_SET_DISCOVERABLE: | 2787 | case MGMT_OP_SET_DISCOVERABLE: |
3007 | err = set_discoverable(sk, index, cp, len); | 2788 | err = set_discoverable(sk, hdev, cp, len); |
3008 | break; | 2789 | break; |
3009 | case MGMT_OP_SET_CONNECTABLE: | 2790 | case MGMT_OP_SET_CONNECTABLE: |
3010 | err = set_connectable(sk, index, cp, len); | 2791 | err = set_connectable(sk, hdev, cp, len); |
3011 | break; | 2792 | break; |
3012 | case MGMT_OP_SET_FAST_CONNECTABLE: | 2793 | case MGMT_OP_SET_FAST_CONNECTABLE: |
3013 | err = set_fast_connectable(sk, index, cp, len); | 2794 | err = set_fast_connectable(sk, hdev, cp, len); |
3014 | break; | 2795 | break; |
3015 | case MGMT_OP_SET_PAIRABLE: | 2796 | case MGMT_OP_SET_PAIRABLE: |
3016 | err = set_pairable(sk, index, cp, len); | 2797 | err = set_pairable(sk, hdev, cp, len); |
3017 | break; | 2798 | break; |
3018 | case MGMT_OP_SET_LINK_SECURITY: | 2799 | case MGMT_OP_SET_LINK_SECURITY: |
3019 | err = set_link_security(sk, index, cp, len); | 2800 | err = set_link_security(sk, hdev, cp, len); |
3020 | break; | 2801 | break; |
3021 | case MGMT_OP_SET_SSP: | 2802 | case MGMT_OP_SET_SSP: |
3022 | err = set_ssp(sk, index, cp, len); | 2803 | err = set_ssp(sk, hdev, cp, len); |
3023 | break; | 2804 | break; |
3024 | case MGMT_OP_SET_HS: | 2805 | case MGMT_OP_SET_HS: |
3025 | err = set_hs(sk, index, cp, len); | 2806 | err = set_hs(sk, hdev, cp, len); |
3026 | break; | 2807 | break; |
3027 | case MGMT_OP_SET_LE: | 2808 | case MGMT_OP_SET_LE: |
3028 | err = set_le(sk, index, cp, len); | 2809 | err = set_le(sk, hdev, cp, len); |
3029 | break; | 2810 | break; |
3030 | case MGMT_OP_ADD_UUID: | 2811 | case MGMT_OP_ADD_UUID: |
3031 | err = add_uuid(sk, index, cp, len); | 2812 | err = add_uuid(sk, hdev, cp, len); |
3032 | break; | 2813 | break; |
3033 | case MGMT_OP_REMOVE_UUID: | 2814 | case MGMT_OP_REMOVE_UUID: |
3034 | err = remove_uuid(sk, index, cp, len); | 2815 | err = remove_uuid(sk, hdev, cp, len); |
3035 | break; | 2816 | break; |
3036 | case MGMT_OP_SET_DEV_CLASS: | 2817 | case MGMT_OP_SET_DEV_CLASS: |
3037 | err = set_dev_class(sk, index, cp, len); | 2818 | err = set_dev_class(sk, hdev, cp, len); |
3038 | break; | 2819 | break; |
3039 | case MGMT_OP_LOAD_LINK_KEYS: | 2820 | case MGMT_OP_LOAD_LINK_KEYS: |
3040 | err = load_link_keys(sk, index, cp, len); | 2821 | err = load_link_keys(sk, hdev, cp, len); |
3041 | break; | 2822 | break; |
3042 | case MGMT_OP_DISCONNECT: | 2823 | case MGMT_OP_DISCONNECT: |
3043 | err = disconnect(sk, index, cp, len); | 2824 | err = disconnect(sk, hdev, cp, len); |
3044 | break; | 2825 | break; |
3045 | case MGMT_OP_GET_CONNECTIONS: | 2826 | case MGMT_OP_GET_CONNECTIONS: |
3046 | err = get_connections(sk, index); | 2827 | err = get_connections(sk, hdev); |
3047 | break; | 2828 | break; |
3048 | case MGMT_OP_PIN_CODE_REPLY: | 2829 | case MGMT_OP_PIN_CODE_REPLY: |
3049 | err = pin_code_reply(sk, index, cp, len); | 2830 | err = pin_code_reply(sk, hdev, cp, len); |
3050 | break; | 2831 | break; |
3051 | case MGMT_OP_PIN_CODE_NEG_REPLY: | 2832 | case MGMT_OP_PIN_CODE_NEG_REPLY: |
3052 | err = pin_code_neg_reply(sk, index, cp, len); | 2833 | err = pin_code_neg_reply(sk, hdev, cp, len); |
3053 | break; | 2834 | break; |
3054 | case MGMT_OP_SET_IO_CAPABILITY: | 2835 | case MGMT_OP_SET_IO_CAPABILITY: |
3055 | err = set_io_capability(sk, index, cp, len); | 2836 | err = set_io_capability(sk, hdev, cp, len); |
3056 | break; | 2837 | break; |
3057 | case MGMT_OP_PAIR_DEVICE: | 2838 | case MGMT_OP_PAIR_DEVICE: |
3058 | err = pair_device(sk, index, cp, len); | 2839 | err = pair_device(sk, hdev, cp, len); |
3059 | break; | 2840 | break; |
3060 | case MGMT_OP_CANCEL_PAIR_DEVICE: | 2841 | case MGMT_OP_CANCEL_PAIR_DEVICE: |
3061 | err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len); | 2842 | err = cancel_pair_device(sk, hdev, buf + sizeof(*hdr), len); |
3062 | break; | 2843 | break; |
3063 | case MGMT_OP_UNPAIR_DEVICE: | 2844 | case MGMT_OP_UNPAIR_DEVICE: |
3064 | err = unpair_device(sk, index, cp, len); | 2845 | err = unpair_device(sk, hdev, cp, len); |
3065 | break; | 2846 | break; |
3066 | case MGMT_OP_USER_CONFIRM_REPLY: | 2847 | case MGMT_OP_USER_CONFIRM_REPLY: |
3067 | err = user_confirm_reply(sk, index, cp, len); | 2848 | err = user_confirm_reply(sk, hdev, cp, len); |
3068 | break; | 2849 | break; |
3069 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | 2850 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: |
3070 | err = user_confirm_neg_reply(sk, index, cp, len); | 2851 | err = user_confirm_neg_reply(sk, hdev, cp, len); |
3071 | break; | 2852 | break; |
3072 | case MGMT_OP_USER_PASSKEY_REPLY: | 2853 | case MGMT_OP_USER_PASSKEY_REPLY: |
3073 | err = user_passkey_reply(sk, index, cp, len); | 2854 | err = user_passkey_reply(sk, hdev, cp, len); |
3074 | break; | 2855 | break; |
3075 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | 2856 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: |
3076 | err = user_passkey_neg_reply(sk, index, cp, len); | 2857 | err = user_passkey_neg_reply(sk, hdev, cp, len); |
3077 | break; | 2858 | break; |
3078 | case MGMT_OP_SET_LOCAL_NAME: | 2859 | case MGMT_OP_SET_LOCAL_NAME: |
3079 | err = set_local_name(sk, index, cp, len); | 2860 | err = set_local_name(sk, hdev, cp, len); |
3080 | break; | 2861 | break; |
3081 | case MGMT_OP_READ_LOCAL_OOB_DATA: | 2862 | case MGMT_OP_READ_LOCAL_OOB_DATA: |
3082 | err = read_local_oob_data(sk, index); | 2863 | err = read_local_oob_data(sk, hdev); |
3083 | break; | 2864 | break; |
3084 | case MGMT_OP_ADD_REMOTE_OOB_DATA: | 2865 | case MGMT_OP_ADD_REMOTE_OOB_DATA: |
3085 | err = add_remote_oob_data(sk, index, cp, len); | 2866 | err = add_remote_oob_data(sk, hdev, cp, len); |
3086 | break; | 2867 | break; |
3087 | case MGMT_OP_REMOVE_REMOTE_OOB_DATA: | 2868 | case MGMT_OP_REMOVE_REMOTE_OOB_DATA: |
3088 | err = remove_remote_oob_data(sk, index, cp, len); | 2869 | err = remove_remote_oob_data(sk, hdev, cp, len); |
3089 | break; | 2870 | break; |
3090 | case MGMT_OP_START_DISCOVERY: | 2871 | case MGMT_OP_START_DISCOVERY: |
3091 | err = start_discovery(sk, index, cp, len); | 2872 | err = start_discovery(sk, hdev, cp, len); |
3092 | break; | 2873 | break; |
3093 | case MGMT_OP_STOP_DISCOVERY: | 2874 | case MGMT_OP_STOP_DISCOVERY: |
3094 | err = stop_discovery(sk, index, cp, len); | 2875 | err = stop_discovery(sk, hdev, cp, len); |
3095 | break; | 2876 | break; |
3096 | case MGMT_OP_CONFIRM_NAME: | 2877 | case MGMT_OP_CONFIRM_NAME: |
3097 | err = confirm_name(sk, index, cp, len); | 2878 | err = confirm_name(sk, hdev, cp, len); |
3098 | break; | 2879 | break; |
3099 | case MGMT_OP_BLOCK_DEVICE: | 2880 | case MGMT_OP_BLOCK_DEVICE: |
3100 | err = block_device(sk, index, cp, len); | 2881 | err = block_device(sk, hdev, cp, len); |
3101 | break; | 2882 | break; |
3102 | case MGMT_OP_UNBLOCK_DEVICE: | 2883 | case MGMT_OP_UNBLOCK_DEVICE: |
3103 | err = unblock_device(sk, index, cp, len); | 2884 | err = unblock_device(sk, hdev, cp, len); |
3104 | break; | 2885 | break; |
3105 | case MGMT_OP_LOAD_LONG_TERM_KEYS: | 2886 | case MGMT_OP_LOAD_LONG_TERM_KEYS: |
3106 | err = load_long_term_keys(sk, index, cp, len); | 2887 | err = load_long_term_keys(sk, hdev, cp, len); |
3107 | break; | 2888 | break; |
3108 | default: | 2889 | default: |
3109 | BT_DBG("Unknown op %u", opcode); | 2890 | BT_DBG("Unknown op %u", opcode); |
@@ -3118,6 +2899,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
3118 | err = msglen; | 2899 | err = msglen; |
3119 | 2900 | ||
3120 | done: | 2901 | done: |
2902 | if (hdev) | ||
2903 | hci_dev_put(hdev); | ||
2904 | |||
3121 | kfree(buf); | 2905 | kfree(buf); |
3122 | return err; | 2906 | return err; |
3123 | } | 2907 | } |