Loading MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ F: drivers/scsi/53c700* 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) M: Alexander Aring <alex.aring@gmail.com> M: Jukka Rissanen <jukka.rissanen@linux.intel.com> L: linux-bluetooth@vger.kernel.org L: linux-wpan@vger.kernel.org S: Maintained Loading drivers/bluetooth/btusb.c +375 −136 Original line number Diff line number Diff line Loading @@ -275,13 +275,19 @@ struct btusb_data { struct work_struct work; struct work_struct waker; struct usb_anchor deferred; struct usb_anchor tx_anchor; int tx_in_flight; spinlock_t txlock; struct usb_anchor intr_anchor; struct usb_anchor bulk_anchor; struct usb_anchor isoc_anchor; struct usb_anchor deferred; int tx_in_flight; spinlock_t txlock; spinlock_t rxlock; struct sk_buff *evt_skb; struct sk_buff *acl_skb; struct sk_buff *sco_skb; struct usb_endpoint_descriptor *intr_ep; struct usb_endpoint_descriptor *bulk_tx_ep; Loading @@ -296,18 +302,189 @@ struct btusb_data { int suspend_count; }; static int inc_tx(struct btusb_data *data) static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; int rv; spin_lock_irqsave(&data->txlock, flags); rv = test_bit(BTUSB_SUSPENDING, &data->flags); if (!rv) data->tx_in_flight++; spin_unlock_irqrestore(&data->txlock, flags); spin_lock_irqsave(&data->rxlock, flags); kfree_skb(data->evt_skb); data->evt_skb = NULL; kfree_skb(data->acl_skb); data->acl_skb = NULL; kfree_skb(data->sco_skb); data->sco_skb = NULL; spin_unlock_irqrestore(&data->rxlock, flags); } static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; spin_lock(&data->rxlock); skb = data->evt_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_EVENT_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_EVENT_PKT; bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_EVENT_HDR_SIZE) { /* Complete event header */ bt_cb(skb)->expect = hci_event_hdr(skb)->plen; if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->evt_skb = skb; spin_unlock(&data->rxlock); return err; } static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; spin_lock(&data->rxlock); skb = data->acl_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; bt_cb(skb)->expect = HCI_ACL_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_ACL_HDR_SIZE) { __le16 dlen = hci_acl_hdr(skb)->dlen; /* Complete ACL header */ bt_cb(skb)->expect = __le16_to_cpu(dlen); if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->acl_skb = skb; spin_unlock(&data->rxlock); return err; } static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; return rv; spin_lock(&data->rxlock); skb = data->sco_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_SCO_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; bt_cb(skb)->expect = HCI_SCO_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_SCO_HDR_SIZE) { /* Complete SCO header */ bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen; if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->sco_skb = skb; spin_unlock(&data->rxlock); return err; } static void btusb_intr_complete(struct urb *urb) Loading @@ -316,8 +493,8 @@ static void btusb_intr_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -325,8 +502,7 @@ static void btusb_intr_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; if (hci_recv_fragment(hdev, HCI_EVENT_PKT, urb->transfer_buffer, if (btusb_recv_intr(data, urb->transfer_buffer, urb->actual_length) < 0) { BT_ERR("%s corrupted event packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -381,8 +557,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_intr_complete, hdev, data->intr_ep->bInterval); btusb_intr_complete, hdev, data->intr_ep->bInterval); urb->transfer_flags |= URB_FREE_BUFFER; Loading @@ -407,8 +582,8 @@ static void btusb_bulk_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -416,8 +591,7 @@ static void btusb_bulk_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, urb->transfer_buffer, if (btusb_recv_bulk(data, urb->transfer_buffer, urb->actual_length) < 0) { BT_ERR("%s corrupted ACL packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -469,8 +643,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, btusb_bulk_complete, hdev); usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, btusb_bulk_complete, hdev); urb->transfer_flags |= URB_FREE_BUFFER; Loading @@ -496,8 +670,8 @@ static void btusb_isoc_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int i, err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -512,8 +686,7 @@ static void btusb_isoc_complete(struct urb *urb) hdev->stat.byte_rx += length; if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, urb->transfer_buffer + offset, if (btusb_recv_isoc(data, urb->transfer_buffer + offset, length) < 0) { BT_ERR("%s corrupted SCO packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -618,8 +791,8 @@ static void btusb_tx_complete(struct urb *urb) struct hci_dev *hdev = (struct hci_dev *)skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; Loading @@ -644,8 +817,8 @@ static void btusb_isoc_tx_complete(struct urb *urb) struct sk_buff *skb = urb->context; struct hci_dev *hdev = (struct hci_dev *)skb->dev; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; Loading Loading @@ -729,6 +902,8 @@ static int btusb_close(struct hci_dev *hdev) clear_bit(BTUSB_INTR_RUNNING, &data->flags); btusb_stop_traffic(data); btusb_free_frags(data); err = usb_autopm_get_interface(data->intf); if (err < 0) goto failed; Loading @@ -748,35 +923,26 @@ static int btusb_flush(struct hci_dev *hdev) BT_DBG("%s", hdev->name); usb_kill_anchored_urbs(&data->tx_anchor); btusb_free_frags(data); return 0; } static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; skb->dev = (void *) hdev; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); dr = kmalloc(sizeof(*dr), GFP_ATOMIC); dr = kmalloc(sizeof(*dr), GFP_KERNEL); if (!dr) { usb_free_urb(urb); return -ENOMEM; return ERR_PTR(-ENOMEM); } dr->bRequestType = data->cmdreq_type; Loading @@ -790,36 +956,48 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) usb_fill_control_urb(urb, data->udev, pipe, (void *)dr, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.cmd_tx++; break; skb->dev = (void *)hdev; return urb; } static struct urb *alloc_bulk_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct urb *urb; unsigned int pipe; case HCI_ACLDATA_PKT: if (!data->bulk_tx_ep) return -ENODEV; return ERR_PTR(-ENODEV); urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.acl_tx++; break; skb->dev = (void *)hdev; case HCI_SCODATA_PKT: if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1) return -ENODEV; return urb; } urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct urb *urb; unsigned int pipe; if (!data->isoc_tx_ep) return ERR_PTR(-ENODEV); urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_isoc_tx_complete, Loading @@ -830,25 +1008,19 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); hdev->stat.sco_tx++; goto skip_waking; skb->dev = (void *)hdev; default: return -EILSEQ; return urb; } err = inc_tx(data); if (err) { usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); err = 0; goto done; } static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb) { struct btusb_data *data = hci_get_drvdata(hdev); int err; skip_waking: usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_KERNEL); if (err < 0) { if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed (%d)", Loading @@ -859,11 +1031,73 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; } static int submit_or_queue_tx_urb(struct hci_dev *hdev, struct urb *urb) { struct btusb_data *data = hci_get_drvdata(hdev); unsigned long flags; bool suspending; spin_lock_irqsave(&data->txlock, flags); suspending = test_bit(BTUSB_SUSPENDING, &data->flags); if (!suspending) data->tx_in_flight++; spin_unlock_irqrestore(&data->txlock, flags); if (!suspending) return submit_tx_urb(hdev, urb); usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); usb_free_urb(urb); return 0; } static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { struct urb *urb; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = alloc_ctrl_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.cmd_tx++; return submit_or_queue_tx_urb(hdev, urb); case HCI_ACLDATA_PKT: urb = alloc_bulk_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.acl_tx++; return submit_or_queue_tx_urb(hdev, urb); case HCI_SCODATA_PKT: if (hci_conn_num(hdev, SCO_LINK) < 1) return -ENODEV; urb = alloc_isoc_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.sco_tx++; return submit_tx_urb(hdev, urb); } return -EILSEQ; } static void btusb_notify(struct hci_dev *hdev, unsigned int evt) { struct btusb_data *data = hci_get_drvdata(hdev); Loading Loading @@ -940,6 +1174,7 @@ static void btusb_work(struct work_struct *work) if (hdev->voice_setting & 0x0020) { static const int alts[3] = { 2, 4, 5 }; new_alts = alts[data->sco_num - 1]; } else { new_alts = data->sco_num; Loading Loading @@ -1356,6 +1591,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) if (skb->data[0]) { u8 evt_status = skb->data[0]; BT_ERR("%s enable Intel manufacturer mode event failed (%02x)", hdev->name, evt_status); kfree_skb(skb); Loading Loading @@ -1717,6 +1953,7 @@ static int btusb_probe(struct usb_interface *intf, if (!id->driver_info) { const struct usb_device_id *match; match = usb_match_id(intf, blacklist_table); if (match) id = match; Loading Loading @@ -1769,13 +2006,14 @@ static int btusb_probe(struct usb_interface *intf, INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); init_usb_anchor(&data->deferred); init_usb_anchor(&data->tx_anchor); spin_lock_init(&data->txlock); init_usb_anchor(&data->tx_anchor); init_usb_anchor(&data->intr_anchor); init_usb_anchor(&data->bulk_anchor); init_usb_anchor(&data->isoc_anchor); init_usb_anchor(&data->deferred); spin_lock_init(&data->rxlock); hdev = hci_alloc_dev(); if (!hdev) Loading Loading @@ -1908,6 +2146,7 @@ static void btusb_disconnect(struct usb_interface *intf) else if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); btusb_free_frags(data); hci_free_dev(hdev); } Loading drivers/net/ieee802154/mrf24j40.c +10 −9 Original line number Diff line number Diff line Loading @@ -323,7 +323,7 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec, #ifdef DEBUG print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ", DUMP_PREFIX_OFFSET, 16, 1, data, *len, 0); printk(KERN_DEBUG "mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n", pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n", lqi_rssi[0], lqi_rssi[1]); #endif Loading Loading @@ -385,7 +385,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) { /* TODO: */ printk(KERN_WARNING "mrf24j40: ed not implemented\n"); pr_warn("mrf24j40: ed not implemented\n"); *level = 0; return 0; } Loading @@ -412,6 +412,7 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) struct mrf24j40 *devrec = dev->priv; u8 val; int ret; dev_dbg(printdev(devrec), "stop\n"); ret = read_short_reg(devrec, REG_INTCON, &val); Loading @@ -419,8 +420,6 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) return; val |= 0x1|0x8; /* Set TXNIE and RXIE. Disable Interrupts */ write_short_reg(devrec, REG_INTCON, val); return; } static int mrf24j40_set_channel(struct ieee802154_dev *dev, Loading Loading @@ -465,6 +464,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, if (changed & IEEE802515_AFILT_SADDR_CHANGED) { /* Short Addr */ u8 addrh, addrl; addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff; addrl = le16_to_cpu(filt->short_addr) & 0xff; Loading @@ -483,16 +483,17 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, write_short_reg(devrec, REG_EADR0 + i, addr[i]); #ifdef DEBUG printk(KERN_DEBUG "Set long addr to: "); pr_debug("Set long addr to: "); for (i = 0; i < 8; i++) printk("%02hhx ", addr[7 - i]); printk(KERN_DEBUG "\n"); pr_debug("%02hhx ", addr[7 - i]); pr_debug("\n"); #endif } if (changed & IEEE802515_AFILT_PANID_CHANGED) { /* PAN ID */ u8 panidl, panidh; panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff; panidl = le16_to_cpu(filt->pan_id) & 0xff; write_short_reg(devrec, REG_PANIDH, panidh); Loading Loading @@ -701,7 +702,7 @@ static int mrf24j40_probe(struct spi_device *spi) int ret = -ENOMEM; struct mrf24j40 *devrec; printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq); dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq); devrec = devm_kzalloc(&spi->dev, sizeof(struct mrf24j40), GFP_KERNEL); if (!devrec) Loading include/net/bluetooth/bluetooth.h +3 −2 Original line number Diff line number Diff line Loading @@ -120,9 +120,9 @@ struct bt_voice { #define BT_RCVMTU 13 __printf(1, 2) int bt_info(const char *fmt, ...); void bt_info(const char *fmt, ...); __printf(1, 2) int bt_err(const char *fmt, ...); void bt_err(const char *fmt, ...); #define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) #define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) Loading Loading @@ -284,6 +284,7 @@ struct hci_req_ctrl { struct bt_skb_cb { __u8 pkt_type; __u8 incoming; __u16 opcode; __u16 expect; __u8 force_active; struct l2cap_chan *chan; Loading include/net/bluetooth/hci.h +1 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,7 @@ enum { #define HCI_ERROR_AUTH_FAILURE 0x05 #define HCI_ERROR_MEMORY_EXCEEDED 0x07 #define HCI_ERROR_CONNECTION_TIMEOUT 0x08 #define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d #define HCI_ERROR_REJ_BAD_ADDR 0x0f #define HCI_ERROR_REMOTE_USER_TERM 0x13 #define HCI_ERROR_REMOTE_LOW_RESOURCES 0x14 Loading Loading
MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ F: drivers/scsi/53c700* 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) M: Alexander Aring <alex.aring@gmail.com> M: Jukka Rissanen <jukka.rissanen@linux.intel.com> L: linux-bluetooth@vger.kernel.org L: linux-wpan@vger.kernel.org S: Maintained Loading
drivers/bluetooth/btusb.c +375 −136 Original line number Diff line number Diff line Loading @@ -275,13 +275,19 @@ struct btusb_data { struct work_struct work; struct work_struct waker; struct usb_anchor deferred; struct usb_anchor tx_anchor; int tx_in_flight; spinlock_t txlock; struct usb_anchor intr_anchor; struct usb_anchor bulk_anchor; struct usb_anchor isoc_anchor; struct usb_anchor deferred; int tx_in_flight; spinlock_t txlock; spinlock_t rxlock; struct sk_buff *evt_skb; struct sk_buff *acl_skb; struct sk_buff *sco_skb; struct usb_endpoint_descriptor *intr_ep; struct usb_endpoint_descriptor *bulk_tx_ep; Loading @@ -296,18 +302,189 @@ struct btusb_data { int suspend_count; }; static int inc_tx(struct btusb_data *data) static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; int rv; spin_lock_irqsave(&data->txlock, flags); rv = test_bit(BTUSB_SUSPENDING, &data->flags); if (!rv) data->tx_in_flight++; spin_unlock_irqrestore(&data->txlock, flags); spin_lock_irqsave(&data->rxlock, flags); kfree_skb(data->evt_skb); data->evt_skb = NULL; kfree_skb(data->acl_skb); data->acl_skb = NULL; kfree_skb(data->sco_skb); data->sco_skb = NULL; spin_unlock_irqrestore(&data->rxlock, flags); } static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; spin_lock(&data->rxlock); skb = data->evt_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_EVENT_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_EVENT_PKT; bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_EVENT_HDR_SIZE) { /* Complete event header */ bt_cb(skb)->expect = hci_event_hdr(skb)->plen; if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->evt_skb = skb; spin_unlock(&data->rxlock); return err; } static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; spin_lock(&data->rxlock); skb = data->acl_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; bt_cb(skb)->expect = HCI_ACL_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_ACL_HDR_SIZE) { __le16 dlen = hci_acl_hdr(skb)->dlen; /* Complete ACL header */ bt_cb(skb)->expect = __le16_to_cpu(dlen); if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->acl_skb = skb; spin_unlock(&data->rxlock); return err; } static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; int err = 0; return rv; spin_lock(&data->rxlock); skb = data->sco_skb; while (count) { int len; if (!skb) { skb = bt_skb_alloc(HCI_MAX_SCO_SIZE, GFP_ATOMIC); if (!skb) { err = -ENOMEM; break; } bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; bt_cb(skb)->expect = HCI_SCO_HDR_SIZE; } len = min_t(uint, bt_cb(skb)->expect, count); memcpy(skb_put(skb, len), buffer, len); count -= len; buffer += len; bt_cb(skb)->expect -= len; if (skb->len == HCI_SCO_HDR_SIZE) { /* Complete SCO header */ bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen; if (skb_tailroom(skb) < bt_cb(skb)->expect) { kfree_skb(skb); skb = NULL; err = -EILSEQ; break; } } if (bt_cb(skb)->expect == 0) { /* Complete frame */ hci_recv_frame(data->hdev, skb); skb = NULL; } } data->sco_skb = skb; spin_unlock(&data->rxlock); return err; } static void btusb_intr_complete(struct urb *urb) Loading @@ -316,8 +493,8 @@ static void btusb_intr_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -325,8 +502,7 @@ static void btusb_intr_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; if (hci_recv_fragment(hdev, HCI_EVENT_PKT, urb->transfer_buffer, if (btusb_recv_intr(data, urb->transfer_buffer, urb->actual_length) < 0) { BT_ERR("%s corrupted event packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -381,8 +557,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_intr_complete, hdev, data->intr_ep->bInterval); btusb_intr_complete, hdev, data->intr_ep->bInterval); urb->transfer_flags |= URB_FREE_BUFFER; Loading @@ -407,8 +582,8 @@ static void btusb_bulk_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -416,8 +591,7 @@ static void btusb_bulk_complete(struct urb *urb) if (urb->status == 0) { hdev->stat.byte_rx += urb->actual_length; if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, urb->transfer_buffer, if (btusb_recv_bulk(data, urb->transfer_buffer, urb->actual_length) < 0) { BT_ERR("%s corrupted ACL packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -469,8 +643,8 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, btusb_bulk_complete, hdev); usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, btusb_bulk_complete, hdev); urb->transfer_flags |= URB_FREE_BUFFER; Loading @@ -496,8 +670,8 @@ static void btusb_isoc_complete(struct urb *urb) struct btusb_data *data = hci_get_drvdata(hdev); int i, err; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) return; Loading @@ -512,8 +686,7 @@ static void btusb_isoc_complete(struct urb *urb) hdev->stat.byte_rx += length; if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, urb->transfer_buffer + offset, if (btusb_recv_isoc(data, urb->transfer_buffer + offset, length) < 0) { BT_ERR("%s corrupted SCO packet", hdev->name); hdev->stat.err_rx++; Loading Loading @@ -618,8 +791,8 @@ static void btusb_tx_complete(struct urb *urb) struct hci_dev *hdev = (struct hci_dev *)skb->dev; struct btusb_data *data = hci_get_drvdata(hdev); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; Loading @@ -644,8 +817,8 @@ static void btusb_isoc_tx_complete(struct urb *urb) struct sk_buff *skb = urb->context; struct hci_dev *hdev = (struct hci_dev *)skb->dev; BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status, urb->actual_length); if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; Loading Loading @@ -729,6 +902,8 @@ static int btusb_close(struct hci_dev *hdev) clear_bit(BTUSB_INTR_RUNNING, &data->flags); btusb_stop_traffic(data); btusb_free_frags(data); err = usb_autopm_get_interface(data->intf); if (err < 0) goto failed; Loading @@ -748,35 +923,26 @@ static int btusb_flush(struct hci_dev *hdev) BT_DBG("%s", hdev->name); usb_kill_anchored_urbs(&data->tx_anchor); btusb_free_frags(data); return 0; } static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct usb_ctrlrequest *dr; struct urb *urb; unsigned int pipe; int err; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; skb->dev = (void *) hdev; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); dr = kmalloc(sizeof(*dr), GFP_ATOMIC); dr = kmalloc(sizeof(*dr), GFP_KERNEL); if (!dr) { usb_free_urb(urb); return -ENOMEM; return ERR_PTR(-ENOMEM); } dr->bRequestType = data->cmdreq_type; Loading @@ -790,36 +956,48 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) usb_fill_control_urb(urb, data->udev, pipe, (void *)dr, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.cmd_tx++; break; skb->dev = (void *)hdev; return urb; } static struct urb *alloc_bulk_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct urb *urb; unsigned int pipe; case HCI_ACLDATA_PKT: if (!data->bulk_tx_ep) return -ENODEV; return ERR_PTR(-ENODEV); urb = usb_alloc_urb(0, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_tx_complete, skb); hdev->stat.acl_tx++; break; skb->dev = (void *)hdev; case HCI_SCODATA_PKT: if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1) return -ENODEV; return urb; } urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); struct urb *urb; unsigned int pipe; if (!data->isoc_tx_ep) return ERR_PTR(-ENODEV); urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL); if (!urb) return -ENOMEM; return ERR_PTR(-ENOMEM); pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); usb_fill_int_urb(urb, data->udev, pipe, skb->data, skb->len, btusb_isoc_tx_complete, Loading @@ -830,25 +1008,19 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); hdev->stat.sco_tx++; goto skip_waking; skb->dev = (void *)hdev; default: return -EILSEQ; return urb; } err = inc_tx(data); if (err) { usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); err = 0; goto done; } static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb) { struct btusb_data *data = hci_get_drvdata(hdev); int err; skip_waking: usb_anchor_urb(urb, &data->tx_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_KERNEL); if (err < 0) { if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed (%d)", Loading @@ -859,11 +1031,73 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) usb_mark_last_busy(data->udev); } done: usb_free_urb(urb); return err; } static int submit_or_queue_tx_urb(struct hci_dev *hdev, struct urb *urb) { struct btusb_data *data = hci_get_drvdata(hdev); unsigned long flags; bool suspending; spin_lock_irqsave(&data->txlock, flags); suspending = test_bit(BTUSB_SUSPENDING, &data->flags); if (!suspending) data->tx_in_flight++; spin_unlock_irqrestore(&data->txlock, flags); if (!suspending) return submit_tx_urb(hdev, urb); usb_anchor_urb(urb, &data->deferred); schedule_work(&data->waker); usb_free_urb(urb); return 0; } static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { struct urb *urb; BT_DBG("%s", hdev->name); if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: urb = alloc_ctrl_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.cmd_tx++; return submit_or_queue_tx_urb(hdev, urb); case HCI_ACLDATA_PKT: urb = alloc_bulk_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.acl_tx++; return submit_or_queue_tx_urb(hdev, urb); case HCI_SCODATA_PKT: if (hci_conn_num(hdev, SCO_LINK) < 1) return -ENODEV; urb = alloc_isoc_urb(hdev, skb); if (IS_ERR(urb)) return PTR_ERR(urb); hdev->stat.sco_tx++; return submit_tx_urb(hdev, urb); } return -EILSEQ; } static void btusb_notify(struct hci_dev *hdev, unsigned int evt) { struct btusb_data *data = hci_get_drvdata(hdev); Loading Loading @@ -940,6 +1174,7 @@ static void btusb_work(struct work_struct *work) if (hdev->voice_setting & 0x0020) { static const int alts[3] = { 2, 4, 5 }; new_alts = alts[data->sco_num - 1]; } else { new_alts = data->sco_num; Loading Loading @@ -1356,6 +1591,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) if (skb->data[0]) { u8 evt_status = skb->data[0]; BT_ERR("%s enable Intel manufacturer mode event failed (%02x)", hdev->name, evt_status); kfree_skb(skb); Loading Loading @@ -1717,6 +1953,7 @@ static int btusb_probe(struct usb_interface *intf, if (!id->driver_info) { const struct usb_device_id *match; match = usb_match_id(intf, blacklist_table); if (match) id = match; Loading Loading @@ -1769,13 +2006,14 @@ static int btusb_probe(struct usb_interface *intf, INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); init_usb_anchor(&data->deferred); init_usb_anchor(&data->tx_anchor); spin_lock_init(&data->txlock); init_usb_anchor(&data->tx_anchor); init_usb_anchor(&data->intr_anchor); init_usb_anchor(&data->bulk_anchor); init_usb_anchor(&data->isoc_anchor); init_usb_anchor(&data->deferred); spin_lock_init(&data->rxlock); hdev = hci_alloc_dev(); if (!hdev) Loading Loading @@ -1908,6 +2146,7 @@ static void btusb_disconnect(struct usb_interface *intf) else if (data->isoc) usb_driver_release_interface(&btusb_driver, data->isoc); btusb_free_frags(data); hci_free_dev(hdev); } Loading
drivers/net/ieee802154/mrf24j40.c +10 −9 Original line number Diff line number Diff line Loading @@ -323,7 +323,7 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec, #ifdef DEBUG print_hex_dump(KERN_DEBUG, "mrf24j40 rx: ", DUMP_PREFIX_OFFSET, 16, 1, data, *len, 0); printk(KERN_DEBUG "mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n", pr_debug("mrf24j40 rx: lqi: %02hhx rssi: %02hhx\n", lqi_rssi[0], lqi_rssi[1]); #endif Loading Loading @@ -385,7 +385,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) { /* TODO: */ printk(KERN_WARNING "mrf24j40: ed not implemented\n"); pr_warn("mrf24j40: ed not implemented\n"); *level = 0; return 0; } Loading @@ -412,6 +412,7 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) struct mrf24j40 *devrec = dev->priv; u8 val; int ret; dev_dbg(printdev(devrec), "stop\n"); ret = read_short_reg(devrec, REG_INTCON, &val); Loading @@ -419,8 +420,6 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) return; val |= 0x1|0x8; /* Set TXNIE and RXIE. Disable Interrupts */ write_short_reg(devrec, REG_INTCON, val); return; } static int mrf24j40_set_channel(struct ieee802154_dev *dev, Loading Loading @@ -465,6 +464,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, if (changed & IEEE802515_AFILT_SADDR_CHANGED) { /* Short Addr */ u8 addrh, addrl; addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff; addrl = le16_to_cpu(filt->short_addr) & 0xff; Loading @@ -483,16 +483,17 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, write_short_reg(devrec, REG_EADR0 + i, addr[i]); #ifdef DEBUG printk(KERN_DEBUG "Set long addr to: "); pr_debug("Set long addr to: "); for (i = 0; i < 8; i++) printk("%02hhx ", addr[7 - i]); printk(KERN_DEBUG "\n"); pr_debug("%02hhx ", addr[7 - i]); pr_debug("\n"); #endif } if (changed & IEEE802515_AFILT_PANID_CHANGED) { /* PAN ID */ u8 panidl, panidh; panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff; panidl = le16_to_cpu(filt->pan_id) & 0xff; write_short_reg(devrec, REG_PANIDH, panidh); Loading Loading @@ -701,7 +702,7 @@ static int mrf24j40_probe(struct spi_device *spi) int ret = -ENOMEM; struct mrf24j40 *devrec; printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq); dev_info(&spi->dev, "probe(). IRQ: %d\n", spi->irq); devrec = devm_kzalloc(&spi->dev, sizeof(struct mrf24j40), GFP_KERNEL); if (!devrec) Loading
include/net/bluetooth/bluetooth.h +3 −2 Original line number Diff line number Diff line Loading @@ -120,9 +120,9 @@ struct bt_voice { #define BT_RCVMTU 13 __printf(1, 2) int bt_info(const char *fmt, ...); void bt_info(const char *fmt, ...); __printf(1, 2) int bt_err(const char *fmt, ...); void bt_err(const char *fmt, ...); #define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) #define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) Loading Loading @@ -284,6 +284,7 @@ struct hci_req_ctrl { struct bt_skb_cb { __u8 pkt_type; __u8 incoming; __u16 opcode; __u16 expect; __u8 force_active; struct l2cap_chan *chan; Loading
include/net/bluetooth/hci.h +1 −0 Original line number Diff line number Diff line Loading @@ -385,6 +385,7 @@ enum { #define HCI_ERROR_AUTH_FAILURE 0x05 #define HCI_ERROR_MEMORY_EXCEEDED 0x07 #define HCI_ERROR_CONNECTION_TIMEOUT 0x08 #define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d #define HCI_ERROR_REJ_BAD_ADDR 0x0f #define HCI_ERROR_REMOTE_USER_TERM 0x13 #define HCI_ERROR_REMOTE_LOW_RESOURCES 0x14 Loading