Commit 9b94cba7 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/bluetooth-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 77882f74 6e3fccfc
......@@ -359,6 +359,8 @@ P: Maxim Krasnyansky
M: maxk@qualcomm.com
L: bluez-devel@lists.sf.net
W: http://bluez.sf.net
W: http://www.bluez.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH RFCOMM LAYER
......@@ -366,7 +368,6 @@ P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH BNEP LAYER
......@@ -374,71 +375,60 @@ P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH CMTP LAYER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI USB DRIVER
BLUETOOTH HCI UART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH HCI UART DRIVER
BLUETOOTH HCI USB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH HCI BCM203X DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BFUSB DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI DTL1 DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BLUECARD DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BT3C DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI BTUART DRIVER
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BLUETOOTH HCI VHCI DRIVER
P: Maxim Krasnyansky
M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BONDING DRIVER
......
......@@ -29,9 +29,7 @@
* Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
*
* $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $
*/
#define VERSION "2.5"
#include <linux/config.h>
#include <linux/module.h>
......@@ -57,9 +55,9 @@
#ifndef CONFIG_BT_HCIUSB_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#undef BT_DMP
#define BT_DMP( A... )
#define BT_DMP(D...)
#endif
#ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
......@@ -67,6 +65,8 @@
#define URB_ZERO_PACKET 0
#endif
#define VERSION "2.6"
static struct usb_driver hci_usb_driver;
static struct usb_device_id bluetooth_ids[] = {
......@@ -100,7 +100,10 @@ static struct usb_device_id blacklist_ids[] = {
/* Digianswer device */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
{ } /* Terminating entry */
/* RTX Telecom based adapter with buggy SCO support */
{ USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
{ } /* Terminating entry */
};
struct _urb *_urb_alloc(int isoc, int gfp)
......@@ -393,7 +396,7 @@ static int hci_usb_close(struct hci_dev *hdev)
{
struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
unsigned long flags;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
......@@ -402,7 +405,7 @@ static int hci_usb_close(struct hci_dev *hdev)
/* Synchronize with completion handlers */
write_lock_irqsave(&husb->completion_lock, flags);
write_unlock_irqrestore(&husb->completion_lock, flags);
hci_usb_unlink_urbs(husb);
hci_usb_flush(hdev);
return 0;
......@@ -414,7 +417,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
int err;
BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
_urb_queue_tail(__pending_q(husb, _urb->type), _urb);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
......@@ -551,7 +554,7 @@ static void hci_usb_tx_process(struct hci_usb *husb)
skb_queue_head(q, skb);
}
#endif
/* Process ACL queue */
q = __transmit_q(husb, HCI_ACLDATA_PKT);
while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
......@@ -656,7 +659,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
if (count >= HCI_SCO_HDR_SIZE) {
struct hci_sco_hdr *h = data;
len = HCI_SCO_HDR_SIZE + h->dlen;
} else
} else
return -EILSEQ;
break;
#endif
......@@ -702,7 +705,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
struct _urb *_urb = container_of(urb, struct _urb, urb);
struct hci_usb *husb = (void *) urb->context;
struct hci_dev *hdev = husb->hdev;
int err, count = urb->actual_length;
int err, count = urb->actual_length;
BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
_urb->type, urb->status, count, urb->transfer_flags);
......@@ -743,7 +746,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
resubmit:
urb->dev = husb->udev;
err = usb_submit_urb(urb, GFP_ATOMIC);
err = usb_submit_urb(urb, GFP_ATOMIC);
BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
_urb->type, err);
......@@ -779,7 +782,7 @@ static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs)
_urb_queue_tail(__completed_q(husb, _urb->type), _urb);
hci_usb_tx_wakeup(husb);
read_unlock(&husb->completion_lock);
}
......@@ -819,9 +822,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
return -ENODEV;
/* Find endpoints that we need */
/* Find endpoints that we need */
uif = intf->cur_altsetting;
for (e = 0; e < uif->desc.bNumEndpoints; e++) {
ep = &uif->endpoint[e];
......@@ -862,16 +864,17 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
husb->ctrl_req = HCI_DIGI_REQ;
else
husb->ctrl_req = HCI_CTRL_REQ;
/* Find isochronous endpoints that we can use */
/* Find isochronous endpoints that we can use */
size = 0;
isoc_iface = NULL;
isoc_alts = 0;
isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO
isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
if (!(id->driver_info & HCI_BROKEN_ISOC))
isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
if (isoc_iface) {
int a;
struct usb_host_endpoint *isoc_out_ep = NULL;
......@@ -917,10 +920,10 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
}
}
#endif
husb->completion_lock = RW_LOCK_UNLOCKED;
for (i = 0; i < 4; i++) {
for (i = 0; i < 4; i++) {
skb_queue_head_init(&husb->transmit_q[i]);
_urb_queue_init(&husb->pending_q[i]);
_urb_queue_init(&husb->completed_q[i]);
......@@ -939,10 +942,10 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
hdev->driver_data = husb;
SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = hci_usb_open;
hdev->close = hci_usb_close;
hdev->flush = hci_usb_flush;
hdev->send = hci_usb_send_frame;
hdev->open = hci_usb_open;
hdev->close = hci_usb_close;
hdev->flush = hci_usb_flush;
hdev->send = hci_usb_send_frame;
hdev->destruct = hci_usb_destruct;
hdev->owner = THIS_MODULE;
......@@ -993,11 +996,11 @@ static void hci_usb_disconnect(struct usb_interface *intf)
}
static struct usb_driver hci_usb_driver = {
.owner = THIS_MODULE,
.name = "hci_usb",
.probe = hci_usb_probe,
.disconnect = hci_usb_disconnect,
.id_table = bluetooth_ids,
.owner = THIS_MODULE,
.name = "hci_usb",
.probe = hci_usb_probe,
.disconnect = hci_usb_disconnect,
.id_table = bluetooth_ids,
};
static int __init hci_usb_init(void)
......
......@@ -23,33 +23,28 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: hci_usb.h,v 1.2 2002/03/18 19:10:04 maxk Exp $
*/
#ifdef __KERNEL__
/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
#define HCI_DEV_CLASS 0xe0 /* Wireless class */
#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
#define HCI_DEV_CLASS 0xe0 /* Wireless class */
#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
#define HCI_CTRL_REQ 0x20
#define HCI_DIGI_REQ 0x40
#define HCI_CTRL_REQ 0x20
#define HCI_DIGI_REQ 0x40
#define HCI_IGNORE 0x01
#define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04
#define HCI_IGNORE 0x01
#define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04
#define HCI_BROKEN_ISOC 0x08
#define HCI_MAX_IFACE_NUM 3
#define HCI_MAX_IFACE_NUM 3
#define HCI_MAX_BULK_TX 4
#define HCI_MAX_BULK_RX 1
#define HCI_MAX_BULK_TX 4
#define HCI_MAX_BULK_RX 1
#define HCI_MAX_ISOC_RX 2
#define HCI_MAX_ISOC_TX 2
#define HCI_MAX_ISOC_FRAMES 10
#define HCI_MAX_ISOC_FRAMES 10
struct _urb_queue {
struct list_head head;
......@@ -79,16 +74,16 @@ static inline void _urb_queue_init(struct _urb_queue *q)
static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
{
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
list_add(&_urb->list, &q->head); _urb->queue = q;
spin_unlock_irqrestore(&q->lock, flags);
}
static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
{
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
list_add_tail(&_urb->list, &q->head); _urb->queue = q;
spin_unlock_irqrestore(&q->lock, flags);
}
......@@ -96,9 +91,9 @@ static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
static inline void _urb_unlink(struct _urb *_urb)
{
struct _urb_queue *q = _urb->queue;
unsigned long flags;
unsigned long flags;
if (q) {
spin_lock_irqsave(&q->lock, flags);
spin_lock_irqsave(&q->lock, flags);
list_del(&_urb->list); _urb->queue = NULL;
spin_unlock_irqrestore(&q->lock, flags);
}
......@@ -106,41 +101,33 @@ static inline void _urb_unlink(struct _urb *_urb)
struct _urb *_urb_dequeue(struct _urb_queue *q);
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
struct hci_usb {
struct hci_dev *hdev;
unsigned long state;
struct usb_device *udev;
struct usb_device *udev;
struct usb_host_endpoint *bulk_in_ep;
struct usb_host_endpoint *bulk_out_ep;
struct usb_host_endpoint *intr_in_ep;
struct usb_interface *isoc_iface;
struct usb_interface *isoc_iface;
struct usb_host_endpoint *isoc_out_ep;
struct usb_host_endpoint *isoc_in_ep;
__u8 ctrl_req;
struct sk_buff_head transmit_q[4];
struct sk_buff *reassembly[4]; // Reassembly buffers
struct sk_buff *reassembly[4]; /* Reassembly buffers */
rwlock_t completion_lock;
atomic_t pending_tx[4]; // Number of pending requests
struct _urb_queue pending_q[4]; // Pending requests
struct _urb_queue completed_q[4]; // Completed requests
atomic_t pending_tx[4]; /* Number of pending requests */
struct _urb_queue pending_q[4]; /* Pending requests */
struct _urb_queue completed_q[4]; /* Completed requests */
};
/* States */
#define HCI_USB_TX_PROCESS 1
#define HCI_USB_TX_WAKEUP 2
#endif /* __KERNEL__ */
......@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: bluetooth.h,v 1.8 2002/04/17 17:37:20 maxk Exp $
*/
#ifndef __BLUETOOTH_H
#define __BLUETOOTH_H
......@@ -41,26 +37,27 @@
#endif
/* Reserv for core and drivers use */
#define BT_SKB_RESERVE 8
#define BT_SKB_RESERVE 8
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define BTPROTO_SCO 2
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define BTPROTO_SCO 2
#define BTPROTO_RFCOMM 3
#define BTPROTO_BNEP 4
#define BTPROTO_CMTP 5
#define BTPROTO_HIDP 6
#define SOL_HCI 0
#define SOL_L2CAP 6
#define SOL_SCO 17
#define SOL_RFCOMM 18
#define SOL_HCI 0
#define SOL_L2CAP 6
#define SOL_SCO 17
#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" , __FUNCTION__ , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
#ifdef HCI_DATA_DUMP
#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len)
#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len)
#else
#define BT_DMP(D...)
#endif
......@@ -122,7 +119,7 @@ struct bt_sock {
struct bt_sock_list {
struct hlist_head head;
rwlock_t lock;
rwlock_t lock;
};
int bt_sock_register(int proto, struct net_proto_family *ops);
......@@ -139,7 +136,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct bt_skb_cb {
int incoming;
int incoming;
};
#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb))
......@@ -155,7 +152,7 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, int how)
}
static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long len,
int nb, int *err)
int nb, int *err)
{
struct sk_buff *skb;
......@@ -178,6 +175,6 @@ static inline int skb_frags_no(struct sk_buff *skb)
void bt_dump(char *pref, __u8 *buf, int count);
int bt_err(__u16 code);
int bt_err(__u16 code);
#endif /* __BLUETOOTH_H */
......@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: hci.h,v 1.4 2002/04/18 22:26:15 maxk Exp $
*/
#ifndef __HCI_H
#define __HCI_H
......
......@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: hci_core.h,v 1.3 2002/04/17 18:55:21 maxk Exp $
*/
#ifndef __HCI_CORE_H
#define __HCI_CORE_H
......@@ -63,12 +59,12 @@ struct hci_conn_hash {
struct hci_dev {
struct list_head list;
spinlock_t lock;
atomic_t refcnt;
atomic_t refcnt;
char name[8];
unsigned long flags;
__u16 id;
__u8 type;
__u8 type;
bdaddr_t bdaddr;
__u8 features[8];
__u16 voice_setting;
......@@ -79,38 +75,38 @@ struct hci_dev {
unsigned long quirks;
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
unsigned int acl_mtu;
unsigned int sco_mtu;
unsigned int sco_mtu;
unsigned int acl_pkts;
unsigned int sco_pkts;
unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
struct tasklet_struct cmd_task;
struct tasklet_struct cmd_task;
struct tasklet_struct rx_task;
struct tasklet_struct tx_task;
struct tasklet_struct tx_task;
struct sk_buff_head rx_q;
struct sk_buff_head raw_q;
struct sk_buff_head cmd_q;
struct sk_buff_head raw_q;
struct sk_buff_head cmd_q;
struct sk_buff *sent_cmd;
struct sk_buff *sent_cmd;
struct semaphore req_lock;
wait_queue_head_t req_wait_q;
__u32 req_status;
__u32 req_result;
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash;
struct hci_dev_stats stat;
struct hci_dev_stats stat;
void *driver_data;
void *core_data;
......@@ -118,12 +114,12 @@ struct hci_dev {
atomic_t promisc;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
struct proc_dir_entry *proc;
#endif
struct class_device class_dev;
struct module *owner;
struct module *owner;
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
......@@ -140,9 +136,9 @@ struct hci_conn {
atomic_t refcnt;
spinlock_t lock;
bdaddr_t dst;
__u16 handle;
__u16 state;
bdaddr_t dst;
__u16 handle;
__u16 state;
__u8 type;
__u8 out;
__u32 link_mode;
......@@ -154,12 +150,12 @@ struct hci_conn {
struct timer_list timer;
struct hci_dev *hdev;
struct hci_dev *hdev;
void *l2cap_data;
void *sco_data;
void *priv;
struct hci_conn *link;
struct hci_conn *link;
};
extern struct hci_proto *hci_proto[];
......@@ -215,7 +211,7 @@ static inline void hci_conn_hash_init(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash;
INIT_LIST_HEAD(&h->list);
spin_lock_init(&h->lock);
h->num = 0;
h->num = 0;
}
static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
......@@ -233,7 +229,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
}
static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
__u16 handle)
__u16 handle)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
......@@ -244,7 +240,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
if (c->handle == handle)
return c;
}
return NULL;
return NULL;
}
static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
......@@ -259,7 +255,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
if (c->type == type && !bacmp(&c->dst, ba))
return c;
}
return NULL;
return NULL;
}
void hci_acl_connect(struct hci_conn *conn);
......@@ -506,7 +502,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *)sk->sk_protinfo)
struct hci_pinfo {
struct hci_dev *hdev;
struct hci_dev *hdev;
struct hci_filter filter;
__u32 cmsg_mask;
};
......
......@@ -22,18 +22,14 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: l2cap.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
*/
#ifndef __L2CAP_H
#define __L2CAP_H
/* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
#define L2CAP_CONN_TIMEOUT (HZ * 40)
#define L2CAP_CONN_TIMEOUT (HZ * 40)
/* L2CAP socket address */
struct sockaddr_l2 {
......@@ -190,10 +186,10 @@ struct l2cap_chan_list {
struct l2cap_conn {
struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu;
unsigned int mtu;
spinlock_t lock;
......@@ -227,9 +223,9 @@ struct l2cap_pinfo {
__u16 sport;
struct l2cap_conn *conn;
struct sock *next_c;
struct sock *prev_c;
struct l2cap_conn *conn;
struct sock *next_c;
struct sock *prev_c;
};
#define L2CAP_CONF_REQ_SENT 0x01
......
......@@ -21,14 +21,6 @@
SOFTWARE IS DISCLAIMED.
*/
/*
RPN support - Dirk Husemann <hud@zurich.ibm.com>
*/
/*
* $Id: rfcomm.h,v 1.29 2002/10/02 20:26:17 maxk Exp $
*/
#ifndef __RFCOMM_H
#define __RFCOMM_H
......
......@@ -22,19 +22,15 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* $Id: sco.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
*/
#ifndef __SCO_H
#define __SCO_H
/* SCO defaults */
#define SCO_DEFAULT_MTU 500
#define SCO_DEFAULT_MTU 500
#define SCO_DEFAULT_FLUSH_TO 0xFFFF
#define SCO_CONN_TIMEOUT (HZ * 40)
#define SCO_DISCONN_TIMEOUT (HZ * 2)
#define SCO_CONN_TIMEOUT (HZ * 40)
#define SCO_DISCONN_TIMEOUT (HZ * 2)
#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
/* SCO socket address */
......
......@@ -14,22 +14,20 @@ menuconfig BT
Linux Bluetooth subsystem consist of several layers:
Bluetooth Core (HCI device and connection manager, scheduler)
HCI Device drivers (interface to the hardware)
L2CAP Module (L2CAP protocol)
SCO Module (SCO links)
RFCOMM Module (RFCOMM protocol)
BNEP Module (BNEP protocol)
CMTP Module (CMTP protocol)
HCI Device drivers (Interface to the hardware)
SCO Module (SCO audio links)
L2CAP Module (Logical Link Control and Adaptation Protocol)
RFCOMM Module (RFCOMM Protocol)
BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CAPI Message Transport Protocol)
Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
layer.
Say Y here to compile Bluetooth support into the kernel or say M to
compile it as module (bluetooth).
To use Linux Bluetooth subsystem, you will need several user-space
utilities like hciconfig and hcid. These utilities and updates to
Bluetooth kernel modules are provided in the BlueZ packages.
For more information, see <http://bluez.sourceforge.net/>.
If you want to compile Bluetooth Core as module (bluetooth) say M here.
For more information, see <http://www.bluez.org/>.
config BT_L2CAP
tristate "L2CAP protocol support"
......@@ -46,7 +44,7 @@ config BT_SCO
tristate "SCO links support"
depends on BT
help
SCO link provides voice transport over Bluetooth. SCO support is
SCO link provides voice transport over Bluetooth. SCO support is
required for voice applications like Headset and Audio.
Say Y here to compile SCO support into the kernel or say M to
......
......@@ -9,4 +9,4 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/
obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o syms.o
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
......@@ -22,12 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth address family and sockets.
*
* $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
*/
#define VERSION "2.4"
/* Bluetooth address family and sockets. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -53,13 +48,16 @@
#ifndef CONFIG_BT_SOCK_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
#define VERSION "2.5"
struct proc_dir_entry *proc_bt;
EXPORT_SYMBOL(proc_bt);
/* Bluetooth sockets */
#define BT_MAX_PROTO 6
#define BT_MAX_PROTO 7
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
static kmem_cache_t *bt_sock_cache;
......@@ -75,6 +73,7 @@ int bt_sock_register(int proto, struct net_proto_family *ops)
bt_proto[proto] = ops;
return 0;
}
EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto)
{
......@@ -87,6 +86,7 @@ int bt_sock_unregister(int proto)
bt_proto[proto] = NULL;
return 0;
}
EXPORT_SYMBOL(bt_sock_unregister);
static int bt_sock_create(struct socket *sock, int proto)
{
......@@ -116,7 +116,7 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio
sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct bt_sock), bt_sock_cache);
if (!sk)
return NULL;
if (pi_size) {
pi = kmalloc(pi_size, prio);
if (!pi) {
......@@ -129,13 +129,14 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio
sock_init_data(sock, sk);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_zapped = 0;
sk->sk_protocol = proto;
sk->sk_state = BT_OPEN;
return sk;
}
EXPORT_SYMBOL(bt_sock_alloc);
void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
{
......@@ -143,6 +144,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
sk_add_node(sk, &l->head);
write_unlock_bh(&l->lock);
}
EXPORT_SYMBOL(bt_sock_link);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
{
......@@ -150,6 +152,7 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
sk_del_node_init(sk);
write_unlock_bh(&l->lock);
}
EXPORT_SYMBOL(bt_sock_unlink);
void bt_accept_enqueue(struct sock *parent, struct sock *sk)
{
......@@ -160,6 +163,7 @@ void bt_accept_enqueue(struct sock *parent, struct sock *sk)
bt_sk(sk)->parent = parent;
parent->sk_ack_backlog++;
}
EXPORT_SYMBOL(bt_accept_enqueue);
static void bt_accept_unlink(struct sock *sk)
{
......@@ -175,19 +179,19 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{
struct list_head *p, *n;
struct sock *sk;
BT_DBG("parent %p", parent);
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
lock_sock(sk);
if (sk->sk_state == BT_CLOSED) {
release_sock(sk);
bt_accept_unlink(sk);
continue;
}
if (sk->sk_state == BT_CONNECTED || !newsock) {
bt_accept_unlink(sk);
if (newsock)
......@@ -199,6 +203,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
}
return NULL;
}
EXPORT_SYMBOL(bt_accept_dequeue);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
......@@ -235,6 +240,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return err ? : copied;
}
EXPORT_SYMBOL(bt_sock_recvmsg);
static inline unsigned int bt_accept_poll(struct sock *parent)
{
......@@ -287,6 +293,7 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
return mask;
}
EXPORT_SYMBOL(bt_sock_poll);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
{
......@@ -322,9 +329,10 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
remove_wait_queue(sk->sk_sleep, &wait);
return err;
}
EXPORT_SYMBOL(bt_sock_wait_state);
static struct net_proto_family bt_sock_family_ops = {
.owner = THIS_MODULE,
.owner = THIS_MODULE,
.family = PF_BLUETOOTH,
.create = bt_sock_create,
};
......@@ -342,7 +350,7 @@ static int __init bt_init(void)
proc_bt = proc_mkdir("bluetooth", NULL);
if (proc_bt)
proc_bt->owner = THIS_MODULE;
/* Init socket cache */
bt_sock_cache = kmem_cache_create("bt_sock",
sizeof(struct bt_sock), 0,
......@@ -352,7 +360,7 @@ static int __init bt_init(void)
BT_ERR("Socket cache creation failed");
return -ENOMEM;
}
sock_register(&bt_sock_family_ops);
BT_INFO("HCI device and connection manager initialized");
......
......@@ -4,12 +4,8 @@ config BT_BNEP
select CRC32
help
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
emulation layer on top of Bluetooth. BNEP is required for Bluetooth
PAN (Personal Area Network).
To use BNEP, you will need user-space utilities provided in the
BlueZ-PAN package.
For more information, see <http://bluez.sourceforge.net>.
emulation layer on top of Bluetooth. BNEP is required for
Bluetooth PAN (Personal Area Network).
Say Y here to compile BNEP support into the kernel or say M to
compile it as module (bnep).
......
......@@ -3,7 +3,7 @@ config BT_CMTP
depends on BT && BT_L2CAP && ISDN_CAPI
help
CMTP (CAPI Message Transport Protocol) is a transport layer
for CAPI messages. CMTP is required for the Bluetooth Common
for CAPI messages. CMTP is required for the Bluetooth Common
ISDN Access Profile.
Say Y here to compile CMTP support into the kernel or say M to
......
......@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* HCI Connection handling.
*
* $Id: hci_conn.c,v 1.2 2002/04/17 17:37:16 maxk Exp $
*/
/* Bluetooth HCI connection handling. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -54,7 +50,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
void hci_acl_connect(struct hci_conn *conn)
......@@ -178,10 +174,10 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
int hci_conn_del(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_dev *hdev = conn->hdev;
BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
hci_conn_del_timer(conn);
if (conn->type == SCO_LINK) {
......@@ -226,14 +222,14 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
list_for_each(p, &hci_dev_list) {
struct hci_dev *d = list_entry(p, struct hci_dev, list);
if (!test_bit(HCI_UP, &d->flags))
continue;
/* Simple routing:
* No source address - find interface with bdaddr != dst
* Source address - find interface with bdaddr == src
*/
* No source address - find interface with bdaddr != dst
* Source address - find interface with bdaddr == src
*/
if (use_src) {
if (!bacmp(&d->bdaddr, src)) {
......@@ -252,6 +248,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
read_unlock_bh(&hci_dev_list_lock);
return hdev;
}
EXPORT_SYMBOL(hci_get_route);
/* Create SCO or ACL connection.
* Device _must_ be locked */
......@@ -294,15 +291,16 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
return acl;
}
}
EXPORT_SYMBOL(hci_connect);
/* Authenticate remote device */
int hci_conn_auth(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
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);
......@@ -310,15 +308,16 @@ int hci_conn_auth(struct hci_conn *conn)
}
return 0;
}
EXPORT_SYMBOL(hci_conn_auth);
/* Enable encryption */
int hci_conn_encrypt(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (conn->link_mode & HCI_LM_ENCRYPT)
return 1;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;
......@@ -330,12 +329,13 @@ int hci_conn_encrypt(struct hci_conn *conn)
}
return 0;
}
EXPORT_SYMBOL(hci_conn_encrypt);
/* Drop all connection on the device */
void hci_conn_hash_flush(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct list_head *p;
BT_DBG("hdev %s", hdev->name);
......
......@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth HCI Core.
*
* $Id: hci_core.c,v 1.6 2002/04/17 17:37:16 maxk Exp $
*/
/* Bluetooth HCI core. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -55,7 +51,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
static void hci_cmd_task(unsigned long arg);
......@@ -288,6 +284,7 @@ struct hci_dev *hci_dev_get(int index)
read_unlock(&hci_dev_list_lock);
return hdev;
}
EXPORT_SYMBOL(hci_dev_get);
/* ---- Inquiry support ---- */
void inquiry_cache_flush(struct hci_dev *hdev)
......@@ -416,7 +413,7 @@ int hci_inquiry(unsigned long arg)
if (!copy_to_user(ptr, &ir, sizeof(ir))) {
ptr += sizeof(ir);
if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
ir.num_rsp))
err = -EFAULT;
} else
......@@ -459,7 +456,7 @@ int hci_dev_open(__u16 dev)
//__hci_request(hdev, hci_reset_req, 0, HZ);
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
clear_bit(HCI_INIT, &hdev->flags);
}
......@@ -514,7 +511,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN);
if (hdev->flush)
......@@ -558,7 +555,7 @@ int hci_dev_close(__u16 dev)
{
struct hci_dev *hdev;
int err;
if (!(hdev = hci_dev_get(dev)))
return -ENODEV;
err = hci_dev_do_close(hdev);
......@@ -649,19 +646,19 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg)
if (err)
break;
}
err = hci_request(hdev, hci_encrypt_req,
dr.dev_opt, HCI_INIT_TIMEOUT);
break;
case HCISETSCAN:
err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
break;
case HCISETPTYPE:
hdev->pkt_type = (__u16) dr.dev_opt;
break;
case HCISETLINKPOL:
hdev->link_policy = (__u16) dr.dev_opt;
break;
......@@ -683,7 +680,7 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg)
default:
err = -EINVAL;
break;
}
}
hci_dev_put(hdev);
return err;
}
......@@ -779,6 +776,7 @@ struct hci_dev *hci_alloc_dev(void)
return hdev;
}
EXPORT_SYMBOL(hci_alloc_dev);
/* Free HCI device */
void hci_free_dev(struct hci_dev *hdev)
......@@ -786,6 +784,7 @@ void hci_free_dev(struct hci_dev *hdev)
/* will free via class release */
class_device_put(&hdev->class_dev);
}
EXPORT_SYMBOL(hci_free_dev);
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
......@@ -802,7 +801,7 @@ int hci_register_dev(struct hci_dev *hdev)
/* Find first available device id */
list_for_each(p, &hci_dev_list) {
if (list_entry(p, struct hci_dev, list)->id != id)
if (list_entry(p, struct hci_dev, list)->id != id)
break;
head = p; id++;
}
......@@ -813,7 +812,7 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set(&hdev->refcnt, 1);
spin_lock_init(&hdev->lock);
hdev->flags = 0;
hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
hdev->link_mode = (HCI_LM_ACCEPT);
......@@ -836,7 +835,7 @@ int hci_register_dev(struct hci_dev *hdev)
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
atomic_set(&hdev->promisc, 0);
write_unlock_bh(&hci_dev_list_lock);
hci_register_sysfs(hdev);
......@@ -845,6 +844,7 @@ int hci_register_dev(struct hci_dev *hdev)
return id;
}
EXPORT_SYMBOL(hci_register_dev);
/* Unregister HCI device */
int hci_unregister_dev(struct hci_dev *hdev)
......@@ -864,6 +864,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
__hci_dev_put(hdev);
return 0;
}
EXPORT_SYMBOL(hci_unregister_dev);
/* Suspend HCI device */
int hci_suspend_dev(struct hci_dev *hdev)
......@@ -871,13 +872,15 @@ int hci_suspend_dev(struct hci_dev *hdev)
hci_notify(hdev, HCI_DEV_SUSPEND);
return 0;
}
EXPORT_SYMBOL(hci_suspend_dev);
/* Resume HCI device */
int hci_resume_dev(struct hci_dev *hdev)
{
hci_notify(hdev, HCI_DEV_RESUME);
return 0;
}
}
EXPORT_SYMBOL(hci_resume_dev);
/* ---- Interface to upper protocols ---- */
......@@ -903,6 +906,7 @@ int hci_register_proto(struct hci_proto *hp)
return err;
}
EXPORT_SYMBOL(hci_register_proto);
int hci_unregister_proto(struct hci_proto *hp)
{
......@@ -924,6 +928,7 @@ int hci_unregister_proto(struct hci_proto *hp)
return err;
}
EXPORT_SYMBOL(hci_unregister_proto);
static int hci_send_frame(struct sk_buff *skb)
{
......@@ -938,7 +943,7 @@ static int hci_send_frame(struct sk_buff *skb)
if (atomic_read(&hdev->promisc)) {
/* Time stamp */
do_gettimeofday(&skb->stamp);
do_gettimeofday(&skb->stamp);
hci_send_to_sock(hdev, skb);
}
......@@ -980,6 +985,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
return 0;
}
EXPORT_SYMBOL(hci_send_cmd);
/* Get data from the previously sent command */
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
......@@ -1026,7 +1032,7 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
if (!(list = skb_shinfo(skb)->frag_list)) {
/* Non fragmented */
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
skb_queue_tail(&conn->data_q, skb);
} else {
/* Fragmented */
......@@ -1044,7 +1050,7 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
skb->dev = (void *) hdev;
skb->pkt_type = HCI_ACLDATA_PKT;
hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
__skb_queue_tail(&conn->data_q, skb);
......@@ -1052,10 +1058,11 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
spin_unlock_bh(&conn->data_q.lock);
}
hci_sched_tx(hdev);
return 0;
}
EXPORT_SYMBOL(hci_send_acl);
/* Send SCO data */
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
......@@ -1082,6 +1089,7 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
hci_sched_tx(hdev);
return 0;
}
EXPORT_SYMBOL(hci_send_sco);
/* ---- HCI TX task (outgoing data) ---- */
......@@ -1091,7 +1099,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *conn = NULL;
int num = 0, min = ~0;
struct list_head *p;
struct list_head *p;
/* We don't have to lock device here. Connections are always
* added and removed with TX task disabled. */
......@@ -1124,7 +1132,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
static inline void hci_acl_tx_to(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p;
struct list_head *p;
struct hci_conn *c;
BT_ERR("%s ACL tx timeout", hdev->name);
......@@ -1265,7 +1273,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
hci_dev_unlock(hdev);
if (conn) {
register struct hci_proto *hp;
......@@ -1348,7 +1356,7 @@ static void hci_cmd_task(unsigned long arg)
BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1);
}
/* Send queued commands */
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
if (hdev->sent_cmd)
......
......@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* HCI Events.
*
* $Id: hci_event.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
*/
/* Bluetooth HCI event handling. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -54,7 +50,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
/* Handle HCI Event packets */
......@@ -98,9 +94,9 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
if (rd->status)
break;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
if (conn) {
if (rd->role)
......@@ -355,7 +351,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
......@@ -572,7 +568,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
hci_dev_unlock(hdev);
......@@ -585,7 +581,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (test_bit(HCI_AUTH, &hdev->flags))
conn->link_mode |= HCI_LM_AUTH;
if (test_bit(HCI_ENCRYPT, &hdev->flags))
conn->link_mode |= HCI_LM_ENCRYPT;
......@@ -643,7 +639,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) {
conn->state = BT_CLOSED;
......@@ -709,7 +705,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
return;
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) {
if (ev->role)
......@@ -731,7 +727,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
BT_DBG("%s status %d", hdev->name, ev->status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) {
if (!ev->status)
......@@ -739,7 +735,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
hci_proto_auth_cfm(conn, ev->status);
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!ev->status) {
struct hci_cp_set_conn_encrypt cp;
......@@ -768,11 +764,11 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
BT_DBG("%s status %d", hdev->name, ev->status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) {
if (!ev->status) {
if (ev->encrypt)
if (ev->encrypt)
conn->link_mode |= HCI_LM_ENCRYPT;
else
conn->link_mode &= ~HCI_LM_ENCRYPT;
......@@ -840,7 +836,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs));
opcode = __le16_to_cpu(cs->opcode);
ogf = hci_opcode_ogf(opcode);
ocf = hci_opcode_ocf(opcode);
......@@ -928,15 +924,16 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
return;
hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->evt = HCI_EV_STACK_INTERNAL;
hdr->plen = sizeof(*ev) + dlen;
ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type;
memcpy(ev->data, data, dlen);
skb->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb);
kfree_skb(skb);
}
EXPORT_SYMBOL(hci_si_event);
......@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth HCI socket layer.
*
* $Id: hci_sock.c,v 1.4 2002/04/18 22:26:14 maxk Exp $
*/
/* Bluetooth HCI sockets. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -56,7 +52,7 @@
#ifndef CONFIG_BT_HCI_SOCK_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
/* ----- HCI socket interface ----- */
......@@ -139,7 +135,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb);
}
read_unlock(&hci_sk_list.lock);
}
......@@ -318,14 +313,14 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_
__u32 mask = hci_pi(sk)->cmsg_mask;
if (mask & HCI_CMSG_DIR)
put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bt_cb(skb)->incoming);
put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bt_cb(skb)->incoming);
if (mask & HCI_CMSG_TSTAMP)
put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
}
static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags)
struct msghdr *msg, size_t len, int flags)
{
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
......@@ -355,7 +350,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
hci_sock_cmsg(sk, msg, skb);
skb_free_datagram(sk, skb);
return err ? : copied;
......@@ -406,7 +401,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (((ogf > HCI_SFLT_MAX_OGF) ||
!hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
!capable(CAP_NET_RAW)) {
!capable(CAP_NET_RAW)) {
err = -EPERM;
goto drop;
}
......@@ -487,9 +482,9 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user
uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
}
{
{
struct hci_filter *f = &hci_pi(sk)->filter;
f->type_mask = uf.type_mask;
f->opcode = uf.opcode;
*((u32 *) f->event_mask + 0) = uf.event_mask[0];
......@@ -501,7 +496,7 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user
err = -ENOPROTOOPT;
break;
}
release_sock(sk);
return err;
}
......@@ -539,7 +534,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user
case HCI_FILTER:
{
struct hci_filter *f = &hci_pi(sk)->filter;
uf.type_mask = f->type_mask;
uf.opcode = f->opcode;
uf.event_mask[0] = *((u32 *) f->event_mask + 0);
......@@ -560,23 +555,23 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user
}
struct proto_ops hci_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hci_sock_release,
.bind = hci_sock_bind,
.getname = hci_sock_getname,
.sendmsg = hci_sock_sendmsg,
.recvmsg = hci_sock_recvmsg,
.ioctl = hci_sock_ioctl,
.poll = datagram_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = hci_sock_setsockopt,
.getsockopt = hci_sock_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hci_sock_release,
.bind = hci_sock_bind,
.getname = hci_sock_getname,
.sendmsg = hci_sock_sendmsg,
.recvmsg = hci_sock_recvmsg,
.ioctl = hci_sock_ioctl,
.poll = datagram_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = hci_sock_setsockopt,
.getsockopt = hci_sock_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
};
static int hci_sock_create(struct socket *sock, int protocol)
......@@ -597,7 +592,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
sk_set_owner(sk, THIS_MODULE);
sock->state = SS_UNCONNECTED;
sk->sk_state = BT_OPEN;
sk->sk_state = BT_OPEN;
bt_sock_link(&hci_sk_list, sk);
return 0;
......@@ -607,14 +602,14 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
{
struct hci_dev *hdev = (struct hci_dev *) ptr;
struct hci_ev_si_device ev;
BT_DBG("hdev %s event %ld", hdev->name, event);
/* Send event to sockets */
ev.event = event;
ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) {
struct sock *sk;
struct hlist_node *node;
......@@ -640,9 +635,9 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
}
struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
.create = hci_sock_create,
};
struct notifier_block hci_sock_nblock = {
......
/* Bluetooth HCI driver model support. */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
......@@ -7,7 +9,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
static ssize_t show_name(struct class_device *cdev, char *buf)
......
......@@ -22,12 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth L2CAP core and sockets.
*
* $Id: l2cap.c,v 1.15 2002/09/09 01:14:52 maxk Exp $
*/
#define VERSION "2.1"
/* Bluetooth L2CAP core and sockets. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -59,9 +54,11 @@
#ifndef CONFIG_BT_L2CAP_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
#define VERSION "2.2"
static struct proto_ops l2cap_sock_ops;
struct bt_sock_list l2cap_sk_list = {
......@@ -135,11 +132,11 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
hcon->l2cap_data = conn;
conn->hcon = hcon;
conn->mtu = hcon->hdev->acl_mtu;
conn->src = &hcon->hdev->bdaddr;
conn->dst = &hcon->dst;
spin_lock_init(&conn->lock);
conn->chan_list.lock = RW_LOCK_UNLOCKED;
......@@ -374,10 +371,10 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
return -EPERM;
sock->ops = &l2cap_sock_ops;
sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL);
......@@ -407,6 +404,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
}
write_lock_bh(&l2cap_sk_list.lock);
if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
err = -EADDRINUSE;
} else {
......@@ -416,6 +414,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
l2cap_pi(sk)->sport = la->l2_psm;
sk->sk_state = BT_BOUND;
}
write_unlock_bh(&l2cap_sk_list.lock);
done:
......@@ -428,8 +427,8 @@ static int l2cap_do_connect(struct sock *sk)
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct l2cap_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
struct hci_conn *hcon;
struct hci_dev *hdev;
int err = 0;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
......@@ -550,8 +549,25 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
}
if (!l2cap_pi(sk)->psm) {
bdaddr_t *src = &bt_sk(sk)->src;
u16 psm;
err = -EINVAL;
goto done;
write_lock_bh(&l2cap_sk_list.lock);
for (psm = 0x1001; psm < 0x1100; psm += 2)
if (!__l2cap_get_sock_by_addr(psm, src)) {
l2cap_pi(sk)->psm = htobs(psm);
l2cap_pi(sk)->sport = htobs(psm);
err = 0;
break;
}
write_unlock_bh(&l2cap_sk_list.lock);
if (err < 0)
goto done;
}
sk->sk_max_ack_backlog = backlog;
......@@ -834,7 +850,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
BT_DBG("sock %p, sk %p", sock, sk);
if (!sk) return 0;
if (!sk)
return 0;
lock_sock(sk);
if (!sk->sk_shutdown) {
......@@ -856,7 +873,8 @@ static int l2cap_sock_release(struct socket *sock)
BT_DBG("sock %p, sk %p", sock, sk);
if (!sk) return 0;
if (!sk)
return 0;
err = l2cap_sock_shutdown(sock, 2);
......@@ -988,7 +1006,7 @@ static void l2cap_chan_del(struct sock *sk, int err)
sk->sk_state = BT_CLOSED;
sk->sk_zapped = 1;
if (err)
sk->sk_err = err;
......@@ -1111,7 +1129,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
count = min_t(unsigned int, conn->mtu, len);
skb = bt_skb_alloc(count, GFP_ATOMIC);
if (!skb)
return NULL;
......@@ -1132,7 +1150,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
}
len -= skb->len;
/* Continuation fragments (no L2CAP header) */
frag = &skb_shinfo(skb)->frag_list;
while (len) {
......@@ -1141,12 +1159,12 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
*frag = bt_skb_alloc(count, GFP_ATOMIC);
if (!*frag)
goto fail;
memcpy(skb_put(*frag, count), data, count);
len -= count;
data += count;
frag = &(*frag)->next;
}
......@@ -1238,7 +1256,7 @@ static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
case L2CAP_CONF_QOS:
break;
default:
if (hint)
break;
......@@ -1306,8 +1324,7 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr)
int result = 0;
/* Configure output options and let the other side know
* which ones we don't like.
*/
* which ones we don't like. */
if (pi->conf_mtu < pi->omtu) {
l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
result = L2CAP_CONF_UNACCEPT;
......@@ -1533,13 +1550,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
case L2CAP_CONF_UNACCEPT:
if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
char req[128];
/*
It does not make sense to adjust L2CAP parameters
that are currently defined in the spec. We simply
resend config request that we sent earlier. It is
stupid :) but it helps qualification testing
which expects at least some response from us.
*/
/* It does not make sense to adjust L2CAP parameters
* that are currently defined in the spec. We simply
* resend config request that we sent earlier. It is
* stupid, but it helps qualification testing which
* expects at least some response from us. */
l2cap_send_req(conn, L2CAP_CONF_REQ,
l2cap_build_conf_req(sk, req), req);
goto done;
......@@ -1594,7 +1609,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
sk->sk_shutdown = SHUTDOWN_MASK;
l2cap_chan_del(sk, ECONNRESET);
bh_unlock_sock(sk);
......@@ -1723,11 +1738,11 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
if (l2cap_pi(sk)->imtu < skb->len)
goto drop;
/* If socket recv buffers overflows we drop data here
* which is *bad* because L2CAP has to be reliable.
* But we don't have any other choice. L2CAP doesn't
* provide flow control mechanism */
/* If socket recv buffers overflows we drop data here
* which is *bad* because L2CAP has to be reliable.
* But we don't have any other choice. L2CAP doesn't
* provide flow control mechanism */
if (!sock_queue_rcv_skb(sk, skb))
goto done;
......@@ -1787,7 +1802,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
skb_pull(skb, 2);
l2cap_conless_channel(conn, psm, skb);
break;
default:
l2cap_data_channel(conn, cid, skb);
break;
......@@ -1839,7 +1854,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
l2cap_conn_ready(conn);
} else
l2cap_conn_del(hcon, bt_err(status));
return 0;
}
......@@ -1861,7 +1876,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
struct l2cap_conn_rsp rsp;
struct sock *sk;
int result;
if (!(conn = hcon->l2cap_data))
return 0;
l = &conn->chan_list;
......@@ -1908,7 +1923,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status)
struct l2cap_conn_rsp rsp;
struct sock *sk;
int result;
if (!(conn = hcon->l2cap_data))
return 0;
l = &conn->chan_list;
......@@ -2069,10 +2084,10 @@ static int l2cap_seq_show(struct seq_file *seq, void *e)
}
static struct seq_operations l2cap_seq_ops = {
.start = l2cap_seq_start,
.next = l2cap_seq_next,
.stop = l2cap_seq_stop,
.show = l2cap_seq_show
.start = l2cap_seq_start,
.next = l2cap_seq_next,
.stop = l2cap_seq_stop,
.show = l2cap_seq_show
};
static int l2cap_seq_open(struct inode *inode, struct file *file)
......@@ -2081,76 +2096,76 @@ static int l2cap_seq_open(struct inode *inode, struct file *file)
}
static struct file_operations l2cap_seq_fops = {
.owner = THIS_MODULE,
.open = l2cap_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.owner = THIS_MODULE,
.open = l2cap_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static int __init l2cap_proc_init(void)
static int __init l2cap_proc_init(void)
{
struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
if (!p)
return -ENOMEM;
struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
if (!p)
return -ENOMEM;
p->owner = THIS_MODULE;
p->proc_fops = &l2cap_seq_fops;
return 0;
p->proc_fops = &l2cap_seq_fops;
return 0;
}
static void __exit l2cap_proc_cleanup(void)
{
remove_proc_entry("l2cap", proc_bt);
remove_proc_entry("l2cap", proc_bt);
}
#else /* CONFIG_PROC_FS */
static int __init l2cap_proc_init(void)
static int __init l2cap_proc_init(void)
{
return 0;
return 0;
}
static void __exit l2cap_proc_cleanup(void)
{
return;
return;
}
#endif /* CONFIG_PROC_FS */
static struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
.bind = l2cap_sock_bind,
.connect = l2cap_sock_connect,
.listen = l2cap_sock_listen,
.accept = l2cap_sock_accept,
.getname = l2cap_sock_getname,
.sendmsg = l2cap_sock_sendmsg,
.recvmsg = bt_sock_recvmsg,
.poll = bt_sock_poll,
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
.ioctl = sock_no_ioctl,
.shutdown = l2cap_sock_shutdown,
.setsockopt = l2cap_sock_setsockopt,
.getsockopt = l2cap_sock_getsockopt
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = l2cap_sock_release,
.bind = l2cap_sock_bind,
.connect = l2cap_sock_connect,
.listen = l2cap_sock_listen,
.accept = l2cap_sock_accept,
.getname = l2cap_sock_getname,
.sendmsg = l2cap_sock_sendmsg,
.recvmsg = bt_sock_recvmsg,
.poll = bt_sock_poll,
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
.ioctl = sock_no_ioctl,
.shutdown = l2cap_sock_shutdown,
.setsockopt = l2cap_sock_setsockopt,
.getsockopt = l2cap_sock_getsockopt
};
static struct net_proto_family l2cap_sock_family_ops = {
.family = PF_BLUETOOTH,
.create = l2cap_sock_create,
.owner = THIS_MODULE,
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = l2cap_sock_create,
};
static struct hci_proto l2cap_hci_proto = {
.name = "L2CAP",
.id = HCI_PROTO_L2CAP,
.connect_ind = l2cap_connect_ind,
.connect_cfm = l2cap_connect_cfm,
.disconn_ind = l2cap_disconn_ind,
.auth_cfm = l2cap_auth_cfm,
.encrypt_cfm = l2cap_encrypt_cfm,
.recv_acldata = l2cap_recv_acldata
.name = "L2CAP",
.id = HCI_PROTO_L2CAP,
.connect_ind = l2cap_connect_ind,
.connect_cfm = l2cap_connect_cfm,
.disconn_ind = l2cap_disconn_ind,
.auth_cfm = l2cap_auth_cfm,
.encrypt_cfm = l2cap_encrypt_cfm,
.recv_acldata = l2cap_recv_acldata
};
static int __init l2cap_init(void)
......@@ -2168,7 +2183,7 @@ static int __init l2cap_init(void)
}
l2cap_proc_init();
BT_INFO("L2CAP ver %s", VERSION);
BT_INFO("L2CAP socket layer initialized");
......@@ -2189,9 +2204,9 @@ static void __exit l2cap_exit(void)
void l2cap_load(void)
{
/* Dummy function to trigger automatic L2CAP module loading by
other modules that use L2CAP sockets but don not use any other
symbols from it. */
/* Dummy function to trigger automatic L2CAP module loading by
* other modules that use L2CAP sockets but don not use any othe
* symbols from it. */
return;
}
EXPORT_SYMBOL(l2cap_load);
......
......@@ -22,11 +22,10 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth kernel library.
*
* $Id: lib.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
*/
/* Bluetooth kernel library. */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
......@@ -58,6 +57,7 @@ void bt_dump(char *pref, __u8 *buf, int count)
if (line[0])
printk(KERN_INFO "%s:%s\n", pref, line);
}
EXPORT_SYMBOL(bt_dump);
void baswap(bdaddr_t *dst, bdaddr_t *src)
{
......@@ -68,6 +68,7 @@ void baswap(bdaddr_t *dst, bdaddr_t *src)
for (i = 0; i < 6; i++)
d[i] = s[5 - i];
}
EXPORT_SYMBOL(baswap);
char *batostr(bdaddr_t *ba)
{
......@@ -76,11 +77,12 @@ char *batostr(bdaddr_t *ba)
i ^= 1;
sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
ba->b[0], ba->b[1], ba->b[2],
ba->b[0], ba->b[1], ba->b[2],
ba->b[3], ba->b[4], ba->b[5]);
return str[i];
}
EXPORT_SYMBOL(batostr);
/* Bluetooth error codes to Unix errno mapping */
int bt_err(__u16 code)
......@@ -173,3 +175,4 @@ int bt_err(__u16 code)
return ENOSYS;
}
}
EXPORT_SYMBOL(bt_err);
......@@ -2,7 +2,7 @@ config BT_RFCOMM
tristate "RFCOMM protocol support"
depends on BT && BT_L2CAP
help
RFCOMM provides connection oriented stream transport. RFCOMM
RFCOMM provides connection oriented stream transport. RFCOMM
support is required for Dialup Networking, OBEX and other Bluetooth
applications.
......
......@@ -50,7 +50,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h>
#define VERSION "1.2"
#define VERSION "1.3"
#ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG
......
......@@ -398,6 +398,27 @@ int rfcomm_sock_listen(struct socket *sock, int backlog)
goto done;
}
if (!rfcomm_pi(sk)->channel) {
bdaddr_t *src = &bt_sk(sk)->src;
u8 channel;
err = -EINVAL;
write_lock_bh(&rfcomm_sk_list.lock);
for (channel = 1; channel < 31; channel++)
if (!__rfcomm_get_sock_by_addr(channel, src)) {
rfcomm_pi(sk)->channel = channel;
err = 0;
break;
}
write_unlock_bh(&rfcomm_sk_list.lock);
if (err < 0)
goto done;
}
sk->sk_max_ack_backlog = backlog;
sk->sk_ack_backlog = 0;
sk->sk_state = BT_LISTEN;
......
......@@ -22,12 +22,7 @@
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth SCO sockets.
*
* $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
*/
#define VERSION "0.3"
/* Bluetooth SCO sockets. */
#include <linux/config.h>
#include <linux/module.h>
......@@ -58,9 +53,11 @@
#ifndef CONFIG_BT_SCO_DEBUG
#undef BT_DBG
#define BT_DBG( A... )
#define BT_DBG(D...)
#endif
#define VERSION "0.3"
static struct proto_ops sco_sock_ops;
static struct bt_sock_list sco_sk_list = {
......@@ -137,7 +134,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
conn->src = &hdev->bdaddr;
conn->dst = &hcon->dst;
if (hdev->sco_mtu > 0)
conn->mtu = hdev->sco_mtu;
else
......@@ -483,7 +480,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
}
write_lock_bh(&sco_sk_list.lock);
if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
err = -EADDRINUSE;
} else {
......@@ -491,7 +488,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
sk->sk_state = BT_BOUND;
}
write_unlock_bh(&sco_sk_list.lock);
done:
......@@ -694,7 +691,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
err = -ENOTCONN;
break;
}
opts.mtu = sco_pi(sk)->conn->mtu;
BT_DBG("mtu %d", opts.mtu);
......@@ -737,7 +734,7 @@ static int sco_sock_release(struct socket *sock)
if (!sk)
return 0;
sco_sock_close(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
......@@ -811,7 +808,7 @@ static void sco_conn_ready(struct sco_conn *conn)
sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
if (!sk) {
bh_unlock_sock(parent);
goto done;
goto done;
}
sco_sock_init(sk, parent);
......@@ -820,14 +817,14 @@ static void sco_conn_ready(struct sco_conn *conn)
bacpy(&bt_sk(sk)->dst, conn->dst);
hci_conn_hold(conn->hcon);
__sco_chan_add(conn, sk, parent);
__sco_chan_add(conn, sk, parent);
sk->sk_state = BT_CONNECTED;
sk->sk_state = BT_CONNECTED;
/* Wake up parent */
parent->sk_data_ready(parent, 1);
bh_unlock_sock(parent);
bh_unlock_sock(parent);
}
done:
......@@ -858,7 +855,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
sco_conn_ready(conn);
} else
sco_conn_del(hcon, bt_err(status));
return 0;
}
......@@ -931,10 +928,10 @@ static int sco_seq_show(struct seq_file *seq, void *e)
}
static struct seq_operations sco_seq_ops = {
.start = sco_seq_start,
.next = sco_seq_next,
.stop = sco_seq_stop,
.show = sco_seq_show
.start = sco_seq_start,
.next = sco_seq_next,
.stop = sco_seq_stop,
.show = sco_seq_show
};
static int sco_seq_open(struct inode *inode, struct file *file)
......@@ -943,74 +940,74 @@ static int sco_seq_open(struct inode *inode, struct file *file)
}
static struct file_operations sco_seq_fops = {
.owner = THIS_MODULE,
.open = sco_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.owner = THIS_MODULE,
.open = sco_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static int __init sco_proc_init(void)
static int __init sco_proc_init(void)
{
struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
if (!p)
return -ENOMEM;
struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
if (!p)
return -ENOMEM;
p->owner = THIS_MODULE;
p->proc_fops = &sco_seq_fops;
return 0;
p->proc_fops = &sco_seq_fops;
return 0;
}
static void __exit sco_proc_cleanup(void)
{
remove_proc_entry("sco", proc_bt);
remove_proc_entry("sco", proc_bt);
}
#else /* CONFIG_PROC_FS */
static int __init sco_proc_init(void)
static int __init sco_proc_init(void)
{
return 0;
return 0;
}
static void __exit sco_proc_cleanup(void)
{
return;
return;
}
#endif /* CONFIG_PROC_FS */
static struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = sco_sock_release,
.bind = sco_sock_bind,
.connect = sco_sock_connect,
.listen = sco_sock_listen,
.accept = sco_sock_accept,
.getname = sco_sock_getname,
.sendmsg = sco_sock_sendmsg,
.recvmsg = bt_sock_recvmsg,
.poll = bt_sock_poll,
.ioctl = sock_no_ioctl,
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
.shutdown = sock_no_shutdown,
.setsockopt = sco_sock_setsockopt,
.getsockopt = sco_sock_getsockopt
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = sco_sock_release,
.bind = sco_sock_bind,
.connect = sco_sock_connect,
.listen = sco_sock_listen,
.accept = sco_sock_accept,
.getname = sco_sock_getname,
.sendmsg = sco_sock_sendmsg,
.recvmsg = bt_sock_recvmsg,
.poll = bt_sock_poll,
.ioctl = sock_no_ioctl,
.mmap = sock_no_mmap,
.socketpair = sock_no_socketpair,
.shutdown = sock_no_shutdown,
.setsockopt = sco_sock_setsockopt,
.getsockopt = sco_sock_getsockopt
};
static struct net_proto_family sco_sock_family_ops = {
.family = PF_BLUETOOTH,
.create = sco_sock_create,
.owner = THIS_MODULE,
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = sco_sock_create,
};
static struct hci_proto sco_hci_proto = {
.name = "SCO",
.id = HCI_PROTO_SCO,
.connect_ind = sco_connect_ind,
.connect_cfm = sco_connect_cfm,
.disconn_ind = sco_disconn_ind,
.recv_scodata = sco_recv_scodata
.name = "SCO",
.id = HCI_PROTO_SCO,
.connect_ind = sco_connect_ind,
.connect_cfm = sco_connect_cfm,
.disconn_ind = sco_disconn_ind,
.recv_scodata = sco_recv_scodata
};
static int __init sco_init(void)
......@@ -1028,7 +1025,7 @@ static int __init sco_init(void)
}
sco_proc_init();
BT_INFO("SCO (Voice Link) ver %s", VERSION);
BT_INFO("SCO socket layer initialized");
......
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation;
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
SOFTWARE IS DISCLAIMED.
*/
/*
* Bluetooth symbols.
*
* $Id: syms.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
/* HCI Core */
EXPORT_SYMBOL(hci_alloc_dev);
EXPORT_SYMBOL(hci_free_dev);
EXPORT_SYMBOL(hci_register_dev);
EXPORT_SYMBOL(hci_unregister_dev);
EXPORT_SYMBOL(hci_suspend_dev);
EXPORT_SYMBOL(hci_resume_dev);
EXPORT_SYMBOL(hci_register_proto);
EXPORT_SYMBOL(hci_unregister_proto);
EXPORT_SYMBOL(hci_get_route);
EXPORT_SYMBOL(hci_connect);
EXPORT_SYMBOL(hci_dev_get);
EXPORT_SYMBOL(hci_conn_auth);
EXPORT_SYMBOL(hci_conn_encrypt);
EXPORT_SYMBOL(hci_send_acl);
EXPORT_SYMBOL(hci_send_sco);
EXPORT_SYMBOL(hci_send_cmd);
EXPORT_SYMBOL(hci_si_event);
/* Bluetooth lib */
EXPORT_SYMBOL(bt_dump);
EXPORT_SYMBOL(baswap);
EXPORT_SYMBOL(batostr);
EXPORT_SYMBOL(bt_err);
/* Bluetooth sockets */
EXPORT_SYMBOL(bt_sock_register);
EXPORT_SYMBOL(bt_sock_unregister);
EXPORT_SYMBOL(bt_sock_alloc);
EXPORT_SYMBOL(bt_sock_link);
EXPORT_SYMBOL(bt_sock_unlink);
EXPORT_SYMBOL(bt_sock_recvmsg);
EXPORT_SYMBOL(bt_sock_poll);
EXPORT_SYMBOL(bt_accept_enqueue);
EXPORT_SYMBOL(bt_accept_dequeue);
EXPORT_SYMBOL(bt_sock_wait_state);
EXPORT_SYMBOL(proc_bt);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment