From: Marcel Holtmann <marcel@rvs.uni-bielefeld.de>
To: BlueZ Mailing List <bluez-devel@lists.sourceforge.net>
Subject: [Bluez-devel] HCI USB driver and SCO support
Date: 02 Aug 2003 03:20:45 +0200 [thread overview]
Message-ID: <1059787251.22190.17.camel@pegasus> (raw)
[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]
Hi Max,
the patch from Jonathan Paisley is working fine. I have tested it on
2.4.18 to 2.4.21 and we can safely use two ISOC TX and RX URB's by
default. But the configuration of the ISOC endpoint must be adjusted on
demand. It depends on the voice setting and number of SCO connections,
otherwise you won't hear any sound. At the moment we don't have access
to these information from within the driver, so I started to extend the
HCI core.
The first patch introduces hdev->notify and reads the voice setting on
device init and stores them in hdev->voice_setting for later use. With
these modification a driver can be notified about added or deleted
connections (ACL + SCO) and if the voice setting was changed.
The second patch is for the HCI USB driver and it shows how to use
hdev->notify. It also contains Jonathans modifications to use two ISOC
TX and RX URB's and it keeps track of the number of ACL and SCO
connections.
In the next step, we must choose the correct ISOC configuration. The
default one should be 0, because we don't use any SCO channel. It is
also a good idea to start the ISOC and BULK transfers only if they are
needed.
Comments?
Regards
Marcel
[-- Attachment #2: patch-2.4.22-pre10-hci-notify --]
[-- Type: text/x-patch, Size: 5886 bytes --]
diff -urN linux-2.4.22-pre10/include/net/bluetooth/hci.h linux-2.4.22-pre10-notify/include/net/bluetooth/hci.h
--- linux-2.4.22-pre10/include/net/bluetooth/hci.h Sat Aug 2 02:33:57 2003
+++ linux-2.4.22-pre10-notify/include/net/bluetooth/hci.h Sat Aug 2 02:34:37 2003
@@ -42,6 +42,11 @@
#define HCI_DEV_SUSPEND 5
#define HCI_DEV_RESUME 6
+/* HCI notify events */
+#define HCI_CONN_ADD 1
+#define HCI_CONN_DEL 2
+#define HCI_VOICE_SETTING 3
+
/* HCI device types */
#define HCI_VHCI 0
#define HCI_USB 1
@@ -269,6 +274,19 @@
__u8 dev_class[3];
} __attribute__ ((packed)) write_class_of_dev_cp;
#define WRITE_CLASS_OF_DEV_CP_SIZE 3
+
+#define OCF_READ_VOICE_SETTING 0x0025
+typedef struct {
+ __u8 status;
+ __u16 voice_setting;
+} __attribute__ ((packed)) read_voice_setting_rp;
+#define READ_VOICE_SETTING_RP_SIZE 3
+
+#define OCF_WRITE_VOICE_SETTING 0x0026
+typedef struct {
+ __u16 voice_setting;
+} __attribute__ ((packed)) write_voice_setting_cp;
+#define WRITE_VOICE_SETTING_CP_SIZE 2
#define OCF_HOST_BUFFER_SIZE 0x0033
typedef struct {
diff -urN linux-2.4.22-pre10/include/net/bluetooth/hci_core.h linux-2.4.22-pre10-notify/include/net/bluetooth/hci_core.h
--- linux-2.4.22-pre10/include/net/bluetooth/hci_core.h Fri Jun 13 16:51:39 2003
+++ linux-2.4.22-pre10-notify/include/net/bluetooth/hci_core.h Sat Aug 2 02:34:37 2003
@@ -68,11 +68,12 @@
__u8 type;
bdaddr_t bdaddr;
__u8 features[8];
+ __u16 voice_setting;
__u16 pkt_type;
__u16 link_policy;
__u16 link_mode;
-
+
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
@@ -116,6 +117,7 @@
int (*flush)(struct hci_dev *hdev);
int (*send)(struct sk_buff *skb);
void (*destruct)(struct hci_dev *hdev);
+ void (*notify)(struct hci_dev *hdev, unsigned int evt, unsigned long arg);
int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
};
diff -urN linux-2.4.22-pre10/net/bluetooth/af_bluetooth.c linux-2.4.22-pre10-notify/net/bluetooth/af_bluetooth.c
--- linux-2.4.22-pre10/net/bluetooth/af_bluetooth.c Sat Aug 2 02:33:57 2003
+++ linux-2.4.22-pre10-notify/net/bluetooth/af_bluetooth.c Sat Aug 2 02:35:01 2003
@@ -27,7 +27,7 @@
*
* $Id: af_bluetooth.c,v 1.8 2002/07/22 20:32:54 maxk Exp $
*/
-#define VERSION "2.3"
+#define VERSION "2.4"
#include <linux/config.h>
#include <linux/module.h>
diff -urN linux-2.4.22-pre10/net/bluetooth/hci_conn.c linux-2.4.22-pre10-notify/net/bluetooth/hci_conn.c
--- linux-2.4.22-pre10/net/bluetooth/hci_conn.c Fri Jun 13 16:51:39 2003
+++ linux-2.4.22-pre10-notify/net/bluetooth/hci_conn.c Sat Aug 2 02:34:37 2003
@@ -168,6 +168,9 @@
hci_dev_hold(hdev);
+ if (hdev->notify)
+ hdev->notify(hdev, HCI_CONN_ADD, (unsigned long) conn);
+
tasklet_disable(&hdev->tx_task);
conn_hash_add(hdev, conn);
tasklet_enable(&hdev->tx_task);
@@ -203,6 +206,9 @@
tasklet_enable(&hdev->tx_task);
skb_queue_purge(&conn->data_q);
+
+ if (hdev->notify)
+ hdev->notify(hdev, HCI_CONN_DEL, (unsigned long) conn);
hci_dev_put(hdev);
diff -urN linux-2.4.22-pre10/net/bluetooth/hci_core.c linux-2.4.22-pre10-notify/net/bluetooth/hci_core.c
--- linux-2.4.22-pre10/net/bluetooth/hci_core.c Sat Aug 2 02:33:57 2003
+++ linux-2.4.22-pre10-notify/net/bluetooth/hci_core.c Sat Aug 2 02:34:37 2003
@@ -240,6 +240,9 @@
/* Read BD Address */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
+ /* Read Voice Setting */
+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
+
/* Optional initialization */
/* Clear Event Filters */
diff -urN linux-2.4.22-pre10/net/bluetooth/hci_event.c linux-2.4.22-pre10-notify/net/bluetooth/hci_event.c
--- linux-2.4.22-pre10/net/bluetooth/hci_event.c Sat Aug 2 02:33:57 2003
+++ linux-2.4.22-pre10-notify/net/bluetooth/hci_event.c Sat Aug 2 02:34:37 2003
@@ -123,6 +123,8 @@
static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{
__u8 status, param;
+ __u16 setting;
+ read_voice_setting_rp *vs;
void *sent;
BT_DBG("%s ocf 0x%x", hdev->name, ocf);
@@ -198,6 +200,7 @@
sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
if (!sent)
break;
+
status = *((__u8 *) skb->data);
param = *((__u8 *) sent);
@@ -215,6 +218,46 @@
hci_req_complete(hdev, status);
break;
+ case OCF_READ_VOICE_SETTING:
+ vs = (read_voice_setting_rp *) skb->data;
+
+ if (vs->status) {
+ BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vc->status);
+ break;
+ }
+
+ setting = __le16_to_cpu(vs->voice_setting);
+
+ if (hdev->voice_setting != setting ) {
+ hdev->voice_setting = setting;
+
+ BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+
+ if (hdev->notify)
+ hdev->notify(hdev, HCI_VOICE_SETTING, 0);
+ }
+
+ break;
+
+ case OCF_WRITE_VOICE_SETTING:
+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
+ if (!sent)
+ break;
+
+ status = *((__u8 *) skb->data);
+ setting = __le16_to_cpu(get_unaligned((__u16 *) sent));
+
+ if (!status && hdev->voice_setting != setting) {
+ hdev->voice_setting = setting;
+
+ BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+
+ if (hdev->notify)
+ hdev->notify(hdev, HCI_VOICE_SETTING, 0);
+ }
+ hci_req_complete(hdev, status);
+ break;
+
case OCF_HOST_BUFFER_SIZE:
status = *((__u8 *) skb->data);
if (status) {
@@ -282,7 +325,8 @@
hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
+ hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
+
break;
case OCF_READ_BD_ADDR:
[-- Attachment #3: patch-2.4.22-pre10-hci-usb --]
[-- Type: text/x-patch, Size: 3965 bytes --]
diff -urN linux-2.4.22-pre10/drivers/bluetooth/hci_usb.c linux-2.4.22-pre10-usb/drivers/bluetooth/hci_usb.c
--- linux-2.4.22-pre10/drivers/bluetooth/hci_usb.c Sat Aug 2 02:33:45 2003
+++ linux-2.4.22-pre10-usb/drivers/bluetooth/hci_usb.c Sat Aug 2 02:54:11 2003
@@ -30,7 +30,7 @@
*
* $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $
*/
-#define VERSION "2.4"
+#define VERSION "2.5"
#include <linux/config.h>
#include <linux/module.h>
@@ -302,7 +302,8 @@
#ifdef CONFIG_BLUEZ_USB_SCO
if (husb->isoc_iface)
- hci_usb_isoc_rx_submit(husb);
+ for (i = 0; i < HCI_MAX_ISOC_RX; i++)
+ hci_usb_isoc_rx_submit(husb);
#endif
} else {
clear_bit(HCI_RUNNING, &hdev->flags);
@@ -522,7 +523,7 @@
#ifdef CONFIG_BLUEZ_USB_SCO
/* Process SCO queue */
q = __transmit_q(husb, HCI_SCODATA_PKT);
- if (!atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) &&
+ if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
(skb = skb_dequeue(q))) {
if (hci_usb_send_isoc(husb, skb) < 0)
skb_queue_head(q, skb);
@@ -769,6 +770,44 @@
kfree(husb);
}
+static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt, unsigned long arg)
+{
+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s cmd %d arg %ld", hdev->name, evt, arg);
+
+ switch (evt) {
+ case HCI_CONN_ADD:
+ conn = (struct hci_conn *) arg;
+
+ BT_DBG("%s add conn type %d", hdev->name, conn->type);
+
+ if (conn->type == ACL_LINK)
+ atomic_inc(&husb->acl_num_conn);
+ else
+ atomic_inc(&husb->sco_num_conn);
+
+ break;
+
+ case HCI_CONN_DEL:
+ conn = (struct hci_conn *) arg;
+
+ BT_DBG("%s del conn type %d", hdev->name, conn->type);
+
+ if (conn->type == ACL_LINK)
+ atomic_dec(&husb->acl_num_conn);
+ else
+ atomic_dec(&husb->sco_num_conn);
+
+ break;
+
+ case HCI_VOICE_SETTING:
+ BT_DBG("%s voice setting 0x%04x", hdev->name, hdev->voice_setting);
+ break;
+ }
+}
+
static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
@@ -901,11 +940,12 @@
hdev->type = HCI_USB;
hdev->driver_data = husb;
- hdev->open = hci_usb_open;
- hdev->close = hci_usb_close;
- hdev->flush = hci_usb_flush;
- hdev->send = hci_usb_send_frame;
+ hdev->open = hci_usb_open;
+ hdev->close = hci_usb_close;
+ hdev->flush = hci_usb_flush;
+ hdev->send = hci_usb_send_frame;
hdev->destruct = hci_usb_destruct;
+ hdev->notify = hci_usb_notify;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
diff -urN linux-2.4.22-pre10/drivers/bluetooth/hci_usb.h linux-2.4.22-pre10-usb/drivers/bluetooth/hci_usb.h
--- linux-2.4.22-pre10/drivers/bluetooth/hci_usb.h Fri Jun 13 16:51:32 2003
+++ linux-2.4.22-pre10-usb/drivers/bluetooth/hci_usb.h Sat Aug 2 02:41:19 2003
@@ -41,6 +41,9 @@
#define HCI_MAX_BULK_TX 4
#define HCI_MAX_BULK_RX 1
+#define HCI_MAX_ISOC_RX 2
+#define HCI_MAX_ISOC_TX 2
+
#define HCI_MAX_ISOC_FRAMES 10
struct _urb_queue {
@@ -120,13 +123,16 @@
struct usb_endpoint_descriptor *isoc_in_ep;
struct sk_buff_head transmit_q[4];
- struct sk_buff *reassembly[4]; // Reassembly buffers
+ struct sk_buff *reassembly[4]; /* Reassembly buffers */
rwlock_t completion_lock;
- atomic_t pending_tx[4]; // Number of pending requests
- struct _urb_queue pending_q[4]; // Pending requests
- struct _urb_queue completed_q[4]; // Completed requests
+ atomic_t pending_tx[4]; /* Number of pending requests */
+ struct _urb_queue pending_q[4]; /* Pending requests */
+ struct _urb_queue completed_q[4]; /* Completed requests */
+
+ atomic_t acl_num_conn; /* Number of ACL connections */
+ atomic_t sco_num_conn; /* Number of SCO connections */
};
/* States */
next reply other threads:[~2003-08-02 1:20 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-02 1:20 Marcel Holtmann [this message]
2003-08-02 9:19 ` [Bluez-devel] HCI USB driver and SCO support James Courtier-Dutton
2003-08-04 9:35 ` Marcel Holtmann
2003-08-05 17:48 ` Max Krasnyansky
2003-08-05 22:56 ` James Courtier-Dutton
2003-08-05 17:44 ` Max Krasnyansky
2003-08-05 22:17 ` Marcel Holtmann
2003-08-05 23:02 ` James Courtier-Dutton
2003-08-06 8:41 ` Marcel Holtmann
2003-08-06 10:23 ` James Courtier-Dutton
2003-08-06 11:07 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1059787251.22190.17.camel@pegasus \
--to=marcel@rvs.uni-bielefeld.de \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.