Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d2805395
Commit
d2805395
authored
Aug 19, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
parents
f3b9605d
63fbd24e
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
476 additions
and
297 deletions
+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
No files found.
MAINTAINERS
View file @
d2805395
...
...
@@ -936,94 +936,19 @@ M: joern@lazybastard.org
L: linux-mtd@lists.infradead.org
S: Maintained
BLUETOOTH
SUBSYSTEM
BLUETOOTH
DRIVERS
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
L: linux-bluetooth@vger.kernel.org
W: http://bluez.sf.net
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
W: http://www.bluez.org/
S: Maintained
BLUETOOTH HIDP LAYER
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
BLUETOOTH SUBSYSTEM
P: Marcel Holtmann
M: marcel@holtmann.org
S: Maintained
BLUETOOTH HCI VHCI DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
T: git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
S: Maintained
BONDING DRIVER
...
...
drivers/bluetooth/Kconfig
View file @
d2805395
...
...
@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
depends on BT
config BT_HCIUSB
tristate "HCI USB driver"
depends on USB
tristate "HCI USB driver
(old version)
"
depends on USB
&& BT_HCIBTUSB=n
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
...
...
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
Say Y here to compile support for SCO over HCI USB.
config BT_HCIBTUSB
tristate "HCI USB driver
(alternate version)
"
depends on USB
&& EXPERIMENTAL && BT_HCIUSB=n
tristate "HCI USB driver"
depends on USB
help
Bluetooth HCI USB driver.
This driver is required if you want to use Bluetooth devices with
USB interface.
This driver is still experimental and has no SCO support.
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (btusb).
...
...
drivers/bluetooth/bt3c_cs.c
View file @
d2805395
...
...
@@ -60,7 +60,7 @@
/* ======================== 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_LICENSE
(
"GPL"
);
MODULE_FIRMWARE
(
"BT3CPCC.bin"
);
...
...
drivers/bluetooth/btusb.c
View file @
d2805395
...
...
@@ -2,7 +2,7 @@
*
* 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
...
...
@@ -41,7 +41,7 @@
#define BT_DBG(D...)
#endif
#define VERSION "0.
2
"
#define VERSION "0.
3
"
static
int
ignore_dga
;
static
int
ignore_csr
;
...
...
@@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
{
}
/* Terminating entry */
};
#define BTUSB_MAX_ISOC_FRAMES 10
#define BTUSB_INTR_RUNNING 0
#define BTUSB_BULK_RUNNING 1
#define BTUSB_ISOC_RUNNING 2
struct
btusb_data
{
struct
hci_dev
*
hdev
;
struct
usb_device
*
udev
;
struct
usb_interface
*
isoc
;
spinlock_t
lock
;
...
...
@@ -176,10 +180,15 @@ struct btusb_data {
struct
usb_anchor
tx_anchor
;
struct
usb_anchor
intr_anchor
;
struct
usb_anchor
bulk_anchor
;
struct
usb_anchor
isoc_anchor
;
struct
usb_endpoint_descriptor
*
intr_ep
;
struct
usb_endpoint_descriptor
*
bulk_tx_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
)
...
...
@@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
return
;
if
(
urb
->
status
==
0
)
{
hdev
->
stat
.
byte_rx
+=
urb
->
actual_length
;
if
(
hci_recv_fragment
(
hdev
,
HCI_EVENT_PKT
,
urb
->
transfer_buffer
,
urb
->
actual_length
)
<
0
)
{
...
...
@@ -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
urb
*
urb
;
...
...
@@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
data
->
intr_ep
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
if
(
!
urb
)
return
-
ENOMEM
;
...
...
@@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
return
;
if
(
urb
->
status
==
0
)
{
hdev
->
stat
.
byte_rx
+=
urb
->
actual_length
;
if
(
hci_recv_fragment
(
hdev
,
HCI_ACLDATA_PKT
,
urb
->
transfer_buffer
,
urb
->
actual_length
)
<
0
)
{
...
...
@@ -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
urb
*
urb
;
...
...
@@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
BT_DBG
(
"%s"
,
hdev
->
name
);
if
(
!
data
->
bulk_rx_ep
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
urb
)
return
-
ENOMEM
;
...
...
@@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
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
)
{
struct
sk_buff
*
skb
=
urb
->
context
;
...
...
@@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
if
(
!
test_and_clear_bit
(
HCI_RUNNING
,
&
hdev
->
flags
))
return
0
;
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
intr_anchor
);
clear_bit
(
BTUSB_BULK_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
...
...
@@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
break
;
case
HCI_ACLDATA_PKT
:
if
(
!
data
->
bulk_tx_ep
||
hdev
->
conn_hash
.
acl_num
<
1
)
return
-
ENODEV
;
urb
=
usb_alloc_urb
(
0
,
GFP_ATOMIC
);
if
(
!
urb
)
return
-
ENOMEM
;
...
...
@@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
break
;
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
++
;
kfree_skb
(
skb
);
return
0
;
break
;
default:
return
-
EILSEQ
;
...
...
@@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
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
)
{
struct
btusb_data
*
data
=
container_of
(
work
,
struct
btusb_data
,
work
);
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
);
usb_kill_anchored_urbs
(
&
data
->
bulk_anchor
);
return
;
}
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
);
if
(
hdev
->
conn_hash
.
sco_num
>
0
)
{
if
(
data
->
isoc_altsetting
!=
2
)
{
clear_bit
(
BTUSB_ISOC_RUNNING
,
&
data
->
flags
);
usb_kill_anchored_urbs
(
&
data
->
isoc_anchor
);
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,
init_usb_anchor
(
&
data
->
tx_anchor
);
init_usb_anchor
(
&
data
->
intr_anchor
);
init_usb_anchor
(
&
data
->
bulk_anchor
);
init_usb_anchor
(
&
data
->
isoc_anchor
);
hdev
=
hci_alloc_dev
();
if
(
!
hdev
)
{
...
...
@@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
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
)
set_bit
(
HCI_QUIRK_RESET_ON_INIT
,
&
hdev
->
quirks
);
...
...
@@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
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
)
{
struct
usb_device
*
udev
=
interface_to_usbdev
(
intf
)
;
struct
usb_device
*
udev
=
data
->
udev
;
if
(
le16_to_cpu
(
udev
->
descriptor
.
bcdDevice
)
>
0x997
)
set_bit
(
HCI_QUIRK_RAW_DEVICE
,
&
hdev
->
quirks
);
data
->
isoc
=
NULL
;
}
if
(
id
->
driver_info
&
BTUSB_BCM92035
)
{
...
...
@@ -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
);
if
(
err
<
0
)
{
hci_free_dev
(
hdev
);
...
...
@@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
hdev
=
data
->
hdev
;
if
(
data
->
isoc
)
usb_driver_release_interface
(
&
btusb_driver
,
data
->
isoc
);
usb_set_intfdata
(
intf
,
NULL
);
hci_unregister_dev
(
hdev
);
...
...
drivers/bluetooth/hci_ldisc.c
View file @
d2805395
...
...
@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
module_param
(
reset
,
bool
,
0644
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
drivers/bluetooth/hci_usb.c
View file @
d2805395
...
...
@@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
MODULE_PARM_DESC
(
isoc
,
"Set isochronous transfers for SCO over HCI support"
);
#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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
drivers/bluetooth/hci_vhci.c
View file @
d2805395
...
...
@@ -377,7 +377,7 @@ module_exit(vhci_exit);
module_param
(
minor
,
int
,
0444
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
net/bluetooth/af_bluetooth.c
View file @
d2805395
...
...
@@ -456,7 +456,7 @@ static void __exit bt_exit(void)
subsys_initcall
(
bt_init
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/bnep/core.c
View file @
d2805395
...
...
@@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
module_param
(
compress_dst
,
bool
,
0644
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/hci_sysfs.c
View file @
d2805395
...
...
@@ -3,8 +3,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
...
...
@@ -12,10 +10,164 @@
#undef BT_DBG
#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
*
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
)
{
case
HCI_VIRTUAL
:
...
...
@@ -40,7 +192,7 @@ static inline char *typetostr(int type)
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
"
,
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
)
...
...
@@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
static
DEVICE_ATTR
(
sniff_min_interval
,
S_IRUGO
|
S_IWUSR
,
show_sniff_min_interval
,
store_sniff_min_interval
);
static
struct
device_attribute
*
b
t_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
,
static
struct
attribute
*
bt_hos
t_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
,
NULL
};
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
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
static
struct
attribute_group
bt_host_group
=
{
.
attrs
=
bt_host_attrs
,
};
struct
class
*
bt_class
=
NULL
;
EXPORT_SYMBOL_GPL
(
bt_class
);
static
struct
bus_type
bt_bus
=
{
.
name
=
"bluetooth"
,
static
struct
attribute_group
*
bt_host_groups
[]
=
{
&
bt_host_group
,
NULL
};
static
struct
platform_device
*
bt_platform
;
static
void
bt_release
(
struct
device
*
dev
)
static
void
bt_host_release
(
struct
device
*
dev
)
{
void
*
data
=
dev_get_drvdata
(
dev
);
kfree
(
data
);
}
static
void
add_conn
(
struct
work_struct
*
work
)
{
struct
hci_conn
*
conn
=
container_of
(
work
,
struct
hci_conn
,
work
);
int
i
;
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
);
}
static
struct
device_type
bt_host
=
{
.
name
=
"host"
,
.
groups
=
bt_host_groups
,
.
release
=
bt_host_release
,
};
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
->
bus
=
&
bt_bus
;
dev
->
type
=
&
bt_host
;
dev
->
class
=
bt_class
;
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
;
}
...
...
@@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
int
__init
bt_sysfs_init
(
void
)
{
int
err
;
btaddconn
=
create_singlethread_workqueue
(
"btaddconn"
);
if
(
!
btaddconn
)
{
err
=
-
ENOMEM
;
goto
out
;
}
if
(
!
btaddconn
)
return
-
ENOMEM
;
btdelconn
=
create_singlethread_workqueue
(
"btdelconn"
);
if
(
!
btdelconn
)
{
err
=
-
ENOMEM
;
goto
out_del
;
}
bt_platform
=
platform_device_register_simple
(
"bluetooth"
,
-
1
,
NULL
,
0
);
if
(
IS_ERR
(
bt_platform
))
{
err
=
PTR_ERR
(
bt_platform
);
goto
out_platform
;
destroy_workqueue
(
btaddconn
);
return
-
ENOMEM
;
}
err
=
bus_register
(
&
bt_bus
);
if
(
err
<
0
)
goto
out_bus
;
bt_class
=
class_create
(
THIS_MODULE
,
"bluetooth"
);
if
(
IS_ERR
(
bt_class
))
{
err
=
PTR_ERR
(
bt_class
);
goto
out_class
;
destroy_workqueue
(
btdelconn
);
destroy_workqueue
(
btaddconn
);
return
PTR_ERR
(
bt_class
);
}
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
)
{
destroy_workqueue
(
btaddconn
);
destroy_workqueue
(
btdelconn
);
class_destroy
(
bt_class
);
bus_unregister
(
&
bt_bus
);
platform_device_unregister
(
bt_platform
);
}
net/bluetooth/l2cap.c
View file @
d2805395
...
...
@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
module_init
(
l2cap_init
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/rfcomm/core.c
View file @
d2805395
...
...
@@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
module_param
(
l2cap_mtu
,
uint
,
0644
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/bluetooth/sco.c
View file @
d2805395
...
...
@@ -1002,7 +1002,7 @@ module_exit(sco_exit);
module_param
(
disable_esco
,
bool
,
0644
);
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_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment