SOFTWARE IS DISCLAIMED.
*/
-/*
- * Bluetooth HCI Core.
- *
- * $Id: hci_core.c,v 1.6 2002/04/17 17:37:16 maxk Exp $
- */
+/* Bluetooth HCI core. */
#include <linux/config.h>
#include <linux/module.h>
#ifndef CONFIG_BT_HCI_CORE_DEBUG
#undef BT_DBG
-#define BT_DBG( A... )
+#define BT_DBG(D...)
#endif
static void hci_cmd_task(unsigned long arg);
read_unlock(&hci_dev_list_lock);
return hdev;
}
+EXPORT_SYMBOL(hci_dev_get);
/* ---- Inquiry support ---- */
void inquiry_cache_flush(struct hci_dev *hdev)
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
}
-int hci_inquiry(unsigned long arg)
+int hci_inquiry(void __user *arg)
{
+ __u8 __user *ptr = arg;
struct hci_inquiry_req ir;
struct hci_dev *hdev;
int err = 0, do_inquiry = 0, max_rsp;
long timeo;
- __u8 *buf, *ptr;
+ __u8 *buf;
- ptr = (void *) arg;
if (copy_from_user(&ir, ptr, sizeof(ir)))
return -EFAULT;
if (!copy_to_user(ptr, &ir, sizeof(ir))) {
ptr += sizeof(ir);
- if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
+ if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) *
ir.num_rsp))
err = -EFAULT;
} else
//__hci_request(hdev, hci_reset_req, 0, HZ);
ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-
+
clear_bit(HCI_INIT, &hdev->flags);
}
inquiry_cache_flush(hdev);
hci_conn_hash_flush(hdev);
hci_dev_unlock_bh(hdev);
-
+
hci_notify(hdev, HCI_DEV_DOWN);
if (hdev->flush)
{
struct hci_dev *hdev;
int err;
-
+
if (!(hdev = hci_dev_get(dev)))
return -ENODEV;
err = hci_dev_do_close(hdev);
return ret;
}
-int hci_dev_cmd(unsigned int cmd, unsigned long arg)
+int hci_dev_cmd(unsigned int cmd, void __user *arg)
{
struct hci_dev *hdev;
struct hci_dev_req dr;
int err = 0;
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+ if (copy_from_user(&dr, arg, sizeof(dr)))
return -EFAULT;
if (!(hdev = hci_dev_get(dr.dev_id)))
if (err)
break;
}
-
+
err = hci_request(hdev, hci_encrypt_req,
dr.dev_opt, HCI_INIT_TIMEOUT);
break;
-
+
case HCISETSCAN:
err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
break;
-
+
case HCISETPTYPE:
hdev->pkt_type = (__u16) dr.dev_opt;
break;
-
+
case HCISETLINKPOL:
hdev->link_policy = (__u16) dr.dev_opt;
break;
default:
err = -EINVAL;
break;
- }
+ }
hci_dev_put(hdev);
return err;
}
-int hci_get_dev_list(unsigned long arg)
+int hci_get_dev_list(void __user *arg)
{
struct hci_dev_list_req *dl;
struct hci_dev_req *dr;
int n = 0, size, err;
__u16 dev_num;
- if (get_user(dev_num, (__u16 *) arg))
+ if (get_user(dev_num, (__u16 __user *) arg))
return -EFAULT;
if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
dl->dev_num = n;
size = sizeof(*dl) + n * sizeof(*dr);
- err = copy_to_user((void *) arg, dl, size);
+ err = copy_to_user(arg, dl, size);
kfree(dl);
return err ? -EFAULT : 0;
}
-int hci_get_dev_info(unsigned long arg)
+int hci_get_dev_info(void __user *arg)
{
struct hci_dev *hdev;
struct hci_dev_info di;
int err = 0;
- if (copy_from_user(&di, (void *) arg, sizeof(di)))
+ if (copy_from_user(&di, arg, sizeof(di)))
return -EFAULT;
if (!(hdev = hci_dev_get(di.dev_id)))
memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
memcpy(&di.features, &hdev->features, sizeof(di.features));
- if (copy_to_user((void *) arg, &di, sizeof(di)))
+ if (copy_to_user(arg, &di, sizeof(di)))
err = -EFAULT;
hci_dev_put(hdev);
return hdev;
}
+EXPORT_SYMBOL(hci_alloc_dev);
/* Free HCI device */
void hci_free_dev(struct hci_dev *hdev)
/* will free via class release */
class_device_put(&hdev->class_dev);
}
+EXPORT_SYMBOL(hci_free_dev);
/* Register HCI device */
int hci_register_dev(struct hci_dev *hdev)
/* Find first available device id */
list_for_each(p, &hci_dev_list) {
- if (list_entry(p, struct hci_dev, list)->id != id)
+ if (list_entry(p, struct hci_dev, list)->id != id)
break;
head = p; id++;
}
atomic_set(&hdev->refcnt, 1);
spin_lock_init(&hdev->lock);
-
+
hdev->flags = 0;
hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
hdev->link_mode = (HCI_LM_ACCEPT);
memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
atomic_set(&hdev->promisc, 0);
-
+
write_unlock_bh(&hci_dev_list_lock);
hci_register_sysfs(hdev);
return id;
}
+EXPORT_SYMBOL(hci_register_dev);
/* Unregister HCI device */
int hci_unregister_dev(struct hci_dev *hdev)
__hci_dev_put(hdev);
return 0;
}
+EXPORT_SYMBOL(hci_unregister_dev);
/* Suspend HCI device */
int hci_suspend_dev(struct hci_dev *hdev)
hci_notify(hdev, HCI_DEV_SUSPEND);
return 0;
}
+EXPORT_SYMBOL(hci_suspend_dev);
/* Resume HCI device */
int hci_resume_dev(struct hci_dev *hdev)
{
hci_notify(hdev, HCI_DEV_RESUME);
return 0;
-}
+}
+EXPORT_SYMBOL(hci_resume_dev);
/* ---- Interface to upper protocols ---- */
return err;
}
+EXPORT_SYMBOL(hci_register_proto);
int hci_unregister_proto(struct hci_proto *hp)
{
return err;
}
+EXPORT_SYMBOL(hci_unregister_proto);
static int hci_send_frame(struct sk_buff *skb)
{
if (atomic_read(&hdev->promisc)) {
/* Time stamp */
- do_gettimeofday(&skb->stamp);
+ do_gettimeofday(&skb->stamp);
hci_send_to_sock(hdev, skb);
}
return 0;
}
+EXPORT_SYMBOL(hci_send_cmd);
/* Get data from the previously sent command */
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
if (!(list = skb_shinfo(skb)->frag_list)) {
/* Non fragmented */
BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-
+
skb_queue_tail(&conn->data_q, skb);
} else {
/* Fragmented */
skb->dev = (void *) hdev;
skb->pkt_type = HCI_ACLDATA_PKT;
hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
-
+
BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
__skb_queue_tail(&conn->data_q, skb);
spin_unlock_bh(&conn->data_q.lock);
}
-
+
hci_sched_tx(hdev);
return 0;
}
+EXPORT_SYMBOL(hci_send_acl);
/* Send SCO data */
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
hci_sched_tx(hdev);
return 0;
}
+EXPORT_SYMBOL(hci_send_sco);
/* ---- HCI TX task (outgoing data) ---- */
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *conn = NULL;
int num = 0, min = ~0;
- struct list_head *p;
+ struct list_head *p;
/* We don't have to lock device here. Connections are always
* added and removed with TX task disabled. */
static inline void hci_acl_tx_to(struct hci_dev *hdev)
{
struct hci_conn_hash *h = &hdev->conn_hash;
- struct list_head *p;
+ struct list_head *p;
struct hci_conn *c;
BT_ERR("%s ACL tx timeout", hdev->name);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, handle);
hci_dev_unlock(hdev);
-
+
if (conn) {
register struct hci_proto *hp;
BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1);
}
-
+
/* Send queued commands */
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
if (hdev->sent_cmd)