Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
1e98cadb
L
linux
项目概览
Linux-御风守护者
/
linux
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1e98cadb
编写于
1月 31, 2010
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
上级
71cc1fa9
6bf8268f
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
254 addition
and
47 deletion
+254
-47
drivers/bluetooth/Kconfig
drivers/bluetooth/Kconfig
+12
-1
drivers/bluetooth/Makefile
drivers/bluetooth/Makefile
+1
-0
drivers/bluetooth/ath3k.c
drivers/bluetooth/ath3k.c
+187
-0
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bluecard_cs.c
+3
-1
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/bt3c_cs.c
+3
-1
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/btuart_cs.c
+3
-1
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/dtl1_cs.c
+3
-1
net/bluetooth/hidp/core.c
net/bluetooth/hidp/core.c
+36
-34
net/bluetooth/l2cap.c
net/bluetooth/l2cap.c
+6
-8
未找到文件。
drivers/bluetooth/Kconfig
浏览文件 @
1e98cadb
...
...
@@ -195,5 +195,16 @@ config BT_MRVL_SDIO
Say Y here to compile support for Marvell BT-over-SDIO driver
into the kernel or say M to compile it as module.
endmenu
config BT_ATH3K
tristate "Atheros firmware download driver"
depends on BT_HCIBTUSB
select FW_LOADER
help
Bluetooth firmware download driver.
This driver loads the firmware into the Atheros Bluetooth
chipset.
Say Y here to compile support for "Atheros firmware download driver"
into the kernel or say M to compile it as module (ath3k).
endmenu
drivers/bluetooth/Makefile
浏览文件 @
1e98cadb
...
...
@@ -15,6 +15,7 @@ obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
obj-$(CONFIG_BT_HCIBTUSB)
+=
btusb.o
obj-$(CONFIG_BT_HCIBTSDIO)
+=
btsdio.o
obj-$(CONFIG_BT_ATH3K)
+=
ath3k.o
obj-$(CONFIG_BT_MRVL)
+=
btmrvl.o
obj-$(CONFIG_BT_MRVL_SDIO)
+=
btmrvl_sdio.o
...
...
drivers/bluetooth/ath3k.c
0 → 100644
浏览文件 @
1e98cadb
/*
* Copyright (c) 2008-2009 Atheros Communications Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/usb.h>
#include <net/bluetooth/bluetooth.h>
#define VERSION "1.0"
static
struct
usb_device_id
ath3k_table
[]
=
{
/* Atheros AR3011 */
{
USB_DEVICE
(
0x0CF3
,
0x3000
)
},
{
}
/* Terminating entry */
};
MODULE_DEVICE_TABLE
(
usb
,
ath3k_table
);
#define USB_REQ_DFU_DNLOAD 1
#define BULK_SIZE 4096
struct
ath3k_data
{
struct
usb_device
*
udev
;
u8
*
fw_data
;
u32
fw_size
;
u32
fw_sent
;
};
static
int
ath3k_load_firmware
(
struct
ath3k_data
*
data
,
unsigned
char
*
firmware
,
int
count
)
{
u8
*
send_buf
;
int
err
,
pipe
,
len
,
size
,
sent
=
0
;
BT_DBG
(
"ath3k %p udev %p"
,
data
,
data
->
udev
);
pipe
=
usb_sndctrlpipe
(
data
->
udev
,
0
);
if
((
usb_control_msg
(
data
->
udev
,
pipe
,
USB_REQ_DFU_DNLOAD
,
USB_TYPE_VENDOR
,
0
,
0
,
firmware
,
20
,
USB_CTRL_SET_TIMEOUT
))
<
0
)
{
BT_ERR
(
"Can't change to loading configuration err"
);
return
-
EBUSY
;
}
sent
+=
20
;
count
-=
20
;
send_buf
=
kmalloc
(
BULK_SIZE
,
GFP_ATOMIC
);
if
(
!
send_buf
)
{
BT_ERR
(
"Can't allocate memory chunk for firmware"
);
return
-
ENOMEM
;
}
while
(
count
)
{
size
=
min_t
(
uint
,
count
,
BULK_SIZE
);
pipe
=
usb_sndbulkpipe
(
data
->
udev
,
0x02
);
memcpy
(
send_buf
,
firmware
+
sent
,
size
);
err
=
usb_bulk_msg
(
data
->
udev
,
pipe
,
send_buf
,
size
,
&
len
,
3000
);
if
(
err
||
(
len
!=
size
))
{
BT_ERR
(
"Error in firmware loading err = %d,"
"len = %d, size = %d"
,
err
,
len
,
size
);
goto
error
;
}
sent
+=
size
;
count
-=
size
;
}
kfree
(
send_buf
);
return
0
;
error:
kfree
(
send_buf
);
return
err
;
}
static
int
ath3k_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
{
const
struct
firmware
*
firmware
;
struct
usb_device
*
udev
=
interface_to_usbdev
(
intf
);
struct
ath3k_data
*
data
;
int
size
;
BT_DBG
(
"intf %p id %p"
,
intf
,
id
);
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
return
-
ENODEV
;
data
=
kzalloc
(
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
!
data
)
return
-
ENOMEM
;
data
->
udev
=
udev
;
if
(
request_firmware
(
&
firmware
,
"ath3k-1.fw"
,
&
udev
->
dev
)
<
0
)
{
kfree
(
data
);
return
-
EIO
;
}
size
=
max_t
(
uint
,
firmware
->
size
,
4096
);
data
->
fw_data
=
kmalloc
(
size
,
GFP_KERNEL
);
if
(
!
data
->
fw_data
)
{
release_firmware
(
firmware
);
kfree
(
data
);
return
-
ENOMEM
;
}
memcpy
(
data
->
fw_data
,
firmware
->
data
,
firmware
->
size
);
data
->
fw_size
=
firmware
->
size
;
data
->
fw_sent
=
0
;
release_firmware
(
firmware
);
usb_set_intfdata
(
intf
,
data
);
if
(
ath3k_load_firmware
(
data
,
data
->
fw_data
,
data
->
fw_size
))
{
usb_set_intfdata
(
intf
,
NULL
);
return
-
EIO
;
}
return
0
;
}
static
void
ath3k_disconnect
(
struct
usb_interface
*
intf
)
{
struct
ath3k_data
*
data
=
usb_get_intfdata
(
intf
);
BT_DBG
(
"ath3k_disconnect intf %p"
,
intf
);
kfree
(
data
->
fw_data
);
kfree
(
data
);
}
static
struct
usb_driver
ath3k_driver
=
{
.
name
=
"ath3k"
,
.
probe
=
ath3k_probe
,
.
disconnect
=
ath3k_disconnect
,
.
id_table
=
ath3k_table
,
};
static
int
__init
ath3k_init
(
void
)
{
BT_INFO
(
"Atheros AR30xx firmware driver ver %s"
,
VERSION
);
return
usb_register
(
&
ath3k_driver
);
}
static
void
__exit
ath3k_exit
(
void
)
{
usb_deregister
(
&
ath3k_driver
);
}
module_init
(
ath3k_init
);
module_exit
(
ath3k_exit
);
MODULE_AUTHOR
(
"Atheros Communications"
);
MODULE_DESCRIPTION
(
"Atheros AR30xx firmware driver"
);
MODULE_VERSION
(
VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_FIRMWARE
(
"ath3k-1.fw"
);
drivers/bluetooth/bluecard_cs.c
浏览文件 @
1e98cadb
...
...
@@ -503,7 +503,9 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
unsigned
int
iobase
;
unsigned
char
reg
;
BUG_ON
(
!
info
->
hdev
);
if
(
!
info
||
!
info
->
hdev
)
/* our irq handler is shared */
return
IRQ_NONE
;
if
(
!
test_bit
(
CARD_READY
,
&
(
info
->
hw_state
)))
return
IRQ_HANDLED
;
...
...
drivers/bluetooth/bt3c_cs.c
浏览文件 @
1e98cadb
...
...
@@ -345,7 +345,9 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
int
iir
;
irqreturn_t
r
=
IRQ_NONE
;
BUG_ON
(
!
info
->
hdev
);
if
(
!
info
||
!
info
->
hdev
)
/* our irq handler is shared */
return
IRQ_NONE
;
iobase
=
info
->
p_dev
->
io
.
BasePort1
;
...
...
drivers/bluetooth/btuart_cs.c
浏览文件 @
1e98cadb
...
...
@@ -295,7 +295,9 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
int
iir
,
lsr
;
irqreturn_t
r
=
IRQ_NONE
;
BUG_ON
(
!
info
->
hdev
);
if
(
!
info
||
!
info
->
hdev
)
/* our irq handler is shared */
return
IRQ_NONE
;
iobase
=
info
->
p_dev
->
io
.
BasePort1
;
...
...
drivers/bluetooth/dtl1_cs.c
浏览文件 @
1e98cadb
...
...
@@ -299,7 +299,9 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
int
iir
,
lsr
;
irqreturn_t
r
=
IRQ_NONE
;
BUG_ON
(
!
info
->
hdev
);
if
(
!
info
||
!
info
->
hdev
)
/* our irq handler is shared */
return
IRQ_NONE
;
iobase
=
info
->
p_dev
->
io
.
BasePort1
;
...
...
net/bluetooth/hidp/core.c
浏览文件 @
1e98cadb
...
...
@@ -243,6 +243,39 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
input_sync
(
dev
);
}
static
int
__hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
struct
sk_buff
*
skb
;
BT_DBG
(
"session %p data %p size %d"
,
session
,
data
,
size
);
if
(
!
(
skb
=
alloc_skb
(
size
+
1
,
GFP_ATOMIC
)))
{
BT_ERR
(
"Can't allocate memory for new frame"
);
return
-
ENOMEM
;
}
*
skb_put
(
skb
,
1
)
=
hdr
;
if
(
data
&&
size
>
0
)
memcpy
(
skb_put
(
skb
,
size
),
data
,
size
);
skb_queue_tail
(
&
session
->
ctrl_transmit
,
skb
);
return
0
;
}
static
inline
int
hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
int
err
;
err
=
__hidp_send_ctrl_message
(
session
,
hdr
,
data
,
size
);
hidp_schedule
(
session
);
return
err
;
}
static
int
hidp_queue_report
(
struct
hidp_session
*
session
,
unsigned
char
*
data
,
int
size
)
{
...
...
@@ -282,7 +315,9 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
static
int
hidp_output_raw_report
(
struct
hid_device
*
hid
,
unsigned
char
*
data
,
size_t
count
)
{
if
(
hidp_queue_report
(
hid
->
driver_data
,
data
,
count
))
if
(
hidp_send_ctrl_message
(
hid
->
driver_data
,
HIDP_TRANS_SET_REPORT
|
HIDP_DATA_RTYPE_FEATURE
,
data
,
count
))
return
-
ENOMEM
;
return
count
;
}
...
...
@@ -307,39 +342,6 @@ static inline void hidp_del_timer(struct hidp_session *session)
del_timer
(
&
session
->
timer
);
}
static
int
__hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
struct
sk_buff
*
skb
;
BT_DBG
(
"session %p data %p size %d"
,
session
,
data
,
size
);
if
(
!
(
skb
=
alloc_skb
(
size
+
1
,
GFP_ATOMIC
)))
{
BT_ERR
(
"Can't allocate memory for new frame"
);
return
-
ENOMEM
;
}
*
skb_put
(
skb
,
1
)
=
hdr
;
if
(
data
&&
size
>
0
)
memcpy
(
skb_put
(
skb
,
size
),
data
,
size
);
skb_queue_tail
(
&
session
->
ctrl_transmit
,
skb
);
return
0
;
}
static
inline
int
hidp_send_ctrl_message
(
struct
hidp_session
*
session
,
unsigned
char
hdr
,
unsigned
char
*
data
,
int
size
)
{
int
err
;
err
=
__hidp_send_ctrl_message
(
session
,
hdr
,
data
,
size
);
hidp_schedule
(
session
);
return
err
;
}
static
void
hidp_process_handshake
(
struct
hidp_session
*
session
,
unsigned
char
param
)
{
...
...
net/bluetooth/l2cap.c
浏览文件 @
1e98cadb
...
...
@@ -1368,7 +1368,6 @@ static int l2cap_ertm_send(struct sock *sk)
while
((
skb
=
sk
->
sk_send_head
)
&&
(
!
l2cap_tx_window_full
(
sk
))
&&
!
(
pi
->
conn_state
&
L2CAP_CONN_REMOTE_BUSY
))
{
tx_skb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
if
(
pi
->
remote_max_tx
&&
bt_cb
(
skb
)
->
retries
==
pi
->
remote_max_tx
)
{
...
...
@@ -1376,6 +1375,8 @@ static int l2cap_ertm_send(struct sock *sk)
break
;
}
tx_skb
=
skb_clone
(
skb
,
GFP_ATOMIC
);
bt_cb
(
skb
)
->
retries
++
;
control
=
get_unaligned_le16
(
tx_skb
->
data
+
L2CAP_HDR_SIZE
);
...
...
@@ -3518,7 +3519,6 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
struct
l2cap_pinfo
*
pi
;
u16
control
,
len
;
u8
tx_seq
;
int
err
;
sk
=
l2cap_get_chan_by_scid
(
&
conn
->
chan_list
,
cid
);
if
(
!
sk
)
{
...
...
@@ -3570,13 +3570,11 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
goto
drop
;
if
(
__is_iframe
(
control
))
err
=
l2cap_data_channel_iframe
(
sk
,
control
,
skb
);
l2cap_data_channel_iframe
(
sk
,
control
,
skb
);
else
err
=
l2cap_data_channel_sframe
(
sk
,
control
,
skb
);
l2cap_data_channel_sframe
(
sk
,
control
,
skb
);
if
(
!
err
)
goto
done
;
break
;
case
L2CAP_MODE_STREAMING
:
control
=
get_unaligned_le16
(
skb
->
data
);
...
...
@@ -3602,7 +3600,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
else
pi
->
expected_tx_seq
=
tx_seq
+
1
;
err
=
l2cap_sar_reassembly_sdu
(
sk
,
skb
,
control
);
l2cap_sar_reassembly_sdu
(
sk
,
skb
,
control
);
goto
done
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录