Commit 48b81cc1 authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents 31c5770b 0227c7b5
...@@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { ...@@ -83,8 +83,8 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
}; };
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "sd8688_helper.bin", .helper = "mrvl/sd8688_helper.bin",
.firmware = "sd8688.bin", .firmware = "mrvl/sd8688.bin",
.reg = &btmrvl_reg_8688, .reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64, .sd_blksz_fw_dl = 64,
}; };
...@@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd."); ...@@ -1185,7 +1185,7 @@ MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION); MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
MODULE_VERSION(VERSION); MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
...@@ -232,7 +232,7 @@ struct bt_sock_list { ...@@ -232,7 +232,7 @@ struct bt_sock_list {
}; };
int bt_sock_register(int proto, const struct net_proto_family *ops); int bt_sock_register(int proto, const struct net_proto_family *ops);
int bt_sock_unregister(int proto); void bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
...@@ -260,12 +260,22 @@ struct l2cap_ctrl { ...@@ -260,12 +260,22 @@ struct l2cap_ctrl {
__u8 retries; __u8 retries;
}; };
struct hci_dev;
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
struct hci_req_ctrl {
bool start;
hci_req_complete_t complete;
};
struct bt_skb_cb { struct bt_skb_cb {
__u8 pkt_type; __u8 pkt_type;
__u8 incoming; __u8 incoming;
__u16 expect; __u16 expect;
__u8 force_active; __u8 force_active;
struct l2cap_ctrl control; struct l2cap_ctrl control;
struct hci_req_ctrl req;
}; };
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
......
...@@ -119,10 +119,16 @@ enum { ...@@ -119,10 +119,16 @@ enum {
HCI_CONNECTABLE, HCI_CONNECTABLE,
HCI_DISCOVERABLE, HCI_DISCOVERABLE,
HCI_LINK_SECURITY, HCI_LINK_SECURITY,
HCI_PENDING_CLASS,
HCI_PERIODIC_INQ, HCI_PERIODIC_INQ,
HCI_FAST_CONNECTABLE,
}; };
/* A mask for the flags that are supposed to remain when a reset happens
* or the HCI device is closed.
*/
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
BIT(HCI_FAST_CONNECTABLE))
/* HCI ioctl defines */ /* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int) #define HCIDEVUP _IOW('H', 201, int)
#define HCIDEVDOWN _IOW('H', 202, int) #define HCIDEVDOWN _IOW('H', 202, int)
...@@ -881,12 +887,25 @@ struct hci_rp_read_data_block_size { ...@@ -881,12 +887,25 @@ struct hci_rp_read_data_block_size {
__le16 num_blocks; __le16 num_blocks;
} __packed; } __packed;
#define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b
struct hci_rp_read_page_scan_activity {
__u8 status;
__le16 interval;
__le16 window;
} __packed;
#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c #define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c
struct hci_cp_write_page_scan_activity { struct hci_cp_write_page_scan_activity {
__le16 interval; __le16 interval;
__le16 window; __le16 window;
} __packed; } __packed;
#define HCI_OP_READ_PAGE_SCAN_TYPE 0x0c46
struct hci_rp_read_page_scan_type {
__u8 status;
__u8 type;
} __packed;
#define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47 #define HCI_OP_WRITE_PAGE_SCAN_TYPE 0x0c47
#define PAGE_SCAN_TYPE_STANDARD 0x00 #define PAGE_SCAN_TYPE_STANDARD 0x00
#define PAGE_SCAN_TYPE_INTERLACED 0x01 #define PAGE_SCAN_TYPE_INTERLACED 0x01
......
...@@ -165,6 +165,10 @@ struct hci_dev { ...@@ -165,6 +165,10 @@ struct hci_dev {
__u16 voice_setting; __u16 voice_setting;
__u8 io_capability; __u8 io_capability;
__s8 inq_tx_power; __s8 inq_tx_power;
__u16 page_scan_interval;
__u16 page_scan_window;
__u8 page_scan_type;
__u16 devid_source; __u16 devid_source;
__u16 devid_vendor; __u16 devid_vendor;
__u16 devid_product; __u16 devid_product;
...@@ -248,8 +252,6 @@ struct hci_dev { ...@@ -248,8 +252,6 @@ struct hci_dev {
__u32 req_status; __u32 req_status;
__u32 req_result; __u32 req_result;
__u16 init_last_cmd;
struct list_head mgmt_pending; struct list_head mgmt_pending;
struct discovery_state discovery; struct discovery_state discovery;
...@@ -574,7 +576,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, ...@@ -574,7 +576,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
return NULL; return NULL;
} }
void hci_acl_disconn(struct hci_conn *conn, __u8 reason); void hci_disconnect(struct hci_conn *conn, __u8 reason);
void hci_setup_sync(struct hci_conn *conn, __u16 handle); void hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status); void hci_sco_setup(struct hci_conn *conn, __u8 status);
...@@ -742,8 +744,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, ...@@ -742,8 +744,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
u8 *randomizer); u8 *randomizer);
int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_update_ad(struct hci_dev *hdev);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb);
...@@ -1041,6 +1041,22 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data, ...@@ -1041,6 +1041,22 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
int hci_register_cb(struct hci_cb *hcb); int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb); int hci_unregister_cb(struct hci_cb *hcb);
struct hci_request {
struct hci_dev *hdev;
struct sk_buff_head cmd_q;
/* If something goes wrong when building the HCI request, the error
* value is stored in this field.
*/
int err;
};
void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param);
void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status);
int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
...@@ -1153,7 +1169,7 @@ struct hci_sec_filter { ...@@ -1153,7 +1169,7 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock) #define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock) #define hci_req_unlock(d) mutex_unlock(&d->req_lock)
void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); void hci_update_ad(struct hci_request *req);
void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
u16 latency, u16 to_multiplier); u16 latency, u16 to_multiplier);
......
...@@ -158,7 +158,6 @@ struct rfcomm_session { ...@@ -158,7 +158,6 @@ struct rfcomm_session {
struct timer_list timer; struct timer_list timer;
unsigned long state; unsigned long state;
unsigned long flags; unsigned long flags;
atomic_t refcnt;
int initiator; int initiator;
/* Default DLC parameters */ /* Default DLC parameters */
...@@ -276,11 +275,6 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) ...@@ -276,11 +275,6 @@ static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src,
bdaddr_t *dst); bdaddr_t *dst);
static inline void rfcomm_session_hold(struct rfcomm_session *s)
{
atomic_inc(&s->refcnt);
}
/* ---- RFCOMM sockets ---- */ /* ---- RFCOMM sockets ---- */
struct sockaddr_rc { struct sockaddr_rc {
sa_family_t rc_family; sa_family_t rc_family;
......
...@@ -397,13 +397,12 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -397,13 +397,12 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
if (ctrl) { if (ctrl) {
u8 *assoc; u8 *assoc;
assoc = kzalloc(assoc_len, GFP_KERNEL); assoc = kmemdup(rsp->amp_assoc, assoc_len, GFP_KERNEL);
if (!assoc) { if (!assoc) {
amp_ctrl_put(ctrl); amp_ctrl_put(ctrl);
return -ENOMEM; return -ENOMEM;
} }
memcpy(assoc, rsp->amp_assoc, assoc_len);
ctrl->assoc = assoc; ctrl->assoc = assoc;
ctrl->assoc_len = assoc_len; ctrl->assoc_len = assoc_len;
ctrl->assoc_rem_len = assoc_len; ctrl->assoc_rem_len = assoc_len;
...@@ -472,13 +471,12 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -472,13 +471,12 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req); size_t assoc_len = le16_to_cpu(hdr->len) - sizeof(*req);
u8 *assoc; u8 *assoc;
assoc = kzalloc(assoc_len, GFP_KERNEL); assoc = kmemdup(req->amp_assoc, assoc_len, GFP_KERNEL);
if (!assoc) { if (!assoc) {
amp_ctrl_put(ctrl); amp_ctrl_put(ctrl);
return -ENOMEM; return -ENOMEM;
} }
memcpy(assoc, req->amp_assoc, assoc_len);
ctrl->assoc = assoc; ctrl->assoc = assoc;
ctrl->assoc_len = assoc_len; ctrl->assoc_len = assoc_len;
ctrl->assoc_rem_len = assoc_len; ctrl->assoc_rem_len = assoc_len;
......
...@@ -92,23 +92,14 @@ int bt_sock_register(int proto, const struct net_proto_family *ops) ...@@ -92,23 +92,14 @@ int bt_sock_register(int proto, const struct net_proto_family *ops)
} }
EXPORT_SYMBOL(bt_sock_register); EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto) void bt_sock_unregister(int proto)
{ {
int err = 0;
if (proto < 0 || proto >= BT_MAX_PROTO) if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL; return;
write_lock(&bt_proto_lock); write_lock(&bt_proto_lock);
bt_proto[proto] = NULL;
if (!bt_proto[proto])
err = -ENOENT;
else
bt_proto[proto] = NULL;
write_unlock(&bt_proto_lock); write_unlock(&bt_proto_lock);
return err;
} }
EXPORT_SYMBOL(bt_sock_unregister); EXPORT_SYMBOL(bt_sock_unregister);
......
...@@ -253,8 +253,6 @@ int __init bnep_sock_init(void) ...@@ -253,8 +253,6 @@ int __init bnep_sock_init(void)
void __exit bnep_sock_cleanup(void) void __exit bnep_sock_cleanup(void)
{ {
bt_procfs_cleanup(&init_net, "bnep"); bt_procfs_cleanup(&init_net, "bnep");
if (bt_sock_unregister(BTPROTO_BNEP) < 0) bt_sock_unregister(BTPROTO_BNEP);
BT_ERR("Can't unregister BNEP socket");
proto_unregister(&bnep_proto); proto_unregister(&bnep_proto);
} }
...@@ -264,8 +264,6 @@ int cmtp_init_sockets(void) ...@@ -264,8 +264,6 @@ int cmtp_init_sockets(void)
void cmtp_cleanup_sockets(void) void cmtp_cleanup_sockets(void)
{ {
bt_procfs_cleanup(&init_net, "cmtp"); bt_procfs_cleanup(&init_net, "cmtp");
if (bt_sock_unregister(BTPROTO_CMTP) < 0) bt_sock_unregister(BTPROTO_CMTP);
BT_ERR("Can't unregister CMTP socket");
proto_unregister(&cmtp_proto); proto_unregister(&cmtp_proto);
} }
...@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) ...@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
} }
void hci_acl_disconn(struct hci_conn *conn, __u8 reason) void hci_disconnect(struct hci_conn *conn, __u8 reason)
{ {
struct hci_cp_disconnect cp; struct hci_cp_disconnect cp;
...@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn) ...@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
hci_amp_disconn(conn, reason); hci_amp_disconn(conn, reason);
break; break;
default: default:
hci_acl_disconn(conn, reason); hci_disconnect(conn, reason);
break; break;
} }
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -854,6 +854,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -854,6 +854,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
skb_queue_tail(&hdev->raw_q, skb); skb_queue_tail(&hdev->raw_q, skb);
queue_work(hdev->workqueue, &hdev->tx_work); queue_work(hdev->workqueue, &hdev->tx_work);
} else { } else {
/* Stand-alone HCI commands must be flaged as
* single-command requests.
*/
bt_cb(skb)->req.start = true;
skb_queue_tail(&hdev->cmd_q, skb); skb_queue_tail(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work); queue_work(hdev->workqueue, &hdev->cmd_work);
} }
...@@ -1121,8 +1126,6 @@ int __init hci_sock_init(void) ...@@ -1121,8 +1126,6 @@ int __init hci_sock_init(void)
void hci_sock_cleanup(void) void hci_sock_cleanup(void)
{ {
bt_procfs_cleanup(&init_net, "hci"); bt_procfs_cleanup(&init_net, "hci");
if (bt_sock_unregister(BTPROTO_HCI) < 0) bt_sock_unregister(BTPROTO_HCI);
BT_ERR("HCI socket unregistration failed");
proto_unregister(&hci_sk_proto); proto_unregister(&hci_sk_proto);
} }
...@@ -590,10 +590,8 @@ int __init bt_sysfs_init(void) ...@@ -590,10 +590,8 @@ int __init bt_sysfs_init(void)
bt_debugfs = debugfs_create_dir("bluetooth", NULL); bt_debugfs = debugfs_create_dir("bluetooth", NULL);
bt_class = class_create(THIS_MODULE, "bluetooth"); bt_class = class_create(THIS_MODULE, "bluetooth");
if (IS_ERR(bt_class))
return PTR_ERR(bt_class);
return 0; return PTR_RET(bt_class);
} }
void bt_sysfs_cleanup(void) void bt_sysfs_cleanup(void)
......
...@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid, ...@@ -311,6 +311,9 @@ static int hidp_get_raw_report(struct hid_device *hid,
int numbered_reports = hid->report_enum[report_type].numbered; int numbered_reports = hid->report_enum[report_type].numbered;
int ret; int ret;
if (atomic_read(&session->terminate))
return -EIO;
switch (report_type) { switch (report_type) {
case HID_FEATURE_REPORT: case HID_FEATURE_REPORT:
report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE; report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
...@@ -722,6 +725,7 @@ static int hidp_session(void *arg) ...@@ -722,6 +725,7 @@ static int hidp_session(void *arg)
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
atomic_inc(&session->terminate);
remove_wait_queue(sk_sleep(intr_sk), &intr_wait); remove_wait_queue(sk_sleep(intr_sk), &intr_wait);
remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); remove_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
......
...@@ -304,8 +304,6 @@ int __init hidp_init_sockets(void) ...@@ -304,8 +304,6 @@ int __init hidp_init_sockets(void)
void __exit hidp_cleanup_sockets(void) void __exit hidp_cleanup_sockets(void)
{ {
bt_procfs_cleanup(&init_net, "hidp"); bt_procfs_cleanup(&init_net, "hidp");
if (bt_sock_unregister(BTPROTO_HIDP) < 0) bt_sock_unregister(BTPROTO_HIDP);
BT_ERR("Can't unregister HIDP socket");
proto_unregister(&hidp_proto); proto_unregister(&hidp_proto);
} }
...@@ -1312,8 +1312,6 @@ int __init l2cap_init_sockets(void) ...@@ -1312,8 +1312,6 @@ int __init l2cap_init_sockets(void)
void l2cap_cleanup_sockets(void) void l2cap_cleanup_sockets(void)
{ {
bt_procfs_cleanup(&init_net, "l2cap"); bt_procfs_cleanup(&init_net, "l2cap");
if (bt_sock_unregister(BTPROTO_L2CAP) < 0) bt_sock_unregister(BTPROTO_L2CAP);
BT_ERR("L2CAP socket unregistration failed");
proto_unregister(&l2cap_proto); proto_unregister(&l2cap_proto);
} }
This diff is collapsed.
This diff is collapsed.
...@@ -1065,8 +1065,7 @@ void __exit rfcomm_cleanup_sockets(void) ...@@ -1065,8 +1065,7 @@ void __exit rfcomm_cleanup_sockets(void)
debugfs_remove(rfcomm_sock_debugfs); debugfs_remove(rfcomm_sock_debugfs);
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) bt_sock_unregister(BTPROTO_RFCOMM);
BT_ERR("RFCOMM socket layer unregistration failed");
proto_unregister(&rfcomm_proto); proto_unregister(&rfcomm_proto);
} }
...@@ -1111,8 +1111,7 @@ void __exit sco_exit(void) ...@@ -1111,8 +1111,7 @@ void __exit sco_exit(void)
debugfs_remove(sco_debugfs); debugfs_remove(sco_debugfs);
if (bt_sock_unregister(BTPROTO_SCO) < 0) bt_sock_unregister(BTPROTO_SCO);
BT_ERR("SCO socket unregistration failed");
proto_unregister(&sco_proto); proto_unregister(&sco_proto);
} }
......
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