[PATCH 4/8] Bluetooth: Add support for user data in hci_request

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

 



This patch makes possible to store some user data in hci_request struct
which will be available in completion callback. Data can be added when
initializing new request using hci_req_init(). With this it's now easy
to run request which can be associated with e.g. specific hci_conn.

Signed-off-by: Andrzej Kaczmarek <andrzej.kaczmarek@xxxxxxxxx>
---
 include/net/bluetooth/bluetooth.h |  3 +-
 include/net/bluetooth/hci_core.h  |  3 +-
 net/bluetooth/hci_conn.c          |  4 +-
 net/bluetooth/hci_core.c          | 29 +++++++++-----
 net/bluetooth/mgmt.c              | 84 +++++++++++++++++++++------------------
 5 files changed, 69 insertions(+), 54 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 904777c1..28378ad 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -273,12 +273,13 @@ struct l2cap_ctrl {
 
 struct hci_dev;
 
-typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
+typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, void *data);
 
 struct hci_req_ctrl {
 	bool			start;
 	u8			event;
 	hci_req_complete_t	complete;
+	void			*data;
 };
 
 struct bt_skb_cb {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 211bad6..30d245f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1162,6 +1162,7 @@ int hci_unregister_cb(struct hci_cb *hcb);
 struct hci_request {
 	struct hci_dev		*hdev;
 	struct sk_buff_head	cmd_q;
+	void			*data;
 
 	/* If something goes wrong when building the HCI request, the error
 	 * value is stored in this field.
@@ -1169,7 +1170,7 @@ struct hci_request {
 	int			err;
 };
 
-void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
+void hci_req_init(struct hci_request *req, struct hci_dev *hdev, void *data);
 int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
 void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
 		 const void *param);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 74b368b..78cfe3b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -571,7 +571,7 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 	mgmt_reenable_advertising(hdev);
 }
 
-static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
+static void create_le_conn_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	struct hci_conn *conn;
 
@@ -728,7 +728,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	conn->pending_sec_level = sec_level;
 	conn->auth_type = auth_type;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) {
 		hci_req_directed_advertising(&req, conn);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d31f144..f5dcbb1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1020,7 +1020,7 @@ static const struct file_operations le_auto_conn_fops = {
 
 /* ---- HCI requests ---- */
 
-static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
+static void hci_req_sync_complete(struct hci_dev *hdev, u8 result, void *data)
 {
 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
 
@@ -1106,7 +1106,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
 
 	BT_DBG("%s", hdev->name);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	hci_req_add_ev(&req, opcode, plen, param, event);
 
@@ -1170,7 +1170,7 @@ static int __hci_req_sync(struct hci_dev *hdev,
 
 	BT_DBG("%s start", hdev->name);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	hdev->req_status = HCI_REQ_PEND;
 
@@ -3573,7 +3573,7 @@ void hci_pend_le_conns_clear(struct hci_dev *hdev)
 	BT_DBG("All LE pending connections cleared");
 }
 
-static void inquiry_complete(struct hci_dev *hdev, u8 status)
+static void inquiry_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	if (status) {
 		BT_ERR("Failed to start inquiry: status %d", status);
@@ -3585,7 +3585,8 @@ static void inquiry_complete(struct hci_dev *hdev, u8 status)
 	}
 }
 
-static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
+static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status,
+					  void *data)
 {
 	/* General inquiry access code (GIAC) */
 	u8 lap[3] = { 0x33, 0x8b, 0x9e };
@@ -3606,7 +3607,7 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
 		break;
 
 	case DISCOV_TYPE_INTERLEAVED:
-		hci_req_init(&req, hdev);
+		hci_req_init(&req, hdev, NULL);
 
 		memset(&cp, 0, sizeof(cp));
 		memcpy(&cp.lap, lap, sizeof(cp.lap));
@@ -3637,7 +3638,7 @@ static void le_scan_disable_work(struct work_struct *work)
 
 	BT_DBG("%s", hdev->name);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	hci_req_add_le_scan_disable(&req);
 
@@ -4263,10 +4264,11 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 		BT_ERR("%s sending frame failed", hdev->name);
 }
 
-void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
+void hci_req_init(struct hci_request *req, struct hci_dev *hdev, void *data)
 {
 	skb_queue_head_init(&req->cmd_q);
 	req->hdev = hdev;
+	req->data = data;
 	req->err = 0;
 }
 
@@ -4292,6 +4294,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
 
 	skb = skb_peek_tail(&req->cmd_q);
 	bt_cb(skb)->req.complete = complete;
+	bt_cb(skb)->req.data = req->data;
 
 	spin_lock_irqsave(&hdev->cmd_q.lock, flags);
 	skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
@@ -5083,6 +5086,7 @@ static void hci_resend_last(struct hci_dev *hdev)
 void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
 {
 	hci_req_complete_t req_complete = NULL;
+	void *req_data = NULL;
 	struct sk_buff *skb;
 	unsigned long flags;
 
@@ -5116,6 +5120,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
 	 */
 	if (hdev->sent_cmd) {
 		req_complete = bt_cb(hdev->sent_cmd)->req.complete;
+		req_data = bt_cb(hdev->sent_cmd)->req.data;
 
 		if (req_complete) {
 			/* We must set the complete callback to NULL to
@@ -5137,13 +5142,14 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
 		}
 
 		req_complete = bt_cb(skb)->req.complete;
+		req_data = bt_cb(skb)->req.data;
 		kfree_skb(skb);
 	}
 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
 
 call_complete:
 	if (req_complete)
-		req_complete(hdev, status);
+		req_complete(hdev, status, req_data);
 }
 
 static void hci_rx_work(struct work_struct *work)
@@ -5273,7 +5279,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
 		    &enable_cp);
 }
 
-static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
+static void update_background_scan_complete(struct hci_dev *hdev, u8 status,
+					    void *data)
 {
 	if (status)
 		BT_DBG("HCI request failed to update background scanning: "
@@ -5292,7 +5299,7 @@ void hci_update_background_scan(struct hci_dev *hdev)
 	struct hci_conn *conn;
 	int err;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (list_empty(&hdev->pend_le_conns)) {
 		/* If there is no pending LE connections, we should stop
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 840b273..bb3188f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -896,7 +896,7 @@ static void service_cache_off(struct work_struct *work)
 	if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
 		return;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	hci_dev_lock(hdev);
 
@@ -926,7 +926,7 @@ static void rpa_expired(struct work_struct *work)
 	 * controller happens in the enable_advertising() function.
 	 */
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	disable_advertising(&req);
 	enable_advertising(&req);
@@ -1046,7 +1046,7 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
 			    sizeof(settings));
 }
 
-static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
+static void clean_up_hci_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	BT_DBG("%s status 0x%02x", hdev->name, status);
 
@@ -1061,7 +1061,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
 	struct hci_request req;
 	struct hci_conn *conn;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_bit(HCI_ISCAN, &hdev->flags) ||
 	    test_bit(HCI_PSCAN, &hdev->flags)) {
@@ -1266,7 +1266,8 @@ static u8 mgmt_le_support(struct hci_dev *hdev)
 		return MGMT_STATUS_SUCCESS;
 }
 
-static void set_discoverable_complete(struct hci_dev *hdev, u8 status)
+static void set_discoverable_complete(struct hci_dev *hdev, u8 status,
+				      void *data)
 {
 	struct pending_cmd *cmd;
 	struct mgmt_mode *cp;
@@ -1312,7 +1313,7 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status)
 	 * that class of device has the limited discoverable
 	 * bit correctly set.
 	 */
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 	update_class(&req);
 	hci_req_run(&req, NULL);
 
@@ -1436,7 +1437,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 	else
 		clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	/* The procedure for LE-only controllers is much simpler - just
 	 * update the advertising data.
@@ -1523,7 +1524,8 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
 		hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
 }
 
-static void set_connectable_complete(struct hci_dev *hdev, u8 status)
+static void set_connectable_complete(struct hci_dev *hdev, u8 status,
+				     void *data)
 {
 	struct pending_cmd *cmd;
 	struct mgmt_mode *cp;
@@ -1627,7 +1629,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
 		goto failed;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	/* If BR/EDR is not enabled and we disable advertising as a
 	 * by-product of disabling connectable, we need to update the
@@ -1913,7 +1915,7 @@ unlock:
 	return err;
 }
 
-static void le_enable_complete(struct hci_dev *hdev, u8 status)
+static void le_enable_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	struct cmd_lookup match = { NULL, hdev };
 
@@ -1942,7 +1944,7 @@ static void le_enable_complete(struct hci_dev *hdev, u8 status)
 
 		hci_dev_lock(hdev);
 
-		hci_req_init(&req, hdev);
+		hci_req_init(&req, hdev, NULL);
 		update_adv_data(&req);
 		update_scan_rsp_data(&req);
 		hci_req_run(&req, NULL);
@@ -2016,7 +2018,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 		goto unlock;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	memset(&hci_cp, 0, sizeof(hci_cp));
 
@@ -2101,7 +2103,7 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
-static void add_uuid_complete(struct hci_dev *hdev, u8 status)
+static void add_uuid_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	BT_DBG("status 0x%02x", status);
 
@@ -2138,7 +2140,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 
 	list_add_tail(&uuid->list, &hdev->uuids);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	update_class(&req);
 	update_eir(&req);
@@ -2180,7 +2182,7 @@ static bool enable_service_cache(struct hci_dev *hdev)
 	return false;
 }
 
-static void remove_uuid_complete(struct hci_dev *hdev, u8 status)
+static void remove_uuid_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	BT_DBG("status 0x%02x", status);
 
@@ -2237,7 +2239,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
 	}
 
 update_class:
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	update_class(&req);
 	update_eir(&req);
@@ -2265,7 +2267,7 @@ unlock:
 	return err;
 }
 
-static void set_class_complete(struct hci_dev *hdev, u8 status)
+static void set_class_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	BT_DBG("status 0x%02x", status);
 
@@ -2309,7 +2311,7 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
 		goto unlock;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
 		hci_dev_unlock(hdev);
@@ -3119,7 +3121,7 @@ static void update_name(struct hci_request *req)
 	hci_req_add(req, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
 }
 
-static void set_name_complete(struct hci_dev *hdev, u8 status)
+static void set_name_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	struct mgmt_cp_set_local_name *cp;
 	struct pending_cmd *cmd;
@@ -3194,7 +3196,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	memcpy(hdev->dev_name, cp->name, sizeof(hdev->dev_name));
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (lmp_bredr_capable(hdev)) {
 		update_name(&req);
@@ -3357,7 +3359,8 @@ static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
 	return err;
 }
 
-static void start_discovery_complete(struct hci_dev *hdev, u8 status)
+static void start_discovery_complete(struct hci_dev *hdev, u8 status,
+				     void *data)
 {
 	unsigned long timeout = 0;
 
@@ -3440,7 +3443,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 
 	hdev->discovery.type = cp->type;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	switch (hdev->discovery.type) {
 	case DISCOV_TYPE_BREDR:
@@ -3561,7 +3564,8 @@ static int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
 	return err;
 }
 
-static void stop_discovery_complete(struct hci_dev *hdev, u8 status)
+static void stop_discovery_complete(struct hci_dev *hdev, u8 status,
+				    void *data)
 {
 	BT_DBG("status %d", status);
 
@@ -3612,7 +3616,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
 		goto unlock;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	switch (hdev->discovery.state) {
 	case DISCOVERY_FINDING:
@@ -3793,7 +3797,7 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_ID, 0, NULL, 0);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 	update_eir(&req);
 	hci_req_run(&req, NULL);
 
@@ -3802,7 +3806,8 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
 	return err;
 }
 
-static void set_advertising_complete(struct hci_dev *hdev, u8 status)
+static void set_advertising_complete(struct hci_dev *hdev, u8 status,
+				     void *data)
 {
 	struct cmd_lookup match = { NULL, hdev };
 
@@ -3885,7 +3890,7 @@ static int set_advertising(struct sock *sk, struct hci_dev *hdev, void *data,
 		goto unlock;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (val)
 		enable_advertising(&req);
@@ -3984,7 +3989,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
 	    hdev->discovery.state == DISCOVERY_STOPPED) {
 		struct hci_request req;
 
-		hci_req_init(&req, hdev);
+		hci_req_init(&req, hdev, NULL);
 
 		hci_req_add_le_scan_disable(&req);
 		hci_req_add_le_passive_scan(&req);
@@ -3997,7 +4002,8 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
-static void fast_connectable_complete(struct hci_dev *hdev, u8 status)
+static void fast_connectable_complete(struct hci_dev *hdev, u8 status,
+				      void *data)
 {
 	struct pending_cmd *cmd;
 
@@ -4078,7 +4084,7 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
 		goto unlock;
 	}
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	write_fast_connectable(&req, cp->val);
 
@@ -4115,7 +4121,7 @@ static void set_bredr_scan(struct hci_request *req)
 		hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 }
 
-static void set_bredr_complete(struct hci_dev *hdev, u8 status)
+static void set_bredr_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	struct pending_cmd *cmd;
 
@@ -4218,7 +4224,7 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
 	 */
 	set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
 		set_bredr_scan(&req);
@@ -4750,7 +4756,7 @@ static void restart_le_auto_conns(struct hci_dev *hdev)
 	}
 }
 
-static void powered_complete(struct hci_dev *hdev, u8 status)
+static void powered_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	struct cmd_lookup match = { NULL, hdev };
 
@@ -4775,7 +4781,7 @@ static int powered_update_hci(struct hci_dev *hdev)
 	struct hci_request req;
 	u8 link_sec;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
 	    !lmp_host_ssp_capable(hdev)) {
@@ -4898,7 +4904,7 @@ void mgmt_discoverable_timeout(struct hci_dev *hdev)
 	clear_bit(HCI_LIMITED_DISCOVERABLE, &hdev->dev_flags);
 	clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 	if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
 		u8 scan = SCAN_PAGE;
 		hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE,
@@ -4944,7 +4950,7 @@ void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
 		 * a disabling of connectable there could be a need to
 		 * update the advertising flags.
 		 */
-		hci_req_init(&req, hdev);
+		hci_req_init(&req, hdev, NULL);
 		update_adv_data(&req);
 		hci_req_run(&req, NULL);
 
@@ -5521,7 +5527,7 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
 	if (match.sk)
 		sock_put(match.sk);
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 
 	if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
 		update_eir(&req);
@@ -5799,7 +5805,7 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
 			  cmd ? cmd->sk : NULL);
 }
 
-static void adv_enable_complete(struct hci_dev *hdev, u8 status)
+static void adv_enable_complete(struct hci_dev *hdev, u8 status, void *data)
 {
 	BT_DBG("%s status %u", hdev->name, status);
 
@@ -5820,7 +5826,7 @@ void mgmt_reenable_advertising(struct hci_dev *hdev)
 	if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
 		return;
 
-	hci_req_init(&req, hdev);
+	hci_req_init(&req, hdev, NULL);
 	enable_advertising(&req);
 
 	/* If this fails we have no option but to let user space know
-- 
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux