Commit b231070a authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents b6b561c3 4b836f39
...@@ -57,7 +57,7 @@ struct ath3k_version { ...@@ -57,7 +57,7 @@ struct ath3k_version {
unsigned char reserved[0x07]; unsigned char reserved[0x07];
}; };
static struct usb_device_id ath3k_table[] = { static const struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */ /* Atheros AR3011 */
{ USB_DEVICE(0x0CF3, 0x3000) }, { USB_DEVICE(0x0CF3, 0x3000) },
...@@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); ...@@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
#define BTUSB_ATH3012 0x80 #define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files /* This table is to load patch and sysconfig files
* for AR3012 */ * for AR3012 */
static struct usb_device_id ath3k_blist_tbl[] = { static const struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/ /* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
static struct usb_driver bfusb_driver; static struct usb_driver bfusb_driver;
static struct usb_device_id bfusb_table[] = { static const struct usb_device_id bfusb_table[] = {
/* AVM BlueFRITZ! USB */ /* AVM BlueFRITZ! USB */
{ USB_DEVICE(0x057c, 0x2200) }, { USB_DEVICE(0x057c, 0x2200) },
...@@ -318,7 +318,6 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch ...@@ -318,7 +318,6 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
return -ENOMEM; return -ENOMEM;
} }
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type; bt_cb(skb)->pkt_type = pkt_type;
data->reassembly = skb; data->reassembly = skb;
...@@ -333,7 +332,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch ...@@ -333,7 +332,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
memcpy(skb_put(data->reassembly, len), buf, len); memcpy(skb_put(data->reassembly, len), buf, len);
if (hdr & 0x08) { if (hdr & 0x08) {
hci_recv_frame(data->reassembly); hci_recv_frame(data->hdev, data->reassembly);
data->reassembly = NULL; data->reassembly = NULL;
} }
...@@ -465,26 +464,18 @@ static int bfusb_close(struct hci_dev *hdev) ...@@ -465,26 +464,18 @@ static int bfusb_close(struct hci_dev *hdev)
return 0; return 0;
} }
static int bfusb_send_frame(struct sk_buff *skb) static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev; struct bfusb_data *data = hci_get_drvdata(hdev);
struct bfusb_data *data;
struct sk_buff *nskb; struct sk_buff *nskb;
unsigned char buf[3]; unsigned char buf[3];
int sent = 0, size, count; int sent = 0, size, count;
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len); BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
data = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++; hdev->stat.cmd_tx++;
...@@ -544,11 +535,6 @@ static int bfusb_send_frame(struct sk_buff *skb) ...@@ -544,11 +535,6 @@ static int bfusb_send_frame(struct sk_buff *skb)
return 0; return 0;
} }
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
static int bfusb_load_firmware(struct bfusb_data *data, static int bfusb_load_firmware(struct bfusb_data *data,
const unsigned char *firmware, int count) const unsigned char *firmware, int count)
{ {
...@@ -699,11 +685,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -699,11 +685,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
hci_set_drvdata(hdev, data); hci_set_drvdata(hdev, data);
SET_HCIDEV_DEV(hdev, &intf->dev); SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = bfusb_open; hdev->open = bfusb_open;
hdev->close = bfusb_close; hdev->close = bfusb_close;
hdev->flush = bfusb_flush; hdev->flush = bfusb_flush;
hdev->send = bfusb_send_frame; hdev->send = bfusb_send_frame;
hdev->ioctl = bfusb_ioctl;
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");
......
...@@ -399,7 +399,6 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) ...@@ -399,7 +399,6 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) { if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = buf[i]; bt_cb(info->rx_skb)->pkt_type = buf[i];
switch (bt_cb(info->rx_skb)->pkt_type) { switch (bt_cb(info->rx_skb)->pkt_type) {
...@@ -477,7 +476,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) ...@@ -477,7 +476,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
break; break;
case RECV_WAIT_DATA: case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb); hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL; info->rx_skb = NULL;
break; break;
...@@ -659,17 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev) ...@@ -659,17 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev)
} }
static int bluecard_hci_send_frame(struct sk_buff *skb) static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
bluecard_info_t *info; bluecard_info_t *info = hci_get_drvdata(hdev);
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
...@@ -693,12 +684,6 @@ static int bluecard_hci_send_frame(struct sk_buff *skb) ...@@ -693,12 +684,6 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
} }
static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */ /* ======================== Card services HCI interaction ======================== */
...@@ -734,11 +719,10 @@ static int bluecard_open(bluecard_info_t *info) ...@@ -734,11 +719,10 @@ static int bluecard_open(bluecard_info_t *info)
hci_set_drvdata(hdev, info); hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bluecard_hci_open; hdev->open = bluecard_hci_open;
hdev->close = bluecard_hci_close; hdev->close = bluecard_hci_close;
hdev->flush = bluecard_hci_flush; hdev->flush = bluecard_hci_flush;
hdev->send = bluecard_hci_send_frame; hdev->send = bluecard_hci_send_frame;
hdev->ioctl = bluecard_hci_ioctl;
id = inb(iobase + 0x30); id = inb(iobase + 0x30);
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#define VERSION "0.10" #define VERSION "0.10"
static struct usb_device_id bpa10x_table[] = { static const struct usb_device_id bpa10x_table[] = {
/* Tektronix BPA 100/105 (Digianswer) */ /* Tektronix BPA 100/105 (Digianswer) */
{ USB_DEVICE(0x08fd, 0x0002) }, { USB_DEVICE(0x08fd, 0x0002) },
...@@ -129,8 +129,6 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) ...@@ -129,8 +129,6 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
return -ENOMEM; return -ENOMEM;
} }
skb->dev = (void *) hdev;
data->rx_skb[queue] = skb; data->rx_skb[queue] = skb;
scb = (void *) skb->cb; scb = (void *) skb->cb;
...@@ -155,7 +153,7 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count) ...@@ -155,7 +153,7 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
data->rx_skb[queue] = NULL; data->rx_skb[queue] = NULL;
bt_cb(skb)->pkt_type = scb->type; bt_cb(skb)->pkt_type = scb->type;
hci_recv_frame(skb); hci_recv_frame(hdev, skb);
} }
count -= len; buf += len; count -= len; buf += len;
...@@ -352,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev) ...@@ -352,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev)
return 0; return 0;
} }
static int bpa10x_send_frame(struct sk_buff *skb) static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct bpa10x_data *data = hci_get_drvdata(hdev); struct bpa10x_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr; struct usb_ctrlrequest *dr;
struct urb *urb; struct urb *urb;
...@@ -366,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb) ...@@ -366,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
skb->dev = (void *) hdev;
urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) if (!urb)
return -ENOMEM; return -ENOMEM;
......
...@@ -247,7 +247,6 @@ static void bt3c_receive(bt3c_info_t *info) ...@@ -247,7 +247,6 @@ static void bt3c_receive(bt3c_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) { if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L); bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
inb(iobase + DATA_H); inb(iobase + DATA_H);
//printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type); //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
...@@ -318,7 +317,7 @@ static void bt3c_receive(bt3c_info_t *info) ...@@ -318,7 +317,7 @@ static void bt3c_receive(bt3c_info_t *info)
break; break;
case RECV_WAIT_DATA: case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb); hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL; info->rx_skb = NULL;
break; break;
...@@ -416,19 +415,11 @@ static int bt3c_hci_close(struct hci_dev *hdev) ...@@ -416,19 +415,11 @@ static int bt3c_hci_close(struct hci_dev *hdev)
} }
static int bt3c_hci_send_frame(struct sk_buff *skb) static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
bt3c_info_t *info; bt3c_info_t *info = hci_get_drvdata(hdev);
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
unsigned long flags; unsigned long flags;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++; hdev->stat.cmd_tx++;
...@@ -455,12 +446,6 @@ static int bt3c_hci_send_frame(struct sk_buff *skb) ...@@ -455,12 +446,6 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
} }
static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */ /* ======================== Card services HCI interaction ======================== */
...@@ -577,11 +562,10 @@ static int bt3c_open(bt3c_info_t *info) ...@@ -577,11 +562,10 @@ static int bt3c_open(bt3c_info_t *info)
hci_set_drvdata(hdev, info); hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bt3c_hci_open; hdev->open = bt3c_hci_open;
hdev->close = bt3c_hci_close; hdev->close = bt3c_hci_close;
hdev->flush = bt3c_hci_flush; hdev->flush = bt3c_hci_flush;
hdev->send = bt3c_hci_send_frame; hdev->send = bt3c_hci_send_frame;
hdev->ioctl = bt3c_hci_ioctl;
/* Load firmware */ /* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
......
...@@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, ...@@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
skb->dev = (void *) priv->btmrvl_dev.hcidev;
skb_queue_head(&priv->adapter->tx_queue, skb); skb_queue_head(&priv->adapter->tx_queue, skb);
priv->btmrvl_dev.sendcmdflag = true; priv->btmrvl_dev.sendcmdflag = true;
...@@ -356,26 +355,12 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv) ...@@ -356,26 +355,12 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
priv->adapter = NULL; priv->adapter = NULL;
} }
static int btmrvl_ioctl(struct hci_dev *hdev, static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
unsigned int cmd, unsigned long arg)
{ {
return -ENOIOCTLCMD; struct btmrvl_private *priv = hci_get_drvdata(hdev);
}
static int btmrvl_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btmrvl_private *priv = NULL;
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len); BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
if (!hdev) {
BT_ERR("Frame for unknown HCI device");
return -ENODEV;
}
priv = hci_get_drvdata(hdev);
if (!test_bit(HCI_RUNNING, &hdev->flags)) { if (!test_bit(HCI_RUNNING, &hdev->flags)) {
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags); BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET, print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
...@@ -650,12 +635,11 @@ int btmrvl_register_hdev(struct btmrvl_private *priv) ...@@ -650,12 +635,11 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
priv->btmrvl_dev.hcidev = hdev; priv->btmrvl_dev.hcidev = hdev;
hci_set_drvdata(hdev, priv); hci_set_drvdata(hdev, priv);
hdev->bus = HCI_SDIO; hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open; hdev->open = btmrvl_open;
hdev->close = btmrvl_close; hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush; hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame; hdev->send = btmrvl_send_frame;
hdev->ioctl = btmrvl_ioctl;
hdev->setup = btmrvl_setup; hdev->setup = btmrvl_setup;
hdev->dev_type = priv->btmrvl_dev.dev_type; hdev->dev_type = priv->btmrvl_dev.dev_type;
......
...@@ -600,15 +600,14 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -600,15 +600,14 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case HCI_SCODATA_PKT: case HCI_SCODATA_PKT:
case HCI_EVENT_PKT: case HCI_EVENT_PKT:
bt_cb(skb)->pkt_type = type; bt_cb(skb)->pkt_type = type;
skb->dev = (void *)hdev;
skb_put(skb, buf_len); skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN); skb_pull(skb, SDIO_HEADER_LEN);
if (type == HCI_EVENT_PKT) { if (type == HCI_EVENT_PKT) {
if (btmrvl_check_evtpkt(priv, skb)) if (btmrvl_check_evtpkt(priv, skb))
hci_recv_frame(skb); hci_recv_frame(hdev, skb);
} else { } else {
hci_recv_frame(skb); hci_recv_frame(hdev, skb);
} }
hdev->stat.byte_rx += buf_len; hdev->stat.byte_rx += buf_len;
...@@ -616,12 +615,11 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) ...@@ -616,12 +615,11 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case MRVL_VENDOR_PKT: case MRVL_VENDOR_PKT:
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT; bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
skb->dev = (void *)hdev;
skb_put(skb, buf_len); skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN); skb_pull(skb, SDIO_HEADER_LEN);
if (btmrvl_process_event(priv, skb)) if (btmrvl_process_event(priv, skb))
hci_recv_frame(skb); hci_recv_frame(hdev, skb);
hdev->stat.byte_rx += buf_len; hdev->stat.byte_rx += buf_len;
break; break;
......
...@@ -157,10 +157,9 @@ static int btsdio_rx_packet(struct btsdio_data *data) ...@@ -157,10 +157,9 @@ static int btsdio_rx_packet(struct btsdio_data *data)
data->hdev->stat.byte_rx += len; data->hdev->stat.byte_rx += len;
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = hdr[3]; bt_cb(skb)->pkt_type = hdr[3];
err = hci_recv_frame(skb); err = hci_recv_frame(data->hdev, skb);
if (err < 0) if (err < 0)
return err; return err;
...@@ -255,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev) ...@@ -255,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev)
return 0; return 0;
} }
static int btsdio_send_frame(struct sk_buff *skb) static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btsdio_data *data = hci_get_drvdata(hdev); struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
......
...@@ -198,7 +198,6 @@ static void btuart_receive(btuart_info_t *info) ...@@ -198,7 +198,6 @@ static void btuart_receive(btuart_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) { if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX); bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
switch (bt_cb(info->rx_skb)->pkt_type) { switch (bt_cb(info->rx_skb)->pkt_type) {
...@@ -265,7 +264,7 @@ static void btuart_receive(btuart_info_t *info) ...@@ -265,7 +264,7 @@ static void btuart_receive(btuart_info_t *info)
break; break;
case RECV_WAIT_DATA: case RECV_WAIT_DATA:
hci_recv_frame(info->rx_skb); hci_recv_frame(info->hdev, info->rx_skb);
info->rx_skb = NULL; info->rx_skb = NULL;
break; break;
...@@ -424,17 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev) ...@@ -424,17 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev)
} }
static int btuart_hci_send_frame(struct sk_buff *skb) static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
btuart_info_t *info; btuart_info_t *info = hci_get_drvdata(hdev);
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
...@@ -458,12 +449,6 @@ static int btuart_hci_send_frame(struct sk_buff *skb) ...@@ -458,12 +449,6 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
} }
static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */ /* ======================== Card services HCI interaction ======================== */
...@@ -495,11 +480,10 @@ static int btuart_open(btuart_info_t *info) ...@@ -495,11 +480,10 @@ static int btuart_open(btuart_info_t *info)
hci_set_drvdata(hdev, info); hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = btuart_hci_open; hdev->open = btuart_hci_open;
hdev->close = btuart_hci_close; hdev->close = btuart_hci_close;
hdev->flush = btuart_hci_flush; hdev->flush = btuart_hci_flush;
hdev->send = btuart_hci_send_frame; hdev->send = btuart_hci_send_frame;
hdev->ioctl = btuart_hci_ioctl;
spin_lock_irqsave(&(info->lock), flags); spin_lock_irqsave(&(info->lock), flags);
......
...@@ -50,7 +50,7 @@ static struct usb_driver btusb_driver; ...@@ -50,7 +50,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_ATH3012 0x80 #define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100 #define BTUSB_INTEL 0x100
static struct usb_device_id btusb_table[] = { static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */ /* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
...@@ -121,7 +121,7 @@ static struct usb_device_id btusb_table[] = { ...@@ -121,7 +121,7 @@ static struct usb_device_id btusb_table[] = {
MODULE_DEVICE_TABLE(usb, btusb_table); MODULE_DEVICE_TABLE(usb, btusb_table);
static struct usb_device_id blacklist_table[] = { static const struct usb_device_id blacklist_table[] = {
/* CSR BlueCore devices */ /* CSR BlueCore devices */
{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
...@@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev) ...@@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev)
return 0; return 0;
} }
static int btusb_send_frame(struct sk_buff *skb) static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr; struct usb_ctrlrequest *dr;
struct urb *urb; struct urb *urb;
...@@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb) ...@@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
skb->dev = (void *) hdev;
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC);
...@@ -774,7 +775,7 @@ static int btusb_send_frame(struct sk_buff *skb) ...@@ -774,7 +775,7 @@ static int btusb_send_frame(struct sk_buff *skb)
break; break;
case HCI_SCODATA_PKT: case HCI_SCODATA_PKT:
if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
return -ENODEV; return -ENODEV;
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
...@@ -833,8 +834,8 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt) ...@@ -833,8 +834,8 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG("%s evt %d", hdev->name, evt); BT_DBG("%s evt %d", hdev->name, evt);
if (hdev->conn_hash.sco_num != data->sco_num) { if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
data->sco_num = hdev->conn_hash.sco_num; data->sco_num = hci_conn_num(hdev, SCO_LINK);
schedule_work(&data->work); schedule_work(&data->work);
} }
} }
...@@ -889,7 +890,7 @@ static void btusb_work(struct work_struct *work) ...@@ -889,7 +890,7 @@ static void btusb_work(struct work_struct *work)
int new_alts; int new_alts;
int err; int err;
if (hdev->conn_hash.sco_num > 0) { if (data->sco_num > 0) {
if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf); err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
if (err < 0) { if (err < 0) {
...@@ -903,9 +904,9 @@ static void btusb_work(struct work_struct *work) ...@@ -903,9 +904,9 @@ static void btusb_work(struct work_struct *work)
if (hdev->voice_setting & 0x0020) { if (hdev->voice_setting & 0x0020) {
static const int alts[3] = { 2, 4, 5 }; static const int alts[3] = { 2, 4, 5 };
new_alts = alts[hdev->conn_hash.sco_num - 1]; new_alts = alts[data->sco_num - 1];
} else { } else {
new_alts = hdev->conn_hash.sco_num; new_alts = data->sco_num;
} }
if (data->isoc_altsetting != new_alts) { if (data->isoc_altsetting != new_alts) {
......
...@@ -108,10 +108,8 @@ static long st_receive(void *priv_data, struct sk_buff *skb) ...@@ -108,10 +108,8 @@ static long st_receive(void *priv_data, struct sk_buff *skb)
return -EFAULT; return -EFAULT;
} }
skb->dev = (void *) lhst->hdev;
/* Forward skb to HCI core layer */ /* Forward skb to HCI core layer */
err = hci_recv_frame(skb); err = hci_recv_frame(lhst->hdev, skb);
if (err < 0) { if (err < 0) {
BT_ERR("Unable to push skb to HCI core(%d)", err); BT_ERR("Unable to push skb to HCI core(%d)", err);
return err; return err;
...@@ -253,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev) ...@@ -253,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev)
return err; return err;
} }
static int ti_st_send_frame(struct sk_buff *skb) static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev *hdev;
struct ti_st *hst; struct ti_st *hst;
long len; long len;
hdev = (struct hci_dev *)skb->dev;
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
......
...@@ -256,9 +256,8 @@ static void dtl1_receive(dtl1_info_t *info) ...@@ -256,9 +256,8 @@ static void dtl1_receive(dtl1_info_t *info)
case 0x83: case 0x83:
case 0x84: case 0x84:
/* send frame to the HCI layer */ /* send frame to the HCI layer */
info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type &= 0x0f; bt_cb(info->rx_skb)->pkt_type &= 0x0f;
hci_recv_frame(info->rx_skb); hci_recv_frame(info->hdev, info->rx_skb);
break; break;
default: default:
/* unknown packet */ /* unknown packet */
...@@ -383,20 +382,12 @@ static int dtl1_hci_close(struct hci_dev *hdev) ...@@ -383,20 +382,12 @@ static int dtl1_hci_close(struct hci_dev *hdev)
} }
static int dtl1_hci_send_frame(struct sk_buff *skb) static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
dtl1_info_t *info; dtl1_info_t *info = hci_get_drvdata(hdev);
struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
struct sk_buff *s; struct sk_buff *s;
nsh_t nsh; nsh_t nsh;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++; hdev->stat.cmd_tx++;
...@@ -438,12 +429,6 @@ static int dtl1_hci_send_frame(struct sk_buff *skb) ...@@ -438,12 +429,6 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
} }
static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
}
/* ======================== Card services HCI interaction ======================== */ /* ======================== Card services HCI interaction ======================== */
...@@ -477,11 +462,10 @@ static int dtl1_open(dtl1_info_t *info) ...@@ -477,11 +462,10 @@ static int dtl1_open(dtl1_info_t *info)
hci_set_drvdata(hdev, info); hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = dtl1_hci_open; hdev->open = dtl1_hci_open;
hdev->close = dtl1_hci_close; hdev->close = dtl1_hci_close;
hdev->flush = dtl1_hci_flush; hdev->flush = dtl1_hci_flush;
hdev->send = dtl1_hci_send_frame; hdev->send = dtl1_hci_send_frame;
hdev->ioctl = dtl1_hci_ioctl;
spin_lock_irqsave(&(info->lock), flags); spin_lock_irqsave(&(info->lock), flags);
......
...@@ -522,7 +522,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) ...@@ -522,7 +522,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE); memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT; bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
hci_recv_frame(bcsp->rx_skb); hci_recv_frame(hu->hdev, bcsp->rx_skb);
} else { } else {
BT_ERR ("Packet for unknown channel (%u %s)", BT_ERR ("Packet for unknown channel (%u %s)",
bcsp->rx_skb->data[1] & 0x0f, bcsp->rx_skb->data[1] & 0x0f,
...@@ -536,7 +536,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) ...@@ -536,7 +536,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
/* Pull out BCSP hdr */ /* Pull out BCSP hdr */
skb_pull(bcsp->rx_skb, 4); skb_pull(bcsp->rx_skb, 4);
hci_recv_frame(bcsp->rx_skb); hci_recv_frame(hu->hdev, bcsp->rx_skb);
} }
bcsp->rx_state = BCSP_W4_PKT_DELIMITER; bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
...@@ -655,7 +655,6 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count) ...@@ -655,7 +655,6 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
bcsp->rx_count = 0; bcsp->rx_count = 0;
return 0; return 0;
} }
bcsp->rx_skb->dev = (void *) hu->hdev;
break; break;
} }
break; break;
......
...@@ -124,30 +124,6 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) ...@@ -124,30 +124,6 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0; return 0;
} }
static inline int h4_check_data_len(struct h4_struct *h4, int len)
{
int room = skb_tailroom(h4->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
hci_recv_frame(h4->rx_skb);
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(h4->rx_skb);
} else {
h4->rx_state = H4_W4_DATA;
h4->rx_count = len;
return len;
}
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
return 0;
}
/* Recv data */ /* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count) static int h4_recv(struct hci_uart *hu, void *data, int count)
{ {
......
...@@ -340,7 +340,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu) ...@@ -340,7 +340,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
/* Remove Three-wire header */ /* Remove Three-wire header */
skb_pull(h5->rx_skb, 4); skb_pull(h5->rx_skb, 4);
hci_recv_frame(h5->rx_skb); hci_recv_frame(hu->hdev, h5->rx_skb);
h5->rx_skb = NULL; h5->rx_skb = NULL;
break; break;
......
...@@ -234,21 +234,13 @@ static int hci_uart_close(struct hci_dev *hdev) ...@@ -234,21 +234,13 @@ static int hci_uart_close(struct hci_dev *hdev)
} }
/* Send frames from HCI layer */ /* Send frames from HCI layer */
static int hci_uart_send_frame(struct sk_buff *skb) static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev* hdev = (struct hci_dev *) skb->dev; struct hci_uart *hu = hci_get_drvdata(hdev);
struct hci_uart *hu;
if (!hdev) {
BT_ERR("Frame for unknown device (hdev=NULL)");
return -ENODEV;
}
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
hu = hci_get_drvdata(hdev);
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
hu->proto->enqueue(hu, skb); hu->proto->enqueue(hu, skb);
......
...@@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu) ...@@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
/* prepare packet */ /* prepare packet */
hcill_packet = (struct hcill_cmd *) skb_put(skb, 1); hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
hcill_packet->cmd = cmd; hcill_packet->cmd = cmd;
skb->dev = (void *) hu->hdev;
/* send packet */ /* send packet */
skb_queue_tail(&ll->txq, skb); skb_queue_tail(&ll->txq, skb);
...@@ -346,14 +345,14 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) ...@@ -346,14 +345,14 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0; return 0;
} }
static inline int ll_check_data_len(struct ll_struct *ll, int len) static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len)
{ {
int room = skb_tailroom(ll->rx_skb); int room = skb_tailroom(ll->rx_skb);
BT_DBG("len %d room %d", len, room); BT_DBG("len %d room %d", len, room);
if (!len) { if (!len) {
hci_recv_frame(ll->rx_skb); hci_recv_frame(hdev, ll->rx_skb);
} else if (len > room) { } else if (len > room) {
BT_ERR("Data length is too large"); BT_ERR("Data length is too large");
kfree_skb(ll->rx_skb); kfree_skb(ll->rx_skb);
...@@ -395,7 +394,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) ...@@ -395,7 +394,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
switch (ll->rx_state) { switch (ll->rx_state) {
case HCILL_W4_DATA: case HCILL_W4_DATA:
BT_DBG("Complete data"); BT_DBG("Complete data");
hci_recv_frame(ll->rx_skb); hci_recv_frame(hu->hdev, ll->rx_skb);
ll->rx_state = HCILL_W4_PACKET_TYPE; ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_skb = NULL; ll->rx_skb = NULL;
...@@ -406,7 +405,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) ...@@ -406,7 +405,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen); BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
ll_check_data_len(ll, eh->plen); ll_check_data_len(hu->hdev, ll, eh->plen);
continue; continue;
case HCILL_W4_ACL_HDR: case HCILL_W4_ACL_HDR:
...@@ -415,7 +414,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) ...@@ -415,7 +414,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("ACL header: dlen %d", dlen); BT_DBG("ACL header: dlen %d", dlen);
ll_check_data_len(ll, dlen); ll_check_data_len(hu->hdev, ll, dlen);
continue; continue;
case HCILL_W4_SCO_HDR: case HCILL_W4_SCO_HDR:
...@@ -423,7 +422,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) ...@@ -423,7 +422,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("SCO header: dlen %d", sh->dlen); BT_DBG("SCO header: dlen %d", sh->dlen);
ll_check_data_len(ll, sh->dlen); ll_check_data_len(hu->hdev, ll, sh->dlen);
continue; continue;
} }
} }
...@@ -494,7 +493,6 @@ static int ll_recv(struct hci_uart *hu, void *data, int count) ...@@ -494,7 +493,6 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
return -ENOMEM; return -ENOMEM;
} }
ll->rx_skb->dev = (void *) hu->hdev;
bt_cb(ll->rx_skb)->pkt_type = type; bt_cb(ll->rx_skb)->pkt_type = type;
} }
......
...@@ -81,21 +81,13 @@ static int vhci_flush(struct hci_dev *hdev) ...@@ -81,21 +81,13 @@ static int vhci_flush(struct hci_dev *hdev)
return 0; return 0;
} }
static int vhci_send_frame(struct sk_buff *skb) static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_dev* hdev = (struct hci_dev *) skb->dev; struct vhci_data *data = hci_get_drvdata(hdev);
struct vhci_data *data;
if (!hdev) {
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
return -ENODEV;
}
if (!test_bit(HCI_RUNNING, &hdev->flags)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
data = hci_get_drvdata(hdev);
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb); skb_queue_tail(&data->readq, skb);
...@@ -179,10 +171,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, ...@@ -179,10 +171,9 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
return -ENODEV; return -ENODEV;
} }
skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type; bt_cb(skb)->pkt_type = pkt_type;
ret = hci_recv_frame(skb); ret = hci_recv_frame(data->hdev, skb);
break; break;
case HCI_VENDOR_PKT: case HCI_VENDOR_PKT:
......
...@@ -218,11 +218,10 @@ void baswap(bdaddr_t *dst, bdaddr_t *src); ...@@ -218,11 +218,10 @@ void baswap(bdaddr_t *dst, bdaddr_t *src);
struct bt_sock { struct bt_sock {
struct sock sk; struct sock sk;
bdaddr_t src;
bdaddr_t dst;
struct list_head accept_q; struct list_head accept_q;
struct sock *parent; struct sock *parent;
unsigned long flags; unsigned long flags;
void (*skb_msg_name)(struct sk_buff *, void *, int *);
}; };
enum { enum {
...@@ -285,6 +284,8 @@ struct bt_skb_cb { ...@@ -285,6 +284,8 @@ struct bt_skb_cb {
__u8 force_active; __u8 force_active;
struct l2cap_ctrl control; struct l2cap_ctrl control;
struct hci_req_ctrl req; struct hci_req_ctrl req;
bdaddr_t bdaddr;
__le16 psm;
}; };
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
......
...@@ -64,16 +64,20 @@ ...@@ -64,16 +64,20 @@
#define HCI_AMP 0x01 #define HCI_AMP 0x01
/* First BR/EDR Controller shall have ID = 0 */ /* First BR/EDR Controller shall have ID = 0 */
#define HCI_BREDR_ID 0 #define AMP_ID_BREDR 0x00
/* AMP controller types */
#define AMP_TYPE_BREDR 0x00
#define AMP_TYPE_80211 0x01
/* AMP controller status */ /* AMP controller status */
#define AMP_CTRL_POWERED_DOWN 0x00 #define AMP_STATUS_POWERED_DOWN 0x00
#define AMP_CTRL_BLUETOOTH_ONLY 0x01 #define AMP_STATUS_BLUETOOTH_ONLY 0x01
#define AMP_CTRL_NO_CAPACITY 0x02 #define AMP_STATUS_NO_CAPACITY 0x02
#define AMP_CTRL_LOW_CAPACITY 0x03 #define AMP_STATUS_LOW_CAPACITY 0x03
#define AMP_CTRL_MEDIUM_CAPACITY 0x04 #define AMP_STATUS_MEDIUM_CAPACITY 0x04
#define AMP_CTRL_HIGH_CAPACITY 0x05 #define AMP_STATUS_HIGH_CAPACITY 0x05
#define AMP_CTRL_FULL_CAPACITY 0x06 #define AMP_STATUS_FULL_CAPACITY 0x06
/* HCI device quirks */ /* HCI device quirks */
enum { enum {
...@@ -118,7 +122,7 @@ enum { ...@@ -118,7 +122,7 @@ enum {
HCI_SSP_ENABLED, HCI_SSP_ENABLED,
HCI_HS_ENABLED, HCI_HS_ENABLED,
HCI_LE_ENABLED, HCI_LE_ENABLED,
HCI_LE_PERIPHERAL, HCI_ADVERTISING,
HCI_CONNECTABLE, HCI_CONNECTABLE,
HCI_DISCOVERABLE, HCI_DISCOVERABLE,
HCI_LINK_SECURITY, HCI_LINK_SECURITY,
...@@ -811,6 +815,14 @@ struct hci_cp_host_buffer_size { ...@@ -811,6 +815,14 @@ struct hci_cp_host_buffer_size {
__le16 sco_max_pkt; __le16 sco_max_pkt;
} __packed; } __packed;
#define HCI_OP_READ_NUM_SUPPORTED_IAC 0x0c38
struct hci_rp_read_num_supported_iac {
__u8 status;
__u8 num_iac;
} __packed;
#define HCI_OP_READ_CURRENT_IAC_LAP 0x0c39
#define HCI_OP_WRITE_INQUIRY_MODE 0x0c45 #define HCI_OP_WRITE_INQUIRY_MODE 0x0c45
#define HCI_MAX_EIR_LENGTH 240 #define HCI_MAX_EIR_LENGTH 240
...@@ -847,6 +859,8 @@ struct hci_rp_read_inq_rsp_tx_power { ...@@ -847,6 +859,8 @@ struct hci_rp_read_inq_rsp_tx_power {
#define HCI_OP_SET_EVENT_MASK_PAGE_2 0x0c63 #define HCI_OP_SET_EVENT_MASK_PAGE_2 0x0c63
#define HCI_OP_READ_LOCATION_DATA 0x0c64
#define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66 #define HCI_OP_READ_FLOW_CONTROL_MODE 0x0c66
struct hci_rp_read_flow_control_mode { struct hci_rp_read_flow_control_mode {
__u8 status; __u8 status;
...@@ -1042,6 +1056,23 @@ struct hci_rp_le_read_local_features { ...@@ -1042,6 +1056,23 @@ struct hci_rp_le_read_local_features {
#define HCI_OP_LE_SET_RANDOM_ADDR 0x2005 #define HCI_OP_LE_SET_RANDOM_ADDR 0x2005
#define LE_ADV_IND 0x00
#define LE_ADV_DIRECT_IND 0x01
#define LE_ADV_SCAN_IND 0x02
#define LE_ADV_NONCONN_IND 0x03
#define HCI_OP_LE_SET_ADV_PARAM 0x2006
struct hci_cp_le_set_adv_param {
__le16 min_interval;
__le16 max_interval;
__u8 type;
__u8 own_address_type;
__u8 direct_addr_type;
bdaddr_t direct_addr;
__u8 channel_map;
__u8 filter_policy;
} __packed;
#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 #define HCI_OP_LE_READ_ADV_TX_POWER 0x2007
struct hci_rp_le_read_adv_tx_power { struct hci_rp_le_read_adv_tx_power {
__u8 status; __u8 status;
......
...@@ -159,11 +159,14 @@ struct hci_dev { ...@@ -159,11 +159,14 @@ struct hci_dev {
__u16 manufacturer; __u16 manufacturer;
__u16 lmp_subver; __u16 lmp_subver;
__u16 voice_setting; __u16 voice_setting;
__u8 num_iac;
__u8 io_capability; __u8 io_capability;
__s8 inq_tx_power; __s8 inq_tx_power;
__u16 page_scan_interval; __u16 page_scan_interval;
__u16 page_scan_window; __u16 page_scan_window;
__u8 page_scan_type; __u8 page_scan_type;
__u16 le_scan_interval;
__u16 le_scan_window;
__u16 devid_source; __u16 devid_source;
__u16 devid_vendor; __u16 devid_vendor;
...@@ -285,9 +288,8 @@ struct hci_dev { ...@@ -285,9 +288,8 @@ struct hci_dev {
int (*close)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev);
int (*setup)(struct hci_dev *hdev); int (*setup)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb); int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt); void (*notify)(struct hci_dev *hdev, unsigned int evt);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
}; };
#define HCI_PHY_HANDLE(handle) (handle & 0xff) #define HCI_PHY_HANDLE(handle) (handle & 0xff)
...@@ -299,6 +301,8 @@ struct hci_conn { ...@@ -299,6 +301,8 @@ struct hci_conn {
bdaddr_t dst; bdaddr_t dst;
__u8 dst_type; __u8 dst_type;
bdaddr_t src;
__u8 src_type;
__u16 handle; __u16 handle;
__u16 state; __u16 state;
__u8 mode; __u8 mode;
...@@ -704,19 +708,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) ...@@ -704,19 +708,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
dev_set_drvdata(&hdev->dev, data); dev_set_drvdata(&hdev->dev, data);
} }
/* hci_dev_list shall be locked */
static inline uint8_t __hci_num_ctrl(void)
{
uint8_t count = 0;
struct list_head *p;
list_for_each(p, &hci_dev_list) {
count++;
}
return count;
}
struct hci_dev *hci_dev_get(int index); struct hci_dev *hci_dev_get(int index);
struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
...@@ -769,7 +760,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); ...@@ -769,7 +760,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb); int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count); int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count); int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
...@@ -808,22 +799,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn); ...@@ -808,22 +799,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
/* returns true if at least one AMP active */
static inline bool hci_amp_capable(void)
{
struct hci_dev *hdev;
bool ret = false;
read_lock(&hci_dev_list_lock);
list_for_each_entry(hdev, &hci_dev_list, list)
if (hdev->amp_type == HCI_AMP &&
test_bit(HCI_UP, &hdev->flags))
ret = true;
read_unlock(&hci_dev_list_lock);
return ret;
}
/* ----- HCI protocols ----- */ /* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01 #define HCI_PROTO_DEFER 0x01
...@@ -1121,24 +1096,24 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); ...@@ -1121,24 +1096,24 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_BREDR_INQUIRY_LEN 0x08 #define DISCOV_BREDR_INQUIRY_LEN 0x08
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_index_added(struct hci_dev *hdev); void mgmt_index_added(struct hci_dev *hdev);
int mgmt_index_removed(struct hci_dev *hdev); void mgmt_index_removed(struct hci_dev *hdev);
int mgmt_set_powered_failed(struct hci_dev *hdev, int err); void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
int mgmt_powered(struct hci_dev *hdev, u8 powered); int mgmt_powered(struct hci_dev *hdev, u8 powered);
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
int mgmt_connectable(struct hci_dev *hdev, u8 connectable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
bool persistent); bool persistent);
int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u32 flags, u8 *name, u8 name_len, u8 addr_type, u32 flags, u8 *name, u8 name_len,
u8 *dev_class); u8 *dev_class);
int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 reason); u8 link_type, u8 addr_type, u8 reason);
int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status); u8 link_type, u8 addr_type, u8 status);
int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 status); u8 addr_type, u8 status);
int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 status); u8 status);
...@@ -1169,16 +1144,16 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, ...@@ -1169,16 +1144,16 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash, int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
u8 *randomizer, u8 status); u8 *randomizer, u8 status);
int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name, u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
u8 ssp, u8 *eir, u16 eir_len); u8 ssp, u8 *eir, u16 eir_len);
int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len); u8 addr_type, s8 rssi, u8 *name, u8 name_len);
int mgmt_discovering(struct hci_dev *hdev, u8 discovering); void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
bool mgmt_valid_hdev(struct hci_dev *hdev);
int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent); int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
void mgmt_reenable_advertising(struct hci_dev *hdev);
/* HCI info for socket */ /* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) sk) #define hci_pi(sk) ((struct hci_pinfo *) sk)
...@@ -1215,8 +1190,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, ...@@ -1215,8 +1190,6 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
__u8 ltk[16]); __u8 ltk[16]);
u8 bdaddr_to_le(u8 bdaddr_type);
#define SCO_AIRMODE_MASK 0x0003 #define SCO_AIRMODE_MASK 0x0003
#define SCO_AIRMODE_CVSD 0x0000 #define SCO_AIRMODE_CVSD 0x0000
#define SCO_AIRMODE_TRANSP 0x0003 #define SCO_AIRMODE_TRANSP 0x0003
......
...@@ -131,6 +131,7 @@ struct l2cap_conninfo { ...@@ -131,6 +131,7 @@ struct l2cap_conninfo {
/* L2CAP fixed channels */ /* L2CAP fixed channels */
#define L2CAP_FC_L2CAP 0x02 #define L2CAP_FC_L2CAP 0x02
#define L2CAP_FC_CONNLESS 0x04
#define L2CAP_FC_A2MP 0x08 #define L2CAP_FC_A2MP 0x08
/* L2CAP Control Field bit masks */ /* L2CAP Control Field bit masks */
...@@ -237,6 +238,7 @@ struct l2cap_conn_rsp { ...@@ -237,6 +238,7 @@ struct l2cap_conn_rsp {
/* protocol/service multiplexer (PSM) */ /* protocol/service multiplexer (PSM) */
#define L2CAP_PSM_SDP 0x0001 #define L2CAP_PSM_SDP 0x0001
#define L2CAP_PSM_RFCOMM 0x0003 #define L2CAP_PSM_RFCOMM 0x0003
#define L2CAP_PSM_3DSP 0x0021
/* channel indentifier */ /* channel indentifier */
#define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_SIGNALING 0x0001
...@@ -442,7 +444,12 @@ struct l2cap_chan { ...@@ -442,7 +444,12 @@ struct l2cap_chan {
__u8 state; __u8 state;
bdaddr_t dst;
__u8 dst_type;
bdaddr_t src;
__u8 src_type;
__le16 psm; __le16 psm;
__le16 sport;
__u16 dcid; __u16 dcid;
__u16 scid; __u16 scid;
...@@ -453,8 +460,6 @@ struct l2cap_chan { ...@@ -453,8 +460,6 @@ struct l2cap_chan {
__u8 chan_type; __u8 chan_type;
__u8 chan_policy; __u8 chan_policy;
__le16 sport;
__u8 sec_level; __u8 sec_level;
__u8 ident; __u8 ident;
...@@ -549,6 +554,7 @@ struct l2cap_ops { ...@@ -549,6 +554,7 @@ struct l2cap_ops {
int state); int state);
void (*ready) (struct l2cap_chan *chan); void (*ready) (struct l2cap_chan *chan);
void (*defer) (struct l2cap_chan *chan); void (*defer) (struct l2cap_chan *chan);
void (*resume) (struct l2cap_chan *chan);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb); unsigned long len, int nb);
}; };
...@@ -557,9 +563,6 @@ struct l2cap_conn { ...@@ -557,9 +563,6 @@ struct l2cap_conn {
struct hci_conn *hcon; struct hci_conn *hcon;
struct hci_chan *hchan; struct hci_chan *hchan;
bdaddr_t *dst;
bdaddr_t *src;
unsigned int mtu; unsigned int mtu;
__u32 feat_mask; __u32 feat_mask;
...@@ -650,6 +653,7 @@ enum { ...@@ -650,6 +653,7 @@ enum {
FLAG_FLUSHABLE, FLAG_FLUSHABLE,
FLAG_EXT_CTRL, FLAG_EXT_CTRL,
FLAG_EFS_ENABLE, FLAG_EFS_ENABLE,
FLAG_DEFER_SETUP,
}; };
enum { enum {
......
...@@ -362,6 +362,13 @@ struct mgmt_cp_set_static_address { ...@@ -362,6 +362,13 @@ struct mgmt_cp_set_static_address {
} __packed; } __packed;
#define MGMT_SET_STATIC_ADDRESS_SIZE 6 #define MGMT_SET_STATIC_ADDRESS_SIZE 6
#define MGMT_OP_SET_SCAN_PARAMS 0x002C
struct mgmt_cp_set_scan_params {
__le16 interval;
__le16 window;
} __packed;
#define MGMT_SET_SCAN_PARAMS_SIZE 4
#define MGMT_EV_CMD_COMPLETE 0x0001 #define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete { struct mgmt_ev_cmd_complete {
__le16 opcode; __le16 opcode;
......
...@@ -300,6 +300,8 @@ struct rfcomm_conninfo { ...@@ -300,6 +300,8 @@ struct rfcomm_conninfo {
struct rfcomm_pinfo { struct rfcomm_pinfo {
struct bt_sock bt; struct bt_sock bt;
bdaddr_t src;
bdaddr_t dst;
struct rfcomm_dlc *dlc; struct rfcomm_dlc *dlc;
u8 channel; u8 channel;
u8 sec_level; u8 sec_level;
......
...@@ -55,9 +55,6 @@ struct sco_conninfo { ...@@ -55,9 +55,6 @@ struct sco_conninfo {
struct sco_conn { struct sco_conn {
struct hci_conn *hcon; struct hci_conn *hcon;
bdaddr_t *dst;
bdaddr_t *src;
spinlock_t lock; spinlock_t lock;
struct sock *sk; struct sock *sk;
...@@ -72,6 +69,8 @@ struct sco_conn { ...@@ -72,6 +69,8 @@ struct sco_conn {
struct sco_pinfo { struct sco_pinfo {
struct bt_sock bt; struct bt_sock bt;
bdaddr_t src;
bdaddr_t dst;
__u32 flags; __u32 flags;
__u16 setting; __u16 setting;
struct sco_conn *conn; struct sco_conn *conn;
......
...@@ -15,8 +15,9 @@ ...@@ -15,8 +15,9 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h> #include "a2mp.h"
#include "amp.h"
/* Global AMP Manager list */ /* Global AMP Manager list */
LIST_HEAD(amp_mgr_list); LIST_HEAD(amp_mgr_list);
...@@ -75,33 +76,26 @@ u8 __next_ident(struct amp_mgr *mgr) ...@@ -75,33 +76,26 @@ u8 __next_ident(struct amp_mgr *mgr)
return mgr->ident; return mgr->ident;
} }
static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
{
cl->id = 0;
cl->type = 0;
cl->status = 1;
}
/* hci_dev_list shall be locked */ /* hci_dev_list shall be locked */
static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl) static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl)
{ {
int i = 0;
struct hci_dev *hdev; struct hci_dev *hdev;
int i = 1;
__a2mp_cl_bredr(cl); cl[0].id = AMP_ID_BREDR;
cl[0].type = AMP_TYPE_BREDR;
cl[0].status = AMP_STATUS_BLUETOOTH_ONLY;
list_for_each_entry(hdev, &hci_dev_list, list) { list_for_each_entry(hdev, &hci_dev_list, list) {
/* Iterate through AMP controllers */ if (hdev->dev_type == HCI_AMP) {
if (hdev->id == HCI_BREDR_ID) cl[i].id = hdev->id;
continue; cl[i].type = hdev->amp_type;
if (test_bit(HCI_UP, &hdev->flags))
/* Starting from second entry */ cl[i].status = hdev->amp_status;
if (++i >= num_ctrl) else
return; cl[i].status = AMP_STATUS_POWERED_DOWN;
i++;
cl[i].id = hdev->id; }
cl[i].type = hdev->amp_type;
cl[i].status = hdev->amp_status;
} }
} }
...@@ -129,6 +123,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -129,6 +123,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
struct a2mp_discov_rsp *rsp; struct a2mp_discov_rsp *rsp;
u16 ext_feat; u16 ext_feat;
u8 num_ctrl; u8 num_ctrl;
struct hci_dev *hdev;
if (len < sizeof(*req)) if (len < sizeof(*req))
return -EINVAL; return -EINVAL;
...@@ -152,7 +147,14 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -152,7 +147,14 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
read_lock(&hci_dev_list_lock); read_lock(&hci_dev_list_lock);
num_ctrl = __hci_num_ctrl(); /* at minimum the BR/EDR needs to be listed */
num_ctrl = 1;
list_for_each_entry(hdev, &hci_dev_list, list) {
if (hdev->dev_type == HCI_AMP)
num_ctrl++;
}
len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp); len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp);
rsp = kmalloc(len, GFP_ATOMIC); rsp = kmalloc(len, GFP_ATOMIC);
if (!rsp) { if (!rsp) {
...@@ -163,7 +165,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -163,7 +165,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
rsp->ext_feat = 0; rsp->ext_feat = 0;
__a2mp_add_cl(mgr, rsp->cl, num_ctrl); __a2mp_add_cl(mgr, rsp->cl);
read_unlock(&hci_dev_list_lock); read_unlock(&hci_dev_list_lock);
...@@ -208,7 +210,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -208,7 +210,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type, BT_DBG("Remote AMP id %d type %d status %d", cl->id, cl->type,
cl->status); cl->status);
if (cl->id != HCI_BREDR_ID && cl->type == HCI_AMP) { if (cl->id != AMP_ID_BREDR && cl->type != AMP_TYPE_BREDR) {
struct a2mp_info_req req; struct a2mp_info_req req;
found = true; found = true;
...@@ -344,7 +346,7 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -344,7 +346,7 @@ static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb,
tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC); tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
hdev = hci_dev_get(req->id); hdev = hci_dev_get(req->id);
if (!hdev || hdev->amp_type == HCI_BREDR || tmp) { if (!hdev || hdev->amp_type == AMP_TYPE_BREDR || tmp) {
struct a2mp_amp_assoc_rsp rsp; struct a2mp_amp_assoc_rsp rsp;
rsp.id = req->id; rsp.id = req->id;
...@@ -451,7 +453,7 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -451,7 +453,7 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
rsp.remote_id = req->local_id; rsp.remote_id = req->local_id;
hdev = hci_dev_get(req->remote_id); hdev = hci_dev_get(req->remote_id);
if (!hdev || hdev->amp_type != HCI_AMP) { if (!hdev || hdev->amp_type == AMP_TYPE_BREDR) {
rsp.status = A2MP_STATUS_INVALID_CTRL_ID; rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
goto send_rsp; goto send_rsp;
} }
...@@ -535,7 +537,8 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, ...@@ -535,7 +537,8 @@ static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
goto send_rsp; goto send_rsp;
} }
hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, mgr->l2cap_conn->dst); hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK,
&mgr->l2cap_conn->hcon->dst);
if (!hcon) { if (!hcon) {
BT_ERR("No phys link exist"); BT_ERR("No phys link exist");
rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS; rsp.status = A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS;
...@@ -871,7 +874,7 @@ void a2mp_send_getinfo_rsp(struct hci_dev *hdev) ...@@ -871,7 +874,7 @@ void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
rsp.id = hdev->id; rsp.id = hdev->id;
rsp.status = A2MP_STATUS_INVALID_CTRL_ID; rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
if (hdev->amp_type != HCI_BREDR) { if (hdev->amp_type != AMP_TYPE_BREDR) {
rsp.status = 0; rsp.status = 0;
rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#define VERSION "2.16" #define VERSION "2.17"
/* Bluetooth sockets */ /* Bluetooth sockets */
#define BT_MAX_PROTO 8 #define BT_MAX_PROTO 8
...@@ -221,12 +221,12 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -221,12 +221,12 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags & (MSG_OOB)) if (flags & (MSG_OOB))
return -EOPNOTSUPP; return -EOPNOTSUPP;
msg->msg_namelen = 0;
skb = skb_recv_datagram(sk, flags, noblock, &err); skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) { if (!skb) {
if (sk->sk_shutdown & RCV_SHUTDOWN) if (sk->sk_shutdown & RCV_SHUTDOWN) {
msg->msg_namelen = 0;
return 0; return 0;
}
return err; return err;
} }
...@@ -238,9 +238,16 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -238,9 +238,16 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_reset_transport_header(skb); skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err == 0) if (err == 0) {
sock_recv_ts_and_drops(msg, sk, skb); sock_recv_ts_and_drops(msg, sk, skb);
if (bt_sk(sk)->skb_msg_name)
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
&msg->msg_namelen);
else
msg->msg_namelen = 0;
}
skb_free_datagram(sk, skb); skb_free_datagram(sk, skb);
return err ? : copied; return err ? : copied;
...@@ -604,7 +611,7 @@ static int bt_seq_show(struct seq_file *seq, void *v) ...@@ -604,7 +611,7 @@ static int bt_seq_show(struct seq_file *seq, void *v)
struct bt_sock_list *l = s->l; struct bt_sock_list *l = s->l;
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent"); seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
if (l->custom_seq_show) { if (l->custom_seq_show) {
seq_putc(seq, ' '); seq_putc(seq, ' ');
...@@ -617,15 +624,13 @@ static int bt_seq_show(struct seq_file *seq, void *v) ...@@ -617,15 +624,13 @@ static int bt_seq_show(struct seq_file *seq, void *v)
struct bt_sock *bt = bt_sk(sk); struct bt_sock *bt = bt_sk(sk);
seq_printf(seq, seq_printf(seq,
"%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu", "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
sk, sk,
atomic_read(&sk->sk_refcnt), atomic_read(&sk->sk_refcnt),
sk_rmem_alloc_get(sk), sk_rmem_alloc_get(sk),
sk_wmem_alloc_get(sk), sk_wmem_alloc_get(sk),
from_kuid(seq_user_ns(seq), sock_i_uid(sk)), from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
sock_i_ino(sk), sock_i_ino(sk),
&bt->src,
&bt->dst,
bt->parent? sock_i_ino(bt->parent): 0LU); bt->parent? sock_i_ino(bt->parent): 0LU);
if (l->custom_seq_show) { if (l->custom_seq_show) {
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h> #include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#include "a2mp.h"
#include "amp.h"
/* Remote AMP Controllers interface */ /* Remote AMP Controllers interface */
void amp_ctrl_get(struct amp_ctrl *ctrl) void amp_ctrl_get(struct amp_ctrl *ctrl)
{ {
...@@ -110,7 +111,7 @@ static u8 __next_handle(struct amp_mgr *mgr) ...@@ -110,7 +111,7 @@ static u8 __next_handle(struct amp_mgr *mgr)
struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
u8 remote_id, bool out) u8 remote_id, bool out)
{ {
bdaddr_t *dst = mgr->l2cap_conn->dst; bdaddr_t *dst = &mgr->l2cap_conn->hcon->dst;
struct hci_conn *hcon; struct hci_conn *hcon;
hcon = hci_conn_add(hdev, AMP_LINK, dst); hcon = hci_conn_add(hdev, AMP_LINK, dst);
...@@ -409,7 +410,8 @@ void amp_create_logical_link(struct l2cap_chan *chan) ...@@ -409,7 +410,8 @@ void amp_create_logical_link(struct l2cap_chan *chan)
struct hci_cp_create_accept_logical_link cp; struct hci_cp_create_accept_logical_link cp;
struct hci_dev *hdev; struct hci_dev *hdev;
BT_DBG("chan %p hs_hcon %p dst %pMR", chan, hs_hcon, chan->conn->dst); BT_DBG("chan %p hs_hcon %p dst %pMR", chan, hs_hcon,
&chan->conn->hcon->dst);
if (!hs_hcon) if (!hs_hcon)
return; return;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include "bnep.h" #include "bnep.h"
...@@ -510,20 +511,13 @@ static int bnep_session(void *arg) ...@@ -510,20 +511,13 @@ static int bnep_session(void *arg)
static struct device *bnep_get_device(struct bnep_session *session) static struct device *bnep_get_device(struct bnep_session *session)
{ {
bdaddr_t *src = &bt_sk(session->sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->sock->sk)->dst;
struct hci_dev *hdev;
struct hci_conn *conn; struct hci_conn *conn;
hdev = hci_get_route(dst, src); conn = l2cap_pi(session->sock->sk)->chan->conn->hcon;
if (!hdev) if (!conn)
return NULL; return NULL;
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); return &conn->dev;
hci_dev_put(hdev);
return conn ? &conn->dev : NULL;
} }
static struct device_type bnep_type = { static struct device_type bnep_type = {
...@@ -539,8 +533,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) ...@@ -539,8 +533,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
BT_DBG(""); BT_DBG("");
baswap((void *) dst, &bt_sk(sock->sk)->dst); baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
baswap((void *) src, &bt_sk(sock->sk)->src); baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
/* session struct allocated as private part of net_device */ /* session struct allocated as private part of net_device */
dev = alloc_netdev(sizeof(struct bnep_session), dev = alloc_netdev(sizeof(struct bnep_session),
......
...@@ -340,20 +340,20 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) ...@@ -340,20 +340,20 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
down_write(&cmtp_session_sem); down_write(&cmtp_session_sem);
s = __cmtp_get_session(&bt_sk(sock->sk)->dst); s = __cmtp_get_session(&l2cap_pi(sock->sk)->chan->dst);
if (s && s->state == BT_CONNECTED) { if (s && s->state == BT_CONNECTED) {
err = -EEXIST; err = -EEXIST;
goto failed; goto failed;
} }
bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst); bacpy(&session->bdaddr, &l2cap_pi(sock->sk)->chan->dst);
session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu, session->mtu = min_t(uint, l2cap_pi(sock->sk)->chan->omtu,
l2cap_pi(sock->sk)->chan->imtu); l2cap_pi(sock->sk)->chan->imtu);
BT_DBG("mtu %d", session->mtu); BT_DBG("mtu %d", session->mtu);
sprintf(session->name, "%pMR", &bt_sk(sock->sk)->dst); sprintf(session->name, "%pMR", &session->bdaddr);
session->sock = sock; session->sock = sock;
session->state = BT_CONFIG; session->state = BT_CONFIG;
......
...@@ -28,8 +28,9 @@ ...@@ -28,8 +28,9 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/smp.h> #include "smp.h"
#include "a2mp.h"
struct sco_param { struct sco_param {
u16 pkt_type; u16 pkt_type;
...@@ -49,30 +50,6 @@ static const struct sco_param sco_param_wideband[] = { ...@@ -49,30 +50,6 @@ static const struct sco_param sco_param_wideband[] = {
{ EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */ { EDR_ESCO_MASK | ESCO_EV3, 0x0008 }, /* T1 */
}; };
static void hci_le_create_connection(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_create_conn cp;
conn->state = BT_CONNECT;
conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
memset(&cp, 0, sizeof(cp));
cp.scan_interval = __constant_cpu_to_le16(0x0060);
cp.scan_window = __constant_cpu_to_le16(0x0030);
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
}
static void hci_le_create_connection_cancel(struct hci_conn *conn) static void hci_le_create_connection_cancel(struct hci_conn *conn)
{ {
hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
...@@ -404,6 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -404,6 +381,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
return NULL; return NULL;
bacpy(&conn->dst, dst); bacpy(&conn->dst, dst);
bacpy(&conn->src, &hdev->bdaddr);
conn->hdev = hdev; conn->hdev = hdev;
conn->type = type; conn->type = type;
conn->mode = HCI_CM_ACTIVE; conn->mode = HCI_CM_ACTIVE;
...@@ -546,34 +524,128 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) ...@@ -546,34 +524,128 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
} }
EXPORT_SYMBOL(hci_get_route); EXPORT_SYMBOL(hci_get_route);
static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
{
struct hci_conn *conn;
if (status == 0)
return;
BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
status);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (!conn)
goto done;
conn->state = BT_CLOSED;
mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
status);
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
done:
hci_dev_unlock(hdev);
}
static int hci_create_le_conn(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
struct hci_cp_le_create_conn cp;
struct hci_request req;
int err;
hci_req_init(&req, hdev);
memset(&cp, 0, sizeof(cp));
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
cp.own_address_type = conn->src_type;
cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
cp.min_ce_len = __constant_cpu_to_le16(0x0000);
cp.max_ce_len = __constant_cpu_to_le16(0x0000);
hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
err = hci_req_run(&req, create_le_conn_complete);
if (err) {
hci_conn_del(conn);
return err;
}
return 0;
}
static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
u8 dst_type, u8 sec_level, u8 auth_type) u8 dst_type, u8 sec_level, u8 auth_type)
{ {
struct hci_conn *le; struct hci_conn *conn;
int err;
if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags)) if (test_bit(HCI_ADVERTISING, &hdev->flags))
return ERR_PTR(-ENOTSUPP); return ERR_PTR(-ENOTSUPP);
le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); /* Some devices send ATT messages as soon as the physical link is
if (!le) { * established. To be able to handle these ATT messages, the user-
le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); * space first establishes the connection and then starts the pairing
if (le) * process.
return ERR_PTR(-EBUSY); *
* So if a hci_conn object already exists for the following connection
* attempt, we simply update pending_sec_level and auth_type fields
* and return the object found.
*/
conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
if (conn) {
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
goto done;
}
le = hci_conn_add(hdev, LE_LINK, dst); /* Since the controller supports only one LE connection attempt at a
if (!le) * time, we return -EBUSY if there is any connection attempt running.
return ERR_PTR(-ENOMEM); */
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (conn)
return ERR_PTR(-EBUSY);
conn = hci_conn_add(hdev, LE_LINK, dst);
if (!conn)
return ERR_PTR(-ENOMEM);
le->dst_type = bdaddr_to_le(dst_type); if (dst_type == BDADDR_LE_PUBLIC)
hci_le_create_connection(le); conn->dst_type = ADDR_LE_DEV_PUBLIC;
else
conn->dst_type = ADDR_LE_DEV_RANDOM;
if (bacmp(&conn->src, BDADDR_ANY)) {
conn->src_type = ADDR_LE_DEV_PUBLIC;
} else {
bacpy(&conn->src, &hdev->static_addr);
conn->src_type = ADDR_LE_DEV_RANDOM;
} }
le->pending_sec_level = sec_level; conn->state = BT_CONNECT;
le->auth_type = auth_type; conn->out = true;
conn->link_mode |= HCI_LM_MASTER;
conn->sec_level = BT_SECURITY_LOW;
conn->pending_sec_level = sec_level;
conn->auth_type = auth_type;
hci_conn_hold(le); err = hci_create_le_conn(conn);
if (err)
return ERR_PTR(err);
return le; done:
hci_conn_hold(conn);
return conn;
} }
static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
......
This diff is collapsed.
...@@ -29,8 +29,9 @@ ...@@ -29,8 +29,9 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h> #include <net/bluetooth/mgmt.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/amp.h> #include "a2mp.h"
#include "amp.h"
/* Handle HCI Event packets */ /* Handle HCI Event packets */
...@@ -417,6 +418,21 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, ...@@ -417,6 +418,21 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev,
hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
} }
static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (rp->status)
return;
hdev->num_iac = rp->num_iac;
BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
}
static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
{ {
__u8 status = *((__u8 *) skb->data); __u8 status = *((__u8 *) skb->data);
...@@ -918,12 +934,12 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -918,12 +934,12 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
if (!status) { if (!status) {
if (*sent) if (*sent)
set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); set_bit(HCI_ADVERTISING, &hdev->dev_flags);
else else
clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
} }
if (!test_bit(HCI_INIT, &hdev->flags)) { if (*sent && !test_bit(HCI_INIT, &hdev->flags)) {
struct hci_request req; struct hci_request req;
hci_req_init(&req, hdev); hci_req_init(&req, hdev);
...@@ -1005,7 +1021,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, ...@@ -1005,7 +1021,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
} else { } else {
hdev->features[1][0] &= ~LMP_HOST_LE; hdev->features[1][0] &= ~LMP_HOST_LE;
clear_bit(HCI_LE_ENABLED, &hdev->dev_flags); clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
} }
if (sent->simul) if (sent->simul)
...@@ -1296,9 +1312,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) ...@@ -1296,9 +1312,11 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
goto unlock; goto unlock;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp; struct hci_cp_auth_requested auth_cp;
cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); auth_cp.handle = __cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
sizeof(auth_cp), &auth_cp);
} }
unlock: unlock:
...@@ -1470,33 +1488,6 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) ...@@ -1470,33 +1488,6 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
{
struct hci_conn *conn;
BT_DBG("%s status 0x%2.2x", hdev->name, status);
if (status) {
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
if (!conn) {
hci_dev_unlock(hdev);
return;
}
BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
conn->state = BT_CLOSED;
mgmt_connect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, status);
hci_proto_connect_cfm(conn, status);
hci_conn_del(conn);
hci_dev_unlock(hdev);
}
}
static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
{ {
struct hci_cp_create_phy_link *cp; struct hci_cp_create_phy_link *cp;
...@@ -1826,10 +1817,25 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1826,10 +1817,25 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
} }
if (ev->status == 0) { if (ev->status == 0) {
if (conn->type == ACL_LINK && conn->flush_key) u8 type = conn->type;
if (type == ACL_LINK && conn->flush_key)
hci_remove_link_key(hdev, &conn->dst); hci_remove_link_key(hdev, &conn->dst);
hci_proto_disconn_cfm(conn, ev->reason); hci_proto_disconn_cfm(conn, ev->reason);
hci_conn_del(conn); hci_conn_del(conn);
/* Re-enable advertising if necessary, since it might
* have been disabled by the connection. From the
* HCI_LE_Set_Advertise_Enable command description in
* the core specification (v4.0):
* "The Controller shall continue advertising until the Host
* issues an LE_Set_Advertise_Enable command with
* Advertising_Enable set to 0x00 (Advertising is disabled)
* or until a connection is created or until the Advertising
* is timed out due to Directed Advertising."
*/
if (type == LE_LINK)
mgmt_reenable_advertising(hdev);
} }
unlock: unlock:
...@@ -2144,6 +2150,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2144,6 +2150,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cc_write_voice_setting(hdev, skb); hci_cc_write_voice_setting(hdev, skb);
break; break;
case HCI_OP_READ_NUM_SUPPORTED_IAC:
hci_cc_read_num_supported_iac(hdev, skb);
break;
case HCI_OP_WRITE_SSP_MODE: case HCI_OP_WRITE_SSP_MODE:
hci_cc_write_ssp_mode(hdev, skb); hci_cc_write_ssp_mode(hdev, skb);
break; break;
...@@ -2347,10 +2357,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2347,10 +2357,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_disconnect(hdev, ev->status); hci_cs_disconnect(hdev, ev->status);
break; break;
case HCI_OP_LE_CREATE_CONN:
hci_cs_le_create_conn(hdev, ev->status);
break;
case HCI_OP_CREATE_PHY_LINK: case HCI_OP_CREATE_PHY_LINK:
hci_cs_create_phylink(hdev, ev->status); hci_cs_create_phylink(hdev, ev->status);
break; break;
...@@ -3490,6 +3496,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3490,6 +3496,17 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
conn->dst_type = ev->bdaddr_type; conn->dst_type = ev->bdaddr_type;
/* The advertising parameters for own address type
* define which source address and source address
* type this connections has.
*/
if (bacmp(&conn->src, BDADDR_ANY)) {
conn->src_type = ADDR_LE_DEV_PUBLIC;
} else {
bacpy(&conn->src, &hdev->static_addr);
conn->src_type = ADDR_LE_DEV_RANDOM;
}
if (ev->role == LE_CONN_ROLE_MASTER) { if (ev->role == LE_CONN_ROLE_MASTER) {
conn->out = true; conn->out = true;
conn->link_mode |= HCI_LM_MASTER; conn->link_mode |= HCI_LM_MASTER;
...@@ -3645,8 +3662,8 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3645,8 +3662,8 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
skb_pull(skb, HCI_EVENT_HDR_SIZE); skb_pull(skb, HCI_EVENT_HDR_SIZE);
if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data; struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
u16 opcode = __le16_to_cpu(hdr->opcode); u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
hci_req_cmd_complete(hdev, opcode, 0); hci_req_cmd_complete(hdev, opcode, 0);
} }
......
...@@ -387,7 +387,6 @@ static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) ...@@ -387,7 +387,6 @@ static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
__net_timestamp(skb); __net_timestamp(skb);
bt_cb(skb)->pkt_type = HCI_EVENT_PKT; bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
skb->dev = (void *) hdev;
hci_send_to_sock(hdev, skb); hci_send_to_sock(hdev, skb);
kfree_skb(skb); kfree_skb(skb);
} }
...@@ -518,6 +517,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, ...@@ -518,6 +517,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags)) if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
return -EBUSY; return -EBUSY;
if (hdev->dev_type != HCI_BREDR)
return -EOPNOTSUPP;
switch (cmd) { switch (cmd) {
case HCISETRAW: case HCISETRAW:
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
...@@ -550,10 +552,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, ...@@ -550,10 +552,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
return hci_sock_blacklist_del(hdev, (void __user *) arg); return hci_sock_blacklist_del(hdev, (void __user *) arg);
} }
if (hdev->ioctl) return -ENOIOCTLCMD;
return hdev->ioctl(hdev, cmd, arg);
return -EINVAL;
} }
static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
...@@ -942,7 +941,6 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -942,7 +941,6 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
bt_cb(skb)->pkt_type = *((unsigned char *) skb->data); bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
skb_pull(skb, 1); skb_pull(skb, 1);
skb->dev = (void *) hdev;
if (hci_pi(sk)->channel == HCI_CHANNEL_RAW && if (hci_pi(sk)->channel == HCI_CHANNEL_RAW &&
bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
......
...@@ -767,10 +767,10 @@ static int hidp_setup_hid(struct hidp_session *session, ...@@ -767,10 +767,10 @@ static int hidp_setup_hid(struct hidp_session *session,
strncpy(hid->name, req->name, sizeof(req->name) - 1); strncpy(hid->name, req->name, sizeof(req->name) - 1);
snprintf(hid->phys, sizeof(hid->phys), "%pMR", snprintf(hid->phys, sizeof(hid->phys), "%pMR",
&bt_sk(session->ctrl_sock->sk)->src); &l2cap_pi(session->ctrl_sock->sk)->chan->src);
snprintf(hid->uniq, sizeof(hid->uniq), "%pMR", snprintf(hid->uniq, sizeof(hid->uniq), "%pMR",
&bt_sk(session->ctrl_sock->sk)->dst); &l2cap_pi(session->ctrl_sock->sk)->chan->dst);
hid->dev.parent = &session->conn->hcon->dev; hid->dev.parent = &session->conn->hcon->dev;
hid->ll_driver = &hidp_hid_driver; hid->ll_driver = &hidp_hid_driver;
...@@ -1283,23 +1283,29 @@ static int hidp_session_thread(void *arg) ...@@ -1283,23 +1283,29 @@ static int hidp_session_thread(void *arg)
static int hidp_verify_sockets(struct socket *ctrl_sock, static int hidp_verify_sockets(struct socket *ctrl_sock,
struct socket *intr_sock) struct socket *intr_sock)
{ {
struct l2cap_chan *ctrl_chan, *intr_chan;
struct bt_sock *ctrl, *intr; struct bt_sock *ctrl, *intr;
struct hidp_session *session; struct hidp_session *session;
if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock)) if (!l2cap_is_socket(ctrl_sock) || !l2cap_is_socket(intr_sock))
return -EINVAL; return -EINVAL;
ctrl_chan = l2cap_pi(ctrl_sock->sk)->chan;
intr_chan = l2cap_pi(intr_sock->sk)->chan;
if (bacmp(&ctrl_chan->src, &intr_chan->src) ||
bacmp(&ctrl_chan->dst, &intr_chan->dst))
return -ENOTUNIQ;
ctrl = bt_sk(ctrl_sock->sk); ctrl = bt_sk(ctrl_sock->sk);
intr = bt_sk(intr_sock->sk); intr = bt_sk(intr_sock->sk);
if (bacmp(&ctrl->src, &intr->src) || bacmp(&ctrl->dst, &intr->dst))
return -ENOTUNIQ;
if (ctrl->sk.sk_state != BT_CONNECTED || if (ctrl->sk.sk_state != BT_CONNECTED ||
intr->sk.sk_state != BT_CONNECTED) intr->sk.sk_state != BT_CONNECTED)
return -EBADFD; return -EBADFD;
/* early session check, we check again during session registration */ /* early session check, we check again during session registration */
session = hidp_session_find(&ctrl->dst); session = hidp_session_find(&ctrl_chan->dst);
if (session) { if (session) {
hidp_session_put(session); hidp_session_put(session);
return -EEXIST; return -EEXIST;
...@@ -1332,7 +1338,7 @@ int hidp_connection_add(struct hidp_connadd_req *req, ...@@ -1332,7 +1338,7 @@ int hidp_connection_add(struct hidp_connadd_req *req,
if (!conn) if (!conn)
return -EBADFD; return -EBADFD;
ret = hidp_session_new(&session, &bt_sk(ctrl_sock->sk)->dst, ctrl_sock, ret = hidp_session_new(&session, &chan->dst, ctrl_sock,
intr_sock, req, conn); intr_sock, req, conn);
if (ret) if (ret)
goto out_conn; goto out_conn;
......
This diff is collapsed.
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
#include "smp.h"
static struct bt_sock_list l2cap_sk_list = { static struct bt_sock_list l2cap_sk_list = {
.lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
...@@ -68,6 +69,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) ...@@ -68,6 +69,9 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (la.l2_cid && la.l2_psm) if (la.l2_cid && la.l2_psm)
return -EINVAL; return -EINVAL;
if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL;
lock_sock(sk); lock_sock(sk);
if (sk->sk_state != BT_OPEN) { if (sk->sk_state != BT_OPEN) {
...@@ -99,11 +103,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) ...@@ -99,11 +103,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (err < 0) if (err < 0)
goto done; goto done;
if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP || switch (chan->chan_type) {
__le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) case L2CAP_CHAN_CONN_LESS:
chan->sec_level = BT_SECURITY_SDP; if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_3DSP)
chan->sec_level = BT_SECURITY_SDP;
break;
case L2CAP_CHAN_CONN_ORIENTED:
if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP ||
__le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
chan->sec_level = BT_SECURITY_SDP;
break;
}
bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); bacpy(&chan->src, &la.l2_bdaddr);
chan->src_type = la.l2_bdaddr_type;
chan->state = BT_BOUND; chan->state = BT_BOUND;
sk->sk_state = BT_BOUND; sk->sk_state = BT_BOUND;
...@@ -134,6 +147,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, ...@@ -134,6 +147,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
if (la.l2_cid && la.l2_psm) if (la.l2_cid && la.l2_psm)
return -EINVAL; return -EINVAL;
if (!bdaddr_type_is_valid(la.l2_bdaddr_type))
return -EINVAL;
if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR)
return -EINVAL;
if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR)
return -EINVAL;
err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
&la.l2_bdaddr, la.l2_bdaddr_type); &la.l2_bdaddr, la.l2_bdaddr_type);
if (err) if (err)
...@@ -265,12 +287,14 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, ...@@ -265,12 +287,14 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
if (peer) { if (peer) {
la->l2_psm = chan->psm; la->l2_psm = chan->psm;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); bacpy(&la->l2_bdaddr, &chan->dst);
la->l2_cid = cpu_to_le16(chan->dcid); la->l2_cid = cpu_to_le16(chan->dcid);
la->l2_bdaddr_type = chan->dst_type;
} else { } else {
la->l2_psm = chan->sport; la->l2_psm = chan->sport;
bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); bacpy(&la->l2_bdaddr, &chan->src);
la->l2_cid = cpu_to_le16(chan->scid); la->l2_cid = cpu_to_le16(chan->scid);
la->l2_bdaddr_type = chan->src_type;
} }
return 0; return 0;
...@@ -660,10 +684,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ...@@ -660,10 +684,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break; break;
} }
if (opt) if (opt) {
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
else set_bit(FLAG_DEFER_SETUP, &chan->flags);
} else {
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
clear_bit(FLAG_DEFER_SETUP, &chan->flags);
}
break; break;
case BT_FLUSHABLE: case BT_FLUSHABLE:
...@@ -678,7 +705,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ...@@ -678,7 +705,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
} }
if (opt == BT_FLUSHABLE_OFF) { if (opt == BT_FLUSHABLE_OFF) {
struct l2cap_conn *conn = chan->conn; conn = chan->conn;
/* proceed further only when we have l2cap_conn and /* proceed further only when we have l2cap_conn and
No Flush support in the LM */ No Flush support in the LM */
if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) {
...@@ -964,13 +991,12 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) ...@@ -964,13 +991,12 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{ {
int err;
struct sock *sk = chan->data; struct sock *sk = chan->data;
struct l2cap_pinfo *pi = l2cap_pi(sk); int err;
lock_sock(sk); lock_sock(sk);
if (pi->rx_busy_skb) { if (l2cap_pi(sk)->rx_busy_skb) {
err = -ENOMEM; err = -ENOMEM;
goto done; goto done;
} }
...@@ -986,9 +1012,9 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) ...@@ -986,9 +1012,9 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
* acked and reassembled until there is buffer space * acked and reassembled until there is buffer space
* available. * available.
*/ */
if (err < 0 && pi->chan->mode == L2CAP_MODE_ERTM) { if (err < 0 && chan->mode == L2CAP_MODE_ERTM) {
pi->rx_busy_skb = skb; l2cap_pi(sk)->rx_busy_skb = skb;
l2cap_chan_busy(pi->chan, 1); l2cap_chan_busy(chan, 1);
err = 0; err = 0;
} }
...@@ -1098,6 +1124,14 @@ static void l2cap_sock_defer_cb(struct l2cap_chan *chan) ...@@ -1098,6 +1124,14 @@ static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
parent->sk_data_ready(parent, 0); parent->sk_data_ready(parent, 0);
} }
static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;
clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
sk->sk_state_change(sk);
}
static struct l2cap_ops l2cap_chan_ops = { static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface", .name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb, .new_connection = l2cap_sock_new_connection_cb,
...@@ -1107,6 +1141,7 @@ static struct l2cap_ops l2cap_chan_ops = { ...@@ -1107,6 +1141,7 @@ static struct l2cap_ops l2cap_chan_ops = {
.state_change = l2cap_sock_state_change_cb, .state_change = l2cap_sock_state_change_cb,
.ready = l2cap_sock_ready_cb, .ready = l2cap_sock_ready_cb,
.defer = l2cap_sock_defer_cb, .defer = l2cap_sock_defer_cb,
.resume = l2cap_sock_resume_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb, .alloc_skb = l2cap_sock_alloc_skb_cb,
}; };
...@@ -1116,6 +1151,7 @@ static void l2cap_sock_destruct(struct sock *sk) ...@@ -1116,6 +1151,7 @@ static void l2cap_sock_destruct(struct sock *sk)
if (l2cap_pi(sk)->chan) if (l2cap_pi(sk)->chan)
l2cap_chan_put(l2cap_pi(sk)->chan); l2cap_chan_put(l2cap_pi(sk)->chan);
if (l2cap_pi(sk)->rx_busy_skb) { if (l2cap_pi(sk)->rx_busy_skb) {
kfree_skb(l2cap_pi(sk)->rx_busy_skb); kfree_skb(l2cap_pi(sk)->rx_busy_skb);
l2cap_pi(sk)->rx_busy_skb = NULL; l2cap_pi(sk)->rx_busy_skb = NULL;
...@@ -1125,10 +1161,22 @@ static void l2cap_sock_destruct(struct sock *sk) ...@@ -1125,10 +1161,22 @@ static void l2cap_sock_destruct(struct sock *sk)
skb_queue_purge(&sk->sk_write_queue); skb_queue_purge(&sk->sk_write_queue);
} }
static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
int *msg_namelen)
{
struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name;
memset(la, 0, sizeof(struct sockaddr_l2));
la->l2_family = AF_BLUETOOTH;
la->l2_psm = bt_cb(skb)->psm;
bacpy(&la->l2_bdaddr, &bt_cb(skb)->bdaddr);
*msg_namelen = sizeof(struct sockaddr_l2);
}
static void l2cap_sock_init(struct sock *sk, struct sock *parent) static void l2cap_sock_init(struct sock *sk, struct sock *parent)
{ {
struct l2cap_pinfo *pi = l2cap_pi(sk); struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_chan *chan = pi->chan;
BT_DBG("sk %p", sk); BT_DBG("sk %p", sk);
...@@ -1152,13 +1200,13 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) ...@@ -1152,13 +1200,13 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
security_sk_clone(parent, sk); security_sk_clone(parent, sk);
} else { } else {
switch (sk->sk_type) { switch (sk->sk_type) {
case SOCK_RAW: case SOCK_RAW:
chan->chan_type = L2CAP_CHAN_RAW; chan->chan_type = L2CAP_CHAN_RAW;
break; break;
case SOCK_DGRAM: case SOCK_DGRAM:
chan->chan_type = L2CAP_CHAN_CONN_LESS; chan->chan_type = L2CAP_CHAN_CONN_LESS;
bt_sk(sk)->skb_msg_name = l2cap_skb_msg_name;
break; break;
case SOCK_SEQPACKET: case SOCK_SEQPACKET:
case SOCK_STREAM: case SOCK_STREAM:
......
This diff is collapsed.
...@@ -641,13 +641,13 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst) ...@@ -641,13 +641,13 @@ static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
{ {
struct rfcomm_session *s; struct rfcomm_session *s;
struct list_head *p, *n; struct list_head *p, *n;
struct bt_sock *sk; struct l2cap_chan *chan;
list_for_each_safe(p, n, &session_list) { list_for_each_safe(p, n, &session_list) {
s = list_entry(p, struct rfcomm_session, list); s = list_entry(p, struct rfcomm_session, list);
sk = bt_sk(s->sock->sk); chan = l2cap_pi(s->sock->sk)->chan;
if ((!bacmp(src, BDADDR_ANY) || !bacmp(&sk->src, src)) && if ((!bacmp(src, BDADDR_ANY) || !bacmp(&chan->src, src)) &&
!bacmp(&sk->dst, dst)) !bacmp(&chan->dst, dst))
return s; return s;
} }
return NULL; return NULL;
...@@ -732,11 +732,11 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, ...@@ -732,11 +732,11 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst) void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
{ {
struct sock *sk = s->sock->sk; struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
if (src) if (src)
bacpy(src, &bt_sk(sk)->src); bacpy(src, &chan->src);
if (dst) if (dst)
bacpy(dst, &bt_sk(sk)->dst); bacpy(dst, &chan->dst);
} }
/* ---- RFCOMM frame sending ---- */ /* ---- RFCOMM frame sending ---- */
...@@ -2112,12 +2112,11 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) ...@@ -2112,12 +2112,11 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
rfcomm_lock(); rfcomm_lock();
list_for_each_entry(s, &session_list, list) { list_for_each_entry(s, &session_list, list) {
struct l2cap_chan *chan = l2cap_pi(s->sock->sk)->chan;
struct rfcomm_dlc *d; struct rfcomm_dlc *d;
list_for_each_entry(d, &s->dlcs, list) { list_for_each_entry(d, &s->dlcs, list) {
struct sock *sk = s->sock->sk;
seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n", seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
&bt_sk(sk)->src, &bt_sk(sk)->dst, &chan->src, &chan->dst,
d->state, d->dlci, d->mtu, d->state, d->dlci, d->mtu,
d->rx_credits, d->tx_credits); d->rx_credits, d->tx_credits);
} }
......
...@@ -87,7 +87,8 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) ...@@ -87,7 +87,8 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
parent->sk_data_ready(parent, 0); parent->sk_data_ready(parent, 0);
} else { } else {
if (d->state == BT_CONNECTED) if (d->state == BT_CONNECTED)
rfcomm_session_getaddr(d->session, &bt_sk(sk)->src, NULL); rfcomm_session_getaddr(d->session,
&rfcomm_pi(sk)->src, NULL);
sk->sk_state_change(sk); sk->sk_state_change(sk);
} }
...@@ -110,7 +111,7 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) ...@@ -110,7 +111,7 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
sk_for_each(sk, &rfcomm_sk_list.head) { sk_for_each(sk, &rfcomm_sk_list.head) {
if (rfcomm_pi(sk)->channel == channel && if (rfcomm_pi(sk)->channel == channel &&
!bacmp(&bt_sk(sk)->src, src)) !bacmp(&rfcomm_pi(sk)->src, src))
break; break;
} }
...@@ -132,11 +133,11 @@ static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t * ...@@ -132,11 +133,11 @@ static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *
if (rfcomm_pi(sk)->channel == channel) { if (rfcomm_pi(sk)->channel == channel) {
/* Exact match. */ /* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src)) if (!bacmp(&rfcomm_pi(sk)->src, src))
break; break;
/* Closest match */ /* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) if (!bacmp(&rfcomm_pi(sk)->src, BDADDR_ANY))
sk1 = sk; sk1 = sk;
} }
} }
...@@ -355,7 +356,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr ...@@ -355,7 +356,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
err = -EADDRINUSE; err = -EADDRINUSE;
} else { } else {
/* Save source address */ /* Save source address */
bacpy(&bt_sk(sk)->src, &sa->rc_bdaddr); bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr);
rfcomm_pi(sk)->channel = sa->rc_channel; rfcomm_pi(sk)->channel = sa->rc_channel;
sk->sk_state = BT_BOUND; sk->sk_state = BT_BOUND;
} }
...@@ -393,13 +394,14 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a ...@@ -393,13 +394,14 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
} }
sk->sk_state = BT_CONNECT; sk->sk_state = BT_CONNECT;
bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); bacpy(&rfcomm_pi(sk)->dst, &sa->rc_bdaddr);
rfcomm_pi(sk)->channel = sa->rc_channel; rfcomm_pi(sk)->channel = sa->rc_channel;
d->sec_level = rfcomm_pi(sk)->sec_level; d->sec_level = rfcomm_pi(sk)->sec_level;
d->role_switch = rfcomm_pi(sk)->role_switch; d->role_switch = rfcomm_pi(sk)->role_switch;
err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); err = rfcomm_dlc_open(d, &rfcomm_pi(sk)->src, &sa->rc_bdaddr,
sa->rc_channel);
if (!err) if (!err)
err = bt_sock_wait_state(sk, BT_CONNECTED, err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK)); sock_sndtimeo(sk, flags & O_NONBLOCK));
...@@ -429,7 +431,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) ...@@ -429,7 +431,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog)
} }
if (!rfcomm_pi(sk)->channel) { if (!rfcomm_pi(sk)->channel) {
bdaddr_t *src = &bt_sk(sk)->src; bdaddr_t *src = &rfcomm_pi(sk)->src;
u8 channel; u8 channel;
err = -EINVAL; err = -EINVAL;
...@@ -530,9 +532,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * ...@@ -530,9 +532,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *
sa->rc_family = AF_BLUETOOTH; sa->rc_family = AF_BLUETOOTH;
sa->rc_channel = rfcomm_pi(sk)->channel; sa->rc_channel = rfcomm_pi(sk)->channel;
if (peer) if (peer)
bacpy(&sa->rc_bdaddr, &bt_sk(sk)->dst); bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->dst);
else else
bacpy(&sa->rc_bdaddr, &bt_sk(sk)->src); bacpy(&sa->rc_bdaddr, &rfcomm_pi(sk)->src);
*len = sizeof(struct sockaddr_rc); *len = sizeof(struct sockaddr_rc);
return 0; return 0;
...@@ -951,8 +953,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * ...@@ -951,8 +953,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM); bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
rfcomm_sock_init(sk, parent); rfcomm_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, &src); bacpy(&rfcomm_pi(sk)->src, &src);
bacpy(&bt_sk(sk)->dst, &dst); bacpy(&rfcomm_pi(sk)->dst, &dst);
rfcomm_pi(sk)->channel = channel; rfcomm_pi(sk)->channel = channel;
sk->sk_state = BT_CONFIG; sk->sk_state = BT_CONFIG;
...@@ -979,7 +981,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) ...@@ -979,7 +981,7 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
sk_for_each(sk, &rfcomm_sk_list.head) { sk_for_each(sk, &rfcomm_sk_list.head) {
seq_printf(f, "%pMR %pMR %d %d\n", seq_printf(f, "%pMR %pMR %d %d\n",
&bt_sk(sk)->src, &bt_sk(sk)->dst, &rfcomm_pi(sk)->src, &rfcomm_pi(sk)->dst,
sk->sk_state, rfcomm_pi(sk)->channel); sk->sk_state, rfcomm_pi(sk)->channel);
} }
......
...@@ -92,9 +92,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) ...@@ -92,9 +92,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
hcon->sco_data = conn; hcon->sco_data = conn;
conn->hcon = hcon; conn->hcon = hcon;
conn->src = &hdev->bdaddr;
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
...@@ -156,16 +153,14 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk, ...@@ -156,16 +153,14 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk,
static int sco_connect(struct sock *sk) static int sco_connect(struct sock *sk)
{ {
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
struct sco_conn *conn; struct sco_conn *conn;
struct hci_conn *hcon; struct hci_conn *hcon;
struct hci_dev *hdev; struct hci_dev *hdev;
int err, type; int err, type;
BT_DBG("%pMR -> %pMR", src, dst); BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
hdev = hci_get_route(dst, src); hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src);
if (!hdev) if (!hdev)
return -EHOSTUNREACH; return -EHOSTUNREACH;
...@@ -182,7 +177,8 @@ static int sco_connect(struct sock *sk) ...@@ -182,7 +177,8 @@ static int sco_connect(struct sock *sk)
goto done; goto done;
} }
hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting); hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
sco_pi(sk)->setting);
if (IS_ERR(hcon)) { if (IS_ERR(hcon)) {
err = PTR_ERR(hcon); err = PTR_ERR(hcon);
goto done; goto done;
...@@ -196,7 +192,7 @@ static int sco_connect(struct sock *sk) ...@@ -196,7 +192,7 @@ static int sco_connect(struct sock *sk)
} }
/* Update source addr of the socket */ /* Update source addr of the socket */
bacpy(src, conn->src); bacpy(&sco_pi(sk)->src, &hcon->src);
err = sco_chan_add(conn, sk, NULL); err = sco_chan_add(conn, sk, NULL);
if (err) if (err)
...@@ -270,7 +266,7 @@ static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba) ...@@ -270,7 +266,7 @@ static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
if (sk->sk_state != BT_LISTEN) if (sk->sk_state != BT_LISTEN)
continue; continue;
if (!bacmp(&bt_sk(sk)->src, ba)) if (!bacmp(&sco_pi(sk)->src, ba))
return sk; return sk;
} }
...@@ -291,11 +287,11 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src) ...@@ -291,11 +287,11 @@ static struct sock *sco_get_sock_listen(bdaddr_t *src)
continue; continue;
/* Exact match. */ /* Exact match. */
if (!bacmp(&bt_sk(sk)->src, src)) if (!bacmp(&sco_pi(sk)->src, src))
break; break;
/* Closest match */ /* Closest match */
if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) if (!bacmp(&sco_pi(sk)->src, BDADDR_ANY))
sk1 = sk; sk1 = sk;
} }
...@@ -475,7 +471,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le ...@@ -475,7 +471,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
goto done; goto done;
} }
bacpy(&bt_sk(sk)->src, &sa->sco_bdaddr); bacpy(&sco_pi(sk)->src, &sa->sco_bdaddr);
sk->sk_state = BT_BOUND; sk->sk_state = BT_BOUND;
...@@ -505,7 +501,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen ...@@ -505,7 +501,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
lock_sock(sk); lock_sock(sk);
/* Set destination address and psm */ /* Set destination address and psm */
bacpy(&bt_sk(sk)->dst, &sa->sco_bdaddr); bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
err = sco_connect(sk); err = sco_connect(sk);
if (err) if (err)
...@@ -522,7 +518,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen ...@@ -522,7 +518,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
static int sco_sock_listen(struct socket *sock, int backlog) static int sco_sock_listen(struct socket *sock, int backlog)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
bdaddr_t *src = &bt_sk(sk)->src; bdaddr_t *src = &sco_pi(sk)->src;
int err = 0; int err = 0;
BT_DBG("sk %p backlog %d", sk, backlog); BT_DBG("sk %p backlog %d", sk, backlog);
...@@ -626,9 +622,9 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len ...@@ -626,9 +622,9 @@ static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len
*len = sizeof(struct sockaddr_sco); *len = sizeof(struct sockaddr_sco);
if (peer) if (peer)
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->dst); bacpy(&sa->sco_bdaddr, &sco_pi(sk)->dst);
else else
bacpy(&sa->sco_bdaddr, &bt_sk(sk)->src); bacpy(&sa->sco_bdaddr, &sco_pi(sk)->src);
return 0; return 0;
} }
...@@ -999,7 +995,7 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -999,7 +995,7 @@ static void sco_conn_ready(struct sco_conn *conn)
} else { } else {
sco_conn_lock(conn); sco_conn_lock(conn);
parent = sco_get_sock_listen(conn->src); parent = sco_get_sock_listen(&conn->hcon->src);
if (!parent) { if (!parent) {
sco_conn_unlock(conn); sco_conn_unlock(conn);
return; return;
...@@ -1017,8 +1013,8 @@ static void sco_conn_ready(struct sco_conn *conn) ...@@ -1017,8 +1013,8 @@ static void sco_conn_ready(struct sco_conn *conn)
sco_sock_init(sk, parent); sco_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, conn->src); bacpy(&sco_pi(sk)->src, &conn->hcon->src);
bacpy(&bt_sk(sk)->dst, conn->dst); bacpy(&sco_pi(sk)->dst, &conn->hcon->dst);
hci_conn_hold(conn->hcon); hci_conn_hold(conn->hcon);
__sco_chan_add(conn, sk, parent); __sco_chan_add(conn, sk, parent);
...@@ -1051,8 +1047,8 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) ...@@ -1051,8 +1047,8 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
if (sk->sk_state != BT_LISTEN) if (sk->sk_state != BT_LISTEN)
continue; continue;
if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || if (!bacmp(&sco_pi(sk)->src, &hdev->bdaddr) ||
!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { !bacmp(&sco_pi(sk)->src, BDADDR_ANY)) {
lm |= HCI_LM_ACCEPT; lm |= HCI_LM_ACCEPT;
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
...@@ -1111,8 +1107,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p) ...@@ -1111,8 +1107,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p)
read_lock(&sco_sk_list.lock); read_lock(&sco_sk_list.lock);
sk_for_each(sk, &sco_sk_list.head) { sk_for_each(sk, &sco_sk_list.head) {
seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src, seq_printf(f, "%pMR %pMR %d\n", &sco_pi(sk)->src,
&bt_sk(sk)->dst, sk->sk_state); &sco_pi(sk)->dst, sk->sk_state);
} }
read_unlock(&sco_sk_list.lock); read_unlock(&sco_sk_list.lock);
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/mgmt.h> #include <net/bluetooth/mgmt.h>
#include <net/bluetooth/smp.h>
#include "smp.h"
#define SMP_TIMEOUT msecs_to_jiffies(30000) #define SMP_TIMEOUT msecs_to_jiffies(30000)
...@@ -85,8 +86,8 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) ...@@ -85,8 +86,8 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
} }
static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
u8 _rat, bdaddr_t *ra, u8 res[16]) u8 _rat, bdaddr_t *ra, u8 res[16])
{ {
u8 p1[16], p2[16]; u8 p1[16], p2[16];
int err; int err;
...@@ -126,8 +127,8 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], ...@@ -126,8 +127,8 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
return err; return err;
} }
static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
u8 r1[16], u8 r2[16], u8 _r[16]) u8 r2[16], u8 _r[16])
{ {
int err; int err;
...@@ -150,7 +151,7 @@ static int smp_rand(u8 *buf) ...@@ -150,7 +151,7 @@ static int smp_rand(u8 *buf)
} }
static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
u16 dlen, void *data) u16 dlen, void *data)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct l2cap_hdr *lh; struct l2cap_hdr *lh;
...@@ -213,9 +214,8 @@ static __u8 seclevel_to_authreq(__u8 sec_level) ...@@ -213,9 +214,8 @@ static __u8 seclevel_to_authreq(__u8 sec_level)
} }
static void build_pairing_cmd(struct l2cap_conn *conn, static void build_pairing_cmd(struct l2cap_conn *conn,
struct smp_cmd_pairing *req, struct smp_cmd_pairing *req,
struct smp_cmd_pairing *rsp, struct smp_cmd_pairing *rsp, __u8 authreq)
__u8 authreq)
{ {
u8 dist_keys = 0; u8 dist_keys = 0;
...@@ -249,7 +249,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) ...@@ -249,7 +249,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
struct smp_chan *smp = conn->smp_chan; struct smp_chan *smp = conn->smp_chan;
if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
(max_key_size < SMP_MIN_ENC_KEY_SIZE)) (max_key_size < SMP_MIN_ENC_KEY_SIZE))
return SMP_ENC_KEY_SIZE; return SMP_ENC_KEY_SIZE;
smp->enc_key_size = max_key_size; smp->enc_key_size = max_key_size;
...@@ -263,15 +263,15 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) ...@@ -263,15 +263,15 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
if (send) if (send)
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason); &reason);
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags);
mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
hcon->dst_type, HCI_ERROR_AUTH_FAILURE); HCI_ERROR_AUTH_FAILURE);
cancel_delayed_work_sync(&conn->security_timer); cancel_delayed_work_sync(&conn->security_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
smp_chan_destroy(conn); smp_chan_destroy(conn);
} }
...@@ -309,8 +309,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, ...@@ -309,8 +309,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
/* If either side has unknown io_caps, use JUST WORKS */ /* If either side has unknown io_caps, use JUST WORKS */
/* Otherwise, look up method from the table */ /* Otherwise, look up method from the table */
if (!(auth & SMP_AUTH_MITM) || if (!(auth & SMP_AUTH_MITM) ||
local_io > SMP_IO_KEYBOARD_DISPLAY || local_io > SMP_IO_KEYBOARD_DISPLAY ||
remote_io > SMP_IO_KEYBOARD_DISPLAY) remote_io > SMP_IO_KEYBOARD_DISPLAY)
method = JUST_WORKS; method = JUST_WORKS;
else else
method = gen_method[remote_io][local_io]; method = gen_method[remote_io][local_io];
...@@ -354,10 +354,10 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, ...@@ -354,10 +354,10 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
hci_dev_lock(hcon->hdev); hci_dev_lock(hcon->hdev);
if (method == REQ_PASSKEY) if (method == REQ_PASSKEY)
ret = mgmt_user_passkey_request(hcon->hdev, conn->dst, ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type); hcon->type, hcon->dst_type);
else else
ret = mgmt_user_confirm_request(hcon->hdev, conn->dst, ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
hcon->type, hcon->dst_type, hcon->type, hcon->dst_type,
cpu_to_le32(passkey), 0); cpu_to_le32(passkey), 0);
...@@ -386,12 +386,13 @@ static void confirm_work(struct work_struct *work) ...@@ -386,12 +386,13 @@ static void confirm_work(struct work_struct *work)
smp->tfm = tfm; smp->tfm = tfm;
if (conn->hcon->out) if (conn->hcon->out)
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, 0, ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->src, conn->hcon->dst_type, conn->dst, res); conn->hcon->src_type, &conn->hcon->src,
conn->hcon->dst_type, &conn->hcon->dst, res);
else else
ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->dst_type, conn->dst, 0, conn->src, conn->hcon->dst_type, &conn->hcon->dst,
res); conn->hcon->src_type, &conn->hcon->src, res);
if (ret) { if (ret) {
reason = SMP_UNSPECIFIED; reason = SMP_UNSPECIFIED;
goto error; goto error;
...@@ -425,11 +426,13 @@ static void random_work(struct work_struct *work) ...@@ -425,11 +426,13 @@ static void random_work(struct work_struct *work)
BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
if (hcon->out) if (hcon->out)
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0, ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
conn->src, hcon->dst_type, conn->dst, res); hcon->src_type, &hcon->src,
hcon->dst_type, &hcon->dst, res);
else else
ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->dst_type, conn->dst, 0, conn->src, res); hcon->dst_type, &hcon->dst,
hcon->src_type, &hcon->src, res);
if (ret) { if (ret) {
reason = SMP_UNSPECIFIED; reason = SMP_UNSPECIFIED;
goto error; goto error;
...@@ -477,9 +480,9 @@ static void random_work(struct work_struct *work) ...@@ -477,9 +480,9 @@ static void random_work(struct work_struct *work)
swap128(key, stk); swap128(key, stk);
memset(stk + smp->enc_key_size, 0, memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type, hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size, HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size,
ediv, rand); ediv, rand);
} }
...@@ -494,7 +497,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) ...@@ -494,7 +497,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
{ {
struct smp_chan *smp; struct smp_chan *smp;
smp = kzalloc(sizeof(struct smp_chan), GFP_ATOMIC); smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
if (!smp) if (!smp)
return NULL; return NULL;
...@@ -649,7 +652,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -649,7 +652,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
if ((req->auth_req & SMP_AUTH_BONDING) && if ((req->auth_req & SMP_AUTH_BONDING) &&
(rsp->auth_req & SMP_AUTH_BONDING)) (rsp->auth_req & SMP_AUTH_BONDING))
auth = SMP_AUTH_BONDING; auth = SMP_AUTH_BONDING;
auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
...@@ -684,7 +687,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -684,7 +687,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
swap128(smp->prnd, random); swap128(smp->prnd, random);
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
random); random);
} else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) { } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) {
queue_work(hdev->workqueue, &smp->confirm); queue_work(hdev->workqueue, &smp->confirm);
} else { } else {
...@@ -714,7 +717,7 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) ...@@ -714,7 +717,7 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
struct smp_ltk *key; struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon; struct hci_conn *hcon = conn->hcon;
key = hci_find_ltk_by_addr(hcon->hdev, conn->dst, hcon->dst_type); key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type);
if (!key) if (!key)
return 0; return 0;
...@@ -728,8 +731,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) ...@@ -728,8 +731,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
hcon->enc_key_size = key->enc_size; hcon->enc_key_size = key->enc_size;
return 1; return 1;
} }
static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{ {
struct smp_cmd_security_req *rp = (void *) skb->data; struct smp_cmd_security_req *rp = (void *) skb->data;
...@@ -835,9 +838,9 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -835,9 +838,9 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
skb_pull(skb, sizeof(*rp)); skb_pull(skb, sizeof(*rp));
hci_dev_lock(hdev); hci_dev_lock(hdev);
authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH); authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type, hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1,
HCI_SMP_LTK, 1, authenticated, smp->tk, smp->enc_key_size, authenticated, smp->tk, smp->enc_key_size,
rp->ediv, rp->rand); rp->ediv, rp->rand);
smp_distribute_keys(conn, 1); smp_distribute_keys(conn, 1);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -985,7 +988,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) ...@@ -985,7 +988,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
authenticated = hcon->sec_level == BT_SECURITY_HIGH; authenticated = hcon->sec_level == BT_SECURITY_HIGH;
hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type, hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
HCI_SMP_LTK_SLAVE, 1, authenticated, HCI_SMP_LTK_SLAVE, 1, authenticated,
enc.ltk, smp->enc_key_size, ediv, ident.rand); enc.ltk, smp->enc_key_size, ediv, ident.rand);
...@@ -1007,10 +1010,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) ...@@ -1007,10 +1010,10 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
/* Just public address */ /* Just public address */
memset(&addrinfo, 0, sizeof(addrinfo)); memset(&addrinfo, 0, sizeof(addrinfo));
bacpy(&addrinfo.bdaddr, conn->src); bacpy(&addrinfo.bdaddr, &conn->hcon->src);
smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo),
&addrinfo); &addrinfo);
*keydist &= ~SMP_DIST_ID_KEY; *keydist &= ~SMP_DIST_ID_KEY;
} }
......
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