Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netbt upon device initialisation, query and cache the de...



details:   https://anonhg.NetBSD.org/src/rev/0dcba6fbdd44
branches:  trunk
changeset: 758964:0dcba6fbdd44
user:      plunky <plunky%NetBSD.org@localhost>
date:      Mon Nov 22 19:56:51 2010 +0000

description:
upon device initialisation, query and cache the device features,
and cache the maximum ACL/SCO packet buffers.

provide an additional SIOCGBTFEAT ioctl to retrieve the cached
features, and add the max values to the SIOC?BTINFO results.

(btreq does not change size)

diffstat:

 sys/netbt/hci.h       |  20 +++++++++++-
 sys/netbt/hci_event.c |  81 +++++++++++++++++++++++++++++++++++++++++++++++---
 sys/netbt/hci_ioctl.c |  14 +++++++-
 3 files changed, 105 insertions(+), 10 deletions(-)

diffs (269 lines):

diff -r eff0c6d41a53 -r 0dcba6fbdd44 sys/netbt/hci.h
--- a/sys/netbt/hci.h   Mon Nov 22 15:42:22 2010 +0000
+++ b/sys/netbt/hci.h   Mon Nov 22 19:56:51 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hci.h,v 1.33 2009/09/11 18:35:50 plunky Exp $  */
+/*     $NetBSD: hci.h,v 1.34 2010/11/22 19:56:51 plunky Exp $  */
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -54,7 +54,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: hci.h,v 1.33 2009/09/11 18:35:50 plunky Exp $
+ * $Id: hci.h,v 1.34 2010/11/22 19:56:51 plunky Exp $
  * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_hci.h,v 1.6 2005/01/07 01:45:43 imp Exp $
  */
 
@@ -2297,6 +2297,8 @@
 #define SIOCBTDUMP      _IOW('b', 13, struct btreq) /* print debug info */
 #define SIOCSBTSCOMTU  _IOWR('b', 17, struct btreq) /* set sco_mtu value */
 
+#define SIOCGBTFEAT    _IOWR('b', 18, struct btreq) /* get unit features */
+
 struct bt_stats {
        uint32_t        err_tx;
        uint32_t        err_rx;
@@ -2324,7 +2326,13 @@
                uint16_t btri_sco_mtu;          /* SCO mtu */
                uint16_t btri_link_policy;      /* Link Policy */
                uint16_t btri_packet_type;      /* Packet Type */
+               uint16_t btri_max_acl;          /* max ACL buffers */
+               uint16_t btri_max_sco;          /* max SCO buffers */
            } btri;
+           struct {
+               uint8_t btrf_page0[HCI_FEATURES_SIZE];  /* basic */
+               uint8_t btrf_page1[HCI_FEATURES_SIZE];  /* extended */
+           } btrf;
            struct bt_stats btrs;   /* unit stats */
        } btru;
 };
@@ -2338,6 +2346,10 @@
 #define btr_sco_mtu    btru.btri.btri_sco_mtu
 #define btr_link_policy btru.btri.btri_link_policy
 #define btr_packet_type btru.btri.btri_packet_type
+#define btr_max_acl    btru.btri.btri_max_acl
+#define btr_max_sco    btru.btri.btri_max_sco
+#define btr_features0  btru.btrf.btrf_page0
+#define btr_features1  btru.btrf.btrf_page1
 #define btr_stats      btru.btrs
 
 /* hci_unit & btr_flags */
@@ -2481,14 +2493,18 @@
        uint16_t         hci_link_policy;       /* link policy */
        uint16_t         hci_lmp_mask;          /* link policy capabilities */
 
+       uint8_t          hci_feat0[HCI_FEATURES_SIZE]; /* features mask */
+       uint8_t          hci_feat1[HCI_FEATURES_SIZE]; /* extended */
        uint8_t          hci_cmds[HCI_COMMANDS_SIZE]; /* opcode bitmask */
 
        /* flow control */
        uint16_t         hci_max_acl_size;      /* ACL payload mtu */
        uint16_t         hci_num_acl_pkts;      /* free ACL packet buffers */
+       uint16_t         hci_max_acl_pkts;      /* max ACL packet buffers */
        uint8_t          hci_num_cmd_pkts;      /* free CMD packet buffers */
        uint8_t          hci_max_sco_size;      /* SCO payload mtu */
        uint16_t         hci_num_sco_pkts;      /* free SCO packet buffers */
+       uint16_t         hci_max_sco_pkts;      /* max SCO packet buffers */
 
        TAILQ_HEAD(,hci_link)   hci_links;      /* list of ACL/SCO links */
        LIST_HEAD(,hci_memo)    hci_memos;      /* cached memo list */
diff -r eff0c6d41a53 -r 0dcba6fbdd44 sys/netbt/hci_event.c
--- a/sys/netbt/hci_event.c     Mon Nov 22 15:42:22 2010 +0000
+++ b/sys/netbt/hci_event.c     Mon Nov 22 19:56:51 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hci_event.c,v 1.21 2009/09/12 18:31:46 plunky Exp $    */
+/*     $NetBSD: hci_event.c,v 1.22 2010/11/22 19:56:51 plunky Exp $    */
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.21 2009/09/12 18:31:46 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.22 2010/11/22 19:56:51 plunky Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -60,6 +60,7 @@
 static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *);
 static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *);
 static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *);
+static void hci_cmd_read_local_extended_features(struct hci_unit *, struct mbuf *);
 static void hci_cmd_read_local_ver(struct hci_unit *, struct mbuf *);
 static void hci_cmd_read_local_commands(struct hci_unit *, struct mbuf *);
 static void hci_cmd_reset(struct hci_unit *, struct mbuf *);
@@ -330,6 +331,10 @@
                hci_cmd_read_local_features(unit, m);
                break;
 
+       case HCI_CMD_READ_LOCAL_EXTENDED_FEATURES:
+               hci_cmd_read_local_extended_features(unit, m);
+               break;
+
        case HCI_CMD_READ_LOCAL_VER:
                hci_cmd_read_local_ver(unit, m);
                break;
@@ -897,8 +902,10 @@
 
        unit->hci_max_acl_size = le16toh(rp.max_acl_size);
        unit->hci_num_acl_pkts = le16toh(rp.num_acl_pkts);
+       unit->hci_max_acl_pkts = le16toh(rp.num_acl_pkts);
        unit->hci_max_sco_size = rp.max_sco_size;
        unit->hci_num_sco_pkts = le16toh(rp.num_sco_pkts);
+       unit->hci_max_sco_pkts = le16toh(rp.num_sco_pkts);
 
        unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE;
 
@@ -923,6 +930,8 @@
        if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
                return;
 
+       memcpy(unit->hci_feat0, rp.features, HCI_FEATURES_SIZE);
+
        unit->hci_lmp_mask = 0;
 
        if (rp.features[0] & HCI_LMP_ROLE_SWITCH)
@@ -937,6 +946,9 @@
        if (rp.features[1] & HCI_LMP_PARK_MODE)
                unit->hci_lmp_mask |= HCI_LINK_POLICY_ENABLE_PARK_MODE;
 
+       DPRINTFN(1, "%s: lmp_mask %4.4x\n",
+               device_xname(unit->hci_dev), unit->hci_lmp_mask);
+
        /* ACL packet mask */
        unit->hci_acl_mask = HCI_PKT_DM1 | HCI_PKT_DH1;
 
@@ -964,6 +976,9 @@
                unit->hci_acl_mask |= HCI_PKT_2MBPS_DH5
                                    | HCI_PKT_3MBPS_DH5;
 
+       DPRINTFN(1, "%s: acl_mask %4.4x\n",
+               device_xname(unit->hci_dev), unit->hci_acl_mask);
+
        unit->hci_packet_type = unit->hci_acl_mask;
 
        /* SCO packet mask */
@@ -988,13 +1003,67 @@
 
        /* XXX what do 2MBPS/3MBPS/3SLOT eSCO mean? */
 
-       unit->hci_flags &= ~BTF_INIT_FEATURES;
+       DPRINTFN(1, "%s: sco_mask %4.4x\n",
+               device_xname(unit->hci_dev), unit->hci_sco_mask);
+
+       /* extended feature masks */
+       if (rp.features[7] & HCI_LMP_EXTENDED_FEATURES) {
+               hci_read_local_extended_features_cp cp;
+
+               cp.page = 0;
+               hci_send_cmd(unit, HCI_CMD_READ_LOCAL_EXTENDED_FEATURES,
+                   &cp, sizeof(cp));
+
+               return;
+       }
 
+       unit->hci_flags &= ~BTF_INIT_FEATURES;
        cv_broadcast(&unit->hci_init);
+}
+
+/*
+ * process results of read_local_extended_features command_complete event
+ */
+static void
+hci_cmd_read_local_extended_features(struct hci_unit *unit, struct mbuf *m)
+{
+       hci_read_local_extended_features_rp rp;
+
+       KASSERT(m->m_pkthdr.len >= sizeof(rp));
+       m_copydata(m, 0, sizeof(rp), &rp);
+       m_adj(m, sizeof(rp));
 
-       DPRINTFN(1, "%s: lmp_mask %4.4x, acl_mask %4.4x, sco_mask %4.4x\n",
-               device_xname(unit->hci_dev), unit->hci_lmp_mask,
-               unit->hci_acl_mask, unit->hci_sco_mask);
+       if (rp.status > 0)
+               return;
+
+       if ((unit->hci_flags & BTF_INIT_FEATURES) == 0)
+               return;
+
+       DPRINTFN(1, "%s: page %d of %d\n", device_xname(unit->hci_dev),
+           rp.page, rp.max_page);
+
+       switch (rp.page) {
+       case 1:
+               memcpy(unit->hci_feat1, rp.features, HCI_FEATURES_SIZE);
+               break;
+
+       case 0: /* (already handled) */
+       default: 
+               break;
+       }
+
+       if (rp.page < rp.max_page) {
+               hci_read_local_extended_features_cp cp;
+
+               cp.page = rp.page + 1;
+               hci_send_cmd(unit, HCI_CMD_READ_LOCAL_EXTENDED_FEATURES,
+                   &cp, sizeof(cp));
+
+               return;
+       }
+
+       unit->hci_flags &= ~BTF_INIT_FEATURES;
+       cv_broadcast(&unit->hci_init);
 }
 
 /*
diff -r eff0c6d41a53 -r 0dcba6fbdd44 sys/netbt/hci_ioctl.c
--- a/sys/netbt/hci_ioctl.c     Mon Nov 22 15:42:22 2010 +0000
+++ b/sys/netbt/hci_ioctl.c     Mon Nov 22 19:56:51 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: hci_ioctl.c,v 1.9 2009/08/20 21:40:59 plunky Exp $     */
+/*     $NetBSD: hci_ioctl.c,v 1.10 2010/11/22 19:56:51 plunky Exp $    */
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_ioctl.c,v 1.9 2009/08/20 21:40:59 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_ioctl.c,v 1.10 2010/11/22 19:56:51 plunky Exp $");
 
 #include <sys/param.h>
 #include <sys/domain.h>
@@ -175,6 +175,7 @@
        case SIOCGBTSTATS:
        case SIOCZBTSTATS:
        case SIOCSBTSCOMTU:
+       case SIOCGBTFEAT:
                SIMPLEQ_FOREACH(unit, &hci_unit_list, hci_next) {
                        if (strncmp(device_xname(unit->hci_dev),
                            btr->btr_name, HCI_DEVNAME_SIZE) == 0)
@@ -216,6 +217,8 @@
                btr->btr_num_sco = unit->hci_num_sco_pkts;
                btr->btr_acl_mtu = unit->hci_max_acl_size;
                btr->btr_sco_mtu = unit->hci_max_sco_size;
+               btr->btr_max_acl = unit->hci_max_acl_pkts;
+               btr->btr_max_sco = unit->hci_max_sco_pkts;
 
                btr->btr_packet_type = unit->hci_packet_type;
                btr->btr_link_policy = unit->hci_link_policy;
@@ -303,6 +306,13 @@
                unit->hci_max_sco_size = btr->btr_sco_mtu;
                break;
 
+       case SIOCGBTFEAT:       /* get unit features */
+               memset(btr, 0, sizeof(struct btreq));
+               strlcpy(btr->btr_name, device_xname(unit->hci_dev), HCI_DEVNAME_SIZE);
+               memcpy(btr->btr_features0, unit->hci_feat0, HCI_FEATURES_SIZE);
+               memcpy(btr->btr_features1, unit->hci_feat1, HCI_FEATURES_SIZE);
+               break;
+
        default:
                err = EFAULT;
                break;



Home | Main Index | Thread Index | Old Index