Commit d75a1aa8 authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents daf52a28 7fc97d57
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
* $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $ * $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $
*/ */
#define VERSION "2.4" #define VERSION "2.5"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -70,12 +70,6 @@ ...@@ -70,12 +70,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[] = {
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
/* Digianswer device */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
/* Generic Bluetooth USB device */ /* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) }, { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
...@@ -93,6 +87,19 @@ static struct usb_device_id bluetooth_ids[] = { ...@@ -93,6 +87,19 @@ static struct usb_device_id bluetooth_ids[] = {
MODULE_DEVICE_TABLE (usb, bluetooth_ids); MODULE_DEVICE_TABLE (usb, bluetooth_ids);
static struct usb_device_id blacklist_ids[] = {
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET },
/* Digianswer device */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
{ } /* Terminating entry */
};
struct _urb *_urb_alloc(int isoc, int gfp) struct _urb *_urb_alloc(int isoc, int gfp)
{ {
struct _urb *_urb = kmalloc(sizeof(struct _urb) + struct _urb *_urb = kmalloc(sizeof(struct _urb) +
...@@ -790,6 +797,13 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -790,6 +797,13 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
BT_DBG("udev %p ifnum %d", udev, ifnum); BT_DBG("udev %p ifnum %d", udev, ifnum);
if (!id->driver_info) {
const struct usb_device_id *match;
match = usb_match_id(intf, blacklist_ids);
if (match)
id = match;
}
iface = udev->actconfig->interface[0]; iface = udev->actconfig->interface[0];
if (id->driver_info & HCI_IGNORE) if (id->driver_info & HCI_IGNORE)
...@@ -928,6 +942,9 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -928,6 +942,9 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
hdev->owner = THIS_MODULE; hdev->owner = THIS_MODULE;
if (id->driver_info & HCI_RESET)
set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
if (hci_register_dev(hdev) < 0) { if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device"); BT_ERR("Can't register HCI device");
hci_free_dev(hdev); hci_free_dev(hdev);
...@@ -994,6 +1011,6 @@ void hci_usb_cleanup(void) ...@@ -994,6 +1011,6 @@ void hci_usb_cleanup(void)
module_init(hci_usb_init); module_init(hci_usb_init);
module_exit(hci_usb_cleanup); module_exit(hci_usb_cleanup);
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>"); MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION); MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -38,7 +38,8 @@ ...@@ -38,7 +38,8 @@
#define HCI_DIGI_REQ 0x40 #define HCI_DIGI_REQ 0x40
#define HCI_IGNORE 0x01 #define HCI_IGNORE 0x01
#define HCI_DIGIANSWER 0x02 #define HCI_RESET 0x02
#define HCI_DIGIANSWER 0x04
#define HCI_MAX_IFACE_NUM 3 #define HCI_MAX_IFACE_NUM 3
......
...@@ -321,6 +321,7 @@ enum ...@@ -321,6 +321,7 @@ enum
NET_TCP_LOW_LATENCY=93, NET_TCP_LOW_LATENCY=93,
NET_IPV4_IPFRAG_SECRET_INTERVAL=94, NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
NET_TCP_WESTWOOD=95, NET_TCP_WESTWOOD=95,
NET_IPV4_IGMP_MAX_MSF=96,
}; };
enum { enum {
......
...@@ -42,6 +42,11 @@ ...@@ -42,6 +42,11 @@
#define HCI_DEV_SUSPEND 5 #define HCI_DEV_SUSPEND 5
#define HCI_DEV_RESUME 6 #define HCI_DEV_RESUME 6
/* HCI notify events */
#define HCI_NOTIFY_CONN_ADD 1
#define HCI_NOTIFY_CONN_DEL 2
#define HCI_NOTIFY_VOICE_SETTING 3
/* HCI device types */ /* HCI device types */
#define HCI_VHCI 0 #define HCI_VHCI 0
#define HCI_USB 1 #define HCI_USB 1
...@@ -50,6 +55,11 @@ ...@@ -50,6 +55,11 @@
#define HCI_RS232 4 #define HCI_RS232 4
#define HCI_PCI 5 #define HCI_PCI 5
/* HCI device quirks */
enum {
HCI_QUIRK_RESET_ON_INIT
};
/* HCI device flags */ /* HCI device flags */
enum { enum {
HCI_UP, HCI_UP,
......
...@@ -77,6 +77,8 @@ struct hci_dev { ...@@ -77,6 +77,8 @@ struct hci_dev {
__u16 link_policy; __u16 link_policy;
__u16 link_mode; __u16 link_mode;
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;
...@@ -128,6 +130,7 @@ struct hci_dev { ...@@ -128,6 +130,7 @@ struct hci_dev {
int (*flush)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb); int (*send)(struct sk_buff *skb);
void (*destruct)(struct hci_dev *hdev); void (*destruct)(struct hci_dev *hdev);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
}; };
......
...@@ -170,6 +170,9 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -170,6 +170,9 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
hci_conn_hash_add(hdev, conn); hci_conn_hash_add(hdev, conn);
tasklet_enable(&hdev->tx_task); tasklet_enable(&hdev->tx_task);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
return conn; return conn;
} }
...@@ -196,6 +199,9 @@ int hci_conn_del(struct hci_conn *conn) ...@@ -196,6 +199,9 @@ int hci_conn_del(struct hci_conn *conn)
hdev->acl_cnt += conn->sent; hdev->acl_cnt += conn->sent;
} }
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
tasklet_disable(&hdev->tx_task); tasklet_disable(&hdev->tx_task);
hci_conn_hash_del(hdev, conn); hci_conn_hash_del(hdev, conn);
tasklet_enable(&hdev->tx_task); tasklet_enable(&hdev->tx_task);
......
...@@ -189,6 +189,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) ...@@ -189,6 +189,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Mandatory initialization */ /* Mandatory initialization */
/* Reset */
if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
/* Read Local Supported Features */ /* Read Local Supported Features */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL); hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
......
...@@ -232,6 +232,9 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb ...@@ -232,6 +232,9 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
hdev->voice_setting = setting; hdev->voice_setting = setting;
BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
} }
break; break;
...@@ -247,6 +250,9 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb ...@@ -247,6 +250,9 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
hdev->voice_setting = setting; hdev->voice_setting = setting;
BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
if (hdev->notify)
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
} }
hci_req_complete(hdev, status); hci_req_complete(hdev, status);
break; break;
......
...@@ -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.1" #define VERSION "1.2"
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG #undef BT_DBG
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ #define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
#define RFCOMM_TTY_MINOR 0 #define RFCOMM_TTY_MINOR 0
static struct tty_driver *rfcomm_tty_driver;
struct rfcomm_dev { struct rfcomm_dev {
struct list_head list; struct list_head list;
atomic_t refcnt; atomic_t refcnt;
...@@ -98,6 +100,8 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) ...@@ -98,6 +100,8 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
rfcomm_dlc_put(dlc); rfcomm_dlc_put(dlc);
tty_unregister_device(rfcomm_tty_driver, dev->id);
/* Refcount should only hit zero when called from rfcomm_dev_del() /* Refcount should only hit zero when called from rfcomm_dev_del()
which will have taken us off the list. Everything else are which will have taken us off the list. Everything else are
refcounting bugs. */ refcounting bugs. */
...@@ -239,7 +243,10 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) ...@@ -239,7 +243,10 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
if (err) { if (err) {
kfree(dev); kfree(dev);
return err; return err;
} else }
tty_register_device(rfcomm_tty_driver, dev->id, NULL);
return dev->id; return dev->id;
} }
...@@ -871,8 +878,6 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsign ...@@ -871,8 +878,6 @@ static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsign
/* ---- TTY structure ---- */ /* ---- TTY structure ---- */
static struct tty_driver *rfcomm_tty_driver;
static struct tty_operations rfcomm_ops = { static struct tty_operations rfcomm_ops = {
.open = rfcomm_tty_open, .open = rfcomm_tty_open,
.close = rfcomm_tty_close, .close = rfcomm_tty_close,
...@@ -906,7 +911,7 @@ int rfcomm_init_ttys(void) ...@@ -906,7 +911,7 @@ int rfcomm_init_ttys(void)
rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR; rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR;
rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW; rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
rfcomm_tty_driver->init_termios = tty_std_termios; rfcomm_tty_driver->init_termios = tty_std_termios;
rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
......
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
#endif #endif
#define IP_MAX_MEMBERSHIPS 20 #define IP_MAX_MEMBERSHIPS 20
#define IP_MAX_MSF 10
#ifdef CONFIG_IP_MULTICAST #ifdef CONFIG_IP_MULTICAST
/* Parameter names and values are taken from igmp-v2-06 draft */ /* Parameter names and values are taken from igmp-v2-06 draft */
...@@ -1325,6 +1326,7 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr) ...@@ -1325,6 +1326,7 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
* Join a socket to a group * Join a socket to a group
*/ */
int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS; int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS;
int sysctl_igmp_max_msf = IP_MAX_MSF;
static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
...@@ -1790,6 +1792,10 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct ...@@ -1790,6 +1792,10 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
} }
/* else, add a new source to the filter */ /* else, add a new source to the filter */
if (psl && psl->sl_count >= sysctl_igmp_max_msf) {
err = -ENOBUFS;
goto done;
}
if (!psl || psl->sl_count == psl->sl_max) { if (!psl || psl->sl_count == psl->sl_max) {
struct ip_sf_socklist *newpsl; struct ip_sf_socklist *newpsl;
int count = IP_SFBLOCK; int count = IP_SFBLOCK;
......
...@@ -618,6 +618,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -618,6 +618,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
case IP_MSFILTER: case IP_MSFILTER:
{ {
extern int sysctl_optmem_max; extern int sysctl_optmem_max;
extern int sysctl_igmp_max_msf;
struct ip_msfilter *msf; struct ip_msfilter *msf;
if (optlen < IP_MSFILTER_SIZE(0)) if (optlen < IP_MSFILTER_SIZE(0))
...@@ -636,9 +637,14 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt ...@@ -636,9 +637,14 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
kfree(msf); kfree(msf);
break; break;
} }
if (IP_MSFILTER_SIZE(msf->imsf_numsrc) < /* numsrc >= (1G-4) overflow in 32 bits */
IP_MSFILTER_SIZE(0) || if (msf->imsf_numsrc >= 0x3ffffffcU ||
IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) { msf->imsf_numsrc > sysctl_igmp_max_msf) {
kfree(msf);
err = -ENOBUFS;
break;
}
if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
kfree(msf); kfree(msf);
err = -EINVAL; err = -EINVAL;
break; break;
......
...@@ -39,6 +39,7 @@ extern int sysctl_icmp_ratemask; ...@@ -39,6 +39,7 @@ extern int sysctl_icmp_ratemask;
/* From igmp.c */ /* From igmp.c */
extern int sysctl_igmp_max_memberships; extern int sysctl_igmp_max_memberships;
extern int sysctl_igmp_max_msf;
/* From inetpeer.c */ /* From inetpeer.c */
extern int inet_peer_threshold; extern int inet_peer_threshold;
...@@ -411,6 +412,14 @@ ctl_table ipv4_table[] = { ...@@ -411,6 +412,14 @@ ctl_table ipv4_table[] = {
}, },
#endif #endif
{
.ctl_name = NET_IPV4_IGMP_MAX_MSF,
.procname = "igmp_max_msf",
.data = &sysctl_igmp_max_msf,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec
},
{ {
.ctl_name = NET_IPV4_INET_PEER_THRESHOLD, .ctl_name = NET_IPV4_INET_PEER_THRESHOLD,
.procname = "inet_peer_threshold", .procname = "inet_peer_threshold",
......
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