Commit da749ce7 authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/network-2.6

into nuts.davemloft.net:/disk1/BK/net-2.6
parents be9bc8d1 44fcd182
...@@ -174,7 +174,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -174,7 +174,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
BT_DBG("intf %p id %p", intf, id); BT_DBG("intf %p id %p", intf, id);
if (intf->altsetting->desc.bInterfaceNumber != 0) if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
return -ENODEV; return -ENODEV;
data = kmalloc(sizeof(*data), GFP_KERNEL); data = kmalloc(sizeof(*data), GFP_KERNEL);
......
...@@ -652,11 +652,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -652,11 +652,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
BT_DBG("intf %p id %p", intf, id); BT_DBG("intf %p id %p", intf, id);
/* Check number of endpoints */ /* Check number of endpoints */
if (intf->altsetting[0].desc.bNumEndpoints < 2) if (intf->cur_altsetting->desc.bNumEndpoints < 2)
return -EIO; return -EIO;
bulk_out_ep = &intf->altsetting[0].endpoint[0]; bulk_out_ep = &intf->cur_altsetting->endpoint[0];
bulk_in_ep = &intf->altsetting[0].endpoint[1]; bulk_in_ep = &intf->cur_altsetting->endpoint[1];
if (!bulk_out_ep || !bulk_in_ep) { if (!bulk_out_ep || !bulk_in_ep) {
BT_ERR("Bulk endpoints not found"); BT_ERR("Bulk endpoints not found");
......
...@@ -795,17 +795,15 @@ static void hci_usb_destruct(struct hci_dev *hdev) ...@@ -795,17 +795,15 @@ static void hci_usb_destruct(struct hci_dev *hdev)
int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
struct usb_host_endpoint *bulk_out_ep[HCI_MAX_IFACE_NUM]; struct usb_host_endpoint *bulk_out_ep = NULL;
struct usb_host_endpoint *isoc_out_ep[HCI_MAX_IFACE_NUM]; struct usb_host_endpoint *bulk_in_ep = NULL;
struct usb_host_endpoint *bulk_in_ep[HCI_MAX_IFACE_NUM]; struct usb_host_endpoint *intr_in_ep = NULL;
struct usb_host_endpoint *isoc_in_ep[HCI_MAX_IFACE_NUM];
struct usb_host_endpoint *intr_in_ep[HCI_MAX_IFACE_NUM];
struct usb_host_endpoint *ep; struct usb_host_endpoint *ep;
struct usb_host_interface *uif; struct usb_host_interface *uif;
struct usb_interface *iface, *isoc_iface; struct usb_interface *isoc_iface;
struct hci_usb *husb; struct hci_usb *husb;
struct hci_dev *hdev; struct hci_dev *hdev;
int i, a, e, size, ifn, isoc_ifnum, isoc_alts; int i, e, size, isoc_ifnum, isoc_alts;
BT_DBG("udev %p intf %p", udev, intf); BT_DBG("udev %p intf %p", udev, intf);
...@@ -816,84 +814,38 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -816,84 +814,38 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
id = match; id = match;
} }
iface = udev->actconfig->interface[0];
if (id->driver_info & HCI_IGNORE) if (id->driver_info & HCI_IGNORE)
return -ENODEV; return -ENODEV;
if (intf->altsetting->desc.bInterfaceNumber > 0) if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
return -ENODEV; return -ENODEV;
/* Check number of endpoints */
if (intf->altsetting[0].desc.bNumEndpoints < 3)
return -EIO;
memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
memset(intr_in_ep, 0, sizeof(intr_in_ep));
size = 0;
isoc_iface = NULL;
isoc_alts = isoc_ifnum = 0;
/* Find endpoints that we need */ /* Find endpoints that we need */
ifn = min_t(unsigned int, udev->actconfig->desc.bNumInterfaces, HCI_MAX_IFACE_NUM); uif = intf->cur_altsetting;
for (i = 0; i < ifn; i++) { for (e = 0; e < uif->desc.bNumEndpoints; e++) {
iface = udev->actconfig->interface[i]; ep = &uif->endpoint[e];
for (a = 0; a < iface->num_altsetting; a++) {
uif = &iface->altsetting[a]; switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
for (e = 0; e < uif->desc.bNumEndpoints; e++) { case USB_ENDPOINT_XFER_INT:
ep = &uif->endpoint[e]; if (ep->desc.bEndpointAddress & USB_DIR_IN)
intr_in_ep = ep;
switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { break;
case USB_ENDPOINT_XFER_INT:
if (ep->desc.bEndpointAddress & USB_DIR_IN) case USB_ENDPOINT_XFER_BULK:
intr_in_ep[i] = ep; if (ep->desc.bEndpointAddress & USB_DIR_IN)
break; bulk_in_ep = ep;
else
case USB_ENDPOINT_XFER_BULK: bulk_out_ep = ep;
if (ep->desc.bEndpointAddress & USB_DIR_IN) break;
bulk_in_ep[i] = ep;
else
bulk_out_ep[i] = ep;
break;
#ifdef CONFIG_BT_HCIUSB_SCO
case USB_ENDPOINT_XFER_ISOC:
if (ep->desc.wMaxPacketSize < size || a > 2)
break;
size = ep->desc.wMaxPacketSize;
isoc_iface = iface;
isoc_alts = a;
isoc_ifnum = i;
if (ep->desc.bEndpointAddress & USB_DIR_IN)
isoc_in_ep[i] = ep;
else
isoc_out_ep[i] = ep;
break;
#endif
}
}
} }
} }
if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) { if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
BT_DBG("Bulk endpoints not found"); BT_DBG("Bulk endpoints not found");
goto done; goto done;
} }
#ifdef CONFIG_BT_HCIUSB_SCO
if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
BT_DBG("Isoc endpoints not found");
isoc_iface = NULL;
}
#endif
if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) { if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
BT_ERR("Can't allocate: control structure"); BT_ERR("Can't allocate: control structure");
goto done; goto done;
...@@ -902,26 +854,67 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -902,26 +854,67 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
memset(husb, 0, sizeof(struct hci_usb)); memset(husb, 0, sizeof(struct hci_usb));
husb->udev = udev; husb->udev = udev;
husb->bulk_out_ep = bulk_out_ep[0]; husb->bulk_out_ep = bulk_out_ep;
husb->bulk_in_ep = bulk_in_ep[0]; husb->bulk_in_ep = bulk_in_ep;
husb->intr_in_ep = intr_in_ep[0]; husb->intr_in_ep = intr_in_ep;
if (id->driver_info & HCI_DIGIANSWER) if (id->driver_info & HCI_DIGIANSWER)
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 */
size = 0;
isoc_iface = NULL;
isoc_alts = 0;
isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO #ifdef CONFIG_BT_HCIUSB_SCO
isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
if (isoc_iface) { if (isoc_iface) {
BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts); int a;
if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) { struct usb_host_endpoint *isoc_out_ep = NULL;
BT_ERR("Can't set isoc interface settings"); struct usb_host_endpoint *isoc_in_ep = NULL;
isoc_iface = NULL;
for (a = 0; a < isoc_iface->num_altsetting; a++) {
uif = &isoc_iface->altsetting[a];
for (e = 0; e < uif->desc.bNumEndpoints; e++) {
ep = &uif->endpoint[e];
switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
if (ep->desc.wMaxPacketSize < size ||
uif->desc.bAlternateSetting > 2)
break;
size = ep->desc.wMaxPacketSize;
isoc_alts = uif->desc.bAlternateSetting;
if (ep->desc.bEndpointAddress & USB_DIR_IN)
isoc_in_ep = ep;
else
isoc_out_ep = ep;
break;
}
}
}
if (!isoc_in_ep || !isoc_out_ep)
BT_DBG("Isoc endpoints not found");
else {
BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
if (usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb) != 0)
BT_ERR("Can't claim isoc interface");
else if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
BT_ERR("Can't set isoc interface settings");
usb_driver_release_interface(&hci_usb_driver, isoc_iface);
} else {
husb->isoc_iface = isoc_iface;
husb->isoc_in_ep = isoc_in_ep;
husb->isoc_out_ep = isoc_out_ep;
}
} }
usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
husb->isoc_iface = isoc_iface;
husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
} }
#endif #endif
...@@ -967,6 +960,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -967,6 +960,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0; return 0;
probe_error: probe_error:
if (husb->isoc_iface)
usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
kfree(husb); kfree(husb);
done: done:
...@@ -976,11 +971,13 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -976,11 +971,13 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
static void hci_usb_disconnect(struct usb_interface *intf) static void hci_usb_disconnect(struct usb_interface *intf)
{ {
struct hci_usb *husb = usb_get_intfdata(intf); struct hci_usb *husb = usb_get_intfdata(intf);
struct hci_dev *hdev = husb->hdev; struct hci_dev *hdev;
if (!husb) if (!husb || intf == husb->isoc_iface)
return; return;
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
hdev = husb->hdev;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
......
...@@ -158,8 +158,7 @@ static int rfcomm_l2sock_create(struct socket **sock) ...@@ -158,8 +158,7 @@ static int rfcomm_l2sock_create(struct socket **sock)
BT_DBG(""); BT_DBG("");
err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET, err = sock_create_kern(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
BTPROTO_L2CAP, sock);
if (!err) { if (!err) {
struct sock *sk = (*sock)->sk; struct sock *sk = (*sock)->sk;
sk->sk_data_ready = rfcomm_l2data_ready; sk->sk_data_ready = rfcomm_l2data_ready;
...@@ -1642,9 +1641,9 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) ...@@ -1642,9 +1641,9 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
BT_DBG("session %p", s); BT_DBG("session %p", s);
if (sock_create_lite(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, &nsock)) if (sock_create_lite(PF_BLUETOOTH, sock->type, BTPROTO_L2CAP, &nsock))
return; return;
nsock->ops = sock->ops; nsock->ops = sock->ops;
__module_get(nsock->ops->owner); __module_get(nsock->ops->owner);
......
...@@ -277,19 +277,19 @@ int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, ...@@ -277,19 +277,19 @@ int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) { if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) {
/* attempt to update an entry for a local interface */ /* attempt to update an entry for a local interface */
if (unlikely(fdb->is_local)) { if (unlikely(fdb->is_local)) {
if (is_local) /* it is okay to have multiple ports with same
printk(KERN_INFO "%s: attempt to add" * address, just don't allow to be spoofed.
" interface with same source address.\n", */
source->dev->name); if (!is_local) {
else if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING "%s: received packet with " printk(KERN_WARNING "%s: received packet with "
" own address as source address\n", " own address as source address\n",
source->dev->name); source->dev->name);
ret = -EEXIST; ret = -EEXIST;
}
goto out; goto out;
} }
if (likely(!fdb->is_static || is_local)) { if (likely(!fdb->is_static || is_local)) {
/* move to end of age list */ /* move to end of age list */
list_del(&fdb->age_list); list_del(&fdb->age_list);
......
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