diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/include/net/bluetooth/bluetooth.h linux-2.6.28-working/include/net/bluetooth/bluetooth.h --- linux-source-2.6.28-pristine/include/net/bluetooth/bluetooth.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/include/net/bluetooth/bluetooth.h 2009-02-18 16:07:39.000000000 +0000 @@ -54,8 +54,8 @@ #define SOL_RFCOMM 18 #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) -#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg) -#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) +#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) +#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) /* Connection and socket states */ enum { @@ -121,7 +121,6 @@ void bt_sock_link(struct bt_sock_list *l void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); -int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); void bt_accept_enqueue(struct sock *parent, struct sock *sk); @@ -171,7 +170,7 @@ static inline int skb_frags_no(struct sk int bt_err(__u16 code); extern int hci_sock_init(void); -extern void hci_sock_cleanup(void); +extern int hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/include/net/bluetooth/hci_core.h linux-2.6.28-working/include/net/bluetooth/hci_core.h --- linux-source-2.6.28-pristine/include/net/bluetooth/hci_core.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/include/net/bluetooth/hci_core.h 2009-02-18 16:07:39.000000000 +0000 @@ -40,7 +40,6 @@ struct inquiry_data { __u8 dev_class[3]; __le16 clock_offset; __s8 rssi; - __u8 ssp_mode; }; struct inquiry_entry { @@ -76,7 +75,6 @@ struct hci_dev { __u8 dev_class[3]; __u8 features[8]; __u8 commands[64]; - __u8 ssp_mode; __u8 hci_ver; __u16 hci_rev; __u16 manufacturer; @@ -163,12 +161,9 @@ struct hci_conn { __u8 attempt; __u8 dev_class[3]; __u8 features[8]; - __u8 ssp_mode; __u16 interval; - __u16 pkt_type; __u16 link_policy; __u32 link_mode; - __u8 auth_type; __u8 power_save; unsigned long pend; @@ -325,8 +320,7 @@ int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); -struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); -int hci_conn_check_link_mode(struct hci_conn *conn); +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src); int hci_conn_auth(struct hci_conn *conn); int hci_conn_encrypt(struct hci_conn *conn); int hci_conn_change_link_key(struct hci_conn *conn); @@ -350,7 +344,7 @@ static inline void hci_conn_put(struct h if (conn->state == BT_CONNECTED) { timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); if (!conn->out) - timeo *= 5; + timeo *= 2; } else timeo = msecs_to_jiffies(10); } else @@ -424,7 +418,6 @@ int hci_get_dev_list(void __user *arg); int hci_get_dev_info(void __user *arg); int hci_get_conn_list(void __user *arg); int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); -int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); int hci_inquiry(void __user *arg); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); @@ -466,7 +459,6 @@ void hci_conn_del_sysfs(struct hci_conn #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) -#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) /* ----- HCI protocols ----- */ struct hci_proto { @@ -482,7 +474,7 @@ struct hci_proto { int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); int (*auth_cfm) (struct hci_conn *conn, __u8 status); - int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); + int (*encrypt_cfm) (struct hci_conn *conn, __u8 status); }; static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) @@ -540,17 +532,17 @@ static inline void hci_proto_auth_cfm(st hp->auth_cfm(conn, status); } -static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) +static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status) { register struct hci_proto *hp; hp = hci_proto[HCI_PROTO_L2CAP]; if (hp && hp->encrypt_cfm) - hp->encrypt_cfm(conn, status, encrypt); + hp->encrypt_cfm(conn, status); hp = hci_proto[HCI_PROTO_SCO]; if (hp && hp->encrypt_cfm) - hp->encrypt_cfm(conn, status, encrypt); + hp->encrypt_cfm(conn, status); } int hci_register_proto(struct hci_proto *hproto); @@ -587,7 +579,7 @@ static inline void hci_encrypt_cfm(struc { struct list_head *p; - hci_proto_encrypt_cfm(conn, status, encrypt); + hci_proto_encrypt_cfm(conn, status); read_lock_bh(&hci_cb_list_lock); list_for_each(p, &hci_cb_list) { diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/include/net/bluetooth/hci.h linux-2.6.28-working/include/net/bluetooth/hci.h --- linux-source-2.6.28-pristine/include/net/bluetooth/hci.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/include/net/bluetooth/hci.h 2009-02-18 16:07:39.000000000 +0000 @@ -72,6 +72,8 @@ enum { HCI_INQUIRY, HCI_RAW, + + HCI_SECMGR }; /* HCI ioctl defines */ @@ -84,7 +86,6 @@ enum { #define HCIGETDEVINFO _IOR('H', 211, int) #define HCIGETCONNLIST _IOR('H', 212, int) #define HCIGETCONNINFO _IOR('H', 213, int) -#define HCIGETAUTHINFO _IOR('H', 215, int) #define HCISETRAW _IOW('H', 220, int) #define HCISETSCAN _IOW('H', 221, int) @@ -96,6 +97,8 @@ enum { #define HCISETACLMTU _IOW('H', 227, int) #define HCISETSCOMTU _IOW('H', 228, int) +#define HCISETSECMGR _IOW('H', 230, int) + #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ @@ -134,8 +137,6 @@ enum { #define ESCO_EV4 0x0010 #define ESCO_EV5 0x0020 -#define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) - /* ACL flags */ #define ACL_CONT 0x01 #define ACL_START 0x02 @@ -177,8 +178,6 @@ enum { #define LMP_SNIFF_SUBR 0x02 -#define LMP_SIMPLE_PAIR 0x08 - /* Connection modes */ #define HCI_CM_ACTIVE 0x0000 #define HCI_CM_HOLD 0x0001 @@ -200,14 +199,6 @@ enum { #define HCI_LM_RELIABLE 0x0010 #define HCI_LM_SECURE 0x0020 -/* Authentication types */ -#define HCI_AT_NO_BONDING 0x00 -#define HCI_AT_NO_BONDING_MITM 0x01 -#define HCI_AT_DEDICATED_BONDING 0x02 -#define HCI_AT_DEDICATED_BONDING_MITM 0x03 -#define HCI_AT_GENERAL_BONDING 0x04 -#define HCI_AT_GENERAL_BONDING_MITM 0x05 - /* ----- HCI Commands ---- */ #define HCI_OP_INQUIRY 0x0401 struct hci_cp_inquiry { @@ -411,17 +402,6 @@ struct hci_rp_write_link_policy { __le16 handle; } __attribute__ ((packed)); -#define HCI_OP_READ_DEF_LINK_POLICY 0x080e -struct hci_rp_read_def_link_policy { - __u8 status; - __le16 policy; -} __attribute__ ((packed)); - -#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f -struct hci_cp_write_def_link_policy { - __le16 policy; -} __attribute__ ((packed)); - #define HCI_OP_SNIFF_SUBRATE 0x0811 struct hci_cp_sniff_subrate { __le16 handle; @@ -521,17 +501,6 @@ struct hci_cp_host_buffer_size { __le16 sco_max_pkt; } __attribute__ ((packed)); -#define HCI_OP_READ_SSP_MODE 0x0c55 -struct hci_rp_read_ssp_mode { - __u8 status; - __u8 mode; -} __attribute__ ((packed)); - -#define HCI_OP_WRITE_SSP_MODE 0x0c56 -struct hci_cp_write_ssp_mode { - __u8 mode; -} __attribute__ ((packed)); - #define HCI_OP_READ_LOCAL_VERSION 0x1001 struct hci_rp_read_local_version { __u8 status; @@ -727,13 +696,6 @@ struct hci_ev_clock_offset { __le16 clock_offset; } __attribute__ ((packed)); -#define HCI_EV_PKT_TYPE_CHANGE 0x1d -struct hci_ev_pkt_type_change { - __u8 status; - __le16 handle; - __le16 pkt_type; -} __attribute__ ((packed)); - #define HCI_EV_PSCAN_REP_MODE 0x20 struct hci_ev_pscan_rep_mode { bdaddr_t bdaddr; @@ -812,23 +774,6 @@ struct extended_inquiry_info { __u8 data[240]; } __attribute__ ((packed)); -#define HCI_EV_IO_CAPA_REQUEST 0x31 -struct hci_ev_io_capa_request { - bdaddr_t bdaddr; -} __attribute__ ((packed)); - -#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 -struct hci_ev_simple_pair_complete { - __u8 status; - bdaddr_t bdaddr; -} __attribute__ ((packed)); - -#define HCI_EV_REMOTE_HOST_FEATURES 0x3d -struct hci_ev_remote_host_features { - bdaddr_t bdaddr; - __u8 features[8]; -} __attribute__ ((packed)); - /* Internal events generated by Bluetooth stack */ #define HCI_EV_STACK_INTERNAL 0xfd struct hci_ev_stack_internal { @@ -1006,11 +951,6 @@ struct hci_conn_info_req { struct hci_conn_info conn_info[0]; }; -struct hci_auth_info_req { - bdaddr_t bdaddr; - __u8 type; -}; - struct hci_inquiry_req { __u16 dev_id; __u16 flags; diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/include/net/bluetooth/rfcomm.h linux-2.6.28-working/include/net/bluetooth/rfcomm.h --- linux-source-2.6.28-pristine/include/net/bluetooth/rfcomm.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/include/net/bluetooth/rfcomm.h 2009-02-18 16:10:10.000000000 +0000 @@ -180,9 +180,7 @@ struct rfcomm_dlc { u8 addr; u8 priority; u8 v24_sig; - u8 remote_v24_sig; u8 mscex; - u8 out; u32 link_mode; diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/af_bluetooth.c linux-2.6.28-working/net/bluetooth/af_bluetooth.c --- linux-source-2.6.28-pristine/net/bluetooth/af_bluetooth.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/af_bluetooth.c 2009-02-15 01:42:26.000000000 +0000 @@ -36,8 +36,10 @@ #include #include #include -#include + +#if defined(CONFIG_KMOD) #include +#endif #include @@ -46,35 +48,11 @@ #define BT_DBG(D...) #endif -#define VERSION "2.13" +#define VERSION "2.11" /* Bluetooth sockets */ #define BT_MAX_PROTO 8 static struct net_proto_family *bt_proto[BT_MAX_PROTO]; - -static struct lock_class_key bt_slock_key[BT_MAX_PROTO]; -static struct lock_class_key bt_lock_key[BT_MAX_PROTO]; -static const char *bt_key_strings[BT_MAX_PROTO] = { - "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP", - "sk_lock-AF_BLUETOOTH-BTPROTO_HCI", - "sk_lock-AF_BLUETOOTH-BTPROTO_SCO", - "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM", - "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP", - "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP", - "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP", - "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP", -}; - -static const char *bt_slock_key_strings[BT_MAX_PROTO] = { - "slock-AF_BLUETOOTH-BTPROTO_L2CAP", - "slock-AF_BLUETOOTH-BTPROTO_HCI", - "slock-AF_BLUETOOTH-BTPROTO_SCO", - "slock-AF_BLUETOOTH-BTPROTO_RFCOMM", - "slock-AF_BLUETOOTH-BTPROTO_BNEP", - "slock-AF_BLUETOOTH-BTPROTO_CMTP", - "slock-AF_BLUETOOTH-BTPROTO_HIDP", - "slock-AF_BLUETOOTH-BTPROTO_AVDTP", -}; static DEFINE_RWLOCK(bt_proto_lock); int bt_sock_register(int proto, struct net_proto_family *ops) @@ -117,21 +95,6 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); -static void bt_reclassify_sock_lock(struct socket *sock, int proto) -{ - struct sock *sk = sock->sk; - - if (!sk) - return; - BUG_ON(sock_owned_by_user(sk)); - - sock_lock_init_class_and_name(sk, - bt_slock_key_strings[proto], - &bt_slock_key[proto], - bt_key_strings[proto], - &bt_lock_key[proto]); -} - static int bt_sock_create(struct net *net, struct socket *sock, int proto) { int err; @@ -142,8 +105,11 @@ static int bt_sock_create(struct net *ne if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; - if (!bt_proto[proto]) +#if defined(CONFIG_KMOD) + if (!bt_proto[proto]) { request_module("bt-proto-%d", proto); + } +#endif err = -EPROTONOSUPPORT; @@ -151,7 +117,6 @@ static int bt_sock_create(struct net *ne if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { err = bt_proto[proto]->create(net, sock, proto); - bt_reclassify_sock_lock(sock, proto); module_put(bt_proto[proto]->owner); } @@ -261,8 +226,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, skb_reset_transport_header(skb); err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err == 0) - sock_recv_timestamp(msg, sk, skb); skb_free_datagram(sk, skb); @@ -326,54 +289,6 @@ unsigned int bt_sock_poll(struct file * } EXPORT_SYMBOL(bt_sock_poll); -int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - struct sock *sk = sock->sk; - struct sk_buff *skb; - long amount; - int err; - - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); - - switch (cmd) { - case TIOCOUTQ: - if (sk->sk_state == BT_LISTEN) - return -EINVAL; - - amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); - if (amount < 0) - amount = 0; - err = put_user(amount, (int __user *) arg); - break; - - case TIOCINQ: - if (sk->sk_state == BT_LISTEN) - return -EINVAL; - - lock_sock(sk); - skb = skb_peek(&sk->sk_receive_queue); - amount = skb ? skb->len : 0; - release_sock(sk); - err = put_user(amount, (int __user *) arg); - break; - - case SIOCGSTAMP: - err = sock_get_timestamp(sk, (struct timeval __user *) arg); - break; - - case SIOCGSTAMPNS: - err = sock_get_timestampns(sk, (struct timespec __user *) arg); - break; - - default: - err = -ENOIOCTLCMD; - break; - } - - return err; -} -EXPORT_SYMBOL(bt_sock_ioctl); - int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) { DECLARE_WAITQUEUE(wait, current); @@ -450,7 +365,7 @@ static void __exit bt_exit(void) subsys_initcall(bt_init); module_exit(bt_exit); -MODULE_AUTHOR("Marcel Holtmann "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth Core ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/bnep/bnep.h linux-2.6.28-working/net/bluetooth/bnep/bnep.h --- linux-source-2.6.28-pristine/net/bluetooth/bnep/bnep.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/bnep/bnep.h 2009-02-15 01:42:26.000000000 +0000 @@ -16,6 +16,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + * $Id: bnep.h,v 1.5 2002/08/04 21:23:58 maxk Exp $ + */ + #ifndef _BNEP_H #define _BNEP_H @@ -170,7 +174,7 @@ struct bnep_session { void bnep_net_setup(struct net_device *dev); int bnep_sock_init(void); -void bnep_sock_cleanup(void); +int bnep_sock_cleanup(void); static inline int bnep_mc_hash(__u8 *addr) { Binary files linux-source-2.6.28-pristine/net/bluetooth/bnep/bnep.ko and linux-2.6.28-working/net/bluetooth/bnep/bnep.ko differ diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/bnep/core.c linux-2.6.28-working/net/bluetooth/bnep/core.c --- linux-source-2.6.28-pristine/net/bluetooth/bnep/core.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/bnep/core.c 2009-02-15 01:42:26.000000000 +0000 @@ -25,6 +25,10 @@ SOFTWARE IS DISCLAIMED. */ +/* + * $Id: core.c,v 1.20 2002/08/04 21:23:58 maxk Exp $ + */ + #include #include @@ -57,10 +61,7 @@ #define BT_DBG(D...) #endif -#define VERSION "1.3" - -static int compress_src = 1; -static int compress_dst = 1; +#define VERSION "1.2" static LIST_HEAD(bnep_session_list); static DECLARE_RWSEM(bnep_session_sem); @@ -134,7 +135,7 @@ static int bnep_ctrl_set_netfilter(struc if (len < 2) return -EILSEQ; - n = get_unaligned_be16(data); + n = ntohs(get_unaligned(data)); data++; len -= 2; if (len < n) @@ -149,8 +150,8 @@ static int bnep_ctrl_set_netfilter(struc int i; for (i = 0; i < n; i++) { - f[i].start = get_unaligned_be16(data++); - f[i].end = get_unaligned_be16(data++); + f[i].start = ntohs(get_unaligned(data++)); + f[i].end = ntohs(get_unaligned(data++)); BT_DBG("proto filter start %d end %d", f[i].start, f[i].end); @@ -179,7 +180,7 @@ static int bnep_ctrl_set_mcfilter(struct if (len < 2) return -EILSEQ; - n = get_unaligned_be16(data); + n = ntohs(get_unaligned((__be16 *) data)); data += 2; len -= 2; if (len < n) @@ -421,10 +422,10 @@ static inline int bnep_tx_frame(struct b iv[il++] = (struct kvec) { &type, 1 }; len++; - if (compress_src && !compare_ether_addr(eh->h_dest, s->eh.h_source)) + if (!compare_ether_addr(eh->h_dest, s->eh.h_source)) type |= 0x01; - if (compress_dst && !compare_ether_addr(eh->h_source, s->eh.h_dest)) + if (!compare_ether_addr(eh->h_source, s->eh.h_dest)) type |= 0x02; if (type) @@ -506,11 +507,6 @@ static int bnep_session(void *arg) /* Delete network device */ unregister_netdev(dev); - /* Wakeup user-space polling for socket errors */ - s->sock->sk->sk_err = EUNATCH; - - wake_up_interruptible(s->sock->sk->sk_sleep); - /* Release the socket */ fput(s->sock->file); @@ -730,13 +726,7 @@ static void __exit bnep_exit(void) module_init(bnep_init); module_exit(bnep_exit); -module_param(compress_src, bool, 0644); -MODULE_PARM_DESC(compress_src, "Compress sources headers"); - -module_param(compress_dst, bool, 0644); -MODULE_PARM_DESC(compress_dst, "Compress destination headers"); - -MODULE_AUTHOR("Marcel Holtmann "); +MODULE_AUTHOR("David Libault , Maxim Krasnyansky "); MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/bnep/netdev.c linux-2.6.28-working/net/bluetooth/bnep/netdev.c --- linux-source-2.6.28-pristine/net/bluetooth/bnep/netdev.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/bnep/netdev.c 2009-02-15 01:42:26.000000000 +0000 @@ -25,6 +25,10 @@ SOFTWARE IS DISCLAIMED. */ +/* + * $Id: netdev.c,v 1.8 2002/08/04 21:23:58 maxk Exp $ + */ + #include #include diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/bnep/sock.c linux-2.6.28-working/net/bluetooth/bnep/sock.c --- linux-source-2.6.28-pristine/net/bluetooth/bnep/sock.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/bnep/sock.c 2009-02-15 01:42:26.000000000 +0000 @@ -24,6 +24,10 @@ SOFTWARE IS DISCLAIMED. */ +/* + * $Id: sock.c,v 1.4 2002/08/04 21:23:58 maxk Exp $ + */ + #include #include @@ -90,7 +94,7 @@ static int bnep_sock_ioctl(struct socket return err; if (nsock->sk->sk_state != BT_CONNECTED) { - sockfd_put(nsock); + fput(nsock->file); return -EBADFD; } @@ -99,7 +103,7 @@ static int bnep_sock_ioctl(struct socket if (copy_to_user(argp, &ca, sizeof(ca))) err = -EFAULT; } else - sockfd_put(nsock); + fput(nsock->file); return err; @@ -253,10 +257,12 @@ error: return err; } -void __exit bnep_sock_cleanup(void) +int __exit bnep_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_BNEP) < 0) BT_ERR("Can't unregister BNEP socket"); proto_unregister(&bnep_proto); + + return 0; } diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/cmtp/sock.c linux-2.6.28-working/net/bluetooth/cmtp/sock.c --- linux-source-2.6.28-pristine/net/bluetooth/cmtp/sock.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/cmtp/sock.c 2009-02-15 01:42:27.000000000 +0000 @@ -88,7 +88,7 @@ static int cmtp_sock_ioctl(struct socket return err; if (nsock->sk->sk_state != BT_CONNECTED) { - sockfd_put(nsock); + fput(nsock->file); return -EBADFD; } @@ -97,7 +97,7 @@ static int cmtp_sock_ioctl(struct socket if (copy_to_user(argp, &ca, sizeof(ca))) err = -EFAULT; } else - sockfd_put(nsock); + fput(nsock->file); return err; diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hci_conn.c linux-2.6.28-working/net/bluetooth/hci_conn.c --- linux-source-2.6.28-pristine/net/bluetooth/hci_conn.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hci_conn.c 2009-02-15 01:42:26.000000000 +0000 @@ -59,31 +59,24 @@ void hci_acl_connect(struct hci_conn *co BT_DBG("%p", conn); conn->state = BT_CONNECT; - conn->out = 1; - + conn->out = 1; conn->link_mode = HCI_LM_MASTER; conn->attempt++; - conn->link_policy = hdev->link_policy; - memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) { - if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { - cp.pscan_rep_mode = ie->data.pscan_rep_mode; - cp.pscan_mode = ie->data.pscan_mode; - cp.clock_offset = ie->data.clock_offset | - cpu_to_le16(0x8000); - } - + if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)) && + inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { + cp.pscan_rep_mode = ie->data.pscan_rep_mode; + cp.pscan_mode = ie->data.pscan_mode; + cp.clock_offset = ie->data.clock_offset | cpu_to_le16(0x8000); memcpy(conn->dev_class, ie->data.dev_class, 3); - conn->ssp_mode = ie->data.ssp_mode; } - cp.pkt_type = cpu_to_le16(conn->pkt_type); + cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK); if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) cp.role_switch = 0x01; else @@ -129,7 +122,7 @@ void hci_add_sco(struct hci_conn *conn, conn->out = 1; cp.handle = cpu_to_le16(handle); - cp.pkt_type = cpu_to_le16(conn->pkt_type); + cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); } @@ -145,7 +138,7 @@ void hci_setup_sync(struct hci_conn *con conn->out = 1; cp.handle = cpu_to_le16(handle); - cp.pkt_type = cpu_to_le16(conn->pkt_type); + cp.pkt_type = cpu_to_le16(hdev->esco_type); cp.tx_bandwidth = cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40); @@ -170,13 +163,11 @@ static void hci_conn_timeout(unsigned lo switch (conn->state) { case BT_CONNECT: - case BT_CONNECT2: if (conn->type == ACL_LINK) hci_acl_connect_cancel(conn); else hci_acl_disconn(conn, 0x13); break; - case BT_CONFIG: case BT_CONNECTED: hci_acl_disconn(conn, 0x13); break; @@ -208,32 +199,22 @@ struct hci_conn *hci_conn_add(struct hci return NULL; bacpy(&conn->dst, dst); - conn->hdev = hdev; - conn->type = type; - conn->mode = HCI_CM_ACTIVE; - conn->state = BT_OPEN; + conn->hdev = hdev; + conn->type = type; + conn->mode = HCI_CM_ACTIVE; + conn->state = BT_OPEN; conn->power_save = 1; - switch (type) { - case ACL_LINK: - conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK; - break; - case SCO_LINK: - if (lmp_esco_capable(hdev)) - conn->pkt_type = hdev->esco_type & SCO_ESCO_MASK; - else - conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK; - break; - case ESCO_LINK: - conn->pkt_type = hdev->esco_type; - break; - } - skb_queue_head_init(&conn->data_q); - setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); - setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); + init_timer(&conn->disc_timer); + conn->disc_timer.function = hci_conn_timeout; + conn->disc_timer.data = (unsigned long) conn; + + init_timer(&conn->idle_timer); + conn->idle_timer.function = hci_conn_idle; + conn->idle_timer.data = (unsigned long) conn; atomic_set(&conn->refcnt, 0); @@ -245,6 +226,8 @@ struct hci_conn *hci_conn_add(struct hci if (hdev->notify) hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); + hci_conn_add_sysfs(conn); + tasklet_enable(&hdev->tx_task); return conn; @@ -276,14 +259,13 @@ int hci_conn_del(struct hci_conn *conn) } tasklet_disable(&hdev->tx_task); - hci_conn_hash_del(hdev, conn); if (hdev->notify) hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); - tasklet_enable(&hdev->tx_task); - skb_queue_purge(&conn->data_q); + hci_conn_del_sysfs(conn); + hci_dev_put(hdev); return 0; } @@ -330,7 +312,7 @@ EXPORT_SYMBOL(hci_get_route); /* Create SCO or ACL connection. * Device _must_ be locked */ -struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type) +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) { struct hci_conn *acl; struct hci_conn *sco; @@ -344,10 +326,8 @@ struct hci_conn *hci_connect(struct hci_ hci_conn_hold(acl); - if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { - acl->auth_type = auth_type; + if (acl->state == BT_OPEN || acl->state == BT_CLOSED) hci_acl_connect(acl); - } if (type == ACL_LINK) return acl; @@ -376,39 +356,18 @@ struct hci_conn *hci_connect(struct hci_ } EXPORT_SYMBOL(hci_connect); -/* Check link security requirement */ -int hci_conn_check_link_mode(struct hci_conn *conn) -{ - BT_DBG("conn %p", conn); - - if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 && - !(conn->link_mode & HCI_LM_ENCRYPT)) - return 0; - - return 1; -} -EXPORT_SYMBOL(hci_conn_check_link_mode); - /* Authenticate remote device */ int hci_conn_auth(struct hci_conn *conn) { BT_DBG("conn %p", conn); - if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { - if (!(conn->auth_type & 0x01)) { - conn->auth_type |= 0x01; - conn->link_mode &= ~HCI_LM_AUTH; - } - } - if (conn->link_mode & HCI_LM_AUTH) return 1; if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { struct hci_cp_auth_requested cp; cp.handle = cpu_to_le16(conn->handle); - hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); + hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); } return 0; } @@ -420,7 +379,7 @@ int hci_conn_encrypt(struct hci_conn *co BT_DBG("conn %p", conn); if (conn->link_mode & HCI_LM_ENCRYPT) - return hci_conn_auth(conn); + return 1; if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) return 0; @@ -429,8 +388,7 @@ int hci_conn_encrypt(struct hci_conn *co struct hci_cp_set_conn_encrypt cp; cp.handle = cpu_to_le16(conn->handle); cp.encrypt = 1; - hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, - sizeof(cp), &cp); + hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); } return 0; } @@ -444,8 +402,7 @@ int hci_conn_change_link_key(struct hci_ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { struct hci_cp_change_conn_link_key cp; cp.handle = cpu_to_le16(conn->handle); - hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, - sizeof(cp), &cp); + hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); } return 0; } @@ -547,8 +504,6 @@ void hci_conn_hash_flush(struct hci_dev c->state = BT_CLOSED; - hci_conn_del_sysfs(c); - hci_proto_disconn_ind(c, 0x16); hci_conn_del(c); } @@ -651,23 +606,3 @@ int hci_get_conn_info(struct hci_dev *hd return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; } - -int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) -{ - struct hci_auth_info_req req; - struct hci_conn *conn; - - if (copy_from_user(&req, arg, sizeof(req))) - return -EFAULT; - - hci_dev_lock_bh(hdev); - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); - if (conn) - req.type = conn->auth_type; - hci_dev_unlock_bh(hdev); - - if (!conn) - return -ENOENT; - - return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; -} diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hci_core.c linux-2.6.28-working/net/bluetooth/hci_core.c --- linux-source-2.6.28-pristine/net/bluetooth/hci_core.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hci_core.c 2009-02-15 01:42:26.000000000 +0000 @@ -24,7 +24,6 @@ /* Bluetooth HCI core. */ -#include #include #include @@ -164,9 +163,6 @@ static inline int hci_request(struct hci { int ret; - if (!test_bit(HCI_UP, &hdev->flags)) - return -ENETDOWN; - /* Serialize all requests */ hci_req_lock(hdev); ret = __hci_request(hdev, req, opt, timeout); @@ -282,20 +278,10 @@ static void hci_encrypt_req(struct hci_d BT_DBG("%s %x", hdev->name, encrypt); - /* Encryption */ + /* Authentication */ hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); } -static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt) -{ - __le16 policy = cpu_to_le16(opt); - - BT_DBG("%s %x", hdev->name, opt); - - /* Default link policy */ - hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy); -} - /* Get HCI device by index. * Device is held on return. */ struct hci_dev *hci_dev_get(int index) @@ -707,35 +693,32 @@ int hci_dev_cmd(unsigned int cmd, void _ msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; - case HCISETLINKPOL: - err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + case HCISETPTYPE: + hdev->pkt_type = (__u16) dr.dev_opt; break; - case HCISETLINKMODE: - hdev->link_mode = ((__u16) dr.dev_opt) & - (HCI_LM_MASTER | HCI_LM_ACCEPT); + case HCISETLINKPOL: + hdev->link_policy = (__u16) dr.dev_opt; break; - case HCISETPTYPE: - hdev->pkt_type = (__u16) dr.dev_opt; + case HCISETLINKMODE: + hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT); break; case HCISETACLMTU: - hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1); - hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0); + hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1); + hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0); break; case HCISETSCOMTU: - hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1); - hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0); + hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1); + hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0); break; default: err = -EINVAL; break; } - hci_dev_put(hdev); return err; } @@ -918,6 +901,8 @@ int hci_unregister_dev(struct hci_dev *h BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); + hci_unregister_sysfs(hdev); + write_lock_bh(&hci_dev_list_lock); list_del(&hdev->list); write_unlock_bh(&hci_dev_list_lock); @@ -929,8 +914,6 @@ int hci_unregister_dev(struct hci_dev *h hci_notify(hdev, HCI_DEV_UNREG); - hci_unregister_sysfs(hdev); - __hci_dev_put(hdev); return 0; @@ -1286,12 +1269,9 @@ static inline struct hci_conn *hci_low_s struct hci_conn *c; c = list_entry(p, struct hci_conn, list); - if (c->type != type || skb_queue_empty(&c->data_q)) + if (c->type != type || c->state != BT_CONNECTED + || skb_queue_empty(&c->data_q)) continue; - - if (c->state != BT_CONNECTED && c->state != BT_CONFIG) - continue; - num++; if (c->sent < min) { @@ -1341,7 +1321,7 @@ static inline void hci_sched_acl(struct if (!test_bit(HCI_RAW, &hdev->flags)) { /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ - if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) + if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) hci_acl_tx_to(hdev); } @@ -1563,7 +1543,7 @@ static void hci_cmd_task(unsigned long a BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); - if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) { + if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) { BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); } diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hci_event.c linux-2.6.28-working/net/bluetooth/hci_event.c --- linux-source-2.6.28-pristine/net/bluetooth/hci_event.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hci_event.c 2009-02-15 01:42:26.000000000 +0000 @@ -110,25 +110,6 @@ static void hci_cc_role_discovery(struct hci_dev_unlock(hdev); } -static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_rp_read_link_policy *rp = (void *) skb->data; - struct hci_conn *conn; - - BT_DBG("%s status 0x%x", hdev->name, rp->status); - - if (rp->status) - return; - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); - if (conn) - conn->link_policy = __le16_to_cpu(rp->policy); - - hci_dev_unlock(hdev); -} - static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_write_link_policy *rp = (void *) skb->data; @@ -147,41 +128,14 @@ static void hci_cc_write_link_policy(str hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); - if (conn) - conn->link_policy = get_unaligned_le16(sent + 2); + if (conn) { + __le16 policy = get_unaligned((__le16 *) (sent + 2)); + conn->link_policy = __le16_to_cpu(policy); + } hci_dev_unlock(hdev); } -static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_rp_read_def_link_policy *rp = (void *) skb->data; - - BT_DBG("%s status 0x%x", hdev->name, rp->status); - - if (rp->status) - return; - - hdev->link_policy = __le16_to_cpu(rp->policy); -} - -static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 status = *((__u8 *) skb->data); - void *sent; - - BT_DBG("%s status 0x%x", hdev->name, status); - - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); - if (!sent) - return; - - if (!status) - hdev->link_policy = get_unaligned_le16(sent); - - hci_req_complete(hdev, status); -} - static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -198,14 +152,12 @@ static void hci_cc_write_local_name(stru BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); if (!sent) return; - memcpy(hdev->dev_name, sent, 248); + if (!status) + memcpy(hdev->dev_name, sent, 248); } static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) @@ -315,14 +267,12 @@ static void hci_cc_write_class_of_dev(st BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); if (!sent) return; - memcpy(hdev->dev_class, sent, 3); + if (!status) + memcpy(hdev->dev_class, sent, 3); } static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) @@ -337,7 +287,7 @@ static void hci_cc_read_voice_setting(st setting = __le16_to_cpu(rp->voice_setting); - if (hdev->voice_setting == setting) + if (hdev->voice_setting == setting ) return; hdev->voice_setting = setting; @@ -354,31 +304,28 @@ static void hci_cc_read_voice_setting(st static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); - __u16 setting; void *sent; BT_DBG("%s status 0x%x", hdev->name, status); - if (status) - return; - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING); if (!sent) return; - setting = get_unaligned_le16(sent); - - if (hdev->voice_setting == setting) - return; + if (!status) { + __u16 setting = __le16_to_cpu(get_unaligned((__le16 *) sent)); - hdev->voice_setting = setting; + if (hdev->voice_setting != setting) { + hdev->voice_setting = setting; - BT_DBG("%s voice setting 0x%04x", hdev->name, setting); + BT_DBG("%s voice setting 0x%04x", hdev->name, setting); - if (hdev->notify) { - tasklet_disable(&hdev->tx_task); - hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); - tasklet_enable(&hdev->tx_task); + if (hdev->notify) { + tasklet_disable(&hdev->tx_task); + hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); + tasklet_enable(&hdev->tx_task); + } + } } } @@ -391,35 +338,6 @@ static void hci_cc_host_buffer_size(stru hci_req_complete(hdev, status); } -static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_rp_read_ssp_mode *rp = (void *) skb->data; - - BT_DBG("%s status 0x%x", hdev->name, rp->status); - - if (rp->status) - return; - - hdev->ssp_mode = rp->mode; -} - -static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 status = *((__u8 *) skb->data); - void *sent; - - BT_DBG("%s status 0x%x", hdev->name, status); - - if (status) - return; - - sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); - if (!sent) - return; - - hdev->ssp_mode = *((__u8 *) sent); -} - static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_read_local_version *rp = (void *) skb->data; @@ -430,8 +348,8 @@ static void hci_cc_read_local_version(st return; hdev->hci_ver = rp->hci_ver; - hdev->hci_rev = __le16_to_cpu(rp->hci_rev); - hdev->manufacturer = __le16_to_cpu(rp->manufacturer); + hdev->hci_rev = btohs(rp->hci_rev); + hdev->manufacturer = btohs(rp->manufacturer); BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, hdev->manufacturer, @@ -619,119 +537,11 @@ static void hci_cs_add_sco(struct hci_de hci_dev_unlock(hdev); } -static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) -{ - struct hci_cp_auth_requested *cp; - struct hci_conn *conn; - - BT_DBG("%s status 0x%x", hdev->name, status); - - if (!status) - return; - - cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED); - if (!cp) - return; - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { - if (conn->state == BT_CONFIG) { - hci_proto_connect_cfm(conn, status); - hci_conn_put(conn); - } - } - - hci_dev_unlock(hdev); -} - -static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) -{ - struct hci_cp_set_conn_encrypt *cp; - struct hci_conn *conn; - - BT_DBG("%s status 0x%x", hdev->name, status); - - if (!status) - return; - - cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT); - if (!cp) - return; - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { - if (conn->state == BT_CONFIG) { - hci_proto_connect_cfm(conn, status); - hci_conn_put(conn); - } - } - - hci_dev_unlock(hdev); -} - static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); } -static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) -{ - struct hci_cp_read_remote_features *cp; - struct hci_conn *conn; - - BT_DBG("%s status 0x%x", hdev->name, status); - - if (!status) - return; - - cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES); - if (!cp) - return; - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { - if (conn->state == BT_CONFIG) { - hci_proto_connect_cfm(conn, status); - hci_conn_put(conn); - } - } - - hci_dev_unlock(hdev); -} - -static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) -{ - struct hci_cp_read_remote_ext_features *cp; - struct hci_conn *conn; - - BT_DBG("%s status 0x%x", hdev->name, status); - - if (!status) - return; - - cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES); - if (!cp) - return; - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) { - if (conn->state == BT_CONFIG) { - hci_proto_connect_cfm(conn, status); - hci_conn_put(conn); - } - } - - hci_dev_unlock(hdev); -} - static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) { struct hci_cp_setup_sync_conn *cp; @@ -844,7 +654,6 @@ static inline void hci_inquiry_result_ev memcpy(data.dev_class, info->dev_class, 3); data.clock_offset = info->clock_offset; data.rssi = 0x00; - data.ssp_mode = 0x00; info++; hci_inquiry_cache_update(hdev, &data); } @@ -867,14 +676,7 @@ static inline void hci_conn_complete_evt if (!ev->status) { conn->handle = __le16_to_cpu(ev->handle); - - if (conn->type == ACL_LINK) { - conn->state = BT_CONFIG; - hci_conn_hold(conn); - } else - conn->state = BT_CONNECTED; - - hci_conn_add_sysfs(conn); + conn->state = BT_CONNECTED; if (test_bit(HCI_AUTH, &hdev->flags)) conn->link_mode |= HCI_LM_AUTH; @@ -886,17 +688,30 @@ static inline void hci_conn_complete_evt if (conn->type == ACL_LINK) { struct hci_cp_read_remote_features cp; cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, - sizeof(cp), &cp); + hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp); + } + + /* Set link policy */ + if (conn->type == ACL_LINK && hdev->link_policy) { + struct hci_cp_write_link_policy cp; + cp.handle = ev->handle; + cp.policy = cpu_to_le16(hdev->link_policy); + hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp); } /* Set packet type for incoming connection */ - if (!conn->out && hdev->hci_ver < 3) { + if (!conn->out) { struct hci_cp_change_conn_ptype cp; cp.handle = ev->handle; - cp.pkt_type = cpu_to_le16(conn->pkt_type); - hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, - sizeof(cp), &cp); + cp.pkt_type = (conn->type == ACL_LINK) ? + cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): + cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); + + hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp); + } else { + /* Update disconnect timer */ + hci_conn_hold(conn); + hci_conn_put(conn); } } else conn->state = BT_CLOSED; @@ -916,10 +731,9 @@ static inline void hci_conn_complete_evt } } - if (ev->status) { - hci_proto_connect_cfm(conn, ev->status); + hci_proto_connect_cfm(conn, ev->status); + if (ev->status) hci_conn_del(conn); - } unlock: hci_dev_unlock(hdev); @@ -939,14 +753,10 @@ static inline void hci_conn_request_evt( if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ - struct inquiry_entry *ie; struct hci_conn *conn; hci_dev_lock(hdev); - if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) - memcpy(ie->data.dev_class, ev->dev_class, 3); - conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { @@ -977,7 +787,7 @@ static inline void hci_conn_request_evt( struct hci_cp_accept_sync_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); - cp.pkt_type = cpu_to_le16(conn->pkt_type); + cp.pkt_type = cpu_to_le16(hdev->esco_type); cp.tx_bandwidth = cpu_to_le32(0x00001f40); cp.rx_bandwidth = cpu_to_le32(0x00001f40); @@ -1013,9 +823,6 @@ static inline void hci_disconn_complete_ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { conn->state = BT_CLOSED; - - hci_conn_del_sysfs(conn); - hci_proto_disconn_ind(conn, ev->reason); hci_conn_del(conn); } @@ -1039,29 +846,15 @@ static inline void hci_auth_complete_evt clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); - if (conn->state == BT_CONFIG) { - if (!ev->status && hdev->ssp_mode > 0 && - conn->ssp_mode > 0) { - struct hci_cp_set_conn_encrypt cp; - cp.handle = ev->handle; - cp.encrypt = 0x01; - hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, - sizeof(cp), &cp); - } else { - conn->state = BT_CONNECTED; - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } - } else - hci_auth_cfm(conn, ev->status); + hci_auth_cfm(conn, ev->status); if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { if (!ev->status) { struct hci_cp_set_conn_encrypt cp; - cp.handle = ev->handle; - cp.encrypt = 0x01; - hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, - sizeof(cp), &cp); + cp.handle = cpu_to_le16(conn->handle); + cp.encrypt = 1; + hci_send_cmd(conn->hdev, + HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); hci_encrypt_cfm(conn, ev->status, 0x00); @@ -1091,24 +884,15 @@ static inline void hci_encrypt_change_ev conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { if (!ev->status) { - if (ev->encrypt) { - /* Encryption implies authentication */ - conn->link_mode |= HCI_LM_AUTH; + if (ev->encrypt) conn->link_mode |= HCI_LM_ENCRYPT; - } else + else conn->link_mode &= ~HCI_LM_ENCRYPT; } clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); - if (conn->state == BT_CONFIG) { - if (!ev->status) - conn->state = BT_CONNECTED; - - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } else - hci_encrypt_cfm(conn, ev->status, ev->encrypt); + hci_encrypt_cfm(conn, ev->status, ev->encrypt); } hci_dev_unlock(hdev); @@ -1143,29 +927,14 @@ static inline void hci_remote_features_e BT_DBG("%s status %d", hdev->name, ev->status); + if (ev->status) + return; + hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (conn) { - if (!ev->status) - memcpy(conn->features, ev->features, 8); - - if (conn->state == BT_CONFIG) { - if (!ev->status && lmp_ssp_capable(hdev) && - lmp_ssp_capable(conn)) { - struct hci_cp_read_remote_ext_features cp; - cp.handle = ev->handle; - cp.page = 0x01; - hci_send_cmd(hdev, - HCI_OP_READ_REMOTE_EXT_FEATURES, - sizeof(cp), &cp); - } else { - conn->state = BT_CONNECTED; - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } - } - } + if (conn) + memcpy(conn->features, ev->features, 8); hci_dev_unlock(hdev); } @@ -1206,22 +975,10 @@ static inline void hci_cmd_complete_evt( hci_cc_role_discovery(hdev, skb); break; - case HCI_OP_READ_LINK_POLICY: - hci_cc_read_link_policy(hdev, skb); - break; - case HCI_OP_WRITE_LINK_POLICY: hci_cc_write_link_policy(hdev, skb); break; - case HCI_OP_READ_DEF_LINK_POLICY: - hci_cc_read_def_link_policy(hdev, skb); - break; - - case HCI_OP_WRITE_DEF_LINK_POLICY: - hci_cc_write_def_link_policy(hdev, skb); - break; - case HCI_OP_RESET: hci_cc_reset(hdev, skb); break; @@ -1266,14 +1023,6 @@ static inline void hci_cmd_complete_evt( hci_cc_host_buffer_size(hdev, skb); break; - case HCI_OP_READ_SSP_MODE: - hci_cc_read_ssp_mode(hdev, skb); - break; - - case HCI_OP_WRITE_SSP_MODE: - hci_cc_write_ssp_mode(hdev, skb); - break; - case HCI_OP_READ_LOCAL_VERSION: hci_cc_read_local_version(hdev, skb); break; @@ -1328,26 +1077,10 @@ static inline void hci_cmd_status_evt(st hci_cs_add_sco(hdev, ev->status); break; - case HCI_OP_AUTH_REQUESTED: - hci_cs_auth_requested(hdev, ev->status); - break; - - case HCI_OP_SET_CONN_ENCRYPT: - hci_cs_set_conn_encrypt(hdev, ev->status); - break; - case HCI_OP_REMOTE_NAME_REQ: hci_cs_remote_name_req(hdev, ev->status); break; - case HCI_OP_READ_REMOTE_FEATURES: - hci_cs_read_remote_features(hdev, ev->status); - break; - - case HCI_OP_READ_REMOTE_EXT_FEATURES: - hci_cs_read_remote_ext_features(hdev, ev->status); - break; - case HCI_OP_SETUP_SYNC_CONN: hci_cs_setup_sync_conn(hdev, ev->status); break; @@ -1419,8 +1152,8 @@ static inline void hci_num_comp_pkts_evt struct hci_conn *conn; __u16 handle, count; - handle = get_unaligned_le16(ptr++); - count = get_unaligned_le16(ptr++); + handle = __le16_to_cpu(get_unaligned(ptr++)); + count = __le16_to_cpu(get_unaligned(ptr++)); conn = hci_conn_hash_lookup_handle(hdev, handle); if (conn) { @@ -1503,22 +1236,6 @@ static inline void hci_clock_offset_evt( hci_dev_unlock(hdev); } -static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_pkt_type_change *ev = (void *) skb->data; - struct hci_conn *conn; - - BT_DBG("%s status %d", hdev->name, ev->status); - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (conn && !ev->status) - conn->pkt_type = __le16_to_cpu(ev->pkt_type); - - hci_dev_unlock(hdev); -} - static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; @@ -1559,7 +1276,6 @@ static inline void hci_inquiry_result_wi memcpy(data.dev_class, info->dev_class, 3); data.clock_offset = info->clock_offset; data.rssi = info->rssi; - data.ssp_mode = 0x00; info++; hci_inquiry_cache_update(hdev, &data); } @@ -1574,7 +1290,6 @@ static inline void hci_inquiry_result_wi memcpy(data.dev_class, info->dev_class, 3); data.clock_offset = info->clock_offset; data.rssi = info->rssi; - data.ssp_mode = 0x00; info++; hci_inquiry_cache_update(hdev, &data); } @@ -1585,40 +1300,7 @@ static inline void hci_inquiry_result_wi static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { - struct hci_ev_remote_ext_features *ev = (void *) skb->data; - struct hci_conn *conn; - BT_DBG("%s", hdev->name); - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (conn) { - if (!ev->status && ev->page == 0x01) { - struct inquiry_entry *ie; - - if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) - ie->data.ssp_mode = (ev->features[0] & 0x01); - - conn->ssp_mode = (ev->features[0] & 0x01); - } - - if (conn->state == BT_CONFIG) { - if (!ev->status && hdev->ssp_mode > 0 && - conn->ssp_mode > 0 && conn->out) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); - } else { - conn->state = BT_CONNECTED; - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } - } - } - - hci_dev_unlock(hdev); } static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) @@ -1631,22 +1313,12 @@ static inline void hci_sync_conn_complet hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); - if (!conn) { - if (ev->link_type == ESCO_LINK) - goto unlock; - - conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr); - if (!conn) - goto unlock; - - conn->type = SCO_LINK; - } + if (!conn) + goto unlock; if (!ev->status) { conn->handle = __le16_to_cpu(ev->handle); conn->state = BT_CONNECTED; - - hci_conn_add_sysfs(conn); } else conn->state = BT_CLOSED; @@ -1700,7 +1372,6 @@ static inline void hci_extended_inquiry_ memcpy(data.dev_class, info->dev_class, 3); data.clock_offset = info->clock_offset; data.rssi = info->rssi; - data.ssp_mode = 0x01; info++; hci_inquiry_cache_update(hdev, &data); } @@ -1708,53 +1379,6 @@ static inline void hci_extended_inquiry_ hci_dev_unlock(hdev); } -static inline 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_conn *conn; - - BT_DBG("%s", hdev->name); - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); - if (conn) - hci_conn_hold(conn); - - hci_dev_unlock(hdev); -} - -static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_simple_pair_complete *ev = (void *) skb->data; - struct hci_conn *conn; - - BT_DBG("%s", hdev->name); - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); - if (conn) - hci_conn_put(conn); - - hci_dev_unlock(hdev); -} - -static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_remote_host_features *ev = (void *) skb->data; - struct inquiry_entry *ie; - - BT_DBG("%s", hdev->name); - - hci_dev_lock(hdev); - - if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) - ie->data.ssp_mode = (ev->features[0] & 0x01); - - hci_dev_unlock(hdev); -} - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; @@ -1847,10 +1471,6 @@ void hci_event_packet(struct hci_dev *hd hci_clock_offset_evt(hdev, skb); break; - case HCI_EV_PKT_TYPE_CHANGE: - hci_pkt_type_change_evt(hdev, skb); - break; - case HCI_EV_PSCAN_REP_MODE: hci_pscan_rep_mode_evt(hdev, skb); break; @@ -1879,18 +1499,6 @@ void hci_event_packet(struct hci_dev *hd hci_extended_inquiry_result_evt(hdev, skb); break; - case HCI_EV_IO_CAPA_REQUEST: - hci_io_capa_request_evt(hdev, skb); - break; - - case HCI_EV_SIMPLE_PAIR_COMPLETE: - hci_simple_pair_complete_evt(hdev, skb); - break; - - case HCI_EV_REMOTE_HOST_FEATURES: - hci_remote_host_features_evt(hdev, skb); - break; - default: BT_DBG("%s event 0x%x", hdev->name, event); break; diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hci_sock.c linux-2.6.28-working/net/bluetooth/hci_sock.c --- linux-source-2.6.28-pristine/net/bluetooth/hci_sock.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hci_sock.c 2009-02-15 01:42:26.000000000 +0000 @@ -84,7 +84,7 @@ static struct hci_sec_filter hci_sec_fil }; static struct bt_sock_list hci_sk_list = { - .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; /* Send frame to RAW socket */ @@ -193,11 +193,19 @@ static inline int hci_sock_bound_ioctl(s return 0; - case HCIGETCONNINFO: - return hci_get_conn_info(hdev, (void __user *) arg); + case HCISETSECMGR: + if (!capable(CAP_NET_ADMIN)) + return -EACCES; - case HCIGETAUTHINFO: - return hci_get_auth_info(hdev, (void __user *) arg); + if (arg) + set_bit(HCI_SECMGR, &hdev->flags); + else + clear_bit(HCI_SECMGR, &hdev->flags); + + return 0; + + case HCIGETCONNINFO: + return hci_get_conn_info(hdev, (void __user *)arg); default: if (hdev->ioctl) @@ -209,7 +217,7 @@ static inline int hci_sock_bound_ioctl(s static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; - void __user *argp = (void __user *) arg; + void __user *argp = (void __user *)arg; int err; BT_DBG("cmd %x arg %lx", cmd, arg); @@ -432,7 +440,7 @@ static int hci_sock_sendmsg(struct kiocb skb->dev = (void *) hdev; if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { - u16 opcode = get_unaligned_le16(skb->data); + u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data)); u16 ogf = hci_opcode_ogf(opcode); u16 ocf = hci_opcode_ocf(opcode); @@ -726,7 +734,7 @@ error: return err; } -void __exit hci_sock_cleanup(void) +int __exit hci_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_HCI) < 0) BT_ERR("HCI socket unregistration failed"); @@ -734,4 +742,6 @@ void __exit hci_sock_cleanup(void) hci_unregister_notifier(&hci_sock_nblock); proto_unregister(&hci_sk_proto); + + return 0; } diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hci_sysfs.c linux-2.6.28-working/net/bluetooth/hci_sysfs.c --- linux-source-2.6.28-pristine/net/bluetooth/hci_sysfs.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hci_sysfs.c 2009-02-18 16:15:40.000000000 +0000 @@ -3,6 +3,8 @@ #include #include +#include + #include #include @@ -11,163 +13,7 @@ #define BT_DBG(D...) #endif -struct class *bt_class = NULL; -EXPORT_SYMBOL_GPL(bt_class); - -static struct workqueue_struct *btaddconn; -static struct workqueue_struct *btdelconn; - -static inline char *link_typetostr(int type) -{ - switch (type) { - case ACL_LINK: - return "ACL"; - case SCO_LINK: - return "SCO"; - case ESCO_LINK: - return "eSCO"; - default: - return "UNKNOWN"; - } -} - -static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct hci_conn *conn = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", link_typetostr(conn->type)); -} - -static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct hci_conn *conn = dev_get_drvdata(dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &conn->dst); - return sprintf(buf, "%s\n", batostr(&bdaddr)); -} - -static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct hci_conn *conn = dev_get_drvdata(dev); - - return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - conn->features[0], conn->features[1], - conn->features[2], conn->features[3], - conn->features[4], conn->features[5], - conn->features[6], conn->features[7]); -} - -#define LINK_ATTR(_name,_mode,_show,_store) \ -struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store) - -static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); -static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); -static LINK_ATTR(features, S_IRUGO, show_link_features, NULL); - -static struct attribute *bt_link_attrs[] = { - &link_attr_type.attr, - &link_attr_address.attr, - &link_attr_features.attr, - NULL -}; - -static struct attribute_group bt_link_group = { - .attrs = bt_link_attrs, -}; - -static struct attribute_group *bt_link_groups[] = { - &bt_link_group, - NULL -}; - -static void bt_link_release(struct device *dev) -{ - void *data = dev_get_drvdata(dev); - kfree(data); -} - -static struct device_type bt_link = { - .name = "link", - .groups = bt_link_groups, - .release = bt_link_release, -}; - -static void add_conn(struct work_struct *work) -{ - struct hci_conn *conn = container_of(work, struct hci_conn, work); - - flush_workqueue(btdelconn); - - if (device_add(&conn->dev) < 0) { - BT_ERR("Failed to register connection device"); - return; - } -} - -void hci_conn_add_sysfs(struct hci_conn *conn) -{ - struct hci_dev *hdev = conn->hdev; - - BT_DBG("conn %p", conn); - - conn->dev.type = &bt_link; - conn->dev.class = bt_class; - conn->dev.parent = &hdev->dev; - - snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d", - hdev->name, conn->handle); - - dev_set_drvdata(&conn->dev, conn); - - device_initialize(&conn->dev); - - INIT_WORK(&conn->work, add_conn); - - queue_work(btaddconn, &conn->work); -} - -/* - * The rfcomm tty device will possibly retain even when conn - * is down, and sysfs doesn't support move zombie device, - * so we should move the device before conn device is destroyed. - */ -static int __match_tty(struct device *dev, void *data) -{ - return !strncmp(dev->bus_id, "rfcomm", 6); -} - -static void del_conn(struct work_struct *work) -{ - struct hci_conn *conn = container_of(work, struct hci_conn, work); - struct hci_dev *hdev = conn->hdev; - - while (1) { - struct device *dev; - - dev = device_find_child(&conn->dev, NULL, __match_tty); - if (!dev) - break; - device_move(dev, NULL); - put_device(dev); - } - - device_del(&conn->dev); - put_device(&conn->dev); - hci_dev_put(hdev); -} - -void hci_conn_del_sysfs(struct hci_conn *conn) -{ - BT_DBG("conn %p", conn); - - if (!device_is_registered(&conn->dev)) - return; - - INIT_WORK(&conn->work, del_conn); - - queue_work(btdelconn, &conn->work); -} - -static inline char *host_typetostr(int type) +static inline char *typetostr(int type) { switch (type) { case HCI_VIRTUAL: @@ -192,7 +38,7 @@ static inline char *host_typetostr(int t 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", typetostr(hdev->type)); } static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -265,13 +111,11 @@ static ssize_t show_inquiry_cache(struct 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", + n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %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); + 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, e->timestamp); } hci_dev_unlock_bh(hdev); @@ -373,62 +217,166 @@ static DEVICE_ATTR(sniff_max_interval, S 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_type.attr, - &dev_attr_name.attr, - &dev_attr_class.attr, - &dev_attr_address.attr, - &dev_attr_features.attr, - &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, +static struct device_attribute *bt_attrs[] = { + &dev_attr_type, + &dev_attr_name, + &dev_attr_class, + &dev_attr_address, + &dev_attr_features, + &dev_attr_manufacturer, + &dev_attr_hci_version, + &dev_attr_hci_revision, + &dev_attr_inquiry_cache, + &dev_attr_idle_timeout, + &dev_attr_sniff_max_interval, + &dev_attr_sniff_min_interval, NULL }; -static struct attribute_group bt_host_group = { - .attrs = bt_host_attrs, -}; +static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct hci_conn *conn = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO"); +} -static struct attribute_group *bt_host_groups[] = { - &bt_host_group, +static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct hci_conn *conn = dev_get_drvdata(dev); + bdaddr_t bdaddr; + baswap(&bdaddr, &conn->dst); + return sprintf(buf, "%s\n", batostr(&bdaddr)); +} + +#define CONN_ATTR(_name,_mode,_show,_store) \ +struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store) + +static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL); +static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL); + +static struct device_attribute *conn_attrs[] = { + &conn_attr_type, + &conn_attr_address, NULL }; -static void bt_host_release(struct device *dev) +struct class *bt_class = NULL; +EXPORT_SYMBOL_GPL(bt_class); + +static struct bus_type bt_bus = { + .name = "bluetooth", +}; + +static struct platform_device *bt_platform; + +static void bt_release(struct device *dev) { void *data = dev_get_drvdata(dev); kfree(data); } -static struct device_type bt_host = { - .name = "host", - .groups = bt_host_groups, - .release = bt_host_release, -}; +static void add_conn(struct work_struct *work) +{ + struct hci_conn *conn = container_of(work, struct hci_conn, work); + int i; + + if (device_add(&conn->dev) < 0) { + BT_ERR("Failed to register connection device"); + return; + } + + for (i = 0; conn_attrs[i]; i++) + if (device_create_file(&conn->dev, conn_attrs[i]) < 0) + BT_ERR("Failed to create connection attribute"); +} + +void hci_conn_add_sysfs(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + bdaddr_t *ba = &conn->dst; + + BT_DBG("conn %p", conn); + + conn->dev.bus = &bt_bus; + conn->dev.parent = &hdev->dev; + + conn->dev.release = bt_release; + + snprintf(conn->dev.bus_id, BUS_ID_SIZE, + "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", + conn->type == ACL_LINK ? "acl" : "sco", + ba->b[5], ba->b[4], ba->b[3], + ba->b[2], ba->b[1], ba->b[0]); + + dev_set_drvdata(&conn->dev, conn); + + device_initialize(&conn->dev); + + INIT_WORK(&conn->work, add_conn); + + schedule_work(&conn->work); +} + +static int __match_tty(struct device *dev, void *data) +{ + /* The rfcomm tty device will possibly retain even when conn + * is down, and sysfs doesn't support move zombie device, + * so we should move the device before conn device is destroyed. + * Due to the only child device of hci_conn dev is rfcomm + * tty_dev, here just return 1 + */ + return 1; +} + +static void del_conn(struct work_struct *work) +{ + struct device *dev; + struct hci_conn *conn = container_of(work, struct hci_conn, work); + + while ((dev = device_find_child(&conn->dev, NULL, __match_tty))) { + device_move(dev, NULL); + put_device(dev); + } + device_del(&conn->dev); + put_device(&conn->dev); +} + +void hci_conn_del_sysfs(struct hci_conn *conn) +{ + BT_DBG("conn %p", conn); + + if (!device_is_registered(&conn->dev)) + return; + + INIT_WORK(&conn->work, del_conn); + + schedule_work(&conn->work); +} int hci_register_sysfs(struct hci_dev *hdev) { struct device *dev = &hdev->dev; + unsigned int i; int err; BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); - dev->type = &bt_host; - dev->class = bt_class; + dev->bus = &bt_bus; dev->parent = hdev->parent; strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); + dev->release = bt_release; + dev_set_drvdata(dev, hdev); err = device_register(dev); if (err < 0) return err; + for (i = 0; bt_attrs[i]; i++) + if (device_create_file(dev, bt_attrs[i]) < 0) + BT_ERR("Failed to create device attribute"); + return 0; } @@ -441,20 +389,22 @@ void hci_unregister_sysfs(struct hci_dev int __init bt_sysfs_init(void) { - btaddconn = create_singlethread_workqueue("btaddconn"); - if (!btaddconn) - return -ENOMEM; - - btdelconn = create_singlethread_workqueue("btdelconn"); - if (!btdelconn) { - destroy_workqueue(btaddconn); - return -ENOMEM; + int err; + + bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); + if (IS_ERR(bt_platform)) + return PTR_ERR(bt_platform); + + err = bus_register(&bt_bus); + if (err < 0) { + platform_device_unregister(bt_platform); + return err; } bt_class = class_create(THIS_MODULE, "bluetooth"); if (IS_ERR(bt_class)) { - destroy_workqueue(btdelconn); - destroy_workqueue(btaddconn); + bus_unregister(&bt_bus); + platform_device_unregister(bt_platform); return PTR_ERR(bt_class); } @@ -463,8 +413,9 @@ int __init bt_sysfs_init(void) void bt_sysfs_cleanup(void) { - destroy_workqueue(btaddconn); - destroy_workqueue(btdelconn); - class_destroy(bt_class); + + bus_unregister(&bt_bus); + + platform_device_unregister(bt_platform); } diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hidp/core.c linux-2.6.28-working/net/bluetooth/hidp/core.c --- linux-source-2.6.28-pristine/net/bluetooth/hidp/core.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hidp/core.c 2009-02-18 16:30:31.000000000 +0000 @@ -135,8 +135,8 @@ static void __hidp_copy_session(struct h } } -static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, - unsigned int type, unsigned int code, int value) +static inline int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, + unsigned int type, unsigned int code, int value) { unsigned char newleds; struct sk_buff *skb; @@ -243,8 +243,7 @@ static void hidp_input_report(struct hid input_sync(dev); } -static int hidp_queue_report(struct hidp_session *session, - unsigned char *data, int size) +static inline int hidp_queue_report(struct hidp_session *session, unsigned char *data, int size) { struct sk_buff *skb; @@ -288,7 +287,7 @@ static void hidp_idle_timeout(unsigned l hidp_schedule(session); } -static void hidp_set_timer(struct hidp_session *session) +static inline void hidp_set_timer(struct hidp_session *session) { if (session->idle_to > 0) mod_timer(&session->timer, jiffies + HZ * session->idle_to); @@ -333,8 +332,7 @@ static inline int hidp_send_ctrl_message return err; } -static void hidp_process_handshake(struct hidp_session *session, - unsigned char param) +static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param) { BT_DBG("session %p param 0x%02x", session, param); @@ -367,23 +365,38 @@ static void hidp_process_handshake(struc } } -static void hidp_process_hid_control(struct hidp_session *session, - unsigned char param) +static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param) { BT_DBG("session %p param 0x%02x", session, param); - if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) { + switch (param) { + case HIDP_CTRL_NOP: + break; + + case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG: /* Flush the transmit queues */ skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); /* Kill session thread */ atomic_inc(&session->terminate); + break; + + case HIDP_CTRL_HARD_RESET: + case HIDP_CTRL_SOFT_RESET: + case HIDP_CTRL_SUSPEND: + case HIDP_CTRL_EXIT_SUSPEND: + /* FIXME: We have to parse these and return no error */ + break; + + default: + __hidp_send_ctrl_message(session, + HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); + break; } } -static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, - unsigned char param) +static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param) { BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); @@ -410,8 +423,7 @@ static void hidp_process_data(struct hid } } -static void hidp_recv_ctrl_frame(struct hidp_session *session, - struct sk_buff *skb) +static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb) { unsigned char hdr, type, param; @@ -445,8 +457,7 @@ static void hidp_recv_ctrl_frame(struct kfree_skb(skb); } -static void hidp_recv_intr_frame(struct hidp_session *session, - struct sk_buff *skb) +static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb) { unsigned char hdr; @@ -578,15 +589,9 @@ static int hidp_session(void *arg) if (session->hid) { if (session->hid->claimed & HID_CLAIMED_INPUT) hidinput_disconnect(session->hid); - hid_destroy_device(session->hid); + hid_free_device(session->hid); } - /* Wakeup user-space polling for socket errors */ - session->intr_sock->sk->sk_err = EUNATCH; - session->ctrl_sock->sk->sk_err = EUNATCH; - - hidp_schedule(session); - fput(session->intr_sock->file); wait_event_timeout(*(ctrl_sk->sk_sleep), @@ -620,18 +625,11 @@ static struct device *hidp_get_device(st return conn ? &conn->dev : NULL; } -static int hidp_setup_input(struct hidp_session *session, - struct hidp_connadd_req *req) +static inline int hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) { - struct input_dev *input; + struct input_dev *input = session->input; int i; - input = input_allocate_device(); - if (!input) - return -ENOMEM; - - session->input = input; - input_set_drvdata(input, session); input->name = "Bluetooth HID Boot Protocol Device"; @@ -683,114 +681,66 @@ static void hidp_close(struct hid_device { } -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; -} - -static int hidp_start(struct hid_device *hid) -{ - struct hidp_session *session = hid->driver_data; - struct hid_report *report; +static const struct { + __u16 idVendor; + __u16 idProduct; + unsigned quirks; +} hidp_blacklist[] = { + /* Apple wireless Mighty Mouse */ + { 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT]. - report_list, list) - hidp_send_report(session, report); - - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT]. - report_list, list) - hidp_send_report(session, report); - - return 0; -} + { } /* Terminating entry */ +}; -static void hidp_stop(struct hid_device *hid) +static void hidp_setup_quirks(struct hid_device *hid) { - struct hidp_session *session = hid->driver_data; - - skb_queue_purge(&session->ctrl_transmit); - skb_queue_purge(&session->intr_transmit); + unsigned int n; - if (hid->claimed & HID_CLAIMED_INPUT) - hidinput_disconnect(hid); - hid->claimed = 0; + for (n = 0; hidp_blacklist[n].idVendor; n++) + if (hidp_blacklist[n].idVendor == le16_to_cpu(hid->vendor) && + hidp_blacklist[n].idProduct == le16_to_cpu(hid->product)) + hid->quirks = hidp_blacklist[n].quirks; } -static struct hid_ll_driver hidp_hid_driver = { - .parse = hidp_parse, - .start = hidp_start, - .stop = hidp_stop, - .open = hidp_open, - .close = hidp_close, - .hidinput_input_event = hidp_hidinput_event, -}; - -static int hidp_setup_hid(struct hidp_session *session, - struct hidp_connadd_req *req) +static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) { - struct hid_device *hid; + struct hid_device *hid = session->hid; + struct hid_report *report; bdaddr_t src, dst; - int ret; - hid = hid_allocate_device(); - if (IS_ERR(hid)) { - ret = PTR_ERR(session->hid); - goto err; - } + baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); + baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); - session->hid = hid; - session->req = req; hid->driver_data = session; - baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); - baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); + hid->country = req->country; hid->bus = BUS_BLUETOOTH; hid->vendor = req->vendor; hid->product = req->product; hid->version = req->version; - hid->country = req->country; strncpy(hid->name, req->name, 128); strncpy(hid->phys, batostr(&src), 64); strncpy(hid->uniq, batostr(&dst), 64); - hid->dev.parent = hidp_get_device(session); - hid->ll_driver = &hidp_hid_driver; + hid->dev = hidp_get_device(session); - ret = hid_add_device(hid); - if (ret) - goto err_hid; + hid->hid_open = hidp_open; + hid->hid_close = hidp_close; - return 0; -err_hid: - hid_destroy_device(hid); - session->hid = NULL; -err: - return ret; + hid->hidinput_input_event = hidp_hidinput_event; + + hidp_setup_quirks(hid); + + list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) + hidp_send_report(session, report); + + list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) + hidp_send_report(session, report); + + if (hidinput_connect(hid) == 0) + hid->claimed |= HID_CLAIMED_INPUT; } int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) @@ -810,6 +760,38 @@ int hidp_add_connection(struct hidp_conn BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); + if (req->rd_size > 0) { + unsigned char *buf = kmalloc(req->rd_size, GFP_KERNEL); + + if (!buf) { + kfree(session); + return -ENOMEM; + } + + if (copy_from_user(buf, req->rd_data, req->rd_size)) { + kfree(buf); + kfree(session); + return -EFAULT; + } + + session->hid = hid_parse_report(buf, req->rd_size); + + kfree(buf); + + if (!session->hid) { + kfree(session); + return -EINVAL; + } + } + + if (!session->hid) { + session->input = input_allocate_device(); + if (!session->input) { + kfree(session); + return -ENOMEM; + } + } + down_write(&hidp_session_sem); s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); @@ -829,7 +811,10 @@ int hidp_add_connection(struct hidp_conn session->intr_sock = intr_sock; session->state = BT_CONNECTED; - setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session); + init_timer(&session->timer); + + session->timer.function = hidp_idle_timeout; + session->timer.data = (unsigned long) session; skb_queue_head_init(&session->ctrl_transmit); skb_queue_head_init(&session->intr_transmit); @@ -837,18 +822,15 @@ int hidp_add_connection(struct hidp_conn session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); session->idle_to = req->idle_to; - if (req->rd_size > 0) { - err = hidp_setup_hid(session, req); - if (err && err != -ENODEV) - goto err_skb; - } - - if (!session->hid) { + if (session->input) { err = hidp_setup_input(session, req); if (err < 0) - goto err_skb; + goto failed; } + if (session->hid) + hidp_setup_hid(session, req); + __hidp_link_session(session); hidp_set_timer(session); @@ -874,16 +856,17 @@ unlink: __hidp_unlink_session(session); - if (session->input) + if (session->input) { input_unregister_device(session->input); - if (session->hid) - hid_destroy_device(session->hid); -err_skb: - skb_queue_purge(&session->ctrl_transmit); - skb_queue_purge(&session->intr_transmit); + session->input = NULL; /* don't try to free it here */ + } + failed: up_write(&hidp_session_sem); + if (session->hid) + hid_free_device(session->hid); + input_free_device(session->input); kfree(session); return err; @@ -908,10 +891,6 @@ int hidp_del_connection(struct hidp_conn skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); - /* Wakeup user-space polling for socket errors */ - session->intr_sock->sk->sk_err = EUNATCH; - session->ctrl_sock->sk->sk_err = EUNATCH; - /* Kill session thread */ atomic_inc(&session->terminate); hidp_schedule(session); @@ -973,43 +952,18 @@ int hidp_get_conninfo(struct hidp_connin return err; } -static const struct hid_device_id hidp_table[] = { - { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) }, - { } -}; - -static struct hid_driver hidp_driver = { - .name = "generic-bluetooth", - .id_table = hidp_table, -}; - static int __init hidp_init(void) { - int ret; - l2cap_load(); BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); - ret = hid_register_driver(&hidp_driver); - if (ret) - goto err; - - ret = hidp_init_sockets(); - if (ret) - goto err_drv; - - return 0; -err_drv: - hid_unregister_driver(&hidp_driver); -err: - return ret; + return hidp_init_sockets(); } static void __exit hidp_exit(void) { hidp_cleanup_sockets(); - hid_unregister_driver(&hidp_driver); } module_init(hidp_init); diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hidp/hidp.h linux-2.6.28-working/net/bluetooth/hidp/hidp.h --- linux-source-2.6.28-pristine/net/bluetooth/hidp/hidp.h 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hidp/hidp.h 2009-02-15 01:42:27.000000000 +0000 @@ -151,8 +151,6 @@ struct hidp_session { struct sk_buff_head ctrl_transmit; struct sk_buff_head intr_transmit; - - struct hidp_connadd_req *req; }; static inline void hidp_schedule(struct hidp_session *session) diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hidp/Makefile linux-2.6.28-working/net/bluetooth/hidp/Makefile --- linux-source-2.6.28-pristine/net/bluetooth/hidp/Makefile 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hidp/Makefile 2009-02-18 16:30:49.000000000 +0000 @@ -2,6 +2,6 @@ # Makefile for the Linux Bluetooth HIDP layer # -obj-$(CONFIG_BT_HIDP) += hidp.o +#obj-$(CONFIG_BT_HIDP) += hidp.o hidp-objs := core.o sock.o diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hidp/modules.order linux-2.6.28-working/net/bluetooth/hidp/modules.order --- linux-source-2.6.28-pristine/net/bluetooth/hidp/modules.order 2009-02-11 15:27:02.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hidp/modules.order 2009-02-21 21:59:37.000000000 +0000 @@ -1 +0,0 @@ -kernel/net/bluetooth/hidp/hidp.ko diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/hidp/sock.c linux-2.6.28-working/net/bluetooth/hidp/sock.c --- linux-source-2.6.28-pristine/net/bluetooth/hidp/sock.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/hidp/sock.c 2009-02-15 01:42:27.000000000 +0000 @@ -86,13 +86,13 @@ static int hidp_sock_ioctl(struct socket isock = sockfd_lookup(ca.intr_sock, &err); if (!isock) { - sockfd_put(csock); + fput(csock->file); return err; } if (csock->sk->sk_state != BT_CONNECTED || isock->sk->sk_state != BT_CONNECTED) { - sockfd_put(csock); - sockfd_put(isock); + fput(csock->file); + fput(isock->file); return -EBADFD; } @@ -101,8 +101,8 @@ static int hidp_sock_ioctl(struct socket if (copy_to_user(argp, &ca, sizeof(ca))) err = -EFAULT; } else { - sockfd_put(csock); - sockfd_put(isock); + fput(csock->file); + fput(isock->file); } return err; diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/l2cap.c linux-2.6.28-working/net/bluetooth/l2cap.c --- linux-source-2.6.28-pristine/net/bluetooth/l2cap.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/l2cap.c 2009-02-18 16:20:04.000000000 +0000 @@ -55,14 +55,14 @@ #define BT_DBG(D...) #endif -#define VERSION "2.11" +#define VERSION "2.9" static u32 l2cap_feat_mask = 0x0000; static const struct proto_ops l2cap_sock_ops; static struct bt_sock_list l2cap_sk_list = { - .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void __l2cap_sock_close(struct sock *sk, int reason); @@ -76,21 +76,11 @@ static struct sk_buff *l2cap_build_cmd(s static void l2cap_sock_timeout(unsigned long arg) { struct sock *sk = (struct sock *) arg; - int reason; BT_DBG("sock %p state %d", sk, sk->sk_state); bh_lock_sock(sk); - - if (sk->sk_state == BT_CONNECT && - (l2cap_pi(sk)->link_mode & (L2CAP_LM_AUTH | - L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE))) - reason = ECONNREFUSED; - else - reason = ETIMEDOUT; - - __l2cap_sock_close(sk, reason); - + __l2cap_sock_close(sk, ETIMEDOUT); bh_unlock_sock(sk); l2cap_sock_kill(sk); @@ -109,6 +99,13 @@ static void l2cap_sock_clear_timer(struc sk_stop_timer(sk, &sk->sk_timer); } +static void l2cap_sock_init_timer(struct sock *sk) +{ + init_timer(&sk->sk_timer); + sk->sk_timer.function = l2cap_sock_timeout; + sk->sk_timer.data = (unsigned long)sk; +} + /* ---- L2CAP channels ---- */ static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) { @@ -250,7 +247,7 @@ static void l2cap_chan_del(struct sock * hci_conn_put(conn->hcon); } - sk->sk_state = BT_CLOSED; + sk->sk_state = BT_CLOSED; sock_set_flag(sk, SOCK_ZAPPED); if (err) @@ -263,21 +260,6 @@ static void l2cap_chan_del(struct sock * sk->sk_state_change(sk); } -/* Service level security */ -static inline int l2cap_check_link_mode(struct sock *sk) -{ - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - - if ((l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || - (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) - return hci_conn_encrypt(conn->hcon); - - if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) - return hci_conn_auth(conn->hcon); - - return 1; -} - static inline u8 l2cap_get_ident(struct l2cap_conn *conn) { u8 id; @@ -312,36 +294,6 @@ static inline int l2cap_send_cmd(struct return hci_send_acl(conn->hcon, skb, 0); } -static void l2cap_do_start(struct sock *sk) -{ - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - - if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { - if (l2cap_check_link_mode(sk)) { - struct l2cap_conn_req req; - req.scid = cpu_to_le16(l2cap_pi(sk)->scid); - req.psm = l2cap_pi(sk)->psm; - - l2cap_pi(sk)->ident = l2cap_get_ident(conn); - - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); - } - } else { - struct l2cap_info_req req; - req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); - - conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; - conn->info_ident = l2cap_get_ident(conn); - - mod_timer(&conn->info_timer, jiffies + - msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); - - l2cap_send_cmd(conn, conn->info_ident, - L2CAP_INFO_REQ, sizeof(req), &req); - } -} - /* ---- L2CAP connections ---- */ static void l2cap_conn_start(struct l2cap_conn *conn) { @@ -356,37 +308,16 @@ static void l2cap_conn_start(struct l2ca bh_lock_sock(sk); if (sk->sk_type != SOCK_SEQPACKET) { - bh_unlock_sock(sk); - continue; - } - - if (sk->sk_state == BT_CONNECT) { - if (l2cap_check_link_mode(sk)) { - struct l2cap_conn_req req; - req.scid = cpu_to_le16(l2cap_pi(sk)->scid); - req.psm = l2cap_pi(sk)->psm; - - l2cap_pi(sk)->ident = l2cap_get_ident(conn); - - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); - } - } else if (sk->sk_state == BT_CONNECT2) { - struct l2cap_conn_rsp rsp; - rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); - rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); - - if (l2cap_check_link_mode(sk)) { - sk->sk_state = BT_CONFIG; - rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - } else { - rsp.result = cpu_to_le16(L2CAP_CR_PEND); - rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); - } - + l2cap_sock_clear_timer(sk); + sk->sk_state = BT_CONNECTED; + sk->sk_state_change(sk); + } else if (sk->sk_state == BT_CONNECT) { + struct l2cap_conn_req req; + l2cap_pi(sk)->ident = l2cap_get_ident(conn); + req.scid = cpu_to_le16(l2cap_pi(sk)->scid); + req.psm = l2cap_pi(sk)->psm; l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); + L2CAP_CONN_REQ, sizeof(req), &req); } bh_unlock_sock(sk); @@ -397,27 +328,22 @@ static void l2cap_conn_start(struct l2ca static void l2cap_conn_ready(struct l2cap_conn *conn) { - struct l2cap_chan_list *l = &conn->chan_list; - struct sock *sk; - BT_DBG("conn %p", conn); - read_lock(&l->lock); + if (conn->chan_list.head || !hlist_empty(&l2cap_sk_list.head)) { + struct l2cap_info_req req; - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { - bh_lock_sock(sk); + req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); - if (sk->sk_type != SOCK_SEQPACKET) { - l2cap_sock_clear_timer(sk); - sk->sk_state = BT_CONNECTED; - sk->sk_state_change(sk); - } else if (sk->sk_state == BT_CONNECT) - l2cap_do_start(sk); + conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; + conn->info_ident = l2cap_get_ident(conn); - bh_unlock_sock(sk); - } + mod_timer(&conn->info_timer, + jiffies + msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); - read_unlock(&l->lock); + l2cap_send_cmd(conn, conn->info_ident, + L2CAP_INFO_REQ, sizeof(req), &req); + } } /* Notify sockets that we cannot guaranty reliability anymore */ @@ -469,8 +395,9 @@ static struct l2cap_conn *l2cap_conn_add conn->feat_mask = 0; - setup_timer(&conn->info_timer, l2cap_info_timeout, - (unsigned long) conn); + init_timer(&conn->info_timer); + conn->info_timer.function = l2cap_info_timeout; + conn->info_timer.data = (unsigned long) conn; spin_lock_init(&conn->lock); rwlock_init(&conn->chan_list.lock); @@ -499,9 +426,6 @@ static void l2cap_conn_del(struct hci_co l2cap_sock_kill(sk); } - if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) - del_timer_sync(&conn->info_timer); - hcon->l2cap_data = NULL; kfree(conn); } @@ -582,7 +506,7 @@ static void l2cap_sock_cleanup_listen(st while ((sk = bt_accept_dequeue(parent, NULL))) l2cap_sock_close(sk); - parent->sk_state = BT_CLOSED; + parent->sk_state = BT_CLOSED; sock_set_flag(parent, SOCK_ZAPPED); } @@ -625,8 +549,9 @@ static void __l2cap_sock_close(struct so req.scid = cpu_to_le16(l2cap_pi(sk)->scid); l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, sizeof(req), &req); - } else + } else { l2cap_chan_del(sk, reason); + } break; case BT_CONNECT: @@ -695,9 +620,9 @@ static struct sock *l2cap_sock_alloc(str sock_reset_flag(sk, SOCK_ZAPPED); sk->sk_protocol = proto; - sk->sk_state = BT_OPEN; + sk->sk_state = BT_OPEN; - setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); + l2cap_sock_init_timer(sk); bt_sock_link(&l2cap_sk_list, sk); return sk; @@ -778,7 +703,6 @@ static int l2cap_do_connect(struct sock struct l2cap_conn *conn; struct hci_conn *hcon; struct hci_dev *hdev; - __u8 auth_type; int err = 0; BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); @@ -790,21 +714,7 @@ static int l2cap_do_connect(struct sock err = -ENOMEM; - if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH || - l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT || - l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { - if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) - auth_type = HCI_AT_NO_BONDING_MITM; - else - auth_type = HCI_AT_GENERAL_BONDING_MITM; - } else { - if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) - auth_type = HCI_AT_NO_BONDING; - else - auth_type = HCI_AT_GENERAL_BONDING; - } - - hcon = hci_connect(hdev, ACL_LINK, dst, auth_type); + hcon = hci_connect(hdev, ACL_LINK, dst); if (!hcon) goto done; @@ -825,11 +735,22 @@ static int l2cap_do_connect(struct sock l2cap_sock_set_timer(sk, sk->sk_sndtimeo); if (hcon->state == BT_CONNECTED) { - if (sk->sk_type != SOCK_SEQPACKET) { + if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { + l2cap_conn_ready(conn); + goto done; + } + + if (sk->sk_type == SOCK_SEQPACKET) { + struct l2cap_conn_req req; + l2cap_pi(sk)->ident = l2cap_get_ident(conn); + req.scid = cpu_to_le16(l2cap_pi(sk)->scid); + req.psm = l2cap_pi(sk)->psm; + l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + L2CAP_CONN_REQ, sizeof(req), &req); + } else { l2cap_sock_clear_timer(sk); sk->sk_state = BT_CONNECTED; - } else - l2cap_do_start(sk); + } } done: @@ -1230,8 +1151,7 @@ static int l2cap_sock_shutdown(struct so __l2cap_sock_close(sk, 0); if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) - err = bt_sock_wait_state(sk, BT_CLOSED, - sk->sk_lingertime); + err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); } release_sock(sk); return err; @@ -1275,11 +1195,6 @@ static void l2cap_chan_ready(struct sock */ parent->sk_data_ready(parent, 0); } - - if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - hci_conn_change_link_key(conn->hcon); - } } /* Copy frame to all raw sockets on that connection */ @@ -1568,10 +1483,10 @@ static inline int l2cap_connect_req(stru struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; struct sock *sk, *parent; - int result, status = L2CAP_CS_NO_INFO; + int result = 0, status = 0; u16 dcid = 0, scid = __le16_to_cpu(req->scid); - __le16 psm = req->psm; + __le16 psm = req->psm; BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); @@ -1582,13 +1497,6 @@ static inline int l2cap_connect_req(stru goto sendresp; } - /* Check if the ACL is secure enough (if not SDP) */ - if (psm != cpu_to_le16(0x0001) && - !hci_conn_check_link_mode(conn->hcon)) { - result = L2CAP_CR_SEC_BLOCK; - goto response; - } - result = L2CAP_CR_NO_MEM; /* Check for backlog size */ @@ -1624,24 +1532,25 @@ static inline int l2cap_connect_req(stru l2cap_sock_set_timer(sk, sk->sk_sndtimeo); + /* Service level security */ + result = L2CAP_CR_PEND; + status = L2CAP_CS_AUTHEN_PEND; + sk->sk_state = BT_CONNECT2; l2cap_pi(sk)->ident = cmd->ident; - if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { - if (l2cap_check_link_mode(sk)) { - sk->sk_state = BT_CONFIG; - result = L2CAP_CR_SUCCESS; - status = L2CAP_CS_NO_INFO; - } else { - sk->sk_state = BT_CONNECT2; - result = L2CAP_CR_PEND; - status = L2CAP_CS_AUTHEN_PEND; - } - } else { - sk->sk_state = BT_CONNECT2; - result = L2CAP_CR_PEND; - status = L2CAP_CS_NO_INFO; + if ((l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || + (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) { + if (!hci_conn_encrypt(conn->hcon)) + goto done; + } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) { + if (!hci_conn_auth(conn->hcon)) + goto done; } + sk->sk_state = BT_CONFIG; + result = status = 0; + +done: write_unlock_bh(&list->lock); response: @@ -1653,21 +1562,6 @@ sendresp: rsp.result = cpu_to_le16(result); rsp.status = cpu_to_le16(status); l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - - if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { - struct l2cap_info_req info; - info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); - - conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; - conn->info_ident = l2cap_get_ident(conn); - - mod_timer(&conn->info_timer, jiffies + - msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); - - l2cap_send_cmd(conn, conn->info_ident, - L2CAP_INFO_REQ, sizeof(info), &info); - } - return 0; } @@ -1776,9 +1670,9 @@ static inline int l2cap_config_req(struc } if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { - u8 buf[64]; + u8 req[64]; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, - l2cap_build_conf_req(sk, buf), buf); + l2cap_build_conf_req(sk, req), req); } unlock: @@ -1820,7 +1714,7 @@ static inline int l2cap_config_rsp(struc default: sk->sk_state = BT_DISCONN; - sk->sk_err = ECONNRESET; + sk->sk_err = ECONNRESET; l2cap_sock_set_timer(sk, HZ * 5); { struct l2cap_disconn_req req; @@ -1939,7 +1833,7 @@ static inline int l2cap_information_rsp( del_timer(&conn->info_timer); if (type == L2CAP_IT_FEAT_MASK) - conn->feat_mask = get_unaligned_le32(rsp->data); + conn->feat_mask = __le32_to_cpu(get_unaligned((__le32 *) rsp->data)); l2cap_conn_start(conn); @@ -2192,8 +2086,10 @@ static int l2cap_disconn_ind(struct hci_ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_chan_list *l; - struct l2cap_conn *conn = hcon->l2cap_data; + struct l2cap_conn *conn = conn = hcon->l2cap_data; + struct l2cap_conn_rsp rsp; struct sock *sk; + int result; if (!conn) return 0; @@ -2205,65 +2101,45 @@ static int l2cap_auth_cfm(struct hci_con read_lock(&l->lock); for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { - struct l2cap_pinfo *pi = l2cap_pi(sk); - bh_lock_sock(sk); - if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && - !(hcon->link_mode & HCI_LM_ENCRYPT) && - !status) { + if (sk->sk_state != BT_CONNECT2 || + (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || + (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) { bh_unlock_sock(sk); continue; } - if (sk->sk_state == BT_CONNECT) { - if (!status) { - struct l2cap_conn_req req; - req.scid = cpu_to_le16(l2cap_pi(sk)->scid); - req.psm = l2cap_pi(sk)->psm; - - l2cap_pi(sk)->ident = l2cap_get_ident(conn); - - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); - } else { - l2cap_sock_clear_timer(sk); - l2cap_sock_set_timer(sk, HZ / 10); - } - } else if (sk->sk_state == BT_CONNECT2) { - struct l2cap_conn_rsp rsp; - __u16 result; - - if (!status) { - sk->sk_state = BT_CONFIG; - result = L2CAP_CR_SUCCESS; - } else { - sk->sk_state = BT_DISCONN; - l2cap_sock_set_timer(sk, HZ / 10); - result = L2CAP_CR_SEC_BLOCK; - } - - rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); - rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); - rsp.result = cpu_to_le16(result); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); + if (!status) { + sk->sk_state = BT_CONFIG; + result = 0; + } else { + sk->sk_state = BT_DISCONN; + l2cap_sock_set_timer(sk, HZ/10); + result = L2CAP_CR_SEC_BLOCK; } + rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); + rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); + rsp.result = cpu_to_le16(result); + rsp.status = cpu_to_le16(0); + l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + L2CAP_CONN_RSP, sizeof(rsp), &rsp); + bh_unlock_sock(sk); } read_unlock(&l->lock); - return 0; } -static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) +static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status) { struct l2cap_chan_list *l; struct l2cap_conn *conn = hcon->l2cap_data; + struct l2cap_conn_rsp rsp; struct sock *sk; + int result; if (!conn) return 0; @@ -2275,59 +2151,36 @@ static int l2cap_encrypt_cfm(struct hci_ read_lock(&l->lock); for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { - struct l2cap_pinfo *pi = l2cap_pi(sk); - bh_lock_sock(sk); - if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && - (sk->sk_state == BT_CONNECTED || - sk->sk_state == BT_CONFIG) && - !status && encrypt == 0x00) { - __l2cap_sock_close(sk, ECONNREFUSED); + if (sk->sk_state != BT_CONNECT2) { bh_unlock_sock(sk); continue; } - if (sk->sk_state == BT_CONNECT) { - if (!status) { - struct l2cap_conn_req req; - req.scid = cpu_to_le16(l2cap_pi(sk)->scid); - req.psm = l2cap_pi(sk)->psm; - - l2cap_pi(sk)->ident = l2cap_get_ident(conn); + if (!status) { + sk->sk_state = BT_CONFIG; + result = 0; + } else { + sk->sk_state = BT_DISCONN; + l2cap_sock_set_timer(sk, HZ/10); + result = L2CAP_CR_SEC_BLOCK; + } - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_REQ, sizeof(req), &req); - } else { - l2cap_sock_clear_timer(sk); - l2cap_sock_set_timer(sk, HZ / 10); - } - } else if (sk->sk_state == BT_CONNECT2) { - struct l2cap_conn_rsp rsp; - __u16 result; - - if (!status) { - sk->sk_state = BT_CONFIG; - result = L2CAP_CR_SUCCESS; - } else { - sk->sk_state = BT_DISCONN; - l2cap_sock_set_timer(sk, HZ / 10); - result = L2CAP_CR_SEC_BLOCK; - } + rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); + rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); + rsp.result = cpu_to_le16(result); + rsp.status = cpu_to_le16(0); + l2cap_send_cmd(conn, l2cap_pi(sk)->ident, + L2CAP_CONN_RSP, sizeof(rsp), &rsp); - rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); - rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); - rsp.result = cpu_to_le16(result); - rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - l2cap_send_cmd(conn, l2cap_pi(sk)->ident, - L2CAP_CONN_RSP, sizeof(rsp), &rsp); - } + if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) + hci_conn_change_link_key(hcon); bh_unlock_sock(sk); } read_unlock(&l->lock); - return 0; } @@ -2454,9 +2307,9 @@ static const struct proto_ops l2cap_sock .sendmsg = l2cap_sock_sendmsg, .recvmsg = bt_sock_recvmsg, .poll = bt_sock_poll, - .ioctl = bt_sock_ioctl, .mmap = sock_no_mmap, .socketpair = sock_no_socketpair, + .ioctl = sock_no_ioctl, .shutdown = l2cap_sock_shutdown, .setsockopt = l2cap_sock_setsockopt, .getsockopt = l2cap_sock_getsockopt @@ -2538,7 +2391,7 @@ EXPORT_SYMBOL(l2cap_load); module_init(l2cap_init); module_exit(l2cap_exit); -MODULE_AUTHOR("Marcel Holtmann "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); Binary files linux-source-2.6.28-pristine/net/bluetooth/l2cap.ko and linux-2.6.28-working/net/bluetooth/l2cap.ko differ diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/modules.order linux-2.6.28-working/net/bluetooth/modules.order --- linux-source-2.6.28-pristine/net/bluetooth/modules.order 2009-02-11 15:27:02.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/modules.order 2009-02-21 21:59:37.000000000 +0000 @@ -2,4 +2,3 @@ kernel/net/bluetooth/l2cap.ko kernel/net/bluetooth/sco.ko kernel/net/bluetooth/rfcomm/rfcomm.ko kernel/net/bluetooth/bnep/bnep.ko -kernel/net/bluetooth/hidp/hidp.ko diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/rfcomm/core.c linux-2.6.28-working/net/bluetooth/rfcomm/core.c --- linux-source-2.6.28-pristine/net/bluetooth/rfcomm/core.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/rfcomm/core.c 2009-02-18 16:11:21.000000000 +0000 @@ -23,6 +23,8 @@ /* * Bluetooth RFCOMM core. + * + * $Id: core.c,v 1.42 2002/10/01 23:26:25 maxk Exp $ */ #include @@ -51,7 +53,7 @@ #define BT_DBG(D...) #endif -#define VERSION "1.10" +#define VERSION "1.8" static int disable_cfc = 0; static int channel_mtu = -1; @@ -228,21 +230,6 @@ static int rfcomm_l2sock_create(struct s return err; } -static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) -{ - struct sock *sk = d->session->sock->sk; - - if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { - if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) - return 1; - } else if (d->link_mode & RFCOMM_LM_AUTH) { - if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) - return 1; - } - - return 0; -} - /* ---- RFCOMM DLCs ---- */ static void rfcomm_dlc_timeout(unsigned long arg) { @@ -292,7 +279,9 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_ if (!d) return NULL; - setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d); + init_timer(&d->timer); + d->timer.function = rfcomm_dlc_timeout; + d->timer.data = (unsigned long) d; skb_queue_head_init(&d->tx_queue); spin_lock_init(&d->lock); @@ -384,23 +373,15 @@ static int __rfcomm_dlc_open(struct rfco d->addr = __addr(s->initiator, dlci); d->priority = 7; - d->state = BT_CONFIG; + d->state = BT_CONFIG; rfcomm_dlc_link(s, d); - d->out = 1; - d->mtu = s->mtu; d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc; - if (s->state == BT_CONNECTED) { - if (rfcomm_check_link_mode(d)) - set_bit(RFCOMM_AUTH_PENDING, &d->flags); - else - rfcomm_send_pn(s, 1, d); - } - + if (s->state == BT_CONNECTED) + rfcomm_send_pn(s, 1, d); rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); - return 0; } @@ -1167,6 +1148,21 @@ static int rfcomm_recv_disc(struct rfcom return 0; } +static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) +{ + struct sock *sk = d->session->sock->sk; + + if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { + if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) + return 1; + } else if (d->link_mode & RFCOMM_LM_AUTH) { + if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) + return 1; + } + + return 0; +} + static void rfcomm_dlc_accept(struct rfcomm_dlc *d) { struct sock *sk = d->session->sock->sk; @@ -1211,8 +1207,10 @@ static int rfcomm_recv_sabm(struct rfcom if (rfcomm_check_link_mode(d)) { set_bit(RFCOMM_AUTH_PENDING, &d->flags); rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); - } else - rfcomm_dlc_accept(d); + return 0; + } + + rfcomm_dlc_accept(d); } return 0; } @@ -1227,8 +1225,10 @@ static int rfcomm_recv_sabm(struct rfcom if (rfcomm_check_link_mode(d)) { set_bit(RFCOMM_AUTH_PENDING, &d->flags); rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); - } else - rfcomm_dlc_accept(d); + return 0; + } + + rfcomm_dlc_accept(d); } else { rfcomm_send_dm(s, dlci); } @@ -1461,12 +1461,8 @@ static int rfcomm_recv_msc(struct rfcomm clear_bit(RFCOMM_TX_THROTTLED, &d->flags); rfcomm_dlc_lock(d); - - d->remote_v24_sig = msc->v24_sig; - if (d->modem_status) d->modem_status(d, msc->v24_sig); - rfcomm_dlc_unlock(d); rfcomm_send_msc(s, 0, dlci, msc->v24_sig); @@ -1642,11 +1638,7 @@ static void rfcomm_process_connect(struc d = list_entry(p, struct rfcomm_dlc, list); if (d->state == BT_CONFIG) { d->mtu = s->mtu; - if (rfcomm_check_link_mode(d)) { - set_bit(RFCOMM_AUTH_PENDING, &d->flags); - rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); - } else - rfcomm_send_pn(s, 1, d); + rfcomm_send_pn(s, 1, d); } } } @@ -1719,11 +1711,7 @@ static inline void rfcomm_process_dlcs(s if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) { rfcomm_dlc_clear_timer(d); - if (d->out) { - rfcomm_send_pn(s, 1, d); - rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); - } else - rfcomm_dlc_accept(d); + rfcomm_dlc_accept(d); if (d->link_mode & RFCOMM_LM_SECURE) { struct sock *sk = s->sock->sk; hci_conn_change_link_key(l2cap_pi(sk)->conn->hcon); @@ -1731,10 +1719,7 @@ static inline void rfcomm_process_dlcs(s continue; } else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) { rfcomm_dlc_clear_timer(d); - if (!d->out) - rfcomm_send_dm(s, d->dlci); - else - d->state = BT_CLOSED; + rfcomm_send_dm(s, d->dlci); __rfcomm_dlc_close(d, ECONNREFUSED); continue; } @@ -1743,7 +1728,7 @@ static inline void rfcomm_process_dlcs(s continue; if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) && - d->mscex == RFCOMM_MSCEX_OK) + d->mscex == RFCOMM_MSCEX_OK) rfcomm_process_tx(d); } } @@ -1786,6 +1771,8 @@ static inline void rfcomm_accept_connect if (err < 0) return; + __module_get(nsock->ops->owner); + /* Set our callbacks */ nsock->sk->sk_data_ready = rfcomm_l2data_ready; nsock->sk->sk_state_change = rfcomm_l2state_change; @@ -1969,8 +1956,7 @@ static void rfcomm_auth_cfm(struct hci_c list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); - if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && - !(conn->link_mode & HCI_LM_ENCRYPT) && !status) + if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) continue; if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) @@ -2004,14 +1990,6 @@ static void rfcomm_encrypt_cfm(struct hc list_for_each_safe(p, n, &s->dlcs) { d = list_entry(p, struct rfcomm_dlc, list); - if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && - (d->state == BT_CONNECTED || - d->state == BT_CONFIG) && - !status && encrypt == 0x00) { - __rfcomm_dlc_close(d, ECONNREFUSED); - continue; - } - if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) continue; @@ -2113,7 +2091,7 @@ MODULE_PARM_DESC(channel_mtu, "Default M module_param(l2cap_mtu, uint, 0644); MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); -MODULE_AUTHOR("Marcel Holtmann "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); Binary files linux-source-2.6.28-pristine/net/bluetooth/rfcomm/rfcomm.ko and linux-2.6.28-working/net/bluetooth/rfcomm/rfcomm.ko differ diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/rfcomm/sock.c linux-2.6.28-working/net/bluetooth/rfcomm/sock.c --- linux-source-2.6.28-pristine/net/bluetooth/rfcomm/sock.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/rfcomm/sock.c 2009-02-18 16:20:40.000000000 +0000 @@ -23,6 +23,8 @@ /* * RFCOMM sockets. + * + * $Id: sock.c,v 1.24 2002/10/03 01:00:34 maxk Exp $ */ #include @@ -58,7 +60,7 @@ static const struct proto_ops rfcomm_sock_ops; static struct bt_sock_list rfcomm_sk_list = { - .lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void rfcomm_sock_close(struct sock *sk); @@ -307,13 +309,13 @@ static struct sock *rfcomm_sock_alloc(st sk->sk_destruct = rfcomm_sock_destruct; sk->sk_sndtimeo = RFCOMM_CONN_TIMEOUT; - sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; - sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; + sk->sk_sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; + sk->sk_rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10; sock_reset_flag(sk, SOCK_ZAPPED); sk->sk_protocol = proto; - sk->sk_state = BT_OPEN; + sk->sk_state = BT_OPEN; bt_sock_link(&rfcomm_sk_list, sk); @@ -411,8 +413,6 @@ static int rfcomm_sock_connect(struct so bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); rfcomm_pi(sk)->channel = sa->rc_channel; - d->link_mode = rfcomm_pi(sk)->link_mode; - err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); if (!err) err = bt_sock_wait_state(sk, BT_CONNECTED, @@ -688,8 +688,6 @@ static int rfcomm_sock_recvmsg(struct ki copied += chunk; size -= chunk; - sock_recv_timestamp(msg, sk, skb); - if (!(flags & MSG_PEEK)) { atomic_sub(chunk, &sk->sk_rmem_alloc); @@ -795,20 +793,15 @@ static int rfcomm_sock_ioctl(struct sock struct sock *sk = sock->sk; int err; - BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg); - - err = bt_sock_ioctl(sock, cmd, arg); + lock_sock(sk); - if (err == -ENOIOCTLCMD) { #ifdef CONFIG_BT_RFCOMM_TTY - lock_sock(sk); - err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg); - release_sock(sk); + err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg); #else - err = -EOPNOTSUPP; + err = -EOPNOTSUPP; #endif - } + release_sock(sk); return err; } diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/rfcomm/tty.c linux-2.6.28-working/net/bluetooth/rfcomm/tty.c --- linux-source-2.6.28-pristine/net/bluetooth/rfcomm/tty.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/rfcomm/tty.c 2009-02-18 16:27:34.000000000 +0000 @@ -23,6 +23,8 @@ /* * RFCOMM TTY. + * + * $Id: tty.c,v 1.24 2002/10/03 01:54:38 holtmann Exp $ */ #include @@ -75,8 +77,6 @@ struct rfcomm_dev { struct device *tty_dev; atomic_t wmem_alloc; - - struct sk_buff_head pending; }; static LIST_HEAD(rfcomm_dev_list); @@ -264,34 +264,13 @@ static int rfcomm_dev_add(struct rfcomm_ init_waitqueue_head(&dev->wait); tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev); - skb_queue_head_init(&dev->pending); - rfcomm_dlc_lock(dlc); - - if (req->flags & (1 << RFCOMM_REUSE_DLC)) { - struct sock *sk = dlc->owner; - struct sk_buff *skb; - - BUG_ON(!sk); - - rfcomm_dlc_throttle(dlc); - - while ((skb = skb_dequeue(&sk->sk_receive_queue))) { - skb_orphan(skb); - skb_queue_tail(&dev->pending, skb); - atomic_sub(skb->len, &sk->sk_rmem_alloc); - } - } - dlc->data_ready = rfcomm_dev_data_ready; dlc->state_change = rfcomm_dev_state_change; dlc->modem_status = rfcomm_dev_modem_status; dlc->owner = dev; dev->dlc = dlc; - - rfcomm_dev_modem_status(dlc, dlc->remote_v24_sig); - rfcomm_dlc_unlock(dlc); /* It's safe to call __module_get() here because socket already @@ -450,8 +429,7 @@ static int rfcomm_release_dev(void __use if (dev->tty) tty_vhangup(dev->tty); - if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) - rfcomm_dev_del(dev); + rfcomm_dev_del(dev); rfcomm_dev_put(dev); return 0; } @@ -560,16 +538,11 @@ static void rfcomm_dev_data_ready(struct struct rfcomm_dev *dev = dlc->owner; struct tty_struct *tty; - if (!dev) { + if (!dev || !(tty = dev->tty)) { kfree_skb(skb); return; } - if (!(tty = dev->tty) || !skb_queue_empty(&dev->pending)) { - skb_queue_tail(&dev->pending, skb); - return; - } - BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len); tty_insert_flip_string(tty, skb->data, skb->len); @@ -592,20 +565,14 @@ static void rfcomm_dev_state_change(stru if (dlc->state == BT_CLOSED) { if (!dev->tty) { if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) { - /* Drop DLC lock here to avoid deadlock - * 1. rfcomm_dev_get will take rfcomm_dev_lock - * but in rfcomm_dev_add there's lock order: - * rfcomm_dev_lock -> dlc lock - * 2. rfcomm_dev_put will deadlock if it's - * the last reference - */ - rfcomm_dlc_unlock(dlc); - if (rfcomm_dev_get(dev->id) == NULL) { - rfcomm_dlc_lock(dlc); + if (rfcomm_dev_get(dev->id) == NULL) return; - } rfcomm_dev_del(dev); + /* We have to drop DLC lock here, otherwise + rfcomm_dev_put() will dead lock if it's + the last reference. */ + rfcomm_dlc_unlock(dlc); rfcomm_dev_put(dev); rfcomm_dlc_lock(dlc); } @@ -643,31 +610,11 @@ static void rfcomm_tty_wakeup(unsigned l return; BT_DBG("dev %p tty %p", dev, tty); - tty_wakeup(tty); -} - -static void rfcomm_tty_copy_pending(struct rfcomm_dev *dev) -{ - struct tty_struct *tty = dev->tty; - struct sk_buff *skb; - int inserted = 0; - - if (!tty) - return; - - BT_DBG("dev %p tty %p", dev, tty); - - rfcomm_dlc_lock(dev->dlc); - - while ((skb = skb_dequeue(&dev->pending))) { - inserted += tty_insert_flip_string(tty, skb->data, skb->len); - kfree_skb(skb); - } - - rfcomm_dlc_unlock(dev->dlc); - if (inserted > 0) - tty_flip_buffer_push(tty); + tty_wakeup(tty); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif } static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) @@ -734,10 +681,6 @@ static int rfcomm_tty_open(struct tty_st if (err == 0) device_move(dev->tty_dev, rfcomm_get_device(dev)); - rfcomm_tty_copy_pending(dev); - - rfcomm_dlc_unthrottle(dev->dlc); - return err; } @@ -1052,6 +995,7 @@ static void rfcomm_tty_flush_buffer(stru return; skb_queue_purge(&dev->dlc->tx_queue); + tty_wakeup(tty); } @@ -1168,7 +1112,6 @@ int rfcomm_init_ttys(void) rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; rfcomm_tty_driver->init_termios = tty_std_termios; rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); if (tty_register_driver(rfcomm_tty_driver)) { diff --exclude='*.o' --exclude='*.cmd' --exclude='*.mod.c' -urp linux-source-2.6.28-pristine/net/bluetooth/sco.c linux-2.6.28-working/net/bluetooth/sco.c --- linux-source-2.6.28-pristine/net/bluetooth/sco.c 2008-12-24 23:26:37.000000000 +0000 +++ linux-2.6.28-working/net/bluetooth/sco.c 2009-02-18 16:20:13.000000000 +0000 @@ -53,14 +53,12 @@ #define BT_DBG(D...) #endif -#define VERSION "0.6" - -static int disable_esco = 0; +#define VERSION "0.5" static const struct proto_ops sco_sock_ops; static struct bt_sock_list sco_sk_list = { - .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent); @@ -99,6 +97,13 @@ static void sco_sock_clear_timer(struct sk_stop_timer(sk, &sk->sk_timer); } +static void sco_sock_init_timer(struct sock *sk) +{ + init_timer(&sk->sk_timer); + sk->sk_timer.function = sco_sock_timeout; + sk->sk_timer.data = (unsigned long)sk; +} + /* ---- SCO connections ---- */ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status) { @@ -195,12 +200,9 @@ static int sco_connect(struct sock *sk) err = -ENOMEM; - if (lmp_esco_capable(hdev) && !disable_esco) - type = ESCO_LINK; - else - type = SCO_LINK; + type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK; - hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING); + hcon = hci_connect(hdev, type, dst); if (!hcon) goto done; @@ -434,7 +436,7 @@ static struct sock *sco_sock_alloc(struc sk->sk_protocol = proto; sk->sk_state = BT_OPEN; - setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk); + sco_sock_init_timer(sk); bt_sock_link(&sco_sk_list, sk); return sk; @@ -926,7 +928,7 @@ static const struct proto_ops sco_sock_o .sendmsg = sco_sock_sendmsg, .recvmsg = bt_sock_recvmsg, .poll = bt_sock_poll, - .ioctl = bt_sock_ioctl, + .ioctl = sock_no_ioctl, .mmap = sock_no_mmap, .socketpair = sock_no_socketpair, .shutdown = sock_no_shutdown, @@ -999,10 +1001,7 @@ static void __exit sco_exit(void) module_init(sco_init); module_exit(sco_exit); -module_param(disable_esco, bool, 0644); -MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation"); - -MODULE_AUTHOR("Marcel Holtmann "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); Binary files linux-source-2.6.28-pristine/net/bluetooth/sco.ko and linux-2.6.28-working/net/bluetooth/sco.ko differ