Return-Path: From: Tedd Ho-Jeong An To: linux-bluetooth@vger.kernel.org, marcel@holtmann.org Cc: albert.o.ho@intel.com, johan.hedberg@intel.com, tedd.hj.an@gmail.com Subject: [RFCv3 3/3] Bluetooth: Add sample BT USB mini-driver Date: Fri, 02 Nov 2012 13:54:31 -0700 Message-ID: <3643102.0sb8ltOP1V@tedd-ubuntu> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" List-ID: From: Tedd Ho-Jeong An This patch adds sample BT USB mini-driver Signed-off-by: Tedd Ho-Jeong An --- drivers/bluetooth/btusb.c | 3 + drivers/bluetooth/btusb_sample.c | 189 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 drivers/bluetooth/btusb_sample.c diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 39a1e6c..630d938 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -193,6 +193,9 @@ static struct usb_device_id blacklist_table[] = { /* Frontline ComProbe Bluetooth Sniffer */ { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER }, + /* BT USB sample mini-driver */ + { USB_DEVICE(0x1234, 0x5678), .driver_info = BTUSB_IGNORE }, + { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb_sample.c b/drivers/bluetooth/btusb_sample.c new file mode 100644 index 0000000..6f4a9e0 --- /dev/null +++ b/drivers/bluetooth/btusb_sample.c @@ -0,0 +1,189 @@ +/* + * + * Bluetooth USB Mini Driver - Sample + * + * Copyright (C) 2012 Intel Corporation + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include + +#include +#include + +#include "btusb.h" + +/* + * This is sample BT USB mini-driver to demonstrate how a vendor can execute + * the vendor specific device initialization routine and handle vendor specific + * events. + * + * In this sample, it will send one vendor HCI command (but not limited to 1) + * as an example. + */ + +#define VENDOR_HCI_SAMPLE_CMD_1 0xfc01 + +/* mini-driver context */ +struct btusb_sample_data { + struct hci_dev *hdev; + + /* for synchronization */ + struct completion wait_evt_complete; +}; + +/* + * Entry point for device setup. + */ +int btusb_sample_setup(struct hci_dev *hdev) +{ + int ret; + struct btusb_sample_data *data; + + /* initialize the sample data */ + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + BT_ERR("failed to allocate the memory for data"); + return -ENOMEM; + } + + hdev->vendor_data = data; + data->hdev = hdev; + + init_completion(&data->wait_evt_complete); + + /* send command */ + ret = hci_send_cmd(hdev, VENDOR_HCI_SAMPLE_CMD_1, 0, NULL); + if (ret < 0) { + BT_ERR("failed to send command: %d", ret); + kfree(data); + return ret; + } + + /* waiting for event */ + ret = wait_for_completion_interruptible(&data->wait_evt_complete); + if (ret < 0) { + BT_ERR("wait completion error: %d", ret); + kfree(data); + return ret; + } + + + /* done */ + kfree(data); + + return 0; +} + +/* + * Vendor specific event handler + * + * During the vendor setup mode, this function is responsible for handling all + * received HCI events. + */ +void btusb_sample_event(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btusb_sample_data *data; + struct hci_event_hdr *hdr; + struct hci_ev_cmd_complete *cc; + u16 opcode; + + data = hdev->vendor_data; + + /* event header */ + hdr = (void *)skb->data; + if (hdr->evt != HCI_EV_CMD_COMPLETE) { + BT_ERR("invalid event code: %02x", hdr->evt); + goto exit_error; + } + skb_pull(skb, sizeof(*hdr)); + + /* command complete event */ + cc = (void *)skb->data; + opcode =le16_to_cpu(cc->opcode); + if (opcode != VENDOR_HCI_SAMPLE_CMD_1) { + BT_ERR("invalid opcode: %04x", opcode); + goto exit_error; + } + skb_pull(skb, sizeof(*cc)); + + /* check status */ + if ((u8)skb->data[0]) { + BT_ERR("evt status failed: %02x", (u8)skb->data[0]); + goto exit_error; + } + +exit_error: + /* this is for handling the flow control */ + del_timer(&hdev->cmd_timer); + atomic_set(&hdev->cmd_cnt, 1); + + /* consume the event here */ + kfree_skb(skb); + + /* complete the wait */ + complete(&data->wait_evt_complete); +} + +/* + * Bind this mini-driver to btusb.ko + */ +int btusb_sample_bind(struct hci_dev *hdev) +{ + /* set the vendor_setup and vendor_event handlers */ + hdev->vendor_setup = btusb_sample_setup; + hdev->vendor_event = btusb_sample_event; + + return 0; +} + +/* + * Unbind this mini-driver to btusb.ko + */ +void btusb_sample_unbind(struct hci_dev *hdev) +{ + + return; +} + +static const struct btusb_driver_info sample_info = { + .description = "BT USB mini driver sample", + .bind = btusb_sample_bind, + .unbind = btusb_sample_unbind, +}; + +static const struct usb_device_id products[] = { + { + USB_DEVICE(0x1234, 0x5678), + .driver_info = (unsigned long) &sample_info, + }, + {}, /* END */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver btusb_sample_minidriver = { + .name = "btusb sample mini-driver", + .probe = btusb_probe_one, + .disconnect = btusb_disconnect, + .id_table = products, +}; +module_usb_driver(btusb_sample_minidriver); + +MODULE_AUTHOR("Tedd Ho-Jeong An "); +MODULE_DESCRIPTION("BT USB sample mini driver"); +MODULE_LICENSE("GPL"); -- 1.7.9.5