Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
d2805395
K
Kernel
项目概览
openeuler
/
Kernel
大约 1 年 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d2805395
编写于
8月 19, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
上级
f3b9605d
63fbd24e
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
476 addition
and
297 deletion
+476
-297
MAINTAINERS
MAINTAINERS
+6
-81
drivers/bluetooth/Kconfig
drivers/bluetooth/Kconfig
+4
-6
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/bt3c_cs.c
+1
-1
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+268
-14
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_ldisc.c
+1
-1
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_usb.c
+1
-1
drivers/bluetooth/hci_vhci.c
drivers/bluetooth/hci_vhci.c
+1
-1
net/bluetooth/af_bluetooth.c
net/bluetooth/af_bluetooth.c
+1
-1
net/bluetooth/bnep/core.c
net/bluetooth/bnep/core.c
+1
-1
net/bluetooth/hci_sysfs.c
net/bluetooth/hci_sysfs.c
+189
-187
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+1
-1
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/core.c
+1
-1
net/bluetooth/sco.c
net/bluetooth/sco.c
+1
-1
未找到文件。
MAINTAINERS
浏览文件 @
d2805395
...
@@ -936,94 +936,19 @@ M: joern@lazybastard.org
...
@@ -936,94 +936,19 @@ M: joern@lazybastard.org
L: linux-mtd@lists.infradead.org
L: linux-mtd@lists.infradead.org
S: Maintained
S: Maintained
BLUETOOTH
SUBSYSTEM
BLUETOOTH
DRIVERS
P: Marcel Holtmann
P: Marcel Holtmann
M: marcel@holtmann.org
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
L: linux-bluetooth@vger.kernel.org
L: linux-bluetooth@vger.kernel.org
W: http://bluez.sf.net
W: http://www.bluez.org/
W: http://www.bluez.org
W: http://www.holtmann.org/linux/bluetooth/
T: git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
S: Maintained
BLUETOOTH RFCOMM LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH BNEP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH CMTP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
S: Maintained
BLUETOOTH HIDP LAYER
BLUETOOTH SUBSYSTEM
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI UART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH HCI USB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
BLUETOOTH HCI BCM203X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BPA10X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BFUSB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI DTL1 DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BLUECARD DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BT3C DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI BTUART DRIVER
P: Marcel Holtmann
P: Marcel Holtmann
M: marcel@holtmann.org
M: marcel@holtmann.org
S: Maintained
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
BLUETOOTH HCI VHCI DRIVER
T: git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
P: Maxim Krasnyansky
M: maxk@qualcomm.com
S: Maintained
S: Maintained
BONDING DRIVER
BONDING DRIVER
...
...
drivers/bluetooth/Kconfig
浏览文件 @
d2805395
...
@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
...
@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
depends on BT
depends on BT
config BT_HCIUSB
config BT_HCIUSB
tristate "HCI USB driver"
tristate "HCI USB driver
(old version)
"
depends on USB
depends on USB
&& BT_HCIBTUSB=n
help
help
Bluetooth HCI USB driver.
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
This driver is required if you want to use Bluetooth devices with
...
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
...
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
Say Y here to compile support for SCO over HCI USB.
Say Y here to compile support for SCO over HCI USB.
config BT_HCIBTUSB
config BT_HCIBTUSB
tristate "HCI USB driver
(alternate version)
"
tristate "HCI USB driver"
depends on USB
&& EXPERIMENTAL && BT_HCIUSB=n
depends on USB
help
help
Bluetooth HCI USB driver.
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
This driver is required if you want to use Bluetooth devices with
USB interface.
USB interface.
This driver is still experimental and has no SCO support.
Say Y here to compile support for Bluetooth USB devices into the
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (btusb).
kernel or say M to compile it as module (btusb).
...
...
drivers/bluetooth/bt3c_cs.c
浏览文件 @
d2805395
...
@@ -60,7 +60,7 @@
...
@@ -60,7 +60,7 @@
/* ======================== Module parameters ======================== */
/* ======================== Module parameters ======================== */
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>
, Jose Orlando Pereira <jop@di.uminho.pt>
"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth driver for the 3Com Bluetooth PCMCIA card"
);
MODULE_DESCRIPTION
(
"Bluetooth driver for the 3Com Bluetooth PCMCIA card"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_FIRMWARE
(
"BT3CPCC.bin"
);
MODULE_FIRMWARE
(
"BT3CPCC.bin"
);
...
...
drivers/bluetooth/btusb.c
浏览文件 @
d2805395
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
*
*
* Generic Bluetooth USB driver
* Generic Bluetooth USB driver
*
*
* Copyright (C) 2005-200
7
Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2005-200
8
Marcel Holtmann <marcel@holtmann.org>
*
*
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
#define BT_DBG(D...)
#define BT_DBG(D...)
#endif
#endif
#define VERSION "0.
2
"
#define VERSION "0.
3
"
static
int
ignore_dga
;
static
int
ignore_dga
;
static
int
ignore_csr
;
static
int
ignore_csr
;
...
@@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
...
@@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
{
}
/* Terminating entry */
{
}
/* Terminating entry */
};
};
#define BTUSB_MAX_ISOC_FRAMES 10
#define BTUSB_INTR_RUNNING 0
#define BTUSB_INTR_RUNNING 0
#define BTUSB_BULK_RUNNING 1
#define BTUSB_BULK_RUNNING 1
#define BTUSB_ISOC_RUNNING 2
struct
btusb_data
{
struct
btusb_data
{
struct
hci_dev
*
hdev
;
struct
hci_dev
*
hdev
;
struct
usb_device
*
udev
;
struct
usb_device
*
udev
;
struct
usb_interface
*
isoc
;
spinlock_t
lock
;
spinlock_t
lock
;
...
@@ -176,10 +180,15 @@ struct btusb_data {
...
@@ -176,10 +180,15 @@ struct btusb_data {
struct
usb_anchor
tx_anchor
;
struct
usb_anchor
tx_anchor
;
struct
usb_anchor
intr_anchor
;
struct
usb_anchor
intr_anchor
;
struct
usb_anchor
bulk_anchor
;
struct
usb_anchor
bulk_anchor
;
struct
usb_anchor
isoc_anchor
;
struct
usb_endpoint_descriptor
*
intr_ep
;
struct
usb_endpoint_descriptor
*
intr_ep
;
struct
usb_endpoint_descriptor
*
bulk_tx_ep
;
struct
usb_endpoint_descriptor
*
bulk_tx_ep
;
struct
usb_endpoint_descriptor
*
bulk_rx_ep
;
struct
usb_endpoint_descriptor
*
bulk_rx_ep
;
struct
usb_endpoint_descriptor
*
isoc_tx_ep
;
struct
usb_endpoint_descriptor
*
isoc_rx_ep
;
int
isoc_altsetting
;
};
};
static
void
btusb_intr_complete
(
struct
urb
*
urb
)
static
void
btusb_intr_complete
(
struct
urb
*
urb
)
...
@@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
...
@@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
return
;
return
;
if
(
urb
->
status
==
0
)
{
if
(
urb
->
status
==
0
)
{
hdev
->
stat
.
byte_rx
+=
urb
->
actual_length
;
if
(
hci_recv_fragment
(
hdev
,
HCI_EVENT_PKT
,
if
(
hci_recv_fragment
(
hdev
,
HCI_EVENT_PKT
,
urb
->
transfer_buffer
,
urb
->
transfer_buffer
,
urb
->
actual_length
)
<
0
)
{
urb
->
actual_length
)
<
0
)
{
...
@@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
...
@@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
}
}
}
}
static
in
line
in
t
btusb_submit_intr_urb
(
struct
hci_dev
*
hdev
)
static
int
btusb_submit_intr_urb
(
struct
hci_dev
*
hdev
)
{
{
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
urb
*
urb
;
struct
urb
*
urb
;
...
@@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
...
@@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
data
->
intr_ep
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
if
(
!
urb
)
if
(
!
urb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
...
@@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
return
;
return
;
if
(
urb
->
status
==
0
)
{
if
(
urb
->
status
==
0
)
{
hdev
->
stat
.
byte_rx
+=
urb
->
actual_length
;
if
(
hci_recv_fragment
(
hdev
,
HCI_ACLDATA_PKT
,
if
(
hci_recv_fragment
(
hdev
,
HCI_ACLDATA_PKT
,
urb
->
transfer_buffer
,
urb
->
transfer_buffer
,
urb
->
actual_length
)
<
0
)
{
urb
->
actual_length
)
<
0
)
{
...
@@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
...
@@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
}
}
}
}
static
in
line
in
t
btusb_submit_bulk_urb
(
struct
hci_dev
*
hdev
)
static
int
btusb_submit_bulk_urb
(
struct
hci_dev
*
hdev
)
{
{
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
urb
*
urb
;
struct
urb
*
urb
;
...
@@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
...
@@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
data
->
bulk_rx_ep
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
urb
)
if
(
!
urb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
...
@@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
return
err
;
return
err
;
}
}
static
void
btusb_isoc_complete
(
struct
urb
*
urb
)
{
struct
hci_dev
*
hdev
=
urb
->
context
;
struct
btusb_data
*
data
=
hdev
->
driver_data
;
int
i
,
err
;
BT_DBG
(
"%s urb %p status %d count %d"
,
hdev
->
name
,
urb
,
urb
->
status
,
urb
->
actual_length
);
if
(
!
test_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
return
;
if
(
urb
->
status
==
0
)
{
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
)
{
unsigned
int
offset
=
urb
->
iso_frame_desc
[
i
].
offset
;
unsigned
int
length
=
urb
->
iso_frame_desc
[
i
].
actual_length
;
if
(
urb
->
iso_frame_desc
[
i
].
status
)
continue
;
hdev
->
stat
.
byte_rx
+=
length
;
if
(
hci_recv_fragment
(
hdev
,
HCI_SCODATA_PKT
,
urb
->
transfer_buffer
+
offset
,
length
)
<
0
)
{
BT_ERR
(
"%s corrupted SCO packet"
,
hdev
->
name
);
hdev
->
stat
.
err_rx
++
;
}
}
}
if
(
!
test_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
))
return
;
usb_anchor_urb
(
urb
,
&
data
->
isoc_anchor
);
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
err
<
0
)
{
BT_ERR
(
"%s urb %p failed to resubmit (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
}
}
static
void
inline
__fill_isoc_descriptor
(
struct
urb
*
urb
,
int
len
,
int
mtu
)
{
int
i
,
offset
=
0
;
BT_DBG
(
"len %d mtu %d"
,
len
,
mtu
);
for
(
i
=
0
;
i
<
BTUSB_MAX_ISOC_FRAMES
&&
len
>=
mtu
;
i
++
,
offset
+=
mtu
,
len
-=
mtu
)
{
urb
->
iso_frame_desc
[
i
].
offset
=
offset
;
urb
->
iso_frame_desc
[
i
].
length
=
mtu
;
}
if
(
len
&&
i
<
BTUSB_MAX_ISOC_FRAMES
)
{
urb
->
iso_frame_desc
[
i
].
offset
=
offset
;
urb
->
iso_frame_desc
[
i
].
length
=
len
;
i
++
;
}
urb
->
number_of_packets
=
i
;
}
static
int
btusb_submit_isoc_urb
(
struct
hci_dev
*
hdev
)
{
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
urb
*
urb
;
unsigned
char
*
buf
;
unsigned
int
pipe
;
int
err
,
size
;
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
data
->
isoc_rx_ep
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
BTUSB_MAX_ISOC_FRAMES
,
GFP_KERNEL
);
if
(
!
urb
)
return
-
ENOMEM
;
size
=
le16_to_cpu
(
data
->
isoc_rx_ep
->
wMaxPacketSize
)
*
BTUSB_MAX_ISOC_FRAMES
;
buf
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
buf
)
{
usb_free_urb
(
urb
);
return
-
ENOMEM
;
}
pipe
=
usb_rcvisocpipe
(
data
->
udev
,
data
->
isoc_rx_ep
->
bEndpointAddress
);
urb
->
dev
=
data
->
udev
;
urb
->
pipe
=
pipe
;
urb
->
context
=
hdev
;
urb
->
complete
=
btusb_isoc_complete
;
urb
->
interval
=
data
->
isoc_rx_ep
->
bInterval
;
urb
->
transfer_flags
=
URB_FREE_BUFFER
|
URB_ISO_ASAP
;
urb
->
transfer_buffer
=
buf
;
urb
->
transfer_buffer_length
=
size
;
__fill_isoc_descriptor
(
urb
,
size
,
le16_to_cpu
(
data
->
isoc_rx_ep
->
wMaxPacketSize
));
usb_anchor_urb
(
urb
,
&
data
->
isoc_anchor
);
err
=
usb_submit_urb
(
urb
,
GFP_KERNEL
);
if
(
err
<
0
)
{
BT_ERR
(
"%s urb %p submission failed (%d)"
,
hdev
->
name
,
urb
,
-
err
);
usb_unanchor_urb
(
urb
);
kfree
(
buf
);
}
usb_free_urb
(
urb
);
return
err
;
}
static
void
btusb_tx_complete
(
struct
urb
*
urb
)
static
void
btusb_tx_complete
(
struct
urb
*
urb
)
{
{
struct
sk_buff
*
skb
=
urb
->
context
;
struct
sk_buff
*
skb
=
urb
->
context
;
...
@@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
...
@@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
if
(
!
test_and_clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
if
(
!
test_and_clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
return
0
;
return
0
;
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
intr_anchor
);
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
...
@@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
...
@@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
break
;
break
;
case
HCI_ACLDATA_PKT
:
case
HCI_ACLDATA_PKT
:
if
(
!
data
->
bulk_tx_ep
||
hdev
->
conn_hash
.
acl_num
<
1
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
if
(
!
urb
)
if
(
!
urb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
@@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
...
@@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
break
;
break
;
case
HCI_SCODATA_PKT
:
case
HCI_SCODATA_PKT
:
if
(
!
data
->
isoc_tx_ep
||
hdev
->
conn_hash
.
sco_num
<
1
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
BTUSB_MAX_ISOC_FRAMES
,
GFP_ATOMIC
);
if
(
!
urb
)
return
-
ENOMEM
;
pipe
=
usb_sndisocpipe
(
data
->
udev
,
data
->
isoc_tx_ep
->
bEndpointAddress
);
urb
->
dev
=
data
->
udev
;
urb
->
pipe
=
pipe
;
urb
->
context
=
skb
;
urb
->
complete
=
btusb_tx_complete
;
urb
->
interval
=
data
->
isoc_tx_ep
->
bInterval
;
urb
->
transfer_flags
=
URB_ISO_ASAP
;
urb
->
transfer_buffer
=
skb
->
data
;
urb
->
transfer_buffer_length
=
skb
->
len
;
__fill_isoc_descriptor
(
urb
,
skb
->
len
,
le16_to_cpu
(
data
->
isoc_tx_ep
->
wMaxPacketSize
));
hdev
->
stat
.
sco_tx
++
;
hdev
->
stat
.
sco_tx
++
;
kfree_skb
(
skb
);
break
;
return
0
;
default:
default:
return
-
EILSEQ
;
return
-
EILSEQ
;
...
@@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
...
@@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
schedule_work
(
&
data
->
work
);
schedule_work
(
&
data
->
work
);
}
}
static
int
inline
__set_isoc_interface
(
struct
hci_dev
*
hdev
,
int
altsetting
)
{
struct
btusb_data
*
data
=
hdev
->
driver_data
;
struct
usb_interface
*
intf
=
data
->
isoc
;
struct
usb_endpoint_descriptor
*
ep_desc
;
int
i
,
err
;
if
(
!
data
->
isoc
)
return
-
ENODEV
;
err
=
usb_set_interface
(
data
->
udev
,
1
,
altsetting
);
if
(
err
<
0
)
{
BT_ERR
(
"%s setting interface failed (%d)"
,
hdev
->
name
,
-
err
);
return
err
;
}
data
->
isoc_altsetting
=
altsetting
;
data
->
isoc_tx_ep
=
NULL
;
data
->
isoc_rx_ep
=
NULL
;
for
(
i
=
0
;
i
<
intf
->
cur_altsetting
->
desc
.
bNumEndpoints
;
i
++
)
{
ep_desc
=
&
intf
->
cur_altsetting
->
endpoint
[
i
].
desc
;
if
(
!
data
->
isoc_tx_ep
&&
usb_endpoint_is_isoc_out
(
ep_desc
))
{
data
->
isoc_tx_ep
=
ep_desc
;
continue
;
}
if
(
!
data
->
isoc_rx_ep
&&
usb_endpoint_is_isoc_in
(
ep_desc
))
{
data
->
isoc_rx_ep
=
ep_desc
;
continue
;
}
}
if
(
!
data
->
isoc_tx_ep
||
!
data
->
isoc_rx_ep
)
{
BT_ERR
(
"%s invalid SCO descriptors"
,
hdev
->
name
);
return
-
ENODEV
;
}
return
0
;
}
static
void
btusb_work
(
struct
work_struct
*
work
)
static
void
btusb_work
(
struct
work_struct
*
work
)
{
{
struct
btusb_data
*
data
=
container_of
(
work
,
struct
btusb_data
,
work
);
struct
btusb_data
*
data
=
container_of
(
work
,
struct
btusb_data
,
work
);
struct
hci_dev
*
hdev
=
data
->
hdev
;
struct
hci_dev
*
hdev
=
data
->
hdev
;
if
(
hdev
->
conn_hash
.
acl_num
==
0
)
{
if
(
hdev
->
conn_hash
.
acl_num
>
0
)
{
if
(
!
test_and_set_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
))
{
if
(
btusb_submit_bulk_urb
(
hdev
)
<
0
)
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
else
btusb_submit_bulk_urb
(
hdev
);
}
}
else
{
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
return
;
}
}
if
(
!
test_and_set_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
))
{
if
(
hdev
->
conn_hash
.
sco_num
>
0
)
{
if
(
btusb_submit_bulk_urb
(
hdev
)
<
0
)
if
(
data
->
isoc_altsetting
!=
2
)
{
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
else
usb_kill_anchored_urbs
(
&
data
->
isoc_anchor
);
btusb_submit_bulk_urb
(
hdev
);
if
(
__set_isoc_interface
(
hdev
,
2
)
<
0
)
return
;
}
if
(
!
test_and_set_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
))
{
if
(
btusb_submit_isoc_urb
(
hdev
)
<
0
)
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
else
btusb_submit_isoc_urb
(
hdev
);
}
}
else
{
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
isoc_anchor
);
__set_isoc_interface
(
hdev
,
0
);
}
}
}
}
...
@@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
...
@@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
init_usb_anchor
(
&
data
->
tx_anchor
);
init_usb_anchor
(
&
data
->
tx_anchor
);
init_usb_anchor
(
&
data
->
intr_anchor
);
init_usb_anchor
(
&
data
->
intr_anchor
);
init_usb_anchor
(
&
data
->
bulk_anchor
);
init_usb_anchor
(
&
data
->
bulk_anchor
);
init_usb_anchor
(
&
data
->
isoc_anchor
);
hdev
=
hci_alloc_dev
();
hdev
=
hci_alloc_dev
();
if
(
!
hdev
)
{
if
(
!
hdev
)
{
...
@@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
...
@@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
hdev
->
owner
=
THIS_MODULE
;
hdev
->
owner
=
THIS_MODULE
;
/* interface numbers are hardcoded in the spec */
data
->
isoc
=
usb_ifnum_to_if
(
data
->
udev
,
1
);
if
(
reset
||
id
->
driver_info
&
BTUSB_RESET
)
if
(
reset
||
id
->
driver_info
&
BTUSB_RESET
)
set_bit
(
HCI_QUIRK_RESET_ON_INIT
,
&
hdev
->
quirks
);
set_bit
(
HCI_QUIRK_RESET_ON_INIT
,
&
hdev
->
quirks
);
...
@@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
...
@@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
set_bit
(
HCI_QUIRK_FIXUP_BUFFER_SIZE
,
&
hdev
->
quirks
);
set_bit
(
HCI_QUIRK_FIXUP_BUFFER_SIZE
,
&
hdev
->
quirks
);
}
}
if
(
id
->
driver_info
&
BTUSB_BROKEN_ISOC
)
data
->
isoc
=
NULL
;
if
(
id
->
driver_info
&
BTUSB_SNIFFER
)
{
if
(
id
->
driver_info
&
BTUSB_SNIFFER
)
{
struct
usb_device
*
udev
=
interface_to_usbdev
(
intf
)
;
struct
usb_device
*
udev
=
data
->
udev
;
if
(
le16_to_cpu
(
udev
->
descriptor
.
bcdDevice
)
>
0x997
)
if
(
le16_to_cpu
(
udev
->
descriptor
.
bcdDevice
)
>
0x997
)
set_bit
(
HCI_QUIRK_RAW_DEVICE
,
&
hdev
->
quirks
);
set_bit
(
HCI_QUIRK_RAW_DEVICE
,
&
hdev
->
quirks
);
data
->
isoc
=
NULL
;
}
}
if
(
id
->
driver_info
&
BTUSB_BCM92035
)
{
if
(
id
->
driver_info
&
BTUSB_BCM92035
)
{
...
@@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf,
...
@@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf,
}
}
}
}
if
(
data
->
isoc
)
{
err
=
usb_driver_claim_interface
(
&
btusb_driver
,
data
->
isoc
,
NULL
);
if
(
err
<
0
)
{
hci_free_dev
(
hdev
);
kfree
(
data
);
return
err
;
}
}
err
=
hci_register_dev
(
hdev
);
err
=
hci_register_dev
(
hdev
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
hci_free_dev
(
hdev
);
hci_free_dev
(
hdev
);
...
@@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
...
@@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
hdev
=
data
->
hdev
;
hdev
=
data
->
hdev
;
if
(
data
->
isoc
)
usb_driver_release_interface
(
&
btusb_driver
,
data
->
isoc
);
usb_set_intfdata
(
intf
,
NULL
);
usb_set_intfdata
(
intf
,
NULL
);
hci_unregister_dev
(
hdev
);
hci_unregister_dev
(
hdev
);
...
...
drivers/bluetooth/hci_ldisc.c
浏览文件 @
d2805395
...
@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
...
@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
module_param
(
reset
,
bool
,
0644
);
module_param
(
reset
,
bool
,
0644
);
MODULE_PARM_DESC
(
reset
,
"Send HCI reset command on initialization"
);
MODULE_PARM_DESC
(
reset
,
"Send HCI reset command on initialization"
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth HCI UART driver ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth HCI UART driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
drivers/bluetooth/hci_usb.c
浏览文件 @
d2805395
...
@@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
...
@@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
MODULE_PARM_DESC
(
isoc
,
"Set isochronous transfers for SCO over HCI support"
);
MODULE_PARM_DESC
(
isoc
,
"Set isochronous transfers for SCO over HCI support"
);
#endif
#endif
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth HCI USB driver ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth HCI USB driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
drivers/bluetooth/hci_vhci.c
浏览文件 @
d2805395
...
@@ -377,7 +377,7 @@ module_exit(vhci_exit);
...
@@ -377,7 +377,7 @@ module_exit(vhci_exit);
module_param
(
minor
,
int
,
0444
);
module_param
(
minor
,
int
,
0444
);
MODULE_PARM_DESC
(
minor
,
"Miscellaneous minor device number"
);
MODULE_PARM_DESC
(
minor
,
"Miscellaneous minor device number"
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth virtual HCI driver ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth virtual HCI driver ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
net/bluetooth/af_bluetooth.c
浏览文件 @
d2805395
...
@@ -456,7 +456,7 @@ static void __exit bt_exit(void)
...
@@ -456,7 +456,7 @@ static void __exit bt_exit(void)
subsys_initcall
(
bt_init
);
subsys_initcall
(
bt_init
);
module_exit
(
bt_exit
);
module_exit
(
bt_exit
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth Core ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth Core ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/bnep/core.c
浏览文件 @
d2805395
...
@@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
...
@@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
module_param
(
compress_dst
,
bool
,
0644
);
module_param
(
compress_dst
,
bool
,
0644
);
MODULE_PARM_DESC
(
compress_dst
,
"Compress destination headers"
);
MODULE_PARM_DESC
(
compress_dst
,
"Compress destination headers"
);
MODULE_AUTHOR
(
"
David Libault <david.libault@inventel.fr>, Maxim Krasnyansky <maxk@qualcomm.com
>"
);
MODULE_AUTHOR
(
"
Marcel Holtmann <marcel@holtmann.org
>"
);
MODULE_DESCRIPTION
(
"Bluetooth BNEP ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth BNEP ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/hci_sysfs.c
浏览文件 @
d2805395
...
@@ -3,8 +3,6 @@
...
@@ -3,8 +3,6 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci_core.h>
...
@@ -12,10 +10,164 @@
...
@@ -12,10 +10,164 @@
#undef BT_DBG
#undef BT_DBG
#define BT_DBG(D...)
#define BT_DBG(D...)
#endif
#endif
struct
class
*
bt_class
=
NULL
;
EXPORT_SYMBOL_GPL
(
bt_class
);
static
struct
workqueue_struct
*
btaddconn
;
static
struct
workqueue_struct
*
btaddconn
;
static
struct
workqueue_struct
*
btdelconn
;
static
struct
workqueue_struct
*
btdelconn
;
static
inline
char
*
typetostr
(
int
type
)
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
)
{
{
switch
(
type
)
{
switch
(
type
)
{
case
HCI_VIRTUAL
:
case
HCI_VIRTUAL
:
...
@@ -40,7 +192,7 @@ static inline char *typetostr(int type)
...
@@ -40,7 +192,7 @@ static inline char *typetostr(int type)
static
ssize_t
show_type
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
static
ssize_t
show_type
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
{
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
struct
hci_dev
*
hdev
=
dev_get_drvdata
(
dev
);
return
sprintf
(
buf
,
"%s
\n
"
,
typetostr
(
hdev
->
type
));
return
sprintf
(
buf
,
"%s
\n
"
,
host_
typetostr
(
hdev
->
type
));
}
}
static
ssize_t
show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
static
ssize_t
show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
...
@@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
...
@@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
static
DEVICE_ATTR
(
sniff_min_interval
,
S_IRUGO
|
S_IWUSR
,
static
DEVICE_ATTR
(
sniff_min_interval
,
S_IRUGO
|
S_IWUSR
,
show_sniff_min_interval
,
store_sniff_min_interval
);
show_sniff_min_interval
,
store_sniff_min_interval
);
static
struct
device_attribute
*
b
t_attrs
[]
=
{
static
struct
attribute
*
bt_hos
t_attrs
[]
=
{
&
dev_attr_type
,
&
dev_attr_type
.
attr
,
&
dev_attr_name
,
&
dev_attr_name
.
attr
,
&
dev_attr_class
,
&
dev_attr_class
.
attr
,
&
dev_attr_address
,
&
dev_attr_address
.
attr
,
&
dev_attr_features
,
&
dev_attr_features
.
attr
,
&
dev_attr_manufacturer
,
&
dev_attr_manufacturer
.
attr
,
&
dev_attr_hci_version
,
&
dev_attr_hci_version
.
attr
,
&
dev_attr_hci_revision
,
&
dev_attr_hci_revision
.
attr
,
&
dev_attr_inquiry_cache
,
&
dev_attr_inquiry_cache
.
attr
,
&
dev_attr_idle_timeout
,
&
dev_attr_idle_timeout
.
attr
,
&
dev_attr_sniff_max_interval
,
&
dev_attr_sniff_max_interval
.
attr
,
&
dev_attr_sniff_min_interval
,
&
dev_attr_sniff_min_interval
.
attr
,
NULL
NULL
};
};
static
ssize_t
show_conn_type
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
static
struct
attribute_group
bt_host_group
=
{
{
.
attrs
=
bt_host_attrs
,
struct
hci_conn
*
conn
=
dev_get_drvdata
(
dev
);
return
sprintf
(
buf
,
"%s
\n
"
,
conn
->
type
==
ACL_LINK
?
"ACL"
:
"SCO"
);
}
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
));
}
static
ssize_t
show_conn_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 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
CONN_ATTR
(
features
,
S_IRUGO
,
show_conn_features
,
NULL
);
static
struct
device_attribute
*
conn_attrs
[]
=
{
&
conn_attr_type
,
&
conn_attr_address
,
&
conn_attr_features
,
NULL
};
};
struct
class
*
bt_class
=
NULL
;
static
struct
attribute_group
*
bt_host_groups
[]
=
{
EXPORT_SYMBOL_GPL
(
bt_class
);
&
bt_host_group
,
NULL
static
struct
bus_type
bt_bus
=
{
.
name
=
"bluetooth"
,
};
};
static
struct
platform_device
*
bt_platform
;
static
void
bt_host_release
(
struct
device
*
dev
)
static
void
bt_release
(
struct
device
*
dev
)
{
{
void
*
data
=
dev_get_drvdata
(
dev
);
void
*
data
=
dev_get_drvdata
(
dev
);
kfree
(
data
);
kfree
(
data
);
}
}
static
void
add_conn
(
struct
work_struct
*
work
)
static
struct
device_type
bt_host
=
{
{
.
name
=
"host"
,
struct
hci_conn
*
conn
=
container_of
(
work
,
struct
hci_conn
,
work
);
.
groups
=
bt_host_groups
,
int
i
;
.
release
=
bt_host_release
,
};
flush_workqueue
(
btdelconn
);
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
;
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:%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
);
}
int
hci_register_sysfs
(
struct
hci_dev
*
hdev
)
int
hci_register_sysfs
(
struct
hci_dev
*
hdev
)
{
{
struct
device
*
dev
=
&
hdev
->
dev
;
struct
device
*
dev
=
&
hdev
->
dev
;
unsigned
int
i
;
int
err
;
int
err
;
BT_DBG
(
"%p name %s type %d"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
BT_DBG
(
"%p name %s type %d"
,
hdev
,
hdev
->
name
,
hdev
->
type
);
dev
->
bus
=
&
bt_bus
;
dev
->
type
=
&
bt_host
;
dev
->
class
=
bt_class
;
dev
->
parent
=
hdev
->
parent
;
dev
->
parent
=
hdev
->
parent
;
strlcpy
(
dev
->
bus_id
,
hdev
->
name
,
BUS_ID_SIZE
);
strlcpy
(
dev
->
bus_id
,
hdev
->
name
,
BUS_ID_SIZE
);
dev
->
release
=
bt_release
;
dev_set_drvdata
(
dev
,
hdev
);
dev_set_drvdata
(
dev
,
hdev
);
err
=
device_register
(
dev
);
err
=
device_register
(
dev
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
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
;
return
0
;
}
}
...
@@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
...
@@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
int
__init
bt_sysfs_init
(
void
)
int
__init
bt_sysfs_init
(
void
)
{
{
int
err
;
btaddconn
=
create_singlethread_workqueue
(
"btaddconn"
);
btaddconn
=
create_singlethread_workqueue
(
"btaddconn"
);
if
(
!
btaddconn
)
{
if
(
!
btaddconn
)
err
=
-
ENOMEM
;
return
-
ENOMEM
;
goto
out
;
}
btdelconn
=
create_singlethread_workqueue
(
"btdelconn"
);
btdelconn
=
create_singlethread_workqueue
(
"btdelconn"
);
if
(
!
btdelconn
)
{
if
(
!
btdelconn
)
{
err
=
-
ENOMEM
;
destroy_workqueue
(
btaddconn
);
goto
out_del
;
return
-
ENOMEM
;
}
bt_platform
=
platform_device_register_simple
(
"bluetooth"
,
-
1
,
NULL
,
0
);
if
(
IS_ERR
(
bt_platform
))
{
err
=
PTR_ERR
(
bt_platform
);
goto
out_platform
;
}
}
err
=
bus_register
(
&
bt_bus
);
if
(
err
<
0
)
goto
out_bus
;
bt_class
=
class_create
(
THIS_MODULE
,
"bluetooth"
);
bt_class
=
class_create
(
THIS_MODULE
,
"bluetooth"
);
if
(
IS_ERR
(
bt_class
))
{
if
(
IS_ERR
(
bt_class
))
{
err
=
PTR_ERR
(
bt_class
);
destroy_workqueue
(
btdelconn
);
goto
out_class
;
destroy_workqueue
(
btaddconn
);
return
PTR_ERR
(
bt_class
);
}
}
return
0
;
return
0
;
out_class:
bus_unregister
(
&
bt_bus
);
out_bus:
platform_device_unregister
(
bt_platform
);
out_platform:
destroy_workqueue
(
btdelconn
);
out_del:
destroy_workqueue
(
btaddconn
);
out:
return
err
;
}
}
void
bt_sysfs_cleanup
(
void
)
void
bt_sysfs_cleanup
(
void
)
{
{
destroy_workqueue
(
btaddconn
);
destroy_workqueue
(
btaddconn
);
destroy_workqueue
(
btdelconn
);
destroy_workqueue
(
btdelconn
);
class_destroy
(
bt_class
);
class_destroy
(
bt_class
);
bus_unregister
(
&
bt_bus
);
platform_device_unregister
(
bt_platform
);
}
}
net/bluetooth/l2cap.c
浏览文件 @
d2805395
...
@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
...
@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
module_init
(
l2cap_init
);
module_init
(
l2cap_init
);
module_exit
(
l2cap_exit
);
module_exit
(
l2cap_exit
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth L2CAP ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth L2CAP ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/rfcomm/core.c
浏览文件 @
d2805395
...
@@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
...
@@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
module_param
(
l2cap_mtu
,
uint
,
0644
);
module_param
(
l2cap_mtu
,
uint
,
0644
);
MODULE_PARM_DESC
(
l2cap_mtu
,
"Default MTU for the L2CAP connection"
);
MODULE_PARM_DESC
(
l2cap_mtu
,
"Default MTU for the L2CAP connection"
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth RFCOMM ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth RFCOMM ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/sco.c
浏览文件 @
d2805395
...
@@ -1002,7 +1002,7 @@ module_exit(sco_exit);
...
@@ -1002,7 +1002,7 @@ module_exit(sco_exit);
module_param
(
disable_esco
,
bool
,
0644
);
module_param
(
disable_esco
,
bool
,
0644
);
MODULE_PARM_DESC
(
disable_esco
,
"Disable eSCO connection creation"
);
MODULE_PARM_DESC
(
disable_esco
,
"Disable eSCO connection creation"
);
MODULE_AUTHOR
(
"Ma
xim Krasnyansky <maxk@qualcomm.com>, Ma
rcel Holtmann <marcel@holtmann.org>"
);
MODULE_AUTHOR
(
"Marcel Holtmann <marcel@holtmann.org>"
);
MODULE_DESCRIPTION
(
"Bluetooth SCO ver "
VERSION
);
MODULE_DESCRIPTION
(
"Bluetooth SCO ver "
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录