Commit 45e826fd authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2015-02-03

Here's what's likely the last bluetooth-next pull request for 3.20.
Notable changes include:

 - xHCI workaround + a new id for the ath3k driver
 - Several new ids for the btusb driver
 - Support for new Intel Bluetooth controllers
 - Minor cleanups to ieee802154 code
 - Nested sleep warning fix in socket accept() code path
 - Fixes for Out of Band pairing handling
 - Support for LE scan restarting for HCI_QUIRK_STRICT_DUPLICATE_FILTER
 - Improvements to data we expose through debugfs
 - Proper handling of Hardware Error HCI events

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents dcdc8994 88d9077c
...@@ -108,6 +108,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -108,6 +108,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3393) }, { USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3423) },
{ USB_DEVICE(0x13d3, 0x3432) }, { USB_DEVICE(0x13d3, 0x3432) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
...@@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */
...@@ -174,6 +176,8 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -174,6 +176,8 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
#define USB_REQ_DFU_DNLOAD 1 #define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096 #define BULK_SIZE 4096
#define FW_HDR_SIZE 20 #define FW_HDR_SIZE 20
#define TIMEGAP_USEC_MIN 50
#define TIMEGAP_USEC_MAX 100
static int ath3k_load_firmware(struct usb_device *udev, static int ath3k_load_firmware(struct usb_device *udev,
const struct firmware *firmware) const struct firmware *firmware)
...@@ -205,6 +209,9 @@ static int ath3k_load_firmware(struct usb_device *udev, ...@@ -205,6 +209,9 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndbulkpipe(udev, 0x02); pipe = usb_sndbulkpipe(udev, 0x02);
while (count) { while (count) {
/* workaround the compatibility issue with xHCI controller*/
usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
size = min_t(uint, count, BULK_SIZE); size = min_t(uint, count, BULK_SIZE);
memcpy(send_buf, firmware->data + sent, size); memcpy(send_buf, firmware->data + sent, size);
...@@ -302,6 +309,9 @@ static int ath3k_load_fwfile(struct usb_device *udev, ...@@ -302,6 +309,9 @@ static int ath3k_load_fwfile(struct usb_device *udev,
pipe = usb_sndbulkpipe(udev, 0x02); pipe = usb_sndbulkpipe(udev, 0x02);
while (count) { while (count) {
/* workaround the compatibility issue with xHCI controller*/
usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);
size = min_t(uint, count, BULK_SIZE); size = min_t(uint, count, BULK_SIZE);
memcpy(send_buf, firmware->data + sent, size); memcpy(send_buf, firmware->data + sent, size);
......
This diff is collapsed.
...@@ -44,9 +44,9 @@ ...@@ -44,9 +44,9 @@
#define CC2520_FREG_MASK 0x3F #define CC2520_FREG_MASK 0x3F
/* status byte values */ /* status byte values */
#define CC2520_STATUS_XOSC32M_STABLE (1 << 7) #define CC2520_STATUS_XOSC32M_STABLE BIT(7)
#define CC2520_STATUS_RSSI_VALID (1 << 6) #define CC2520_STATUS_RSSI_VALID BIT(6)
#define CC2520_STATUS_TX_UNDERFLOW (1 << 3) #define CC2520_STATUS_TX_UNDERFLOW BIT(3)
/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */ /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
#define CC2520_MINCHANNEL 11 #define CC2520_MINCHANNEL 11
...@@ -549,14 +549,14 @@ cc2520_ed(struct ieee802154_hw *hw, u8 *level) ...@@ -549,14 +549,14 @@ cc2520_ed(struct ieee802154_hw *hw, u8 *level)
u8 rssi; u8 rssi;
int ret; int ret;
ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status); ret = cc2520_read_register(priv, CC2520_RSSISTAT, &status);
if (ret) if (ret)
return ret; return ret;
if (status != RSSI_VALID) if (status != RSSI_VALID)
return -EINVAL; return -EINVAL;
ret = cc2520_read_register(priv , CC2520_RSSI, &rssi); ret = cc2520_read_register(priv, CC2520_RSSI, &rssi);
if (ret) if (ret)
return ret; return ret;
......
...@@ -79,6 +79,8 @@ struct discovery_state { ...@@ -79,6 +79,8 @@ struct discovery_state {
s8 rssi; s8 rssi;
u16 uuid_count; u16 uuid_count;
u8 (*uuids)[16]; u8 (*uuids)[16];
unsigned long scan_start;
unsigned long scan_duration;
}; };
struct hci_conn_hash { struct hci_conn_hash {
...@@ -145,6 +147,7 @@ struct oob_data { ...@@ -145,6 +147,7 @@ struct oob_data {
struct list_head list; struct list_head list;
bdaddr_t bdaddr; bdaddr_t bdaddr;
u8 bdaddr_type; u8 bdaddr_type;
u8 present;
u8 hash192[16]; u8 hash192[16];
u8 rand192[16]; u8 rand192[16];
u8 hash256[16]; u8 hash256[16];
...@@ -232,6 +235,7 @@ struct hci_dev { ...@@ -232,6 +235,7 @@ struct hci_dev {
__u16 conn_info_min_age; __u16 conn_info_min_age;
__u16 conn_info_max_age; __u16 conn_info_max_age;
__u8 ssp_debug_mode; __u8 ssp_debug_mode;
__u8 hw_error_code;
__u32 clock; __u32 clock;
__u16 devid_source; __u16 devid_source;
...@@ -293,6 +297,7 @@ struct hci_dev { ...@@ -293,6 +297,7 @@ struct hci_dev {
struct work_struct power_on; struct work_struct power_on;
struct delayed_work power_off; struct delayed_work power_off;
struct work_struct error_reset;
__u16 discov_timeout; __u16 discov_timeout;
struct delayed_work discov_off; struct delayed_work discov_off;
...@@ -351,6 +356,7 @@ struct hci_dev { ...@@ -351,6 +356,7 @@ struct hci_dev {
unsigned long dev_flags; unsigned long dev_flags;
struct delayed_work le_scan_disable; struct delayed_work le_scan_disable;
struct delayed_work le_scan_restart;
__s8 adv_tx_power; __s8 adv_tx_power;
__u8 adv_data[HCI_MAX_AD_LENGTH]; __u8 adv_data[HCI_MAX_AD_LENGTH];
...@@ -369,6 +375,7 @@ struct hci_dev { ...@@ -369,6 +375,7 @@ struct hci_dev {
int (*setup)(struct hci_dev *hdev); int (*setup)(struct hci_dev *hdev);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb); int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt); void (*notify)(struct hci_dev *hdev, unsigned int evt);
void (*hw_error)(struct hci_dev *hdev, u8 code);
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
}; };
...@@ -527,6 +534,8 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev) ...@@ -527,6 +534,8 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
hdev->discovery.uuid_count = 0; hdev->discovery.uuid_count = 0;
kfree(hdev->discovery.uuids); kfree(hdev->discovery.uuids);
hdev->discovery.uuids = NULL; hdev->discovery.uuids = NULL;
hdev->discovery.scan_start = 0;
hdev->discovery.scan_duration = 0;
} }
bool hci_discovery_active(struct hci_dev *hdev); bool hci_discovery_active(struct hci_dev *hdev);
...@@ -1325,6 +1334,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); ...@@ -1325,6 +1334,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ #define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */
#define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
#define DISCOV_BREDR_INQUIRY_LEN 0x08 #define DISCOV_BREDR_INQUIRY_LEN 0x08
#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_new_settings(struct hci_dev *hdev); int mgmt_new_settings(struct hci_dev *hdev);
...@@ -1369,7 +1379,6 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -1369,7 +1379,6 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
void mgmt_auth_failed(struct hci_conn *conn, u8 status); void mgmt_auth_failed(struct hci_conn *conn, u8 status);
void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
u8 status); u8 status);
void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
......
...@@ -301,10 +301,6 @@ struct mgmt_cp_user_passkey_neg_reply { ...@@ -301,10 +301,6 @@ struct mgmt_cp_user_passkey_neg_reply {
#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020 #define MGMT_OP_READ_LOCAL_OOB_DATA 0x0020
#define MGMT_READ_LOCAL_OOB_DATA_SIZE 0 #define MGMT_READ_LOCAL_OOB_DATA_SIZE 0
struct mgmt_rp_read_local_oob_data { struct mgmt_rp_read_local_oob_data {
__u8 hash[16];
__u8 rand[16];
} __packed;
struct mgmt_rp_read_local_oob_ext_data {
__u8 hash192[16]; __u8 hash192[16];
__u8 rand192[16]; __u8 rand192[16];
__u8 hash256[16]; __u8 hash256[16];
......
...@@ -511,13 +511,12 @@ static int bnep_session(void *arg) ...@@ -511,13 +511,12 @@ static int bnep_session(void *arg)
static struct device *bnep_get_device(struct bnep_session *session) static struct device *bnep_get_device(struct bnep_session *session)
{ {
struct hci_conn *conn; struct l2cap_conn *conn = l2cap_pi(session->sock->sk)->chan->conn;
conn = l2cap_pi(session->sock->sk)->chan->conn->hcon; if (!conn || !conn->hcon)
if (!conn)
return NULL; return NULL;
return &conn->dev; return &conn->hcon->dev;
} }
static struct device_type bnep_type = { static struct device_type bnep_type = {
......
...@@ -609,6 +609,7 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt) ...@@ -609,6 +609,7 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
u8 mode = 0x01; u8 mode = 0x01;
hci_req_add(req, HCI_OP_WRITE_SSP_MODE, hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
sizeof(mode), &mode); sizeof(mode), &mode);
} else { } else {
...@@ -870,8 +871,10 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt) ...@@ -870,8 +871,10 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt)
hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL); hci_req_add(req, HCI_OP_READ_SYNC_TRAIN_PARAMS, 0, NULL);
/* Enable Secure Connections if supported and configured */ /* Enable Secure Connections if supported and configured */
if (bredr_sc_enabled(hdev)) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
bredr_sc_enabled(hdev)) {
u8 support = 0x01; u8 support = 0x01;
hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT, hci_req_add(req, HCI_OP_WRITE_SC_SUPPORT,
sizeof(support), &support); sizeof(support), &support);
} }
...@@ -1614,6 +1617,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -1614,6 +1617,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
cancel_delayed_work(&hdev->service_cache); cancel_delayed_work(&hdev->service_cache);
cancel_delayed_work_sync(&hdev->le_scan_disable); cancel_delayed_work_sync(&hdev->le_scan_disable);
cancel_delayed_work_sync(&hdev->le_scan_restart);
if (test_bit(HCI_MGMT, &hdev->dev_flags)) if (test_bit(HCI_MGMT, &hdev->dev_flags))
cancel_delayed_work_sync(&hdev->rpa_expired); cancel_delayed_work_sync(&hdev->rpa_expired);
...@@ -1625,6 +1629,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -1625,6 +1629,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_dev_lock(hdev); hci_dev_lock(hdev);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { if (!test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
if (hdev->dev_type == HCI_BREDR) if (hdev->dev_type == HCI_BREDR)
mgmt_powered(hdev, 0); mgmt_powered(hdev, 0);
...@@ -1635,6 +1641,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -1635,6 +1641,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hci_conn_hash_flush(hdev); hci_conn_hash_flush(hdev);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
smp_unregister(hdev);
hci_notify(hdev, HCI_DEV_DOWN); hci_notify(hdev, HCI_DEV_DOWN);
if (hdev->flush) if (hdev->flush)
...@@ -1714,32 +1722,14 @@ int hci_dev_close(__u16 dev) ...@@ -1714,32 +1722,14 @@ int hci_dev_close(__u16 dev)
return err; return err;
} }
int hci_dev_reset(__u16 dev) static int hci_dev_do_reset(struct hci_dev *hdev)
{ {
struct hci_dev *hdev; int ret;
int ret = 0;
hdev = hci_dev_get(dev); BT_DBG("%s %p", hdev->name, hdev);
if (!hdev)
return -ENODEV;
hci_req_lock(hdev); hci_req_lock(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
ret = -ENETDOWN;
goto done;
}
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
ret = -EBUSY;
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
ret = -EOPNOTSUPP;
goto done;
}
/* Drop queues */ /* Drop queues */
skb_queue_purge(&hdev->rx_q); skb_queue_purge(&hdev->rx_q);
skb_queue_purge(&hdev->cmd_q); skb_queue_purge(&hdev->cmd_q);
...@@ -1762,12 +1752,41 @@ int hci_dev_reset(__u16 dev) ...@@ -1762,12 +1752,41 @@ int hci_dev_reset(__u16 dev)
ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); ret = __hci_req_sync(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
done:
hci_req_unlock(hdev); hci_req_unlock(hdev);
hci_dev_put(hdev);
return ret; return ret;
} }
int hci_dev_reset(__u16 dev)
{
struct hci_dev *hdev;
int err;
hdev = hci_dev_get(dev);
if (!hdev)
return -ENODEV;
if (!test_bit(HCI_UP, &hdev->flags)) {
err = -ENETDOWN;
goto done;
}
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) {
err = -EBUSY;
goto done;
}
if (test_bit(HCI_UNCONFIGURED, &hdev->dev_flags)) {
err = -EOPNOTSUPP;
goto done;
}
err = hci_dev_do_reset(hdev);
done:
hci_dev_put(hdev);
return err;
}
int hci_dev_reset_stat(__u16 dev) int hci_dev_reset_stat(__u16 dev)
{ {
struct hci_dev *hdev; struct hci_dev *hdev;
...@@ -2131,8 +2150,24 @@ static void hci_power_off(struct work_struct *work) ...@@ -2131,8 +2150,24 @@ static void hci_power_off(struct work_struct *work)
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
hci_dev_do_close(hdev); hci_dev_do_close(hdev);
}
smp_unregister(hdev); static void hci_error_reset(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, error_reset);
BT_DBG("%s", hdev->name);
if (hdev->hw_error)
hdev->hw_error(hdev, hdev->hw_error_code);
else
BT_ERR("%s hardware error 0x%2.2x", hdev->name,
hdev->hw_error_code);
if (hci_dev_do_close(hdev))
return;
hci_dev_do_open(hdev);
} }
static void hci_discov_off(struct work_struct *work) static void hci_discov_off(struct work_struct *work)
...@@ -2547,9 +2582,15 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -2547,9 +2582,15 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
if (hash192 && rand192) { if (hash192 && rand192) {
memcpy(data->hash192, hash192, sizeof(data->hash192)); memcpy(data->hash192, hash192, sizeof(data->hash192));
memcpy(data->rand192, rand192, sizeof(data->rand192)); memcpy(data->rand192, rand192, sizeof(data->rand192));
if (hash256 && rand256)
data->present = 0x03;
} else { } else {
memset(data->hash192, 0, sizeof(data->hash192)); memset(data->hash192, 0, sizeof(data->hash192));
memset(data->rand192, 0, sizeof(data->rand192)); memset(data->rand192, 0, sizeof(data->rand192));
if (hash256 && rand256)
data->present = 0x02;
else
data->present = 0x00;
} }
if (hash256 && rand256) { if (hash256 && rand256) {
...@@ -2558,6 +2599,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -2558,6 +2599,8 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
} else { } else {
memset(data->hash256, 0, sizeof(data->hash256)); memset(data->hash256, 0, sizeof(data->hash256));
memset(data->rand256, 0, sizeof(data->rand256)); memset(data->rand256, 0, sizeof(data->rand256));
if (hash192 && rand192)
data->present = 0x01;
} }
BT_DBG("%s for %pMR", hdev->name, bdaddr); BT_DBG("%s for %pMR", hdev->name, bdaddr);
...@@ -2788,6 +2831,8 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status, ...@@ -2788,6 +2831,8 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
return; return;
} }
hdev->discovery.scan_start = 0;
switch (hdev->discovery.type) { switch (hdev->discovery.type) {
case DISCOV_TYPE_LE: case DISCOV_TYPE_LE:
hci_dev_lock(hdev); hci_dev_lock(hdev);
...@@ -2827,6 +2872,8 @@ static void le_scan_disable_work(struct work_struct *work) ...@@ -2827,6 +2872,8 @@ static void le_scan_disable_work(struct work_struct *work)
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
cancel_delayed_work_sync(&hdev->le_scan_restart);
hci_req_init(&req, hdev); hci_req_init(&req, hdev);
hci_req_add_le_scan_disable(&req); hci_req_add_le_scan_disable(&req);
...@@ -2836,6 +2883,74 @@ static void le_scan_disable_work(struct work_struct *work) ...@@ -2836,6 +2883,74 @@ static void le_scan_disable_work(struct work_struct *work)
BT_ERR("Disable LE scanning request failed: err %d", err); BT_ERR("Disable LE scanning request failed: err %d", err);
} }
static void le_scan_restart_work_complete(struct hci_dev *hdev, u8 status,
u16 opcode)
{
unsigned long timeout, duration, scan_start, now;
BT_DBG("%s", hdev->name);
if (status) {
BT_ERR("Failed to restart LE scan: status %d", status);
return;
}
if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
!hdev->discovery.scan_start)
return;
/* When the scan was started, hdev->le_scan_disable has been queued
* after duration from scan_start. During scan restart this job
* has been canceled, and we need to queue it again after proper
* timeout, to make sure that scan does not run indefinitely.
*/
duration = hdev->discovery.scan_duration;
scan_start = hdev->discovery.scan_start;
now = jiffies;
if (now - scan_start <= duration) {
int elapsed;
if (now >= scan_start)
elapsed = now - scan_start;
else
elapsed = ULONG_MAX - scan_start + now;
timeout = duration - elapsed;
} else {
timeout = 0;
}
queue_delayed_work(hdev->workqueue,
&hdev->le_scan_disable, timeout);
}
static void le_scan_restart_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev,
le_scan_restart.work);
struct hci_request req;
struct hci_cp_le_set_scan_enable cp;
int err;
BT_DBG("%s", hdev->name);
/* If controller is not scanning we are done. */
if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
return;
hci_req_init(&req, hdev);
hci_req_add_le_scan_disable(&req);
memset(&cp, 0, sizeof(cp));
cp.enable = LE_SCAN_ENABLE;
cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
err = hci_req_run(&req, le_scan_restart_work_complete);
if (err)
BT_ERR("Restart LE scan request failed: err %d", err);
}
/* Copy the Identity Address of the controller. /* Copy the Identity Address of the controller.
* *
* If the controller has a public BD_ADDR, then by default use that one. * If the controller has a public BD_ADDR, then by default use that one.
...@@ -2927,10 +3042,12 @@ struct hci_dev *hci_alloc_dev(void) ...@@ -2927,10 +3042,12 @@ struct hci_dev *hci_alloc_dev(void)
INIT_WORK(&hdev->cmd_work, hci_cmd_work); INIT_WORK(&hdev->cmd_work, hci_cmd_work);
INIT_WORK(&hdev->tx_work, hci_tx_work); INIT_WORK(&hdev->tx_work, hci_tx_work);
INIT_WORK(&hdev->power_on, hci_power_on); INIT_WORK(&hdev->power_on, hci_power_on);
INIT_WORK(&hdev->error_reset, hci_error_reset);
INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); INIT_DELAYED_WORK(&hdev->power_off, hci_power_off);
INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off);
INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work); INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
skb_queue_head_init(&hdev->rx_q); skb_queue_head_init(&hdev->rx_q);
skb_queue_head_init(&hdev->cmd_q); skb_queue_head_init(&hdev->cmd_q);
...@@ -3100,8 +3217,6 @@ void hci_unregister_dev(struct hci_dev *hdev) ...@@ -3100,8 +3217,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
rfkill_destroy(hdev->rfkill); rfkill_destroy(hdev->rfkill);
} }
smp_unregister(hdev);
device_del(&hdev->dev); device_del(&hdev->dev);
debugfs_remove_recursive(hdev->debugfs); debugfs_remove_recursive(hdev->debugfs);
......
...@@ -156,6 +156,35 @@ static const struct file_operations uuids_fops = { ...@@ -156,6 +156,35 @@ static const struct file_operations uuids_fops = {
.release = single_release, .release = single_release,
}; };
static int remote_oob_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
struct oob_data *data;
hci_dev_lock(hdev);
list_for_each_entry(data, &hdev->remote_oob_data, list) {
seq_printf(f, "%pMR (type %u) %u %*phN %*phN %*phN %*phN\n",
&data->bdaddr, data->bdaddr_type, data->present,
16, data->hash192, 16, data->rand192,
16, data->hash256, 19, data->rand256);
}
hci_dev_unlock(hdev);
return 0;
}
static int remote_oob_open(struct inode *inode, struct file *file)
{
return single_open(file, remote_oob_show, inode->i_private);
}
static const struct file_operations remote_oob_fops = {
.open = remote_oob_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int conn_info_min_age_set(void *data, u64 val) static int conn_info_min_age_set(void *data, u64 val)
{ {
struct hci_dev *hdev = data; struct hci_dev *hdev = data;
...@@ -212,6 +241,24 @@ static int conn_info_max_age_get(void *data, u64 *val) ...@@ -212,6 +241,24 @@ static int conn_info_max_age_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get, DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get,
conn_info_max_age_set, "%llu\n"); conn_info_max_age_set, "%llu\n");
static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = test_bit(HCI_USE_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static const struct file_operations use_debug_keys_fops = {
.open = simple_open,
.read = use_debug_keys_read,
.llseek = default_llseek,
};
static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf, static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -238,17 +285,26 @@ void hci_debugfs_create_common(struct hci_dev *hdev) ...@@ -238,17 +285,26 @@ void hci_debugfs_create_common(struct hci_dev *hdev)
&hdev->manufacturer); &hdev->manufacturer);
debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver); debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev); debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
debugfs_create_u8("hardware_error", 0444, hdev->debugfs,
&hdev->hw_error_code);
debugfs_create_file("device_list", 0444, hdev->debugfs, hdev, debugfs_create_file("device_list", 0444, hdev->debugfs, hdev,
&device_list_fops); &device_list_fops);
debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev, debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
&blacklist_fops); &blacklist_fops);
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
debugfs_create_file("remote_oob", 0400, hdev->debugfs, hdev,
&remote_oob_fops);
debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev,
&conn_info_min_age_fops); &conn_info_min_age_fops);
debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev, debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev,
&conn_info_max_age_fops); &conn_info_max_age_fops);
if (lmp_ssp_capable(hdev) || lmp_le_capable(hdev))
debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
hdev, &use_debug_keys_fops);
if (lmp_sc_capable(hdev) || lmp_le_capable(hdev)) if (lmp_sc_capable(hdev) || lmp_le_capable(hdev))
debugfs_create_file("sc_only_mode", 0444, hdev->debugfs, debugfs_create_file("sc_only_mode", 0444, hdev->debugfs,
hdev, &sc_only_mode_fops); hdev, &sc_only_mode_fops);
...@@ -354,6 +410,24 @@ static int voice_setting_get(void *data, u64 *val) ...@@ -354,6 +410,24 @@ static int voice_setting_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get, DEFINE_SIMPLE_ATTRIBUTE(voice_setting_fops, voice_setting_get,
NULL, "0x%4.4llx\n"); NULL, "0x%4.4llx\n");
static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct hci_dev *hdev = file->private_data;
char buf[3];
buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
buf[1] = '\n';
buf[2] = '\0';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static const struct file_operations ssp_debug_mode_fops = {
.open = simple_open,
.read = ssp_debug_mode_read,
.llseek = default_llseek,
};
static int auto_accept_delay_set(void *data, u64 val) static int auto_accept_delay_set(void *data, u64 val)
{ {
struct hci_dev *hdev = data; struct hci_dev *hdev = data;
...@@ -474,9 +548,12 @@ void hci_debugfs_create_bredr(struct hci_dev *hdev) ...@@ -474,9 +548,12 @@ void hci_debugfs_create_bredr(struct hci_dev *hdev)
debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev, debugfs_create_file("voice_setting", 0444, hdev->debugfs, hdev,
&voice_setting_fops); &voice_setting_fops);
if (lmp_ssp_capable(hdev)) if (lmp_ssp_capable(hdev)) {
debugfs_create_file("ssp_debug_mode", 0444, hdev->debugfs,
hdev, &ssp_debug_mode_fops);
debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs, debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
hdev, &auto_accept_delay_fops); hdev, &auto_accept_delay_fops);
}
if (lmp_sniff_capable(hdev)) { if (lmp_sniff_capable(hdev)) {
debugfs_create_file("idle_timeout", 0644, hdev->debugfs, debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
......
...@@ -36,6 +36,9 @@ ...@@ -36,6 +36,9 @@
#include "amp.h" #include "amp.h"
#include "smp.h" #include "smp.h"
#define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00"
/* Handle HCI Event packets */ /* Handle HCI Event packets */
static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
...@@ -197,7 +200,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -197,7 +200,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
/* Reset all non-persistent flags */ /* Reset all non-persistent flags */
hdev->dev_flags &= ~HCI_PERSISTENT_MASK; hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
hdev->discovery.state = DISCOVERY_STOPPED; hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
hdev->inq_tx_power = HCI_TX_POWER_INVALID; hdev->inq_tx_power = HCI_TX_POWER_INVALID;
hdev->adv_tx_power = HCI_TX_POWER_INVALID; hdev->adv_tx_power = HCI_TX_POWER_INVALID;
...@@ -525,9 +529,7 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -525,9 +529,7 @@ static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
hdev->features[1][0] &= ~LMP_HOST_SC; hdev->features[1][0] &= ~LMP_HOST_SC;
} }
if (test_bit(HCI_MGMT, &hdev->dev_flags)) if (!test_bit(HCI_MGMT, &hdev->dev_flags) && !status) {
mgmt_sc_enable_complete(hdev, sent->support, status);
else if (!status) {
if (sent->support) if (sent->support)
set_bit(HCI_SC_ENABLED, &hdev->dev_flags); set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
else else
...@@ -1487,6 +1489,21 @@ static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1487,6 +1489,21 @@ static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
u8 status = *((u8 *) skb->data);
u8 *mode;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status)
return;
mode = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE);
if (mode)
hdev->ssp_debug_mode = *mode;
}
static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{ {
BT_DBG("%s status 0x%2.2x", hdev->name, status); BT_DBG("%s status 0x%2.2x", hdev->name, status);
...@@ -2669,7 +2686,8 @@ static void hci_remote_features_evt(struct hci_dev *hdev, ...@@ -2669,7 +2686,8 @@ static void hci_remote_features_evt(struct hci_dev *hdev,
if (conn->state != BT_CONFIG) if (conn->state != BT_CONFIG)
goto unlock; goto unlock;
if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { if (!ev->status && lmp_ext_feat_capable(hdev) &&
lmp_ext_feat_capable(conn)) {
struct hci_cp_read_remote_ext_features cp; struct hci_cp_read_remote_ext_features cp;
cp.handle = ev->handle; cp.handle = ev->handle;
cp.page = 0x01; cp.page = 0x01;
...@@ -2980,6 +2998,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2980,6 +2998,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_read_tx_power(hdev, skb); hci_cc_read_tx_power(hdev, skb);
break; break;
case HCI_OP_WRITE_SSP_DEBUG_MODE:
hci_cc_write_ssp_debug_mode(hdev, skb);
break;
default: default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break; break;
...@@ -3098,7 +3120,9 @@ static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3098,7 +3120,9 @@ static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_hardware_error *ev = (void *) skb->data; struct hci_ev_hardware_error *ev = (void *) skb->data;
BT_ERR("%s hardware error 0x%2.2x", hdev->name, ev->code); hdev->hw_error_code = ev->code;
queue_work(hdev->req_workqueue, &hdev->error_reset);
} }
static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
...@@ -3857,6 +3881,52 @@ static u8 hci_get_auth_req(struct hci_conn *conn) ...@@ -3857,6 +3881,52 @@ static u8 hci_get_auth_req(struct hci_conn *conn)
return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01); return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
} }
static u8 bredr_oob_data_present(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct oob_data *data;
data = hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR);
if (!data)
return 0x00;
if (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) {
if (bredr_sc_enabled(hdev)) {
/* When Secure Connections is enabled, then just
* return the present value stored with the OOB
* data. The stored value contains the right present
* information. However it can only be trusted when
* not in Secure Connection Only mode.
*/
if (!test_bit(HCI_SC_ONLY, &hdev->dev_flags))
return data->present;
/* When Secure Connections Only mode is enabled, then
* the P-256 values are required. If they are not
* available, then do not declare that OOB data is
* present.
*/
if (!memcmp(data->rand256, ZERO_KEY, 16) ||
!memcmp(data->hash256, ZERO_KEY, 16))
return 0x00;
return 0x02;
}
/* When Secure Connections is not enabled or actually
* not supported by the hardware, then check that if
* P-192 data values are present.
*/
if (!memcmp(data->rand192, ZERO_KEY, 16) ||
!memcmp(data->hash192, ZERO_KEY, 16))
return 0x00;
return 0x01;
}
return 0x00;
}
static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_io_capa_request *ev = (void *) skb->data; struct hci_ev_io_capa_request *ev = (void *) skb->data;
...@@ -3908,12 +3978,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3908,12 +3978,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->auth_type &= HCI_AT_NO_BONDING_MITM; conn->auth_type &= HCI_AT_NO_BONDING_MITM;
cp.authentication = conn->auth_type; cp.authentication = conn->auth_type;
cp.oob_data = bredr_oob_data_present(conn);
if (hci_find_remote_oob_data(hdev, &conn->dst, BDADDR_BREDR) &&
(conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
cp.oob_data = 0x01;
else
cp.oob_data = 0x00;
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
sizeof(cp), &cp); sizeof(cp), &cp);
...@@ -4165,33 +4230,39 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, ...@@ -4165,33 +4230,39 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
goto unlock; goto unlock;
data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR); data = hci_find_remote_oob_data(hdev, &ev->bdaddr, BDADDR_BREDR);
if (data) { if (!data) {
if (bredr_sc_enabled(hdev)) { struct hci_cp_remote_oob_data_neg_reply cp;
struct hci_cp_remote_oob_ext_data_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY, bacpy(&cp.bdaddr, &ev->bdaddr);
sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
} else { sizeof(cp), &cp);
struct hci_cp_remote_oob_data_reply cp; goto unlock;
}
bacpy(&cp.bdaddr, &ev->bdaddr); if (bredr_sc_enabled(hdev)) {
memcpy(cp.hash, data->hash192, sizeof(cp.hash)); struct hci_cp_remote_oob_ext_data_reply cp;
memcpy(cp.rand, data->rand192, sizeof(cp.rand));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, bacpy(&cp.bdaddr, &ev->bdaddr);
sizeof(cp), &cp); if (test_bit(HCI_SC_ONLY, &hdev->dev_flags)) {
memset(cp.hash192, 0, sizeof(cp.hash192));
memset(cp.rand192, 0, sizeof(cp.rand192));
} else {
memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
memcpy(cp.rand192, data->rand192, sizeof(cp.rand192));
} }
memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
memcpy(cp.rand256, data->rand256, sizeof(cp.rand256));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
sizeof(cp), &cp);
} else { } else {
struct hci_cp_remote_oob_data_neg_reply cp; struct hci_cp_remote_oob_data_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr); bacpy(&cp.bdaddr, &ev->bdaddr);
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, memcpy(cp.hash, data->hash192, sizeof(cp.hash));
memcpy(cp.rand, data->rand192, sizeof(cp.rand));
hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
sizeof(cp), &cp); sizeof(cp), &cp);
} }
......
...@@ -302,7 +302,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) ...@@ -302,7 +302,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
int flags) int flags)
{ {
DECLARE_WAITQUEUE(wait, current); DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *nsk; struct sock *sk = sock->sk, *nsk;
long timeo; long timeo;
int err = 0; int err = 0;
...@@ -316,8 +316,6 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, ...@@ -316,8 +316,6 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) { while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) { if (sk->sk_state != BT_LISTEN) {
err = -EBADFD; err = -EBADFD;
break; break;
...@@ -338,10 +336,11 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, ...@@ -338,10 +336,11 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock,
} }
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock_nested(sk, L2CAP_NESTING_PARENT); lock_sock_nested(sk, L2CAP_NESTING_PARENT);
} }
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
......
This diff is collapsed.
...@@ -468,7 +468,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) ...@@ -468,7 +468,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags) static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
{ {
DECLARE_WAITQUEUE(wait, current); DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *nsk; struct sock *sk = sock->sk, *nsk;
long timeo; long timeo;
int err = 0; int err = 0;
...@@ -487,8 +487,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -487,8 +487,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) { while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) { if (sk->sk_state != BT_LISTEN) {
err = -EBADFD; err = -EBADFD;
break; break;
...@@ -509,10 +507,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f ...@@ -509,10 +507,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
} }
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock_nested(sk, SINGLE_DEPTH_NESTING); lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
} }
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
......
...@@ -618,7 +618,7 @@ static int sco_sock_listen(struct socket *sock, int backlog) ...@@ -618,7 +618,7 @@ static int sco_sock_listen(struct socket *sock, int backlog)
static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags) static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
{ {
DECLARE_WAITQUEUE(wait, current); DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct sock *sk = sock->sk, *ch; struct sock *sk = sock->sk, *ch;
long timeo; long timeo;
int err = 0; int err = 0;
...@@ -632,8 +632,6 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag ...@@ -632,8 +632,6 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
/* Wait for an incoming connection. (wake-one). */ /* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait); add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (1) { while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->sk_state != BT_LISTEN) { if (sk->sk_state != BT_LISTEN) {
err = -EBADFD; err = -EBADFD;
break; break;
...@@ -654,10 +652,10 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag ...@@ -654,10 +652,10 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag
} }
release_sock(sk); release_sock(sk);
timeo = schedule_timeout(timeo);
timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo);
lock_sock(sk); lock_sock(sk);
} }
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait); remove_wait_queue(sk_sleep(sk), &wait);
if (err) if (err)
......
...@@ -620,7 +620,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, ...@@ -620,7 +620,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
oob_data = hci_find_remote_oob_data(hdev, &hcon->dst, oob_data = hci_find_remote_oob_data(hdev, &hcon->dst,
bdaddr_type); bdaddr_type);
if (oob_data) { if (oob_data && oob_data->present) {
set_bit(SMP_FLAG_OOB, &smp->flags); set_bit(SMP_FLAG_OOB, &smp->flags);
oob_flag = SMP_OOB_PRESENT; oob_flag = SMP_OOB_PRESENT;
memcpy(smp->rr, oob_data->rand256, 16); memcpy(smp->rr, oob_data->rand256, 16);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment