⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hci_usb.c

📁 S3CEB2410开发板中蓝牙设备开发.如果有对arm920T板子上开发蓝牙技术感兴趣
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    BlueZ - Bluetooth protocol stack for Linux   Copyright (C) 2000-2001 Qualcomm Incorporated   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License version 2 as   published by the Free Software Foundation;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS    SOFTWARE IS DISCLAIMED.*//* * BlueZ HCI USB driver. * Based on original USB Bluetooth driver for Linux kernel *    Copyright (c) 2000 Greg Kroah-Hartman        <greg@kroah.com> *    Copyright (c) 2000 Mark Douglas Corner       <mcorner@umich.edu> * * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $     */#define VERSION "1.0"#include <linux/config.h>#include <linux/module.h>#include <linux/version.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/poll.h>#include <linux/slab.h>#include <linux/tty.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/signal.h>#include <linux/ioctl.h>#include <linux/skbuff.h>#include <linux/usb.h>#include <net/bluetooth/bluetooth.h>#include <net/bluetooth/bluez.h>#include <net/bluetooth/hci_core.h>#include <net/bluetooth/hci_usb.h>#ifndef HCI_USB_DEBUG#undef  DBG#define DBG( A... )#undef  DMP#define DMP( A... )#endifstatic struct usb_device_id usb_bluetooth_ids [] = {	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },	{ }	/* Terminating entry */};MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);static int hci_usb_ctrl_msg(struct hci_usb *husb,  struct sk_buff *skb);static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);static void hci_usb_unlink_urbs(struct hci_usb *husb){	usb_unlink_urb(husb->read_urb);	usb_unlink_urb(husb->intr_urb);	usb_unlink_urb(husb->ctrl_urb);	usb_unlink_urb(husb->write_urb);}static void hci_usb_free_bufs(struct hci_usb *husb){	if (husb->read_urb) {		if (husb->read_urb->transfer_buffer)			kfree(husb->read_urb->transfer_buffer);		usb_free_urb(husb->read_urb);	}	if (husb->intr_urb) {		if (husb->intr_urb->transfer_buffer)			kfree(husb->intr_urb->transfer_buffer);		usb_free_urb(husb->intr_urb);	}	if (husb->ctrl_urb)		usb_free_urb(husb->ctrl_urb);	if (husb->write_urb)		usb_free_urb(husb->write_urb);	if (husb->intr_skb)		kfree_skb(husb->intr_skb);}/* ------- Interface to HCI layer ------ *//* Initialize device */int hci_usb_open(struct hci_dev *hdev){	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;	int status;	DBG("%s", hdev->name);	husb->read_urb->dev = husb->udev;	if ((status = usb_submit_urb(husb->read_urb)))		DBG("read submit failed. %d", status);	husb->intr_urb->dev = husb->udev;	if ((status = usb_submit_urb(husb->intr_urb)))		DBG("interrupt submit failed. %d", status);	hdev->flags |= HCI_RUNNING;	return 0;}/* Reset device */int hci_usb_flush(struct hci_dev *hdev){	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;	DBG("%s", hdev->name);	/* Drop TX queues */	skb_queue_purge(&husb->tx_ctrl_q);	skb_queue_purge(&husb->tx_write_q);	return 0;}/* Close device */int hci_usb_close(struct hci_dev *hdev){	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;	DBG("%s", hdev->name);	hdev->flags &= ~HCI_RUNNING;	hci_usb_unlink_urbs(husb);	hci_usb_flush(hdev);	return 0;}void hci_usb_ctrl_wakeup(struct hci_usb *husb){	struct sk_buff *skb;	if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))		return;	DBG("%s", husb->hdev.name);	if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))		goto done;	if (hci_usb_ctrl_msg(husb, skb)){		kfree_skb(skb);		goto done;	}	DMP(skb->data, skb->len);	husb->hdev.stat.byte_tx += skb->len;	return;done:	clear_bit(HCI_TX_CTRL, &husb->tx_state);	return;}void hci_usb_write_wakeup(struct hci_usb *husb){	struct sk_buff *skb;	if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))		return;	DBG("%s", husb->hdev.name);	if (!(skb = skb_dequeue(&husb->tx_write_q)))		goto done;	if (hci_usb_write_msg(husb, skb)) {		skb_queue_head(&husb->tx_write_q, skb);		goto done;	}	DMP(skb->data, skb->len);	husb->hdev.stat.byte_tx += skb->len;	return;done:	clear_bit(HCI_TX_WRITE, &husb->tx_state);	return;}/* Send frames from HCI layer */int hci_usb_send_frame(struct sk_buff *skb){	struct hci_dev *hdev = (struct hci_dev *) skb->dev;	struct hci_usb *husb;	if (!hdev) {		ERR("frame for uknown device (hdev=NULL)");		return -ENODEV;	}	if (!(hdev->flags & HCI_RUNNING))		return 0;	husb = (struct hci_usb *) hdev->driver_data;	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);	switch (skb->pkt_type) {		case HCI_COMMAND_PKT:			skb_queue_tail(&husb->tx_ctrl_q, skb);			hci_usb_ctrl_wakeup(husb);			hdev->stat.cmd_tx++;			return 0;		case HCI_ACLDATA_PKT:			skb_queue_tail(&husb->tx_write_q, skb);			hci_usb_write_wakeup(husb);			hdev->stat.acl_tx++;			return 0;		case HCI_SCODATA_PKT:			return -EOPNOTSUPP;	};	return 0;}/* ---------- USB ------------- */static void hci_usb_ctrl(struct urb *urb){	struct sk_buff *skb = (struct sk_buff *) urb->context;	struct hci_dev *hdev;	struct hci_usb *husb;	if (!skb)		return;	hdev = (struct hci_dev *) skb->dev;	husb = (struct hci_usb *) hdev->driver_data;	DBG("%s", hdev->name);	if (urb->status)		DBG("%s ctrl status: %d", hdev->name, urb->status);	clear_bit(HCI_TX_CTRL, &husb->tx_state);	kfree_skb(skb);	/* Wake up device */	hci_usb_ctrl_wakeup(husb);}static void hci_usb_bulk_write(struct urb *urb){	struct sk_buff *skb = (struct sk_buff *) urb->context;	struct hci_dev *hdev;	struct hci_usb *husb;	if (!skb)		return;	hdev = (struct hci_dev *) skb->dev;	husb = (struct hci_usb *) hdev->driver_data;	DBG("%s", hdev->name);	if (urb->status)		DBG("%s bulk write status: %d", hdev->name, urb->status);	clear_bit(HCI_TX_WRITE, &husb->tx_state);	kfree_skb(skb);	/* Wake up device */	hci_usb_write_wakeup(husb);	return;}static void hci_usb_intr(struct urb *urb){	struct hci_usb *husb = (struct hci_usb *) urb->context;	unsigned char *data = urb->transfer_buffer;	register int count  = urb->actual_length;	register struct sk_buff *skb = husb->intr_skb;	hci_event_hdr *eh;	register int len;	if (!husb)		return;	DBG("%s count %d", husb->hdev.name, count);	if (urb->status || !count) {		DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);		return;	}	/* Do we really have to handle continuations here ? */	if (!skb) {		/* New frame */		if (count < HCI_EVENT_HDR_SIZE) {			DBG("%s bad frame len %d", husb->hdev.name, count);			return;		}		eh = (hci_event_hdr *) data;		len = eh->plen + HCI_EVENT_HDR_SIZE;		if (count > len) {			DBG("%s corrupted frame, len %d", husb->hdev.name, count);			return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -