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