diff options
| author | Rafael J. Wysocki <[email protected]> | 2016-10-29 01:29:17 +0200 | 
|---|---|---|
| committer | Rafael J. Wysocki <[email protected]> | 2016-10-29 01:29:17 +0200 | 
| commit | 8b2ada27dc1045e8191673bf769a1136ce8a0127 (patch) | |
| tree | df2fe577fb2f01c477e7e217cec9fd47c6ce812b /net/bluetooth/hci_request.c | |
| parent | 2f1d407adab026b34a105ed27b1d4d7e910c4448 (diff) | |
| parent | 1adb469b9b76276d7e5ea36a20a24c47d6618a0b (diff) | |
Merge branches 'pm-cpufreq-fixes' and 'pm-sleep-fixes'
* pm-cpufreq-fixes:
  cpufreq: intel_pstate: Always set max P-state in performance mode
  cpufreq: intel_pstate: Set P-state upfront in performance mode
* pm-sleep-fixes:
  PM / suspend: Fix missing KERN_CONT for suspend message
Diffstat (limited to 'net/bluetooth/hci_request.c')
| -rw-r--r-- | net/bluetooth/hci_request.c | 95 | 
1 files changed, 67 insertions, 28 deletions
| diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index b0e23dfc5c34..e2288421fe6b 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -21,8 +21,6 @@     SOFTWARE IS DISCLAIMED.  */ -#include <asm/unaligned.h> -  #include <net/bluetooth/bluetooth.h>  #include <net/bluetooth/hci_core.h>  #include <net/bluetooth/mgmt.h> @@ -971,48 +969,88 @@ void __hci_req_enable_advertising(struct hci_request *req)  	hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);  } -static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) +static u8 append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)  { -	u8 ad_len = 0; -	size_t name_len; +	size_t complete_len; +	size_t short_len; +	int max_len; -	name_len = strlen(hdev->dev_name); -	if (name_len > 0) { -		size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; +	max_len = HCI_MAX_AD_LENGTH - ad_len - 2; +	complete_len = strlen(hdev->dev_name); +	short_len = strlen(hdev->short_name); -		if (name_len > max_len) { -			name_len = max_len; -			ptr[1] = EIR_NAME_SHORT; -		} else -			ptr[1] = EIR_NAME_COMPLETE; +	/* no space left for name */ +	if (max_len < 1) +		return ad_len; -		ptr[0] = name_len + 1; +	/* no name set */ +	if (!complete_len) +		return ad_len; -		memcpy(ptr + 2, hdev->dev_name, name_len); +	/* complete name fits and is eq to max short name len or smaller */ +	if (complete_len <= max_len && +	    complete_len <= HCI_MAX_SHORT_NAME_LENGTH) { +		return eir_append_data(ptr, ad_len, EIR_NAME_COMPLETE, +				       hdev->dev_name, complete_len); +	} -		ad_len += (name_len + 2); -		ptr += (name_len + 2); +	/* short name set and fits */ +	if (short_len && short_len <= max_len) { +		return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, +				       hdev->short_name, short_len); +	} + +	/* no short name set so shorten complete name */ +	if (!short_len) { +		return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, +				       hdev->dev_name, max_len);  	}  	return ad_len;  } +static u8 append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len) +{ +	return eir_append_le16(ptr, ad_len, EIR_APPEARANCE, hdev->appearance); +} + +static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr) +{ +	u8 scan_rsp_len = 0; + +	if (hdev->appearance) { +		scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len); +	} + +	return append_local_name(hdev, ptr, scan_rsp_len); +} +  static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,  					u8 *ptr)  {  	struct adv_info *adv_instance; +	u32 instance_flags; +	u8 scan_rsp_len = 0;  	adv_instance = hci_find_adv_instance(hdev, instance);  	if (!adv_instance)  		return 0; -	/* TODO: Set the appropriate entries based on advertising instance flags -	 * here once flags other than 0 are supported. -	 */ -	memcpy(ptr, adv_instance->scan_rsp_data, +	instance_flags = adv_instance->flags; + +	if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) { +		scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len); +	} + +	memcpy(&ptr[scan_rsp_len], adv_instance->scan_rsp_data,  	       adv_instance->scan_rsp_len); -	return adv_instance->scan_rsp_len; +	scan_rsp_len += adv_instance->scan_rsp_len; + +	if (instance_flags & MGMT_ADV_FLAG_LOCAL_NAME) +		scan_rsp_len = append_local_name(hdev, ptr, scan_rsp_len); + +	return scan_rsp_len;  }  void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance) @@ -1194,7 +1232,7 @@ static void adv_timeout_expire(struct work_struct *work)  	hci_req_init(&req, hdev); -	hci_req_clear_adv_instance(hdev, &req, instance, false); +	hci_req_clear_adv_instance(hdev, NULL, &req, instance, false);  	if (list_empty(&hdev->adv_instances))  		__hci_req_disable_advertising(&req); @@ -1284,8 +1322,9 @@ static void cancel_adv_timeout(struct hci_dev *hdev)   *   setting.   * - force == false: Only instances that have a timeout will be removed.   */ -void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req, -				u8 instance, bool force) +void hci_req_clear_adv_instance(struct hci_dev *hdev, struct sock *sk, +				struct hci_request *req, u8 instance, +				bool force)  {  	struct adv_info *adv_instance, *n, *next_instance = NULL;  	int err; @@ -1311,7 +1350,7 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,  			rem_inst = adv_instance->instance;  			err = hci_remove_adv_instance(hdev, rem_inst);  			if (!err) -				mgmt_advertising_removed(NULL, hdev, rem_inst); +				mgmt_advertising_removed(sk, hdev, rem_inst);  		}  	} else {  		adv_instance = hci_find_adv_instance(hdev, instance); @@ -1325,7 +1364,7 @@ void hci_req_clear_adv_instance(struct hci_dev *hdev, struct hci_request *req,  			err = hci_remove_adv_instance(hdev, instance);  			if (!err) -				mgmt_advertising_removed(NULL, hdev, instance); +				mgmt_advertising_removed(sk, hdev, instance);  		}  	} @@ -1716,7 +1755,7 @@ void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,  			 * function. To be safe hard-code one of the  			 * values that's suitable for SCO.  			 */ -			rej.reason = HCI_ERROR_REMOTE_LOW_RESOURCES; +			rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;  			hci_req_add(req, HCI_OP_REJECT_SYNC_CONN_REQ,  				    sizeof(rej), &rej); |