Commit 6e3fccfc authored by David S. Miller's avatar David S. Miller

Merge http://linux-mh.bkbits.net/bluetooth-2.6

into kernel.bkbits.net:/home/davem/bluetooth-2.6
parents c517cfc4 130a7545
...@@ -359,6 +359,8 @@ P: Maxim Krasnyansky ...@@ -359,6 +359,8 @@ P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
L: bluez-devel@lists.sf.net L: bluez-devel@lists.sf.net
W: http://bluez.sf.net W: http://bluez.sf.net
W: http://www.bluez.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH RFCOMM LAYER BLUETOOTH RFCOMM LAYER
...@@ -366,7 +368,6 @@ P: Marcel Holtmann ...@@ -366,7 +368,6 @@ P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
P: Maxim Krasnyansky P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained S: Maintained
BLUETOOTH BNEP LAYER BLUETOOTH BNEP LAYER
...@@ -374,71 +375,60 @@ P: Marcel Holtmann ...@@ -374,71 +375,60 @@ P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
P: Maxim Krasnyansky P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained S: Maintained
BLUETOOTH CMTP LAYER BLUETOOTH CMTP LAYER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI USB DRIVER BLUETOOTH HCI UART DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
P: Maxim Krasnyansky P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained S: Maintained
BLUETOOTH HCI UART DRIVER BLUETOOTH HCI USB DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
P: Maxim Krasnyansky P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained S: Maintained
BLUETOOTH HCI BCM203X DRIVER BLUETOOTH HCI BCM203X DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI BFUSB DRIVER BLUETOOTH HCI BFUSB DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI DTL1 DRIVER BLUETOOTH HCI DTL1 DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI BLUECARD DRIVER BLUETOOTH HCI BLUECARD DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI BT3C DRIVER BLUETOOTH HCI BT3C DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI BTUART DRIVER BLUETOOTH HCI BTUART DRIVER
P: Marcel Holtmann P: Marcel Holtmann
M: marcel@holtmann.org M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained S: Maintained
BLUETOOTH HCI VHCI DRIVER BLUETOOTH HCI VHCI DRIVER
P: Maxim Krasnyansky P: Maxim Krasnyansky
M: maxk@qualcomm.com M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained S: Maintained
BONDING DRIVER BONDING DRIVER
......
...@@ -29,9 +29,7 @@ ...@@ -29,9 +29,7 @@
* Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com> * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu> * 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/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -57,9 +55,9 @@ ...@@ -57,9 +55,9 @@
#ifndef CONFIG_BT_HCIUSB_DEBUG #ifndef CONFIG_BT_HCIUSB_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#undef BT_DMP #undef BT_DMP
#define BT_DMP( A... ) #define BT_DMP(D...)
#endif #endif
#ifndef CONFIG_BT_HCIUSB_ZERO_PACKET #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
...@@ -67,6 +65,8 @@ ...@@ -67,6 +65,8 @@
#define URB_ZERO_PACKET 0 #define URB_ZERO_PACKET 0
#endif #endif
#define VERSION "2.6"
static struct usb_driver hci_usb_driver; static struct usb_driver hci_usb_driver;
static struct usb_device_id bluetooth_ids[] = { static struct usb_device_id bluetooth_ids[] = {
...@@ -100,7 +100,10 @@ static struct usb_device_id blacklist_ids[] = { ...@@ -100,7 +100,10 @@ static struct usb_device_id blacklist_ids[] = {
/* Digianswer device */ /* Digianswer device */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, { 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) struct _urb *_urb_alloc(int isoc, int gfp)
...@@ -393,7 +396,7 @@ static int hci_usb_close(struct hci_dev *hdev) ...@@ -393,7 +396,7 @@ static int hci_usb_close(struct hci_dev *hdev)
{ {
struct hci_usb *husb = (struct hci_usb *) hdev->driver_data; struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
unsigned long flags; unsigned long flags;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0; return 0;
...@@ -402,7 +405,7 @@ static int hci_usb_close(struct hci_dev *hdev) ...@@ -402,7 +405,7 @@ static int hci_usb_close(struct hci_dev *hdev)
/* Synchronize with completion handlers */ /* Synchronize with completion handlers */
write_lock_irqsave(&husb->completion_lock, flags); write_lock_irqsave(&husb->completion_lock, flags);
write_unlock_irqrestore(&husb->completion_lock, flags); write_unlock_irqrestore(&husb->completion_lock, flags);
hci_usb_unlink_urbs(husb); hci_usb_unlink_urbs(husb);
hci_usb_flush(hdev); hci_usb_flush(hdev);
return 0; return 0;
...@@ -414,7 +417,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb) ...@@ -414,7 +417,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
int err; int err;
BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type); BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
_urb_queue_tail(__pending_q(husb, _urb->type), _urb); _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) { if (err) {
...@@ -551,7 +554,7 @@ static void hci_usb_tx_process(struct hci_usb *husb) ...@@ -551,7 +554,7 @@ static void hci_usb_tx_process(struct hci_usb *husb)
skb_queue_head(q, skb); skb_queue_head(q, skb);
} }
#endif #endif
/* Process ACL queue */ /* Process ACL queue */
q = __transmit_q(husb, HCI_ACLDATA_PKT); q = __transmit_q(husb, HCI_ACLDATA_PKT);
while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX && 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 ...@@ -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) { if (count >= HCI_SCO_HDR_SIZE) {
struct hci_sco_hdr *h = data; struct hci_sco_hdr *h = data;
len = HCI_SCO_HDR_SIZE + h->dlen; len = HCI_SCO_HDR_SIZE + h->dlen;
} else } else
return -EILSEQ; return -EILSEQ;
break; break;
#endif #endif
...@@ -702,7 +705,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs) ...@@ -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 _urb *_urb = container_of(urb, struct _urb, urb);
struct hci_usb *husb = (void *) urb->context; struct hci_usb *husb = (void *) urb->context;
struct hci_dev *hdev = husb->hdev; 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, BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
_urb->type, urb->status, count, urb->transfer_flags); _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) ...@@ -743,7 +746,7 @@ static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
resubmit: resubmit:
urb->dev = husb->udev; 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, BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
_urb->type, err); _urb->type, err);
...@@ -779,7 +782,7 @@ static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs) ...@@ -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); _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
hci_usb_tx_wakeup(husb); hci_usb_tx_wakeup(husb);
read_unlock(&husb->completion_lock); read_unlock(&husb->completion_lock);
} }
...@@ -819,9 +822,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -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) if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
return -ENODEV; return -ENODEV;
/* Find endpoints that we need */
/* Find endpoints that we need */
uif = intf->cur_altsetting; uif = intf->cur_altsetting;
for (e = 0; e < uif->desc.bNumEndpoints; e++) { for (e = 0; e < uif->desc.bNumEndpoints; e++) {
ep = &uif->endpoint[e]; ep = &uif->endpoint[e];
...@@ -862,16 +864,17 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -862,16 +864,17 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
husb->ctrl_req = HCI_DIGI_REQ; husb->ctrl_req = HCI_DIGI_REQ;
else else
husb->ctrl_req = HCI_CTRL_REQ; husb->ctrl_req = HCI_CTRL_REQ;
/* Find isochronous endpoints that we can use */
/* Find isochronous endpoints that we can use */
size = 0; size = 0;
isoc_iface = NULL; isoc_iface = NULL;
isoc_alts = 0; isoc_alts = 0;
isoc_ifnum = 1; isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO #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) { if (isoc_iface) {
int a; int a;
struct usb_host_endpoint *isoc_out_ep = NULL; 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) ...@@ -917,10 +920,10 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
} }
} }
#endif #endif
husb->completion_lock = RW_LOCK_UNLOCKED; 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]); skb_queue_head_init(&husb->transmit_q[i]);
_urb_queue_init(&husb->pending_q[i]); _urb_queue_init(&husb->pending_q[i]);
_urb_queue_init(&husb->completed_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) ...@@ -939,10 +942,10 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
hdev->driver_data = husb; hdev->driver_data = husb;
SET_HCIDEV_DEV(hdev, &intf->dev); SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = hci_usb_open; hdev->open = hci_usb_open;
hdev->close = hci_usb_close; hdev->close = hci_usb_close;
hdev->flush = hci_usb_flush; hdev->flush = hci_usb_flush;
hdev->send = hci_usb_send_frame; hdev->send = hci_usb_send_frame;
hdev->destruct = hci_usb_destruct; hdev->destruct = hci_usb_destruct;
hdev->owner = THIS_MODULE; hdev->owner = THIS_MODULE;
...@@ -993,11 +996,11 @@ static void hci_usb_disconnect(struct usb_interface *intf) ...@@ -993,11 +996,11 @@ static void hci_usb_disconnect(struct usb_interface *intf)
} }
static struct usb_driver hci_usb_driver = { static struct usb_driver hci_usb_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "hci_usb", .name = "hci_usb",
.probe = hci_usb_probe, .probe = hci_usb_probe,
.disconnect = hci_usb_disconnect, .disconnect = hci_usb_disconnect,
.id_table = bluetooth_ids, .id_table = bluetooth_ids,
}; };
static int __init hci_usb_init(void) static int __init hci_usb_init(void)
......
...@@ -23,33 +23,28 @@ ...@@ -23,33 +23,28 @@
SOFTWARE IS DISCLAIMED. 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 */ /* Class, SubClass, and Protocol codes that describe a Bluetooth device */
#define HCI_DEV_CLASS 0xe0 /* Wireless class */ #define HCI_DEV_CLASS 0xe0 /* Wireless class */
#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */ #define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */ #define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
#define HCI_CTRL_REQ 0x20 #define HCI_CTRL_REQ 0x20
#define HCI_DIGI_REQ 0x40 #define HCI_DIGI_REQ 0x40
#define HCI_IGNORE 0x01 #define HCI_IGNORE 0x01
#define HCI_RESET 0x02 #define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04 #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_TX 4
#define HCI_MAX_BULK_RX 1 #define HCI_MAX_BULK_RX 1
#define HCI_MAX_ISOC_RX 2 #define HCI_MAX_ISOC_RX 2
#define HCI_MAX_ISOC_TX 2 #define HCI_MAX_ISOC_TX 2
#define HCI_MAX_ISOC_FRAMES 10 #define HCI_MAX_ISOC_FRAMES 10
struct _urb_queue { struct _urb_queue {
struct list_head head; struct list_head head;
...@@ -79,16 +74,16 @@ static inline void _urb_queue_init(struct _urb_queue *q) ...@@ -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) static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&q->lock, flags); spin_lock_irqsave(&q->lock, flags);
list_add(&_urb->list, &q->head); _urb->queue = q; list_add(&_urb->list, &q->head); _urb->queue = q;
spin_unlock_irqrestore(&q->lock, flags); spin_unlock_irqrestore(&q->lock, flags);
} }
static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb) static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&q->lock, flags); spin_lock_irqsave(&q->lock, flags);
list_add_tail(&_urb->list, &q->head); _urb->queue = q; list_add_tail(&_urb->list, &q->head); _urb->queue = q;
spin_unlock_irqrestore(&q->lock, flags); spin_unlock_irqrestore(&q->lock, flags);
} }
...@@ -96,9 +91,9 @@ static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb) ...@@ -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) static inline void _urb_unlink(struct _urb *_urb)
{ {
struct _urb_queue *q = _urb->queue; struct _urb_queue *q = _urb->queue;
unsigned long flags; unsigned long flags;
if (q) { if (q) {
spin_lock_irqsave(&q->lock, flags); spin_lock_irqsave(&q->lock, flags);
list_del(&_urb->list); _urb->queue = NULL; list_del(&_urb->list); _urb->queue = NULL;
spin_unlock_irqrestore(&q->lock, flags); spin_unlock_irqrestore(&q->lock, flags);
} }
...@@ -106,41 +101,33 @@ static inline void _urb_unlink(struct _urb *_urb) ...@@ -106,41 +101,33 @@ static inline void _urb_unlink(struct _urb *_urb)
struct _urb *_urb_dequeue(struct _urb_queue *q); 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_usb {
struct hci_dev *hdev; struct hci_dev *hdev;
unsigned long state; unsigned long state;
struct usb_device *udev; struct usb_device *udev;
struct usb_host_endpoint *bulk_in_ep; struct usb_host_endpoint *bulk_in_ep;
struct usb_host_endpoint *bulk_out_ep; struct usb_host_endpoint *bulk_out_ep;
struct usb_host_endpoint *intr_in_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_out_ep;
struct usb_host_endpoint *isoc_in_ep; struct usb_host_endpoint *isoc_in_ep;
__u8 ctrl_req; __u8 ctrl_req;
struct sk_buff_head transmit_q[4]; 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; rwlock_t completion_lock;
atomic_t pending_tx[4]; // Number of pending requests atomic_t pending_tx[4]; /* Number of pending requests */
struct _urb_queue pending_q[4]; // Pending requests struct _urb_queue pending_q[4]; /* Pending requests */
struct _urb_queue completed_q[4]; // Completed requests struct _urb_queue completed_q[4]; /* Completed requests */
}; };
/* States */ /* States */
#define HCI_USB_TX_PROCESS 1 #define HCI_USB_TX_PROCESS 1
#define HCI_USB_TX_WAKEUP 2 #define HCI_USB_TX_WAKEUP 2
#endif /* __KERNEL__ */
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/*
* $Id: bluetooth.h,v 1.8 2002/04/17 17:37:20 maxk Exp $
*/
#ifndef __BLUETOOTH_H #ifndef __BLUETOOTH_H
#define __BLUETOOTH_H #define __BLUETOOTH_H
...@@ -41,26 +37,27 @@ ...@@ -41,26 +37,27 @@
#endif #endif
/* Reserv for core and drivers use */ /* Reserv for core and drivers use */
#define BT_SKB_RESERVE 8 #define BT_SKB_RESERVE 8
#define BTPROTO_L2CAP 0 #define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1 #define BTPROTO_HCI 1
#define BTPROTO_SCO 2 #define BTPROTO_SCO 2
#define BTPROTO_RFCOMM 3 #define BTPROTO_RFCOMM 3
#define BTPROTO_BNEP 4 #define BTPROTO_BNEP 4
#define BTPROTO_CMTP 5 #define BTPROTO_CMTP 5
#define BTPROTO_HIDP 6
#define SOL_HCI 0 #define SOL_HCI 0
#define SOL_L2CAP 6 #define SOL_L2CAP 6
#define SOL_SCO 17 #define SOL_SCO 17
#define SOL_RFCOMM 18 #define SOL_RFCOMM 18
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) #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_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
#ifdef HCI_DATA_DUMP #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 #else
#define BT_DMP(D...) #define BT_DMP(D...)
#endif #endif
...@@ -122,7 +119,7 @@ struct bt_sock { ...@@ -122,7 +119,7 @@ struct bt_sock {
struct bt_sock_list { struct bt_sock_list {
struct hlist_head head; struct hlist_head head;
rwlock_t lock; rwlock_t lock;
}; };
int bt_sock_register(int proto, struct net_proto_family *ops); 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); ...@@ -139,7 +136,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */ /* Skb helpers */
struct bt_skb_cb { struct bt_skb_cb {
int incoming; int incoming;
}; };
#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) #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) ...@@ -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, 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; struct sk_buff *skb;
...@@ -178,6 +175,6 @@ static inline int skb_frags_no(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); void bt_dump(char *pref, __u8 *buf, int count);
int bt_err(__u16 code); int bt_err(__u16 code);
#endif /* __BLUETOOTH_H */ #endif /* __BLUETOOTH_H */
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/*
* $Id: hci.h,v 1.4 2002/04/18 22:26:15 maxk Exp $
*/
#ifndef __HCI_H #ifndef __HCI_H
#define __HCI_H #define __HCI_H
......
...@@ -22,10 +22,6 @@ ...@@ -22,10 +22,6 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/*
* $Id: hci_core.h,v 1.3 2002/04/17 18:55:21 maxk Exp $
*/
#ifndef __HCI_CORE_H #ifndef __HCI_CORE_H
#define __HCI_CORE_H #define __HCI_CORE_H
...@@ -63,12 +59,12 @@ struct hci_conn_hash { ...@@ -63,12 +59,12 @@ struct hci_conn_hash {
struct hci_dev { struct hci_dev {
struct list_head list; struct list_head list;
spinlock_t lock; spinlock_t lock;
atomic_t refcnt; atomic_t refcnt;
char name[8]; char name[8];
unsigned long flags; unsigned long flags;
__u16 id; __u16 id;
__u8 type; __u8 type;
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 features[8]; __u8 features[8];
__u16 voice_setting; __u16 voice_setting;
...@@ -79,38 +75,38 @@ struct hci_dev { ...@@ -79,38 +75,38 @@ struct hci_dev {
unsigned long quirks; unsigned long quirks;
atomic_t cmd_cnt; atomic_t cmd_cnt;
unsigned int acl_cnt; unsigned int acl_cnt;
unsigned int sco_cnt; unsigned int sco_cnt;
unsigned int acl_mtu; unsigned int acl_mtu;
unsigned int sco_mtu; unsigned int sco_mtu;
unsigned int acl_pkts; unsigned int acl_pkts;
unsigned int sco_pkts; unsigned int sco_pkts;
unsigned long cmd_last_tx; unsigned long cmd_last_tx;
unsigned long acl_last_tx; unsigned long acl_last_tx;
unsigned long sco_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 rx_task;
struct tasklet_struct tx_task; struct tasklet_struct tx_task;
struct sk_buff_head rx_q; struct sk_buff_head rx_q;
struct sk_buff_head raw_q; struct sk_buff_head raw_q;
struct sk_buff_head cmd_q; struct sk_buff_head cmd_q;
struct sk_buff *sent_cmd; struct sk_buff *sent_cmd;
struct semaphore req_lock; struct semaphore req_lock;
wait_queue_head_t req_wait_q; wait_queue_head_t req_wait_q;
__u32 req_status; __u32 req_status;
__u32 req_result; __u32 req_result;
struct inquiry_cache inq_cache; struct inquiry_cache inq_cache;
struct hci_conn_hash conn_hash; struct hci_conn_hash conn_hash;
struct hci_dev_stats stat; struct hci_dev_stats stat;
void *driver_data; void *driver_data;
void *core_data; void *core_data;
...@@ -118,12 +114,12 @@ struct hci_dev { ...@@ -118,12 +114,12 @@ struct hci_dev {
atomic_t promisc; atomic_t promisc;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc; struct proc_dir_entry *proc;
#endif #endif
struct class_device class_dev; struct class_device class_dev;
struct module *owner; struct module *owner;
int (*open)(struct hci_dev *hdev); int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev);
...@@ -140,9 +136,9 @@ struct hci_conn { ...@@ -140,9 +136,9 @@ struct hci_conn {
atomic_t refcnt; atomic_t refcnt;
spinlock_t lock; spinlock_t lock;
bdaddr_t dst; bdaddr_t dst;
__u16 handle; __u16 handle;
__u16 state; __u16 state;
__u8 type; __u8 type;
__u8 out; __u8 out;
__u32 link_mode; __u32 link_mode;
...@@ -154,12 +150,12 @@ struct hci_conn { ...@@ -154,12 +150,12 @@ struct hci_conn {
struct timer_list timer; struct timer_list timer;
struct hci_dev *hdev; struct hci_dev *hdev;
void *l2cap_data; void *l2cap_data;
void *sco_data; void *sco_data;
void *priv; void *priv;
struct hci_conn *link; struct hci_conn *link;
}; };
extern struct hci_proto *hci_proto[]; extern struct hci_proto *hci_proto[];
...@@ -215,7 +211,7 @@ static inline void hci_conn_hash_init(struct hci_dev *hdev) ...@@ -215,7 +211,7 @@ static inline void hci_conn_hash_init(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn_hash *h = &hdev->conn_hash;
INIT_LIST_HEAD(&h->list); INIT_LIST_HEAD(&h->list);
spin_lock_init(&h->lock); 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) 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) ...@@ -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, 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 hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p; struct list_head *p;
...@@ -244,7 +240,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, ...@@ -244,7 +240,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
if (c->handle == handle) if (c->handle == handle)
return c; return c;
} }
return NULL; return NULL;
} }
static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, 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, ...@@ -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)) if (c->type == type && !bacmp(&c->dst, ba))
return c; return c;
} }
return NULL; return NULL;
} }
void hci_acl_connect(struct hci_conn *conn); 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); ...@@ -506,7 +502,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
/* HCI info for socket */ /* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *)sk->sk_protinfo) #define hci_pi(sk) ((struct hci_pinfo *)sk->sk_protinfo)
struct hci_pinfo { struct hci_pinfo {
struct hci_dev *hdev; struct hci_dev *hdev;
struct hci_filter filter; struct hci_filter filter;
__u32 cmsg_mask; __u32 cmsg_mask;
}; };
......
...@@ -22,18 +22,14 @@ ...@@ -22,18 +22,14 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/*
* $Id: l2cap.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
*/
#ifndef __L2CAP_H #ifndef __L2CAP_H
#define __L2CAP_H #define __L2CAP_H
/* L2CAP defaults */ /* L2CAP defaults */
#define L2CAP_DEFAULT_MTU 672 #define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
#define L2CAP_CONN_TIMEOUT (HZ * 40) #define L2CAP_CONN_TIMEOUT (HZ * 40)
/* L2CAP socket address */ /* L2CAP socket address */
struct sockaddr_l2 { struct sockaddr_l2 {
...@@ -190,10 +186,10 @@ struct l2cap_chan_list { ...@@ -190,10 +186,10 @@ struct l2cap_chan_list {
struct l2cap_conn { struct l2cap_conn {
struct hci_conn *hcon; struct hci_conn *hcon;
bdaddr_t *dst; bdaddr_t *dst;
bdaddr_t *src; bdaddr_t *src;
unsigned int mtu; unsigned int mtu;
spinlock_t lock; spinlock_t lock;
...@@ -227,9 +223,9 @@ struct l2cap_pinfo { ...@@ -227,9 +223,9 @@ struct l2cap_pinfo {
__u16 sport; __u16 sport;
struct l2cap_conn *conn; struct l2cap_conn *conn;
struct sock *next_c; struct sock *next_c;
struct sock *prev_c; struct sock *prev_c;
}; };
#define L2CAP_CONF_REQ_SENT 0x01 #define L2CAP_CONF_REQ_SENT 0x01
......
...@@ -21,14 +21,6 @@ ...@@ -21,14 +21,6 @@
SOFTWARE IS DISCLAIMED. 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 #ifndef __RFCOMM_H
#define __RFCOMM_H #define __RFCOMM_H
......
...@@ -22,19 +22,15 @@ ...@@ -22,19 +22,15 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/*
* $Id: sco.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
*/
#ifndef __SCO_H #ifndef __SCO_H
#define __SCO_H #define __SCO_H
/* SCO defaults */ /* SCO defaults */
#define SCO_DEFAULT_MTU 500 #define SCO_DEFAULT_MTU 500
#define SCO_DEFAULT_FLUSH_TO 0xFFFF #define SCO_DEFAULT_FLUSH_TO 0xFFFF
#define SCO_CONN_TIMEOUT (HZ * 40) #define SCO_CONN_TIMEOUT (HZ * 40)
#define SCO_DISCONN_TIMEOUT (HZ * 2) #define SCO_DISCONN_TIMEOUT (HZ * 2)
#define SCO_CONN_IDLE_TIMEOUT (HZ * 60) #define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
/* SCO socket address */ /* SCO socket address */
......
...@@ -14,22 +14,20 @@ menuconfig BT ...@@ -14,22 +14,20 @@ menuconfig BT
Linux Bluetooth subsystem consist of several layers: Linux Bluetooth subsystem consist of several layers:
Bluetooth Core (HCI device and connection manager, scheduler) Bluetooth Core (HCI device and connection manager, scheduler)
HCI Device drivers (interface to the hardware) HCI Device drivers (Interface to the hardware)
L2CAP Module (L2CAP protocol) SCO Module (SCO audio links)
SCO Module (SCO links) L2CAP Module (Logical Link Control and Adaptation Protocol)
RFCOMM Module (RFCOMM protocol) RFCOMM Module (RFCOMM Protocol)
BNEP Module (BNEP protocol) BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CMTP protocol) CMTP Module (CAPI Message Transport Protocol)
Say Y here to enable Linux Bluetooth support and to build Bluetooth Core Say Y here to compile Bluetooth support into the kernel or say M to
layer. compile it as module (bluetooth).
To use Linux Bluetooth subsystem, you will need several user-space To use Linux Bluetooth subsystem, you will need several user-space
utilities like hciconfig and hcid. These utilities and updates to utilities like hciconfig and hcid. These utilities and updates to
Bluetooth kernel modules are provided in the BlueZ packages. Bluetooth kernel modules are provided in the BlueZ packages.
For more information, see <http://bluez.sourceforge.net/>. For more information, see <http://www.bluez.org/>.
If you want to compile Bluetooth Core as module (bluetooth) say M here.
config BT_L2CAP config BT_L2CAP
tristate "L2CAP protocol support" tristate "L2CAP protocol support"
...@@ -46,7 +44,7 @@ config BT_SCO ...@@ -46,7 +44,7 @@ config BT_SCO
tristate "SCO links support" tristate "SCO links support"
depends on BT depends on BT
help 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. required for voice applications like Headset and Audio.
Say Y here to compile SCO support into the kernel or say M to Say Y here to compile SCO support into the kernel or say M to
......
...@@ -9,4 +9,4 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/ ...@@ -9,4 +9,4 @@ obj-$(CONFIG_BT_RFCOMM) += rfcomm/
obj-$(CONFIG_BT_BNEP) += bnep/ obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/ 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 @@ ...@@ -22,12 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth address family and sockets. */
* Bluetooth address family and sockets.
*
* $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
*/
#define VERSION "2.4"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -53,13 +48,16 @@ ...@@ -53,13 +48,16 @@
#ifndef CONFIG_BT_SOCK_DEBUG #ifndef CONFIG_BT_SOCK_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.5"
struct proc_dir_entry *proc_bt; struct proc_dir_entry *proc_bt;
EXPORT_SYMBOL(proc_bt);
/* Bluetooth sockets */ /* Bluetooth sockets */
#define BT_MAX_PROTO 6 #define BT_MAX_PROTO 7
static struct net_proto_family *bt_proto[BT_MAX_PROTO]; static struct net_proto_family *bt_proto[BT_MAX_PROTO];
static kmem_cache_t *bt_sock_cache; static kmem_cache_t *bt_sock_cache;
...@@ -75,6 +73,7 @@ int bt_sock_register(int proto, struct net_proto_family *ops) ...@@ -75,6 +73,7 @@ int bt_sock_register(int proto, struct net_proto_family *ops)
bt_proto[proto] = ops; bt_proto[proto] = ops;
return 0; return 0;
} }
EXPORT_SYMBOL(bt_sock_register);
int bt_sock_unregister(int proto) int bt_sock_unregister(int proto)
{ {
...@@ -87,6 +86,7 @@ int bt_sock_unregister(int proto) ...@@ -87,6 +86,7 @@ int bt_sock_unregister(int proto)
bt_proto[proto] = NULL; bt_proto[proto] = NULL;
return 0; return 0;
} }
EXPORT_SYMBOL(bt_sock_unregister);
static int bt_sock_create(struct socket *sock, int proto) 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 ...@@ -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); sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct bt_sock), bt_sock_cache);
if (!sk) if (!sk)
return NULL; return NULL;
if (pi_size) { if (pi_size) {
pi = kmalloc(pi_size, prio); pi = kmalloc(pi_size, prio);
if (!pi) { if (!pi) {
...@@ -129,13 +129,14 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio ...@@ -129,13 +129,14 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio
sock_init_data(sock, sk); sock_init_data(sock, sk);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_zapped = 0; sk->sk_zapped = 0;
sk->sk_protocol = proto; sk->sk_protocol = proto;
sk->sk_state = BT_OPEN; sk->sk_state = BT_OPEN;
return sk; return sk;
} }
EXPORT_SYMBOL(bt_sock_alloc);
void bt_sock_link(struct bt_sock_list *l, struct sock *sk) 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) ...@@ -143,6 +144,7 @@ void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
sk_add_node(sk, &l->head); sk_add_node(sk, &l->head);
write_unlock_bh(&l->lock); write_unlock_bh(&l->lock);
} }
EXPORT_SYMBOL(bt_sock_link);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk) 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) ...@@ -150,6 +152,7 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
sk_del_node_init(sk); sk_del_node_init(sk);
write_unlock_bh(&l->lock); write_unlock_bh(&l->lock);
} }
EXPORT_SYMBOL(bt_sock_unlink);
void bt_accept_enqueue(struct sock *parent, struct sock *sk) void bt_accept_enqueue(struct sock *parent, struct sock *sk)
{ {
...@@ -160,6 +163,7 @@ 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; bt_sk(sk)->parent = parent;
parent->sk_ack_backlog++; parent->sk_ack_backlog++;
} }
EXPORT_SYMBOL(bt_accept_enqueue);
static void bt_accept_unlink(struct sock *sk) static void bt_accept_unlink(struct sock *sk)
{ {
...@@ -175,19 +179,19 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) ...@@ -175,19 +179,19 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{ {
struct list_head *p, *n; struct list_head *p, *n;
struct sock *sk; struct sock *sk;
BT_DBG("parent %p", parent); BT_DBG("parent %p", parent);
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
lock_sock(sk); lock_sock(sk);
if (sk->sk_state == BT_CLOSED) { if (sk->sk_state == BT_CLOSED) {
release_sock(sk); release_sock(sk);
bt_accept_unlink(sk); bt_accept_unlink(sk);
continue; continue;
} }
if (sk->sk_state == BT_CONNECTED || !newsock) { if (sk->sk_state == BT_CONNECTED || !newsock) {
bt_accept_unlink(sk); bt_accept_unlink(sk);
if (newsock) if (newsock)
...@@ -199,6 +203,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) ...@@ -199,6 +203,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL(bt_accept_dequeue);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags) struct msghdr *msg, size_t len, int flags)
...@@ -235,6 +240,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -235,6 +240,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return err ? : copied; return err ? : copied;
} }
EXPORT_SYMBOL(bt_sock_recvmsg);
static inline unsigned int bt_accept_poll(struct sock *parent) 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 ...@@ -287,6 +293,7 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w
return mask; return mask;
} }
EXPORT_SYMBOL(bt_sock_poll);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) 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) ...@@ -322,9 +329,10 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
remove_wait_queue(sk->sk_sleep, &wait); remove_wait_queue(sk->sk_sleep, &wait);
return err; return err;
} }
EXPORT_SYMBOL(bt_sock_wait_state);
static struct net_proto_family bt_sock_family_ops = { static struct net_proto_family bt_sock_family_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.create = bt_sock_create, .create = bt_sock_create,
}; };
...@@ -342,7 +350,7 @@ static int __init bt_init(void) ...@@ -342,7 +350,7 @@ static int __init bt_init(void)
proc_bt = proc_mkdir("bluetooth", NULL); proc_bt = proc_mkdir("bluetooth", NULL);
if (proc_bt) if (proc_bt)
proc_bt->owner = THIS_MODULE; proc_bt->owner = THIS_MODULE;
/* Init socket cache */ /* Init socket cache */
bt_sock_cache = kmem_cache_create("bt_sock", bt_sock_cache = kmem_cache_create("bt_sock",
sizeof(struct bt_sock), 0, sizeof(struct bt_sock), 0,
...@@ -352,7 +360,7 @@ static int __init bt_init(void) ...@@ -352,7 +360,7 @@ static int __init bt_init(void)
BT_ERR("Socket cache creation failed"); BT_ERR("Socket cache creation failed");
return -ENOMEM; return -ENOMEM;
} }
sock_register(&bt_sock_family_ops); sock_register(&bt_sock_family_ops);
BT_INFO("HCI device and connection manager initialized"); BT_INFO("HCI device and connection manager initialized");
......
...@@ -4,12 +4,8 @@ config BT_BNEP ...@@ -4,12 +4,8 @@ config BT_BNEP
select CRC32 select CRC32
help help
BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
emulation layer on top of Bluetooth. BNEP is required for Bluetooth emulation layer on top of Bluetooth. BNEP is required for
PAN (Personal Area Network). 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>.
Say Y here to compile BNEP support into the kernel or say M to Say Y here to compile BNEP support into the kernel or say M to
compile it as module (bnep). compile it as module (bnep).
......
...@@ -3,7 +3,7 @@ config BT_CMTP ...@@ -3,7 +3,7 @@ config BT_CMTP
depends on BT && BT_L2CAP && ISDN_CAPI depends on BT && BT_L2CAP && ISDN_CAPI
help help
CMTP (CAPI Message Transport Protocol) is a transport layer 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. ISDN Access Profile.
Say Y here to compile CMTP support into the kernel or say M to Say Y here to compile CMTP support into the kernel or say M to
......
...@@ -22,11 +22,7 @@ ...@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth HCI connection handling. */
* HCI Connection handling.
*
* $Id: hci_conn.c,v 1.2 2002/04/17 17:37:16 maxk Exp $
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -54,7 +50,7 @@ ...@@ -54,7 +50,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG #ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
void hci_acl_connect(struct hci_conn *conn) 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) ...@@ -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) 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); BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
hci_conn_del_timer(conn); hci_conn_del_timer(conn);
if (conn->type == SCO_LINK) { if (conn->type == SCO_LINK) {
...@@ -226,14 +222,14 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) ...@@ -226,14 +222,14 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
list_for_each(p, &hci_dev_list) { list_for_each(p, &hci_dev_list) {
struct hci_dev *d = list_entry(p, struct hci_dev, list); struct hci_dev *d = list_entry(p, struct hci_dev, list);
if (!test_bit(HCI_UP, &d->flags)) if (!test_bit(HCI_UP, &d->flags))
continue; continue;
/* Simple routing: /* Simple routing:
* No source address - find interface with bdaddr != dst * No source address - find interface with bdaddr != dst
* Source address - find interface with bdaddr == src * Source address - find interface with bdaddr == src
*/ */
if (use_src) { if (use_src) {
if (!bacmp(&d->bdaddr, src)) { if (!bacmp(&d->bdaddr, src)) {
...@@ -252,6 +248,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) ...@@ -252,6 +248,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
read_unlock_bh(&hci_dev_list_lock); read_unlock_bh(&hci_dev_list_lock);
return hdev; return hdev;
} }
EXPORT_SYMBOL(hci_get_route);
/* Create SCO or ACL connection. /* Create SCO or ACL connection.
* Device _must_ be locked */ * Device _must_ be locked */
...@@ -294,15 +291,16 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -294,15 +291,16 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
return acl; return acl;
} }
} }
EXPORT_SYMBOL(hci_connect);
/* Authenticate remote device */ /* Authenticate remote device */
int hci_conn_auth(struct hci_conn *conn) int hci_conn_auth(struct hci_conn *conn)
{ {
BT_DBG("conn %p", conn); BT_DBG("conn %p", conn);
if (conn->link_mode & HCI_LM_AUTH) if (conn->link_mode & HCI_LM_AUTH)
return 1; return 1;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp; struct hci_cp_auth_requested cp;
cp.handle = __cpu_to_le16(conn->handle); cp.handle = __cpu_to_le16(conn->handle);
...@@ -310,15 +308,16 @@ int hci_conn_auth(struct hci_conn *conn) ...@@ -310,15 +308,16 @@ int hci_conn_auth(struct hci_conn *conn)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(hci_conn_auth);
/* Enable encryption */ /* Enable encryption */
int hci_conn_encrypt(struct hci_conn *conn) int hci_conn_encrypt(struct hci_conn *conn)
{ {
BT_DBG("conn %p", conn); BT_DBG("conn %p", conn);
if (conn->link_mode & HCI_LM_ENCRYPT) if (conn->link_mode & HCI_LM_ENCRYPT)
return 1; return 1;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0; return 0;
...@@ -330,12 +329,13 @@ int hci_conn_encrypt(struct hci_conn *conn) ...@@ -330,12 +329,13 @@ int hci_conn_encrypt(struct hci_conn *conn)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(hci_conn_encrypt);
/* Drop all connection on the device */ /* Drop all connection on the device */
void hci_conn_hash_flush(struct hci_dev *hdev) void hci_conn_hash_flush(struct hci_dev *hdev)
{ {
struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p; struct list_head *p;
BT_DBG("hdev %s", hdev->name); BT_DBG("hdev %s", hdev->name);
......
...@@ -22,11 +22,7 @@ ...@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth HCI core. */
* Bluetooth HCI Core.
*
* $Id: hci_core.c,v 1.6 2002/04/17 17:37:16 maxk Exp $
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -55,7 +51,7 @@ ...@@ -55,7 +51,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG #ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
static void hci_cmd_task(unsigned long arg); static void hci_cmd_task(unsigned long arg);
...@@ -288,6 +284,7 @@ struct hci_dev *hci_dev_get(int index) ...@@ -288,6 +284,7 @@ struct hci_dev *hci_dev_get(int index)
read_unlock(&hci_dev_list_lock); read_unlock(&hci_dev_list_lock);
return hdev; return hdev;
} }
EXPORT_SYMBOL(hci_dev_get);
/* ---- Inquiry support ---- */ /* ---- Inquiry support ---- */
void inquiry_cache_flush(struct hci_dev *hdev) void inquiry_cache_flush(struct hci_dev *hdev)
...@@ -416,7 +413,7 @@ int hci_inquiry(unsigned long arg) ...@@ -416,7 +413,7 @@ int hci_inquiry(unsigned long arg)
if (!copy_to_user(ptr, &ir, sizeof(ir))) { if (!copy_to_user(ptr, &ir, sizeof(ir))) {
ptr += 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)) ir.num_rsp))
err = -EFAULT; err = -EFAULT;
} else } else
...@@ -459,7 +456,7 @@ int hci_dev_open(__u16 dev) ...@@ -459,7 +456,7 @@ int hci_dev_open(__u16 dev)
//__hci_request(hdev, hci_reset_req, 0, HZ); //__hci_request(hdev, hci_reset_req, 0, HZ);
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
clear_bit(HCI_INIT, &hdev->flags); clear_bit(HCI_INIT, &hdev->flags);
} }
...@@ -514,7 +511,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) ...@@ -514,7 +511,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
inquiry_cache_flush(hdev); inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev); hci_conn_hash_flush(hdev);
hci_dev_unlock_bh(hdev); hci_dev_unlock_bh(hdev);
hci_notify(hdev, HCI_DEV_DOWN); hci_notify(hdev, HCI_DEV_DOWN);
if (hdev->flush) if (hdev->flush)
...@@ -558,7 +555,7 @@ int hci_dev_close(__u16 dev) ...@@ -558,7 +555,7 @@ int hci_dev_close(__u16 dev)
{ {
struct hci_dev *hdev; struct hci_dev *hdev;
int err; int err;
if (!(hdev = hci_dev_get(dev))) if (!(hdev = hci_dev_get(dev)))
return -ENODEV; return -ENODEV;
err = hci_dev_do_close(hdev); err = hci_dev_do_close(hdev);
...@@ -649,19 +646,19 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg) ...@@ -649,19 +646,19 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg)
if (err) if (err)
break; break;
} }
err = hci_request(hdev, hci_encrypt_req, err = hci_request(hdev, hci_encrypt_req,
dr.dev_opt, HCI_INIT_TIMEOUT); dr.dev_opt, HCI_INIT_TIMEOUT);
break; break;
case HCISETSCAN: case HCISETSCAN:
err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT); err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
break; break;
case HCISETPTYPE: case HCISETPTYPE:
hdev->pkt_type = (__u16) dr.dev_opt; hdev->pkt_type = (__u16) dr.dev_opt;
break; break;
case HCISETLINKPOL: case HCISETLINKPOL:
hdev->link_policy = (__u16) dr.dev_opt; hdev->link_policy = (__u16) dr.dev_opt;
break; break;
...@@ -683,7 +680,7 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg) ...@@ -683,7 +680,7 @@ int hci_dev_cmd(unsigned int cmd, unsigned long arg)
default: default:
err = -EINVAL; err = -EINVAL;
break; break;
} }
hci_dev_put(hdev); hci_dev_put(hdev);
return err; return err;
} }
...@@ -779,6 +776,7 @@ struct hci_dev *hci_alloc_dev(void) ...@@ -779,6 +776,7 @@ struct hci_dev *hci_alloc_dev(void)
return hdev; return hdev;
} }
EXPORT_SYMBOL(hci_alloc_dev);
/* Free HCI device */ /* Free HCI device */
void hci_free_dev(struct hci_dev *hdev) void hci_free_dev(struct hci_dev *hdev)
...@@ -786,6 +784,7 @@ 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 */ /* will free via class release */
class_device_put(&hdev->class_dev); class_device_put(&hdev->class_dev);
} }
EXPORT_SYMBOL(hci_free_dev);
/* Register HCI device */ /* Register HCI device */
int hci_register_dev(struct hci_dev *hdev) int hci_register_dev(struct hci_dev *hdev)
...@@ -802,7 +801,7 @@ 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 */ /* Find first available device id */
list_for_each(p, &hci_dev_list) { 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; break;
head = p; id++; head = p; id++;
} }
...@@ -813,7 +812,7 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -813,7 +812,7 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set(&hdev->refcnt, 1); atomic_set(&hdev->refcnt, 1);
spin_lock_init(&hdev->lock); spin_lock_init(&hdev->lock);
hdev->flags = 0; hdev->flags = 0;
hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
hdev->link_mode = (HCI_LM_ACCEPT); hdev->link_mode = (HCI_LM_ACCEPT);
...@@ -836,7 +835,7 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -836,7 +835,7 @@ int hci_register_dev(struct hci_dev *hdev)
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
atomic_set(&hdev->promisc, 0); atomic_set(&hdev->promisc, 0);
write_unlock_bh(&hci_dev_list_lock); write_unlock_bh(&hci_dev_list_lock);
hci_register_sysfs(hdev); hci_register_sysfs(hdev);
...@@ -845,6 +844,7 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -845,6 +844,7 @@ int hci_register_dev(struct hci_dev *hdev)
return id; return id;
} }
EXPORT_SYMBOL(hci_register_dev);
/* Unregister HCI device */ /* Unregister HCI device */
int hci_unregister_dev(struct hci_dev *hdev) int hci_unregister_dev(struct hci_dev *hdev)
...@@ -864,6 +864,7 @@ int hci_unregister_dev(struct hci_dev *hdev) ...@@ -864,6 +864,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
__hci_dev_put(hdev); __hci_dev_put(hdev);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_unregister_dev);
/* Suspend HCI device */ /* Suspend HCI device */
int hci_suspend_dev(struct hci_dev *hdev) int hci_suspend_dev(struct hci_dev *hdev)
...@@ -871,13 +872,15 @@ 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); hci_notify(hdev, HCI_DEV_SUSPEND);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_suspend_dev);
/* Resume HCI device */ /* Resume HCI device */
int hci_resume_dev(struct hci_dev *hdev) int hci_resume_dev(struct hci_dev *hdev)
{ {
hci_notify(hdev, HCI_DEV_RESUME); hci_notify(hdev, HCI_DEV_RESUME);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_resume_dev);
/* ---- Interface to upper protocols ---- */ /* ---- Interface to upper protocols ---- */
...@@ -903,6 +906,7 @@ int hci_register_proto(struct hci_proto *hp) ...@@ -903,6 +906,7 @@ int hci_register_proto(struct hci_proto *hp)
return err; return err;
} }
EXPORT_SYMBOL(hci_register_proto);
int hci_unregister_proto(struct hci_proto *hp) int hci_unregister_proto(struct hci_proto *hp)
{ {
...@@ -924,6 +928,7 @@ int hci_unregister_proto(struct hci_proto *hp) ...@@ -924,6 +928,7 @@ int hci_unregister_proto(struct hci_proto *hp)
return err; return err;
} }
EXPORT_SYMBOL(hci_unregister_proto);
static int hci_send_frame(struct sk_buff *skb) static int hci_send_frame(struct sk_buff *skb)
{ {
...@@ -938,7 +943,7 @@ 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)) { if (atomic_read(&hdev->promisc)) {
/* Time stamp */ /* Time stamp */
do_gettimeofday(&skb->stamp); do_gettimeofday(&skb->stamp);
hci_send_to_sock(hdev, skb); 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 ...@@ -980,6 +985,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
return 0; return 0;
} }
EXPORT_SYMBOL(hci_send_cmd);
/* Get data from the previously sent command */ /* Get data from the previously sent command */
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf) 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) ...@@ -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)) { if (!(list = skb_shinfo(skb)->frag_list)) {
/* Non fragmented */ /* Non fragmented */
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len); BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
skb_queue_tail(&conn->data_q, skb); skb_queue_tail(&conn->data_q, skb);
} else { } else {
/* Fragmented */ /* Fragmented */
...@@ -1044,7 +1050,7 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) ...@@ -1044,7 +1050,7 @@ int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
skb->dev = (void *) hdev; skb->dev = (void *) hdev;
skb->pkt_type = HCI_ACLDATA_PKT; skb->pkt_type = HCI_ACLDATA_PKT;
hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT); hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
__skb_queue_tail(&conn->data_q, skb); __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) ...@@ -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); spin_unlock_bh(&conn->data_q.lock);
} }
hci_sched_tx(hdev); hci_sched_tx(hdev);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_send_acl);
/* Send SCO data */ /* Send SCO data */
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) 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) ...@@ -1082,6 +1089,7 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
hci_sched_tx(hdev); hci_sched_tx(hdev);
return 0; return 0;
} }
EXPORT_SYMBOL(hci_send_sco);
/* ---- HCI TX task (outgoing data) ---- */ /* ---- HCI TX task (outgoing data) ---- */
...@@ -1091,7 +1099,7 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int ...@@ -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_hash *h = &hdev->conn_hash;
struct hci_conn *conn = NULL; struct hci_conn *conn = NULL;
int num = 0, min = ~0; int num = 0, min = ~0;
struct list_head *p; struct list_head *p;
/* We don't have to lock device here. Connections are always /* We don't have to lock device here. Connections are always
* added and removed with TX task disabled. */ * 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 ...@@ -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) static inline void hci_acl_tx_to(struct hci_dev *hdev)
{ {
struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn_hash *h = &hdev->conn_hash;
struct list_head *p; struct list_head *p;
struct hci_conn *c; struct hci_conn *c;
BT_ERR("%s ACL tx timeout", hdev->name); 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) ...@@ -1265,7 +1273,7 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); conn = hci_conn_hash_lookup_handle(hdev, handle);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
if (conn) { if (conn) {
register struct hci_proto *hp; register struct hci_proto *hp;
...@@ -1348,7 +1356,7 @@ static void hci_cmd_task(unsigned long arg) ...@@ -1348,7 +1356,7 @@ static void hci_cmd_task(unsigned long arg)
BT_ERR("%s command tx timeout", hdev->name); BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1); atomic_set(&hdev->cmd_cnt, 1);
} }
/* Send queued commands */ /* Send queued commands */
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) { if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
if (hdev->sent_cmd) if (hdev->sent_cmd)
......
...@@ -22,11 +22,7 @@ ...@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth HCI event handling. */
* HCI Events.
*
* $Id: hci_event.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -54,7 +50,7 @@ ...@@ -54,7 +50,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG #ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
/* Handle HCI Event packets */ /* Handle HCI Event packets */
...@@ -98,9 +94,9 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * ...@@ -98,9 +94,9 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
if (rd->status) if (rd->status)
break; break;
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle)); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
if (conn) { if (conn) {
if (rd->role) if (rd->role)
...@@ -355,7 +351,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) ...@@ -355,7 +351,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
return; return;
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name, 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 ...@@ -572,7 +568,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) { if (!conn) {
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -585,7 +581,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -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)) if (test_bit(HCI_AUTH, &hdev->flags))
conn->link_mode |= HCI_LM_AUTH; conn->link_mode |= HCI_LM_AUTH;
if (test_bit(HCI_ENCRYPT, &hdev->flags)) if (test_bit(HCI_ENCRYPT, &hdev->flags))
conn->link_mode |= HCI_LM_ENCRYPT; conn->link_mode |= HCI_LM_ENCRYPT;
...@@ -643,7 +639,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff ...@@ -643,7 +639,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
return; return;
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) { if (conn) {
conn->state = BT_CLOSED; conn->state = BT_CLOSED;
...@@ -709,7 +705,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb ...@@ -709,7 +705,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
return; return;
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) { if (conn) {
if (ev->role) if (ev->role)
...@@ -731,7 +727,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -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); BT_DBG("%s status %d", hdev->name, ev->status);
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) { if (conn) {
if (!ev->status) if (!ev->status)
...@@ -739,7 +735,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -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); clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
hci_proto_auth_cfm(conn, ev->status); hci_proto_auth_cfm(conn, ev->status);
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
if (!ev->status) { if (!ev->status) {
struct hci_cp_set_conn_encrypt cp; 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 * ...@@ -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); BT_DBG("%s status %d", hdev->name, ev->status);
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle); conn = hci_conn_hash_lookup_handle(hdev, handle);
if (conn) { if (conn) {
if (!ev->status) { if (!ev->status) {
if (ev->encrypt) if (ev->encrypt)
conn->link_mode |= HCI_LM_ENCRYPT; conn->link_mode |= HCI_LM_ENCRYPT;
else else
conn->link_mode &= ~HCI_LM_ENCRYPT; conn->link_mode &= ~HCI_LM_ENCRYPT;
...@@ -840,7 +836,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -840,7 +836,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
case HCI_EV_CMD_STATUS: case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data; cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs)); skb_pull(skb, sizeof(cs));
opcode = __le16_to_cpu(cs->opcode); opcode = __le16_to_cpu(cs->opcode);
ogf = hci_opcode_ogf(opcode); ogf = hci_opcode_ogf(opcode);
ocf = hci_opcode_ocf(opcode); ocf = hci_opcode_ocf(opcode);
...@@ -928,15 +924,16 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) ...@@ -928,15 +924,16 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
return; return;
hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE); 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; hdr->plen = sizeof(*ev) + dlen;
ev = (void *) skb_put(skb, sizeof(*ev) + dlen); ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
ev->type = type; ev->type = type;
memcpy(ev->data, data, dlen); memcpy(ev->data, data, dlen);
skb->pkt_type = HCI_EVENT_PKT; skb->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev; skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb); hci_send_to_sock(hdev, skb);
kfree_skb(skb); kfree_skb(skb);
} }
EXPORT_SYMBOL(hci_si_event);
...@@ -22,11 +22,7 @@ ...@@ -22,11 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth HCI sockets. */
* Bluetooth HCI socket layer.
*
* $Id: hci_sock.c,v 1.4 2002/04/18 22:26:14 maxk Exp $
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -56,7 +52,7 @@ ...@@ -56,7 +52,7 @@
#ifndef CONFIG_BT_HCI_SOCK_DEBUG #ifndef CONFIG_BT_HCI_SOCK_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
/* ----- HCI socket interface ----- */ /* ----- HCI socket interface ----- */
...@@ -139,7 +135,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -139,7 +135,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (sock_queue_rcv_skb(sk, nskb)) if (sock_queue_rcv_skb(sk, nskb))
kfree_skb(nskb); kfree_skb(nskb);
} }
read_unlock(&hci_sk_list.lock); read_unlock(&hci_sk_list.lock);
} }
...@@ -318,14 +313,14 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ ...@@ -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; __u32 mask = hci_pi(sk)->cmsg_mask;
if (mask & HCI_CMSG_DIR) 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) 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, 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; int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -355,7 +350,7 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -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); err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
hci_sock_cmsg(sk, msg, skb); hci_sock_cmsg(sk, msg, skb);
skb_free_datagram(sk, skb); skb_free_datagram(sk, skb);
return err ? : copied; return err ? : copied;
...@@ -406,7 +401,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -406,7 +401,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (((ogf > HCI_SFLT_MAX_OGF) || if (((ogf > HCI_SFLT_MAX_OGF) ||
!hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[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; err = -EPERM;
goto drop; goto drop;
} }
...@@ -487,9 +482,9 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user ...@@ -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); uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
} }
{ {
struct hci_filter *f = &hci_pi(sk)->filter; struct hci_filter *f = &hci_pi(sk)->filter;
f->type_mask = uf.type_mask; f->type_mask = uf.type_mask;
f->opcode = uf.opcode; f->opcode = uf.opcode;
*((u32 *) f->event_mask + 0) = uf.event_mask[0]; *((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 ...@@ -501,7 +496,7 @@ int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user
err = -ENOPROTOOPT; err = -ENOPROTOOPT;
break; break;
} }
release_sock(sk); release_sock(sk);
return err; return err;
} }
...@@ -539,7 +534,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user ...@@ -539,7 +534,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user
case HCI_FILTER: case HCI_FILTER:
{ {
struct hci_filter *f = &hci_pi(sk)->filter; struct hci_filter *f = &hci_pi(sk)->filter;
uf.type_mask = f->type_mask; uf.type_mask = f->type_mask;
uf.opcode = f->opcode; uf.opcode = f->opcode;
uf.event_mask[0] = *((u32 *) f->event_mask + 0); 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 ...@@ -560,23 +555,23 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user
} }
struct proto_ops hci_sock_ops = { struct proto_ops hci_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = hci_sock_release, .release = hci_sock_release,
.bind = hci_sock_bind, .bind = hci_sock_bind,
.getname = hci_sock_getname, .getname = hci_sock_getname,
.sendmsg = hci_sock_sendmsg, .sendmsg = hci_sock_sendmsg,
.recvmsg = hci_sock_recvmsg, .recvmsg = hci_sock_recvmsg,
.ioctl = hci_sock_ioctl, .ioctl = hci_sock_ioctl,
.poll = datagram_poll, .poll = datagram_poll,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = sock_no_shutdown, .shutdown = sock_no_shutdown,
.setsockopt = hci_sock_setsockopt, .setsockopt = hci_sock_setsockopt,
.getsockopt = hci_sock_getsockopt, .getsockopt = hci_sock_getsockopt,
.connect = sock_no_connect, .connect = sock_no_connect,
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = sock_no_accept, .accept = sock_no_accept,
.mmap = sock_no_mmap .mmap = sock_no_mmap
}; };
static int hci_sock_create(struct socket *sock, int protocol) static int hci_sock_create(struct socket *sock, int protocol)
...@@ -597,7 +592,7 @@ 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); sk_set_owner(sk, THIS_MODULE);
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
sk->sk_state = BT_OPEN; sk->sk_state = BT_OPEN;
bt_sock_link(&hci_sk_list, sk); bt_sock_link(&hci_sk_list, sk);
return 0; return 0;
...@@ -607,14 +602,14 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, ...@@ -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_dev *hdev = (struct hci_dev *) ptr;
struct hci_ev_si_device ev; struct hci_ev_si_device ev;
BT_DBG("hdev %s event %ld", hdev->name, event); BT_DBG("hdev %s event %ld", hdev->name, event);
/* Send event to sockets */ /* Send event to sockets */
ev.event = event; ev.event = event;
ev.dev_id = hdev->id; ev.dev_id = hdev->id;
hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev); hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
if (event == HCI_DEV_UNREG) { if (event == HCI_DEV_UNREG) {
struct sock *sk; struct sock *sk;
struct hlist_node *node; struct hlist_node *node;
...@@ -640,9 +635,9 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, ...@@ -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 = { struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.create = hci_sock_create, .create = hci_sock_create,
}; };
struct notifier_block hci_sock_nblock = { struct notifier_block hci_sock_nblock = {
......
/* Bluetooth HCI driver model support. */
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -7,7 +9,7 @@ ...@@ -7,7 +9,7 @@
#ifndef CONFIG_BT_HCI_CORE_DEBUG #ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
static ssize_t show_name(struct class_device *cdev, char *buf) static ssize_t show_name(struct class_device *cdev, char *buf)
......
This diff is collapsed.
...@@ -22,11 +22,10 @@ ...@@ -22,11 +22,10 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth kernel library. */
* Bluetooth kernel library.
* #include <linux/config.h>
* $Id: lib.c,v 1.1 2002/03/08 21:06:59 maxk Exp $ #include <linux/module.h>
*/
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/stddef.h> #include <linux/stddef.h>
...@@ -58,6 +57,7 @@ void bt_dump(char *pref, __u8 *buf, int count) ...@@ -58,6 +57,7 @@ void bt_dump(char *pref, __u8 *buf, int count)
if (line[0]) if (line[0])
printk(KERN_INFO "%s:%s\n", pref, line); printk(KERN_INFO "%s:%s\n", pref, line);
} }
EXPORT_SYMBOL(bt_dump);
void baswap(bdaddr_t *dst, bdaddr_t *src) void baswap(bdaddr_t *dst, bdaddr_t *src)
{ {
...@@ -68,6 +68,7 @@ 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++) for (i = 0; i < 6; i++)
d[i] = s[5 - i]; d[i] = s[5 - i];
} }
EXPORT_SYMBOL(baswap);
char *batostr(bdaddr_t *ba) char *batostr(bdaddr_t *ba)
{ {
...@@ -76,11 +77,12 @@ char *batostr(bdaddr_t *ba) ...@@ -76,11 +77,12 @@ char *batostr(bdaddr_t *ba)
i ^= 1; i ^= 1;
sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", 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]); ba->b[3], ba->b[4], ba->b[5]);
return str[i]; return str[i];
} }
EXPORT_SYMBOL(batostr);
/* Bluetooth error codes to Unix errno mapping */ /* Bluetooth error codes to Unix errno mapping */
int bt_err(__u16 code) int bt_err(__u16 code)
...@@ -173,3 +175,4 @@ int bt_err(__u16 code) ...@@ -173,3 +175,4 @@ int bt_err(__u16 code)
return ENOSYS; return ENOSYS;
} }
} }
EXPORT_SYMBOL(bt_err);
...@@ -2,7 +2,7 @@ config BT_RFCOMM ...@@ -2,7 +2,7 @@ config BT_RFCOMM
tristate "RFCOMM protocol support" tristate "RFCOMM protocol support"
depends on BT && BT_L2CAP depends on BT && BT_L2CAP
help 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 support is required for Dialup Networking, OBEX and other Bluetooth
applications. applications.
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h> #include <net/bluetooth/rfcomm.h>
#define VERSION "1.2" #define VERSION "1.3"
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG #undef BT_DBG
......
...@@ -398,6 +398,27 @@ int rfcomm_sock_listen(struct socket *sock, int backlog) ...@@ -398,6 +398,27 @@ int rfcomm_sock_listen(struct socket *sock, int backlog)
goto done; 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_max_ack_backlog = backlog;
sk->sk_ack_backlog = 0; sk->sk_ack_backlog = 0;
sk->sk_state = BT_LISTEN; sk->sk_state = BT_LISTEN;
......
...@@ -22,12 +22,7 @@ ...@@ -22,12 +22,7 @@
SOFTWARE IS DISCLAIMED. SOFTWARE IS DISCLAIMED.
*/ */
/* /* Bluetooth SCO sockets. */
* Bluetooth SCO sockets.
*
* $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
*/
#define VERSION "0.3"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -58,9 +53,11 @@ ...@@ -58,9 +53,11 @@
#ifndef CONFIG_BT_SCO_DEBUG #ifndef CONFIG_BT_SCO_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG( A... ) #define BT_DBG(D...)
#endif #endif
#define VERSION "0.3"
static struct proto_ops sco_sock_ops; static struct proto_ops sco_sock_ops;
static struct bt_sock_list sco_sk_list = { 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) ...@@ -137,7 +134,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
conn->src = &hdev->bdaddr; conn->src = &hdev->bdaddr;
conn->dst = &hcon->dst; conn->dst = &hcon->dst;
if (hdev->sco_mtu > 0) if (hdev->sco_mtu > 0)
conn->mtu = hdev->sco_mtu; conn->mtu = hdev->sco_mtu;
else else
...@@ -483,7 +480,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le ...@@ -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); write_lock_bh(&sco_sk_list.lock);
if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) { if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
err = -EADDRINUSE; err = -EADDRINUSE;
} else { } else {
...@@ -491,7 +488,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le ...@@ -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); bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr);
sk->sk_state = BT_BOUND; sk->sk_state = BT_BOUND;
} }
write_unlock_bh(&sco_sk_list.lock); write_unlock_bh(&sco_sk_list.lock);
done: done:
...@@ -694,7 +691,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char ...@@ -694,7 +691,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
err = -ENOTCONN; err = -ENOTCONN;
break; break;
} }
opts.mtu = sco_pi(sk)->conn->mtu; opts.mtu = sco_pi(sk)->conn->mtu;
BT_DBG("mtu %d", opts.mtu); BT_DBG("mtu %d", opts.mtu);
...@@ -737,7 +734,7 @@ static int sco_sock_release(struct socket *sock) ...@@ -737,7 +734,7 @@ static int sco_sock_release(struct socket *sock)
if (!sk) if (!sk)
return 0; return 0;
sco_sock_close(sk); sco_sock_close(sk);
if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) { if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) {
...@@ -811,7 +808,7 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -811,7 +808,7 @@ static void sco_conn_ready(struct sco_conn *conn)
sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC); sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
if (!sk) { if (!sk) {
bh_unlock_sock(parent); bh_unlock_sock(parent);
goto done; goto done;
} }
sco_sock_init(sk, parent); sco_sock_init(sk, parent);
...@@ -820,14 +817,14 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -820,14 +817,14 @@ static void sco_conn_ready(struct sco_conn *conn)
bacpy(&bt_sk(sk)->dst, conn->dst); bacpy(&bt_sk(sk)->dst, conn->dst);
hci_conn_hold(conn->hcon); 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 */ /* Wake up parent */
parent->sk_data_ready(parent, 1); parent->sk_data_ready(parent, 1);
bh_unlock_sock(parent); bh_unlock_sock(parent);
} }
done: done:
...@@ -858,7 +855,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) ...@@ -858,7 +855,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
sco_conn_ready(conn); sco_conn_ready(conn);
} else } else
sco_conn_del(hcon, bt_err(status)); sco_conn_del(hcon, bt_err(status));
return 0; return 0;
} }
...@@ -931,10 +928,10 @@ static int sco_seq_show(struct seq_file *seq, void *e) ...@@ -931,10 +928,10 @@ static int sco_seq_show(struct seq_file *seq, void *e)
} }
static struct seq_operations sco_seq_ops = { static struct seq_operations sco_seq_ops = {
.start = sco_seq_start, .start = sco_seq_start,
.next = sco_seq_next, .next = sco_seq_next,
.stop = sco_seq_stop, .stop = sco_seq_stop,
.show = sco_seq_show .show = sco_seq_show
}; };
static int sco_seq_open(struct inode *inode, struct file *file) 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) ...@@ -943,74 +940,74 @@ static int sco_seq_open(struct inode *inode, struct file *file)
} }
static struct file_operations sco_seq_fops = { static struct file_operations sco_seq_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = sco_seq_open, .open = sco_seq_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .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); struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
p->owner = THIS_MODULE; p->owner = THIS_MODULE;
p->proc_fops = &sco_seq_fops; p->proc_fops = &sco_seq_fops;
return 0; return 0;
} }
static void __exit sco_proc_cleanup(void) static void __exit sco_proc_cleanup(void)
{ {
remove_proc_entry("sco", proc_bt); remove_proc_entry("sco", proc_bt);
} }
#else /* CONFIG_PROC_FS */ #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) static void __exit sco_proc_cleanup(void)
{ {
return; return;
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
static struct proto_ops sco_sock_ops = { static struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = sco_sock_release, .release = sco_sock_release,
.bind = sco_sock_bind, .bind = sco_sock_bind,
.connect = sco_sock_connect, .connect = sco_sock_connect,
.listen = sco_sock_listen, .listen = sco_sock_listen,
.accept = sco_sock_accept, .accept = sco_sock_accept,
.getname = sco_sock_getname, .getname = sco_sock_getname,
.sendmsg = sco_sock_sendmsg, .sendmsg = sco_sock_sendmsg,
.recvmsg = bt_sock_recvmsg, .recvmsg = bt_sock_recvmsg,
.poll = bt_sock_poll, .poll = bt_sock_poll,
.ioctl = sock_no_ioctl, .ioctl = sock_no_ioctl,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.shutdown = sock_no_shutdown, .shutdown = sock_no_shutdown,
.setsockopt = sco_sock_setsockopt, .setsockopt = sco_sock_setsockopt,
.getsockopt = sco_sock_getsockopt .getsockopt = sco_sock_getsockopt
}; };
static struct net_proto_family sco_sock_family_ops = { static struct net_proto_family sco_sock_family_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
.create = sco_sock_create, .owner = THIS_MODULE,
.owner = THIS_MODULE, .create = sco_sock_create,
}; };
static struct hci_proto sco_hci_proto = { static struct hci_proto sco_hci_proto = {
.name = "SCO", .name = "SCO",
.id = HCI_PROTO_SCO, .id = HCI_PROTO_SCO,
.connect_ind = sco_connect_ind, .connect_ind = sco_connect_ind,
.connect_cfm = sco_connect_cfm, .connect_cfm = sco_connect_cfm,
.disconn_ind = sco_disconn_ind, .disconn_ind = sco_disconn_ind,
.recv_scodata = sco_recv_scodata .recv_scodata = sco_recv_scodata
}; };
static int __init sco_init(void) static int __init sco_init(void)
...@@ -1028,7 +1025,7 @@ static int __init sco_init(void) ...@@ -1028,7 +1025,7 @@ static int __init sco_init(void)
} }
sco_proc_init(); sco_proc_init();
BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO (Voice Link) ver %s", VERSION);
BT_INFO("SCO socket layer initialized"); 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