diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/bnep/netdev.c | 6 | ||||
-rw-r--r-- | net/bluetooth/cmtp/capi.c | 37 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 12 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 4 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 121 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 132 | ||||
-rw-r--r-- | net/bluetooth/hidp/hidp.h | 4 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 18 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 12 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 4 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 4 |
13 files changed, 226 insertions, 133 deletions
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 26fb831ef7e..b6234b73c4c 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -64,7 +64,7 @@ static void bnep_net_set_mc_list(struct net_device *dev) struct sk_buff *skb; int size; - BT_DBG("%s mc_count %d", dev->name, dev->mc_count); + BT_DBG("%s mc_count %d", dev->name, netdev_mc_count(dev)); size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2; skb = alloc_skb(size, GFP_ATOMIC); @@ -97,7 +97,9 @@ static void bnep_net_set_mc_list(struct net_device *dev) /* FIXME: We should group addresses here. */ - for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) { + for (i = 0; + i < netdev_mc_count(dev) && i < BNEP_MAX_MULTICAST_FILTERS; + i++) { memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN); memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN); dmi = dmi->next; diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 97f8d68d574..3487cfe74ae 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -21,7 +21,8 @@ */ #include <linux/module.h> - +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -516,33 +517,37 @@ static char *cmtp_procinfo(struct capi_ctr *ctrl) return "CAPI Message Transport Protocol"; } -static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl) +static int cmtp_proc_show(struct seq_file *m, void *v) { + struct capi_ctr *ctrl = m->private; struct cmtp_session *session = ctrl->driverdata; struct cmtp_application *app; struct list_head *p, *n; - int len = 0; - len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl)); - len += sprintf(page + len, "addr %s\n", session->name); - len += sprintf(page + len, "ctrl %d\n", session->num); + seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl)); + seq_printf(m, "addr %s\n", session->name); + seq_printf(m, "ctrl %d\n", session->num); list_for_each_safe(p, n, &session->applications) { app = list_entry(p, struct cmtp_application, list); - len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping); + seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping); } - if (off + count >= len) - *eof = 1; - - if (len < off) - return 0; - - *start = page + off; + return 0; +} - return ((count < len - off) ? count : len - off); +static int cmtp_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cmtp_proc_show, PDE(inode)->data); } +static const struct file_operations cmtp_proc_fops = { + .owner = THIS_MODULE, + .open = cmtp_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; int cmtp_attach_device(struct cmtp_session *session) { @@ -582,7 +587,7 @@ int cmtp_attach_device(struct cmtp_session *session) session->ctrl.send_message = cmtp_send_message; session->ctrl.procinfo = cmtp_procinfo; - session->ctrl.ctr_read_proc = cmtp_ctr_read_proc; + session->ctrl.proc_fops = &cmtp_proc_fops; if (attach_capi_ctr(&session->ctrl) < 0) { BT_ERR("Can't attach new controller"); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b7c4224f4e7..b10e3cdb08f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -377,6 +377,9 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 if (acl->state == BT_CONNECTED && (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { + acl->power_save = 1; + hci_conn_enter_active_mode(acl); + if (lmp_esco_capable(hdev)) hci_setup_sync(sco, acl->handle); else diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 94ba3498202..4ad23192c7a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -491,6 +491,10 @@ int hci_dev_open(__u16 dev) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) set_bit(HCI_RAW, &hdev->flags); + /* Treat all non BR/EDR controllers as raw devices for now */ + if (hdev->dev_type != HCI_BREDR) + set_bit(HCI_RAW, &hdev->flags); + if (hdev->open(hdev)) { ret = -EIO; goto done; @@ -797,7 +801,7 @@ int hci_get_dev_info(void __user *arg) strcpy(di.name, hdev->name); di.bdaddr = hdev->bdaddr; - di.type = hdev->type; + di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); di.flags = hdev->flags; di.pkt_type = hdev->pkt_type; di.acl_mtu = hdev->acl_mtu; @@ -869,8 +873,8 @@ int hci_register_dev(struct hci_dev *hdev) struct list_head *head = &hci_dev_list, *p; int i, id = 0; - BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, - hdev->type, hdev->owner); + BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, + hdev->bus, hdev->owner); if (!hdev->open || !hdev->close || !hdev->destruct) return -EINVAL; @@ -946,7 +950,7 @@ int hci_unregister_dev(struct hci_dev *hdev) { int i; - BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); write_lock_bh(&hci_dev_list_lock); list_del(&hdev->list); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 28517bad796..6c57fc71c7e 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1698,7 +1698,9 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu hci_conn_add_sysfs(conn); break; + case 0x11: /* Unsupported Feature or Parameter Value */ case 0x1c: /* SCO interval rejected */ + case 0x1a: /* Unsupported Remote Feature */ case 0x1f: /* Unspecified error */ if (conn->out && conn->attempt < 2) { conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 688cfebfbee..38f08f6b86f 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -329,6 +329,9 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ } if (mask & HCI_CMSG_TSTAMP) { +#ifdef CONFIG_COMPAT + struct compat_timeval ctv; +#endif struct timeval tv; void *data; int len; @@ -339,7 +342,6 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ len = sizeof(tv); #ifdef CONFIG_COMPAT if (msg->msg_flags & MSG_CMSG_COMPAT) { - struct compat_timeval ctv; ctv.tv_sec = tv.tv_sec; ctv.tv_usec = tv.tv_usec; data = &ctv; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 2bc6f6a8de6..cafb55b0cea 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -2,6 +2,8 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -9,6 +11,9 @@ struct class *bt_class = NULL; EXPORT_SYMBOL_GPL(bt_class); +struct dentry *bt_debugfs = NULL; +EXPORT_SYMBOL_GPL(bt_debugfs); + static struct workqueue_struct *bt_workq; static inline char *link_typetostr(int type) @@ -166,9 +171,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) queue_work(bt_workq, &conn->work_del); } -static inline char *host_typetostr(int type) +static inline char *host_bustostr(int bus) { - switch (type) { + switch (bus) { case HCI_VIRTUAL: return "VIRTUAL"; case HCI_USB: @@ -188,10 +193,28 @@ static inline char *host_typetostr(int type) } } +static inline char *host_typetostr(int type) +{ + switch (type) { + case HCI_BREDR: + return "BR/EDR"; + case HCI_80211: + return "802.11"; + default: + return "UNKNOWN"; + } +} + +static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct hci_dev *hdev = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); +} + static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", host_typetostr(hdev->type)); + return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); } static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -251,32 +274,6 @@ static ssize_t show_hci_revision(struct device *dev, struct device_attribute *at return sprintf(buf, "%d\n", hdev->hci_rev); } -static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct hci_dev *hdev = dev_get_drvdata(dev); - struct inquiry_cache *cache = &hdev->inq_cache; - struct inquiry_entry *e; - int n = 0; - - hci_dev_lock_bh(hdev); - - for (e = cache->list; e; e = e->next) { - struct inquiry_data *data = &e->data; - bdaddr_t bdaddr; - baswap(&bdaddr, &data->bdaddr); - n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", - batostr(&bdaddr), - data->pscan_rep_mode, data->pscan_period_mode, - data->pscan_mode, data->dev_class[2], - data->dev_class[1], data->dev_class[0], - __le16_to_cpu(data->clock_offset), - data->rssi, data->ssp_mode, e->timestamp); - } - - hci_dev_unlock_bh(hdev); - return n; -} - static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); @@ -355,6 +352,7 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib return count; } +static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); @@ -363,7 +361,6 @@ static DEVICE_ATTR(features, S_IRUGO, show_features, NULL); static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); -static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, show_idle_timeout, store_idle_timeout); @@ -373,6 +370,7 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, show_sniff_min_interval, store_sniff_min_interval); static struct attribute *bt_host_attrs[] = { + &dev_attr_bus.attr, &dev_attr_type.attr, &dev_attr_name.attr, &dev_attr_class.attr, @@ -381,7 +379,6 @@ static struct attribute *bt_host_attrs[] = { &dev_attr_manufacturer.attr, &dev_attr_hci_version.attr, &dev_attr_hci_revision.attr, - &dev_attr_inquiry_cache.attr, &dev_attr_idle_timeout.attr, &dev_attr_sniff_max_interval.attr, &dev_attr_sniff_min_interval.attr, @@ -409,12 +406,50 @@ static struct device_type bt_host = { .release = bt_host_release, }; +static int inquiry_cache_show(struct seq_file *f, void *p) +{ + struct hci_dev *hdev = f->private; + struct inquiry_cache *cache = &hdev->inq_cache; + struct inquiry_entry *e; + + hci_dev_lock_bh(hdev); + + for (e = cache->list; e; e = e->next) { + struct inquiry_data *data = &e->data; + bdaddr_t bdaddr; + baswap(&bdaddr, &data->bdaddr); + seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", + batostr(&bdaddr), + data->pscan_rep_mode, data->pscan_period_mode, + data->pscan_mode, data->dev_class[2], + data->dev_class[1], data->dev_class[0], + __le16_to_cpu(data->clock_offset), + data->rssi, data->ssp_mode, e->timestamp); + } + + hci_dev_unlock_bh(hdev); + + return 0; +} + +static int inquiry_cache_open(struct inode *inode, struct file *file) +{ + return single_open(file, inquiry_cache_show, inode->i_private); +} + +static const struct file_operations inquiry_cache_fops = { + .open = inquiry_cache_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int hci_register_sysfs(struct hci_dev *hdev) { struct device *dev = &hdev->dev; int err; - BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); dev->type = &bt_host; dev->class = bt_class; @@ -428,12 +463,24 @@ int hci_register_sysfs(struct hci_dev *hdev) if (err < 0) return err; + if (!bt_debugfs) + return 0; + + hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); + if (!hdev->debugfs) + return 0; + + debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, + hdev, &inquiry_cache_fops); + return 0; } void hci_unregister_sysfs(struct hci_dev *hdev) { - BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + + debugfs_remove_recursive(hdev->debugfs); device_del(&hdev->dev); } @@ -444,6 +491,8 @@ int __init bt_sysfs_init(void) if (!bt_workq) return -ENOMEM; + bt_debugfs = debugfs_create_dir("bluetooth", NULL); + bt_class = class_create(THIS_MODULE, "bluetooth"); if (IS_ERR(bt_class)) { destroy_workqueue(bt_workq); @@ -455,7 +504,9 @@ int __init bt_sysfs_init(void) void bt_sysfs_cleanup(void) { - destroy_workqueue(bt_workq); - class_destroy(bt_class); + + debugfs_remove_recursive(bt_debugfs); + + destroy_workqueue(bt_workq); } diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 18e7f5a43dc..280529ad927 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -243,6 +243,39 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) input_sync(dev); } +static int __hidp_send_ctrl_message(struct hidp_session *session, + unsigned char hdr, unsigned char *data, int size) +{ + struct sk_buff *skb; + + BT_DBG("session %p data %p size %d", session, data, size); + + if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) { + BT_ERR("Can't allocate memory for new frame"); + return -ENOMEM; + } + + *skb_put(skb, 1) = hdr; + if (data && size > 0) + memcpy(skb_put(skb, size), data, size); + + skb_queue_tail(&session->ctrl_transmit, skb); + + return 0; +} + +static inline int hidp_send_ctrl_message(struct hidp_session *session, + unsigned char hdr, unsigned char *data, int size) +{ + int err; + + err = __hidp_send_ctrl_message(session, hdr, data, size); + + hidp_schedule(session); + + return err; +} + static int hidp_queue_report(struct hidp_session *session, unsigned char *data, int size) { @@ -280,9 +313,22 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep return hidp_queue_report(session, buf, rsize); } -static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count) +static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, + unsigned char report_type) { - if (hidp_queue_report(hid->driver_data, data, count)) + switch (report_type) { + case HID_FEATURE_REPORT: + report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; + break; + case HID_OUTPUT_REPORT: + report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; + break; + default: + return -EINVAL; + } + + if (hidp_send_ctrl_message(hid->driver_data, report_type, + data, count)) return -ENOMEM; return count; } @@ -307,39 +353,6 @@ static inline void hidp_del_timer(struct hidp_session *session) del_timer(&session->timer); } -static int __hidp_send_ctrl_message(struct hidp_session *session, - unsigned char hdr, unsigned char *data, int size) -{ - struct sk_buff *skb; - - BT_DBG("session %p data %p size %d", session, data, size); - - if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) { - BT_ERR("Can't allocate memory for new frame"); - return -ENOMEM; - } - - *skb_put(skb, 1) = hdr; - if (data && size > 0) - memcpy(skb_put(skb, size), data, size); - - skb_queue_tail(&session->ctrl_transmit, skb); - - return 0; -} - -static inline int hidp_send_ctrl_message(struct hidp_session *session, - unsigned char hdr, unsigned char *data, int size) -{ - int err; - - err = __hidp_send_ctrl_message(session, hdr, data, size); - - hidp_schedule(session); - - return err; -} - static void hidp_process_handshake(struct hidp_session *session, unsigned char param) { @@ -701,29 +714,9 @@ static void hidp_close(struct hid_device *hid) static int hidp_parse(struct hid_device *hid) { struct hidp_session *session = hid->driver_data; - struct hidp_connadd_req *req = session->req; - unsigned char *buf; - int ret; - - buf = kmalloc(req->rd_size, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (copy_from_user(buf, req->rd_data, req->rd_size)) { - kfree(buf); - return -EFAULT; - } - - ret = hid_parse_report(session->hid, buf, req->rd_size); - - kfree(buf); - - if (ret) - return ret; - - session->req = NULL; - return 0; + return hid_parse_report(session->hid, session->rd_data, + session->rd_size); } static int hidp_start(struct hid_device *hid) @@ -768,12 +761,24 @@ static int hidp_setup_hid(struct hidp_session *session, bdaddr_t src, dst; int err; + session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); + if (!session->rd_data) + return -ENOMEM; + + if (copy_from_user(session->rd_data, req->rd_data, req->rd_size)) { + err = -EFAULT; + goto fault; + } + session->rd_size = req->rd_size; + hid = hid_allocate_device(); - if (IS_ERR(hid)) - return PTR_ERR(hid); + if (IS_ERR(hid)) { + err = PTR_ERR(hid); + goto fault; + } session->hid = hid; - session->req = req; + hid->driver_data = session; baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); @@ -804,6 +809,10 @@ failed: hid_destroy_device(hid); session->hid = NULL; +fault: + kfree(session->rd_data); + session->rd_data = NULL; + return err; } @@ -898,6 +907,9 @@ unlink: session->hid = NULL; } + kfree(session->rd_data); + session->rd_data = NULL; + purge: skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index faf3d74c358..a4e215d50c1 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h @@ -154,7 +154,9 @@ struct hidp_session { struct sk_buff_head ctrl_transmit; struct sk_buff_head intr_transmit; - struct hidp_connadd_req *req; + /* Report descriptor */ + __u8 *rd_data; + uint rd_size; }; static inline void hidp_schedule(struct hidp_session *session) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 1120cf14a54..4db7ae2fe07 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1368,7 +1368,6 @@ static int l2cap_ertm_send(struct sock *sk) while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk)) && !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) { - tx_skb = skb_clone(skb, GFP_ATOMIC); if (pi->remote_max_tx && bt_cb(skb)->retries == pi->remote_max_tx) { @@ -1376,6 +1375,8 @@ static int l2cap_ertm_send(struct sock *sk) break; } + tx_skb = skb_clone(skb, GFP_ATOMIC); + bt_cb(skb)->retries++; control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); @@ -3518,7 +3519,6 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk struct l2cap_pinfo *pi; u16 control, len; u8 tx_seq; - int err; sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); if (!sk) { @@ -3570,13 +3570,11 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk goto drop; if (__is_iframe(control)) - err = l2cap_data_channel_iframe(sk, control, skb); + l2cap_data_channel_iframe(sk, control, skb); else - err = l2cap_data_channel_sframe(sk, control, skb); + l2cap_data_channel_sframe(sk, control, skb); - if (!err) - goto done; - break; + goto done; case L2CAP_MODE_STREAMING: control = get_unaligned_le16(skb->data); @@ -3602,7 +3600,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk else pi->expected_tx_seq = tx_seq + 1; - err = l2cap_sar_reassembly_sdu(sk, skb, control); + l2cap_sar_reassembly_sdu(sk, skb, control); goto done; @@ -3939,7 +3937,9 @@ drop: return 0; } -static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) +static ssize_t l2cap_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fc5ee3296e2..db8a68e1a5b 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -252,7 +252,6 @@ static void rfcomm_session_timeout(unsigned long arg) BT_DBG("session %p state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); - rfcomm_session_put(s); rfcomm_schedule(RFCOMM_SCHED_TIMEO); } @@ -1151,7 +1150,11 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) break; case BT_DISCONN: - rfcomm_session_put(s); + /* When socket is closed and we are not RFCOMM + * initiator rfcomm_process_rx already calls + * rfcomm_session_put() */ + if (s->sock->sk->sk_state != BT_CLOSED) + rfcomm_session_put(s); break; } } @@ -1920,6 +1923,7 @@ static inline void rfcomm_process_sessions(void) if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) { s->state = BT_DISCONN; rfcomm_send_disc(s, 0); + rfcomm_session_put(s); continue; } @@ -2094,7 +2098,9 @@ static struct hci_cb rfcomm_cb = { .security_cfm = rfcomm_security_cfm }; -static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) +static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct rfcomm_session *s; struct list_head *pp, *p; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4b5968dda67..ca87d6ac6a2 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -1061,7 +1061,9 @@ done: return result; } -static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf) +static ssize_t rfcomm_sock_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index dd8f6ec57dc..f93b939539b 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -953,7 +953,9 @@ drop: return 0; } -static ssize_t sco_sysfs_show(struct class *dev, char *buf) +static ssize_t sco_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; |