Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 37696
Collapse All | Expand All

(-)linux-2.6.0/CREDITS (+1 lines)
Lines 1395-1400 Link Here
1395
E: marcel@holtmann.org
1395
E: marcel@holtmann.org
1396
W: http://www.holtmann.org
1396
W: http://www.holtmann.org
1397
D: Author and maintainer of the various Bluetooth HCI drivers
1397
D: Author and maintainer of the various Bluetooth HCI drivers
1398
D: Author and maintainer of the CAPI message transport protocol driver
1398
D: Various other Bluetooth related patches, cleanups and fixes
1399
D: Various other Bluetooth related patches, cleanups and fixes
1399
S: Germany
1400
S: Germany
1400
1401
(-)linux-2.6.0/drivers/bluetooth/bcm203x.c (+309 lines)
Line 0 Link Here
1
/*
2
 *
3
 *  Broadcom Blutonium firmware driver
4
 *
5
 *  Copyright (C) 2003  Marcel Holtmann <marcel@holtmann.org>
6
 *
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *
22
 */
23
24
#include <linux/config.h>
25
#include <linux/module.h>
26
27
#include <linux/kernel.h>
28
#include <linux/init.h>
29
#include <linux/slab.h>
30
#include <linux/types.h>
31
#include <linux/errno.h>
32
#include <linux/timer.h>
33
34
#include <linux/device.h>
35
#include <linux/firmware.h>
36
37
#include <linux/usb.h>
38
39
#include <net/bluetooth/bluetooth.h>
40
41
#ifndef CONFIG_BT_HCIBCM203X_DEBUG
42
#undef  BT_DBG
43
#define BT_DBG(D...)
44
#endif
45
46
#define VERSION "1.0"
47
48
static struct usb_device_id bcm203x_table[] = {
49
	/* Broadcom Blutonium (BCM2033) */
50
	{ USB_DEVICE(0x0a5c, 0x2033) },
51
52
	{ }	/* Terminating entry */
53
};
54
55
MODULE_DEVICE_TABLE(usb, bcm203x_table);
56
57
58
#define BCM203X_ERROR		0
59
#define BCM203X_RESET		1
60
#define BCM203X_LOAD_MINIDRV	2
61
#define BCM203X_SELECT_MEMORY	3
62
#define BCM203X_CHECK_MEMORY	4
63
#define BCM203X_LOAD_FIRMWARE	5
64
#define BCM203X_CHECK_FIRMWARE	6
65
66
#define BCM203X_IN_EP		0x81
67
#define BCM203X_OUT_EP		0x02
68
69
struct bcm203x_data {
70
	struct usb_device	*udev;
71
72
	unsigned long		state;
73
74
	struct timer_list	timer;
75
76
	struct urb		*urb;
77
	unsigned char		buffer[4096];
78
79
	unsigned char		*fw_data;
80
	unsigned int		fw_size;
81
	unsigned int		fw_sent;
82
};
83
84
static void bcm203x_complete(struct urb *urb, struct pt_regs *regs)
85
{
86
	struct bcm203x_data *data = urb->context;
87
	struct usb_device *udev = urb->dev;
88
	int len;
89
90
	BT_DBG("udev %p urb %p", udev, urb);
91
92
	if (urb->status) {
93
		BT_ERR("URB failed with status %d", urb->status);
94
		data->state = BCM203X_ERROR;
95
		return;
96
	}
97
98
	switch (data->state) {
99
	case BCM203X_LOAD_MINIDRV:
100
		memcpy(data->buffer, "#", 1);
101
102
		usb_fill_bulk_urb(urb, udev,
103
				usb_sndbulkpipe(udev, BCM203X_OUT_EP),
104
				data->buffer, 1, bcm203x_complete, data);
105
106
		data->state = BCM203X_SELECT_MEMORY;
107
108
		mod_timer(&data->timer, jiffies + (HZ / 10));
109
		break;
110
111
	case BCM203X_SELECT_MEMORY:
112
		usb_fill_int_urb(urb, udev,
113
				usb_rcvintpipe(udev, BCM203X_IN_EP),
114
				data->buffer, 32, bcm203x_complete, data, 1);
115
116
		data->state = BCM203X_CHECK_MEMORY;
117
118
		if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
119
			BT_ERR("Can't submit URB");
120
		break;
121
122
	case BCM203X_CHECK_MEMORY:
123
		if (data->buffer[0] != '#') {
124
			BT_ERR("Memory select failed");
125
			data->state = BCM203X_ERROR;
126
			break;
127
		}
128
129
		data->state = BCM203X_LOAD_FIRMWARE;
130
131
	case BCM203X_LOAD_FIRMWARE:
132
		if (data->fw_sent == data->fw_size) {
133
			usb_fill_int_urb(urb, udev,
134
					usb_rcvintpipe(udev, BCM203X_IN_EP),
135
					data->buffer, 32,
136
					bcm203x_complete, data, 1);
137
138
			data->state = BCM203X_CHECK_FIRMWARE;
139
		} else {
140
			len = min_t(uint, data->fw_size - data->fw_sent,
141
							sizeof(data->buffer));
142
143
			usb_fill_bulk_urb(urb, udev,
144
					usb_sndbulkpipe(udev, BCM203X_OUT_EP),
145
					data->fw_data + data->fw_sent, len,
146
					bcm203x_complete, data);
147
148
			data->fw_sent += len;
149
		}
150
151
		if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
152
			BT_ERR("Can't submit URB");
153
		break;
154
155
	case BCM203X_CHECK_FIRMWARE:
156
		if (data->buffer[0] != '.') {
157
			BT_ERR("Firmware loading failed");
158
			data->state = BCM203X_ERROR;
159
			break;
160
		}
161
162
		data->state = BCM203X_RESET;
163
		break;
164
	}
165
}
166
167
static void bcm203x_timer(unsigned long user_data)
168
{
169
	struct bcm203x_data *data = (struct bcm203x_data *) user_data;
170
171
	if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
172
		BT_ERR("Can't submit URB");
173
}
174
175
static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id)
176
{
177
	const struct firmware *firmware;
178
	struct usb_device *udev = interface_to_usbdev(intf);
179
	struct bcm203x_data *data;
180
181
	BT_DBG("intf %p id %p", intf, id);
182
183
	if (intf->altsetting->desc.bInterfaceNumber != 0)
184
		return -ENODEV;
185
186
	data = kmalloc(sizeof(*data), GFP_KERNEL);
187
	if (!data) {
188
		BT_ERR("Can't allocate memory for data structure");
189
		return -ENOMEM;
190
	}
191
192
	memset(data, 0, sizeof(*data));
193
194
	data->udev  = udev;
195
	data->state = BCM203X_LOAD_MINIDRV;
196
197
	data->urb = usb_alloc_urb(0, GFP_KERNEL);
198
	if (!data->urb) {
199
		BT_ERR("Can't allocate URB");
200
		kfree(data);
201
		return -ENOMEM;
202
	}
203
204
	if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
205
		BT_ERR("Mini driver request failed");
206
		usb_free_urb(data->urb);
207
		kfree(data);
208
		return -EIO;
209
	}
210
211
	BT_DBG("minidrv data %p size %d", firmware->data, firmware->size);
212
213
	if (firmware->size > sizeof(data->buffer)) {
214
		BT_ERR("Mini driver exceeds size of buffer");
215
		release_firmware(firmware);
216
		usb_free_urb(data->urb);
217
		kfree(data);
218
		return -EIO;
219
	}
220
221
	memcpy(data->buffer, firmware->data, firmware->size);
222
223
	usb_fill_bulk_urb(data->urb, udev,
224
			usb_sndbulkpipe(udev, BCM203X_OUT_EP),
225
			data->buffer, firmware->size, bcm203x_complete, data);
226
227
	release_firmware(firmware);
228
229
	if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) {
230
		BT_ERR("Firmware request failed");
231
		usb_free_urb(data->urb);
232
		kfree(data);
233
		return -EIO;
234
	}
235
236
	BT_DBG("firmware data %p size %d", firmware->data, firmware->size);
237
238
	data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
239
	if (!data->fw_data) {
240
		BT_ERR("Can't allocate memory for firmware image");
241
		usb_free_urb(data->urb);
242
		kfree(data);
243
		return -ENOMEM;
244
	}
245
246
	memcpy(data->fw_data, firmware->data, firmware->size);
247
	data->fw_size = firmware->size;
248
	data->fw_sent = 0;
249
250
	release_firmware(firmware);
251
252
	init_timer(&data->timer);
253
	data->timer.function = bcm203x_timer;
254
	data->timer.data = (unsigned long) data;
255
256
	usb_set_intfdata(intf, data);
257
258
	mod_timer(&data->timer, jiffies + HZ);
259
260
	return 0;
261
}
262
263
static void bcm203x_disconnect(struct usb_interface *intf)
264
{
265
	struct bcm203x_data *data = usb_get_intfdata(intf);
266
267
	BT_DBG("intf %p", intf);
268
269
	usb_unlink_urb(data->urb);
270
271
	usb_set_intfdata(intf, NULL);
272
273
	usb_free_urb(data->urb);
274
	kfree(data->fw_data);
275
	kfree(data);
276
}
277
278
static struct usb_driver bcm203x_driver = {
279
	.owner		= THIS_MODULE,
280
	.name		= "bcm203x",
281
	.probe		= bcm203x_probe,
282
	.disconnect	= bcm203x_disconnect,
283
	.id_table	= bcm203x_table,
284
};
285
286
static int __init bcm203x_init(void)
287
{
288
	int err;
289
290
	BT_INFO("Broadcom Blutonium firmware driver ver %s", VERSION);
291
292
	err = usb_register(&bcm203x_driver);
293
	if (err < 0)
294
		BT_ERR("Failed to register USB driver");
295
296
	return err;
297
}
298
299
static void __exit bcm203x_cleanup(void)
300
{
301
	usb_deregister(&bcm203x_driver);
302
}
303
304
module_init(bcm203x_init);
305
module_exit(bcm203x_cleanup);
306
307
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
308
MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
309
MODULE_LICENSE("GPL");
(-)linux-2.6.0/drivers/bluetooth/bfusb.c (+782 lines)
Line 0 Link Here
1
/*
2
 *
3
 *  AVM BlueFRITZ! USB driver
4
 *
5
 *  Copyright (C) 2003  Marcel Holtmann <marcel@holtmann.org>
6
 *
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *
22
 */
23
24
#include <linux/config.h>
25
#include <linux/module.h>
26
27
#include <linux/kernel.h>
28
#include <linux/init.h>
29
#include <linux/slab.h>
30
#include <linux/types.h>
31
#include <linux/sched.h>
32
#include <linux/errno.h>
33
#include <linux/skbuff.h>
34
35
#include <linux/device.h>
36
#include <linux/firmware.h>
37
38
#include <linux/usb.h>
39
40
#include <net/bluetooth/bluetooth.h>
41
#include <net/bluetooth/hci_core.h>
42
43
#ifndef CONFIG_BT_HCIBFUSB_DEBUG
44
#undef  BT_DBG
45
#define BT_DBG(D...)
46
#endif
47
48
#define VERSION "1.1"
49
50
static struct usb_driver bfusb_driver;
51
52
static struct usb_device_id bfusb_table[] = {
53
	/* AVM BlueFRITZ! USB */
54
	{ USB_DEVICE(0x057c, 0x2200) },
55
56
	{ }	/* Terminating entry */
57
};
58
59
MODULE_DEVICE_TABLE(usb, bfusb_table);
60
61
62
#define BFUSB_MAX_BLOCK_SIZE	256
63
64
#define BFUSB_BLOCK_TIMEOUT	(HZ * 3)
65
66
#define BFUSB_TX_PROCESS	1
67
#define BFUSB_TX_WAKEUP		2
68
69
#define BFUSB_MAX_BULK_TX	2
70
#define BFUSB_MAX_BULK_RX	2
71
72
struct bfusb {
73
	struct hci_dev		hdev;
74
75
	unsigned long		state;
76
77
	struct usb_device	*udev;
78
79
	unsigned int		bulk_in_ep;
80
	unsigned int		bulk_out_ep;
81
	unsigned int		bulk_pkt_size;
82
83
	rwlock_t		lock;
84
85
	struct sk_buff_head	transmit_q;
86
87
	struct sk_buff		*reassembly;
88
89
	atomic_t		pending_tx;
90
	struct sk_buff_head	pending_q;
91
	struct sk_buff_head	completed_q;
92
};
93
94
struct bfusb_scb {
95
	struct urb *urb;
96
};
97
98
static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
99
static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
100
101
static struct urb *bfusb_get_completed(struct bfusb *bfusb)
102
{
103
	struct sk_buff *skb;
104
	struct urb *urb = NULL;
105
106
	BT_DBG("bfusb %p", bfusb);
107
108
	skb = skb_dequeue(&bfusb->completed_q);
109
	if (skb) {
110
		urb = ((struct bfusb_scb *) skb->cb)->urb;
111
		kfree_skb(skb);
112
	}
113
114
	return urb;
115
}
116
117
static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
118
{
119
	struct sk_buff *skb;
120
	struct urb *urb;
121
122
	BT_DBG("bfusb %p", bfusb);
123
124
	while ((skb = skb_dequeue(&bfusb->pending_q))) {
125
		urb = ((struct bfusb_scb *) skb->cb)->urb;
126
		usb_unlink_urb(urb);
127
		skb_queue_tail(&bfusb->completed_q, skb);
128
	}
129
130
	while ((urb = bfusb_get_completed(bfusb)))
131
		usb_free_urb(urb);
132
}
133
134
135
static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
136
{
137
	struct bfusb_scb *scb = (void *) skb->cb;
138
	struct urb *urb = bfusb_get_completed(bfusb);
139
	int err, pipe;
140
141
	BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
142
143
	if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
144
		return -ENOMEM;
145
146
	pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
147
148
	usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len,
149
			bfusb_tx_complete, skb);
150
151
	scb->urb = urb;
152
153
	skb_queue_tail(&bfusb->pending_q, skb);
154
155
	err = usb_submit_urb(urb, GFP_ATOMIC);
156
	if (err) {
157
		BT_ERR("%s bulk tx submit failed urb %p err %d", 
158
					bfusb->hdev.name, urb, err);
159
		skb_unlink(skb);
160
		usb_free_urb(urb);
161
	} else
162
		atomic_inc(&bfusb->pending_tx);
163
164
	return err;
165
}
166
167
static void bfusb_tx_wakeup(struct bfusb *bfusb)
168
{
169
	struct sk_buff *skb;
170
171
	BT_DBG("bfusb %p", bfusb);
172
173
	if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
174
		set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
175
		return;
176
	}
177
178
	do {
179
		clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
180
181
		while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
182
				(skb = skb_dequeue(&bfusb->transmit_q))) {
183
			if (bfusb_send_bulk(bfusb, skb) < 0) {
184
				skb_queue_head(&bfusb->transmit_q, skb);
185
				break;
186
			}
187
		}
188
189
	} while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
190
191
	clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
192
}
193
194
static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
195
{
196
	struct sk_buff *skb = (struct sk_buff *) urb->context;
197
	struct bfusb *bfusb = (struct bfusb *) skb->dev;
198
199
	BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
200
201
	atomic_dec(&bfusb->pending_tx);
202
203
	if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
204
		return;
205
206
	if (!urb->status)
207
		bfusb->hdev.stat.byte_tx += skb->len;
208
	else
209
		bfusb->hdev.stat.err_tx++;
210
211
	read_lock(&bfusb->lock);
212
213
	skb_unlink(skb);
214
	skb_queue_tail(&bfusb->completed_q, skb);
215
216
	bfusb_tx_wakeup(bfusb);
217
218
	read_unlock(&bfusb->lock);
219
}
220
221
222
static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
223
{
224
	struct bfusb_scb *scb;
225
	struct sk_buff *skb;
226
	int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
227
228
	BT_DBG("bfusb %p urb %p", bfusb, urb);
229
230
	if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
231
		return -ENOMEM;
232
233
	if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) {
234
		usb_free_urb(urb);
235
		return -ENOMEM;
236
	}
237
238
	skb->dev = (void *) bfusb;
239
240
	scb = (struct bfusb_scb *) skb->cb;
241
	scb->urb = urb;
242
243
	pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
244
245
	usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size,
246
			bfusb_rx_complete, skb);
247
248
	skb_queue_tail(&bfusb->pending_q, skb);
249
250
	err = usb_submit_urb(urb, GFP_ATOMIC);
251
	if (err) {
252
		BT_ERR("%s bulk rx submit failed urb %p err %d",
253
					bfusb->hdev.name, urb, err);
254
		skb_unlink(skb);
255
		kfree_skb(skb);
256
		usb_free_urb(urb);
257
	}
258
259
	return err;
260
}
261
262
static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
263
{
264
	BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
265
266
	if (hdr & 0x10) {
267
		BT_ERR("%s error in block", bfusb->hdev.name);
268
		if (bfusb->reassembly)
269
			kfree_skb(bfusb->reassembly);
270
		bfusb->reassembly = NULL;
271
		return -EIO;
272
	}
273
274
	if (hdr & 0x04) {
275
		struct sk_buff *skb;
276
		unsigned char pkt_type;
277
		int pkt_len = 0;
278
279
		if (bfusb->reassembly) {
280
			BT_ERR("%s unexpected start block", bfusb->hdev.name);
281
			kfree_skb(bfusb->reassembly);
282
			bfusb->reassembly = NULL;
283
		}
284
285
		if (len < 1) {
286
			BT_ERR("%s no packet type found", bfusb->hdev.name);
287
			return -EPROTO;
288
		}
289
290
		pkt_type = *data++; len--;
291
292
		switch (pkt_type) {
293
		case HCI_EVENT_PKT:
294
			if (len >= HCI_EVENT_HDR_SIZE) {
295
				struct hci_event_hdr *hdr = (struct hci_event_hdr *) data;
296
				pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
297
			} else {
298
				BT_ERR("%s event block is too short", bfusb->hdev.name);
299
				return -EILSEQ;
300
			}
301
			break;
302
303
		case HCI_ACLDATA_PKT:
304
			if (len >= HCI_ACL_HDR_SIZE) {
305
				struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data;
306
				pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
307
			} else {
308
				BT_ERR("%s data block is too short", bfusb->hdev.name);
309
				return -EILSEQ;
310
			}
311
			break;
312
313
		case HCI_SCODATA_PKT:
314
			if (len >= HCI_SCO_HDR_SIZE) {
315
				struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data;
316
				pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
317
			} else {
318
				BT_ERR("%s audio block is too short", bfusb->hdev.name);
319
				return -EILSEQ;
320
			}
321
			break;
322
		}
323
324
		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
325
		if (!skb) {
326
			BT_ERR("%s no memory for the packet", bfusb->hdev.name);
327
			return -ENOMEM;
328
		}
329
330
		skb->dev = (void *) &bfusb->hdev;
331
		skb->pkt_type = pkt_type;
332
333
		bfusb->reassembly = skb;
334
	} else {
335
		if (!bfusb->reassembly) {
336
			BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
337
			return -EIO;
338
		}
339
	}
340
341
	if (len > 0)
342
		memcpy(skb_put(bfusb->reassembly, len), data, len);
343
344
	if (hdr & 0x08) {
345
		hci_recv_frame(bfusb->reassembly);
346
		bfusb->reassembly = NULL;
347
	}
348
349
	return 0;
350
}
351
352
static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
353
{
354
	struct sk_buff *skb = (struct sk_buff *) urb->context;
355
	struct bfusb *bfusb = (struct bfusb *) skb->dev;
356
	unsigned char *buf = urb->transfer_buffer;
357
	int count = urb->actual_length;
358
	int err, hdr, len;
359
360
	BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
361
362
	if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
363
		return;
364
365
	read_lock(&bfusb->lock);
366
367
	if (urb->status || !count)
368
		goto resubmit;
369
370
	bfusb->hdev.stat.byte_rx += count;
371
372
	skb_put(skb, count);
373
374
	while (count) {
375
		hdr = buf[0] | (buf[1] << 8);
376
377
		if (hdr & 0x4000) {
378
			len = 0;
379
			count -= 2;
380
			buf   += 2;
381
		} else {
382
			len = (buf[2] == 0) ? 256 : buf[2];
383
			count -= 3;
384
			buf   += 3;
385
		}
386
387
		if (count < len) {
388
			BT_ERR("%s block extends over URB buffer ranges",
389
					bfusb->hdev.name);
390
		}
391
392
		if ((hdr & 0xe1) == 0xc1)
393
			bfusb_recv_block(bfusb, hdr, buf, len);
394
395
		count -= len;
396
		buf   += len;
397
	}
398
399
	skb_unlink(skb);
400
	kfree_skb(skb);
401
402
	bfusb_rx_submit(bfusb, urb);
403
404
	read_unlock(&bfusb->lock);
405
406
	return;
407
408
resubmit:
409
	urb->dev = bfusb->udev;
410
411
	err = usb_submit_urb(urb, GFP_ATOMIC);
412
	if (err) {
413
		BT_ERR("%s bulk resubmit failed urb %p err %d",
414
					bfusb->hdev.name, urb, err);
415
	}
416
417
	read_unlock(&bfusb->lock);
418
}
419
420
421
static int bfusb_open(struct hci_dev *hdev)
422
{
423
	struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
424
	unsigned long flags;
425
	int i, err;
426
427
	BT_DBG("hdev %p bfusb %p", hdev, bfusb);
428
429
	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
430
		return 0;
431
432
	write_lock_irqsave(&bfusb->lock, flags);
433
434
	err = bfusb_rx_submit(bfusb, NULL);
435
	if (!err) {
436
		for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
437
			bfusb_rx_submit(bfusb, NULL);
438
	} else {
439
		clear_bit(HCI_RUNNING, &hdev->flags);
440
	}
441
442
	write_unlock_irqrestore(&bfusb->lock, flags);
443
444
	return err;
445
}
446
447
static int bfusb_flush(struct hci_dev *hdev)
448
{
449
	struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
450
451
	BT_DBG("hdev %p bfusb %p", hdev, bfusb);
452
453
	skb_queue_purge(&bfusb->transmit_q);
454
455
	return 0;
456
}
457
458
static int bfusb_close(struct hci_dev *hdev)
459
{
460
	struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
461
	unsigned long flags;
462
463
	BT_DBG("hdev %p bfusb %p", hdev, bfusb);
464
465
	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
466
		return 0;
467
468
	write_lock_irqsave(&bfusb->lock, flags);
469
	write_unlock_irqrestore(&bfusb->lock, flags);
470
471
	bfusb_unlink_urbs(bfusb);
472
	bfusb_flush(hdev);
473
474
	return 0;
475
}
476
477
static int bfusb_send_frame(struct sk_buff *skb)
478
{
479
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
480
	struct bfusb *bfusb;
481
	struct sk_buff *nskb;
482
	unsigned char buf[3];
483
	int sent = 0, size, count;
484
485
	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
486
487
	if (!hdev) {
488
		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
489
		return -ENODEV;
490
	}
491
492
	if (!test_bit(HCI_RUNNING, &hdev->flags))
493
		return -EBUSY;
494
495
	bfusb = (struct bfusb *) hdev->driver_data;
496
497
	switch (skb->pkt_type) {
498
	case HCI_COMMAND_PKT:
499
		hdev->stat.cmd_tx++;
500
		break;
501
	case HCI_ACLDATA_PKT:
502
		hdev->stat.acl_tx++;
503
		break;
504
	case HCI_SCODATA_PKT:
505
		hdev->stat.sco_tx++;
506
		break;
507
	};
508
509
	/* Prepend skb with frame type */
510
	memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
511
512
	count = skb->len;
513
514
	/* Max HCI frame size seems to be 1511 + 1 */
515
	if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) {
516
		BT_ERR("Can't allocate memory for new packet");
517
		return -ENOMEM;
518
	}
519
520
	nskb->dev = (void *) bfusb;
521
522
	while (count) {
523
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
524
525
		buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
526
		buf[1] = 0x00;
527
		buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
528
529
		memcpy(skb_put(nskb, 3), buf, 3);
530
		memcpy(skb_put(nskb, size), skb->data + sent, size);
531
532
		sent  += size;
533
		count -= size;
534
	}
535
536
	/* Don't send frame with multiple size of bulk max packet */
537
	if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
538
		buf[0] = 0xdd;
539
		buf[1] = 0x00;
540
		memcpy(skb_put(nskb, 2), buf, 2);
541
	}
542
543
	read_lock(&bfusb->lock);
544
545
	skb_queue_tail(&bfusb->transmit_q, nskb);
546
	bfusb_tx_wakeup(bfusb);
547
548
	read_unlock(&bfusb->lock);
549
550
	kfree_skb(skb);
551
552
	return 0;
553
}
554
555
static void bfusb_destruct(struct hci_dev *hdev)
556
{
557
	struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
558
559
	BT_DBG("hdev %p bfusb %p", hdev, bfusb);
560
561
	kfree(bfusb);
562
}
563
564
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
565
{
566
	return -ENOIOCTLCMD;
567
}
568
569
570
static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
571
{
572
	unsigned char *buf;
573
	int err, pipe, len, size, sent = 0;
574
575
	BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev);
576
577
	BT_INFO("BlueFRITZ! USB loading firmware");
578
579
	pipe = usb_sndctrlpipe(bfusb->udev, 0);
580
581
	if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
582
				0, 1, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT) < 0) {
583
		BT_ERR("Can't change to loading configuration");
584
		return -EBUSY;
585
	}
586
587
	buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
588
	if (!buf) {
589
		BT_ERR("Can't allocate memory chunk for firmware");
590
		return -ENOMEM;
591
	}
592
593
	pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
594
595
	while (count) {
596
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
597
598
		memcpy(buf, firmware + sent, size);
599
600
		err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
601
					&len, BFUSB_BLOCK_TIMEOUT);
602
603
		if (err || (len != size)) {
604
			BT_ERR("Error in firmware loading");
605
			goto error;
606
		}
607
608
		sent  += size;
609
		count -= size;
610
	}
611
612
	if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
613
				&len, BFUSB_BLOCK_TIMEOUT)) < 0) {
614
		BT_ERR("Error in null packet request");
615
		goto error;
616
	}
617
618
	pipe = usb_sndctrlpipe(bfusb->udev, 0);
619
620
        if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
621
				0, 2, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) {
622
		BT_ERR("Can't change to running configuration");
623
		goto error;
624
	}
625
626
	BT_INFO("BlueFRITZ! USB device ready");
627
628
	kfree(buf);
629
	return 0;
630
631
error:
632
	kfree(buf);
633
634
	pipe = usb_sndctrlpipe(bfusb->udev, 0);
635
636
	usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
637
				0, 0, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
638
639
	return err;
640
}
641
642
static int bfusb_probe(struct usb_interface *iface, const struct usb_device_id *id)
643
{
644
	const struct firmware *firmware;
645
	struct usb_device *udev = interface_to_usbdev(iface);
646
	struct usb_host_endpoint *bulk_out_ep;
647
	struct usb_host_endpoint *bulk_in_ep;
648
	struct hci_dev *hdev;
649
	struct bfusb *bfusb;
650
651
	BT_DBG("iface %p id %p", iface, id);
652
653
	/* Check number of endpoints */
654
	if (iface->altsetting[0].desc.bNumEndpoints < 2)
655
		return -EIO;
656
657
	bulk_out_ep = &iface->altsetting[0].endpoint[0];
658
	bulk_in_ep  = &iface->altsetting[0].endpoint[1];
659
660
	if (!bulk_out_ep || !bulk_in_ep) {
661
		BT_ERR("Bulk endpoints not found");
662
		goto done;
663
	}
664
665
	/* Initialize control structure and load firmware */
666
	if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
667
		BT_ERR("Can't allocate memory for control structure");
668
		goto done;
669
	}
670
671
	memset(bfusb, 0, sizeof(struct bfusb));
672
673
	bfusb->udev = udev;
674
	bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
675
	bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
676
	bfusb->bulk_pkt_size = bulk_out_ep->desc.wMaxPacketSize;
677
678
	bfusb->lock = RW_LOCK_UNLOCKED;
679
680
	bfusb->reassembly = NULL;
681
682
	skb_queue_head_init(&bfusb->transmit_q);
683
	skb_queue_head_init(&bfusb->pending_q);
684
	skb_queue_head_init(&bfusb->completed_q);
685
686
	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
687
		BT_ERR("Firmware request failed");
688
		goto error;
689
	}
690
691
	BT_DBG("firmware data %p size %d", firmware->data, firmware->size);
692
693
	if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
694
		BT_ERR("Firmware loading failed");
695
		goto release;
696
	}
697
698
	release_firmware(firmware);
699
700
	/* Initialize and register HCI device */
701
	hdev = &bfusb->hdev;
702
703
	hdev->type = HCI_USB;
704
	hdev->driver_data = bfusb;
705
706
	hdev->open     = bfusb_open;
707
	hdev->close    = bfusb_close;
708
	hdev->flush    = bfusb_flush;
709
	hdev->send     = bfusb_send_frame;
710
	hdev->destruct = bfusb_destruct;
711
	hdev->ioctl    = bfusb_ioctl;
712
713
	hdev->owner = THIS_MODULE;
714
715
	if (hci_register_dev(hdev) < 0) {
716
		BT_ERR("Can't register HCI device");
717
		goto error;
718
	}
719
720
	usb_set_intfdata(iface, bfusb);
721
722
	return 0;
723
724
release:
725
	release_firmware(firmware);
726
727
error:
728
	kfree(bfusb);
729
730
done:
731
	return -EIO;
732
}
733
734
static void bfusb_disconnect(struct usb_interface *iface)
735
{
736
	struct bfusb *bfusb = usb_get_intfdata(iface);
737
	struct hci_dev *hdev = &bfusb->hdev;
738
739
	BT_DBG("iface %p", iface);
740
741
	if (!hdev)
742
		return;
743
744
	usb_set_intfdata(iface, NULL);
745
746
	bfusb_close(hdev);
747
748
	if (hci_unregister_dev(hdev) < 0)
749
		BT_ERR("Can't unregister HCI device %s", hdev->name);
750
}
751
752
static struct usb_driver bfusb_driver = {
753
	.owner		= THIS_MODULE,
754
	.name		= "bfusb",
755
	.probe		= bfusb_probe,
756
	.disconnect	= bfusb_disconnect,
757
	.id_table	= bfusb_table,
758
};
759
760
static int __init bfusb_init(void)
761
{
762
	int err;
763
764
	BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
765
766
	if ((err = usb_register(&bfusb_driver)) < 0)
767
		BT_ERR("Failed to register BlueFRITZ! USB driver");
768
769
	return err;
770
}
771
772
static void __exit bfusb_cleanup(void)
773
{
774
	usb_deregister(&bfusb_driver);
775
}
776
777
module_init(bfusb_init);
778
module_exit(bfusb_cleanup);
779
780
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
781
MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
782
MODULE_LICENSE("GPL");
(-)linux-2.6.0/drivers/bluetooth/bluecard_cs.c (-3 / +5 lines)
Lines 499-505 Link Here
499
}
499
}
500
500
501
501
502
void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
502
static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
503
{
503
{
504
	bluecard_info_t *info = dev_inst;
504
	bluecard_info_t *info = dev_inst;
505
	unsigned int iobase;
505
	unsigned int iobase;
Lines 507-517 Link Here
507
507
508
	if (!info) {
508
	if (!info) {
509
		printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
509
		printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
510
		return;
510
		return IRQ_NONE;
511
	}
511
	}
512
512
513
	if (!test_bit(CARD_READY, &(info->hw_state)))
513
	if (!test_bit(CARD_READY, &(info->hw_state)))
514
		return;
514
		return IRQ_NONE;
515
515
516
	iobase = info->link.io.BasePort1;
516
	iobase = info->link.io.BasePort1;
517
517
Lines 556-561 Link Here
556
	outb(info->ctrl_reg, iobase + REG_CONTROL);
556
	outb(info->ctrl_reg, iobase + REG_CONTROL);
557
557
558
	spin_unlock(&(info->lock));
558
	spin_unlock(&(info->lock));
559
560
	return IRQ_HANDLED;
559
}
561
}
560
562
561
563
(-)linux-2.6.0/drivers/bluetooth/bt3c_cs.c (-2 / +4 lines)
Lines 355-361 Link Here
355
}
355
}
356
356
357
357
358
void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
358
static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
359
{
359
{
360
	bt3c_info_t *info = dev_inst;
360
	bt3c_info_t *info = dev_inst;
361
	unsigned int iobase;
361
	unsigned int iobase;
Lines 363-369 Link Here
363
363
364
	if (!info) {
364
	if (!info) {
365
		printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
365
		printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
366
		return;
366
		return IRQ_NONE;
367
	}
367
	}
368
368
369
	iobase = info->link.io.BasePort1;
369
	iobase = info->link.io.BasePort1;
Lines 396-401 Link Here
396
	}
396
	}
397
397
398
	spin_unlock(&(info->lock));
398
	spin_unlock(&(info->lock));
399
400
	return IRQ_HANDLED;
399
}
401
}
400
402
401
403
(-)linux-2.6.0/drivers/bluetooth/btuart_cs.c (-2 / +4 lines)
Lines 301-307 Link Here
301
}
301
}
302
302
303
303
304
void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
304
static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
305
{
305
{
306
	btuart_info_t *info = dev_inst;
306
	btuart_info_t *info = dev_inst;
307
	unsigned int iobase;
307
	unsigned int iobase;
Lines 310-316 Link Here
310
310
311
	if (!info) {
311
	if (!info) {
312
		printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
312
		printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
313
		return;
313
		return IRQ_NONE;
314
	}
314
	}
315
315
316
	iobase = info->link.io.BasePort1;
316
	iobase = info->link.io.BasePort1;
Lines 351-356 Link Here
351
	}
351
	}
352
352
353
	spin_unlock(&(info->lock));
353
	spin_unlock(&(info->lock));
354
355
	return IRQ_HANDLED;
354
}
356
}
355
357
356
358
(-)linux-2.6.0/drivers/bluetooth/dtl1_cs.c (-2 / +4 lines)
Lines 304-310 Link Here
304
}
304
}
305
305
306
306
307
void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
307
static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
308
{
308
{
309
	dtl1_info_t *info = dev_inst;
309
	dtl1_info_t *info = dev_inst;
310
	unsigned int iobase;
310
	unsigned int iobase;
Lines 314-320 Link Here
314
314
315
	if (!info) {
315
	if (!info) {
316
		printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
316
		printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
317
		return;
317
		return IRQ_NONE;
318
	}
318
	}
319
319
320
	iobase = info->link.io.BasePort1;
320
	iobase = info->link.io.BasePort1;
Lines 363-368 Link Here
363
	}
363
	}
364
364
365
	spin_unlock(&(info->lock));
365
	spin_unlock(&(info->lock));
366
367
	return IRQ_HANDLED;
366
}
368
}
367
369
368
370
(-)linux-2.6.0/drivers/bluetooth/hci_usb.c (-26 / +36 lines)
Lines 62-68 Link Here
62
#define BT_DMP( A... )
62
#define BT_DMP( A... )
63
#endif
63
#endif
64
64
65
#ifndef CONFIG_BT_USB_ZERO_PACKET
65
#ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
66
#undef  URB_ZERO_PACKET
66
#undef  URB_ZERO_PACKET
67
#define URB_ZERO_PACKET 0
67
#define URB_ZERO_PACKET 0
68
#endif
68
#endif
Lines 70-81 Link Here
70
static struct usb_driver hci_usb_driver; 
70
static struct usb_driver hci_usb_driver; 
71
71
72
static struct usb_device_id bluetooth_ids[] = {
72
static struct usb_device_id bluetooth_ids[] = {
73
	/* Broadcom BCM2033 without firmware */
74
	{ USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE },
75
76
	/* Digianswer device */
77
	{ USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
78
73
	/* Generic Bluetooth USB device */
79
	/* Generic Bluetooth USB device */
74
	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
80
	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
75
81
76
	/* Ericsson with non-standard id */
82
	/* Ericsson with non-standard id */
77
	{ USB_DEVICE(0x0bdb, 0x1002) },
83
	{ USB_DEVICE(0x0bdb, 0x1002) },
78
84
85
	/* ALPS Module with non-standard id */
86
	{ USB_DEVICE(0x044e, 0x3002) },
87
79
	/* Bluetooth Ultraport Module from IBM */
88
	/* Bluetooth Ultraport Module from IBM */
80
	{ USB_DEVICE(0x04bf, 0x030a) },
89
	{ USB_DEVICE(0x04bf, 0x030a) },
81
90
Lines 84-96 Link Here
84
93
85
MODULE_DEVICE_TABLE (usb, bluetooth_ids);
94
MODULE_DEVICE_TABLE (usb, bluetooth_ids);
86
95
87
static struct usb_device_id ignore_ids[] = {
88
	/* Broadcom BCM2033 without firmware */
89
	{ USB_DEVICE(0x0a5c, 0x2033) },
90
91
	{ }	/* Terminating entry */
92
};
93
94
struct _urb *_urb_alloc(int isoc, int gfp)
96
struct _urb *_urb_alloc(int isoc, int gfp)
95
{
97
{
96
	struct _urb *_urb = kmalloc(sizeof(struct _urb) +
98
	struct _urb *_urb = kmalloc(sizeof(struct _urb) +
Lines 134-140 Link Here
134
	return _urb_dequeue(__completed_q(husb, type)); 
136
	return _urb_dequeue(__completed_q(husb, type)); 
135
}
137
}
136
138
137
#ifdef CONFIG_BT_USB_SCO
139
#ifdef CONFIG_BT_HCIUSB_SCO
138
static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
140
static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
139
{
141
{
140
	int offset = 0, i;
142
	int offset = 0, i;
Lines 232-238 Link Here
232
	return err;
234
	return err;
233
}
235
}
234
236
235
#ifdef CONFIG_BT_USB_SCO
237
#ifdef CONFIG_BT_HCIUSB_SCO
236
static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
238
static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
237
{
239
{
238
	struct _urb *_urb;
240
	struct _urb *_urb;
Lines 301-309 Link Here
301
		for (i = 0; i < HCI_MAX_BULK_RX; i++)
303
		for (i = 0; i < HCI_MAX_BULK_RX; i++)
302
			hci_usb_bulk_rx_submit(husb);
304
			hci_usb_bulk_rx_submit(husb);
303
305
304
#ifdef CONFIG_BT_USB_SCO
306
#ifdef CONFIG_BT_HCIUSB_SCO
305
		if (husb->isoc_iface)
307
		if (husb->isoc_iface)
306
			hci_usb_isoc_rx_submit(husb);
308
			for (i = 0; i < HCI_MAX_ISOC_RX; i++)
309
				hci_usb_isoc_rx_submit(husb);
307
#endif
310
#endif
308
	} else {
311
	} else {
309
		clear_bit(HCI_RUNNING, &hdev->flags);
312
		clear_bit(HCI_RUNNING, &hdev->flags);
Lines 425-431 Link Here
425
	} else
428
	} else
426
		dr = (void *) _urb->urb.setup_packet;
429
		dr = (void *) _urb->urb.setup_packet;
427
430
428
	dr->bRequestType = HCI_CTRL_REQ;
431
	dr->bRequestType = husb->ctrl_req;
429
	dr->bRequest = 0;
432
	dr->bRequest = 0;
430
	dr->wIndex   = 0;
433
	dr->wIndex   = 0;
431
	dr->wValue   = 0;
434
	dr->wValue   = 0;
Lines 466-472 Link Here
466
	return __tx_submit(husb, _urb);
469
	return __tx_submit(husb, _urb);
467
}
470
}
468
471
469
#ifdef CONFIG_BT_USB_SCO
472
#ifdef CONFIG_BT_HCIUSB_SCO
470
static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
473
static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
471
{
474
{
472
	struct _urb *_urb = __get_completed(husb, skb->pkt_type);
475
	struct _urb *_urb = __get_completed(husb, skb->pkt_type);
Lines 517-526 Link Here
517
				skb_queue_head(q, skb);
520
				skb_queue_head(q, skb);
518
		}
521
		}
519
522
520
#ifdef CONFIG_BT_USB_SCO
523
#ifdef CONFIG_BT_HCIUSB_SCO
521
		/* Process SCO queue */
524
		/* Process SCO queue */
522
		q = __transmit_q(husb, HCI_SCODATA_PKT);
525
		q = __transmit_q(husb, HCI_SCODATA_PKT);
523
		if (!atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) &&
526
		if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
524
				(skb = skb_dequeue(q))) {
527
				(skb = skb_dequeue(q))) {
525
			if (hci_usb_send_isoc(husb, skb) < 0)
528
			if (hci_usb_send_isoc(husb, skb) < 0)
526
				skb_queue_head(q, skb);
529
				skb_queue_head(q, skb);
Lines 576-582 Link Here
576
		hdev->stat.acl_tx++;
579
		hdev->stat.acl_tx++;
577
		break;
580
		break;
578
581
579
#ifdef CONFIG_BT_USB_SCO
582
#ifdef CONFIG_BT_HCIUSB_SCO
580
	case HCI_SCODATA_PKT:
583
	case HCI_SCODATA_PKT:
581
		hdev->stat.sco_tx++;
584
		hdev->stat.sco_tx++;
582
		break;
585
		break;
Lines 626-632 Link Here
626
				} else
629
				} else
627
					return -EILSEQ;
630
					return -EILSEQ;
628
				break;
631
				break;
629
#ifdef CONFIG_BT_USB_SCO
632
#ifdef CONFIG_BT_HCIUSB_SCO
630
			case HCI_SCODATA_PKT:
633
			case HCI_SCODATA_PKT:
631
				if (count >= HCI_SCO_HDR_SIZE) {
634
				if (count >= HCI_SCO_HDR_SIZE) {
632
					struct hci_sco_hdr *h = data;
635
					struct hci_sco_hdr *h = data;
Lines 691-697 Link Here
691
		goto resubmit;
694
		goto resubmit;
692
695
693
	if (_urb->type == HCI_SCODATA_PKT) {
696
	if (_urb->type == HCI_SCODATA_PKT) {
694
#ifdef CONFIG_BT_USB_SCO
697
#ifdef CONFIG_BT_HCIUSB_SCO
695
		int i;
698
		int i;
696
		for (i=0; i < urb->number_of_packets; i++) {
699
		for (i=0; i < urb->number_of_packets; i++) {
697
			BT_DBG("desc %d status %d offset %d len %d", i,
700
			BT_DBG("desc %d status %d offset %d len %d", i,
Lines 785-793 Link Here
785
788
786
	iface = udev->actconfig->interface[0];
789
	iface = udev->actconfig->interface[0];
787
790
788
	/* Check our black list */
791
	if (id->driver_info & HCI_IGNORE)
789
	if (usb_match_id(intf, ignore_ids))
792
		return -ENODEV;
790
		return -EIO;
793
794
	if (intf->altsetting->desc.bInterfaceNumber > 0)
795
		return -ENODEV;
791
796
792
	/* Check number of endpoints */
797
	/* Check number of endpoints */
793
	if (intf->altsetting[0].desc.bNumEndpoints < 3)
798
	if (intf->altsetting[0].desc.bNumEndpoints < 3)
Lines 826-834 Link Here
826
						bulk_out_ep[i] = ep;
831
						bulk_out_ep[i] = ep;
827
					break;
832
					break;
828
833
829
#ifdef CONFIG_BT_USB_SCO
834
#ifdef CONFIG_BT_HCIUSB_SCO
830
				case USB_ENDPOINT_XFER_ISOC:
835
				case USB_ENDPOINT_XFER_ISOC:
831
					if (ep->desc.wMaxPacketSize < size)
836
					if (ep->desc.wMaxPacketSize < size || a > 2)
832
						break;
837
						break;
833
					size = ep->desc.wMaxPacketSize;
838
					size = ep->desc.wMaxPacketSize;
834
839
Lines 852-858 Link Here
852
		goto done;
857
		goto done;
853
	}
858
	}
854
859
855
#ifdef CONFIG_BT_USB_SCO
860
#ifdef CONFIG_BT_HCIUSB_SCO
856
	if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
861
	if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
857
		BT_DBG("Isoc endpoints not found");
862
		BT_DBG("Isoc endpoints not found");
858
		isoc_iface = NULL;
863
		isoc_iface = NULL;
Lines 871-877 Link Here
871
	husb->bulk_in_ep  = bulk_in_ep[0];
876
	husb->bulk_in_ep  = bulk_in_ep[0];
872
	husb->intr_in_ep  = intr_in_ep[0];
877
	husb->intr_in_ep  = intr_in_ep[0];
873
878
874
#ifdef CONFIG_BT_USB_SCO
879
	if (id->driver_info & HCI_DIGIANSWER)
880
		husb->ctrl_req = HCI_DIGI_REQ;
881
	else
882
		husb->ctrl_req = HCI_CTRL_REQ;
883
884
#ifdef CONFIG_BT_HCIUSB_SCO
875
	if (isoc_iface) {
885
	if (isoc_iface) {
876
		BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
886
		BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
877
		if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
887
		if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
(-)linux-2.6.0/drivers/bluetooth/hci_usb.h (+9 lines)
Lines 35-46 Link Here
35
#define HCI_DEV_PROTOCOL     0x01	/* Bluetooth programming protocol */
35
#define HCI_DEV_PROTOCOL     0x01	/* Bluetooth programming protocol */
36
36
37
#define HCI_CTRL_REQ	     0x20
37
#define HCI_CTRL_REQ	     0x20
38
#define HCI_DIGI_REQ	     0x40
39
40
#define HCI_IGNORE           0x01
41
#define HCI_DIGIANSWER       0x02
38
42
39
#define HCI_MAX_IFACE_NUM	3 
43
#define HCI_MAX_IFACE_NUM	3 
40
44
41
#define HCI_MAX_BULK_TX     	4
45
#define HCI_MAX_BULK_TX     	4
42
#define HCI_MAX_BULK_RX     	1
46
#define HCI_MAX_BULK_RX     	1
43
47
48
#define HCI_MAX_ISOC_RX		2
49
#define HCI_MAX_ISOC_TX		2
50
44
#define HCI_MAX_ISOC_FRAMES     10
51
#define HCI_MAX_ISOC_FRAMES     10
45
52
46
struct _urb_queue {
53
struct _urb_queue {
Lines 119-124 Link Here
119
	struct usb_host_endpoint	*isoc_out_ep;
126
	struct usb_host_endpoint	*isoc_out_ep;
120
	struct usb_host_endpoint	*isoc_in_ep;
127
	struct usb_host_endpoint	*isoc_in_ep;
121
128
129
	__u8			ctrl_req;
130
122
	struct sk_buff_head	transmit_q[4];
131
	struct sk_buff_head	transmit_q[4];
123
	struct sk_buff		*reassembly[4]; // Reassembly buffers
132
	struct sk_buff		*reassembly[4]; // Reassembly buffers
124
133
(-)linux-2.6.0/drivers/bluetooth/Kconfig (-15 / +32 lines)
Lines 13-34 Link Here
13
	  Say Y here to compile support for Bluetooth USB devices into the
13
	  Say Y here to compile support for Bluetooth USB devices into the
14
	  kernel or say M to compile it as module (hci_usb).
14
	  kernel or say M to compile it as module (hci_usb).
15
15
16
config BT_USB_SCO
16
config BT_HCIUSB_SCO
17
	bool "SCO over HCI USB support"
17
	bool "SCO (voice) support"
18
	depends on BT_HCIUSB
18
	depends on BT_HCIUSB
19
	help
19
	help
20
	  This option enables the SCO support in the HCI USB driver. You need this
20
	  This option enables the SCO support in the HCI USB driver. You need this
21
	  to transmit voice data with your Bluetooth USB device. 
21
	  to transmit voice data with your Bluetooth USB device.
22
	  Say Y here to compile support for SCO over HCI USB.
23
22
24
config BT_USB_ZERO_PACKET
23
	  Say Y here to compile support for SCO over HCI USB.
25
	bool "USB zero packet support"
26
	depends on BT_HCIUSB
27
	help
28
	  This option is provided only as a work around for buggy Bluetooth USB 
29
	  devices. Do _not_ enable it unless you know for sure that your device 
30
	  requires zero packets.
31
	  Most people should say N here.
32
24
33
config BT_HCIUART
25
config BT_HCIUART
34
	tristate "HCI UART driver"
26
	tristate "HCI UART driver"
Lines 65-77 Link Here
65
	  Say Y here to compile support for HCI BCSP protocol.
57
	  Say Y here to compile support for HCI BCSP protocol.
66
58
67
config BT_HCIUART_BCSP_TXCRC
59
config BT_HCIUART_BCSP_TXCRC
68
        bool "Transmit CRC with every BCSP packet"
60
	bool "Transmit CRC with every BCSP packet"
69
        depends on BT_HCIUART_BCSP
61
	depends on BT_HCIUART_BCSP
70
        help
62
	help
71
	  If you say Y here, a 16-bit CRC checksum will be transmitted along with
63
	  If you say Y here, a 16-bit CRC checksum will be transmitted along with
72
	  every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
64
	  every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
73
	  This increases reliability, but slightly reduces efficiency.
65
	  This increases reliability, but slightly reduces efficiency.
74
66
67
config BT_HCIBCM203X
68
	tristate "HCI BCM203x USB driver"
69
	depends on USB && BT
70
	select FW_LOADER
71
	help
72
	  Bluetooth HCI BCM203x USB driver.
73
	  This driver provides the firmware loading mechanism for the Broadcom
74
	  Blutonium based devices.
75
76
	  Say Y here to compile support for HCI BCM203x devices into the
77
	  kernel or say M to compile it as module (bcm203x).
78
79
config BT_HCIBFUSB
80
	tristate "HCI BlueFRITZ! USB driver"
81
	depends on USB && BT
82
	select FW_LOADER
83
	help
84
	  Bluetooth HCI BlueFRITZ! USB driver.
85
	  This driver provides support for Bluetooth USB devices with AVM
86
	  interface:
87
	     AVM BlueFRITZ! USB
88
89
	  Say Y here to compile support for HCI BFUSB devices into the
90
	  kernel or say M to compile it as module (bfusb).
91
75
config BT_HCIDTL1
92
config BT_HCIDTL1
76
	tristate "HCI DTL1 (PC Card) driver"
93
	tristate "HCI DTL1 (PC Card) driver"
77
	depends on PCMCIA && BT
94
	depends on PCMCIA && BT
(-)linux-2.6.0/drivers/bluetooth/Makefile (+2 lines)
Lines 5-10 Link Here
5
obj-$(CONFIG_BT_HCIUSB)		+= hci_usb.o
5
obj-$(CONFIG_BT_HCIUSB)		+= hci_usb.o
6
obj-$(CONFIG_BT_HCIVHCI)	+= hci_vhci.o
6
obj-$(CONFIG_BT_HCIVHCI)	+= hci_vhci.o
7
obj-$(CONFIG_BT_HCIUART)	+= hci_uart.o
7
obj-$(CONFIG_BT_HCIUART)	+= hci_uart.o
8
obj-$(CONFIG_BT_HCIBCM203X)	+= bcm203x.o
9
obj-$(CONFIG_BT_HCIBFUSB)	+= bfusb.o
8
obj-$(CONFIG_BT_HCIDTL1)	+= dtl1_cs.o
10
obj-$(CONFIG_BT_HCIDTL1)	+= dtl1_cs.o
9
obj-$(CONFIG_BT_HCIBT3C)	+= bt3c_cs.o
11
obj-$(CONFIG_BT_HCIBT3C)	+= bt3c_cs.o
10
obj-$(CONFIG_BT_HCIBLUECARD)	+= bluecard_cs.o
12
obj-$(CONFIG_BT_HCIBLUECARD)	+= bluecard_cs.o
(-)linux-2.6.0/include/net/bluetooth/bluetooth.h (-1 / +2 lines)
Lines 47-53 Link Here
47
#define BTPROTO_HCI     1
47
#define BTPROTO_HCI     1
48
#define BTPROTO_SCO   	2
48
#define BTPROTO_SCO   	2
49
#define BTPROTO_RFCOMM	3
49
#define BTPROTO_RFCOMM	3
50
#define BTPROTO_BNEP    4
50
#define BTPROTO_BNEP	4
51
#define BTPROTO_CMTP	5
51
52
52
#define SOL_HCI     0
53
#define SOL_HCI     0
53
#define SOL_L2CAP   6
54
#define SOL_L2CAP   6
(-)linux-2.6.0/include/net/bluetooth/hci.h (+10 lines)
Lines 408-413 Link Here
408
	__u16    clock_offset;
408
	__u16    clock_offset;
409
} __attribute__ ((packed));
409
} __attribute__ ((packed));
410
410
411
#define HCI_EV_INQUIRY_RESULT_WITH_RSSI	0x22
412
struct inquiry_info_with_rssi {
413
	bdaddr_t bdaddr;
414
	__u8     pscan_rep_mode;
415
	__u8     pscan_period_mode;
416
	__u8     dev_class[3];
417
	__u16    clock_offset;
418
	__u8     rssi;
419
} __attribute__ ((packed));
420
411
#define HCI_EV_CONN_COMPLETE 	0x03
421
#define HCI_EV_CONN_COMPLETE 	0x03
412
struct hci_ev_conn_complete {
422
struct hci_ev_conn_complete {
413
	__u8     status;
423
	__u8     status;
(-)linux-2.6.0/include/net/bluetooth/rfcomm.h (-2 / +7 lines)
Lines 167-174 Link Here
167
	int              initiator;
167
	int              initiator;
168
168
169
	/* Default DLC parameters */
169
	/* Default DLC parameters */
170
	int    cfc;
170
	uint   mtu;
171
	uint   mtu;
171
	uint   credits;
172
172
173
	struct list_head dlcs;
173
	struct list_head dlcs;
174
};
174
};
Lines 190-196 Link Here
190
	u8            mscex;
190
	u8            mscex;
191
191
192
	uint          mtu;
192
	uint          mtu;
193
	uint          credits;
193
	uint          cfc;
194
	uint          rx_credits;
194
	uint          rx_credits;
195
	uint          tx_credits;
195
	uint          tx_credits;
196
196
Lines 219-224 Link Here
219
#define RFCOMM_MSCEX_RX     2
219
#define RFCOMM_MSCEX_RX     2
220
#define RFCOMM_MSCEX_OK     (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
220
#define RFCOMM_MSCEX_OK     (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
221
221
222
/* CFC states */
223
#define RFCOMM_CFC_UNKNOWN  -1
224
#define RFCOMM_CFC_DISABLED 0
225
#define RFCOMM_CFC_ENABLED  RFCOMM_MAX_CREDITS
226
222
extern struct task_struct *rfcomm_thread;
227
extern struct task_struct *rfcomm_thread;
223
extern unsigned long rfcomm_event;
228
extern unsigned long rfcomm_event;
224
229
(-)linux-2.6.0/MAINTAINERS (+18 lines)
Lines 355-360 Link Here
355
W:	http://bluez.sf.net
355
W:	http://bluez.sf.net
356
S:	Maintained
356
S:	Maintained
357
357
358
BLUETOOTH CMTP LAYER
359
P:	Marcel Holtmann
360
M:	marcel@holtmann.org
361
W:	http://www.holtmann.org/linux/bluetooth/
362
S:	Maintained
363
358
BLUETOOTH HCI USB DRIVER
364
BLUETOOTH HCI USB DRIVER
359
P:	Maxim Krasnyansky
365
P:	Maxim Krasnyansky
360
M:	maxk@qualcomm.com
366
M:	maxk@qualcomm.com
Lines 367-372 Link Here
367
W:	http://bluez.sf.net
373
W:	http://bluez.sf.net
368
S:	Maintained
374
S:	Maintained
369
375
376
BLUETOOTH HCI BCM203X DRIVER
377
P:	Marcel Holtmann
378
M:	marcel@holtmann.org
379
W:	http://www.holtmann.org/linux/bluetooth/
380
S:	Maintained
381
382
BLUETOOTH HCI BFUSB DRIVER
383
P:	Marcel Holtmann
384
M:	marcel@holtmann.org
385
W:	http://www.holtmann.org/linux/bluetooth/
386
S:	Maintained
387
370
BLUETOOTH HCI DTL1 DRIVER
388
BLUETOOTH HCI DTL1 DRIVER
371
P:	Marcel Holtmann
389
P:	Marcel Holtmann
372
M:	marcel@holtmann.org
390
M:	marcel@holtmann.org
(-)linux-2.6.0/Makefile (-1 / +1 lines)
Lines 1-7 Link Here
1
VERSION = 2
1
VERSION = 2
2
PATCHLEVEL = 6
2
PATCHLEVEL = 6
3
SUBLEVEL = 0
3
SUBLEVEL = 0
4
EXTRAVERSION =
4
EXTRAVERSION = -mh2
5
5
6
# *DOCUMENTATION*
6
# *DOCUMENTATION*
7
# To see a list of typical targets execute "make help"
7
# To see a list of typical targets execute "make help"
(-)linux-2.6.0/net/bluetooth/af_bluetooth.c (-1 / +2 lines)
Lines 59-65 Link Here
59
struct proc_dir_entry *proc_bt;
59
struct proc_dir_entry *proc_bt;
60
60
61
/* Bluetooth sockets */
61
/* Bluetooth sockets */
62
#define BT_MAX_PROTO	5
62
#define BT_MAX_PROTO	6
63
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
63
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
64
64
65
static kmem_cache_t *bt_sock_cache;
65
static kmem_cache_t *bt_sock_cache;
Lines 360-362 Link Here
360
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
360
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
361
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
361
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
362
MODULE_LICENSE("GPL");
362
MODULE_LICENSE("GPL");
363
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
(-)linux-2.6.0/net/bluetooth/bnep/core.c (-1 / +1 lines)
Lines 707-710 Link Here
707
MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
707
MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
708
MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
708
MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
709
MODULE_LICENSE("GPL");
709
MODULE_LICENSE("GPL");
710
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
710
MODULE_ALIAS("bt-proto-4");
(-)linux-2.6.0/net/bluetooth/cmtp/capi.c (+630 lines)
Line 0 Link Here
1
/* 
2
   CMTP implementation for Linux Bluetooth stack (BlueZ).
3
   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License version 2 as
7
   published by the Free Software Foundation;
8
9
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
14
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
15
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
16
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
19
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
20
   SOFTWARE IS DISCLAIMED.
21
*/
22
23
#include <linux/config.h>
24
#include <linux/module.h>
25
26
#include <linux/types.h>
27
#include <linux/errno.h>
28
#include <linux/kernel.h>
29
#include <linux/major.h>
30
#include <linux/sched.h>
31
#include <linux/slab.h>
32
#include <linux/poll.h>
33
#include <linux/fcntl.h>
34
#include <linux/skbuff.h>
35
#include <linux/socket.h>
36
#include <linux/ioctl.h>
37
#include <linux/file.h>
38
#include <net/sock.h>
39
40
#include <linux/isdn/capilli.h>
41
#include <linux/isdn/capicmd.h>
42
#include <linux/isdn/capiutil.h>
43
44
#include "cmtp.h"
45
46
#ifndef CONFIG_BT_CMTP_DEBUG
47
#undef  BT_DBG
48
#define BT_DBG(D...)
49
#endif
50
51
#define CAPI_INTEROPERABILITY		0x20
52
53
#define CAPI_INTEROPERABILITY_REQ	CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
54
#define CAPI_INTEROPERABILITY_CONF	CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
55
#define CAPI_INTEROPERABILITY_IND	CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
56
#define CAPI_INTEROPERABILITY_RESP	CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
57
58
#define CAPI_INTEROPERABILITY_REQ_LEN	(CAPI_MSG_BASELEN + 2)
59
#define CAPI_INTEROPERABILITY_CONF_LEN	(CAPI_MSG_BASELEN + 4)
60
#define CAPI_INTEROPERABILITY_IND_LEN	(CAPI_MSG_BASELEN + 2)
61
#define CAPI_INTEROPERABILITY_RESP_LEN	(CAPI_MSG_BASELEN + 2)
62
63
#define CAPI_FUNCTION_REGISTER		0
64
#define CAPI_FUNCTION_RELEASE		1
65
#define CAPI_FUNCTION_GET_PROFILE	2
66
#define CAPI_FUNCTION_GET_MANUFACTURER	3
67
#define CAPI_FUNCTION_GET_VERSION	4
68
#define CAPI_FUNCTION_GET_SERIAL_NUMBER	5
69
#define CAPI_FUNCTION_MANUFACTURER	6
70
#define CAPI_FUNCTION_LOOPBACK		7
71
72
73
#define CMTP_MSGNUM	1
74
#define CMTP_APPLID	2
75
#define CMTP_MAPPING	3
76
77
static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
78
{
79
	struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
80
81
	BT_DBG("session %p application %p appl %d", session, app, appl);
82
83
	if (!app)
84
		return NULL;
85
86
	memset(app, 0, sizeof(*app));
87
88
	app->state = BT_OPEN;
89
	app->appl = appl;
90
91
	list_add_tail(&app->list, &session->applications);
92
93
	return app;
94
}
95
96
static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
97
{
98
	BT_DBG("session %p application %p", session, app);
99
100
	if (app) {
101
		list_del(&app->list);
102
		kfree(app);
103
	}
104
}
105
106
static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
107
{
108
	struct cmtp_application *app;
109
	struct list_head *p, *n;
110
111
	list_for_each_safe(p, n, &session->applications) {
112
		app = list_entry(p, struct cmtp_application, list);
113
		switch (pattern) {
114
		case CMTP_MSGNUM:
115
			if (app->msgnum == value)
116
				return app;
117
			break;
118
		case CMTP_APPLID:
119
			if (app->appl == value)
120
				return app;
121
			break;
122
		case CMTP_MAPPING:
123
			if (app->mapping == value)
124
				return app;
125
			break;
126
		}
127
	}
128
129
	return NULL;
130
}
131
132
static int cmtp_msgnum_get(struct cmtp_session *session)
133
{
134
	session->msgnum++;
135
136
	if ((session->msgnum & 0xff) > 200)
137
		session->msgnum = CMTP_INITIAL_MSGNUM + 1;
138
139
	return session->msgnum;
140
}
141
142
143
static void cmtp_send_interopmsg(struct cmtp_session *session,
144
					__u8 subcmd, __u16 appl, __u16 msgnum,
145
					__u16 function, unsigned char *buf, int len)
146
{
147
	struct sk_buff *skb;
148
	unsigned char *s;
149
150
	BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
151
152
	if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
153
		BT_ERR("Can't allocate memory for interoperability packet");
154
		return;
155
	}
156
157
	s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
158
159
	capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
160
	capimsg_setu16(s, 2, appl);
161
	capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
162
	capimsg_setu8 (s, 5, subcmd);
163
	capimsg_setu16(s, 6, msgnum);
164
165
	/* Interoperability selector (Bluetooth Device Management) */
166
	capimsg_setu16(s, 8, 0x0001);
167
168
	capimsg_setu8 (s, 10, 3 + len);
169
	capimsg_setu16(s, 11, function);
170
	capimsg_setu8 (s, 13, len);
171
172
	if (len > 0)
173
		memcpy(s + 14, buf, len);
174
175
	cmtp_send_capimsg(session, skb);
176
}
177
178
static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
179
{
180
	struct capi_ctr *ctrl = &session->ctrl;
181
	struct cmtp_application *application;
182
	__u16 appl, msgnum, func, info;
183
	__u32 controller;
184
185
	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
186
187
	switch (CAPIMSG_SUBCOMMAND(skb->data)) {
188
	case CAPI_CONF:
189
		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
190
		info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
191
192
		switch (func) {
193
		case CAPI_FUNCTION_REGISTER:
194
			msgnum = CAPIMSG_MSGID(skb->data);
195
196
			application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
197
			if (application) {
198
				application->state = BT_CONNECTED;
199
				application->msgnum = 0;
200
				application->mapping = CAPIMSG_APPID(skb->data);
201
				wake_up_interruptible(&session->wait);
202
			}
203
204
			break;
205
206
		case CAPI_FUNCTION_RELEASE:
207
			appl = CAPIMSG_APPID(skb->data);
208
209
			application = cmtp_application_get(session, CMTP_MAPPING, appl);
210
			if (application) {
211
				application->state = BT_CLOSED;
212
				application->msgnum = 0;
213
				wake_up_interruptible(&session->wait);
214
			}
215
216
			break;
217
218
		case CAPI_FUNCTION_GET_PROFILE:
219
			controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
220
			msgnum = CAPIMSG_MSGID(skb->data);
221
222
			if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
223
				session->ncontroller = controller;
224
				wake_up_interruptible(&session->wait);
225
				break;
226
			}
227
228
			if (!info && ctrl) {
229
				memcpy(&ctrl->profile,
230
					skb->data + CAPI_MSG_BASELEN + 11,
231
					sizeof(capi_profile));
232
				session->state = BT_CONNECTED;
233
				capi_ctr_ready(ctrl);
234
			}
235
236
			break;
237
238
		case CAPI_FUNCTION_GET_MANUFACTURER:
239
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
240
241
			if (!info && ctrl) {
242
				strncpy(ctrl->manu,
243
					skb->data + CAPI_MSG_BASELEN + 15,
244
					skb->data[CAPI_MSG_BASELEN + 14]);
245
			}
246
247
			break;
248
249
		case CAPI_FUNCTION_GET_VERSION:
250
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
251
252
			if (!info && ctrl) {
253
				ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
254
				ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
255
				ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
256
				ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
257
			}
258
259
			break;
260
261
		case CAPI_FUNCTION_GET_SERIAL_NUMBER:
262
			controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
263
264
			if (!info && ctrl) {
265
				memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
266
				strncpy(ctrl->serial,
267
					skb->data + CAPI_MSG_BASELEN + 17,
268
					skb->data[CAPI_MSG_BASELEN + 16]);
269
			}
270
271
			break;
272
		}
273
274
		break;
275
276
	case CAPI_IND:
277
		func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
278
279
		if (func == CAPI_FUNCTION_LOOPBACK) {
280
			appl = CAPIMSG_APPID(skb->data);
281
			msgnum = CAPIMSG_MSGID(skb->data);
282
			cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
283
						skb->data + CAPI_MSG_BASELEN + 6,
284
						skb->data[CAPI_MSG_BASELEN + 5]);
285
		}
286
287
		break;
288
	}
289
290
	kfree_skb(skb);
291
}
292
293
void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
294
{
295
	struct capi_ctr *ctrl = &session->ctrl;
296
	struct cmtp_application *application;
297
	__u16 cmd, appl;
298
	__u32 contr;
299
300
	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
301
302
	if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
303
		cmtp_recv_interopmsg(session, skb);
304
		return;
305
	}
306
307
	if (session->flags & (1 << CMTP_LOOPBACK)) {
308
		kfree_skb(skb);
309
		return;
310
	}
311
312
	cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
313
	appl = CAPIMSG_APPID(skb->data);
314
	contr = CAPIMSG_CONTROL(skb->data);
315
316
	application = cmtp_application_get(session, CMTP_MAPPING, appl);
317
	if (application) {
318
		appl = application->appl;
319
		CAPIMSG_SETAPPID(skb->data, appl);
320
	} else {
321
		BT_ERR("Can't find application with id %d", appl);
322
		kfree_skb(skb);
323
		return;
324
	}
325
326
	if ((contr & 0x7f) == 0x01) {
327
		contr = (contr & 0xffffff80) | session->num;
328
		CAPIMSG_SETCONTROL(skb->data, contr);
329
	}
330
331
	if (!ctrl) {
332
		BT_ERR("Can't find controller %d for message", session->num);
333
		kfree_skb(skb);
334
		return;
335
	}
336
337
	capi_ctr_handle_message(ctrl, appl, skb);
338
}
339
340
void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
341
{
342
	struct cmtp_scb *scb = (void *) skb->cb;
343
344
	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
345
346
	scb->id = -1;
347
	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
348
349
	skb_queue_tail(&session->transmit, skb);
350
351
	cmtp_schedule(session);
352
}
353
354
355
static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
356
{
357
	BT_DBG("ctrl %p data %p", ctrl, data);
358
359
	return 0;
360
}
361
362
static void cmtp_reset_ctr(struct capi_ctr *ctrl)
363
{
364
	struct cmtp_session *session = ctrl->driverdata;
365
366
	BT_DBG("ctrl %p", ctrl);
367
368
	capi_ctr_reseted(ctrl);
369
370
	atomic_inc(&session->terminate);
371
	cmtp_schedule(session);
372
}
373
374
static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
375
{
376
	DECLARE_WAITQUEUE(wait, current);
377
	struct cmtp_session *session = ctrl->driverdata;
378
	struct cmtp_application *application;
379
	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
380
	unsigned char buf[8];
381
	int err = 0, nconn, want = rp->level3cnt;
382
383
	BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
384
		ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
385
386
	application = cmtp_application_add(session, appl);
387
	if (!application) {
388
		BT_ERR("Can't allocate memory for new application");
389
		return;
390
	}
391
392
	if (want < 0)
393
		nconn = ctrl->profile.nbchannel * -want;
394
	else
395
		nconn = want;
396
397
	if (nconn == 0)
398
		nconn = ctrl->profile.nbchannel;
399
400
	capimsg_setu16(buf, 0, nconn);
401
	capimsg_setu16(buf, 2, rp->datablkcnt);
402
	capimsg_setu16(buf, 4, rp->datablklen);
403
404
	application->state = BT_CONFIG;
405
	application->msgnum = cmtp_msgnum_get(session);
406
407
	cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
408
				CAPI_FUNCTION_REGISTER, buf, 6);
409
410
	add_wait_queue(&session->wait, &wait);
411
	while (1) {
412
		set_current_state(TASK_INTERRUPTIBLE);
413
414
		if (!timeo) {
415
			err = -EAGAIN;
416
			break;
417
		}
418
419
		if (application->state == BT_CLOSED) {
420
			err = -application->err;
421
			break;
422
		}
423
424
		if (application->state == BT_CONNECTED)
425
			break;
426
427
		if (signal_pending(current)) {
428
			err = -EINTR;
429
			break;
430
		}
431
432
		timeo = schedule_timeout(timeo);
433
	}
434
	set_current_state(TASK_RUNNING);
435
	remove_wait_queue(&session->wait, &wait);
436
437
	if (err) {
438
		cmtp_application_del(session, application);
439
		return;
440
	}
441
}
442
443
static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
444
{
445
	DECLARE_WAITQUEUE(wait, current);
446
	struct cmtp_session *session = ctrl->driverdata;
447
	struct cmtp_application *application;
448
	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
449
450
	BT_DBG("ctrl %p appl %d", ctrl, appl);
451
452
	application = cmtp_application_get(session, CMTP_APPLID, appl);
453
	if (!application) {
454
		BT_ERR("Can't find application");
455
		return;
456
	}
457
458
	application->msgnum = cmtp_msgnum_get(session);
459
460
	cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
461
				CAPI_FUNCTION_RELEASE, NULL, 0);
462
463
	add_wait_queue(&session->wait, &wait);
464
	while (timeo) {
465
		set_current_state(TASK_INTERRUPTIBLE);
466
467
		if (application->state == BT_CLOSED)
468
			break;
469
470
		if (signal_pending(current))
471
			break;
472
473
		timeo = schedule_timeout(timeo);
474
	}
475
	set_current_state(TASK_RUNNING);
476
	remove_wait_queue(&session->wait, &wait);
477
478
	cmtp_application_del(session, application);
479
}
480
481
static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
482
{
483
	struct cmtp_session *session = ctrl->driverdata;
484
	struct cmtp_application *application;
485
	__u16 appl;
486
	__u32 contr;
487
488
	BT_DBG("ctrl %p skb %p", ctrl, skb);
489
490
	appl = CAPIMSG_APPID(skb->data);
491
	contr = CAPIMSG_CONTROL(skb->data);
492
493
	application = cmtp_application_get(session, CMTP_APPLID, appl);
494
	if ((!application) || (application->state != BT_CONNECTED)) {
495
		BT_ERR("Can't find application with id %d", appl);
496
		kfree_skb(skb);
497
		return CAPI_ILLAPPNR;
498
	}
499
500
	CAPIMSG_SETAPPID(skb->data, application->mapping);
501
502
	if ((contr & 0x7f) == session->num) {
503
		contr = (contr & 0xffffff80) | 0x01;
504
		CAPIMSG_SETCONTROL(skb->data, contr);
505
	}
506
507
	cmtp_send_capimsg(session, skb);
508
509
	return CAPI_NOERROR;
510
}
511
512
static char *cmtp_procinfo(struct capi_ctr *ctrl)
513
{
514
	return "CAPI Message Transport Protocol";
515
}
516
517
static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
518
{
519
	struct cmtp_session *session = ctrl->driverdata;
520
	struct cmtp_application *app;
521
	struct list_head *p, *n;
522
	int len = 0;
523
524
	len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
525
	len += sprintf(page + len, "addr %s\n", session->name);
526
	len += sprintf(page + len, "ctrl %d\n", session->num);
527
528
	list_for_each_safe(p, n, &session->applications) {
529
		app = list_entry(p, struct cmtp_application, list);
530
		len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
531
	}
532
533
	if (off + count >= len)
534
		*eof = 1;
535
536
	if (len < off)
537
		return 0;
538
539
	*start = page + off;
540
541
	return ((count < len - off) ? count : len - off);
542
}
543
544
545
int cmtp_attach_device(struct cmtp_session *session)
546
{
547
	DECLARE_WAITQUEUE(wait, current);
548
	unsigned long timeo = CMTP_INTEROP_TIMEOUT;
549
	unsigned char buf[4];
550
551
	BT_DBG("session %p", session);
552
553
	capimsg_setu32(buf, 0, 0);
554
555
	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
556
				CAPI_FUNCTION_GET_PROFILE, buf, 4);
557
558
	add_wait_queue(&session->wait, &wait);
559
	while (timeo) {
560
		set_current_state(TASK_INTERRUPTIBLE);
561
562
		if (session->ncontroller)
563
			break;
564
565
		if (signal_pending(current))
566
			break;
567
568
		timeo = schedule_timeout(timeo);
569
	}
570
	set_current_state(TASK_RUNNING);
571
	remove_wait_queue(&session->wait, &wait);
572
573
	BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
574
575
	if (!timeo)
576
		return -ETIMEDOUT;
577
578
	if (!session->ncontroller)
579
		return -ENODEV;
580
581
582
	if (session->ncontroller > 1)
583
		BT_INFO("Setting up only CAPI controller 1");
584
585
	session->ctrl.owner      = THIS_MODULE;
586
	session->ctrl.driverdata = session;
587
	strcpy(session->ctrl.name, session->name);
588
589
	session->ctrl.driver_name   = "cmtp";
590
	session->ctrl.load_firmware = cmtp_load_firmware;
591
	session->ctrl.reset_ctr     = cmtp_reset_ctr;
592
	session->ctrl.register_appl = cmtp_register_appl;
593
	session->ctrl.release_appl  = cmtp_release_appl;
594
	session->ctrl.send_message  = cmtp_send_message;
595
596
	session->ctrl.procinfo      = cmtp_procinfo;
597
	session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
598
599
	if (attach_capi_ctr(&session->ctrl) < 0) {
600
		BT_ERR("Can't attach new controller");
601
		return -EBUSY;
602
	}
603
604
	session->num = session->ctrl.cnr;
605
606
	BT_DBG("session %p num %d", session, session->num);
607
608
	capimsg_setu32(buf, 0, 1);
609
610
	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
611
				CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
612
613
	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
614
				CAPI_FUNCTION_GET_VERSION, buf, 4);
615
616
	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
617
				CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
618
619
	cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
620
				CAPI_FUNCTION_GET_PROFILE, buf, 4);
621
622
	return 0;
623
}
624
625
void cmtp_detach_device(struct cmtp_session *session)
626
{
627
	BT_DBG("session %p", session);
628
629
	detach_capi_ctr(&session->ctrl);
630
}
(-)linux-2.6.0/net/bluetooth/cmtp/cmtp.h (+136 lines)
Line 0 Link Here
1
/* 
2
   CMTP implementation for Linux Bluetooth stack (BlueZ).
3
   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License version 2 as
7
   published by the Free Software Foundation;
8
9
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
14
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
15
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
16
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
19
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
20
   SOFTWARE IS DISCLAIMED.
21
*/
22
23
#ifndef __CMTP_H
24
#define __CMTP_H
25
26
#include <linux/types.h>
27
#include <net/bluetooth/bluetooth.h>
28
29
#define BTNAMSIZ 18
30
31
/* CMTP ioctl defines */
32
#define CMTPCONNADD	_IOW('C', 200, int)
33
#define CMTPCONNDEL	_IOW('C', 201, int)
34
#define CMTPGETCONNLIST	_IOR('C', 210, int)
35
#define CMTPGETCONNINFO	_IOR('C', 211, int)
36
37
#define CMTP_LOOPBACK	0
38
39
struct cmtp_connadd_req {
40
	int   sock;	// Connected socket
41
	__u32 flags;
42
};
43
44
struct cmtp_conndel_req {
45
	bdaddr_t bdaddr;
46
	__u32    flags;
47
};
48
49
struct cmtp_conninfo {
50
	bdaddr_t bdaddr;
51
	__u32    flags;
52
	__u16    state;
53
	int      num;
54
};
55
56
struct cmtp_connlist_req {
57
	__u32  cnum;
58
	struct cmtp_conninfo *ci;
59
};
60
61
int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
62
int cmtp_del_connection(struct cmtp_conndel_req *req);
63
int cmtp_get_connlist(struct cmtp_connlist_req *req);
64
int cmtp_get_conninfo(struct cmtp_conninfo *ci);
65
66
/* CMTP session defines */
67
#define CMTP_INTEROP_TIMEOUT	(HZ * 5)
68
#define CMTP_INITIAL_MSGNUM	0xff00
69
70
struct cmtp_session {
71
	struct list_head list;
72
73
	struct socket *sock;
74
75
	bdaddr_t bdaddr;
76
77
	unsigned long state;
78
	unsigned long flags;
79
80
	uint mtu;
81
82
	char name[BTNAMSIZ];
83
84
	atomic_t terminate;
85
86
	wait_queue_head_t wait;
87
88
	int ncontroller;
89
	int num;
90
	struct capi_ctr ctrl;
91
92
	struct list_head applications;
93
94
	unsigned long blockids;
95
	int msgnum;
96
97
	struct sk_buff_head transmit;
98
99
	struct sk_buff *reassembly[16];
100
};
101
102
struct cmtp_application {
103
	struct list_head list;
104
105
	unsigned long state;
106
	int err;
107
108
	__u16 appl;
109
	__u16 mapping;
110
111
	__u16 msgnum;
112
};
113
114
struct cmtp_scb {
115
	int id;
116
	int data;
117
};
118
119
int  cmtp_attach_device(struct cmtp_session *session);
120
void cmtp_detach_device(struct cmtp_session *session);
121
122
void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
123
void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
124
125
static inline void cmtp_schedule(struct cmtp_session *session)
126
{
127
	struct sock *sk = session->sock->sk;
128
129
	wake_up_interruptible(sk->sk_sleep);
130
}
131
132
/* CMTP init defines */
133
int cmtp_init_sockets(void);
134
void cmtp_cleanup_sockets(void);
135
136
#endif /* __CMTP_H */
(-)linux-2.6.0/net/bluetooth/cmtp/core.c (+507 lines)
Line 0 Link Here
1
/* 
2
   CMTP implementation for Linux Bluetooth stack (BlueZ).
3
   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License version 2 as
7
   published by the Free Software Foundation;
8
9
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
14
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
15
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
16
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
19
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
20
   SOFTWARE IS DISCLAIMED.
21
*/
22
23
#include <linux/config.h>
24
#include <linux/module.h>
25
26
#include <linux/types.h>
27
#include <linux/errno.h>
28
#include <linux/kernel.h>
29
#include <linux/major.h>
30
#include <linux/sched.h>
31
#include <linux/slab.h>
32
#include <linux/poll.h>
33
#include <linux/fcntl.h>
34
#include <linux/skbuff.h>
35
#include <linux/socket.h>
36
#include <linux/ioctl.h>
37
#include <linux/file.h>
38
#include <linux/init.h>
39
#include <net/sock.h>
40
41
#include <linux/isdn/capilli.h>
42
43
#include <net/bluetooth/bluetooth.h>
44
#include <net/bluetooth/l2cap.h>
45
46
#include "cmtp.h"
47
48
#ifndef CONFIG_BT_CMTP_DEBUG
49
#undef  BT_DBG
50
#define BT_DBG(D...)
51
#endif
52
53
#define VERSION "1.0"
54
55
static DECLARE_RWSEM(cmtp_session_sem);
56
static LIST_HEAD(cmtp_session_list);
57
58
static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
59
{
60
	struct cmtp_session *session;
61
	struct list_head *p;
62
63
	BT_DBG("");
64
65
	list_for_each(p, &cmtp_session_list) {
66
		session = list_entry(p, struct cmtp_session, list);
67
		if (!bacmp(bdaddr, &session->bdaddr))
68
			return session;
69
	}
70
	return NULL;
71
}
72
73
static void __cmtp_link_session(struct cmtp_session *session)
74
{
75
	__module_get(THIS_MODULE);
76
	list_add(&session->list, &cmtp_session_list);
77
}
78
79
static void __cmtp_unlink_session(struct cmtp_session *session)
80
{
81
	list_del(&session->list);
82
	module_put(THIS_MODULE);
83
}
84
85
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
86
{
87
	bacpy(&ci->bdaddr, &session->bdaddr);
88
89
	ci->flags = session->flags;
90
	ci->state = session->state;
91
92
	ci->num = session->num;
93
}
94
95
96
static inline int cmtp_alloc_block_id(struct cmtp_session *session)
97
{
98
	int i, id = -1;
99
100
	for (i = 0; i < 16; i++)
101
		if (!test_and_set_bit(i, &session->blockids)) {
102
			id = i;
103
			break;
104
		}
105
106
	return id;
107
}
108
109
static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
110
{
111
	clear_bit(id, &session->blockids);
112
}
113
114
static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
115
{
116
	struct sk_buff *skb = session->reassembly[id], *nskb;
117
	int size;
118
119
	BT_DBG("session %p buf %p count %d", session, buf, count);
120
121
	size = (skb) ? skb->len + count : count;
122
123
	if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
124
		BT_ERR("Can't allocate memory for CAPI message");
125
		return;
126
	}
127
128
	if (skb && (skb->len > 0))
129
		memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
130
131
	memcpy(skb_put(nskb, count), buf, count);
132
133
	session->reassembly[id] = nskb;
134
135
	if (skb)
136
		kfree_skb(skb);
137
}
138
139
static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
140
{
141
	__u8 hdr, hdrlen, id;
142
	__u16 len;
143
144
	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
145
146
	while (skb->len > 0) {
147
		hdr = skb->data[0];
148
149
		switch (hdr & 0xc0) {
150
		case 0x40:
151
			hdrlen = 2;
152
			len = skb->data[1];
153
			break;
154
		case 0x80:
155
			hdrlen = 3;
156
			len = skb->data[1] | (skb->data[2] << 8);
157
			break;
158
		default:
159
			hdrlen = 1;
160
			len = 0;
161
			break;
162
		}
163
164
		id = (hdr & 0x3c) >> 2;
165
166
		BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
167
168
		if (hdrlen + len > skb->len) {
169
			BT_ERR("Wrong size or header information in CMTP frame");
170
			break;
171
		}
172
173
		if (len == 0) {
174
			skb_pull(skb, hdrlen);
175
			continue;
176
		}
177
178
		switch (hdr & 0x03) {
179
		case 0x00:
180
			cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
181
			cmtp_recv_capimsg(session, session->reassembly[id]);
182
			session->reassembly[id] = NULL;
183
			break;
184
		case 0x01:
185
			cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
186
			break;
187
		default:
188
			if (session->reassembly[id] != NULL)
189
				kfree_skb(session->reassembly[id]);
190
			session->reassembly[id] = NULL;
191
			break;
192
		}
193
194
		skb_pull(skb, hdrlen + len);
195
	}
196
197
	kfree_skb(skb);
198
	return 0;
199
}
200
201
static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
202
{
203
	struct socket *sock = session->sock;
204
	struct iovec iv = { data, len };
205
	struct msghdr msg;
206
207
	BT_DBG("session %p data %p len %d", session, data, len);
208
209
	if (!len)
210
		return 0;
211
212
	memset(&msg, 0, sizeof(msg));
213
	msg.msg_iovlen = 1;
214
	msg.msg_iov = &iv;
215
216
	return sock_sendmsg(sock, &msg, len);
217
}
218
219
static int cmtp_process_transmit(struct cmtp_session *session)
220
{
221
	struct sk_buff *skb, *nskb;
222
	unsigned char *hdr;
223
	unsigned int size, tail;
224
225
	BT_DBG("session %p", session);
226
227
	if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
228
		BT_ERR("Can't allocate memory for new frame");
229
		return -ENOMEM;
230
	}
231
232
	while ((skb = skb_dequeue(&session->transmit))) {
233
		struct cmtp_scb *scb = (void *) skb->cb;
234
235
		if ((tail = (session->mtu - nskb->len)) < 5) {
236
			cmtp_send_frame(session, nskb->data, nskb->len);
237
			skb_trim(nskb, 0);
238
			tail = session->mtu;
239
		}
240
241
		size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
242
243
		if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
244
			skb_queue_head(&session->transmit, skb);
245
			break;
246
		}
247
248
		if (size < 256) {
249
			hdr = skb_put(nskb, 2);
250
			hdr[0] = 0x40
251
				| ((scb->id << 2) & 0x3c)
252
				| ((skb->len == size) ? 0x00 : 0x01);
253
			hdr[1] = size;
254
		} else {
255
			hdr = skb_put(nskb, 3);
256
			hdr[0] = 0x80
257
				| ((scb->id << 2) & 0x3c)
258
				| ((skb->len == size) ? 0x00 : 0x01);
259
			hdr[1] = size & 0xff;
260
			hdr[2] = size >> 8;
261
		}
262
263
		memcpy(skb_put(nskb, size), skb->data, size);
264
		skb_pull(skb, size);
265
266
		if (skb->len > 0) {
267
			skb_queue_head(&session->transmit, skb);
268
		} else {
269
			cmtp_free_block_id(session, scb->id);
270
			if (scb->data) {
271
				cmtp_send_frame(session, nskb->data, nskb->len);
272
				skb_trim(nskb, 0);
273
			}
274
			kfree_skb(skb);
275
		}
276
	}
277
278
	cmtp_send_frame(session, nskb->data, nskb->len);
279
280
	kfree_skb(nskb);
281
282
	return skb_queue_len(&session->transmit);
283
}
284
285
static int cmtp_session(void *arg)
286
{
287
	struct cmtp_session *session = arg;
288
	struct sock *sk = session->sock->sk;
289
	struct sk_buff *skb;
290
	wait_queue_t wait;
291
292
	BT_DBG("session %p", session);
293
294
	daemonize("kcmtpd_ctr_%d", session->num);
295
	set_user_nice(current, -15);
296
	current->flags |= PF_IOTHREAD;
297
298
	set_fs(KERNEL_DS);
299
300
	init_waitqueue_entry(&wait, current);
301
	add_wait_queue(sk->sk_sleep, &wait);
302
	while (!atomic_read(&session->terminate)) {
303
		set_current_state(TASK_INTERRUPTIBLE);
304
305
		if (sk->sk_state != BT_CONNECTED)
306
			break;
307
308
		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
309
			skb_orphan(skb);
310
			cmtp_recv_frame(session, skb);
311
		}
312
313
		cmtp_process_transmit(session);
314
315
		schedule();
316
	}
317
	set_current_state(TASK_RUNNING);
318
	remove_wait_queue(sk->sk_sleep, &wait);
319
320
	down_write(&cmtp_session_sem);
321
322
	if (!(session->flags & (1 << CMTP_LOOPBACK)))
323
		cmtp_detach_device(session);
324
325
	fput(session->sock->file);
326
327
	__cmtp_unlink_session(session);
328
329
	up_write(&cmtp_session_sem);
330
331
	kfree(session);
332
	return 0;
333
}
334
335
int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
336
{
337
	struct cmtp_session *session, *s;
338
	bdaddr_t src, dst;
339
	int i, err;
340
341
	BT_DBG("");
342
343
	baswap(&src, &bt_sk(sock->sk)->src);
344
	baswap(&dst, &bt_sk(sock->sk)->dst);
345
346
	session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
347
	if (!session) 
348
		return -ENOMEM;
349
	memset(session, 0, sizeof(struct cmtp_session));
350
351
	down_write(&cmtp_session_sem);
352
353
	s = __cmtp_get_session(&bt_sk(sock->sk)->dst);
354
	if (s && s->state == BT_CONNECTED) {
355
		err = -EEXIST;
356
		goto failed;
357
	}
358
359
	bacpy(&session->bdaddr, &bt_sk(sock->sk)->dst);
360
361
	session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
362
363
	BT_DBG("mtu %d", session->mtu);
364
365
	sprintf(session->name, "%s", batostr(&dst));
366
367
	session->sock  = sock;
368
	session->state = BT_CONFIG;
369
370
	init_waitqueue_head(&session->wait);
371
372
	session->msgnum = CMTP_INITIAL_MSGNUM;
373
374
	INIT_LIST_HEAD(&session->applications);
375
376
	skb_queue_head_init(&session->transmit);
377
378
	for (i = 0; i < 16; i++)
379
		session->reassembly[i] = NULL;
380
381
	session->flags = req->flags;
382
383
	__cmtp_link_session(session);
384
385
	err = kernel_thread(cmtp_session, session, CLONE_KERNEL);
386
	if (err < 0)
387
		goto unlink;
388
389
	if (!(session->flags & (1 << CMTP_LOOPBACK))) {
390
		err = cmtp_attach_device(session);
391
		if (err < 0)
392
			goto detach;
393
	}
394
395
	up_write(&cmtp_session_sem);
396
	return 0;
397
398
detach:
399
	cmtp_detach_device(session);
400
401
unlink:
402
	__cmtp_unlink_session(session);
403
404
failed:
405
	up_write(&cmtp_session_sem);
406
	kfree(session);
407
	return err;
408
}
409
410
int cmtp_del_connection(struct cmtp_conndel_req *req)
411
{
412
	struct cmtp_session *session;
413
	int err = 0;
414
415
	BT_DBG("");
416
417
	down_read(&cmtp_session_sem);
418
419
	session = __cmtp_get_session(&req->bdaddr);
420
	if (session) {
421
		/* Flush the transmit queue */
422
		skb_queue_purge(&session->transmit);
423
424
		/* Kill session thread */
425
		atomic_inc(&session->terminate);
426
		cmtp_schedule(session);
427
	} else
428
		err = -ENOENT;
429
430
	up_read(&cmtp_session_sem);
431
	return err;
432
}
433
434
int cmtp_get_connlist(struct cmtp_connlist_req *req)
435
{
436
	struct list_head *p;
437
	int err = 0, n = 0;
438
439
	BT_DBG("");
440
441
	down_read(&cmtp_session_sem);
442
443
	list_for_each(p, &cmtp_session_list) {
444
		struct cmtp_session *session;
445
		struct cmtp_conninfo ci;
446
447
		session = list_entry(p, struct cmtp_session, list);
448
449
		__cmtp_copy_session(session, &ci);
450
451
		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
452
			err = -EFAULT;
453
			break;
454
		}
455
456
		if (++n >= req->cnum)
457
			break;
458
459
		req->ci++;
460
	}
461
	req->cnum = n;
462
463
	up_read(&cmtp_session_sem);
464
	return err;
465
}
466
467
int cmtp_get_conninfo(struct cmtp_conninfo *ci)
468
{
469
	struct cmtp_session *session;
470
	int err = 0;
471
472
	down_read(&cmtp_session_sem);
473
474
	session = __cmtp_get_session(&ci->bdaddr);
475
	if (session)
476
		__cmtp_copy_session(session, ci);
477
	else
478
		err = -ENOENT;
479
480
	up_read(&cmtp_session_sem);
481
	return err;
482
}
483
484
485
int __init init_cmtp(void)
486
{
487
	l2cap_load();
488
489
	BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION);
490
491
	cmtp_init_sockets();
492
493
	return 0;
494
}
495
496
void __exit exit_cmtp(void)
497
{
498
	cmtp_cleanup_sockets();
499
}
500
501
module_init(init_cmtp);
502
module_exit(exit_cmtp);
503
504
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
505
MODULE_DESCRIPTION("Bluetooth CMTP ver " VERSION);
506
MODULE_LICENSE("GPL");
507
MODULE_ALIAS("bt-proto-5");
(-)linux-2.6.0/net/bluetooth/cmtp/Kconfig (+11 lines)
Line 0 Link Here
1
config BT_CMTP
2
	tristate "CMTP protocol support"
3
	depends on BT && BT_L2CAP && ISDN_CAPI
4
	help
5
	  CMTP (CAPI Message Transport Protocol) is a transport layer
6
	  for CAPI messages. CMTP is required for the Bluetooth Common
7
	  ISDN Access Profile.
8
9
	  Say Y here to compile CMTP support into the kernel or say M to
10
	  compile it as module (cmtp).
11
(-)linux-2.6.0/net/bluetooth/cmtp/Makefile (+7 lines)
Line 0 Link Here
1
#
2
# Makefile for the Linux Bluetooth CMTP layer
3
#
4
5
obj-$(CONFIG_BT_CMTP) += cmtp.o
6
7
cmtp-objs := core.o sock.o capi.o
(-)linux-2.6.0/net/bluetooth/cmtp/sock.c (+198 lines)
Line 0 Link Here
1
/* 
2
   CMTP implementation for Linux Bluetooth stack (BlueZ).
3
   Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License version 2 as
7
   published by the Free Software Foundation;
8
9
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
14
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
15
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
16
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18
   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
19
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
20
   SOFTWARE IS DISCLAIMED.
21
*/
22
23
#include <linux/config.h>
24
#include <linux/module.h>
25
26
#include <linux/types.h>
27
#include <linux/errno.h>
28
#include <linux/kernel.h>
29
#include <linux/major.h>
30
#include <linux/sched.h>
31
#include <linux/slab.h>
32
#include <linux/poll.h>
33
#include <linux/fcntl.h>
34
#include <linux/skbuff.h>
35
#include <linux/socket.h>
36
#include <linux/ioctl.h>
37
#include <linux/file.h>
38
#include <net/sock.h>
39
40
#include <linux/isdn/capilli.h>
41
42
#include <asm/system.h>
43
#include <asm/uaccess.h>
44
45
#include "cmtp.h"
46
47
#ifndef CONFIG_BT_CMTP_DEBUG
48
#undef  BT_DBG
49
#define BT_DBG(D...)
50
#endif
51
52
static int cmtp_sock_release(struct socket *sock)
53
{
54
	struct sock *sk = sock->sk;
55
56
	BT_DBG("sock %p sk %p", sock, sk);
57
58
	if (!sk)
59
		return 0;
60
61
	sock_orphan(sk);
62
	sock_put(sk);
63
64
	return 0;
65
}
66
67
static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
68
{
69
	struct cmtp_connadd_req ca;
70
	struct cmtp_conndel_req cd;
71
	struct cmtp_connlist_req cl;
72
	struct cmtp_conninfo ci;
73
	struct socket *nsock;
74
	int err;
75
76
	BT_DBG("cmd %x arg %lx", cmd, arg);
77
78
	switch (cmd) {
79
	case CMTPCONNADD:
80
		if (!capable(CAP_NET_ADMIN))
81
			return -EACCES;
82
83
		if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
84
			return -EFAULT;
85
86
		nsock = sockfd_lookup(ca.sock, &err);
87
		if (!nsock)
88
			return err;
89
90
		if (nsock->sk->sk_state != BT_CONNECTED)
91
			return -EBADFD;
92
93
		err = cmtp_add_connection(&ca, nsock);
94
		if (!err) {
95
			if (copy_to_user((void *) arg, &ca, sizeof(ca)))
96
				err = -EFAULT;
97
		} else
98
			fput(nsock->file);
99
100
		return err;
101
102
	case CMTPCONNDEL:
103
		if (!capable(CAP_NET_ADMIN))
104
			return -EACCES;
105
106
		if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
107
			return -EFAULT;
108
109
		return cmtp_del_connection(&cd);
110
111
	case CMTPGETCONNLIST:
112
		if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
113
			return -EFAULT;
114
115
		if (cl.cnum <= 0)
116
			return -EINVAL;
117
118
		err = cmtp_get_connlist(&cl);
119
		if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
120
			return -EFAULT;
121
122
		return err;
123
124
	case CMTPGETCONNINFO:
125
		if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
126
			return -EFAULT;
127
128
		err = cmtp_get_conninfo(&ci);
129
		if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
130
			return -EFAULT;
131
132
		return err;
133
	}
134
135
	return -EINVAL;
136
}
137
138
static struct proto_ops cmtp_sock_ops = {
139
	.family		= PF_BLUETOOTH,
140
	.owner		= THIS_MODULE,
141
	.release	= cmtp_sock_release,
142
	.ioctl		= cmtp_sock_ioctl,
143
	.bind		= sock_no_bind,
144
	.getname	= sock_no_getname,
145
	.sendmsg	= sock_no_sendmsg,
146
	.recvmsg	= sock_no_recvmsg,
147
	.poll		= sock_no_poll,
148
	.listen		= sock_no_listen,
149
	.shutdown	= sock_no_shutdown,
150
	.setsockopt	= sock_no_setsockopt,
151
	.getsockopt	= sock_no_getsockopt,
152
	.connect	= sock_no_connect,
153
	.socketpair	= sock_no_socketpair,
154
	.accept		= sock_no_accept,
155
	.mmap		= sock_no_mmap
156
};
157
158
static int cmtp_sock_create(struct socket *sock, int protocol)
159
{
160
	struct sock *sk;
161
162
	BT_DBG("sock %p", sock);
163
164
	if (sock->type != SOCK_RAW)
165
		return -ESOCKTNOSUPPORT;
166
167
	sock->ops = &cmtp_sock_ops;
168
169
	if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL)))
170
		return -ENOMEM;
171
172
	sock->ops = &cmtp_sock_ops;
173
174
	sock->state = SS_UNCONNECTED;
175
176
	sk->sk_destruct = NULL;
177
	sk->sk_protocol = protocol;
178
179
	return 0;
180
}
181
182
static struct net_proto_family cmtp_sock_family_ops = {
183
	.family =	PF_BLUETOOTH,
184
	.create =	cmtp_sock_create
185
};
186
187
int cmtp_init_sockets(void)
188
{
189
	bt_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops);
190
191
	return 0;
192
}
193
194
void cmtp_cleanup_sockets(void)
195
{
196
	if (bt_sock_unregister(BTPROTO_CMTP))
197
		BT_ERR("Can't unregister CMTP socket");
198
}
(-)linux-2.6.0/net/bluetooth/hci_event.c (+27 lines)
Lines 452-457 Link Here
452
	hci_dev_unlock(hdev);
452
	hci_dev_unlock(hdev);
453
}
453
}
454
454
455
/* Inquiry Result With RSSI */
456
static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
457
{
458
	struct inquiry_info_with_rssi *info = (struct inquiry_info_with_rssi *) (skb->data + 1);
459
	int num_rsp = *((__u8 *) skb->data);
460
461
	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
462
463
	hci_dev_lock(hdev);
464
	for (; num_rsp; num_rsp--) {
465
		struct inquiry_info tmp;
466
		bacpy(&tmp.bdaddr, &info->bdaddr);
467
		tmp.pscan_rep_mode    = info->pscan_rep_mode;
468
		tmp.pscan_period_mode = info->pscan_period_mode;
469
		tmp.pscan_mode        = 0x00;
470
		memcpy(tmp.dev_class, &info->dev_class, 3);
471
		tmp.clock_offset      = info->clock_offset;
472
		info++;
473
		inquiry_cache_update(hdev, &tmp);
474
	}
475
	hci_dev_unlock(hdev);
476
}
477
455
/* Connect Request */
478
/* Connect Request */
456
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
479
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
457
{
480
{
Lines 744-749 Link Here
744
		hci_inquiry_result_evt(hdev, skb);
767
		hci_inquiry_result_evt(hdev, skb);
745
		break;
768
		break;
746
769
770
	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
771
		hci_inquiry_result_with_rssi_evt(hdev, skb);
772
		break;
773
747
	case HCI_EV_CONN_REQUEST:
774
	case HCI_EV_CONN_REQUEST:
748
		hci_conn_request_evt(hdev, skb);
775
		hci_conn_request_evt(hdev, skb);
749
		break;
776
		break;
(-)linux-2.6.0/net/bluetooth/hci_sock.c (-6 / +6 lines)
Lines 66-85 Link Here
66
	/* Packet types */
66
	/* Packet types */
67
	0x10,
67
	0x10,
68
	/* Events */
68
	/* Events */
69
	{ 0xd9fe, 0x0 },
69
	{ 0x1000d9fe, 0x0000300c },
70
	/* Commands */
70
	/* Commands */
71
	{
71
	{
72
		{ 0x0 },
72
		{ 0x0 },
73
		/* OGF_LINK_CTL */
73
		/* OGF_LINK_CTL */
74
		{ 0x2a000002, 0x0, 0x0, 0x0  },
74
		{ 0xbe000006, 0x00000001, 0x0000, 0x00 },
75
		/* OGF_LINK_POLICY */
75
		/* OGF_LINK_POLICY */
76
		{ 0x1200, 0x0, 0x0, 0x0      },
76
		{ 0x00005200, 0x00000000, 0x0000, 0x00 },
77
		/* OGF_HOST_CTL */
77
		/* OGF_HOST_CTL */
78
		{ 0x80100000, 0x202a, 0x0, 0x0 },
78
		{ 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
79
		/* OGF_INFO_PARAM */
79
		/* OGF_INFO_PARAM */
80
		{ 0x22a, 0x0, 0x0, 0x0       },
80
		{ 0x000002be, 0x00000000, 0x0000, 0x00 },
81
		/* OGF_STATUS_PARAM */
81
		/* OGF_STATUS_PARAM */
82
		{ 0x2e, 0x0, 0x0, 0x0        }
82
		{ 0x000000ea, 0x00000000, 0x0000, 0x00 }
83
	}
83
	}
84
};
84
};
85
85
(-)linux-2.6.0/net/bluetooth/Kconfig (+3 lines)
Lines 21-26 Link Here
21
	     SCO Module (SCO links)
21
	     SCO Module (SCO links)
22
	     RFCOMM Module (RFCOMM protocol)  
22
	     RFCOMM Module (RFCOMM protocol)  
23
	     BNEP Module (BNEP protocol)
23
	     BNEP Module (BNEP protocol)
24
	     CMTP Module (CMTP protocol)
24
25
25
	  Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
26
	  Say Y here to enable Linux Bluetooth support and to build Bluetooth Core
26
	  layer.
27
	  layer.
Lines 57-62 Link Here
57
58
58
source "net/bluetooth/bnep/Kconfig"
59
source "net/bluetooth/bnep/Kconfig"
59
60
61
source "net/bluetooth/cmtp/Kconfig"
62
60
source "drivers/bluetooth/Kconfig"
63
source "drivers/bluetooth/Kconfig"
61
64
62
endmenu
65
endmenu
(-)linux-2.6.0/net/bluetooth/l2cap.c (+1 lines)
Lines 2201-2203 Link Here
2201
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
2201
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
2202
MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
2202
MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
2203
MODULE_LICENSE("GPL");
2203
MODULE_LICENSE("GPL");
2204
MODULE_ALIAS("bt-proto-0");
(-)linux-2.6.0/net/bluetooth/Makefile (+1 lines)
Lines 7-11 Link Here
7
obj-$(CONFIG_BT_SCO)	+= sco.o
7
obj-$(CONFIG_BT_SCO)	+= sco.o
8
obj-$(CONFIG_BT_RFCOMM)	+= rfcomm/
8
obj-$(CONFIG_BT_RFCOMM)	+= rfcomm/
9
obj-$(CONFIG_BT_BNEP)	+= bnep/
9
obj-$(CONFIG_BT_BNEP)	+= bnep/
10
obj-$(CONFIG_BT_CMTP)	+= cmtp/
10
11
11
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_proc.o lib.o syms.o
12
bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_proc.o lib.o syms.o
(-)linux-2.6.0/net/bluetooth/rfcomm/core.c (-32 / +27 lines)
Lines 52-58 Link Here
52
#include <net/bluetooth/l2cap.h>
52
#include <net/bluetooth/l2cap.h>
53
#include <net/bluetooth/rfcomm.h>
53
#include <net/bluetooth/rfcomm.h>
54
54
55
#define VERSION "1.0"
55
#define VERSION "1.1"
56
56
57
#ifndef CONFIG_BT_RFCOMM_DEBUG
57
#ifndef CONFIG_BT_RFCOMM_DEBUG
58
#undef  BT_DBG
58
#undef  BT_DBG
Lines 207-213 Link Here
207
	d->mtu        = RFCOMM_DEFAULT_MTU;
207
	d->mtu        = RFCOMM_DEFAULT_MTU;
208
	d->v24_sig    = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
208
	d->v24_sig    = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
209
209
210
	d->credits    = RFCOMM_MAX_CREDITS;
210
	d->cfc        = RFCOMM_CFC_DISABLED;
211
	d->rx_credits = RFCOMM_DEFAULT_CREDITS;
211
	d->rx_credits = RFCOMM_DEFAULT_CREDITS;
212
}
212
}
213
213
Lines 314-321 Link Here
314
	d->state    = BT_CONFIG;
314
	d->state    = BT_CONFIG;
315
	rfcomm_dlc_link(s, d);
315
	rfcomm_dlc_link(s, d);
316
316
317
	d->mtu     = s->mtu;
317
	d->mtu = s->mtu;
318
	d->credits = s->credits;
318
	d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
319
319
320
	if (s->state == BT_CONNECTED)
320
	if (s->state == BT_CONNECTED)
321
		rfcomm_send_pn(s, 1, d);
321
		rfcomm_send_pn(s, 1, d);
Lines 415-421 Link Here
415
{
415
{
416
	BT_DBG("dlc %p state %ld", d, d->state);
416
	BT_DBG("dlc %p state %ld", d, d->state);
417
417
418
	if (!d->credits) {
418
	if (!d->cfc) {
419
		d->v24_sig |= RFCOMM_V24_FC;
419
		d->v24_sig |= RFCOMM_V24_FC;
420
		set_bit(RFCOMM_MSC_PENDING, &d->flags);
420
		set_bit(RFCOMM_MSC_PENDING, &d->flags);
421
	}
421
	}
Lines 426-432 Link Here
426
{
426
{
427
	BT_DBG("dlc %p state %ld", d, d->state);
427
	BT_DBG("dlc %p state %ld", d, d->state);
428
428
429
	if (!d->credits) {
429
	if (!d->cfc) {
430
		d->v24_sig &= ~RFCOMM_V24_FC;
430
		d->v24_sig &= ~RFCOMM_V24_FC;
431
		set_bit(RFCOMM_MSC_PENDING, &d->flags);
431
		set_bit(RFCOMM_MSC_PENDING, &d->flags);
432
	}
432
	}
Lines 479-486 Link Here
479
	s->state = state;
479
	s->state = state;
480
	s->sock  = sock;
480
	s->sock  = sock;
481
481
482
	s->mtu     = RFCOMM_DEFAULT_MTU;
482
	s->mtu   = RFCOMM_DEFAULT_MTU;
483
	s->credits = RFCOMM_MAX_CREDITS;
483
	s->cfc   = RFCOMM_CFC_UNKNOWN;
484
	
484
	
485
	list_add(&s->list, &session_list);
485
	list_add(&s->list, &session_list);
486
486
Lines 752-758 Link Here
752
	pn->ack_timer   = 0;
752
	pn->ack_timer   = 0;
753
	pn->max_retrans = 0;
753
	pn->max_retrans = 0;
754
754
755
	if (d->credits) {
755
	if (s->cfc) {
756
		pn->flow_ctrl = cr ? 0xf0 : 0xe0;
756
		pn->flow_ctrl = cr ? 0xf0 : 0xe0;
757
		pn->credits = RFCOMM_DEFAULT_CREDITS;
757
		pn->credits = RFCOMM_DEFAULT_CREDITS;
758
	} else {
758
	} else {
Lines 1142-1169 Link Here
1142
1142
1143
static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1143
static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
1144
{
1144
{
1145
	struct rfcomm_session *s = d->session;
1146
1145
	BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", 
1147
	BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d", 
1146
			d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1148
			d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
1147
1149
1148
	if (cr) {
1150
	if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {
1149
		if (pn->flow_ctrl == 0xf0) {
1151
		d->cfc = s->cfc = RFCOMM_CFC_ENABLED;
1150
			d->tx_credits = pn->credits;
1152
		d->tx_credits = pn->credits;
1151
		} else {
1152
			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1153
			d->credits = 0;
1154
		}
1155
	} else {
1153
	} else {
1156
		if (pn->flow_ctrl == 0xe0) {
1154
		d->cfc = s->cfc = RFCOMM_CFC_DISABLED;
1157
			d->tx_credits = pn->credits;
1155
		set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1158
		} else {
1159
			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1160
			d->credits = 0;
1161
		}
1162
	}
1156
	}
1163
1157
1164
	d->priority = pn->priority;
1158
	d->priority = pn->priority;
1165
1159
1166
	d->mtu = btohs(pn->mtu);
1160
	d->mtu = s->mtu = btohs(pn->mtu);
1167
1161
1168
	return 0;
1162
	return 0;
1169
}
1163
}
Lines 1353-1359 Link Here
1353
		return 0;
1347
		return 0;
1354
1348
1355
	if (cr) {
1349
	if (cr) {
1356
		if (msc->v24_sig & RFCOMM_V24_FC && !d->credits)
1350
		if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
1357
			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1351
			set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1358
		else
1352
		else
1359
			clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
1353
			clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
Lines 1444-1450 Link Here
1444
		goto drop;
1438
		goto drop;
1445
	}
1439
	}
1446
1440
1447
	if (pf && d->credits) {
1441
	if (pf && d->cfc) {
1448
		u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1442
		u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
1449
1443
1450
		d->tx_credits += credits;
1444
		d->tx_credits += credits;
Lines 1549-1568 Link Here
1549
	struct sk_buff *skb;
1543
	struct sk_buff *skb;
1550
	int err;
1544
	int err;
1551
1545
1552
	BT_DBG("dlc %p state %ld credits %d rx_credits %d tx_credits %d", 
1546
	BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d", 
1553
			d, d->state, d->credits, d->rx_credits, d->tx_credits);
1547
			d, d->state, d->cfc, d->rx_credits, d->tx_credits);
1554
1548
1555
	/* Send pending MSC */
1549
	/* Send pending MSC */
1556
	if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
1550
	if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
1557
		rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); 
1551
		rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig); 
1558
	
1552
	
1559
	if (d->credits) {
1553
	if (d->cfc) {
1560
		/* CFC enabled. 
1554
		/* CFC enabled. 
1561
		 * Give them some credits */
1555
		 * Give them some credits */
1562
		if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
1556
		if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
1563
			       	d->rx_credits <= (d->credits >> 2)) {
1557
			       	d->rx_credits <= (d->cfc >> 2)) {
1564
			rfcomm_send_credits(d->session, d->addr, d->credits - d->rx_credits);
1558
			rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
1565
			d->rx_credits = d->credits;
1559
			d->rx_credits = d->cfc;
1566
		}
1560
		}
1567
	} else {
1561
	} else {
1568
		/* CFC disabled.
1562
		/* CFC disabled.
Lines 1583-1589 Link Here
1583
		d->tx_credits--;
1577
		d->tx_credits--;
1584
	}
1578
	}
1585
1579
1586
	if (d->credits && !d->tx_credits) {
1580
	if (d->cfc && !d->tx_credits) {
1587
		/* We're out of TX credits.
1581
		/* We're out of TX credits.
1588
		 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1582
		 * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
1589
		set_bit(RFCOMM_TX_THROTTLED, &d->flags);
1583
		set_bit(RFCOMM_TX_THROTTLED, &d->flags);
Lines 1998-2000 Link Here
1998
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
1992
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
1999
MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
1993
MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
2000
MODULE_LICENSE("GPL");
1994
MODULE_LICENSE("GPL");
1995
MODULE_ALIAS("bt-proto-3");
(-)linux-2.6.0/net/bluetooth/sco.c (+1 lines)
Lines 1054-1056 Link Here
1054
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
1054
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
1055
MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
1055
MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
1056
MODULE_LICENSE("GPL");
1056
MODULE_LICENSE("GPL");
1057
MODULE_ALIAS("bt-proto-2");

Return to bug 37696