1 diff -urN linux-2.4.18/CREDITS linux-2.4.18-mh9/CREDITS
2 --- linux-2.4.18/CREDITS Mon Feb 25 20:37:50 2002
3 +++ linux-2.4.18-mh9/CREDITS Mon Aug 25 18:38:09 2003
5 S: Provo, Utah 84606-5607
9 +E: marcel@holtmann.org
10 +W: http://www.holtmann.org
11 +D: Author and maintainer of the various Bluetooth HCI drivers
12 +D: Author and maintainer of the CAPI message transport protocol driver
13 +D: Various other Bluetooth related patches, cleanups and fixes
17 E: hooft@EMBL-Heidelberg.DE
18 D: Shared libs for graphics-tools and for the f2c compiler
19 diff -urN linux-2.4.18/Documentation/Configure.help linux-2.4.18-mh9/Documentation/Configure.help
20 --- linux-2.4.18/Documentation/Configure.help Mon Feb 25 20:37:51 2002
21 +++ linux-2.4.18-mh9/Documentation/Configure.help Mon Aug 25 18:38:10 2003
22 @@ -2824,14 +2824,6 @@
26 -HCI EMU (virtual device) driver
28 - Bluetooth Virtual HCI device driver.
29 - This driver is required if you want to use HCI Emulation software.
31 - Say Y here to compile support for Virtual HCI devices into the
32 - kernel or say M to compile it as module (hci_usb.o).
37 @@ -11037,6 +11029,12 @@
41 +Hotplug firmware loading support (EXPERIMENTAL)
43 + This option is provided for the case where no in-kernel-tree modules require
44 + hotplug firmware loading support, but a module built outside the kernel tree
47 Use PCI shared memory for NIC registers
49 Use PCI shared memory for the NIC registers, rather than going through
50 @@ -19870,11 +19868,15 @@
51 Bluetooth can be found at <http://www.bluetooth.com/>.
53 Linux Bluetooth subsystem consist of several layers:
54 - HCI Core (device and connection manager, scheduler)
55 + BlueZ Core (HCI device and connection manager, scheduler)
56 HCI Device drivers (interface to the hardware)
57 L2CAP Module (L2CAP protocol)
58 + SCO Module (SCO links)
59 + RFCOMM Module (RFCOMM protocol)
60 + BNEP Module (BNEP protocol)
61 + CMTP Module (CMTP protocol)
63 - Say Y here to enable Linux Bluetooth support and to build HCI Core
64 + Say Y here to enable Linux Bluetooth support and to build BlueZ Core
67 To use Linux Bluetooth subsystem, you will need several user-space
68 @@ -19882,7 +19884,7 @@
69 Bluetooth kernel modules are provided in the BlueZ package.
70 For more information, see <http://bluez.sourceforge.net/>.
72 - If you want to compile HCI Core as module (hci.o) say M here.
73 + If you want to compile BlueZ Core as module (bluez.o) say M here.
75 L2CAP protocol support
77 @@ -19893,15 +19895,91 @@
78 Say Y here to compile L2CAP support into the kernel or say M to
79 compile it as module (l2cap.o).
83 + SCO link provides voice transport over Bluetooth. SCO support is
84 + required for voice applications like Headset and Audio.
86 + Say Y here to compile SCO support into the kernel or say M to
87 + compile it as module (sco.o).
89 +RFCOMM protocol support
91 + RFCOMM provides connection oriented stream transport. RFCOMM
92 + support is required for Dialup Networking, OBEX and other Bluetooth
95 + Say Y here to compile RFCOMM support into the kernel or say M to
96 + compile it as module (rfcomm.o).
98 +RFCOMM TTY emulation support
99 +CONFIG_BLUEZ_RFCOMM_TTY
100 + This option enables TTY emulation support for RFCOMM channels.
102 +BNEP protocol support
104 + BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
105 + emulation layer on top of Bluetooth. BNEP is required for Bluetooth
106 + PAN (Personal Area Network).
108 + To use BNEP, you will need user-space utilities provided in the
110 + For more information, see <http://bluez.sourceforge.net>.
112 + Say Y here to compile BNEP support into the kernel or say M to
113 + compile it as module (bnep.o).
115 +CMTP protocol support
117 + CMTP (CAPI Message Transport Protocol) is a transport layer
118 + for CAPI messages. CMTP is required for the Bluetooth Common
119 + ISDN Access Profile.
121 + Say Y here to compile CMTP support into the kernel or say M to
122 + compile it as module (cmtp.o).
124 +BNEP multicast filter support
125 +CONFIG_BLUEZ_BNEP_MC_FILTER
126 + This option enables the multicast filter support for BNEP.
128 +BNEP protocol filter support
129 +CONFIG_BLUEZ_BNEP_PROTO_FILTER
130 + This option enables the protocol filter support for BNEP.
134 Bluetooth HCI UART driver.
135 This driver is required if you want to use Bluetooth devices with
136 - serial port interface.
137 + serial port interface. You will also need this driver if you have
138 + UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
139 + adapter and BrainBoxes Bluetooth PC Card.
141 Say Y here to compile support for Bluetooth UART devices into the
142 kernel or say M to compile it as module (hci_uart.o).
144 +HCI UART (H4) protocol support
145 +CONFIG_BLUEZ_HCIUART_H4
146 + UART (H4) is serial protocol for communication between Bluetooth
147 + device and host. This protocol is required for most Bluetooth devices
148 + with UART interface, including PCMCIA and CF cards.
150 + Say Y here to compile support for HCI UART (H4) protocol.
152 +HCI BCSP protocol support
153 +CONFIG_BLUEZ_HCIUART_BCSP
154 + BCSP (BlueCore Serial Protocol) is serial protocol for communication
155 + between Bluetooth device and host. This protocol is required for non
156 + USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
159 + Say Y here to compile support for HCI BCSP protocol.
161 +HCI BCSP transmit CRC with every BCSP packet
162 +CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
163 + If you say Y here, a 16-bit CRC checksum will be transmitted along with
164 + every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
165 + This increases reliability, but slightly reduces efficiency.
169 Bluetooth HCI USB driver.
170 @@ -19911,13 +19989,90 @@
171 Say Y here to compile support for Bluetooth USB devices into the
172 kernel or say M to compile it as module (hci_usb.o).
174 -HCI VHCI virtual HCI device driver
175 +HCI USB SCO (voice) support
176 +CONFIG_BLUEZ_USB_SCO
177 + This option enables the SCO support in the HCI USB driver. You need this
178 + to transmit voice data with your Bluetooth USB device. And your device
179 + must also support sending SCO data over the HCI layer, because some of
180 + them sends the SCO data to an internal PCM adapter.
182 + Say Y here to compile support for HCI SCO data.
184 +HCI USB zero packet support
185 +CONFIG_BLUEZ_USB_ZERO_PACKET
186 + This option is provided only as a work around for buggy Bluetooth USB
187 + devices. Do NOT enable it unless you know for sure that your device
188 + requires zero packets.
190 + Most people should say N here.
192 +HCI VHCI Virtual HCI device driver
194 Bluetooth Virtual HCI device driver.
195 This driver is required if you want to use HCI Emulation software.
197 Say Y here to compile support for virtual HCI devices into the
198 kernel or say M to compile it as module (hci_vhci.o).
200 +HCI BFUSB device driver
201 +CONFIG_BLUEZ_HCIBFUSB
202 + Bluetooth HCI BlueFRITZ! USB driver.
203 + This driver provides support for Bluetooth USB devices with AVM
207 + Say Y here to compile support for HCI BFUSB devices into the
208 + kernel or say M to compile it as module (bfusb.o).
210 +HCI DTL1 (PC Card) device driver
211 +CONFIG_BLUEZ_HCIDTL1
212 + Bluetooth HCI DTL1 (PC Card) driver.
213 + This driver provides support for Bluetooth PCMCIA devices with
214 + Nokia DTL1 interface:
215 + Nokia Bluetooth Card
216 + Socket Bluetooth CF Card
218 + Say Y here to compile support for HCI DTL1 devices into the
219 + kernel or say M to compile it as module (dtl1_cs.o).
221 +HCI BT3C (PC Card) device driver
222 +CONFIG_BLUEZ_HCIBT3C
223 + Bluetooth HCI BT3C (PC Card) driver.
224 + This driver provides support for Bluetooth PCMCIA devices with
225 + 3Com BT3C interface:
226 + 3Com Bluetooth Card (3CRWB6096)
229 + The HCI BT3C driver uses external firmware loader program provided in
230 + the BlueFW package. For more information, see <http://bluez.sf.net>.
232 + Say Y here to compile support for HCI BT3C devices into the
233 + kernel or say M to compile it as module (bt3c_cs.o).
235 +HCI BlueCard (PC Card) device driver
236 +CONFIG_BLUEZ_HCIBLUECARD
237 + Bluetooth HCI BlueCard (PC Card) driver.
238 + This driver provides support for Bluetooth PCMCIA devices with
239 + Anycom BlueCard interface:
240 + Anycom Bluetooth PC Card
241 + Anycom Bluetooth CF Card
243 + Say Y here to compile support for HCI BlueCard devices into the
244 + kernel or say M to compile it as module (bluecard_cs.o).
246 +HCI UART (PC Card) device driver
247 +CONFIG_BLUEZ_HCIBTUART
248 + Bluetooth HCI UART (PC Card) driver.
249 + This driver provides support for Bluetooth PCMCIA devices with
251 + Xircom CreditCard Bluetooth Adapter
252 + Xircom RealPort2 Bluetooth Adapter
255 + Cyber-blue Compact Flash Card
257 + Say Y here to compile support for HCI UART devices into the
258 + kernel or say M to compile it as module (btuart_cs.o).
260 # The following options are for Linux when running on the Hitachi
261 # SuperH family of RISC microprocessors.
262 diff -urN linux-2.4.18/Documentation/firmware_class/README linux-2.4.18-mh9/Documentation/firmware_class/README
263 --- linux-2.4.18/Documentation/firmware_class/README Thu Jan 1 01:00:00 1970
264 +++ linux-2.4.18-mh9/Documentation/firmware_class/README Mon Aug 25 18:38:10 2003
267 + request_firmware() hotplug interface:
268 + ------------------------------------
269 + Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
274 + Today, the most extended way to use firmware in the Linux kernel is linking
275 + it statically in a header file. Which has political and technical issues:
277 + 1) Some firmware is not legal to redistribute.
278 + 2) The firmware occupies memory permanently, even though it often is just
280 + 3) Some people, like the Debian crowd, don't consider some firmware free
281 + enough and remove entire drivers (e.g.: keyspan).
283 + about in-kernel persistence:
284 + ---------------------------
285 + Under some circumstances, as explained below, it would be interesting to keep
286 + firmware images in non-swappable kernel memory or even in the kernel image
287 + (probably within initramfs).
289 + Note that this functionality has not been implemented.
291 + - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
293 + - If the device that needs the firmware is needed to access the
294 + filesystem. When upon some error the device has to be reset and the
295 + firmware reloaded, it won't be possible to get it from userspace.
297 + - A diskless client with a network card that needs firmware.
298 + - The filesystem is stored in a disk behind an scsi device
299 + that needs firmware.
300 + - Replacing buggy DSDT/SSDT ACPI tables on boot.
301 + Note: this would require the persistent objects to be included
302 + within the kernel image, probably within initramfs.
304 + And the same device can be needed to access the filesystem or not depending
305 + on the setup, so I think that the choice on what firmware to make
306 + persistent should be left to userspace.
308 + - Why register_firmware()+__init can be useful:
309 + - For boot devices needing firmware.
310 + - To make the transition easier:
311 + The firmware can be declared __init and register_firmware()
312 + called on module_init. Then the firmware is warranted to be
313 + there even if "firmware hotplug userspace" is not there yet or
314 + it doesn't yet provide the needed firmware.
315 + Once the firmware is widely available in userspace, it can be
316 + removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
318 + In either case, if firmware hotplug support is there, it can move the
319 + firmware out of kernel memory into the real filesystem for later
322 + Note: If persistence is implemented on top of initramfs,
323 + register_firmware() may not be appropriate.
324 diff -urN linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.18-mh9/Documentation/firmware_class/firmware_sample_driver.c
325 --- linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c Thu Jan 1 01:00:00 1970
326 +++ linux-2.4.18-mh9/Documentation/firmware_class/firmware_sample_driver.c Mon Aug 25 18:38:10 2003
329 + * firmware_sample_driver.c -
331 + * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
333 + * Sample code on how to use request_firmware() from drivers.
335 + * Note that register_firmware() is currently useless.
339 +#include <linux/module.h>
340 +#include <linux/kernel.h>
341 +#include <linux/init.h>
342 +#include <linux/string.h>
344 +#include "linux/firmware.h"
346 +#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
347 +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
348 +char __init inkernel_firmware[] = "let's say that this is firmware\n";
351 +static char ghost_device[] = "ghost0";
353 +static void sample_firmware_load(char *firmware, int size)
356 + memcpy(buf, firmware, size);
358 + printk("firmware_sample_driver: firmware: %s\n", buf);
361 +static void sample_probe_default(void)
363 + /* uses the default method to get the firmware */
364 + const struct firmware *fw_entry;
365 + printk("firmware_sample_driver: a ghost device got inserted :)\n");
367 + if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
370 + "firmware_sample_driver: Firmware not available\n");
374 + sample_firmware_load(fw_entry->data, fw_entry->size);
376 + release_firmware(fw_entry);
378 + /* finish setting up the device */
380 +static void sample_probe_specific(void)
382 + /* Uses some specific hotplug support to get the firmware from
383 + * userspace directly into the hardware, or via some sysfs file */
385 + /* NOTE: This currently doesn't work */
387 + printk("firmware_sample_driver: a ghost device got inserted :)\n");
389 + if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
392 + "firmware_sample_driver: Firmware load failed\n");
396 + /* request_firmware blocks until userspace finished, so at
397 + * this point the firmware should be already in the device */
399 + /* finish setting up the device */
401 +static void sample_probe_async_cont(const struct firmware *fw, void *context)
405 + "firmware_sample_driver: firmware load failed\n");
409 + printk("firmware_sample_driver: device pointer \"%s\"\n",
411 + sample_firmware_load(fw->data, fw->size);
413 +static void sample_probe_async(void)
415 + /* Let's say that I can't sleep */
417 + error = request_firmware_nowait (THIS_MODULE,
418 + "sample_driver_fw", ghost_device,
419 + "my device pointer",
420 + sample_probe_async_cont);
423 + "firmware_sample_driver:"
424 + " request_firmware_nowait failed\n");
428 +static int sample_init(void)
430 +#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
431 + register_firmware("sample_driver_fw", inkernel_firmware,
432 + sizeof(inkernel_firmware));
434 + /* since there is no real hardware insertion I just call the
435 + * sample probe functions here */
436 + sample_probe_specific();
437 + sample_probe_default();
438 + sample_probe_async();
441 +static void __exit sample_exit(void)
445 +module_init (sample_init);
446 +module_exit (sample_exit);
448 +MODULE_LICENSE("GPL");
449 diff -urN linux-2.4.18/Documentation/firmware_class/hotplug-script linux-2.4.18-mh9/Documentation/firmware_class/hotplug-script
450 --- linux-2.4.18/Documentation/firmware_class/hotplug-script Thu Jan 1 01:00:00 1970
451 +++ linux-2.4.18-mh9/Documentation/firmware_class/hotplug-script Mon Aug 25 18:38:10 2003
455 +# Simple hotplug script sample:
457 +# Both $DEVPATH and $FIRMWARE are already provided in the environment.
459 +HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
461 +echo 1 > /sysfs/$DEVPATH/loading
462 +cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
463 +echo 0 > /sysfs/$DEVPATH/loading
465 +# To cancel the load in case of error:
467 +# echo -1 > /sysfs/$DEVPATH/loading
469 diff -urN linux-2.4.18/MAINTAINERS linux-2.4.18-mh9/MAINTAINERS
470 --- linux-2.4.18/MAINTAINERS Mon Feb 25 20:37:52 2002
471 +++ linux-2.4.18-mh9/MAINTAINERS Mon Aug 25 18:38:10 2003
473 L: linux-kernel@vger.kernel.org
476 -BLUETOOTH SUBSYSTEM (BlueZ)
478 +P: Maxim Krasnyansky
479 +M: maxk@qualcomm.com
480 +W: http://bluez.sf.net
483 +BLUETOOTH RFCOMM LAYER
484 +P: Maxim Krasnyansky
485 +M: maxk@qualcomm.com
486 +W: http://bluez.sf.net
489 +BLUETOOTH BNEP LAYER
490 +P: Maxim Krasnyansky
491 +M: maxk@qualcomm.com
492 +W: http://bluez.sf.net
495 +BLUETOOTH CMTP LAYER
497 +M: marcel@holtmann.org
498 +W: http://www.holtmann.org/linux/bluetooth/
501 +BLUETOOTH HCI USB DRIVER
502 +P: Maxim Krasnyansky
503 +M: maxk@qualcomm.com
504 +W: http://bluez.sf.net
507 +BLUETOOTH HCI UART DRIVER
508 +P: Maxim Krasnyansky
509 +M: maxk@qualcomm.com
510 +W: http://bluez.sf.net
513 +BLUETOOTH HCI BFUSB DRIVER
515 +M: marcel@holtmann.org
516 +W: http://www.holtmann.org/linux/bluetooth/
519 +BLUETOOTH HCI DTL1 DRIVER
521 +M: marcel@holtmann.org
522 +W: http://www.holtmann.org/linux/bluetooth/
525 +BLUETOOTH HCI BLUECARD DRIVER
527 +M: marcel@holtmann.org
528 +W: http://www.holtmann.org/linux/bluetooth/
531 +BLUETOOTH HCI BT3C DRIVER
533 +M: marcel@holtmann.org
534 +W: http://www.holtmann.org/linux/bluetooth/
537 +BLUETOOTH HCI BTUART DRIVER
539 +M: marcel@holtmann.org
540 +W: http://www.holtmann.org/linux/bluetooth/
543 +BLUETOOTH HCI VHCI DRIVER
546 W: http://bluez.sf.net
547 diff -urN linux-2.4.18/arch/alpha/config.in linux-2.4.18-mh9/arch/alpha/config.in
548 --- linux-2.4.18/arch/alpha/config.in Wed Nov 21 00:49:31 2001
549 +++ linux-2.4.18-mh9/arch/alpha/config.in Mon Aug 25 18:38:10 2003
551 source drivers/usb/Config.in
552 source drivers/input/Config.in
554 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
555 - source net/bluetooth/Config.in
557 +source net/bluetooth/Config.in
559 mainmenu_option next_comment
560 comment 'Kernel hacking'
561 diff -urN linux-2.4.18/arch/arm/config.in linux-2.4.18-mh9/arch/arm/config.in
562 --- linux-2.4.18/arch/arm/config.in Fri Nov 9 22:58:02 2001
563 +++ linux-2.4.18-mh9/arch/arm/config.in Mon Aug 25 18:38:10 2003
566 source drivers/usb/Config.in
568 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
569 - source net/bluetooth/Config.in
571 +source net/bluetooth/Config.in
573 mainmenu_option next_comment
574 comment 'Kernel hacking'
575 diff -urN linux-2.4.18/arch/i386/config.in linux-2.4.18-mh9/arch/i386/config.in
576 --- linux-2.4.18/arch/i386/config.in Mon Feb 25 20:37:52 2002
577 +++ linux-2.4.18-mh9/arch/i386/config.in Mon Aug 25 18:38:10 2003
580 source drivers/usb/Config.in
582 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
583 - source net/bluetooth/Config.in
585 +source net/bluetooth/Config.in
587 mainmenu_option next_comment
588 comment 'Kernel hacking'
589 diff -urN linux-2.4.18/arch/ppc/config.in linux-2.4.18-mh9/arch/ppc/config.in
590 --- linux-2.4.18/arch/ppc/config.in Mon Feb 25 20:37:55 2002
591 +++ linux-2.4.18-mh9/arch/ppc/config.in Mon Aug 25 18:38:10 2003
594 source drivers/usb/Config.in
596 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
597 - source net/bluetooth/Config.in
599 +source net/bluetooth/Config.in
601 mainmenu_option next_comment
602 comment 'Kernel hacking'
603 diff -urN linux-2.4.18/arch/sparc/config.in linux-2.4.18-mh9/arch/sparc/config.in
604 --- linux-2.4.18/arch/sparc/config.in Tue Jun 12 04:15:27 2001
605 +++ linux-2.4.18-mh9/arch/sparc/config.in Mon Aug 25 18:38:10 2003
610 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
611 - source net/bluetooth/Config.in
613 +source net/bluetooth/Config.in
615 mainmenu_option next_comment
617 diff -urN linux-2.4.18/arch/sparc64/config.in linux-2.4.18-mh9/arch/sparc64/config.in
618 --- linux-2.4.18/arch/sparc64/config.in Fri Dec 21 18:41:53 2001
619 +++ linux-2.4.18-mh9/arch/sparc64/config.in Mon Aug 25 18:38:10 2003
622 source drivers/usb/Config.in
624 -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
625 - source net/bluetooth/Config.in
627 +source net/bluetooth/Config.in
629 mainmenu_option next_comment
631 diff -urN linux-2.4.18/arch/sparc64/kernel/ioctl32.c linux-2.4.18-mh9/arch/sparc64/kernel/ioctl32.c
632 --- linux-2.4.18/arch/sparc64/kernel/ioctl32.c Mon Feb 25 20:37:56 2002
633 +++ linux-2.4.18-mh9/arch/sparc64/kernel/ioctl32.c Mon Aug 25 18:38:10 2003
636 #include <net/bluetooth/bluetooth.h>
637 #include <net/bluetooth/hci.h>
638 +#include <net/bluetooth/rfcomm.h>
640 #include <linux/usb.h>
641 #include <linux/usbdevice_fs.h>
642 @@ -3822,6 +3823,15 @@
646 +/* Bluetooth ioctls */
647 +#define HCIUARTSETPROTO _IOW('U', 200, int)
648 +#define HCIUARTGETPROTO _IOR('U', 201, int)
650 +#define BNEPCONNADD _IOW('B', 200, int)
651 +#define BNEPCONNDEL _IOW('B', 201, int)
652 +#define BNEPGETCONNLIST _IOR('B', 210, int)
653 +#define BNEPGETCONNINFO _IOR('B', 211, int)
655 struct mtd_oob_buf32 {
658 @@ -3878,6 +3888,11 @@
659 return ((0 == ret) ? 0 : -EFAULT);
662 +#define CMTPCONNADD _IOW('C', 200, int)
663 +#define CMTPCONNDEL _IOW('C', 201, int)
664 +#define CMTPGETCONNLIST _IOR('C', 210, int)
665 +#define CMTPGETCONNINFO _IOR('C', 211, int)
669 unsigned int handler;
670 @@ -4540,6 +4555,21 @@
671 COMPATIBLE_IOCTL(HCISETSCAN)
672 COMPATIBLE_IOCTL(HCISETAUTH)
673 COMPATIBLE_IOCTL(HCIINQUIRY)
674 +COMPATIBLE_IOCTL(HCIUARTSETPROTO)
675 +COMPATIBLE_IOCTL(HCIUARTGETPROTO)
676 +COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
677 +COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
678 +COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
679 +COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
680 +COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
681 +COMPATIBLE_IOCTL(BNEPCONNADD)
682 +COMPATIBLE_IOCTL(BNEPCONNDEL)
683 +COMPATIBLE_IOCTL(BNEPGETCONNLIST)
684 +COMPATIBLE_IOCTL(BNEPGETCONNINFO)
685 +COMPATIBLE_IOCTL(CMTPCONNADD)
686 +COMPATIBLE_IOCTL(CMTPCONNDEL)
687 +COMPATIBLE_IOCTL(CMTPGETCONNLIST)
688 +COMPATIBLE_IOCTL(CMTPGETCONNINFO)
690 COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
691 COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
692 diff -urN linux-2.4.18/drivers/bluetooth/Config.in linux-2.4.18-mh9/drivers/bluetooth/Config.in
693 --- linux-2.4.18/drivers/bluetooth/Config.in Fri Sep 7 18:28:38 2001
694 +++ linux-2.4.18-mh9/drivers/bluetooth/Config.in Mon Aug 25 18:38:10 2003
697 +# Bluetooth HCI device drivers configuration
700 mainmenu_option next_comment
701 comment 'Bluetooth device drivers'
703 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
704 +if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
705 + bool ' SCO (voice) support' CONFIG_BLUEZ_USB_SCO
706 + bool ' USB zero packet support' CONFIG_BLUEZ_USB_ZERO_PACKET
709 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
710 -dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
711 +if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
712 + bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
713 + bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
714 + dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
717 +dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
719 +dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
721 +dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
723 +dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
725 +dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
727 +dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
731 diff -urN linux-2.4.18/drivers/bluetooth/Makefile linux-2.4.18-mh9/drivers/bluetooth/Makefile
732 --- linux-2.4.18/drivers/bluetooth/Makefile Fri Sep 7 18:28:38 2001
733 +++ linux-2.4.18-mh9/drivers/bluetooth/Makefile Mon Aug 25 18:38:10 2003
736 -# Makefile for Bluetooth HCI device drivers.
737 +# Makefile for the Linux Bluetooth HCI device drivers
740 O_TARGET := bluetooth.o
742 +list-multi := hci_uart.o
744 obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
745 -obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
746 obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
748 +obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
749 +uart-y := hci_ldisc.o
750 +uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
751 +uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
753 +obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
755 +obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
756 +obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
757 +obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
758 +obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
760 include $(TOPDIR)/Rules.make
762 +hci_uart.o: $(uart-y)
763 + $(LD) -r -o $@ $(uart-y)
764 diff -urN linux-2.4.18/drivers/bluetooth/Makefile.lib linux-2.4.18-mh9/drivers/bluetooth/Makefile.lib
765 --- linux-2.4.18/drivers/bluetooth/Makefile.lib Thu Jan 1 01:00:00 1970
766 +++ linux-2.4.18-mh9/drivers/bluetooth/Makefile.lib Mon Aug 25 18:38:10 2003
768 +obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
769 diff -urN linux-2.4.18/drivers/bluetooth/bfusb.c linux-2.4.18-mh9/drivers/bluetooth/bfusb.c
770 --- linux-2.4.18/drivers/bluetooth/bfusb.c Thu Jan 1 01:00:00 1970
771 +++ linux-2.4.18-mh9/drivers/bluetooth/bfusb.c Mon Aug 25 18:38:10 2003
775 + * AVM BlueFRITZ! USB driver
777 + * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
780 + * This program is free software; you can redistribute it and/or modify
781 + * it under the terms of the GNU General Public License as published by
782 + * the Free Software Foundation; either version 2 of the License, or
783 + * (at your option) any later version.
785 + * This program is distributed in the hope that it will be useful,
786 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
787 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
788 + * GNU General Public License for more details.
790 + * You should have received a copy of the GNU General Public License
791 + * along with this program; if not, write to the Free Software
792 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
796 +#include <linux/config.h>
797 +#include <linux/module.h>
799 +#include <linux/kernel.h>
800 +#include <linux/init.h>
801 +#include <linux/slab.h>
802 +#include <linux/types.h>
803 +#include <linux/sched.h>
804 +#include <linux/errno.h>
805 +#include <linux/skbuff.h>
807 +#include <linux/firmware.h>
808 +#include <linux/usb.h>
810 +#include <net/bluetooth/bluetooth.h>
811 +#include <net/bluetooth/hci_core.h>
813 +#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
815 +#define BT_DBG(D...)
818 +#define VERSION "1.1"
820 +static struct usb_device_id bfusb_table[] = {
821 + /* AVM BlueFRITZ! USB */
822 + { USB_DEVICE(0x057c, 0x2200) },
824 + { } /* Terminating entry */
827 +MODULE_DEVICE_TABLE(usb, bfusb_table);
830 +#define BFUSB_MAX_BLOCK_SIZE 256
832 +#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
834 +#define BFUSB_TX_PROCESS 1
835 +#define BFUSB_TX_WAKEUP 2
837 +#define BFUSB_MAX_BULK_TX 1
838 +#define BFUSB_MAX_BULK_RX 1
841 + struct hci_dev hdev;
843 + unsigned long state;
845 + struct usb_device *udev;
847 + unsigned int bulk_in_ep;
848 + unsigned int bulk_out_ep;
849 + unsigned int bulk_pkt_size;
853 + struct sk_buff_head transmit_q;
855 + struct sk_buff *reassembly;
857 + atomic_t pending_tx;
858 + struct sk_buff_head pending_q;
859 + struct sk_buff_head completed_q;
866 +static void bfusb_tx_complete(struct urb *urb);
867 +static void bfusb_rx_complete(struct urb *urb);
869 +static struct urb *bfusb_get_completed(struct bfusb *bfusb)
871 + struct sk_buff *skb;
872 + struct urb *urb = NULL;
874 + BT_DBG("bfusb %p", bfusb);
876 + skb = skb_dequeue(&bfusb->completed_q);
878 + urb = ((struct bfusb_scb *) skb->cb)->urb;
885 +static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
887 + struct sk_buff *skb;
890 + BT_DBG("bfusb %p", bfusb);
892 + while ((skb = skb_dequeue(&bfusb->pending_q))) {
893 + urb = ((struct bfusb_scb *) skb->cb)->urb;
894 + usb_unlink_urb(urb);
895 + skb_queue_tail(&bfusb->completed_q, skb);
898 + while ((urb = bfusb_get_completed(bfusb)))
903 +static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
905 + struct bfusb_scb *scb = (void *) skb->cb;
906 + struct urb *urb = bfusb_get_completed(bfusb);
909 + BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
911 + if (!urb && !(urb = usb_alloc_urb(0)))
914 + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
916 + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
917 + bfusb_tx_complete, skb);
919 + urb->transfer_flags = USB_QUEUE_BULK;
923 + skb_queue_tail(&bfusb->pending_q, skb);
925 + err = usb_submit_urb(urb);
927 + BT_ERR("%s bulk tx submit failed urb %p err %d",
928 + bfusb->hdev.name, urb, err);
932 + atomic_inc(&bfusb->pending_tx);
937 +static void bfusb_tx_wakeup(struct bfusb *bfusb)
939 + struct sk_buff *skb;
941 + BT_DBG("bfusb %p", bfusb);
943 + if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
944 + set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
949 + clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
951 + while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
952 + (skb = skb_dequeue(&bfusb->transmit_q))) {
953 + if (bfusb_send_bulk(bfusb, skb) < 0) {
954 + skb_queue_head(&bfusb->transmit_q, skb);
959 + } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
961 + clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
964 +static void bfusb_tx_complete(struct urb *urb)
966 + struct sk_buff *skb = (struct sk_buff *) urb->context;
967 + struct bfusb *bfusb = (struct bfusb *) skb->dev;
969 + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
971 + atomic_dec(&bfusb->pending_tx);
973 + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
977 + bfusb->hdev.stat.byte_tx += skb->len;
979 + bfusb->hdev.stat.err_tx++;
981 + read_lock(&bfusb->lock);
984 + skb_queue_tail(&bfusb->completed_q, skb);
986 + bfusb_tx_wakeup(bfusb);
988 + read_unlock(&bfusb->lock);
992 +static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
994 + struct bfusb_scb *scb;
995 + struct sk_buff *skb;
996 + int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
998 + BT_DBG("bfusb %p urb %p", bfusb, urb);
1000 + if (!urb && !(urb = usb_alloc_urb(0)))
1003 + if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
1004 + usb_free_urb(urb);
1008 + skb->dev = (void *) bfusb;
1010 + scb = (struct bfusb_scb *) skb->cb;
1013 + pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
1015 + FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
1016 + bfusb_rx_complete, skb);
1018 + urb->transfer_flags = USB_QUEUE_BULK;
1020 + skb_queue_tail(&bfusb->pending_q, skb);
1022 + err = usb_submit_urb(urb);
1024 + BT_ERR("%s bulk rx submit failed urb %p err %d",
1025 + bfusb->hdev.name, urb, err);
1028 + usb_free_urb(urb);
1034 +static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
1036 + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
1039 + BT_ERR("%s error in block", bfusb->hdev.name);
1040 + if (bfusb->reassembly)
1041 + kfree_skb(bfusb->reassembly);
1042 + bfusb->reassembly = NULL;
1047 + struct sk_buff *skb;
1048 + unsigned char pkt_type;
1051 + if (bfusb->reassembly) {
1052 + BT_ERR("%s unexpected start block", bfusb->hdev.name);
1053 + kfree_skb(bfusb->reassembly);
1054 + bfusb->reassembly = NULL;
1058 + BT_ERR("%s no packet type found", bfusb->hdev.name);
1062 + pkt_type = *data++; len--;
1064 + switch (pkt_type) {
1065 + case HCI_EVENT_PKT:
1066 + if (len >= HCI_EVENT_HDR_SIZE) {
1067 + hci_event_hdr *hdr = (hci_event_hdr *) data;
1068 + pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
1070 + BT_ERR("%s event block is too short", bfusb->hdev.name);
1075 + case HCI_ACLDATA_PKT:
1076 + if (len >= HCI_ACL_HDR_SIZE) {
1077 + hci_acl_hdr *hdr = (hci_acl_hdr *) data;
1078 + pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
1080 + BT_ERR("%s data block is too short", bfusb->hdev.name);
1085 + case HCI_SCODATA_PKT:
1086 + if (len >= HCI_SCO_HDR_SIZE) {
1087 + hci_sco_hdr *hdr = (hci_sco_hdr *) data;
1088 + pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
1090 + BT_ERR("%s audio block is too short", bfusb->hdev.name);
1096 + skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
1098 + BT_ERR("%s no memory for the packet", bfusb->hdev.name);
1102 + skb->dev = (void *) &bfusb->hdev;
1103 + skb->pkt_type = pkt_type;
1105 + bfusb->reassembly = skb;
1107 + if (!bfusb->reassembly) {
1108 + BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
1114 + memcpy(skb_put(bfusb->reassembly, len), data, len);
1117 + hci_recv_frame(bfusb->reassembly);
1118 + bfusb->reassembly = NULL;
1124 +static void bfusb_rx_complete(struct urb *urb)
1126 + struct sk_buff *skb = (struct sk_buff *) urb->context;
1127 + struct bfusb *bfusb = (struct bfusb *) skb->dev;
1128 + unsigned char *buf = urb->transfer_buffer;
1129 + int count = urb->actual_length;
1130 + int err, hdr, len;
1132 + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
1134 + if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
1137 + read_lock(&bfusb->lock);
1139 + if (urb->status || !count)
1142 + bfusb->hdev.stat.byte_rx += count;
1144 + skb_put(skb, count);
1147 + hdr = buf[0] | (buf[1] << 8);
1149 + if (hdr & 0x4000) {
1154 + len = (buf[2] == 0) ? 256 : buf[2];
1159 + if (count < len) {
1160 + BT_ERR("%s block extends over URB buffer ranges",
1161 + bfusb->hdev.name);
1164 + if ((hdr & 0xe1) == 0xc1)
1165 + bfusb_recv_block(bfusb, hdr, buf, len);
1174 + bfusb_rx_submit(bfusb, urb);
1176 + read_unlock(&bfusb->lock);
1181 + urb->dev = bfusb->udev;
1183 + err = usb_submit_urb(urb);
1185 + BT_ERR("%s bulk resubmit failed urb %p err %d",
1186 + bfusb->hdev.name, urb, err);
1189 + read_unlock(&bfusb->lock);
1193 +static int bfusb_open(struct hci_dev *hdev)
1195 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1196 + unsigned long flags;
1199 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1201 + if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
1204 + MOD_INC_USE_COUNT;
1206 + write_lock_irqsave(&bfusb->lock, flags);
1208 + err = bfusb_rx_submit(bfusb, NULL);
1210 + for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
1211 + bfusb_rx_submit(bfusb, NULL);
1213 + clear_bit(HCI_RUNNING, &hdev->flags);
1214 + MOD_DEC_USE_COUNT;
1217 + write_unlock_irqrestore(&bfusb->lock, flags);
1222 +static int bfusb_flush(struct hci_dev *hdev)
1224 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1226 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1228 + skb_queue_purge(&bfusb->transmit_q);
1233 +static int bfusb_close(struct hci_dev *hdev)
1235 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1236 + unsigned long flags;
1238 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1240 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
1243 + write_lock_irqsave(&bfusb->lock, flags);
1245 + bfusb_unlink_urbs(bfusb);
1246 + bfusb_flush(hdev);
1248 + write_unlock_irqrestore(&bfusb->lock, flags);
1250 + MOD_DEC_USE_COUNT;
1255 +static int bfusb_send_frame(struct sk_buff *skb)
1257 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
1258 + struct bfusb *bfusb;
1259 + struct sk_buff *nskb;
1260 + unsigned char buf[3];
1261 + int sent = 0, size, count;
1263 + BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
1266 + BT_ERR("Frame for unknown HCI device (hdev=NULL)");
1270 + if (!test_bit(HCI_RUNNING, &hdev->flags))
1273 + bfusb = (struct bfusb *) hdev->driver_data;
1275 + switch (skb->pkt_type) {
1276 + case HCI_COMMAND_PKT:
1277 + hdev->stat.cmd_tx++;
1279 + case HCI_ACLDATA_PKT:
1280 + hdev->stat.acl_tx++;
1282 + case HCI_SCODATA_PKT:
1283 + hdev->stat.sco_tx++;
1287 + /* Prepend skb with frame type */
1288 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
1292 + /* Max HCI frame size seems to be 1511 + 1 */
1293 + if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
1294 + BT_ERR("Can't allocate memory for new packet");
1298 + nskb->dev = (void *) bfusb;
1301 + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
1303 + buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
1305 + buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
1307 + memcpy(skb_put(nskb, 3), buf, 3);
1308 + memcpy(skb_put(nskb, size), skb->data + sent, size);
1314 + /* Don't send frame with multiple size of bulk max packet */
1315 + if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
1318 + memcpy(skb_put(nskb, 2), buf, 2);
1321 + read_lock(&bfusb->lock);
1323 + skb_queue_tail(&bfusb->transmit_q, nskb);
1324 + bfusb_tx_wakeup(bfusb);
1326 + read_unlock(&bfusb->lock);
1333 +static void bfusb_destruct(struct hci_dev *hdev)
1335 + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
1337 + BT_DBG("hdev %p bfusb %p", hdev, bfusb);
1342 +static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
1344 + return -ENOIOCTLCMD;
1348 +static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
1350 + unsigned char *buf;
1351 + int err, pipe, len, size, sent = 0;
1353 + BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
1355 + BT_INFO("BlueFRITZ! USB loading firmware");
1357 + if (usb_set_configuration(bfusb->udev, 1) < 0) {
1358 + BT_ERR("Can't change to loading configuration");
1362 + buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
1364 + BT_ERR("Can't allocate memory chunk for firmware");
1368 + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
1371 + size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
1373 + memcpy(buf, firmware + sent, size);
1375 + err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
1376 + &len, BFUSB_BLOCK_TIMEOUT);
1378 + if (err || (len != size)) {
1379 + BT_ERR("Error in firmware loading");
1387 + if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
1388 + &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
1389 + BT_ERR("Error in null packet request");
1393 + if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
1394 + BT_ERR("Can't change to running configuration");
1398 + BT_INFO("BlueFRITZ! USB device ready");
1406 + pipe = usb_sndctrlpipe(bfusb->udev, 0);
1408 + usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
1409 + 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
1414 +static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
1416 + const struct firmware *firmware;
1418 + struct usb_interface *iface;
1419 + struct usb_interface_descriptor *iface_desc;
1420 + struct usb_endpoint_descriptor *bulk_out_ep;
1421 + struct usb_endpoint_descriptor *bulk_in_ep;
1422 + struct hci_dev *hdev;
1423 + struct bfusb *bfusb;
1425 + BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
1427 + /* Check number of endpoints */
1428 + iface = &udev->actconfig->interface[0];
1429 + iface_desc = &iface->altsetting[0];
1431 + if (iface_desc->bNumEndpoints < 2)
1434 + bulk_out_ep = &iface_desc->endpoint[0];
1435 + bulk_in_ep = &iface_desc->endpoint[1];
1437 + if (!bulk_out_ep || !bulk_in_ep) {
1438 + BT_ERR("Bulk endpoints not found");
1442 + /* Initialize control structure and load firmware */
1443 + if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
1444 + BT_ERR("Can't allocate memory for control structure");
1448 + memset(bfusb, 0, sizeof(struct bfusb));
1450 + bfusb->udev = udev;
1451 + bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
1452 + bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
1453 + bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
1455 + bfusb->lock = RW_LOCK_UNLOCKED;
1457 + bfusb->reassembly = NULL;
1459 + skb_queue_head_init(&bfusb->transmit_q);
1460 + skb_queue_head_init(&bfusb->pending_q);
1461 + skb_queue_head_init(&bfusb->completed_q);
1463 + snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
1465 + if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
1466 + BT_ERR("Firmware request failed");
1470 + if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
1471 + BT_ERR("Firmware loading failed");
1475 + release_firmware(firmware);
1477 + /* Initialize and register HCI device */
1478 + hdev = &bfusb->hdev;
1480 + hdev->type = HCI_USB;
1481 + hdev->driver_data = bfusb;
1483 + hdev->open = bfusb_open;
1484 + hdev->close = bfusb_close;
1485 + hdev->flush = bfusb_flush;
1486 + hdev->send = bfusb_send_frame;
1487 + hdev->destruct = bfusb_destruct;
1488 + hdev->ioctl = bfusb_ioctl;
1490 + if (hci_register_dev(hdev) < 0) {
1491 + BT_ERR("Can't register HCI device");
1498 + release_firmware(firmware);
1507 +static void bfusb_disconnect(struct usb_device *udev, void *ptr)
1509 + struct bfusb *bfusb = (struct bfusb *) ptr;
1510 + struct hci_dev *hdev = &bfusb->hdev;
1512 + BT_DBG("udev %p ptr %p", udev, ptr);
1517 + bfusb_close(hdev);
1519 + if (hci_unregister_dev(hdev) < 0)
1520 + BT_ERR("Can't unregister HCI device %s", hdev->name);
1523 +static struct usb_driver bfusb_driver = {
1525 + probe: bfusb_probe,
1526 + disconnect: bfusb_disconnect,
1527 + id_table: bfusb_table,
1530 +static int __init bfusb_init(void)
1534 + BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
1535 + BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
1537 + if ((err = usb_register(&bfusb_driver)) < 0)
1538 + BT_ERR("Failed to register BlueFRITZ! USB driver");
1543 +static void __exit bfusb_cleanup(void)
1545 + usb_deregister(&bfusb_driver);
1548 +module_init(bfusb_init);
1549 +module_exit(bfusb_cleanup);
1551 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1552 +MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
1553 +MODULE_LICENSE("GPL");
1554 diff -urN linux-2.4.18/drivers/bluetooth/bluecard_cs.c linux-2.4.18-mh9/drivers/bluetooth/bluecard_cs.c
1555 --- linux-2.4.18/drivers/bluetooth/bluecard_cs.c Thu Jan 1 01:00:00 1970
1556 +++ linux-2.4.18-mh9/drivers/bluetooth/bluecard_cs.c Mon Aug 25 18:38:10 2003
1560 + * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
1562 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
1565 + * This program is free software; you can redistribute it and/or modify
1566 + * it under the terms of the GNU General Public License version 2 as
1567 + * published by the Free Software Foundation;
1569 + * Software distributed under the License is distributed on an "AS
1570 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
1571 + * implied. See the License for the specific language governing
1572 + * rights and limitations under the License.
1574 + * The initial developer of the original code is David A. Hinds
1575 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
1576 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
1580 +#include <linux/config.h>
1581 +#include <linux/module.h>
1583 +#include <linux/kernel.h>
1584 +#include <linux/init.h>
1585 +#include <linux/slab.h>
1586 +#include <linux/types.h>
1587 +#include <linux/sched.h>
1588 +#include <linux/timer.h>
1589 +#include <linux/errno.h>
1590 +#include <linux/ptrace.h>
1591 +#include <linux/ioport.h>
1592 +#include <linux/spinlock.h>
1593 +#include <linux/skbuff.h>
1594 +#include <asm/io.h>
1596 +#include <pcmcia/version.h>
1597 +#include <pcmcia/cs_types.h>
1598 +#include <pcmcia/cs.h>
1599 +#include <pcmcia/cistpl.h>
1600 +#include <pcmcia/ciscode.h>
1601 +#include <pcmcia/ds.h>
1602 +#include <pcmcia/cisreg.h>
1604 +#include <net/bluetooth/bluetooth.h>
1605 +#include <net/bluetooth/hci_core.h>
1609 +/* ======================== Module parameters ======================== */
1612 +/* Bit map of interrupts to choose from */
1613 +static u_int irq_mask = 0x86bc;
1614 +static int irq_list[4] = { -1 };
1616 +MODULE_PARM(irq_mask, "i");
1617 +MODULE_PARM(irq_list, "1-4i");
1619 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1620 +MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
1621 +MODULE_LICENSE("GPL");
1625 +/* ======================== Local structures ======================== */
1628 +typedef struct bluecard_info_t {
1632 + struct hci_dev hdev;
1634 + spinlock_t lock; /* For serializing operations */
1635 + struct timer_list timer; /* For LED control */
1637 + struct sk_buff_head txq;
1638 + unsigned long tx_state;
1640 + unsigned long rx_state;
1641 + unsigned long rx_count;
1642 + struct sk_buff *rx_skb;
1644 + unsigned char ctrl_reg;
1645 + unsigned long hw_state; /* Status of the hardware and LED control */
1649 +void bluecard_config(dev_link_t *link);
1650 +void bluecard_release(u_long arg);
1651 +int bluecard_event(event_t event, int priority, event_callback_args_t *args);
1653 +static dev_info_t dev_info = "bluecard_cs";
1655 +dev_link_t *bluecard_attach(void);
1656 +void bluecard_detach(dev_link_t *);
1658 +static dev_link_t *dev_list = NULL;
1661 +/* Default baud rate: 57600, 115200, 230400 or 460800 */
1662 +#define DEFAULT_BAUD_RATE 230400
1665 +/* Hardware states */
1666 +#define CARD_READY 1
1667 +#define CARD_HAS_PCCARD_ID 4
1668 +#define CARD_HAS_POWER_LED 5
1669 +#define CARD_HAS_ACTIVITY_LED 6
1671 +/* Transmit states */
1672 +#define XMIT_SENDING 1
1673 +#define XMIT_WAKEUP 2
1674 +#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
1675 +#define XMIT_BUF_ONE_READY 6
1676 +#define XMIT_BUF_TWO_READY 7
1677 +#define XMIT_SENDING_READY 8
1679 +/* Receiver states */
1680 +#define RECV_WAIT_PACKET_TYPE 0
1681 +#define RECV_WAIT_EVENT_HEADER 1
1682 +#define RECV_WAIT_ACL_HEADER 2
1683 +#define RECV_WAIT_SCO_HEADER 3
1684 +#define RECV_WAIT_DATA 4
1686 +/* Special packet types */
1687 +#define PKT_BAUD_RATE_57600 0x80
1688 +#define PKT_BAUD_RATE_115200 0x81
1689 +#define PKT_BAUD_RATE_230400 0x82
1690 +#define PKT_BAUD_RATE_460800 0x83
1693 +/* These are the register offsets */
1694 +#define REG_COMMAND 0x20
1695 +#define REG_INTERRUPT 0x21
1696 +#define REG_CONTROL 0x22
1697 +#define REG_RX_CONTROL 0x24
1698 +#define REG_CARD_RESET 0x30
1699 +#define REG_LED_CTRL 0x30
1702 +#define REG_COMMAND_TX_BUF_ONE 0x01
1703 +#define REG_COMMAND_TX_BUF_TWO 0x02
1704 +#define REG_COMMAND_RX_BUF_ONE 0x04
1705 +#define REG_COMMAND_RX_BUF_TWO 0x08
1706 +#define REG_COMMAND_RX_WIN_ONE 0x00
1707 +#define REG_COMMAND_RX_WIN_TWO 0x10
1710 +#define REG_CONTROL_BAUD_RATE_57600 0x00
1711 +#define REG_CONTROL_BAUD_RATE_115200 0x01
1712 +#define REG_CONTROL_BAUD_RATE_230400 0x02
1713 +#define REG_CONTROL_BAUD_RATE_460800 0x03
1714 +#define REG_CONTROL_RTS 0x04
1715 +#define REG_CONTROL_BT_ON 0x08
1716 +#define REG_CONTROL_BT_RESET 0x10
1717 +#define REG_CONTROL_BT_RES_PU 0x20
1718 +#define REG_CONTROL_INTERRUPT 0x40
1719 +#define REG_CONTROL_CARD_RESET 0x80
1721 +/* REG_RX_CONTROL */
1722 +#define RTS_LEVEL_SHIFT_BITS 0x02
1726 +/* ======================== LED handling routines ======================== */
1729 +void bluecard_activity_led_timeout(u_long arg)
1731 + bluecard_info_t *info = (bluecard_info_t *)arg;
1732 + unsigned int iobase = info->link.io.BasePort1;
1734 + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
1735 + /* Disable activity LED */
1736 + outb(0x08 | 0x20, iobase + 0x30);
1738 + /* Disable power LED */
1739 + outb(0x00, iobase + 0x30);
1744 +static void bluecard_enable_activity_led(bluecard_info_t *info)
1746 + unsigned int iobase = info->link.io.BasePort1;
1748 + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
1749 + /* Enable activity LED */
1750 + outb(0x10 | 0x40, iobase + 0x30);
1752 + /* Stop the LED after HZ/4 */
1753 + mod_timer(&(info->timer), jiffies + HZ / 4);
1755 + /* Enable power LED */
1756 + outb(0x08 | 0x20, iobase + 0x30);
1758 + /* Stop the LED after HZ/2 */
1759 + mod_timer(&(info->timer), jiffies + HZ / 2);
1765 +/* ======================== Interrupt handling ======================== */
1768 +static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
1772 + actual = (len > 15) ? 15 : len;
1774 + outb_p(actual, iobase + offset);
1776 + for (i = 0; i < actual; i++)
1777 + outb_p(buf[i], iobase + offset + i + 1);
1783 +static void bluecard_write_wakeup(bluecard_info_t *info)
1786 + printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
1790 + if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
1793 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
1794 + set_bit(XMIT_WAKEUP, &(info->tx_state));
1799 + register unsigned int iobase = info->link.io.BasePort1;
1800 + register unsigned int offset;
1801 + register unsigned char command;
1802 + register unsigned long ready_bit;
1803 + register struct sk_buff *skb;
1806 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
1808 + if (!(info->link.state & DEV_PRESENT))
1811 + if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
1812 + if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
1815 + command = REG_COMMAND_TX_BUF_TWO;
1816 + ready_bit = XMIT_BUF_TWO_READY;
1818 + if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
1821 + command = REG_COMMAND_TX_BUF_ONE;
1822 + ready_bit = XMIT_BUF_ONE_READY;
1825 + if (!(skb = skb_dequeue(&(info->txq))))
1828 + if (skb->pkt_type & 0x80) {
1830 + info->ctrl_reg |= REG_CONTROL_RTS;
1831 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1834 + /* Activate LED */
1835 + bluecard_enable_activity_led(info);
1838 + len = bluecard_write(iobase, offset, skb->data, skb->len);
1840 + /* Tell the FPGA to send the data */
1841 + outb_p(command, iobase + REG_COMMAND);
1843 + /* Mark the buffer as dirty */
1844 + clear_bit(ready_bit, &(info->tx_state));
1846 + if (skb->pkt_type & 0x80) {
1848 + wait_queue_head_t wait;
1849 + unsigned char baud_reg;
1851 + switch (skb->pkt_type) {
1852 + case PKT_BAUD_RATE_460800:
1853 + baud_reg = REG_CONTROL_BAUD_RATE_460800;
1855 + case PKT_BAUD_RATE_230400:
1856 + baud_reg = REG_CONTROL_BAUD_RATE_230400;
1858 + case PKT_BAUD_RATE_115200:
1859 + baud_reg = REG_CONTROL_BAUD_RATE_115200;
1861 + case PKT_BAUD_RATE_57600:
1862 + /* Fall through... */
1864 + baud_reg = REG_CONTROL_BAUD_RATE_57600;
1868 + /* Wait until the command reaches the baseband */
1869 + init_waitqueue_head(&wait);
1870 + interruptible_sleep_on_timeout(&wait, HZ / 10);
1872 + /* Set baud on baseband */
1873 + info->ctrl_reg &= ~0x03;
1874 + info->ctrl_reg |= baud_reg;
1875 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1878 + info->ctrl_reg &= ~REG_CONTROL_RTS;
1879 + outb(info->ctrl_reg, iobase + REG_CONTROL);
1881 + /* Wait before the next HCI packet can be send */
1882 + interruptible_sleep_on_timeout(&wait, HZ);
1886 + if (len == skb->len) {
1889 + skb_pull(skb, len);
1890 + skb_queue_head(&(info->txq), skb);
1893 + info->hdev.stat.byte_tx += len;
1895 + /* Change buffer */
1896 + change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
1898 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
1900 + clear_bit(XMIT_SENDING, &(info->tx_state));
1904 +static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
1908 + outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
1910 + len = inb(iobase + offset);
1917 + outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
1921 + buf[n] = inb(iobase + offset + i);
1932 +static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
1934 + unsigned int iobase;
1935 + unsigned char buf[31];
1939 + printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
1943 + iobase = info->link.io.BasePort1;
1945 + if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
1946 + bluecard_enable_activity_led(info);
1948 + len = bluecard_read(iobase, offset, buf, sizeof(buf));
1950 + for (i = 0; i < len; i++) {
1952 + /* Allocate packet */
1953 + if (info->rx_skb == NULL) {
1954 + info->rx_state = RECV_WAIT_PACKET_TYPE;
1955 + info->rx_count = 0;
1956 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
1957 + printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
1962 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
1964 + info->rx_skb->dev = (void *)&(info->hdev);
1965 + info->rx_skb->pkt_type = buf[i];
1967 + switch (info->rx_skb->pkt_type) {
1971 + if (offset != 0x00) {
1972 + set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
1973 + set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
1974 + set_bit(XMIT_SENDING_READY, &(info->tx_state));
1975 + bluecard_write_wakeup(info);
1978 + kfree_skb(info->rx_skb);
1979 + info->rx_skb = NULL;
1982 + case HCI_EVENT_PKT:
1983 + info->rx_state = RECV_WAIT_EVENT_HEADER;
1984 + info->rx_count = HCI_EVENT_HDR_SIZE;
1987 + case HCI_ACLDATA_PKT:
1988 + info->rx_state = RECV_WAIT_ACL_HEADER;
1989 + info->rx_count = HCI_ACL_HDR_SIZE;
1992 + case HCI_SCODATA_PKT:
1993 + info->rx_state = RECV_WAIT_SCO_HEADER;
1994 + info->rx_count = HCI_SCO_HDR_SIZE;
1998 + /* unknown packet */
1999 + printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
2000 + info->hdev.stat.err_rx++;
2002 + kfree_skb(info->rx_skb);
2003 + info->rx_skb = NULL;
2010 + *skb_put(info->rx_skb, 1) = buf[i];
2013 + if (info->rx_count == 0) {
2016 + hci_event_hdr *eh;
2020 + switch (info->rx_state) {
2022 + case RECV_WAIT_EVENT_HEADER:
2023 + eh = (hci_event_hdr *)(info->rx_skb->data);
2024 + info->rx_state = RECV_WAIT_DATA;
2025 + info->rx_count = eh->plen;
2028 + case RECV_WAIT_ACL_HEADER:
2029 + ah = (hci_acl_hdr *)(info->rx_skb->data);
2030 + dlen = __le16_to_cpu(ah->dlen);
2031 + info->rx_state = RECV_WAIT_DATA;
2032 + info->rx_count = dlen;
2035 + case RECV_WAIT_SCO_HEADER:
2036 + sh = (hci_sco_hdr *)(info->rx_skb->data);
2037 + info->rx_state = RECV_WAIT_DATA;
2038 + info->rx_count = sh->dlen;
2041 + case RECV_WAIT_DATA:
2042 + hci_recv_frame(info->rx_skb);
2043 + info->rx_skb = NULL;
2055 + info->hdev.stat.byte_rx += len;
2059 +void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
2061 + bluecard_info_t *info = dev_inst;
2062 + unsigned int iobase;
2063 + unsigned char reg;
2066 + printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
2070 + if (!test_bit(CARD_READY, &(info->hw_state)))
2073 + iobase = info->link.io.BasePort1;
2075 + spin_lock(&(info->lock));
2077 + /* Disable interrupt */
2078 + info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
2079 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2081 + reg = inb(iobase + REG_INTERRUPT);
2083 + if ((reg != 0x00) && (reg != 0xff)) {
2086 + bluecard_receive(info, 0x00);
2087 + outb(0x04, iobase + REG_INTERRUPT);
2088 + outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
2092 + bluecard_receive(info, 0x10);
2093 + outb(0x08, iobase + REG_INTERRUPT);
2094 + outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
2098 + set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
2099 + outb(0x01, iobase + REG_INTERRUPT);
2100 + bluecard_write_wakeup(info);
2104 + set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
2105 + outb(0x02, iobase + REG_INTERRUPT);
2106 + bluecard_write_wakeup(info);
2111 + /* Enable interrupt */
2112 + info->ctrl_reg |= REG_CONTROL_INTERRUPT;
2113 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2115 + spin_unlock(&(info->lock));
2120 +/* ======================== Device specific HCI commands ======================== */
2123 +static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
2125 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2126 + struct sk_buff *skb;
2128 + /* Ericsson baud rate command */
2129 + unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
2131 + if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
2132 + printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
2139 + skb->pkt_type = PKT_BAUD_RATE_460800;
2143 + skb->pkt_type = PKT_BAUD_RATE_230400;
2147 + skb->pkt_type = PKT_BAUD_RATE_115200;
2150 + /* Fall through... */
2153 + skb->pkt_type = PKT_BAUD_RATE_57600;
2157 + memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
2159 + skb_queue_tail(&(info->txq), skb);
2161 + bluecard_write_wakeup(info);
2168 +/* ======================== HCI interface ======================== */
2171 +static int bluecard_hci_flush(struct hci_dev *hdev)
2173 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2175 + /* Drop TX queue */
2176 + skb_queue_purge(&(info->txq));
2182 +static int bluecard_hci_open(struct hci_dev *hdev)
2184 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2185 + unsigned int iobase = info->link.io.BasePort1;
2187 + bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
2189 + if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
2193 + outb(0x08 | 0x20, iobase + 0x30);
2199 +static int bluecard_hci_close(struct hci_dev *hdev)
2201 + bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
2202 + unsigned int iobase = info->link.io.BasePort1;
2204 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
2207 + bluecard_hci_flush(hdev);
2210 + outb(0x00, iobase + 0x30);
2216 +static int bluecard_hci_send_frame(struct sk_buff *skb)
2218 + bluecard_info_t *info;
2219 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
2222 + printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
2226 + info = (bluecard_info_t *)(hdev->driver_data);
2228 + switch (skb->pkt_type) {
2229 + case HCI_COMMAND_PKT:
2230 + hdev->stat.cmd_tx++;
2232 + case HCI_ACLDATA_PKT:
2233 + hdev->stat.acl_tx++;
2235 + case HCI_SCODATA_PKT:
2236 + hdev->stat.sco_tx++;
2240 + /* Prepend skb with frame type */
2241 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
2242 + skb_queue_tail(&(info->txq), skb);
2244 + bluecard_write_wakeup(info);
2250 +static void bluecard_hci_destruct(struct hci_dev *hdev)
2255 +static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
2257 + return -ENOIOCTLCMD;
2262 +/* ======================== Card services HCI interaction ======================== */
2265 +int bluecard_open(bluecard_info_t *info)
2267 + unsigned int iobase = info->link.io.BasePort1;
2268 + struct hci_dev *hdev;
2271 + spin_lock_init(&(info->lock));
2273 + init_timer(&(info->timer));
2274 + info->timer.function = &bluecard_activity_led_timeout;
2275 + info->timer.data = (u_long)info;
2277 + skb_queue_head_init(&(info->txq));
2279 + info->rx_state = RECV_WAIT_PACKET_TYPE;
2280 + info->rx_count = 0;
2281 + info->rx_skb = NULL;
2283 + id = inb(iobase + 0x30);
2285 + if ((id & 0x0f) == 0x02)
2286 + set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
2289 + set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
2292 + set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
2295 + info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
2296 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2298 + /* Turn FPGA off */
2299 + outb(0x80, iobase + 0x30);
2301 + /* Wait some time */
2302 + set_current_state(TASK_INTERRUPTIBLE);
2303 + schedule_timeout(HZ / 100);
2305 + /* Turn FPGA on */
2306 + outb(0x00, iobase + 0x30);
2308 + /* Activate card */
2309 + info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
2310 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2312 + /* Enable interrupt */
2313 + outb(0xff, iobase + REG_INTERRUPT);
2314 + info->ctrl_reg |= REG_CONTROL_INTERRUPT;
2315 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2317 + /* Start the RX buffers */
2318 + outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
2319 + outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
2321 + /* Signal that the hardware is ready */
2322 + set_bit(CARD_READY, &(info->hw_state));
2324 + /* Drop TX queue */
2325 + skb_queue_purge(&(info->txq));
2327 + /* Control the point at which RTS is enabled */
2328 + outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
2330 + /* Timeout before it is safe to send the first HCI packet */
2331 + set_current_state(TASK_INTERRUPTIBLE);
2332 + schedule_timeout((HZ * 5) / 4); // or set it to 3/2
2335 + /* Initialize and register HCI device */
2337 + hdev = &(info->hdev);
2339 + hdev->type = HCI_PCCARD;
2340 + hdev->driver_data = info;
2342 + hdev->open = bluecard_hci_open;
2343 + hdev->close = bluecard_hci_close;
2344 + hdev->flush = bluecard_hci_flush;
2345 + hdev->send = bluecard_hci_send_frame;
2346 + hdev->destruct = bluecard_hci_destruct;
2347 + hdev->ioctl = bluecard_hci_ioctl;
2349 + if (hci_register_dev(hdev) < 0) {
2350 + printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
2358 +int bluecard_close(bluecard_info_t *info)
2360 + unsigned int iobase = info->link.io.BasePort1;
2361 + struct hci_dev *hdev = &(info->hdev);
2363 + bluecard_hci_close(hdev);
2365 + clear_bit(CARD_READY, &(info->hw_state));
2368 + info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
2369 + outb(info->ctrl_reg, iobase + REG_CONTROL);
2371 + /* Turn FPGA off */
2372 + outb(0x80, iobase + 0x30);
2374 + if (hci_unregister_dev(hdev) < 0)
2375 + printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
2382 +/* ======================== Card services ======================== */
2385 +static void cs_error(client_handle_t handle, int func, int ret)
2387 + error_info_t err = { func, ret };
2389 + CardServices(ReportError, handle, &err);
2393 +dev_link_t *bluecard_attach(void)
2395 + bluecard_info_t *info;
2396 + client_reg_t client_reg;
2400 + /* Create new info device */
2401 + info = kmalloc(sizeof(*info), GFP_KERNEL);
2404 + memset(info, 0, sizeof(*info));
2406 + link = &info->link;
2407 + link->priv = info;
2409 + link->release.function = &bluecard_release;
2410 + link->release.data = (u_long)link;
2411 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
2412 + link->io.NumPorts1 = 8;
2413 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
2414 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
2416 + if (irq_list[0] == -1)
2417 + link->irq.IRQInfo2 = irq_mask;
2419 + for (i = 0; i < 4; i++)
2420 + link->irq.IRQInfo2 |= 1 << irq_list[i];
2422 + link->irq.Handler = bluecard_interrupt;
2423 + link->irq.Instance = info;
2425 + link->conf.Attributes = CONF_ENABLE_IRQ;
2426 + link->conf.Vcc = 50;
2427 + link->conf.IntType = INT_MEMORY_AND_IO;
2429 + /* Register with Card Services */
2430 + link->next = dev_list;
2432 + client_reg.dev_info = &dev_info;
2433 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
2434 + client_reg.EventMask =
2435 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
2436 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
2437 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
2438 + client_reg.event_handler = &bluecard_event;
2439 + client_reg.Version = 0x0210;
2440 + client_reg.event_callback_args.client_data = link;
2442 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
2443 + if (ret != CS_SUCCESS) {
2444 + cs_error(link->handle, RegisterClient, ret);
2445 + bluecard_detach(link);
2453 +void bluecard_detach(dev_link_t *link)
2455 + bluecard_info_t *info = link->priv;
2456 + dev_link_t **linkp;
2459 + /* Locate device structure */
2460 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
2461 + if (*linkp == link)
2464 + if (*linkp == NULL)
2467 + del_timer(&link->release);
2468 + if (link->state & DEV_CONFIG)
2469 + bluecard_release((u_long)link);
2471 + if (link->handle) {
2472 + ret = CardServices(DeregisterClient, link->handle);
2473 + if (ret != CS_SUCCESS)
2474 + cs_error(link->handle, DeregisterClient, ret);
2477 + /* Unlink device structure, free bits */
2478 + *linkp = link->next;
2484 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
2488 + i = CardServices(fn, handle, tuple);
2489 + if (i != CS_SUCCESS)
2490 + return CS_NO_MORE_ITEMS;
2492 + i = CardServices(GetTupleData, handle, tuple);
2493 + if (i != CS_SUCCESS)
2496 + return CardServices(ParseTuple, handle, tuple, parse);
2500 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
2501 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
2503 +void bluecard_config(dev_link_t *link)
2505 + client_handle_t handle = link->handle;
2506 + bluecard_info_t *info = link->priv;
2510 + config_info_t config;
2511 + int i, n, last_ret, last_fn;
2513 + tuple.TupleData = (cisdata_t *)buf;
2514 + tuple.TupleOffset = 0;
2515 + tuple.TupleDataMax = 255;
2516 + tuple.Attributes = 0;
2518 + /* Get configuration register information */
2519 + tuple.DesiredTuple = CISTPL_CONFIG;
2520 + last_ret = first_tuple(handle, &tuple, &parse);
2521 + if (last_ret != CS_SUCCESS) {
2522 + last_fn = ParseTuple;
2525 + link->conf.ConfigBase = parse.config.base;
2526 + link->conf.Present = parse.config.rmask[0];
2528 + /* Configure card */
2529 + link->state |= DEV_CONFIG;
2530 + i = CardServices(GetConfigurationInfo, handle, &config);
2531 + link->conf.Vcc = config.Vcc;
2533 + link->conf.ConfigIndex = 0x20;
2534 + link->io.NumPorts1 = 64;
2535 + link->io.IOAddrLines = 6;
2537 + for (n = 0; n < 0x400; n += 0x40) {
2538 + link->io.BasePort1 = n ^ 0x300;
2539 + i = CardServices(RequestIO, link->handle, &link->io);
2540 + if (i == CS_SUCCESS)
2544 + if (i != CS_SUCCESS) {
2545 + cs_error(link->handle, RequestIO, i);
2549 + i = CardServices(RequestIRQ, link->handle, &link->irq);
2550 + if (i != CS_SUCCESS) {
2551 + cs_error(link->handle, RequestIRQ, i);
2552 + link->irq.AssignedIRQ = 0;
2555 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
2556 + if (i != CS_SUCCESS) {
2557 + cs_error(link->handle, RequestConfiguration, i);
2561 + MOD_INC_USE_COUNT;
2563 + if (bluecard_open(info) != 0)
2566 + strcpy(info->node.dev_name, info->hdev.name);
2567 + link->dev = &info->node;
2568 + link->state &= ~DEV_CONFIG_PENDING;
2573 + cs_error(link->handle, last_fn, last_ret);
2576 + bluecard_release((u_long)link);
2580 +void bluecard_release(u_long arg)
2582 + dev_link_t *link = (dev_link_t *)arg;
2583 + bluecard_info_t *info = link->priv;
2585 + if (link->state & DEV_PRESENT)
2586 + bluecard_close(info);
2588 + MOD_DEC_USE_COUNT;
2592 + CardServices(ReleaseConfiguration, link->handle);
2593 + CardServices(ReleaseIO, link->handle, &link->io);
2594 + CardServices(ReleaseIRQ, link->handle, &link->irq);
2596 + link->state &= ~DEV_CONFIG;
2600 +int bluecard_event(event_t event, int priority, event_callback_args_t *args)
2602 + dev_link_t *link = args->client_data;
2603 + bluecard_info_t *info = link->priv;
2606 + case CS_EVENT_CARD_REMOVAL:
2607 + link->state &= ~DEV_PRESENT;
2608 + if (link->state & DEV_CONFIG) {
2609 + bluecard_close(info);
2610 + mod_timer(&link->release, jiffies + HZ / 20);
2613 + case CS_EVENT_CARD_INSERTION:
2614 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2615 + bluecard_config(link);
2617 + case CS_EVENT_PM_SUSPEND:
2618 + link->state |= DEV_SUSPEND;
2619 + /* Fall through... */
2620 + case CS_EVENT_RESET_PHYSICAL:
2621 + if (link->state & DEV_CONFIG)
2622 + CardServices(ReleaseConfiguration, link->handle);
2624 + case CS_EVENT_PM_RESUME:
2625 + link->state &= ~DEV_SUSPEND;
2626 + /* Fall through... */
2627 + case CS_EVENT_CARD_RESET:
2629 + CardServices(RequestConfiguration, link->handle, &link->conf);
2638 +/* ======================== Module initialization ======================== */
2641 +int __init init_bluecard_cs(void)
2646 + CardServices(GetCardServicesInfo, &serv);
2647 + if (serv.Revision != CS_RELEASE_CODE) {
2648 + printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
2652 + err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
2658 +void __exit exit_bluecard_cs(void)
2660 + unregister_pccard_driver(&dev_info);
2662 + while (dev_list != NULL)
2663 + bluecard_detach(dev_list);
2667 +module_init(init_bluecard_cs);
2668 +module_exit(exit_bluecard_cs);
2671 diff -urN linux-2.4.18/drivers/bluetooth/bt3c_cs.c linux-2.4.18-mh9/drivers/bluetooth/bt3c_cs.c
2672 --- linux-2.4.18/drivers/bluetooth/bt3c_cs.c Thu Jan 1 01:00:00 1970
2673 +++ linux-2.4.18-mh9/drivers/bluetooth/bt3c_cs.c Mon Aug 25 18:38:10 2003
2677 + * Driver for the 3Com Bluetooth PCMCIA card
2679 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
2680 + * Jose Orlando Pereira <jop@di.uminho.pt>
2683 + * This program is free software; you can redistribute it and/or modify
2684 + * it under the terms of the GNU General Public License version 2 as
2685 + * published by the Free Software Foundation;
2687 + * Software distributed under the License is distributed on an "AS
2688 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
2689 + * implied. See the License for the specific language governing
2690 + * rights and limitations under the License.
2692 + * The initial developer of the original code is David A. Hinds
2693 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
2694 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
2698 +#include <linux/config.h>
2699 +#include <linux/module.h>
2701 +#define __KERNEL_SYSCALLS__
2703 +#include <linux/kernel.h>
2704 +#include <linux/kmod.h>
2705 +#include <linux/init.h>
2706 +#include <linux/slab.h>
2707 +#include <linux/types.h>
2708 +#include <linux/sched.h>
2709 +#include <linux/delay.h>
2710 +#include <linux/timer.h>
2711 +#include <linux/errno.h>
2712 +#include <linux/unistd.h>
2713 +#include <linux/ptrace.h>
2714 +#include <linux/ioport.h>
2715 +#include <linux/spinlock.h>
2717 +#include <linux/skbuff.h>
2718 +#include <linux/string.h>
2719 +#include <linux/serial.h>
2720 +#include <linux/serial_reg.h>
2721 +#include <asm/system.h>
2722 +#include <asm/bitops.h>
2723 +#include <asm/io.h>
2725 +#include <pcmcia/version.h>
2726 +#include <pcmcia/cs_types.h>
2727 +#include <pcmcia/cs.h>
2728 +#include <pcmcia/cistpl.h>
2729 +#include <pcmcia/ciscode.h>
2730 +#include <pcmcia/ds.h>
2731 +#include <pcmcia/cisreg.h>
2733 +#include <net/bluetooth/bluetooth.h>
2734 +#include <net/bluetooth/hci_core.h>
2738 +/* ======================== Module parameters ======================== */
2741 +/* Bit map of interrupts to choose from */
2742 +static u_int irq_mask = 0xffff;
2743 +static int irq_list[4] = { -1 };
2745 +MODULE_PARM(irq_mask, "i");
2746 +MODULE_PARM(irq_list, "1-4i");
2748 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
2749 +MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
2750 +MODULE_LICENSE("GPL");
2754 +/* ======================== Local structures ======================== */
2757 +typedef struct bt3c_info_t {
2761 + struct hci_dev hdev;
2763 + spinlock_t lock; /* For serializing operations */
2765 + struct sk_buff_head txq;
2766 + unsigned long tx_state;
2768 + unsigned long rx_state;
2769 + unsigned long rx_count;
2770 + struct sk_buff *rx_skb;
2774 +void bt3c_config(dev_link_t *link);
2775 +void bt3c_release(u_long arg);
2776 +int bt3c_event(event_t event, int priority, event_callback_args_t *args);
2778 +static dev_info_t dev_info = "bt3c_cs";
2780 +dev_link_t *bt3c_attach(void);
2781 +void bt3c_detach(dev_link_t *);
2783 +static dev_link_t *dev_list = NULL;
2786 +/* Transmit states */
2787 +#define XMIT_SENDING 1
2788 +#define XMIT_WAKEUP 2
2789 +#define XMIT_WAITING 8
2791 +/* Receiver states */
2792 +#define RECV_WAIT_PACKET_TYPE 0
2793 +#define RECV_WAIT_EVENT_HEADER 1
2794 +#define RECV_WAIT_ACL_HEADER 2
2795 +#define RECV_WAIT_SCO_HEADER 3
2796 +#define RECV_WAIT_DATA 4
2800 +/* ======================== Special I/O functions ======================== */
2810 +inline void bt3c_address(unsigned int iobase, unsigned short addr)
2812 + outb(addr & 0xff, iobase + ADDR_L);
2813 + outb((addr >> 8) & 0xff, iobase + ADDR_H);
2817 +inline void bt3c_put(unsigned int iobase, unsigned short value)
2819 + outb(value & 0xff, iobase + DATA_L);
2820 + outb((value >> 8) & 0xff, iobase + DATA_H);
2824 +inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
2826 + bt3c_address(iobase, addr);
2827 + bt3c_put(iobase, value);
2831 +inline unsigned short bt3c_get(unsigned int iobase)
2833 + unsigned short value = inb(iobase + DATA_L);
2835 + value |= inb(iobase + DATA_H) << 8;
2841 +inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
2843 + bt3c_address(iobase, addr);
2845 + return bt3c_get(iobase);
2850 +/* ======================== Interrupt handling ======================== */
2853 +static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
2857 + bt3c_address(iobase, 0x7080);
2859 + /* Fill FIFO with current frame */
2860 + while (actual < len) {
2861 + /* Transmit next byte */
2862 + bt3c_put(iobase, buf[actual]);
2866 + bt3c_io_write(iobase, 0x7005, actual);
2872 +static void bt3c_write_wakeup(bt3c_info_t *info, int from)
2874 + unsigned long flags;
2877 + printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
2881 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
2884 + spin_lock_irqsave(&(info->lock), flags);
2887 + register unsigned int iobase = info->link.io.BasePort1;
2888 + register struct sk_buff *skb;
2891 + if (!(info->link.state & DEV_PRESENT))
2895 + if (!(skb = skb_dequeue(&(info->txq)))) {
2896 + clear_bit(XMIT_SENDING, &(info->tx_state));
2901 + len = bt3c_write(iobase, 256, skb->data, skb->len);
2903 + if (len != skb->len) {
2904 + printk(KERN_WARNING "bt3c_cs: very strange\n");
2909 + info->hdev.stat.byte_tx += len;
2913 + spin_unlock_irqrestore(&(info->lock), flags);
2917 +static void bt3c_receive(bt3c_info_t *info)
2919 + unsigned int iobase;
2920 + int size = 0, avail;
2923 + printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
2927 + iobase = info->link.io.BasePort1;
2929 + avail = bt3c_read(iobase, 0x7006);
2930 + //printk("bt3c_cs: receiving %d bytes\n", avail);
2932 + bt3c_address(iobase, 0x7480);
2933 + while (size < avail) {
2935 + info->hdev.stat.byte_rx++;
2937 + /* Allocate packet */
2938 + if (info->rx_skb == NULL) {
2939 + info->rx_state = RECV_WAIT_PACKET_TYPE;
2940 + info->rx_count = 0;
2941 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
2942 + printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
2948 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
2950 + info->rx_skb->dev = (void *)&(info->hdev);
2951 + info->rx_skb->pkt_type = inb(iobase + DATA_L);
2952 + inb(iobase + DATA_H);
2953 + //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
2955 + switch (info->rx_skb->pkt_type) {
2957 + case HCI_EVENT_PKT:
2958 + info->rx_state = RECV_WAIT_EVENT_HEADER;
2959 + info->rx_count = HCI_EVENT_HDR_SIZE;
2962 + case HCI_ACLDATA_PKT:
2963 + info->rx_state = RECV_WAIT_ACL_HEADER;
2964 + info->rx_count = HCI_ACL_HDR_SIZE;
2967 + case HCI_SCODATA_PKT:
2968 + info->rx_state = RECV_WAIT_SCO_HEADER;
2969 + info->rx_count = HCI_SCO_HDR_SIZE;
2973 + /* Unknown packet */
2974 + printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
2975 + info->hdev.stat.err_rx++;
2976 + clear_bit(HCI_RUNNING, &(info->hdev.flags));
2978 + kfree_skb(info->rx_skb);
2979 + info->rx_skb = NULL;
2986 + __u8 x = inb(iobase + DATA_L);
2988 + *skb_put(info->rx_skb, 1) = x;
2989 + inb(iobase + DATA_H);
2992 + if (info->rx_count == 0) {
2995 + hci_event_hdr *eh;
2999 + switch (info->rx_state) {
3001 + case RECV_WAIT_EVENT_HEADER:
3002 + eh = (hci_event_hdr *)(info->rx_skb->data);
3003 + info->rx_state = RECV_WAIT_DATA;
3004 + info->rx_count = eh->plen;
3007 + case RECV_WAIT_ACL_HEADER:
3008 + ah = (hci_acl_hdr *)(info->rx_skb->data);
3009 + dlen = __le16_to_cpu(ah->dlen);
3010 + info->rx_state = RECV_WAIT_DATA;
3011 + info->rx_count = dlen;
3014 + case RECV_WAIT_SCO_HEADER:
3015 + sh = (hci_sco_hdr *)(info->rx_skb->data);
3016 + info->rx_state = RECV_WAIT_DATA;
3017 + info->rx_count = sh->dlen;
3020 + case RECV_WAIT_DATA:
3021 + hci_recv_frame(info->rx_skb);
3022 + info->rx_skb = NULL;
3033 + bt3c_io_write(iobase, 0x7006, 0x0000);
3037 +void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
3039 + bt3c_info_t *info = dev_inst;
3040 + unsigned int iobase;
3044 + printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
3048 + iobase = info->link.io.BasePort1;
3050 + spin_lock(&(info->lock));
3052 + iir = inb(iobase + CONTROL);
3054 + int stat = bt3c_read(iobase, 0x7001);
3056 + if ((stat & 0xff) == 0x7f) {
3057 + printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
3058 + } else if ((stat & 0xff) != 0xff) {
3059 + if (stat & 0x0020) {
3060 + int stat = bt3c_read(iobase, 0x7002) & 0x10;
3061 + printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
3063 + if (stat & 0x0001)
3064 + bt3c_receive(info);
3065 + if (stat & 0x0002) {
3066 + //printk("bt3c_cs: ACK %04x\n", stat);
3067 + clear_bit(XMIT_SENDING, &(info->tx_state));
3068 + bt3c_write_wakeup(info, 1);
3071 + bt3c_io_write(iobase, 0x7001, 0x0000);
3073 + outb(iir, iobase + CONTROL);
3077 + spin_unlock(&(info->lock));
3083 +/* ======================== HCI interface ======================== */
3086 +static int bt3c_hci_flush(struct hci_dev *hdev)
3088 + bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
3090 + /* Drop TX queue */
3091 + skb_queue_purge(&(info->txq));
3097 +static int bt3c_hci_open(struct hci_dev *hdev)
3099 + set_bit(HCI_RUNNING, &(hdev->flags));
3105 +static int bt3c_hci_close(struct hci_dev *hdev)
3107 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
3110 + bt3c_hci_flush(hdev);
3116 +static int bt3c_hci_send_frame(struct sk_buff *skb)
3118 + bt3c_info_t *info;
3119 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
3122 + printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
3126 + info = (bt3c_info_t *) (hdev->driver_data);
3128 + switch (skb->pkt_type) {
3129 + case HCI_COMMAND_PKT:
3130 + hdev->stat.cmd_tx++;
3132 + case HCI_ACLDATA_PKT:
3133 + hdev->stat.acl_tx++;
3135 + case HCI_SCODATA_PKT:
3136 + hdev->stat.sco_tx++;
3140 + /* Prepend skb with frame type */
3141 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
3142 + skb_queue_tail(&(info->txq), skb);
3144 + bt3c_write_wakeup(info, 0);
3150 +static void bt3c_hci_destruct(struct hci_dev *hdev)
3155 +static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
3157 + return -ENOIOCTLCMD;
3162 +/* ======================== User mode firmware loader ======================== */
3165 +#define FW_LOADER "/sbin/bluefw"
3169 +static int bt3c_fw_loader_exec(void *dev)
3171 + char *argv[] = { FW_LOADER, "pccard", dev, NULL };
3172 + char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
3175 + err = exec_usermodehelper(FW_LOADER, argv, envp);
3177 + printk(KERN_WARNING "bt3c_cs: Failed to exec \"%s pccard %s\".\n", FW_LOADER, (char *)dev);
3183 +static int bt3c_firmware_load(bt3c_info_t *info)
3190 + /* Check if root fs is mounted */
3191 + if (!current->fs->root) {
3192 + printk(KERN_WARNING "bt3c_cs: Root filesystem is not mounted.\n");
3196 + sprintf(dev, "%04x", info->link.io.BasePort1);
3198 + pid = kernel_thread(bt3c_fw_loader_exec, (void *)dev, 0);
3200 + printk(KERN_WARNING "bt3c_cs: Forking of kernel thread failed (errno=%d).\n", -pid);
3204 + /* Block signals, everything but SIGKILL/SIGSTOP */
3205 + spin_lock_irq(¤t->sigmask_lock);
3206 + tmpsig = current->blocked;
3207 + siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
3208 + recalc_sigpending(current);
3209 + spin_unlock_irq(¤t->sigmask_lock);
3211 + result = waitpid(pid, NULL, __WCLONE);
3213 + /* Allow signals again */
3214 + spin_lock_irq(¤t->sigmask_lock);
3215 + current->blocked = tmpsig;
3216 + recalc_sigpending(current);
3217 + spin_unlock_irq(¤t->sigmask_lock);
3219 + if (result != pid) {
3220 + printk(KERN_WARNING "bt3c_cs: Waiting for pid %d failed (errno=%d).\n", pid, -result);
3229 +/* ======================== Card services HCI interaction ======================== */
3232 +int bt3c_open(bt3c_info_t *info)
3234 + struct hci_dev *hdev;
3237 + spin_lock_init(&(info->lock));
3239 + skb_queue_head_init(&(info->txq));
3241 + info->rx_state = RECV_WAIT_PACKET_TYPE;
3242 + info->rx_count = 0;
3243 + info->rx_skb = NULL;
3245 + /* Load firmware */
3247 + if ((err = bt3c_firmware_load(info)) < 0)
3250 + /* Timeout before it is safe to send the first HCI packet */
3252 + set_current_state(TASK_INTERRUPTIBLE);
3253 + schedule_timeout(HZ);
3256 + /* Initialize and register HCI device */
3258 + hdev = &(info->hdev);
3260 + hdev->type = HCI_PCCARD;
3261 + hdev->driver_data = info;
3263 + hdev->open = bt3c_hci_open;
3264 + hdev->close = bt3c_hci_close;
3265 + hdev->flush = bt3c_hci_flush;
3266 + hdev->send = bt3c_hci_send_frame;
3267 + hdev->destruct = bt3c_hci_destruct;
3268 + hdev->ioctl = bt3c_hci_ioctl;
3270 + if (hci_register_dev(hdev) < 0) {
3271 + printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
3279 +int bt3c_close(bt3c_info_t *info)
3281 + struct hci_dev *hdev = &(info->hdev);
3283 + bt3c_hci_close(hdev);
3285 + if (hci_unregister_dev(hdev) < 0)
3286 + printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
3293 +/* ======================== Card services ======================== */
3296 +static void cs_error(client_handle_t handle, int func, int ret)
3298 + error_info_t err = { func, ret };
3300 + CardServices(ReportError, handle, &err);
3304 +dev_link_t *bt3c_attach(void)
3306 + bt3c_info_t *info;
3307 + client_reg_t client_reg;
3311 + /* Create new info device */
3312 + info = kmalloc(sizeof(*info), GFP_KERNEL);
3315 + memset(info, 0, sizeof(*info));
3317 + link = &info->link;
3318 + link->priv = info;
3320 + link->release.function = &bt3c_release;
3321 + link->release.data = (u_long)link;
3322 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
3323 + link->io.NumPorts1 = 8;
3324 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
3325 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
3327 + if (irq_list[0] == -1)
3328 + link->irq.IRQInfo2 = irq_mask;
3330 + for (i = 0; i < 4; i++)
3331 + link->irq.IRQInfo2 |= 1 << irq_list[i];
3333 + link->irq.Handler = bt3c_interrupt;
3334 + link->irq.Instance = info;
3336 + link->conf.Attributes = CONF_ENABLE_IRQ;
3337 + link->conf.Vcc = 50;
3338 + link->conf.IntType = INT_MEMORY_AND_IO;
3340 + /* Register with Card Services */
3341 + link->next = dev_list;
3343 + client_reg.dev_info = &dev_info;
3344 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
3345 + client_reg.EventMask =
3346 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
3347 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
3348 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
3349 + client_reg.event_handler = &bt3c_event;
3350 + client_reg.Version = 0x0210;
3351 + client_reg.event_callback_args.client_data = link;
3353 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
3354 + if (ret != CS_SUCCESS) {
3355 + cs_error(link->handle, RegisterClient, ret);
3356 + bt3c_detach(link);
3364 +void bt3c_detach(dev_link_t *link)
3366 + bt3c_info_t *info = link->priv;
3367 + dev_link_t **linkp;
3370 + /* Locate device structure */
3371 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
3372 + if (*linkp == link)
3375 + if (*linkp == NULL)
3378 + del_timer(&link->release);
3380 + if (link->state & DEV_CONFIG)
3381 + bt3c_release((u_long)link);
3383 + if (link->handle) {
3384 + ret = CardServices(DeregisterClient, link->handle);
3385 + if (ret != CS_SUCCESS)
3386 + cs_error(link->handle, DeregisterClient, ret);
3389 + /* Unlink device structure, free bits */
3390 + *linkp = link->next;
3396 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
3400 + i = CardServices(fn, handle, tuple);
3401 + if (i != CS_SUCCESS)
3402 + return CS_NO_MORE_ITEMS;
3404 + i = CardServices(GetTupleData, handle, tuple);
3405 + if (i != CS_SUCCESS)
3408 + return CardServices(ParseTuple, handle, tuple, parse);
3412 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
3413 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
3415 +void bt3c_config(dev_link_t *link)
3417 + static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
3418 + client_handle_t handle = link->handle;
3419 + bt3c_info_t *info = link->priv;
3423 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
3424 + config_info_t config;
3425 + int i, j, try, last_ret, last_fn;
3427 + tuple.TupleData = (cisdata_t *)buf;
3428 + tuple.TupleOffset = 0;
3429 + tuple.TupleDataMax = 255;
3430 + tuple.Attributes = 0;
3432 + /* Get configuration register information */
3433 + tuple.DesiredTuple = CISTPL_CONFIG;
3434 + last_ret = first_tuple(handle, &tuple, &parse);
3435 + if (last_ret != CS_SUCCESS) {
3436 + last_fn = ParseTuple;
3439 + link->conf.ConfigBase = parse.config.base;
3440 + link->conf.Present = parse.config.rmask[0];
3442 + /* Configure card */
3443 + link->state |= DEV_CONFIG;
3444 + i = CardServices(GetConfigurationInfo, handle, &config);
3445 + link->conf.Vcc = config.Vcc;
3447 + /* First pass: look for a config entry that looks normal. */
3448 + tuple.TupleData = (cisdata_t *)buf;
3449 + tuple.TupleOffset = 0;
3450 + tuple.TupleDataMax = 255;
3451 + tuple.Attributes = 0;
3452 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
3453 + /* Two tries: without IO aliases, then with aliases */
3454 + for (try = 0; try < 2; try++) {
3455 + i = first_tuple(handle, &tuple, &parse);
3456 + while (i != CS_NO_MORE_ITEMS) {
3457 + if (i != CS_SUCCESS)
3459 + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
3460 + link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
3461 + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
3462 + link->conf.ConfigIndex = cf->index;
3463 + link->io.BasePort1 = cf->io.win[0].base;
3464 + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
3465 + i = CardServices(RequestIO, link->handle, &link->io);
3466 + if (i == CS_SUCCESS)
3470 + i = next_tuple(handle, &tuple, &parse);
3474 + /* Second pass: try to find an entry that isn't picky about
3475 + its base address, then try to grab any standard serial port
3476 + address, and finally try to get any free port. */
3477 + i = first_tuple(handle, &tuple, &parse);
3478 + while (i != CS_NO_MORE_ITEMS) {
3479 + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
3480 + link->conf.ConfigIndex = cf->index;
3481 + for (j = 0; j < 5; j++) {
3482 + link->io.BasePort1 = base[j];
3483 + link->io.IOAddrLines = base[j] ? 16 : 3;
3484 + i = CardServices(RequestIO, link->handle, &link->io);
3485 + if (i == CS_SUCCESS)
3489 + i = next_tuple(handle, &tuple, &parse);
3493 + if (i != CS_SUCCESS) {
3494 + printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
3495 + cs_error(link->handle, RequestIO, i);
3499 + i = CardServices(RequestIRQ, link->handle, &link->irq);
3500 + if (i != CS_SUCCESS) {
3501 + cs_error(link->handle, RequestIRQ, i);
3502 + link->irq.AssignedIRQ = 0;
3505 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
3506 + if (i != CS_SUCCESS) {
3507 + cs_error(link->handle, RequestConfiguration, i);
3511 + MOD_INC_USE_COUNT;
3513 + if (bt3c_open(info) != 0)
3516 + strcpy(info->node.dev_name, info->hdev.name);
3517 + link->dev = &info->node;
3518 + link->state &= ~DEV_CONFIG_PENDING;
3523 + cs_error(link->handle, last_fn, last_ret);
3526 + bt3c_release((u_long)link);
3530 +void bt3c_release(u_long arg)
3532 + dev_link_t *link = (dev_link_t *)arg;
3533 + bt3c_info_t *info = link->priv;
3535 + if (link->state & DEV_PRESENT)
3538 + MOD_DEC_USE_COUNT;
3542 + CardServices(ReleaseConfiguration, link->handle);
3543 + CardServices(ReleaseIO, link->handle, &link->io);
3544 + CardServices(ReleaseIRQ, link->handle, &link->irq);
3546 + link->state &= ~DEV_CONFIG;
3550 +int bt3c_event(event_t event, int priority, event_callback_args_t *args)
3552 + dev_link_t *link = args->client_data;
3553 + bt3c_info_t *info = link->priv;
3556 + case CS_EVENT_CARD_REMOVAL:
3557 + link->state &= ~DEV_PRESENT;
3558 + if (link->state & DEV_CONFIG) {
3560 + mod_timer(&link->release, jiffies + HZ / 20);
3563 + case CS_EVENT_CARD_INSERTION:
3564 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
3565 + bt3c_config(link);
3567 + case CS_EVENT_PM_SUSPEND:
3568 + link->state |= DEV_SUSPEND;
3569 + /* Fall through... */
3570 + case CS_EVENT_RESET_PHYSICAL:
3571 + if (link->state & DEV_CONFIG)
3572 + CardServices(ReleaseConfiguration, link->handle);
3574 + case CS_EVENT_PM_RESUME:
3575 + link->state &= ~DEV_SUSPEND;
3576 + /* Fall through... */
3577 + case CS_EVENT_CARD_RESET:
3579 + CardServices(RequestConfiguration, link->handle, &link->conf);
3588 +/* ======================== Module initialization ======================== */
3591 +int __init init_bt3c_cs(void)
3596 + CardServices(GetCardServicesInfo, &serv);
3597 + if (serv.Revision != CS_RELEASE_CODE) {
3598 + printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
3602 + err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
3608 +void __exit exit_bt3c_cs(void)
3610 + unregister_pccard_driver(&dev_info);
3612 + while (dev_list != NULL)
3613 + bt3c_detach(dev_list);
3617 +module_init(init_bt3c_cs);
3618 +module_exit(exit_bt3c_cs);
3621 diff -urN linux-2.4.18/drivers/bluetooth/btuart_cs.c linux-2.4.18-mh9/drivers/bluetooth/btuart_cs.c
3622 --- linux-2.4.18/drivers/bluetooth/btuart_cs.c Thu Jan 1 01:00:00 1970
3623 +++ linux-2.4.18-mh9/drivers/bluetooth/btuart_cs.c Mon Aug 25 18:38:10 2003
3627 + * Driver for Bluetooth PCMCIA cards with HCI UART interface
3629 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
3632 + * This program is free software; you can redistribute it and/or modify
3633 + * it under the terms of the GNU General Public License version 2 as
3634 + * published by the Free Software Foundation;
3636 + * Software distributed under the License is distributed on an "AS
3637 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
3638 + * implied. See the License for the specific language governing
3639 + * rights and limitations under the License.
3641 + * The initial developer of the original code is David A. Hinds
3642 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
3643 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
3647 +#include <linux/config.h>
3648 +#include <linux/module.h>
3650 +#include <linux/kernel.h>
3651 +#include <linux/init.h>
3652 +#include <linux/slab.h>
3653 +#include <linux/types.h>
3654 +#include <linux/sched.h>
3655 +#include <linux/timer.h>
3656 +#include <linux/errno.h>
3657 +#include <linux/ptrace.h>
3658 +#include <linux/ioport.h>
3659 +#include <linux/spinlock.h>
3661 +#include <linux/skbuff.h>
3662 +#include <linux/string.h>
3663 +#include <linux/serial.h>
3664 +#include <linux/serial_reg.h>
3665 +#include <asm/system.h>
3666 +#include <asm/bitops.h>
3667 +#include <asm/io.h>
3669 +#include <pcmcia/version.h>
3670 +#include <pcmcia/cs_types.h>
3671 +#include <pcmcia/cs.h>
3672 +#include <pcmcia/cistpl.h>
3673 +#include <pcmcia/ciscode.h>
3674 +#include <pcmcia/ds.h>
3675 +#include <pcmcia/cisreg.h>
3677 +#include <net/bluetooth/bluetooth.h>
3678 +#include <net/bluetooth/hci_core.h>
3682 +/* ======================== Module parameters ======================== */
3685 +/* Bit map of interrupts to choose from */
3686 +static u_int irq_mask = 0xffff;
3687 +static int irq_list[4] = { -1 };
3689 +MODULE_PARM(irq_mask, "i");
3690 +MODULE_PARM(irq_list, "1-4i");
3692 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
3693 +MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
3694 +MODULE_LICENSE("GPL");
3698 +/* ======================== Local structures ======================== */
3701 +typedef struct btuart_info_t {
3705 + struct hci_dev hdev;
3707 + spinlock_t lock; /* For serializing operations */
3709 + struct sk_buff_head txq;
3710 + unsigned long tx_state;
3712 + unsigned long rx_state;
3713 + unsigned long rx_count;
3714 + struct sk_buff *rx_skb;
3718 +void btuart_config(dev_link_t *link);
3719 +void btuart_release(u_long arg);
3720 +int btuart_event(event_t event, int priority, event_callback_args_t *args);
3722 +static dev_info_t dev_info = "btuart_cs";
3724 +dev_link_t *btuart_attach(void);
3725 +void btuart_detach(dev_link_t *);
3727 +static dev_link_t *dev_list = NULL;
3730 +/* Maximum baud rate */
3731 +#define SPEED_MAX 115200
3733 +/* Default baud rate: 57600, 115200, 230400 or 460800 */
3734 +#define DEFAULT_BAUD_RATE 115200
3737 +/* Transmit states */
3738 +#define XMIT_SENDING 1
3739 +#define XMIT_WAKEUP 2
3740 +#define XMIT_WAITING 8
3742 +/* Receiver states */
3743 +#define RECV_WAIT_PACKET_TYPE 0
3744 +#define RECV_WAIT_EVENT_HEADER 1
3745 +#define RECV_WAIT_ACL_HEADER 2
3746 +#define RECV_WAIT_SCO_HEADER 3
3747 +#define RECV_WAIT_DATA 4
3751 +/* ======================== Interrupt handling ======================== */
3754 +static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
3758 + /* Tx FIFO should be empty */
3759 + if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
3762 + /* Fill FIFO with current frame */
3763 + while ((fifo_size-- > 0) && (actual < len)) {
3764 + /* Transmit next byte */
3765 + outb(buf[actual], iobase + UART_TX);
3773 +static void btuart_write_wakeup(btuart_info_t *info)
3776 + printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
3780 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
3781 + set_bit(XMIT_WAKEUP, &(info->tx_state));
3786 + register unsigned int iobase = info->link.io.BasePort1;
3787 + register struct sk_buff *skb;
3790 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
3792 + if (!(info->link.state & DEV_PRESENT))
3795 + if (!(skb = skb_dequeue(&(info->txq))))
3799 + len = btuart_write(iobase, 16, skb->data, skb->len);
3800 + set_bit(XMIT_WAKEUP, &(info->tx_state));
3802 + if (len == skb->len) {
3805 + skb_pull(skb, len);
3806 + skb_queue_head(&(info->txq), skb);
3809 + info->hdev.stat.byte_tx += len;
3811 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
3813 + clear_bit(XMIT_SENDING, &(info->tx_state));
3817 +static void btuart_receive(btuart_info_t *info)
3819 + unsigned int iobase;
3820 + int boguscount = 0;
3823 + printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
3827 + iobase = info->link.io.BasePort1;
3830 + info->hdev.stat.byte_rx++;
3832 + /* Allocate packet */
3833 + if (info->rx_skb == NULL) {
3834 + info->rx_state = RECV_WAIT_PACKET_TYPE;
3835 + info->rx_count = 0;
3836 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
3837 + printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
3842 + if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
3844 + info->rx_skb->dev = (void *)&(info->hdev);
3845 + info->rx_skb->pkt_type = inb(iobase + UART_RX);
3847 + switch (info->rx_skb->pkt_type) {
3849 + case HCI_EVENT_PKT:
3850 + info->rx_state = RECV_WAIT_EVENT_HEADER;
3851 + info->rx_count = HCI_EVENT_HDR_SIZE;
3854 + case HCI_ACLDATA_PKT:
3855 + info->rx_state = RECV_WAIT_ACL_HEADER;
3856 + info->rx_count = HCI_ACL_HDR_SIZE;
3859 + case HCI_SCODATA_PKT:
3860 + info->rx_state = RECV_WAIT_SCO_HEADER;
3861 + info->rx_count = HCI_SCO_HDR_SIZE;
3865 + /* Unknown packet */
3866 + printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
3867 + info->hdev.stat.err_rx++;
3868 + clear_bit(HCI_RUNNING, &(info->hdev.flags));
3870 + kfree_skb(info->rx_skb);
3871 + info->rx_skb = NULL;
3878 + *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
3881 + if (info->rx_count == 0) {
3884 + hci_event_hdr *eh;
3889 + switch (info->rx_state) {
3891 + case RECV_WAIT_EVENT_HEADER:
3892 + eh = (hci_event_hdr *)(info->rx_skb->data);
3893 + info->rx_state = RECV_WAIT_DATA;
3894 + info->rx_count = eh->plen;
3897 + case RECV_WAIT_ACL_HEADER:
3898 + ah = (hci_acl_hdr *)(info->rx_skb->data);
3899 + dlen = __le16_to_cpu(ah->dlen);
3900 + info->rx_state = RECV_WAIT_DATA;
3901 + info->rx_count = dlen;
3904 + case RECV_WAIT_SCO_HEADER:
3905 + sh = (hci_sco_hdr *)(info->rx_skb->data);
3906 + info->rx_state = RECV_WAIT_DATA;
3907 + info->rx_count = sh->dlen;
3910 + case RECV_WAIT_DATA:
3911 + hci_recv_frame(info->rx_skb);
3912 + info->rx_skb = NULL;
3921 + /* Make sure we don't stay here to long */
3922 + if (boguscount++ > 16)
3925 + } while (inb(iobase + UART_LSR) & UART_LSR_DR);
3929 +void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
3931 + btuart_info_t *info = dev_inst;
3932 + unsigned int iobase;
3933 + int boguscount = 0;
3937 + printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
3941 + iobase = info->link.io.BasePort1;
3943 + spin_lock(&(info->lock));
3945 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
3948 + /* Clear interrupt */
3949 + lsr = inb(iobase + UART_LSR);
3952 + case UART_IIR_RLSI:
3953 + printk(KERN_NOTICE "btuart_cs: RLSI\n");
3955 + case UART_IIR_RDI:
3956 + /* Receive interrupt */
3957 + btuart_receive(info);
3959 + case UART_IIR_THRI:
3960 + if (lsr & UART_LSR_THRE) {
3961 + /* Transmitter ready for data */
3962 + btuart_write_wakeup(info);
3966 + printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
3970 + /* Make sure we don't stay here to long */
3971 + if (boguscount++ > 100)
3974 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
3978 + spin_unlock(&(info->lock));
3982 +static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
3984 + unsigned long flags;
3985 + unsigned int iobase;
3986 + int fcr; /* FIFO control reg */
3987 + int lcr; /* Line control reg */
3991 + printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
3995 + iobase = info->link.io.BasePort1;
3997 + spin_lock_irqsave(&(info->lock), flags);
3999 + /* Turn off interrupts */
4000 + outb(0, iobase + UART_IER);
4002 + divisor = SPEED_MAX / speed;
4004 + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
4007 + * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
4008 + * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
4009 + * about this timeout since it will always be fast enough.
4012 + if (speed < 38400)
4013 + fcr |= UART_FCR_TRIGGER_1;
4015 + fcr |= UART_FCR_TRIGGER_14;
4017 + /* Bluetooth cards use 8N1 */
4018 + lcr = UART_LCR_WLEN8;
4020 + outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
4021 + outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
4022 + outb(divisor >> 8, iobase + UART_DLM);
4023 + outb(lcr, iobase + UART_LCR); /* Set 8N1 */
4024 + outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
4026 + /* Turn on interrups */
4027 + outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
4029 + spin_unlock_irqrestore(&(info->lock), flags);
4034 +/* ======================== HCI interface ======================== */
4037 +static int btuart_hci_flush(struct hci_dev *hdev)
4039 + btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
4041 + /* Drop TX queue */
4042 + skb_queue_purge(&(info->txq));
4048 +static int btuart_hci_open(struct hci_dev *hdev)
4050 + set_bit(HCI_RUNNING, &(hdev->flags));
4056 +static int btuart_hci_close(struct hci_dev *hdev)
4058 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
4061 + btuart_hci_flush(hdev);
4067 +static int btuart_hci_send_frame(struct sk_buff *skb)
4069 + btuart_info_t *info;
4070 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
4073 + printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
4077 + info = (btuart_info_t *)(hdev->driver_data);
4079 + switch (skb->pkt_type) {
4080 + case HCI_COMMAND_PKT:
4081 + hdev->stat.cmd_tx++;
4083 + case HCI_ACLDATA_PKT:
4084 + hdev->stat.acl_tx++;
4086 + case HCI_SCODATA_PKT:
4087 + hdev->stat.sco_tx++;
4091 + /* Prepend skb with frame type */
4092 + memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
4093 + skb_queue_tail(&(info->txq), skb);
4095 + btuart_write_wakeup(info);
4101 +static void btuart_hci_destruct(struct hci_dev *hdev)
4106 +static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
4108 + return -ENOIOCTLCMD;
4113 +/* ======================== Card services HCI interaction ======================== */
4116 +int btuart_open(btuart_info_t *info)
4118 + unsigned long flags;
4119 + unsigned int iobase = info->link.io.BasePort1;
4120 + struct hci_dev *hdev;
4122 + spin_lock_init(&(info->lock));
4124 + skb_queue_head_init(&(info->txq));
4126 + info->rx_state = RECV_WAIT_PACKET_TYPE;
4127 + info->rx_count = 0;
4128 + info->rx_skb = NULL;
4130 + spin_lock_irqsave(&(info->lock), flags);
4133 + outb(0, iobase + UART_MCR);
4135 + /* Turn off interrupts */
4136 + outb(0, iobase + UART_IER);
4138 + /* Initialize UART */
4139 + outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
4140 + outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
4142 + /* Turn on interrupts */
4143 + // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
4145 + spin_unlock_irqrestore(&(info->lock), flags);
4147 + btuart_change_speed(info, DEFAULT_BAUD_RATE);
4149 + /* Timeout before it is safe to send the first HCI packet */
4150 + set_current_state(TASK_INTERRUPTIBLE);
4151 + schedule_timeout(HZ);
4154 + /* Initialize and register HCI device */
4156 + hdev = &(info->hdev);
4158 + hdev->type = HCI_PCCARD;
4159 + hdev->driver_data = info;
4161 + hdev->open = btuart_hci_open;
4162 + hdev->close = btuart_hci_close;
4163 + hdev->flush = btuart_hci_flush;
4164 + hdev->send = btuart_hci_send_frame;
4165 + hdev->destruct = btuart_hci_destruct;
4166 + hdev->ioctl = btuart_hci_ioctl;
4168 + if (hci_register_dev(hdev) < 0) {
4169 + printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
4177 +int btuart_close(btuart_info_t *info)
4179 + unsigned long flags;
4180 + unsigned int iobase = info->link.io.BasePort1;
4181 + struct hci_dev *hdev = &(info->hdev);
4183 + btuart_hci_close(hdev);
4185 + spin_lock_irqsave(&(info->lock), flags);
4188 + outb(0, iobase + UART_MCR);
4190 + /* Turn off interrupts */
4191 + outb(0, iobase + UART_IER);
4193 + spin_unlock_irqrestore(&(info->lock), flags);
4195 + if (hci_unregister_dev(hdev) < 0)
4196 + printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
4203 +/* ======================== Card services ======================== */
4206 +static void cs_error(client_handle_t handle, int func, int ret)
4208 + error_info_t err = { func, ret };
4210 + CardServices(ReportError, handle, &err);
4214 +dev_link_t *btuart_attach(void)
4216 + btuart_info_t *info;
4217 + client_reg_t client_reg;
4221 + /* Create new info device */
4222 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4225 + memset(info, 0, sizeof(*info));
4227 + link = &info->link;
4228 + link->priv = info;
4230 + link->release.function = &btuart_release;
4231 + link->release.data = (u_long)link;
4232 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
4233 + link->io.NumPorts1 = 8;
4234 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
4235 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
4237 + if (irq_list[0] == -1)
4238 + link->irq.IRQInfo2 = irq_mask;
4240 + for (i = 0; i < 4; i++)
4241 + link->irq.IRQInfo2 |= 1 << irq_list[i];
4243 + link->irq.Handler = btuart_interrupt;
4244 + link->irq.Instance = info;
4246 + link->conf.Attributes = CONF_ENABLE_IRQ;
4247 + link->conf.Vcc = 50;
4248 + link->conf.IntType = INT_MEMORY_AND_IO;
4250 + /* Register with Card Services */
4251 + link->next = dev_list;
4253 + client_reg.dev_info = &dev_info;
4254 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
4255 + client_reg.EventMask =
4256 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
4257 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
4258 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
4259 + client_reg.event_handler = &btuart_event;
4260 + client_reg.Version = 0x0210;
4261 + client_reg.event_callback_args.client_data = link;
4263 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
4264 + if (ret != CS_SUCCESS) {
4265 + cs_error(link->handle, RegisterClient, ret);
4266 + btuart_detach(link);
4274 +void btuart_detach(dev_link_t *link)
4276 + btuart_info_t *info = link->priv;
4277 + dev_link_t **linkp;
4280 + /* Locate device structure */
4281 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
4282 + if (*linkp == link)
4285 + if (*linkp == NULL)
4288 + del_timer(&link->release);
4289 + if (link->state & DEV_CONFIG)
4290 + btuart_release((u_long)link);
4292 + if (link->handle) {
4293 + ret = CardServices(DeregisterClient, link->handle);
4294 + if (ret != CS_SUCCESS)
4295 + cs_error(link->handle, DeregisterClient, ret);
4298 + /* Unlink device structure, free bits */
4299 + *linkp = link->next;
4305 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
4309 + i = CardServices(fn, handle, tuple);
4310 + if (i != CS_SUCCESS)
4311 + return CS_NO_MORE_ITEMS;
4313 + i = CardServices(GetTupleData, handle, tuple);
4314 + if (i != CS_SUCCESS)
4317 + return CardServices(ParseTuple, handle, tuple, parse);
4321 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
4322 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
4324 +void btuart_config(dev_link_t *link)
4326 + static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
4327 + client_handle_t handle = link->handle;
4328 + btuart_info_t *info = link->priv;
4332 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
4333 + config_info_t config;
4334 + int i, j, try, last_ret, last_fn;
4336 + tuple.TupleData = (cisdata_t *)buf;
4337 + tuple.TupleOffset = 0;
4338 + tuple.TupleDataMax = 255;
4339 + tuple.Attributes = 0;
4341 + /* Get configuration register information */
4342 + tuple.DesiredTuple = CISTPL_CONFIG;
4343 + last_ret = first_tuple(handle, &tuple, &parse);
4344 + if (last_ret != CS_SUCCESS) {
4345 + last_fn = ParseTuple;
4348 + link->conf.ConfigBase = parse.config.base;
4349 + link->conf.Present = parse.config.rmask[0];
4351 + /* Configure card */
4352 + link->state |= DEV_CONFIG;
4353 + i = CardServices(GetConfigurationInfo, handle, &config);
4354 + link->conf.Vcc = config.Vcc;
4356 + /* First pass: look for a config entry that looks normal. */
4357 + tuple.TupleData = (cisdata_t *) buf;
4358 + tuple.TupleOffset = 0;
4359 + tuple.TupleDataMax = 255;
4360 + tuple.Attributes = 0;
4361 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
4362 + /* Two tries: without IO aliases, then with aliases */
4363 + for (try = 0; try < 2; try++) {
4364 + i = first_tuple(handle, &tuple, &parse);
4365 + while (i != CS_NO_MORE_ITEMS) {
4366 + if (i != CS_SUCCESS)
4368 + if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
4369 + link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
4370 + if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
4371 + link->conf.ConfigIndex = cf->index;
4372 + link->io.BasePort1 = cf->io.win[0].base;
4373 + link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
4374 + i = CardServices(RequestIO, link->handle, &link->io);
4375 + if (i == CS_SUCCESS)
4379 + i = next_tuple(handle, &tuple, &parse);
4383 + /* Second pass: try to find an entry that isn't picky about
4384 + its base address, then try to grab any standard serial port
4385 + address, and finally try to get any free port. */
4386 + i = first_tuple(handle, &tuple, &parse);
4387 + while (i != CS_NO_MORE_ITEMS) {
4388 + if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
4389 + && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
4390 + link->conf.ConfigIndex = cf->index;
4391 + for (j = 0; j < 5; j++) {
4392 + link->io.BasePort1 = base[j];
4393 + link->io.IOAddrLines = base[j] ? 16 : 3;
4394 + i = CardServices(RequestIO, link->handle, &link->io);
4395 + if (i == CS_SUCCESS)
4399 + i = next_tuple(handle, &tuple, &parse);
4403 + if (i != CS_SUCCESS) {
4404 + printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
4405 + cs_error(link->handle, RequestIO, i);
4409 + i = CardServices(RequestIRQ, link->handle, &link->irq);
4410 + if (i != CS_SUCCESS) {
4411 + cs_error(link->handle, RequestIRQ, i);
4412 + link->irq.AssignedIRQ = 0;
4415 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
4416 + if (i != CS_SUCCESS) {
4417 + cs_error(link->handle, RequestConfiguration, i);
4421 + MOD_INC_USE_COUNT;
4423 + if (btuart_open(info) != 0)
4426 + strcpy(info->node.dev_name, info->hdev.name);
4427 + link->dev = &info->node;
4428 + link->state &= ~DEV_CONFIG_PENDING;
4433 + cs_error(link->handle, last_fn, last_ret);
4436 + btuart_release((u_long) link);
4440 +void btuart_release(u_long arg)
4442 + dev_link_t *link = (dev_link_t *)arg;
4443 + btuart_info_t *info = link->priv;
4445 + if (link->state & DEV_PRESENT)
4446 + btuart_close(info);
4448 + MOD_DEC_USE_COUNT;
4452 + CardServices(ReleaseConfiguration, link->handle);
4453 + CardServices(ReleaseIO, link->handle, &link->io);
4454 + CardServices(ReleaseIRQ, link->handle, &link->irq);
4456 + link->state &= ~DEV_CONFIG;
4460 +int btuart_event(event_t event, int priority, event_callback_args_t *args)
4462 + dev_link_t *link = args->client_data;
4463 + btuart_info_t *info = link->priv;
4466 + case CS_EVENT_CARD_REMOVAL:
4467 + link->state &= ~DEV_PRESENT;
4468 + if (link->state & DEV_CONFIG) {
4469 + btuart_close(info);
4470 + mod_timer(&link->release, jiffies + HZ / 20);
4473 + case CS_EVENT_CARD_INSERTION:
4474 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4475 + btuart_config(link);
4477 + case CS_EVENT_PM_SUSPEND:
4478 + link->state |= DEV_SUSPEND;
4479 + /* Fall through... */
4480 + case CS_EVENT_RESET_PHYSICAL:
4481 + if (link->state & DEV_CONFIG)
4482 + CardServices(ReleaseConfiguration, link->handle);
4484 + case CS_EVENT_PM_RESUME:
4485 + link->state &= ~DEV_SUSPEND;
4486 + /* Fall through... */
4487 + case CS_EVENT_CARD_RESET:
4489 + CardServices(RequestConfiguration, link->handle, &link->conf);
4498 +/* ======================== Module initialization ======================== */
4501 +int __init init_btuart_cs(void)
4506 + CardServices(GetCardServicesInfo, &serv);
4507 + if (serv.Revision != CS_RELEASE_CODE) {
4508 + printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
4512 + err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
4518 +void __exit exit_btuart_cs(void)
4520 + unregister_pccard_driver(&dev_info);
4522 + while (dev_list != NULL)
4523 + btuart_detach(dev_list);
4527 +module_init(init_btuart_cs);
4528 +module_exit(exit_btuart_cs);
4531 diff -urN linux-2.4.18/drivers/bluetooth/dtl1_cs.c linux-2.4.18-mh9/drivers/bluetooth/dtl1_cs.c
4532 --- linux-2.4.18/drivers/bluetooth/dtl1_cs.c Thu Jan 1 01:00:00 1970
4533 +++ linux-2.4.18-mh9/drivers/bluetooth/dtl1_cs.c Mon Aug 25 18:38:10 2003
4537 + * A driver for Nokia Connectivity Card DTL-1 devices
4539 + * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
4542 + * This program is free software; you can redistribute it and/or modify
4543 + * it under the terms of the GNU General Public License version 2 as
4544 + * published by the Free Software Foundation;
4546 + * Software distributed under the License is distributed on an "AS
4547 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
4548 + * implied. See the License for the specific language governing
4549 + * rights and limitations under the License.
4551 + * The initial developer of the original code is David A. Hinds
4552 + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
4553 + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
4557 +#include <linux/config.h>
4558 +#include <linux/module.h>
4560 +#include <linux/kernel.h>
4561 +#include <linux/init.h>
4562 +#include <linux/slab.h>
4563 +#include <linux/types.h>
4564 +#include <linux/sched.h>
4565 +#include <linux/timer.h>
4566 +#include <linux/errno.h>
4567 +#include <linux/ptrace.h>
4568 +#include <linux/ioport.h>
4569 +#include <linux/spinlock.h>
4571 +#include <linux/skbuff.h>
4572 +#include <linux/string.h>
4573 +#include <linux/serial.h>
4574 +#include <linux/serial_reg.h>
4575 +#include <asm/system.h>
4576 +#include <asm/bitops.h>
4577 +#include <asm/io.h>
4579 +#include <pcmcia/version.h>
4580 +#include <pcmcia/cs_types.h>
4581 +#include <pcmcia/cs.h>
4582 +#include <pcmcia/cistpl.h>
4583 +#include <pcmcia/ciscode.h>
4584 +#include <pcmcia/ds.h>
4585 +#include <pcmcia/cisreg.h>
4587 +#include <net/bluetooth/bluetooth.h>
4588 +#include <net/bluetooth/hci_core.h>
4592 +/* ======================== Module parameters ======================== */
4595 +/* Bit map of interrupts to choose from */
4596 +static u_int irq_mask = 0xffff;
4597 +static int irq_list[4] = { -1 };
4599 +MODULE_PARM(irq_mask, "i");
4600 +MODULE_PARM(irq_list, "1-4i");
4602 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
4603 +MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
4604 +MODULE_LICENSE("GPL");
4608 +/* ======================== Local structures ======================== */
4611 +typedef struct dtl1_info_t {
4615 + struct hci_dev hdev;
4617 + spinlock_t lock; /* For serializing operations */
4619 + unsigned long flowmask; /* HCI flow mask */
4622 + struct sk_buff_head txq;
4623 + unsigned long tx_state;
4625 + unsigned long rx_state;
4626 + unsigned long rx_count;
4627 + struct sk_buff *rx_skb;
4631 +void dtl1_config(dev_link_t *link);
4632 +void dtl1_release(u_long arg);
4633 +int dtl1_event(event_t event, int priority, event_callback_args_t *args);
4635 +static dev_info_t dev_info = "dtl1_cs";
4637 +dev_link_t *dtl1_attach(void);
4638 +void dtl1_detach(dev_link_t *);
4640 +static dev_link_t *dev_list = NULL;
4643 +/* Transmit states */
4644 +#define XMIT_SENDING 1
4645 +#define XMIT_WAKEUP 2
4646 +#define XMIT_WAITING 8
4648 +/* Receiver States */
4649 +#define RECV_WAIT_NSH 0
4650 +#define RECV_WAIT_DATA 1
4657 +} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
4659 +#define NSHL 4 /* Nokia Specific Header Length */
4663 +/* ======================== Interrupt handling ======================== */
4666 +static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
4670 + /* Tx FIFO should be empty */
4671 + if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
4674 + /* Fill FIFO with current frame */
4675 + while ((fifo_size-- > 0) && (actual < len)) {
4676 + /* Transmit next byte */
4677 + outb(buf[actual], iobase + UART_TX);
4685 +static void dtl1_write_wakeup(dtl1_info_t *info)
4688 + printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
4692 + if (test_bit(XMIT_WAITING, &(info->tx_state))) {
4693 + set_bit(XMIT_WAKEUP, &(info->tx_state));
4697 + if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
4698 + set_bit(XMIT_WAKEUP, &(info->tx_state));
4703 + register unsigned int iobase = info->link.io.BasePort1;
4704 + register struct sk_buff *skb;
4707 + clear_bit(XMIT_WAKEUP, &(info->tx_state));
4709 + if (!(info->link.state & DEV_PRESENT))
4712 + if (!(skb = skb_dequeue(&(info->txq))))
4716 + len = dtl1_write(iobase, 32, skb->data, skb->len);
4718 + if (len == skb->len) {
4719 + set_bit(XMIT_WAITING, &(info->tx_state));
4722 + skb_pull(skb, len);
4723 + skb_queue_head(&(info->txq), skb);
4726 + info->hdev.stat.byte_tx += len;
4728 + } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
4730 + clear_bit(XMIT_SENDING, &(info->tx_state));
4734 +static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
4736 + u8 flowmask = *(u8 *)skb->data;
4739 + printk(KERN_INFO "dtl1_cs: Nokia control data = ");
4740 + for (i = 0; i < skb->len; i++) {
4741 + printk("%02x ", skb->data[i]);
4745 + /* transition to active state */
4746 + if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
4747 + clear_bit(XMIT_WAITING, &(info->tx_state));
4748 + dtl1_write_wakeup(info);
4751 + info->flowmask = flowmask;
4757 +static void dtl1_receive(dtl1_info_t *info)
4759 + unsigned int iobase;
4761 + int boguscount = 0;
4764 + printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
4768 + iobase = info->link.io.BasePort1;
4771 + info->hdev.stat.byte_rx++;
4773 + /* Allocate packet */
4774 + if (info->rx_skb == NULL)
4775 + if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
4776 + printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
4777 + info->rx_state = RECV_WAIT_NSH;
4778 + info->rx_count = NSHL;
4782 + *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
4783 + nsh = (nsh_t *)info->rx_skb->data;
4787 + if (info->rx_count == 0) {
4789 + switch (info->rx_state) {
4790 + case RECV_WAIT_NSH:
4791 + info->rx_state = RECV_WAIT_DATA;
4792 + info->rx_count = nsh->len + (nsh->len & 0x0001);
4794 + case RECV_WAIT_DATA:
4795 + info->rx_skb->pkt_type = nsh->type;
4797 + /* remove PAD byte if it exists */
4798 + if (nsh->len & 0x0001) {
4799 + info->rx_skb->tail--;
4800 + info->rx_skb->len--;
4804 + skb_pull(info->rx_skb, NSHL);
4806 + switch (info->rx_skb->pkt_type) {
4808 + /* control data for the Nokia Card */
4809 + dtl1_control(info, info->rx_skb);
4814 + /* send frame to the HCI layer */
4815 + info->rx_skb->dev = (void *)&(info->hdev);
4816 + info->rx_skb->pkt_type &= 0x0f;
4817 + hci_recv_frame(info->rx_skb);
4820 + /* unknown packet */
4821 + printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
4822 + kfree_skb(info->rx_skb);
4826 + info->rx_state = RECV_WAIT_NSH;
4827 + info->rx_count = NSHL;
4828 + info->rx_skb = NULL;
4834 + /* Make sure we don't stay here to long */
4835 + if (boguscount++ > 32)
4838 + } while (inb(iobase + UART_LSR) & UART_LSR_DR);
4842 +void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
4844 + dtl1_info_t *info = dev_inst;
4845 + unsigned int iobase;
4846 + unsigned char msr;
4847 + int boguscount = 0;
4851 + printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
4855 + iobase = info->link.io.BasePort1;
4857 + spin_lock(&(info->lock));
4859 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
4862 + /* Clear interrupt */
4863 + lsr = inb(iobase + UART_LSR);
4866 + case UART_IIR_RLSI:
4867 + printk(KERN_NOTICE "dtl1_cs: RLSI\n");
4869 + case UART_IIR_RDI:
4870 + /* Receive interrupt */
4871 + dtl1_receive(info);
4873 + case UART_IIR_THRI:
4874 + if (lsr & UART_LSR_THRE) {
4875 + /* Transmitter ready for data */
4876 + dtl1_write_wakeup(info);
4880 + printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
4884 + /* Make sure we don't stay here to long */
4885 + if (boguscount++ > 100)
4888 + iir = inb(iobase + UART_IIR) & UART_IIR_ID;
4892 + msr = inb(iobase + UART_MSR);
4894 + if (info->ri_latch ^ (msr & UART_MSR_RI)) {
4895 + info->ri_latch = msr & UART_MSR_RI;
4896 + clear_bit(XMIT_WAITING, &(info->tx_state));
4897 + dtl1_write_wakeup(info);
4900 + spin_unlock(&(info->lock));
4905 +/* ======================== HCI interface ======================== */
4908 +static int dtl1_hci_open(struct hci_dev *hdev)
4910 + set_bit(HCI_RUNNING, &(hdev->flags));
4916 +static int dtl1_hci_flush(struct hci_dev *hdev)
4918 + dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
4920 + /* Drop TX queue */
4921 + skb_queue_purge(&(info->txq));
4927 +static int dtl1_hci_close(struct hci_dev *hdev)
4929 + if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
4932 + dtl1_hci_flush(hdev);
4938 +static int dtl1_hci_send_frame(struct sk_buff *skb)
4940 + dtl1_info_t *info;
4941 + struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
4942 + struct sk_buff *s;
4946 + printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
4950 + info = (dtl1_info_t *)(hdev->driver_data);
4952 + switch (skb->pkt_type) {
4953 + case HCI_COMMAND_PKT:
4954 + hdev->stat.cmd_tx++;
4957 + case HCI_ACLDATA_PKT:
4958 + hdev->stat.acl_tx++;
4961 + case HCI_SCODATA_PKT:
4962 + hdev->stat.sco_tx++;
4968 + nsh.len = skb->len;
4970 + s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
4971 + skb_reserve(s, NSHL);
4972 + memcpy(skb_put(s, skb->len), skb->data, skb->len);
4973 + if (skb->len & 0x0001)
4974 + *skb_put(s, 1) = 0; /* PAD */
4976 + /* Prepend skb with Nokia frame header and queue */
4977 + memcpy(skb_push(s, NSHL), &nsh, NSHL);
4978 + skb_queue_tail(&(info->txq), s);
4980 + dtl1_write_wakeup(info);
4988 +static void dtl1_hci_destruct(struct hci_dev *hdev)
4993 +static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
4995 + return -ENOIOCTLCMD;
5000 +/* ======================== Card services HCI interaction ======================== */
5003 +int dtl1_open(dtl1_info_t *info)
5005 + unsigned long flags;
5006 + unsigned int iobase = info->link.io.BasePort1;
5007 + struct hci_dev *hdev;
5009 + spin_lock_init(&(info->lock));
5011 + skb_queue_head_init(&(info->txq));
5013 + info->rx_state = RECV_WAIT_NSH;
5014 + info->rx_count = NSHL;
5015 + info->rx_skb = NULL;
5017 + set_bit(XMIT_WAITING, &(info->tx_state));
5019 + spin_lock_irqsave(&(info->lock), flags);
5022 + outb(0, iobase + UART_MCR);
5024 + /* Turn off interrupts */
5025 + outb(0, iobase + UART_IER);
5027 + /* Initialize UART */
5028 + outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
5029 + outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
5031 + info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
5033 + /* Turn on interrupts */
5034 + outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
5036 + spin_unlock_irqrestore(&(info->lock), flags);
5038 + /* Timeout before it is safe to send the first HCI packet */
5039 + set_current_state(TASK_INTERRUPTIBLE);
5040 + schedule_timeout(HZ * 2);
5043 + /* Initialize and register HCI device */
5045 + hdev = &(info->hdev);
5047 + hdev->type = HCI_PCCARD;
5048 + hdev->driver_data = info;
5050 + hdev->open = dtl1_hci_open;
5051 + hdev->close = dtl1_hci_close;
5052 + hdev->flush = dtl1_hci_flush;
5053 + hdev->send = dtl1_hci_send_frame;
5054 + hdev->destruct = dtl1_hci_destruct;
5055 + hdev->ioctl = dtl1_hci_ioctl;
5057 + if (hci_register_dev(hdev) < 0) {
5058 + printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
5066 +int dtl1_close(dtl1_info_t *info)
5068 + unsigned long flags;
5069 + unsigned int iobase = info->link.io.BasePort1;
5070 + struct hci_dev *hdev = &(info->hdev);
5072 + dtl1_hci_close(hdev);
5074 + spin_lock_irqsave(&(info->lock), flags);
5077 + outb(0, iobase + UART_MCR);
5079 + /* Turn off interrupts */
5080 + outb(0, iobase + UART_IER);
5082 + spin_unlock_irqrestore(&(info->lock), flags);
5084 + if (hci_unregister_dev(hdev) < 0)
5085 + printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
5092 +/* ======================== Card services ======================== */
5095 +static void cs_error(client_handle_t handle, int func, int ret)
5097 + error_info_t err = { func, ret };
5099 + CardServices(ReportError, handle, &err);
5103 +dev_link_t *dtl1_attach(void)
5105 + dtl1_info_t *info;
5106 + client_reg_t client_reg;
5110 + /* Create new info device */
5111 + info = kmalloc(sizeof(*info), GFP_KERNEL);
5114 + memset(info, 0, sizeof(*info));
5116 + link = &info->link;
5117 + link->priv = info;
5119 + link->release.function = &dtl1_release;
5120 + link->release.data = (u_long)link;
5121 + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
5122 + link->io.NumPorts1 = 8;
5123 + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
5124 + link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
5126 + if (irq_list[0] == -1)
5127 + link->irq.IRQInfo2 = irq_mask;
5129 + for (i = 0; i < 4; i++)
5130 + link->irq.IRQInfo2 |= 1 << irq_list[i];
5132 + link->irq.Handler = dtl1_interrupt;
5133 + link->irq.Instance = info;
5135 + link->conf.Attributes = CONF_ENABLE_IRQ;
5136 + link->conf.Vcc = 50;
5137 + link->conf.IntType = INT_MEMORY_AND_IO;
5139 + /* Register with Card Services */
5140 + link->next = dev_list;
5142 + client_reg.dev_info = &dev_info;
5143 + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
5144 + client_reg.EventMask =
5145 + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
5146 + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
5147 + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
5148 + client_reg.event_handler = &dtl1_event;
5149 + client_reg.Version = 0x0210;
5150 + client_reg.event_callback_args.client_data = link;
5152 + ret = CardServices(RegisterClient, &link->handle, &client_reg);
5153 + if (ret != CS_SUCCESS) {
5154 + cs_error(link->handle, RegisterClient, ret);
5155 + dtl1_detach(link);
5163 +void dtl1_detach(dev_link_t *link)
5165 + dtl1_info_t *info = link->priv;
5166 + dev_link_t **linkp;
5169 + /* Locate device structure */
5170 + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
5171 + if (*linkp == link)
5174 + if (*linkp == NULL)
5177 + del_timer(&link->release);
5178 + if (link->state & DEV_CONFIG)
5179 + dtl1_release((u_long)link);
5181 + if (link->handle) {
5182 + ret = CardServices(DeregisterClient, link->handle);
5183 + if (ret != CS_SUCCESS)
5184 + cs_error(link->handle, DeregisterClient, ret);
5187 + /* Unlink device structure, free bits */
5188 + *linkp = link->next;
5194 +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
5198 + i = CardServices(fn, handle, tuple);
5199 + if (i != CS_SUCCESS)
5200 + return CS_NO_MORE_ITEMS;
5202 + i = CardServices(GetTupleData, handle, tuple);
5203 + if (i != CS_SUCCESS)
5206 + return CardServices(ParseTuple, handle, tuple, parse);
5210 +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
5211 +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
5213 +void dtl1_config(dev_link_t *link)
5215 + client_handle_t handle = link->handle;
5216 + dtl1_info_t *info = link->priv;
5220 + cistpl_cftable_entry_t *cf = &parse.cftable_entry;
5221 + config_info_t config;
5222 + int i, last_ret, last_fn;
5224 + tuple.TupleData = (cisdata_t *)buf;
5225 + tuple.TupleOffset = 0;
5226 + tuple.TupleDataMax = 255;
5227 + tuple.Attributes = 0;
5229 + /* Get configuration register information */
5230 + tuple.DesiredTuple = CISTPL_CONFIG;
5231 + last_ret = first_tuple(handle, &tuple, &parse);
5232 + if (last_ret != CS_SUCCESS) {
5233 + last_fn = ParseTuple;
5236 + link->conf.ConfigBase = parse.config.base;
5237 + link->conf.Present = parse.config.rmask[0];
5239 + /* Configure card */
5240 + link->state |= DEV_CONFIG;
5241 + i = CardServices(GetConfigurationInfo, handle, &config);
5242 + link->conf.Vcc = config.Vcc;
5244 + tuple.TupleData = (cisdata_t *)buf;
5245 + tuple.TupleOffset = 0;
5246 + tuple.TupleDataMax = 255;
5247 + tuple.Attributes = 0;
5248 + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
5250 + /* Look for a generic full-sized window */
5251 + link->io.NumPorts1 = 8;
5252 + i = first_tuple(handle, &tuple, &parse);
5253 + while (i != CS_NO_MORE_ITEMS) {
5254 + if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
5255 + link->conf.ConfigIndex = cf->index;
5256 + link->io.BasePort1 = cf->io.win[0].base;
5257 + link->io.NumPorts1 = cf->io.win[0].len; /*yo */
5258 + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
5259 + i = CardServices(RequestIO, link->handle, &link->io);
5260 + if (i == CS_SUCCESS)
5263 + i = next_tuple(handle, &tuple, &parse);
5266 + if (i != CS_SUCCESS) {
5267 + cs_error(link->handle, RequestIO, i);
5271 + i = CardServices(RequestIRQ, link->handle, &link->irq);
5272 + if (i != CS_SUCCESS) {
5273 + cs_error(link->handle, RequestIRQ, i);
5274 + link->irq.AssignedIRQ = 0;
5277 + i = CardServices(RequestConfiguration, link->handle, &link->conf);
5278 + if (i != CS_SUCCESS) {
5279 + cs_error(link->handle, RequestConfiguration, i);
5283 + MOD_INC_USE_COUNT;
5285 + if (dtl1_open(info) != 0)
5288 + strcpy(info->node.dev_name, info->hdev.name);
5289 + link->dev = &info->node;
5290 + link->state &= ~DEV_CONFIG_PENDING;
5295 + cs_error(link->handle, last_fn, last_ret);
5298 + dtl1_release((u_long)link);
5302 +void dtl1_release(u_long arg)
5304 + dev_link_t *link = (dev_link_t *)arg;
5305 + dtl1_info_t *info = link->priv;
5307 + if (link->state & DEV_PRESENT)
5310 + MOD_DEC_USE_COUNT;
5314 + CardServices(ReleaseConfiguration, link->handle);
5315 + CardServices(ReleaseIO, link->handle, &link->io);
5316 + CardServices(ReleaseIRQ, link->handle, &link->irq);
5318 + link->state &= ~DEV_CONFIG;
5322 +int dtl1_event(event_t event, int priority, event_callback_args_t *args)
5324 + dev_link_t *link = args->client_data;
5325 + dtl1_info_t *info = link->priv;
5328 + case CS_EVENT_CARD_REMOVAL:
5329 + link->state &= ~DEV_PRESENT;
5330 + if (link->state & DEV_CONFIG) {
5332 + mod_timer(&link->release, jiffies + HZ / 20);
5335 + case CS_EVENT_CARD_INSERTION:
5336 + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
5337 + dtl1_config(link);
5339 + case CS_EVENT_PM_SUSPEND:
5340 + link->state |= DEV_SUSPEND;
5341 + /* Fall through... */
5342 + case CS_EVENT_RESET_PHYSICAL:
5343 + if (link->state & DEV_CONFIG)
5344 + CardServices(ReleaseConfiguration, link->handle);
5346 + case CS_EVENT_PM_RESUME:
5347 + link->state &= ~DEV_SUSPEND;
5348 + /* Fall through... */
5349 + case CS_EVENT_CARD_RESET:
5351 + CardServices(RequestConfiguration, link->handle, &link->conf);
5360 +/* ======================== Module initialization ======================== */
5363 +int __init init_dtl1_cs(void)
5368 + CardServices(GetCardServicesInfo, &serv);
5369 + if (serv.Revision != CS_RELEASE_CODE) {
5370 + printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
5374 + err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
5380 +void __exit exit_dtl1_cs(void)
5382 + unregister_pccard_driver(&dev_info);
5384 + while (dev_list != NULL)
5385 + dtl1_detach(dev_list);
5389 +module_init(init_dtl1_cs);
5390 +module_exit(exit_dtl1_cs);
5393 diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.c linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.c
5394 --- linux-2.4.18/drivers/bluetooth/hci_bcsp.c Thu Jan 1 01:00:00 1970
5395 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.c Mon Aug 25 18:38:10 2003
5398 + BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
5399 + Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
5402 + hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
5403 + ABCSP by Carl Orsborn <cjo@csr.com>
5405 + This program is free software; you can redistribute it and/or modify
5406 + it under the terms of the GNU General Public License version 2 as
5407 + published by the Free Software Foundation;
5409 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5410 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5411 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
5412 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
5413 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
5414 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
5415 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
5416 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5418 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
5419 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
5420 + SOFTWARE IS DISCLAIMED.
5424 + * $Id: hci_bcsp.c,v 1.2 2002/09/26 05:05:14 maxk Exp $
5427 +#define VERSION "0.1"
5429 +#include <linux/config.h>
5430 +#include <linux/module.h>
5432 +#include <linux/version.h>
5433 +#include <linux/config.h>
5434 +#include <linux/kernel.h>
5435 +#include <linux/init.h>
5436 +#include <linux/sched.h>
5437 +#include <linux/types.h>
5438 +#include <linux/fcntl.h>
5439 +#include <linux/interrupt.h>
5440 +#include <linux/ptrace.h>
5441 +#include <linux/poll.h>
5443 +#include <linux/slab.h>
5444 +#include <linux/tty.h>
5445 +#include <linux/errno.h>
5446 +#include <linux/string.h>
5447 +#include <linux/signal.h>
5448 +#include <linux/ioctl.h>
5449 +#include <linux/skbuff.h>
5451 +#include <net/bluetooth/bluetooth.h>
5452 +#include <net/bluetooth/hci_core.h>
5453 +#include "hci_uart.h"
5454 +#include "hci_bcsp.h"
5456 +#ifndef HCI_UART_DEBUG
5458 +#define BT_DBG( A... )
5460 +#define BT_DMP( A... )
5463 +/* ---- BCSP CRC calculation ---- */
5465 +/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
5466 +initial value 0xffff, bits shifted in reverse order. */
5468 +static const u16 crc_table[] = {
5469 + 0x0000, 0x1081, 0x2102, 0x3183,
5470 + 0x4204, 0x5285, 0x6306, 0x7387,
5471 + 0x8408, 0x9489, 0xa50a, 0xb58b,
5472 + 0xc60c, 0xd68d, 0xe70e, 0xf78f
5475 +/* Initialise the crc calculator */
5476 +#define BCSP_CRC_INIT(x) x = 0xffff
5479 + Update crc with next data byte
5481 + Implementation note
5482 + The data byte is treated as two nibbles. The crc is generated
5483 + in reverse, i.e., bits are fed into the register from the top.
5485 +static void bcsp_crc_update(u16 *crc, u8 d)
5489 + reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
5490 + reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
5496 + Get reverse of generated crc
5498 + Implementation note
5499 + The crc generator (bcsp_crc_init() and bcsp_crc_update())
5500 + creates a reversed crc, so it needs to be swapped back before
5503 +static u16 bcsp_crc_reverse(u16 crc)
5507 + for (b = 0, rev = 0; b < 16; b++) {
5515 +/* ---- BCSP core ---- */
5517 +static void bcsp_slip_msgdelim(struct sk_buff *skb)
5519 + const char pkt_delim = 0xc0;
5520 + memcpy(skb_put(skb, 1), &pkt_delim, 1);
5523 +static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
5525 + const char esc_c0[2] = { 0xdb, 0xdc };
5526 + const char esc_db[2] = { 0xdb, 0xdd };
5530 + memcpy(skb_put(skb, 2), &esc_c0, 2);
5533 + memcpy(skb_put(skb, 2), &esc_db, 2);
5536 + memcpy(skb_put(skb, 1), &c, 1);
5540 +static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
5542 + struct bcsp_struct *bcsp = hu->priv;
5544 + if (skb->len > 0xFFF) {
5545 + BT_ERR("Packet too long");
5550 + switch (skb->pkt_type) {
5551 + case HCI_ACLDATA_PKT:
5552 + case HCI_COMMAND_PKT:
5553 + skb_queue_tail(&bcsp->rel, skb);
5556 + case HCI_SCODATA_PKT:
5557 + skb_queue_tail(&bcsp->unrel, skb);
5561 + BT_ERR("Unknown packet type");
5568 +static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
5569 + int len, int pkt_type)
5571 + struct sk_buff *nskb;
5575 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5576 + u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
5579 + switch (pkt_type) {
5580 + case HCI_ACLDATA_PKT:
5581 + chan = 6; /* BCSP ACL channel */
5582 + rel = 1; /* reliable channel */
5584 + case HCI_COMMAND_PKT:
5585 + chan = 5; /* BCSP cmd/evt channel */
5586 + rel = 1; /* reliable channel */
5588 + case HCI_SCODATA_PKT:
5589 + chan = 7; /* BCSP SCO channel */
5590 + rel = 0; /* unreliable channel */
5593 + chan = 1; /* BCSP LE channel */
5594 + rel = 0; /* unreliable channel */
5596 + case BCSP_ACK_PKT:
5597 + chan = 0; /* BCSP internal channel */
5598 + rel = 0; /* unreliable channel */
5601 + BT_ERR("Unknown packet type");
5605 + /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
5606 + (because bytes 0xc0 and 0xdb are escaped, worst case is
5607 + when the packet is all made of 0xc0 and 0xdb :) )
5608 + + 2 (0xc0 delimiters at start and end). */
5610 + nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
5614 + nskb->pkt_type = pkt_type;
5616 + bcsp_slip_msgdelim(nskb);
5618 + hdr[0] = bcsp->rxseq_txack << 3;
5619 + bcsp->txack_req = 0;
5620 + BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
5623 + hdr[0] |= 0x80 + bcsp->msgq_txseq;
5624 + BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
5625 + bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
5627 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5631 + hdr[1] = (len << 4) & 0xFF;
5633 + hdr[2] = len >> 4;
5634 + hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
5636 + /* Put BCSP header */
5637 + for (i = 0; i < 4; i++) {
5638 + bcsp_slip_one_byte(nskb, hdr[i]);
5639 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5640 + bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
5645 + for (i = 0; i < len; i++) {
5646 + bcsp_slip_one_byte(nskb, data[i]);
5647 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5648 + bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
5652 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
5654 + bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
5655 + bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
5656 + bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
5659 + bcsp_slip_msgdelim(nskb);
5663 +/* This is a rewrite of pkt_avail in ABCSP */
5664 +static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
5666 + struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
5667 + unsigned long flags;
5668 + struct sk_buff *skb;
5670 + /* First of all, check for unreliable messages in the queue,
5671 + since they have priority */
5673 + if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
5674 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
5679 + skb_queue_head(&bcsp->unrel, skb);
5680 + BT_ERR("Could not dequeue pkt because alloc_skb failed");
5684 + /* Now, try to send a reliable pkt. We can only send a
5685 + reliable packet if the number of packets sent but not yet ack'ed
5686 + is < than the winsize */
5688 + spin_lock_irqsave(&bcsp->unack.lock, flags);
5690 + if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
5691 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
5693 + __skb_queue_tail(&bcsp->unack, skb);
5694 + mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
5695 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5698 + skb_queue_head(&bcsp->rel, skb);
5699 + BT_ERR("Could not dequeue pkt because alloc_skb failed");
5703 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5706 + /* We could not send a reliable packet, either because there are
5707 + none or because there are too many unack'ed pkts. Did we receive
5708 + any packets we have not acknowledged yet ? */
5710 + if (bcsp->txack_req) {
5711 + /* if so, craft an empty ACK pkt and send it on BCSP unreliable
5713 + struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
5717 + /* We have nothing to send */
5721 +static int bcsp_flush(struct hci_uart *hu)
5723 + BT_DBG("hu %p", hu);
5727 +/* Remove ack'ed packets */
5728 +static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
5730 + unsigned long flags;
5731 + struct sk_buff *skb;
5732 + int i, pkts_to_be_removed;
5735 + spin_lock_irqsave(&bcsp->unack.lock, flags);
5737 + pkts_to_be_removed = bcsp->unack.qlen;
5738 + seqno = bcsp->msgq_txseq;
5740 + while (pkts_to_be_removed) {
5741 + if (bcsp->rxack == seqno)
5743 + pkts_to_be_removed--;
5744 + seqno = (seqno - 1) & 0x07;
5747 + if (bcsp->rxack != seqno)
5748 + BT_ERR("Peer acked invalid packet");
5750 + BT_DBG("Removing %u pkts out of %u, up to seqno %u",
5751 + pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
5753 + for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
5754 + && skb != (struct sk_buff *) &bcsp->unack; i++) {
5755 + struct sk_buff *nskb;
5758 + __skb_unlink(skb, &bcsp->unack);
5762 + if (bcsp->unack.qlen == 0)
5763 + del_timer(&bcsp->tbcsp);
5764 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
5766 + if (i != pkts_to_be_removed)
5767 + BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
5770 +/* Handle BCSP link-establishment packets. When we
5771 + detect a "sync" packet, symptom that the BT module has reset,
5772 + we do nothing :) (yet) */
5773 +static void bcsp_handle_le_pkt(struct hci_uart *hu)
5775 + struct bcsp_struct *bcsp = hu->priv;
5776 + u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
5777 + u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
5778 + u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
5780 + /* spot "conf" pkts and reply with a "conf rsp" pkt */
5781 + if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
5782 + !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
5783 + struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
5785 + BT_DBG("Found a LE conf pkt");
5788 + memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
5789 + nskb->pkt_type = BCSP_LE_PKT;
5791 + skb_queue_head(&bcsp->unrel, nskb);
5792 + hci_uart_tx_wakeup(hu);
5794 + /* Spot "sync" pkts. If we find one...disaster! */
5795 + else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
5796 + !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
5797 + BT_ERR("Found a LE sync pkt, card has reset");
5801 +static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
5803 + const u8 c0 = 0xc0, db = 0xdb;
5805 + switch (bcsp->rx_esc_state) {
5806 + case BCSP_ESCSTATE_NOESC:
5809 + bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
5812 + memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
5813 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5814 + bcsp->rx_state != BCSP_W4_CRC)
5815 + bcsp_crc_update(&bcsp->message_crc, byte);
5820 + case BCSP_ESCSTATE_ESC:
5823 + memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
5824 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5825 + bcsp->rx_state != BCSP_W4_CRC)
5826 + bcsp_crc_update(&bcsp-> message_crc, 0xc0);
5827 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
5832 + memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
5833 + if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
5834 + bcsp->rx_state != BCSP_W4_CRC)
5835 + bcsp_crc_update(&bcsp-> message_crc, 0xdb);
5836 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
5841 + BT_ERR ("Invalid byte %02x after esc byte", byte);
5842 + kfree_skb(bcsp->rx_skb);
5843 + bcsp->rx_skb = NULL;
5844 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5845 + bcsp->rx_count = 0;
5850 +static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
5852 + struct bcsp_struct *bcsp = hu->priv;
5855 + if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
5856 + BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
5857 + bcsp->rxseq_txack++;
5858 + bcsp->rxseq_txack %= 0x8;
5859 + bcsp->txack_req = 1;
5861 + /* If needed, transmit an ack pkt */
5862 + hci_uart_tx_wakeup(hu);
5865 + bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
5866 + BT_DBG("Request for pkt %u from card", bcsp->rxack);
5868 + bcsp_pkt_cull(bcsp);
5869 + if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
5870 + bcsp->rx_skb->data[0] & 0x80) {
5871 + bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
5873 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
5874 + bcsp->rx_skb->data[0] & 0x80) {
5875 + bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
5877 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
5878 + bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
5880 + } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
5881 + !(bcsp->rx_skb->data[0] & 0x80)) {
5882 + bcsp_handle_le_pkt(hu);
5888 + if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
5889 + (bcsp->rx_skb->data[1] & 0x0f) != 1) {
5890 + BT_ERR ("Packet for unknown channel (%u %s)",
5891 + bcsp->rx_skb->data[1] & 0x0f,
5892 + bcsp->rx_skb->data[0] & 0x80 ?
5893 + "reliable" : "unreliable");
5895 + kfree_skb(bcsp->rx_skb);
5897 + /* Pull out BCSP hdr */
5898 + skb_pull(bcsp->rx_skb, 4);
5900 + hci_recv_frame(bcsp->rx_skb);
5902 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5903 + bcsp->rx_skb = NULL;
5907 +static int bcsp_recv(struct hci_uart *hu, void *data, int count)
5909 + struct bcsp_struct *bcsp = hu->priv;
5910 + register unsigned char *ptr;
5912 + BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
5913 + hu, count, bcsp->rx_state, bcsp->rx_count);
5917 + if (bcsp->rx_count) {
5918 + if (*ptr == 0xc0) {
5919 + BT_ERR("Short BCSP packet");
5920 + kfree_skb(bcsp->rx_skb);
5921 + bcsp->rx_state = BCSP_W4_PKT_START;
5922 + bcsp->rx_count = 0;
5924 + bcsp_unslip_one_byte(bcsp, *ptr);
5930 + switch (bcsp->rx_state) {
5931 + case BCSP_W4_BCSP_HDR:
5932 + if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
5933 + bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
5934 + BT_ERR("Error in BCSP hdr checksum");
5935 + kfree_skb(bcsp->rx_skb);
5936 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5937 + bcsp->rx_count = 0;
5940 + if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
5941 + && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
5942 + BT_ERR ("Out-of-order packet arrived, got %u expected %u",
5943 + bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
5945 + kfree_skb(bcsp->rx_skb);
5946 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5947 + bcsp->rx_count = 0;
5950 + bcsp->rx_state = BCSP_W4_DATA;
5951 + bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
5952 + (bcsp->rx_skb->data[2] << 4); /* May be 0 */
5955 + case BCSP_W4_DATA:
5956 + if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
5957 + bcsp->rx_state = BCSP_W4_CRC;
5958 + bcsp->rx_count = 2;
5960 + bcsp_complete_rx_pkt(hu);
5964 + if (bcsp_crc_reverse(bcsp->message_crc) !=
5965 + (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
5966 + bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
5968 + BT_ERR ("Checksum failed: computed %04x received %04x",
5969 + bcsp_crc_reverse(bcsp->message_crc),
5970 + (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
5971 + bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
5973 + kfree_skb(bcsp->rx_skb);
5974 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
5975 + bcsp->rx_count = 0;
5978 + skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
5979 + bcsp_complete_rx_pkt(hu);
5982 + case BCSP_W4_PKT_DELIMITER:
5985 + bcsp->rx_state = BCSP_W4_PKT_START;
5988 + /*BT_ERR("Ignoring byte %02x", *ptr);*/
5994 + case BCSP_W4_PKT_START:
6001 + bcsp->rx_state = BCSP_W4_BCSP_HDR;
6002 + bcsp->rx_count = 4;
6003 + bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
6004 + BCSP_CRC_INIT(bcsp->message_crc);
6006 + /* Do not increment ptr or decrement count
6007 + * Allocate packet. Max len of a BCSP pkt=
6008 + * 0xFFF (payload) +4 (header) +2 (crc) */
6010 + bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
6011 + if (!bcsp->rx_skb) {
6012 + BT_ERR("Can't allocate mem for new packet");
6013 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
6014 + bcsp->rx_count = 0;
6017 + bcsp->rx_skb->dev = (void *) &hu->hdev;
6026 + /* Arrange to retransmit all messages in the relq. */
6027 +static void bcsp_timed_event(unsigned long arg)
6029 + struct hci_uart *hu = (struct hci_uart *) arg;
6030 + struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
6031 + struct sk_buff *skb;
6032 + unsigned long flags;
6034 + BT_ERR("Timeout, retransmitting %u pkts", bcsp->unack.qlen);
6035 + spin_lock_irqsave(&bcsp->unack.lock, flags);
6037 + while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
6038 + bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
6039 + skb_queue_head(&bcsp->rel, skb);
6042 + spin_unlock_irqrestore(&bcsp->unack.lock, flags);
6044 + hci_uart_tx_wakeup(hu);
6047 +static int bcsp_open(struct hci_uart *hu)
6049 + struct bcsp_struct *bcsp;
6051 + BT_DBG("hu %p", hu);
6053 + bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
6056 + memset(bcsp, 0, sizeof(*bcsp));
6059 + skb_queue_head_init(&bcsp->unack);
6060 + skb_queue_head_init(&bcsp->rel);
6061 + skb_queue_head_init(&bcsp->unrel);
6063 + init_timer(&bcsp->tbcsp);
6064 + bcsp->tbcsp.function = bcsp_timed_event;
6065 + bcsp->tbcsp.data = (u_long) hu;
6067 + bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
6072 +static int bcsp_close(struct hci_uart *hu)
6074 + struct bcsp_struct *bcsp = hu->priv;
6077 + BT_DBG("hu %p", hu);
6079 + skb_queue_purge(&bcsp->unack);
6080 + skb_queue_purge(&bcsp->rel);
6081 + skb_queue_purge(&bcsp->unrel);
6082 + del_timer(&bcsp->tbcsp);
6088 +static struct hci_uart_proto bcsp = {
6089 + id: HCI_UART_BCSP,
6091 + close: bcsp_close,
6092 + enqueue: bcsp_enqueue,
6093 + dequeue: bcsp_dequeue,
6098 +int bcsp_init(void)
6100 + return hci_uart_register_proto(&bcsp);
6103 +int bcsp_deinit(void)
6105 + return hci_uart_unregister_proto(&bcsp);
6107 diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.h linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.h
6108 --- linux-2.4.18/drivers/bluetooth/hci_bcsp.h Thu Jan 1 01:00:00 1970
6109 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.h Mon Aug 25 18:38:10 2003
6112 + BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
6113 + Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
6116 + hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
6117 + ABCSP by Carl Orsborn <cjo@csr.com>
6119 + This program is free software; you can redistribute it and/or modify
6120 + it under the terms of the GNU General Public License version 2 as
6121 + published by the Free Software Foundation;
6123 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6124 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6125 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6126 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6127 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6128 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6129 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6130 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6132 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6133 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6134 + SOFTWARE IS DISCLAIMED.
6138 + * $Id: hci_bcsp.h,v 1.2 2002/09/26 05:05:14 maxk Exp $
6141 +#ifndef __HCI_BCSP_H__
6142 +#define __HCI_BCSP_H__
6144 +#define BCSP_TXWINSIZE 4
6146 +#define BCSP_ACK_PKT 0x05
6147 +#define BCSP_LE_PKT 0x06
6149 +struct bcsp_struct {
6150 + struct sk_buff_head unack; /* Unack'ed packets queue */
6151 + struct sk_buff_head rel; /* Reliable packets queue */
6152 + struct sk_buff_head unrel; /* Unreliable packets queue */
6154 + unsigned long rx_count;
6155 + struct sk_buff *rx_skb;
6156 + u8 rxseq_txack; /* rxseq == txack. */
6157 + u8 rxack; /* Last packet sent by us that the peer ack'ed */
6158 + struct timer_list tbcsp;
6161 + BCSP_W4_PKT_DELIMITER,
6162 + BCSP_W4_PKT_START,
6169 + BCSP_ESCSTATE_NOESC,
6174 + u8 txack_req; /* Do we need to send ack's to the peer? */
6176 + /* Reliable packet sequence number - used to assign seq to each rel pkt. */
6180 +#endif /* __HCI_BCSP_H__ */
6181 diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.c linux-2.4.18-mh9/drivers/bluetooth/hci_h4.c
6182 --- linux-2.4.18/drivers/bluetooth/hci_h4.c Thu Jan 1 01:00:00 1970
6183 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_h4.c Mon Aug 25 18:38:10 2003
6186 + BlueZ - Bluetooth protocol stack for Linux
6187 + Copyright (C) 2000-2001 Qualcomm Incorporated
6189 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6191 + This program is free software; you can redistribute it and/or modify
6192 + it under the terms of the GNU General Public License version 2 as
6193 + published by the Free Software Foundation;
6195 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6196 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6197 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6198 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6199 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6200 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6201 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6202 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6204 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6205 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6206 + SOFTWARE IS DISCLAIMED.
6210 + * BlueZ HCI UART(H4) protocol.
6212 + * $Id: hci_h4.c,v 1.3 2002/09/09 01:17:32 maxk Exp $
6214 +#define VERSION "1.2"
6216 +#include <linux/config.h>
6217 +#include <linux/module.h>
6219 +#include <linux/version.h>
6220 +#include <linux/kernel.h>
6221 +#include <linux/init.h>
6222 +#include <linux/sched.h>
6223 +#include <linux/types.h>
6224 +#include <linux/fcntl.h>
6225 +#include <linux/interrupt.h>
6226 +#include <linux/ptrace.h>
6227 +#include <linux/poll.h>
6229 +#include <linux/slab.h>
6230 +#include <linux/tty.h>
6231 +#include <linux/errno.h>
6232 +#include <linux/string.h>
6233 +#include <linux/signal.h>
6234 +#include <linux/ioctl.h>
6235 +#include <linux/skbuff.h>
6237 +#include <net/bluetooth/bluetooth.h>
6238 +#include <net/bluetooth/hci_core.h>
6239 +#include "hci_uart.h"
6240 +#include "hci_h4.h"
6242 +#ifndef HCI_UART_DEBUG
6244 +#define BT_DBG( A... )
6246 +#define BT_DMP( A... )
6249 +/* Initialize protocol */
6250 +static int h4_open(struct hci_uart *hu)
6252 + struct h4_struct *h4;
6254 + BT_DBG("hu %p", hu);
6256 + h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
6259 + memset(h4, 0, sizeof(*h4));
6261 + skb_queue_head_init(&h4->txq);
6267 +/* Flush protocol data */
6268 +static int h4_flush(struct hci_uart *hu)
6270 + struct h4_struct *h4 = hu->priv;
6272 + BT_DBG("hu %p", hu);
6273 + skb_queue_purge(&h4->txq);
6277 +/* Close protocol */
6278 +static int h4_close(struct hci_uart *hu)
6280 + struct h4_struct *h4 = hu->priv;
6283 + BT_DBG("hu %p", hu);
6285 + skb_queue_purge(&h4->txq);
6287 + kfree_skb(h4->rx_skb);
6294 +/* Enqueue frame for transmittion (padding, crc, etc) */
6295 +static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
6297 + struct h4_struct *h4 = hu->priv;
6299 + BT_DBG("hu %p skb %p", hu, skb);
6301 + /* Prepend skb with frame type */
6302 + memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
6303 + skb_queue_tail(&h4->txq, skb);
6307 +static inline int h4_check_data_len(struct h4_struct *h4, int len)
6309 + register int room = skb_tailroom(h4->rx_skb);
6311 + BT_DBG("len %d room %d", len, room);
6313 + BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
6314 + hci_recv_frame(h4->rx_skb);
6315 + } else if (len > room) {
6316 + BT_ERR("Data length is too large");
6317 + kfree_skb(h4->rx_skb);
6319 + h4->rx_state = H4_W4_DATA;
6320 + h4->rx_count = len;
6324 + h4->rx_state = H4_W4_PACKET_TYPE;
6325 + h4->rx_skb = NULL;
6331 +static int h4_recv(struct hci_uart *hu, void *data, int count)
6333 + struct h4_struct *h4 = hu->priv;
6334 + register char *ptr;
6335 + hci_event_hdr *eh;
6338 + register int len, type, dlen;
6340 + BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
6341 + hu, count, h4->rx_state, h4->rx_count);
6345 + if (h4->rx_count) {
6346 + len = MIN(h4->rx_count, count);
6347 + memcpy(skb_put(h4->rx_skb, len), ptr, len);
6348 + h4->rx_count -= len; count -= len; ptr += len;
6353 + switch (h4->rx_state) {
6355 + BT_DBG("Complete data");
6357 + BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
6359 + hci_recv_frame(h4->rx_skb);
6361 + h4->rx_state = H4_W4_PACKET_TYPE;
6362 + h4->rx_skb = NULL;
6365 + case H4_W4_EVENT_HDR:
6366 + eh = (hci_event_hdr *) h4->rx_skb->data;
6368 + BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
6370 + h4_check_data_len(h4, eh->plen);
6373 + case H4_W4_ACL_HDR:
6374 + ah = (hci_acl_hdr *) h4->rx_skb->data;
6375 + dlen = __le16_to_cpu(ah->dlen);
6377 + BT_DBG("ACL header: dlen %d", dlen);
6379 + h4_check_data_len(h4, dlen);
6382 + case H4_W4_SCO_HDR:
6383 + sh = (hci_sco_hdr *) h4->rx_skb->data;
6385 + BT_DBG("SCO header: dlen %d", sh->dlen);
6387 + h4_check_data_len(h4, sh->dlen);
6392 + /* H4_W4_PACKET_TYPE */
6394 + case HCI_EVENT_PKT:
6395 + BT_DBG("Event packet");
6396 + h4->rx_state = H4_W4_EVENT_HDR;
6397 + h4->rx_count = HCI_EVENT_HDR_SIZE;
6398 + type = HCI_EVENT_PKT;
6401 + case HCI_ACLDATA_PKT:
6402 + BT_DBG("ACL packet");
6403 + h4->rx_state = H4_W4_ACL_HDR;
6404 + h4->rx_count = HCI_ACL_HDR_SIZE;
6405 + type = HCI_ACLDATA_PKT;
6408 + case HCI_SCODATA_PKT:
6409 + BT_DBG("SCO packet");
6410 + h4->rx_state = H4_W4_SCO_HDR;
6411 + h4->rx_count = HCI_SCO_HDR_SIZE;
6412 + type = HCI_SCODATA_PKT;
6416 + BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
6417 + hu->hdev.stat.err_rx++;
6423 + /* Allocate packet */
6424 + h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
6425 + if (!h4->rx_skb) {
6426 + BT_ERR("Can't allocate mem for new packet");
6427 + h4->rx_state = H4_W4_PACKET_TYPE;
6431 + h4->rx_skb->dev = (void *) &hu->hdev;
6432 + h4->rx_skb->pkt_type = type;
6437 +static struct sk_buff *h4_dequeue(struct hci_uart *hu)
6439 + struct h4_struct *h4 = hu->priv;
6440 + return skb_dequeue(&h4->txq);
6443 +static struct hci_uart_proto h4p = {
6448 + enqueue: h4_enqueue,
6449 + dequeue: h4_dequeue,
6455 + return hci_uart_register_proto(&h4p);
6458 +int h4_deinit(void)
6460 + return hci_uart_unregister_proto(&h4p);
6462 diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.h linux-2.4.18-mh9/drivers/bluetooth/hci_h4.h
6463 --- linux-2.4.18/drivers/bluetooth/hci_h4.h Thu Jan 1 01:00:00 1970
6464 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_h4.h Mon Aug 25 18:38:10 2003
6467 + BlueZ - Bluetooth protocol stack for Linux
6468 + Copyright (C) 2000-2001 Qualcomm Incorporated
6470 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6472 + This program is free software; you can redistribute it and/or modify
6473 + it under the terms of the GNU General Public License version 2 as
6474 + published by the Free Software Foundation;
6476 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6477 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6478 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6479 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6480 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6481 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6482 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6483 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6485 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6486 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6487 + SOFTWARE IS DISCLAIMED.
6491 + * $Id: hci_h4.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
6496 + unsigned long rx_state;
6497 + unsigned long rx_count;
6498 + struct sk_buff *rx_skb;
6499 + struct sk_buff_head txq;
6502 +/* H4 receiver States */
6503 +#define H4_W4_PACKET_TYPE 0
6504 +#define H4_W4_EVENT_HDR 1
6505 +#define H4_W4_ACL_HDR 2
6506 +#define H4_W4_SCO_HDR 3
6507 +#define H4_W4_DATA 4
6509 +#endif /* __KERNEL__ */
6510 diff -urN linux-2.4.18/drivers/bluetooth/hci_ldisc.c linux-2.4.18-mh9/drivers/bluetooth/hci_ldisc.c
6511 --- linux-2.4.18/drivers/bluetooth/hci_ldisc.c Thu Jan 1 01:00:00 1970
6512 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_ldisc.c Mon Aug 25 18:38:10 2003
6515 + BlueZ - Bluetooth protocol stack for Linux
6516 + Copyright (C) 2000-2001 Qualcomm Incorporated
6518 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6520 + This program is free software; you can redistribute it and/or modify
6521 + it under the terms of the GNU General Public License version 2 as
6522 + published by the Free Software Foundation;
6524 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6525 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6526 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
6527 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
6528 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
6529 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
6530 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
6531 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6533 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
6534 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
6535 + SOFTWARE IS DISCLAIMED.
6539 + * BlueZ HCI UART driver.
6541 + * $Id: hci_ldisc.c,v 1.5 2002/10/02 18:37:20 maxk Exp $
6543 +#define VERSION "2.1"
6545 +#include <linux/config.h>
6546 +#include <linux/module.h>
6548 +#include <linux/version.h>
6549 +#include <linux/config.h>
6550 +#include <linux/kernel.h>
6551 +#include <linux/init.h>
6552 +#include <linux/sched.h>
6553 +#include <linux/types.h>
6554 +#include <linux/fcntl.h>
6555 +#include <linux/interrupt.h>
6556 +#include <linux/ptrace.h>
6557 +#include <linux/poll.h>
6559 +#include <linux/slab.h>
6560 +#include <linux/tty.h>
6561 +#include <linux/errno.h>
6562 +#include <linux/string.h>
6563 +#include <linux/signal.h>
6564 +#include <linux/ioctl.h>
6565 +#include <linux/skbuff.h>
6567 +#include <net/bluetooth/bluetooth.h>
6568 +#include <net/bluetooth/hci_core.h>
6569 +#include "hci_uart.h"
6571 +#ifndef HCI_UART_DEBUG
6573 +#define BT_DBG( A... )
6575 +#define BT_DMP( A... )
6578 +static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
6580 +int hci_uart_register_proto(struct hci_uart_proto *p)
6582 + if (p->id >= HCI_UART_MAX_PROTO)
6592 +int hci_uart_unregister_proto(struct hci_uart_proto *p)
6594 + if (p->id >= HCI_UART_MAX_PROTO)
6600 + hup[p->id] = NULL;
6604 +static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
6606 + if (id >= HCI_UART_MAX_PROTO)
6611 +static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
6613 + struct hci_dev *hdev = &hu->hdev;
6615 + /* Update HCI stat counters */
6616 + switch (pkt_type) {
6617 + case HCI_COMMAND_PKT:
6618 + hdev->stat.cmd_tx++;
6621 + case HCI_ACLDATA_PKT:
6622 + hdev->stat.acl_tx++;
6625 + case HCI_SCODATA_PKT:
6626 + hdev->stat.cmd_tx++;
6631 +static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
6633 + struct sk_buff *skb = hu->tx_skb;
6635 + skb = hu->proto->dequeue(hu);
6637 + hu->tx_skb = NULL;
6641 +int hci_uart_tx_wakeup(struct hci_uart *hu)
6643 + struct tty_struct *tty = hu->tty;
6644 + struct hci_dev *hdev = &hu->hdev;
6645 + struct sk_buff *skb;
6647 + if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
6648 + set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
6655 + clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
6657 + while ((skb = hci_uart_dequeue(hu))) {
6660 + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
6661 + len = tty->driver.write(tty, 0, skb->data, skb->len);
6662 + hdev->stat.byte_tx += len;
6664 + skb_pull(skb, len);
6670 + hci_uart_tx_complete(hu, skb->pkt_type);
6674 + if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
6677 + clear_bit(HCI_UART_SENDING, &hu->tx_state);
6681 +/* ------- Interface to HCI layer ------ */
6682 +/* Initialize device */
6683 +static int hci_uart_open(struct hci_dev *hdev)
6685 + BT_DBG("%s %p", hdev->name, hdev);
6687 + /* Nothing to do for UART driver */
6689 + set_bit(HCI_RUNNING, &hdev->flags);
6694 +static int hci_uart_flush(struct hci_dev *hdev)
6696 + struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
6697 + struct tty_struct *tty = hu->tty;
6699 + BT_DBG("hdev %p tty %p", hdev, tty);
6702 + kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
6705 + /* Flush any pending characters in the driver and discipline. */
6706 + if (tty->ldisc.flush_buffer)
6707 + tty->ldisc.flush_buffer(tty);
6709 + if (tty->driver.flush_buffer)
6710 + tty->driver.flush_buffer(tty);
6712 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6713 + hu->proto->flush(hu);
6719 +static int hci_uart_close(struct hci_dev *hdev)
6721 + BT_DBG("hdev %p", hdev);
6723 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
6726 + hci_uart_flush(hdev);
6730 +/* Send frames from HCI layer */
6731 +static int hci_uart_send_frame(struct sk_buff *skb)
6733 + struct hci_dev* hdev = (struct hci_dev *) skb->dev;
6734 + struct tty_struct *tty;
6735 + struct hci_uart *hu;
6738 + BT_ERR("Frame for uknown device (hdev=NULL)");
6742 + if (!test_bit(HCI_RUNNING, &hdev->flags))
6745 + hu = (struct hci_uart *) hdev->driver_data;
6748 + BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
6750 + hu->proto->enqueue(hu, skb);
6752 + hci_uart_tx_wakeup(hu);
6756 +static void hci_uart_destruct(struct hci_dev *hdev)
6758 + struct hci_uart *hu;
6760 + if (!hdev) return;
6762 + BT_DBG("%s", hdev->name);
6764 + hu = (struct hci_uart *) hdev->driver_data;
6767 + MOD_DEC_USE_COUNT;
6770 +/* ------ LDISC part ------ */
6771 +/* hci_uart_tty_open
6773 + * Called when line discipline changed to HCI_UART.
6776 + * tty pointer to tty info structure
6778 + * 0 if success, otherwise error code
6780 +static int hci_uart_tty_open(struct tty_struct *tty)
6782 + struct hci_uart *hu = (void *) tty->disc_data;
6784 + BT_DBG("tty %p", tty);
6789 + if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
6790 + BT_ERR("Can't allocate controll structure");
6793 + memset(hu, 0, sizeof(struct hci_uart));
6795 + tty->disc_data = hu;
6798 + spin_lock_init(&hu->rx_lock);
6800 + /* Flush any pending characters in the driver and line discipline */
6801 + if (tty->ldisc.flush_buffer)
6802 + tty->ldisc.flush_buffer(tty);
6804 + if (tty->driver.flush_buffer)
6805 + tty->driver.flush_buffer(tty);
6807 + MOD_INC_USE_COUNT;
6811 +/* hci_uart_tty_close()
6813 + * Called when the line discipline is changed to something
6814 + * else, the tty is closed, or the tty detects a hangup.
6816 +static void hci_uart_tty_close(struct tty_struct *tty)
6818 + struct hci_uart *hu = (void *)tty->disc_data;
6820 + BT_DBG("tty %p", tty);
6822 + /* Detach from the tty */
6823 + tty->disc_data = NULL;
6826 + struct hci_dev *hdev = &hu->hdev;
6827 + hci_uart_close(hdev);
6829 + if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
6830 + hu->proto->close(hu);
6831 + hci_unregister_dev(hdev);
6834 + MOD_DEC_USE_COUNT;
6838 +/* hci_uart_tty_wakeup()
6840 + * Callback for transmit wakeup. Called when low level
6841 + * device driver can accept more send data.
6843 + * Arguments: tty pointer to associated tty instance data
6844 + * Return Value: None
6846 +static void hci_uart_tty_wakeup(struct tty_struct *tty)
6848 + struct hci_uart *hu = (void *)tty->disc_data;
6855 + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
6857 + if (tty != hu->tty)
6860 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6861 + hci_uart_tx_wakeup(hu);
6864 +/* hci_uart_tty_room()
6866 + * Callback function from tty driver. Return the amount of
6867 + * space left in the receiver's buffer to decide if remote
6868 + * transmitter is to be throttled.
6870 + * Arguments: tty pointer to associated tty instance data
6871 + * Return Value: number of bytes left in receive buffer
6873 +static int hci_uart_tty_room (struct tty_struct *tty)
6878 +/* hci_uart_tty_receive()
6880 + * Called by tty low level driver when receive data is
6883 + * Arguments: tty pointer to tty isntance data
6884 + * data pointer to received data
6885 + * flags pointer to flags for data
6886 + * count count of received data in bytes
6888 + * Return Value: None
6890 +static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
6892 + struct hci_uart *hu = (void *)tty->disc_data;
6894 + if (!hu || tty != hu->tty)
6897 + if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
6900 + spin_lock(&hu->rx_lock);
6901 + hu->proto->recv(hu, (void *) data, count);
6902 + hu->hdev.stat.byte_rx += count;
6903 + spin_unlock(&hu->rx_lock);
6905 + if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
6906 + tty->driver.unthrottle(tty);
6909 +static int hci_uart_register_dev(struct hci_uart *hu)
6911 + struct hci_dev *hdev;
6915 + /* Initialize and register HCI device */
6918 + hdev->type = HCI_UART;
6919 + hdev->driver_data = hu;
6921 + hdev->open = hci_uart_open;
6922 + hdev->close = hci_uart_close;
6923 + hdev->flush = hci_uart_flush;
6924 + hdev->send = hci_uart_send_frame;
6925 + hdev->destruct = hci_uart_destruct;
6927 + if (hci_register_dev(hdev) < 0) {
6928 + BT_ERR("Can't register HCI device %s", hdev->name);
6931 + MOD_INC_USE_COUNT;
6935 +static int hci_uart_set_proto(struct hci_uart *hu, int id)
6937 + struct hci_uart_proto *p;
6940 + p = hci_uart_get_proto(id);
6942 + return -EPROTONOSUPPORT;
6944 + err = p->open(hu);
6950 + err = hci_uart_register_dev(hu);
6958 +/* hci_uart_tty_ioctl()
6960 + * Process IOCTL system call for the tty device.
6964 + * tty pointer to tty instance data
6965 + * file pointer to open file object for device
6966 + * cmd IOCTL command code
6967 + * arg argument for IOCTL call (cmd dependent)
6969 + * Return Value: Command dependent
6971 +static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
6972 + unsigned int cmd, unsigned long arg)
6974 + struct hci_uart *hu = (void *)tty->disc_data;
6979 + /* Verify the status of the device */
6984 + case HCIUARTSETPROTO:
6985 + if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
6986 + err = hci_uart_set_proto(hu, arg);
6988 + clear_bit(HCI_UART_PROTO_SET, &hu->flags);
6991 + tty->low_latency = 1;
6995 + case HCIUARTGETPROTO:
6996 + if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
6997 + return hu->proto->id;
7001 + err = n_tty_ioctl(tty, file, cmd, arg);
7009 + * We don't provide read/write/poll interface for user space.
7011 +static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
7015 +static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
7019 +static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
7024 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7026 +int h4_deinit(void);
7028 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7029 +int bcsp_init(void);
7030 +int bcsp_deinit(void);
7033 +int __init hci_uart_init(void)
7035 + static struct tty_ldisc hci_uart_ldisc;
7038 + BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
7040 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
7042 + /* Register the tty discipline */
7044 + memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
7045 + hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
7046 + hci_uart_ldisc.name = "n_hci";
7047 + hci_uart_ldisc.open = hci_uart_tty_open;
7048 + hci_uart_ldisc.close = hci_uart_tty_close;
7049 + hci_uart_ldisc.read = hci_uart_tty_read;
7050 + hci_uart_ldisc.write = hci_uart_tty_write;
7051 + hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
7052 + hci_uart_ldisc.poll = hci_uart_tty_poll;
7053 + hci_uart_ldisc.receive_room= hci_uart_tty_room;
7054 + hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
7055 + hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
7057 + if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
7058 + BT_ERR("Can't register HCI line discipline (%d)", err);
7062 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7065 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7072 +void hci_uart_cleanup(void)
7076 +#ifdef CONFIG_BLUEZ_HCIUART_H4
7079 +#ifdef CONFIG_BLUEZ_HCIUART_BCSP
7083 + /* Release tty registration of line discipline */
7084 + if ((err = tty_register_ldisc(N_HCI, NULL)))
7085 + BT_ERR("Can't unregister HCI line discipline (%d)", err);
7088 +module_init(hci_uart_init);
7089 +module_exit(hci_uart_cleanup);
7091 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
7092 +MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
7093 +MODULE_LICENSE("GPL");
7094 diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.c linux-2.4.18-mh9/drivers/bluetooth/hci_uart.c
7095 --- linux-2.4.18/drivers/bluetooth/hci_uart.c Fri Sep 7 18:28:38 2001
7096 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_uart.c Thu Jan 1 01:00:00 1970
7099 - BlueZ - Bluetooth protocol stack for Linux
7100 - Copyright (C) 2000-2001 Qualcomm Incorporated
7102 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7104 - This program is free software; you can redistribute it and/or modify
7105 - it under the terms of the GNU General Public License version 2 as
7106 - published by the Free Software Foundation;
7108 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7109 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7110 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
7111 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
7112 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
7113 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
7114 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
7115 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
7117 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
7118 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
7119 - SOFTWARE IS DISCLAIMED.
7123 - * BlueZ HCI UART driver.
7125 - * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
7127 -#define VERSION "1.0"
7129 -#include <linux/config.h>
7130 -#include <linux/module.h>
7132 -#include <linux/version.h>
7133 -#include <linux/config.h>
7134 -#include <linux/kernel.h>
7135 -#include <linux/init.h>
7136 -#include <linux/sched.h>
7137 -#include <linux/types.h>
7138 -#include <linux/fcntl.h>
7139 -#include <linux/interrupt.h>
7140 -#include <linux/ptrace.h>
7141 -#include <linux/poll.h>
7143 -#include <linux/slab.h>
7144 -#include <linux/tty.h>
7145 -#include <linux/errno.h>
7146 -#include <linux/string.h>
7147 -#include <linux/signal.h>
7148 -#include <linux/ioctl.h>
7149 -#include <linux/skbuff.h>
7151 -#include <net/bluetooth/bluetooth.h>
7152 -#include <net/bluetooth/bluez.h>
7153 -#include <net/bluetooth/hci_core.h>
7154 -#include <net/bluetooth/hci_uart.h>
7156 -#ifndef HCI_UART_DEBUG
7158 -#define DBG( A... )
7160 -#define DMP( A... )
7163 -/* ------- Interface to HCI layer ------ */
7164 -/* Initialize device */
7165 -int n_hci_open(struct hci_dev *hdev)
7167 - DBG("%s %p", hdev->name, hdev);
7169 - /* Nothing to do for UART driver */
7171 - hdev->flags |= HCI_RUNNING;
7177 -int n_hci_flush(struct hci_dev *hdev)
7179 - struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
7180 - struct tty_struct *tty = n_hci->tty;
7182 - DBG("hdev %p tty %p", hdev, tty);
7184 - /* Drop TX queue */
7185 - skb_queue_purge(&n_hci->txq);
7187 - /* Flush any pending characters in the driver and discipline. */
7188 - if (tty->ldisc.flush_buffer)
7189 - tty->ldisc.flush_buffer(tty);
7191 - if (tty->driver.flush_buffer)
7192 - tty->driver.flush_buffer(tty);
7198 -int n_hci_close(struct hci_dev *hdev)
7200 - DBG("hdev %p", hdev);
7202 - hdev->flags &= ~HCI_RUNNING;
7204 - n_hci_flush(hdev);
7209 -int n_hci_tx_wakeup(struct n_hci *n_hci)
7211 - register struct tty_struct *tty = n_hci->tty;
7213 - if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
7214 - set_bit(TRANS_WAKEUP, &n_hci->tx_state);
7220 - register struct sk_buff *skb;
7223 - clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
7225 - if (!(skb = skb_dequeue(&n_hci->txq)))
7228 - DMP(skb->data, skb->len);
7230 - /* Send frame to TTY driver */
7231 - tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
7232 - len = tty->driver.write(tty, 0, skb->data, skb->len);
7234 - n_hci->hdev.stat.byte_tx += len;
7236 - DBG("sent %d", len);
7238 - if (len == skb->len) {
7239 - /* Full frame was sent */
7242 - /* Subtract sent part and requeue */
7243 - skb_pull(skb, len);
7244 - skb_queue_head(&n_hci->txq, skb);
7246 - } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
7247 - clear_bit(TRANS_SENDING, &n_hci->tx_state);
7252 -/* Send frames from HCI layer */
7253 -int n_hci_send_frame(struct sk_buff *skb)
7255 - struct hci_dev* hdev = (struct hci_dev *) skb->dev;
7256 - struct tty_struct *tty;
7257 - struct n_hci *n_hci;
7260 - ERR("Frame for uknown device (hdev=NULL)");
7264 - if (!(hdev->flags & HCI_RUNNING))
7267 - n_hci = (struct n_hci *) hdev->driver_data;
7268 - tty = n_hci2tty(n_hci);
7270 - DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
7272 - switch (skb->pkt_type) {
7273 - case HCI_COMMAND_PKT:
7274 - hdev->stat.cmd_tx++;
7277 - case HCI_ACLDATA_PKT:
7278 - hdev->stat.acl_tx++;
7281 - case HCI_SCODATA_PKT:
7282 - hdev->stat.cmd_tx++;
7286 - /* Prepend skb with frame type and queue */
7287 - memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
7288 - skb_queue_tail(&n_hci->txq, skb);
7290 - n_hci_tx_wakeup(n_hci);
7295 -/* ------ LDISC part ------ */
7299 - * Called when line discipline changed to N_HCI.
7302 - * tty pointer to tty info structure
7304 - * 0 if success, otherwise error code
7306 -static int n_hci_tty_open(struct tty_struct *tty)
7308 - struct n_hci *n_hci = tty2n_hci(tty);
7309 - struct hci_dev *hdev;
7311 - DBG("tty %p", tty);
7316 - if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
7317 - ERR("Can't allocate controll structure");
7320 - memset(n_hci, 0, sizeof(struct n_hci));
7322 - /* Initialize and register HCI device */
7323 - hdev = &n_hci->hdev;
7325 - hdev->type = HCI_UART;
7326 - hdev->driver_data = n_hci;
7328 - hdev->open = n_hci_open;
7329 - hdev->close = n_hci_close;
7330 - hdev->flush = n_hci_flush;
7331 - hdev->send = n_hci_send_frame;
7333 - if (hci_register_dev(hdev) < 0) {
7334 - ERR("Can't register HCI device %s", hdev->name);
7339 - tty->disc_data = n_hci;
7342 - spin_lock_init(&n_hci->rx_lock);
7343 - n_hci->rx_state = WAIT_PACKET_TYPE;
7345 - skb_queue_head_init(&n_hci->txq);
7347 - MOD_INC_USE_COUNT;
7349 - /* Flush any pending characters in the driver and discipline. */
7350 - if (tty->ldisc.flush_buffer)
7351 - tty->ldisc.flush_buffer(tty);
7353 - if (tty->driver.flush_buffer)
7354 - tty->driver.flush_buffer(tty);
7359 -/* n_hci_tty_close()
7361 - * Called when the line discipline is changed to something
7362 - * else, the tty is closed, or the tty detects a hangup.
7364 -static void n_hci_tty_close(struct tty_struct *tty)
7366 - struct n_hci *n_hci = tty2n_hci(tty);
7367 - struct hci_dev *hdev = &n_hci->hdev;
7369 - DBG("tty %p hdev %p", tty, hdev);
7371 - if (n_hci != NULL) {
7372 - n_hci_close(hdev);
7374 - if (hci_unregister_dev(hdev) < 0) {
7375 - ERR("Can't unregister HCI device %s",hdev->name);
7378 - hdev->driver_data = NULL;
7379 - tty->disc_data = NULL;
7382 - MOD_DEC_USE_COUNT;
7386 -/* n_hci_tty_wakeup()
7388 - * Callback for transmit wakeup. Called when low level
7389 - * device driver can accept more send data.
7391 - * Arguments: tty pointer to associated tty instance data
7392 - * Return Value: None
7394 -static void n_hci_tty_wakeup( struct tty_struct *tty )
7396 - struct n_hci *n_hci = tty2n_hci(tty);
7403 - tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
7405 - if (tty != n_hci->tty)
7408 - n_hci_tx_wakeup(n_hci);
7411 -/* n_hci_tty_room()
7413 - * Callback function from tty driver. Return the amount of
7414 - * space left in the receiver's buffer to decide if remote
7415 - * transmitter is to be throttled.
7417 - * Arguments: tty pointer to associated tty instance data
7418 - * Return Value: number of bytes left in receive buffer
7420 -static int n_hci_tty_room (struct tty_struct *tty)
7425 -static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
7427 - register int room = skb_tailroom(n_hci->rx_skb);
7429 - DBG("len %d room %d", len, room);
7431 - DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
7432 - hci_recv_frame(n_hci->rx_skb);
7433 - } else if (len > room) {
7434 - ERR("Data length is to large");
7435 - kfree_skb(n_hci->rx_skb);
7436 - n_hci->hdev.stat.err_rx++;
7438 - n_hci->rx_state = WAIT_DATA;
7439 - n_hci->rx_count = len;
7443 - n_hci->rx_state = WAIT_PACKET_TYPE;
7444 - n_hci->rx_skb = NULL;
7445 - n_hci->rx_count = 0;
7449 -static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
7451 - register const char *ptr;
7452 - hci_event_hdr *eh;
7455 - register int len, type, dlen;
7457 - DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
7459 - n_hci->hdev.stat.byte_rx += count;
7463 - if (n_hci->rx_count) {
7464 - len = MIN(n_hci->rx_count, count);
7465 - memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
7466 - n_hci->rx_count -= len; count -= len; ptr += len;
7468 - if (n_hci->rx_count)
7471 - switch (n_hci->rx_state) {
7473 - DBG("Complete data");
7475 - DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
7477 - hci_recv_frame(n_hci->rx_skb);
7479 - n_hci->rx_state = WAIT_PACKET_TYPE;
7480 - n_hci->rx_skb = NULL;
7483 - case WAIT_EVENT_HDR:
7484 - eh = (hci_event_hdr *) n_hci->rx_skb->data;
7486 - DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
7488 - n_hci_check_data_len(n_hci, eh->plen);
7491 - case WAIT_ACL_HDR:
7492 - ah = (hci_acl_hdr *) n_hci->rx_skb->data;
7493 - dlen = __le16_to_cpu(ah->dlen);
7495 - DBG("ACL header: dlen %d", dlen);
7497 - n_hci_check_data_len(n_hci, dlen);
7500 - case WAIT_SCO_HDR:
7501 - sh = (hci_sco_hdr *) n_hci->rx_skb->data;
7503 - DBG("SCO header: dlen %d", sh->dlen);
7505 - n_hci_check_data_len(n_hci, sh->dlen);
7510 - /* WAIT_PACKET_TYPE */
7512 - case HCI_EVENT_PKT:
7513 - DBG("Event packet");
7514 - n_hci->rx_state = WAIT_EVENT_HDR;
7515 - n_hci->rx_count = HCI_EVENT_HDR_SIZE;
7516 - type = HCI_EVENT_PKT;
7519 - case HCI_ACLDATA_PKT:
7520 - DBG("ACL packet");
7521 - n_hci->rx_state = WAIT_ACL_HDR;
7522 - n_hci->rx_count = HCI_ACL_HDR_SIZE;
7523 - type = HCI_ACLDATA_PKT;
7526 - case HCI_SCODATA_PKT:
7527 - DBG("SCO packet");
7528 - n_hci->rx_state = WAIT_SCO_HDR;
7529 - n_hci->rx_count = HCI_SCO_HDR_SIZE;
7530 - type = HCI_SCODATA_PKT;
7534 - ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
7535 - n_hci->hdev.stat.err_rx++;
7541 - /* Allocate packet */
7542 - if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
7543 - ERR("Can't allocate mem for new packet");
7545 - n_hci->rx_state = WAIT_PACKET_TYPE;
7546 - n_hci->rx_count = 0;
7549 - n_hci->rx_skb->dev = (void *) &n_hci->hdev;
7550 - n_hci->rx_skb->pkt_type = type;
7554 -/* n_hci_tty_receive()
7556 - * Called by tty low level driver when receive data is
7559 - * Arguments: tty pointer to tty isntance data
7560 - * data pointer to received data
7561 - * flags pointer to flags for data
7562 - * count count of received data in bytes
7564 - * Return Value: None
7566 -static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
7568 - struct n_hci *n_hci = tty2n_hci(tty);
7570 - if (!n_hci || tty != n_hci->tty)
7573 - spin_lock(&n_hci->rx_lock);
7574 - n_hci_rx(n_hci, data, flags, count);
7575 - spin_unlock(&n_hci->rx_lock);
7577 - if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
7578 - tty->driver.unthrottle(tty);
7581 -/* n_hci_tty_ioctl()
7583 - * Process IOCTL system call for the tty device.
7587 - * tty pointer to tty instance data
7588 - * file pointer to open file object for device
7589 - * cmd IOCTL command code
7590 - * arg argument for IOCTL call (cmd dependent)
7592 - * Return Value: Command dependent
7594 -static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
7595 - unsigned int cmd, unsigned long arg)
7597 - struct n_hci *n_hci = tty2n_hci(tty);
7602 - /* Verify the status of the device */
7608 - error = n_tty_ioctl(tty, file, cmd, arg);
7616 - * We don't provide read/write/poll interface for user space.
7618 -static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
7622 -static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
7626 -static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
7631 -int __init n_hci_init(void)
7633 - static struct tty_ldisc n_hci_ldisc;
7636 - INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
7638 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
7640 - /* Register the tty discipline */
7642 - memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
7643 - n_hci_ldisc.magic = TTY_LDISC_MAGIC;
7644 - n_hci_ldisc.name = "n_hci";
7645 - n_hci_ldisc.open = n_hci_tty_open;
7646 - n_hci_ldisc.close = n_hci_tty_close;
7647 - n_hci_ldisc.read = n_hci_tty_read;
7648 - n_hci_ldisc.write = n_hci_tty_write;
7649 - n_hci_ldisc.ioctl = n_hci_tty_ioctl;
7650 - n_hci_ldisc.poll = n_hci_tty_poll;
7651 - n_hci_ldisc.receive_room= n_hci_tty_room;
7652 - n_hci_ldisc.receive_buf = n_hci_tty_receive;
7653 - n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
7655 - if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
7656 - ERR("Can't register HCI line discipline (%d)", err);
7663 -void n_hci_cleanup(void)
7667 - /* Release tty registration of line discipline */
7668 - if ((err = tty_register_ldisc(N_HCI, NULL)))
7669 - ERR("Can't unregister HCI line discipline (%d)", err);
7672 -module_init(n_hci_init);
7673 -module_exit(n_hci_cleanup);
7675 -MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
7676 -MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
7677 -MODULE_LICENSE("GPL");
7678 diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.h linux-2.4.18-mh9/drivers/bluetooth/hci_uart.h
7679 --- linux-2.4.18/drivers/bluetooth/hci_uart.h Thu Jan 1 01:00:00 1970
7680 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_uart.h Mon Aug 25 18:38:10 2003
7683 + BlueZ - Bluetooth protocol stack for Linux
7684 + Copyright (C) 2000-2001 Qualcomm Incorporated
7686 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7688 + This program is free software; you can redistribute it and/or modify
7689 + it under the terms of the GNU General Public License version 2 as
7690 + published by the Free Software Foundation;
7692 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7693 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7694 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
7695 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
7696 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
7697 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
7698 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
7699 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
7701 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
7702 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
7703 + SOFTWARE IS DISCLAIMED.
7707 + * $Id: hci_uart.h,v 1.2 2002/09/09 01:17:32 maxk Exp $
7715 +#define HCIUARTSETPROTO _IOW('U', 200, int)
7716 +#define HCIUARTGETPROTO _IOR('U', 201, int)
7718 +/* UART protocols */
7719 +#define HCI_UART_MAX_PROTO 3
7721 +#define HCI_UART_H4 0
7722 +#define HCI_UART_BCSP 1
7723 +#define HCI_UART_NCSP 2
7728 +struct hci_uart_proto {
7730 + int (*open)(struct hci_uart *hu);
7731 + int (*close)(struct hci_uart *hu);
7732 + int (*flush)(struct hci_uart *hu);
7733 + int (*recv)(struct hci_uart *hu, void *data, int len);
7734 + int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
7735 + struct sk_buff *(*dequeue)(struct hci_uart *hu);
7739 + struct tty_struct *tty;
7740 + struct hci_dev hdev;
7741 + unsigned long flags;
7743 + struct hci_uart_proto *proto;
7746 + struct sk_buff *tx_skb;
7747 + unsigned long tx_state;
7748 + spinlock_t rx_lock;
7751 +/* HCI_UART flag bits */
7752 +#define HCI_UART_PROTO_SET 0
7755 +#define HCI_UART_SENDING 1
7756 +#define HCI_UART_TX_WAKEUP 2
7758 +int hci_uart_register_proto(struct hci_uart_proto *p);
7759 +int hci_uart_unregister_proto(struct hci_uart_proto *p);
7760 +int hci_uart_tx_wakeup(struct hci_uart *hu);
7762 +#endif /* __KERNEL__ */
7763 diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.c linux-2.4.18-mh9/drivers/bluetooth/hci_usb.c
7764 --- linux-2.4.18/drivers/bluetooth/hci_usb.c Fri Sep 7 18:28:38 2001
7765 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_usb.c Mon Aug 25 18:38:12 2003
7768 - BlueZ - Bluetooth protocol stack for Linux
7769 + HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
7770 Copyright (C) 2000-2001 Qualcomm Incorporated
7772 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
7774 + Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
7776 This program is free software; you can redistribute it and/or modify
7777 it under the terms of the GNU General Public License version 2 as
7778 published by the Free Software Foundation;
7779 @@ -23,598 +24,901 @@
7783 - * BlueZ HCI USB driver.
7784 * Based on original USB Bluetooth driver for Linux kernel
7785 * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
7786 * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
7788 - * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
7789 + * $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $
7791 -#define VERSION "1.0"
7792 +#define VERSION "2.4"
7794 #include <linux/config.h>
7795 #include <linux/module.h>
7797 #include <linux/version.h>
7798 -#include <linux/config.h>
7799 #include <linux/kernel.h>
7800 #include <linux/init.h>
7801 #include <linux/sched.h>
7802 +#include <linux/unistd.h>
7803 #include <linux/types.h>
7804 -#include <linux/fcntl.h>
7805 #include <linux/interrupt.h>
7806 -#include <linux/ptrace.h>
7807 -#include <linux/poll.h>
7809 #include <linux/slab.h>
7810 -#include <linux/tty.h>
7811 #include <linux/errno.h>
7812 #include <linux/string.h>
7813 -#include <linux/signal.h>
7814 -#include <linux/ioctl.h>
7815 #include <linux/skbuff.h>
7817 #include <linux/usb.h>
7819 #include <net/bluetooth/bluetooth.h>
7820 -#include <net/bluetooth/bluez.h>
7821 #include <net/bluetooth/hci_core.h>
7822 -#include <net/bluetooth/hci_usb.h>
7824 +#include "hci_usb.h"
7826 #ifndef HCI_USB_DEBUG
7828 -#define DBG( A... )
7830 -#define DMP( A... )
7832 +#define BT_DBG( A... )
7834 +#define BT_DMP( A... )
7837 -static struct usb_device_id usb_bluetooth_ids [] = {
7838 +#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET
7839 +#undef USB_ZERO_PACKET
7840 +#define USB_ZERO_PACKET 0
7843 +static struct usb_driver hci_usb_driver;
7845 +static struct usb_device_id bluetooth_ids[] = {
7846 + /* Generic Bluetooth USB device */
7847 { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
7849 + /* Ericsson with non-standard id */
7850 + { USB_DEVICE(0x0bdb, 0x1002) },
7852 + /* Bluetooth Ultraport Module from IBM */
7853 + { USB_DEVICE(0x04bf, 0x030a) },
7855 { } /* Terminating entry */
7858 -MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
7859 +MODULE_DEVICE_TABLE (usb, bluetooth_ids);
7861 -static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
7862 -static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
7863 +static struct usb_device_id ignore_ids[] = {
7864 + /* Broadcom BCM2033 without firmware */
7865 + { USB_DEVICE(0x0a5c, 0x2033) },
7867 -static void hci_usb_unlink_urbs(struct hci_usb *husb)
7869 - usb_unlink_urb(husb->read_urb);
7870 - usb_unlink_urb(husb->intr_urb);
7871 - usb_unlink_urb(husb->ctrl_urb);
7872 - usb_unlink_urb(husb->write_urb);
7874 + { } /* Terminating entry */
7877 -static void hci_usb_free_bufs(struct hci_usb *husb)
7878 +struct _urb *_urb_alloc(int isoc, int gfp)
7880 - if (husb->read_urb) {
7881 - if (husb->read_urb->transfer_buffer)
7882 - kfree(husb->read_urb->transfer_buffer);
7883 - usb_free_urb(husb->read_urb);
7886 - if (husb->intr_urb) {
7887 - if (husb->intr_urb->transfer_buffer)
7888 - kfree(husb->intr_urb->transfer_buffer);
7889 - usb_free_urb(husb->intr_urb);
7890 + struct _urb *_urb = kmalloc(sizeof(struct _urb) +
7891 + sizeof(iso_packet_descriptor_t) * isoc, gfp);
7893 + memset(_urb, 0, sizeof(*_urb));
7894 + spin_lock_init(&_urb->urb.lock);
7899 +struct _urb *_urb_dequeue(struct _urb_queue *q)
7901 + struct _urb *_urb = NULL;
7902 + unsigned long flags;
7903 + spin_lock_irqsave(&q->lock, flags);
7905 + struct list_head *head = &q->head;
7906 + struct list_head *next = head->next;
7907 + if (next != head) {
7908 + _urb = list_entry(next, struct _urb, list);
7909 + list_del(next); _urb->queue = NULL;
7912 + spin_unlock_irqrestore(&q->lock, flags);
7916 - if (husb->ctrl_urb)
7917 - usb_free_urb(husb->ctrl_urb);
7918 +static void hci_usb_rx_complete(struct urb *urb);
7919 +static void hci_usb_tx_complete(struct urb *urb);
7921 - if (husb->write_urb)
7922 - usb_free_urb(husb->write_urb);
7923 +#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
7924 +#define __pending_q(husb, type) (&husb->pending_q[type-1])
7925 +#define __completed_q(husb, type) (&husb->completed_q[type-1])
7926 +#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
7927 +#define __reassembly(husb, type) (husb->reassembly[type-1])
7929 - if (husb->intr_skb)
7930 - kfree_skb(husb->intr_skb);
7931 +static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
7933 + return _urb_dequeue(__completed_q(husb, type));
7936 -/* ------- Interface to HCI layer ------ */
7937 -/* Initialize device */
7938 -int hci_usb_open(struct hci_dev *hdev)
7939 +static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
7941 - struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
7944 - DBG("%s", hdev->name);
7946 - husb->read_urb->dev = husb->udev;
7947 - if ((status = usb_submit_urb(husb->read_urb)))
7948 - DBG("read submit failed. %d", status);
7949 + int offset = 0, i;
7951 - husb->intr_urb->dev = husb->udev;
7952 - if ((status = usb_submit_urb(husb->intr_urb)))
7953 - DBG("interrupt submit failed. %d", status);
7954 + BT_DBG("len %d mtu %d", len, mtu);
7956 - hdev->flags |= HCI_RUNNING;
7959 + for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
7960 + urb->iso_frame_desc[i].offset = offset;
7961 + urb->iso_frame_desc[i].length = mtu;
7962 + BT_DBG("desc %d offset %d len %d", i, offset, mtu);
7964 + if (len && i < HCI_MAX_ISOC_FRAMES) {
7965 + urb->iso_frame_desc[i].offset = offset;
7966 + urb->iso_frame_desc[i].length = len;
7967 + BT_DBG("desc %d offset %d len %d", i, offset, len);
7970 + urb->number_of_packets = i;
7974 -int hci_usb_flush(struct hci_dev *hdev)
7975 +static int hci_usb_intr_rx_submit(struct hci_usb *husb)
7977 - struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
7978 + struct _urb *_urb;
7980 + int err, pipe, interval, size;
7983 - DBG("%s", hdev->name);
7984 + BT_DBG("%s", husb->hdev.name);
7986 - /* Drop TX queues */
7987 - skb_queue_purge(&husb->tx_ctrl_q);
7988 - skb_queue_purge(&husb->tx_write_q);
7989 + size = husb->intr_in_ep->wMaxPacketSize;
7992 + buf = kmalloc(size, GFP_ATOMIC);
7996 + _urb = _urb_alloc(0, GFP_ATOMIC);
8001 + _urb->type = HCI_EVENT_PKT;
8002 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8005 + pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
8006 + interval = husb->intr_in_ep->bInterval;
8007 + FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
8009 + err = usb_submit_urb(urb);
8011 + BT_ERR("%s intr rx submit failed urb %p err %d",
8012 + husb->hdev.name, urb, err);
8013 + _urb_unlink(_urb);
8021 -int hci_usb_close(struct hci_dev *hdev)
8022 +static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
8024 - struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8025 + struct _urb *_urb;
8027 + int err, pipe, size = HCI_MAX_FRAME_SIZE;
8030 - DBG("%s", hdev->name);
8031 + buf = kmalloc(size, GFP_ATOMIC);
8035 - hdev->flags &= ~HCI_RUNNING;
8036 - hci_usb_unlink_urbs(husb);
8037 + _urb = _urb_alloc(0, GFP_ATOMIC);
8042 + _urb->type = HCI_ACLDATA_PKT;
8043 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8045 - hci_usb_flush(hdev);
8047 + pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
8048 + FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
8049 + urb->transfer_flags = USB_QUEUE_BULK;
8052 + BT_DBG("%s urb %p", husb->hdev.name, urb);
8054 + err = usb_submit_urb(urb);
8056 + BT_ERR("%s bulk rx submit failed urb %p err %d",
8057 + husb->hdev.name, urb, err);
8058 + _urb_unlink(_urb);
8065 -void hci_usb_ctrl_wakeup(struct hci_usb *husb)
8066 +#ifdef CONFIG_BLUEZ_USB_SCO
8067 +static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
8069 - struct sk_buff *skb;
8071 - if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
8073 + struct _urb *_urb;
8075 + int err, mtu, size;
8078 - DBG("%s", husb->hdev.name);
8079 + mtu = husb->isoc_in_ep->wMaxPacketSize;
8080 + size = mtu * HCI_MAX_ISOC_FRAMES;
8082 - if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
8084 + buf = kmalloc(size, GFP_ATOMIC);
8088 - if (hci_usb_ctrl_msg(husb, skb)){
8091 + _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
8096 + _urb->type = HCI_SCODATA_PKT;
8097 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8099 - DMP(skb->data, skb->len);
8102 - husb->hdev.stat.byte_tx += skb->len;
8104 + urb->context = husb;
8105 + urb->dev = husb->udev;
8106 + urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
8107 + urb->complete = hci_usb_rx_complete;
8110 - clear_bit(HCI_TX_CTRL, &husb->tx_state);
8112 + urb->transfer_buffer_length = size;
8113 + urb->transfer_buffer = buf;
8114 + urb->transfer_flags = USB_ISO_ASAP;
8116 + __fill_isoc_desc(urb, size, mtu);
8118 + BT_DBG("%s urb %p", husb->hdev.name, urb);
8120 + err = usb_submit_urb(urb);
8122 + BT_ERR("%s isoc rx submit failed urb %p err %d",
8123 + husb->hdev.name, urb, err);
8124 + _urb_unlink(_urb);
8132 -void hci_usb_write_wakeup(struct hci_usb *husb)
8133 +/* Initialize device */
8134 +static int hci_usb_open(struct hci_dev *hdev)
8136 - struct sk_buff *skb;
8137 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8139 + unsigned long flags;
8141 - if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
8143 + BT_DBG("%s", hdev->name);
8145 - DBG("%s", husb->hdev.name);
8146 + if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
8149 - if (!(skb = skb_dequeue(&husb->tx_write_q)))
8151 + MOD_INC_USE_COUNT;
8153 - if (hci_usb_write_msg(husb, skb)) {
8154 - skb_queue_head(&husb->tx_write_q, skb);
8156 + write_lock_irqsave(&husb->completion_lock, flags);
8158 + err = hci_usb_intr_rx_submit(husb);
8160 + for (i = 0; i < HCI_MAX_BULK_RX; i++)
8161 + hci_usb_bulk_rx_submit(husb);
8163 +#ifdef CONFIG_BLUEZ_USB_SCO
8164 + if (husb->isoc_iface)
8165 + for (i = 0; i < HCI_MAX_ISOC_RX; i++)
8166 + hci_usb_isoc_rx_submit(husb);
8169 + clear_bit(HCI_RUNNING, &hdev->flags);
8170 + MOD_DEC_USE_COUNT;
8173 - DMP(skb->data, skb->len);
8174 + write_unlock_irqrestore(&husb->completion_lock, flags);
8179 +static int hci_usb_flush(struct hci_dev *hdev)
8181 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8184 - husb->hdev.stat.byte_tx += skb->len;
8186 + BT_DBG("%s", hdev->name);
8189 - clear_bit(HCI_TX_WRITE, &husb->tx_state);
8191 + for (i=0; i < 4; i++)
8192 + skb_queue_purge(&husb->transmit_q[i]);
8196 -/* Send frames from HCI layer */
8197 -int hci_usb_send_frame(struct sk_buff *skb)
8198 +static void hci_usb_unlink_urbs(struct hci_usb *husb)
8200 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
8201 - struct hci_usb *husb;
8205 - ERR("frame for uknown device (hdev=NULL)");
8207 + BT_DBG("%s", husb->hdev.name);
8209 + for (i=0; i < 4; i++) {
8210 + struct _urb *_urb;
8213 + /* Kill pending requests */
8214 + while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
8216 + BT_DBG("%s unlinking _urb %p type %d urb %p",
8217 + husb->hdev.name, _urb, _urb->type, urb);
8218 + usb_unlink_urb(urb);
8219 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8222 + /* Release completed requests */
8223 + while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
8225 + BT_DBG("%s freeing _urb %p type %d urb %p",
8226 + husb->hdev.name, _urb, _urb->type, urb);
8227 + if (urb->setup_packet)
8228 + kfree(urb->setup_packet);
8229 + if (urb->transfer_buffer)
8230 + kfree(urb->transfer_buffer);
8234 + /* Release reassembly buffers */
8235 + if (husb->reassembly[i]) {
8236 + kfree_skb(husb->reassembly[i]);
8237 + husb->reassembly[i] = NULL;
8242 - if (!(hdev->flags & HCI_RUNNING))
8244 +static int hci_usb_close(struct hci_dev *hdev)
8246 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8247 + unsigned long flags;
8249 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
8252 - husb = (struct hci_usb *) hdev->driver_data;
8253 + BT_DBG("%s", hdev->name);
8255 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
8256 + write_lock_irqsave(&husb->completion_lock, flags);
8258 + hci_usb_unlink_urbs(husb);
8259 + hci_usb_flush(hdev);
8261 - switch (skb->pkt_type) {
8262 - case HCI_COMMAND_PKT:
8263 - skb_queue_tail(&husb->tx_ctrl_q, skb);
8264 - hci_usb_ctrl_wakeup(husb);
8265 - hdev->stat.cmd_tx++;
8268 - case HCI_ACLDATA_PKT:
8269 - skb_queue_tail(&husb->tx_write_q, skb);
8270 - hci_usb_write_wakeup(husb);
8271 - hdev->stat.acl_tx++;
8274 - case HCI_SCODATA_PKT:
8275 - return -EOPNOTSUPP;
8277 + write_unlock_irqrestore(&husb->completion_lock, flags);
8279 + MOD_DEC_USE_COUNT;
8283 -/* ---------- USB ------------- */
8285 -static void hci_usb_ctrl(struct urb *urb)
8286 +static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
8288 - struct sk_buff *skb = (struct sk_buff *) urb->context;
8289 - struct hci_dev *hdev;
8290 - struct hci_usb *husb;
8294 - hdev = (struct hci_dev *) skb->dev;
8295 - husb = (struct hci_usb *) hdev->driver_data;
8296 + struct urb *urb = &_urb->urb;
8299 - DBG("%s", hdev->name);
8300 + BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
8302 + _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
8303 + err = usb_submit_urb(urb);
8305 + BT_ERR("%s tx submit failed urb %p type %d err %d",
8306 + husb->hdev.name, urb, _urb->type, err);
8307 + _urb_unlink(_urb);
8308 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8310 + atomic_inc(__pending_tx(husb, _urb->type));
8315 +static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
8317 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8322 + _urb = _urb_alloc(0, GFP_ATOMIC);
8325 + _urb->type = skb->pkt_type;
8327 + dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
8333 + dr = (void *) _urb->urb.setup_packet;
8336 - DBG("%s ctrl status: %d", hdev->name, urb->status);
8337 + dr->requesttype = HCI_CTRL_REQ;
8341 + dr->length = __cpu_to_le16(skb->len);
8343 - clear_bit(HCI_TX_CTRL, &husb->tx_state);
8346 + FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
8347 + (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
8349 - /* Wake up device */
8350 - hci_usb_ctrl_wakeup(husb);
8351 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8354 + return __tx_submit(husb, _urb);
8357 -static void hci_usb_bulk_write(struct urb *urb)
8358 +static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
8360 - struct sk_buff *skb = (struct sk_buff *) urb->context;
8361 - struct hci_dev *hdev;
8362 - struct hci_usb *husb;
8366 - hdev = (struct hci_dev *) skb->dev;
8367 - husb = (struct hci_usb *) hdev->driver_data;
8368 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8372 - DBG("%s", hdev->name);
8375 - DBG("%s bulk write status: %d", hdev->name, urb->status);
8377 + _urb = _urb_alloc(0, GFP_ATOMIC);
8380 + _urb->type = skb->pkt_type;
8383 - clear_bit(HCI_TX_WRITE, &husb->tx_state);
8386 + pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
8387 + FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
8388 + hci_usb_tx_complete, husb);
8389 + urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
8391 - /* Wake up device */
8392 - hci_usb_write_wakeup(husb);
8393 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8397 + return __tx_submit(husb, _urb);
8400 -static void hci_usb_intr(struct urb *urb)
8401 +#ifdef CONFIG_BLUEZ_USB_SCO
8402 +static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
8404 - struct hci_usb *husb = (struct hci_usb *) urb->context;
8405 - unsigned char *data = urb->transfer_buffer;
8406 - register int count = urb->actual_length;
8407 - register struct sk_buff *skb = husb->intr_skb;
8408 - hci_event_hdr *eh;
8410 + struct _urb *_urb = __get_completed(husb, skb->pkt_type);
8414 + _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
8417 + _urb->type = skb->pkt_type;
8422 + BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
8424 - DBG("%s count %d", husb->hdev.name, count);
8427 + urb->context = husb;
8428 + urb->dev = husb->udev;
8429 + urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
8430 + urb->complete = hci_usb_tx_complete;
8431 + urb->transfer_flags = USB_ISO_ASAP;
8433 - if (urb->status || !count) {
8434 - DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
8437 + urb->transfer_buffer = skb->data;
8438 + urb->transfer_buffer_length = skb->len;
8440 + __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
8442 - /* Do we really have to handle continuations here ? */
8445 - if (count < HCI_EVENT_HDR_SIZE) {
8446 - DBG("%s bad frame len %d", husb->hdev.name, count);
8450 + return __tx_submit(husb, _urb);
8454 +static void hci_usb_tx_process(struct hci_usb *husb)
8456 + struct sk_buff_head *q;
8457 + struct sk_buff *skb;
8459 - eh = (hci_event_hdr *) data;
8460 - len = eh->plen + HCI_EVENT_HDR_SIZE;
8461 + BT_DBG("%s", husb->hdev.name);
8463 - if (count > len) {
8464 - DBG("%s corrupted frame, len %d", husb->hdev.name, count);
8467 + clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
8469 + /* Process command queue */
8470 + q = __transmit_q(husb, HCI_COMMAND_PKT);
8471 + if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
8472 + (skb = skb_dequeue(q))) {
8473 + if (hci_usb_send_ctrl(husb, skb) < 0)
8474 + skb_queue_head(q, skb);
8477 - /* Allocate skb */
8478 - if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
8479 - ERR("Can't allocate mem for new packet");
8481 +#ifdef CONFIG_BLUEZ_USB_SCO
8482 + /* Process SCO queue */
8483 + q = __transmit_q(husb, HCI_SCODATA_PKT);
8484 + if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
8485 + (skb = skb_dequeue(q))) {
8486 + if (hci_usb_send_isoc(husb, skb) < 0)
8487 + skb_queue_head(q, skb);
8491 + /* Process ACL queue */
8492 + q = __transmit_q(husb, HCI_ACLDATA_PKT);
8493 + while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
8494 + (skb = skb_dequeue(q))) {
8495 + if (hci_usb_send_bulk(husb, skb) < 0) {
8496 + skb_queue_head(q, skb);
8500 - skb->dev = (void *) &husb->hdev;
8501 - skb->pkt_type = HCI_EVENT_PKT;
8502 + } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
8505 - husb->intr_skb = skb;
8506 - husb->intr_count = len;
8508 - /* Continuation */
8509 - if (count > husb->intr_count) {
8510 - ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
8511 +static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
8513 + /* Serialize TX queue processing to avoid data reordering */
8514 + if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
8515 + hci_usb_tx_process(husb);
8516 + clear_bit(HCI_USB_TX_PROCESS, &husb->state);
8518 + set_bit(HCI_USB_TX_WAKEUP, &husb->state);
8522 - husb->intr_skb = NULL;
8523 - husb->intr_count = 0;
8526 +/* Send frames from HCI layer */
8527 +static int hci_usb_send_frame(struct sk_buff *skb)
8529 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
8530 + struct hci_usb *husb;
8533 + BT_ERR("frame for uknown device (hdev=NULL)");
8537 - memcpy(skb_put(skb, count), data, count);
8538 - husb->intr_count -= count;
8539 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8543 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
8545 - if (!husb->intr_count) {
8546 - /* Got complete frame */
8547 + husb = (struct hci_usb *) hdev->driver_data;
8549 - husb->hdev.stat.byte_rx += skb->len;
8550 - hci_recv_frame(skb);
8551 + switch (skb->pkt_type) {
8552 + case HCI_COMMAND_PKT:
8553 + hdev->stat.cmd_tx++;
8556 + case HCI_ACLDATA_PKT:
8557 + hdev->stat.acl_tx++;
8560 +#ifdef CONFIG_BLUEZ_USB_SCO
8561 + case HCI_SCODATA_PKT:
8562 + hdev->stat.sco_tx++;
8566 - husb->intr_skb = NULL;
8572 + read_lock(&husb->completion_lock);
8574 + skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
8575 + hci_usb_tx_wakeup(husb);
8577 + read_unlock(&husb->completion_lock);
8581 -static void hci_usb_bulk_read(struct urb *urb)
8582 +static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
8584 - struct hci_usb *husb = (struct hci_usb *) urb->context;
8585 - unsigned char *data = urb->transfer_buffer;
8586 - int count = urb->actual_length, status;
8587 - struct sk_buff *skb;
8589 - register __u16 dlen;
8593 + BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
8595 - DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
8596 + husb->hdev.stat.byte_rx += count;
8598 - if (urb->status) {
8599 - /* Do not re-submit URB on critical errors */
8600 - switch (urb->status) {
8610 + struct sk_buff *skb = __reassembly(husb, type);
8611 + struct { int expect; } *scb;
8615 + /* Start of the frame */
8618 + case HCI_EVENT_PKT:
8619 + if (count >= HCI_EVENT_HDR_SIZE) {
8620 + hci_event_hdr *h = data;
8621 + len = HCI_EVENT_HDR_SIZE + h->plen;
8627 + case HCI_ACLDATA_PKT:
8628 + if (count >= HCI_ACL_HDR_SIZE) {
8629 + hci_acl_hdr *h = data;
8630 + len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
8634 +#ifdef CONFIG_BLUEZ_USB_SCO
8635 + case HCI_SCODATA_PKT:
8636 + if (count >= HCI_SCO_HDR_SIZE) {
8637 + hci_sco_hdr *h = data;
8638 + len = HCI_SCO_HDR_SIZE + h->dlen;
8644 + BT_DBG("new packet len %d", len);
8646 + skb = bluez_skb_alloc(len, GFP_ATOMIC);
8648 + BT_ERR("%s no memory for the packet", husb->hdev.name);
8651 + skb->dev = (void *) &husb->hdev;
8652 + skb->pkt_type = type;
8654 + __reassembly(husb, type) = skb;
8656 + scb = (void *) skb->cb;
8657 + scb->expect = len;
8659 + /* Continuation */
8660 + scb = (void *) skb->cb;
8661 + len = scb->expect;
8664 - ah = (hci_acl_hdr *) data;
8665 - dlen = le16_to_cpu(ah->dlen);
8666 + len = min(len, count);
8668 + memcpy(skb_put(skb, len), data, len);
8670 + scb->expect -= len;
8671 + if (!scb->expect) {
8672 + /* Complete frame */
8673 + __reassembly(husb, type) = NULL;
8674 + hci_recv_frame(skb);
8677 - /* Verify frame len and completeness */
8678 - if ((count - HCI_ACL_HDR_SIZE) != dlen) {
8679 - ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
8681 + count -= len; data += len;
8686 - /* Allocate packet */
8687 - if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
8688 - ERR("Can't allocate mem for new packet");
8691 +static void hci_usb_rx_complete(struct urb *urb)
8693 + struct _urb *_urb = container_of(urb, struct _urb, urb);
8694 + struct hci_usb *husb = (void *) urb->context;
8695 + struct hci_dev *hdev = &husb->hdev;
8696 + int err, count = urb->actual_length;
8698 - memcpy(skb_put(skb, count), data, count);
8699 - skb->dev = (void *) &husb->hdev;
8700 - skb->pkt_type = HCI_ACLDATA_PKT;
8701 + BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
8702 + _urb->type, urb->status, count, urb->transfer_flags);
8704 - husb->hdev.stat.byte_rx += skb->len;
8705 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8708 - hci_recv_frame(skb);
8709 + read_lock(&husb->completion_lock);
8712 - husb->read_urb->dev = husb->udev;
8713 - if ((status = usb_submit_urb(husb->read_urb)))
8714 - DBG("%s read URB submit failed %d", husb->hdev.name, status);
8715 + if (urb->status || !count)
8718 + if (_urb->type == HCI_SCODATA_PKT) {
8719 +#ifdef CONFIG_BLUEZ_USB_SCO
8721 + for (i=0; i < urb->number_of_packets; i++) {
8722 + BT_DBG("desc %d status %d offset %d len %d", i,
8723 + urb->iso_frame_desc[i].status,
8724 + urb->iso_frame_desc[i].offset,
8725 + urb->iso_frame_desc[i].actual_length);
8727 + if (!urb->iso_frame_desc[i].status)
8728 + __recv_frame(husb, _urb->type,
8729 + urb->transfer_buffer + urb->iso_frame_desc[i].offset,
8730 + urb->iso_frame_desc[i].actual_length);
8736 + err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
8738 + BT_ERR("%s corrupted packet: type %d count %d",
8739 + husb->hdev.name, _urb->type, count);
8740 + hdev->stat.err_rx++;
8744 - DBG("%s read URB re-submited", husb->hdev.name);
8746 + if (_urb->type != HCI_EVENT_PKT) {
8747 + urb->dev = husb->udev;
8748 + err = usb_submit_urb(urb);
8749 + BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
8752 + read_unlock(&husb->completion_lock);
8755 -static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
8756 +static void hci_usb_tx_complete(struct urb *urb)
8758 - struct urb *urb = husb->ctrl_urb;
8759 - devrequest *dr = &husb->dev_req;
8761 + struct _urb *_urb = container_of(urb, struct _urb, urb);
8762 + struct hci_usb *husb = (void *) urb->context;
8763 + struct hci_dev *hdev = &husb->hdev;
8765 - DBG("%s len %d", husb->hdev.name, skb->len);
8766 + BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
8767 + urb->status, urb->transfer_flags);
8769 - pipe = usb_sndctrlpipe(husb->udev, 0);
8770 + atomic_dec(__pending_tx(husb, _urb->type));
8772 - dr->requesttype = HCI_CTRL_REQ;
8776 - dr->length = cpu_to_le16(skb->len);
8777 + urb->transfer_buffer = NULL;
8778 + kfree_skb((struct sk_buff *) _urb->priv);
8780 - FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
8781 - hci_usb_ctrl, skb);
8783 - if ((status = usb_submit_urb(urb))) {
8784 - DBG("%s control URB submit failed %d", husb->hdev.name, status);
8787 + if (!test_bit(HCI_RUNNING, &hdev->flags))
8793 + hdev->stat.byte_tx += urb->transfer_buffer_length;
8795 + hdev->stat.err_tx++;
8797 -static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
8799 - struct urb *urb = husb->write_urb;
8801 + read_lock(&husb->completion_lock);
8803 - DBG("%s len %d", husb->hdev.name, skb->len);
8804 + _urb_unlink(_urb);
8805 + _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
8807 - pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
8808 + hci_usb_tx_wakeup(husb);
8810 + read_unlock(&husb->completion_lock);
8813 - FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
8814 - hci_usb_bulk_write, skb);
8815 - urb->transfer_flags |= USB_QUEUE_BULK;
8816 +static void hci_usb_destruct(struct hci_dev *hdev)
8818 + struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
8820 - if ((status = usb_submit_urb(urb))) {
8821 - DBG("%s write URB submit failed %d", husb->hdev.name, status);
8824 + BT_DBG("%s", hdev->name);
8830 -static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
8831 +static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
8833 - struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
8834 + struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
8835 + struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
8836 + struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
8837 + struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
8838 + struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
8839 struct usb_interface_descriptor *uif;
8840 struct usb_endpoint_descriptor *ep;
8841 + struct usb_interface *iface, *isoc_iface;
8842 struct hci_usb *husb;
8843 struct hci_dev *hdev;
8844 - int i, size, pipe;
8846 + int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
8848 - DBG("udev %p ifnum %d", udev, ifnum);
8850 - /* Check device signature */
8851 - if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
8852 - (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
8853 - (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
8856 - MOD_INC_USE_COUNT;
8857 + BT_DBG("udev %p ifnum %d", udev, ifnum);
8859 - uif = &udev->actconfig->interface[ifnum].altsetting[0];
8860 + iface = &udev->actconfig->interface[0];
8862 - if (uif->bNumEndpoints != 3) {
8863 - DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
8864 - MOD_DEC_USE_COUNT;
8865 + /* Check our black list */
8866 + if (usb_match_id(udev, iface, ignore_ids))
8870 - bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
8871 + /* Check number of endpoints */
8872 + if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
8875 + memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
8876 + memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
8877 + memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
8878 + memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
8879 + memset(intr_in_ep, 0, sizeof(intr_in_ep));
8882 + isoc_iface = NULL;
8883 + isoc_alts = isoc_ifnum = 0;
8885 /* Find endpoints that we need */
8886 - for ( i = 0; i < uif->bNumEndpoints; ++i) {
8887 - ep = &uif->endpoint[i];
8889 - switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
8890 - case USB_ENDPOINT_XFER_BULK:
8891 - if (ep->bEndpointAddress & USB_DIR_IN)
8896 + ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
8897 + for (i = 0; i < ifn; i++) {
8898 + iface = &udev->actconfig->interface[i];
8899 + for (a = 0; a < iface->num_altsetting; a++) {
8900 + uif = &iface->altsetting[a];
8901 + for (e = 0; e < uif->bNumEndpoints; e++) {
8902 + ep = &uif->endpoint[e];
8904 + switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
8905 + case USB_ENDPOINT_XFER_INT:
8906 + if (ep->bEndpointAddress & USB_DIR_IN)
8907 + intr_in_ep[i] = ep;
8910 + case USB_ENDPOINT_XFER_BULK:
8911 + if (ep->bEndpointAddress & USB_DIR_IN)
8912 + bulk_in_ep[i] = ep;
8914 + bulk_out_ep[i] = ep;
8917 +#ifdef CONFIG_BLUEZ_USB_SCO
8918 + case USB_ENDPOINT_XFER_ISOC:
8919 + if (ep->wMaxPacketSize < size || a > 2)
8921 + size = ep->wMaxPacketSize;
8923 + isoc_iface = iface;
8927 + if (ep->bEndpointAddress & USB_DIR_IN)
8928 + isoc_in_ep[i] = ep;
8930 + isoc_out_ep[i] = ep;
8938 - case USB_ENDPOINT_XFER_INT:
8942 + if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
8943 + BT_DBG("Bulk endpoints not found");
8947 - if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
8948 - DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
8949 - MOD_DEC_USE_COUNT;
8951 +#ifdef CONFIG_BLUEZ_USB_SCO
8952 + if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
8953 + BT_DBG("Isoc endpoints not found");
8954 + isoc_iface = NULL;
8958 if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
8959 - ERR("Can't allocate: control structure");
8960 - MOD_DEC_USE_COUNT;
8962 + BT_ERR("Can't allocate: control structure");
8966 memset(husb, 0, sizeof(struct hci_usb));
8969 - husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
8971 - if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
8972 - ERR("Can't allocate: control URB");
8976 - if (!(husb->write_urb = usb_alloc_urb(0))) {
8977 - ERR("Can't allocate: write URB");
8981 - if (!(husb->read_urb = usb_alloc_urb(0))) {
8982 - ERR("Can't allocate: read URB");
8987 - pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
8988 - size = HCI_MAX_FRAME_SIZE;
8990 - if (!(buf = kmalloc(size, GFP_KERNEL))) {
8991 - ERR("Can't allocate: read buffer");
8995 - FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
8996 - husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
8999 - pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
9000 - size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
9002 - if (!(husb->intr_urb = usb_alloc_urb(0))) {
9003 - ERR("Can't allocate: interrupt URB");
9005 + husb->bulk_out_ep = bulk_out_ep[0];
9006 + husb->bulk_in_ep = bulk_in_ep[0];
9007 + husb->intr_in_ep = intr_in_ep[0];
9009 +#ifdef CONFIG_BLUEZ_USB_SCO
9011 + BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
9012 + if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
9013 + BT_ERR("Can't set isoc interface settings");
9014 + isoc_iface = NULL;
9016 + usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
9017 + husb->isoc_iface = isoc_iface;
9018 + husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
9019 + husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
9023 + husb->completion_lock = RW_LOCK_UNLOCKED;
9025 - if (!(buf = kmalloc(size, GFP_KERNEL))) {
9026 - ERR("Can't allocate: interrupt buffer");
9028 + for (i = 0; i < 4; i++) {
9029 + skb_queue_head_init(&husb->transmit_q[i]);
9030 + _urb_queue_init(&husb->pending_q[i]);
9031 + _urb_queue_init(&husb->completed_q[i]);
9034 - FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
9036 - skb_queue_head_init(&husb->tx_ctrl_q);
9037 - skb_queue_head_init(&husb->tx_write_q);
9039 /* Initialize and register HCI device */
9042 - hdev->type = HCI_USB;
9043 + hdev->type = HCI_USB;
9044 hdev->driver_data = husb;
9046 hdev->open = hci_usb_open;
9047 hdev->close = hci_usb_close;
9048 hdev->flush = hci_usb_flush;
9049 - hdev->send = hci_usb_send_frame;
9050 + hdev->send = hci_usb_send_frame;
9051 + hdev->destruct = hci_usb_destruct;
9053 if (hci_register_dev(hdev) < 0) {
9054 - ERR("Can't register HCI device %s", hdev->name);
9055 + BT_ERR("Can't register HCI device");
9062 - hci_usb_free_bufs(husb);
9064 - MOD_DEC_USE_COUNT;
9070 @@ -626,38 +930,34 @@
9074 - DBG("%s", hdev->name);
9075 + BT_DBG("%s", hdev->name);
9077 hci_usb_close(hdev);
9079 - if (hci_unregister_dev(hdev) < 0) {
9080 - ERR("Can't unregister HCI device %s", hdev->name);
9082 + if (husb->isoc_iface)
9083 + usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
9085 - hci_usb_free_bufs(husb);
9088 - MOD_DEC_USE_COUNT;
9089 + if (hci_unregister_dev(hdev) < 0)
9090 + BT_ERR("Can't unregister HCI device %s", hdev->name);
9093 -static struct usb_driver hci_usb_driver =
9095 +static struct usb_driver hci_usb_driver = {
9097 probe: hci_usb_probe,
9098 disconnect: hci_usb_disconnect,
9099 - id_table: usb_bluetooth_ids,
9100 + id_table: bluetooth_ids,
9103 int hci_usb_init(void)
9107 - INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9108 + BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9110 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9111 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9113 if ((err = usb_register(&hci_usb_driver)) < 0)
9114 - ERR("Failed to register HCI USB driver");
9115 + BT_ERR("Failed to register HCI USB driver");
9119 diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.h linux-2.4.18-mh9/drivers/bluetooth/hci_usb.h
9120 --- linux-2.4.18/drivers/bluetooth/hci_usb.h Thu Jan 1 01:00:00 1970
9121 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_usb.h Mon Aug 25 18:38:12 2003
9124 + HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
9125 + Copyright (C) 2000-2001 Qualcomm Incorporated
9126 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9128 + Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
9130 + This program is free software; you can redistribute it and/or modify
9131 + it under the terms of the GNU General Public License version 2 as
9132 + published by the Free Software Foundation;
9134 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9135 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9136 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
9137 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
9138 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
9139 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9140 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9141 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9143 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
9144 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
9145 + SOFTWARE IS DISCLAIMED.
9149 + * $Id: hci_usb.h,v 1.2 2002/03/18 19:10:04 maxk Exp $
9154 +/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
9155 +#define HCI_DEV_CLASS 0xe0 /* Wireless class */
9156 +#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
9157 +#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
9159 +#define HCI_CTRL_REQ 0x20
9161 +#define HCI_MAX_IFACE_NUM 3
9163 +#define HCI_MAX_BULK_TX 4
9164 +#define HCI_MAX_BULK_RX 1
9166 +#define HCI_MAX_ISOC_RX 2
9167 +#define HCI_MAX_ISOC_TX 2
9169 +#define HCI_MAX_ISOC_FRAMES 10
9171 +struct _urb_queue {
9172 + struct list_head head;
9177 + struct list_head list;
9178 + struct _urb_queue *queue;
9184 +struct _urb *_urb_alloc(int isoc, int gfp);
9186 +static inline void _urb_free(struct _urb *_urb)
9191 +static inline void _urb_queue_init(struct _urb_queue *q)
9193 + INIT_LIST_HEAD(&q->head);
9194 + spin_lock_init(&q->lock);
9197 +static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
9199 + unsigned long flags;
9200 + spin_lock_irqsave(&q->lock, flags);
9201 + list_add(&_urb->list, &q->head); _urb->queue = q;
9202 + spin_unlock_irqrestore(&q->lock, flags);
9205 +static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
9207 + unsigned long flags;
9208 + spin_lock_irqsave(&q->lock, flags);
9209 + list_add_tail(&_urb->list, &q->head); _urb->queue = q;
9210 + spin_unlock_irqrestore(&q->lock, flags);
9213 +static inline void _urb_unlink(struct _urb *_urb)
9215 + struct _urb_queue *q = _urb->queue;
9216 + unsigned long flags;
9218 + spin_lock_irqsave(&q->lock, flags);
9219 + list_del(&_urb->list); _urb->queue = NULL;
9220 + spin_unlock_irqrestore(&q->lock, flags);
9224 +struct _urb *_urb_dequeue(struct _urb_queue *q);
9226 +#ifndef container_of
9227 +#define container_of(ptr, type, member) ({ \
9228 + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
9229 + (type *)( (char *)__mptr - offsetof(type,member) );})
9233 + struct hci_dev hdev;
9235 + unsigned long state;
9237 + struct usb_device *udev;
9239 + struct usb_endpoint_descriptor *bulk_in_ep;
9240 + struct usb_endpoint_descriptor *bulk_out_ep;
9241 + struct usb_endpoint_descriptor *intr_in_ep;
9243 + struct usb_interface *isoc_iface;
9244 + struct usb_endpoint_descriptor *isoc_out_ep;
9245 + struct usb_endpoint_descriptor *isoc_in_ep;
9247 + struct sk_buff_head transmit_q[4];
9248 + struct sk_buff *reassembly[4]; // Reassembly buffers
9250 + rwlock_t completion_lock;
9252 + atomic_t pending_tx[4]; // Number of pending requests
9253 + struct _urb_queue pending_q[4]; // Pending requests
9254 + struct _urb_queue completed_q[4]; // Completed requests
9258 +#define HCI_USB_TX_PROCESS 1
9259 +#define HCI_USB_TX_WAKEUP 2
9261 +#endif /* __KERNEL__ */
9262 diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.c linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.c
9263 --- linux-2.4.18/drivers/bluetooth/hci_vhci.c Fri Sep 7 18:28:38 2001
9264 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.c Mon Aug 25 18:38:10 2003
9267 * BlueZ HCI virtual device driver.
9269 - * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $
9270 + * $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $
9272 -#define VERSION "1.0"
9273 +#define VERSION "1.1"
9275 #include <linux/config.h>
9276 #include <linux/module.h>
9278 #include <asm/uaccess.h>
9280 #include <net/bluetooth/bluetooth.h>
9281 -#include <net/bluetooth/bluez.h>
9282 #include <net/bluetooth/hci_core.h>
9283 -#include <net/bluetooth/hci_vhci.h>
9284 +#include "hci_vhci.h"
9286 /* HCI device part */
9288 -int hci_vhci_open(struct hci_dev *hdev)
9289 +static int hci_vhci_open(struct hci_dev *hdev)
9291 - hdev->flags |= HCI_RUNNING;
9292 + set_bit(HCI_RUNNING, &hdev->flags);
9296 -int hci_vhci_flush(struct hci_dev *hdev)
9297 +static int hci_vhci_flush(struct hci_dev *hdev)
9299 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
9300 skb_queue_purge(&hci_vhci->readq);
9304 -int hci_vhci_close(struct hci_dev *hdev)
9305 +static int hci_vhci_close(struct hci_dev *hdev)
9307 - hdev->flags &= ~HCI_RUNNING;
9308 + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
9311 hci_vhci_flush(hdev);
9315 -int hci_vhci_send_frame(struct sk_buff *skb)
9316 +static void hci_vhci_destruct(struct hci_dev *hdev)
9318 + struct hci_vhci_struct *vhci;
9320 + if (!hdev) return;
9322 + vhci = (struct hci_vhci_struct *) hdev->driver_data;
9325 + MOD_DEC_USE_COUNT;
9328 +static int hci_vhci_send_frame(struct sk_buff *skb)
9330 struct hci_dev* hdev = (struct hci_dev *) skb->dev;
9331 struct hci_vhci_struct *hci_vhci;
9334 - ERR("Frame for uknown device (hdev=NULL)");
9335 + BT_ERR("Frame for uknown device (hdev=NULL)");
9339 - if (!(hdev->flags & HCI_RUNNING))
9340 + if (!test_bit(HCI_RUNNING, &hdev->flags))
9343 hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
9346 add_wait_queue(&hci_vhci->read_wait, &wait);
9348 - current->state = TASK_INTERRUPTIBLE;
9349 + set_current_state(TASK_INTERRUPTIBLE);
9351 /* Read frames from device queue */
9352 if (!(skb = skb_dequeue(&hci_vhci->readq))) {
9358 - current->state = TASK_RUNNING;
9359 + set_current_state(TASK_RUNNING);
9360 remove_wait_queue(&hci_vhci->read_wait, &wait);
9363 @@ -270,11 +282,13 @@
9364 hdev->close = hci_vhci_close;
9365 hdev->flush = hci_vhci_flush;
9366 hdev->send = hci_vhci_send_frame;
9367 + hdev->destruct = hci_vhci_destruct;
9369 if (hci_register_dev(hdev) < 0) {
9373 + MOD_INC_USE_COUNT;
9375 file->private_data = hci_vhci;
9377 @@ -285,12 +299,10 @@
9378 struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
9380 if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
9381 - ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
9382 + BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
9386 file->private_data = NULL;
9391 @@ -315,12 +327,12 @@
9393 int __init hci_vhci_init(void)
9395 - INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9396 + BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
9398 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9399 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
9401 if (misc_register(&hci_vhci_miscdev)) {
9402 - ERR("Can't register misc device %d\n", VHCI_MINOR);
9403 + BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
9409 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
9410 MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
9411 -MODULE_LICENSE("GPL");
9412 +MODULE_LICENSE("GPL");
9413 diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.h linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.h
9414 --- linux-2.4.18/drivers/bluetooth/hci_vhci.h Thu Jan 1 01:00:00 1970
9415 +++ linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.h Mon Aug 25 18:38:10 2003
9418 + BlueZ - Bluetooth protocol stack for Linux
9419 + Copyright (C) 2000-2001 Qualcomm Incorporated
9421 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
9423 + This program is free software; you can redistribute it and/or modify
9424 + it under the terms of the GNU General Public License version 2 as
9425 + published by the Free Software Foundation;
9427 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9428 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9429 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
9430 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
9431 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
9432 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9433 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9434 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9436 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
9437 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
9438 + SOFTWARE IS DISCLAIMED.
9442 + * $Id: hci_vhci.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
9445 +#ifndef __HCI_VHCI_H
9446 +#define __HCI_VHCI_H
9450 +struct hci_vhci_struct {
9451 + struct hci_dev hdev;
9453 + wait_queue_head_t read_wait;
9454 + struct sk_buff_head readq;
9455 + struct fasync_struct *fasync;
9458 +/* VHCI device flags */
9459 +#define VHCI_FASYNC 0x0010
9461 +#endif /* __KERNEL__ */
9463 +#define VHCI_DEV "/dev/vhci"
9464 +#define VHCI_MINOR 250
9466 +#endif /* __HCI_VHCI_H */
9467 diff -urN linux-2.4.18/drivers/char/pcmcia/serial_cs.c linux-2.4.18-mh9/drivers/char/pcmcia/serial_cs.c
9468 --- linux-2.4.18/drivers/char/pcmcia/serial_cs.c Fri Dec 21 18:41:54 2001
9469 +++ linux-2.4.18-mh9/drivers/char/pcmcia/serial_cs.c Mon Aug 25 18:38:10 2003
9472 A driver for PCMCIA serial devices
9474 - serial_cs.c 1.128 2001/10/18 12:18:35
9475 + serial_cs.c 1.138 2002/10/25 06:24:52
9477 The contents of this file are subject to the Mozilla Public
9478 License Version 1.1 (the "License"); you may not use this file
9480 and other provisions required by the GPL. If you do not delete
9481 the provisions above, a recipient may use your version of this
9482 file under either the MPL or the GPL.
9485 ======================================================================*/
9487 #include <linux/module.h>
9489 static int irq_list[4] = { -1 };
9490 MODULE_PARM(irq_list, "1-4i");
9492 -/* Enable the speaker? */
9493 -INT_MODULE_PARM(do_sound, 1);
9494 +INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
9495 +INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
9498 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
9499 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
9500 static char *version =
9501 -"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
9502 +"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
9504 #define DEBUG(n, args...)
9507 { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
9508 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
9509 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
9510 + { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
9511 { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
9512 { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
9513 { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
9515 client_reg_t client_reg;
9520 DEBUG(0, "serial_attach()\n");
9522 /* Create new serial device */
9524 link->release.function = &serial_release;
9525 link->release.data = (u_long)link;
9526 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
9527 - link->io.NumPorts1 = 8;
9528 + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
9529 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
9530 link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
9531 if (irq_list[0] == -1)
9532 @@ -169,13 +170,12 @@
9533 for (i = 0; i < 4; i++)
9534 link->irq.IRQInfo2 |= 1 << irq_list[i];
9535 link->conf.Attributes = CONF_ENABLE_IRQ;
9536 - link->conf.Vcc = 50;
9538 link->conf.Attributes |= CONF_ENABLE_SPKR;
9539 link->conf.Status = CCSR_AUDIO_ENA;
9541 link->conf.IntType = INT_MEMORY_AND_IO;
9544 /* Register with Card Services */
9545 link->next = dev_list;
9548 serial_detach(link);
9554 } /* serial_attach */
9559 DEBUG(0, "serial_detach(0x%p)\n", link);
9562 /* Locate device structure */
9563 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
9564 if (*linkp == link) break;
9565 @@ -224,17 +224,17 @@
9566 del_timer(&link->release);
9567 if (link->state & DEV_CONFIG)
9568 serial_release((u_long)link);
9572 ret = CardServices(DeregisterClient, link->handle);
9573 if (ret != CS_SUCCESS)
9574 cs_error(link->handle, DeregisterClient, ret);
9578 /* Unlink device structure, free bits */
9579 *linkp = link->next;
9583 } /* serial_detach */
9585 /*====================================================================*/
9586 @@ -243,18 +243,20 @@
9588 struct serial_struct serial;
9592 memset(&serial, 0, sizeof(serial));
9595 serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
9597 + serial.flags |= ASYNC_BUGGY_UART;
9598 line = register_serial(&serial);
9600 printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
9601 " irq %d failed\n", (u_long)serial.port, serial.irq);
9606 info->line[info->ndev] = line;
9607 sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
9608 info->node[info->ndev].major = TTY_MAJOR;
9611 info->node[info->ndev-1].next = &info->node[info->ndev];
9618 @@ -313,7 +315,10 @@
9619 return setup_serial(info, port, config.AssignedIRQ);
9621 link->conf.Vcc = config.Vcc;
9624 + link->io.NumPorts1 = 8;
9625 + link->io.NumPorts2 = 0;
9627 /* First pass: look for a config entry that looks normal. */
9628 tuple.TupleData = (cisdata_t *)buf;
9629 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
9631 i = next_tuple(handle, &tuple, &parse);
9636 /* Second pass: try to find an entry that isn't picky about
9637 its base address, then try to grab any standard serial port
9638 address, and finally try to get any free port. */
9640 for (j = 0; j < 5; j++) {
9641 link->io.BasePort1 = base[j];
9642 link->io.IOAddrLines = base[j] ? 16 : 3;
9643 - i = CardServices(RequestIO, link->handle,
9645 + i = CardServices(RequestIO, link->handle, &link->io);
9646 if (i == CS_SUCCESS) goto found_port;
9650 cs_error(link->handle, RequestIO, i);
9655 i = CardServices(RequestIRQ, link->handle, &link->irq);
9656 if (i != CS_SUCCESS) {
9657 cs_error(link->handle, RequestIRQ, i);
9658 @@ -390,8 +394,12 @@
9661 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
9662 + config_info_t config;
9665 + CardServices(GetConfigurationInfo, handle, &config);
9666 + link->conf.Vcc = config.Vcc;
9668 tuple.TupleData = (cisdata_t *)buf;
9669 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
9670 tuple.Attributes = 0;
9671 @@ -433,12 +441,12 @@
9672 i = next_tuple(handle, &tuple, &parse);
9677 if (i != CS_SUCCESS) {
9678 - cs_error(link->handle, RequestIO, i);
9680 + /* At worst, try to configure as a single port */
9681 + return simple_config(link);
9685 i = CardServices(RequestIRQ, link->handle, &link->irq);
9686 if (i != CS_SUCCESS) {
9687 cs_error(link->handle, RequestIRQ, i);
9688 @@ -454,14 +462,27 @@
9689 cs_error(link->handle, RequestConfiguration, i);
9694 + /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
9695 + 8 registers are for the UART, the others are extra registers */
9696 + if (info->manfid == MANFID_OXSEMI) {
9697 + if (cf->index == 1 || cf->index == 3) {
9698 + setup_serial(info, base2, link->irq.AssignedIRQ);
9699 + outb(12,link->io.BasePort1+1);
9701 + setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
9707 setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
9708 /* The Nokia cards are not really multiport cards */
9709 if (info->manfid == MANFID_NOKIA)
9711 for (i = 0; i < info->multi-1; i++)
9712 setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
9719 int i, last_ret, last_fn;
9721 DEBUG(0, "serial_config(0x%p)\n", link);
9724 tuple.TupleData = (cisdata_t *)buf;
9725 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
9726 tuple.Attributes = 0;
9729 link->conf.ConfigBase = parse.config.base;
9730 link->conf.Present = parse.config.rmask[0];
9733 /* Configure card */
9734 link->state |= DEV_CONFIG;
9737 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
9738 tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
9739 info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
9741 - /* Is this a multiport card? */
9743 + /* Scan list of known multiport card ID's */
9744 tuple.DesiredTuple = CISTPL_MANFID;
9745 if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
9746 info->manfid = le16_to_cpu(buf[0]);
9747 @@ -537,15 +558,15 @@
9753 if (info->multi > 1)
9756 simple_config(link);
9759 if (info->ndev == 0)
9763 if (info->manfid == MANFID_IBM) {
9764 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
9765 CS_CHECK(AccessConfigurationRegister, link->handle, ®);
9767 cs_error(link->handle, last_fn, last_ret);
9769 serial_release((u_long)link);
9770 + link->state &= ~DEV_CONFIG_PENDING;
9772 } /* serial_config */
9776 After a card is removed, serial_release() will unregister the net
9777 device, and release the PCMCIA configuration.
9780 ======================================================================*/
9782 void serial_release(u_long arg)
9784 dev_link_t *link = (dev_link_t *)arg;
9785 serial_info_t *info = link->priv;
9789 DEBUG(0, "serial_release(0x%p)\n", link);
9791 for (i = 0; i < info->ndev; i++) {
9793 CardServices(ReleaseIO, link->handle, &link->io);
9794 CardServices(ReleaseIRQ, link->handle, &link->irq);
9798 link->state &= ~DEV_CONFIG;
9800 } /* serial_release */
9802 stuff to run after an event is received. A CARD_REMOVAL event
9803 also sets some flags to discourage the serial drivers from
9804 talking to the ports.
9807 ======================================================================*/
9809 static int serial_event(event_t event, int priority,
9812 dev_link_t *link = args->client_data;
9813 serial_info_t *info = link->priv;
9816 DEBUG(1, "serial_event(0x%06x)\n", event);
9820 case CS_EVENT_CARD_REMOVAL:
9821 link->state &= ~DEV_PRESENT;
9823 if (serv.Revision != CS_RELEASE_CODE) {
9824 printk(KERN_NOTICE "serial_cs: Card Services release "
9825 "does not match!\n");
9829 register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
9831 diff -urN linux-2.4.18/drivers/usb/Config.in linux-2.4.18-mh9/drivers/usb/Config.in
9832 --- linux-2.4.18/drivers/usb/Config.in Mon Feb 25 20:38:07 2002
9833 +++ linux-2.4.18-mh9/drivers/usb/Config.in Mon Aug 25 18:38:10 2003
9836 comment 'USB Device Class drivers'
9837 dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
9838 -dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
9839 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
9840 + if [ "$CONFIG_BLUEZ" = "n" ]; then
9841 + dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
9843 + comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
9846 if [ "$CONFIG_SCSI" = "n" ]; then
9847 comment ' SCSI support is needed for USB Storage'
9849 diff -urN linux-2.4.18/include/linux/firmware.h linux-2.4.18-mh9/include/linux/firmware.h
9850 --- linux-2.4.18/include/linux/firmware.h Thu Jan 1 01:00:00 1970
9851 +++ linux-2.4.18-mh9/include/linux/firmware.h Mon Aug 25 18:38:10 2003
9853 +#ifndef _LINUX_FIRMWARE_H
9854 +#define _LINUX_FIRMWARE_H
9855 +#include <linux/module.h>
9856 +#include <linux/types.h>
9857 +#define FIRMWARE_NAME_MAX 30
9862 +int request_firmware (const struct firmware **fw, const char *name,
9863 + const char *device);
9864 +int request_firmware_nowait (
9865 + struct module *module,
9866 + const char *name, const char *device, void *context,
9867 + void (*cont)(const struct firmware *fw, void *context));
9868 +/* On 2.5 'device' is 'struct device *' */
9870 +void release_firmware (const struct firmware *fw);
9871 +void register_firmware (const char *name, const u8 *data, size_t size);
9873 diff -urN linux-2.4.18/include/linux/kernel.h linux-2.4.18-mh9/include/linux/kernel.h
9874 --- linux-2.4.18/include/linux/kernel.h Mon Feb 25 20:38:13 2002
9875 +++ linux-2.4.18-mh9/include/linux/kernel.h Mon Aug 25 18:38:11 2003
9877 #include <linux/linkage.h>
9878 #include <linux/stddef.h>
9879 #include <linux/types.h>
9880 +#include <linux/compiler.h>
9882 /* Optimization barrier */
9883 /* The "volatile" is due to gcc bugs */
9885 char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
9889 +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
9891 +#endif /* _LINUX_KERNEL_H */
9892 diff -urN linux-2.4.18/include/net/bluetooth/bluetooth.h linux-2.4.18-mh9/include/net/bluetooth/bluetooth.h
9893 --- linux-2.4.18/include/net/bluetooth/bluetooth.h Fri Sep 7 18:28:38 2001
9894 +++ linux-2.4.18-mh9/include/net/bluetooth/bluetooth.h Mon Aug 25 18:38:11 2003
9899 - * $Id: bluetooth.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
9900 + * $Id: bluetooth.h,v 1.9 2002/05/06 21:11:55 maxk Exp $
9903 #ifndef __BLUETOOTH_H
9906 #include <asm/types.h>
9907 #include <asm/byteorder.h>
9908 +#include <linux/poll.h>
9909 +#include <net/sock.h>
9911 #ifndef AF_BLUETOOTH
9912 #define AF_BLUETOOTH 31
9913 #define PF_BLUETOOTH AF_BLUETOOTH
9916 +/* Reserv for core and drivers use */
9917 +#define BLUEZ_SKB_RESERVE 8
9920 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
9923 #define BTPROTO_L2CAP 0
9924 #define BTPROTO_HCI 1
9925 +#define BTPROTO_SCO 2
9926 +#define BTPROTO_RFCOMM 3
9927 +#define BTPROTO_BNEP 4
9928 +#define BTPROTO_CMTP 5
9933 +#define SOL_RFCOMM 18
9936 +#ifdef CONFIG_BLUEZ_DEBUG
9938 +#define HCI_CORE_DEBUG 1
9939 +#define HCI_SOCK_DEBUG 1
9940 +#define HCI_UART_DEBUG 1
9941 +#define HCI_USB_DEBUG 1
9942 +//#define HCI_DATA_DUMP 1
9944 +#define L2CAP_DEBUG 1
9945 +#define SCO_DEBUG 1
9946 +#define AF_BLUETOOTH_DEBUG 1
9948 +#endif /* CONFIG_BLUEZ_DEBUG */
9950 +extern void bluez_dump(char *pref, __u8 *buf, int count);
9952 +#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
9953 +#define __func__ __FUNCTION__
9956 +#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
9957 +#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
9958 +#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
9960 +#ifdef HCI_DATA_DUMP
9961 +#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
9963 +#define BT_DMP(D...)
9966 /* Connection and socket states */
9978 } __attribute__((packed)) bdaddr_t;
9980 -#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
9981 +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
9982 +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
9984 /* Copy, swap, convert BD Address */
9985 static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
9987 char *batostr(bdaddr_t *ba);
9988 bdaddr_t *strtoba(char *str);
9990 +/* Common socket structures and functions */
9992 +#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
9993 +#define bluez_sk(pi) ((struct sock *) \
9994 + ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
9996 +struct bluez_pinfo {
10000 + struct list_head accept_q;
10001 + struct sock *parent;
10004 +struct bluez_sock_list {
10005 + struct sock *head;
10009 +int bluez_sock_register(int proto, struct net_proto_family *ops);
10010 +int bluez_sock_unregister(int proto);
10011 +void bluez_sock_init(struct socket *sock, struct sock *sk);
10012 +void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
10013 +void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
10014 +int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
10015 +uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
10016 +int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
10018 +void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
10019 +struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
10022 +struct bluez_skb_cb {
10025 +#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
10027 +static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
10029 + struct sk_buff *skb;
10031 + if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
10032 + skb_reserve(skb, BLUEZ_SKB_RESERVE);
10033 + bluez_cb(skb)->incomming = 0;
10038 +static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
10039 + int nb, int *err)
10041 + struct sk_buff *skb;
10043 + if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
10044 + skb_reserve(skb, BLUEZ_SKB_RESERVE);
10045 + bluez_cb(skb)->incomming = 0;
10051 +static inline int skb_frags_no(struct sk_buff *skb)
10053 + register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
10054 + register int n = 1;
10056 + for (; frag; frag=frag->next, n++);
10060 +int hci_core_init(void);
10061 +int hci_core_cleanup(void);
10062 +int hci_sock_init(void);
10063 +int hci_sock_cleanup(void);
10065 int bterr(__u16 code);
10067 +#ifndef MODULE_LICENSE
10068 +#define MODULE_LICENSE(x)
10071 +#ifndef list_for_each_safe
10072 +#define list_for_each_safe(pos, n, head) \
10073 + for (pos = (head)->next, n = pos->next; pos != (head); \
10074 + pos = n, n = pos->next)
10077 #endif /* __BLUETOOTH_H */
10078 diff -urN linux-2.4.18/include/net/bluetooth/bluez.h linux-2.4.18-mh9/include/net/bluetooth/bluez.h
10079 --- linux-2.4.18/include/net/bluetooth/bluez.h Fri Sep 7 18:28:38 2001
10080 +++ linux-2.4.18-mh9/include/net/bluetooth/bluez.h Thu Jan 1 01:00:00 1970
10083 - BlueZ - Bluetooth protocol stack for Linux
10084 - Copyright (C) 2000-2001 Qualcomm Incorporated
10086 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
10088 - This program is free software; you can redistribute it and/or modify
10089 - it under the terms of the GNU General Public License version 2 as
10090 - published by the Free Software Foundation;
10092 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10093 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10094 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
10095 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
10096 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
10097 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
10098 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
10099 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
10101 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
10102 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
10103 - SOFTWARE IS DISCLAIMED.
10107 - * $Id: bluez.h,v 1.4 2001/08/03 04:19:49 maxk Exp $
10110 -#ifndef __IF_BLUEZ_H
10111 -#define __IF_BLUEZ_H
10113 -#include <net/sock.h>
10115 -#define BLUEZ_MAX_PROTO 2
10117 -/* Reserv for core and drivers use */
10118 -#define BLUEZ_SKB_RESERVE 8
10121 -#define MIN(a,b) ((a) < (b) ? (a) : (b))
10125 -#ifdef BLUEZ_DEBUG
10127 -#define HCI_CORE_DEBUG 1
10128 -#define HCI_SOCK_DEBUG 1
10129 -#define HCI_UART_DEBUG 1
10130 -#define HCI_USB_DEBUG 1
10131 -//#define HCI_DATA_DUMP 1
10133 -#define L2CAP_DEBUG 1
10135 -#endif /* BLUEZ_DEBUG */
10137 -extern void bluez_dump(char *pref, __u8 *buf, int count);
10139 -#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
10140 -#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
10141 -#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
10143 -#ifdef HCI_DATA_DUMP
10144 -#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
10149 -/* ----- Sockets ------ */
10150 -struct bluez_sock_list {
10151 - struct sock *head;
10155 -extern int bluez_sock_register(int proto, struct net_proto_family *ops);
10156 -extern int bluez_sock_unregister(int proto);
10158 -extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
10159 -extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
10161 -/* ----- SKB helpers ----- */
10162 -struct bluez_skb_cb {
10165 -#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
10167 -static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
10169 - struct sk_buff *skb;
10171 - if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
10172 - skb_reserve(skb, BLUEZ_SKB_RESERVE);
10173 - bluez_cb(skb)->incomming = 0;
10178 -static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
10179 - int nb, int *err)
10181 - struct sk_buff *skb;
10183 - if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
10184 - skb_reserve(skb, BLUEZ_SKB_RESERVE);
10185 - bluez_cb(skb)->incomming = 0;
10191 -static inline int skb_frags_no(struct sk_buff *skb)
10193 - register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
10194 - register int n = 1;
10196 - for (; frag; frag=frag->next, n++);
10200 -extern int hci_core_init(void);
10201 -extern int hci_core_cleanup(void);
10202 -extern int hci_sock_init(void);
10203 -extern int hci_sock_cleanup(void);
10205 -#endif /* __IF_BLUEZ_H */
10206 diff -urN linux-2.4.18/include/net/bluetooth/hci.h linux-2.4.18-mh9/include/net/bluetooth/hci.h
10207 --- linux-2.4.18/include/net/bluetooth/hci.h Fri Sep 7 18:28:38 2001
10208 +++ linux-2.4.18-mh9/include/net/bluetooth/hci.h Mon Aug 25 18:38:12 2003
10209 @@ -23,59 +23,80 @@
10213 - * $Id: hci.h,v 1.15 2001/08/05 06:02:15 maxk Exp $
10214 + * $Id: hci.h,v 1.5 2002/06/27 17:29:30 maxk Exp $
10220 -#include <asm/byteorder.h>
10222 -#define HCI_MAX_DEV 8
10223 -#define HCI_MAX_FRAME_SIZE 2048
10224 +#define HCI_MAX_ACL_SIZE 1024
10225 +#define HCI_MAX_SCO_SIZE 255
10226 +#define HCI_MAX_EVENT_SIZE 260
10227 +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
10229 /* HCI dev events */
10230 #define HCI_DEV_REG 1
10231 #define HCI_DEV_UNREG 2
10232 #define HCI_DEV_UP 3
10233 #define HCI_DEV_DOWN 4
10234 +#define HCI_DEV_SUSPEND 5
10235 +#define HCI_DEV_RESUME 6
10237 +/* HCI notify events */
10238 +#define HCI_NOTIFY_CONN_ADD 1
10239 +#define HCI_NOTIFY_CONN_DEL 2
10240 +#define HCI_NOTIFY_VOICE_SETTING 3
10242 /* HCI device types */
10243 -#define HCI_UART 0
10244 +#define HCI_VHCI 0
10246 -#define HCI_VHCI 2
10248 -/* HCI device modes */
10249 -#define HCI_NORMAL 0x0001
10250 -#define HCI_RAW 0x0002
10251 -#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
10252 -#define HCI_SOCK 0x1000
10254 -/* HCI device states */
10255 -#define HCI_INIT 0x0010
10256 -#define HCI_UP 0x0020
10257 -#define HCI_RUNNING 0x0040
10258 +#define HCI_PCCARD 2
10259 +#define HCI_UART 3
10260 +#define HCI_RS232 4
10263 /* HCI device flags */
10264 -#define HCI_PSCAN 0x0100
10265 -#define HCI_ISCAN 0x0200
10266 -#define HCI_AUTH 0x0400
10281 -/* HCI Ioctl defines */
10282 +/* HCI ioctl defines */
10283 #define HCIDEVUP _IOW('H', 201, int)
10284 #define HCIDEVDOWN _IOW('H', 202, int)
10285 #define HCIDEVRESET _IOW('H', 203, int)
10286 -#define HCIRESETSTAT _IOW('H', 204, int)
10287 -#define HCIGETINFO _IOR('H', 205, int)
10288 -#define HCIGETDEVLIST _IOR('H', 206, int)
10289 -#define HCISETRAW _IOW('H', 207, int)
10290 -#define HCISETSCAN _IOW('H', 208, int)
10291 -#define HCISETAUTH _IOW('H', 209, int)
10292 -#define HCIINQUIRY _IOR('H', 210, int)
10293 -#define HCISETPTYPE _IOW('H', 211, int)
10294 +#define HCIDEVRESTAT _IOW('H', 204, int)
10296 +#define HCIGETDEVLIST _IOR('H', 210, int)
10297 +#define HCIGETDEVINFO _IOR('H', 211, int)
10298 #define HCIGETCONNLIST _IOR('H', 212, int)
10299 +#define HCIGETCONNINFO _IOR('H', 213, int)
10301 -#ifndef __NO_HCI_DEFS
10302 +#define HCISETRAW _IOW('H', 220, int)
10303 +#define HCISETSCAN _IOW('H', 221, int)
10304 +#define HCISETAUTH _IOW('H', 222, int)
10305 +#define HCISETENCRYPT _IOW('H', 223, int)
10306 +#define HCISETPTYPE _IOW('H', 224, int)
10307 +#define HCISETLINKPOL _IOW('H', 225, int)
10308 +#define HCISETLINKMODE _IOW('H', 226, int)
10309 +#define HCISETACLMTU _IOW('H', 227, int)
10310 +#define HCISETSCOMTU _IOW('H', 228, int)
10312 +#define HCIINQUIRY _IOR('H', 240, int)
10314 +/* HCI timeouts */
10315 +#define HCI_CONN_TIMEOUT (HZ * 40)
10316 +#define HCI_DISCONN_TIMEOUT (HZ * 2)
10317 +#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
10319 /* HCI Packet types */
10320 #define HCI_COMMAND_PKT 0x01
10321 @@ -92,11 +113,18 @@
10322 #define HCI_DH3 0x0800
10323 #define HCI_DH5 0x8000
10325 +#define HCI_HV1 0x0020
10326 +#define HCI_HV2 0x0040
10327 +#define HCI_HV3 0x0080
10329 +#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
10330 +#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
10333 -#define ACL_CONT 0x0001
10334 -#define ACL_START 0x0002
10335 -#define ACL_ACTIVE_BCAST 0x0010
10336 -#define ACL_PICO_BCAST 0x0020
10337 +#define ACL_CONT 0x01
10338 +#define ACL_START 0x02
10339 +#define ACL_ACTIVE_BCAST 0x04
10340 +#define ACL_PICO_BCAST 0x08
10342 /* Baseband links */
10343 #define SCO_LINK 0x00
10344 @@ -125,6 +153,20 @@
10345 #define LMP_PSCHEME 0x02
10346 #define LMP_PCONTROL 0x04
10348 +/* Link policies */
10349 +#define HCI_LP_RSWITCH 0x0001
10350 +#define HCI_LP_HOLD 0x0002
10351 +#define HCI_LP_SNIFF 0x0004
10352 +#define HCI_LP_PARK 0x0008
10355 +#define HCI_LM_ACCEPT 0x8000
10356 +#define HCI_LM_MASTER 0x0001
10357 +#define HCI_LM_AUTH 0x0002
10358 +#define HCI_LM_ENCRYPT 0x0004
10359 +#define HCI_LM_TRUSTED 0x0008
10360 +#define HCI_LM_RELIABLE 0x0010
10362 /* ----- HCI Commands ----- */
10363 /* OGF & OCF values */
10365 @@ -137,9 +179,10 @@
10371 + __u16 manufacturer;
10372 + __u16 lmp_subver;
10373 } __attribute__ ((packed)) read_local_version_rp;
10374 +#define READ_LOCAL_VERSION_RP_SIZE 9
10376 #define OCF_READ_LOCAL_FEATURES 0x0003
10378 @@ -165,18 +208,24 @@
10379 /* Host Controller and Baseband */
10380 #define OGF_HOST_CTL 0x03
10381 #define OCF_RESET 0x0003
10382 +#define OCF_READ_AUTH_ENABLE 0x001F
10383 #define OCF_WRITE_AUTH_ENABLE 0x0020
10384 - #define AUTH_DISABLED 0x00
10385 - #define AUTH_ENABLED 0x01
10386 + #define AUTH_DISABLED 0x00
10387 + #define AUTH_ENABLED 0x01
10389 +#define OCF_READ_ENCRYPT_MODE 0x0021
10390 +#define OCF_WRITE_ENCRYPT_MODE 0x0022
10391 + #define ENCRYPT_DISABLED 0x00
10392 + #define ENCRYPT_P2P 0x01
10393 + #define ENCRYPT_BOTH 0x02
10395 #define OCF_WRITE_CA_TIMEOUT 0x0016
10396 #define OCF_WRITE_PG_TIMEOUT 0x0018
10398 #define OCF_WRITE_SCAN_ENABLE 0x001A
10399 - #define SCANS_DISABLED 0x00
10400 - #define IS_ENA_PS_DIS 0x01
10401 - #define IS_DIS_PS_ENA 0x02
10402 - #define IS_ENA_PS_ENA 0x03
10403 + #define SCAN_DISABLED 0x00
10404 + #define SCAN_INQUIRY 0x01
10405 + #define SCAN_PAGE 0x02
10407 #define OCF_SET_EVENT_FLT 0x0005
10409 @@ -226,9 +275,31 @@
10410 } __attribute__ ((packed)) write_class_of_dev_cp;
10411 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
10413 +#define OCF_READ_VOICE_SETTING 0x0025
10416 + __u16 voice_setting;
10417 +} __attribute__ ((packed)) read_voice_setting_rp;
10418 +#define READ_VOICE_SETTING_RP_SIZE 3
10420 +#define OCF_WRITE_VOICE_SETTING 0x0026
10422 + __u16 voice_setting;
10423 +} __attribute__ ((packed)) write_voice_setting_cp;
10424 +#define WRITE_VOICE_SETTING_CP_SIZE 2
10426 +#define OCF_HOST_BUFFER_SIZE 0x0033
10430 + __u16 acl_max_pkt;
10431 + __u16 sco_max_pkt;
10432 +} __attribute__ ((packed)) host_buffer_size_cp;
10433 +#define HOST_BUFFER_SIZE_CP_SIZE 7
10436 #define OGF_LINK_CTL 0x01
10437 -#define OCF_CREATE_CONN 0x0005
10438 +#define OCF_CREATE_CONN 0x0005
10442 @@ -246,6 +317,13 @@
10443 } __attribute__ ((packed)) accept_conn_req_cp;
10444 #define ACCEPT_CONN_REQ_CP_SIZE 7
10446 +#define OCF_REJECT_CONN_REQ 0x000a
10450 +} __attribute__ ((packed)) reject_conn_req_cp;
10451 +#define REJECT_CONN_REQ_CP_SIZE 7
10453 #define OCF_DISCONNECT 0x0006
10456 @@ -253,17 +331,142 @@
10457 } __attribute__ ((packed)) disconnect_cp;
10458 #define DISCONNECT_CP_SIZE 3
10460 +#define OCF_ADD_SCO 0x0007
10464 +} __attribute__ ((packed)) add_sco_cp;
10465 +#define ADD_SCO_CP_SIZE 4
10467 #define OCF_INQUIRY 0x0001
10473 } __attribute__ ((packed)) inquiry_cp;
10474 #define INQUIRY_CP_SIZE 5
10476 -#define OGF_LINK_POLICY 0x02 /* Link Policy */
10480 +} __attribute__ ((packed)) status_bdaddr_rp;
10481 +#define STATUS_BDADDR_RP_SIZE 7
10483 +#define OCF_INQUIRY_CANCEL 0x0002
10485 +#define OCF_LINK_KEY_REPLY 0x000B
10486 +#define OCF_LINK_KEY_NEG_REPLY 0x000C
10489 + __u8 link_key[16];
10490 +} __attribute__ ((packed)) link_key_reply_cp;
10491 +#define LINK_KEY_REPLY_CP_SIZE 22
10493 +#define OCF_PIN_CODE_REPLY 0x000D
10494 +#define OCF_PIN_CODE_NEG_REPLY 0x000E
10498 + __u8 pin_code[16];
10499 +} __attribute__ ((packed)) pin_code_reply_cp;
10500 +#define PIN_CODE_REPLY_CP_SIZE 23
10502 +#define OCF_CHANGE_CONN_PTYPE 0x000F
10506 +} __attribute__ ((packed)) change_conn_ptype_cp;
10507 +#define CHANGE_CONN_PTYPE_CP_SIZE 4
10509 +#define OCF_AUTH_REQUESTED 0x0011
10512 +} __attribute__ ((packed)) auth_requested_cp;
10513 +#define AUTH_REQUESTED_CP_SIZE 2
10515 +#define OCF_SET_CONN_ENCRYPT 0x0013
10519 +} __attribute__ ((packed)) set_conn_encrypt_cp;
10520 +#define SET_CONN_ENCRYPT_CP_SIZE 3
10522 +#define OCF_REMOTE_NAME_REQ 0x0019
10525 + __u8 pscan_rep_mode;
10527 + __u16 clock_offset;
10528 +} __attribute__ ((packed)) remote_name_req_cp;
10529 +#define REMOTE_NAME_REQ_CP_SIZE 10
10531 +#define OCF_READ_REMOTE_FEATURES 0x001B
10534 +} __attribute__ ((packed)) read_remote_features_cp;
10535 +#define READ_REMOTE_FEATURES_CP_SIZE 2
10537 +#define OCF_READ_REMOTE_VERSION 0x001D
10540 +} __attribute__ ((packed)) read_remote_version_cp;
10541 +#define READ_REMOTE_VERSION_CP_SIZE 2
10544 +#define OGF_LINK_POLICY 0x02
10545 +#define OCF_ROLE_DISCOVERY 0x0009
10548 +} __attribute__ ((packed)) role_discovery_cp;
10549 +#define ROLE_DISCOVERY_CP_SIZE 2
10554 +} __attribute__ ((packed)) role_discovery_rp;
10555 +#define ROLE_DISCOVERY_RP_SIZE 4
10557 -/* --------- HCI Events --------- */
10558 +#define OCF_READ_LINK_POLICY 0x000C
10561 +} __attribute__ ((packed)) read_link_policy_cp;
10562 +#define READ_LINK_POLICY_CP_SIZE 2
10567 +} __attribute__ ((packed)) read_link_policy_rp;
10568 +#define READ_LINK_POLICY_RP_SIZE 5
10570 +#define OCF_SWITCH_ROLE 0x000B
10574 +} __attribute__ ((packed)) switch_role_cp;
10575 +#define SWITCH_ROLE_CP_SIZE 7
10577 +#define OCF_WRITE_LINK_POLICY 0x000D
10581 +} __attribute__ ((packed)) write_link_policy_cp;
10582 +#define WRITE_LINK_POLICY_CP_SIZE 4
10586 +} __attribute__ ((packed)) write_link_policy_rp;
10587 +#define WRITE_LINK_POLICY_RP_SIZE 3
10589 +/* Status params */
10590 +#define OGF_STATUS_PARAM 0x05
10592 +/* Testing commands */
10593 +#define OGF_TESTING_CMD 0x3e
10595 +/* Vendor specific commands */
10596 +#define OGF_VENDOR_CMD 0x3f
10598 +/* ---- HCI Events ---- */
10599 #define EVT_INQUIRY_COMPLETE 0x01
10601 #define EVT_INQUIRY_RESULT 0x02
10602 @@ -272,7 +475,7 @@
10603 __u8 pscan_rep_mode;
10604 __u8 pscan_period_mode;
10607 + __u8 dev_class[3];
10608 __u16 clock_offset;
10609 } __attribute__ ((packed)) inquiry_info;
10610 #define INQUIRY_INFO_SIZE 14
10611 @@ -303,6 +506,44 @@
10612 } __attribute__ ((packed)) evt_disconn_complete;
10613 #define EVT_DISCONN_COMPLETE_SIZE 4
10615 +#define EVT_AUTH_COMPLETE 0x06
10619 +} __attribute__ ((packed)) evt_auth_complete;
10620 +#define EVT_AUTH_COMPLETE_SIZE 3
10622 +#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
10627 +} __attribute__ ((packed)) evt_remote_name_req_complete;
10628 +#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
10630 +#define EVT_ENCRYPT_CHANGE 0x08
10635 +} __attribute__ ((packed)) evt_encrypt_change;
10636 +#define EVT_ENCRYPT_CHANGE_SIZE 5
10638 +#define EVT_QOS_SETUP_COMPLETE 0x0D
10640 + __u8 service_type;
10641 + __u32 token_rate;
10642 + __u32 peak_bandwidth;
10644 + __u32 delay_variation;
10645 +} __attribute__ ((packed)) hci_qos;
10650 +} __attribute__ ((packed)) evt_qos_setup_complete;
10651 +#define EVT_QOS_SETUP_COMPLETE_SIZE 20
10653 #define EVT_CMD_COMPLETE 0x0e
10656 @@ -321,16 +562,78 @@
10657 #define EVT_NUM_COMP_PKTS 0x13
10660 - /* variable lenght part */
10661 + /* variable length part */
10662 } __attribute__ ((packed)) evt_num_comp_pkts;
10663 #define EVT_NUM_COMP_PKTS_SIZE 1
10665 -#define EVT_HCI_DEV_EVENT 0xfd
10666 +#define EVT_ROLE_CHANGE 0x12
10671 +} __attribute__ ((packed)) evt_role_change;
10672 +#define EVT_ROLE_CHANGE_SIZE 8
10674 +#define EVT_PIN_CODE_REQ 0x16
10677 +} __attribute__ ((packed)) evt_pin_code_req;
10678 +#define EVT_PIN_CODE_REQ_SIZE 6
10680 +#define EVT_LINK_KEY_REQ 0x17
10683 +} __attribute__ ((packed)) evt_link_key_req;
10684 +#define EVT_LINK_KEY_REQ_SIZE 6
10686 +#define EVT_LINK_KEY_NOTIFY 0x18
10689 + __u8 link_key[16];
10691 +} __attribute__ ((packed)) evt_link_key_notify;
10692 +#define EVT_LINK_KEY_NOTIFY_SIZE 23
10694 +#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
10698 + __u8 features[8];
10699 +} __attribute__ ((packed)) evt_read_remote_features_complete;
10700 +#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
10702 +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
10707 + __u16 manufacturer;
10708 + __u16 lmp_subver;
10709 +} __attribute__ ((packed)) evt_read_remote_version_complete;
10710 +#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
10712 +/* Internal events generated by BlueZ stack */
10713 +#define EVT_STACK_INTERNAL 0xfd
10717 +} __attribute__ ((packed)) evt_stack_internal;
10718 +#define EVT_STACK_INTERNAL_SIZE 2
10720 +#define EVT_SI_DEVICE 0x01
10724 +} __attribute__ ((packed)) evt_si_device;
10725 +#define EVT_SI_DEVICE_SIZE 4
10727 +#define EVT_SI_SECURITY 0x02
10731 -} __attribute__ ((packed)) evt_hci_dev_event;
10732 -#define EVT_HCI_DEV_EVENT_SIZE 4
10736 +} __attribute__ ((packed)) evt_si_security;
10738 /* -------- HCI Packet structures -------- */
10739 #define HCI_TYPE_LEN 1
10740 @@ -369,14 +672,14 @@
10741 #define acl_handle(h) (h & 0x0fff)
10742 #define acl_flags(h) (h >> 12)
10744 -#endif /* _NO_HCI_DEFS */
10746 /* HCI Socket options */
10747 -#define HCI_DATA_DIR 0x0001
10748 -#define HCI_FILTER 0x0002
10749 +#define HCI_DATA_DIR 1
10750 +#define HCI_FILTER 2
10751 +#define HCI_TIME_STAMP 3
10753 /* HCI CMSG flags */
10754 #define HCI_CMSG_DIR 0x0001
10755 +#define HCI_CMSG_TSTAMP 0x0002
10757 struct sockaddr_hci {
10758 sa_family_t hci_family;
10759 @@ -387,27 +690,29 @@
10760 struct hci_filter {
10762 __u32 event_mask[2];
10766 -struct hci_dev_req {
10771 -struct hci_dev_list_req {
10773 - struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
10776 -struct hci_inquiry_req {
10783 -#define IREQ_CACHE_FLUSH 0x0001
10784 +#define HCI_FLT_TYPE_BITS 31
10785 +#define HCI_FLT_EVENT_BITS 63
10786 +#define HCI_FLT_OGF_BITS 63
10787 +#define HCI_FLT_OCF_BITS 127
10789 +#if BITS_PER_LONG == 64
10790 +static inline void hci_set_bit(int nr, void *addr)
10792 + *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
10794 +static inline int hci_test_bit(int nr, void *addr)
10796 + return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
10799 +#define hci_set_bit set_bit
10800 +#define hci_test_bit test_bit
10803 +/* Ioctl requests structures */
10804 struct hci_dev_stats {
10807 @@ -433,11 +738,13 @@
10811 + __u32 link_policy;
10821 struct hci_dev_stats stat;
10823 @@ -445,12 +752,48 @@
10824 struct hci_conn_info {
10833 +struct hci_dev_req {
10838 +struct hci_dev_list_req {
10840 + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
10843 struct hci_conn_list_req {
10846 struct hci_conn_info conn_info[0];
10849 +struct hci_conn_info_req {
10852 + struct hci_conn_info conn_info[0];
10855 +struct hci_inquiry_req {
10862 +#define IREQ_CACHE_FLUSH 0x0001
10864 +struct hci_remotename_req {
10871 #endif /* __HCI_H */
10872 diff -urN linux-2.4.18/include/net/bluetooth/hci_core.h linux-2.4.18-mh9/include/net/bluetooth/hci_core.h
10873 --- linux-2.4.18/include/net/bluetooth/hci_core.h Fri Sep 7 18:28:38 2001
10874 +++ linux-2.4.18-mh9/include/net/bluetooth/hci_core.h Mon Aug 25 18:38:12 2003
10879 - * $Id: hci_core.h,v 1.11 2001/08/05 06:02:15 maxk Exp $
10880 + * $Id: hci_core.h,v 1.5 2002/06/27 04:56:30 maxk Exp $
10883 #ifndef __HCI_CORE_H
10884 @@ -32,14 +32,12 @@
10885 #include <net/bluetooth/hci.h>
10887 /* HCI upper protocols */
10888 -#define HCI_MAX_PROTO 1
10889 #define HCI_PROTO_L2CAP 0
10890 +#define HCI_PROTO_SCO 1
10892 #define HCI_INIT_TIMEOUT (HZ * 10)
10894 -/* ----- Inquiry cache ----- */
10895 -#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
10896 -#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
10897 +/* HCI Core structures */
10899 struct inquiry_entry {
10900 struct inquiry_entry *next;
10901 @@ -53,111 +51,182 @@
10902 struct inquiry_entry *list;
10905 -static inline void inquiry_cache_init(struct inquiry_cache *cache)
10907 - spin_lock_init(&cache->lock);
10908 - cache->list = NULL;
10910 +struct conn_hash {
10911 + struct list_head list;
10913 + unsigned int num;
10916 -static inline void inquiry_cache_lock(struct inquiry_cache *cache)
10918 - spin_lock(&cache->lock);
10921 + struct list_head list;
10925 -static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
10927 - spin_unlock(&cache->lock);
10930 + unsigned long flags;
10934 + __u8 features[8];
10935 + __u16 voice_setting;
10937 -static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
10939 - spin_lock_bh(&cache->lock);
10942 + __u16 link_policy;
10945 -static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
10947 - spin_unlock_bh(&cache->lock);
10949 + atomic_t cmd_cnt;
10950 + unsigned int acl_cnt;
10951 + unsigned int sco_cnt;
10953 -static inline long inquiry_cache_age(struct inquiry_cache *cache)
10955 - return jiffies - cache->timestamp;
10957 + unsigned int acl_mtu;
10958 + unsigned int sco_mtu;
10959 + unsigned int acl_pkts;
10960 + unsigned int sco_pkts;
10962 -static inline long inquiry_entry_age(struct inquiry_entry *e)
10964 - return jiffies - e->timestamp;
10966 -extern void inquiry_cache_flush(struct inquiry_cache *cache);
10967 + unsigned long cmd_last_tx;
10968 + unsigned long acl_last_tx;
10969 + unsigned long sco_last_tx;
10971 + struct tasklet_struct cmd_task;
10972 + struct tasklet_struct rx_task;
10973 + struct tasklet_struct tx_task;
10976 + struct sk_buff_head rx_q;
10977 + struct sk_buff_head raw_q;
10978 + struct sk_buff_head cmd_q;
10980 + struct sk_buff *sent_cmd;
10982 + struct semaphore req_lock;
10983 + wait_queue_head_t req_wait_q;
10984 + __u32 req_status;
10985 + __u32 req_result;
10987 + struct inquiry_cache inq_cache;
10988 + struct conn_hash conn_hash;
10990 + struct hci_dev_stats stat;
10992 + void *driver_data;
10995 + atomic_t promisc;
10997 + int (*open)(struct hci_dev *hdev);
10998 + int (*close)(struct hci_dev *hdev);
10999 + int (*flush)(struct hci_dev *hdev);
11000 + int (*send)(struct sk_buff *skb);
11001 + void (*destruct)(struct hci_dev *hdev);
11002 + void (*notify)(struct hci_dev *hdev, unsigned int evt, unsigned long arg);
11003 + int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
11006 -/* ----- HCI Connections ----- */
11008 struct list_head list;
11017 - unsigned int sent;
11020 + unsigned long pend;
11022 + unsigned int sent;
11024 + struct sk_buff_head data_q;
11026 + struct timer_list timer;
11028 struct hci_dev *hdev;
11033 - struct sk_buff_head data_q;
11034 + struct hci_conn *link;
11037 -struct conn_hash {
11038 - struct list_head list;
11040 - unsigned int num;
11042 +extern struct hci_proto *hci_proto[];
11043 +extern struct list_head hdev_list;
11044 +extern rwlock_t hdev_list_lock;
11046 +/* ----- Inquiry cache ----- */
11047 +#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
11048 +#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
11050 +#define inquiry_cache_lock(c) spin_lock(&c->lock)
11051 +#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
11052 +#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
11053 +#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
11055 -static inline void conn_hash_init(struct conn_hash *h)
11056 +static inline void inquiry_cache_init(struct hci_dev *hdev)
11058 - INIT_LIST_HEAD(&h->list);
11059 - spin_lock_init(&h->lock);
11061 + struct inquiry_cache *c = &hdev->inq_cache;
11062 + spin_lock_init(&c->lock);
11066 -static inline void conn_hash_lock(struct conn_hash *h)
11067 +static inline long inquiry_cache_age(struct hci_dev *hdev)
11069 - spin_lock(&h->lock);
11070 + struct inquiry_cache *c = &hdev->inq_cache;
11071 + return jiffies - c->timestamp;
11074 -static inline void conn_hash_unlock(struct conn_hash *h)
11075 +static inline long inquiry_entry_age(struct inquiry_entry *e)
11077 - spin_unlock(&h->lock);
11078 + return jiffies - e->timestamp;
11081 -static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
11082 +struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
11083 +void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
11084 +void inquiry_cache_flush(struct hci_dev *hdev);
11085 +int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
11087 +/* ----- HCI Connections ----- */
11089 + HCI_CONN_AUTH_PEND,
11090 + HCI_CONN_ENCRYPT_PEND
11093 +#define hci_conn_lock(c) spin_lock(&c->lock)
11094 +#define hci_conn_unlock(c) spin_unlock(&c->lock)
11095 +#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
11096 +#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
11098 +#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
11099 +#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
11100 +#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
11101 +#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
11103 +static inline void conn_hash_init(struct hci_dev *hdev)
11105 - list_add(&c->list, &h->list);
11107 + struct conn_hash *h = &hdev->conn_hash;
11108 + INIT_LIST_HEAD(&h->list);
11109 + spin_lock_init(&h->lock);
11113 -static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
11114 +static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
11116 - conn_hash_lock(h);
11117 - __conn_hash_add(h, handle, c);
11118 - conn_hash_unlock(h);
11119 + struct conn_hash *h = &hdev->conn_hash;
11120 + list_add(&c->list, &h->list);
11124 -static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
11125 +static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
11127 + struct conn_hash *h = &hdev->conn_hash;
11128 list_del(&c->list);
11132 -static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
11134 - conn_hash_lock(h);
11135 - __conn_hash_del(h, c);
11136 - conn_hash_unlock(h);
11139 -static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
11140 +static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
11143 + register struct conn_hash *h = &hdev->conn_hash;
11144 register struct list_head *p;
11145 register struct hci_conn *c;
11147 @@ -169,101 +238,95 @@
11151 -static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
11152 +static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
11153 + __u8 type, bdaddr_t *ba)
11155 - struct hci_conn *conn;
11156 + register struct conn_hash *h = &hdev->conn_hash;
11157 + register struct list_head *p;
11158 + register struct hci_conn *c;
11160 - conn_hash_lock(h);
11161 - conn = __conn_hash_lookup(h, handle);
11162 - conn_hash_unlock(h);
11164 + list_for_each(p, &h->list) {
11165 + c = list_entry(p, struct hci_conn, list);
11166 + if (c->type == type && !bacmp(&c->dst, ba))
11172 -/* ----- HCI Devices ----- */
11181 - __u8 features[8];
11185 - atomic_t cmd_cnt;
11186 - unsigned int acl_cnt;
11187 - unsigned int sco_cnt;
11189 - unsigned int acl_mtu;
11190 - unsigned int sco_mtu;
11191 - unsigned int acl_max;
11192 - unsigned int sco_max;
11194 - void *driver_data;
11195 - void *l2cap_data;
11198 - struct tasklet_struct cmd_task;
11199 - struct tasklet_struct rx_task;
11200 - struct tasklet_struct tx_task;
11202 - struct sk_buff_head rx_q;
11203 - struct sk_buff_head raw_q;
11204 - struct sk_buff_head cmd_q;
11206 - struct sk_buff *sent_cmd;
11208 - struct semaphore req_lock;
11209 - wait_queue_head_t req_wait_q;
11210 - __u32 req_status;
11211 - __u32 req_result;
11213 - struct inquiry_cache inq_cache;
11214 +void hci_acl_connect(struct hci_conn *conn);
11215 +void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
11216 +void hci_add_sco(struct hci_conn *conn, __u16 handle);
11218 - struct conn_hash conn_hash;
11219 +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
11220 +int hci_conn_del(struct hci_conn *conn);
11221 +void hci_conn_hash_flush(struct hci_dev *hdev);
11223 - struct hci_dev_stats stat;
11224 +struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
11225 +int hci_conn_auth(struct hci_conn *conn);
11226 +int hci_conn_encrypt(struct hci_conn *conn);
11228 - int (*open)(struct hci_dev *hdev);
11229 - int (*close)(struct hci_dev *hdev);
11230 - int (*flush)(struct hci_dev *hdev);
11231 - int (*send)(struct sk_buff *skb);
11233 +static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
11235 + mod_timer(&conn->timer, jiffies + timeout);
11238 -static inline void hci_dev_hold(struct hci_dev *hdev)
11239 +static inline void hci_conn_del_timer(struct hci_conn *conn)
11241 - atomic_inc(&hdev->refcnt);
11242 + del_timer(&conn->timer);
11245 -static inline void hci_dev_put(struct hci_dev *hdev)
11246 +static inline void hci_conn_hold(struct hci_conn *conn)
11248 - atomic_dec(&hdev->refcnt);
11249 + atomic_inc(&conn->refcnt);
11250 + hci_conn_del_timer(conn);
11253 -extern struct hci_dev *hci_dev_get(int index);
11254 -extern int hci_register_dev(struct hci_dev *hdev);
11255 -extern int hci_unregister_dev(struct hci_dev *hdev);
11256 -extern int hci_dev_open(__u16 dev);
11257 -extern int hci_dev_close(__u16 dev);
11258 -extern int hci_dev_reset(__u16 dev);
11259 -extern int hci_dev_reset_stat(__u16 dev);
11260 -extern int hci_dev_info(unsigned long arg);
11261 -extern int hci_dev_list(unsigned long arg);
11262 -extern int hci_dev_setscan(unsigned long arg);
11263 -extern int hci_dev_setauth(unsigned long arg);
11264 -extern int hci_dev_setptype(unsigned long arg);
11265 -extern int hci_conn_list(unsigned long arg);
11266 -extern int hci_inquiry(unsigned long arg);
11267 +static inline void hci_conn_put(struct hci_conn *conn)
11269 + if (atomic_dec_and_test(&conn->refcnt)) {
11270 + if (conn->type == SCO_LINK)
11271 + hci_conn_set_timer(conn, HZ / 100);
11272 + else if (conn->out)
11273 + hci_conn_set_timer(conn, HCI_DISCONN_TIMEOUT);
11277 -extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
11278 -extern __u32 hci_dev_getmode(struct hci_dev *hdev);
11279 +/* ----- HCI Devices ----- */
11280 +static inline void hci_dev_put(struct hci_dev *d)
11282 + if (atomic_dec_and_test(&d->refcnt))
11285 +#define hci_dev_hold(d) atomic_inc(&d->refcnt)
11287 +#define hci_dev_lock(d) spin_lock(&d->lock)
11288 +#define hci_dev_unlock(d) spin_unlock(&d->lock)
11289 +#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
11290 +#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
11292 +struct hci_dev *hci_dev_get(int index);
11293 +struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
11294 +int hci_register_dev(struct hci_dev *hdev);
11295 +int hci_unregister_dev(struct hci_dev *hdev);
11296 +int hci_suspend_dev(struct hci_dev *hdev);
11297 +int hci_resume_dev(struct hci_dev *hdev);
11298 +int hci_dev_open(__u16 dev);
11299 +int hci_dev_close(__u16 dev);
11300 +int hci_dev_reset(__u16 dev);
11301 +int hci_dev_reset_stat(__u16 dev);
11302 +int hci_dev_cmd(unsigned int cmd, unsigned long arg);
11303 +int hci_get_dev_list(unsigned long arg);
11304 +int hci_get_dev_info(unsigned long arg);
11305 +int hci_get_conn_list(unsigned long arg);
11306 +int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
11307 +int hci_inquiry(unsigned long arg);
11309 -extern int hci_recv_frame(struct sk_buff *skb);
11310 +int hci_recv_frame(struct sk_buff *skb);
11311 +void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
11313 /* ----- LMP capabilities ----- */
11314 #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
11315 +#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
11317 /* ----- HCI tasks ----- */
11318 static inline void hci_sched_cmd(struct hci_dev *hdev)
11319 @@ -284,43 +347,130 @@
11320 /* ----- HCI protocols ----- */
11326 + unsigned long flags;
11330 - int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
11331 - int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
11332 + int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
11333 + int (*connect_cfm) (struct hci_conn *conn, __u8 status);
11334 int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
11335 - int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
11336 + int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11337 int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
11338 + int (*auth_cfm) (struct hci_conn *conn, __u8 status);
11339 + int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
11342 -extern int hci_register_proto(struct hci_proto *hproto);
11343 -extern int hci_unregister_proto(struct hci_proto *hproto);
11344 -extern int hci_register_notifier(struct notifier_block *nb);
11345 -extern int hci_unregister_notifier(struct notifier_block *nb);
11346 -extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
11347 -extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
11348 -extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
11349 -extern int hci_send_raw(struct sk_buff *skb);
11350 -extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11351 -extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
11352 +static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
11354 + register struct hci_proto *hp;
11357 + hp = hci_proto[HCI_PROTO_L2CAP];
11358 + if (hp && hp->connect_ind)
11359 + mask |= hp->connect_ind(hdev, bdaddr, type);
11361 + hp = hci_proto[HCI_PROTO_SCO];
11362 + if (hp && hp->connect_ind)
11363 + mask |= hp->connect_ind(hdev, bdaddr, type);
11368 +static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
11370 + register struct hci_proto *hp;
11372 + hp = hci_proto[HCI_PROTO_L2CAP];
11373 + if (hp && hp->connect_cfm)
11374 + hp->connect_cfm(conn, status);
11376 + hp = hci_proto[HCI_PROTO_SCO];
11377 + if (hp && hp->connect_cfm)
11378 + hp->connect_cfm(conn, status);
11381 +static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
11383 + register struct hci_proto *hp;
11385 + hp = hci_proto[HCI_PROTO_L2CAP];
11386 + if (hp && hp->disconn_ind)
11387 + hp->disconn_ind(conn, reason);
11389 + hp = hci_proto[HCI_PROTO_SCO];
11390 + if (hp && hp->disconn_ind)
11391 + hp->disconn_ind(conn, reason);
11394 +static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
11396 + register struct hci_proto *hp;
11398 + hp = hci_proto[HCI_PROTO_L2CAP];
11399 + if (hp && hp->auth_cfm)
11400 + hp->auth_cfm(conn, status);
11402 + hp = hci_proto[HCI_PROTO_SCO];
11403 + if (hp && hp->auth_cfm)
11404 + hp->auth_cfm(conn, status);
11407 +static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
11409 + register struct hci_proto *hp;
11411 + hp = hci_proto[HCI_PROTO_L2CAP];
11412 + if (hp && hp->encrypt_cfm)
11413 + hp->encrypt_cfm(conn, status);
11415 + hp = hci_proto[HCI_PROTO_SCO];
11416 + if (hp && hp->encrypt_cfm)
11417 + hp->encrypt_cfm(conn, status);
11420 +int hci_register_proto(struct hci_proto *hproto);
11421 +int hci_unregister_proto(struct hci_proto *hproto);
11422 +int hci_register_notifier(struct notifier_block *nb);
11423 +int hci_unregister_notifier(struct notifier_block *nb);
11425 +int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
11426 +int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
11427 +int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
11429 +void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
11431 +void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
11433 /* ----- HCI Sockets ----- */
11434 -extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
11435 +void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
11437 /* HCI info for socket */
11438 -#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
11439 +#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
11441 struct hci_dev *hdev;
11442 struct hci_filter filter;
11446 +/* HCI security filter */
11447 +#define HCI_SFLT_MAX_OGF 5
11449 +struct hci_sec_filter {
11451 + __u32 event_mask[2];
11452 + __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
11455 /* ----- HCI requests ----- */
11456 #define HCI_REQ_DONE 0
11457 #define HCI_REQ_PEND 1
11458 #define HCI_REQ_CANCELED 2
11460 +#define hci_req_lock(d) down(&d->req_lock)
11461 +#define hci_req_unlock(d) up(&d->req_lock)
11463 +void hci_req_complete(struct hci_dev *hdev, int result);
11464 +void hci_req_cancel(struct hci_dev *hdev, int err);
11466 #endif /* __HCI_CORE_H */
11467 diff -urN linux-2.4.18/include/net/bluetooth/hci_uart.h linux-2.4.18-mh9/include/net/bluetooth/hci_uart.h
11468 --- linux-2.4.18/include/net/bluetooth/hci_uart.h Fri Sep 7 18:28:38 2001
11469 +++ linux-2.4.18-mh9/include/net/bluetooth/hci_uart.h Thu Jan 1 01:00:00 1970
11472 - BlueZ - Bluetooth protocol stack for Linux
11473 - Copyright (C) 2000-2001 Qualcomm Incorporated
11475 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
11477 - This program is free software; you can redistribute it and/or modify
11478 - it under the terms of the GNU General Public License version 2 as
11479 - published by the Free Software Foundation;
11481 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11482 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11483 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
11484 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
11485 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
11486 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11487 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
11488 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11490 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
11491 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
11492 - SOFTWARE IS DISCLAIMED.
11496 - * $Id: hci_uart.h,v 1.2 2001/06/02 01:40:08 maxk Exp $
11505 -#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
11506 -#define n_hci2tty(n_hci) ((n_hci)->tty)
11509 - struct tty_struct *tty;
11510 - struct hci_dev hdev;
11512 - struct sk_buff_head txq;
11513 - unsigned long tx_state;
11515 - spinlock_t rx_lock;
11516 - unsigned long rx_state;
11517 - unsigned long rx_count;
11518 - struct sk_buff *rx_skb;
11521 -/* Transmit states */
11522 -#define TRANS_SENDING 1
11523 -#define TRANS_WAKEUP 2
11525 -/* Receiver States */
11526 -#define WAIT_PACKET_TYPE 0
11527 -#define WAIT_EVENT_HDR 1
11528 -#define WAIT_ACL_HDR 2
11529 -#define WAIT_SCO_HDR 3
11530 -#define WAIT_DATA 4
11532 -#endif /* __KERNEL__ */
11533 diff -urN linux-2.4.18/include/net/bluetooth/hci_usb.h linux-2.4.18-mh9/include/net/bluetooth/hci_usb.h
11534 --- linux-2.4.18/include/net/bluetooth/hci_usb.h Fri Sep 7 18:28:38 2001
11535 +++ linux-2.4.18-mh9/include/net/bluetooth/hci_usb.h Thu Jan 1 01:00:00 1970
11538 - BlueZ - Bluetooth protocol stack for Linux
11539 - Copyright (C) 2000-2001 Qualcomm Incorporated
11541 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
11543 - This program is free software; you can redistribute it and/or modify
11544 - it under the terms of the GNU General Public License version 2 as
11545 - published by the Free Software Foundation;
11547 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11548 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11549 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
11550 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
11551 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
11552 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11553 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
11554 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11556 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
11557 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
11558 - SOFTWARE IS DISCLAIMED.
11562 - * $Id: hci_usb.h,v 1.3 2001/06/02 01:40:08 maxk Exp $
11567 -/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
11568 -#define HCI_DEV_CLASS 0xe0 /* Wireless class */
11569 -#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
11570 -#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
11572 -#define HCI_CTRL_REQ 0x20
11575 - struct usb_device *udev;
11577 - devrequest dev_req;
11578 - struct urb *ctrl_urb;
11579 - struct urb *intr_urb;
11580 - struct urb *read_urb;
11581 - struct urb *write_urb;
11585 - struct sk_buff *intr_skb;
11588 - __u8 bulk_out_ep_addr;
11589 - __u8 bulk_in_ep_addr;
11590 - __u8 intr_in_ep_addr;
11591 - __u8 intr_in_interval;
11593 - struct hci_dev hdev;
11595 - unsigned long tx_state;
11596 - struct sk_buff_head tx_ctrl_q;
11597 - struct sk_buff_head tx_write_q;
11600 -/* Transmit states */
11601 -#define HCI_TX_CTRL 1
11602 -#define HCI_TX_WRITE 2
11604 -#endif /* __KERNEL__ */
11605 diff -urN linux-2.4.18/include/net/bluetooth/hci_vhci.h linux-2.4.18-mh9/include/net/bluetooth/hci_vhci.h
11606 --- linux-2.4.18/include/net/bluetooth/hci_vhci.h Fri Sep 7 18:28:38 2001
11607 +++ linux-2.4.18-mh9/include/net/bluetooth/hci_vhci.h Thu Jan 1 01:00:00 1970
11610 - BlueZ - Bluetooth protocol stack for Linux
11611 - Copyright (C) 2000-2001 Qualcomm Incorporated
11613 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
11615 - This program is free software; you can redistribute it and/or modify
11616 - it under the terms of the GNU General Public License version 2 as
11617 - published by the Free Software Foundation;
11619 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11620 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11621 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
11622 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
11623 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
11624 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11625 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
11626 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11628 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
11629 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
11630 - SOFTWARE IS DISCLAIMED.
11634 - * $Id: hci_vhci.h,v 1.2 2001/08/01 01:02:20 maxk Exp $
11637 -#ifndef __HCI_VHCI_H
11638 -#define __HCI_VHCI_H
11642 -struct hci_vhci_struct {
11643 - struct hci_dev hdev;
11645 - wait_queue_head_t read_wait;
11646 - struct sk_buff_head readq;
11647 - struct fasync_struct *fasync;
11650 -/* VHCI device flags */
11651 -#define VHCI_FASYNC 0x0010
11653 -#endif /* __KERNEL__ */
11655 -#define VHCI_DEV "/dev/vhci"
11656 -#define VHCI_MINOR 250
11658 -#endif /* __HCI_VHCI_H */
11659 diff -urN linux-2.4.18/include/net/bluetooth/l2cap.h linux-2.4.18-mh9/include/net/bluetooth/l2cap.h
11660 --- linux-2.4.18/include/net/bluetooth/l2cap.h Fri Sep 7 18:28:38 2001
11661 +++ linux-2.4.18-mh9/include/net/bluetooth/l2cap.h Mon Aug 25 18:38:12 2003
11662 @@ -23,22 +23,17 @@
11666 - * $Id: l2cap.h,v 1.5 2001/06/14 21:28:26 maxk Exp $
11667 + * $Id: l2cap.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
11673 -#include <asm/types.h>
11674 -#include <asm/byteorder.h>
11676 /* L2CAP defaults */
11677 #define L2CAP_DEFAULT_MTU 672
11678 #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
11680 #define L2CAP_CONN_TIMEOUT (HZ * 40)
11681 -#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
11682 -#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
11684 /* L2CAP socket address */
11685 struct sockaddr_l2 {
11686 @@ -47,17 +42,12 @@
11687 bdaddr_t l2_bdaddr;
11690 -/* set/get sockopt defines */
11691 -#define L2CAP_OPTIONS 0x01
11692 +/* Socket options */
11693 +#define L2CAP_OPTIONS 0x01
11694 struct l2cap_options {
11698 - __u32 token_rate;
11699 - __u32 bucket_size;
11705 #define L2CAP_CONNINFO 0x02
11710 +#define L2CAP_LM 0x03
11711 +#define L2CAP_LM_MASTER 0x0001
11712 +#define L2CAP_LM_AUTH 0x0002
11713 +#define L2CAP_LM_ENCRYPT 0x0004
11714 +#define L2CAP_LM_TRUSTED 0x0008
11715 +#define L2CAP_LM_RELIABLE 0x0010
11717 +#define L2CAP_QOS 0x04
11718 +struct l2cap_qos {
11719 + __u16 service_type;
11720 + __u32 token_rate;
11721 + __u32 token_bucket_size;
11722 + __u32 peak_bandwidth;
11724 + __u32 delay_variation;
11727 +#define L2CAP_SERV_NO_TRAFFIC 0x00
11728 +#define L2CAP_SERV_BEST_EFFORT 0x01
11729 +#define L2CAP_SERV_GUARANTEED 0x02
11731 /* L2CAP command codes */
11732 #define L2CAP_COMMAND_REJ 0x01
11733 #define L2CAP_CONN_REQ 0x02
11735 #define L2CAP_INFO_RSP 0x0b
11737 /* L2CAP structures */
11742 @@ -112,11 +122,17 @@
11743 } __attribute__ ((packed)) l2cap_conn_rsp;
11744 #define L2CAP_CONN_RSP_SIZE 8
11746 -#define L2CAP_CONN_SUCCESS 0x0000
11747 -#define L2CAP_CONN_PEND 0x0001
11748 -#define L2CAP_CONN_BAD_PSM 0x0002
11749 -#define L2CAP_CONN_SEC_BLOCK 0x0003
11750 -#define L2CAP_CONN_NO_MEM 0x0004
11751 +/* connect result */
11752 +#define L2CAP_CR_SUCCESS 0x0000
11753 +#define L2CAP_CR_PEND 0x0001
11754 +#define L2CAP_CR_BAD_PSM 0x0002
11755 +#define L2CAP_CR_SEC_BLOCK 0x0003
11756 +#define L2CAP_CR_NO_MEM 0x0004
11758 +/* connect status */
11759 +#define L2CAP_CS_NO_INFO 0x0000
11760 +#define L2CAP_CS_AUTHEN_PEND 0x0001
11761 +#define L2CAP_CS_AUTHOR_PEND 0x0002
11765 @@ -147,6 +163,8 @@
11766 #define L2CAP_CONF_FLUSH_TO 0x02
11767 #define L2CAP_CONF_QOS 0x03
11769 +#define L2CAP_CONF_MAX_SIZE 22
11774 @@ -158,5 +176,75 @@
11776 } __attribute__ ((packed)) l2cap_disconn_rsp;
11777 #define L2CAP_DISCONN_RSP_SIZE 4
11782 +} __attribute__ ((packed)) l2cap_info_req;
11783 +#define L2CAP_INFO_REQ_SIZE 2
11789 +} __attribute__ ((packed)) l2cap_info_rsp;
11790 +#define L2CAP_INFO_RSP_SIZE 4
11792 +/* ----- L2CAP connections ----- */
11793 +struct l2cap_chan_list {
11794 + struct sock *head;
11799 +struct l2cap_conn {
11800 + struct hci_conn *hcon;
11805 + unsigned int mtu;
11809 + struct sk_buff *rx_skb;
11814 + struct l2cap_chan_list chan_list;
11817 +/* ----- L2CAP channel and socket info ----- */
11818 +#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
11820 +struct l2cap_pinfo {
11837 + struct l2cap_conn *conn;
11838 + struct sock *next_c;
11839 + struct sock *prev_c;
11842 +#define L2CAP_CONF_REQ_SENT 0x01
11843 +#define L2CAP_CONF_INPUT_DONE 0x02
11844 +#define L2CAP_CONF_OUTPUT_DONE 0x04
11845 +#define L2CAP_CONF_MAX_RETRIES 2
11847 +void l2cap_load(void);
11849 #endif /* __L2CAP_H */
11850 diff -urN linux-2.4.18/include/net/bluetooth/l2cap_core.h linux-2.4.18-mh9/include/net/bluetooth/l2cap_core.h
11851 --- linux-2.4.18/include/net/bluetooth/l2cap_core.h Fri Sep 7 18:28:38 2001
11852 +++ linux-2.4.18-mh9/include/net/bluetooth/l2cap_core.h Thu Jan 1 01:00:00 1970
11855 - BlueZ - Bluetooth protocol stack for Linux
11856 - Copyright (C) 2000-2001 Qualcomm Incorporated
11858 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
11860 - This program is free software; you can redistribute it and/or modify
11861 - it under the terms of the GNU General Public License version 2 as
11862 - published by the Free Software Foundation;
11864 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11865 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11866 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
11867 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
11868 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
11869 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11870 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
11871 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
11873 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
11874 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
11875 - SOFTWARE IS DISCLAIMED.
11879 - * $Id: l2cap_core.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
11882 -#ifndef __L2CAP_CORE_H
11883 -#define __L2CAP_CORE_H
11887 -/* ----- L2CAP interface ----- */
11888 -struct l2cap_iff {
11889 - struct list_head list;
11890 - struct hci_dev *hdev;
11891 - bdaddr_t *bdaddr;
11894 - struct list_head conn_list;
11897 -static inline void l2cap_iff_lock(struct l2cap_iff *iff)
11899 - spin_lock(&iff->lock);
11902 -static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
11904 - spin_unlock(&iff->lock);
11907 -/* ----- L2CAP connections ----- */
11908 -struct l2cap_chan_list {
11909 - struct sock *head;
11914 -struct l2cap_conn {
11915 - struct l2cap_iff *iff;
11916 - struct list_head list;
11918 - struct hci_conn *hconn;
11928 - struct sk_buff *rx_skb;
11933 - struct l2cap_chan_list chan_list;
11935 - struct timer_list timer;
11938 -static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
11940 - list_add(&c->list, &iff->conn_list);
11943 -static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
11945 - list_del(&c->list);
11948 -/* ----- L2CAP channel and socket info ----- */
11949 -#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
11951 -struct l2cap_accept_q {
11952 - struct sock *head;
11953 - struct sock *tail;
11956 -struct l2cap_pinfo {
11973 - struct l2cap_conn *conn;
11974 - struct sock *next_c;
11975 - struct sock *prev_c;
11977 - struct sock *parent;
11978 - struct sock *next_q;
11979 - struct sock *prev_q;
11981 - struct l2cap_accept_q accept_q;
11984 -#define CONF_REQ_SENT 0x01
11985 -#define CONF_INPUT_DONE 0x02
11986 -#define CONF_OUTPUT_DONE 0x04
11988 -extern struct bluez_sock_list l2cap_sk_list;
11989 -extern struct list_head l2cap_iff_list;
11990 -extern rwlock_t l2cap_rt_lock;
11992 -extern void l2cap_register_proc(void);
11993 -extern void l2cap_unregister_proc(void);
11995 -#endif /* __KERNEL__ */
11997 -#endif /* __L2CAP_CORE_H */
11998 diff -urN linux-2.4.18/include/net/bluetooth/rfcomm.h linux-2.4.18-mh9/include/net/bluetooth/rfcomm.h
11999 --- linux-2.4.18/include/net/bluetooth/rfcomm.h Thu Jan 1 01:00:00 1970
12000 +++ linux-2.4.18-mh9/include/net/bluetooth/rfcomm.h Mon Aug 25 18:38:12 2003
12003 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
12004 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
12005 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
12007 + This program is free software; you can redistribute it and/or modify
12008 + it under the terms of the GNU General Public License version 2 as
12009 + published by the Free Software Foundation;
12011 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12012 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12013 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12014 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12015 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12016 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12017 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12018 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12020 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12021 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12022 + SOFTWARE IS DISCLAIMED.
12026 + RPN support - Dirk Husemann <hud@zurich.ibm.com>
12030 + * $Id: rfcomm.h,v 1.31 2002/10/18 20:12:11 maxk Exp $
12033 +#ifndef __RFCOMM_H
12034 +#define __RFCOMM_H
12036 +#define RFCOMM_PSM 3
12038 +#define RFCOMM_CONN_TIMEOUT (HZ * 30)
12039 +#define RFCOMM_DISC_TIMEOUT (HZ * 20)
12041 +#define RFCOMM_DEFAULT_MTU 127
12042 +#define RFCOMM_DEFAULT_CREDITS 7
12044 +#define RFCOMM_MAX_L2CAP_MTU 1024
12045 +#define RFCOMM_MAX_CREDITS 40
12047 +#define RFCOMM_SKB_HEAD_RESERVE 8
12048 +#define RFCOMM_SKB_TAIL_RESERVE 2
12049 +#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
12051 +#define RFCOMM_SABM 0x2f
12052 +#define RFCOMM_DISC 0x43
12053 +#define RFCOMM_UA 0x63
12054 +#define RFCOMM_DM 0x0f
12055 +#define RFCOMM_UIH 0xef
12057 +#define RFCOMM_TEST 0x08
12058 +#define RFCOMM_FCON 0x28
12059 +#define RFCOMM_FCOFF 0x18
12060 +#define RFCOMM_MSC 0x38
12061 +#define RFCOMM_RPN 0x24
12062 +#define RFCOMM_RLS 0x14
12063 +#define RFCOMM_PN 0x20
12064 +#define RFCOMM_NSC 0x04
12066 +#define RFCOMM_V24_FC 0x02
12067 +#define RFCOMM_V24_RTC 0x04
12068 +#define RFCOMM_V24_RTR 0x08
12069 +#define RFCOMM_V24_IC 0x40
12070 +#define RFCOMM_V24_DV 0x80
12072 +#define RFCOMM_RPN_BR_2400 0x0
12073 +#define RFCOMM_RPN_BR_4800 0x1
12074 +#define RFCOMM_RPN_BR_7200 0x2
12075 +#define RFCOMM_RPN_BR_9600 0x3
12076 +#define RFCOMM_RPN_BR_19200 0x4
12077 +#define RFCOMM_RPN_BR_38400 0x5
12078 +#define RFCOMM_RPN_BR_57600 0x6
12079 +#define RFCOMM_RPN_BR_115200 0x7
12080 +#define RFCOMM_RPN_BR_230400 0x8
12082 +#define RFCOMM_RPN_DATA_5 0x0
12083 +#define RFCOMM_RPN_DATA_6 0x1
12084 +#define RFCOMM_RPN_DATA_7 0x2
12085 +#define RFCOMM_RPN_DATA_8 0x3
12087 +#define RFCOMM_RPN_STOP_1 0
12088 +#define RFCOMM_RPN_STOP_15 1
12090 +#define RFCOMM_RPN_PARITY_NONE 0x0
12091 +#define RFCOMM_RPN_PARITY_ODD 0x4
12092 +#define RFCOMM_RPN_PARITY_EVEN 0x5
12093 +#define RFCOMM_RPN_PARITY_MARK 0x6
12094 +#define RFCOMM_RPN_PARITY_SPACE 0x7
12096 +#define RFCOMM_RPN_FLOW_NONE 0x00
12098 +#define RFCOMM_RPN_XON_CHAR 0x11
12099 +#define RFCOMM_RPN_XOFF_CHAR 0x13
12101 +#define RFCOMM_RPN_PM_BITRATE 0x0001
12102 +#define RFCOMM_RPN_PM_DATA 0x0002
12103 +#define RFCOMM_RPN_PM_STOP 0x0004
12104 +#define RFCOMM_RPN_PM_PARITY 0x0008
12105 +#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
12106 +#define RFCOMM_RPN_PM_XON 0x0020
12107 +#define RFCOMM_RPN_PM_XOFF 0x0040
12108 +#define RFCOMM_RPN_PM_FLOW 0x3F00
12110 +#define RFCOMM_RPN_PM_ALL 0x3F7F
12112 +struct rfcomm_hdr {
12115 + u8 len; // Actual size can be 2 bytes
12116 +} __attribute__ ((packed));
12118 +struct rfcomm_cmd {
12123 +} __attribute__ ((packed));
12125 +struct rfcomm_mcc {
12128 +} __attribute__ ((packed));
12130 +struct rfcomm_pn {
12138 +} __attribute__ ((packed));
12140 +struct rfcomm_rpn {
12143 + u8 line_settings;
12148 +} __attribute__ ((packed));
12150 +struct rfcomm_rls {
12153 +} __attribute__ ((packed));
12155 +struct rfcomm_msc {
12158 +} __attribute__ ((packed));
12160 +/* ---- Core structures, flags etc ---- */
12162 +struct rfcomm_session {
12163 + struct list_head list;
12164 + struct socket *sock;
12165 + unsigned long state;
12166 + unsigned long flags;
12170 + /* Default DLC parameters */
12174 + struct list_head dlcs;
12177 +struct rfcomm_dlc {
12178 + struct list_head list;
12179 + struct rfcomm_session *session;
12180 + struct sk_buff_head tx_queue;
12181 + struct timer_list timer;
12184 + unsigned long state;
12185 + unsigned long flags;
12200 + void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
12201 + void (*state_change)(struct rfcomm_dlc *d, int err);
12202 + void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
12205 +/* DLC and session flags */
12206 +#define RFCOMM_RX_THROTTLED 0
12207 +#define RFCOMM_TX_THROTTLED 1
12208 +#define RFCOMM_MSC_PENDING 2
12209 +#define RFCOMM_TIMED_OUT 3
12211 +/* Scheduling flags and events */
12212 +#define RFCOMM_SCHED_STATE 0
12213 +#define RFCOMM_SCHED_RX 1
12214 +#define RFCOMM_SCHED_TX 2
12215 +#define RFCOMM_SCHED_TIMEO 3
12216 +#define RFCOMM_SCHED_WAKEUP 31
12218 +/* MSC exchange flags */
12219 +#define RFCOMM_MSCEX_TX 1
12220 +#define RFCOMM_MSCEX_RX 2
12221 +#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
12223 +extern struct task_struct *rfcomm_thread;
12224 +extern unsigned long rfcomm_event;
12226 +static inline void rfcomm_schedule(uint event)
12228 + if (!rfcomm_thread)
12230 + set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
12231 + wake_up_process(rfcomm_thread);
12234 +extern struct semaphore rfcomm_sem;
12235 +#define rfcomm_lock() down(&rfcomm_sem);
12236 +#define rfcomm_unlock() up(&rfcomm_sem);
12238 +/* ---- RFCOMM DLCs (channels) ---- */
12239 +struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
12240 +void rfcomm_dlc_free(struct rfcomm_dlc *d);
12241 +int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
12242 +int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
12243 +int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
12244 +int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
12245 +int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
12247 +#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
12248 +#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
12250 +static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
12252 + atomic_inc(&d->refcnt);
12255 +static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
12257 + if (atomic_dec_and_test(&d->refcnt))
12258 + rfcomm_dlc_free(d);
12261 +extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
12262 +extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
12264 +static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
12266 + if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
12267 + __rfcomm_dlc_throttle(d);
12270 +static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
12272 + if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
12273 + __rfcomm_dlc_unthrottle(d);
12276 +/* ---- RFCOMM sessions ---- */
12277 +struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
12278 +struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
12279 +struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
12280 +void rfcomm_session_del(struct rfcomm_session *s);
12281 +void rfcomm_session_close(struct rfcomm_session *s, int err);
12282 +void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
12284 +static inline void rfcomm_session_hold(struct rfcomm_session *s)
12286 + atomic_inc(&s->refcnt);
12289 +static inline void rfcomm_session_put(struct rfcomm_session *s)
12291 + if (atomic_dec_and_test(&s->refcnt))
12292 + rfcomm_session_del(s);
12295 +/* ---- RFCOMM chechsum ---- */
12296 +extern u8 rfcomm_crc_table[];
12298 +/* ---- RFCOMM sockets ---- */
12299 +struct sockaddr_rc {
12300 + sa_family_t rc_family;
12301 + bdaddr_t rc_bdaddr;
12305 +#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
12307 +struct rfcomm_pinfo {
12308 + struct rfcomm_dlc *dlc;
12312 +int rfcomm_init_sockets(void);
12313 +void rfcomm_cleanup_sockets(void);
12315 +int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
12317 +/* ---- RFCOMM TTY ---- */
12318 +#define RFCOMM_MAX_DEV 256
12320 +#define RFCOMMCREATEDEV _IOW('R', 200, int)
12321 +#define RFCOMMRELEASEDEV _IOW('R', 201, int)
12322 +#define RFCOMMGETDEVLIST _IOR('R', 210, int)
12323 +#define RFCOMMGETDEVINFO _IOR('R', 211, int)
12324 +#define RFCOMMSTEALDLC _IOW('R', 220, int)
12326 +#define RFCOMM_REUSE_DLC 0
12327 +#define RFCOMM_RELEASE_ONHUP 1
12328 +#define RFCOMM_HANGUP_NOW 2
12329 +#define RFCOMM_TTY_ATTACHED 3
12331 +struct rfcomm_dev_req {
12339 +struct rfcomm_dev_info {
12348 +struct rfcomm_dev_list_req {
12350 + struct rfcomm_dev_info dev_info[0];
12353 +int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
12354 +int rfcomm_init_ttys(void);
12355 +void rfcomm_cleanup_ttys(void);
12357 +#endif /* __RFCOMM_H */
12358 diff -urN linux-2.4.18/include/net/bluetooth/sco.h linux-2.4.18-mh9/include/net/bluetooth/sco.h
12359 --- linux-2.4.18/include/net/bluetooth/sco.h Thu Jan 1 01:00:00 1970
12360 +++ linux-2.4.18-mh9/include/net/bluetooth/sco.h Mon Aug 25 18:38:12 2003
12363 + BlueZ - Bluetooth protocol stack for Linux
12364 + Copyright (C) 2000-2001 Qualcomm Incorporated
12366 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
12368 + This program is free software; you can redistribute it and/or modify
12369 + it under the terms of the GNU General Public License version 2 as
12370 + published by the Free Software Foundation;
12372 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12373 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12374 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12375 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
12376 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
12377 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12378 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12379 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12381 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
12382 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
12383 + SOFTWARE IS DISCLAIMED.
12387 + * $Id: sco.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
12393 +/* SCO defaults */
12394 +#define SCO_DEFAULT_MTU 500
12395 +#define SCO_DEFAULT_FLUSH_TO 0xFFFF
12397 +#define SCO_CONN_TIMEOUT (HZ * 40)
12398 +#define SCO_DISCONN_TIMEOUT (HZ * 2)
12399 +#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
12401 +/* SCO socket address */
12402 +struct sockaddr_sco {
12403 + sa_family_t sco_family;
12404 + bdaddr_t sco_bdaddr;
12407 +/* set/get sockopt defines */
12408 +#define SCO_OPTIONS 0x01
12409 +struct sco_options {
12413 +#define SCO_CONNINFO 0x02
12414 +struct sco_conninfo {
12415 + __u16 hci_handle;
12418 +/* ---- SCO connections ---- */
12420 + struct hci_conn *hcon;
12428 + unsigned int mtu;
12431 +#define sco_conn_lock(c) spin_lock(&c->lock);
12432 +#define sco_conn_unlock(c) spin_unlock(&c->lock);
12434 +/* ----- SCO socket info ----- */
12435 +#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
12437 +struct sco_pinfo {
12439 + struct sco_conn *conn;
12442 +#endif /* __SCO_H */
12443 diff -urN linux-2.4.18/include/pcmcia/ciscode.h linux-2.4.18-mh9/include/pcmcia/ciscode.h
12444 --- linux-2.4.18/include/pcmcia/ciscode.h Fri Dec 21 18:42:04 2001
12445 +++ linux-2.4.18-mh9/include/pcmcia/ciscode.h Mon Aug 25 18:38:12 2003
12448 - * ciscode.h 1.48 2001/08/24 12:16:12
12449 + * ciscode.h 1.57 2002/11/03 20:38:14
12451 * The contents of this file are subject to the Mozilla Public License
12452 * Version 1.1 (the "License"); you may not use this file except in
12454 #define PRODID_INTEL_DUAL_RS232 0x0301
12455 #define PRODID_INTEL_2PLUS 0x8422
12457 +#define MANFID_KME 0x0032
12458 +#define PRODID_KME_KXLC005_A 0x0704
12459 +#define PRODID_KME_KXLC005_B 0x2904
12461 #define MANFID_LINKSYS 0x0143
12462 #define PRODID_LINKSYS_PCMLM28 0xc0ab
12463 #define PRODID_LINKSYS_3400 0x3341
12465 #define PRODID_OSITECH_JACK_336 0x0007
12466 #define PRODID_OSITECH_SEVEN 0x0008
12468 +#define MANFID_OXSEMI 0x0279
12470 #define MANFID_PIONEER 0x000b
12472 #define MANFID_PSION 0x016c
12473 @@ -103,6 +109,7 @@
12474 #define PRODID_QUATECH_SPP100 0x0003
12475 #define PRODID_QUATECH_DUAL_RS232 0x0012
12476 #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
12477 +#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
12478 #define PRODID_QUATECH_QUAD_RS232 0x001b
12479 #define PRODID_QUATECH_DUAL_RS422 0x000e
12480 #define PRODID_QUATECH_QUAD_RS422 0x0045
12481 @@ -120,8 +127,11 @@
12483 #define MANFID_TDK 0x0105
12484 #define PRODID_TDK_CF010 0x0900
12485 +#define PRODID_TDK_GN3410 0x4815
12487 #define MANFID_TOSHIBA 0x0098
12489 +#define MANFID_UNGERMANN 0x02c0
12491 #define MANFID_XIRCOM 0x0105
12493 diff -urN linux-2.4.18/lib/Config.in linux-2.4.18-mh9/lib/Config.in
12494 --- linux-2.4.18/lib/Config.in Thu Jan 1 01:00:00 1970
12495 +++ linux-2.4.18-mh9/lib/Config.in Mon Aug 25 18:38:12 2003
12498 +# Library configuration
12500 +mainmenu_option next_comment
12501 +comment 'Library routines'
12503 +if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
12504 + "$CONFIG_HOTPLUG" = "y" ]; then
12505 + tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
12509 diff -urN linux-2.4.18/lib/Makefile linux-2.4.18-mh9/lib/Makefile
12510 --- linux-2.4.18/lib/Makefile Tue Sep 18 00:31:15 2001
12511 +++ linux-2.4.18-mh9/lib/Makefile Mon Aug 25 18:38:12 2003
12516 -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
12517 +export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
12520 obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
12522 +obj-$(CONFIG_FW_LOADER) += firmware_class.o
12523 obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
12524 obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
12526 +include $(TOPDIR)/drivers/bluetooth/Makefile.lib
12528 ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
12529 obj-y += dec_and_lock.o
12530 diff -urN linux-2.4.18/lib/firmware_class.c linux-2.4.18-mh9/lib/firmware_class.c
12531 --- linux-2.4.18/lib/firmware_class.c Thu Jan 1 01:00:00 1970
12532 +++ linux-2.4.18-mh9/lib/firmware_class.c Mon Aug 25 18:38:12 2003
12535 + * firmware_class.c - Multi purpose firmware loading support
12537 + * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
12539 + * Please see Documentation/firmware_class/ for more information.
12543 + * Based on kernel/kmod.c and drivers/usb/usb.c
12549 + Reorganized not to be a daemon by Adam Richter, with guidance
12550 + from Greg Zornetzer.
12552 + Modified to avoid chroot and file sharing problems.
12553 + Mikael Pettersson
12555 + Limit the concurrent number of kmod modprobes to catch loops from
12556 + "modprobe needs a service that is in a module".
12557 + Keith Owens <kaos@ocs.com.au> December 1999
12559 + Unblock all signals when we exec a usermode process.
12560 + Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
12563 + * drivers/usb/usb.c
12565 + * (C) Copyright Linus Torvalds 1999
12566 + * (C) Copyright Johannes Erdfelt 1999-2001
12567 + * (C) Copyright Andreas Gal 1999
12568 + * (C) Copyright Gregory P. Smith 1999
12569 + * (C) Copyright Deti Fliegl 1999 (new USB architecture)
12570 + * (C) Copyright Randy Dunlap 2000
12571 + * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
12572 + * (C) Copyright Yggdrasil Computing, Inc. 2000
12573 + * (usb_device_id matching changes by Adam J. Richter)
12576 +#include <linux/config.h>
12577 +#include <linux/module.h>
12578 +#include <linux/string.h>
12579 +#include <linux/types.h>
12580 +#include <linux/init.h>
12581 +#include <linux/slab.h>
12582 +#include <linux/kmod.h>
12583 +#include <linux/proc_fs.h>
12584 +#include <linux/vmalloc.h>
12585 +#include <asm/hardirq.h>
12587 +#include "linux/firmware.h"
12589 +MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
12590 +MODULE_DESCRIPTION("Multi purpose firmware loading support");
12591 +MODULE_LICENSE("GPL");
12593 +#define err(format, arg...) \
12594 + printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
12595 +#define warn(format, arg...) \
12596 + printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
12597 +#define dbg(format, arg...) \
12598 + printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
12600 +static int loading_timeout = 10; /* In seconds */
12601 +static struct proc_dir_entry *proc_dir_timeout;
12602 +static struct proc_dir_entry *proc_dir;
12604 +#ifdef CONFIG_HOTPLUG
12607 +call_helper(char *verb, const char *name, const char *device)
12609 + char *argv[3], **envp, *buf, *scratch;
12614 + if (!hotplug_path[0])
12616 + if (in_interrupt()) {
12617 + err("in_interrupt");
12620 + if (!current->fs->root) {
12621 + warn("call_policy %s -- no FS yet", verb);
12625 + if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
12626 + err("unable to allocate envp");
12629 + if (!(buf = kmalloc(256, GFP_KERNEL))) {
12631 + err("unable to allocate buf");
12635 + /* only one standardized param to hotplug command: type */
12636 + argv[0] = hotplug_path;
12637 + argv[1] = "firmware";
12640 + /* minimal command environment */
12641 + envp[i++] = "HOME=/";
12642 + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
12645 + /* hint that policy agent should enter no-stdout debug mode */
12646 + envp[i++] = "DEBUG=kernel";
12651 + envp[i++] = scratch;
12652 + scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
12653 + "DEVPATH=/driver/firmware/%s", device) + 1;
12656 + envp[i++] = scratch;
12657 + scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
12659 + envp[i++] = scratch;
12660 + scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
12661 + "FIRMWARE=%s", name) + 1;
12666 + dbg("firmware: %s %s %s", argv[0], argv[1], verb);
12669 + retval = call_usermodehelper(argv[0], argv, envp);
12671 + printk("call_usermodehelper return %d\n", retval);
12681 +call_helper(char *verb, const char *name, const char *device)
12686 +#endif /* CONFIG_HOTPLUG */
12688 +struct firmware_priv {
12689 + struct completion completion;
12690 + struct proc_dir_entry *proc_dir;
12691 + struct proc_dir_entry *attr_data;
12692 + struct proc_dir_entry *attr_loading;
12693 + struct firmware *fw;
12697 + struct timer_list timeout;
12701 +firmware_timeout_show(char *buf, char **start, off_t off,
12702 + int count, int *eof, void *data)
12704 + return sprintf(buf, "%d\n", loading_timeout);
12708 + * firmware_timeout_store:
12710 + * Sets the number of seconds to wait for the firmware. Once
12711 + * this expires an error will be return to the driver and no
12712 + * firmware will be provided.
12714 + * Note: zero means 'wait for ever'
12718 +firmware_timeout_store(struct file *file, const char *buf,
12719 + unsigned long count, void *data)
12721 + loading_timeout = simple_strtol(buf, NULL, 10);
12726 +firmware_loading_show(char *buf, char **start, off_t off,
12727 + int count, int *eof, void *data)
12729 + struct firmware_priv *fw_priv = data;
12730 + return sprintf(buf, "%d\n", fw_priv->loading);
12734 + * firmware_loading_store: - loading control file
12736 + * The relevant values are:
12738 + * 1: Start a load, discarding any previous partial load.
12739 + * 0: Conclude the load and handle the data to the driver code.
12740 + * -1: Conclude the load with an error and discard any written data.
12743 +firmware_loading_store(struct file *file, const char *buf,
12744 + unsigned long count, void *data)
12746 + struct firmware_priv *fw_priv = data;
12747 + int prev_loading = fw_priv->loading;
12749 + fw_priv->loading = simple_strtol(buf, NULL, 10);
12751 + switch (fw_priv->loading) {
12753 + fw_priv->abort = 1;
12755 + complete(&fw_priv->completion);
12758 + kfree(fw_priv->fw->data);
12759 + fw_priv->fw->data = NULL;
12760 + fw_priv->fw->size = 0;
12761 + fw_priv->alloc_size = 0;
12764 + if (prev_loading == 1)
12765 + complete(&fw_priv->completion);
12773 +firmware_data_read(char *buffer, char **start, off_t offset,
12774 + int count, int *eof, void *data)
12776 + struct firmware_priv *fw_priv = data;
12777 + struct firmware *fw = fw_priv->fw;
12779 + if (offset > fw->size)
12781 + if (offset + count > fw->size)
12782 + count = fw->size - offset;
12784 + memcpy(buffer, fw->data + offset, count);
12785 + *start = (void *) ((long) count);
12789 +fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
12794 + if (min_size <= fw_priv->alloc_size)
12796 + if((min_size % PAGE_SIZE) == 0)
12797 + new_size = min_size;
12799 + new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
12800 + new_data = vmalloc(new_size);
12802 + printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
12803 + /* Make sure that we don't keep incomplete data */
12804 + fw_priv->abort = 1;
12807 + fw_priv->alloc_size = new_size;
12808 + if (fw_priv->fw->data) {
12809 + memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
12810 + vfree(fw_priv->fw->data);
12812 + fw_priv->fw->data = new_data;
12813 + BUG_ON(min_size > fw_priv->alloc_size);
12818 + * firmware_data_write:
12822 + * Data written to the 'data' attribute will be later handled to
12823 + * the driver as a firmware image.
12826 +firmware_data_write(struct file *file, const char *buffer,
12827 + unsigned long count, void *data)
12829 + struct firmware_priv *fw_priv = data;
12830 + struct firmware *fw = fw_priv->fw;
12831 + int offset = file->f_pos;
12834 + retval = fw_realloc_buffer(fw_priv, offset + count);
12836 + printk("%s: retval:%d\n", __FUNCTION__, retval);
12840 + memcpy(fw->data + offset, buffer, count);
12842 + fw->size = max_t(size_t, offset + count, fw->size);
12843 + file->f_pos += count;
12848 +firmware_class_timeout(u_long data)
12850 + struct firmware_priv *fw_priv = (struct firmware_priv *) data;
12851 + fw_priv->abort = 1;
12853 + complete(&fw_priv->completion);
12856 +fw_setup_class_device(struct firmware_priv **fw_priv_p,
12857 + const char *fw_name, const char *device)
12860 + struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
12862 + *fw_priv_p = fw_priv;
12864 + retval = -ENOMEM;
12867 + memset(fw_priv, 0, sizeof (*fw_priv));
12869 + init_completion(&fw_priv->completion);
12871 + fw_priv->timeout.function = firmware_class_timeout;
12872 + fw_priv->timeout.data = (u_long) fw_priv;
12873 + init_timer(&fw_priv->timeout);
12875 + retval = -EAGAIN;
12876 + fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
12877 + if (!fw_priv->proc_dir)
12878 + goto err_free_fw_priv;
12880 + fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
12881 + fw_priv->proc_dir);
12882 + if (!fw_priv->attr_data)
12883 + goto err_remove_dir;
12885 + fw_priv->attr_data->read_proc = firmware_data_read;
12886 + fw_priv->attr_data->write_proc = firmware_data_write;
12887 + fw_priv->attr_data->data = fw_priv;
12889 + fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
12890 + fw_priv->proc_dir);
12891 + if (!fw_priv->attr_loading)
12892 + goto err_remove_data;
12894 + fw_priv->attr_loading->read_proc = firmware_loading_show;
12895 + fw_priv->attr_loading->write_proc = firmware_loading_store;
12896 + fw_priv->attr_loading->data = fw_priv;
12899 + fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
12900 + if (!fw_priv->fw) {
12901 + printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
12903 + retval = -ENOMEM;
12904 + goto err_remove_loading;
12906 + memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
12910 +err_remove_loading:
12911 + remove_proc_entry("loading", fw_priv->proc_dir);
12913 + remove_proc_entry("data", fw_priv->proc_dir);
12915 + remove_proc_entry(device, proc_dir);
12922 +fw_remove_class_device(struct firmware_priv *fw_priv)
12924 + remove_proc_entry("loading", fw_priv->proc_dir);
12925 + remove_proc_entry("data", fw_priv->proc_dir);
12926 + remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
12930 + * request_firmware: - request firmware to hotplug and wait for it
12932 + * @firmware will be used to return a firmware image by the name
12933 + * of @name for device @device.
12935 + * Should be called from user context where sleeping is allowed.
12937 + * @name will be use as $FIRMWARE in the hotplug environment and
12938 + * should be distinctive enough not to be confused with any other
12939 + * firmware image for this or any other device.
12942 +request_firmware(const struct firmware **firmware, const char *name,
12943 + const char *device)
12945 + struct firmware_priv *fw_priv;
12949 + retval = -EINVAL;
12952 + *firmware = NULL;
12954 + retval = fw_setup_class_device(&fw_priv, name, device);
12958 + retval = call_helper("add", name, device);
12961 + if (loading_timeout) {
12962 + fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
12963 + add_timer(&fw_priv->timeout);
12966 + wait_for_completion(&fw_priv->completion);
12968 + del_timer(&fw_priv->timeout);
12969 + fw_remove_class_device(fw_priv);
12971 + if (fw_priv->fw->size && !fw_priv->abort) {
12972 + *firmware = fw_priv->fw;
12974 + retval = -ENOENT;
12975 + vfree(fw_priv->fw->data);
12976 + kfree(fw_priv->fw);
12984 +release_firmware(const struct firmware *fw)
12993 + * register_firmware: - provide a firmware image for later usage
12996 + * Make sure that @data will be available by requesting firmware @name.
12998 + * Note: This will not be possible until some kind of persistence
13002 +register_firmware(const char *name, const u8 *data, size_t size)
13004 + /* This is meaningless without firmware caching, so until we
13005 + * decide if firmware caching is reasonable just leave it as a
13009 +/* Async support */
13010 +struct firmware_work {
13011 + struct tq_struct work;
13012 + struct module *module;
13013 + const char *name;
13014 + const char *device;
13016 + void (*cont)(const struct firmware *fw, void *context);
13020 +request_firmware_work_func(void *arg)
13022 + struct firmware_work *fw_work = arg;
13023 + const struct firmware *fw;
13026 + request_firmware(&fw, fw_work->name, fw_work->device);
13027 + fw_work->cont(fw, fw_work->context);
13028 + release_firmware(fw);
13029 + __MOD_DEC_USE_COUNT(fw_work->module);
13034 + * request_firmware_nowait:
13037 + * Asynchronous variant of request_firmware() for contexts where
13038 + * it is not possible to sleep.
13040 + * @cont will be called asynchronously when the firmware request is over.
13042 + * @context will be passed over to @cont.
13044 + * @fw may be %NULL if firmware request fails.
13048 +request_firmware_nowait(
13049 + struct module *module,
13050 + const char *name, const char *device, void *context,
13051 + void (*cont)(const struct firmware *fw, void *context))
13053 + struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
13057 + if (!try_inc_mod_count(module)) {
13062 + *fw_work = (struct firmware_work) {
13063 + .module = module,
13065 + .device = device,
13066 + .context = context,
13069 + INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
13071 + schedule_task(&fw_work->work);
13076 +firmware_class_init(void)
13078 + proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
13081 + proc_dir_timeout = create_proc_entry("timeout",
13082 + 0644 | S_IFREG, proc_dir);
13083 + if (!proc_dir_timeout) {
13084 + remove_proc_entry("driver/firmware", NULL);
13087 + proc_dir_timeout->read_proc = firmware_timeout_show;
13088 + proc_dir_timeout->write_proc = firmware_timeout_store;
13091 +static void __exit
13092 +firmware_class_exit(void)
13094 + remove_proc_entry("timeout", proc_dir);
13095 + remove_proc_entry("driver/firmware", NULL);
13098 +module_init(firmware_class_init);
13099 +module_exit(firmware_class_exit);
13101 +EXPORT_SYMBOL(release_firmware);
13102 +EXPORT_SYMBOL(request_firmware);
13103 +EXPORT_SYMBOL(request_firmware_nowait);
13104 +EXPORT_SYMBOL(register_firmware);
13105 diff -urN linux-2.4.18/net/bluetooth/Config.in linux-2.4.18-mh9/net/bluetooth/Config.in
13106 --- linux-2.4.18/net/bluetooth/Config.in Tue Jun 12 04:15:27 2001
13107 +++ linux-2.4.18-mh9/net/bluetooth/Config.in Mon Aug 25 18:38:12 2003
13110 -# Bluetooth configuration
13111 +# Bluetooth subsystem configuration
13114 if [ "$CONFIG_NET" != "n" ]; then
13116 mainmenu_option next_comment
13117 comment 'Bluetooth support'
13118 dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
13120 if [ "$CONFIG_BLUEZ" != "n" ]; then
13121 dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
13122 + dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
13123 + source net/bluetooth/rfcomm/Config.in
13124 + source net/bluetooth/bnep/Config.in
13125 + source net/bluetooth/cmtp/Config.in
13126 source drivers/bluetooth/Config.in
13132 diff -urN linux-2.4.18/net/bluetooth/Makefile linux-2.4.18-mh9/net/bluetooth/Makefile
13133 --- linux-2.4.18/net/bluetooth/Makefile Tue Jun 12 04:15:27 2001
13134 +++ linux-2.4.18-mh9/net/bluetooth/Makefile Mon Aug 25 18:38:12 2003
13137 -# Makefile for the Bluetooth subsystem
13138 +# Makefile for the Linux Bluetooth subsystem
13140 -O_TARGET := bluetooth.o
13142 -list-multi := hci.o l2cap.o
13143 -export-objs := syms.o
13144 -hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
13145 -l2cap-objs := l2cap_core.o l2cap_proc.o
13146 +O_TARGET := bluetooth.o
13148 -obj-$(CONFIG_BLUEZ) += hci.o
13149 +list-multi := bluez.o
13150 +export-objs := syms.o l2cap.o
13152 +bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
13154 +obj-$(CONFIG_BLUEZ) += bluez.o
13155 obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
13156 +obj-$(CONFIG_BLUEZ_SCO) += sco.o
13158 -include $(TOPDIR)/Rules.make
13159 +subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
13160 +subdir-$(CONFIG_BLUEZ_BNEP) += bnep
13161 +subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
13163 -hci.o: $(hci-objs)
13164 - $(LD) -r -o $@ $(hci-objs)
13165 +ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
13166 +obj-y += rfcomm/rfcomm.o
13169 +ifeq ($(CONFIG_BLUEZ_BNEP),y)
13170 +obj-y += bnep/bnep.o
13173 +include $(TOPDIR)/Rules.make
13175 -l2cap.o: $(l2cap-objs)
13176 - $(LD) -r -o $@ $(l2cap-objs)
13177 +bluez.o: $(bluez-objs)
13178 + $(LD) -r -o $@ $(bluez-objs)
13179 diff -urN linux-2.4.18/net/bluetooth/af_bluetooth.c linux-2.4.18-mh9/net/bluetooth/af_bluetooth.c
13180 --- linux-2.4.18/net/bluetooth/af_bluetooth.c Fri Sep 7 18:28:38 2001
13181 +++ linux-2.4.18-mh9/net/bluetooth/af_bluetooth.c Mon Aug 25 18:38:12 2003
13182 @@ -25,14 +25,15 @@
13184 * BlueZ Bluetooth address family and sockets.
13186 - * $Id: af_bluetooth.c,v 1.4 2001/07/05 18:42:44 maxk Exp $
13187 + * $Id: af_bluetooth.c,v 1.8 2002/07/22 20:32:54 maxk Exp $
13189 -#define VERSION "1.1"
13190 +#define VERSION "2.4"
13192 #include <linux/config.h>
13193 #include <linux/module.h>
13195 #include <linux/types.h>
13196 +#include <linux/list.h>
13197 #include <linux/errno.h>
13198 #include <linux/kernel.h>
13199 #include <linux/major.h>
13201 #include <linux/slab.h>
13202 #include <linux/skbuff.h>
13203 #include <linux/init.h>
13204 +#include <linux/poll.h>
13205 #include <linux/proc_fs.h>
13206 #include <net/sock.h>
13208 @@ -48,70 +50,79 @@
13211 #include <net/bluetooth/bluetooth.h>
13212 -#include <net/bluetooth/bluez.h>
13214 +#ifndef AF_BLUETOOTH_DEBUG
13216 +#define BT_DBG( A... )
13219 /* Bluetooth sockets */
13220 -static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
13221 +#define BLUEZ_MAX_PROTO 6
13222 +static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
13224 int bluez_sock_register(int proto, struct net_proto_family *ops)
13226 - if (proto > BLUEZ_MAX_PROTO)
13227 + if (proto >= BLUEZ_MAX_PROTO)
13230 - if (bluez_sock[proto])
13231 + if (bluez_proto[proto])
13234 - bluez_sock[proto] = ops;
13235 + bluez_proto[proto] = ops;
13239 int bluez_sock_unregister(int proto)
13241 - if (proto > BLUEZ_MAX_PROTO)
13242 + if (proto >= BLUEZ_MAX_PROTO)
13245 - if (!bluez_sock[proto])
13246 + if (!bluez_proto[proto])
13249 - bluez_sock[proto] = NULL;
13250 + bluez_proto[proto] = NULL;
13254 static int bluez_sock_create(struct socket *sock, int proto)
13256 - if (proto > BLUEZ_MAX_PROTO)
13257 + if (proto >= BLUEZ_MAX_PROTO)
13260 #if defined(CONFIG_KMOD)
13261 - if (!bluez_sock[proto]) {
13262 + if (!bluez_proto[proto]) {
13263 char module_name[30];
13264 sprintf(module_name, "bt-proto-%d", proto);
13265 request_module(module_name);
13269 - if (!bluez_sock[proto])
13270 + if (!bluez_proto[proto])
13273 - return bluez_sock[proto]->create(sock, proto);
13274 + return bluez_proto[proto]->create(sock, proto);
13277 +void bluez_sock_init(struct socket *sock, struct sock *sk)
13279 + sock_init_data(sock, sk);
13280 + INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
13283 void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
13285 - write_lock(&l->lock);
13287 + write_lock_bh(&l->lock);
13288 sk->next = l->head;
13292 - write_unlock(&l->lock);
13293 + write_unlock_bh(&l->lock);
13296 void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
13300 - write_lock(&l->lock);
13301 + write_lock_bh(&l->lock);
13302 for (skp = &l->head; *skp; skp = &((*skp)->next)) {
13305 @@ -119,7 +130,162 @@
13309 - write_unlock(&l->lock);
13310 + write_unlock_bh(&l->lock);
13313 +void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
13315 + BT_DBG("parent %p, sk %p", parent, sk);
13318 + list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
13319 + bluez_pi(sk)->parent = parent;
13320 + parent->ack_backlog++;
13323 +static void bluez_accept_unlink(struct sock *sk)
13325 + BT_DBG("sk %p state %d", sk, sk->state);
13327 + list_del_init(&bluez_pi(sk)->accept_q);
13328 + bluez_pi(sk)->parent->ack_backlog--;
13329 + bluez_pi(sk)->parent = NULL;
13333 +struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
13335 + struct list_head *p, *n;
13336 + struct bluez_pinfo *pi;
13339 + BT_DBG("parent %p", parent);
13341 + list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
13342 + pi = list_entry(p, struct bluez_pinfo, accept_q);
13343 + sk = bluez_sk(pi);
13346 + if (sk->state == BT_CLOSED) {
13347 + release_sock(sk);
13348 + bluez_accept_unlink(sk);
13352 + if (sk->state == BT_CONNECTED || !newsock) {
13353 + bluez_accept_unlink(sk);
13355 + sock_graft(sk, newsock);
13356 + release_sock(sk);
13359 + release_sock(sk);
13364 +int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
13366 + int noblock = flags & MSG_DONTWAIT;
13367 + struct sock *sk = sock->sk;
13368 + struct sk_buff *skb;
13371 + BT_DBG("sock %p sk %p len %d", sock, sk, len);
13373 + if (flags & (MSG_OOB))
13374 + return -EOPNOTSUPP;
13376 + if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
13377 + if (sk->shutdown & RCV_SHUTDOWN)
13382 + msg->msg_namelen = 0;
13384 + copied = skb->len;
13385 + if (len < copied) {
13386 + msg->msg_flags |= MSG_TRUNC;
13390 + skb->h.raw = skb->data;
13391 + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
13393 + skb_free_datagram(sk, skb);
13395 + return err ? : copied;
13398 +unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
13400 + struct sock *sk = sock->sk;
13401 + unsigned int mask;
13403 + BT_DBG("sock %p, sk %p", sock, sk);
13405 + poll_wait(file, sk->sleep, wait);
13408 + if (sk->err || !skb_queue_empty(&sk->error_queue))
13411 + if (sk->shutdown == SHUTDOWN_MASK)
13414 + if (!skb_queue_empty(&sk->receive_queue) ||
13415 + !list_empty(&bluez_pi(sk)->accept_q) ||
13416 + (sk->shutdown & RCV_SHUTDOWN))
13417 + mask |= POLLIN | POLLRDNORM;
13419 + if (sk->state == BT_CLOSED)
13422 + if (sk->state == BT_CONNECT || sk->state == BT_CONNECT2)
13425 + if (sock_writeable(sk))
13426 + mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
13428 + set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
13433 +int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
13435 + DECLARE_WAITQUEUE(wait, current);
13438 + BT_DBG("sk %p", sk);
13440 + add_wait_queue(sk->sleep, &wait);
13441 + while (sk->state != state) {
13442 + set_current_state(TASK_INTERRUPTIBLE);
13449 + if (signal_pending(current)) {
13450 + err = sock_intr_errno(timeo);
13454 + release_sock(sk);
13455 + timeo = schedule_timeout(timeo);
13459 + err = sock_error(sk);
13463 + set_current_state(TASK_RUNNING);
13464 + remove_wait_queue(sk->sleep, &wait);
13468 struct net_proto_family bluez_sock_family_ops =
13469 @@ -129,9 +295,9 @@
13471 int bluez_init(void)
13473 - INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
13474 + BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
13476 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
13477 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
13479 proc_mkdir("bluetooth", NULL);
13481 @@ -164,5 +330,6 @@
13482 module_exit(bluez_cleanup);
13484 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
13485 -MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
13486 +MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
13487 +MODULE_LICENSE("GPL");
13489 diff -urN linux-2.4.18/net/bluetooth/bnep/Config.in linux-2.4.18-mh9/net/bluetooth/bnep/Config.in
13490 --- linux-2.4.18/net/bluetooth/bnep/Config.in Thu Jan 1 01:00:00 1970
13491 +++ linux-2.4.18-mh9/net/bluetooth/bnep/Config.in Mon Aug 25 18:38:12 2003
13494 +# Bluetooth BNEP layer configuration
13497 +dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
13499 +if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
13500 + bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
13501 + bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
13504 diff -urN linux-2.4.18/net/bluetooth/bnep/Makefile linux-2.4.18-mh9/net/bluetooth/bnep/Makefile
13505 --- linux-2.4.18/net/bluetooth/bnep/Makefile Thu Jan 1 01:00:00 1970
13506 +++ linux-2.4.18-mh9/net/bluetooth/bnep/Makefile Mon Aug 25 18:38:12 2003
13509 +# Makefile for the Linux Bluetooth BNEP layer
13512 +O_TARGET := bnep.o
13514 +obj-y := core.o sock.o netdev.o crc32.o
13515 +obj-m += $(O_TARGET)
13517 +include $(TOPDIR)/Rules.make
13518 diff -urN linux-2.4.18/net/bluetooth/bnep/bnep.h linux-2.4.18-mh9/net/bluetooth/bnep/bnep.h
13519 --- linux-2.4.18/net/bluetooth/bnep/bnep.h Thu Jan 1 01:00:00 1970
13520 +++ linux-2.4.18-mh9/net/bluetooth/bnep/bnep.h Mon Aug 25 18:38:12 2003
13523 + BNEP protocol definition for Linux Bluetooth stack (BlueZ).
13524 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
13526 + This program is free software; you can redistribute it and/or modify
13527 + it under the terms of the GNU General Public License, version 2, as
13528 + published by the Free Software Foundation.
13530 + This program is distributed in the hope that it will be useful,
13531 + but WITHOUT ANY WARRANTY; without even the implied warranty of
13532 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13533 + GNU General Public License for more details.
13535 + You should have received a copy of the GNU General Public License
13536 + along with this program; if not, write to the Free Software
13537 + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13541 + * $Id: bnep2.h,v 1.9 2002/07/14 07:09:19 maxk Exp $
13547 +#include <linux/types.h>
13548 +#include <net/bluetooth/bluetooth.h>
13550 +#include "crc32.h"
13553 +#define BNEP_MAX_PROTO_FILTERS 5
13554 +#define BNEP_MAX_MULTICAST_FILTERS 20
13557 +#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
13558 +#define BNEP_UUID16 0x02
13559 +#define BNEP_UUID32 0x04
13560 +#define BNEP_UUID128 0x16
13562 +#define BNEP_SVC_PANU 0x1115
13563 +#define BNEP_SVC_NAP 0x1116
13564 +#define BNEP_SVC_GN 0x1117
13567 +#define BNEP_GENERAL 0x00
13568 +#define BNEP_CONTROL 0x01
13569 +#define BNEP_COMPRESSED 0x02
13570 +#define BNEP_COMPRESSED_SRC_ONLY 0x03
13571 +#define BNEP_COMPRESSED_DST_ONLY 0x04
13574 +#define BNEP_CMD_NOT_UNDERSTOOD 0x00
13575 +#define BNEP_SETUP_CONN_REQ 0x01
13576 +#define BNEP_SETUP_CONN_RSP 0x02
13577 +#define BNEP_FILTER_NET_TYPE_SET 0x03
13578 +#define BNEP_FILTER_NET_TYPE_RSP 0x04
13579 +#define BNEP_FILTER_MULTI_ADDR_SET 0x05
13580 +#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
13582 +// Extension types
13583 +#define BNEP_EXT_CONTROL 0x00
13585 +// Response messages
13586 +#define BNEP_SUCCESS 0x00
13588 +#define BNEP_CONN_INVALID_DST 0x01
13589 +#define BNEP_CONN_INVALID_SRC 0x02
13590 +#define BNEP_CONN_INVALID_SVC 0x03
13591 +#define BNEP_CONN_NOT_ALLOWED 0x04
13593 +#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
13594 +#define BNEP_FILTER_INVALID_RANGE 0x02
13595 +#define BNEP_FILTER_INVALID_MCADDR 0x02
13596 +#define BNEP_FILTER_LIMIT_REACHED 0x03
13597 +#define BNEP_FILTER_DENIED_SECURITY 0x04
13600 +#define BNEP_MTU 1691
13601 +#define BNEP_PSM 0x0f
13602 +#define BNEP_FLUSH_TO 0xffff
13603 +#define BNEP_CONNECT_TO 15
13604 +#define BNEP_FILTER_TO 15
13607 +#define BNEP_TYPE_MASK 0x7f
13608 +#define BNEP_EXT_HEADER 0x80
13610 +struct bnep_setup_conn_req {
13615 +} __attribute__((packed));
13617 +struct bnep_set_filter_req {
13622 +} __attribute__((packed));
13624 +struct bnep_control_rsp {
13628 +} __attribute__((packed));
13630 +struct bnep_ext_hdr {
13634 +} __attribute__((packed));
13636 +/* BNEP ioctl defines */
13637 +#define BNEPCONNADD _IOW('B', 200, int)
13638 +#define BNEPCONNDEL _IOW('B', 201, int)
13639 +#define BNEPGETCONNLIST _IOR('B', 210, int)
13640 +#define BNEPGETCONNINFO _IOR('B', 211, int)
13642 +struct bnep_connadd_req {
13643 + int sock; // Connected socket
13646 + char device[16]; // Name of the Ethernet device
13649 +struct bnep_conndel_req {
13651 + __u8 dst[ETH_ALEN];
13654 +struct bnep_conninfo {
13658 + __u8 dst[ETH_ALEN];
13662 +struct bnep_connlist_req {
13664 + struct bnep_conninfo *ci;
13667 +struct bnep_proto_filter {
13672 +int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
13673 +int bnep_del_connection(struct bnep_conndel_req *req);
13674 +int bnep_get_connlist(struct bnep_connlist_req *req);
13675 +int bnep_get_conninfo(struct bnep_conninfo *ci);
13678 +struct bnep_session {
13679 + struct list_head list;
13681 + unsigned int role;
13682 + unsigned long state;
13683 + unsigned long flags;
13686 + struct ethhdr eh;
13687 + struct msghdr msg;
13689 + struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
13692 + struct socket *sock;
13693 + struct net_device dev;
13694 + struct net_device_stats stats;
13697 +int bnep_net_init(struct net_device *dev);
13698 +int bnep_sock_init(void);
13699 +int bnep_sock_cleanup(void);
13701 +static inline int bnep_mc_hash(__u8 *addr)
13703 + return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
13707 diff -urN linux-2.4.18/net/bluetooth/bnep/core.c linux-2.4.18-mh9/net/bluetooth/bnep/core.c
13708 --- linux-2.4.18/net/bluetooth/bnep/core.c Thu Jan 1 01:00:00 1970
13709 +++ linux-2.4.18-mh9/net/bluetooth/bnep/core.c Mon Aug 25 18:38:12 2003
13712 + BNEP implementation for Linux Bluetooth stack (BlueZ).
13713 + Copyright (C) 2001-2002 Inventel Systemes
13714 + Written 2001-2002 by
13715 + Clément Moreau <clement.moreau@inventel.fr>
13716 + David Libault <david.libault@inventel.fr>
13718 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
13720 + This program is free software; you can redistribute it and/or modify
13721 + it under the terms of the GNU General Public License version 2 as
13722 + published by the Free Software Foundation;
13724 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
13725 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13726 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
13727 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13728 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
13729 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13730 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13731 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13733 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
13734 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
13735 + SOFTWARE IS DISCLAIMED.
13739 + * $Id: core.c,v 1.18 2002/07/14 07:09:19 maxk Exp $
13742 +#define __KERNEL_SYSCALLS__
13744 +#include <linux/config.h>
13745 +#include <linux/module.h>
13747 +#include <linux/kernel.h>
13748 +#include <linux/sched.h>
13749 +#include <linux/signal.h>
13750 +#include <linux/init.h>
13751 +#include <linux/wait.h>
13752 +#include <linux/errno.h>
13753 +#include <linux/smp_lock.h>
13754 +#include <linux/net.h>
13755 +#include <net/sock.h>
13757 +#include <linux/socket.h>
13758 +#include <linux/file.h>
13760 +#include <linux/netdevice.h>
13761 +#include <linux/etherdevice.h>
13762 +#include <linux/skbuff.h>
13764 +#include <asm/unaligned.h>
13766 +#include <net/bluetooth/bluetooth.h>
13767 +#include <net/bluetooth/l2cap.h>
13771 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
13773 +#define BT_DBG(D...)
13776 +#define VERSION "1.1"
13778 +static LIST_HEAD(bnep_session_list);
13779 +static DECLARE_RWSEM(bnep_session_sem);
13781 +static struct bnep_session *__bnep_get_session(u8 *dst)
13783 + struct bnep_session *s;
13784 + struct list_head *p;
13788 + list_for_each(p, &bnep_session_list) {
13789 + s = list_entry(p, struct bnep_session, list);
13790 + if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
13796 +static void __bnep_link_session(struct bnep_session *s)
13798 + MOD_INC_USE_COUNT;
13799 + list_add(&s->list, &bnep_session_list);
13802 +static void __bnep_unlink_session(struct bnep_session *s)
13804 + list_del(&s->list);
13805 + MOD_DEC_USE_COUNT;
13808 +static int bnep_send(struct bnep_session *s, void *data, size_t len)
13810 + struct socket *sock = s->sock;
13811 + struct iovec iv = { data, len };
13812 + s->msg.msg_iov = &iv;
13813 + s->msg.msg_iovlen = 1;
13814 + return sock->ops->sendmsg(sock, &s->msg, len, NULL);
13817 +static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
13819 + struct bnep_control_rsp rsp;
13820 + rsp.type = BNEP_CONTROL;
13822 + rsp.resp = htons(resp);
13823 + return bnep_send(s, &rsp, sizeof(rsp));
13826 +static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
13833 + n = ntohs(get_unaligned(data));
13834 + data++; len -= 2;
13839 + BT_DBG("filter len %d", n);
13841 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
13843 + if (n <= BNEP_MAX_PROTO_FILTERS) {
13844 + struct bnep_proto_filter *f = s->proto_filter;
13847 + for (i = 0; i < n; i++) {
13848 + f[i].start = get_unaligned(data++);
13849 + f[i].end = get_unaligned(data++);
13851 + BT_DBG("proto filter start %d end %d",
13852 + f[i].start, f[i].end);
13854 + if (i < BNEP_MAX_PROTO_FILTERS)
13855 + memset(f + i, 0, sizeof(*f));
13857 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
13859 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
13862 + bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
13867 +static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
13874 + n = ntohs(get_unaligned((u16 *) data));
13875 + data += 2; len -= 2;
13880 + BT_DBG("filter len %d", n);
13882 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
13883 + n /= (ETH_ALEN * 2);
13886 + s->mc_filter = 0;
13888 + /* Always send broadcast */
13889 + set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
13891 + /* Add address ranges to the multicast hash */
13892 + for (; n > 0; n--) {
13895 + memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
13896 + a2 = data; data += ETH_ALEN;
13898 + BT_DBG("mc filter %s -> %s",
13899 + batostr((void *) a1), batostr((void *) a2));
13901 + #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
13903 + /* Iterate from a1 to a2 */
13904 + set_bit(bnep_mc_hash(a1), &s->mc_filter);
13905 + while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
13907 + set_bit(bnep_mc_hash(a1), &s->mc_filter);
13912 + BT_DBG("mc filter hash 0x%llx", s->mc_filter);
13914 + bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
13916 + bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
13921 +static int bnep_rx_control(struct bnep_session *s, void *data, int len)
13923 + u8 cmd = *(u8 *)data;
13929 + case BNEP_CMD_NOT_UNDERSTOOD:
13930 + case BNEP_SETUP_CONN_REQ:
13931 + case BNEP_SETUP_CONN_RSP:
13932 + case BNEP_FILTER_NET_TYPE_RSP:
13933 + case BNEP_FILTER_MULTI_ADDR_RSP:
13934 + /* Ignore these for now */
13937 + case BNEP_FILTER_NET_TYPE_SET:
13938 + err = bnep_ctrl_set_netfilter(s, data, len);
13941 + case BNEP_FILTER_MULTI_ADDR_SET:
13942 + err = bnep_ctrl_set_mcfilter(s, data, len);
13947 + pkt[0] = BNEP_CONTROL;
13948 + pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
13950 + bnep_send(s, pkt, sizeof(pkt));
13958 +static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
13960 + struct bnep_ext_hdr *h;
13964 + h = (void *) skb->data;
13965 + if (!skb_pull(skb, sizeof(*h))) {
13970 + BT_DBG("type 0x%x len %d", h->type, h->len);
13972 + switch (h->type & BNEP_TYPE_MASK) {
13973 + case BNEP_EXT_CONTROL:
13974 + bnep_rx_control(s, skb->data, skb->len);
13978 + /* Unknown extension, skip it. */
13982 + if (!skb_pull(skb, h->len)) {
13986 + } while (!err && (h->type & BNEP_EXT_HEADER));
13991 +static u8 __bnep_rx_hlen[] = {
13992 + ETH_HLEN, /* BNEP_GENERAL */
13993 + 0, /* BNEP_CONTROL */
13994 + 2, /* BNEP_COMPRESSED */
13995 + ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
13996 + ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
13998 +#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
14000 +static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
14002 + struct net_device *dev = &s->dev;
14003 + struct sk_buff *nskb;
14006 + dev->last_rx = jiffies;
14007 + s->stats.rx_bytes += skb->len;
14009 + type = *(u8 *) skb->data; skb_pull(skb, 1);
14011 + if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
14014 + if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
14015 + bnep_rx_control(s, skb->data, skb->len);
14020 + skb->mac.raw = skb->data;
14022 + /* Verify and pull out header */
14023 + if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
14026 + s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
14028 + if (type & BNEP_EXT_HEADER) {
14029 + if (bnep_rx_extension(s, skb) < 0)
14033 + /* Strip 802.1p header */
14034 + if (ntohs(s->eh.h_proto) == 0x8100) {
14035 + if (!skb_pull(skb, 4))
14037 + s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
14040 + /* We have to alloc new skb and copy data here :(. Because original skb
14041 + * may not be modified and because of the alignment requirements. */
14042 + nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
14044 + s->stats.rx_dropped++;
14048 + skb_reserve(nskb, 2);
14050 + /* Decompress header and construct ether frame */
14051 + switch (type & BNEP_TYPE_MASK) {
14052 + case BNEP_COMPRESSED:
14053 + memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
14056 + case BNEP_COMPRESSED_SRC_ONLY:
14057 + memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
14058 + memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
14059 + put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
14062 + case BNEP_COMPRESSED_DST_ONLY:
14063 + memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
14064 + memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
14067 + case BNEP_GENERAL:
14068 + memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
14069 + put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
14073 + memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
14076 + s->stats.rx_packets++;
14078 + nskb->ip_summed = CHECKSUM_UNNECESSARY;
14079 + nskb->protocol = eth_type_trans(nskb, dev);
14080 + netif_rx_ni(nskb);
14084 + s->stats.rx_errors++;
14089 +static u8 __bnep_tx_types[] = {
14091 + BNEP_COMPRESSED_SRC_ONLY,
14092 + BNEP_COMPRESSED_DST_ONLY,
14096 +static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
14098 + struct ethhdr *eh = (void *) skb->data;
14099 + struct socket *sock = s->sock;
14100 + struct iovec iv[3];
14101 + int len = 0, il = 0;
14104 + BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
14107 + /* Control frame sent by us */
14111 + iv[il++] = (struct iovec) { &type, 1 };
14114 + if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
14117 + if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
14121 + skb_pull(skb, ETH_ALEN * 2);
14123 + type = __bnep_tx_types[type];
14125 + case BNEP_COMPRESSED_SRC_ONLY:
14126 + iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
14130 + case BNEP_COMPRESSED_DST_ONLY:
14131 + iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
14137 + iv[il++] = (struct iovec) { skb->data, skb->len };
14140 + /* FIXME: linearize skb */
14142 + s->msg.msg_iov = iv;
14143 + s->msg.msg_iovlen = il;
14144 + len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
14148 + s->stats.tx_bytes += len;
14149 + s->stats.tx_packets++;
14156 +static int bnep_session(void *arg)
14158 + struct bnep_session *s = arg;
14159 + struct net_device *dev = &s->dev;
14160 + struct sock *sk = s->sock->sk;
14161 + struct sk_buff *skb;
14162 + wait_queue_t wait;
14166 + daemonize(); reparent_to_init();
14168 + sprintf(current->comm, "kbnepd %s", dev->name);
14170 + sigfillset(¤t->blocked);
14171 + flush_signals(current);
14173 + current->nice = -15;
14175 + set_fs(KERNEL_DS);
14177 + init_waitqueue_entry(&wait, current);
14178 + add_wait_queue(sk->sleep, &wait);
14179 + while (!atomic_read(&s->killed)) {
14180 + set_current_state(TASK_INTERRUPTIBLE);
14183 + while ((skb = skb_dequeue(&sk->receive_queue))) {
14185 + bnep_rx_frame(s, skb);
14188 + if (sk->state != BT_CONNECTED)
14192 + while ((skb = skb_dequeue(&sk->write_queue)))
14193 + if (bnep_tx_frame(s, skb))
14195 + netif_wake_queue(dev);
14199 + set_current_state(TASK_RUNNING);
14200 + remove_wait_queue(sk->sleep, &wait);
14202 + /* Cleanup session */
14203 + down_write(&bnep_session_sem);
14205 + /* Delete network device */
14206 + unregister_netdev(dev);
14208 + /* Release the socket */
14209 + fput(s->sock->file);
14211 + __bnep_unlink_session(s);
14213 + up_write(&bnep_session_sem);
14218 +int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
14220 + struct net_device *dev;
14221 + struct bnep_session *s, *ss;
14222 + u8 dst[ETH_ALEN], src[ETH_ALEN];
14227 + baswap((void *) dst, &bluez_pi(sock->sk)->dst);
14228 + baswap((void *) src, &bluez_pi(sock->sk)->src);
14230 + s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
14233 + memset(s, 0, sizeof(struct bnep_session));
14235 + down_write(&bnep_session_sem);
14237 + ss = __bnep_get_session(dst);
14238 + if (ss && ss->state == BT_CONNECTED) {
14245 + if (*req->device)
14246 + strcpy(dev->name, req->device);
14248 + strcpy(dev->name, "bnep%d");
14250 + memset(dev->broadcast, 0xff, ETH_ALEN);
14252 + /* This is rx header therefor addresses are swaped.
14253 + * ie eh.h_dest is our local address. */
14254 + memcpy(s->eh.h_dest, &src, ETH_ALEN);
14255 + memcpy(s->eh.h_source, &dst, ETH_ALEN);
14258 + s->role = req->role;
14259 + s->state = BT_CONNECTED;
14261 + s->msg.msg_flags = MSG_NOSIGNAL;
14263 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
14264 + /* Set default mc filter */
14265 + set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
14268 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
14269 + /* Set default protocol filter */
14271 + /* (IPv4, ARP) */
14272 + s->proto_filter[0].start = htons(0x0800);
14273 + s->proto_filter[0].end = htons(0x0806);
14274 + /* (RARP, AppleTalk) */
14275 + s->proto_filter[1].start = htons(0x8035);
14276 + s->proto_filter[1].end = htons(0x80F3);
14277 + /* (IPX, IPv6) */
14278 + s->proto_filter[2].start = htons(0x8137);
14279 + s->proto_filter[2].end = htons(0x86DD);
14282 + dev->init = bnep_net_init;
14284 + err = register_netdev(dev);
14289 + __bnep_link_session(s);
14291 + err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
14293 + /* Session thread start failed, gotta cleanup. */
14294 + unregister_netdev(dev);
14295 + __bnep_unlink_session(s);
14299 + up_write(&bnep_session_sem);
14300 + strcpy(req->device, dev->name);
14304 + up_write(&bnep_session_sem);
14309 +int bnep_del_connection(struct bnep_conndel_req *req)
14311 + struct bnep_session *s;
14316 + down_read(&bnep_session_sem);
14318 + s = __bnep_get_session(req->dst);
14320 + /* Wakeup user-space which is polling for socket errors.
14321 + * This is temporary hack untill we have shutdown in L2CAP */
14322 + s->sock->sk->err = EUNATCH;
14324 + /* Kill session thread */
14325 + atomic_inc(&s->killed);
14326 + wake_up_interruptible(s->sock->sk->sleep);
14330 + up_read(&bnep_session_sem);
14334 +static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
14336 + memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
14337 + strcpy(ci->device, s->dev.name);
14338 + ci->flags = s->flags;
14339 + ci->state = s->state;
14340 + ci->role = s->role;
14343 +int bnep_get_connlist(struct bnep_connlist_req *req)
14345 + struct list_head *p;
14346 + int err = 0, n = 0;
14348 + down_read(&bnep_session_sem);
14350 + list_for_each(p, &bnep_session_list) {
14351 + struct bnep_session *s;
14352 + struct bnep_conninfo ci;
14354 + s = list_entry(p, struct bnep_session, list);
14356 + __bnep_copy_ci(&ci, s);
14358 + if (copy_to_user(req->ci, &ci, sizeof(ci))) {
14363 + if (++n >= req->cnum)
14370 + up_read(&bnep_session_sem);
14374 +int bnep_get_conninfo(struct bnep_conninfo *ci)
14376 + struct bnep_session *s;
14379 + down_read(&bnep_session_sem);
14381 + s = __bnep_get_session(ci->dst);
14383 + __bnep_copy_ci(ci, s);
14387 + up_read(&bnep_session_sem);
14391 +static int __init bnep_init_module(void)
14395 + bnep_crc32_init();
14396 + bnep_sock_init();
14398 + BT_INFO("BlueZ BNEP ver %s", VERSION);
14399 + BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
14400 + BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
14401 + BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
14402 + BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
14407 +static void __exit bnep_cleanup_module(void)
14409 + bnep_sock_cleanup();
14410 + bnep_crc32_cleanup();
14413 +module_init(bnep_init_module);
14414 +module_exit(bnep_cleanup_module);
14416 +MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
14417 +MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
14418 +MODULE_LICENSE("GPL");
14419 diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.c linux-2.4.18-mh9/net/bluetooth/bnep/crc32.c
14420 --- linux-2.4.18/net/bluetooth/bnep/crc32.c Thu Jan 1 01:00:00 1970
14421 +++ linux-2.4.18-mh9/net/bluetooth/bnep/crc32.c Mon Aug 25 18:38:12 2003
14424 + * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
14426 + * FIXME: Remove in 2.5
14429 +#include <linux/kernel.h>
14430 +#include <linux/module.h>
14431 +#include <linux/types.h>
14432 +#include <linux/slab.h>
14433 +#include <linux/init.h>
14434 +#include <asm/atomic.h>
14436 +#include "crc32.h"
14438 +#define CRCPOLY_BE 0x04c11db7
14439 +#define CRC_BE_BITS 8
14441 +static u32 *bnep_crc32_table;
14444 + * This code is in the public domain; copyright abandoned.
14445 + * Liability for non-performance of this code is limited to the amount
14446 + * you paid for it. Since it is distributed for free, your refund will
14447 + * be very very small. If it breaks, you get to keep both pieces.
14449 +u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
14452 + crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
14457 +int __init bnep_crc32_init(void)
14460 + u32 crc = 0x80000000;
14462 + bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
14463 + if (!bnep_crc32_table)
14466 + bnep_crc32_table[0] = 0;
14468 + for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
14469 + crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
14470 + for (j = 0; j < i; j++)
14471 + bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
14476 +void __exit bnep_crc32_cleanup(void)
14478 + if (bnep_crc32_table)
14479 + kfree(bnep_crc32_table);
14480 + bnep_crc32_table = NULL;
14482 diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.h linux-2.4.18-mh9/net/bluetooth/bnep/crc32.h
14483 --- linux-2.4.18/net/bluetooth/bnep/crc32.h Thu Jan 1 01:00:00 1970
14484 +++ linux-2.4.18-mh9/net/bluetooth/bnep/crc32.h Mon Aug 25 18:38:12 2003
14488 + * See crc32.c for license and changes
14490 + * FIXME: Remove in 2.5
14493 +int bnep_crc32_init(void);
14494 +void bnep_crc32_cleanup(void);
14495 +u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
14496 diff -urN linux-2.4.18/net/bluetooth/bnep/netdev.c linux-2.4.18-mh9/net/bluetooth/bnep/netdev.c
14497 --- linux-2.4.18/net/bluetooth/bnep/netdev.c Thu Jan 1 01:00:00 1970
14498 +++ linux-2.4.18-mh9/net/bluetooth/bnep/netdev.c Mon Aug 25 18:38:12 2003
14501 + BNEP implementation for Linux Bluetooth stack (BlueZ).
14502 + Copyright (C) 2001-2002 Inventel Systemes
14503 + Written 2001-2002 by
14504 + Clément Moreau <clement.moreau@inventel.fr>
14505 + David Libault <david.libault@inventel.fr>
14507 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
14509 + This program is free software; you can redistribute it and/or modify
14510 + it under the terms of the GNU General Public License version 2 as
14511 + published by the Free Software Foundation;
14513 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14514 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14515 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14516 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14517 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14518 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14519 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14520 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14522 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
14523 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
14524 + SOFTWARE IS DISCLAIMED.
14528 + * $Id: netdev.c,v 1.7 2002/07/14 05:39:26 maxk Exp $
14531 +#include <linux/config.h>
14532 +#include <linux/module.h>
14534 +#include <linux/socket.h>
14535 +#include <linux/netdevice.h>
14536 +#include <linux/etherdevice.h>
14537 +#include <linux/skbuff.h>
14538 +#include <linux/wait.h>
14540 +#include <asm/unaligned.h>
14542 +#include <net/bluetooth/bluetooth.h>
14543 +#include <net/bluetooth/hci_core.h>
14544 +#include <net/bluetooth/l2cap.h>
14548 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
14550 +#define BT_DBG( A... )
14553 +#define BNEP_TX_QUEUE_LEN 20
14555 +static int bnep_net_open(struct net_device *dev)
14557 + netif_start_queue(dev);
14561 +static int bnep_net_close(struct net_device *dev)
14563 + netif_stop_queue(dev);
14567 +static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
14569 + struct bnep_session *s = dev->priv;
14570 + return &s->stats;
14573 +static void bnep_net_set_mc_list(struct net_device *dev)
14575 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
14576 + struct bnep_session *s = dev->priv;
14577 + struct sock *sk = s->sock->sk;
14578 + struct bnep_set_filter_req *r;
14579 + struct sk_buff *skb;
14582 + BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
14584 + size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
14585 + skb = alloc_skb(size, GFP_ATOMIC);
14587 + BT_ERR("%s Multicast list allocation failed", dev->name);
14591 + r = (void *) skb->data;
14592 + __skb_put(skb, sizeof(*r));
14594 + r->type = BNEP_CONTROL;
14595 + r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
14597 + if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
14598 + u8 start[ETH_ALEN] = { 0x01 };
14600 + /* Request all addresses */
14601 + memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
14602 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
14603 + r->len = htons(ETH_ALEN * 2);
14605 + struct dev_mc_list *dmi = dev->mc_list;
14606 + int i, len = skb->len;
14608 + if (dev->flags & IFF_BROADCAST) {
14609 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
14610 + memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
14613 + /* FIXME: We should group addresses here. */
14615 + for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
14616 + memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
14617 + memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
14620 + r->len = htons(skb->len - len);
14623 + skb_queue_tail(&sk->write_queue, skb);
14624 + wake_up_interruptible(sk->sleep);
14628 +static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
14630 + BT_DBG("%s", dev->name);
14634 +static void bnep_net_timeout(struct net_device *dev)
14636 + BT_DBG("net_timeout");
14637 + netif_wake_queue(dev);
14640 +static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
14645 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
14646 +static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
14648 + struct ethhdr *eh = (void *) skb->data;
14650 + if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
14651 + BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
14652 + eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
14653 + eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
14660 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
14661 +/* Determine ether protocol. Based on eth_type_trans. */
14662 +static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
14664 + struct ethhdr *eh = (void *) skb->data;
14666 + if (ntohs(eh->h_proto) >= 1536)
14667 + return eh->h_proto;
14669 + if (get_unaligned((u16 *) skb->data) == 0xFFFF)
14670 + return htons(ETH_P_802_3);
14672 + return htons(ETH_P_802_2);
14675 +static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
14677 + u16 proto = bnep_net_eth_proto(skb);
14678 + struct bnep_proto_filter *f = s->proto_filter;
14681 + for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
14682 + if (proto >= f[i].start && proto <= f[i].end)
14686 + BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
14691 +static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
14693 + struct bnep_session *s = dev->priv;
14694 + struct sock *sk = s->sock->sk;
14696 + BT_DBG("skb %p, dev %p", skb, dev);
14698 +#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
14699 + if (bnep_net_mc_filter(skb, s)) {
14705 +#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
14706 + if (bnep_net_proto_filter(skb, s)) {
14713 + * We cannot send L2CAP packets from here as we are potentially in a bh.
14714 + * So we have to queue them and wake up session thread which is sleeping
14715 + * on the sk->sleep.
14717 + dev->trans_start = jiffies;
14718 + skb_queue_tail(&sk->write_queue, skb);
14719 + wake_up_interruptible(sk->sleep);
14721 + if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
14722 + BT_DBG("tx queue is full");
14725 + * Session thread will do netif_wake_queue() */
14726 + netif_stop_queue(dev);
14732 +int bnep_net_init(struct net_device *dev)
14734 + struct bnep_session *s = dev->priv;
14736 + memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
14737 + dev->addr_len = ETH_ALEN;
14739 + ether_setup(dev);
14741 + dev->open = bnep_net_open;
14742 + dev->stop = bnep_net_close;
14743 + dev->hard_start_xmit = bnep_net_xmit;
14744 + dev->get_stats = bnep_net_get_stats;
14745 + dev->do_ioctl = bnep_net_ioctl;
14746 + dev->set_mac_address = bnep_net_set_mac_addr;
14747 + dev->set_multicast_list = bnep_net_set_mc_list;
14749 + dev->watchdog_timeo = HZ * 2;
14750 + dev->tx_timeout = bnep_net_timeout;
14754 diff -urN linux-2.4.18/net/bluetooth/bnep/sock.c linux-2.4.18-mh9/net/bluetooth/bnep/sock.c
14755 --- linux-2.4.18/net/bluetooth/bnep/sock.c Thu Jan 1 01:00:00 1970
14756 +++ linux-2.4.18-mh9/net/bluetooth/bnep/sock.c Mon Aug 25 18:38:12 2003
14759 + BNEP implementation for Linux Bluetooth stack (BlueZ).
14760 + Copyright (C) 2001-2002 Inventel Systemes
14761 + Written 2001-2002 by
14762 + David Libault <david.libault@inventel.fr>
14764 + Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
14766 + This program is free software; you can redistribute it and/or modify
14767 + it under the terms of the GNU General Public License version 2 as
14768 + published by the Free Software Foundation;
14770 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14771 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14772 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14773 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
14774 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14775 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14776 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14777 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14779 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
14780 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
14781 + SOFTWARE IS DISCLAIMED.
14785 + * $Id: sock.c,v 1.3 2002/07/10 22:59:52 maxk Exp $
14788 +#include <linux/config.h>
14789 +#include <linux/module.h>
14791 +#include <linux/types.h>
14792 +#include <linux/errno.h>
14793 +#include <linux/kernel.h>
14794 +#include <linux/major.h>
14795 +#include <linux/sched.h>
14796 +#include <linux/slab.h>
14797 +#include <linux/poll.h>
14798 +#include <linux/fcntl.h>
14799 +#include <linux/skbuff.h>
14800 +#include <linux/socket.h>
14801 +#include <linux/ioctl.h>
14802 +#include <linux/file.h>
14803 +#include <net/sock.h>
14805 +#include <asm/system.h>
14806 +#include <asm/uaccess.h>
14810 +#ifndef CONFIG_BLUEZ_BNEP_DEBUG
14812 +#define BT_DBG( A... )
14815 +static inline struct socket *socki_lookup(struct inode *inode)
14817 + return &inode->u.socket_i;
14820 +static struct socket *sockfd_lookup(int fd, int *err)
14822 + struct file *file;
14823 + struct inode *inode;
14824 + struct socket *sock;
14826 + if (!(file = fget(fd))) {
14831 + inode = file->f_dentry->d_inode;
14832 + if (!inode->i_sock || !(sock = socki_lookup(inode))) {
14833 + *err = -ENOTSOCK;
14838 + if (sock->file != file) {
14839 + printk(KERN_ERR "socki_lookup: socket file changed!\n");
14840 + sock->file = file;
14845 +static int bnep_sock_release(struct socket *sock)
14847 + struct sock *sk = sock->sk;
14849 + BT_DBG("sock %p sk %p", sock, sk);
14857 + MOD_DEC_USE_COUNT;
14861 +static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
14863 + struct bnep_connlist_req cl;
14864 + struct bnep_connadd_req ca;
14865 + struct bnep_conndel_req cd;
14866 + struct bnep_conninfo ci;
14867 + struct socket *nsock;
14870 + BT_DBG("cmd %x arg %lx", cmd, arg);
14873 + case BNEPCONNADD:
14874 + if (!capable(CAP_NET_ADMIN))
14877 + if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
14880 + nsock = sockfd_lookup(ca.sock, &err);
14884 + if (nsock->sk->state != BT_CONNECTED)
14887 + err = bnep_add_connection(&ca, nsock);
14889 + if (copy_to_user((void *) arg, &ca, sizeof(ca)))
14892 + fput(nsock->file);
14896 + case BNEPCONNDEL:
14897 + if (!capable(CAP_NET_ADMIN))
14900 + if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
14903 + return bnep_del_connection(&cd);
14905 + case BNEPGETCONNLIST:
14906 + if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
14909 + if (cl.cnum <= 0)
14912 + err = bnep_get_connlist(&cl);
14913 + if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
14918 + case BNEPGETCONNINFO:
14919 + if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
14922 + err = bnep_get_conninfo(&ci);
14923 + if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
14935 +static struct proto_ops bnep_sock_ops = {
14936 + family: PF_BLUETOOTH,
14937 + release: bnep_sock_release,
14938 + ioctl: bnep_sock_ioctl,
14939 + bind: sock_no_bind,
14940 + getname: sock_no_getname,
14941 + sendmsg: sock_no_sendmsg,
14942 + recvmsg: sock_no_recvmsg,
14943 + poll: sock_no_poll,
14944 + listen: sock_no_listen,
14945 + shutdown: sock_no_shutdown,
14946 + setsockopt: sock_no_setsockopt,
14947 + getsockopt: sock_no_getsockopt,
14948 + connect: sock_no_connect,
14949 + socketpair: sock_no_socketpair,
14950 + accept: sock_no_accept,
14951 + mmap: sock_no_mmap
14954 +static int bnep_sock_create(struct socket *sock, int protocol)
14958 + BT_DBG("sock %p", sock);
14960 + if (sock->type != SOCK_RAW)
14961 + return -ESOCKTNOSUPPORT;
14963 + sock->ops = &bnep_sock_ops;
14965 + if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
14968 + MOD_INC_USE_COUNT;
14970 + sock->state = SS_UNCONNECTED;
14971 + sock_init_data(sock, sk);
14973 + sk->destruct = NULL;
14974 + sk->protocol = protocol;
14979 +static struct net_proto_family bnep_sock_family_ops = {
14980 + family: PF_BLUETOOTH,
14981 + create: bnep_sock_create
14984 +int bnep_sock_init(void)
14986 + bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
14990 +int bnep_sock_cleanup(void)
14992 + if (bluez_sock_unregister(BTPROTO_BNEP))
14993 + BT_ERR("Can't unregister BNEP socket");
14996 diff -urN linux-2.4.18/net/bluetooth/cmtp/Config.in linux-2.4.18-mh9/net/bluetooth/cmtp/Config.in
14997 --- linux-2.4.18/net/bluetooth/cmtp/Config.in Thu Jan 1 01:00:00 1970
14998 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/Config.in Mon Aug 25 18:38:12 2003
15001 +# Bluetooth CMTP layer configuration
15004 +if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
15005 + dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
15007 diff -urN linux-2.4.18/net/bluetooth/cmtp/Makefile linux-2.4.18-mh9/net/bluetooth/cmtp/Makefile
15008 --- linux-2.4.18/net/bluetooth/cmtp/Makefile Thu Jan 1 01:00:00 1970
15009 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/Makefile Mon Aug 25 18:38:12 2003
15012 +# Makefile for the Linux Bluetooth CMTP layer
15015 +O_TARGET := cmtp.o
15017 +obj-y := core.o sock.o capi.o
15018 +obj-m += $(O_TARGET)
15020 +include $(TOPDIR)/Rules.make
15021 diff -urN linux-2.4.18/net/bluetooth/cmtp/capi.c linux-2.4.18-mh9/net/bluetooth/cmtp/capi.c
15022 --- linux-2.4.18/net/bluetooth/cmtp/capi.c Thu Jan 1 01:00:00 1970
15023 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/capi.c Mon Aug 25 18:38:12 2003
15026 + CMTP implementation for Linux Bluetooth stack (BlueZ).
15027 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
15029 + This program is free software; you can redistribute it and/or modify
15030 + it under the terms of the GNU General Public License version 2 as
15031 + published by the Free Software Foundation;
15033 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15034 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15035 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15036 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15037 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15038 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15039 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15040 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15042 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15043 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15044 + SOFTWARE IS DISCLAIMED.
15047 +#include <linux/config.h>
15048 +#include <linux/module.h>
15050 +#include <linux/types.h>
15051 +#include <linux/errno.h>
15052 +#include <linux/kernel.h>
15053 +#include <linux/major.h>
15054 +#include <linux/sched.h>
15055 +#include <linux/slab.h>
15056 +#include <linux/poll.h>
15057 +#include <linux/fcntl.h>
15058 +#include <linux/skbuff.h>
15059 +#include <linux/socket.h>
15060 +#include <linux/ioctl.h>
15061 +#include <linux/file.h>
15062 +#include <net/sock.h>
15064 +#include <linux/capi.h>
15066 +#include "../drivers/isdn/avmb1/capilli.h"
15067 +#include "../drivers/isdn/avmb1/capicmd.h"
15068 +#include "../drivers/isdn/avmb1/capiutil.h"
15072 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
15074 +#define BT_DBG(D...)
15077 +#define REVISION "1.0"
15079 +#define CAPI_INTEROPERABILITY 0x20
15081 +#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
15082 +#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
15083 +#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
15084 +#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
15086 +#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
15087 +#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
15088 +#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
15089 +#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
15091 +#define CAPI_FUNCTION_REGISTER 0
15092 +#define CAPI_FUNCTION_RELEASE 1
15093 +#define CAPI_FUNCTION_GET_PROFILE 2
15094 +#define CAPI_FUNCTION_GET_MANUFACTURER 3
15095 +#define CAPI_FUNCTION_GET_VERSION 4
15096 +#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
15097 +#define CAPI_FUNCTION_MANUFACTURER 6
15098 +#define CAPI_FUNCTION_LOOPBACK 7
15100 +static struct capi_driver_interface *di;
15103 +#define CMTP_MSGNUM 1
15104 +#define CMTP_APPLID 2
15105 +#define CMTP_MAPPING 3
15107 +static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
15109 + struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
15111 + BT_DBG("session %p application %p appl %d", session, app, appl);
15116 + memset(app, 0, sizeof(*app));
15118 + app->state = BT_OPEN;
15119 + app->appl = appl;
15121 + list_add_tail(&app->list, &session->applications);
15126 +static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
15128 + BT_DBG("session %p application %p", session, app);
15131 + list_del(&app->list);
15136 +static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
15138 + struct cmtp_application *app;
15139 + struct list_head *p, *n;
15141 + list_for_each_safe(p, n, &session->applications) {
15142 + app = list_entry(p, struct cmtp_application, list);
15143 + switch (pattern) {
15144 + case CMTP_MSGNUM:
15145 + if (app->msgnum == value)
15148 + case CMTP_APPLID:
15149 + if (app->appl == value)
15152 + case CMTP_MAPPING:
15153 + if (app->mapping == value)
15162 +static int cmtp_msgnum_get(struct cmtp_session *session)
15164 + session->msgnum++;
15166 + if ((session->msgnum & 0xff) > 200)
15167 + session->msgnum = CMTP_INITIAL_MSGNUM + 1;
15169 + return session->msgnum;
15173 +static void cmtp_send_interopmsg(struct cmtp_session *session,
15174 + __u8 subcmd, __u16 appl, __u16 msgnum,
15175 + __u16 function, unsigned char *buf, int len)
15177 + struct sk_buff *skb;
15178 + unsigned char *s;
15180 + BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
15182 + if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
15183 + BT_ERR("Can't allocate memory for interoperability packet");
15187 + s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
15189 + capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
15190 + capimsg_setu16(s, 2, appl);
15191 + capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
15192 + capimsg_setu8 (s, 5, subcmd);
15193 + capimsg_setu16(s, 6, msgnum);
15195 + /* Interoperability selector (Bluetooth Device Management) */
15196 + capimsg_setu16(s, 8, 0x0001);
15198 + capimsg_setu8 (s, 10, 3 + len);
15199 + capimsg_setu16(s, 11, function);
15200 + capimsg_setu8 (s, 13, len);
15203 + memcpy(s + 14, buf, len);
15205 + cmtp_send_capimsg(session, skb);
15208 +static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
15210 + struct capi_ctr *ctrl = session->ctrl;
15211 + struct cmtp_application *application;
15212 + __u16 appl, msgnum, func, info;
15213 + __u32 controller;
15215 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
15217 + switch (CAPIMSG_SUBCOMMAND(skb->data)) {
15219 + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
15220 + info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
15223 + case CAPI_FUNCTION_REGISTER:
15224 + msgnum = CAPIMSG_MSGID(skb->data);
15226 + application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
15227 + if (application) {
15228 + application->state = BT_CONNECTED;
15229 + application->msgnum = 0;
15230 + application->mapping = CAPIMSG_APPID(skb->data);
15231 + wake_up_interruptible(&session->wait);
15236 + case CAPI_FUNCTION_RELEASE:
15237 + appl = CAPIMSG_APPID(skb->data);
15239 + application = cmtp_application_get(session, CMTP_MAPPING, appl);
15240 + if (application) {
15241 + application->state = BT_CLOSED;
15242 + application->msgnum = 0;
15243 + wake_up_interruptible(&session->wait);
15248 + case CAPI_FUNCTION_GET_PROFILE:
15249 + controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
15250 + msgnum = CAPIMSG_MSGID(skb->data);
15252 + if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
15253 + session->ncontroller = controller;
15254 + wake_up_interruptible(&session->wait);
15258 + if (!info && ctrl) {
15259 + memcpy(&ctrl->profile,
15260 + skb->data + CAPI_MSG_BASELEN + 11,
15261 + sizeof(capi_profile));
15262 + session->state = BT_CONNECTED;
15263 + ctrl->ready(ctrl);
15268 + case CAPI_FUNCTION_GET_MANUFACTURER:
15269 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
15271 + if (!info && ctrl) {
15272 + strncpy(ctrl->manu,
15273 + skb->data + CAPI_MSG_BASELEN + 15,
15274 + skb->data[CAPI_MSG_BASELEN + 14]);
15279 + case CAPI_FUNCTION_GET_VERSION:
15280 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
15282 + if (!info && ctrl) {
15283 + ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
15284 + ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
15285 + ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
15286 + ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
15291 + case CAPI_FUNCTION_GET_SERIAL_NUMBER:
15292 + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
15294 + if (!info && ctrl) {
15295 + memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
15296 + strncpy(ctrl->serial,
15297 + skb->data + CAPI_MSG_BASELEN + 17,
15298 + skb->data[CAPI_MSG_BASELEN + 16]);
15307 + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
15309 + if (func == CAPI_FUNCTION_LOOPBACK) {
15310 + appl = CAPIMSG_APPID(skb->data);
15311 + msgnum = CAPIMSG_MSGID(skb->data);
15312 + cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
15313 + skb->data + CAPI_MSG_BASELEN + 6,
15314 + skb->data[CAPI_MSG_BASELEN + 5]);
15323 +void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
15325 + struct capi_ctr *ctrl = session->ctrl;
15326 + struct cmtp_application *application;
15327 + __u16 cmd, appl, info;
15328 + __u32 ncci, contr;
15330 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
15332 + if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
15333 + cmtp_recv_interopmsg(session, skb);
15337 + if (session->flags & (1 << CMTP_LOOPBACK)) {
15342 + cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
15343 + appl = CAPIMSG_APPID(skb->data);
15344 + contr = CAPIMSG_CONTROL(skb->data);
15346 + application = cmtp_application_get(session, CMTP_MAPPING, appl);
15347 + if (application) {
15348 + appl = application->appl;
15349 + CAPIMSG_SETAPPID(skb->data, appl);
15351 + BT_ERR("Can't find application with id %d", appl);
15356 + if ((contr & 0x7f) == 0x01) {
15357 + contr = (contr & 0xffffff80) | session->num;
15358 + CAPIMSG_SETCONTROL(skb->data, contr);
15362 + BT_ERR("Can't find controller %d for message", session->num);
15368 + case CAPI_CONNECT_B3_CONF:
15369 + ncci = CAPIMSG_NCCI(skb->data);
15370 + info = CAPIMSG_U16(skb->data, 12);
15372 + BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
15375 + ctrl->new_ncci(ctrl, appl, ncci, 8);
15377 + ctrl->handle_capimsg(ctrl, appl, skb);
15380 + case CAPI_CONNECT_B3_IND:
15381 + ncci = CAPIMSG_NCCI(skb->data);
15383 + BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
15385 + ctrl->new_ncci(ctrl, appl, ncci, 8);
15386 + ctrl->handle_capimsg(ctrl, appl, skb);
15389 + case CAPI_DISCONNECT_B3_IND:
15390 + ncci = CAPIMSG_NCCI(skb->data);
15392 + BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
15394 + if (ncci == 0xffffffff)
15395 + BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
15397 + ctrl->handle_capimsg(ctrl, appl, skb);
15398 + ctrl->free_ncci(ctrl, appl, ncci);
15402 + ctrl->handle_capimsg(ctrl, appl, skb);
15407 +void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
15409 + struct cmtp_scb *scb = (void *) skb->cb;
15411 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
15414 + scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
15416 + skb_queue_tail(&session->transmit, skb);
15418 + cmtp_schedule(session);
15422 +static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
15424 + BT_DBG("ctrl %p data %p", ctrl, data);
15429 +static void cmtp_reset_ctr(struct capi_ctr *ctrl)
15431 + BT_DBG("ctrl %p", ctrl);
15433 + ctrl->reseted(ctrl);
15436 +static void cmtp_remove_ctr(struct capi_ctr *ctrl)
15438 + struct cmtp_session *session = ctrl->driverdata;
15440 + BT_DBG("ctrl %p", ctrl);
15442 + ctrl->suspend_output(ctrl);
15444 + atomic_inc(&session->terminate);
15445 + cmtp_schedule(session);
15448 +static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
15450 + DECLARE_WAITQUEUE(wait, current);
15451 + struct cmtp_session *session = ctrl->driverdata;
15452 + struct cmtp_application *application;
15453 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
15454 + unsigned char buf[8];
15455 + int err = 0, nconn, want = rp->level3cnt;
15457 + BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
15458 + ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
15460 + application = cmtp_application_add(session, appl);
15461 + if (!application) {
15462 + BT_ERR("Can't allocate memory for new application");
15463 + ctrl->appl_released(ctrl, appl);
15468 + nconn = ctrl->profile.nbchannel * -want;
15473 + nconn = ctrl->profile.nbchannel;
15475 + capimsg_setu16(buf, 0, nconn);
15476 + capimsg_setu16(buf, 2, rp->datablkcnt);
15477 + capimsg_setu16(buf, 4, rp->datablklen);
15479 + application->state = BT_CONFIG;
15480 + application->msgnum = cmtp_msgnum_get(session);
15482 + cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
15483 + CAPI_FUNCTION_REGISTER, buf, 6);
15485 + add_wait_queue(&session->wait, &wait);
15487 + set_current_state(TASK_INTERRUPTIBLE);
15494 + if (application->state == BT_CLOSED) {
15495 + err = -application->err;
15499 + if (application->state == BT_CONNECTED)
15502 + if (signal_pending(current)) {
15507 + timeo = schedule_timeout(timeo);
15509 + set_current_state(TASK_RUNNING);
15510 + remove_wait_queue(&session->wait, &wait);
15513 + ctrl->appl_released(ctrl, appl);
15514 + cmtp_application_del(session, application);
15518 + ctrl->appl_registered(ctrl, appl);
15521 +static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
15523 + DECLARE_WAITQUEUE(wait, current);
15524 + struct cmtp_session *session = ctrl->driverdata;
15525 + struct cmtp_application *application;
15526 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
15528 + BT_DBG("ctrl %p appl %d", ctrl, appl);
15530 + application = cmtp_application_get(session, CMTP_APPLID, appl);
15531 + if (!application) {
15532 + BT_ERR("Can't find application");
15536 + application->msgnum = cmtp_msgnum_get(session);
15538 + cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
15539 + CAPI_FUNCTION_RELEASE, NULL, 0);
15541 + add_wait_queue(&session->wait, &wait);
15543 + set_current_state(TASK_INTERRUPTIBLE);
15545 + if (application->state == BT_CLOSED)
15548 + if (signal_pending(current))
15551 + timeo = schedule_timeout(timeo);
15553 + set_current_state(TASK_RUNNING);
15554 + remove_wait_queue(&session->wait, &wait);
15556 + cmtp_application_del(session, application);
15557 + ctrl->appl_released(ctrl, appl);
15560 +static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
15562 + struct cmtp_session *session = ctrl->driverdata;
15563 + struct cmtp_application *application;
15567 + BT_DBG("ctrl %p skb %p", ctrl, skb);
15569 + appl = CAPIMSG_APPID(skb->data);
15570 + contr = CAPIMSG_CONTROL(skb->data);
15572 + application = cmtp_application_get(session, CMTP_APPLID, appl);
15573 + if ((!application) || (application->state != BT_CONNECTED)) {
15574 + BT_ERR("Can't find application with id %d", appl);
15579 + CAPIMSG_SETAPPID(skb->data, application->mapping);
15581 + if ((contr & 0x7f) == session->num) {
15582 + contr = (contr & 0xffffff80) | 0x01;
15583 + CAPIMSG_SETCONTROL(skb->data, contr);
15586 + cmtp_send_capimsg(session, skb);
15589 +static char *cmtp_procinfo(struct capi_ctr *ctrl)
15591 + return "CAPI Message Transport Protocol";
15594 +static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
15596 + struct cmtp_session *session = ctrl->driverdata;
15597 + struct cmtp_application *app;
15598 + struct list_head *p, *n;
15601 + len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
15602 + len += sprintf(page + len, "addr %s\n", session->name);
15603 + len += sprintf(page + len, "ctrl %d\n", session->num);
15605 + list_for_each_safe(p, n, &session->applications) {
15606 + app = list_entry(p, struct cmtp_application, list);
15607 + len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
15610 + if (off + count >= len)
15616 + *start = page + off;
15618 + return ((count < len - off) ? count : len - off);
15621 +static struct capi_driver cmtp_driver = {
15623 + revision: REVISION,
15624 + load_firmware: cmtp_load_firmware,
15625 + reset_ctr: cmtp_reset_ctr,
15626 + remove_ctr: cmtp_remove_ctr,
15627 + register_appl: cmtp_register_appl,
15628 + release_appl: cmtp_release_appl,
15629 + send_message: cmtp_send_message,
15630 + procinfo: cmtp_procinfo,
15631 + ctr_read_proc: cmtp_ctr_read_proc,
15633 + driver_read_proc: 0,
15638 +int cmtp_attach_device(struct cmtp_session *session)
15640 + DECLARE_WAITQUEUE(wait, current);
15641 + unsigned long timeo = CMTP_INTEROP_TIMEOUT;
15642 + unsigned char buf[4];
15644 + BT_DBG("session %p", session);
15646 + capimsg_setu32(buf, 0, 0);
15648 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
15649 + CAPI_FUNCTION_GET_PROFILE, buf, 4);
15651 + add_wait_queue(&session->wait, &wait);
15653 + set_current_state(TASK_INTERRUPTIBLE);
15655 + if (session->ncontroller)
15658 + if (signal_pending(current))
15661 + timeo = schedule_timeout(timeo);
15663 + set_current_state(TASK_RUNNING);
15664 + remove_wait_queue(&session->wait, &wait);
15666 + BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
15669 + return -ETIMEDOUT;
15671 + if (!session->ncontroller)
15675 + if (session->ncontroller > 1)
15676 + BT_INFO("Setting up only CAPI controller 1");
15678 + if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
15679 + BT_ERR("Can't attach new controller");
15683 + session->num = session->ctrl->cnr;
15685 + BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
15687 + capimsg_setu32(buf, 0, 1);
15689 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
15690 + CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
15692 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
15693 + CAPI_FUNCTION_GET_VERSION, buf, 4);
15695 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
15696 + CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
15698 + cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
15699 + CAPI_FUNCTION_GET_PROFILE, buf, 4);
15704 +void cmtp_detach_device(struct cmtp_session *session)
15706 + struct capi_ctr *ctrl = session->ctrl;
15708 + BT_DBG("session %p ctrl %p", session, ctrl);
15713 + ctrl->reseted(ctrl);
15715 + di->detach_ctr(ctrl);
15718 +int cmtp_init_capi(void)
15720 + if (!(di = attach_capi_driver(&cmtp_driver))) {
15721 + BT_ERR("Can't attach CAPI driver");
15728 +void cmtp_cleanup_capi(void)
15730 + detach_capi_driver(&cmtp_driver);
15732 diff -urN linux-2.4.18/net/bluetooth/cmtp/cmtp.h linux-2.4.18-mh9/net/bluetooth/cmtp/cmtp.h
15733 --- linux-2.4.18/net/bluetooth/cmtp/cmtp.h Thu Jan 1 01:00:00 1970
15734 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/cmtp.h Mon Aug 25 18:38:12 2003
15737 + CMTP implementation for Linux Bluetooth stack (BlueZ).
15738 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
15740 + This program is free software; you can redistribute it and/or modify
15741 + it under the terms of the GNU General Public License version 2 as
15742 + published by the Free Software Foundation;
15744 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15745 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15746 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15747 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15748 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15749 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15750 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15751 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15753 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15754 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15755 + SOFTWARE IS DISCLAIMED.
15761 +#include <linux/types.h>
15762 +#include <net/bluetooth/bluetooth.h>
15764 +#define BTNAMSIZ 18
15766 +/* CMTP ioctl defines */
15767 +#define CMTPCONNADD _IOW('C', 200, int)
15768 +#define CMTPCONNDEL _IOW('C', 201, int)
15769 +#define CMTPGETCONNLIST _IOR('C', 210, int)
15770 +#define CMTPGETCONNINFO _IOR('C', 211, int)
15772 +#define CMTP_LOOPBACK 0
15774 +struct cmtp_connadd_req {
15775 + int sock; // Connected socket
15779 +struct cmtp_conndel_req {
15784 +struct cmtp_conninfo {
15791 +struct cmtp_connlist_req {
15793 + struct cmtp_conninfo *ci;
15796 +int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
15797 +int cmtp_del_connection(struct cmtp_conndel_req *req);
15798 +int cmtp_get_connlist(struct cmtp_connlist_req *req);
15799 +int cmtp_get_conninfo(struct cmtp_conninfo *ci);
15801 +/* CMTP session defines */
15802 +#define CMTP_INTEROP_TIMEOUT (HZ * 5)
15803 +#define CMTP_INITIAL_MSGNUM 0xff00
15805 +struct cmtp_session {
15806 + struct list_head list;
15808 + struct socket *sock;
15812 + unsigned long state;
15813 + unsigned long flags;
15817 + char name[BTNAMSIZ];
15819 + atomic_t terminate;
15821 + wait_queue_head_t wait;
15825 + struct capi_ctr *ctrl;
15827 + struct list_head applications;
15829 + unsigned long blockids;
15832 + struct sk_buff_head transmit;
15834 + struct sk_buff *reassembly[16];
15837 +struct cmtp_application {
15838 + struct list_head list;
15840 + unsigned long state;
15854 +int cmtp_attach_device(struct cmtp_session *session);
15855 +void cmtp_detach_device(struct cmtp_session *session);
15857 +void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
15858 +void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
15860 +static inline void cmtp_schedule(struct cmtp_session *session)
15862 + struct sock *sk = session->sock->sk;
15864 + wake_up_interruptible(sk->sleep);
15867 +/* CMTP init defines */
15868 +int cmtp_init_capi(void);
15869 +int cmtp_init_sockets(void);
15870 +void cmtp_cleanup_capi(void);
15871 +void cmtp_cleanup_sockets(void);
15873 +#endif /* __CMTP_H */
15874 diff -urN linux-2.4.18/net/bluetooth/cmtp/core.c linux-2.4.18-mh9/net/bluetooth/cmtp/core.c
15875 --- linux-2.4.18/net/bluetooth/cmtp/core.c Thu Jan 1 01:00:00 1970
15876 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/core.c Mon Aug 25 18:38:12 2003
15879 + CMTP implementation for Linux Bluetooth stack (BlueZ).
15880 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
15882 + This program is free software; you can redistribute it and/or modify
15883 + it under the terms of the GNU General Public License version 2 as
15884 + published by the Free Software Foundation;
15886 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15887 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15888 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15889 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15890 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
15891 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15892 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15893 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15895 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
15896 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
15897 + SOFTWARE IS DISCLAIMED.
15900 +#include <linux/config.h>
15901 +#include <linux/module.h>
15903 +#include <linux/types.h>
15904 +#include <linux/errno.h>
15905 +#include <linux/kernel.h>
15906 +#include <linux/major.h>
15907 +#include <linux/sched.h>
15908 +#include <linux/slab.h>
15909 +#include <linux/poll.h>
15910 +#include <linux/fcntl.h>
15911 +#include <linux/skbuff.h>
15912 +#include <linux/socket.h>
15913 +#include <linux/ioctl.h>
15914 +#include <linux/file.h>
15915 +#include <linux/init.h>
15916 +#include <net/sock.h>
15918 +#include <net/bluetooth/bluetooth.h>
15919 +#include <net/bluetooth/l2cap.h>
15923 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
15925 +#define BT_DBG(D...)
15928 +#define VERSION "1.0"
15930 +static DECLARE_RWSEM(cmtp_session_sem);
15931 +static LIST_HEAD(cmtp_session_list);
15933 +static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
15935 + struct cmtp_session *session;
15936 + struct list_head *p;
15940 + list_for_each(p, &cmtp_session_list) {
15941 + session = list_entry(p, struct cmtp_session, list);
15942 + if (!bacmp(bdaddr, &session->bdaddr))
15948 +static void __cmtp_link_session(struct cmtp_session *session)
15950 + MOD_INC_USE_COUNT;
15951 + list_add(&session->list, &cmtp_session_list);
15954 +static void __cmtp_unlink_session(struct cmtp_session *session)
15956 + list_del(&session->list);
15957 + MOD_DEC_USE_COUNT;
15960 +static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
15962 + bacpy(&ci->bdaddr, &session->bdaddr);
15964 + ci->flags = session->flags;
15965 + ci->state = session->state;
15967 + ci->num = session->num;
15971 +static inline int cmtp_alloc_block_id(struct cmtp_session *session)
15975 + for (i = 0; i < 16; i++)
15976 + if (!test_and_set_bit(i, &session->blockids)) {
15984 +static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
15986 + clear_bit(id, &session->blockids);
15989 +static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
15991 + struct sk_buff *skb = session->reassembly[id], *nskb;
15994 + BT_DBG("session %p buf %p count %d", session, buf, count);
15996 + size = (skb) ? skb->len + count : count;
15998 + if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
15999 + BT_ERR("Can't allocate memory for CAPI message");
16003 + if (skb && (skb->len > 0))
16004 + memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
16006 + memcpy(skb_put(nskb, count), buf, count);
16008 + session->reassembly[id] = nskb;
16014 +static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
16016 + __u8 hdr, hdrlen, id;
16019 + BT_DBG("session %p skb %p len %d", session, skb, skb->len);
16021 + while (skb->len > 0) {
16022 + hdr = skb->data[0];
16024 + switch (hdr & 0xc0) {
16027 + len = skb->data[1];
16031 + len = skb->data[1] | (skb->data[2] << 8);
16039 + id = (hdr & 0x3c) >> 2;
16041 + BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
16043 + if (hdrlen + len > skb->len) {
16044 + BT_ERR("Wrong size or header information in CMTP frame");
16049 + skb_pull(skb, hdrlen);
16053 + switch (hdr & 0x03) {
16055 + cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
16056 + cmtp_recv_capimsg(session, session->reassembly[id]);
16057 + session->reassembly[id] = NULL;
16060 + cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
16063 + if (session->reassembly[id] != NULL)
16064 + kfree_skb(session->reassembly[id]);
16065 + session->reassembly[id] = NULL;
16069 + skb_pull(skb, hdrlen + len);
16076 +static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
16078 + struct socket *sock = session->sock;
16079 + struct iovec iv = { data, len };
16080 + struct msghdr msg;
16083 + BT_DBG("session %p data %p len %d", session, data, len);
16088 + memset(&msg, 0, sizeof(msg));
16089 + msg.msg_iovlen = 1;
16090 + msg.msg_iov = &iv;
16092 + err = sock->ops->sendmsg(sock, &msg, len, 0);
16096 +static int cmtp_process_transmit(struct cmtp_session *session)
16098 + struct sk_buff *skb, *nskb;
16099 + unsigned char *hdr;
16100 + unsigned int size, tail;
16102 + BT_DBG("session %p", session);
16104 + if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
16105 + BT_ERR("Can't allocate memory for new frame");
16109 + while ((skb = skb_dequeue(&session->transmit))) {
16110 + struct cmtp_scb *scb = (void *) skb->cb;
16112 + if ((tail = (session->mtu - nskb->len)) < 5) {
16113 + cmtp_send_frame(session, nskb->data, nskb->len);
16114 + skb_trim(nskb, 0);
16115 + tail = session->mtu;
16118 + size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
16120 + if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
16121 + skb_queue_head(&session->transmit, skb);
16125 + if (size < 256) {
16126 + hdr = skb_put(nskb, 2);
16128 + | ((scb->id << 2) & 0x3c)
16129 + | ((skb->len == size) ? 0x00 : 0x01);
16132 + hdr = skb_put(nskb, 3);
16134 + | ((scb->id << 2) & 0x3c)
16135 + | ((skb->len == size) ? 0x00 : 0x01);
16136 + hdr[1] = size & 0xff;
16137 + hdr[2] = size >> 8;
16140 + memcpy(skb_put(nskb, size), skb->data, size);
16141 + skb_pull(skb, size);
16143 + if (skb->len > 0) {
16144 + skb_queue_head(&session->transmit, skb);
16146 + cmtp_free_block_id(session, scb->id);
16148 + cmtp_send_frame(session, nskb->data, nskb->len);
16149 + skb_trim(nskb, 0);
16155 + cmtp_send_frame(session, nskb->data, nskb->len);
16159 + return skb_queue_len(&session->transmit);
16162 +static int cmtp_session(void *arg)
16164 + struct cmtp_session *session = arg;
16165 + struct sock *sk = session->sock->sk;
16166 + struct sk_buff *skb;
16167 + wait_queue_t wait;
16169 + BT_DBG("session %p", session);
16171 + daemonize(); reparent_to_init();
16173 + sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
16175 + sigfillset(¤t->blocked);
16176 + flush_signals(current);
16178 + current->nice = -15;
16180 + set_fs(KERNEL_DS);
16182 + init_waitqueue_entry(&wait, current);
16183 + add_wait_queue(sk->sleep, &wait);
16184 + while (!atomic_read(&session->terminate)) {
16185 + set_current_state(TASK_INTERRUPTIBLE);
16187 + if (sk->state != BT_CONNECTED)
16190 + while ((skb = skb_dequeue(&sk->receive_queue))) {
16192 + cmtp_recv_frame(session, skb);
16195 + cmtp_process_transmit(session);
16199 + set_current_state(TASK_RUNNING);
16200 + remove_wait_queue(sk->sleep, &wait);
16202 + down_write(&cmtp_session_sem);
16204 + if (!(session->flags & (1 << CMTP_LOOPBACK)))
16205 + cmtp_detach_device(session);
16207 + fput(session->sock->file);
16209 + __cmtp_unlink_session(session);
16211 + up_write(&cmtp_session_sem);
16217 +int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
16219 + struct cmtp_session *session, *s;
16220 + bdaddr_t src, dst;
16225 + baswap(&src, &bluez_pi(sock->sk)->src);
16226 + baswap(&dst, &bluez_pi(sock->sk)->dst);
16228 + session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
16231 + memset(session, 0, sizeof(struct cmtp_session));
16233 + down_write(&cmtp_session_sem);
16235 + s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
16236 + if (s && s->state == BT_CONNECTED) {
16241 + bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
16243 + session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
16245 + BT_DBG("mtu %d", session->mtu);
16247 + sprintf(session->name, "%s", batostr(&dst));
16249 + session->sock = sock;
16250 + session->state = BT_CONFIG;
16252 + init_waitqueue_head(&session->wait);
16254 + session->ctrl = NULL;
16255 + session->msgnum = CMTP_INITIAL_MSGNUM;
16257 + INIT_LIST_HEAD(&session->applications);
16259 + skb_queue_head_init(&session->transmit);
16261 + for (i = 0; i < 16; i++)
16262 + session->reassembly[i] = NULL;
16264 + session->flags = req->flags;
16266 + __cmtp_link_session(session);
16268 + err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
16272 + if (!(session->flags & (1 << CMTP_LOOPBACK))) {
16273 + err = cmtp_attach_device(session);
16278 + up_write(&cmtp_session_sem);
16282 + cmtp_detach_device(session);
16285 + __cmtp_unlink_session(session);
16288 + up_write(&cmtp_session_sem);
16293 +int cmtp_del_connection(struct cmtp_conndel_req *req)
16295 + struct cmtp_session *session;
16300 + down_read(&cmtp_session_sem);
16302 + session = __cmtp_get_session(&req->bdaddr);
16304 + /* Flush the transmit queue */
16305 + skb_queue_purge(&session->transmit);
16307 + /* Kill session thread */
16308 + atomic_inc(&session->terminate);
16309 + cmtp_schedule(session);
16313 + up_read(&cmtp_session_sem);
16317 +int cmtp_get_connlist(struct cmtp_connlist_req *req)
16319 + struct list_head *p;
16320 + int err = 0, n = 0;
16324 + down_read(&cmtp_session_sem);
16326 + list_for_each(p, &cmtp_session_list) {
16327 + struct cmtp_session *session;
16328 + struct cmtp_conninfo ci;
16330 + session = list_entry(p, struct cmtp_session, list);
16332 + __cmtp_copy_session(session, &ci);
16334 + if (copy_to_user(req->ci, &ci, sizeof(ci))) {
16339 + if (++n >= req->cnum)
16346 + up_read(&cmtp_session_sem);
16350 +int cmtp_get_conninfo(struct cmtp_conninfo *ci)
16352 + struct cmtp_session *session;
16355 + down_read(&cmtp_session_sem);
16357 + session = __cmtp_get_session(&ci->bdaddr);
16359 + __cmtp_copy_session(session, ci);
16363 + up_read(&cmtp_session_sem);
16368 +int __init init_cmtp(void)
16372 + cmtp_init_capi();
16373 + cmtp_init_sockets();
16375 + BT_INFO("BlueZ CMTP ver %s", VERSION);
16376 + BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
16381 +void __exit exit_cmtp(void)
16383 + cmtp_cleanup_sockets();
16384 + cmtp_cleanup_capi();
16387 +module_init(init_cmtp);
16388 +module_exit(exit_cmtp);
16390 +MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
16391 +MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
16392 +MODULE_LICENSE("GPL");
16393 diff -urN linux-2.4.18/net/bluetooth/cmtp/sock.c linux-2.4.18-mh9/net/bluetooth/cmtp/sock.c
16394 --- linux-2.4.18/net/bluetooth/cmtp/sock.c Thu Jan 1 01:00:00 1970
16395 +++ linux-2.4.18-mh9/net/bluetooth/cmtp/sock.c Mon Aug 25 18:38:12 2003
16398 + CMTP implementation for Linux Bluetooth stack (BlueZ).
16399 + Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
16401 + This program is free software; you can redistribute it and/or modify
16402 + it under the terms of the GNU General Public License version 2 as
16403 + published by the Free Software Foundation;
16405 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16406 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16407 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16408 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
16409 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16410 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16411 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16412 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16414 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
16415 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
16416 + SOFTWARE IS DISCLAIMED.
16419 +#include <linux/config.h>
16420 +#include <linux/module.h>
16422 +#include <linux/types.h>
16423 +#include <linux/errno.h>
16424 +#include <linux/kernel.h>
16425 +#include <linux/major.h>
16426 +#include <linux/sched.h>
16427 +#include <linux/slab.h>
16428 +#include <linux/poll.h>
16429 +#include <linux/fcntl.h>
16430 +#include <linux/skbuff.h>
16431 +#include <linux/socket.h>
16432 +#include <linux/ioctl.h>
16433 +#include <linux/file.h>
16434 +#include <net/sock.h>
16436 +#include <asm/system.h>
16437 +#include <asm/uaccess.h>
16441 +#ifndef CONFIG_BLUEZ_CMTP_DEBUG
16443 +#define BT_DBG(D...)
16446 +static inline struct socket *socki_lookup(struct inode *inode)
16448 + return &inode->u.socket_i;
16451 +static struct socket *sockfd_lookup(int fd, int *err)
16453 + struct file *file;
16454 + struct inode *inode;
16455 + struct socket *sock;
16457 + if (!(file = fget(fd))) {
16462 + inode = file->f_dentry->d_inode;
16463 + if (!inode->i_sock || !(sock = socki_lookup(inode))) {
16464 + *err = -ENOTSOCK;
16469 + if (sock->file != file) {
16470 + printk(KERN_ERR "socki_lookup: socket file changed!\n");
16471 + sock->file = file;
16476 +static int cmtp_sock_release(struct socket *sock)
16478 + struct sock *sk = sock->sk;
16480 + BT_DBG("sock %p sk %p", sock, sk);
16488 + MOD_DEC_USE_COUNT;
16492 +static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
16494 + struct cmtp_connadd_req ca;
16495 + struct cmtp_conndel_req cd;
16496 + struct cmtp_connlist_req cl;
16497 + struct cmtp_conninfo ci;
16498 + struct socket *nsock;
16501 + BT_DBG("cmd %x arg %lx", cmd, arg);
16504 + case CMTPCONNADD:
16505 + if (!capable(CAP_NET_ADMIN))
16508 + if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
16511 + nsock = sockfd_lookup(ca.sock, &err);
16515 + if (nsock->sk->state != BT_CONNECTED)
16518 + err = cmtp_add_connection(&ca, nsock);
16520 + if (copy_to_user((void *) arg, &ca, sizeof(ca)))
16523 + fput(nsock->file);
16527 + case CMTPCONNDEL:
16528 + if (!capable(CAP_NET_ADMIN))
16531 + if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
16534 + return cmtp_del_connection(&cd);
16536 + case CMTPGETCONNLIST:
16537 + if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
16540 + if (cl.cnum <= 0)
16543 + err = cmtp_get_connlist(&cl);
16544 + if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
16549 + case CMTPGETCONNINFO:
16550 + if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
16553 + err = cmtp_get_conninfo(&ci);
16554 + if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
16563 +static struct proto_ops cmtp_sock_ops = {
16564 + family: PF_BLUETOOTH,
16565 + release: cmtp_sock_release,
16566 + ioctl: cmtp_sock_ioctl,
16567 + bind: sock_no_bind,
16568 + getname: sock_no_getname,
16569 + sendmsg: sock_no_sendmsg,
16570 + recvmsg: sock_no_recvmsg,
16571 + poll: sock_no_poll,
16572 + listen: sock_no_listen,
16573 + shutdown: sock_no_shutdown,
16574 + setsockopt: sock_no_setsockopt,
16575 + getsockopt: sock_no_getsockopt,
16576 + connect: sock_no_connect,
16577 + socketpair: sock_no_socketpair,
16578 + accept: sock_no_accept,
16579 + mmap: sock_no_mmap
16582 +static int cmtp_sock_create(struct socket *sock, int protocol)
16586 + BT_DBG("sock %p", sock);
16588 + if (sock->type != SOCK_RAW)
16589 + return -ESOCKTNOSUPPORT;
16591 + sock->ops = &cmtp_sock_ops;
16593 + if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
16596 + MOD_INC_USE_COUNT;
16598 + sock->state = SS_UNCONNECTED;
16599 + sock_init_data(sock, sk);
16601 + sk->destruct = NULL;
16602 + sk->protocol = protocol;
16607 +static struct net_proto_family cmtp_sock_family_ops = {
16608 + family: PF_BLUETOOTH,
16609 + create: cmtp_sock_create
16612 +int cmtp_init_sockets(void)
16616 + if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
16617 + BT_ERR("Can't register CMTP socket layer (%d)", err);
16624 +void cmtp_cleanup_sockets(void)
16628 + if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
16629 + BT_ERR("Can't unregister CMTP socket layer (%d)", err);
16633 diff -urN linux-2.4.18/net/bluetooth/hci_conn.c linux-2.4.18-mh9/net/bluetooth/hci_conn.c
16634 --- linux-2.4.18/net/bluetooth/hci_conn.c Thu Jan 1 01:00:00 1970
16635 +++ linux-2.4.18-mh9/net/bluetooth/hci_conn.c Mon Aug 25 18:38:12 2003
16638 + BlueZ - Bluetooth protocol stack for Linux
16639 + Copyright (C) 2000-2001 Qualcomm Incorporated
16641 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
16643 + This program is free software; you can redistribute it and/or modify
16644 + it under the terms of the GNU General Public License version 2 as
16645 + published by the Free Software Foundation;
16647 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16648 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16649 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
16650 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
16651 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16652 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16653 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16654 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16656 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
16657 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
16658 + SOFTWARE IS DISCLAIMED.
16662 + * HCI Connection handling.
16664 + * $Id: hci_conn.c,v 1.5 2002/07/17 18:46:25 maxk Exp $
16667 +#include <linux/config.h>
16668 +#include <linux/module.h>
16670 +#include <linux/types.h>
16671 +#include <linux/errno.h>
16672 +#include <linux/kernel.h>
16673 +#include <linux/major.h>
16674 +#include <linux/sched.h>
16675 +#include <linux/slab.h>
16676 +#include <linux/poll.h>
16677 +#include <linux/fcntl.h>
16678 +#include <linux/init.h>
16679 +#include <linux/skbuff.h>
16680 +#include <linux/interrupt.h>
16681 +#include <linux/notifier.h>
16682 +#include <net/sock.h>
16684 +#include <asm/system.h>
16685 +#include <asm/uaccess.h>
16686 +#include <asm/unaligned.h>
16688 +#include <net/bluetooth/bluetooth.h>
16689 +#include <net/bluetooth/hci_core.h>
16691 +#ifndef HCI_CORE_DEBUG
16693 +#define BT_DBG( A... )
16696 +void hci_acl_connect(struct hci_conn *conn)
16698 + struct hci_dev *hdev = conn->hdev;
16699 + struct inquiry_entry *ie;
16700 + create_conn_cp cp;
16702 + BT_DBG("%p", conn);
16704 + conn->state = BT_CONNECT;
16706 + conn->link_mode = HCI_LM_MASTER;
16708 + memset(&cp, 0, sizeof(cp));
16709 + bacpy(&cp.bdaddr, &conn->dst);
16710 + cp.pscan_rep_mode = 0x01;
16712 + if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
16713 + inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
16714 + cp.pscan_rep_mode = ie->info.pscan_rep_mode;
16715 + cp.pscan_mode = ie->info.pscan_mode;
16716 + cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
16719 + cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
16720 + if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
16721 + cp.role_switch = 0x01;
16723 + cp.role_switch = 0x00;
16725 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
16726 + CREATE_CONN_CP_SIZE, &cp);
16729 +void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
16731 + disconnect_cp cp;
16733 + BT_DBG("%p", conn);
16735 + conn->state = BT_DISCONN;
16737 + cp.handle = __cpu_to_le16(conn->handle);
16738 + cp.reason = reason;
16739 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
16740 + DISCONNECT_CP_SIZE, &cp);
16743 +void hci_add_sco(struct hci_conn *conn, __u16 handle)
16745 + struct hci_dev *hdev = conn->hdev;
16748 + BT_DBG("%p", conn);
16750 + conn->state = BT_CONNECT;
16753 + cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
16754 + cp.handle = __cpu_to_le16(handle);
16756 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
16759 +static void hci_conn_timeout(unsigned long arg)
16761 + struct hci_conn *conn = (void *)arg;
16762 + struct hci_dev *hdev = conn->hdev;
16764 + BT_DBG("conn %p state %d", conn, conn->state);
16766 + if (atomic_read(&conn->refcnt))
16769 + hci_dev_lock(hdev);
16770 + if (conn->state == BT_CONNECTED)
16771 + hci_acl_disconn(conn, 0x13);
16773 + conn->state = BT_CLOSED;
16774 + hci_dev_unlock(hdev);
16778 +static void hci_conn_init_timer(struct hci_conn *conn)
16780 + init_timer(&conn->timer);
16781 + conn->timer.function = hci_conn_timeout;
16782 + conn->timer.data = (unsigned long)conn;
16785 +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
16787 + struct hci_conn *conn;
16789 + BT_DBG("%s dst %s", hdev->name, batostr(dst));
16791 + if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
16793 + memset(conn, 0, sizeof(struct hci_conn));
16795 + bacpy(&conn->dst, dst);
16796 + conn->type = type;
16797 + conn->hdev = hdev;
16798 + conn->state = BT_OPEN;
16800 + skb_queue_head_init(&conn->data_q);
16801 + hci_conn_init_timer(conn);
16803 + atomic_set(&conn->refcnt, 0);
16805 + hci_dev_hold(hdev);
16807 + if (hdev->notify)
16808 + hdev->notify(hdev, HCI_NOTIFY_CONN_ADD, (unsigned long) conn);
16810 + tasklet_disable(&hdev->tx_task);
16811 + conn_hash_add(hdev, conn);
16812 + tasklet_enable(&hdev->tx_task);
16817 +int hci_conn_del(struct hci_conn *conn)
16819 + struct hci_dev *hdev = conn->hdev;
16821 + BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
16823 + hci_conn_del_timer(conn);
16825 + if (conn->type == SCO_LINK) {
16826 + struct hci_conn *acl = conn->link;
16828 + acl->link = NULL;
16829 + hci_conn_put(acl);
16832 + struct hci_conn *sco = conn->link;
16834 + sco->link = NULL;
16836 + /* Unacked frames */
16837 + hdev->acl_cnt += conn->sent;
16840 + tasklet_disable(&hdev->tx_task);
16841 + conn_hash_del(hdev, conn);
16842 + tasklet_enable(&hdev->tx_task);
16844 + skb_queue_purge(&conn->data_q);
16846 + if (hdev->notify)
16847 + hdev->notify(hdev, HCI_NOTIFY_CONN_DEL, (unsigned long) conn);
16849 + hci_dev_put(hdev);
16855 +struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
16857 + int use_src = bacmp(src, BDADDR_ANY);
16858 + struct hci_dev *hdev = NULL;
16859 + struct list_head *p;
16861 + BT_DBG("%s -> %s", batostr(src), batostr(dst));
16863 + read_lock_bh(&hdev_list_lock);
16865 + list_for_each(p, &hdev_list) {
16866 + struct hci_dev *d;
16867 + d = list_entry(p, struct hci_dev, list);
16869 + if (!test_bit(HCI_UP, &d->flags))
16872 + /* Simple routing:
16873 + * No source address - find interface with bdaddr != dst
16874 + * Source address - find interface with bdaddr == src
16878 + if (!bacmp(&d->bdaddr, src)) {
16882 + if (bacmp(&d->bdaddr, dst)) {
16889 + hci_dev_hold(hdev);
16891 + read_unlock_bh(&hdev_list_lock);
16895 +/* Create SCO or ACL connection.
16896 + * Device _must_ be locked */
16897 +struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
16899 + struct hci_conn *acl;
16901 + BT_DBG("%s dst %s", hdev->name, batostr(dst));
16903 + if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
16904 + if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
16908 + hci_conn_hold(acl);
16910 + if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
16911 + hci_acl_connect(acl);
16913 + if (type == SCO_LINK) {
16914 + struct hci_conn *sco;
16916 + if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
16917 + if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
16918 + hci_conn_put(acl);
16925 + hci_conn_hold(sco);
16927 + if (acl->state == BT_CONNECTED &&
16928 + (sco->state == BT_OPEN || sco->state == BT_CLOSED))
16929 + hci_add_sco(sco, acl->handle);
16937 +/* Authenticate remote device */
16938 +int hci_conn_auth(struct hci_conn *conn)
16940 + BT_DBG("conn %p", conn);
16942 + if (conn->link_mode & HCI_LM_AUTH)
16945 + if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
16946 + auth_requested_cp ar;
16947 + ar.handle = __cpu_to_le16(conn->handle);
16948 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
16949 + AUTH_REQUESTED_CP_SIZE, &ar);
16954 +/* Enable encryption */
16955 +int hci_conn_encrypt(struct hci_conn *conn)
16957 + BT_DBG("conn %p", conn);
16959 + if (conn->link_mode & HCI_LM_ENCRYPT)
16962 + if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
16965 + if (hci_conn_auth(conn)) {
16966 + set_conn_encrypt_cp ce;
16967 + ce.handle = __cpu_to_le16(conn->handle);
16969 + hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
16970 + SET_CONN_ENCRYPT_CP_SIZE, &ce);
16975 +/* Drop all connection on the device */
16976 +void hci_conn_hash_flush(struct hci_dev *hdev)
16978 + struct conn_hash *h = &hdev->conn_hash;
16979 + struct list_head *p;
16981 + BT_DBG("hdev %s", hdev->name);
16983 + p = h->list.next;
16984 + while (p != &h->list) {
16985 + struct hci_conn *c;
16987 + c = list_entry(p, struct hci_conn, list);
16990 + c->state = BT_CLOSED;
16992 + hci_proto_disconn_ind(c, 0x16);
16997 +int hci_get_conn_list(unsigned long arg)
16999 + struct hci_conn_list_req req, *cl;
17000 + struct hci_conn_info *ci;
17001 + struct hci_dev *hdev;
17002 + struct list_head *p;
17005 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
17008 + if (!(hdev = hci_dev_get(req.dev_id)))
17011 + size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
17013 + if (verify_area(VERIFY_WRITE, (void *)arg, size))
17016 + if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
17018 + ci = cl->conn_info;
17020 + hci_dev_lock_bh(hdev);
17021 + list_for_each(p, &hdev->conn_hash.list) {
17022 + register struct hci_conn *c;
17023 + c = list_entry(p, struct hci_conn, list);
17025 + bacpy(&(ci + n)->bdaddr, &c->dst);
17026 + (ci + n)->handle = c->handle;
17027 + (ci + n)->type = c->type;
17028 + (ci + n)->out = c->out;
17029 + (ci + n)->state = c->state;
17030 + (ci + n)->link_mode = c->link_mode;
17033 + hci_dev_unlock_bh(hdev);
17035 + cl->dev_id = hdev->id;
17036 + cl->conn_num = n;
17037 + size = n * sizeof(struct hci_conn_info) + sizeof(req);
17039 + hci_dev_put(hdev);
17041 + copy_to_user((void *) arg, cl, size);
17047 +int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
17049 + struct hci_conn_info_req req;
17050 + struct hci_conn_info ci;
17051 + struct hci_conn *conn;
17052 + char *ptr = (void *) arg + sizeof(req);
17054 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
17057 + if (verify_area(VERIFY_WRITE, ptr, sizeof(ci)))
17060 + hci_dev_lock_bh(hdev);
17061 + conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
17063 + bacpy(&ci.bdaddr, &conn->dst);
17064 + ci.handle = conn->handle;
17065 + ci.type = conn->type;
17066 + ci.out = conn->out;
17067 + ci.state = conn->state;
17068 + ci.link_mode = conn->link_mode;
17070 + hci_dev_unlock_bh(hdev);
17075 + copy_to_user(ptr, &ci, sizeof(ci));
17078 diff -urN linux-2.4.18/net/bluetooth/hci_core.c linux-2.4.18-mh9/net/bluetooth/hci_core.c
17079 --- linux-2.4.18/net/bluetooth/hci_core.c Fri Nov 9 23:21:21 2001
17080 +++ linux-2.4.18-mh9/net/bluetooth/hci_core.c Mon Aug 25 18:38:12 2003
17081 @@ -25,11 +25,12 @@
17085 - * $Id: hci_core.c,v 1.22 2001/08/03 04:19:50 maxk Exp $
17086 + * $Id: hci_core.c,v 1.14 2002/08/26 16:57:57 maxk Exp $
17089 #include <linux/config.h>
17090 #include <linux/module.h>
17091 +#include <linux/kmod.h>
17093 #include <linux/types.h>
17094 #include <linux/errno.h>
17095 @@ -50,12 +51,11 @@
17096 #include <asm/unaligned.h>
17098 #include <net/bluetooth/bluetooth.h>
17099 -#include <net/bluetooth/bluez.h>
17100 #include <net/bluetooth/hci_core.h>
17102 #ifndef HCI_CORE_DEBUG
17104 -#define DBG( A... )
17106 +#define BT_DBG( A... )
17109 static void hci_cmd_task(unsigned long arg);
17110 @@ -63,279 +63,69 @@
17111 static void hci_tx_task(unsigned long arg);
17112 static void hci_notify(struct hci_dev *hdev, int event);
17114 -static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
17115 +rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
17117 /* HCI device list */
17118 -struct hci_dev *hdev_list[HCI_MAX_DEV];
17119 -spinlock_t hdev_list_lock;
17120 -#define GET_HDEV(a) (hdev_list[a])
17122 -/* HCI protocol list */
17123 -struct hci_proto *hproto_list[HCI_MAX_PROTO];
17124 -#define GET_HPROTO(a) (hproto_list[a])
17125 +LIST_HEAD(hdev_list);
17126 +rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
17128 -/* HCI notifiers list */
17129 -struct notifier_block *hci_dev_notifier;
17131 -/* HCI device notifications */
17132 -int hci_register_notifier(struct notifier_block *nb)
17135 - struct hci_dev *hdev;
17137 - if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
17140 - /* Notify about already registered devices */
17141 - spin_lock(&hdev_list_lock);
17142 - for (i = 0; i < HCI_MAX_DEV; i++) {
17143 - if (!(hdev = GET_HDEV(i)))
17145 - if (hdev->flags & HCI_UP)
17146 - (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
17148 - spin_unlock(&hdev_list_lock);
17153 -int hci_unregister_notifier(struct notifier_block *nb)
17155 - return notifier_chain_unregister(&hci_dev_notifier, nb);
17158 -static inline void hci_notify(struct hci_dev *hdev, int event)
17160 - notifier_call_chain(&hci_dev_notifier, event, hdev);
17163 -/* Get HCI device by index (device is locked on return)*/
17164 -struct hci_dev *hci_dev_get(int index)
17166 - struct hci_dev *hdev;
17167 - DBG("%d", index);
17169 - if (index < 0 || index >= HCI_MAX_DEV)
17172 - spin_lock(&hdev_list_lock);
17173 - if ((hdev = GET_HDEV(index)))
17174 - hci_dev_hold(hdev);
17175 - spin_unlock(&hdev_list_lock);
17180 -/* Flush inquiry cache */
17181 -void inquiry_cache_flush(struct inquiry_cache *cache)
17183 - struct inquiry_entry *next = cache->list, *e;
17185 - DBG("cache %p", cache);
17187 - cache->list = NULL;
17188 - while ((e = next)) {
17194 -/* Lookup by bdaddr.
17195 - * Cache must be locked. */
17196 -static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
17198 - struct inquiry_entry *e;
17200 - DBG("cache %p, %s", cache, batostr(bdaddr));
17202 - for (e = cache->list; e; e = e->next)
17203 - if (!bacmp(&e->info.bdaddr, bdaddr))
17209 -static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
17211 - struct inquiry_entry *e;
17213 - DBG("cache %p, %s", cache, batostr(&info->bdaddr));
17215 - inquiry_cache_lock(cache);
17217 - if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
17218 - /* Entry not in the cache. Add new one. */
17219 - if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
17221 - memset(e, 0, sizeof(struct inquiry_entry));
17222 - e->next = cache->list;
17226 - memcpy(&e->info, info, sizeof(inquiry_info));
17227 - e->timestamp = jiffies;
17228 - cache->timestamp = jiffies;
17230 - inquiry_cache_unlock(cache);
17233 -static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
17235 - inquiry_info *info = (inquiry_info *) buf;
17236 - struct inquiry_entry *e;
17238 +/* HCI protocols */
17239 +#define HCI_MAX_PROTO 2
17240 +struct hci_proto *hci_proto[HCI_MAX_PROTO];
17242 - inquiry_cache_lock(cache);
17244 - for (e = cache->list; e && copied < num; e = e->next, copied++)
17245 - memcpy(info++, &e->info, sizeof(inquiry_info));
17246 +/* HCI notifiers list */
17247 +static struct notifier_block *hci_notifier;
17249 - inquiry_cache_unlock(cache);
17251 - DBG("cache %p, copied %d", cache, copied);
17254 +/* ---- HCI notifications ---- */
17256 -/* --------- BaseBand connections --------- */
17257 -static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
17258 +int hci_register_notifier(struct notifier_block *nb)
17260 - struct hci_conn *conn;
17262 - DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
17264 - if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
17265 - ERR("%s handle 0x%x already exists", hdev->name, handle);
17269 - if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
17271 - memset(conn, 0, sizeof(struct hci_conn));
17273 - bacpy(&conn->dst, dst);
17274 - conn->handle = handle;
17275 - conn->type = type;
17276 - conn->hdev = hdev;
17278 - skb_queue_head_init(&conn->data_q);
17280 - hci_dev_hold(hdev);
17281 - conn_hash_add(&hdev->conn_hash, handle, conn);
17284 + return notifier_chain_register(&hci_notifier, nb);
17287 -static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
17288 +int hci_unregister_notifier(struct notifier_block *nb)
17290 - DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
17292 - conn_hash_del(&hdev->conn_hash, conn);
17293 - hci_dev_put(hdev);
17295 - /* Unacked frames */
17296 - hdev->acl_cnt += conn->sent;
17298 - skb_queue_purge(&conn->data_q);
17302 + return notifier_chain_unregister(&hci_notifier, nb);
17305 -/* Drop all connection on the device */
17306 -static void hci_conn_hash_flush(struct hci_dev *hdev)
17307 +void hci_notify(struct hci_dev *hdev, int event)
17309 - struct conn_hash *h = &hdev->conn_hash;
17310 - struct hci_proto *hp;
17311 - struct list_head *p;
17313 - DBG("hdev %s", hdev->name);
17315 - p = h->list.next;
17316 - while (p != &h->list) {
17317 - struct hci_conn *c;
17319 - c = list_entry(p, struct hci_conn, list);
17322 - if (c->type == ACL_LINK) {
17323 - /* ACL link notify L2CAP layer */
17324 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
17325 - hp->disconn_ind(c, 0x16);
17327 - /* SCO link (no notification) */
17330 - hci_conn_del(hdev, c);
17332 + notifier_call_chain(&hci_notifier, event, hdev);
17335 -int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
17337 - struct inquiry_cache *cache = &hdev->inq_cache;
17338 - struct inquiry_entry *e;
17339 - create_conn_cp cc;
17340 - __u16 clock_offset;
17342 - DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
17344 - if (!(hdev->flags & HCI_UP))
17347 - inquiry_cache_lock_bh(cache);
17349 - if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
17350 - cc.pscan_rep_mode = 0;
17351 - cc.pscan_mode = 0;
17352 - clock_offset = 0;
17354 - cc.pscan_rep_mode = e->info.pscan_rep_mode;
17355 - cc.pscan_mode = e->info.pscan_mode;
17356 - clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
17359 - inquiry_cache_unlock_bh(cache);
17361 - bacpy(&cc.bdaddr, bdaddr);
17362 - cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
17363 - cc.clock_offset = __cpu_to_le16(clock_offset);
17365 - if (lmp_rswitch_capable(hdev))
17366 - cc.role_switch = 0x01;
17368 - cc.role_switch = 0x00;
17370 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
17371 +/* ---- HCI hotplug support ---- */
17375 +#ifdef CONFIG_HOTPLUG
17377 -int hci_disconnect(struct hci_conn *conn, __u8 reason)
17378 +static int hci_run_hotplug(char *dev, char *action)
17380 - disconnect_cp dc;
17382 - DBG("conn %p handle %d", conn, conn->handle);
17383 + char *argv[3], *envp[5], dstr[20], astr[32];
17385 - dc.handle = __cpu_to_le16(conn->handle);
17386 - dc.reason = reason;
17387 - hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
17388 + sprintf(dstr, "DEVICE=%s", dev);
17389 + sprintf(astr, "ACTION=%s", action);
17393 + argv[0] = hotplug_path;
17394 + argv[1] = "bluetooth";
17397 -/* --------- HCI request handling ------------ */
17398 -static inline void hci_req_lock(struct hci_dev *hdev)
17400 - down(&hdev->req_lock);
17401 + envp[0] = "HOME=/";
17402 + envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
17407 + return call_usermodehelper(argv[0], argv, envp);
17410 +#define hci_run_hotplug(A...)
17413 -static inline void hci_req_unlock(struct hci_dev *hdev)
17415 - up(&hdev->req_lock);
17417 +/* ---- HCI requests ---- */
17419 -static inline void hci_req_complete(struct hci_dev *hdev, int result)
17420 +void hci_req_complete(struct hci_dev *hdev, int result)
17422 - DBG("%s result 0x%2.2x", hdev->name, result);
17423 + BT_DBG("%s result 0x%2.2x", hdev->name, result);
17425 if (hdev->req_status == HCI_REQ_PEND) {
17426 hdev->req_result = result;
17427 @@ -344,9 +134,9 @@
17431 -static inline void hci_req_cancel(struct hci_dev *hdev, int err)
17432 +void hci_req_cancel(struct hci_dev *hdev, int err)
17434 - DBG("%s err 0x%2.2x", hdev->name, err);
17435 + BT_DBG("%s err 0x%2.2x", hdev->name, err);
17437 if (hdev->req_status == HCI_REQ_PEND) {
17438 hdev->req_result = err;
17439 @@ -356,23 +146,22 @@
17442 /* Execute request and wait for completion. */
17443 -static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
17444 - unsigned long opt, __u32 timeout)
17445 +static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
17447 DECLARE_WAITQUEUE(wait, current);
17450 - DBG("%s start", hdev->name);
17451 + BT_DBG("%s start", hdev->name);
17453 hdev->req_status = HCI_REQ_PEND;
17455 add_wait_queue(&hdev->req_wait_q, &wait);
17456 - current->state = TASK_INTERRUPTIBLE;
17457 + set_current_state(TASK_INTERRUPTIBLE);
17460 schedule_timeout(timeout);
17462 - current->state = TASK_RUNNING;
17463 + set_current_state(TASK_RUNNING);
17464 remove_wait_queue(&hdev->req_wait_q, &wait);
17466 if (signal_pending(current))
17467 @@ -394,7 +183,7 @@
17469 hdev->req_status = hdev->req_result = 0;
17471 - DBG("%s end: err %d", hdev->name, err);
17472 + BT_DBG("%s end: err %d", hdev->name, err);
17476 @@ -412,10 +201,9 @@
17480 -/* --------- HCI requests ---------- */
17481 static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
17483 - DBG("%s %ld", hdev->name, opt);
17484 + BT_DBG("%s %ld", hdev->name, opt);
17487 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
17488 @@ -423,10 +211,10 @@
17490 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
17492 - set_event_flt_cp ec;
17493 + set_event_flt_cp ef;
17496 - DBG("%s %ld", hdev->name, opt);
17497 + BT_DBG("%s %ld", hdev->name, opt);
17499 /* Mandatory initialization */
17501 @@ -436,14 +224,30 @@
17502 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
17503 hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
17506 + /* Host buffer size */
17508 + host_buffer_size_cp bs;
17509 + bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
17510 + bs.sco_mtu = HCI_MAX_SCO_SIZE;
17511 + bs.acl_max_pkt = __cpu_to_le16(0xffff);
17512 + bs.sco_max_pkt = __cpu_to_le16(0xffff);
17513 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
17514 + HOST_BUFFER_SIZE_CP_SIZE, &bs);
17518 /* Read BD Address */
17519 hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
17521 + /* Read Voice Setting */
17522 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
17524 /* Optional initialization */
17526 /* Clear Event Filters */
17527 - ec.flt_type = FLT_CLEAR_ALL;
17528 - hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
17529 + ef.flt_type = FLT_CLEAR_ALL;
17530 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
17532 /* Page timeout ~20 secs */
17533 param = __cpu_to_le16(0x8000);
17534 @@ -458,7 +262,7 @@
17538 - DBG("%s %x", hdev->name, scan);
17539 + BT_DBG("%s %x", hdev->name, scan);
17541 /* Inquiry and Page scans */
17542 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
17543 @@ -468,116 +272,272 @@
17547 - DBG("%s %x", hdev->name, auth);
17548 + BT_DBG("%s %x", hdev->name, auth);
17550 /* Authentication */
17551 hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
17554 -static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
17555 +static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
17557 - struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
17559 + __u8 encrypt = opt;
17561 - DBG("%s", hdev->name);
17562 + BT_DBG("%s %x", hdev->name, encrypt);
17564 - /* Start Inquiry */
17565 - memcpy(&ic.lap, &ir->lap, 3);
17566 - ic.lenght = ir->length;
17567 - ic.num_rsp = ir->num_rsp;
17568 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
17569 + /* Authentication */
17570 + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
17573 -/* HCI ioctl helpers */
17574 -int hci_dev_open(__u16 dev)
17575 +/* Get HCI device by index.
17576 + * Device is locked on return. */
17577 +struct hci_dev *hci_dev_get(int index)
17579 struct hci_dev *hdev;
17582 - if (!(hdev = hci_dev_get(dev)))
17584 + struct list_head *p;
17586 - DBG("%s %p", hdev->name, hdev);
17587 + BT_DBG("%d", index);
17589 - hci_req_lock(hdev);
17593 - if (hdev->flags & HCI_UP) {
17596 + read_lock(&hdev_list_lock);
17597 + list_for_each(p, &hdev_list) {
17598 + hdev = list_entry(p, struct hci_dev, list);
17599 + if (hdev->id == index) {
17600 + hci_dev_hold(hdev);
17606 + read_unlock(&hdev_list_lock);
17610 - if (hdev->open(hdev)) {
17614 +/* ---- Inquiry support ---- */
17615 +void inquiry_cache_flush(struct hci_dev *hdev)
17617 + struct inquiry_cache *cache = &hdev->inq_cache;
17618 + struct inquiry_entry *next = cache->list, *e;
17620 - if (hdev->flags & HCI_NORMAL) {
17621 - atomic_set(&hdev->cmd_cnt, 1);
17622 - hdev->flags |= HCI_INIT;
17623 + BT_DBG("cache %p", cache);
17625 - //__hci_request(hdev, hci_reset_req, 0, HZ);
17626 - ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
17628 - hdev->flags &= ~HCI_INIT;
17629 + cache->list = NULL;
17630 + while ((e = next)) {
17637 - hdev->flags |= HCI_UP;
17638 - hci_notify(hdev, HCI_DEV_UP);
17640 - /* Init failed, cleanup */
17641 - tasklet_kill(&hdev->rx_task);
17642 - tasklet_kill(&hdev->tx_task);
17643 - tasklet_kill(&hdev->cmd_task);
17644 +struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
17646 + struct inquiry_cache *cache = &hdev->inq_cache;
17647 + struct inquiry_entry *e;
17649 - skb_queue_purge(&hdev->cmd_q);
17650 - skb_queue_purge(&hdev->rx_q);
17651 + BT_DBG("cache %p, %s", cache, batostr(bdaddr));
17654 - hdev->flush(hdev);
17655 + for (e = cache->list; e; e = e->next)
17656 + if (!bacmp(&e->info.bdaddr, bdaddr))
17661 - if (hdev->sent_cmd) {
17662 - kfree_skb(hdev->sent_cmd);
17663 - hdev->sent_cmd = NULL;
17665 +void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
17667 + struct inquiry_cache *cache = &hdev->inq_cache;
17668 + struct inquiry_entry *e;
17670 - hdev->close(hdev);
17672 + BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
17675 - hci_req_unlock(hdev);
17676 - hci_dev_put(hdev);
17677 + if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
17678 + /* Entry not in the cache. Add new one. */
17679 + if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
17681 + memset(e, 0, sizeof(struct inquiry_entry));
17682 + e->next = cache->list;
17687 + memcpy(&e->info, info, sizeof(inquiry_info));
17688 + e->timestamp = jiffies;
17689 + cache->timestamp = jiffies;
17692 -int hci_dev_close(__u16 dev)
17693 +int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
17695 - struct hci_dev *hdev;
17697 - if (!(hdev = hci_dev_get(dev)))
17699 + struct inquiry_cache *cache = &hdev->inq_cache;
17700 + inquiry_info *info = (inquiry_info *) buf;
17701 + struct inquiry_entry *e;
17704 - DBG("%s %p", hdev->name, hdev);
17705 + for (e = cache->list; e && copied < num; e = e->next, copied++)
17706 + memcpy(info++, &e->info, sizeof(inquiry_info));
17708 - hci_req_cancel(hdev, ENODEV);
17709 - hci_req_lock(hdev);
17710 + BT_DBG("cache %p, copied %d", cache, copied);
17714 - if (!(hdev->flags & HCI_UP))
17716 +static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
17718 + struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
17721 - /* Kill RX and TX tasks */
17722 - tasklet_kill(&hdev->rx_task);
17723 - tasklet_kill(&hdev->tx_task);
17724 + BT_DBG("%s", hdev->name);
17726 - inquiry_cache_flush(&hdev->inq_cache);
17727 + if (test_bit(HCI_INQUIRY, &hdev->flags))
17730 - hci_conn_hash_flush(hdev);
17731 + /* Start Inquiry */
17732 + memcpy(&ic.lap, &ir->lap, 3);
17733 + ic.length = ir->length;
17734 + ic.num_rsp = ir->num_rsp;
17735 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
17738 - /* Clear flags */
17739 - hdev->flags &= HCI_SOCK;
17740 - hdev->flags |= HCI_NORMAL;
17741 +int hci_inquiry(unsigned long arg)
17743 + struct hci_inquiry_req ir;
17744 + struct hci_dev *hdev;
17745 + int err = 0, do_inquiry = 0, max_rsp;
17749 + ptr = (void *) arg;
17750 + if (copy_from_user(&ir, ptr, sizeof(ir)))
17753 + if (!(hdev = hci_dev_get(ir.dev_id)))
17756 + hci_dev_lock_bh(hdev);
17757 + if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
17758 + ir.flags & IREQ_CACHE_FLUSH) {
17759 + inquiry_cache_flush(hdev);
17762 + hci_dev_unlock_bh(hdev);
17764 + timeo = ir.length * 2 * HZ;
17765 + if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
17768 + /* for unlimited number of responses we will use buffer with 255 entries */
17769 + max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
17771 + /* cache_dump can't sleep. Therefore we allocate temp buffer and then
17772 + * copy it to the user space.
17774 + if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
17779 + hci_dev_lock_bh(hdev);
17780 + ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
17781 + hci_dev_unlock_bh(hdev);
17783 + BT_DBG("num_rsp %d", ir.num_rsp);
17785 + if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
17786 + (sizeof(inquiry_info) * ir.num_rsp))) {
17787 + copy_to_user(ptr, &ir, sizeof(ir));
17788 + ptr += sizeof(ir);
17789 + copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
17796 + hci_dev_put(hdev);
17800 +/* ---- HCI ioctl helpers ---- */
17802 +int hci_dev_open(__u16 dev)
17804 + struct hci_dev *hdev;
17807 + if (!(hdev = hci_dev_get(dev)))
17810 + BT_DBG("%s %p", hdev->name, hdev);
17812 + hci_req_lock(hdev);
17814 + if (test_bit(HCI_UP, &hdev->flags)) {
17819 + if (hdev->open(hdev)) {
17824 + if (!test_bit(HCI_RAW, &hdev->flags)) {
17825 + atomic_set(&hdev->cmd_cnt, 1);
17826 + set_bit(HCI_INIT, &hdev->flags);
17828 + //__hci_request(hdev, hci_reset_req, 0, HZ);
17829 + ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
17831 + clear_bit(HCI_INIT, &hdev->flags);
17835 + set_bit(HCI_UP, &hdev->flags);
17836 + hci_notify(hdev, HCI_DEV_UP);
17838 + /* Init failed, cleanup */
17839 + tasklet_kill(&hdev->rx_task);
17840 + tasklet_kill(&hdev->tx_task);
17841 + tasklet_kill(&hdev->cmd_task);
17843 + skb_queue_purge(&hdev->cmd_q);
17844 + skb_queue_purge(&hdev->rx_q);
17847 + hdev->flush(hdev);
17849 + if (hdev->sent_cmd) {
17850 + kfree_skb(hdev->sent_cmd);
17851 + hdev->sent_cmd = NULL;
17854 + hdev->close(hdev);
17859 + hci_req_unlock(hdev);
17860 + hci_dev_put(hdev);
17864 +static int hci_dev_do_close(struct hci_dev *hdev)
17866 + BT_DBG("%s %p", hdev->name, hdev);
17868 + hci_req_cancel(hdev, ENODEV);
17869 + hci_req_lock(hdev);
17871 + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
17872 + hci_req_unlock(hdev);
17876 + /* Kill RX and TX tasks */
17877 + tasklet_kill(&hdev->rx_task);
17878 + tasklet_kill(&hdev->tx_task);
17880 + hci_dev_lock_bh(hdev);
17881 + inquiry_cache_flush(hdev);
17882 + hci_conn_hash_flush(hdev);
17883 + hci_dev_unlock_bh(hdev);
17885 hci_notify(hdev, HCI_DEV_DOWN);
17888 @@ -586,9 +546,9 @@
17890 skb_queue_purge(&hdev->cmd_q);
17891 atomic_set(&hdev->cmd_cnt, 1);
17892 - hdev->flags |= HCI_INIT;
17893 - __hci_request(hdev, hci_reset_req, 0, HZ);
17894 - hdev->flags &= ~HCI_INIT;
17895 + set_bit(HCI_INIT, &hdev->flags);
17896 + __hci_request(hdev, hci_reset_req, 0, HZ/4);
17897 + clear_bit(HCI_INIT, &hdev->flags);
17899 /* Kill cmd task */
17900 tasklet_kill(&hdev->cmd_task);
17901 @@ -605,17 +565,28 @@
17904 /* After this point our queues are empty
17905 - * and no tasks are scheduled.
17907 + * and no tasks are scheduled. */
17911 - hci_req_unlock(hdev);
17912 - hci_dev_put(hdev);
17913 + /* Clear flags */
17916 + hci_req_unlock(hdev);
17920 +int hci_dev_close(__u16 dev)
17922 + struct hci_dev *hdev;
17925 + if (!(hdev = hci_dev_get(dev)))
17927 + err = hci_dev_do_close(hdev);
17928 + hci_dev_put(hdev);
17932 int hci_dev_reset(__u16 dev)
17934 struct hci_dev *hdev;
17935 @@ -627,16 +598,17 @@
17936 hci_req_lock(hdev);
17937 tasklet_disable(&hdev->tx_task);
17939 - if (!(hdev->flags & HCI_UP))
17940 + if (!test_bit(HCI_UP, &hdev->flags))
17944 skb_queue_purge(&hdev->rx_q);
17945 skb_queue_purge(&hdev->cmd_q);
17947 - inquiry_cache_flush(&hdev->inq_cache);
17949 + hci_dev_lock_bh(hdev);
17950 + inquiry_cache_flush(hdev);
17951 hci_conn_hash_flush(hdev);
17952 + hci_dev_unlock_bh(hdev);
17956 @@ -650,7 +622,6 @@
17957 tasklet_enable(&hdev->tx_task);
17958 hci_req_unlock(hdev);
17964 @@ -669,30 +640,11 @@
17968 -int hci_dev_setauth(unsigned long arg)
17970 - struct hci_dev *hdev;
17971 - struct hci_dev_req dr;
17974 - if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
17977 - if (!(hdev = hci_dev_get(dr.dev_id)))
17980 - ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
17982 - hci_dev_put(hdev);
17987 -int hci_dev_setscan(unsigned long arg)
17988 +int hci_dev_cmd(unsigned int cmd, unsigned long arg)
17990 struct hci_dev *hdev;
17991 struct hci_dev_req dr;
17995 if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
17997 @@ -700,48 +652,78 @@
17998 if (!(hdev = hci_dev_get(dr.dev_id)))
18001 - ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18003 - hci_dev_put(hdev);
18006 + err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18011 + case HCISETENCRYPT:
18012 + if (!lmp_encrypt_capable(hdev)) {
18013 + err = -EOPNOTSUPP;
18017 -int hci_dev_setptype(unsigned long arg)
18019 - struct hci_dev *hdev;
18020 - struct hci_dev_req dr;
18022 + if (!test_bit(HCI_AUTH, &hdev->flags)) {
18023 + /* Auth must be enabled first */
18024 + err = hci_request(hdev, hci_auth_req,
18025 + dr.dev_opt, HCI_INIT_TIMEOUT);
18030 + err = hci_request(hdev, hci_encrypt_req,
18031 + dr.dev_opt, HCI_INIT_TIMEOUT);
18035 + err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
18038 + case HCISETPTYPE:
18039 + hdev->pkt_type = (__u16) dr.dev_opt;
18042 + case HCISETLINKPOL:
18043 + hdev->link_policy = (__u16) dr.dev_opt;
18046 - if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
18048 + case HCISETLINKMODE:
18049 + hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
18052 - if (!(hdev = hci_dev_get(dr.dev_id)))
18054 + case HCISETACLMTU:
18055 + hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
18056 + hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
18059 - hdev->pkt_type = (__u16) dr.dev_opt;
18060 + case HCISETSCOMTU:
18061 + hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
18062 + hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
18075 -int hci_dev_list(unsigned long arg)
18076 +int hci_get_dev_list(unsigned long arg)
18078 struct hci_dev_list_req *dl;
18079 struct hci_dev_req *dr;
18080 - struct hci_dev *hdev;
18082 + struct list_head *p;
18086 if (get_user(dev_num, (__u16 *) arg))
18089 - /* Avoid long loop, overflow */
18090 - if (dev_num > 2048)
18094 - size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
18095 + size = dev_num * sizeof(*dr) + sizeof(*dl);
18097 if (verify_area(VERIFY_WRITE, (void *) arg, size))
18099 @@ -750,25 +732,27 @@
18103 - spin_lock_bh(&hdev_list_lock);
18104 - for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
18105 - if ((hdev = hdev_list[i])) {
18106 - (dr + n)->dev_id = hdev->id;
18107 - (dr + n)->dev_opt = hdev->flags;
18110 + read_lock_bh(&hdev_list_lock);
18111 + list_for_each(p, &hdev_list) {
18112 + struct hci_dev *hdev;
18113 + hdev = list_entry(p, struct hci_dev, list);
18114 + (dr + n)->dev_id = hdev->id;
18115 + (dr + n)->dev_opt = hdev->flags;
18116 + if (++n >= dev_num)
18119 - spin_unlock_bh(&hdev_list_lock);
18120 + read_unlock_bh(&hdev_list_lock);
18123 - size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
18124 + size = n * sizeof(*dr) + sizeof(*dl);
18126 copy_to_user((void *) arg, dl, size);
18132 -int hci_dev_info(unsigned long arg)
18133 +int hci_get_dev_info(unsigned long arg)
18135 struct hci_dev *hdev;
18136 struct hci_dev_info di;
18137 @@ -786,9 +770,11 @@
18138 di.flags = hdev->flags;
18139 di.pkt_type = hdev->pkt_type;
18140 di.acl_mtu = hdev->acl_mtu;
18141 - di.acl_max = hdev->acl_max;
18142 + di.acl_pkts = hdev->acl_pkts;
18143 di.sco_mtu = hdev->sco_mtu;
18144 - di.sco_max = hdev->sco_max;
18145 + di.sco_pkts = hdev->sco_pkts;
18146 + di.link_policy = hdev->link_policy;
18147 + di.link_mode = hdev->link_mode;
18149 memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
18150 memcpy(&di.features, &hdev->features, sizeof(di.features));
18151 @@ -801,258 +787,168 @@
18155 -__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
18157 - __u32 omode = hdev->flags & HCI_MODE_MASK;
18159 - hdev->flags &= ~HCI_MODE_MASK;
18160 - hdev->flags |= (mode & HCI_MODE_MASK);
18164 +/* ---- Interface to HCI drivers ---- */
18166 -__u32 hci_dev_getmode(struct hci_dev *hdev)
18167 +/* Register HCI device */
18168 +int hci_register_dev(struct hci_dev *hdev)
18170 - return hdev->flags & HCI_MODE_MASK;
18172 + struct list_head *head = &hdev_list, *p;
18175 -int hci_conn_list(unsigned long arg)
18177 - struct hci_conn_list_req req, *cl;
18178 - struct hci_conn_info *ci;
18179 - struct hci_dev *hdev;
18180 - struct list_head *p;
18182 + BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
18184 - if (copy_from_user(&req, (void *) arg, sizeof(req)))
18186 + if (!hdev->open || !hdev->close || !hdev->destruct)
18189 - if (!(hdev = hci_dev_get(req.dev_id)))
18191 + write_lock_bh(&hdev_list_lock);
18193 - /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
18194 - if(req.conn_num < 2048)
18196 + /* Find first available device id */
18197 + list_for_each(p, &hdev_list) {
18198 + if (list_entry(p, struct hci_dev, list)->id != id)
18203 - size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
18205 - if (!(cl = kmalloc(size, GFP_KERNEL)))
18207 - ci = cl->conn_info;
18208 + sprintf(hdev->name, "hci%d", id);
18210 + list_add(&hdev->list, head);
18212 - local_bh_disable();
18213 - conn_hash_lock(&hdev->conn_hash);
18214 - list_for_each(p, &hdev->conn_hash.list) {
18215 - register struct hci_conn *c;
18216 - c = list_entry(p, struct hci_conn, list);
18217 + atomic_set(&hdev->refcnt, 1);
18218 + spin_lock_init(&hdev->lock);
18221 + hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
18222 + hdev->link_mode = (HCI_LM_ACCEPT);
18224 - (ci + n)->handle = c->handle;
18225 - bacpy(&(ci + n)->bdaddr, &c->dst);
18228 - conn_hash_unlock(&hdev->conn_hash);
18229 - local_bh_enable();
18231 - cl->dev_id = hdev->id;
18232 - cl->conn_num = n;
18233 - size = n * sizeof(struct hci_conn_info) + sizeof(req);
18234 + tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
18235 + tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
18236 + tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
18238 - hci_dev_put(hdev);
18239 + skb_queue_head_init(&hdev->rx_q);
18240 + skb_queue_head_init(&hdev->cmd_q);
18241 + skb_queue_head_init(&hdev->raw_q);
18243 - if(copy_to_user((void *) arg, cl, size))
18247 + init_waitqueue_head(&hdev->req_wait_q);
18248 + init_MUTEX(&hdev->req_lock);
18250 -int hci_inquiry(unsigned long arg)
18252 - struct inquiry_cache *cache;
18253 - struct hci_inquiry_req ir;
18254 - struct hci_dev *hdev;
18255 - int err = 0, do_inquiry = 0;
18258 + inquiry_cache_init(hdev);
18260 - ptr = (void *) arg;
18261 - if (copy_from_user(&ir, ptr, sizeof(ir)))
18263 + conn_hash_init(hdev);
18265 - if (!(hdev = hci_dev_get(ir.dev_id)))
18267 + memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
18269 - cache = &hdev->inq_cache;
18270 + atomic_set(&hdev->promisc, 0);
18272 - inquiry_cache_lock(cache);
18273 - if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
18274 - inquiry_cache_flush(cache);
18277 - inquiry_cache_unlock(cache);
18278 + MOD_INC_USE_COUNT;
18280 - /* Limit inquiry time, also avoid overflows */
18281 + write_unlock_bh(&hdev_list_lock);
18283 - if(ir.length > 2048 || ir.num_rsp > 2048)
18288 + hci_notify(hdev, HCI_DEV_REG);
18289 + hci_run_hotplug(hdev->name, "register");
18291 - timeo = ir.length * 2 * HZ;
18292 - if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
18297 - /* cache_dump can't sleep. Therefore we allocate temp buffer and then
18298 - * copy it to the user space.
18300 - if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
18304 - ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
18305 +/* Unregister HCI device */
18306 +int hci_unregister_dev(struct hci_dev *hdev)
18308 + BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
18310 - DBG("num_rsp %d", ir.num_rsp);
18311 + write_lock_bh(&hdev_list_lock);
18312 + list_del(&hdev->list);
18313 + write_unlock_bh(&hdev_list_lock);
18315 - if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
18316 - copy_to_user(ptr, &ir, sizeof(ir));
18317 - ptr += sizeof(ir);
18318 - copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
18321 + hci_dev_do_close(hdev);
18324 + hci_notify(hdev, HCI_DEV_UNREG);
18325 + hci_run_hotplug(hdev->name, "unregister");
18331 + MOD_DEC_USE_COUNT;
18335 -/* Interface to HCI drivers */
18337 -/* Register HCI device */
18338 -int hci_register_dev(struct hci_dev *hdev)
18339 +/* Suspend HCI device */
18340 +int hci_suspend_dev(struct hci_dev *hdev)
18344 - DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
18346 - /* Find free slot */
18347 - spin_lock_bh(&hdev_list_lock);
18348 - for (i = 0; i < HCI_MAX_DEV; i++) {
18349 - if (!hdev_list[i]) {
18350 - hdev_list[i] = hdev;
18351 + hci_notify(hdev, HCI_DEV_SUSPEND);
18352 + hci_run_hotplug(hdev->name, "suspend");
18356 - sprintf(hdev->name, "hci%d", i);
18357 - atomic_set(&hdev->refcnt, 0);
18359 - hdev->flags = HCI_NORMAL;
18360 +/* Resume HCI device */
18361 +int hci_resume_dev(struct hci_dev *hdev)
18363 + hci_notify(hdev, HCI_DEV_RESUME);
18364 + hci_run_hotplug(hdev->name, "resume");
18368 - hdev->pkt_type = (HCI_DM1 | HCI_DH1);
18370 - tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
18371 - tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
18372 - tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
18374 - skb_queue_head_init(&hdev->rx_q);
18375 - skb_queue_head_init(&hdev->cmd_q);
18376 - skb_queue_head_init(&hdev->raw_q);
18378 - init_waitqueue_head(&hdev->req_wait_q);
18379 - init_MUTEX(&hdev->req_lock);
18381 - inquiry_cache_init(&hdev->inq_cache);
18383 - conn_hash_init(&hdev->conn_hash);
18385 - memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
18387 - hci_notify(hdev, HCI_DEV_REG);
18389 - MOD_INC_USE_COUNT;
18393 - spin_unlock_bh(&hdev_list_lock);
18395 - return (i == HCI_MAX_DEV) ? -1 : i;
18398 -/* Unregister HCI device */
18399 -int hci_unregister_dev(struct hci_dev *hdev)
18400 +/* Receive frame from HCI drivers */
18401 +int hci_recv_frame(struct sk_buff *skb)
18405 - DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
18407 - if (hdev->flags & HCI_UP)
18408 - hci_dev_close(hdev->id);
18409 + struct hci_dev *hdev = (struct hci_dev *) skb->dev;
18411 - /* Find device slot */
18412 - spin_lock(&hdev_list_lock);
18413 - for (i = 0; i < HCI_MAX_DEV; i++) {
18414 - if (hdev_list[i] == hdev) {
18415 - hdev_list[i] = NULL;
18416 - MOD_DEC_USE_COUNT;
18419 + if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
18420 + !test_bit(HCI_INIT, &hdev->flags)) ) {
18424 - spin_unlock(&hdev_list_lock);
18426 - hci_notify(hdev, HCI_DEV_UNREG);
18428 - /* Sleep while device is in use */
18429 - while (atomic_read(&hdev->refcnt)) {
18430 - int sleep_cnt = 100;
18431 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
18433 - DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
18434 + /* Incomming skb */
18435 + bluez_cb(skb)->incomming = 1;
18437 - sleep_on_timeout(&hdev->req_wait_q, HZ*10);
18438 - if (!(--sleep_cnt))
18442 + do_gettimeofday(&skb->stamp);
18444 + /* Queue frame for rx task */
18445 + skb_queue_tail(&hdev->rx_q, skb);
18446 + hci_sched_rx(hdev);
18450 -/* Interface to upper protocols */
18451 +/* ---- Interface to upper protocols ---- */
18453 /* Register/Unregister protocols.
18454 - * hci_task_lock is used to ensure that no tasks are running.
18456 -int hci_register_proto(struct hci_proto *hproto)
18457 + * hci_task_lock is used to ensure that no tasks are running. */
18458 +int hci_register_proto(struct hci_proto *hp)
18462 - DBG("%p name %s", hproto, hproto->name);
18463 + BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18465 - if (hproto->id >= HCI_MAX_PROTO)
18466 + if (hp->id >= HCI_MAX_PROTO)
18469 write_lock_bh(&hci_task_lock);
18471 - if (!hproto_list[hproto->id])
18472 - hproto_list[hproto->id] = hproto;
18473 + if (!hci_proto[hp->id])
18474 + hci_proto[hp->id] = hp;
18479 write_unlock_bh(&hci_task_lock);
18484 -int hci_unregister_proto(struct hci_proto *hproto)
18485 +int hci_unregister_proto(struct hci_proto *hp)
18489 - DBG("%p name %s", hproto, hproto->name);
18490 + BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
18492 - if (hproto->id > HCI_MAX_PROTO)
18493 + if (hp->id >= HCI_MAX_PROTO)
18496 write_lock_bh(&hci_task_lock);
18498 - if (hproto_list[hproto->id])
18499 - hproto_list[hproto->id] = NULL;
18500 + if (hci_proto[hp->id])
18501 + hci_proto[hp->id] = NULL;
18505 @@ -1070,10 +966,14 @@
18509 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
18510 + BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
18512 + if (atomic_read(&hdev->promisc)) {
18514 + do_gettimeofday(&skb->stamp);
18516 - if (hdev->flags & HCI_SOCK)
18517 hci_send_to_sock(hdev, skb);
18520 /* Get rid of skb owner, prior to sending to the driver. */
18522 @@ -1081,128 +981,6 @@
18523 return hdev->send(skb);
18526 -/* Connection scheduler */
18527 -static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
18529 - struct conn_hash *h = &hdev->conn_hash;
18530 - struct hci_conn *conn = NULL;
18531 - int num = 0, min = 0xffff;
18532 - struct list_head *p;
18534 - conn_hash_lock(h);
18535 - list_for_each(p, &h->list) {
18536 - register struct hci_conn *c;
18538 - c = list_entry(p, struct hci_conn, list);
18540 - if (c->type != type || skb_queue_empty(&c->data_q))
18544 - if (c->sent < min) {
18549 - conn_hash_unlock(h);
18552 - int q = hdev->acl_cnt / num;
18553 - *quote = q ? q : 1;
18557 - DBG("conn %p quote %d", conn, *quote);
18562 -static inline void hci_sched_acl(struct hci_dev *hdev)
18564 - struct hci_conn *conn;
18565 - struct sk_buff *skb;
18568 - DBG("%s", hdev->name);
18570 - while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) {
18571 - while (quote && (skb = skb_dequeue(&conn->data_q))) {
18572 - DBG("skb %p len %d", skb, skb->len);
18574 - hci_send_frame(skb);
18583 -/* Schedule SCO */
18584 -static inline void hci_sched_sco(struct hci_dev *hdev)
18586 - /* FIXME: For now we queue SCO packets to the raw queue
18588 - while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
18589 - hci_send_frame(skb);
18590 - conn->sco_sent++;
18596 -/* Get data from the previously sent command */
18597 -static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
18599 - hci_command_hdr *hc;
18601 - if (!hdev->sent_cmd)
18604 - hc = (void *) hdev->sent_cmd->data;
18606 - if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
18609 - DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
18611 - return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
18614 -/* Send raw HCI frame */
18615 -int hci_send_raw(struct sk_buff *skb)
18617 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
18624 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
18626 - if (hdev->flags & HCI_NORMAL) {
18627 - /* Queue frame according it's type */
18628 - switch (skb->pkt_type) {
18629 - case HCI_COMMAND_PKT:
18630 - skb_queue_tail(&hdev->cmd_q, skb);
18631 - hci_sched_cmd(hdev);
18634 - case HCI_ACLDATA_PKT:
18635 - case HCI_SCODATA_PKT:
18637 - * Check header here and queue to apropriate connection.
18643 - skb_queue_tail(&hdev->raw_q, skb);
18644 - hci_sched_tx(hdev);
18648 /* Send HCI command */
18649 int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
18651 @@ -1210,10 +988,10 @@
18652 hci_command_hdr *hc;
18653 struct sk_buff *skb;
18655 - DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
18656 + BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
18658 if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
18659 - ERR("%s Can't allocate memory for HCI command", hdev->name);
18660 + BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
18664 @@ -1224,7 +1002,7 @@
18666 memcpy(skb_put(skb, plen), param, plen);
18668 - DBG("skb len %d", skb->len);
18669 + BT_DBG("skb len %d", skb->len);
18671 skb->pkt_type = HCI_COMMAND_PKT;
18672 skb->dev = (void *) hdev;
18673 @@ -1234,10 +1012,28 @@
18677 +/* Get data from the previously sent command */
18678 +void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
18680 + hci_command_hdr *hc;
18682 + if (!hdev->sent_cmd)
18685 + hc = (void *) hdev->sent_cmd->data;
18687 + if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
18690 + BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
18692 + return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
18695 /* Send ACL data */
18696 static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
18698 - int len = skb->len;
18699 + int len = skb->len;
18702 ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
18703 @@ -1252,7 +1048,7 @@
18704 struct hci_dev *hdev = conn->hdev;
18705 struct sk_buff *list;
18707 - DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
18708 + BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
18710 skb->dev = (void *) hdev;
18711 skb->pkt_type = HCI_ACLDATA_PKT;
18712 @@ -1260,12 +1056,12 @@
18714 if (!(list = skb_shinfo(skb)->frag_list)) {
18715 /* Non fragmented */
18716 - DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
18717 + BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
18719 skb_queue_tail(&conn->data_q, skb);
18722 - DBG("%s frag %p len %d", hdev->name, skb, skb->len);
18723 + BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
18725 skb_shinfo(skb)->frag_list = NULL;
18727 @@ -1280,7 +1076,7 @@
18728 skb->pkt_type = HCI_ACLDATA_PKT;
18729 hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
18731 - DBG("%s frag %p len %d", hdev->name, skb, skb->len);
18732 + BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
18734 __skb_queue_tail(&conn->data_q, skb);
18736 @@ -1298,7 +1094,7 @@
18737 struct hci_dev *hdev = conn->hdev;
18740 - DBG("%s len %d", hdev->name, skb->len);
18741 + BT_DBG("%s len %d", hdev->name, skb->len);
18743 if (skb->len > hdev->sco_mtu) {
18745 @@ -1315,544 +1111,136 @@
18746 skb->pkt_type = HCI_SCODATA_PKT;
18747 skb_queue_tail(&conn->data_q, skb);
18748 hci_sched_tx(hdev);
18753 -/* Handle HCI Event packets */
18755 -/* Command Complete OGF LINK_CTL */
18756 -static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
18758 - DBG("%s ocf 0x%x", hdev->name, ocf);
18762 - DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
18767 -/* Command Complete OGF LINK_POLICY */
18768 -static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
18770 - DBG("%s ocf 0x%x", hdev->name, ocf);
18774 - DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
18779 -/* Command Complete OGF HOST_CTL */
18780 -static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
18782 - __u8 status, param;
18786 - DBG("%s ocf 0x%x", hdev->name, ocf);
18790 - status = *((__u8 *) skb->data);
18792 - hci_req_complete(hdev, status);
18795 - case OCF_SET_EVENT_FLT:
18796 - status = *((__u8 *) skb->data);
18799 - DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
18801 - DBG("%s SET_EVENT_FLT succeseful", hdev->name);
18805 - case OCF_WRITE_AUTH_ENABLE:
18806 - if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
18809 - status = *((__u8 *) skb->data);
18810 - param = *((__u8 *) sent);
18811 +/* ---- HCI TX task (outgoing data) ---- */
18814 - if (param == AUTH_ENABLED)
18815 - hdev->flags |= HCI_AUTH;
18817 - hdev->flags &= ~HCI_AUTH;
18819 - hci_req_complete(hdev, status);
18822 - case OCF_WRITE_CA_TIMEOUT:
18823 - status = *((__u8 *) skb->data);
18826 - DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
18828 - DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
18832 - case OCF_WRITE_PG_TIMEOUT:
18833 - status = *((__u8 *) skb->data);
18836 - DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
18838 - DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
18842 - case OCF_WRITE_SCAN_ENABLE:
18843 - if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
18845 - status = *((__u8 *) skb->data);
18846 - param = *((__u8 *) sent);
18848 - DBG("param 0x%x", param);
18852 - case IS_ENA_PS_ENA:
18853 - hdev->flags |= HCI_PSCAN | HCI_ISCAN;
18856 - case IS_ENA_PS_DIS:
18857 - hdev->flags &= ~HCI_PSCAN;
18858 - hdev->flags |= HCI_ISCAN;
18861 - case IS_DIS_PS_ENA:
18862 - hdev->flags &= ~HCI_ISCAN;
18863 - hdev->flags |= HCI_PSCAN;
18867 - hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
18871 - hci_req_complete(hdev, status);
18875 - DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
18880 -/* Command Complete OGF INFO_PARAM */
18881 -static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
18882 +/* HCI Connection scheduler */
18883 +static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
18885 - read_local_features_rp *lf;
18886 - read_buffer_size_rp *bs;
18887 - read_bd_addr_rp *ba;
18889 - DBG("%s ocf 0x%x", hdev->name, ocf);
18892 - case OCF_READ_LOCAL_FEATURES:
18893 - lf = (read_local_features_rp *) skb->data;
18895 - if (lf->status) {
18896 - DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
18900 - memcpy(hdev->features, lf->features, sizeof(hdev->features));
18902 - /* Adjust default settings according to features
18903 - * supported by device. */
18904 - if (hdev->features[0] & LMP_3SLOT)
18905 - hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
18907 - if (hdev->features[0] & LMP_5SLOT)
18908 - hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
18910 - DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
18914 - case OCF_READ_BUFFER_SIZE:
18915 - bs = (read_buffer_size_rp *) skb->data;
18917 - if (bs->status) {
18918 - DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
18922 - hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
18923 - hdev->sco_mtu = bs->sco_mtu;
18924 - hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
18925 - hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
18927 - DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
18928 - hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
18929 + struct conn_hash *h = &hdev->conn_hash;
18930 + struct hci_conn *conn = NULL;
18931 + int num = 0, min = ~0;
18932 + struct list_head *p;
18935 + /* We don't have to lock device here. Connections are always
18936 + * added and removed with TX task disabled. */
18937 + list_for_each(p, &h->list) {
18938 + struct hci_conn *c;
18939 + c = list_entry(p, struct hci_conn, list);
18941 - case OCF_READ_BD_ADDR:
18942 - ba = (read_bd_addr_rp *) skb->data;
18943 + if (c->type != type || c->state != BT_CONNECTED
18944 + || skb_queue_empty(&c->data_q))
18948 - if (!ba->status) {
18949 - bacpy(&hdev->bdaddr, &ba->bdaddr);
18951 - DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
18952 + if (c->sent < min) {
18958 - hci_req_complete(hdev, ba->status);
18961 + int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
18962 + int q = cnt / num;
18963 + *quote = q ? q : 1;
18968 - DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
18971 + BT_DBG("conn %p quote %d", conn, *quote);
18975 -/* Command Status OGF LINK_CTL */
18976 -static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
18977 +static inline void hci_acl_tx_to(struct hci_dev *hdev)
18979 - struct hci_proto * hp;
18981 - DBG("%s ocf 0x%x", hdev->name, ocf);
18984 - case OCF_CREATE_CONN:
18986 - create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
18991 - DBG("%s Create connection error: status 0x%x %s", hdev->name,
18992 - status, batostr(&cc->bdaddr));
18993 + struct conn_hash *h = &hdev->conn_hash;
18994 + struct list_head *p;
18995 + struct hci_conn *c;
18997 - /* Notify upper protocols */
18998 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
18999 - tasklet_disable(&hdev->tx_task);
19000 - hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
19001 - tasklet_enable(&hdev->tx_task);
19005 + BT_ERR("%s ACL tx timeout", hdev->name);
19007 - case OCF_INQUIRY:
19009 - DBG("%s Inquiry error: status 0x%x", hdev->name, status);
19010 - hci_req_complete(hdev, status);
19011 + /* Kill stalled connections */
19012 + list_for_each(p, &h->list) {
19013 + c = list_entry(p, struct hci_conn, list);
19014 + if (c->type == ACL_LINK && c->sent) {
19015 + BT_ERR("%s killing stalled ACL connection %s",
19016 + hdev->name, batostr(&c->dst));
19017 + hci_acl_disconn(c, 0x13);
19022 - DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
19027 -/* Command Status OGF LINK_POLICY */
19028 -static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
19030 - DBG("%s ocf 0x%x", hdev->name, ocf);
19034 - DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
19039 -/* Command Status OGF HOST_CTL */
19040 -static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
19042 - DBG("%s ocf 0x%x", hdev->name, ocf);
19046 - DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
19051 -/* Command Status OGF INFO_PARAM */
19052 -static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
19054 - DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
19058 - DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
19063 -/* Inquiry Complete */
19064 -static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19066 - __u8 status = *((__u8 *) skb->data);
19068 - DBG("%s status %d", hdev->name, status);
19070 - hci_req_complete(hdev, status);
19074 -/* Inquiry Result */
19075 -static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
19076 +static inline void hci_sched_acl(struct hci_dev *hdev)
19078 - inquiry_info *info = (inquiry_info *) (skb->data + 1);
19079 - int num_rsp = *((__u8 *) skb->data);
19081 - DBG("%s num_rsp %d", hdev->name, num_rsp);
19082 + struct hci_conn *conn;
19083 + struct sk_buff *skb;
19086 - for (; num_rsp; num_rsp--)
19087 - inquiry_cache_update(&hdev->inq_cache, info++);
19089 + BT_DBG("%s", hdev->name);
19091 -/* Connect Request */
19092 -static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
19094 - evt_conn_request *cr = (evt_conn_request *) skb->data;
19095 - struct hci_proto *hp;
19096 - accept_conn_req_cp ac;
19098 + /* ACL tx timeout must be longer than maximum
19099 + * link supervision timeout (40.9 seconds) */
19100 + if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
19101 + hci_acl_tx_to(hdev);
19103 - DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
19104 + while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) {
19105 + while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
19106 + BT_DBG("skb %p len %d", skb, skb->len);
19107 + hci_send_frame(skb);
19108 + hdev->acl_last_tx = jiffies;
19110 - /* Notify upper protocols */
19111 - if (cr->link_type == ACL_LINK) {
19112 - /* ACL link notify L2CAP */
19113 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
19114 - tasklet_disable(&hdev->tx_task);
19115 - accept = hp->connect_ind(hdev, &cr->bdaddr);
19116 - tasklet_enable(&hdev->tx_task);
19121 - /* SCO link (no notification) */
19122 - /* FIXME: Should be accept it here or let the requester (app) accept it ? */
19127 - /* Connection accepted by upper layer */
19128 - bacpy(&ac.bdaddr, &cr->bdaddr);
19129 - ac.role = 0x01; /* Remain slave */
19130 - hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
19132 - /* Connection rejected by upper layer */
19134 - * Should we use HCI reject here ?
19140 -/* Connect Complete */
19141 -static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19142 +/* Schedule SCO */
19143 +static inline void hci_sched_sco(struct hci_dev *hdev)
19145 - evt_conn_complete *cc = (evt_conn_complete *) skb->data;
19146 - struct hci_conn *conn = NULL;
19147 - struct hci_proto *hp;
19149 - DBG("%s", hdev->name);
19151 - tasklet_disable(&hdev->tx_task);
19154 - conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
19155 + struct hci_conn *conn;
19156 + struct sk_buff *skb;
19159 - /* Notify upper protocols */
19160 - if (cc->link_type == ACL_LINK) {
19161 - /* ACL link notify L2CAP layer */
19162 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
19163 - hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
19165 - /* SCO link (no notification) */
19167 + BT_DBG("%s", hdev->name);
19169 - tasklet_enable(&hdev->tx_task);
19171 + while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, "e))) {
19172 + while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
19173 + BT_DBG("skb %p len %d", skb, skb->len);
19174 + hci_send_frame(skb);
19176 -/* Disconnect Complete */
19177 -static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
19179 - evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
19180 - struct hci_conn *conn = NULL;
19181 - struct hci_proto *hp;
19182 - __u16 handle = __le16_to_cpu(dc->handle);
19184 - DBG("%s", hdev->name);
19186 - if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
19187 - tasklet_disable(&hdev->tx_task);
19189 - /* Notify upper protocols */
19190 - if (conn->type == ACL_LINK) {
19191 - /* ACL link notify L2CAP layer */
19192 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
19193 - hp->disconn_ind(conn, dc->reason);
19195 - /* SCO link (no notification) */
19197 + if (conn->sent == ~0)
19201 - hci_conn_del(hdev, conn);
19203 - tasklet_enable(&hdev->tx_task);
19207 -/* Number of completed packets */
19208 -static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
19209 +static void hci_tx_task(unsigned long arg)
19211 - evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
19215 - skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
19217 - DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
19218 + struct hci_dev *hdev = (struct hci_dev *) arg;
19219 + struct sk_buff *skb;
19221 - if (skb->len < nc->num_hndl * 4) {
19222 - DBG("%s bad parameters", hdev->name);
19225 + read_lock(&hci_task_lock);
19227 - tasklet_disable(&hdev->tx_task);
19228 + BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
19230 - for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
19231 - struct hci_conn *conn;
19232 - __u16 handle, count;
19233 + /* Schedule queues and send stuff to HCI driver */
19235 - handle = __le16_to_cpu(get_unaligned(ptr++));
19236 - count = __le16_to_cpu(get_unaligned(ptr++));
19237 + hci_sched_acl(hdev);
19239 - hdev->acl_cnt += count;
19240 + hci_sched_sco(hdev);
19242 - if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
19243 - conn->sent -= count;
19245 + /* Send next queued raw (unknown type) packet */
19246 + while ((skb = skb_dequeue(&hdev->raw_q)))
19247 + hci_send_frame(skb);
19249 - tasklet_enable(&hdev->tx_task);
19251 - hci_sched_tx(hdev);
19252 + read_unlock(&hci_task_lock);
19255 -static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
19257 - hci_event_hdr *he = (hci_event_hdr *) skb->data;
19258 - evt_cmd_status *cs;
19259 - evt_cmd_complete *ec;
19260 - __u16 opcode, ocf, ogf;
19262 - skb_pull(skb, HCI_EVENT_HDR_SIZE);
19264 - DBG("%s evt 0x%x", hdev->name, he->evt);
19266 - switch (he->evt) {
19267 - case EVT_NUM_COMP_PKTS:
19268 - hci_num_comp_pkts_evt(hdev, skb);
19271 - case EVT_INQUIRY_COMPLETE:
19272 - hci_inquiry_complete_evt(hdev, skb);
19275 - case EVT_INQUIRY_RESULT:
19276 - hci_inquiry_result_evt(hdev, skb);
19279 - case EVT_CONN_REQUEST:
19280 - hci_conn_request_evt(hdev, skb);
19283 - case EVT_CONN_COMPLETE:
19284 - hci_conn_complete_evt(hdev, skb);
19287 - case EVT_DISCONN_COMPLETE:
19288 - hci_disconn_complete_evt(hdev, skb);
19291 - case EVT_CMD_STATUS:
19292 - cs = (evt_cmd_status *) skb->data;
19293 - skb_pull(skb, EVT_CMD_STATUS_SIZE);
19295 - opcode = __le16_to_cpu(cs->opcode);
19296 - ogf = cmd_opcode_ogf(opcode);
19297 - ocf = cmd_opcode_ocf(opcode);
19300 - case OGF_INFO_PARAM:
19301 - hci_cs_info_param(hdev, ocf, cs->status);
19304 - case OGF_HOST_CTL:
19305 - hci_cs_host_ctl(hdev, ocf, cs->status);
19308 - case OGF_LINK_CTL:
19309 - hci_cs_link_ctl(hdev, ocf, cs->status);
19312 - case OGF_LINK_POLICY:
19313 - hci_cs_link_policy(hdev, ocf, cs->status);
19317 - DBG("%s Command Status OGF %x", hdev->name, ogf);
19322 - atomic_set(&hdev->cmd_cnt, 1);
19323 - if (!skb_queue_empty(&hdev->cmd_q))
19324 - hci_sched_cmd(hdev);
19328 - case EVT_CMD_COMPLETE:
19329 - ec = (evt_cmd_complete *) skb->data;
19330 - skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
19332 - opcode = __le16_to_cpu(ec->opcode);
19333 - ogf = cmd_opcode_ogf(opcode);
19334 - ocf = cmd_opcode_ocf(opcode);
19337 - case OGF_INFO_PARAM:
19338 - hci_cc_info_param(hdev, ocf, skb);
19341 - case OGF_HOST_CTL:
19342 - hci_cc_host_ctl(hdev, ocf, skb);
19345 - case OGF_LINK_CTL:
19346 - hci_cc_link_ctl(hdev, ocf, skb);
19349 - case OGF_LINK_POLICY:
19350 - hci_cc_link_policy(hdev, ocf, skb);
19354 - DBG("%s Command Completed OGF %x", hdev->name, ogf);
19359 - atomic_set(&hdev->cmd_cnt, 1);
19360 - if (!skb_queue_empty(&hdev->cmd_q))
19361 - hci_sched_cmd(hdev);
19367 - hdev->stat.evt_rx++;
19369 +/* ----- HCI RX task (incomming data proccessing) ----- */
19371 /* ACL data packet */
19372 static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
19373 @@ -1867,51 +1255,86 @@
19374 flags = acl_flags(handle);
19375 handle = acl_handle(handle);
19377 - DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
19378 + BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
19380 + hdev->stat.acl_rx++;
19382 - if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
19383 + hci_dev_lock(hdev);
19384 + conn = conn_hash_lookup_handle(hdev, handle);
19385 + hci_dev_unlock(hdev);
19388 register struct hci_proto *hp;
19390 /* Send to upper protocol */
19391 - if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
19392 + if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
19393 hp->recv_acldata(conn, skb, flags);
19398 - ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
19399 + BT_ERR("%s ACL packet for unknown connection handle %d",
19400 + hdev->name, handle);
19405 - hdev->stat.acl_rx++;
19408 /* SCO data packet */
19409 static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
19411 - DBG("%s len %d", hdev->name, skb->len);
19412 + hci_sco_hdr *sh = (void *) skb->data;
19413 + struct hci_conn *conn;
19416 + skb_pull(skb, HCI_SCO_HDR_SIZE);
19418 + handle = __le16_to_cpu(sh->handle);
19420 + BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
19423 hdev->stat.sco_rx++;
19425 + hci_dev_lock(hdev);
19426 + conn = conn_hash_lookup_handle(hdev, handle);
19427 + hci_dev_unlock(hdev);
19430 + register struct hci_proto *hp;
19432 + /* Send to upper protocol */
19433 + if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
19434 + hp->recv_scodata(conn, skb);
19438 + BT_ERR("%s SCO packet for unknown connection handle %d",
19439 + hdev->name, handle);
19445 -/* ----- HCI tasks ----- */
19446 void hci_rx_task(unsigned long arg)
19448 struct hci_dev *hdev = (struct hci_dev *) arg;
19449 struct sk_buff *skb;
19451 - DBG("%s", hdev->name);
19452 + BT_DBG("%s", hdev->name);
19454 read_lock(&hci_task_lock);
19456 while ((skb = skb_dequeue(&hdev->rx_q))) {
19457 - if (hdev->flags & HCI_SOCK) {
19458 + if (atomic_read(&hdev->promisc)) {
19459 /* Send copy to the sockets */
19460 hci_send_to_sock(hdev, skb);
19463 - if (hdev->flags & HCI_INIT) {
19464 + if (test_bit(HCI_RAW, &hdev->flags)) {
19469 + if (test_bit(HCI_INIT, &hdev->flags)) {
19470 /* Don't process data packets in this states. */
19471 switch (skb->pkt_type) {
19472 case HCI_ACLDATA_PKT:
19473 @@ -1921,64 +1344,43 @@
19477 - if (hdev->flags & HCI_NORMAL) {
19478 - /* Process frame */
19479 - switch (skb->pkt_type) {
19480 - case HCI_EVENT_PKT:
19481 - hci_event_packet(hdev, skb);
19483 + /* Process frame */
19484 + switch (skb->pkt_type) {
19485 + case HCI_EVENT_PKT:
19486 + hci_event_packet(hdev, skb);
19489 - case HCI_ACLDATA_PKT:
19490 - DBG("%s ACL data packet", hdev->name);
19491 - hci_acldata_packet(hdev, skb);
19493 + case HCI_ACLDATA_PKT:
19494 + BT_DBG("%s ACL data packet", hdev->name);
19495 + hci_acldata_packet(hdev, skb);
19498 - case HCI_SCODATA_PKT:
19499 - DBG("%s SCO data packet", hdev->name);
19500 - hci_scodata_packet(hdev, skb);
19502 + case HCI_SCODATA_PKT:
19503 + BT_DBG("%s SCO data packet", hdev->name);
19504 + hci_scodata_packet(hdev, skb);
19518 read_unlock(&hci_task_lock);
19521 -static void hci_tx_task(unsigned long arg)
19523 - struct hci_dev *hdev = (struct hci_dev *) arg;
19524 - struct sk_buff *skb;
19526 - read_lock(&hci_task_lock);
19528 - DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
19530 - /* Schedule queues and send stuff to HCI driver */
19532 - hci_sched_acl(hdev);
19534 - hci_sched_sco(hdev);
19536 - /* Send next queued raw (unknown type) packet */
19537 - while ((skb = skb_dequeue(&hdev->raw_q)))
19538 - hci_send_frame(skb);
19540 - read_unlock(&hci_task_lock);
19543 static void hci_cmd_task(unsigned long arg)
19545 struct hci_dev *hdev = (struct hci_dev *) arg;
19546 struct sk_buff *skb;
19548 - DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
19549 + BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
19551 + if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
19552 + BT_ERR("%s command tx timeout", hdev->name);
19553 + atomic_set(&hdev->cmd_cnt, 1);
19556 /* Send queued commands */
19557 if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
19558 if (hdev->sent_cmd)
19559 @@ -1987,6 +1389,7 @@
19560 if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
19561 atomic_dec(&hdev->cmd_cnt);
19562 hci_send_frame(skb);
19563 + hdev->cmd_last_tx = jiffies;
19565 skb_queue_head(&hdev->cmd_q, skb);
19566 hci_sched_cmd(hdev);
19567 @@ -1994,33 +1397,10 @@
19571 -/* Receive frame from HCI drivers */
19572 -int hci_recv_frame(struct sk_buff *skb)
19574 - struct hci_dev *hdev = (struct hci_dev *) skb->dev;
19576 - if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
19581 - DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
19583 - /* Incomming skb */
19584 - bluez_cb(skb)->incomming = 1;
19586 - /* Queue frame for rx task */
19587 - skb_queue_tail(&hdev->rx_q, skb);
19588 - hci_sched_rx(hdev);
19592 +/* ---- Initialization ---- */
19594 int hci_core_init(void)
19597 - spin_lock_init(&hdev_list_lock);
19602 @@ -2028,5 +1408,3 @@
19607 -MODULE_LICENSE("GPL");
19608 diff -urN linux-2.4.18/net/bluetooth/hci_event.c linux-2.4.18-mh9/net/bluetooth/hci_event.c
19609 --- linux-2.4.18/net/bluetooth/hci_event.c Thu Jan 1 01:00:00 1970
19610 +++ linux-2.4.18-mh9/net/bluetooth/hci_event.c Mon Aug 25 18:38:12 2003
19613 + BlueZ - Bluetooth protocol stack for Linux
19614 + Copyright (C) 2000-2001 Qualcomm Incorporated
19616 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
19618 + This program is free software; you can redistribute it and/or modify
19619 + it under the terms of the GNU General Public License version 2 as
19620 + published by the Free Software Foundation;
19622 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19623 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19624 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
19625 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
19626 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
19627 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19628 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19629 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19631 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19632 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
19633 + SOFTWARE IS DISCLAIMED.
19639 + * $Id: hci_event.c,v 1.4 2002/07/27 18:14:38 maxk Exp $
19642 +#include <linux/config.h>
19643 +#include <linux/module.h>
19645 +#include <linux/types.h>
19646 +#include <linux/errno.h>
19647 +#include <linux/kernel.h>
19648 +#include <linux/major.h>
19649 +#include <linux/sched.h>
19650 +#include <linux/slab.h>
19651 +#include <linux/poll.h>
19652 +#include <linux/fcntl.h>
19653 +#include <linux/init.h>
19654 +#include <linux/skbuff.h>
19655 +#include <linux/interrupt.h>
19656 +#include <linux/notifier.h>
19657 +#include <net/sock.h>
19659 +#include <asm/system.h>
19660 +#include <asm/uaccess.h>
19661 +#include <asm/unaligned.h>
19663 +#include <net/bluetooth/bluetooth.h>
19664 +#include <net/bluetooth/hci_core.h>
19666 +#ifndef HCI_CORE_DEBUG
19668 +#define BT_DBG( A... )
19671 +/* Handle HCI Event packets */
19673 +/* Command Complete OGF LINK_CTL */
19674 +static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19678 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
19681 + case OCF_INQUIRY_CANCEL:
19682 + status = *((__u8 *) skb->data);
19685 + BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
19687 + clear_bit(HCI_INQUIRY, &hdev->flags);
19688 + hci_req_complete(hdev, status);
19693 + BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
19698 +/* Command Complete OGF LINK_POLICY */
19699 +static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19701 + struct hci_conn *conn;
19702 + role_discovery_rp *rd;
19704 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
19707 + case OCF_ROLE_DISCOVERY:
19708 + rd = (void *) skb->data;
19713 + hci_dev_lock(hdev);
19715 + conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
19718 + conn->link_mode &= ~HCI_LM_MASTER;
19720 + conn->link_mode |= HCI_LM_MASTER;
19723 + hci_dev_unlock(hdev);
19727 + BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
19728 + hdev->name, ocf);
19733 +/* Command Complete OGF HOST_CTL */
19734 +static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19736 + __u8 status, param;
19738 + read_voice_setting_rp *vs;
19741 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
19745 + status = *((__u8 *) skb->data);
19746 + hci_req_complete(hdev, status);
19749 + case OCF_SET_EVENT_FLT:
19750 + status = *((__u8 *) skb->data);
19752 + BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
19754 + BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
19758 + case OCF_WRITE_AUTH_ENABLE:
19759 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
19763 + status = *((__u8 *) skb->data);
19764 + param = *((__u8 *) sent);
19767 + if (param == AUTH_ENABLED)
19768 + set_bit(HCI_AUTH, &hdev->flags);
19770 + clear_bit(HCI_AUTH, &hdev->flags);
19772 + hci_req_complete(hdev, status);
19775 + case OCF_WRITE_ENCRYPT_MODE:
19776 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
19780 + status = *((__u8 *) skb->data);
19781 + param = *((__u8 *) sent);
19785 + set_bit(HCI_ENCRYPT, &hdev->flags);
19787 + clear_bit(HCI_ENCRYPT, &hdev->flags);
19789 + hci_req_complete(hdev, status);
19792 + case OCF_WRITE_CA_TIMEOUT:
19793 + status = *((__u8 *) skb->data);
19795 + BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
19797 + BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
19801 + case OCF_WRITE_PG_TIMEOUT:
19802 + status = *((__u8 *) skb->data);
19804 + BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
19806 + BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
19810 + case OCF_WRITE_SCAN_ENABLE:
19811 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
19815 + status = *((__u8 *) skb->data);
19816 + param = *((__u8 *) sent);
19818 + BT_DBG("param 0x%x", param);
19821 + clear_bit(HCI_PSCAN, &hdev->flags);
19822 + clear_bit(HCI_ISCAN, &hdev->flags);
19823 + if (param & SCAN_INQUIRY)
19824 + set_bit(HCI_ISCAN, &hdev->flags);
19826 + if (param & SCAN_PAGE)
19827 + set_bit(HCI_PSCAN, &hdev->flags);
19829 + hci_req_complete(hdev, status);
19832 + case OCF_READ_VOICE_SETTING:
19833 + vs = (read_voice_setting_rp *) skb->data;
19835 + if (vs->status) {
19836 + BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vc->status);
19840 + setting = __le16_to_cpu(vs->voice_setting);
19842 + if (hdev->voice_setting != setting ) {
19843 + hdev->voice_setting = setting;
19845 + BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
19847 + if (hdev->notify)
19848 + hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING, 0);
19853 + case OCF_WRITE_VOICE_SETTING:
19854 + sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
19858 + status = *((__u8 *) skb->data);
19859 + setting = __le16_to_cpu(get_unaligned((__u16 *) sent));
19861 + if (!status && hdev->voice_setting != setting) {
19862 + hdev->voice_setting = setting;
19864 + BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
19866 + if (hdev->notify)
19867 + hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING, 0);
19869 + hci_req_complete(hdev, status);
19872 + case OCF_HOST_BUFFER_SIZE:
19873 + status = *((__u8 *) skb->data);
19875 + BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
19876 + hci_req_complete(hdev, status);
19881 + BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
19886 +/* Command Complete OGF INFO_PARAM */
19887 +static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
19889 + read_local_features_rp *lf;
19890 + read_buffer_size_rp *bs;
19891 + read_bd_addr_rp *ba;
19893 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
19896 + case OCF_READ_LOCAL_FEATURES:
19897 + lf = (read_local_features_rp *) skb->data;
19899 + if (lf->status) {
19900 + BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
19904 + memcpy(hdev->features, lf->features, sizeof(hdev->features));
19906 + /* Adjust default settings according to features
19907 + * supported by device. */
19908 + if (hdev->features[0] & LMP_3SLOT)
19909 + hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
19911 + if (hdev->features[0] & LMP_5SLOT)
19912 + hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
19914 + if (hdev->features[1] & LMP_HV2)
19915 + hdev->pkt_type |= (HCI_HV2);
19917 + if (hdev->features[1] & LMP_HV3)
19918 + hdev->pkt_type |= (HCI_HV3);
19920 + BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
19924 + case OCF_READ_BUFFER_SIZE:
19925 + bs = (read_buffer_size_rp *) skb->data;
19927 + if (bs->status) {
19928 + BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
19929 + hci_req_complete(hdev, bs->status);
19933 + hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
19934 + hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
19935 + hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
19936 + hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
19938 + BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
19939 + hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
19943 + case OCF_READ_BD_ADDR:
19944 + ba = (read_bd_addr_rp *) skb->data;
19946 + if (!ba->status) {
19947 + bacpy(&hdev->bdaddr, &ba->bdaddr);
19949 + BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
19952 + hci_req_complete(hdev, ba->status);
19956 + BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
19961 +/* Command Status OGF LINK_CTL */
19962 +static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
19964 + struct hci_conn *conn;
19965 + create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
19970 + hci_dev_lock(hdev);
19972 + conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
19974 + BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
19975 + status, batostr(&cc->bdaddr), conn);
19979 + conn->state = BT_CLOSED;
19980 + hci_proto_connect_cfm(conn, status);
19981 + hci_conn_del(conn);
19985 + conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
19988 + conn->link_mode |= HCI_LM_MASTER;
19990 + BT_ERR("No memmory for new connection");
19994 + hci_dev_unlock(hdev);
19997 +static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
19999 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20002 + case OCF_CREATE_CONN:
20003 + hci_cs_create_conn(hdev, status);
20006 + case OCF_ADD_SCO:
20008 + struct hci_conn *acl, *sco;
20009 + add_sco_cp *cp = hci_sent_cmd_data(hdev,
20010 + OGF_LINK_CTL, OCF_ADD_SCO);
20016 + handle = __le16_to_cpu(cp->handle);
20018 + BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
20020 + hci_dev_lock(hdev);
20022 + acl = conn_hash_lookup_handle(hdev, handle);
20023 + if (acl && (sco = acl->link)) {
20024 + sco->state = BT_CLOSED;
20025 + hci_proto_connect_cfm(sco, status);
20026 + hci_conn_del(sco);
20029 + hci_dev_unlock(hdev);
20033 + case OCF_INQUIRY:
20035 + BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
20036 + hci_req_complete(hdev, status);
20038 + set_bit(HCI_INQUIRY, &hdev->flags);
20043 + BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
20044 + hdev->name, ocf, status);
20049 +/* Command Status OGF LINK_POLICY */
20050 +static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
20052 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20056 + BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
20061 +/* Command Status OGF HOST_CTL */
20062 +static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
20064 + BT_DBG("%s ocf 0x%x", hdev->name, ocf);
20068 + BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
20073 +/* Command Status OGF INFO_PARAM */
20074 +static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
20076 + BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
20080 + BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
20085 +/* Inquiry Complete */
20086 +static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20088 + __u8 status = *((__u8 *) skb->data);
20090 + BT_DBG("%s status %d", hdev->name, status);
20092 + clear_bit(HCI_INQUIRY, &hdev->flags);
20093 + hci_req_complete(hdev, status);
20096 +/* Inquiry Result */
20097 +static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
20099 + inquiry_info *info = (inquiry_info *) (skb->data + 1);
20100 + int num_rsp = *((__u8 *) skb->data);
20102 + BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
20104 + hci_dev_lock(hdev);
20105 + for (; num_rsp; num_rsp--)
20106 + inquiry_cache_update(hdev, info++);
20107 + hci_dev_unlock(hdev);
20110 +/* Connect Request */
20111 +static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
20113 + evt_conn_request *cr = (evt_conn_request *) skb->data;
20114 + int mask = hdev->link_mode;
20116 + BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
20117 + batostr(&cr->bdaddr), cr->link_type);
20119 + mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
20121 + if (mask & HCI_LM_ACCEPT) {
20122 + /* Connection accepted */
20123 + struct hci_conn *conn;
20124 + accept_conn_req_cp ac;
20126 + hci_dev_lock(hdev);
20127 + conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
20129 + if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
20130 + BT_ERR("No memmory for new connection");
20131 + hci_dev_unlock(hdev);
20135 + conn->state = BT_CONNECT;
20136 + hci_dev_unlock(hdev);
20138 + bacpy(&ac.bdaddr, &cr->bdaddr);
20140 + if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
20141 + ac.role = 0x00; /* Become master */
20143 + ac.role = 0x01; /* Remain slave */
20145 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
20146 + ACCEPT_CONN_REQ_CP_SIZE, &ac);
20148 + /* Connection rejected */
20149 + reject_conn_req_cp rc;
20151 + bacpy(&rc.bdaddr, &cr->bdaddr);
20152 + rc.reason = 0x0f;
20153 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
20154 + REJECT_CONN_REQ_CP_SIZE, &rc);
20158 +/* Connect Complete */
20159 +static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20161 + evt_conn_complete *cc = (evt_conn_complete *) skb->data;
20162 + struct hci_conn *conn = NULL;
20164 + BT_DBG("%s", hdev->name);
20166 + hci_dev_lock(hdev);
20168 + conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
20170 + hci_dev_unlock(hdev);
20174 + if (!cc->status) {
20175 + conn->handle = __le16_to_cpu(cc->handle);
20176 + conn->state = BT_CONNECTED;
20178 + if (test_bit(HCI_AUTH, &hdev->flags))
20179 + conn->link_mode |= HCI_LM_AUTH;
20181 + if (test_bit(HCI_ENCRYPT, &hdev->flags))
20182 + conn->link_mode |= HCI_LM_ENCRYPT;
20185 + /* Set link policy */
20186 + if (conn->type == ACL_LINK && hdev->link_policy) {
20187 + write_link_policy_cp lp;
20188 + lp.handle = cc->handle;
20189 + lp.policy = __cpu_to_le16(hdev->link_policy);
20190 + hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
20191 + WRITE_LINK_POLICY_CP_SIZE, &lp);
20194 + /* Set packet type for incomming connection */
20195 + if (!conn->out) {
20196 + change_conn_ptype_cp cp;
20197 + cp.handle = cc->handle;
20198 + cp.pkt_type = (conn->type == ACL_LINK) ?
20199 + __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
20200 + __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
20202 + hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
20203 + CHANGE_CONN_PTYPE_CP_SIZE, &cp);
20206 + conn->state = BT_CLOSED;
20208 + if (conn->type == ACL_LINK) {
20209 + struct hci_conn *sco = conn->link;
20212 + hci_add_sco(sco, conn->handle);
20214 + hci_proto_connect_cfm(sco, cc->status);
20215 + hci_conn_del(sco);
20220 + hci_proto_connect_cfm(conn, cc->status);
20222 + hci_conn_del(conn);
20224 + hci_dev_unlock(hdev);
20227 +/* Disconnect Complete */
20228 +static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20230 + evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
20231 + struct hci_conn *conn = NULL;
20232 + __u16 handle = __le16_to_cpu(dc->handle);
20234 + BT_DBG("%s status %d", hdev->name, dc->status);
20239 + hci_dev_lock(hdev);
20241 + conn = conn_hash_lookup_handle(hdev, handle);
20243 + conn->state = BT_CLOSED;
20244 + hci_proto_disconn_ind(conn, dc->reason);
20245 + hci_conn_del(conn);
20248 + hci_dev_unlock(hdev);
20251 +/* Number of completed packets */
20252 +static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
20254 + evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
20258 + skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
20260 + BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
20262 + if (skb->len < nc->num_hndl * 4) {
20263 + BT_DBG("%s bad parameters", hdev->name);
20267 + tasklet_disable(&hdev->tx_task);
20269 + for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
20270 + struct hci_conn *conn;
20271 + __u16 handle, count;
20273 + handle = __le16_to_cpu(get_unaligned(ptr++));
20274 + count = __le16_to_cpu(get_unaligned(ptr++));
20276 + conn = conn_hash_lookup_handle(hdev, handle);
20278 + conn->sent -= count;
20280 + if (conn->type == SCO_LINK) {
20281 + if ((hdev->sco_cnt += count) > hdev->sco_pkts)
20282 + hdev->sco_cnt = hdev->sco_pkts;
20284 + if ((hdev->acl_cnt += count) > hdev->acl_pkts)
20285 + hdev->acl_cnt = hdev->acl_pkts;
20289 + hci_sched_tx(hdev);
20291 + tasklet_enable(&hdev->tx_task);
20295 +static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
20297 + evt_role_change *rc = (evt_role_change *) skb->data;
20298 + struct hci_conn *conn = NULL;
20300 + BT_DBG("%s status %d", hdev->name, rc->status);
20305 + hci_dev_lock(hdev);
20307 + conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
20310 + conn->link_mode &= ~HCI_LM_MASTER;
20312 + conn->link_mode |= HCI_LM_MASTER;
20315 + hci_dev_unlock(hdev);
20318 +/* Authentication Complete */
20319 +static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
20321 + evt_auth_complete *ac = (evt_auth_complete *) skb->data;
20322 + struct hci_conn *conn = NULL;
20323 + __u16 handle = __le16_to_cpu(ac->handle);
20325 + BT_DBG("%s status %d", hdev->name, ac->status);
20327 + hci_dev_lock(hdev);
20329 + conn = conn_hash_lookup_handle(hdev, handle);
20332 + conn->link_mode |= HCI_LM_AUTH;
20333 + clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
20335 + hci_proto_auth_cfm(conn, ac->status);
20337 + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
20338 + if (!ac->status) {
20339 + set_conn_encrypt_cp ce;
20340 + ce.handle = __cpu_to_le16(conn->handle);
20342 + hci_send_cmd(conn->hdev, OGF_LINK_CTL,
20343 + OCF_SET_CONN_ENCRYPT,
20344 + SET_CONN_ENCRYPT_CP_SIZE, &ce);
20346 + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
20347 + hci_proto_encrypt_cfm(conn, ac->status);
20352 + hci_dev_unlock(hdev);
20355 +/* Encryption Change */
20356 +static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
20358 + evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
20359 + struct hci_conn *conn = NULL;
20360 + __u16 handle = __le16_to_cpu(ec->handle);
20362 + BT_DBG("%s status %d", hdev->name, ec->status);
20364 + hci_dev_lock(hdev);
20366 + conn = conn_hash_lookup_handle(hdev, handle);
20368 + if (!ec->status) {
20370 + conn->link_mode |= HCI_LM_ENCRYPT;
20372 + conn->link_mode &= ~HCI_LM_ENCRYPT;
20374 + clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
20376 + hci_proto_encrypt_cfm(conn, ec->status);
20379 + hci_dev_unlock(hdev);
20382 +void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
20384 + hci_event_hdr *he = (hci_event_hdr *) skb->data;
20385 + evt_cmd_status *cs;
20386 + evt_cmd_complete *ec;
20387 + __u16 opcode, ocf, ogf;
20389 + skb_pull(skb, HCI_EVENT_HDR_SIZE);
20391 + BT_DBG("%s evt 0x%x", hdev->name, he->evt);
20393 + switch (he->evt) {
20394 + case EVT_NUM_COMP_PKTS:
20395 + hci_num_comp_pkts_evt(hdev, skb);
20398 + case EVT_INQUIRY_COMPLETE:
20399 + hci_inquiry_complete_evt(hdev, skb);
20402 + case EVT_INQUIRY_RESULT:
20403 + hci_inquiry_result_evt(hdev, skb);
20406 + case EVT_CONN_REQUEST:
20407 + hci_conn_request_evt(hdev, skb);
20410 + case EVT_CONN_COMPLETE:
20411 + hci_conn_complete_evt(hdev, skb);
20414 + case EVT_DISCONN_COMPLETE:
20415 + hci_disconn_complete_evt(hdev, skb);
20418 + case EVT_ROLE_CHANGE:
20419 + hci_role_change_evt(hdev, skb);
20422 + case EVT_AUTH_COMPLETE:
20423 + hci_auth_complete_evt(hdev, skb);
20426 + case EVT_ENCRYPT_CHANGE:
20427 + hci_encrypt_change_evt(hdev, skb);
20430 + case EVT_CMD_STATUS:
20431 + cs = (evt_cmd_status *) skb->data;
20432 + skb_pull(skb, EVT_CMD_STATUS_SIZE);
20434 + opcode = __le16_to_cpu(cs->opcode);
20435 + ogf = cmd_opcode_ogf(opcode);
20436 + ocf = cmd_opcode_ocf(opcode);
20439 + case OGF_INFO_PARAM:
20440 + hci_cs_info_param(hdev, ocf, cs->status);
20443 + case OGF_HOST_CTL:
20444 + hci_cs_host_ctl(hdev, ocf, cs->status);
20447 + case OGF_LINK_CTL:
20448 + hci_cs_link_ctl(hdev, ocf, cs->status);
20451 + case OGF_LINK_POLICY:
20452 + hci_cs_link_policy(hdev, ocf, cs->status);
20456 + BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
20461 + atomic_set(&hdev->cmd_cnt, 1);
20462 + if (!skb_queue_empty(&hdev->cmd_q))
20463 + hci_sched_cmd(hdev);
20467 + case EVT_CMD_COMPLETE:
20468 + ec = (evt_cmd_complete *) skb->data;
20469 + skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
20471 + opcode = __le16_to_cpu(ec->opcode);
20472 + ogf = cmd_opcode_ogf(opcode);
20473 + ocf = cmd_opcode_ocf(opcode);
20476 + case OGF_INFO_PARAM:
20477 + hci_cc_info_param(hdev, ocf, skb);
20480 + case OGF_HOST_CTL:
20481 + hci_cc_host_ctl(hdev, ocf, skb);
20484 + case OGF_LINK_CTL:
20485 + hci_cc_link_ctl(hdev, ocf, skb);
20488 + case OGF_LINK_POLICY:
20489 + hci_cc_link_policy(hdev, ocf, skb);
20493 + BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
20498 + atomic_set(&hdev->cmd_cnt, 1);
20499 + if (!skb_queue_empty(&hdev->cmd_q))
20500 + hci_sched_cmd(hdev);
20506 + hdev->stat.evt_rx++;
20509 +/* General internal stack event */
20510 +void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
20512 + hci_event_hdr *eh;
20513 + evt_stack_internal *si;
20514 + struct sk_buff *skb;
20518 + size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
20519 + skb = bluez_skb_alloc(size, GFP_ATOMIC);
20523 + ptr = skb_put(skb, size);
20526 + eh->evt = EVT_STACK_INTERNAL;
20527 + eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
20528 + ptr += HCI_EVENT_HDR_SIZE;
20532 + memcpy(si->data, data, dlen);
20534 + skb->pkt_type = HCI_EVENT_PKT;
20535 + skb->dev = (void *) hdev;
20536 + hci_send_to_sock(hdev, skb);
20539 diff -urN linux-2.4.18/net/bluetooth/hci_sock.c linux-2.4.18-mh9/net/bluetooth/hci_sock.c
20540 --- linux-2.4.18/net/bluetooth/hci_sock.c Fri Sep 7 18:28:38 2001
20541 +++ linux-2.4.18-mh9/net/bluetooth/hci_sock.c Mon Aug 25 18:38:12 2003
20544 * BlueZ HCI socket layer.
20546 - * $Id: hci_sock.c,v 1.9 2001/08/05 06:02:16 maxk Exp $
20547 + * $Id: hci_sock.c,v 1.5 2002/07/22 20:32:54 maxk Exp $
20550 #include <linux/config.h>
20551 @@ -49,45 +49,54 @@
20553 #include <asm/system.h>
20554 #include <asm/uaccess.h>
20555 +#include <asm/unaligned.h>
20557 #include <net/bluetooth/bluetooth.h>
20558 -#include <net/bluetooth/bluez.h>
20559 #include <net/bluetooth/hci_core.h>
20561 #ifndef HCI_SOCK_DEBUG
20563 -#define DBG( A... )
20565 +#define BT_DBG( A... )
20568 -/* HCI socket interface */
20569 +/* ----- HCI socket interface ----- */
20571 +/* Security filter */
20572 +static struct hci_sec_filter hci_sec_filter = {
20573 + /* Packet types */
20580 + /* OGF_LINK_CTL */
20581 + { 0x2a000002, 0x0, 0x0, 0x0 },
20582 + /* OGF_LINK_POLICY */
20583 + { 0x1200, 0x0, 0x0, 0x0 },
20584 + /* OGF_HOST_CTL */
20585 + { 0x80100000, 0x202a, 0x0, 0x0 },
20586 + /* OGF_INFO_PARAM */
20587 + { 0x22a, 0x0, 0x0, 0x0 },
20588 + /* OGF_STATUS_PARAM */
20589 + { 0x2e, 0x0, 0x0, 0x0 }
20593 static struct bluez_sock_list hci_sk_list = {
20594 lock: RW_LOCK_UNLOCKED
20597 -static struct sock *hci_sock_lookup(struct hci_dev *hdev)
20601 - read_lock(&hci_sk_list.lock);
20602 - for (sk = hci_sk_list.head; sk; sk = sk->next) {
20603 - if (hci_pi(sk)->hdev == hdev)
20606 - read_unlock(&hci_sk_list.lock);
20610 /* Send frame to RAW socket */
20611 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
20615 - DBG("hdev %p len %d", hdev, skb->len);
20616 + BT_DBG("hdev %p len %d", hdev, skb->len);
20618 read_lock(&hci_sk_list.lock);
20619 for (sk = hci_sk_list.head; sk; sk = sk->next) {
20620 - struct hci_filter *flt;
20621 + struct hci_filter *flt;
20622 struct sk_buff *nskb;
20624 if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
20625 @@ -100,13 +109,19 @@
20627 flt = &hci_pi(sk)->filter;
20629 - if (!test_bit(skb->pkt_type, &flt->type_mask))
20630 + if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
20633 if (skb->pkt_type == HCI_EVENT_PKT) {
20634 - register int evt = (*(__u8 *)skb->data & 63);
20635 + register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
20637 + if (!hci_test_bit(evt, &flt->event_mask))
20640 - if (!test_bit(evt, &flt->event_mask))
20641 + if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
20642 + flt->opcode != *(__u16 *)(skb->data + 3)) ||
20643 + (evt == EVT_CMD_STATUS &&
20644 + flt->opcode != *(__u16 *)(skb->data + 4))))
20648 @@ -116,8 +131,8 @@
20649 /* Put type byte before the data */
20650 memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
20652 - skb_queue_tail(&sk->receive_queue, nskb);
20653 - sk->data_ready(sk, nskb->len);
20654 + if (sock_queue_rcv_skb(sk, nskb))
20657 read_unlock(&hci_sk_list.lock);
20659 @@ -127,7 +142,7 @@
20660 struct sock *sk = sock->sk;
20661 struct hci_dev *hdev = hci_pi(sk)->hdev;
20663 - DBG("sock %p sk %p", sock, sk);
20664 + BT_DBG("sock %p sk %p", sock, sk);
20668 @@ -135,9 +150,7 @@
20669 bluez_sock_unlink(&hci_sk_list, sk);
20672 - if (!hci_sock_lookup(hdev))
20673 - hdev->flags &= ~HCI_SOCK;
20675 + atomic_dec(&hdev->promisc);
20679 @@ -149,24 +162,55 @@
20687 -static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
20688 +/* Ioctls that require bound socket */
20689 +static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
20691 - struct sock *sk = sock->sk;
20692 struct hci_dev *hdev = hci_pi(sk)->hdev;
20695 - DBG("cmd %x arg %lx", cmd, arg);
20701 - return hci_dev_info(arg);
20703 + if (!capable(CAP_NET_ADMIN))
20707 + set_bit(HCI_RAW, &hdev->flags);
20709 + clear_bit(HCI_RAW, &hdev->flags);
20713 + case HCIGETCONNINFO:
20714 + return hci_get_conn_info(hdev, arg);
20718 + return hdev->ioctl(hdev, cmd, arg);
20723 +static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
20725 + struct sock *sk = sock->sk;
20728 + BT_DBG("cmd %x arg %lx", cmd, arg);
20731 case HCIGETDEVLIST:
20732 - return hci_dev_list(arg);
20733 + return hci_get_dev_list(arg);
20735 + case HCIGETDEVINFO:
20736 + return hci_get_dev_info(arg);
20738 + case HCIGETCONNLIST:
20739 + return hci_get_conn_list(arg);
20742 if (!capable(CAP_NET_ADMIN))
20743 @@ -183,48 +227,31 @@
20745 return hci_dev_reset(arg);
20747 - case HCIRESETSTAT:
20748 + case HCIDEVRESTAT:
20749 if (!capable(CAP_NET_ADMIN))
20751 return hci_dev_reset_stat(arg);
20754 - if (!capable(CAP_NET_ADMIN))
20756 - return hci_dev_setscan(arg);
20759 - if (!capable(CAP_NET_ADMIN))
20761 - return hci_dev_setauth(arg);
20764 - if (!capable(CAP_NET_ADMIN))
20773 - mode = HCI_NORMAL;
20775 - return hci_dev_setmode(hdev, mode);
20777 + case HCISETENCRYPT:
20779 + case HCISETLINKPOL:
20780 + case HCISETLINKMODE:
20781 + case HCISETACLMTU:
20782 + case HCISETSCOMTU:
20783 if (!capable(CAP_NET_ADMIN))
20785 - return hci_dev_setptype(arg);
20786 + return hci_dev_cmd(cmd, arg);
20789 return hci_inquiry(arg);
20791 - case HCIGETCONNLIST:
20792 - return hci_conn_list(arg);
20797 + err = hci_sock_bound_ioctl(sk, cmd, arg);
20798 + release_sock(sk);
20803 @@ -233,28 +260,35 @@
20804 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
20805 struct sock *sk = sock->sk;
20806 struct hci_dev *hdev = NULL;
20809 - DBG("sock %p sk %p", sock, sk);
20810 + BT_DBG("sock %p sk %p", sock, sk);
20812 if (!haddr || haddr->hci_family != AF_BLUETOOTH)
20817 if (hci_pi(sk)->hdev) {
20818 - /* Already bound */
20824 if (haddr->hci_dev != HCI_DEV_NONE) {
20825 - if (!(hdev = hci_dev_get(haddr->hci_dev)))
20827 + if (!(hdev = hci_dev_get(haddr->hci_dev))) {
20832 - hdev->flags |= HCI_SOCK;
20833 + atomic_inc(&hdev->promisc);
20836 hci_pi(sk)->hdev = hdev;
20837 sk->state = BT_BOUND;
20841 + release_sock(sk);
20845 static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
20846 @@ -262,73 +296,44 @@
20847 struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
20848 struct sock *sk = sock->sk;
20850 - DBG("sock %p sk %p", sock, sk);
20851 + BT_DBG("sock %p sk %p", sock, sk);
20855 *addr_len = sizeof(*haddr);
20856 haddr->hci_family = AF_BLUETOOTH;
20857 haddr->hci_dev = hci_pi(sk)->hdev->id;
20859 + release_sock(sk);
20863 -static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
20864 - struct scm_cookie *scm)
20866 - struct sock *sk = sock->sk;
20867 - struct hci_dev *hdev = hci_pi(sk)->hdev;
20868 - struct sk_buff *skb;
20871 - DBG("sock %p sk %p", sock, sk);
20873 - if (msg->msg_flags & MSG_OOB)
20874 - return -EOPNOTSUPP;
20876 - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
20882 - if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
20885 - if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
20890 - skb->dev = (void *) hdev;
20891 - skb->pkt_type = *((unsigned char *) skb->data);
20892 - skb_pull(skb, 1);
20894 - /* Send frame to HCI core */
20895 - hci_send_raw(skb);
20900 static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
20902 __u32 mask = hci_pi(sk)->cmsg_mask;
20904 if (mask & HCI_CMSG_DIR)
20905 put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
20907 + if (mask & HCI_CMSG_TSTAMP)
20908 + put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
20911 -static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
20912 - int flags, struct scm_cookie *scm)
20913 +static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
20915 int noblock = flags & MSG_DONTWAIT;
20916 struct sock *sk = sock->sk;
20917 struct sk_buff *skb;
20920 - DBG("sock %p sk %p", sock, sk);
20921 + BT_DBG("sock %p, sk %p", sock, sk);
20923 - if (flags & (MSG_OOB | MSG_PEEK))
20924 + if (flags & (MSG_OOB))
20925 return -EOPNOTSUPP;
20927 + if (sk->state == BT_CLOSED)
20930 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
20933 @@ -343,28 +348,107 @@
20934 skb->h.raw = skb->data;
20935 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
20937 - if (hci_pi(sk)->cmsg_mask)
20938 - hci_sock_cmsg(sk, msg, skb);
20940 + hci_sock_cmsg(sk, msg, skb);
20942 skb_free_datagram(sk, skb);
20944 return err ? : copied;
20947 +static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
20948 + struct scm_cookie *scm)
20950 + struct sock *sk = sock->sk;
20951 + struct hci_dev *hdev;
20952 + struct sk_buff *skb;
20955 + BT_DBG("sock %p sk %p", sock, sk);
20957 + if (msg->msg_flags & MSG_OOB)
20958 + return -EOPNOTSUPP;
20960 + if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
20968 + if (!(hdev = hci_pi(sk)->hdev)) {
20973 + if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
20976 + if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
20981 + skb->pkt_type = *((unsigned char *) skb->data);
20982 + skb_pull(skb, 1);
20983 + skb->dev = (void *) hdev;
20985 + if (skb->pkt_type == HCI_COMMAND_PKT) {
20986 + u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
20987 + u16 ogf = cmd_opcode_ogf(opcode);
20988 + u16 ocf = cmd_opcode_ocf(opcode);
20990 + if (((ogf > HCI_SFLT_MAX_OGF) ||
20991 + !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
20992 + !capable(CAP_NET_RAW)) {
20997 + if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
20998 + skb_queue_tail(&hdev->raw_q, skb);
20999 + hci_sched_tx(hdev);
21001 + skb_queue_tail(&hdev->cmd_q, skb);
21002 + hci_sched_cmd(hdev);
21005 + if (!capable(CAP_NET_RAW)) {
21010 + skb_queue_tail(&hdev->raw_q, skb);
21011 + hci_sched_tx(hdev);
21017 + release_sock(sk);
21025 int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
21027 struct sock *sk = sock->sk;
21028 - struct hci_filter flt;
21029 + struct hci_filter flt = { opcode: 0 };
21030 int err = 0, opt = 0;
21032 - DBG("sk %p, opt %d", sk, optname);
21033 + BT_DBG("sk %p, opt %d", sk, optname);
21039 - if (get_user(opt, (int *)optval))
21041 + if (get_user(opt, (int *)optval)) {
21047 hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
21048 @@ -372,12 +456,31 @@
21049 hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
21052 + case HCI_TIME_STAMP:
21053 + if (get_user(opt, (int *)optval)) {
21059 + hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
21061 + hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
21065 len = MIN(len, sizeof(struct hci_filter));
21066 if (copy_from_user(&flt, optval, len)) {
21071 + if (!capable(CAP_NET_RAW)) {
21072 + flt.type_mask &= hci_sec_filter.type_mask;
21073 + flt.event_mask[0] &= hci_sec_filter.event_mask[0];
21074 + flt.event_mask[1] &= hci_sec_filter.event_mask[1];
21077 memcpy(&hci_pi(sk)->filter, &flt, len);
21080 @@ -409,6 +512,16 @@
21084 + case HCI_TIME_STAMP:
21085 + if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
21090 + if (put_user(opt, optval))
21095 len = MIN(len, sizeof(struct hci_filter));
21096 if (copy_to_user(optval, &hci_pi(sk)->filter, len))
21097 @@ -446,7 +559,7 @@
21101 - DBG("sock %p", sock);
21102 + BT_DBG("sock %p", sock);
21104 if (sock->type != SOCK_RAW)
21105 return -ESOCKTNOSUPPORT;
21106 @@ -464,44 +577,31 @@
21107 sk->protocol = protocol;
21108 sk->state = BT_OPEN;
21110 - /* Initialize filter */
21111 - hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
21112 - hci_pi(sk)->filter.event_mask[0] = ~0L;
21113 - hci_pi(sk)->filter.event_mask[1] = ~0L;
21115 bluez_sock_link(&hci_sk_list, sk);
21122 static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
21124 struct hci_dev *hdev = (struct hci_dev *) ptr;
21125 - struct sk_buff *skb;
21127 - DBG("hdev %s event %ld", hdev->name, event);
21128 + evt_si_device sd;
21130 + BT_DBG("hdev %s event %ld", hdev->name, event);
21132 /* Send event to sockets */
21133 - if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
21134 - hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
21135 - evt_hci_dev_event he = { event, hdev->id };
21137 - skb->pkt_type = HCI_EVENT_PKT;
21138 - memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
21139 - memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
21141 - hci_send_to_sock(NULL, skb);
21145 + sd.event = event;
21146 + sd.dev_id = hdev->id;
21147 + hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
21149 if (event == HCI_DEV_UNREG) {
21152 /* Detach sockets from device */
21153 read_lock(&hci_sk_list.lock);
21154 for (sk = hci_sk_list.head; sk; sk = sk->next) {
21155 + bh_lock_sock(sk);
21156 if (hci_pi(sk)->hdev == hdev) {
21157 hci_pi(sk)->hdev = NULL;
21159 @@ -510,6 +610,7 @@
21163 + bh_unlock_sock(sk);
21165 read_unlock(&hci_sk_list.lock);
21167 @@ -529,21 +630,19 @@
21168 int hci_sock_init(void)
21170 if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
21171 - ERR("Can't register HCI socket");
21172 + BT_ERR("Can't register HCI socket");
21176 hci_register_notifier(&hci_sock_nblock);
21181 int hci_sock_cleanup(void)
21183 if (bluez_sock_unregister(BTPROTO_HCI))
21184 - ERR("Can't unregister HCI socket");
21185 + BT_ERR("Can't unregister HCI socket");
21187 hci_unregister_notifier(&hci_sock_nblock);
21191 diff -urN linux-2.4.18/net/bluetooth/l2cap.c linux-2.4.18-mh9/net/bluetooth/l2cap.c
21192 --- linux-2.4.18/net/bluetooth/l2cap.c Thu Jan 1 01:00:00 1970
21193 +++ linux-2.4.18-mh9/net/bluetooth/l2cap.c Mon Aug 25 18:38:12 2003
21196 + BlueZ - Bluetooth protocol stack for Linux
21197 + Copyright (C) 2000-2001 Qualcomm Incorporated
21199 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
21201 + This program is free software; you can redistribute it and/or modify
21202 + it under the terms of the GNU General Public License version 2 as
21203 + published by the Free Software Foundation;
21205 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21206 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21207 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
21208 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
21209 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
21210 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21211 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21212 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21214 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21215 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
21216 + SOFTWARE IS DISCLAIMED.
21220 + * BlueZ L2CAP core and sockets.
21222 + * $Id: l2cap.c,v 1.15 2002/09/09 01:14:52 maxk Exp $
21224 +#define VERSION "2.3"
21226 +#include <linux/config.h>
21227 +#include <linux/module.h>
21229 +#include <linux/types.h>
21230 +#include <linux/errno.h>
21231 +#include <linux/kernel.h>
21232 +#include <linux/major.h>
21233 +#include <linux/sched.h>
21234 +#include <linux/slab.h>
21235 +#include <linux/poll.h>
21236 +#include <linux/fcntl.h>
21237 +#include <linux/init.h>
21238 +#include <linux/skbuff.h>
21239 +#include <linux/interrupt.h>
21240 +#include <linux/socket.h>
21241 +#include <linux/skbuff.h>
21242 +#include <linux/proc_fs.h>
21243 +#include <linux/list.h>
21244 +#include <net/sock.h>
21246 +#include <asm/system.h>
21247 +#include <asm/uaccess.h>
21248 +#include <asm/unaligned.h>
21250 +#include <net/bluetooth/bluetooth.h>
21251 +#include <net/bluetooth/hci_core.h>
21252 +#include <net/bluetooth/l2cap.h>
21254 +#ifndef L2CAP_DEBUG
21256 +#define BT_DBG( A... )
21259 +static struct proto_ops l2cap_sock_ops;
21261 +struct bluez_sock_list l2cap_sk_list = {
21262 + lock: RW_LOCK_UNLOCKED
21265 +static int l2cap_conn_del(struct hci_conn *conn, int err);
21267 +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
21268 +static void l2cap_chan_del(struct sock *sk, int err);
21269 +static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
21271 +static void __l2cap_sock_close(struct sock *sk, int reason);
21272 +static void l2cap_sock_close(struct sock *sk);
21273 +static void l2cap_sock_kill(struct sock *sk);
21275 +static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
21276 +static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
21278 +/* ----- L2CAP timers ------ */
21279 +static void l2cap_sock_timeout(unsigned long arg)
21281 + struct sock *sk = (struct sock *) arg;
21283 + BT_DBG("sock %p state %d", sk, sk->state);
21285 + bh_lock_sock(sk);
21286 + __l2cap_sock_close(sk, ETIMEDOUT);
21287 + bh_unlock_sock(sk);
21289 + l2cap_sock_kill(sk);
21293 +static void l2cap_sock_set_timer(struct sock *sk, long timeout)
21295 + BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
21297 + if (!mod_timer(&sk->timer, jiffies + timeout))
21301 +static void l2cap_sock_clear_timer(struct sock *sk)
21303 + BT_DBG("sock %p state %d", sk, sk->state);
21305 + if (timer_pending(&sk->timer) && del_timer(&sk->timer))
21309 +static void l2cap_sock_init_timer(struct sock *sk)
21311 + init_timer(&sk->timer);
21312 + sk->timer.function = l2cap_sock_timeout;
21313 + sk->timer.data = (unsigned long)sk;
21316 +/* -------- L2CAP connections --------- */
21317 +static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
21319 + struct l2cap_conn *conn;
21321 + if ((conn = hcon->l2cap_data))
21327 + if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
21329 + memset(conn, 0, sizeof(struct l2cap_conn));
21331 + hcon->l2cap_data = conn;
21332 + conn->hcon = hcon;
21334 + conn->mtu = hcon->hdev->acl_mtu;
21335 + conn->src = &hcon->hdev->bdaddr;
21336 + conn->dst = &hcon->dst;
21338 + spin_lock_init(&conn->lock);
21339 + conn->chan_list.lock = RW_LOCK_UNLOCKED;
21341 + BT_DBG("hcon %p conn %p", hcon, conn);
21343 + MOD_INC_USE_COUNT;
21347 +static int l2cap_conn_del(struct hci_conn *hcon, int err)
21349 + struct l2cap_conn *conn;
21352 + if (!(conn = hcon->l2cap_data))
21355 + BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
21357 + if (conn->rx_skb)
21358 + kfree_skb(conn->rx_skb);
21360 + /* Kill channels */
21361 + while ((sk = conn->chan_list.head)) {
21362 + bh_lock_sock(sk);
21363 + l2cap_chan_del(sk, err);
21364 + bh_unlock_sock(sk);
21365 + l2cap_sock_kill(sk);
21368 + hcon->l2cap_data = NULL;
21371 + MOD_DEC_USE_COUNT;
21375 +/* -------- Socket interface ---------- */
21376 +static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
21379 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
21380 + if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
21386 +/* Find socket with psm and source bdaddr.
21387 + * Returns closest match.
21389 +static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
21391 + struct sock *sk, *sk1 = NULL;
21393 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
21394 + if (state && sk->state != state)
21397 + if (l2cap_pi(sk)->psm == psm) {
21398 + /* Exact match. */
21399 + if (!bacmp(&bluez_pi(sk)->src, src))
21402 + /* Closest match */
21403 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
21407 + return sk ? sk : sk1;
21410 +/* Find socket with given address (psm, src).
21411 + * Returns locked socket */
21412 +static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
21415 + read_lock(&l2cap_sk_list.lock);
21416 + s = __l2cap_get_sock_by_psm(state, psm, src);
21417 + if (s) bh_lock_sock(s);
21418 + read_unlock(&l2cap_sk_list.lock);
21422 +static void l2cap_sock_destruct(struct sock *sk)
21424 + BT_DBG("sk %p", sk);
21426 + skb_queue_purge(&sk->receive_queue);
21427 + skb_queue_purge(&sk->write_queue);
21429 + MOD_DEC_USE_COUNT;
21432 +static void l2cap_sock_cleanup_listen(struct sock *parent)
21436 + BT_DBG("parent %p", parent);
21438 + /* Close not yet accepted channels */
21439 + while ((sk = bluez_accept_dequeue(parent, NULL)))
21440 + l2cap_sock_close(sk);
21442 + parent->state = BT_CLOSED;
21443 + parent->zapped = 1;
21446 +/* Kill socket (only if zapped and orphan)
21447 + * Must be called on unlocked socket.
21449 +static void l2cap_sock_kill(struct sock *sk)
21451 + if (!sk->zapped || sk->socket)
21454 + BT_DBG("sk %p state %d", sk, sk->state);
21456 + /* Kill poor orphan */
21457 + bluez_sock_unlink(&l2cap_sk_list, sk);
21464 +static void __l2cap_sock_close(struct sock *sk, int reason)
21466 + BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
21468 + switch (sk->state) {
21470 + l2cap_sock_cleanup_listen(sk);
21473 + case BT_CONNECTED:
21475 + case BT_CONNECT2:
21476 + if (sk->type == SOCK_SEQPACKET) {
21477 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
21478 + l2cap_disconn_req req;
21480 + sk->state = BT_DISCONN;
21481 + l2cap_sock_set_timer(sk, sk->sndtimeo);
21483 + req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
21484 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
21485 + l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
21487 + l2cap_chan_del(sk, reason);
21493 + l2cap_chan_del(sk, reason);
21502 +/* Must be called on unlocked socket. */
21503 +static void l2cap_sock_close(struct sock *sk)
21505 + l2cap_sock_clear_timer(sk);
21507 + __l2cap_sock_close(sk, ECONNRESET);
21508 + release_sock(sk);
21509 + l2cap_sock_kill(sk);
21512 +static void l2cap_sock_init(struct sock *sk, struct sock *parent)
21514 + struct l2cap_pinfo *pi = l2cap_pi(sk);
21516 + BT_DBG("sk %p", sk);
21519 + sk->type = parent->type;
21520 + pi->imtu = l2cap_pi(parent)->imtu;
21521 + pi->omtu = l2cap_pi(parent)->omtu;
21522 + pi->link_mode = l2cap_pi(parent)->link_mode;
21524 + pi->imtu = L2CAP_DEFAULT_MTU;
21526 + pi->link_mode = 0;
21529 + /* Default config options */
21530 + pi->conf_mtu = L2CAP_DEFAULT_MTU;
21531 + pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
21534 +static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
21538 + if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
21541 + bluez_sock_init(sock, sk);
21545 + sk->destruct = l2cap_sock_destruct;
21546 + sk->sndtimeo = L2CAP_CONN_TIMEOUT;
21548 + sk->protocol = proto;
21549 + sk->state = BT_OPEN;
21551 + l2cap_sock_init_timer(sk);
21553 + bluez_sock_link(&l2cap_sk_list, sk);
21555 + MOD_INC_USE_COUNT;
21559 +static int l2cap_sock_create(struct socket *sock, int protocol)
21563 + BT_DBG("sock %p", sock);
21565 + sock->state = SS_UNCONNECTED;
21567 + if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
21568 + return -ESOCKTNOSUPPORT;
21570 + if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
21573 + sock->ops = &l2cap_sock_ops;
21575 + if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
21578 + l2cap_sock_init(sk, NULL);
21582 +static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
21584 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
21585 + struct sock *sk = sock->sk;
21588 + BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
21590 + if (!addr || addr->sa_family != AF_BLUETOOTH)
21595 + if (sk->state != BT_OPEN) {
21600 + write_lock_bh(&l2cap_sk_list.lock);
21601 + if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
21602 + err = -EADDRINUSE;
21604 + /* Save source address */
21605 + bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
21606 + l2cap_pi(sk)->psm = la->l2_psm;
21607 + sk->sport = la->l2_psm;
21608 + sk->state = BT_BOUND;
21610 + write_unlock_bh(&l2cap_sk_list.lock);
21613 + release_sock(sk);
21617 +static int l2cap_do_connect(struct sock *sk)
21619 + bdaddr_t *src = &bluez_pi(sk)->src;
21620 + bdaddr_t *dst = &bluez_pi(sk)->dst;
21621 + struct l2cap_conn *conn;
21622 + struct hci_conn *hcon;
21623 + struct hci_dev *hdev;
21626 + BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
21628 + if (!(hdev = hci_get_route(dst, src)))
21629 + return -EHOSTUNREACH;
21631 + hci_dev_lock_bh(hdev);
21635 + hcon = hci_connect(hdev, ACL_LINK, dst);
21639 + conn = l2cap_conn_add(hcon, 0);
21641 + hci_conn_put(hcon);
21647 + /* Update source addr of the socket */
21648 + bacpy(src, conn->src);
21650 + l2cap_chan_add(conn, sk, NULL);
21652 + sk->state = BT_CONNECT;
21653 + l2cap_sock_set_timer(sk, sk->sndtimeo);
21655 + if (hcon->state == BT_CONNECTED) {
21656 + if (sk->type == SOCK_SEQPACKET) {
21657 + l2cap_conn_req req;
21658 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
21659 + req.psm = l2cap_pi(sk)->psm;
21660 + l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
21662 + l2cap_sock_clear_timer(sk);
21663 + sk->state = BT_CONNECTED;
21668 + hci_dev_unlock_bh(hdev);
21669 + hci_dev_put(hdev);
21673 +static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
21675 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
21676 + struct sock *sk = sock->sk;
21681 + BT_DBG("sk %p", sk);
21683 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
21688 + if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
21693 + switch(sk->state) {
21695 + case BT_CONNECT2:
21697 + /* Already connecting */
21700 + case BT_CONNECTED:
21701 + /* Already connected */
21706 + /* Can connect */
21714 + /* Set destination address and psm */
21715 + bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
21716 + l2cap_pi(sk)->psm = la->l2_psm;
21718 + if ((err = l2cap_do_connect(sk)))
21722 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
21723 + sock_sndtimeo(sk, flags & O_NONBLOCK));
21726 + release_sock(sk);
21730 +int l2cap_sock_listen(struct socket *sock, int backlog)
21732 + struct sock *sk = sock->sk;
21735 + BT_DBG("sk %p backlog %d", sk, backlog);
21739 + if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
21744 + if (!l2cap_pi(sk)->psm) {
21749 + sk->max_ack_backlog = backlog;
21750 + sk->ack_backlog = 0;
21751 + sk->state = BT_LISTEN;
21754 + release_sock(sk);
21758 +int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
21760 + DECLARE_WAITQUEUE(wait, current);
21761 + struct sock *sk = sock->sk, *nsk;
21767 + if (sk->state != BT_LISTEN) {
21772 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
21774 + BT_DBG("sk %p timeo %ld", sk, timeo);
21776 + /* Wait for an incoming connection. (wake-one). */
21777 + add_wait_queue_exclusive(sk->sleep, &wait);
21778 + while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
21779 + set_current_state(TASK_INTERRUPTIBLE);
21785 + release_sock(sk);
21786 + timeo = schedule_timeout(timeo);
21789 + if (sk->state != BT_LISTEN) {
21794 + if (signal_pending(current)) {
21795 + err = sock_intr_errno(timeo);
21799 + set_current_state(TASK_RUNNING);
21800 + remove_wait_queue(sk->sleep, &wait);
21805 + newsock->state = SS_CONNECTED;
21807 + BT_DBG("new socket %p", nsk);
21810 + release_sock(sk);
21814 +static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
21816 + struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
21817 + struct sock *sk = sock->sk;
21819 + BT_DBG("sock %p, sk %p", sock, sk);
21821 + addr->sa_family = AF_BLUETOOTH;
21822 + *len = sizeof(struct sockaddr_l2);
21825 + bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
21827 + bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
21829 + la->l2_psm = l2cap_pi(sk)->psm;
21833 +static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
21835 + struct sock *sk = sock->sk;
21838 + BT_DBG("sock %p, sk %p", sock, sk);
21841 + return sock_error(sk);
21843 + if (msg->msg_flags & MSG_OOB)
21844 + return -EOPNOTSUPP;
21846 + /* Check outgoing MTU */
21847 + if (len > l2cap_pi(sk)->omtu)
21852 + if (sk->state == BT_CONNECTED)
21853 + err = l2cap_chan_send(sk, msg, len);
21857 + release_sock(sk);
21861 +static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
21863 + struct sock *sk = sock->sk;
21864 + struct l2cap_options opts;
21865 + int err = 0, len;
21868 + BT_DBG("sk %p", sk);
21872 + switch (optname) {
21873 + case L2CAP_OPTIONS:
21874 + len = MIN(sizeof(opts), optlen);
21875 + if (copy_from_user((char *)&opts, optval, len)) {
21879 + l2cap_pi(sk)->imtu = opts.imtu;
21880 + l2cap_pi(sk)->omtu = opts.omtu;
21884 + if (get_user(opt, (__u32 *)optval)) {
21889 + l2cap_pi(sk)->link_mode = opt;
21893 + err = -ENOPROTOOPT;
21897 + release_sock(sk);
21901 +static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
21903 + struct sock *sk = sock->sk;
21904 + struct l2cap_options opts;
21905 + struct l2cap_conninfo cinfo;
21906 + int len, err = 0;
21908 + if (get_user(len, optlen))
21913 + switch (optname) {
21914 + case L2CAP_OPTIONS:
21915 + opts.imtu = l2cap_pi(sk)->imtu;
21916 + opts.omtu = l2cap_pi(sk)->omtu;
21917 + opts.flush_to = l2cap_pi(sk)->flush_to;
21919 + len = MIN(len, sizeof(opts));
21920 + if (copy_to_user(optval, (char *)&opts, len))
21926 + if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
21930 + case L2CAP_CONNINFO:
21931 + if (sk->state != BT_CONNECTED) {
21936 + cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
21938 + len = MIN(len, sizeof(cinfo));
21939 + if (copy_to_user(optval, (char *)&cinfo, len))
21945 + err = -ENOPROTOOPT;
21949 + release_sock(sk);
21953 +static int l2cap_sock_shutdown(struct socket *sock, int how)
21955 + struct sock *sk = sock->sk;
21958 + BT_DBG("sock %p, sk %p", sock, sk);
21960 + if (!sk) return 0;
21963 + if (!sk->shutdown) {
21964 + sk->shutdown = SHUTDOWN_MASK;
21965 + l2cap_sock_clear_timer(sk);
21966 + __l2cap_sock_close(sk, 0);
21969 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
21971 + release_sock(sk);
21975 +static int l2cap_sock_release(struct socket *sock)
21977 + struct sock *sk = sock->sk;
21980 + BT_DBG("sock %p, sk %p", sock, sk);
21982 + if (!sk) return 0;
21984 + err = l2cap_sock_shutdown(sock, 2);
21987 + l2cap_sock_kill(sk);
21991 +/* --------- L2CAP channels --------- */
21992 +static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
21995 + for (s = l->head; s; s = l2cap_pi(s)->next_c) {
21996 + if (l2cap_pi(s)->dcid == cid)
22002 +static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
22005 + for (s = l->head; s; s = l2cap_pi(s)->next_c) {
22006 + if (l2cap_pi(s)->scid == cid)
22012 +/* Find channel with given SCID.
22013 + * Returns locked socket */
22014 +static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
22017 + read_lock(&l->lock);
22018 + s = __l2cap_get_chan_by_scid(l, cid);
22019 + if (s) bh_lock_sock(s);
22020 + read_unlock(&l->lock);
22024 +static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
22026 + __u16 cid = 0x0040;
22028 + for (; cid < 0xffff; cid++) {
22029 + if(!__l2cap_get_chan_by_scid(l, cid))
22036 +static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
22041 + l2cap_pi(l->head)->prev_c = sk;
22043 + l2cap_pi(sk)->next_c = l->head;
22044 + l2cap_pi(sk)->prev_c = NULL;
22048 +static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
22050 + struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
22052 + write_lock(&l->lock);
22053 + if (sk == l->head)
22057 + l2cap_pi(next)->prev_c = prev;
22059 + l2cap_pi(prev)->next_c = next;
22060 + write_unlock(&l->lock);
22065 +static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
22067 + struct l2cap_chan_list *l = &conn->chan_list;
22069 + BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
22071 + l2cap_pi(sk)->conn = conn;
22073 + if (sk->type == SOCK_SEQPACKET) {
22074 + /* Alloc CID for connection-oriented socket */
22075 + l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
22076 + } else if (sk->type == SOCK_DGRAM) {
22077 + /* Connectionless socket */
22078 + l2cap_pi(sk)->scid = 0x0002;
22079 + l2cap_pi(sk)->dcid = 0x0002;
22080 + l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
22082 + /* Raw socket can send/recv signalling messages only */
22083 + l2cap_pi(sk)->scid = 0x0001;
22084 + l2cap_pi(sk)->dcid = 0x0001;
22085 + l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
22088 + __l2cap_chan_link(l, sk);
22091 + bluez_accept_enqueue(parent, sk);
22094 +static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
22096 + struct l2cap_chan_list *l = &conn->chan_list;
22097 + write_lock(&l->lock);
22098 + __l2cap_chan_add(conn, sk, parent);
22099 + write_unlock(&l->lock);
22102 +/* Delete channel.
22103 + * Must be called on the locked socket. */
22104 +static void l2cap_chan_del(struct sock *sk, int err)
22106 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
22107 + struct sock *parent = bluez_pi(sk)->parent;
22109 + l2cap_sock_clear_timer(sk);
22111 + BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
22114 + /* Unlink from channel list */
22115 + l2cap_chan_unlink(&conn->chan_list, sk);
22116 + l2cap_pi(sk)->conn = NULL;
22117 + hci_conn_put(conn->hcon);
22120 + sk->state = BT_CLOSED;
22127 + parent->data_ready(parent, 0);
22129 + sk->state_change(sk);
22132 +static void l2cap_conn_ready(struct l2cap_conn *conn)
22134 + struct l2cap_chan_list *l = &conn->chan_list;
22137 + BT_DBG("conn %p", conn);
22139 + read_lock(&l->lock);
22141 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
22142 + bh_lock_sock(sk);
22144 + if (sk->type != SOCK_SEQPACKET) {
22145 + l2cap_sock_clear_timer(sk);
22146 + sk->state = BT_CONNECTED;
22147 + sk->state_change(sk);
22148 + } else if (sk->state == BT_CONNECT) {
22149 + l2cap_conn_req req;
22150 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
22151 + req.psm = l2cap_pi(sk)->psm;
22152 + l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
22155 + bh_unlock_sock(sk);
22158 + read_unlock(&l->lock);
22161 +/* Notify sockets that we cannot guaranty reliability anymore */
22162 +static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
22164 + struct l2cap_chan_list *l = &conn->chan_list;
22167 + BT_DBG("conn %p", conn);
22169 + read_lock(&l->lock);
22170 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
22171 + if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
22174 + read_unlock(&l->lock);
22177 +static void l2cap_chan_ready(struct sock *sk)
22179 + struct sock *parent = bluez_pi(sk)->parent;
22181 + BT_DBG("sk %p, parent %p", sk, parent);
22183 + l2cap_pi(sk)->conf_state = 0;
22184 + l2cap_sock_clear_timer(sk);
22187 + /* Outgoing channel.
22188 + * Wake up socket sleeping on connect.
22190 + sk->state = BT_CONNECTED;
22191 + sk->state_change(sk);
22193 + /* Incomming channel.
22194 + * Wake up socket sleeping on accept.
22196 + parent->data_ready(parent, 0);
22200 +/* Copy frame to all raw sockets on that connection */
22201 +void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
22203 + struct l2cap_chan_list *l = &conn->chan_list;
22204 + struct sk_buff *nskb;
22205 + struct sock * sk;
22207 + BT_DBG("conn %p", conn);
22209 + read_lock(&l->lock);
22210 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
22211 + if (sk->type != SOCK_RAW)
22214 + /* Don't send frame to the socket it came from */
22215 + if (skb->sk == sk)
22218 + if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
22221 + if (sock_queue_rcv_skb(sk, nskb))
22224 + read_unlock(&l->lock);
22227 +static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
22229 + struct l2cap_conn *conn = l2cap_pi(sk)->conn;
22230 + struct sk_buff *skb, **frag;
22231 + int err, hlen, count, sent=0;
22234 + BT_DBG("sk %p len %d", sk, len);
22236 + /* First fragment (with L2CAP header) */
22237 + if (sk->type == SOCK_DGRAM)
22238 + hlen = L2CAP_HDR_SIZE + 2;
22240 + hlen = L2CAP_HDR_SIZE;
22242 + count = MIN(conn->mtu - hlen, len);
22244 + skb = bluez_skb_send_alloc(sk, hlen + count,
22245 + msg->msg_flags & MSG_DONTWAIT, &err);
22249 + /* Create L2CAP header */
22250 + lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
22251 + lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
22252 + lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
22254 + if (sk->type == SOCK_DGRAM)
22255 + put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
22257 + if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
22265 + /* Continuation fragments (no L2CAP header) */
22266 + frag = &skb_shinfo(skb)->frag_list;
22268 + count = MIN(conn->mtu, len);
22270 + *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
22274 + if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
22282 + frag = &(*frag)->next;
22285 + if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
22295 +/* --------- L2CAP signalling commands --------- */
22296 +static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
22300 + /* Get next available identificator.
22301 + * 1 - 199 are used by kernel.
22302 + * 200 - 254 are used by utilities like l2ping, etc
22305 + spin_lock(&conn->lock);
22307 + if (++conn->tx_ident > 199)
22308 + conn->tx_ident = 1;
22310 + id = conn->tx_ident;
22312 + spin_unlock(&conn->lock);
22317 +static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
22318 + __u8 code, __u8 ident, __u16 dlen, void *data)
22320 + struct sk_buff *skb, **frag;
22321 + l2cap_cmd_hdr *cmd;
22325 + BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
22327 + len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
22328 + count = MIN(conn->mtu, len);
22330 + skb = bluez_skb_alloc(count, GFP_ATOMIC);
22334 + lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
22335 + lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
22336 + lh->cid = __cpu_to_le16(0x0001);
22338 + cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
22339 + cmd->code = code;
22340 + cmd->ident = ident;
22341 + cmd->len = __cpu_to_le16(dlen);
22344 + count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
22345 + memcpy(skb_put(skb, count), data, count);
22351 + /* Continuation fragments (no L2CAP header) */
22352 + frag = &skb_shinfo(skb)->frag_list;
22354 + count = MIN(conn->mtu, len);
22356 + *frag = bluez_skb_alloc(count, GFP_ATOMIC);
22360 + memcpy(skb_put(*frag, count), data, count);
22365 + frag = &(*frag)->next;
22375 +static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
22377 + __u8 ident = l2cap_get_ident(conn);
22378 + struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
22380 + BT_DBG("code 0x%2.2x", code);
22384 + return hci_send_acl(conn->hcon, skb, 0);
22387 +static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
22389 + struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
22391 + BT_DBG("code 0x%2.2x", code);
22395 + return hci_send_acl(conn->hcon, skb, 0);
22398 +static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
22400 + l2cap_conf_opt *opt = *ptr;
22403 + len = L2CAP_CONF_OPT_SIZE + opt->len;
22406 + *type = opt->type;
22407 + *olen = opt->len;
22409 + switch (opt->len) {
22411 + *val = *((__u8 *) opt->val);
22415 + *val = __le16_to_cpu(*((__u16 *)opt->val));
22419 + *val = __le32_to_cpu(*((__u32 *)opt->val));
22423 + *val = (unsigned long) opt->val;
22427 + BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
22431 +static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
22433 + int type, hint, olen;
22434 + unsigned long val;
22435 + void *ptr = data;
22437 + BT_DBG("sk %p len %d", sk, len);
22439 + while (len >= L2CAP_CONF_OPT_SIZE) {
22440 + len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
22442 + hint = type & 0x80;
22446 + case L2CAP_CONF_MTU:
22447 + l2cap_pi(sk)->conf_mtu = val;
22450 + case L2CAP_CONF_FLUSH_TO:
22451 + l2cap_pi(sk)->flush_to = val;
22454 + case L2CAP_CONF_QOS:
22461 + /* FIXME: Reject unknown option */
22467 +static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
22469 + register l2cap_conf_opt *opt = *ptr;
22471 + BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
22473 + opt->type = type;
22478 + *((__u8 *) opt->val) = val;
22482 + *((__u16 *) opt->val) = __cpu_to_le16(val);
22486 + *((__u32 *) opt->val) = __cpu_to_le32(val);
22490 + memcpy(opt->val, (void *) val, len);
22494 + *ptr += L2CAP_CONF_OPT_SIZE + len;
22497 +static int l2cap_build_conf_req(struct sock *sk, void *data)
22499 + struct l2cap_pinfo *pi = l2cap_pi(sk);
22500 + l2cap_conf_req *req = (l2cap_conf_req *) data;
22501 + void *ptr = req->data;
22503 + BT_DBG("sk %p", sk);
22505 + if (pi->imtu != L2CAP_DEFAULT_MTU)
22506 + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
22508 + /* FIXME. Need actual value of the flush timeout */
22509 + //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
22510 + // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
22512 + req->dcid = __cpu_to_le16(pi->dcid);
22513 + req->flags = __cpu_to_le16(0);
22515 + return ptr - data;
22518 +static inline int l2cap_conf_output(struct sock *sk, void **ptr)
22520 + struct l2cap_pinfo *pi = l2cap_pi(sk);
22523 + /* Configure output options and let the other side know
22524 + * which ones we don't like.
22526 + if (pi->conf_mtu < pi->omtu) {
22527 + l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
22528 + result = L2CAP_CONF_UNACCEPT;
22530 + pi->omtu = pi->conf_mtu;
22533 + BT_DBG("sk %p result %d", sk, result);
22537 +static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
22539 + l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
22540 + void *ptr = rsp->data;
22543 + BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
22546 + *result = l2cap_conf_output(sk, &ptr);
22550 + rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
22551 + rsp->result = __cpu_to_le16(result ? *result : 0);
22552 + rsp->flags = __cpu_to_le16(flags);
22554 + return ptr - data;
22557 +static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22559 + struct l2cap_chan_list *list = &conn->chan_list;
22560 + l2cap_conn_req *req = (l2cap_conn_req *) data;
22561 + l2cap_conn_rsp rsp;
22562 + struct sock *sk, *parent;
22563 + int result = 0, status = 0;
22565 + __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
22566 + __u16 psm = req->psm;
22568 + BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
22570 + /* Check if we have socket listening on psm */
22571 + parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
22573 + result = L2CAP_CR_BAD_PSM;
22577 + result = L2CAP_CR_NO_MEM;
22579 + /* Check for backlog size */
22580 + if (parent->ack_backlog > parent->max_ack_backlog) {
22581 + BT_DBG("backlog full %d", parent->ack_backlog);
22585 + sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
22589 + write_lock(&list->lock);
22591 + /* Check if we already have channel with that dcid */
22592 + if (__l2cap_get_chan_by_dcid(list, scid)) {
22593 + write_unlock(&list->lock);
22595 + l2cap_sock_kill(sk);
22599 + hci_conn_hold(conn->hcon);
22601 + l2cap_sock_init(sk, parent);
22602 + bacpy(&bluez_pi(sk)->src, conn->src);
22603 + bacpy(&bluez_pi(sk)->dst, conn->dst);
22604 + l2cap_pi(sk)->psm = psm;
22605 + l2cap_pi(sk)->dcid = scid;
22607 + __l2cap_chan_add(conn, sk, parent);
22608 + dcid = l2cap_pi(sk)->scid;
22610 + l2cap_sock_set_timer(sk, sk->sndtimeo);
22612 + /* Service level security */
22613 + result = L2CAP_CR_PEND;
22614 + status = L2CAP_CS_AUTHEN_PEND;
22615 + sk->state = BT_CONNECT2;
22616 + l2cap_pi(sk)->ident = cmd->ident;
22618 + if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
22619 + if (!hci_conn_encrypt(conn->hcon))
22621 + } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
22622 + if (!hci_conn_auth(conn->hcon))
22626 + sk->state = BT_CONFIG;
22627 + result = status = 0;
22630 + write_unlock(&list->lock);
22633 + bh_unlock_sock(parent);
22636 + rsp.scid = __cpu_to_le16(scid);
22637 + rsp.dcid = __cpu_to_le16(dcid);
22638 + rsp.result = __cpu_to_le16(result);
22639 + rsp.status = __cpu_to_le16(status);
22640 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
22644 +static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22646 + l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
22647 + __u16 scid, dcid, result, status;
22651 + scid = __le16_to_cpu(rsp->scid);
22652 + dcid = __le16_to_cpu(rsp->dcid);
22653 + result = __le16_to_cpu(rsp->result);
22654 + status = __le16_to_cpu(rsp->status);
22656 + BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
22658 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
22661 + switch (result) {
22662 + case L2CAP_CR_SUCCESS:
22663 + sk->state = BT_CONFIG;
22664 + l2cap_pi(sk)->dcid = dcid;
22665 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
22667 + l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
22670 + case L2CAP_CR_PEND:
22674 + l2cap_chan_del(sk, ECONNREFUSED);
22678 + bh_unlock_sock(sk);
22682 +static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22684 + l2cap_conf_req * req = (l2cap_conf_req *) data;
22685 + __u16 dcid, flags;
22690 + dcid = __le16_to_cpu(req->dcid);
22691 + flags = __le16_to_cpu(req->flags);
22693 + BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
22695 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
22698 + l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
22700 + if (flags & 0x0001) {
22701 + /* Incomplete config. Send empty response. */
22702 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
22706 + /* Complete config. */
22707 + l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
22712 + /* Output config done */
22713 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
22715 + if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
22716 + sk->state = BT_CONNECTED;
22717 + l2cap_chan_ready(sk);
22718 + } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
22720 + l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
22724 + bh_unlock_sock(sk);
22728 +static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22730 + l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
22731 + __u16 scid, flags, result;
22735 + scid = __le16_to_cpu(rsp->scid);
22736 + flags = __le16_to_cpu(rsp->flags);
22737 + result = __le16_to_cpu(rsp->result);
22739 + BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
22741 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
22744 + switch (result) {
22745 + case L2CAP_CONF_SUCCESS:
22748 + case L2CAP_CONF_UNACCEPT:
22749 + if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
22752 + It does not make sense to adjust L2CAP parameters
22753 + that are currently defined in the spec. We simply
22754 + resend config request that we sent earlier. It is
22755 + stupid :) but it helps qualification testing
22756 + which expects at least some response from us.
22758 + l2cap_send_req(conn, L2CAP_CONF_REQ,
22759 + l2cap_build_conf_req(sk, req), req);
22763 + sk->state = BT_DISCONN;
22764 + sk->err = ECONNRESET;
22765 + l2cap_sock_set_timer(sk, HZ * 5);
22767 + l2cap_disconn_req req;
22768 + req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
22769 + req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
22770 + l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
22775 + if (flags & 0x01)
22778 + /* Input config done */
22779 + l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
22781 + if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
22782 + sk->state = BT_CONNECTED;
22783 + l2cap_chan_ready(sk);
22787 + bh_unlock_sock(sk);
22791 +static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22793 + l2cap_disconn_req *req = (l2cap_disconn_req *) data;
22794 + l2cap_disconn_rsp rsp;
22795 + __u16 dcid, scid;
22798 + scid = __le16_to_cpu(req->scid);
22799 + dcid = __le16_to_cpu(req->dcid);
22801 + BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
22803 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
22806 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
22807 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
22808 + l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
22810 + sk->shutdown = SHUTDOWN_MASK;
22812 + l2cap_chan_del(sk, ECONNRESET);
22813 + bh_unlock_sock(sk);
22815 + l2cap_sock_kill(sk);
22819 +static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
22821 + l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
22822 + __u16 dcid, scid;
22825 + scid = __le16_to_cpu(rsp->scid);
22826 + dcid = __le16_to_cpu(rsp->dcid);
22828 + BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
22830 + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
22832 + l2cap_chan_del(sk, 0);
22833 + bh_unlock_sock(sk);
22835 + l2cap_sock_kill(sk);
22839 +static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
22841 + __u8 *data = skb->data;
22842 + int len = skb->len;
22843 + l2cap_cmd_hdr cmd;
22846 + while (len >= L2CAP_CMD_HDR_SIZE) {
22847 + memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
22848 + data += L2CAP_CMD_HDR_SIZE;
22849 + len -= L2CAP_CMD_HDR_SIZE;
22851 + cmd.len = __le16_to_cpu(cmd.len);
22853 + BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
22855 + if (cmd.len > len || !cmd.ident) {
22856 + BT_DBG("corrupted command");
22860 + switch (cmd.code) {
22861 + case L2CAP_CONN_REQ:
22862 + err = l2cap_connect_req(conn, &cmd, data);
22865 + case L2CAP_CONN_RSP:
22866 + err = l2cap_connect_rsp(conn, &cmd, data);
22869 + case L2CAP_CONF_REQ:
22870 + err = l2cap_config_req(conn, &cmd, data);
22873 + case L2CAP_CONF_RSP:
22874 + err = l2cap_config_rsp(conn, &cmd, data);
22877 + case L2CAP_DISCONN_REQ:
22878 + err = l2cap_disconnect_req(conn, &cmd, data);
22881 + case L2CAP_DISCONN_RSP:
22882 + err = l2cap_disconnect_rsp(conn, &cmd, data);
22885 + case L2CAP_COMMAND_REJ:
22886 + /* FIXME: We should process this */
22887 + l2cap_raw_recv(conn, skb);
22890 + case L2CAP_ECHO_REQ:
22891 + l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
22894 + case L2CAP_ECHO_RSP:
22895 + case L2CAP_INFO_REQ:
22896 + case L2CAP_INFO_RSP:
22897 + l2cap_raw_recv(conn, skb);
22901 + BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
22907 + l2cap_cmd_rej rej;
22908 + BT_DBG("error %d", err);
22910 + /* FIXME: Map err to a valid reason. */
22911 + rej.reason = __cpu_to_le16(0);
22912 + l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
22922 +static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
22926 + sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
22928 + BT_DBG("unknown cid 0x%4.4x", cid);
22932 + BT_DBG("sk %p, len %d", sk, skb->len);
22934 + if (sk->state != BT_CONNECTED)
22937 + if (l2cap_pi(sk)->imtu < skb->len)
22940 + /* If socket recv buffers overflows we drop data here
22941 + * which is *bad* because L2CAP has to be reliable.
22942 + * But we don't have any other choice. L2CAP doesn't
22943 + * provide flow control mechanism */
22945 + if (!sock_queue_rcv_skb(sk, skb))
22952 + if (sk) bh_unlock_sock(sk);
22956 +static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
22960 + sk = l2cap_get_sock_by_psm(0, psm, conn->src);
22964 + BT_DBG("sk %p, len %d", sk, skb->len);
22966 + if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
22969 + if (l2cap_pi(sk)->imtu < skb->len)
22972 + if (!sock_queue_rcv_skb(sk, skb))
22979 + if (sk) bh_unlock_sock(sk);
22983 +static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
22985 + l2cap_hdr *lh = (l2cap_hdr *) skb->data;
22986 + __u16 cid, psm, len;
22988 + skb_pull(skb, L2CAP_HDR_SIZE);
22989 + cid = __le16_to_cpu(lh->cid);
22990 + len = __le16_to_cpu(lh->len);
22992 + BT_DBG("len %d, cid 0x%4.4x", len, cid);
22996 + l2cap_sig_channel(conn, skb);
23000 + psm = get_unaligned((__u16 *) skb->data);
23001 + skb_pull(skb, 2);
23002 + l2cap_conless_channel(conn, psm, skb);
23006 + l2cap_data_channel(conn, cid, skb);
23011 +/* ------------ L2CAP interface with lower layer (HCI) ------------- */
23013 +static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
23015 + int exact = 0, lm1 = 0, lm2 = 0;
23016 + register struct sock *sk;
23018 + if (type != ACL_LINK)
23021 + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
23023 + /* Find listening sockets and check their link_mode */
23024 + read_lock(&l2cap_sk_list.lock);
23025 + for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
23026 + if (sk->state != BT_LISTEN)
23029 + if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
23030 + lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
23032 + } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
23033 + lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
23035 + read_unlock(&l2cap_sk_list.lock);
23037 + return exact ? lm1 : lm2;
23040 +static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
23042 + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
23044 + if (hcon->type != ACL_LINK)
23048 + struct l2cap_conn *conn;
23050 + conn = l2cap_conn_add(hcon, status);
23052 + l2cap_conn_ready(conn);
23054 + l2cap_conn_del(hcon, bterr(status));
23059 +static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
23061 + BT_DBG("hcon %p reason %d", hcon, reason);
23063 + if (hcon->type != ACL_LINK)
23066 + l2cap_conn_del(hcon, bterr(reason));
23070 +static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
23072 + struct l2cap_chan_list *l;
23073 + struct l2cap_conn *conn;
23074 + l2cap_conn_rsp rsp;
23078 + if (!(conn = hcon->l2cap_data))
23080 + l = &conn->chan_list;
23082 + BT_DBG("conn %p", conn);
23084 + read_lock(&l->lock);
23086 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
23087 + bh_lock_sock(sk);
23089 + if (sk->state != BT_CONNECT2 ||
23090 + (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
23091 + bh_unlock_sock(sk);
23096 + sk->state = BT_CONFIG;
23099 + sk->state = BT_DISCONN;
23100 + l2cap_sock_set_timer(sk, HZ/10);
23101 + result = L2CAP_CR_SEC_BLOCK;
23104 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
23105 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
23106 + rsp.result = __cpu_to_le16(result);
23107 + rsp.status = __cpu_to_le16(0);
23108 + l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
23109 + L2CAP_CONN_RSP_SIZE, &rsp);
23111 + bh_unlock_sock(sk);
23114 + read_unlock(&l->lock);
23118 +static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
23120 + struct l2cap_chan_list *l;
23121 + struct l2cap_conn *conn;
23122 + l2cap_conn_rsp rsp;
23126 + if (!(conn = hcon->l2cap_data))
23128 + l = &conn->chan_list;
23130 + BT_DBG("conn %p", conn);
23132 + read_lock(&l->lock);
23134 + for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
23135 + bh_lock_sock(sk);
23137 + if (sk->state != BT_CONNECT2) {
23138 + bh_unlock_sock(sk);
23143 + sk->state = BT_CONFIG;
23146 + sk->state = BT_DISCONN;
23147 + l2cap_sock_set_timer(sk, HZ/10);
23148 + result = L2CAP_CR_SEC_BLOCK;
23151 + rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
23152 + rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
23153 + rsp.result = __cpu_to_le16(result);
23154 + rsp.status = __cpu_to_le16(0);
23155 + l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
23156 + L2CAP_CONN_RSP_SIZE, &rsp);
23158 + bh_unlock_sock(sk);
23161 + read_unlock(&l->lock);
23165 +static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
23167 + struct l2cap_conn *conn = hcon->l2cap_data;
23169 + if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
23172 + BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
23174 + if (flags & ACL_START) {
23178 + if (conn->rx_len) {
23179 + BT_ERR("Unexpected start frame (len %d)", skb->len);
23180 + kfree_skb(conn->rx_skb);
23181 + conn->rx_skb = NULL;
23182 + conn->rx_len = 0;
23183 + l2cap_conn_unreliable(conn, ECOMM);
23186 + if (skb->len < 2) {
23187 + BT_ERR("Frame is too short (len %d)", skb->len);
23188 + l2cap_conn_unreliable(conn, ECOMM);
23192 + hdr = (l2cap_hdr *) skb->data;
23193 + len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
23195 + if (len == skb->len) {
23196 + /* Complete frame received */
23197 + l2cap_recv_frame(conn, skb);
23201 + BT_DBG("Start: total len %d, frag len %d", len, skb->len);
23203 + if (skb->len > len) {
23204 + BT_ERR("Frame is too long (len %d, expected len %d)",
23206 + l2cap_conn_unreliable(conn, ECOMM);
23210 + /* Allocate skb for the complete frame including header */
23211 + conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
23212 + if (!conn->rx_skb)
23215 + memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
23216 + conn->rx_len = len - skb->len;
23218 + BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
23220 + if (!conn->rx_len) {
23221 + BT_ERR("Unexpected continuation frame (len %d)", skb->len);
23222 + l2cap_conn_unreliable(conn, ECOMM);
23226 + if (skb->len > conn->rx_len) {
23227 + BT_ERR("Fragment is too long (len %d, expected %d)",
23228 + skb->len, conn->rx_len);
23229 + kfree_skb(conn->rx_skb);
23230 + conn->rx_skb = NULL;
23231 + conn->rx_len = 0;
23232 + l2cap_conn_unreliable(conn, ECOMM);
23236 + memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
23237 + conn->rx_len -= skb->len;
23239 + if (!conn->rx_len) {
23240 + /* Complete frame received */
23241 + l2cap_recv_frame(conn, conn->rx_skb);
23242 + conn->rx_skb = NULL;
23251 +/* ----- Proc fs support ------ */
23252 +static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
23254 + struct l2cap_pinfo *pi;
23258 + read_lock_bh(&list->lock);
23260 + for (sk = list->head; sk; sk = sk->next) {
23261 + pi = l2cap_pi(sk);
23262 + ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
23263 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
23264 + sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
23268 + read_unlock_bh(&list->lock);
23270 + ptr += sprintf(ptr, "\n");
23271 + return ptr - buf;
23274 +static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
23279 + BT_DBG("count %d, offset %ld", count, offset);
23281 + ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
23284 + if (len <= count + offset)
23287 + *start = buf + offset;
23298 +static struct proto_ops l2cap_sock_ops = {
23299 + family: PF_BLUETOOTH,
23300 + release: l2cap_sock_release,
23301 + bind: l2cap_sock_bind,
23302 + connect: l2cap_sock_connect,
23303 + listen: l2cap_sock_listen,
23304 + accept: l2cap_sock_accept,
23305 + getname: l2cap_sock_getname,
23306 + sendmsg: l2cap_sock_sendmsg,
23307 + recvmsg: bluez_sock_recvmsg,
23308 + poll: bluez_sock_poll,
23309 + socketpair: sock_no_socketpair,
23310 + ioctl: sock_no_ioctl,
23311 + shutdown: l2cap_sock_shutdown,
23312 + setsockopt: l2cap_sock_setsockopt,
23313 + getsockopt: l2cap_sock_getsockopt,
23314 + mmap: sock_no_mmap
23317 +static struct net_proto_family l2cap_sock_family_ops = {
23318 + family: PF_BLUETOOTH,
23319 + create: l2cap_sock_create
23322 +static struct hci_proto l2cap_hci_proto = {
23324 + id: HCI_PROTO_L2CAP,
23325 + connect_ind: l2cap_connect_ind,
23326 + connect_cfm: l2cap_connect_cfm,
23327 + disconn_ind: l2cap_disconn_ind,
23328 + recv_acldata: l2cap_recv_acldata,
23329 + auth_cfm: l2cap_auth_cfm,
23330 + encrypt_cfm: l2cap_encrypt_cfm
23333 +int __init l2cap_init(void)
23337 + if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
23338 + BT_ERR("Can't register L2CAP socket");
23342 + if ((err = hci_register_proto(&l2cap_hci_proto))) {
23343 + BT_ERR("Can't register L2CAP protocol");
23347 + create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
23349 + BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
23350 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
23354 +void l2cap_cleanup(void)
23356 + remove_proc_entry("bluetooth/l2cap", NULL);
23358 + /* Unregister socket and protocol */
23359 + if (bluez_sock_unregister(BTPROTO_L2CAP))
23360 + BT_ERR("Can't unregister L2CAP socket");
23362 + if (hci_unregister_proto(&l2cap_hci_proto))
23363 + BT_ERR("Can't unregister L2CAP protocol");
23366 +void l2cap_load(void)
23368 + /* Dummy function to trigger automatic L2CAP module loading by
23369 + other modules that use L2CAP sockets but do not use any other
23370 + symbols from it. */
23374 +EXPORT_SYMBOL(l2cap_load);
23376 +module_init(l2cap_init);
23377 +module_exit(l2cap_cleanup);
23379 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
23380 +MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
23381 +MODULE_LICENSE("GPL");
23382 diff -urN linux-2.4.18/net/bluetooth/l2cap_core.c linux-2.4.18-mh9/net/bluetooth/l2cap_core.c
23383 --- linux-2.4.18/net/bluetooth/l2cap_core.c Sun Sep 30 21:26:08 2001
23384 +++ linux-2.4.18-mh9/net/bluetooth/l2cap_core.c Thu Jan 1 01:00:00 1970
23387 - BlueZ - Bluetooth protocol stack for Linux
23388 - Copyright (C) 2000-2001 Qualcomm Incorporated
23390 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
23392 - This program is free software; you can redistribute it and/or modify
23393 - it under the terms of the GNU General Public License version 2 as
23394 - published by the Free Software Foundation;
23396 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23397 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23398 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
23399 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
23400 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
23401 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23402 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23403 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23405 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
23406 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
23407 - SOFTWARE IS DISCLAIMED.
23411 - * BlueZ L2CAP core and sockets.
23413 - * $Id: l2cap_core.c,v 1.19 2001/08/03 04:19:50 maxk Exp $
23415 -#define VERSION "1.1"
23417 -#include <linux/config.h>
23418 -#include <linux/module.h>
23420 -#include <linux/types.h>
23421 -#include <linux/errno.h>
23422 -#include <linux/kernel.h>
23423 -#include <linux/major.h>
23424 -#include <linux/sched.h>
23425 -#include <linux/slab.h>
23426 -#include <linux/poll.h>
23427 -#include <linux/fcntl.h>
23428 -#include <linux/init.h>
23429 -#include <linux/skbuff.h>
23430 -#include <linux/interrupt.h>
23431 -#include <linux/socket.h>
23432 -#include <linux/skbuff.h>
23433 -#include <linux/proc_fs.h>
23434 -#include <linux/list.h>
23435 -#include <net/sock.h>
23437 -#include <asm/system.h>
23438 -#include <asm/uaccess.h>
23440 -#include <net/bluetooth/bluetooth.h>
23441 -#include <net/bluetooth/bluez.h>
23442 -#include <net/bluetooth/hci_core.h>
23443 -#include <net/bluetooth/l2cap.h>
23444 -#include <net/bluetooth/l2cap_core.h>
23446 -#ifndef L2CAP_DEBUG
23448 -#define DBG( A... )
23451 -struct proto_ops l2cap_sock_ops;
23453 -struct bluez_sock_list l2cap_sk_list = {
23454 - lock: RW_LOCK_UNLOCKED
23457 -struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
23458 -rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
23460 -static int l2cap_conn_del(struct l2cap_conn *conn, int err);
23462 -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
23463 -static void l2cap_chan_del(struct sock *sk, int err);
23464 -static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
23466 -static void l2cap_sock_close(struct sock *sk);
23467 -static void l2cap_sock_kill(struct sock *sk);
23469 -static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
23470 -static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
23472 -/* -------- L2CAP interfaces & routing --------- */
23473 -/* Add/delete L2CAP interface.
23474 - * Must be called with locked rt_lock
23477 -static void l2cap_iff_add(struct hci_dev *hdev)
23479 - struct l2cap_iff *iff;
23481 - DBG("%s", hdev->name);
23483 - DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
23485 - /* Allocate new interface and lock HCI device */
23486 - if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
23487 - ERR("Can't allocate new interface %s", hdev->name);
23490 - memset(iff, 0, sizeof(struct l2cap_iff));
23492 - hci_dev_hold(hdev);
23493 - hdev->l2cap_data = iff;
23494 - iff->hdev = hdev;
23495 - iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
23496 - iff->bdaddr = &hdev->bdaddr;
23498 - spin_lock_init(&iff->lock);
23499 - INIT_LIST_HEAD(&iff->conn_list);
23501 - list_add(&iff->list, &l2cap_iff_list);
23504 -static void l2cap_iff_del(struct hci_dev *hdev)
23506 - struct l2cap_iff *iff;
23508 - if (!(iff = hdev->l2cap_data))
23511 - DBG("%s iff %p", hdev->name, iff);
23513 - list_del(&iff->list);
23515 - l2cap_iff_lock(iff);
23517 - /* Drop connections */
23518 - while (!list_empty(&iff->conn_list)) {
23519 - struct l2cap_conn *c;
23521 - c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
23522 - l2cap_conn_del(c, ENODEV);
23525 - l2cap_iff_unlock(iff);
23527 - /* Unlock HCI device */
23528 - hdev->l2cap_data = NULL;
23529 - hci_dev_put(hdev);
23534 -/* Get route. Returns L2CAP interface.
23535 - * Must be called with locked rt_lock
23537 -static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
23539 - struct list_head *p;
23542 - DBG("%s -> %s", batostr(src), batostr(dst));
23544 - use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
23546 - /* Simple routing:
23547 - * No source address - find interface with bdaddr != dst
23548 - * Source address - find interface with bdaddr == src
23551 - list_for_each(p, &l2cap_iff_list) {
23552 - struct l2cap_iff *iff;
23554 - iff = list_entry(p, struct l2cap_iff, list);
23556 - if (use_src && !bacmp(iff->bdaddr, src))
23558 - else if (bacmp(iff->bdaddr, dst))
23564 -/* ----- L2CAP timers ------ */
23565 -static void l2cap_sock_timeout(unsigned long arg)
23567 - struct sock *sk = (struct sock *) arg;
23569 - DBG("sock %p state %d", sk, sk->state);
23571 - bh_lock_sock(sk);
23572 - switch (sk->state) {
23574 - l2cap_chan_del(sk, ETIMEDOUT);
23578 - sk->err = ETIMEDOUT;
23579 - sk->state_change(sk);
23582 - bh_unlock_sock(sk);
23584 - l2cap_sock_kill(sk);
23588 -static void l2cap_sock_set_timer(struct sock *sk, long timeout)
23590 - DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
23592 - if (!mod_timer(&sk->timer, jiffies + timeout))
23596 -static void l2cap_sock_clear_timer(struct sock *sk)
23598 - DBG("sock %p state %d", sk, sk->state);
23600 - if (timer_pending(&sk->timer) && del_timer(&sk->timer))
23604 -static void l2cap_sock_init_timer(struct sock *sk)
23606 - init_timer(&sk->timer);
23607 - sk->timer.function = l2cap_sock_timeout;
23608 - sk->timer.data = (unsigned long)sk;
23611 -static void l2cap_conn_timeout(unsigned long arg)
23613 - struct l2cap_conn *conn = (void *)arg;
23615 - DBG("conn %p state %d", conn, conn->state);
23617 - if (conn->state == BT_CONNECTED) {
23618 - hci_disconnect(conn->hconn, 0x13);
23624 -static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
23626 - DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
23628 - mod_timer(&conn->timer, jiffies + timeout);
23631 -static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
23633 - DBG("conn %p state %d", conn, conn->state);
23635 - del_timer(&conn->timer);
23638 -static void l2cap_conn_init_timer(struct l2cap_conn *conn)
23640 - init_timer(&conn->timer);
23641 - conn->timer.function = l2cap_conn_timeout;
23642 - conn->timer.data = (unsigned long)conn;
23645 -/* -------- L2CAP connections --------- */
23646 -/* Add new connection to the interface.
23647 - * Interface must be locked
23649 -static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
23651 - struct l2cap_conn *conn;
23652 - bdaddr_t *src = iff->bdaddr;
23654 - if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
23657 - memset(conn, 0, sizeof(struct l2cap_conn));
23659 - conn->state = BT_OPEN;
23661 - bacpy(&conn->src, src);
23662 - bacpy(&conn->dst, dst);
23664 - spin_lock_init(&conn->lock);
23665 - conn->chan_list.lock = RW_LOCK_UNLOCKED;
23667 - l2cap_conn_init_timer(conn);
23669 - __l2cap_conn_link(iff, conn);
23671 - DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
23673 - MOD_INC_USE_COUNT;
23678 -/* Delete connection on the interface.
23679 - * Interface must be locked
23681 -static int l2cap_conn_del(struct l2cap_conn *conn, int err)
23685 - DBG("conn %p, state %d, err %d", conn, conn->state, err);
23687 - l2cap_conn_clear_timer(conn);
23688 - __l2cap_conn_unlink(conn->iff, conn);
23690 - conn->state = BT_CLOSED;
23692 - if (conn->rx_skb)
23693 - kfree_skb(conn->rx_skb);
23695 - /* Kill channels */
23696 - while ((sk = conn->chan_list.head)) {
23697 - bh_lock_sock(sk);
23698 - l2cap_sock_clear_timer(sk);
23699 - l2cap_chan_del(sk, err);
23700 - bh_unlock_sock(sk);
23702 - l2cap_sock_kill(sk);
23707 - MOD_DEC_USE_COUNT;
23711 -static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
23713 - struct list_head *p;
23715 - list_for_each(p, &iff->conn_list) {
23716 - struct l2cap_conn *c;
23718 - c = list_entry(p, struct l2cap_conn, list);
23719 - if (!bacmp(&c->dst, dst))
23725 -int l2cap_connect(struct sock *sk)
23727 - bdaddr_t *src = &l2cap_pi(sk)->src;
23728 - bdaddr_t *dst = &l2cap_pi(sk)->dst;
23729 - struct l2cap_conn *conn;
23730 - struct l2cap_iff *iff;
23733 - DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
23735 - read_lock_bh(&l2cap_rt_lock);
23737 - /* Get route to remote BD address */
23738 - if (!(iff = l2cap_get_route(src, dst))) {
23739 - err = -EHOSTUNREACH;
23743 - /* Update source addr of the socket */
23744 - bacpy(src, iff->bdaddr);
23746 - l2cap_iff_lock(iff);
23748 - if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
23749 - /* Connection doesn't exist */
23750 - if (!(conn = l2cap_conn_add(iff, dst))) {
23751 - l2cap_iff_unlock(iff);
23758 - l2cap_iff_unlock(iff);
23760 - l2cap_chan_add(conn, sk, NULL);
23762 - sk->state = BT_CONNECT;
23763 - l2cap_sock_set_timer(sk, sk->sndtimeo);
23765 - switch (conn->state) {
23766 - case BT_CONNECTED:
23767 - if (sk->type == SOCK_SEQPACKET) {
23768 - l2cap_conn_req req;
23769 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
23770 - req.psm = l2cap_pi(sk)->psm;
23771 - l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
23773 - l2cap_sock_clear_timer(sk);
23774 - sk->state = BT_CONNECTED;
23782 - /* Create ACL connection */
23783 - conn->state = BT_CONNECT;
23784 - hci_connect(iff->hdev, dst);
23789 - read_unlock_bh(&l2cap_rt_lock);
23793 -/* ------ Channel queues for listening sockets ------ */
23794 -void l2cap_accept_queue(struct sock *parent, struct sock *sk)
23796 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
23798 - DBG("parent %p, sk %p", parent, sk);
23801 - l2cap_pi(sk)->parent = parent;
23802 - l2cap_pi(sk)->next_q = NULL;
23805 - q->head = q->tail = sk;
23807 - struct sock *tail = q->tail;
23809 - l2cap_pi(sk)->prev_q = tail;
23810 - l2cap_pi(tail)->next_q = sk;
23814 - parent->ack_backlog++;
23817 -void l2cap_accept_unlink(struct sock *sk)
23819 - struct sock *parent = l2cap_pi(sk)->parent;
23820 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
23821 - struct sock *next, *prev;
23823 - DBG("sk %p", sk);
23825 - next = l2cap_pi(sk)->next_q;
23826 - prev = l2cap_pi(sk)->prev_q;
23828 - if (sk == q->head)
23830 - if (sk == q->tail)
23834 - l2cap_pi(next)->prev_q = prev;
23836 - l2cap_pi(prev)->next_q = next;
23838 - l2cap_pi(sk)->parent = NULL;
23840 - parent->ack_backlog--;
23844 -/* Get next connected channel in queue. */
23845 -struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
23847 - struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
23850 - for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
23851 - if (!state || sk->state == state) {
23852 - l2cap_accept_unlink(sk);
23857 - DBG("parent %p, sk %p", parent, sk);
23862 -/* -------- Socket interface ---------- */
23863 -static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
23865 - bdaddr_t *src = &addr->l2_bdaddr;
23866 - __u16 psm = addr->l2_psm;
23869 - for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
23870 - if (l2cap_pi(sk)->psm == psm &&
23871 - !bacmp(&l2cap_pi(sk)->src, src))
23878 -/* Find socket listening on psm and source bdaddr.
23879 - * Returns closest match.
23881 -static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
23883 - struct sock *sk, *sk1 = NULL;
23885 - read_lock(&l2cap_sk_list.lock);
23887 - for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
23888 - struct l2cap_pinfo *pi;
23890 - if (sk->state != BT_LISTEN)
23893 - pi = l2cap_pi(sk);
23895 - if (pi->psm == psm) {
23896 - /* Exact match. */
23897 - if (!bacmp(&pi->src, src))
23900 - /* Closest match */
23901 - if (!bacmp(&pi->src, BDADDR_ANY))
23906 - read_unlock(&l2cap_sk_list.lock);
23908 - return sk ? sk : sk1;
23911 -static void l2cap_sock_destruct(struct sock *sk)
23913 - DBG("sk %p", sk);
23915 - skb_queue_purge(&sk->receive_queue);
23916 - skb_queue_purge(&sk->write_queue);
23918 - MOD_DEC_USE_COUNT;
23921 -static void l2cap_sock_cleanup_listen(struct sock *parent)
23925 - DBG("parent %p", parent);
23927 - /* Close not yet accepted channels */
23928 - while ((sk = l2cap_accept_dequeue(parent, 0)))
23929 - l2cap_sock_close(sk);
23931 - parent->state = BT_CLOSED;
23932 - parent->zapped = 1;
23935 -/* Kill socket (only if zapped and orphan)
23936 - * Must be called on unlocked socket.
23938 -static void l2cap_sock_kill(struct sock *sk)
23940 - if (!sk->zapped || sk->socket)
23943 - DBG("sk %p state %d", sk, sk->state);
23945 - /* Kill poor orphan */
23946 - bluez_sock_unlink(&l2cap_sk_list, sk);
23952 - * Must be called on unlocked socket.
23954 -static void l2cap_sock_close(struct sock *sk)
23956 - struct l2cap_conn *conn;
23958 - l2cap_sock_clear_timer(sk);
23962 - conn = l2cap_pi(sk)->conn;
23964 - DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
23966 - switch (sk->state) {
23968 - l2cap_sock_cleanup_listen(sk);
23971 - case BT_CONNECTED:
23973 - if (sk->type == SOCK_SEQPACKET) {
23974 - l2cap_disconn_req req;
23976 - sk->state = BT_DISCONN;
23978 - req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
23979 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
23980 - l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
23982 - l2cap_sock_set_timer(sk, sk->sndtimeo);
23984 - l2cap_chan_del(sk, ECONNRESET);
23990 - l2cap_chan_del(sk, ECONNRESET);
23998 - release_sock(sk);
24000 - l2cap_sock_kill(sk);
24003 -static void l2cap_sock_init(struct sock *sk, struct sock *parent)
24005 - struct l2cap_pinfo *pi = l2cap_pi(sk);
24007 - DBG("sk %p", sk);
24010 - sk->type = parent->type;
24012 - pi->imtu = l2cap_pi(parent)->imtu;
24013 - pi->omtu = l2cap_pi(parent)->omtu;
24015 - pi->imtu = L2CAP_DEFAULT_MTU;
24019 - /* Default config options */
24020 - pi->conf_mtu = L2CAP_DEFAULT_MTU;
24021 - pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
24024 -static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
24028 - if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
24031 - sock_init_data(sock, sk);
24035 - sk->destruct = l2cap_sock_destruct;
24036 - sk->sndtimeo = L2CAP_CONN_TIMEOUT;
24038 - sk->protocol = proto;
24039 - sk->state = BT_OPEN;
24041 - l2cap_sock_init_timer(sk);
24043 - bluez_sock_link(&l2cap_sk_list, sk);
24045 - MOD_INC_USE_COUNT;
24050 -static int l2cap_sock_create(struct socket *sock, int protocol)
24054 - DBG("sock %p", sock);
24056 - sock->state = SS_UNCONNECTED;
24058 - if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
24059 - return -ESOCKTNOSUPPORT;
24061 - sock->ops = &l2cap_sock_ops;
24063 - if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
24066 - l2cap_sock_init(sk, NULL);
24071 -static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
24073 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
24074 - struct sock *sk = sock->sk;
24077 - DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
24079 - if (!addr || addr->sa_family != AF_BLUETOOTH)
24084 - if (sk->state != BT_OPEN) {
24089 - write_lock(&l2cap_sk_list.lock);
24091 - if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
24092 - err = -EADDRINUSE;
24096 - /* Save source address */
24097 - bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
24098 - l2cap_pi(sk)->psm = la->l2_psm;
24099 - sk->state = BT_BOUND;
24102 - write_unlock(&l2cap_sk_list.lock);
24105 - release_sock(sk);
24110 -static int l2cap_sock_w4_connect(struct sock *sk, int flags)
24112 - DECLARE_WAITQUEUE(wait, current);
24113 - long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
24116 - DBG("sk %p", sk);
24118 - add_wait_queue(sk->sleep, &wait);
24119 - current->state = TASK_INTERRUPTIBLE;
24121 - while (sk->state != BT_CONNECTED) {
24127 - release_sock(sk);
24128 - timeo = schedule_timeout(timeo);
24132 - if (sk->state == BT_CONNECTED)
24136 - err = sock_error(sk);
24140 - if (signal_pending(current)) {
24141 - err = sock_intr_errno(timeo);
24145 - current->state = TASK_RUNNING;
24146 - remove_wait_queue(sk->sleep, &wait);
24151 -static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
24153 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
24154 - struct sock *sk = sock->sk;
24159 - DBG("sk %p", sk);
24161 - if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
24166 - if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
24171 - if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
24176 - /* Set destination address and psm */
24177 - bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
24178 - l2cap_pi(sk)->psm = la->l2_psm;
24180 - if ((err = l2cap_connect(sk)))
24183 - err = l2cap_sock_w4_connect(sk, flags);
24186 - release_sock(sk);
24190 -int l2cap_sock_listen(struct socket *sock, int backlog)
24192 - struct sock *sk = sock->sk;
24195 - DBG("sk %p backlog %d", sk, backlog);
24199 - if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
24204 - if (!l2cap_pi(sk)->psm) {
24209 - sk->max_ack_backlog = backlog;
24210 - sk->ack_backlog = 0;
24211 - sk->state = BT_LISTEN;
24214 - release_sock(sk);
24218 -int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
24220 - DECLARE_WAITQUEUE(wait, current);
24221 - struct sock *sk = sock->sk, *ch;
24227 - if (sk->state != BT_LISTEN) {
24232 - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
24234 - DBG("sk %p timeo %ld", sk, timeo);
24236 - /* Wait for an incoming connection. (wake-one). */
24237 - add_wait_queue_exclusive(sk->sleep, &wait);
24238 - current->state = TASK_INTERRUPTIBLE;
24239 - while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
24245 - release_sock(sk);
24246 - timeo = schedule_timeout(timeo);
24249 - if (sk->state != BT_LISTEN) {
24254 - if (signal_pending(current)) {
24255 - err = sock_intr_errno(timeo);
24259 - current->state = TASK_RUNNING;
24260 - remove_wait_queue(sk->sleep, &wait);
24265 - sock_graft(ch, newsock);
24266 - newsock->state = SS_CONNECTED;
24268 - DBG("new socket %p", ch);
24271 - release_sock(sk);
24276 -static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
24278 - struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
24279 - struct sock *sk = sock->sk;
24281 - DBG("sock %p, sk %p", sock, sk);
24283 - addr->sa_family = AF_BLUETOOTH;
24284 - *len = sizeof(struct sockaddr_l2);
24287 - bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
24289 - bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
24291 - la->l2_psm = l2cap_pi(sk)->psm;
24296 -static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
24298 - struct sock *sk = sock->sk;
24301 - DBG("sock %p, sk %p", sock, sk);
24304 - return sock_error(sk);
24306 - if (msg->msg_flags & MSG_OOB)
24307 - return -EOPNOTSUPP;
24311 - if (sk->state == BT_CONNECTED)
24312 - err = l2cap_chan_send(sk, msg, len);
24316 - release_sock(sk);
24320 -static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
24322 - struct sock *sk = sock->sk;
24323 - int noblock = flags & MSG_DONTWAIT;
24325 - struct sk_buff *skb;
24327 - DBG("sock %p, sk %p", sock, sk);
24329 - if (flags & (MSG_OOB))
24330 - return -EOPNOTSUPP;
24332 - if (sk->state == BT_CLOSED)
24335 - if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
24338 - msg->msg_namelen = 0;
24340 - copied = skb->len;
24341 - if (len < copied) {
24342 - msg->msg_flags |= MSG_TRUNC;
24346 - skb->h.raw = skb->data;
24347 - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
24349 - skb_free_datagram(sk, skb);
24351 - return err ? : copied;
24354 -int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
24356 - struct sock *sk = sock->sk;
24357 - struct l2cap_options opts;
24360 - DBG("sk %p", sk);
24364 - switch (optname) {
24365 - case L2CAP_OPTIONS:
24366 - if (copy_from_user((char *)&opts, optval, optlen)) {
24370 - l2cap_pi(sk)->imtu = opts.imtu;
24371 - l2cap_pi(sk)->omtu = opts.omtu;
24375 - err = -ENOPROTOOPT;
24379 - release_sock(sk);
24383 -int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
24385 - struct sock *sk = sock->sk;
24386 - struct l2cap_options opts;
24387 - struct l2cap_conninfo cinfo;
24388 - int len, err = 0;
24390 - if (get_user(len, optlen))
24395 - switch (optname) {
24396 - case L2CAP_OPTIONS:
24397 - opts.imtu = l2cap_pi(sk)->imtu;
24398 - opts.omtu = l2cap_pi(sk)->omtu;
24399 - opts.flush_to = l2cap_pi(sk)->flush_to;
24401 - len = MIN(len, sizeof(opts));
24402 - if (copy_to_user(optval, (char *)&opts, len))
24407 - case L2CAP_CONNINFO:
24408 - if (sk->state != BT_CONNECTED) {
24413 - cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
24415 - len = MIN(len, sizeof(cinfo));
24416 - if (copy_to_user(optval, (char *)&cinfo, len))
24422 - err = -ENOPROTOOPT;
24426 - release_sock(sk);
24430 -static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
24432 - struct sock *sk = sock->sk;
24433 - struct l2cap_accept_q *aq;
24434 - unsigned int mask;
24436 - DBG("sock %p, sk %p", sock, sk);
24438 - poll_wait(file, sk->sleep, wait);
24441 - if (sk->err || !skb_queue_empty(&sk->error_queue))
24444 - if (sk->shutdown == SHUTDOWN_MASK)
24447 - aq = &l2cap_pi(sk)->accept_q;
24448 - if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
24449 - mask |= POLLIN | POLLRDNORM;
24451 - if (sk->state == BT_CLOSED)
24454 - if (sock_writeable(sk))
24455 - mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
24457 - set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
24462 -static int l2cap_sock_release(struct socket *sock)
24464 - struct sock *sk = sock->sk;
24466 - DBG("sock %p, sk %p", sock, sk);
24473 - l2cap_sock_close(sk);
24478 -/* --------- L2CAP channels --------- */
24479 -static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
24483 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
24484 - if (l2cap_pi(s)->dcid == cid)
24491 -static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
24495 - read_lock(&l->lock);
24496 - s = __l2cap_get_chan_by_dcid(l, cid);
24497 - read_unlock(&l->lock);
24502 -static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
24506 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
24507 - if (l2cap_pi(s)->scid == cid)
24513 -static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
24517 - read_lock(&l->lock);
24518 - s = __l2cap_get_chan_by_scid(l, cid);
24519 - read_unlock(&l->lock);
24524 -static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
24528 - for (s = l->head; s; s = l2cap_pi(s)->next_c) {
24529 - if (l2cap_pi(s)->ident == ident)
24536 -static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
24540 - read_lock(&l->lock);
24541 - s = __l2cap_get_chan_by_ident(l, ident);
24542 - read_unlock(&l->lock);
24547 -static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
24549 - __u16 cid = 0x0040;
24551 - for (; cid < 0xffff; cid++) {
24552 - if(!__l2cap_get_chan_by_scid(l, cid))
24559 -static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
24564 - l2cap_pi(l->head)->prev_c = sk;
24566 - l2cap_pi(sk)->next_c = l->head;
24567 - l2cap_pi(sk)->prev_c = NULL;
24571 -static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
24573 - struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
24575 - write_lock(&l->lock);
24576 - if (sk == l->head)
24580 - l2cap_pi(next)->prev_c = prev;
24582 - l2cap_pi(prev)->next_c = next;
24583 - write_unlock(&l->lock);
24588 -static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
24590 - struct l2cap_chan_list *l = &conn->chan_list;
24592 - DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
24594 - l2cap_conn_clear_timer(conn);
24596 - atomic_inc(&conn->refcnt);
24597 - l2cap_pi(sk)->conn = conn;
24599 - if (sk->type == SOCK_SEQPACKET) {
24600 - /* Alloc CID for normal socket */
24601 - l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
24603 - /* Raw socket can send only signalling messages */
24604 - l2cap_pi(sk)->scid = 0x0001;
24605 - l2cap_pi(sk)->dcid = 0x0001;
24606 - l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
24609 - __l2cap_chan_link(l, sk);
24612 - l2cap_accept_queue(parent, sk);
24615 -static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
24617 - struct l2cap_chan_list *l = &conn->chan_list;
24619 - write_lock(&l->lock);
24620 - __l2cap_chan_add(conn, sk, parent);
24621 - write_unlock(&l->lock);
24624 -/* Delete channel.
24625 - * Must be called on the locked socket. */
24626 -static void l2cap_chan_del(struct sock *sk, int err)
24628 - struct l2cap_conn *conn;
24629 - struct sock *parent;
24631 - conn = l2cap_pi(sk)->conn;
24632 - parent = l2cap_pi(sk)->parent;
24634 - DBG("sk %p, conn %p, err %d", sk, conn, err);
24637 - /* Unlink from parent accept queue */
24638 - bh_lock_sock(parent);
24639 - l2cap_accept_unlink(sk);
24640 - bh_unlock_sock(parent);
24646 - /* Unlink from channel list */
24647 - l2cap_chan_unlink(&conn->chan_list, sk);
24648 - l2cap_pi(sk)->conn = NULL;
24651 - timeout = L2CAP_DISCONN_TIMEOUT;
24653 - timeout = L2CAP_CONN_IDLE_TIMEOUT;
24655 - if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
24656 - /* Schedule Baseband disconnect */
24657 - l2cap_conn_set_timer(conn, timeout);
24661 - sk->state = BT_CLOSED;
24663 - sk->state_change(sk);
24668 -static void l2cap_conn_ready(struct l2cap_conn *conn)
24670 - struct l2cap_chan_list *l = &conn->chan_list;
24673 - DBG("conn %p", conn);
24675 - read_lock(&l->lock);
24677 - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
24678 - bh_lock_sock(sk);
24680 - if (sk->type != SOCK_SEQPACKET) {
24681 - sk->state = BT_CONNECTED;
24682 - sk->state_change(sk);
24683 - l2cap_sock_clear_timer(sk);
24684 - } else if (sk->state == BT_CONNECT) {
24685 - l2cap_conn_req req;
24686 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
24687 - req.psm = l2cap_pi(sk)->psm;
24688 - l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
24690 - l2cap_sock_set_timer(sk, sk->sndtimeo);
24693 - bh_unlock_sock(sk);
24696 - read_unlock(&l->lock);
24699 -static void l2cap_chan_ready(struct sock *sk)
24701 - struct sock *parent = l2cap_pi(sk)->parent;
24703 - DBG("sk %p, parent %p", sk, parent);
24705 - l2cap_pi(sk)->conf_state = 0;
24706 - l2cap_sock_clear_timer(sk);
24709 - /* Outgoing channel.
24710 - * Wake up socket sleeping on connect.
24712 - sk->state = BT_CONNECTED;
24713 - sk->state_change(sk);
24715 - /* Incomming channel.
24716 - * Wake up socket sleeping on accept.
24718 - parent->data_ready(parent, 1);
24722 -/* Copy frame to all raw sockets on that connection */
24723 -void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
24725 - struct l2cap_chan_list *l = &conn->chan_list;
24726 - struct sk_buff *nskb;
24727 - struct sock * sk;
24729 - DBG("conn %p", conn);
24731 - read_lock(&l->lock);
24732 - for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
24733 - if (sk->type != SOCK_RAW)
24736 - /* Don't send frame to the socket it came from */
24737 - if (skb->sk == sk)
24740 - if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
24743 - skb_queue_tail(&sk->receive_queue, nskb);
24744 - sk->data_ready(sk, nskb->len);
24746 - read_unlock(&l->lock);
24749 -static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
24751 - struct l2cap_conn *conn = l2cap_pi(sk)->conn;
24752 - struct sk_buff *skb, **frag;
24753 - int err, size, count, sent=0;
24756 - /* Check outgoing MTU */
24757 - if (len > l2cap_pi(sk)->omtu)
24760 - DBG("sk %p len %d", sk, len);
24762 - /* First fragment (with L2CAP header) */
24763 - count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
24764 - size = L2CAP_HDR_SIZE + count;
24765 - if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
24768 - /* Create L2CAP header */
24769 - lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
24770 - lh->len = __cpu_to_le16(len);
24771 - lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
24773 - if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
24781 - /* Continuation fragments (no L2CAP header) */
24782 - frag = &skb_shinfo(skb)->frag_list;
24784 - count = MIN(conn->iff->mtu, len);
24786 - *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
24790 - if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
24798 - frag = &(*frag)->next;
24801 - if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
24811 -/* --------- L2CAP signalling commands --------- */
24812 -static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
24816 - /* Get next available identificator.
24817 - * 1 - 199 are used by kernel.
24818 - * 200 - 254 are used by utilities like l2ping, etc
24821 - spin_lock(&conn->lock);
24823 - if (++conn->tx_ident > 199)
24824 - conn->tx_ident = 1;
24826 - id = conn->tx_ident;
24828 - spin_unlock(&conn->lock);
24833 -static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
24835 - struct sk_buff *skb;
24836 - l2cap_cmd_hdr *cmd;
24840 - DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
24842 - size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
24843 - if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
24846 - lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
24847 - lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
24848 - lh->cid = __cpu_to_le16(0x0001);
24850 - cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
24851 - cmd->code = code;
24852 - cmd->ident = ident;
24853 - cmd->len = __cpu_to_le16(len);
24856 - memcpy(skb_put(skb, len), data, len);
24861 -static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
24863 - struct sk_buff *skb;
24866 - DBG("code 0x%2.2x", code);
24868 - ident = l2cap_get_ident(conn);
24869 - if (!(skb = l2cap_build_cmd(code, ident, len, data)))
24871 - return hci_send_acl(conn->hconn, skb, 0);
24874 -static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
24876 - struct sk_buff *skb;
24878 - DBG("code 0x%2.2x", code);
24880 - if (!(skb = l2cap_build_cmd(code, ident, len, data)))
24882 - return hci_send_acl(conn->hconn, skb, 0);
24885 -static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
24887 - l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
24890 - *type = opt->type;
24891 - switch (opt->len) {
24893 - *val = *((__u8 *) opt->val);
24897 - *val = __le16_to_cpu(*((__u16 *)opt->val));
24901 - *val = __le32_to_cpu(*((__u32 *)opt->val));
24909 - DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
24911 - len = L2CAP_CONF_OPT_SIZE + opt->len;
24918 -static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
24920 - __u8 type, hint; __u32 val;
24921 - __u8 *ptr = data;
24923 - DBG("sk %p len %d", sk, len);
24925 - while (len >= L2CAP_CONF_OPT_SIZE) {
24926 - len -= l2cap_get_conf_opt(&ptr, &type, &val);
24928 - hint = type & 0x80;
24932 - case L2CAP_CONF_MTU:
24933 - l2cap_pi(sk)->conf_mtu = val;
24936 - case L2CAP_CONF_FLUSH_TO:
24937 - l2cap_pi(sk)->flush_to = val;
24940 - case L2CAP_CONF_QOS:
24947 - /* FIXME: Reject unknon option */
24953 -static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
24955 - register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
24957 - DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
24959 - opt->type = type;
24963 - *((__u8 *) opt->val) = val;
24967 - *((__u16 *) opt->val) = __cpu_to_le16(val);
24971 - *((__u32 *) opt->val) = __cpu_to_le32(val);
24975 - *ptr += L2CAP_CONF_OPT_SIZE + len;
24978 -static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
24980 - struct l2cap_pinfo *pi = l2cap_pi(sk);
24981 - l2cap_conf_req *req = (l2cap_conf_req *) data;
24982 - __u8 *ptr = req->data;
24984 - DBG("sk %p", sk);
24986 - if (pi->imtu != L2CAP_DEFAULT_MTU)
24987 - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
24989 - /* FIXME. Need actual value of the flush timeout */
24990 - //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
24991 - // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
24993 - req->dcid = __cpu_to_le16(pi->dcid);
24994 - req->flags = __cpu_to_le16(0);
24996 - return ptr - data;
24999 -static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
25001 - struct l2cap_pinfo *pi = l2cap_pi(sk);
25004 - /* Configure output options and let other side know
25005 - * which ones we don't like.
25007 - if (pi->conf_mtu < pi->omtu) {
25008 - l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
25009 - result = L2CAP_CONF_UNACCEPT;
25011 - pi->omtu = pi->conf_mtu;
25014 - DBG("sk %p result %d", sk, result);
25018 -static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
25020 - l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
25021 - __u8 *ptr = rsp->data;
25023 - DBG("sk %p complete %d", sk, result ? 1 : 0);
25026 - *result = l2cap_conf_output(sk, &ptr);
25028 - rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25029 - rsp->result = __cpu_to_le16(result ? *result : 0);
25030 - rsp->flags = __cpu_to_le16(0);
25032 - return ptr - data;
25035 -static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25037 - struct l2cap_chan_list *list = &conn->chan_list;
25038 - l2cap_conn_req *req = (l2cap_conn_req *) data;
25039 - l2cap_conn_rsp rsp;
25040 - struct sock *sk, *parent;
25042 - __u16 scid = __le16_to_cpu(req->scid);
25043 - __u16 psm = req->psm;
25045 - DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
25047 - /* Check if we have socket listening on psm */
25048 - if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
25051 - bh_lock_sock(parent);
25052 - write_lock(&list->lock);
25054 - /* Check if we already have channel with that dcid */
25055 - if (__l2cap_get_chan_by_dcid(list, scid))
25058 - /* Check for backlog size */
25059 - if (parent->ack_backlog > parent->max_ack_backlog)
25062 - if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
25065 - l2cap_sock_init(sk, parent);
25067 - bacpy(&l2cap_pi(sk)->src, &conn->src);
25068 - bacpy(&l2cap_pi(sk)->dst, &conn->dst);
25069 - l2cap_pi(sk)->psm = psm;
25070 - l2cap_pi(sk)->dcid = scid;
25072 - __l2cap_chan_add(conn, sk, parent);
25073 - sk->state = BT_CONFIG;
25075 - write_unlock(&list->lock);
25076 - bh_unlock_sock(parent);
25078 - rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
25079 - rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25080 - rsp.result = __cpu_to_le16(0);
25081 - rsp.status = __cpu_to_le16(0);
25082 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
25087 - write_unlock(&list->lock);
25088 - bh_unlock_sock(parent);
25091 - rsp.scid = __cpu_to_le16(scid);
25092 - rsp.dcid = __cpu_to_le16(0);
25093 - rsp.status = __cpu_to_le16(0);
25094 - rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
25095 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
25100 -static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25102 - l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
25103 - __u16 scid, dcid, result, status;
25106 - scid = __le16_to_cpu(rsp->scid);
25107 - dcid = __le16_to_cpu(rsp->dcid);
25108 - result = __le16_to_cpu(rsp->result);
25109 - status = __le16_to_cpu(rsp->status);
25111 - DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
25113 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
25116 - bh_lock_sock(sk);
25121 - sk->state = BT_CONFIG;
25122 - l2cap_pi(sk)->dcid = dcid;
25123 - l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
25125 - l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
25127 - l2cap_chan_del(sk, ECONNREFUSED);
25130 - bh_unlock_sock(sk);
25134 -static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25136 - l2cap_conf_req * req = (l2cap_conf_req *) data;
25137 - __u16 dcid, flags;
25142 - dcid = __le16_to_cpu(req->dcid);
25143 - flags = __le16_to_cpu(req->flags);
25145 - DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
25147 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
25150 - bh_lock_sock(sk);
25152 - l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
25154 - if (flags & 0x01) {
25155 - /* Incomplete config. Send empty response. */
25156 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
25160 - /* Complete config. */
25161 - l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
25166 - /* Output config done */
25167 - l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
25169 - if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
25170 - sk->state = BT_CONNECTED;
25171 - l2cap_chan_ready(sk);
25172 - } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
25174 - l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
25178 - bh_unlock_sock(sk);
25183 -static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25185 - l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
25186 - __u16 scid, flags, result;
25190 - scid = __le16_to_cpu(rsp->scid);
25191 - flags = __le16_to_cpu(rsp->flags);
25192 - result = __le16_to_cpu(rsp->result);
25194 - DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
25196 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
25199 - bh_lock_sock(sk);
25202 - l2cap_disconn_req req;
25204 - /* They didn't like our options. Well... we do not negotiate.
25207 - sk->state = BT_DISCONN;
25209 - req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25210 - req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
25211 - l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
25213 - l2cap_sock_set_timer(sk, sk->sndtimeo);
25217 - if (flags & 0x01)
25220 - /* Input config done */
25221 - l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
25223 - if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
25224 - sk->state = BT_CONNECTED;
25225 - l2cap_chan_ready(sk);
25229 - bh_unlock_sock(sk);
25234 -static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25236 - l2cap_disconn_req *req = (l2cap_disconn_req *) data;
25237 - l2cap_disconn_rsp rsp;
25238 - __u16 dcid, scid;
25241 - scid = __le16_to_cpu(req->scid);
25242 - dcid = __le16_to_cpu(req->dcid);
25244 - DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
25246 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
25249 - bh_lock_sock(sk);
25251 - rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
25252 - rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
25253 - l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
25255 - l2cap_chan_del(sk, ECONNRESET);
25257 - bh_unlock_sock(sk);
25259 - l2cap_sock_kill(sk);
25264 -static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
25266 - l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
25267 - __u16 dcid, scid;
25270 - scid = __le16_to_cpu(rsp->scid);
25271 - dcid = __le16_to_cpu(rsp->dcid);
25273 - DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
25275 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
25278 - bh_lock_sock(sk);
25279 - l2cap_sock_clear_timer(sk);
25280 - l2cap_chan_del(sk, ECONNABORTED);
25281 - bh_unlock_sock(sk);
25283 - l2cap_sock_kill(sk);
25288 -static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
25290 - __u8 *data = skb->data;
25291 - int len = skb->len;
25292 - l2cap_cmd_hdr cmd;
25295 - while (len >= L2CAP_CMD_HDR_SIZE) {
25296 - memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
25297 - data += L2CAP_CMD_HDR_SIZE;
25298 - len -= L2CAP_CMD_HDR_SIZE;
25300 - cmd.len = __le16_to_cpu(cmd.len);
25302 - DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
25304 - if (cmd.len > len || !cmd.ident) {
25305 - DBG("corrupted command");
25309 - switch (cmd.code) {
25310 - case L2CAP_CONN_REQ:
25311 - err = l2cap_connect_req(conn, &cmd, data);
25314 - case L2CAP_CONN_RSP:
25315 - err = l2cap_connect_rsp(conn, &cmd, data);
25318 - case L2CAP_CONF_REQ:
25319 - err = l2cap_config_req(conn, &cmd, data);
25322 - case L2CAP_CONF_RSP:
25323 - err = l2cap_config_rsp(conn, &cmd, data);
25326 - case L2CAP_DISCONN_REQ:
25327 - err = l2cap_disconnect_req(conn, &cmd, data);
25330 - case L2CAP_DISCONN_RSP:
25331 - err = l2cap_disconnect_rsp(conn, &cmd, data);
25334 - case L2CAP_COMMAND_REJ:
25335 - /* FIXME: We should process this */
25336 - l2cap_raw_recv(conn, skb);
25339 - case L2CAP_ECHO_REQ:
25340 - l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
25343 - case L2CAP_ECHO_RSP:
25344 - case L2CAP_INFO_REQ:
25345 - case L2CAP_INFO_RSP:
25346 - l2cap_raw_recv(conn, skb);
25350 - ERR("Uknown signaling command 0x%2.2x", cmd.code);
25356 - l2cap_cmd_rej rej;
25357 - DBG("error %d", err);
25359 - /* FIXME: Map err to a valid reason. */
25360 - rej.reason = __cpu_to_le16(0);
25361 - l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
25371 -static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
25375 - if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
25376 - DBG("unknown cid 0x%4.4x", cid);
25380 - DBG("sk %p, len %d", sk, skb->len);
25382 - if (sk->state != BT_CONNECTED)
25385 - if (l2cap_pi(sk)->imtu < skb->len)
25388 - skb_queue_tail(&sk->receive_queue, skb);
25389 - sk->data_ready(sk, skb->len);
25399 -static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
25401 - l2cap_hdr *lh = (l2cap_hdr *) skb->data;
25404 - skb_pull(skb, L2CAP_HDR_SIZE);
25405 - cid = __le16_to_cpu(lh->cid);
25406 - len = __le16_to_cpu(lh->len);
25408 - DBG("len %d, cid 0x%4.4x", len, cid);
25410 - if (cid == 0x0001)
25411 - l2cap_sig_channel(conn, skb);
25413 - l2cap_data_channel(conn, cid, skb);
25416 -/* ------------ L2CAP interface with lower layer (HCI) ------------- */
25417 -static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
25419 - struct hci_dev *hdev = (struct hci_dev *) ptr;
25421 - DBG("hdev %s, event %ld", hdev->name, event);
25423 - write_lock(&l2cap_rt_lock);
25427 - l2cap_iff_add(hdev);
25430 - case HCI_DEV_DOWN:
25431 - l2cap_iff_del(hdev);
25435 - write_unlock(&l2cap_rt_lock);
25437 - return NOTIFY_DONE;
25440 -int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
25442 - struct l2cap_iff *iff;
25444 - DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
25446 - if (!(iff = hdev->l2cap_data)) {
25447 - ERR("unknown interface");
25451 - /* Always accept connection */
25455 -int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
25457 - struct l2cap_conn *conn;
25458 - struct l2cap_iff *iff;
25461 - DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
25463 - if (!(iff = hdev->l2cap_data)) {
25464 - ERR("unknown interface");
25468 - l2cap_iff_lock(iff);
25470 - conn = l2cap_get_conn_by_addr(iff, bdaddr);
25473 - /* Outgoing connection */
25474 - DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
25476 - if (!status && hconn) {
25477 - conn->state = BT_CONNECTED;
25478 - conn->hconn = hconn;
25480 - hconn->l2cap_data = (void *)conn;
25482 - /* Establish channels */
25483 - l2cap_conn_ready(conn);
25485 - l2cap_conn_del(conn, bterr(status));
25488 - /* Incomming connection */
25489 - DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
25491 - if (status || !hconn)
25494 - if (!(conn = l2cap_conn_add(iff, bdaddr))) {
25499 - conn->hconn = hconn;
25500 - hconn->l2cap_data = (void *)conn;
25502 - conn->state = BT_CONNECTED;
25506 - l2cap_iff_unlock(iff);
25511 -int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
25513 - struct l2cap_conn *conn = hconn->l2cap_data;
25515 - DBG("hconn %p reason %d", hconn, reason);
25518 - ERR("unknown connection");
25521 - conn->hconn = NULL;
25523 - l2cap_iff_lock(conn->iff);
25524 - l2cap_conn_del(conn, bterr(reason));
25525 - l2cap_iff_unlock(conn->iff);
25530 -int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
25532 - struct l2cap_conn *conn = hconn->l2cap_data;
25535 - ERR("unknown connection %p", hconn);
25539 - DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
25541 - if (flags & ACL_START) {
25542 - int flen, tlen, size;
25545 - if (conn->rx_len) {
25546 - ERR("Unexpected start frame (len %d)", skb->len);
25547 - kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
25548 - conn->rx_len = 0;
25551 - if (skb->len < L2CAP_HDR_SIZE) {
25552 - ERR("Frame is too small (len %d)", skb->len);
25556 - lh = (l2cap_hdr *)skb->data;
25557 - tlen = __le16_to_cpu(lh->len);
25558 - flen = skb->len - L2CAP_HDR_SIZE;
25560 - DBG("Start: total len %d, frag len %d", tlen, flen);
25562 - if (flen == tlen) {
25563 - /* Complete frame received */
25564 - l2cap_recv_frame(conn, skb);
25568 - /* Allocate skb for the complete frame (with header) */
25569 - size = L2CAP_HDR_SIZE + tlen;
25570 - if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
25573 - memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
25575 - conn->rx_len = tlen - flen;
25577 - DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
25579 - if (!conn->rx_len) {
25580 - ERR("Unexpected continuation frame (len %d)", skb->len);
25584 - if (skb->len > conn->rx_len) {
25585 - ERR("Fragment is too large (len %d)", skb->len);
25586 - kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
25590 - memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
25591 - conn->rx_len -= skb->len;
25593 - if (!conn->rx_len) {
25594 - /* Complete frame received */
25595 - l2cap_recv_frame(conn, conn->rx_skb);
25596 - conn->rx_skb = NULL;
25605 -struct proto_ops l2cap_sock_ops = {
25606 - family: PF_BLUETOOTH,
25607 - release: l2cap_sock_release,
25608 - bind: l2cap_sock_bind,
25609 - connect: l2cap_sock_connect,
25610 - listen: l2cap_sock_listen,
25611 - accept: l2cap_sock_accept,
25612 - getname: l2cap_sock_getname,
25613 - sendmsg: l2cap_sock_sendmsg,
25614 - recvmsg: l2cap_sock_recvmsg,
25615 - poll: l2cap_sock_poll,
25616 - socketpair: sock_no_socketpair,
25617 - ioctl: sock_no_ioctl,
25618 - shutdown: sock_no_shutdown,
25619 - setsockopt: l2cap_sock_setsockopt,
25620 - getsockopt: l2cap_sock_getsockopt,
25621 - mmap: sock_no_mmap
25624 -struct net_proto_family l2cap_sock_family_ops = {
25625 - family: PF_BLUETOOTH,
25626 - create: l2cap_sock_create
25629 -struct hci_proto l2cap_hci_proto = {
25631 - id: HCI_PROTO_L2CAP,
25632 - connect_ind: l2cap_connect_ind,
25633 - connect_cfm: l2cap_connect_cfm,
25634 - disconn_ind: l2cap_disconn_ind,
25635 - recv_acldata: l2cap_recv_acldata,
25638 -struct notifier_block l2cap_nblock = {
25639 - notifier_call: l2cap_dev_event
25642 -int __init l2cap_init(void)
25644 - INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
25646 - INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
25648 - if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
25649 - ERR("Can't register L2CAP socket");
25653 - if (hci_register_proto(&l2cap_hci_proto) < 0) {
25654 - ERR("Can't register L2CAP protocol");
25658 - hci_register_notifier(&l2cap_nblock);
25660 - l2cap_register_proc();
25665 -void l2cap_cleanup(void)
25667 - l2cap_unregister_proc();
25669 - /* Unregister socket, protocol and notifier */
25670 - if (bluez_sock_unregister(BTPROTO_L2CAP))
25671 - ERR("Can't unregister L2CAP socket");
25673 - if (hci_unregister_proto(&l2cap_hci_proto) < 0)
25674 - ERR("Can't unregister L2CAP protocol");
25676 - hci_unregister_notifier(&l2cap_nblock);
25678 - /* We _must_ not have any sockets and/or connections
25682 - /* Free interface list and unlock HCI devices */
25684 - struct list_head *list = &l2cap_iff_list;
25686 - while (!list_empty(list)) {
25687 - struct l2cap_iff *iff;
25689 - iff = list_entry(list->next, struct l2cap_iff, list);
25690 - l2cap_iff_del(iff->hdev);
25695 -module_init(l2cap_init);
25696 -module_exit(l2cap_cleanup);
25698 -MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
25699 -MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
25700 -MODULE_LICENSE("GPL");
25702 diff -urN linux-2.4.18/net/bluetooth/l2cap_proc.c linux-2.4.18-mh9/net/bluetooth/l2cap_proc.c
25703 --- linux-2.4.18/net/bluetooth/l2cap_proc.c Fri Sep 7 18:28:38 2001
25704 +++ linux-2.4.18-mh9/net/bluetooth/l2cap_proc.c Thu Jan 1 01:00:00 1970
25707 - BlueZ - Bluetooth protocol stack for Linux
25708 - Copyright (C) 2000-2001 Qualcomm Incorporated
25710 - Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
25712 - This program is free software; you can redistribute it and/or modify
25713 - it under the terms of the GNU General Public License version 2 as
25714 - published by the Free Software Foundation;
25716 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25717 - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25718 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
25719 - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
25720 - CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
25721 - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
25722 - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25723 - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25725 - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25726 - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25727 - SOFTWARE IS DISCLAIMED.
25731 - * BlueZ L2CAP proc fs support.
25733 - * $Id: l2cap_proc.c,v 1.2 2001/06/02 01:40:09 maxk Exp $
25736 -#include <linux/config.h>
25737 -#include <linux/module.h>
25739 -#include <linux/types.h>
25740 -#include <linux/errno.h>
25741 -#include <linux/kernel.h>
25742 -#include <linux/major.h>
25743 -#include <linux/sched.h>
25744 -#include <linux/slab.h>
25745 -#include <linux/poll.h>
25746 -#include <linux/fcntl.h>
25747 -#include <linux/init.h>
25748 -#include <linux/skbuff.h>
25749 -#include <linux/interrupt.h>
25750 -#include <linux/socket.h>
25751 -#include <linux/skbuff.h>
25752 -#include <linux/proc_fs.h>
25753 -#include <linux/list.h>
25754 -#include <net/sock.h>
25756 -#include <asm/system.h>
25757 -#include <asm/uaccess.h>
25759 -#include <net/bluetooth/bluez.h>
25760 -#include <net/bluetooth/bluetooth.h>
25761 -#include <net/bluetooth/hci_core.h>
25762 -#include <net/bluetooth/l2cap_core.h>
25764 -#ifndef L2CAP_DEBUG
25766 -#define DBG( A... )
25769 -/* ----- PROC fs support ----- */
25770 -static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
25772 - struct list_head *p;
25775 - list_for_each(p, &iff->conn_list) {
25776 - struct l2cap_conn *c;
25778 - c = list_entry(p, struct l2cap_conn, list);
25779 - ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
25780 - c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
25783 - return ptr - buf;
25786 -static int l2cap_iff_dump(char *buf)
25788 - struct list_head *p;
25791 - ptr += sprintf(ptr, "Interfaces:\n");
25793 - write_lock(&l2cap_rt_lock);
25795 - list_for_each(p, &l2cap_iff_list) {
25796 - struct l2cap_iff *iff;
25798 - iff = list_entry(p, struct l2cap_iff, list);
25800 - ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
25802 - l2cap_iff_lock(iff);
25803 - ptr += l2cap_conn_dump(ptr, iff);
25804 - l2cap_iff_unlock(iff);
25807 - write_unlock(&l2cap_rt_lock);
25809 - ptr += sprintf(ptr, "\n");
25811 - return ptr - buf;
25814 -static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
25816 - struct l2cap_pinfo *pi;
25820 - ptr += sprintf(ptr, "Sockets:\n");
25822 - write_lock(&list->lock);
25824 - for (sk = list->head; sk; sk = sk->next) {
25825 - pi = l2cap_pi(sk);
25826 - ptr += sprintf(ptr, " %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
25827 - batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
25830 - write_unlock(&list->lock);
25832 - ptr += sprintf(ptr, "\n");
25834 - return ptr - buf;
25837 -static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
25842 - DBG("count %d, offset %ld", count, offset);
25844 - ptr += l2cap_iff_dump(ptr);
25845 - ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
25848 - if (len <= count + offset)
25851 - *start = buf + offset;
25862 -void l2cap_register_proc(void)
25864 - create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
25867 -void l2cap_unregister_proc(void)
25869 - remove_proc_entry("bluetooth/l2cap", NULL);
25871 diff -urN linux-2.4.18/net/bluetooth/lib.c linux-2.4.18-mh9/net/bluetooth/lib.c
25872 --- linux-2.4.18/net/bluetooth/lib.c Fri Sep 7 18:28:38 2001
25873 +++ linux-2.4.18-mh9/net/bluetooth/lib.c Mon Aug 25 18:38:12 2003
25876 * BlueZ kernel library.
25878 - * $Id: lib.c,v 1.3 2001/06/22 23:14:23 maxk Exp $
25879 + * $Id: lib.c,v 1.2 2002/06/20 19:55:08 maxk Exp $
25882 #include <linux/kernel.h>
25883 @@ -105,7 +105,7 @@
25892 diff -urN linux-2.4.18/net/bluetooth/rfcomm/Config.in linux-2.4.18-mh9/net/bluetooth/rfcomm/Config.in
25893 --- linux-2.4.18/net/bluetooth/rfcomm/Config.in Thu Jan 1 01:00:00 1970
25894 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/Config.in Mon Aug 25 18:38:12 2003
25897 +# Bluetooth RFCOMM layer configuration
25900 +dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
25902 +if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
25903 + bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
25906 diff -urN linux-2.4.18/net/bluetooth/rfcomm/Makefile linux-2.4.18-mh9/net/bluetooth/rfcomm/Makefile
25907 --- linux-2.4.18/net/bluetooth/rfcomm/Makefile Thu Jan 1 01:00:00 1970
25908 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/Makefile Mon Aug 25 18:38:12 2003
25911 +# Makefile for the Linux Bluetooth RFCOMM layer
25914 +O_TARGET := rfcomm.o
25916 +obj-y := core.o sock.o crc.o
25917 +obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
25918 +obj-m += $(O_TARGET)
25920 +include $(TOPDIR)/Rules.make
25921 diff -urN linux-2.4.18/net/bluetooth/rfcomm/core.c linux-2.4.18-mh9/net/bluetooth/rfcomm/core.c
25922 --- linux-2.4.18/net/bluetooth/rfcomm/core.c Thu Jan 1 01:00:00 1970
25923 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/core.c Mon Aug 25 18:38:12 2003
25926 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
25927 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
25928 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
25930 + This program is free software; you can redistribute it and/or modify
25931 + it under the terms of the GNU General Public License version 2 as
25932 + published by the Free Software Foundation;
25934 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25935 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25936 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
25937 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
25938 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
25939 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
25940 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25941 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25943 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
25944 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
25945 + SOFTWARE IS DISCLAIMED.
25949 + RPN support - Dirk Husemann <hud@zurich.ibm.com>
25955 + * $Id: core.c,v 1.46 2002/10/18 20:12:12 maxk Exp $
25958 +#define __KERNEL_SYSCALLS__
25960 +#include <linux/config.h>
25961 +#include <linux/module.h>
25962 +#include <linux/errno.h>
25963 +#include <linux/kernel.h>
25964 +#include <linux/sched.h>
25965 +#include <linux/signal.h>
25966 +#include <linux/init.h>
25967 +#include <linux/wait.h>
25968 +#include <linux/net.h>
25969 +#include <linux/proc_fs.h>
25970 +#include <net/sock.h>
25971 +#include <asm/uaccess.h>
25972 +#include <asm/unaligned.h>
25974 +#include <net/bluetooth/bluetooth.h>
25975 +#include <net/bluetooth/l2cap.h>
25976 +#include <net/bluetooth/rfcomm.h>
25978 +#define VERSION "1.0"
25980 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
25982 +#define BT_DBG(D...)
25985 +struct task_struct *rfcomm_thread;
25986 +DECLARE_MUTEX(rfcomm_sem);
25987 +unsigned long rfcomm_event;
25989 +static LIST_HEAD(session_list);
25990 +static atomic_t terminate, running;
25992 +static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
25993 +static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
25994 +static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
25995 +static int rfcomm_queue_disc(struct rfcomm_dlc *d);
25996 +static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
25997 +static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
25998 +static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
25999 +static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
26000 +static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
26001 +static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
26003 +static void rfcomm_process_connect(struct rfcomm_session *s);
26005 +/* ---- RFCOMM frame parsing macros ---- */
26006 +#define __get_dlci(b) ((b & 0xfc) >> 2)
26007 +#define __get_channel(b) ((b & 0xf8) >> 3)
26008 +#define __get_dir(b) ((b & 0x04) >> 2)
26009 +#define __get_type(b) ((b & 0xef))
26011 +#define __test_ea(b) ((b & 0x01))
26012 +#define __test_cr(b) ((b & 0x02))
26013 +#define __test_pf(b) ((b & 0x10))
26015 +#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
26016 +#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
26017 +#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
26018 +#define __srv_channel(dlci) (dlci >> 1)
26019 +#define __dir(dlci) (dlci & 0x01)
26021 +#define __len8(len) (((len) << 1) | 1)
26022 +#define __len16(len) ((len) << 1)
26025 +#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
26026 +#define __get_mcc_type(b) ((b & 0xfc) >> 2)
26027 +#define __get_mcc_len(b) ((b & 0xfe) >> 1)
26030 +#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
26031 +#define __get_rpn_data_bits(line) ((line) & 0x3)
26032 +#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
26033 +#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
26035 +/* ---- RFCOMM FCS computation ---- */
26037 +/* CRC on 2 bytes */
26038 +#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
26040 +/* FCS on 2 bytes */
26041 +static inline u8 __fcs(u8 *data)
26043 + return (0xff - __crc(data));
26046 +/* FCS on 3 bytes */
26047 +static inline u8 __fcs2(u8 *data)
26049 + return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
26053 +static inline int __check_fcs(u8 *data, int type, u8 fcs)
26055 + u8 f = __crc(data);
26057 + if (type != RFCOMM_UIH)
26058 + f = rfcomm_crc_table[f ^ data[2]];
26060 + return rfcomm_crc_table[f ^ fcs] != 0xcf;
26063 +/* ---- L2CAP callbacks ---- */
26064 +static void rfcomm_l2state_change(struct sock *sk)
26066 + BT_DBG("%p state %d", sk, sk->state);
26067 + rfcomm_schedule(RFCOMM_SCHED_STATE);
26070 +static void rfcomm_l2data_ready(struct sock *sk, int bytes)
26072 + BT_DBG("%p bytes %d", sk, bytes);
26073 + rfcomm_schedule(RFCOMM_SCHED_RX);
26076 +static int rfcomm_l2sock_create(struct socket **sock)
26082 + err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
26084 + struct sock *sk = (*sock)->sk;
26085 + sk->data_ready = rfcomm_l2data_ready;
26086 + sk->state_change = rfcomm_l2state_change;
26091 +/* ---- RFCOMM DLCs ---- */
26092 +static void rfcomm_dlc_timeout(unsigned long arg)
26094 + struct rfcomm_dlc *d = (void *) arg;
26096 + BT_DBG("dlc %p state %ld", d, d->state);
26098 + set_bit(RFCOMM_TIMED_OUT, &d->flags);
26099 + rfcomm_dlc_put(d);
26100 + rfcomm_schedule(RFCOMM_SCHED_TIMEO);
26103 +static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
26105 + BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
26107 + if (!mod_timer(&d->timer, jiffies + timeout))
26108 + rfcomm_dlc_hold(d);
26111 +static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
26113 + BT_DBG("dlc %p state %ld", d, d->state);
26115 + if (timer_pending(&d->timer) && del_timer(&d->timer))
26116 + rfcomm_dlc_put(d);
26119 +static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
26123 + d->state = BT_OPEN;
26126 + d->mtu = RFCOMM_DEFAULT_MTU;
26127 + d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
26130 + d->rx_credits = RFCOMM_DEFAULT_CREDITS;
26133 +struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
26135 + struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
26138 + memset(d, 0, sizeof(*d));
26140 + init_timer(&d->timer);
26141 + d->timer.function = rfcomm_dlc_timeout;
26142 + d->timer.data = (unsigned long) d;
26144 + skb_queue_head_init(&d->tx_queue);
26145 + spin_lock_init(&d->lock);
26146 + atomic_set(&d->refcnt, 1);
26148 + rfcomm_dlc_clear_state(d);
26154 +void rfcomm_dlc_free(struct rfcomm_dlc *d)
26158 + skb_queue_purge(&d->tx_queue);
26162 +static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
26164 + BT_DBG("dlc %p session %p", d, s);
26166 + rfcomm_session_hold(s);
26168 + rfcomm_dlc_hold(d);
26169 + list_add(&d->list, &s->dlcs);
26173 +static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
26175 + struct rfcomm_session *s = d->session;
26177 + BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
26179 + list_del(&d->list);
26180 + d->session = NULL;
26181 + rfcomm_dlc_put(d);
26183 + rfcomm_session_put(s);
26186 +static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
26188 + struct rfcomm_dlc *d;
26189 + struct list_head *p;
26191 + list_for_each(p, &s->dlcs) {
26192 + d = list_entry(p, struct rfcomm_dlc, list);
26193 + if (d->dlci == dlci)
26199 +static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
26201 + struct rfcomm_session *s;
26205 + BT_DBG("dlc %p state %ld %s %s channel %d",
26206 + d, d->state, batostr(src), batostr(dst), channel);
26208 + if (channel < 1 || channel > 30)
26211 + if (d->state != BT_OPEN && d->state != BT_CLOSED)
26214 + s = rfcomm_session_get(src, dst);
26216 + s = rfcomm_session_create(src, dst, &err);
26221 + dlci = __dlci(!s->initiator, channel);
26223 + /* Check if DLCI already exists */
26224 + if (rfcomm_dlc_get(s, dlci))
26227 + rfcomm_dlc_clear_state(d);
26230 + d->addr = __addr(s->initiator, dlci);
26233 + d->state = BT_CONFIG;
26234 + rfcomm_dlc_link(s, d);
26237 + d->credits = s->credits;
26239 + if (s->state == BT_CONNECTED)
26240 + rfcomm_send_pn(s, 1, d);
26241 + rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
26245 +int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
26252 + fs = get_fs(); set_fs(KERNEL_DS);
26253 + r = __rfcomm_dlc_open(d, src, dst, channel);
26260 +static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
26262 + struct rfcomm_session *s = d->session;
26266 + BT_DBG("dlc %p state %ld dlci %d err %d session %p",
26267 + d, d->state, d->dlci, err, s);
26269 + switch (d->state) {
26270 + case BT_CONNECTED:
26273 + d->state = BT_DISCONN;
26274 + if (skb_queue_empty(&d->tx_queue)) {
26275 + rfcomm_send_disc(s, d->dlci);
26276 + rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
26278 + rfcomm_queue_disc(d);
26279 + rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
26284 + rfcomm_dlc_clear_timer(d);
26286 + rfcomm_dlc_lock(d);
26287 + d->state = BT_CLOSED;
26288 + d->state_change(d, err);
26289 + rfcomm_dlc_unlock(d);
26291 + skb_queue_purge(&d->tx_queue);
26292 + rfcomm_dlc_unlink(d);
26298 +int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
26305 + fs = get_fs(); set_fs(KERNEL_DS);
26306 + r = __rfcomm_dlc_close(d, err);
26313 +int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
26315 + int len = skb->len;
26317 + if (d->state != BT_CONNECTED)
26318 + return -ENOTCONN;
26320 + BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
26322 + if (len > d->mtu)
26325 + rfcomm_make_uih(skb, d->addr);
26326 + skb_queue_tail(&d->tx_queue, skb);
26328 + if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
26329 + rfcomm_schedule(RFCOMM_SCHED_TX);
26333 +void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
26335 + BT_DBG("dlc %p state %ld", d, d->state);
26337 + if (!d->credits) {
26338 + d->v24_sig |= RFCOMM_V24_FC;
26339 + set_bit(RFCOMM_MSC_PENDING, &d->flags);
26341 + rfcomm_schedule(RFCOMM_SCHED_TX);
26344 +void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
26346 + BT_DBG("dlc %p state %ld", d, d->state);
26348 + if (!d->credits) {
26349 + d->v24_sig &= ~RFCOMM_V24_FC;
26350 + set_bit(RFCOMM_MSC_PENDING, &d->flags);
26352 + rfcomm_schedule(RFCOMM_SCHED_TX);
26356 + Set/get modem status functions use _local_ status i.e. what we report
26357 + to the other side.
26358 + Remote status is provided by dlc->modem_status() callback.
26360 +int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
26362 + BT_DBG("dlc %p state %ld v24_sig 0x%x",
26363 + d, d->state, v24_sig);
26365 + if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
26366 + v24_sig |= RFCOMM_V24_FC;
26368 + v24_sig &= ~RFCOMM_V24_FC;
26370 + d->v24_sig = v24_sig;
26372 + if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
26373 + rfcomm_schedule(RFCOMM_SCHED_TX);
26378 +int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
26380 + BT_DBG("dlc %p state %ld v24_sig 0x%x",
26381 + d, d->state, d->v24_sig);
26383 + *v24_sig = d->v24_sig;
26387 +/* ---- RFCOMM sessions ---- */
26388 +struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
26390 + struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
26393 + memset(s, 0, sizeof(*s));
26395 + BT_DBG("session %p sock %p", s, sock);
26397 + INIT_LIST_HEAD(&s->dlcs);
26398 + s->state = state;
26401 + s->mtu = RFCOMM_DEFAULT_MTU;
26404 + list_add(&s->list, &session_list);
26406 + /* Do not increment module usage count for listeting sessions.
26407 + * Otherwise we won't be able to unload the module. */
26408 + if (state != BT_LISTEN)
26409 + MOD_INC_USE_COUNT;
26413 +void rfcomm_session_del(struct rfcomm_session *s)
26415 + int state = s->state;
26417 + BT_DBG("session %p state %ld", s, s->state);
26419 + list_del(&s->list);
26421 + if (state == BT_CONNECTED)
26422 + rfcomm_send_disc(s, 0);
26424 + sock_release(s->sock);
26427 + if (state != BT_LISTEN)
26428 + MOD_DEC_USE_COUNT;
26431 +struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
26433 + struct rfcomm_session *s;
26434 + struct list_head *p, *n;
26435 + struct bluez_pinfo *pi;
26436 + list_for_each_safe(p, n, &session_list) {
26437 + s = list_entry(p, struct rfcomm_session, list);
26438 + pi = bluez_pi(s->sock->sk);
26440 + if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
26441 + !bacmp(&pi->dst, dst))
26447 +void rfcomm_session_close(struct rfcomm_session *s, int err)
26449 + struct rfcomm_dlc *d;
26450 + struct list_head *p, *n;
26452 + BT_DBG("session %p state %ld err %d", s, s->state, err);
26454 + rfcomm_session_hold(s);
26456 + s->state = BT_CLOSED;
26458 + /* Close all dlcs */
26459 + list_for_each_safe(p, n, &s->dlcs) {
26460 + d = list_entry(p, struct rfcomm_dlc, list);
26461 + d->state = BT_CLOSED;
26462 + __rfcomm_dlc_close(d, err);
26465 + rfcomm_session_put(s);
26468 +struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
26470 + struct rfcomm_session *s = NULL;
26471 + struct sockaddr_l2 addr;
26472 + struct l2cap_options opts;
26473 + struct socket *sock;
26476 + BT_DBG("%s %s", batostr(src), batostr(dst));
26478 + *err = rfcomm_l2sock_create(&sock);
26482 + bacpy(&addr.l2_bdaddr, src);
26483 + addr.l2_family = AF_BLUETOOTH;
26485 + *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
26489 + /* Set L2CAP options */
26490 + size = sizeof(opts);
26491 + sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
26493 + opts.imtu = RFCOMM_MAX_L2CAP_MTU;
26494 + sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
26496 + s = rfcomm_session_add(sock, BT_BOUND);
26502 + s->initiator = 1;
26504 + bacpy(&addr.l2_bdaddr, dst);
26505 + addr.l2_family = AF_BLUETOOTH;
26506 + addr.l2_psm = htobs(RFCOMM_PSM);
26507 + *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
26508 + if (*err == 0 || *err == -EAGAIN)
26511 + rfcomm_session_del(s);
26515 + sock_release(sock);
26519 +void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
26521 + struct sock *sk = s->sock->sk;
26523 + bacpy(src, &bluez_pi(sk)->src);
26525 + bacpy(dst, &bluez_pi(sk)->dst);
26528 +/* ---- RFCOMM frame sending ---- */
26529 +static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
26531 + struct socket *sock = s->sock;
26532 + struct iovec iv = { data, len };
26533 + struct msghdr msg;
26536 + BT_DBG("session %p len %d", s, len);
26538 + memset(&msg, 0, sizeof(msg));
26539 + msg.msg_iovlen = 1;
26540 + msg.msg_iov = &iv;
26542 + err = sock->ops->sendmsg(sock, &msg, len, 0);
26546 +static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
26548 + struct rfcomm_cmd cmd;
26550 + BT_DBG("%p dlci %d", s, dlci);
26552 + cmd.addr = __addr(s->initiator, dlci);
26553 + cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
26554 + cmd.len = __len8(0);
26555 + cmd.fcs = __fcs2((u8 *) &cmd);
26557 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
26560 +static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
26562 + struct rfcomm_cmd cmd;
26564 + BT_DBG("%p dlci %d", s, dlci);
26566 + cmd.addr = __addr(!s->initiator, dlci);
26567 + cmd.ctrl = __ctrl(RFCOMM_UA, 1);
26568 + cmd.len = __len8(0);
26569 + cmd.fcs = __fcs2((u8 *) &cmd);
26571 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
26574 +static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
26576 + struct rfcomm_cmd cmd;
26578 + BT_DBG("%p dlci %d", s, dlci);
26580 + cmd.addr = __addr(s->initiator, dlci);
26581 + cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
26582 + cmd.len = __len8(0);
26583 + cmd.fcs = __fcs2((u8 *) &cmd);
26585 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
26588 +static int rfcomm_queue_disc(struct rfcomm_dlc *d)
26590 + struct rfcomm_cmd *cmd;
26591 + struct sk_buff *skb;
26593 + BT_DBG("dlc %p dlci %d", d, d->dlci);
26595 + skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
26599 + cmd = (void *) __skb_put(skb, sizeof(*cmd));
26600 + cmd->addr = d->addr;
26601 + cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
26602 + cmd->len = __len8(0);
26603 + cmd->fcs = __fcs2((u8 *) cmd);
26605 + skb_queue_tail(&d->tx_queue, skb);
26606 + rfcomm_schedule(RFCOMM_SCHED_TX);
26610 +static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
26612 + struct rfcomm_cmd cmd;
26614 + BT_DBG("%p dlci %d", s, dlci);
26616 + cmd.addr = __addr(!s->initiator, dlci);
26617 + cmd.ctrl = __ctrl(RFCOMM_DM, 1);
26618 + cmd.len = __len8(0);
26619 + cmd.fcs = __fcs2((u8 *) &cmd);
26621 + return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
26624 +static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
26626 + struct rfcomm_hdr *hdr;
26627 + struct rfcomm_mcc *mcc;
26628 + u8 buf[16], *ptr = buf;
26630 + BT_DBG("%p cr %d type %d", s, cr, type);
26632 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26633 + hdr->addr = __addr(s->initiator, 0);
26634 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26635 + hdr->len = __len8(sizeof(*mcc) + 1);
26637 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26638 + mcc->type = __mcc_type(cr, RFCOMM_NSC);
26639 + mcc->len = __len8(1);
26641 + /* Type that we didn't like */
26642 + *ptr = __mcc_type(cr, type); ptr++;
26644 + *ptr = __fcs(buf); ptr++;
26646 + return rfcomm_send_frame(s, buf, ptr - buf);
26649 +static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
26651 + struct rfcomm_hdr *hdr;
26652 + struct rfcomm_mcc *mcc;
26653 + struct rfcomm_pn *pn;
26654 + u8 buf[16], *ptr = buf;
26656 + BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
26658 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26659 + hdr->addr = __addr(s->initiator, 0);
26660 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26661 + hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
26663 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26664 + mcc->type = __mcc_type(cr, RFCOMM_PN);
26665 + mcc->len = __len8(sizeof(*pn));
26667 + pn = (void *) ptr; ptr += sizeof(*pn);
26668 + pn->dlci = d->dlci;
26669 + pn->priority = d->priority;
26670 + pn->ack_timer = 0;
26671 + pn->max_retrans = 0;
26673 + if (cr || d->credits) {
26674 + pn->flow_ctrl = cr ? 0xf0 : 0xe0;
26675 + pn->credits = RFCOMM_DEFAULT_CREDITS;
26677 + pn->flow_ctrl = 0;
26681 + pn->mtu = htobs(d->mtu);
26683 + *ptr = __fcs(buf); ptr++;
26685 + return rfcomm_send_frame(s, buf, ptr - buf);
26688 +static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
26689 + u8 bit_rate, u8 data_bits, u8 stop_bits,
26690 + u8 parity, u8 flow_ctrl_settings,
26691 + u8 xon_char, u8 xoff_char, u16 param_mask)
26693 + struct rfcomm_hdr *hdr;
26694 + struct rfcomm_mcc *mcc;
26695 + struct rfcomm_rpn *rpn;
26696 + u8 buf[16], *ptr = buf;
26698 + BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
26699 + "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
26700 + s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
26701 + flow_ctrl_settings, xon_char, xoff_char, param_mask);
26703 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26704 + hdr->addr = __addr(s->initiator, 0);
26705 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26706 + hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
26708 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26709 + mcc->type = __mcc_type(cr, RFCOMM_RPN);
26710 + mcc->len = __len8(sizeof(*rpn));
26712 + rpn = (void *) ptr; ptr += sizeof(*rpn);
26713 + rpn->dlci = __addr(1, dlci);
26714 + rpn->bit_rate = bit_rate;
26715 + rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
26716 + rpn->flow_ctrl = flow_ctrl_settings;
26717 + rpn->xon_char = xon_char;
26718 + rpn->xoff_char = xoff_char;
26719 + rpn->param_mask = param_mask;
26721 + *ptr = __fcs(buf); ptr++;
26723 + return rfcomm_send_frame(s, buf, ptr - buf);
26726 +static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
26728 + struct rfcomm_hdr *hdr;
26729 + struct rfcomm_mcc *mcc;
26730 + struct rfcomm_rls *rls;
26731 + u8 buf[16], *ptr = buf;
26733 + BT_DBG("%p cr %d status 0x%x", s, cr, status);
26735 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26736 + hdr->addr = __addr(s->initiator, 0);
26737 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26738 + hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
26740 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26741 + mcc->type = __mcc_type(cr, RFCOMM_RLS);
26742 + mcc->len = __len8(sizeof(*rls));
26744 + rls = (void *) ptr; ptr += sizeof(*rls);
26745 + rls->dlci = __addr(1, dlci);
26746 + rls->status = status;
26748 + *ptr = __fcs(buf); ptr++;
26750 + return rfcomm_send_frame(s, buf, ptr - buf);
26753 +static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
26755 + struct rfcomm_hdr *hdr;
26756 + struct rfcomm_mcc *mcc;
26757 + struct rfcomm_msc *msc;
26758 + u8 buf[16], *ptr = buf;
26760 + BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
26762 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26763 + hdr->addr = __addr(s->initiator, 0);
26764 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26765 + hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
26767 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26768 + mcc->type = __mcc_type(cr, RFCOMM_MSC);
26769 + mcc->len = __len8(sizeof(*msc));
26771 + msc = (void *) ptr; ptr += sizeof(*msc);
26772 + msc->dlci = __addr(1, dlci);
26773 + msc->v24_sig = v24_sig | 0x01;
26775 + *ptr = __fcs(buf); ptr++;
26777 + return rfcomm_send_frame(s, buf, ptr - buf);
26780 +static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
26782 + struct rfcomm_hdr *hdr;
26783 + struct rfcomm_mcc *mcc;
26784 + u8 buf[16], *ptr = buf;
26786 + BT_DBG("%p cr %d", s, cr);
26788 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26789 + hdr->addr = __addr(s->initiator, 0);
26790 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26791 + hdr->len = __len8(sizeof(*mcc));
26793 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26794 + mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
26795 + mcc->len = __len8(0);
26797 + *ptr = __fcs(buf); ptr++;
26799 + return rfcomm_send_frame(s, buf, ptr - buf);
26802 +static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
26804 + struct rfcomm_hdr *hdr;
26805 + struct rfcomm_mcc *mcc;
26806 + u8 buf[16], *ptr = buf;
26808 + BT_DBG("%p cr %d", s, cr);
26810 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26811 + hdr->addr = __addr(s->initiator, 0);
26812 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26813 + hdr->len = __len8(sizeof(*mcc));
26815 + mcc = (void *) ptr; ptr += sizeof(*mcc);
26816 + mcc->type = __mcc_type(cr, RFCOMM_FCON);
26817 + mcc->len = __len8(0);
26819 + *ptr = __fcs(buf); ptr++;
26821 + return rfcomm_send_frame(s, buf, ptr - buf);
26824 +static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
26826 + struct socket *sock = s->sock;
26827 + struct iovec iv[3];
26828 + struct msghdr msg;
26829 + unsigned char hdr[5], crc[1];
26834 + BT_DBG("%p cr %d", s, cr);
26836 + hdr[0] = __addr(s->initiator, 0);
26837 + hdr[1] = __ctrl(RFCOMM_UIH, 0);
26838 + hdr[2] = 0x01 | ((len + 2) << 1);
26839 + hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
26840 + hdr[4] = 0x01 | (len << 1);
26842 + crc[0] = __fcs(hdr);
26844 + iv[0].iov_base = hdr;
26845 + iv[0].iov_len = 5;
26846 + iv[1].iov_base = pattern;
26847 + iv[1].iov_len = len;
26848 + iv[2].iov_base = crc;
26849 + iv[2].iov_len = 1;
26851 + memset(&msg, 0, sizeof(msg));
26852 + msg.msg_iovlen = 3;
26853 + msg.msg_iov = iv;
26854 + return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
26857 +static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
26859 + struct rfcomm_hdr *hdr;
26860 + u8 buf[16], *ptr = buf;
26862 + BT_DBG("%p addr %d credits %d", s, addr, credits);
26864 + hdr = (void *) ptr; ptr += sizeof(*hdr);
26865 + hdr->addr = addr;
26866 + hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
26867 + hdr->len = __len8(0);
26869 + *ptr = credits; ptr++;
26871 + *ptr = __fcs(buf); ptr++;
26873 + return rfcomm_send_frame(s, buf, ptr - buf);
26876 +static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
26878 + struct rfcomm_hdr *hdr;
26879 + int len = skb->len;
26883 + hdr = (void *) skb_push(skb, 4);
26884 + put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
26886 + hdr = (void *) skb_push(skb, 3);
26887 + hdr->len = __len8(len);
26889 + hdr->addr = addr;
26890 + hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
26892 + crc = skb_put(skb, 1);
26893 + *crc = __fcs((void *) hdr);
26896 +/* ---- RFCOMM frame reception ---- */
26897 +static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
26899 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
26902 + /* Data channel */
26903 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
26905 + rfcomm_send_dm(s, dlci);
26909 + switch (d->state) {
26911 + rfcomm_dlc_clear_timer(d);
26913 + rfcomm_dlc_lock(d);
26914 + d->state = BT_CONNECTED;
26915 + d->state_change(d, 0);
26916 + rfcomm_dlc_unlock(d);
26918 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
26922 + d->state = BT_CLOSED;
26923 + __rfcomm_dlc_close(d, 0);
26927 + /* Control channel */
26928 + switch (s->state) {
26930 + s->state = BT_CONNECTED;
26931 + rfcomm_process_connect(s);
26938 +static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
26942 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
26946 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
26948 + if (d->state == BT_CONNECT || d->state == BT_CONFIG)
26949 + err = ECONNREFUSED;
26951 + err = ECONNRESET;
26953 + d->state = BT_CLOSED;
26954 + __rfcomm_dlc_close(d, err);
26957 + if (s->state == BT_CONNECT)
26958 + err = ECONNREFUSED;
26960 + err = ECONNRESET;
26962 + s->state = BT_CLOSED;
26963 + rfcomm_session_close(s, err);
26968 +static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
26972 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
26975 + struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
26977 + rfcomm_send_ua(s, dlci);
26979 + if (d->state == BT_CONNECT || d->state == BT_CONFIG)
26980 + err = ECONNREFUSED;
26982 + err = ECONNRESET;
26984 + d->state = BT_CLOSED;
26985 + __rfcomm_dlc_close(d, err);
26987 + rfcomm_send_dm(s, dlci);
26990 + rfcomm_send_ua(s, 0);
26992 + if (s->state == BT_CONNECT)
26993 + err = ECONNREFUSED;
26995 + err = ECONNRESET;
26997 + s->state = BT_CLOSED;
26998 + rfcomm_session_close(s, err);
27004 +static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
27006 + struct rfcomm_dlc *d;
27009 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
27012 + rfcomm_send_ua(s, 0);
27014 + if (s->state == BT_OPEN) {
27015 + s->state = BT_CONNECTED;
27016 + rfcomm_process_connect(s);
27021 + /* Check if DLC exists */
27022 + d = rfcomm_dlc_get(s, dlci);
27024 + if (d->state == BT_OPEN) {
27025 + /* DLC was previously opened by PN request */
27026 + rfcomm_send_ua(s, dlci);
27028 + rfcomm_dlc_lock(d);
27029 + d->state = BT_CONNECTED;
27030 + d->state_change(d, 0);
27031 + rfcomm_dlc_unlock(d);
27033 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
27038 + /* Notify socket layer about incomming connection */
27039 + channel = __srv_channel(dlci);
27040 + if (rfcomm_connect_ind(s, channel, &d)) {
27042 + d->addr = __addr(s->initiator, dlci);
27043 + rfcomm_dlc_link(s, d);
27045 + rfcomm_send_ua(s, dlci);
27047 + rfcomm_dlc_lock(d);
27048 + d->state = BT_CONNECTED;
27049 + d->state_change(d, 0);
27050 + rfcomm_dlc_unlock(d);
27052 + rfcomm_send_msc(s, 1, dlci, d->v24_sig);
27054 + rfcomm_send_dm(s, dlci);
27060 +static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
27062 + struct rfcomm_session *s = d->session;
27064 + BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
27065 + d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
27068 + if (pn->flow_ctrl == 0xf0) {
27069 + s->credits = RFCOMM_MAX_CREDITS;
27070 + d->credits = s->credits;
27071 + d->tx_credits = pn->credits;
27073 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
27077 + if (pn->flow_ctrl == 0xe0) {
27078 + s->credits = RFCOMM_MAX_CREDITS;
27079 + d->credits = s->credits;
27080 + d->tx_credits = pn->credits;
27082 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
27087 + d->priority = pn->priority;
27089 + d->mtu = btohs(pn->mtu);
27094 +static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
27096 + struct rfcomm_pn *pn = (void *) skb->data;
27097 + struct rfcomm_dlc *d;
27098 + u8 dlci = pn->dlci;
27100 + BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
27105 + d = rfcomm_dlc_get(s, dlci);
27109 + rfcomm_apply_pn(d, cr, pn);
27110 + rfcomm_send_pn(s, 0, d);
27112 + /* PN response */
27113 + switch (d->state) {
27115 + rfcomm_apply_pn(d, cr, pn);
27117 + d->state = BT_CONNECT;
27118 + rfcomm_send_sabm(s, d->dlci);
27123 + u8 channel = __srv_channel(dlci);
27128 + /* PN request for non existing DLC.
27129 + * Assume incomming connection. */
27130 + if (rfcomm_connect_ind(s, channel, &d)) {
27132 + d->addr = __addr(s->initiator, dlci);
27133 + rfcomm_dlc_link(s, d);
27135 + rfcomm_apply_pn(d, cr, pn);
27137 + d->state = BT_OPEN;
27138 + rfcomm_send_pn(s, 0, d);
27140 + rfcomm_send_dm(s, dlci);
27146 +static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
27148 + struct rfcomm_rpn *rpn = (void *) skb->data;
27149 + u8 dlci = __get_dlci(rpn->dlci);
27152 + u8 data_bits = 0;
27153 + u8 stop_bits = 0;
27155 + u8 flow_ctrl = 0;
27157 + u8 xoff_char = 0;
27158 + u16 rpn_mask = RFCOMM_RPN_PM_ALL;
27160 + BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
27161 + dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
27162 + rpn->xon_char, rpn->xoff_char, rpn->param_mask);
27168 + /* request: return default setting */
27169 + bit_rate = RFCOMM_RPN_BR_115200;
27170 + data_bits = RFCOMM_RPN_DATA_8;
27171 + stop_bits = RFCOMM_RPN_STOP_1;
27172 + parity = RFCOMM_RPN_PARITY_NONE;
27173 + flow_ctrl = RFCOMM_RPN_FLOW_NONE;
27174 + xon_char = RFCOMM_RPN_XON_CHAR;
27175 + xoff_char = RFCOMM_RPN_XOFF_CHAR;
27179 + /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
27180 + no flow control lines, normal XON/XOFF chars */
27181 + if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
27182 + bit_rate = rpn->bit_rate;
27183 + if (bit_rate != RFCOMM_RPN_BR_115200) {
27184 + BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
27185 + bit_rate = RFCOMM_RPN_BR_115200;
27186 + rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
27189 + if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
27190 + data_bits = __get_rpn_data_bits(rpn->line_settings);
27191 + if (data_bits != RFCOMM_RPN_DATA_8) {
27192 + BT_DBG("RPN data bits mismatch 0x%x", data_bits);
27193 + data_bits = RFCOMM_RPN_DATA_8;
27194 + rpn_mask ^= RFCOMM_RPN_PM_DATA;
27197 + if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
27198 + stop_bits = __get_rpn_stop_bits(rpn->line_settings);
27199 + if (stop_bits != RFCOMM_RPN_STOP_1) {
27200 + BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
27201 + stop_bits = RFCOMM_RPN_STOP_1;
27202 + rpn_mask ^= RFCOMM_RPN_PM_STOP;
27205 + if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
27206 + parity = __get_rpn_parity(rpn->line_settings);
27207 + if (parity != RFCOMM_RPN_PARITY_NONE) {
27208 + BT_DBG("RPN parity mismatch 0x%x", parity);
27209 + parity = RFCOMM_RPN_PARITY_NONE;
27210 + rpn_mask ^= RFCOMM_RPN_PM_PARITY;
27213 + if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
27214 + flow_ctrl = rpn->flow_ctrl;
27215 + if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
27216 + BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
27217 + flow_ctrl = RFCOMM_RPN_FLOW_NONE;
27218 + rpn_mask ^= RFCOMM_RPN_PM_FLOW;
27221 + if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
27222 + xon_char = rpn->xon_char;
27223 + if (xon_char != RFCOMM_RPN_XON_CHAR) {
27224 + BT_DBG("RPN XON char mismatch 0x%x", xon_char);
27225 + xon_char = RFCOMM_RPN_XON_CHAR;
27226 + rpn_mask ^= RFCOMM_RPN_PM_XON;
27229 + if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
27230 + xoff_char = rpn->xoff_char;
27231 + if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
27232 + BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
27233 + xoff_char = RFCOMM_RPN_XOFF_CHAR;
27234 + rpn_mask ^= RFCOMM_RPN_PM_XOFF;
27239 + rfcomm_send_rpn(s, 0, dlci,
27240 + bit_rate, data_bits, stop_bits, parity, flow_ctrl,
27241 + xon_char, xoff_char, rpn_mask);
27246 +static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
27248 + struct rfcomm_rls *rls = (void *) skb->data;
27249 + u8 dlci = __get_dlci(rls->dlci);
27251 + BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
27256 + /* FIXME: We should probably do something with this
27257 + information here. But for now it's sufficient just
27258 + to reply -- Bluetooth 1.1 says it's mandatory to
27259 + recognise and respond to RLS */
27261 + rfcomm_send_rls(s, 0, dlci, rls->status);
27266 +static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
27268 + struct rfcomm_msc *msc = (void *) skb->data;
27269 + struct rfcomm_dlc *d;
27270 + u8 dlci = __get_dlci(msc->dlci);
27272 + BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
27274 + d = rfcomm_dlc_get(s, dlci);
27279 + if (msc->v24_sig & RFCOMM_V24_FC && !d->credits)
27280 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
27282 + clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
27284 + rfcomm_dlc_lock(d);
27285 + if (d->modem_status)
27286 + d->modem_status(d, msc->v24_sig);
27287 + rfcomm_dlc_unlock(d);
27289 + rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
27291 + d->mscex |= RFCOMM_MSCEX_RX;
27293 + d->mscex |= RFCOMM_MSCEX_TX;
27298 +static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
27300 + struct rfcomm_mcc *mcc = (void *) skb->data;
27301 + u8 type, cr, len;
27303 + cr = __test_cr(mcc->type);
27304 + type = __get_mcc_type(mcc->type);
27305 + len = __get_mcc_len(mcc->len);
27307 + BT_DBG("%p type 0x%x cr %d", s, type, cr);
27309 + skb_pull(skb, 2);
27313 + rfcomm_recv_pn(s, cr, skb);
27317 + rfcomm_recv_rpn(s, cr, len, skb);
27321 + rfcomm_recv_rls(s, cr, skb);
27325 + rfcomm_recv_msc(s, cr, skb);
27328 + case RFCOMM_FCOFF:
27330 + set_bit(RFCOMM_TX_THROTTLED, &s->flags);
27331 + rfcomm_send_fcoff(s, 0);
27335 + case RFCOMM_FCON:
27337 + clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
27338 + rfcomm_send_fcon(s, 0);
27342 + case RFCOMM_TEST:
27344 + rfcomm_send_test(s, 0, skb->data, skb->len);
27351 + BT_ERR("Unknown control type 0x%02x", type);
27352 + rfcomm_send_nsc(s, cr, type);
27358 +static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
27360 + struct rfcomm_dlc *d;
27362 + BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
27364 + d = rfcomm_dlc_get(s, dlci);
27366 + rfcomm_send_dm(s, dlci);
27370 + if (pf && d->credits) {
27371 + u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
27373 + d->tx_credits += credits;
27374 + if (d->tx_credits)
27375 + clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
27378 + if (skb->len && d->state == BT_CONNECTED) {
27379 + rfcomm_dlc_lock(d);
27381 + d->data_ready(d, skb);
27382 + rfcomm_dlc_unlock(d);
27391 +static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
27393 + struct rfcomm_hdr *hdr = (void *) skb->data;
27394 + u8 type, dlci, fcs;
27396 + dlci = __get_dlci(hdr->addr);
27397 + type = __get_type(hdr->ctrl);
27400 + skb->len--; skb->tail--;
27401 + fcs = *(u8 *) skb->tail;
27403 + if (__check_fcs(skb->data, type, fcs)) {
27404 + BT_ERR("bad checksum in packet");
27409 + if (__test_ea(hdr->len))
27410 + skb_pull(skb, 3);
27412 + skb_pull(skb, 4);
27415 + case RFCOMM_SABM:
27416 + if (__test_pf(hdr->ctrl))
27417 + rfcomm_recv_sabm(s, dlci);
27420 + case RFCOMM_DISC:
27421 + if (__test_pf(hdr->ctrl))
27422 + rfcomm_recv_disc(s, dlci);
27426 + if (__test_pf(hdr->ctrl))
27427 + rfcomm_recv_ua(s, dlci);
27431 + rfcomm_recv_dm(s, dlci);
27436 + return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
27438 + rfcomm_recv_mcc(s, skb);
27442 + BT_ERR("Unknown packet type 0x%02x\n", type);
27449 +/* ---- Connection and data processing ---- */
27451 +static void rfcomm_process_connect(struct rfcomm_session *s)
27453 + struct rfcomm_dlc *d;
27454 + struct list_head *p, *n;
27456 + BT_DBG("session %p state %ld", s, s->state);
27458 + list_for_each_safe(p, n, &s->dlcs) {
27459 + d = list_entry(p, struct rfcomm_dlc, list);
27460 + if (d->state == BT_CONFIG) {
27462 + rfcomm_send_pn(s, 1, d);
27467 +/* Send data queued for the DLC.
27468 + * Return number of frames left in the queue.
27470 +static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
27472 + struct sk_buff *skb;
27475 + BT_DBG("dlc %p state %ld credits %d rx_credits %d tx_credits %d",
27476 + d, d->state, d->credits, d->rx_credits, d->tx_credits);
27478 + /* Send pending MSC */
27479 + if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
27480 + rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
27482 + if (d->credits) {
27484 + * Give them some credits */
27485 + if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
27486 + d->rx_credits <= (d->credits >> 2)) {
27487 + rfcomm_send_credits(d->session, d->addr, d->credits - d->rx_credits);
27488 + d->rx_credits = d->credits;
27492 + * Give ourselves some credits */
27493 + d->tx_credits = 5;
27496 + if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
27497 + return skb_queue_len(&d->tx_queue);
27499 + while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
27500 + err = rfcomm_send_frame(d->session, skb->data, skb->len);
27502 + skb_queue_head(&d->tx_queue, skb);
27509 + if (d->credits && !d->tx_credits) {
27510 + /* We're out of TX credits.
27511 + * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
27512 + set_bit(RFCOMM_TX_THROTTLED, &d->flags);
27515 + return skb_queue_len(&d->tx_queue);
27518 +static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
27520 + struct rfcomm_dlc *d;
27521 + struct list_head *p, *n;
27523 + BT_DBG("session %p state %ld", s, s->state);
27525 + list_for_each_safe(p, n, &s->dlcs) {
27526 + d = list_entry(p, struct rfcomm_dlc, list);
27527 + if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
27528 + __rfcomm_dlc_close(d, ETIMEDOUT);
27532 + if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
27535 + if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
27536 + d->mscex == RFCOMM_MSCEX_OK)
27537 + rfcomm_process_tx(d);
27541 +static inline void rfcomm_process_rx(struct rfcomm_session *s)
27543 + struct socket *sock = s->sock;
27544 + struct sock *sk = sock->sk;
27545 + struct sk_buff *skb;
27547 + BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
27549 + /* Get data directly from socket receive queue without copying it. */
27550 + while ((skb = skb_dequeue(&sk->receive_queue))) {
27552 + rfcomm_recv_frame(s, skb);
27555 + if (sk->state == BT_CLOSED) {
27556 + if (!s->initiator)
27557 + rfcomm_session_put(s);
27559 + rfcomm_session_close(s, sk->err);
27563 +static inline void rfcomm_accept_connection(struct rfcomm_session *s)
27565 + struct socket *sock = s->sock, *nsock;
27568 + /* Fast check for a new connection.
27569 + * Avoids unnesesary socket allocations. */
27570 + if (list_empty(&bluez_pi(sock->sk)->accept_q))
27573 + BT_DBG("session %p", s);
27575 + nsock = sock_alloc();
27579 + nsock->type = sock->type;
27580 + nsock->ops = sock->ops;
27582 + err = sock->ops->accept(sock, nsock, O_NONBLOCK);
27584 + sock_release(nsock);
27588 + /* Set our callbacks */
27589 + nsock->sk->data_ready = rfcomm_l2data_ready;
27590 + nsock->sk->state_change = rfcomm_l2state_change;
27592 + s = rfcomm_session_add(nsock, BT_OPEN);
27594 + rfcomm_session_hold(s);
27596 + sock_release(nsock);
27599 +static inline void rfcomm_check_connection(struct rfcomm_session *s)
27601 + struct sock *sk = s->sock->sk;
27603 + BT_DBG("%p state %ld", s, s->state);
27605 + switch(sk->state) {
27606 + case BT_CONNECTED:
27607 + s->state = BT_CONNECT;
27609 + /* We can adjust MTU on outgoing sessions.
27610 + * L2CAP MTU minus UIH header and FCS. */
27611 + s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
27613 + rfcomm_send_sabm(s, 0);
27617 + s->state = BT_CLOSED;
27618 + rfcomm_session_close(s, sk->err);
27623 +static inline void rfcomm_process_sessions(void)
27625 + struct list_head *p, *n;
27629 + list_for_each_safe(p, n, &session_list) {
27630 + struct rfcomm_session *s;
27631 + s = list_entry(p, struct rfcomm_session, list);
27633 + if (s->state == BT_LISTEN) {
27634 + rfcomm_accept_connection(s);
27638 + rfcomm_session_hold(s);
27640 + switch (s->state) {
27642 + rfcomm_check_connection(s);
27646 + rfcomm_process_rx(s);
27650 + rfcomm_process_dlcs(s);
27652 + rfcomm_session_put(s);
27658 +static void rfcomm_worker(void)
27662 + daemonize(); reparent_to_init();
27663 + set_fs(KERNEL_DS);
27665 + while (!atomic_read(&terminate)) {
27666 + BT_DBG("worker loop event 0x%lx", rfcomm_event);
27668 + if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
27669 + /* No pending events. Let's sleep.
27670 + * Incomming connections and data will wake us up. */
27671 + set_current_state(TASK_INTERRUPTIBLE);
27675 + /* Process stuff */
27676 + clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
27677 + rfcomm_process_sessions();
27679 + set_current_state(TASK_RUNNING);
27683 +static int rfcomm_add_listener(bdaddr_t *ba)
27685 + struct sockaddr_l2 addr;
27686 + struct l2cap_options opts;
27687 + struct socket *sock;
27688 + struct rfcomm_session *s;
27689 + int size, err = 0;
27691 + /* Create socket */
27692 + err = rfcomm_l2sock_create(&sock);
27694 + BT_ERR("Create socket failed %d", err);
27698 + /* Bind socket */
27699 + bacpy(&addr.l2_bdaddr, ba);
27700 + addr.l2_family = AF_BLUETOOTH;
27701 + addr.l2_psm = htobs(RFCOMM_PSM);
27702 + err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
27704 + BT_ERR("Bind failed %d", err);
27708 + /* Set L2CAP options */
27709 + size = sizeof(opts);
27710 + sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
27712 + opts.imtu = RFCOMM_MAX_L2CAP_MTU;
27713 + sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
27715 + /* Start listening on the socket */
27716 + err = sock->ops->listen(sock, 10);
27718 + BT_ERR("Listen failed %d", err);
27722 + /* Add listening session */
27723 + s = rfcomm_session_add(sock, BT_LISTEN);
27727 + rfcomm_session_hold(s);
27730 + sock_release(sock);
27734 +static void rfcomm_kill_listener(void)
27736 + struct rfcomm_session *s;
27737 + struct list_head *p, *n;
27741 + list_for_each_safe(p, n, &session_list) {
27742 + s = list_entry(p, struct rfcomm_session, list);
27743 + rfcomm_session_del(s);
27747 +static int rfcomm_run(void *unused)
27749 + rfcomm_thread = current;
27751 + atomic_inc(&running);
27753 + daemonize(); reparent_to_init();
27755 + sigfillset(¤t->blocked);
27756 + set_fs(KERNEL_DS);
27758 + sprintf(current->comm, "krfcommd");
27762 + rfcomm_add_listener(BDADDR_ANY);
27766 + rfcomm_kill_listener();
27768 + atomic_dec(&running);
27772 +/* ---- Proc fs support ---- */
27773 +static int rfcomm_dlc_dump(char *buf)
27775 + struct rfcomm_session *s;
27777 + struct list_head *p, *pp;
27782 + list_for_each(p, &session_list) {
27783 + s = list_entry(p, struct rfcomm_session, list);
27784 + sk = s->sock->sk;
27786 + list_for_each(pp, &s->dlcs) {
27787 + struct rfcomm_dlc *d;
27788 + d = list_entry(pp, struct rfcomm_dlc, list);
27790 + ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
27791 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
27792 + d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
27798 + return ptr - buf;
27801 +extern int rfcomm_sock_dump(char *buf);
27803 +static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
27808 + BT_DBG("count %d, offset %ld", count, offset);
27810 + ptr += rfcomm_dlc_dump(ptr);
27811 + ptr += rfcomm_sock_dump(ptr);
27814 + if (len <= count + offset)
27817 + *start = buf + offset;
27828 +/* ---- Initialization ---- */
27829 +int __init rfcomm_init(void)
27833 + kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
27835 + rfcomm_init_sockets();
27837 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
27838 + rfcomm_init_ttys();
27841 + create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
27843 + BT_INFO("BlueZ RFCOMM ver %s", VERSION);
27844 + BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
27845 + BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
27849 +void rfcomm_cleanup(void)
27851 + /* Terminate working thread.
27852 + * ie. Set terminate flag and wake it up */
27853 + atomic_inc(&terminate);
27854 + rfcomm_schedule(RFCOMM_SCHED_STATE);
27856 + /* Wait until thread is running */
27857 + while (atomic_read(&running))
27860 + remove_proc_entry("bluetooth/rfcomm", NULL);
27862 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
27863 + rfcomm_cleanup_ttys();
27866 + rfcomm_cleanup_sockets();
27870 +module_init(rfcomm_init);
27871 +module_exit(rfcomm_cleanup);
27873 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
27874 +MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
27875 +MODULE_LICENSE("GPL");
27876 diff -urN linux-2.4.18/net/bluetooth/rfcomm/crc.c linux-2.4.18-mh9/net/bluetooth/rfcomm/crc.c
27877 --- linux-2.4.18/net/bluetooth/rfcomm/crc.c Thu Jan 1 01:00:00 1970
27878 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/crc.c Mon Aug 25 18:38:12 2003
27881 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
27882 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
27883 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
27885 + This program is free software; you can redistribute it and/or modify
27886 + it under the terms of the GNU General Public License version 2 as
27887 + published by the Free Software Foundation;
27889 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27890 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27891 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
27892 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
27893 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
27894 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27895 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27896 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27898 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
27899 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
27900 + SOFTWARE IS DISCLAIMED.
27904 + * RFCOMM FCS calculation.
27906 + * $Id: crc.c,v 1.2 2002/09/21 09:54:32 holtmann Exp $
27909 +/* reversed, 8-bit, poly=0x07 */
27910 +unsigned char rfcomm_crc_table[256] = {
27911 + 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
27912 + 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
27913 + 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
27914 + 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
27916 + 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
27917 + 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
27918 + 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
27919 + 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
27921 + 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
27922 + 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
27923 + 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
27924 + 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
27926 + 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
27927 + 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
27928 + 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
27929 + 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
27931 + 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
27932 + 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
27933 + 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
27934 + 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
27936 + 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
27937 + 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
27938 + 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
27939 + 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
27941 + 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
27942 + 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
27943 + 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
27944 + 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
27946 + 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
27947 + 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
27948 + 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
27949 + 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
27951 diff -urN linux-2.4.18/net/bluetooth/rfcomm/sock.c linux-2.4.18-mh9/net/bluetooth/rfcomm/sock.c
27952 --- linux-2.4.18/net/bluetooth/rfcomm/sock.c Thu Jan 1 01:00:00 1970
27953 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/sock.c Mon Aug 25 18:38:12 2003
27956 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
27957 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
27958 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
27960 + This program is free software; you can redistribute it and/or modify
27961 + it under the terms of the GNU General Public License version 2 as
27962 + published by the Free Software Foundation;
27964 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27965 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27966 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
27967 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
27968 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
27969 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27970 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27971 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27973 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
27974 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
27975 + SOFTWARE IS DISCLAIMED.
27979 + * RFCOMM sockets.
27981 + * $Id: sock.c,v 1.30 2002/10/18 20:12:12 maxk Exp $
27984 +#include <linux/config.h>
27985 +#include <linux/module.h>
27987 +#include <linux/types.h>
27988 +#include <linux/errno.h>
27989 +#include <linux/kernel.h>
27990 +#include <linux/major.h>
27991 +#include <linux/sched.h>
27992 +#include <linux/slab.h>
27993 +#include <linux/poll.h>
27994 +#include <linux/fcntl.h>
27995 +#include <linux/init.h>
27996 +#include <linux/skbuff.h>
27997 +#include <linux/interrupt.h>
27998 +#include <linux/socket.h>
27999 +#include <linux/skbuff.h>
28000 +#include <linux/list.h>
28001 +#include <net/sock.h>
28003 +#include <asm/system.h>
28004 +#include <asm/uaccess.h>
28006 +#include <net/bluetooth/bluetooth.h>
28007 +#include <net/bluetooth/rfcomm.h>
28009 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
28011 +#define BT_DBG(D...)
28014 +static struct proto_ops rfcomm_sock_ops;
28016 +static struct bluez_sock_list rfcomm_sk_list = {
28017 + lock: RW_LOCK_UNLOCKED
28020 +static void rfcomm_sock_close(struct sock *sk);
28021 +static void rfcomm_sock_kill(struct sock *sk);
28023 +/* ---- DLC callbacks ----
28025 + * called under rfcomm_dlc_lock()
28027 +static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
28029 + struct sock *sk = d->owner;
28033 + atomic_add(skb->len, &sk->rmem_alloc);
28034 + skb_queue_tail(&sk->receive_queue, skb);
28035 + sk->data_ready(sk, skb->len);
28037 + if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
28038 + rfcomm_dlc_throttle(d);
28041 +static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
28043 + struct sock *sk = d->owner, *parent;
28047 + BT_DBG("dlc %p state %ld err %d", d, d->state, err);
28049 + bh_lock_sock(sk);
28053 + sk->state = d->state;
28055 + parent = bluez_pi(sk)->parent;
28057 + if (d->state == BT_CONNECTED)
28058 + rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
28059 + sk->state_change(sk);
28061 + parent->data_ready(parent, 0);
28063 + bh_unlock_sock(sk);
28066 +/* ---- Socket functions ---- */
28067 +static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
28071 + for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
28072 + if (rfcomm_pi(sk)->channel == channel &&
28073 + !bacmp(&bluez_pi(sk)->src, src))
28080 +/* Find socket with channel and source bdaddr.
28081 + * Returns closest match.
28083 +static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
28085 + struct sock *sk, *sk1 = NULL;
28087 + for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
28088 + if (state && sk->state != state)
28091 + if (rfcomm_pi(sk)->channel == channel) {
28092 + /* Exact match. */
28093 + if (!bacmp(&bluez_pi(sk)->src, src))
28096 + /* Closest match */
28097 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
28101 + return sk ? sk : sk1;
28104 +/* Find socket with given address (channel, src).
28105 + * Returns locked socket */
28106 +static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
28109 + read_lock(&rfcomm_sk_list.lock);
28110 + s = __rfcomm_get_sock_by_channel(state, channel, src);
28111 + if (s) bh_lock_sock(s);
28112 + read_unlock(&rfcomm_sk_list.lock);
28116 +static void rfcomm_sock_destruct(struct sock *sk)
28118 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
28120 + BT_DBG("sk %p dlc %p", sk, d);
28122 + skb_queue_purge(&sk->receive_queue);
28123 + skb_queue_purge(&sk->write_queue);
28125 + rfcomm_dlc_lock(d);
28126 + rfcomm_pi(sk)->dlc = NULL;
28128 + /* Detach DLC if it's owned by this socket */
28129 + if (d->owner == sk)
28131 + rfcomm_dlc_unlock(d);
28133 + rfcomm_dlc_put(d);
28135 + MOD_DEC_USE_COUNT;
28138 +static void rfcomm_sock_cleanup_listen(struct sock *parent)
28142 + BT_DBG("parent %p", parent);
28144 + /* Close not yet accepted dlcs */
28145 + while ((sk = bluez_accept_dequeue(parent, NULL))) {
28146 + rfcomm_sock_close(sk);
28147 + rfcomm_sock_kill(sk);
28150 + parent->state = BT_CLOSED;
28151 + parent->zapped = 1;
28154 +/* Kill socket (only if zapped and orphan)
28155 + * Must be called on unlocked socket.
28157 +static void rfcomm_sock_kill(struct sock *sk)
28159 + if (!sk->zapped || sk->socket)
28162 + BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
28164 + /* Kill poor orphan */
28165 + bluez_sock_unlink(&rfcomm_sk_list, sk);
28170 +static void __rfcomm_sock_close(struct sock *sk)
28172 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
28174 + BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
28176 + switch (sk->state) {
28178 + rfcomm_sock_cleanup_listen(sk);
28182 + case BT_CONNECT2:
28184 + case BT_CONNECTED:
28185 + rfcomm_dlc_close(d, 0);
28194 + * Must be called on unlocked socket.
28196 +static void rfcomm_sock_close(struct sock *sk)
28199 + __rfcomm_sock_close(sk);
28200 + release_sock(sk);
28203 +static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
28205 + BT_DBG("sk %p", sk);
28208 + sk->type = parent->type;
28211 +static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
28213 + struct rfcomm_dlc *d;
28216 + sk = sk_alloc(PF_BLUETOOTH, prio, 1);
28220 + d = rfcomm_dlc_alloc(prio);
28225 + d->data_ready = rfcomm_sk_data_ready;
28226 + d->state_change = rfcomm_sk_state_change;
28228 + rfcomm_pi(sk)->dlc = d;
28231 + bluez_sock_init(sock, sk);
28235 + sk->destruct = rfcomm_sock_destruct;
28236 + sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
28238 + sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
28239 + sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
28241 + sk->protocol = proto;
28242 + sk->state = BT_OPEN;
28244 + bluez_sock_link(&rfcomm_sk_list, sk);
28246 + BT_DBG("sk %p", sk);
28248 + MOD_INC_USE_COUNT;
28252 +static int rfcomm_sock_create(struct socket *sock, int protocol)
28256 + BT_DBG("sock %p", sock);
28258 + sock->state = SS_UNCONNECTED;
28260 + if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
28261 + return -ESOCKTNOSUPPORT;
28263 + sock->ops = &rfcomm_sock_ops;
28265 + if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
28268 + rfcomm_sock_init(sk, NULL);
28272 +static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
28274 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
28275 + struct sock *sk = sock->sk;
28278 + BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
28280 + if (!addr || addr->sa_family != AF_BLUETOOTH)
28285 + if (sk->state != BT_OPEN) {
28290 + write_lock_bh(&rfcomm_sk_list.lock);
28292 + if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
28293 + err = -EADDRINUSE;
28295 + /* Save source address */
28296 + bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
28297 + rfcomm_pi(sk)->channel = sa->rc_channel;
28298 + sk->state = BT_BOUND;
28301 + write_unlock_bh(&rfcomm_sk_list.lock);
28304 + release_sock(sk);
28308 +static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
28310 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
28311 + struct sock *sk = sock->sk;
28312 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
28315 + BT_DBG("sk %p", sk);
28317 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
28320 + if (sk->state != BT_OPEN && sk->state != BT_BOUND)
28323 + if (sk->type != SOCK_STREAM)
28328 + sk->state = BT_CONNECT;
28329 + bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
28330 + rfcomm_pi(sk)->channel = sa->rc_channel;
28332 + err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
28334 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
28335 + sock_sndtimeo(sk, flags & O_NONBLOCK));
28337 + release_sock(sk);
28341 +int rfcomm_sock_listen(struct socket *sock, int backlog)
28343 + struct sock *sk = sock->sk;
28346 + BT_DBG("sk %p backlog %d", sk, backlog);
28350 + if (sk->state != BT_BOUND) {
28355 + sk->max_ack_backlog = backlog;
28356 + sk->ack_backlog = 0;
28357 + sk->state = BT_LISTEN;
28360 + release_sock(sk);
28364 +int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
28366 + DECLARE_WAITQUEUE(wait, current);
28367 + struct sock *sk = sock->sk, *nsk;
28373 + if (sk->state != BT_LISTEN) {
28378 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
28380 + BT_DBG("sk %p timeo %ld", sk, timeo);
28382 + /* Wait for an incoming connection. (wake-one). */
28383 + add_wait_queue_exclusive(sk->sleep, &wait);
28384 + while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
28385 + set_current_state(TASK_INTERRUPTIBLE);
28391 + release_sock(sk);
28392 + timeo = schedule_timeout(timeo);
28395 + if (sk->state != BT_LISTEN) {
28400 + if (signal_pending(current)) {
28401 + err = sock_intr_errno(timeo);
28405 + set_current_state(TASK_RUNNING);
28406 + remove_wait_queue(sk->sleep, &wait);
28411 + newsock->state = SS_CONNECTED;
28413 + BT_DBG("new socket %p", nsk);
28416 + release_sock(sk);
28420 +static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
28422 + struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
28423 + struct sock *sk = sock->sk;
28425 + BT_DBG("sock %p, sk %p", sock, sk);
28427 + sa->rc_family = AF_BLUETOOTH;
28428 + sa->rc_channel = rfcomm_pi(sk)->channel;
28430 + bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
28432 + bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
28434 + *len = sizeof(struct sockaddr_rc);
28438 +static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
28439 + struct scm_cookie *scm)
28441 + struct sock *sk = sock->sk;
28442 + struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
28443 + struct sk_buff *skb;
28447 + if (msg->msg_flags & MSG_OOB)
28448 + return -EOPNOTSUPP;
28450 + if (sk->shutdown & SEND_SHUTDOWN)
28453 + BT_DBG("sock %p, sk %p", sock, sk);
28458 + size = min_t(uint, len, d->mtu);
28460 + skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
28461 + msg->msg_flags & MSG_DONTWAIT, &err);
28464 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
28466 + err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
28473 + err = rfcomm_dlc_send(d, skb);
28483 + release_sock(sk);
28485 + return sent ? sent : err;
28488 +static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
28490 + DECLARE_WAITQUEUE(wait, current);
28492 + add_wait_queue(sk->sleep, &wait);
28494 + set_current_state(TASK_INTERRUPTIBLE);
28496 + if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
28497 + signal_pending(current) || !timeo)
28500 + set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
28501 + release_sock(sk);
28502 + timeo = schedule_timeout(timeo);
28504 + clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
28507 + __set_current_state(TASK_RUNNING);
28508 + remove_wait_queue(sk->sleep, &wait);
28512 +static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
28513 + int flags, struct scm_cookie *scm)
28515 + struct sock *sk = sock->sk;
28516 + int target, err = 0, copied = 0;
28519 + if (flags & MSG_OOB)
28520 + return -EOPNOTSUPP;
28522 + msg->msg_namelen = 0;
28524 + BT_DBG("sk %p size %d", sk, size);
28528 + target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
28529 + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
28532 + struct sk_buff *skb;
28535 + skb = skb_dequeue(&sk->receive_queue);
28537 + if (copied >= target)
28540 + if ((err = sock_error(sk)) != 0)
28542 + if (sk->shutdown & RCV_SHUTDOWN)
28549 + timeo = rfcomm_sock_data_wait(sk, timeo);
28551 + if (signal_pending(current)) {
28552 + err = sock_intr_errno(timeo);
28558 + chunk = min_t(unsigned int, skb->len, size);
28559 + if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
28560 + skb_queue_head(&sk->receive_queue, skb);
28562 + copied = -EFAULT;
28568 + if (!(flags & MSG_PEEK)) {
28569 + atomic_sub(chunk, &sk->rmem_alloc);
28571 + skb_pull(skb, chunk);
28573 + skb_queue_head(&sk->receive_queue, skb);
28579 + /* put message back and return */
28580 + skb_queue_head(&sk->receive_queue, skb);
28586 + if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
28587 + rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
28589 + release_sock(sk);
28590 + return copied ? : err;
28593 +static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
28595 + struct sock *sk = sock->sk;
28598 + BT_DBG("sk %p", sk);
28602 + switch (optname) {
28604 + err = -ENOPROTOOPT;
28608 + release_sock(sk);
28612 +static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
28614 + struct sock *sk = sock->sk;
28615 + int len, err = 0;
28617 + BT_DBG("sk %p", sk);
28619 + if (get_user(len, optlen))
28624 + switch (optname) {
28626 + err = -ENOPROTOOPT;
28630 + release_sock(sk);
28634 +static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
28636 + struct sock *sk = sock->sk;
28641 +#ifdef CONFIG_BLUEZ_RFCOMM_TTY
28642 + err = rfcomm_dev_ioctl(sk, cmd, arg);
28644 + err = -EOPNOTSUPP;
28647 + release_sock(sk);
28652 +static int rfcomm_sock_shutdown(struct socket *sock, int how)
28654 + struct sock *sk = sock->sk;
28657 + BT_DBG("sock %p, sk %p", sock, sk);
28659 + if (!sk) return 0;
28662 + if (!sk->shutdown) {
28663 + sk->shutdown = SHUTDOWN_MASK;
28664 + __rfcomm_sock_close(sk);
28667 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
28669 + release_sock(sk);
28673 +static int rfcomm_sock_release(struct socket *sock)
28675 + struct sock *sk = sock->sk;
28678 + BT_DBG("sock %p, sk %p", sock, sk);
28683 + err = rfcomm_sock_shutdown(sock, 2);
28686 + rfcomm_sock_kill(sk);
28690 +/* ---- RFCOMM core layer callbacks ----
28692 + * called under rfcomm_lock()
28694 +int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
28696 + struct sock *sk, *parent;
28697 + bdaddr_t src, dst;
28700 + BT_DBG("session %p channel %d", s, channel);
28702 + rfcomm_session_getaddr(s, &src, &dst);
28704 + /* Check if we have socket listening on this channel */
28705 + parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
28709 + /* Check for backlog size */
28710 + if (parent->ack_backlog > parent->max_ack_backlog) {
28711 + BT_DBG("backlog full %d", parent->ack_backlog);
28715 + sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
28719 + rfcomm_sock_init(sk, parent);
28720 + bacpy(&bluez_pi(sk)->src, &src);
28721 + bacpy(&bluez_pi(sk)->dst, &dst);
28722 + rfcomm_pi(sk)->channel = channel;
28724 + sk->state = BT_CONFIG;
28725 + bluez_accept_enqueue(parent, sk);
28727 + /* Accept connection and return socket DLC */
28728 + *d = rfcomm_pi(sk)->dlc;
28732 + bh_unlock_sock(parent);
28736 +/* ---- Proc fs support ---- */
28737 +int rfcomm_sock_dump(char *buf)
28739 + struct bluez_sock_list *list = &rfcomm_sk_list;
28740 + struct rfcomm_pinfo *pi;
28744 + write_lock_bh(&list->lock);
28746 + for (sk = list->head; sk; sk = sk->next) {
28747 + pi = rfcomm_pi(sk);
28748 + ptr += sprintf(ptr, "sk %s %s %d %d\n",
28749 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
28750 + sk->state, rfcomm_pi(sk)->channel);
28753 + write_unlock_bh(&list->lock);
28755 + return ptr - buf;
28758 +static struct proto_ops rfcomm_sock_ops = {
28759 + family: PF_BLUETOOTH,
28760 + release: rfcomm_sock_release,
28761 + bind: rfcomm_sock_bind,
28762 + connect: rfcomm_sock_connect,
28763 + listen: rfcomm_sock_listen,
28764 + accept: rfcomm_sock_accept,
28765 + getname: rfcomm_sock_getname,
28766 + sendmsg: rfcomm_sock_sendmsg,
28767 + recvmsg: rfcomm_sock_recvmsg,
28768 + shutdown: rfcomm_sock_shutdown,
28769 + setsockopt: rfcomm_sock_setsockopt,
28770 + getsockopt: rfcomm_sock_getsockopt,
28771 + ioctl: rfcomm_sock_ioctl,
28772 + poll: bluez_sock_poll,
28773 + socketpair: sock_no_socketpair,
28774 + mmap: sock_no_mmap
28777 +static struct net_proto_family rfcomm_sock_family_ops = {
28778 + family: PF_BLUETOOTH,
28779 + create: rfcomm_sock_create
28782 +int rfcomm_init_sockets(void)
28786 + if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
28787 + BT_ERR("Can't register RFCOMM socket layer");
28794 +void rfcomm_cleanup_sockets(void)
28798 + /* Unregister socket, protocol and notifier */
28799 + if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
28800 + BT_ERR("Can't unregister RFCOMM socket layer %d", err);
28802 diff -urN linux-2.4.18/net/bluetooth/rfcomm/tty.c linux-2.4.18-mh9/net/bluetooth/rfcomm/tty.c
28803 --- linux-2.4.18/net/bluetooth/rfcomm/tty.c Thu Jan 1 01:00:00 1970
28804 +++ linux-2.4.18-mh9/net/bluetooth/rfcomm/tty.c Mon Aug 25 18:38:12 2003
28807 + RFCOMM implementation for Linux Bluetooth stack (BlueZ).
28808 + Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
28809 + Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
28811 + This program is free software; you can redistribute it and/or modify
28812 + it under the terms of the GNU General Public License version 2 as
28813 + published by the Free Software Foundation;
28815 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28816 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28817 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
28818 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
28819 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
28820 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
28821 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28822 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28824 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
28825 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
28826 + SOFTWARE IS DISCLAIMED.
28832 + * $Id: tty.c,v 1.26 2002/10/18 20:12:12 maxk Exp $
28835 +#include <linux/config.h>
28836 +#include <linux/module.h>
28838 +#include <linux/tty.h>
28839 +#include <linux/tty_driver.h>
28840 +#include <linux/tty_flip.h>
28842 +#include <linux/slab.h>
28843 +#include <linux/skbuff.h>
28845 +#include <net/bluetooth/bluetooth.h>
28846 +#include <net/bluetooth/rfcomm.h>
28848 +#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
28850 +#define BT_DBG(D...)
28853 +#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
28854 +#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
28855 +#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
28856 +#define RFCOMM_TTY_MINOR 0
28858 +struct rfcomm_dev {
28859 + struct list_head list;
28864 + unsigned long flags;
28872 + uint modem_status;
28874 + struct rfcomm_dlc *dlc;
28875 + struct tty_struct *tty;
28876 + wait_queue_head_t wait;
28877 + struct tasklet_struct wakeup_task;
28879 + atomic_t wmem_alloc;
28882 +static LIST_HEAD(rfcomm_dev_list);
28883 +static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
28885 +static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
28886 +static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
28887 +static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
28889 +static void rfcomm_tty_wakeup(unsigned long arg);
28891 +/* ---- Device functions ---- */
28892 +static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
28894 + struct rfcomm_dlc *dlc = dev->dlc;
28896 + BT_DBG("dev %p dlc %p", dev, dlc);
28898 + rfcomm_dlc_lock(dlc);
28899 + /* Detach DLC if it's owned by this dev */
28900 + if (dlc->owner == dev)
28901 + dlc->owner = NULL;
28902 + rfcomm_dlc_unlock(dlc);
28904 + rfcomm_dlc_put(dlc);
28907 + MOD_DEC_USE_COUNT;
28910 +static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
28912 + atomic_inc(&dev->refcnt);
28915 +static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
28917 + if (atomic_dec_and_test(&dev->refcnt))
28918 + rfcomm_dev_destruct(dev);
28921 +static struct rfcomm_dev *__rfcomm_dev_get(int id)
28923 + struct rfcomm_dev *dev;
28924 + struct list_head *p;
28926 + list_for_each(p, &rfcomm_dev_list) {
28927 + dev = list_entry(p, struct rfcomm_dev, list);
28928 + if (dev->id == id)
28935 +static inline struct rfcomm_dev *rfcomm_dev_get(int id)
28937 + struct rfcomm_dev *dev;
28939 + read_lock(&rfcomm_dev_lock);
28940 + dev = __rfcomm_dev_get(id);
28941 + read_unlock(&rfcomm_dev_lock);
28943 + if (dev) rfcomm_dev_hold(dev);
28947 +static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
28949 + struct rfcomm_dev *dev;
28950 + struct list_head *head = &rfcomm_dev_list, *p;
28953 + BT_DBG("id %d channel %d", req->dev_id, req->channel);
28955 + dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
28958 + memset(dev, 0, sizeof(struct rfcomm_dev));
28960 + write_lock_bh(&rfcomm_dev_lock);
28962 + if (req->dev_id < 0) {
28965 + list_for_each(p, &rfcomm_dev_list) {
28966 + if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
28973 + dev->id = req->dev_id;
28975 + list_for_each(p, &rfcomm_dev_list) {
28976 + struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
28978 + if (entry->id == dev->id) {
28979 + err = -EADDRINUSE;
28983 + if (entry->id > dev->id - 1)
28990 + if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
28995 + sprintf(dev->name, "rfcomm%d", dev->id);
28997 + list_add(&dev->list, head);
28998 + atomic_set(&dev->refcnt, 1);
29000 + bacpy(&dev->src, &req->src);
29001 + bacpy(&dev->dst, &req->dst);
29002 + dev->channel = req->channel;
29004 + dev->flags = req->flags &
29005 + ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
29007 + init_waitqueue_head(&dev->wait);
29008 + tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
29010 + rfcomm_dlc_lock(dlc);
29011 + dlc->data_ready = rfcomm_dev_data_ready;
29012 + dlc->state_change = rfcomm_dev_state_change;
29013 + dlc->modem_status = rfcomm_dev_modem_status;
29015 + dlc->owner = dev;
29017 + rfcomm_dlc_unlock(dlc);
29019 + MOD_INC_USE_COUNT;
29022 + write_unlock_bh(&rfcomm_dev_lock);
29031 +static void rfcomm_dev_del(struct rfcomm_dev *dev)
29033 + BT_DBG("dev %p", dev);
29035 + write_lock_bh(&rfcomm_dev_lock);
29036 + list_del_init(&dev->list);
29037 + write_unlock_bh(&rfcomm_dev_lock);
29039 + rfcomm_dev_put(dev);
29042 +/* ---- Send buffer ---- */
29044 +static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
29046 + /* We can't let it be zero, because we don't get a callback
29047 + when tx_credits becomes nonzero, hence we'd never wake up */
29048 + return dlc->mtu * (dlc->tx_credits?:1);
29051 +static void rfcomm_wfree(struct sk_buff *skb)
29053 + struct rfcomm_dev *dev = (void *) skb->sk;
29054 + atomic_sub(skb->truesize, &dev->wmem_alloc);
29055 + if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
29056 + tasklet_schedule(&dev->wakeup_task);
29057 + rfcomm_dev_put(dev);
29060 +static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
29062 + rfcomm_dev_hold(dev);
29063 + atomic_add(skb->truesize, &dev->wmem_alloc);
29064 + skb->sk = (void *) dev;
29065 + skb->destructor = rfcomm_wfree;
29068 +static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
29070 + if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
29071 + struct sk_buff *skb = alloc_skb(size, priority);
29073 + rfcomm_set_owner_w(skb, dev);
29080 +/* ---- Device IOCTLs ---- */
29082 +#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
29084 +static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
29086 + struct rfcomm_dev_req req;
29087 + struct rfcomm_dlc *dlc;
29090 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
29093 + BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
29095 + if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
29098 + if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
29099 + /* Socket must be connected */
29100 + if (sk->state != BT_CONNECTED)
29103 + dlc = rfcomm_pi(sk)->dlc;
29104 + rfcomm_dlc_hold(dlc);
29106 + dlc = rfcomm_dlc_alloc(GFP_KERNEL);
29111 + id = rfcomm_dev_add(&req, dlc);
29113 + rfcomm_dlc_put(dlc);
29117 + if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
29118 + /* DLC is now used by device.
29119 + * Socket must be disconnected */
29120 + sk->state = BT_CLOSED;
29126 +static int rfcomm_release_dev(unsigned long arg)
29128 + struct rfcomm_dev_req req;
29129 + struct rfcomm_dev *dev;
29131 + if (copy_from_user(&req, (void *) arg, sizeof(req)))
29134 + BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
29136 + if (!capable(CAP_NET_ADMIN))
29139 + if (!(dev = rfcomm_dev_get(req.dev_id)))
29142 + if (req.flags & (1 << RFCOMM_HANGUP_NOW))
29143 + rfcomm_dlc_close(dev->dlc, 0);
29145 + rfcomm_dev_del(dev);
29146 + rfcomm_dev_put(dev);
29150 +static int rfcomm_get_dev_list(unsigned long arg)
29152 + struct rfcomm_dev_list_req *dl;
29153 + struct rfcomm_dev_info *di;
29154 + struct list_head *p;
29160 + if (get_user(dev_num, (u16 *) arg))
29166 + size = sizeof(*dl) + dev_num * sizeof(*di);
29168 + if (verify_area(VERIFY_WRITE, (void *)arg, size))
29171 + if (!(dl = kmalloc(size, GFP_KERNEL)))
29174 + di = dl->dev_info;
29176 + read_lock_bh(&rfcomm_dev_lock);
29178 + list_for_each(p, &rfcomm_dev_list) {
29179 + struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
29180 + (di + n)->id = dev->id;
29181 + (di + n)->flags = dev->flags;
29182 + (di + n)->state = dev->dlc->state;
29183 + (di + n)->channel = dev->channel;
29184 + bacpy(&(di + n)->src, &dev->src);
29185 + bacpy(&(di + n)->dst, &dev->dst);
29186 + if (++n >= dev_num)
29190 + read_unlock_bh(&rfcomm_dev_lock);
29193 + size = sizeof(*dl) + n * sizeof(*di);
29195 + copy_to_user((void *) arg, dl, size);
29200 +static int rfcomm_get_dev_info(unsigned long arg)
29202 + struct rfcomm_dev *dev;
29203 + struct rfcomm_dev_info di;
29208 + if (copy_from_user(&di, (void *)arg, sizeof(di)))
29211 + if (!(dev = rfcomm_dev_get(di.id)))
29214 + di.flags = dev->flags;
29215 + di.channel = dev->channel;
29216 + di.state = dev->dlc->state;
29217 + bacpy(&di.src, &dev->src);
29218 + bacpy(&di.dst, &dev->dst);
29220 + if (copy_to_user((void *)arg, &di, sizeof(di)))
29223 + rfcomm_dev_put(dev);
29227 +int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
29229 + BT_DBG("cmd %d arg %ld", cmd, arg);
29232 + case RFCOMMCREATEDEV:
29233 + return rfcomm_create_dev(sk, arg);
29235 + case RFCOMMRELEASEDEV:
29236 + return rfcomm_release_dev(arg);
29238 + case RFCOMMGETDEVLIST:
29239 + return rfcomm_get_dev_list(arg);
29241 + case RFCOMMGETDEVINFO:
29242 + return rfcomm_get_dev_info(arg);
29248 +/* ---- DLC callbacks ---- */
29249 +static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
29251 + struct rfcomm_dev *dev = dlc->owner;
29252 + struct tty_struct *tty;
29254 + if (!dev || !(tty = dev->tty)) {
29259 + BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
29261 + if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
29263 + for (i = 0; i < skb->len; i++) {
29264 + if (tty->flip.count >= TTY_FLIPBUF_SIZE)
29265 + tty_flip_buffer_push(tty);
29267 + tty_insert_flip_char(tty, skb->data[i], 0);
29269 + tty_flip_buffer_push(tty);
29271 + tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
29276 +static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
29278 + struct rfcomm_dev *dev = dlc->owner;
29282 + BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
29285 + wake_up_interruptible(&dev->wait);
29287 + if (dlc->state == BT_CLOSED) {
29289 + if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
29290 + rfcomm_dev_hold(dev);
29291 + rfcomm_dev_del(dev);
29293 + /* We have to drop DLC lock here, otherwise
29294 + * rfcomm_dev_put() will dead lock if it's the last refference */
29295 + rfcomm_dlc_unlock(dlc);
29296 + rfcomm_dev_put(dev);
29297 + rfcomm_dlc_lock(dlc);
29300 + tty_hangup(dev->tty);
29304 +static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
29306 + struct rfcomm_dev *dev = dlc->owner;
29310 + BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
29312 + dev->modem_status =
29313 + ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
29314 + ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
29315 + ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
29316 + ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
29319 +/* ---- TTY functions ---- */
29320 +static void rfcomm_tty_wakeup(unsigned long arg)
29322 + struct rfcomm_dev *dev = (void *) arg;
29323 + struct tty_struct *tty = dev->tty;
29327 + BT_DBG("dev %p tty %p", dev, tty);
29329 + if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
29330 + (tty->ldisc.write_wakeup)(tty);
29332 + wake_up_interruptible(&tty->write_wait);
29333 +#ifdef SERIAL_HAVE_POLL_WAIT
29334 + wake_up_interruptible(&tty->poll_wait);
29338 +static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
29340 + DECLARE_WAITQUEUE(wait, current);
29341 + struct rfcomm_dev *dev;
29342 + struct rfcomm_dlc *dlc;
29345 + id = MINOR(tty->device) - tty->driver.minor_start;
29347 + BT_DBG("tty %p id %d", tty, id);
29349 + dev = rfcomm_dev_get(id);
29353 + BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
29355 + if (dev->opened++ != 0)
29360 + /* Attach TTY and open DLC */
29362 + rfcomm_dlc_lock(dlc);
29363 + tty->driver_data = dev;
29365 + rfcomm_dlc_unlock(dlc);
29366 + set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
29368 + err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
29372 + /* Wait for DLC to connect */
29373 + add_wait_queue(&dev->wait, &wait);
29375 + set_current_state(TASK_INTERRUPTIBLE);
29377 + if (dlc->state == BT_CLOSED) {
29382 + if (dlc->state == BT_CONNECTED)
29385 + if (signal_pending(current)) {
29392 + set_current_state(TASK_RUNNING);
29393 + remove_wait_queue(&dev->wait, &wait);
29398 +static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
29400 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29404 + BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
29406 + if (--dev->opened == 0) {
29407 + /* Close DLC and dettach TTY */
29408 + rfcomm_dlc_close(dev->dlc, 0);
29410 + clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
29411 + tasklet_kill(&dev->wakeup_task);
29413 + rfcomm_dlc_lock(dev->dlc);
29414 + tty->driver_data = NULL;
29416 + rfcomm_dlc_unlock(dev->dlc);
29419 + rfcomm_dev_put(dev);
29422 +static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
29424 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29425 + struct rfcomm_dlc *dlc = dev->dlc;
29426 + struct sk_buff *skb;
29427 + int err = 0, sent = 0, size;
29429 + BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
29432 + size = min_t(uint, count, dlc->mtu);
29435 + skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
29437 + skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
29442 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
29445 + copy_from_user(skb_put(skb, size), buf + sent, size);
29447 + memcpy(skb_put(skb, size), buf + sent, size);
29449 + if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
29458 + return sent ? sent : err;
29461 +static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
29463 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29464 + struct rfcomm_dlc *dlc = dev->dlc;
29465 + struct sk_buff *skb;
29467 + BT_DBG("tty %p char %x", tty, ch);
29469 + skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
29474 + skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
29476 + *(char *)skb_put(skb, 1) = ch;
29478 + if ((rfcomm_dlc_send(dlc, skb)) < 0)
29482 +static int rfcomm_tty_write_room(struct tty_struct *tty)
29484 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29487 + BT_DBG("tty %p", tty);
29489 + room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
29496 +static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
29498 + u8 v24_sig, mask;
29500 + BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
29502 + if (cmd == TIOCMSET)
29505 + rfcomm_dlc_get_modem_status(dlc, &v24_sig);
29507 + mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
29508 + ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
29509 + ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
29510 + ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
29511 + ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
29512 + ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
29514 + if (cmd == TIOCMBIC)
29515 + v24_sig &= ~mask;
29519 + rfcomm_dlc_set_modem_status(dlc, v24_sig);
29523 +static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
29525 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29526 + struct rfcomm_dlc *dlc = dev->dlc;
29530 + BT_DBG("tty %p cmd 0x%02x", tty, cmd);
29534 + BT_DBG("TCGETS is not supported");
29535 + return -ENOIOCTLCMD;
29538 + BT_DBG("TCSETS is not supported");
29539 + return -ENOIOCTLCMD;
29542 + BT_DBG("TIOCMGET");
29544 + return put_user(dev->modem_status, (unsigned int *)arg);
29546 + case TIOCMSET: /* Turns on and off the lines as specified by the mask */
29547 + case TIOCMBIS: /* Turns on the lines as specified by the mask */
29548 + case TIOCMBIC: /* Turns off the lines as specified by the mask */
29549 + if ((err = get_user(status, (unsigned int *)arg)))
29551 + return rfcomm_tty_set_modem_status(cmd, dlc, status);
29554 + BT_DBG("TIOCMIWAIT");
29557 + case TIOCGICOUNT:
29558 + BT_DBG("TIOCGICOUNT");
29561 + case TIOCGSERIAL:
29562 + BT_ERR("TIOCGSERIAL is not supported");
29563 + return -ENOIOCTLCMD;
29565 + case TIOCSSERIAL:
29566 + BT_ERR("TIOCSSERIAL is not supported");
29567 + return -ENOIOCTLCMD;
29569 + case TIOCSERGSTRUCT:
29570 + BT_ERR("TIOCSERGSTRUCT is not supported");
29571 + return -ENOIOCTLCMD;
29573 + case TIOCSERGETLSR:
29574 + BT_ERR("TIOCSERGETLSR is not supported");
29575 + return -ENOIOCTLCMD;
29577 + case TIOCSERCONFIG:
29578 + BT_ERR("TIOCSERCONFIG is not supported");
29579 + return -ENOIOCTLCMD;
29582 + return -ENOIOCTLCMD; /* ioctls which we must ignore */
29586 + return -ENOIOCTLCMD;
29589 +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
29591 +static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
29593 + BT_DBG("tty %p", tty);
29595 + if ((tty->termios->c_cflag == old->c_cflag) &&
29596 + (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
29599 + /* handle turning off CRTSCTS */
29600 + if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
29601 + BT_DBG("turning off CRTSCTS");
29605 +static void rfcomm_tty_throttle(struct tty_struct *tty)
29607 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29609 + BT_DBG("tty %p dev %p", tty, dev);
29611 + rfcomm_dlc_throttle(dev->dlc);
29614 +static void rfcomm_tty_unthrottle(struct tty_struct *tty)
29616 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29618 + BT_DBG("tty %p dev %p", tty, dev);
29620 + rfcomm_dlc_unthrottle(dev->dlc);
29623 +static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
29625 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29626 + struct rfcomm_dlc *dlc = dev->dlc;
29628 + BT_DBG("tty %p dev %p", tty, dev);
29630 + if (skb_queue_len(&dlc->tx_queue))
29636 +static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
29638 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29642 + BT_DBG("tty %p dev %p", tty, dev);
29644 + skb_queue_purge(&dev->dlc->tx_queue);
29646 + if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
29647 + tty->ldisc.write_wakeup(tty);
29650 +static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
29652 + BT_DBG("tty %p ch %c", tty, ch);
29655 +static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
29657 + BT_DBG("tty %p timeout %d", tty, timeout);
29660 +static void rfcomm_tty_hangup(struct tty_struct *tty)
29662 + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
29666 + BT_DBG("tty %p dev %p", tty, dev);
29668 + rfcomm_tty_flush_buffer(tty);
29670 + if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
29671 + rfcomm_dev_del(dev);
29674 +static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
29679 +/* ---- TTY structure ---- */
29680 +static int rfcomm_tty_refcount; /* If we manage several devices */
29682 +static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
29683 +static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
29684 +static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
29686 +static struct tty_driver rfcomm_tty_driver = {
29687 + magic: TTY_DRIVER_MAGIC,
29688 + driver_name: "rfcomm",
29689 +#ifdef CONFIG_DEVFS_FS
29690 + name: "bluetooth/rfcomm/%d",
29694 + major: RFCOMM_TTY_MAJOR,
29695 + minor_start: RFCOMM_TTY_MINOR,
29696 + num: RFCOMM_TTY_PORTS,
29697 + type: TTY_DRIVER_TYPE_SERIAL,
29698 + subtype: SERIAL_TYPE_NORMAL,
29699 + flags: TTY_DRIVER_REAL_RAW,
29701 + refcount: &rfcomm_tty_refcount,
29702 + table: rfcomm_tty_table,
29703 + termios: rfcomm_tty_termios,
29704 + termios_locked: rfcomm_tty_termios_locked,
29706 + open: rfcomm_tty_open,
29707 + close: rfcomm_tty_close,
29708 + put_char: rfcomm_tty_put_char,
29709 + write: rfcomm_tty_write,
29710 + write_room: rfcomm_tty_write_room,
29711 + chars_in_buffer: rfcomm_tty_chars_in_buffer,
29712 + flush_buffer: rfcomm_tty_flush_buffer,
29713 + ioctl: rfcomm_tty_ioctl,
29714 + throttle: rfcomm_tty_throttle,
29715 + unthrottle: rfcomm_tty_unthrottle,
29716 + set_termios: rfcomm_tty_set_termios,
29717 + send_xchar: rfcomm_tty_send_xchar,
29720 + hangup: rfcomm_tty_hangup,
29721 + wait_until_sent: rfcomm_tty_wait_until_sent,
29722 + read_proc: rfcomm_tty_read_proc,
29725 +int rfcomm_init_ttys(void)
29729 + /* Initalize our global data */
29730 + for (i = 0; i < RFCOMM_TTY_PORTS; i++)
29731 + rfcomm_tty_table[i] = NULL;
29733 + /* Register the TTY driver */
29734 + rfcomm_tty_driver.init_termios = tty_std_termios;
29735 + rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
29736 + rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
29738 + if (tty_register_driver(&rfcomm_tty_driver)) {
29739 + BT_ERR("Can't register RFCOMM TTY driver");
29746 +void rfcomm_cleanup_ttys(void)
29748 + tty_unregister_driver(&rfcomm_tty_driver);
29751 diff -urN linux-2.4.18/net/bluetooth/sco.c linux-2.4.18-mh9/net/bluetooth/sco.c
29752 --- linux-2.4.18/net/bluetooth/sco.c Thu Jan 1 01:00:00 1970
29753 +++ linux-2.4.18-mh9/net/bluetooth/sco.c Mon Aug 25 18:38:12 2003
29756 + BlueZ - Bluetooth protocol stack for Linux
29757 + Copyright (C) 2000-2001 Qualcomm Incorporated
29759 + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
29761 + This program is free software; you can redistribute it and/or modify
29762 + it under the terms of the GNU General Public License version 2 as
29763 + published by the Free Software Foundation;
29765 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
29766 + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29767 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
29768 + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
29769 + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
29770 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29771 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29772 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29774 + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
29775 + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
29776 + SOFTWARE IS DISCLAIMED.
29780 + * BlueZ SCO sockets.
29782 + * $Id: sco.c,v 1.4 2002/07/22 20:32:54 maxk Exp $
29784 +#define VERSION "0.3"
29786 +#include <linux/config.h>
29787 +#include <linux/module.h>
29789 +#include <linux/types.h>
29790 +#include <linux/errno.h>
29791 +#include <linux/kernel.h>
29792 +#include <linux/major.h>
29793 +#include <linux/sched.h>
29794 +#include <linux/slab.h>
29795 +#include <linux/poll.h>
29796 +#include <linux/fcntl.h>
29797 +#include <linux/init.h>
29798 +#include <linux/skbuff.h>
29799 +#include <linux/interrupt.h>
29800 +#include <linux/socket.h>
29801 +#include <linux/skbuff.h>
29802 +#include <linux/proc_fs.h>
29803 +#include <linux/list.h>
29804 +#include <net/sock.h>
29806 +#include <asm/system.h>
29807 +#include <asm/uaccess.h>
29809 +#include <net/bluetooth/bluetooth.h>
29810 +#include <net/bluetooth/hci_core.h>
29811 +#include <net/bluetooth/sco.h>
29815 +#define BT_DBG( A... )
29818 +static struct proto_ops sco_sock_ops;
29820 +static struct bluez_sock_list sco_sk_list = {
29821 + lock: RW_LOCK_UNLOCKED
29824 +static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
29825 +static void sco_chan_del(struct sock *sk, int err);
29826 +static inline struct sock * sco_chan_get(struct sco_conn *conn);
29828 +static int sco_conn_del(struct hci_conn *conn, int err);
29830 +static void sco_sock_close(struct sock *sk);
29831 +static void sco_sock_kill(struct sock *sk);
29833 +/* ----- SCO timers ------ */
29834 +static void sco_sock_timeout(unsigned long arg)
29836 + struct sock *sk = (struct sock *) arg;
29838 + BT_DBG("sock %p state %d", sk, sk->state);
29840 + bh_lock_sock(sk);
29841 + sk->err = ETIMEDOUT;
29842 + sk->state_change(sk);
29843 + bh_unlock_sock(sk);
29845 + sco_sock_kill(sk);
29849 +static void sco_sock_set_timer(struct sock *sk, long timeout)
29851 + BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
29853 + if (!mod_timer(&sk->timer, jiffies + timeout))
29857 +static void sco_sock_clear_timer(struct sock *sk)
29859 + BT_DBG("sock %p state %d", sk, sk->state);
29861 + if (timer_pending(&sk->timer) && del_timer(&sk->timer))
29865 +static void sco_sock_init_timer(struct sock *sk)
29867 + init_timer(&sk->timer);
29868 + sk->timer.function = sco_sock_timeout;
29869 + sk->timer.data = (unsigned long)sk;
29872 +/* -------- SCO connections --------- */
29873 +static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
29875 + struct hci_dev *hdev = hcon->hdev;
29876 + struct sco_conn *conn;
29878 + if ((conn = hcon->sco_data))
29884 + if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
29886 + memset(conn, 0, sizeof(struct sco_conn));
29888 + spin_lock_init(&conn->lock);
29890 + hcon->sco_data = conn;
29891 + conn->hcon = hcon;
29893 + conn->src = &hdev->bdaddr;
29894 + conn->dst = &hcon->dst;
29896 + if (hdev->sco_mtu > 0)
29897 + conn->mtu = hdev->sco_mtu;
29901 + BT_DBG("hcon %p conn %p", hcon, conn);
29903 + MOD_INC_USE_COUNT;
29907 +static int sco_conn_del(struct hci_conn *hcon, int err)
29909 + struct sco_conn *conn;
29912 + if (!(conn = hcon->sco_data))
29915 + BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
29917 + /* Kill socket */
29918 + if ((sk = sco_chan_get(conn))) {
29919 + bh_lock_sock(sk);
29920 + sco_sock_clear_timer(sk);
29921 + sco_chan_del(sk, err);
29922 + bh_unlock_sock(sk);
29923 + sco_sock_kill(sk);
29926 + hcon->sco_data = NULL;
29929 + MOD_DEC_USE_COUNT;
29933 +int sco_connect(struct sock *sk)
29935 + bdaddr_t *src = &bluez_pi(sk)->src;
29936 + bdaddr_t *dst = &bluez_pi(sk)->dst;
29937 + struct sco_conn *conn;
29938 + struct hci_conn *hcon;
29939 + struct hci_dev *hdev;
29942 + BT_DBG("%s -> %s", batostr(src), batostr(dst));
29944 + if (!(hdev = hci_get_route(dst, src)))
29945 + return -EHOSTUNREACH;
29947 + hci_dev_lock_bh(hdev);
29951 + hcon = hci_connect(hdev, SCO_LINK, dst);
29955 + conn = sco_conn_add(hcon, 0);
29957 + hci_conn_put(hcon);
29961 + /* Update source addr of the socket */
29962 + bacpy(src, conn->src);
29964 + err = sco_chan_add(conn, sk, NULL);
29968 + if (hcon->state == BT_CONNECTED) {
29969 + sco_sock_clear_timer(sk);
29970 + sk->state = BT_CONNECTED;
29972 + sk->state = BT_CONNECT;
29973 + sco_sock_set_timer(sk, sk->sndtimeo);
29976 + hci_dev_unlock_bh(hdev);
29977 + hci_dev_put(hdev);
29981 +static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
29983 + struct sco_conn *conn = sco_pi(sk)->conn;
29984 + struct sk_buff *skb;
29987 + /* Check outgoing MTU */
29988 + if (len > conn->mtu)
29991 + BT_DBG("sk %p len %d", sk, len);
29993 + count = MIN(conn->mtu, len);
29994 + if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
29997 + if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
30002 + if ((err = hci_send_sco(conn->hcon, skb)) < 0)
30012 +static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
30014 + struct sock *sk = sco_chan_get(conn);
30019 + BT_DBG("sk %p len %d", sk, skb->len);
30021 + if (sk->state != BT_CONNECTED)
30024 + if (!sock_queue_rcv_skb(sk, skb))
30032 +/* -------- Socket interface ---------- */
30033 +static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
30037 + for (sk = sco_sk_list.head; sk; sk = sk->next) {
30038 + if (!bacmp(&bluez_pi(sk)->src, ba))
30045 +/* Find socket listening on source bdaddr.
30046 + * Returns closest match.
30048 +static struct sock *sco_get_sock_listen(bdaddr_t *src)
30050 + struct sock *sk, *sk1 = NULL;
30052 + read_lock(&sco_sk_list.lock);
30054 + for (sk = sco_sk_list.head; sk; sk = sk->next) {
30055 + if (sk->state != BT_LISTEN)
30058 + /* Exact match. */
30059 + if (!bacmp(&bluez_pi(sk)->src, src))
30062 + /* Closest match */
30063 + if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
30067 + read_unlock(&sco_sk_list.lock);
30069 + return sk ? sk : sk1;
30072 +static void sco_sock_destruct(struct sock *sk)
30074 + BT_DBG("sk %p", sk);
30076 + skb_queue_purge(&sk->receive_queue);
30077 + skb_queue_purge(&sk->write_queue);
30079 + MOD_DEC_USE_COUNT;
30082 +static void sco_sock_cleanup_listen(struct sock *parent)
30086 + BT_DBG("parent %p", parent);
30088 + /* Close not yet accepted channels */
30089 + while ((sk = bluez_accept_dequeue(parent, NULL))) {
30090 + sco_sock_close(sk);
30091 + sco_sock_kill(sk);
30094 + parent->state = BT_CLOSED;
30095 + parent->zapped = 1;
30098 +/* Kill socket (only if zapped and orphan)
30099 + * Must be called on unlocked socket.
30101 +static void sco_sock_kill(struct sock *sk)
30103 + if (!sk->zapped || sk->socket)
30106 + BT_DBG("sk %p state %d", sk, sk->state);
30108 + /* Kill poor orphan */
30109 + bluez_sock_unlink(&sco_sk_list, sk);
30115 + * Must be called on unlocked socket.
30117 +static void sco_sock_close(struct sock *sk)
30119 + struct sco_conn *conn;
30121 + sco_sock_clear_timer(sk);
30125 + conn = sco_pi(sk)->conn;
30127 + BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
30129 + switch (sk->state) {
30131 + sco_sock_cleanup_listen(sk);
30134 + case BT_CONNECTED:
30138 + sco_chan_del(sk, ECONNRESET);
30146 + release_sock(sk);
30149 +static void sco_sock_init(struct sock *sk, struct sock *parent)
30151 + BT_DBG("sk %p", sk);
30154 + sk->type = parent->type;
30157 +static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
30161 + if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
30164 + bluez_sock_init(sock, sk);
30168 + sk->destruct = sco_sock_destruct;
30169 + sk->sndtimeo = SCO_CONN_TIMEOUT;
30171 + sk->protocol = proto;
30172 + sk->state = BT_OPEN;
30174 + sco_sock_init_timer(sk);
30176 + bluez_sock_link(&sco_sk_list, sk);
30178 + MOD_INC_USE_COUNT;
30182 +static int sco_sock_create(struct socket *sock, int protocol)
30186 + BT_DBG("sock %p", sock);
30188 + sock->state = SS_UNCONNECTED;
30190 + if (sock->type != SOCK_SEQPACKET)
30191 + return -ESOCKTNOSUPPORT;
30193 + sock->ops = &sco_sock_ops;
30195 + if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
30198 + sco_sock_init(sk, NULL);
30202 +static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
30204 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
30205 + struct sock *sk = sock->sk;
30206 + bdaddr_t *src = &sa->sco_bdaddr;
30209 + BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
30211 + if (!addr || addr->sa_family != AF_BLUETOOTH)
30216 + if (sk->state != BT_OPEN) {
30221 + write_lock_bh(&sco_sk_list.lock);
30223 + if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
30224 + err = -EADDRINUSE;
30226 + /* Save source address */
30227 + bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
30228 + sk->state = BT_BOUND;
30231 + write_unlock_bh(&sco_sk_list.lock);
30234 + release_sock(sk);
30239 +static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
30241 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
30242 + struct sock *sk = sock->sk;
30246 + BT_DBG("sk %p", sk);
30248 + if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
30251 + if (sk->state != BT_OPEN && sk->state != BT_BOUND)
30254 + if (sk->type != SOCK_SEQPACKET)
30259 + /* Set destination address and psm */
30260 + bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
30262 + if ((err = sco_connect(sk)))
30265 + err = bluez_sock_wait_state(sk, BT_CONNECTED,
30266 + sock_sndtimeo(sk, flags & O_NONBLOCK));
30269 + release_sock(sk);
30273 +int sco_sock_listen(struct socket *sock, int backlog)
30275 + struct sock *sk = sock->sk;
30278 + BT_DBG("sk %p backlog %d", sk, backlog);
30282 + if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
30287 + sk->max_ack_backlog = backlog;
30288 + sk->ack_backlog = 0;
30289 + sk->state = BT_LISTEN;
30292 + release_sock(sk);
30296 +int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
30298 + DECLARE_WAITQUEUE(wait, current);
30299 + struct sock *sk = sock->sk, *ch;
30305 + if (sk->state != BT_LISTEN) {
30310 + timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
30312 + BT_DBG("sk %p timeo %ld", sk, timeo);
30314 + /* Wait for an incoming connection. (wake-one). */
30315 + add_wait_queue_exclusive(sk->sleep, &wait);
30316 + while (!(ch = bluez_accept_dequeue(sk, newsock))) {
30317 + set_current_state(TASK_INTERRUPTIBLE);
30323 + release_sock(sk);
30324 + timeo = schedule_timeout(timeo);
30327 + if (sk->state != BT_LISTEN) {
30332 + if (signal_pending(current)) {
30333 + err = sock_intr_errno(timeo);
30337 + set_current_state(TASK_RUNNING);
30338 + remove_wait_queue(sk->sleep, &wait);
30343 + newsock->state = SS_CONNECTED;
30345 + BT_DBG("new socket %p", ch);
30348 + release_sock(sk);
30352 +static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
30354 + struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
30355 + struct sock *sk = sock->sk;
30357 + BT_DBG("sock %p, sk %p", sock, sk);
30359 + addr->sa_family = AF_BLUETOOTH;
30360 + *len = sizeof(struct sockaddr_sco);
30363 + bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
30365 + bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
30370 +static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
30372 + struct sock *sk = sock->sk;
30375 + BT_DBG("sock %p, sk %p", sock, sk);
30378 + return sock_error(sk);
30380 + if (msg->msg_flags & MSG_OOB)
30381 + return -EOPNOTSUPP;
30385 + if (sk->state == BT_CONNECTED)
30386 + err = sco_send_frame(sk, msg, len);
30390 + release_sock(sk);
30394 +int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
30396 + struct sock *sk = sock->sk;
30399 + BT_DBG("sk %p", sk);
30403 + switch (optname) {
30405 + err = -ENOPROTOOPT;
30409 + release_sock(sk);
30413 +int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
30415 + struct sock *sk = sock->sk;
30416 + struct sco_options opts;
30417 + struct sco_conninfo cinfo;
30418 + int len, err = 0;
30420 + BT_DBG("sk %p", sk);
30422 + if (get_user(len, optlen))
30427 + switch (optname) {
30428 + case SCO_OPTIONS:
30429 + if (sk->state != BT_CONNECTED) {
30434 + opts.mtu = sco_pi(sk)->conn->mtu;
30436 + BT_DBG("mtu %d", opts.mtu);
30438 + len = MIN(len, sizeof(opts));
30439 + if (copy_to_user(optval, (char *)&opts, len))
30444 + case SCO_CONNINFO:
30445 + if (sk->state != BT_CONNECTED) {
30450 + cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
30452 + len = MIN(len, sizeof(cinfo));
30453 + if (copy_to_user(optval, (char *)&cinfo, len))
30459 + err = -ENOPROTOOPT;
30463 + release_sock(sk);
30467 +static int sco_sock_release(struct socket *sock)
30469 + struct sock *sk = sock->sk;
30472 + BT_DBG("sock %p, sk %p", sock, sk);
30477 + sco_sock_close(sk);
30478 + if (sk->linger) {
30480 + err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
30481 + release_sock(sk);
30485 + sco_sock_kill(sk);
30489 +static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
30491 + BT_DBG("conn %p", conn);
30493 + sco_pi(sk)->conn = conn;
30497 + bluez_accept_enqueue(parent, sk);
30500 +static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
30504 + sco_conn_lock(conn);
30508 + __sco_chan_add(conn, sk, parent);
30510 + sco_conn_unlock(conn);
30514 +static inline struct sock * sco_chan_get(struct sco_conn *conn)
30516 + struct sock *sk = NULL;
30517 + sco_conn_lock(conn);
30519 + sco_conn_unlock(conn);
30523 +/* Delete channel.
30524 + * Must be called on the locked socket. */
30525 +static void sco_chan_del(struct sock *sk, int err)
30527 + struct sco_conn *conn;
30529 + conn = sco_pi(sk)->conn;
30531 + BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
30534 + sco_conn_lock(conn);
30536 + sco_pi(sk)->conn = NULL;
30537 + sco_conn_unlock(conn);
30538 + hci_conn_put(conn->hcon);
30541 + sk->state = BT_CLOSED;
30543 + sk->state_change(sk);
30548 +static void sco_conn_ready(struct sco_conn *conn)
30550 + struct sock *parent, *sk;
30552 + BT_DBG("conn %p", conn);
30554 + sco_conn_lock(conn);
30556 + if ((sk = conn->sk)) {
30557 + sco_sock_clear_timer(sk);
30558 + bh_lock_sock(sk);
30559 + sk->state = BT_CONNECTED;
30560 + sk->state_change(sk);
30561 + bh_unlock_sock(sk);
30563 + parent = sco_get_sock_listen(conn->src);
30567 + bh_lock_sock(parent);
30569 + sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
30571 + bh_unlock_sock(parent);
30575 + sco_sock_init(sk, parent);
30577 + bacpy(&bluez_pi(sk)->src, conn->src);
30578 + bacpy(&bluez_pi(sk)->dst, conn->dst);
30580 + hci_conn_hold(conn->hcon);
30581 + __sco_chan_add(conn, sk, parent);
30583 + sk->state = BT_CONNECTED;
30585 + /* Wake up parent */
30586 + parent->data_ready(parent, 1);
30588 + bh_unlock_sock(parent);
30592 + sco_conn_unlock(conn);
30595 +/* ----- SCO interface with lower layer (HCI) ----- */
30596 +int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
30598 + BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
30600 + /* Always accept connection */
30601 + return HCI_LM_ACCEPT;
30604 +int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
30606 + BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
30608 + if (hcon->type != SCO_LINK)
30612 + struct sco_conn *conn;
30614 + conn = sco_conn_add(hcon, status);
30616 + sco_conn_ready(conn);
30618 + sco_conn_del(hcon, bterr(status));
30623 +int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
30625 + BT_DBG("hcon %p reason %d", hcon, reason);
30627 + if (hcon->type != SCO_LINK)
30630 + sco_conn_del(hcon, bterr(reason));
30634 +int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
30636 + struct sco_conn *conn = hcon->sco_data;
30641 + BT_DBG("conn %p len %d", conn, skb->len);
30644 + sco_recv_frame(conn, skb);
30653 +/* ----- Proc fs support ------ */
30654 +static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
30656 + struct sco_pinfo *pi;
30660 + write_lock_bh(&list->lock);
30662 + for (sk = list->head; sk; sk = sk->next) {
30664 + ptr += sprintf(ptr, "%s %s %d\n",
30665 + batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
30669 + write_unlock_bh(&list->lock);
30671 + ptr += sprintf(ptr, "\n");
30673 + return ptr - buf;
30676 +static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
30681 + BT_DBG("count %d, offset %ld", count, offset);
30683 + ptr += sco_sock_dump(ptr, &sco_sk_list);
30686 + if (len <= count + offset)
30689 + *start = buf + offset;
30700 +static struct proto_ops sco_sock_ops = {
30701 + family: PF_BLUETOOTH,
30702 + release: sco_sock_release,
30703 + bind: sco_sock_bind,
30704 + connect: sco_sock_connect,
30705 + listen: sco_sock_listen,
30706 + accept: sco_sock_accept,
30707 + getname: sco_sock_getname,
30708 + sendmsg: sco_sock_sendmsg,
30709 + recvmsg: bluez_sock_recvmsg,
30710 + poll: bluez_sock_poll,
30711 + socketpair: sock_no_socketpair,
30712 + ioctl: sock_no_ioctl,
30713 + shutdown: sock_no_shutdown,
30714 + setsockopt: sco_sock_setsockopt,
30715 + getsockopt: sco_sock_getsockopt,
30716 + mmap: sock_no_mmap
30719 +static struct net_proto_family sco_sock_family_ops = {
30720 + family: PF_BLUETOOTH,
30721 + create: sco_sock_create
30724 +static struct hci_proto sco_hci_proto = {
30726 + id: HCI_PROTO_SCO,
30727 + connect_ind: sco_connect_ind,
30728 + connect_cfm: sco_connect_cfm,
30729 + disconn_ind: sco_disconn_ind,
30730 + recv_scodata: sco_recv_scodata,
30733 +int __init sco_init(void)
30737 + if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
30738 + BT_ERR("Can't register SCO socket layer");
30742 + if ((err = hci_register_proto(&sco_hci_proto))) {
30743 + BT_ERR("Can't register SCO protocol");
30747 + create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
30749 + BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
30750 + BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
30754 +void sco_cleanup(void)
30758 + remove_proc_entry("bluetooth/sco", NULL);
30760 + /* Unregister socket, protocol and notifier */
30761 + if ((err = bluez_sock_unregister(BTPROTO_SCO)))
30762 + BT_ERR("Can't unregister SCO socket layer %d", err);
30764 + if ((err = hci_unregister_proto(&sco_hci_proto)))
30765 + BT_ERR("Can't unregister SCO protocol %d", err);
30768 +module_init(sco_init);
30769 +module_exit(sco_cleanup);
30771 +MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
30772 +MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
30773 +MODULE_LICENSE("GPL");
30774 diff -urN linux-2.4.18/net/bluetooth/syms.c linux-2.4.18-mh9/net/bluetooth/syms.c
30775 --- linux-2.4.18/net/bluetooth/syms.c Fri Sep 7 18:28:38 2001
30776 +++ linux-2.4.18-mh9/net/bluetooth/syms.c Mon Aug 25 18:38:12 2003
30781 - * $Id: syms.c,v 1.1 2001/07/12 19:31:24 maxk Exp $
30782 + * $Id: syms.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
30785 #include <linux/config.h>
30786 @@ -39,25 +39,28 @@
30787 #include <linux/socket.h>
30789 #include <net/bluetooth/bluetooth.h>
30790 -#include <net/bluetooth/bluez.h>
30791 #include <net/bluetooth/hci_core.h>
30794 EXPORT_SYMBOL(hci_register_dev);
30795 EXPORT_SYMBOL(hci_unregister_dev);
30796 +EXPORT_SYMBOL(hci_suspend_dev);
30797 +EXPORT_SYMBOL(hci_resume_dev);
30799 EXPORT_SYMBOL(hci_register_proto);
30800 EXPORT_SYMBOL(hci_unregister_proto);
30801 -EXPORT_SYMBOL(hci_register_notifier);
30802 -EXPORT_SYMBOL(hci_unregister_notifier);
30804 +EXPORT_SYMBOL(hci_get_route);
30805 EXPORT_SYMBOL(hci_connect);
30806 -EXPORT_SYMBOL(hci_disconnect);
30807 EXPORT_SYMBOL(hci_dev_get);
30808 +EXPORT_SYMBOL(hci_conn_auth);
30809 +EXPORT_SYMBOL(hci_conn_encrypt);
30811 EXPORT_SYMBOL(hci_recv_frame);
30812 EXPORT_SYMBOL(hci_send_acl);
30813 EXPORT_SYMBOL(hci_send_sco);
30814 -EXPORT_SYMBOL(hci_send_raw);
30815 +EXPORT_SYMBOL(hci_send_cmd);
30816 +EXPORT_SYMBOL(hci_si_event);
30819 EXPORT_SYMBOL(bluez_dump);
30821 /* BlueZ sockets */
30822 EXPORT_SYMBOL(bluez_sock_register);
30823 EXPORT_SYMBOL(bluez_sock_unregister);
30824 +EXPORT_SYMBOL(bluez_sock_init);
30825 EXPORT_SYMBOL(bluez_sock_link);
30826 EXPORT_SYMBOL(bluez_sock_unlink);
30827 +EXPORT_SYMBOL(bluez_sock_recvmsg);
30828 +EXPORT_SYMBOL(bluez_sock_poll);
30829 +EXPORT_SYMBOL(bluez_accept_enqueue);
30830 +EXPORT_SYMBOL(bluez_accept_dequeue);
30831 +EXPORT_SYMBOL(bluez_sock_wait_state);